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