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 <inttypes.h> 32 #include ELFUTILS_HEADER(asm) 33 #include <libelf.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <unistd.h> 37 38 39 static const char fname[] = "asm-tst9-out.o"; 40 41 42 static int32_t input[] = 43 { 44 0, 1, 129, 510, 2000, 33000, 0x7ffffff, 0x7fffffff 45 }; 46 #define ninput (sizeof (input) / sizeof (input[0])) 47 48 49 static const GElf_Ehdr expected_ehdr = 50 { 51 .e_ident = { [EI_MAG0] = ELFMAG0, 52 [EI_MAG1] = ELFMAG1, 53 [EI_MAG2] = ELFMAG2, 54 [EI_MAG3] = ELFMAG3, 55 [EI_CLASS] = ELFCLASS32, 56 [EI_DATA] = ELFDATA2LSB, 57 [EI_VERSION] = EV_CURRENT }, 58 .e_type = ET_REL, 59 .e_machine = EM_386, 60 .e_version = EV_CURRENT, 61 .e_shoff = 180, 62 .e_ehsize = sizeof (Elf32_Ehdr), 63 .e_shentsize = sizeof (Elf32_Shdr), 64 .e_shnum = 3, 65 .e_shstrndx = 2 66 }; 67 68 69 static const char *scnnames[3] = 70 { 71 [0] = "", 72 [1] = ".data", 73 [2] = ".shstrtab" 74 }; 75 76 77 static const char expecteddata[] = 78 { 79 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7f, 80 0x81, 0x01, 0x81, 0x01, 0xff, 0xfe, 0xff, 0xff, 0x0f, 0xff, 0x7e, 0xfe, 81 0x03, 0xfe, 0x03, 0x82, 0xfc, 0xff, 0xff, 0x0f, 0x82, 0x7c, 0xd0, 0x0f, 82 0xd0, 0x0f, 0xb0, 0xf0, 0xff, 0xff, 0x0f, 0xb0, 0x70, 0xe8, 0x81, 0x02, 83 0xe8, 0x81, 0x02, 0x98, 0xfe, 0xfd, 0xff, 0x0f, 0x98, 0xfe, 0x7d, 0xff, 84 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x81, 0x80, 0x80, 0xc0, 0x0f, 85 0x81, 0x80, 0x80, 0x40, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 86 0xff, 0x07, 0x81, 0x80, 0x80, 0x80, 0x08, 0x81, 0x80, 0x80, 0x80, 0x78 87 }; 88 89 90 int 91 main (void) 92 { 93 AsmCtx_t *ctx; 94 AsmScn_t *scn; 95 int result = 0; 96 int fd; 97 Elf *elf; 98 GElf_Ehdr ehdr_mem; 99 GElf_Ehdr *ehdr; 100 size_t cnt; 101 102 elf_version (EV_CURRENT); 103 104 Ebl *ebl = ebl_openbackend_machine (EM_386); 105 if (ebl == NULL) 106 { 107 puts ("cannot open backend library"); 108 return 1; 109 } 110 111 ctx = asm_begin (fname, ebl, false); 112 if (ctx == NULL) 113 { 114 printf ("cannot create assembler context: %s\n", asm_errmsg (-1)); 115 return 1; 116 } 117 118 /* Create two sections. */ 119 scn = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 120 if (scn == NULL) 121 { 122 printf ("cannot create section in output file: %s\n", asm_errmsg (-1)); 123 asm_abort (ctx); 124 return 1; 125 } 126 127 /* Special alignment for the .text section. */ 128 if (asm_align (scn, 16) != 0) 129 { 130 printf ("cannot align .text section: %s\n", asm_errmsg (-1)); 131 result = 1; 132 } 133 134 /* Add a few ULEB128 and SLEB128 numbers. */ 135 for (cnt = 0; cnt < ninput; ++cnt) 136 { 137 if (asm_adduleb128 (scn, input[cnt]) != 0) 138 { 139 printf ("cannot insert uleb %" PRIu32 ": %s\n", 140 (uint32_t) input[cnt], asm_errmsg (-1)); 141 result = 1; 142 } 143 144 if (asm_addsleb128 (scn, input[cnt]) != 0) 145 { 146 printf ("cannot insert sleb %" PRId32 ": %s\n", 147 input[cnt], asm_errmsg (-1)); 148 result = 1; 149 } 150 151 if (asm_adduleb128 (scn, -input[cnt]) != 0) 152 { 153 printf ("cannot insert uleb %" PRIu32 ": %s\n", 154 (uint32_t) -input[cnt], asm_errmsg (-1)); 155 result = 1; 156 } 157 158 if (asm_addsleb128 (scn, -input[cnt]) != 0) 159 { 160 printf ("cannot insert sleb %" PRId32 ": %s\n", 161 -input[cnt], asm_errmsg (-1)); 162 result = 1; 163 } 164 } 165 166 /* Create the output file. */ 167 if (asm_end (ctx) != 0) 168 { 169 printf ("cannot create output file: %s\n", asm_errmsg (-1)); 170 asm_abort (ctx); 171 return 1; 172 } 173 174 /* Check the file. */ 175 fd = open (fname, O_RDONLY); 176 if (fd == -1) 177 { 178 printf ("cannot open generated file: %m\n"); 179 result = 1; 180 goto out; 181 } 182 183 elf = elf_begin (fd, ELF_C_READ, NULL); 184 if (elf == NULL) 185 { 186 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 187 result = 1; 188 goto out_close; 189 } 190 if (elf_kind (elf) != ELF_K_ELF) 191 { 192 puts ("not a valid ELF file"); 193 result = 1; 194 goto out_close2; 195 } 196 197 ehdr = gelf_getehdr (elf, &ehdr_mem); 198 if (ehdr == NULL) 199 { 200 printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 201 result = 1; 202 goto out_close2; 203 } 204 205 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0) 206 { 207 puts ("ELF header does not match"); 208 result = 1; 209 goto out_close2; 210 } 211 212 for (cnt = 1; cnt < 3; ++cnt) 213 { 214 Elf_Scn *scn; 215 GElf_Shdr shdr_mem; 216 GElf_Shdr *shdr; 217 218 scn = elf_getscn (elf, cnt); 219 if (scn == NULL) 220 { 221 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1)); 222 result = 1; 223 continue; 224 } 225 226 shdr = gelf_getshdr (scn, &shdr_mem); 227 if (shdr == NULL) 228 { 229 printf ("cannot get section header for section %Zd: %s\n", 230 cnt, elf_errmsg (-1)); 231 result = 1; 232 continue; 233 } 234 235 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 236 scnnames[cnt]) != 0) 237 { 238 printf ("section %Zd's name differs: %s vs %s\n", cnt, 239 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name), 240 scnnames[cnt]); 241 result = 1; 242 } 243 244 if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS)) 245 { 246 printf ("section %Zd's type differs\n", cnt); 247 result = 1; 248 } 249 250 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE)) 251 || (cnt == 2 && shdr->sh_flags != 0)) 252 { 253 printf ("section %Zd's flags differs\n", cnt); 254 result = 1; 255 } 256 257 if (shdr->sh_addr != 0) 258 { 259 printf ("section %Zd's address differs\n", cnt); 260 result = 1; 261 } 262 263 if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15)) 264 || (cnt == 2 265 && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15) 266 + sizeof (expecteddata)))) 267 { 268 printf ("section %Zd's offset differs\n", cnt); 269 result = 1; 270 } 271 272 if ((cnt == 1 && shdr->sh_size != sizeof (expecteddata)) 273 || (cnt == 2 && shdr->sh_size != 17)) 274 { 275 printf ("section %Zd's size differs\n", cnt); 276 result = 1; 277 } 278 279 if (shdr->sh_link != 0) 280 { 281 printf ("section %Zd's link differs\n", cnt); 282 result = 1; 283 } 284 285 if (shdr->sh_info != 0) 286 { 287 printf ("section %Zd's info differs\n", cnt); 288 result = 1; 289 } 290 291 if ((cnt == 1 && shdr->sh_addralign != 16) 292 || (cnt != 1 && shdr->sh_addralign != 1)) 293 { 294 printf ("section %Zd's addralign differs\n", cnt); 295 result = 1; 296 } 297 298 if (shdr->sh_entsize != 0) 299 { 300 printf ("section %Zd's entsize differs\n", cnt); 301 result = 1; 302 } 303 304 if (cnt == 1) 305 { 306 Elf_Data *data = elf_getdata (scn, NULL); 307 308 if (data == NULL) 309 { 310 printf ("cannot get data of section %Zd\n", cnt); 311 result = 1; 312 } 313 else 314 { 315 if (data->d_size != sizeof (expecteddata)) 316 { 317 printf ("data block size of section %Zd wrong: got %Zd, " 318 "expected 96\n", cnt, data->d_size); 319 result = 1; 320 } 321 322 if (memcmp (data->d_buf, expecteddata, sizeof (expecteddata)) 323 != 0) 324 { 325 printf ("data block content of section %Zd wrong\n", cnt); 326 result = 1; 327 } 328 } 329 } 330 } 331 332 out_close2: 333 elf_end (elf); 334 out_close: 335 close (fd); 336 out: 337 /* We don't need the file anymore. */ 338 unlink (fname); 339 340 ebl_closebackend (ebl); 341 342 return result; 343 } 344