PATCH: binutils/1179: -adjust-vma with negative number causes objdump -S to fail

H. J. Lu hjl@lucon.org
Mon Aug 8 16:03:00 GMT 2005


I didn't try to support -adjust-vma for non-relocatable files. Without
relocation information, it is tricky to get the debug info right. I
am not sure if it is worth the effort. We also have to adjust it for
debug info. This patch works on ELF/i386.


H.J.
----
bfd/

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

	PR binutils/1179
	* dwarf2.c (dwarf2_debug): Add dwarf_abbrev_vma,
	dwarf_line_vma, dwarf_str_vma and dwarf_ranges_vma.
	(read_indirect_string): Adjust for dwarf_str_vma.
	(read_abbrevs): Adjust for dwarf_abbrev_vma.
	(decode_line_info): Adjust dwarf_line_vma.
	(read_debug_ranges): Adjust for dwarf_ranges_vma.
	(read_rangelist): Likewise.

binutils/

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

	PR binutils/1179
	* objdump.c (disassemble_bytes): Don't adjust
	adjust_section_vma.
	(dump_bfd): Disallow adjust_section_vma for non-relocatable
	files.

--- binutils/bfd/dwarf2.c.adjust	2005-07-10 10:11:11.000000000 -0700
+++ binutils/bfd/dwarf2.c	2005-08-08 08:46:20.000000000 -0700
@@ -101,24 +101,36 @@ struct dwarf2_debug
   /* Length of the loaded .debug_abbrev section.  */
   unsigned long dwarf_abbrev_size;
 
+  /* Address of the loaded .debug_abbrev section.  */
+  bfd_vma dwarf_abbrev_vma;
+
   /* Buffer for decode_line_info.  */
   bfd_byte *dwarf_line_buffer;
 
   /* Length of the loaded .debug_line section.  */
   unsigned long dwarf_line_size;
 
+  /* Address of the loaded .debug_line section.  */
+  bfd_vma dwarf_line_vma;
+
   /* Pointer to the .debug_str section loaded into memory.  */
   bfd_byte *dwarf_str_buffer;
 
   /* Length of the loaded .debug_str section.  */
   unsigned long dwarf_str_size;
 
+  /* Address of the loaded .debug_str section.  */
+  bfd_vma dwarf_str_vma;
+
   /* Pointer to the .debug_ranges section loaded into memory. */
   bfd_byte *dwarf_ranges_buffer;
 
   /* Length of the loaded .debug_ranges section. */
   unsigned long dwarf_ranges_size;
 
+  /* Address of the loaded .debug_ranges section.  */
+  bfd_vma dwarf_ranges_vma;
+
   /* If the most recent call to bfd_find_nearest_line was given an
      address in an inlined function, preserve a pointer into the
      calling chain for subsequent calls to bfd_find_inliner_info to
@@ -319,6 +331,7 @@ read_indirect_string (struct comp_unit* 
 
       sz = msec->rawsize ? msec->rawsize : msec->size;
       stash->dwarf_str_size = sz;
+      stash->dwarf_str_vma = msec->vma;
       stash->dwarf_str_buffer = bfd_alloc (abfd, sz);
       if (! stash->dwarf_str_buffer)
 	return NULL;
@@ -328,6 +341,8 @@ read_indirect_string (struct comp_unit* 
 	return NULL;
     }
 
+  offset -= stash->dwarf_str_vma;
+
   if (offset >= stash->dwarf_str_size)
     {
       (*_bfd_error_handler) (_("Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."),
@@ -429,6 +444,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t of
 	}
 
       stash->dwarf_abbrev_size = msec->size;
+      stash->dwarf_abbrev_vma = msec->vma;
       stash->dwarf_abbrev_buffer
 	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
 						     stash->syms);
@@ -436,6 +452,8 @@ read_abbrevs (bfd *abfd, bfd_uint64_t of
 	  return 0;
     }
 
+  offset -= stash->dwarf_abbrev_vma;
+
   if (offset >= stash->dwarf_abbrev_size)
     {
       (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."),
@@ -951,6 +969,7 @@ decode_line_info (struct comp_unit *unit
 	}
 
       stash->dwarf_line_size = msec->size;
+      stash->dwarf_line_vma = msec->vma;
       stash->dwarf_line_buffer
 	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
 						     stash->syms);
@@ -960,7 +979,8 @@ decode_line_info (struct comp_unit *unit
 
   /* It is possible to get a bad value for the line_offset.  Validate
      it here so that we won't get a segfault below.  */
-  if (unit->line_offset >= stash->dwarf_line_size)
+  if ((unit->line_offset - stash->dwarf_line_vma)
+      >= stash->dwarf_line_size)
     {
       (*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."),
 			     unit->line_offset, stash->dwarf_line_size);
@@ -983,7 +1003,8 @@ decode_line_info (struct comp_unit *unit
   table->last_line = NULL;
   table->lcl_head = NULL;
 
-  line_ptr = stash->dwarf_line_buffer + unit->line_offset;
+  line_ptr = stash->dwarf_line_buffer + (unit->line_offset
+					 - stash->dwarf_line_vma);
 
   /* Read in the prologue.  */
   lh.total_length = read_4_bytes (abfd, line_ptr);
@@ -1386,6 +1407,7 @@ read_debug_ranges (struct comp_unit *uni
 	}
 
       stash->dwarf_ranges_size = msec->size;
+      stash->dwarf_ranges_vma = msec->vma;
       stash->dwarf_ranges_buffer
 	= bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
 						     stash->syms);
@@ -1599,7 +1621,8 @@ read_rangelist (struct comp_unit *unit, 
       if (! read_debug_ranges (unit))
 	return;
     }
-  ranges_ptr = unit->stash->dwarf_ranges_buffer + offset;
+  ranges_ptr = (unit->stash->dwarf_ranges_buffer
+		+ (offset - unit->stash->dwarf_ranges_vma));
     
   for (;;)
     {
--- binutils/binutils/objdump.c.adjust	2005-07-07 19:45:03.000000000 -0700
+++ binutils/binutils/objdump.c	2005-08-08 08:55:49.000000000 -0700
@@ -1355,10 +1355,7 @@ disassemble_bytes (struct disassemble_in
 	  done_dot = FALSE;
 
 	  if (with_line_numbers || with_source_code)
-	    /* The line number tables will refer to unadjusted
-	       section VMAs, so we must undo any VMA modifications
-	       when calling show_line.  */
-	    show_line (aux->abfd, section, addr_offset - adjust_section_vma);
+	    show_line (aux->abfd, section, addr_offset);
 
 	  if (! prefix_addresses)
 	    {
@@ -2616,7 +2613,17 @@ dump_bfd (bfd *abfd)
      the BFD information is a hack.  However, we must do it, or
      bfd_find_nearest_line will not do the right thing.  */
   if (adjust_section_vma != 0)
-    bfd_map_over_sections (abfd, adjust_addresses, NULL);
+    {
+      if (abfd->flags & HAS_RELOC)
+	bfd_map_over_sections (abfd, adjust_addresses, NULL);
+      else if (with_line_numbers || with_source_code)
+	{
+	  non_fatal (_("%s: not a relocatable file. Can't adjust section address"),
+		     bfd_get_filename (abfd));
+	  exit_status = 1;
+	  return;
+	}
+    }
 
   if (! dump_debugging_tags)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),



More information about the Binutils mailing list