You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
6.0 KiB
257 lines
6.0 KiB
/* Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. |
|
This file is part of elfutils. |
|
Written by Ulrich Drepper <drepper@redhat.com>, 1998. |
|
|
|
This file is free software; you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation; either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
elfutils is distributed in the hope that it will be useful, but |
|
WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
|
|
#include <config.h> |
|
|
|
#include <fcntl.h> |
|
#include <gelf.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <time.h> |
|
#include <unistd.h> |
|
#include "system.h" |
|
|
|
|
|
static const char *machines[] = |
|
{ |
|
#define MACHINE(name) [name] = #name |
|
MACHINE (EM_NONE), |
|
MACHINE (EM_M32), |
|
MACHINE (EM_SPARC), |
|
MACHINE (EM_386), |
|
MACHINE (EM_68K), |
|
MACHINE (EM_88K), |
|
MACHINE (EM_860), |
|
MACHINE (EM_MIPS), |
|
MACHINE (EM_MIPS_RS3_LE), |
|
MACHINE (EM_PARISC), |
|
MACHINE (EM_VPP500), |
|
MACHINE (EM_SPARC32PLUS), |
|
MACHINE (EM_960), |
|
MACHINE (EM_PPC), |
|
MACHINE (EM_PPC64), |
|
MACHINE (EM_V800), |
|
MACHINE (EM_FR20), |
|
MACHINE (EM_RH32), |
|
MACHINE (EM_RCE), |
|
MACHINE (EM_ARM), |
|
MACHINE (EM_FAKE_ALPHA), |
|
MACHINE (EM_SH), |
|
MACHINE (EM_SPARCV9), |
|
MACHINE (EM_TRICORE), |
|
MACHINE (EM_ARC), |
|
MACHINE (EM_H8_300), |
|
MACHINE (EM_H8_300H), |
|
MACHINE (EM_H8S), |
|
MACHINE (EM_H8_500), |
|
MACHINE (EM_IA_64), |
|
MACHINE (EM_MIPS_X), |
|
MACHINE (EM_COLDFIRE), |
|
MACHINE (EM_68HC12), |
|
MACHINE (EM_MMA), |
|
MACHINE (EM_PCP), |
|
MACHINE (EM_NCPU), |
|
MACHINE (EM_NDR1), |
|
MACHINE (EM_STARCORE), |
|
MACHINE (EM_ME16), |
|
MACHINE (EM_ST100), |
|
MACHINE (EM_TINYJ), |
|
MACHINE (EM_FX66), |
|
MACHINE (EM_ST9PLUS), |
|
MACHINE (EM_ST7), |
|
MACHINE (EM_68HC16), |
|
MACHINE (EM_68HC11), |
|
MACHINE (EM_68HC08), |
|
MACHINE (EM_68HC05), |
|
MACHINE (EM_SVX), |
|
MACHINE (EM_ST19), |
|
MACHINE (EM_VAX) |
|
}; |
|
|
|
|
|
int |
|
main (int argc, char *argv[]) |
|
{ |
|
int fd; |
|
Elf *elf; |
|
Elf_Cmd cmd; |
|
size_t n; |
|
int arg = 1; |
|
int verbose = 0; |
|
|
|
/* Recognize optional verbosity flag. */ |
|
if (arg < argc && strcmp (argv[arg], "-v") == 0) |
|
{ |
|
verbose = 1; |
|
++arg; |
|
} |
|
|
|
/* Any more arguments available. */ |
|
if (arg >= argc) |
|
error (EXIT_FAILURE, 0, "No input file given"); |
|
|
|
/* Open the input file. */ |
|
fd = open (argv[arg], O_RDONLY); |
|
if (fd == -1) |
|
{ |
|
perror ("cannot open input file"); |
|
exit (1); |
|
} |
|
|
|
/* Set the ELF version we are using here. */ |
|
if (elf_version (EV_CURRENT) == EV_NONE) |
|
{ |
|
puts ("ELF library too old"); |
|
exit (1); |
|
} |
|
|
|
/* Start reading the file. */ |
|
cmd = ELF_C_READ; |
|
elf = elf_begin (fd, cmd, NULL); |
|
if (elf == NULL) |
|
{ |
|
printf ("elf_begin: %s\n", elf_errmsg (-1)); |
|
exit (1); |
|
} |
|
|
|
/* If it is no archive punt. */ |
|
if (elf_kind (elf) != ELF_K_AR) |
|
{ |
|
printf ("%s is not an archive\n", argv[1]); |
|
exit (1); |
|
} |
|
|
|
if (verbose) |
|
{ |
|
/* The verbose variant. We print a lot of information. */ |
|
Elf *subelf; |
|
char buf[100]; |
|
time_t t; |
|
|
|
/* Get the elements of the archive one after the other. */ |
|
while ((subelf = elf_begin (fd, cmd, elf)) != NULL) |
|
{ |
|
/* The the header for this element. */ |
|
Elf_Arhdr *arhdr = elf_getarhdr (subelf); |
|
|
|
if (arhdr == NULL) |
|
{ |
|
printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); |
|
break; |
|
} |
|
|
|
switch (elf_kind (subelf)) |
|
{ |
|
case ELF_K_ELF: |
|
fputs ("ELF file:\n", stdout); |
|
break; |
|
|
|
case ELF_K_AR: |
|
fputs ("archive:\n", stdout); |
|
break; |
|
|
|
default: |
|
fputs ("unknown file:\n", stdout); |
|
break; |
|
} |
|
|
|
/* Print general information. */ |
|
t = arhdr->ar_date; |
|
strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S%z", gmtime (&t)); |
|
printf (" name : \"%s\"\n" |
|
" time : %s\n" |
|
" uid : %ld\n" |
|
" gid : %ld\n" |
|
" mode : %o\n" |
|
" size : %ld\n" |
|
" rawname : \"%s\"\n", |
|
arhdr->ar_name, |
|
buf, |
|
(long int) arhdr->ar_uid, |
|
(long int) arhdr->ar_gid, |
|
arhdr->ar_mode, |
|
(long int) arhdr->ar_size, |
|
arhdr->ar_rawname); |
|
|
|
/* For ELF files we can provide some more information. */ |
|
if (elf_kind (subelf) == ELF_K_ELF) |
|
{ |
|
GElf_Ehdr ehdr; |
|
|
|
/* Get the ELF header. */ |
|
if (gelf_getehdr (subelf, &ehdr) == NULL) |
|
printf (" *** cannot get ELF header: %s\n", elf_errmsg (-1)); |
|
else |
|
{ |
|
printf (" binary class : %s\n", |
|
ehdr.e_ident[EI_CLASS] == ELFCLASS32 |
|
? "ELFCLASS32" : "ELFCLASS64"); |
|
printf (" data encoding: %s\n", |
|
ehdr.e_ident[EI_DATA] == ELFDATA2LSB |
|
? "ELFDATA2LSB" : "ELFDATA2MSB"); |
|
printf (" binary type : %s\n", |
|
ehdr.e_type == ET_REL |
|
? "relocatable" |
|
: (ehdr.e_type == ET_EXEC |
|
? "executable" |
|
: (ehdr.e_type == ET_DYN |
|
? "dynamic" |
|
: "core file"))); |
|
printf (" machine : %s\n", |
|
(ehdr.e_machine >= (sizeof (machines) |
|
/ sizeof (machines[0])) |
|
|| machines[ehdr.e_machine] == NULL) |
|
? "???" |
|
: machines[ehdr.e_machine]); |
|
} |
|
} |
|
|
|
/* Get next archive element. */ |
|
cmd = elf_next (subelf); |
|
if (elf_end (subelf) != 0) |
|
printf ("error while freeing sub-ELF descriptor: %s\n", |
|
elf_errmsg (-1)); |
|
} |
|
} |
|
else |
|
{ |
|
/* The simple version. Only print a bit of information. */ |
|
Elf_Arsym *arsym = elf_getarsym (elf, &n); |
|
|
|
if (n == 0) |
|
printf ("no symbol table in archive: %s\n", elf_errmsg (-1)); |
|
else |
|
{ |
|
--n; |
|
|
|
while (n-- > 0) |
|
printf ("name = \"%s\", offset = %ld, hash = %lx\n", |
|
arsym[n].as_name, (long int) arsym[n].as_off, |
|
arsym[n].as_hash); |
|
} |
|
} |
|
|
|
/* Free the ELF handle. */ |
|
if (elf_end (elf) != 0) |
|
printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1)); |
|
|
|
/* Close the underlying file. */ |
|
close (fd); |
|
|
|
return 0; |
|
}
|
|
|