1/* Copyright (C) 2002 Red Hat, Inc. 2 Written by Ulrich Drepper <drepper@redhat.com>, 2002. 3 4 This program is Open Source software; you can redistribute it and/or 5 modify it under the terms of the Open Software License version 1.0 as 6 published by the Open Source Initiative. 7 8 You should have received a copy of the Open Software License along 9 with this program; if not, you may obtain a copy of the Open Software 10 License version 1.0 from http://www.opensource.org/licenses/osl.php or 11 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 12 3001 King Ranch Road, Ukiah, CA 95482. */ 13 14#include <fcntl.h> 15#include <libasm.h> 16#include <libelf.h> 17#include <stdio.h> 18#include <string.h> 19#include <unistd.h> 20 21 22static const char fname[] = "asm-tst2-out.o"; 23 24 25static const GElf_Ehdr expected_ehdr = 26 { 27 .e_ident = { [EI_MAG0] = ELFMAG0, 28 [EI_MAG1] = ELFMAG1, 29 [EI_MAG2] = ELFMAG2, 30 [EI_MAG3] = ELFMAG3, 31 [EI_CLASS] = ELFCLASS32, 32 [EI_DATA] = ELFDATA2LSB, 33 [EI_VERSION] = EV_CURRENT }, 34 .e_type = ET_REL, 35 .e_machine = EM_386, 36 .e_version = EV_CURRENT, 37 .e_shoff = 96, 38 .e_ehsize = sizeof (Elf32_Ehdr), 39 .e_shentsize = sizeof (Elf32_Shdr), 40 .e_shnum = 3, 41 .e_shstrndx = 2 42 }; 43 44 45static const char *scnnames[3] = 46 { 47 [0] = "", 48 [1] = ".data", 49 [2] = ".shstrtab" 50 }; 51 52 53int 54main (void) 55{ 56 AsmCtx_t *ctx; 57 AsmScn_t *scn1; 58 AsmScn_t *scn2; 59 int result = 0; 60 int fd; 61 Elf *elf; 62 GElf_Ehdr ehdr_mem; 63 GElf_Ehdr *ehdr; 64 size_t cnt; 65 66 elf_version (EV_CURRENT); 67 68 ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB); 69 if (ctx == NULL) 70 { 71 printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 72 return 1; 73 } 74 75 /* Create two sections. */ 76 scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 77 scn2 = asm_newsubscn (scn1, 1); 78 if (scn1 == NULL || scn2 == NULL) 79 { 80 printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 81 asm_abort (ctx); 82 return 1; 83 } 84 85 /* Special alignment for the .text section. */ 86 if (asm_align (scn1, 16) != 0) 87 { 88 printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 89 result = 1; 90 } 91 92 /* Add a few strings. */ 93 if (asm_addstrz (scn1, "one", 4) != 0) 94 { 95 printf ("cannot insert first string: %s\n", asm_errmsg (-1)); 96 result = 1; 97 } 98 if (asm_addstrz (scn2, "three", 0) != 0) 99 { 100 printf ("cannot insert second string: %s\n", asm_errmsg (-1)); 101 result = 1; 102 } 103 if (asm_addstrz (scn1, "two", 4) != 0) 104 { 105 printf ("cannot insert third string: %s\n", asm_errmsg (-1)); 106 result = 1; 107 } 108 109 /* Create the output file. */ 110 if (asm_end (ctx) != 0) 111 { 112 printf ("cannot create output file: %s\n", asm_errmsg (-1)); 113 asm_abort (ctx); 114 return 1; 115 } 116 117 /* Check the file. */ 118 fd = open (fname, O_RDONLY); 119 if (fd == -1) 120 { 121 printf ("cannot open generated file: %m\n"); 122 result = 1; 123 goto out; 124 } 125 126 elf = elf_begin (fd, ELF_C_READ, NULL); 127 if (elf == NULL) 128 { 129 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 130 result = 1; 131 goto out_close; 132 } 133 if (elf_kind (elf) != ELF_K_ELF) 134 { 135 puts ("not a valid ELF file"); 136 result = 1; 137 goto out_close2; 138 } 139 140 ehdr = gelf_getehdr (elf, &ehdr_mem); 141 if (ehdr == NULL) 142 { 143 printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 144 result = 1; 145 goto out_close2; 146 } 147 148 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 149 { 150 puts ("ELF header does not match"); 151 result = 1; 152 goto out_close2; 153 } 154 155 for (cnt = 1; cnt < 3; ++cnt) 156 { 157 Elf_Scn *scn; 158 GElf_Shdr shdr_mem; 159 GElf_Shdr *shdr; 160 161 scn = elf_getscn (elf, cnt); 162 if (scn == NULL) 163 { 164 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1)); 165 result = 1; 166 continue; 167 } 168 169 shdr = gelf_getshdr (scn, &shdr_mem); 170 if (shdr == NULL) 171 { 172 printf ("cannot get section header for section %Zd: %s\n", 173 cnt, elf_errmsg (-1)); 174 result = 1; 175 continue; 176 } 177 178 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 179 scnnames[cnt]) != 0) 180 { 181 printf ("section %Zd's name differs: %s vs %s\n", cnt, 182 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 183 scnnames[cnt]); 184 result = 1; 185 } 186 187 if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS)) 188 { 189 printf ("section %Zd's type differs\n", cnt); 190 result = 1; 191 } 192 193 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 194 || (cnt == 2 && shdr->sh_flags != 0)) 195 { 196 printf ("section %Zd's flags differs\n", cnt); 197 result = 1; 198 } 199 200 if (shdr->sh_addr != 0) 201 { 202 printf ("section %Zd's address differs\n", cnt); 203 result = 1; 204 } 205 206 if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15)) 207 || (cnt == 2 208 && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15) 209 + strlen ("one") + 1 210 + strlen ("two") + 1 211 + strlen ("three") + 1))) 212 { 213 printf ("section %Zd's offset differs\n", cnt); 214 result = 1; 215 } 216 217 if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1 218 + strlen ("two") + 1 219 + strlen ("three") + 1)) 220 || (cnt == 2 && shdr->sh_size != 17)) 221 { 222 printf ("section %Zd's size differs\n", cnt); 223 result = 1; 224 } 225 226 if (shdr->sh_link != 0) 227 { 228 printf ("section %Zd's link differs\n", cnt); 229 result = 1; 230 } 231 232 if (shdr->sh_info != 0) 233 { 234 printf ("section %Zd's info differs\n", cnt); 235 result = 1; 236 } 237 238 if ((cnt == 1 && shdr->sh_addralign != 16) 239 || (cnt != 1 && shdr->sh_addralign != 1)) 240 { 241 printf ("section %Zd's addralign differs\n", cnt); 242 result = 1; 243 } 244 245 if (shdr->sh_entsize != 0) 246 { 247 printf ("section %Zd's entsize differs\n", cnt); 248 result = 1; 249 } 250 } 251 252 out_close2: 253 elf_end (elf); 254 out_close: 255 close (fd); 256 out: 257 /* We don't need the file anymore. */ 258 unlink (fname); 259 260 return result; 261} 262