Home | History | Annotate | Download | only in tests
      1 /* Test program for elf_update function.
      2    Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
      3    This file is part of Red Hat elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 2000.
      5 
      6    Red Hat elfutils is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by the
      8    Free Software Foundation; version 2 of the License.
      9 
     10    Red Hat 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 GNU
     13    General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License along
     16    with Red Hat elfutils; if not, write to the Free Software Foundation,
     17    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
     18 
     19    Red Hat elfutils is an included package of the Open Invention Network.
     20    An included package of the Open Invention Network is a package for which
     21    Open Invention Network licensees cross-license their patents.  No patent
     22    license is granted, either expressly or impliedly, by designation as an
     23    included package.  Should you wish to participate in the Open Invention
     24    Network licensing program, please visit www.openinventionnetwork.com
     25    <http://www.openinventionnetwork.com>.  */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 # include <config.h>
     29 #endif
     30 
     31 #include <errno.h>
     32 #include <fcntl.h>
     33 #include <libelf.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <unistd.h>
     38 
     39 #include ELFUTILS_HEADER(ebl)
     40 
     41 
     42 int
     43 main (int argc, char *argv[] __attribute__ ((unused)))
     44 {
     45   const char fname[] = "xxx";
     46   int fd;
     47   Elf *elf;
     48   Elf32_Ehdr *ehdr;
     49   Elf32_Phdr *phdr;
     50   Elf_Scn *scn;
     51   Elf32_Shdr *shdr;
     52   Elf_Data *data;
     53   struct Ebl_Strtab *shst;
     54   struct Ebl_Strent *firstse;
     55   struct Ebl_Strent *secondse;
     56   struct Ebl_Strent *thirdse;
     57   struct Ebl_Strent *fourthse;
     58   struct Ebl_Strent *shstrtabse;
     59   int i;
     60 
     61   fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
     62   if (fd == -1)
     63     {
     64       printf ("cannot open `%s': %s\n", fname, strerror (errno));
     65       exit (1);
     66     }
     67 
     68   elf_version (EV_CURRENT);
     69 
     70   elf_fill (0x42);
     71 
     72   elf = elf_begin (fd, ELF_C_WRITE, NULL);
     73   if (elf == NULL)
     74     {
     75       printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
     76       exit (1);
     77     }
     78 
     79   /* Create an ELF header.  */
     80   ehdr = elf32_newehdr (elf);
     81   if (ehdr == NULL)
     82     {
     83       printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
     84       exit (1);
     85     }
     86 
     87   /* Print the ELF header values.  */
     88   if (argc > 1)
     89     {
     90       for (i = 0; i < EI_NIDENT; ++i)
     91 	printf (" %02x", ehdr->e_ident[i]);
     92       printf ("\
     93 \ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
     94 	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
     95 	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
     96 	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
     97 	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
     98 	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
     99 	      ehdr->e_shnum, ehdr->e_shstrndx);
    100     }
    101 
    102   ehdr->e_ident[0] = 42;
    103   ehdr->e_ident[4] = 1;
    104   ehdr->e_ident[5] = 1;
    105   ehdr->e_ident[6] = 2;
    106   ehdr->e_type = ET_EXEC;
    107   ehdr->e_version = 1;
    108   ehdr->e_ehsize = 1;
    109   elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
    110 
    111   /* Create the program header.  */
    112   phdr = elf32_newphdr (elf, 1);
    113   if (phdr == NULL)
    114     {
    115       printf ("cannot create program header: %s\n", elf_errmsg (-1));
    116       exit (1);
    117     }
    118 
    119   phdr[0].p_type = PT_PHDR;
    120   elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
    121 
    122   shst = ebl_strtabinit (true);
    123 
    124   scn = elf_newscn (elf);
    125   if (scn == NULL)
    126     {
    127       printf ("cannot create first section: %s\n", elf_errmsg (-1));
    128       exit (1);
    129     }
    130   shdr = elf32_getshdr (scn);
    131   if (shdr == NULL)
    132     {
    133       printf ("cannot get header for first section: %s\n", elf_errmsg (-1));
    134       exit (1);
    135     }
    136 
    137   firstse = ebl_strtabadd (shst, ".first", 0);
    138 
    139   shdr->sh_type = SHT_PROGBITS;
    140   shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
    141   shdr->sh_addr = 0;
    142   shdr->sh_link = 0;
    143   shdr->sh_info = 0;
    144   shdr->sh_entsize = 1;
    145 
    146   data = elf_newdata (scn);
    147   if (data == NULL)
    148     {
    149       printf ("cannot create data first section: %s\n", elf_errmsg (-1));
    150       exit (1);
    151     }
    152 
    153   data->d_buf = "hello";
    154   data->d_type = ELF_T_BYTE;
    155   data->d_version = EV_CURRENT;
    156   data->d_size = 5;
    157   data->d_align = 16;
    158 
    159 
    160   scn = elf_newscn (elf);
    161   if (scn == NULL)
    162     {
    163       printf ("cannot create second section: %s\n", elf_errmsg (-1));
    164       exit (1);
    165     }
    166   shdr = elf32_getshdr (scn);
    167   if (shdr == NULL)
    168     {
    169       printf ("cannot get header for second section: %s\n", elf_errmsg (-1));
    170       exit (1);
    171     }
    172 
    173   secondse = ebl_strtabadd (shst, ".second", 0);
    174 
    175   shdr->sh_type = SHT_PROGBITS;
    176   shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
    177   shdr->sh_addr = 0;
    178   shdr->sh_link = 0;
    179   shdr->sh_info = 0;
    180   shdr->sh_entsize = 1;
    181 
    182   data = elf_newdata (scn);
    183   if (data == NULL)
    184     {
    185       printf ("cannot create data second section: %s\n", elf_errmsg (-1));
    186       exit (1);
    187     }
    188 
    189   data->d_buf = "world";
    190   data->d_type = ELF_T_BYTE;
    191   data->d_version = EV_CURRENT;
    192   data->d_size = 5;
    193   data->d_align = 16;
    194 
    195 
    196   scn = elf_newscn (elf);
    197   if (scn == NULL)
    198     {
    199       printf ("cannot create third section: %s\n", elf_errmsg (-1));
    200       exit (1);
    201     }
    202   shdr = elf32_getshdr (scn);
    203   if (shdr == NULL)
    204     {
    205       printf ("cannot get header for third section: %s\n", elf_errmsg (-1));
    206       exit (1);
    207     }
    208 
    209   thirdse = ebl_strtabadd (shst, ".third", 0);
    210 
    211   shdr->sh_type = SHT_PROGBITS;
    212   shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
    213   shdr->sh_addr = 0;
    214   shdr->sh_link = 0;
    215   shdr->sh_info = 0;
    216   shdr->sh_entsize = 1;
    217 
    218   data = elf_newdata (scn);
    219   if (data == NULL)
    220     {
    221       printf ("cannot create data third section: %s\n", elf_errmsg (-1));
    222       exit (1);
    223     }
    224 
    225   data->d_buf = "!!!!!";
    226   data->d_type = ELF_T_BYTE;
    227   data->d_version = EV_CURRENT;
    228   data->d_size = 5;
    229   data->d_align = 16;
    230 
    231 
    232   scn = elf_newscn (elf);
    233   if (scn == NULL)
    234     {
    235       printf ("cannot create fourth section: %s\n", elf_errmsg (-1));
    236       exit (1);
    237     }
    238   shdr = elf32_getshdr (scn);
    239   if (shdr == NULL)
    240     {
    241       printf ("cannot get header for fourth section: %s\n", elf_errmsg (-1));
    242       exit (1);
    243     }
    244 
    245   fourthse = ebl_strtabadd (shst, ".fourth", 0);
    246 
    247   shdr->sh_type = SHT_NOBITS;
    248   shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
    249   shdr->sh_addr = 0;
    250   shdr->sh_link = 0;
    251   shdr->sh_info = 0;
    252   shdr->sh_entsize = 1;
    253   shdr->sh_size = 100;
    254 
    255   data = elf_newdata (scn);
    256   if (data == NULL)
    257     {
    258       printf ("cannot create data fourth section: %s\n", elf_errmsg (-1));
    259       exit (1);
    260     }
    261 
    262   data->d_buf = NULL;
    263   data->d_type = ELF_T_BYTE;
    264   data->d_version = EV_CURRENT;
    265   data->d_size = 100;
    266   data->d_align = 16;
    267 
    268 
    269   scn = elf_newscn (elf);
    270   if (scn == NULL)
    271     {
    272       printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1));
    273       exit (1);
    274     }
    275   shdr = elf32_getshdr (scn);
    276   if (shdr == NULL)
    277     {
    278       printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1));
    279       exit (1);
    280     }
    281 
    282   shstrtabse = ebl_strtabadd (shst, ".shstrtab", 0);
    283 
    284   shdr->sh_type = SHT_STRTAB;
    285   shdr->sh_flags = 0;
    286   shdr->sh_addr = 0;
    287   shdr->sh_link = SHN_UNDEF;
    288   shdr->sh_info = SHN_UNDEF;
    289   shdr->sh_entsize = 1;
    290 
    291   /* We have to store the section index in the ELF header.  */
    292   ehdr->e_shstrndx = elf_ndxscn (scn);
    293 
    294   data = elf_newdata (scn);
    295   if (data == NULL)
    296     {
    297       printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
    298       exit (1);
    299     }
    300 
    301   /* No more sections, finalize the section header string table.  */
    302   ebl_strtabfinalize (shst, data);
    303 
    304   elf32_getshdr (elf_getscn (elf, 1))->sh_name = ebl_strtaboffset (firstse);
    305   elf32_getshdr (elf_getscn (elf, 2))->sh_name = ebl_strtaboffset (secondse);
    306   elf32_getshdr (elf_getscn (elf, 3))->sh_name = ebl_strtaboffset (thirdse);
    307   elf32_getshdr (elf_getscn (elf, 4))->sh_name = ebl_strtaboffset (fourthse);
    308   shdr->sh_name = ebl_strtaboffset (shstrtabse);
    309 
    310   /* Let the library compute the internal structure information.  */
    311   if (elf_update (elf, ELF_C_NULL) < 0)
    312     {
    313       printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
    314       exit (1);
    315     }
    316 
    317   ehdr = elf32_getehdr (elf);
    318 
    319   phdr[0].p_offset = ehdr->e_phoff;
    320   phdr[0].p_offset = ehdr->e_phoff;
    321   phdr[0].p_vaddr = ehdr->e_phoff;
    322   phdr[0].p_paddr = ehdr->e_phoff;
    323   phdr[0].p_flags = PF_R | PF_X;
    324   phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
    325   phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
    326   phdr[0].p_align = sizeof (Elf32_Word);
    327 
    328   /* Write out the file.  */
    329   if (elf_update (elf, ELF_C_WRITE) < 0)
    330     {
    331       printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
    332       exit (1);
    333     }
    334 
    335   /* We don't need the string table anymore.  */
    336   ebl_strtabfree (shst);
    337 
    338   /* And the data allocated in the .shstrtab section.  */
    339   free (data->d_buf);
    340 
    341   /* Print the ELF header values.  */
    342   if (argc > 1)
    343     {
    344       for (i = 0; i < EI_NIDENT; ++i)
    345 	printf (" %02x", ehdr->e_ident[i]);
    346       printf ("\
    347 \ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
    348 	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
    349 	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
    350 	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
    351 	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
    352 	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
    353 	      ehdr->e_shnum, ehdr->e_shstrndx);
    354     }
    355 
    356   if (elf_end (elf) != 0)
    357     {
    358       printf ("failure in elf_end: %s\n", elf_errmsg (-1));
    359       exit (1);
    360     }
    361 
    362   unlink (fname);
    363 
    364   return 0;
    365 }
    366