This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: readelf: Prepare for dumping DWARF info with objdump


On Wed, Sep 07, 2005 at 11:09:58AM -0700, H. J. Lu wrote:
> DWARF is independent of ELF. Other formats can also use DWARF. But
> we can only dump DWARF info with readelf. I am in the process to add
> dumping DWARF to objdump and I'd like to use DWARF code in readelf.
> This patch is a starting point.
> 
> BTW, this patch depends on
> 
> http://sourceware.org/ml/binutils/2005-09/msg00045.html
> 
> 

Here is the updated patch.



H.J.
----
2005-09-13  H.J. Lu  <hongjiu.lu@intel.com>

	* readelf.c (is_relocatable): New.
	(byte_get_signed): Moved.
	(last_pointer_size): Likewise.
	(warned_about_missing_comp_units): Likewise.
	(num_debug_info_entries): Likewise.
	(debug_apply_rela_addends): Likewise.
	(get_debug_info): Likewise.
	(dwarf_section): New structure for DWARF section.
	(load_debug_section): New.
	(free_debug_section): Likewise.
	(debug_str_section): Likewise.
	(debug_abbrev_section): Likewise.
	(debug_str_contents): Removed.
	(debug_str_size): Likewise.
	(debug_loc_contents): Likewise.
	(debug_loc_size): Likewise.
	(debug_range_contents): Likewise.
	(debug_range_size): Likewise.
	(load_debug_str): Likewise.
	(free_debug_str): Likewise.
	(load_debug_loc): Likewise.
	(free_debug_loc): Likewise.
	(load_debug_arange): Likewise.
	(free_debug_arange): Likewise.
	(load_debug_abbrev): Likewise.
	(free_debug_abbrev): Likewise.
	(fetch_indirect_string): Updated.
	(debug_apply_rela_addends): Likewise.
	(process_debug_info): Likewise.
	(get_debug_info): Likewise.
	(display_debug_lines): Likewise.
	(display_debug_pubnames): Likewise.
	(display_debug_macinfo): Likewise.
	(display_debug_abbrev): Likewise.
	(display_debug_loc): Likewise.
	(display_debug_str): Likewise.
	(display_debug_info): Likewise.
	(display_debug_aranges): Likewise.
	(display_debug_ranges): Likewise.
	(display_debug_frames): Likewise.
	(display_debug_not_supported): Likewise.
	(debug_displays): Likewise.
	(display_debug_section): Likewise.
	(get_file_header): Set is_relocatable.

--- binutils/readelf.c.gen	2005-09-13 10:16:26.000000000 -0700
+++ binutils/readelf.c	2005-09-13 11:18:49.000000000 -0700
@@ -171,6 +171,7 @@ static int do_debug_loc;
 static int do_arch;
 static int do_notes;
 static int is_32bit_elf;
+static int is_relocatable;
 static int have_frame_base;
 static int need_base_address;
 static bfd_vma eh_addr_size;
@@ -405,26 +406,6 @@ byte_get_little_endian (unsigned char *f
     }
 }
 
-static bfd_vma
-byte_get_signed (unsigned char *field, int size)
-{
-  bfd_vma x = byte_get (field, size);
-
-  switch (size)
-    {
-    case 1:
-      return (x ^ 0x80) - 0x80;
-    case 2:
-      return (x ^ 0x8000) - 0x8000;
-    case 4:
-      return (x ^ 0x80000000) - 0x80000000;
-    case 8:
-      return x;
-    default:
-      abort ();
-    }
-}
-
 static void
 byte_put_little_endian (unsigned char *field, bfd_vma value, int size)
 {
@@ -7473,6 +7454,223 @@ dump_section (Elf_Internal_Shdr *section
   return 1;
 }
 
+struct dwarf_section
+{
+  const char *name;
+  unsigned char *start;
+  bfd_vma address;
+  bfd_size_type size;
+};
+
+static int process_debug_info (struct dwarf_section *, void *, int);
+static unsigned int last_pointer_size = 0;
+static int warned_about_missing_comp_units = FALSE;
+static unsigned int num_debug_info_entries = 0;
+
+static void
+load_debug_section (struct dwarf_section *section, void *file)
+{
+  Elf_Internal_Shdr *sec;
+  char buf [64];
+
+  /* If it is already loaded, do nothing.  */
+  if (section->start != NULL)
+    return;
+
+  /* Locate the debug section.  */
+  sec = find_section (section->name);
+  if (sec == NULL)
+    return;
+
+  snprintf (buf, sizeof (buf), _("%s section data"), section->name);
+  section->address = sec->sh_addr;
+  section->size = sec->sh_size;
+  section->start = get_data (NULL, file, sec->sh_offset, 1,
+			     sec->sh_size, buf);
+}
+
+static void
+free_debug_section (struct dwarf_section *section)
+{
+  if (section->start == NULL)
+    return;
+
+  free ((char *) section->start);
+  section->start = NULL;
+  section->size = 0;
+}
+
+/* Apply addends of RELA relocations.  */
+
+static int
+debug_apply_rela_addends (void *file,
+			  Elf_Internal_Shdr *section,
+			  unsigned char *start)
+{
+  Elf_Internal_Shdr *relsec;
+  unsigned char *end = start + section->sh_size;
+  /* FIXME: The relocation field size is relocation type dependent.  */
+  unsigned int reloc_size = 4;
+
+  if (!is_relocatable)
+    return 1;
+
+  if (section->sh_size < reloc_size)
+    return 1;
+
+  for (relsec = section_headers;
+       relsec < section_headers + elf_header.e_shnum;
+       ++relsec)
+    {
+      unsigned long nrelas;
+      Elf_Internal_Rela *rela, *rp;
+      Elf_Internal_Shdr *symsec;
+      Elf_Internal_Sym *symtab;
+      Elf_Internal_Sym *sym;
+
+      if (relsec->sh_type != SHT_RELA
+	  || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
+	  || SECTION_HEADER (relsec->sh_info) != section
+	  || relsec->sh_size == 0
+	  || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
+	continue;
+
+      if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+			      &rela, &nrelas))
+	return 0;
+
+      symsec = SECTION_HEADER (relsec->sh_link);
+      symtab = GET_ELF_SYMBOLS (file, symsec);
+
+      for (rp = rela; rp < rela + nrelas; ++rp)
+	{
+	  unsigned char *loc;
+
+	  loc = start + rp->r_offset;
+	  if ((loc + reloc_size) > end)
+	    {
+	      warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
+		    (unsigned long) rp->r_offset,
+		    SECTION_NAME (section));
+	      continue;
+	    }
+
+	  if (is_32bit_elf)
+	    {
+	      sym = symtab + ELF32_R_SYM (rp->r_info);
+
+	      if (ELF32_R_SYM (rp->r_info) != 0
+		  && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
+		  /* Relocations against object symbols can happen,
+		     eg when referencing a global array.  For an
+		     example of this see the _clz.o binary in libgcc.a.  */
+		  && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
+		{
+		  warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
+			get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
+			SECTION_NAME (section));
+		  continue;
+		}
+	    }
+	  else
+	    {
+	      /* In MIPS little-endian objects, r_info isn't really a
+		 64-bit little-endian value: it has a 32-bit little-endian
+		 symbol index followed by four individual byte fields.
+		 Reorder INFO accordingly.  */
+	      if (elf_header.e_machine == EM_MIPS
+		  && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+		rp->r_info = (((rp->r_info & 0xffffffff) << 32)
+			      | ((rp->r_info >> 56) & 0xff)
+			      | ((rp->r_info >> 40) & 0xff00)
+			      | ((rp->r_info >> 24) & 0xff0000)
+			      | ((rp->r_info >> 8) & 0xff000000));
+
+	      sym = symtab + ELF64_R_SYM (rp->r_info);
+
+	      if (ELF64_R_SYM (rp->r_info) != 0
+		  && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
+		  && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
+		{
+		  warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
+			get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
+			SECTION_NAME (section));
+		  continue;
+		}
+	    }
+
+	  byte_put (loc, rp->r_addend, reloc_size);
+	}
+
+      free (symtab);
+      free (rela);
+      break;
+    }
+  return 1;
+}
+
+/* Locate and scan the .debug_info section in the file and record the pointer
+   sizes and offsets for the compilation units in it.  Usually an executable
+   will have just one pointer size, but this is not guaranteed, and so we try
+   not to make any assumptions.  Returns zero upon failure, or the number of
+   compilation units upon success.  */
+
+static unsigned int
+get_debug_info (void * file)
+{
+  Elf_Internal_Shdr * section;
+  struct dwarf_section sec;
+  int ret;
+
+  /* Reset the last pointer size so that we can issue correct error
+     messages if we are displaying the contents of more than one section.  */
+  last_pointer_size = 0;
+  warned_about_missing_comp_units = FALSE;
+
+  /* If we already have the information there is nothing else to do.  */
+  if (num_debug_info_entries > 0)
+    return num_debug_info_entries;
+
+  sec.name = ".debug_info";
+  section = find_section (sec.name);
+  if (section == NULL)
+    return 0;
+
+  sec.start = get_data (NULL, file, section->sh_offset, 1,
+			section->sh_size,
+			_("extracting information from .debug_info section"));
+  if (sec.start == NULL)
+    return 0;
+
+  sec.address = section->sh_addr;
+  sec.size = section->sh_size;
+  ret = (debug_apply_rela_addends (file, section, sec.start)
+	 && process_debug_info (&sec, file, 1));
+
+  free (sec.start);
+
+  return ret ? num_debug_info_entries : 0;
+}
+
+static bfd_vma
+byte_get_signed (unsigned char *field, int size)
+{
+  bfd_vma x = byte_get (field, size);
+
+  switch (size)
+    {
+    case 1:
+      return (x ^ 0x80) - 0x80;
+    case 2:
+      return (x ^ 0x8000) - 0x8000;
+    case 4:
+      return (x ^ 0x80000000) - 0x80000000;
+    case 8:
+      return x;
+    default:
+      abort ();
+    }
+}
 
 static unsigned long int
 read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
@@ -7594,266 +7792,34 @@ process_extended_line_op (unsigned char 
   return len;
 }
 
-static const char *debug_str_contents;
-static bfd_vma debug_str_size;
-
-static void
-load_debug_str (FILE *file)
-{
-  Elf_Internal_Shdr *sec;
-
-  /* If it is already loaded, do nothing.  */
-  if (debug_str_contents != NULL)
-    return;
-
-  /* Locate the .debug_str section.  */
-  sec = find_section (".debug_str");
-  if (sec == NULL)
-    return;
-
-  debug_str_size = sec->sh_size;
-
-  debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
-				 _("debug_str section data"));
-}
-
-static void
-free_debug_str (void)
-{
-  if (debug_str_contents == NULL)
-    return;
-
-  free ((char *) debug_str_contents);
-  debug_str_contents = NULL;
-  debug_str_size = 0;
-}
+static struct dwarf_section debug_str_section = {
+  ".debug_str",
+  NULL,
+  0,
+  0
+};
 
 static const char *
 fetch_indirect_string (unsigned long offset)
 {
-  if (debug_str_contents == NULL)
+  if (debug_str_section.start == NULL)
     return _("<no .debug_str section>");
 
-  if (offset > debug_str_size)
+  if (offset > debug_str_section.size)
     {
       warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
       return _("<offset is too big>");
     }
 
-  return debug_str_contents + offset;
-}
-
-static const char *debug_loc_contents;
-static bfd_vma debug_loc_size;
-
-static void
-load_debug_loc (FILE *file)
-{
-  Elf_Internal_Shdr *sec;
-
-  /* If it is already loaded, do nothing.  */
-  if (debug_loc_contents != NULL)
-    return;
-
-  /* Locate the .debug_loc section.  */
-  sec = find_section (".debug_loc");
-  if (sec == NULL)
-    return;
-
-  debug_loc_size = sec->sh_size;
-
-  debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
-				 _("debug_loc section data"));
-}
-
-static void
-free_debug_loc (void)
-{
-  if (debug_loc_contents == NULL)
-    return;
-
-  free ((char *) debug_loc_contents);
-  debug_loc_contents = NULL;
-  debug_loc_size = 0;
+  return debug_str_section.start + offset;
 }
 
-static const char *   debug_range_contents;
-static unsigned long  debug_range_size;
-
-static void
-load_debug_range (FILE *file)
-{
-  Elf_Internal_Shdr *sec;
-
-  /* If it is already loaded, do nothing.  */
-  if (debug_range_contents != NULL)
-    return;
-
-  /* Locate the .debug_ranges section.  */
-  sec = find_section (".debug_ranges");
-  if (sec == NULL)
-    return;
-
-  debug_range_size = sec->sh_size;
-
-  debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
-				   _("debug_range section data"));
-}
-
-static void
-free_debug_range (void)
-{
-  if (debug_range_contents == NULL)
-    return;
-
-  free ((char *) debug_range_contents);
-  debug_range_contents = NULL;
-  debug_range_size = 0;
-}
-
-static unsigned char *debug_abbrev_contents;
-static unsigned long debug_abbrev_size;
-
-static void
-load_debug_abbrev (FILE *file)
-{
-  Elf_Internal_Shdr *sec;
-
-  /* If it is already loaded, do nothing.  */
-  if (debug_abbrev_contents != NULL)
-    return;
-
-  /* Locate the .debug_ranges section.  */
-  sec = find_section (".debug_abbrev");
-  if (sec == NULL)
-    return;
-
-  debug_abbrev_size = sec->sh_size;
-
-  debug_abbrev_contents = get_data (NULL, file, sec->sh_offset, 1,
-				    sec->sh_size,
-				    _("debug_abbrev section data"));
-}
-
-static void
-free_debug_abbrev (void)
-{
-  if (debug_abbrev_contents == NULL)
-    return;
-
-  free ((char *) debug_abbrev_contents);
-  debug_abbrev_contents = NULL;
-  debug_abbrev_size = 0;
-}
-
-/* Apply addends of RELA relocations.  */
-
-static int
-debug_apply_rela_addends (FILE *file,
-			  Elf_Internal_Shdr *section,
-			  unsigned char *start)
-{
-  Elf_Internal_Shdr *relsec;
-  unsigned char *end = start + section->sh_size;
-  /* FIXME: The relocation field size is relocation type dependent.  */
-  unsigned int reloc_size = 4;
-
-  if (elf_header.e_type != ET_REL)
-    return 1;
-
-  if (section->sh_size < reloc_size)
-    return 1;
-
-  for (relsec = section_headers;
-       relsec < section_headers + elf_header.e_shnum;
-       ++relsec)
-    {
-      unsigned long nrelas;
-      Elf_Internal_Rela *rela, *rp;
-      Elf_Internal_Shdr *symsec;
-      Elf_Internal_Sym *symtab;
-      Elf_Internal_Sym *sym;
-
-      if (relsec->sh_type != SHT_RELA
-	  || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
-	  || SECTION_HEADER (relsec->sh_info) != section
-	  || relsec->sh_size == 0
-	  || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
-	continue;
-
-      if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
-			      &rela, &nrelas))
-	return 0;
-
-      symsec = SECTION_HEADER (relsec->sh_link);
-      symtab = GET_ELF_SYMBOLS (file, symsec);
-
-      for (rp = rela; rp < rela + nrelas; ++rp)
-	{
-	  unsigned char *loc;
-
-	  loc = start + rp->r_offset;
-	  if ((loc + reloc_size) > end)
-	    {
-	      warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
-		    (unsigned long) rp->r_offset,
-		    SECTION_NAME (section));
-	      continue;
-	    }
-
-	  if (is_32bit_elf)
-	    {
-	      sym = symtab + ELF32_R_SYM (rp->r_info);
-
-	      if (ELF32_R_SYM (rp->r_info) != 0
-		  && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
-		  /* Relocations against object symbols can happen,
-		     eg when referencing a global array.  For an
-		     example of this see the _clz.o binary in libgcc.a.  */
-		  && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
-		{
-		  warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
-			get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
-			SECTION_NAME (section));
-		  continue;
-		}
-	    }
-	  else
-	    {
-	      /* In MIPS little-endian objects, r_info isn't really a
-		 64-bit little-endian value: it has a 32-bit little-endian
-		 symbol index followed by four individual byte fields.
-		 Reorder INFO accordingly.  */
-	      if (elf_header.e_machine == EM_MIPS
-		  && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
-		rp->r_info = (((rp->r_info & 0xffffffff) << 32)
-			      | ((rp->r_info >> 56) & 0xff)
-			      | ((rp->r_info >> 40) & 0xff00)
-			      | ((rp->r_info >> 24) & 0xff0000)
-			      | ((rp->r_info >> 8) & 0xff000000));
-
-	      sym = symtab + ELF64_R_SYM (rp->r_info);
-
-	      if (ELF64_R_SYM (rp->r_info) != 0
-		  && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
-		  && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
-		{
-		  warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
-			get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
-			SECTION_NAME (section));
-		  continue;
-		}
-	    }
-
-	  byte_put (loc, rp->r_addend, reloc_size);
-	}
-
-      free (symtab);
-      free (rela);
-      break;
-    }
-  return 1;
-}
+static struct dwarf_section debug_abbrev_section = {
+  ".debug_abbrev",
+  NULL,
+  0,
+  0
+};
 
 /* FIXME:  There are better and more efficient ways to handle
    these structures.  For now though, I just want something that
@@ -8495,9 +8461,6 @@ typedef struct
 debug_info;
 
 static debug_info *   debug_information = NULL;
-static unsigned int   num_debug_info_entries = 0;
-static unsigned int   last_pointer_size = 0;
-static int            warned_about_missing_comp_units = FALSE;
 
 static unsigned char *
 read_and_display_attr_value (unsigned long attribute,
@@ -9087,10 +9050,11 @@ read_and_display_attr (unsigned long att
    anything to the user.  */
 
 static int
-process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
-		    FILE *file, int do_loc)
+process_debug_info (struct dwarf_section *section, void *file,
+		    int do_loc)
 {
-  unsigned char *end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
   unsigned char *section_begin;
   unsigned int unit;
   unsigned int num_units = 0;
@@ -9120,7 +9084,7 @@ process_debug_info (Elf_Internal_Shdr *s
 
       if (num_units == 0)
 	{
-	  error (_("No comp units in .debug_info section ?"));
+	  error (_("No comp units in %s section ?"), section->name);
 	  return 0;
 	}
 
@@ -9137,18 +9101,16 @@ process_debug_info (Elf_Internal_Shdr *s
 
   if (!do_loc)
     {
-      printf (_("The section %s contains:\n\n"),
-	      SECTION_NAME (section));
+      printf (_("The section %s contains:\n\n"), section->name);
 
-      load_debug_str (file);
-      load_debug_loc (file);
-      load_debug_range (file);
+      load_debug_section (&debug_str_section, file);
     }
 
-  load_debug_abbrev (file);
-  if (debug_abbrev_contents == NULL)
+  load_debug_section (&debug_abbrev_section, file);
+  if (debug_abbrev_section.start == NULL)
     {
-      warn (_("Unable to locate .debug_abbrev section!\n"));
+      warn (_("Unable to locate %s section!\n"),
+	    debug_abbrev_section.name);
       return 0;
     }
 
@@ -9230,8 +9192,10 @@ process_debug_info (Elf_Internal_Shdr *s
 
       /* Process the abbrevs used by this compilation unit.  */
       process_abbrev_section
-	(debug_abbrev_contents + compunit.cu_abbrev_offset,
-	 debug_abbrev_contents + debug_abbrev_size);
+	((unsigned char *) debug_abbrev_section.start
+	 + compunit.cu_abbrev_offset,
+	 (unsigned char *) debug_abbrev_section.start
+	 + debug_abbrev_section.size);
 
       level = 0;
       while (tags < start)
@@ -9305,7 +9269,7 @@ process_debug_info (Elf_Internal_Shdr *s
  	}
     }
  
-  free_debug_abbrev ();
+  free_debug_section (&debug_abbrev_section);
 
   /* Set num_debug_info_entries here so that it can be used to check if
      we need to process .debug_loc and .debug_ranges sections.  */
@@ -9315,9 +9279,7 @@ process_debug_info (Elf_Internal_Shdr *s
       
   if (!do_loc)
     {
-      free_debug_range ();
-      free_debug_str ();
-      free_debug_loc (); 
+      free_debug_section (&debug_str_section);
 
       printf ("\n");
     }
@@ -9367,55 +9329,16 @@ get_pointer_size_and_offset_of_comp_unit
   return last_pointer_size;
 }
 
-/* Locate and scan the .debug_info section in the file and record the pointer
-   sizes and offsets for the compilation units in it.  Usually an executable
-   will have just one pointer size, but this is not guaranteed, and so we try
-   not to make any assumptions.  Returns zero upon failure, or the number of
-   compilation units upon success.  */
-
-static unsigned int
-get_debug_info (FILE * file)
-{
-  Elf_Internal_Shdr * section;
-  unsigned char *     start;
-  int		      ret;
-
-  /* Reset the last pointer size so that we can issue correct error
-     messages if we are displaying the contents of more than one section.  */
-  last_pointer_size = 0;
-  warned_about_missing_comp_units = FALSE;
-
-  /* If we already have the information there is nothing else to do.  */
-  if (num_debug_info_entries > 0)
-    return num_debug_info_entries;
-
-  section = find_section (".debug_info");
-  if (section == NULL)
-    return 0;
-
-  start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
-		    _("extracting information from .debug_info section"));
-  if (start == NULL)
-    return 0;
-
-  ret = (debug_apply_rela_addends (file, section, start)
-	 && process_debug_info (section, start, file, 1));
-
-  free (start);
-
-  return ret ? num_debug_info_entries : 0;
-}
-
 static int
-display_debug_lines (Elf_Internal_Shdr *section,
-		     unsigned char *start, FILE *file)
+display_debug_lines (struct dwarf_section *section, void *file)
 {
+  unsigned char *start = section->start;
   unsigned char *data = start;
-  unsigned char *end = start + section->sh_size;
+  unsigned char *end = start + section->size;
   unsigned int comp_unit = 0;
 
   printf (_("\nDump of debug contents of section %s:\n\n"),
-	  SECTION_NAME (section));
+	  section->name);
 
   get_debug_info (file);
 
@@ -9450,7 +9373,7 @@ display_debug_lines (Elf_Internal_Shdr *
 	  initial_length_size = 4;
 	}
 
-      if (info.li_length + initial_length_size > section->sh_size)
+      if (info.li_length + initial_length_size > section->size)
 	{
 	  warn
 	    (_("The line info appears to be corrupt - the section is too small\n"));
@@ -9697,16 +9620,14 @@ display_debug_lines (Elf_Internal_Shdr *
 }
 
 static int
-display_debug_pubnames (Elf_Internal_Shdr *section,
-			unsigned char *start,
-			FILE *file ATTRIBUTE_UNUSED)
+display_debug_pubnames (struct dwarf_section *section,
+			void *file ATTRIBUTE_UNUSED)
 {
   DWARF2_Internal_PubNames pubnames;
-  unsigned char *end;
-
-  end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
 
-  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+  printf (_("Contents of the %s section:\n\n"), section->name);
 
   while (start < end)
     {
@@ -9783,16 +9704,16 @@ display_debug_pubnames (Elf_Internal_Shd
 }
 
 static int
-display_debug_macinfo (Elf_Internal_Shdr *section,
-		       unsigned char *start,
-		       FILE *file ATTRIBUTE_UNUSED)
+display_debug_macinfo (struct dwarf_section *section,
+		       void *file ATTRIBUTE_UNUSED)
 {
-  unsigned char *end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
   unsigned char *curr = start;
   unsigned int bytes_read;
   enum dwarf_macinfo_record_type op;
 
-  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+  printf (_("Contents of the %s section:\n\n"), section->name);
 
   while (curr < end)
     {
@@ -9860,14 +9781,14 @@ display_debug_macinfo (Elf_Internal_Shdr
 
 
 static int
-display_debug_abbrev (Elf_Internal_Shdr *section,
-		      unsigned char *start,
-		      FILE *file ATTRIBUTE_UNUSED)
+display_debug_abbrev (struct dwarf_section *section,
+		      void *file ATTRIBUTE_UNUSED)
 {
   abbrev_entry *entry;
-  unsigned char *end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
 
-  printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+  printf (_("Contents of the %s section:\n\n"), section->name);
 
   do
     {
@@ -9903,9 +9824,9 @@ display_debug_abbrev (Elf_Internal_Shdr 
 }
 
 static int
-display_debug_loc (Elf_Internal_Shdr *section,
-		   unsigned char *start, FILE *file)
+display_debug_loc (struct dwarf_section *section, void *file)
 {
+  unsigned char *start = section->start;
   unsigned char *section_end;
   unsigned long bytes;
   unsigned char *section_begin = start;
@@ -9918,12 +9839,12 @@ display_debug_loc (Elf_Internal_Shdr *se
   int use_debug_info = 1;
   unsigned char *next;
 
-  bytes = section->sh_size;
+  bytes = section->size;
   section_end = start + bytes;
 
   if (bytes == 0)
     {
-      printf (_("\nThe .debug_loc section is empty.\n"));
+      printf (_("\nThe %s section is empty.\n"), section->name);
       return 0;
     }
 
@@ -9974,10 +9895,10 @@ display_debug_loc (Elf_Internal_Shdr *se
     error (_("No location lists in .debug_info section!\n"));
 
   if (debug_information [first].loc_offsets [0] != 0)
-    warn (_("Location lists in .debug_loc section start at 0x%lx\n"),
-	  debug_information [first].loc_offsets [0]);
+    warn (_("Location lists in %s section start at 0x%lx\n"),
+	  section->name, debug_information [first].loc_offsets [0]);
 
-  printf (_("Contents of the .debug_loc section:\n\n"));
+  printf (_("Contents of the %s section:\n\n"), section->name);
   printf (_("    Offset   Begin    End      Expression\n"));
 
   seen_first_offset = 0;
@@ -10095,23 +10016,20 @@ display_debug_loc (Elf_Internal_Shdr *se
 }
 
 static int
-display_debug_str (Elf_Internal_Shdr *section,
-		   unsigned char *start,
-		   FILE *file ATTRIBUTE_UNUSED)
+display_debug_str (struct dwarf_section *section,
+		   void *file ATTRIBUTE_UNUSED)
 {
-  unsigned long bytes;
-  bfd_vma addr;
-
-  addr  = section->sh_addr;
-  bytes = section->sh_size;
+  unsigned char *start = section->start;
+  unsigned long bytes = section->size;
+  bfd_vma addr = section->address;
 
   if (bytes == 0)
     {
-      printf (_("\nThe .debug_str section is empty.\n"));
+      printf (_("\nThe %s section is empty.\n"), section->name);
       return 0;
     }
 
-  printf (_("Contents of the .debug_str section:\n\n"));
+  printf (_("Contents of the %s section:\n\n"), section->name);
 
   while (bytes)
     {
@@ -10157,21 +10075,20 @@ display_debug_str (Elf_Internal_Shdr *se
 
 
 static int
-display_debug_info (Elf_Internal_Shdr * section,
-		    unsigned char * start, FILE * file)
+display_debug_info (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, start, file, 0);
+  return process_debug_info (section, file, 0);
 }
 
 
 static int
-display_debug_aranges (Elf_Internal_Shdr *section,
-		       unsigned char *start,
-		       FILE *file ATTRIBUTE_UNUSED)
+display_debug_aranges (struct dwarf_section *section,
+		       void *file ATTRIBUTE_UNUSED)
 {
-  unsigned char *end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
 
-  printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+  printf (_("The section %s contains:\n\n"), section->name);
 
   while (start < end)
     {
@@ -10261,10 +10178,10 @@ display_debug_aranges (Elf_Internal_Shdr
 }
 
 static int
-display_debug_ranges (Elf_Internal_Shdr *section,
-		      unsigned char *start,
-		      FILE *file ATTRIBUTE_UNUSED)
+display_debug_ranges (struct dwarf_section *section,
+		      void *file ATTRIBUTE_UNUSED)
 {
+  unsigned char *start = section->start;
   unsigned char *section_end;
   unsigned long bytes;
   unsigned char *section_begin = start;
@@ -10277,12 +10194,12 @@ display_debug_ranges (Elf_Internal_Shdr 
   int use_debug_info = 1;
   unsigned char *next;
 
-  bytes = section->sh_size;
+  bytes = section->size;
   section_end = start + bytes;
 
   if (bytes == 0)
     {
-      printf (_("\nThe .debug_ranges section is empty.\n"));
+      printf (_("\nThe %s section is empty.\n"), section->name);
       return 0;
     }
 
@@ -10333,10 +10250,10 @@ display_debug_ranges (Elf_Internal_Shdr 
     error (_("No range lists in .debug_info section!\n"));
 
   if (debug_information [first].range_lists [0] != 0)
-    warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
-	  debug_information [first].range_lists [0]);
+    warn (_("Range lists in %s section start at 0x%lx\n"),
+	  section->name, debug_information [first].range_lists [0]);
 
-  printf (_("Contents of the .debug_ranges section:\n\n"));
+  printf (_("Contents of the %s section:\n\n"), section->name);
   printf (_("    Offset   Begin    End\n"));
 
   seen_first_offset = 0;
@@ -10361,11 +10278,13 @@ display_debug_ranges (Elf_Internal_Shdr 
 	  else
 	    {
 	      if (start < next)
-		warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
-		      (long)(start - section_begin), (long)(next - section_begin));
+		warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
+		      (long)(start - section_begin),
+		      (long)(next - section_begin), section->name);
 	      else if (start > next)
-		warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
-		      (long)(start - section_begin), (long)(next - section_begin));
+		warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
+		      (long)(start - section_begin),
+		      (long)(next - section_begin), section->name);
 	    }
 	  start = next;
 
@@ -10545,20 +10464,20 @@ get_encoded_value (unsigned char *data, 
 #define SLEB()	read_leb128 (start, & length_return, 1); start += length_return
 
 static int
-display_debug_frames (Elf_Internal_Shdr *section,
-		      unsigned char *start,
-		      FILE *file ATTRIBUTE_UNUSED)
+display_debug_frames (struct dwarf_section *section,
+		      void *file ATTRIBUTE_UNUSED)
 {
-  unsigned char *end = start + section->sh_size;
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
   unsigned char *section_start = start;
   Frame_Chunk *chunks = 0;
   Frame_Chunk *remembered_state = 0;
   Frame_Chunk *rs;
-  int is_eh = streq (SECTION_NAME (section), ".eh_frame");
+  int is_eh = streq (section->name, ".eh_frame");
   unsigned int length_return;
   int max_regs = 0;
 
-  printf (_("The section %s contains:\n"), SECTION_NAME (section));
+  printf (_("The section %s contains:\n"), section->name);
 
   while (start < end)
     {
@@ -10766,10 +10685,11 @@ display_debug_frames (Elf_Internal_Shdr 
 
 	  fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
 	  if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
-	      /* Don't adjust for ET_REL since there's invariably a pcrel
-		 reloc here, which we haven't applied.  */
-	      && elf_header.e_type != ET_REL)
-	    fc->pc_begin += section->sh_addr + (start - section_start);
+	      /* Don't adjust for relocatable file since there's
+		 invariably a pcrel reloc here, which we haven't
+		 applied.  */
+	      && !is_relocatable)
+	    fc->pc_begin += section->address + (start - section_start);
 	  start += encoded_ptr_size;
 	  fc->pc_range = byte_get (start, encoded_ptr_size);
 	  start += encoded_ptr_size;
@@ -10969,8 +10889,8 @@ display_debug_frames (Elf_Internal_Shdr 
 	    case DW_CFA_set_loc:
 	      vma = get_encoded_value (start, fc->fde_encoding);
 	      if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
-		  && elf_header.e_type != ET_REL)
-		vma += section->sh_addr + (start - section_start);
+		  && !is_relocatable)
+		vma += section->address + (start - section_start);
 	      start += encoded_ptr_size;
 	      if (do_debug_frames_interp)
 		frame_display_row (fc, &need_col_headers, &max_regs);
@@ -11222,12 +11142,11 @@ display_debug_frames (Elf_Internal_Shdr 
 #undef SLEB
 
 static int
-display_debug_not_supported (Elf_Internal_Shdr *section,
-			     unsigned char *start ATTRIBUTE_UNUSED,
-			     FILE *file ATTRIBUTE_UNUSED)
+display_debug_not_supported (struct dwarf_section *section,
+			     void *file ATTRIBUTE_UNUSED)
 {
   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
-	    SECTION_NAME (section));
+	    section->name);
 
   return 1;
 }
@@ -11237,7 +11156,7 @@ display_debug_not_supported (Elf_Interna
 static struct
 {
   const char *const name;
-  int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
+  int (*display) (struct dwarf_section *, void *);
   unsigned int relocate : 1;
 }
 debug_displays[] =
@@ -11282,21 +11201,24 @@ display_debug_section (Elf_Internal_Shdr
   for (i = NUM_ELEM (debug_displays); i--;)
     if (streq (debug_displays[i].name, name))
       {
-	unsigned char *start;
+	struct dwarf_section sec;
 
-	start = get_data (NULL, file, section->sh_offset, 1, length,
-			  _("debug section data"));
-	if (start == NULL)
+	sec.name = name;
+	sec.address = section->sh_addr;
+	sec.size = section->sh_size;
+	sec.start = get_data (NULL, file, section->sh_offset, 1,
+			      length, _("debug section data"));
+	if (sec.start == NULL)
 	  {
 	    result = 0;
 	    break;
 	  }
 
 	if (!debug_displays[i].relocate
-	    || debug_apply_rela_addends (file, section, start))
-	  result &= debug_displays[i].display (section, start, file);
+	    || debug_apply_rela_addends (file, section, sec.start))
+	  result &= debug_displays[i].display (&sec, file);
 
-	free (start);
+	free (sec.start);
 
 	/* If we loaded in the abbrev section
 	   at some point, we must release it here.  */
@@ -12235,6 +12157,8 @@ get_file_header (FILE *file)
 	get_64bit_section_headers (file, 1);
     }
 
+  is_relocatable = elf_header.e_type == ET_REL;
+
   return 1;
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]