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 + -
显示快捷键?