This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Fix PR18374 by making readelf and objdump ignore end-of-list markers in the .debug_loc section if th


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f

commit d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri May 15 11:21:38 2015 +0100

    Fix PR18374 by making readelf and objdump ignore end-of-list markers in the .debug_loc section if there are relocations against them.
    
    	PR binutils/18374
    bin	* dwarf.h (struct dwarf_section): Add reloc_info and num_relocs
    	fields.
    	(struct dwarf_section_display): Change bitfield to boolean.
    	(reloc_at): Add prototype.
    	* dwarf.c (display_loc_list): Ignore list terminators if there are
    	relocs against them.
    	(display_debug_loc): Issue a warning if there are relocs against
    	the .debug_loc section.
    	(display_displays): Initialise reloc_info and num_relocs fields.
    	* objdump.c (load_specific_debug_section): Initialise reloc_info
    	and num_relocs fields.
    	(reloc_at): New function.
    	* readelf.c (is_32bit_abs_reloc): Add IA64's R_IA64_DIS32LSB
    	reloc.
    	(reloc_at): New function.
    	(apply_relocations): Add relocs_return and num_relocs_return
    	parameters.  Fill them in with the loaded relocs if non-NULL.
    	(dump_section_as_bytes): Update call to apply_relocations.
    	(load_specific_debug_section): Initialise reloc_info and
    	num_relocs fields.
    
    tests	* binutils-all/pr18374.s: New test file.
    	* binutils-all/readelf.exp: Assemble and run the new test.
    	* binutils-all/readelf.pr18374: Expected output from readelf.

Diff:
---
 binutils/ChangeLog                              |  24 +++
 binutils/dwarf.c                                | 168 +++++++++--------
 binutils/dwarf.h                                |  12 +-
 binutils/objdump.c                              |  42 ++++-
 binutils/readelf.c                              |  61 +++++-
 binutils/testsuite/ChangeLog                    |   7 +
 binutils/testsuite/binutils-all/pr18374.s       | 234 ++++++++++++++++++++++++
 binutils/testsuite/binutils-all/readelf.exp     |  16 ++
 binutils/testsuite/binutils-all/readelf.pr18374 |  14 ++
 9 files changed, 492 insertions(+), 86 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 84beb7e..5d017a1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -8,6 +8,30 @@
 	uncompressed size.  Don't check the zlib header.
 	(load_specific_debug_section): Updated.
 
+2015-05-15  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18374
+	* dwarf.h (struct dwarf_section): Add reloc_info and num_relocs
+	fields.
+	(struct dwarf_section_display): Change bitfield to boolean.
+	(reloc_at): Add prototype.
+	* dwarf.c (display_loc_list): Ignore list terminators if there are
+	relocs against them.
+	(display_debug_loc): Issue a warning if there are relocs against
+	the .debug_loc section.
+	(display_displays): Initialise reloc_info and num_relocs fields.
+	* objdump.c (load_specific_debug_section): Initialise reloc_info
+	and num_relocs fields.
+	(reloc_at): New function.
+	* readelf.c (is_32bit_abs_reloc): Add IA64's R_IA64_DIS32LSB
+	reloc.
+	(reloc_at): New function.
+	(apply_relocations): Add relocs_return and num_relocs_return
+	parameters.  Fill them in with the loaded relocs if non-NULL.
+	(dump_section_as_bytes): Update call to apply_relocations.
+	(load_specific_debug_section): Initialise reloc_info and
+	num_relocs fields.
+
 2015-05-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* elfedit.c (elf_class): Return ELF_CLASS_BOTH by default.
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 96d959a..71b0e97 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -4367,6 +4367,8 @@ display_loc_list (struct dwarf_section *section,
 
   while (1)
     {
+      unsigned long off = offset + (start - *start_ptr);
+
       if (start + 2 * pointer_size > section_end)
 	{
 	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
@@ -4374,7 +4376,7 @@ display_loc_list (struct dwarf_section *section,
 	  break;
 	}
 
-      printf ("    %8.8lx ", offset + (start - *start_ptr));
+      printf ("    %8.8lx ", off);
 
       /* Note: we use sign extension here in order to be sure that we can detect
 	 the -1 escape value.  Sign extension into the top 32 bits of a 32-bit
@@ -4385,8 +4387,18 @@ display_loc_list (struct dwarf_section *section,
 
       if (begin == 0 && end == 0)
 	{
-	  printf (_("<End of list>\n"));
-	  break;
+	  /* PR 18374: In a object file we can have a location list that
+	     starts with a begin and end of 0 because there are relocations
+	     that need to be applied to the addresses.  Actually applying
+	     the relocations now does not help as they will probably resolve
+	     to 0, since the object file has not been fully linked.  Real
+	     end of list markers will not have any relocations against them.  */
+	  if (! reloc_at (section, off)
+	      && ! reloc_at (section, off + pointer_size))
+	    {
+	      printf (_("<End of list>\n"));
+	      break;
+	    }
 	}
 
       /* Check base address specifiers.  */
@@ -4607,7 +4619,6 @@ display_debug_loc (struct dwarf_section *section, void *file)
   unsigned int first = 0;
   unsigned int i;
   unsigned int j;
-  unsigned int k;
   int seen_first_offset = 0;
   int locs_sorted = 1;
   unsigned char *next;
@@ -4683,13 +4694,16 @@ display_debug_loc (struct dwarf_section *section, void *file)
   if (!locs_sorted)
     array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
   printf (_("Contents of the %s section:\n\n"), section->name);
-  printf (_("    Offset   Begin    End      Expression\n"));
+  if (reloc_at (section, 0))
+    printf (_(" Warning: This section has relocations - addresses seen here may not be accurate.\n\n"));
+  printf (_("    Offset   Begin            End              Expression\n"));
 
   seen_first_offset = 0;
   for (i = first; i < num_debug_info_entries; i++)
     {
       unsigned long offset;
       unsigned long base_address;
+      unsigned int k;
       int has_frame_base;
 
       if (!locs_sorted)
@@ -7561,76 +7575,76 @@ dwarf_select_sections_all (void)
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_abbrev,   &do_debug_abbrevs,	0 },
-  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_aranges,  &do_debug_aranges,	1 },
-  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_frames,   &do_debug_frames,	1 },
-  { { ".debug_info",	    ".zdebug_info",	NULL, NULL, 0, 0, abbrev, NULL },
-    display_debug_info,	    &do_debug_info,	1 },
-  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_lines,    &do_debug_lines,	1 },
-  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_pubnames, &do_debug_pubnames,	0 },
-  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_gnu_pubnames, &do_debug_pubnames, 0 },
-  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_debug_frames,   &do_debug_frames,	1 },
-  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_str,	    &do_debug_str,	0 },
-  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_pubnames, &do_debug_pubtypes,	0 },
-  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_gnu_pubnames, &do_debug_pubtypes, 0 },
-  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_ranges,   &do_debug_ranges,	1 },
-  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_not_supported, NULL,		0 },
-  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_not_supported, NULL,		0 },
-  { { ".debug_types",	    ".zdebug_types",	NULL, NULL, 0, 0, abbrev, NULL },
-    display_debug_types,    &do_debug_info,	1 },
-  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_not_supported, NULL,		0 },
-  { { ".gdb_index",	    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_gdb_index,      &do_gdb_index,	0 },
-  { { ".trace_info",	    "",			NULL, NULL, 0, 0, trace_abbrev, NULL },
-    display_trace_info,	    &do_trace_info,	1 },
-  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_debug_abbrev,   &do_trace_abbrevs,	0 },
-  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_debug_aranges,  &do_trace_aranges,	0 },
-  { { ".debug_info.dwo",    ".zdebug_info.dwo",	NULL, NULL, 0, 0, abbrev_dwo, NULL },
-    display_debug_info,	    &do_debug_info,	1 },
-  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_abbrev,   &do_debug_abbrevs,	0 },
-  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL },
-    display_debug_types,    &do_debug_info,	1 },
-  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_lines,    &do_debug_lines,	1 },
-  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, 0, NULL },
-    display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0, NULL },
-    display_debug_str,      &do_debug_str,	1 },
-  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_str_offsets, NULL,		0 },
-  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL },
-    display_debug_str_offsets, NULL,		0 },
-  { { ".debug_addr",	    ".zdebug_addr",     NULL, NULL, 0, 0, 0, NULL },
-    display_debug_addr,     &do_debug_addr,	1 },
-  { { ".debug_cu_index",    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_cu_index,       &do_debug_cu_index,	0 },
-  { { ".debug_tu_index",    "",			NULL, NULL, 0, 0, 0, NULL },
-    display_cu_index,       &do_debug_cu_index,	0 },
+  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_abbrev,   &do_debug_abbrevs,	FALSE },
+  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_aranges,  &do_debug_aranges,	TRUE },
+  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_frames,   &do_debug_frames,	TRUE },
+  { { ".debug_info",	    ".zdebug_info",	NULL, NULL, 0, 0, abbrev, NULL, 0, NULL },
+    display_debug_info,	    &do_debug_info,	TRUE },
+  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_lines,    &do_debug_lines,	TRUE },
+  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_pubnames, &do_debug_pubnames,	FALSE },
+  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_gnu_pubnames, &do_debug_pubnames, FALSE },
+  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_frames,   &do_debug_frames,	TRUE },
+  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_macinfo,  &do_debug_macinfo,	FALSE },
+  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_macro,    &do_debug_macinfo,	TRUE },
+  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_str,	    &do_debug_str,	FALSE },
+  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_loc,	    &do_debug_loc,	TRUE },
+  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_pubnames, &do_debug_pubtypes,	FALSE },
+  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_gnu_pubnames, &do_debug_pubtypes, FALSE },
+  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_ranges,   &do_debug_ranges,	TRUE },
+  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_not_supported, NULL,		FALSE },
+  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_not_supported, NULL,		FALSE },
+  { { ".debug_types",	    ".zdebug_types",	NULL, NULL, 0, 0, abbrev, NULL, 0, NULL },
+    display_debug_types,    &do_debug_info,	TRUE },
+  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_not_supported, NULL,		FALSE },
+  { { ".gdb_index",	    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_gdb_index,      &do_gdb_index,	FALSE },
+  { { ".trace_info",	    "",			NULL, NULL, 0, 0, trace_abbrev, NULL, 0, NULL },
+    display_trace_info,	    &do_trace_info,	TRUE },
+  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_abbrev,   &do_trace_abbrevs,	FALSE },
+  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_aranges,  &do_trace_aranges,	FALSE },
+  { { ".debug_info.dwo",    ".zdebug_info.dwo",	NULL, NULL, 0, 0, abbrev_dwo, NULL, 0, NULL },
+    display_debug_info,	    &do_debug_info,	TRUE },
+  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_abbrev,   &do_debug_abbrevs,	FALSE },
+  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL, 0, NULL },
+    display_debug_types,    &do_debug_info,	TRUE },
+  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_lines,    &do_debug_lines,	TRUE },
+  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_loc,	    &do_debug_loc,	TRUE },
+  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_macro,    &do_debug_macinfo,	TRUE },
+  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_macinfo,  &do_debug_macinfo,	FALSE },
+  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_str,      &do_debug_str,	TRUE },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_str_offsets, NULL,		FALSE },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_str_offsets, NULL,		FALSE },
+  { { ".debug_addr",	    ".zdebug_addr",     NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_debug_addr,     &do_debug_addr,	TRUE },
+  { { ".debug_cu_index",    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_cu_index,       &do_debug_cu_index,	FALSE },
+  { { ".debug_tu_index",    "",			NULL, NULL, 0, 0, 0, NULL, 0, NULL },
+    display_cu_index,       &do_debug_cu_index,	FALSE },
 };
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 0e661d4..e679320 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -124,6 +124,11 @@ struct dwarf_section
   dwarf_vma address;
   dwarf_size_type size;
   enum dwarf_section_display_enum abbrev_sec;
+
+  /* Used by clients to help them implement the reloc_at callback.  */
+  void * reloc_info;
+  unsigned long num_relocs;
+
   /* A spare field for random use.  */
   void *user_data;
 };
@@ -135,7 +140,7 @@ struct dwarf_section_display
   struct dwarf_section section;
   int (*display) (struct dwarf_section *, void *);
   int *enabled;
-  unsigned int relocate : 1;
+  bfd_boolean relocate;
 };
 
 extern struct dwarf_section_display debug_displays [];
@@ -217,3 +222,8 @@ extern void * xcmalloc (size_t, size_t);
 extern void * xcrealloc (void *, size_t, size_t);
 
 extern dwarf_vma read_leb128 (unsigned char *, unsigned int *, bfd_boolean, const unsigned char * const);
+
+/* A callback into the client.  Retuns TRUE if there is a
+   relocation against the given debug section at the given
+   offset.  */
+extern bfd_boolean reloc_at (struct dwarf_section *, dwarf_vma);
diff --git a/binutils/objdump.c b/binutils/objdump.c
index f87c9c3..f51b6f5 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2278,6 +2278,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   if (section->start != NULL)
     return 1;
 
+  section->reloc_info = NULL;
+  section->num_relocs = 0;  
   section->address = bfd_get_section_vma (abfd, sec);
   section->size = bfd_get_section_size (sec);
   section->start = NULL;
@@ -2308,11 +2310,49 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
 	          section->name);
           return 0;
         }
-    }
+
+      long reloc_size;
+
+      reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
+      if (reloc_size > 0)
+	{
+	  unsigned long reloc_count;
+	  arelent **relocs;
+
+	  relocs = (arelent **) xmalloc (reloc_size);
+
+	  reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, NULL);
+	  if (reloc_count == 0)
+	    free (relocs);
+	  else
+	    {
+	      section->reloc_info = relocs;
+	      section->num_relocs = reloc_count;
+	    }
+	}
+    }	
 
   return 1;
 }
 
+bfd_boolean
+reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
+{
+  arelent ** relocs;
+  arelent * rp;
+
+  if (dsec == NULL || dsec->reloc_info == NULL)
+    return FALSE;
+
+  relocs = (arelent **) dsec->reloc_info;
+
+  for (; (rp = * relocs) != NULL; ++ relocs)
+    if (rp->address == offset)
+      return TRUE;
+
+  return FALSE;
+}
+
 int
 load_debug_section (enum dwarf_section_display_enum debug, void *file)
 {
diff --git a/binutils/readelf.c b/binutils/readelf.c
index e7090ff..e299e1b 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -11302,7 +11302,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_H8_300H:
       return reloc_type == 1; /* R_H8_DIR32.  */
     case EM_IA_64:
-      return reloc_type == 0x65; /* R_IA64_SECREL32LSB.  */
+      return reloc_type == 0x65 /* R_IA64_SECREL32LSB.  */
+	|| reloc_type == 0x25;  /* R_IA64_DIR32LSB.  */
     case EM_IP2K_OLD:
     case EM_IP2K:
       return reloc_type == 2; /* R_IP2K_32.  */
@@ -11696,19 +11697,51 @@ is_none_reloc (unsigned int reloc_type)
   return FALSE;
 }
 
+/* Returns TRUE if there is a relocation against
+   section NAME at OFFSET bytes.  */
+
+bfd_boolean
+reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
+{
+  Elf_Internal_Rela * relocs;
+  Elf_Internal_Rela * rp;
+
+  if (dsec == NULL || dsec->reloc_info == NULL)
+    return FALSE;
+
+  relocs = (Elf_Internal_Rela *) dsec->reloc_info;
+
+  for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
+    if (rp->r_offset == offset)
+      return TRUE;
+
+   return FALSE;
+}
+
 /* Apply relocations to a section.
    Note: So far support has been added only for those relocations
    which can be found in debug sections.
+   If RELOCS_RETURN is non-NULL then returns in it a pointer to the
+   loaded relocs.  It is then the caller's responsibility to free them.
    FIXME: Add support for more relocations ?  */
 
 static void
-apply_relocations (void * file,
-		   const Elf_Internal_Shdr * section,
-		   unsigned char * start, bfd_size_type size)
+apply_relocations (void *                     file,
+		   const Elf_Internal_Shdr *  section,
+		   unsigned char *            start,
+		   bfd_size_type              size,
+		   void **                     relocs_return,
+		   unsigned long *            num_relocs_return)
 {
   Elf_Internal_Shdr * relsec;
   unsigned char * end = start + size;
 
+  if (relocs_return != NULL)
+    {
+      * (Elf_Internal_Rela **) relocs_return = NULL;
+      * num_relocs_return = 0;
+    }
+
   if (elf_header.e_type != ET_REL)
     return;
 
@@ -11860,7 +11893,15 @@ apply_relocations (void * file,
 	}
 
       free (symtab);
-      free (relocs);
+
+      if (relocs_return)
+	{
+	  * (Elf_Internal_Rela **) relocs_return = relocs;
+	  * num_relocs_return = num_relocs;
+	}
+      else
+	free (relocs);
+
       break;
     }
 }
@@ -11999,7 +12040,7 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
 
   if (relocate)
     {
-      apply_relocations (file, section, start, section->sh_size);
+      apply_relocations (file, section, start, section->sh_size, NULL, NULL);
     }
   else
     {
@@ -12194,7 +12235,13 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
     return 0;
 
   if (debug_displays [debug].relocate)
-    apply_relocations ((FILE *) file, sec, section->start, section->size);
+    apply_relocations ((FILE *) file, sec, section->start, section->size,
+		       & section->reloc_info, & section->num_relocs);
+  else
+    {
+      section->reloc_info = NULL;
+      section->num_relocs = 0;
+    }
 
   return 1;
 }
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 8b1e3b4..ad8d8ad 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -4,6 +4,13 @@
 	with "$OBJDUMP -W".
 	* binutils-all/libdw2-compressedgabi.out: Updated.
 
+2015-05-15  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18374
+	* binutils-all/pr18374.s: New test file.
+	* binutils-all/readelf.exp: Assemble and run the new test.
+	* binutils-all/readelf.pr18374: Expected output from readelf.
+
 2015-05-12  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* binutils-all/elfedit-1.d: Also skip x86_64-*-nacl*.
diff --git a/binutils/testsuite/binutils-all/pr18374.s b/binutils/testsuite/binutils-all/pr18374.s
new file mode 100644
index 0000000..793fb70
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pr18374.s
@@ -0,0 +1,234 @@
+	.section	.debug_info,"",%progbits
+	.4byte	0x77
+	.2byte	0x4
+	.4byte	.Ldebug_abbrev0
+	.byte	0x4
+	.uleb128 0x1
+	.4byte	.LASF3
+	.byte	0xc
+	.ascii	"x.c\000"
+	.4byte	.LASF4
+	.4byte	.Ltext0
+	.4byte	.Letext0
+	.4byte	.Ldebug_line0
+	.uleb128 0x2
+	.ascii	"foo\000"
+	.byte	0x1
+	.byte	0x2
+	.4byte	.LFB0
+	.4byte	.LFE0
+	.uleb128 0x1
+	.byte	0x9c
+	.4byte	0x64
+	.uleb128 0x3
+	.ascii	"b\000"
+	.byte	0x1
+	.byte	0x2
+	.4byte	0x64
+	.4byte	.LLST0
+	.uleb128 0x4
+	.4byte	.LASF0
+	.byte	0x1
+	.byte	0x2
+	.4byte	0x66
+	.4byte	.LLST1
+	.uleb128 0x5
+	.ascii	"ptr\000"
+	.byte	0x1
+	.byte	0x4
+	.4byte	0x6d
+	.uleb128 0x1
+	.byte	0x50
+	.byte	0
+	.uleb128 0x6
+	.byte	0x4
+	.uleb128 0x7
+	.byte	0x4
+	.byte	0x7
+	.4byte	.LASF1
+	.uleb128 0x8
+	.byte	0x4
+	.4byte	0x73
+	.uleb128 0x7
+	.byte	0x1
+	.byte	0x8
+	.4byte	.LASF2
+	.byte	0
+
+	.section	.debug_abbrev,"",%progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0xe
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x6
+	.uleb128 0x10
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0x1
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x27
+	.uleb128 0x19
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x6
+	.uleb128 0x40
+	.uleb128 0x18
+	.uleb128 0x2117
+	.uleb128 0x19
+	.uleb128 0x1
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x5
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.uleb128 0x4
+	.uleb128 0x5
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.uleb128 0x5
+	.uleb128 0x34
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x18
+	.byte	0
+	.byte	0
+	.uleb128 0x6
+	.uleb128 0xf
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.byte	0
+	.byte	0
+	.uleb128 0x7
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.byte	0
+	.byte	0
+	.uleb128 0x8
+	.uleb128 0xf
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0
+	.byte	0
+	.byte	0
+
+	.section	.debug_loc,"",%progbits
+.Ldebug_loc0:
+.LLST0:
+	.4byte	.LVL0
+	.4byte	.LVL2
+	.2byte	0x1
+	.byte	0x50
+	.4byte	.LVL2
+	.4byte	.LFE0
+	.2byte	0x4
+	.byte	0xf3
+	.uleb128 0x1
+	.byte	0x50
+	.byte	0x9f
+	.4byte	0
+	.4byte	0
+.LLST1:
+	.4byte	.LVL0
+	.4byte	.LVL1
+	.2byte	0x1
+	.byte	0x51
+	.4byte	.LVL1
+	.4byte	.LVL2
+	.2byte	0x3
+	.byte	0x71
+	.sleb128 -1
+	.byte	0x9f
+	.4byte	.LVL2
+	.4byte	.LVL3
+	.2byte	0xb
+	.byte	0x70
+	.sleb128 0
+	.byte	0x20
+	.byte	0xf3
+	.uleb128 0x1
+	.byte	0x51
+	.byte	0x22
+	.byte	0x70
+	.sleb128 0
+	.byte	0x22
+	.byte	0x9f
+	.4byte	.LVL3
+	.4byte	.LFE0
+	.2byte	0xb
+	.byte	0x70
+	.sleb128 0
+	.byte	0x20
+	.byte	0x70
+	.sleb128 0
+	.byte	0x22
+	.byte	0xf3
+	.uleb128 0x1
+	.byte	0x51
+	.byte	0x22
+	.byte	0x9f
+	.4byte	0
+	.4byte	0
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index 3c6472b..58e140c 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -356,3 +356,19 @@ if ![is_remote host] {
 }
 
 readelf_test -n $tempfile readelf.n  {}
+
+# PR 18374 - Check that relocations against the .debug_loc section
+# do not prevent readelf from displaying all the location lists.
+if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then {
+    perror "could not assemble PR18374 test file"
+    unresolved "readelf - failed to assemble"
+    return
+}
+
+if ![is_remote host] {
+    set tempfile tmpdir/pr18374.o
+} else {
+    set tempfile [remote_download host tmpdir/pr18374.o]
+}
+
+readelf_test --debug-dump=loc $tempfile readelf.pr18374  {}
diff --git a/binutils/testsuite/binutils-all/readelf.pr18374 b/binutils/testsuite/binutils-all/readelf.pr18374
new file mode 100644
index 0000000..5be90f1
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.pr18374
@@ -0,0 +1,14 @@
+Contents of the .*ebug_loc section:
+
+ Warning: This section has relocations - addresses seen here may not be accurate.
+
+    Offset   Begin            End              Expression
+    0+0 0+0 0+0 .*
+    0000000b 0+0 0+0 .*
+    00000019 <End of list>
+    00000021 0+0 0+0 .*
+    0000002c 0+0 0+0 .*
+    00000039 0+0 0+0 .*
+    0000004e 0+0 0+0 .*
+    00000063 <End of list>
+#pass


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