Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
      2    This file is part of Red Hat elfutils.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      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 #include <config.h>
     27 
     28 #include <errno.h>
     29 #include <error.h>
     30 #include <fcntl.h>
     31 #include <gelf.h>
     32 #include <inttypes.h>
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <unistd.h>
     36 
     37 
     38 /* Prototypes for local functions.  */
     39 static int handle_section (Elf *elf, Elf_Scn *scn);
     40 static void print_bytes (Elf_Data *data);
     41 static void print_symtab (Elf *elf, Elf_Data *data);
     42 
     43 
     44 int
     45 main (int argc, char *argv[])
     46 {
     47   Elf *elf;
     48   int fd;
     49   int cnt;
     50 
     51   if (argc <= 1)
     52     exit (1);
     53 
     54   /* Open the test file.  This is given as the first parameter to the
     55      program.  */
     56   fd = open (argv[1], O_RDONLY);
     57   if (fd == -1)
     58     error (EXIT_FAILURE, errno, "cannot open input file `%s'", argv[1]);
     59 
     60   /* Set the library versio we expect.  */
     61   elf_version (EV_CURRENT);
     62 
     63   /* Create the ELF descriptor.  */
     64   elf = elf_begin (fd, ELF_C_READ, NULL);
     65   if (elf == NULL)
     66     error (EXIT_FAILURE, 0, "cannot create ELF descriptor: %s",
     67 	   elf_errmsg (0));
     68 
     69   /* Now proces all the sections mentioned in the rest of the command line.  */
     70   for (cnt = 2; cnt < argc; ++cnt)
     71     if (handle_section (elf, elf_getscn (elf, atoi (argv[cnt]))) != 0)
     72       /* When we encounter an error stop immediately.  */
     73       error (EXIT_FAILURE, 0, "while processing section %d: %s", cnt,
     74 	   elf_errmsg (0));
     75 
     76   /* Close the descriptor.  */
     77   if (elf_end (elf) != 0)
     78     error (EXIT_FAILURE, 0, "failure while closing ELF descriptor: %s",
     79 	   elf_errmsg (0));
     80 
     81   return 0;
     82 }
     83 
     84 
     85 static int
     86 handle_section (Elf *elf, Elf_Scn *scn)
     87 {
     88   GElf_Ehdr *ehdr;
     89   GElf_Ehdr ehdr_mem;
     90   GElf_Shdr *shdr;
     91   GElf_Shdr shdr_mem;
     92   Elf_Data *data;
     93 
     94   /* First get the ELF and section header.  */
     95   ehdr = gelf_getehdr (elf, &ehdr_mem);
     96   shdr = gelf_getshdr (scn, &shdr_mem);
     97   if (ehdr == NULL || shdr == NULL)
     98     return 1;
     99 
    100   /* Print the information from the ELF section header.   */
    101   printf ("name      = %s\n"
    102 	  "type      = %" PRId32 "\n"
    103 	  "flags     = %" PRIx64 "\n"
    104 	  "addr      = %" PRIx64 "\n"
    105 	  "offset    = %" PRIx64 "\n"
    106 	  "size      = %" PRId64 "\n"
    107 	  "link      = %" PRId32 "\n"
    108 	  "info      = %" PRIx32 "\n"
    109 	  "addralign = %" PRIx64 "\n"
    110 	  "entsize   = %" PRId64 "\n",
    111 	  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
    112 	  shdr->sh_type,
    113 	  shdr->sh_flags,
    114 	  shdr->sh_addr,
    115 	  shdr->sh_offset,
    116 	  shdr->sh_size,
    117 	  shdr->sh_link,
    118 	  shdr->sh_info,
    119 	  shdr->sh_addralign,
    120 	  shdr->sh_entsize);
    121 
    122   /* Get the section data now.  */
    123   data = elf_getdata (scn, NULL);
    124   if (data == NULL)
    125     return 1;
    126 
    127   /* Now proces the different section types accordingly.  */
    128   switch (shdr->sh_type)
    129     {
    130     case SHT_SYMTAB:
    131       print_symtab (elf, data);
    132       break;
    133 
    134     case SHT_PROGBITS:
    135     default:
    136       print_bytes (data);
    137       break;
    138     }
    139 
    140   /* Separate form the next section.  */
    141   puts ("");
    142 
    143   /* All done correctly.  */
    144   return 0;
    145 }
    146 
    147 
    148 static void
    149 print_bytes (Elf_Data *data)
    150 {
    151   size_t size = data->d_size;
    152   off_t offset = data->d_off;
    153   unsigned char *buf = (unsigned char *) data->d_buf;
    154   size_t cnt;
    155 
    156   for (cnt = 0; cnt < size; cnt += 16)
    157     {
    158       size_t inner;
    159 
    160       printf ("%*Zx: ", sizeof (size_t) == 4 ? 8 : 16, (size_t) offset + cnt);
    161 
    162       for (inner = 0; inner < 16 && cnt + inner < size; ++inner)
    163 	printf (" %02hhx", buf[cnt + inner]);
    164 
    165       puts ("");
    166     }
    167 }
    168 
    169 
    170 static void
    171 print_symtab (Elf *elf, Elf_Data *data)
    172 {
    173   int class = gelf_getclass (elf);
    174   size_t nsym = data->d_size / (class == ELFCLASS32
    175 				? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
    176   size_t cnt;
    177 
    178   for (cnt = 0; cnt < nsym; ++cnt)
    179     {
    180       GElf_Sym sym_mem;
    181       GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);
    182 
    183       printf ("%5Zu: %*" PRIx64 " %6" PRIx64 " %4d\n",
    184 	      cnt,
    185 	      class == ELFCLASS32 ? 8 : 16,
    186 	      sym->st_value,
    187 	      sym->st_size,
    188 	      GELF_ST_TYPE (sym->st_info));
    189     }
    190 }
    191