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-tst1-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 = 88, 46 .e_ehsize = sizeof (Elf32_Ehdr), 47 .e_shentsize = sizeof (Elf32_Shdr), 48 .e_shnum = 4, 49 .e_shstrndx = 3 50 }; 51 52 53 static const char *scnnames[4] = 54 { 55 [0] = "", 56 [1] = ".text", 57 [2] = ".data", 58 [3] = ".shstrtab" 59 }; 60 61 62 int 63 main (void) 64 { 65 AsmCtx_t *ctx; 66 AsmScn_t *scn1; 67 AsmScn_t *scn2; 68 int fd; 69 Elf *elf; 70 GElf_Ehdr ehdr_mem; 71 GElf_Ehdr *ehdr; 72 int result = 0; 73 size_t cnt; 74 75 elf_version (EV_CURRENT); 76 77 Ebl *ebl = ebl_openbackend_machine (EM_386); 78 if (ebl == NULL) 79 { 80 puts ("cannot open backend library"); 81 return 1; 82 } 83 84 ctx = asm_begin (fname, ebl, false); 85 if (ctx == NULL) 86 { 87 printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 88 return 1; 89 } 90 91 /* Create two sections. */ 92 scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); 93 scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 94 if (scn1 == NULL || scn2 == NULL) 95 { 96 printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 97 asm_abort (ctx); 98 return 1; 99 } 100 101 /* Special alignment for the .text section. */ 102 if (asm_align (scn1, 32) != 0) 103 { 104 printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 105 result = 1; 106 } 107 108 /* Create the output file. */ 109 if (asm_end (ctx) != 0) 110 { 111 printf ("cannot create output file: %s\n", asm_errmsg (-1)); 112 asm_abort (ctx); 113 return 1; 114 } 115 116 /* Check the file. */ 117 fd = open (fname, O_RDONLY); 118 if (fd == -1) 119 { 120 printf ("cannot open generated file: %m\n"); 121 result = 1; 122 goto out; 123 } 124 125 elf = elf_begin (fd, ELF_C_READ, NULL); 126 if (elf == NULL) 127 { 128 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 129 result = 1; 130 goto out_close; 131 } 132 if (elf_kind (elf) != ELF_K_ELF) 133 { 134 puts ("not a valid ELF file"); 135 result = 1; 136 goto out_close2; 137 } 138 139 ehdr = gelf_getehdr (elf, &ehdr_mem); 140 if (ehdr == NULL) 141 { 142 printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 143 result = 1; 144 goto out_close2; 145 } 146 147 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 148 { 149 puts ("ELF header does not match"); 150 result = 1; 151 goto out_close2; 152 } 153 154 for (cnt = 1; cnt < 4; ++cnt) 155 { 156 Elf_Scn *scn; 157 GElf_Shdr shdr_mem; 158 GElf_Shdr *shdr; 159 160 scn = elf_getscn (elf, cnt); 161 if (scn == NULL) 162 { 163 printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1)); 164 result = 1; 165 continue; 166 } 167 168 shdr = gelf_getshdr (scn, &shdr_mem); 169 if (shdr == NULL) 170 { 171 printf ("cannot get section header for section %zd: %s\n", 172 cnt, elf_errmsg (-1)); 173 result = 1; 174 continue; 175 } 176 177 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 178 scnnames[cnt]) != 0) 179 { 180 printf ("section %zd's name differs: %s vs %s\n", cnt, 181 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 182 scnnames[cnt]); 183 result = 1; 184 } 185 186 if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS)) 187 { 188 printf ("section %zd's type differs\n", cnt); 189 result = 1; 190 } 191 192 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR)) 193 || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 194 || (cnt == 3 && 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 (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31)) 207 { 208 printf ("section %zd's offset differs\n", cnt); 209 result = 1; 210 } 211 212 if ((cnt != 3 && shdr->sh_size != 0) 213 || (cnt == 3 && shdr->sh_size != 23)) 214 { 215 printf ("section %zd's size differs\n", cnt); 216 result = 1; 217 } 218 219 if (shdr->sh_link != 0) 220 { 221 printf ("section %zd's link differs\n", cnt); 222 result = 1; 223 } 224 225 if (shdr->sh_info != 0) 226 { 227 printf ("section %zd's info differs\n", cnt); 228 result = 1; 229 } 230 231 if ((cnt == 1 && shdr->sh_addralign != 32) 232 || (cnt != 1 && shdr->sh_addralign != 1)) 233 { 234 printf ("section %zd's addralign differs\n", cnt); 235 result = 1; 236 } 237 238 if (shdr->sh_entsize != 0) 239 { 240 printf ("section %zd's entsize differs\n", cnt); 241 result = 1; 242 } 243 } 244 245 out_close2: 246 elf_end (elf); 247 out_close: 248 close (fd); 249 out: 250 /* We don't need the file anymore. */ 251 unlink (fname); 252 253 ebl_closebackend (ebl); 254 255 return result; 256 } 257