1 /* Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
2 This file is part of elfutils.
3 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include <fcntl.h>
21 #include <gelf.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26 #include <unistd.h>
27 #include "system.h"
28
29 #ifdef __DragonFly__
30 #undef MACHINE
31 #endif
32
33 static const char *machines[] =
34 {
35 #define MACHINE(name) [name] = #name
36 MACHINE (EM_NONE),
37 MACHINE (EM_M32),
38 MACHINE (EM_SPARC),
39 MACHINE (EM_386),
40 MACHINE (EM_68K),
41 MACHINE (EM_88K),
42 MACHINE (EM_860),
43 MACHINE (EM_MIPS),
44 MACHINE (EM_MIPS_RS3_LE),
45 MACHINE (EM_PARISC),
46 MACHINE (EM_VPP500),
47 MACHINE (EM_SPARC32PLUS),
48 MACHINE (EM_960),
49 MACHINE (EM_PPC),
50 MACHINE (EM_PPC64),
51 MACHINE (EM_V800),
52 MACHINE (EM_FR20),
53 MACHINE (EM_RH32),
54 MACHINE (EM_RCE),
55 MACHINE (EM_ARM),
56 MACHINE (EM_FAKE_ALPHA),
57 MACHINE (EM_SH),
58 MACHINE (EM_SPARCV9),
59 MACHINE (EM_TRICORE),
60 MACHINE (EM_ARC),
61 MACHINE (EM_H8_300),
62 MACHINE (EM_H8_300H),
63 MACHINE (EM_H8S),
64 MACHINE (EM_H8_500),
65 MACHINE (EM_IA_64),
66 MACHINE (EM_MIPS_X),
67 MACHINE (EM_COLDFIRE),
68 MACHINE (EM_68HC12),
69 MACHINE (EM_MMA),
70 MACHINE (EM_PCP),
71 MACHINE (EM_NCPU),
72 MACHINE (EM_NDR1),
73 MACHINE (EM_STARCORE),
74 MACHINE (EM_ME16),
75 MACHINE (EM_ST100),
76 MACHINE (EM_TINYJ),
77 MACHINE (EM_FX66),
78 MACHINE (EM_ST9PLUS),
79 MACHINE (EM_ST7),
80 MACHINE (EM_68HC16),
81 MACHINE (EM_68HC11),
82 MACHINE (EM_68HC08),
83 MACHINE (EM_68HC05),
84 MACHINE (EM_SVX),
85 MACHINE (EM_ST19),
86 MACHINE (EM_VAX)
87 };
88
89
90 int
main(int argc,char * argv[])91 main (int argc, char *argv[])
92 {
93 int fd;
94 Elf *elf;
95 Elf_Cmd cmd;
96 size_t n;
97 int arg = 1;
98 int verbose = 0;
99
100 /* Recognize optional verbosity flag. */
101 if (arg < argc && strcmp (argv[arg], "-v") == 0)
102 {
103 verbose = 1;
104 ++arg;
105 }
106
107 /* Any more arguments available. */
108 if (arg >= argc)
109 error (EXIT_FAILURE, 0, "No input file given");
110
111 /* Open the input file. */
112 fd = open (argv[arg], O_RDONLY);
113 if (fd == -1)
114 {
115 perror ("cannot open input file");
116 exit (1);
117 }
118
119 /* Set the ELF version we are using here. */
120 if (elf_version (EV_CURRENT) == EV_NONE)
121 {
122 puts ("ELF library too old");
123 exit (1);
124 }
125
126 /* Start reading the file. */
127 cmd = ELF_C_READ;
128 elf = elf_begin (fd, cmd, NULL);
129 if (elf == NULL)
130 {
131 printf ("elf_begin: %s\n", elf_errmsg (-1));
132 exit (1);
133 }
134
135 /* If it is no archive punt. */
136 if (elf_kind (elf) != ELF_K_AR)
137 {
138 printf ("%s is not an archive\n", argv[1]);
139 exit (1);
140 }
141
142 if (verbose)
143 {
144 /* The verbose variant. We print a lot of information. */
145 Elf *subelf;
146 char buf[100];
147 time_t t;
148
149 /* Get the elements of the archive one after the other. */
150 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
151 {
152 /* The the header for this element. */
153 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
154
155 if (arhdr == NULL)
156 {
157 printf ("cannot get arhdr: %s\n", elf_errmsg (-1));
158 break;
159 }
160
161 switch (elf_kind (subelf))
162 {
163 case ELF_K_ELF:
164 fputs ("ELF file:\n", stdout);
165 break;
166
167 case ELF_K_AR:
168 fputs ("archive:\n", stdout);
169 break;
170
171 default:
172 fputs ("unknown file:\n", stdout);
173 break;
174 }
175
176 /* Print general information. */
177 t = arhdr->ar_date;
178 strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S%z", gmtime (&t));
179 printf (" name : \"%s\"\n"
180 " time : %s\n"
181 " uid : %ld\n"
182 " gid : %ld\n"
183 " mode : %o\n"
184 " size : %ld\n"
185 " rawname : \"%s\"\n",
186 arhdr->ar_name,
187 buf,
188 (long int) arhdr->ar_uid,
189 (long int) arhdr->ar_gid,
190 arhdr->ar_mode,
191 (long int) arhdr->ar_size,
192 arhdr->ar_rawname);
193
194 /* For ELF files we can provide some more information. */
195 if (elf_kind (subelf) == ELF_K_ELF)
196 {
197 GElf_Ehdr ehdr;
198
199 /* Get the ELF header. */
200 if (gelf_getehdr (subelf, &ehdr) == NULL)
201 printf (" *** cannot get ELF header: %s\n", elf_errmsg (-1));
202 else
203 {
204 printf (" binary class : %s\n",
205 ehdr.e_ident[EI_CLASS] == ELFCLASS32
206 ? "ELFCLASS32" : "ELFCLASS64");
207 printf (" data encoding: %s\n",
208 ehdr.e_ident[EI_DATA] == ELFDATA2LSB
209 ? "ELFDATA2LSB" : "ELFDATA2MSB");
210 printf (" binary type : %s\n",
211 ehdr.e_type == ET_REL
212 ? "relocatable"
213 : (ehdr.e_type == ET_EXEC
214 ? "executable"
215 : (ehdr.e_type == ET_DYN
216 ? "dynamic"
217 : "core file")));
218 printf (" machine : %s\n",
219 (ehdr.e_machine >= (sizeof (machines)
220 / sizeof (machines[0]))
221 || machines[ehdr.e_machine] == NULL)
222 ? "???"
223 : machines[ehdr.e_machine]);
224 }
225 }
226
227 /* Get next archive element. */
228 cmd = elf_next (subelf);
229 if (elf_end (subelf) != 0)
230 printf ("error while freeing sub-ELF descriptor: %s\n",
231 elf_errmsg (-1));
232 }
233 }
234 else
235 {
236 /* The simple version. Only print a bit of information. */
237 Elf_Arsym *arsym = elf_getarsym (elf, &n);
238
239 if (n == 0)
240 printf ("no symbol table in archive: %s\n", elf_errmsg (-1));
241 else
242 {
243 --n;
244
245 while (n-- > 0)
246 printf ("name = \"%s\", offset = %ld, hash = %lx\n",
247 arsym[n].as_name, (long int) arsym[n].as_off,
248 arsym[n].as_hash);
249 }
250 }
251
252 /* Free the ELF handle. */
253 if (elf_end (elf) != 0)
254 printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
255
256 /* Close the underlying file. */
257 close (fd);
258
259 return 0;
260 }
261