• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
main(int argc,char * argv[])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
handle_section(Elf * elf,Elf_Scn * scn)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
print_bytes(Elf_Data * data)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
print_symtab(Elf * elf,Elf_Data * data)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