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