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