Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 2002 Red Hat, Inc.
      2    Written by Ulrich Drepper <drepper (at) 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 
     23 static const char fname[] = "asm-tst9-out.o";
     24 
     25 
     26 static int32_t input[] =
     27   {
     28     0, 1, 129, 510, 2000, 33000, 0x7ffffff, 0x7fffffff
     29   };
     30 #define ninput (sizeof (input) / sizeof (input[0]))
     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 = 180,
     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 static 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 
     74 int
     75 main (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