readelf.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,305 行 · 第 1/5 页
C
2,305 行
/* readelf.c -- display contents of an ELF format file Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Originally developed by Eric Youngdale <eric@andante.jic.com> Modifications by Nick Clifton <nickc@cygnus.com> This file is part of GNU Binutils. This program 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 2 of the License, or (at your option) any later version. This program 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <assert.h>#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <time.h>#if __GNUC__ >= 2/* Define BFD64 here, even if our default architecture is 32 bit ELF as this will allow us to read in and parse 64bit and 32bit ELF files. Only do this if we belive that the compiler can support a 64 bit data type. For now we only rely on GCC being able to do this. */#define BFD64#endif#include "bfd.h"#include "elf/common.h"#include "elf/external.h"#include "elf/internal.h"#include "elf/dwarf2.h"/* The following headers use the elf/reloc-macros.h file to automatically generate relocation recognition functions such as elf_mips_reloc_type() */#define RELOC_MACROS_GEN_FUNC#include "elf/i386.h"#include "elf/v850.h"#include "elf/ppc.h"#include "elf/mips.h"#include "elf/alpha.h"#include "elf/arm.h"#include "elf/m68k.h"#include "elf/sparc.h"#include "elf/m32r.h"#include "elf/d10v.h"#include "elf/d30v.h"#include "elf/sh.h"#include "elf/mn10200.h"#include "elf/mn10300.h"#include "elf/hppa.h"#include "elf/arc.h"#include "elf/fr30.h"#include "elf/mcore.h"#include "elf/i960.h"#include "elf/pj.h"#include "elf/avr.h"#include "elf/ia64.h"#include "elf/cris.h"#include "elf/i860.h"#include "elf/x86-64.h"#include "bucomm.h"#include "getopt.h"char * program_name = "readelf";unsigned int dynamic_addr;bfd_size_type dynamic_size;unsigned int rela_addr;unsigned int rela_size;char * dynamic_strings;char * string_table;unsigned long string_table_length;unsigned long num_dynamic_syms;Elf_Internal_Sym * dynamic_symbols;Elf_Internal_Syminfo * dynamic_syminfo;unsigned long dynamic_syminfo_offset;unsigned int dynamic_syminfo_nent;char program_interpreter [64];int dynamic_info[DT_JMPREL + 1];int version_info[16];int loadaddr = 0;Elf_Internal_Ehdr elf_header;Elf_Internal_Shdr * section_headers;Elf_Internal_Dyn * dynamic_segment;int show_name;int do_dynamic;int do_syms;int do_reloc;int do_sections;int do_segments;int do_unwind;int do_using_dynamic;int do_header;int do_dump;int do_version;int do_histogram;int do_debugging;int do_debug_info;int do_debug_abbrevs;int do_debug_lines;int do_debug_pubnames;int do_debug_aranges;int do_debug_frames;int do_debug_frames_interp;int do_arch;int do_notes;int is_32bit_elf;/* A dynamic array of flags indicating which sections require dumping. */char * dump_sects = NULL;unsigned int num_dump_sects = 0;#define HEX_DUMP (1 << 0)#define DISASS_DUMP (1 << 1)#define DEBUG_DUMP (1 << 2)/* How to rpint a vma value. */typedef enum print_mode{ HEX, DEC, DEC_5, UNSIGNED, PREFIX_HEX, FULL_HEX, LONG_HEX}print_mode;/* Forward declarations for dumb compilers. */static void print_vma PARAMS ((bfd_vma, print_mode));static bfd_vma (* byte_get) PARAMS ((unsigned char *, int));static bfd_vma byte_get_little_endian PARAMS ((unsigned char *, int));static bfd_vma byte_get_big_endian PARAMS ((unsigned char *, int));static const char * get_mips_dynamic_type PARAMS ((unsigned long));static const char * get_sparc64_dynamic_type PARAMS ((unsigned long));static const char * get_parisc_dynamic_type PARAMS ((unsigned long));static const char * get_dynamic_type PARAMS ((unsigned long));static int slurp_rela_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *));static int slurp_rel_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rel **, unsigned long *));static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));static char * get_file_type PARAMS ((unsigned));static char * get_machine_name PARAMS ((unsigned));static void decode_ARM_machine_flags PARAMS ((unsigned, char []));static char * get_machine_flags PARAMS ((unsigned, unsigned));static const char * get_mips_segment_type PARAMS ((unsigned long));static const char * get_parisc_segment_type PARAMS ((unsigned long));static const char * get_ia64_segment_type PARAMS ((unsigned long));static const char * get_segment_type PARAMS ((unsigned long));static const char * get_mips_section_type_name PARAMS ((unsigned int));static const char * get_parisc_section_type_name PARAMS ((unsigned int));static const char * get_ia64_section_type_name PARAMS ((unsigned int));static const char * get_section_type_name PARAMS ((unsigned int));static const char * get_symbol_binding PARAMS ((unsigned int));static const char * get_symbol_type PARAMS ((unsigned int));static const char * get_symbol_visibility PARAMS ((unsigned int));static const char * get_symbol_index_type PARAMS ((unsigned int));static const char * get_dynamic_flags PARAMS ((bfd_vma));static void usage PARAMS ((void));static void parse_args PARAMS ((int, char **));static int process_file_header PARAMS ((void));static int process_program_headers PARAMS ((FILE *));static int process_section_headers PARAMS ((FILE *));static int process_unwind PARAMS ((FILE *));static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *));static void dynamic_segment_parisc_val PARAMS ((Elf_Internal_Dyn *));static int process_dynamic_segment PARAMS ((FILE *));static int process_symbol_table PARAMS ((FILE *));static int process_section_contents PARAMS ((FILE *));static void process_file PARAMS ((char *));static int process_relocs PARAMS ((FILE *));static int process_version_sections PARAMS ((FILE *));static char * get_ver_flags PARAMS ((unsigned int));static int get_32bit_section_headers PARAMS ((FILE *));static int get_64bit_section_headers PARAMS ((FILE *));static int get_32bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));static int get_64bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));static int get_file_header PARAMS ((FILE *));static Elf_Internal_Sym * get_32bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));static Elf_Internal_Sym * get_64bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));static const char * get_elf_section_flags PARAMS ((bfd_vma));static int * get_dynamic_data PARAMS ((FILE *, unsigned int));static int get_32bit_dynamic_segment PARAMS ((FILE *));static int get_64bit_dynamic_segment PARAMS ((FILE *));#ifdef SUPPORT_DISASSEMBLYstatic int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));#endifstatic int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));static int process_extended_line_op PARAMS ((unsigned char *, int, int));static void reset_state_machine PARAMS ((int));static char * get_TAG_name PARAMS ((unsigned long));static char * get_AT_name PARAMS ((unsigned long));static char * get_FORM_name PARAMS ((unsigned long));static void free_abbrevs PARAMS ((void));static void add_abbrev PARAMS ((unsigned long, unsigned long, int));static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long, unsigned long));static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));static void decode_location_expression PARAMS ((unsigned char *, unsigned int, unsigned long));static void request_dump PARAMS ((unsigned int, char));static const char * get_elf_class PARAMS ((unsigned char));static const char * get_data_encoding PARAMS ((unsigned char));static const char * get_osabi_name PARAMS ((unsigned char));static int guess_is_rela PARAMS ((unsigned long));static char * get_note_type PARAMS ((unsigned int));static int process_note PARAMS ((Elf32_Internal_Note *));static int process_corefile_note_segment PARAMS ((FILE *, bfd_vma, bfd_vma));static int process_corefile_note_segments PARAMS ((FILE *));static int process_corefile_contents PARAMS ((FILE *));typedef int Elf32_Word;#ifndef TRUE#define TRUE 1#define FALSE 0#endif#define UNKNOWN -1#define SECTION_NAME(X) ((X) == NULL ? "<none>" : \ ((X)->sh_name >= string_table_length \ ? "<corrupt>" : string_table + (X)->sh_name))#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */#define BYTE_GET(field) byte_get (field, sizeof (field))/* If we can support a 64 bit data type then BFD64 should be defined and sizeof (bfd_vma) == 8. In this case when translating from an external 8 byte field to an internal field, we can assume that the internal field is also 8 bytes wide and so we can extract all the data. If, however, BFD64 is not defined, then we must assume that the internal data structure only has 4 byte wide fields that are the equivalent of the 8 byte wide external counterparts, and so we must truncate the data. */#ifdef BFD64#define BYTE_GET8(field) byte_get (field, -8)#else#define BYTE_GET8(field) byte_get (field, 8)#endif#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))#define GET_DATA_ALLOC(offset, size, var, type, reason) \ if (fseek (file, offset, SEEK_SET)) \ { \ error (_("Unable to seek to start of %s at %x\n"), reason, offset); \ return 0; \ } \ \ var = (type) malloc (size); \ \ if (var == NULL) \ { \ error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \ return 0; \ } \ \ if (fread (var, size, 1, file) != 1) \ { \ error (_("Unable to read in %d bytes of %s\n"), size, reason); \ free (var); \ var = NULL; \ return 0; \ }#define GET_DATA(offset, var, reason) \ if (fseek (file, offset, SEEK_SET)) \ { \ error (_("Unable to seek to %x for %s\n"), offset, reason); \ return 0; \ } \ else if (fread (& var, sizeof (var), 1, file) != 1) \ { \ error (_("Unable to read data at %x for %s\n"), offset, reason); \ return 0; \ }#define GET_ELF_SYMBOLS(file, offset, size) \ (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size) \ : get_64bit_elf_symbols (file, offset, size))#ifdef ANSI_PROTOTYPESstatic voiderror (const char * message, ...){ va_list args; fprintf (stderr, _("%s: Error: "), program_name); va_start (args, message); vfprintf (stderr, message, args); va_end (args); return;}static voidwarn (const char * message, ...){ va_list args; fprintf (stderr, _("%s: Warning: "), program_name); va_start (args, message); vfprintf (stderr, message, args); va_end (args); return;}#elsestatic voiderror (va_alist) va_dcl{ char * message; va_list args; fprintf (stderr, _("%s: Error: "), program_name); va_start (args); message = va_arg (args, char *); vfprintf (stderr, message, args); va_end (args); return;}static voidwarn (va_alist) va_dcl{ char * message; va_list args; fprintf (stderr, _("%s: Warning: "), program_name); va_start (args); message = va_arg (args, char *); vfprintf (stderr, message, args); va_end (args); return;}#endifstatic bfd_vmabyte_get_little_endian (field, size) unsigned char * field; int size;{ switch (size) { case 1: return * field; case 2: return ((unsigned int) (field [0])) | (((unsigned int) (field [1])) << 8);#ifndef BFD64 case 8: /* We want to extract data from an 8 byte wide field and place it into a 4 byte wide field. Since this is a little endian source we can juts use the 4 byte extraction code. */ /* Fall through. */#endif case 4: return ((unsigned long) (field [0])) | (((unsigned long) (field [1])) << 8) | (((unsigned long) (field [2])) << 16) | (((unsigned long) (field [3])) << 24);#ifdef BFD64 case 8: case -8: /* This is a special case, generated by the BYTE_GET8 macro. It means that we are loading an 8 byte value from a field in an external structure into an 8 byte value in a field in an internal strcuture. */ return ((bfd_vma) (field [0])) | (((bfd_vma) (field [1])) << 8) | (((bfd_vma) (field [2])) << 16) | (((bfd_vma) (field [3])) << 24) | (((bfd_vma) (field [4])) << 32) | (((bfd_vma) (field [5])) << 40) | (((bfd_vma) (field [6])) << 48) | (((bfd_vma) (field [7])) << 56);#endif default: error (_("Unhandled data length: %d\n"), size); abort (); }}/* Print a VMA value. */static voidprint_vma (vma, mode) bfd_vma vma; print_mode mode;{#ifdef BFD64 if (is_32bit_elf)#endif { switch (mode) { case FULL_HEX: printf ("0x"); /* drop through */ case LONG_HEX: printf ("%8.8lx", (unsigned long) vma); break; case PREFIX_HEX: printf ("0x"); /* drop through */ case HEX: printf ("%lx", (unsigned long) vma); break; case DEC: printf ("%ld", (unsigned long) vma); break; case DEC_5: printf ("%5ld", (long) vma); break; case UNSIGNED: printf ("%lu", (unsigned long) vma); break; } }#ifdef BFD64 else { switch (mode) { case FULL_HEX: printf ("0x"); /* drop through */ case LONG_HEX: printf_vma (vma); break; case PREFIX_HEX: printf ("0x"); /* drop through */ case HEX:#if BFD_HOST_64BIT_LONG printf ("%lx", vma);#else if (_bfd_int64_high (vma)) printf ("%lx%lx", _bfd_int64_high (vma), _bfd_int64_low (vma)); else printf ("%lx", _bfd_int64_low (vma));#endif break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?