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