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