This is the mail archive of the binutils@sources.redhat.com 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]

PATCH: Support more than 1 comp unit


_bfd_dwarf2_find_nearest_line doesn't support more than one comp unit.
This patch fixes it. I also removed one set of read_unsigned_leb128
and read_signed_leb128.


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

	* dwarf2.c (comp_unit): Add unit_offset and unit_length.
	(read_unsigned_leb128): Removed.
	(read_signed_leb128): Removed.
	(find_abstract_instance_name): Use unit_offset.
	(parse_comp_unit): Accept unit_length and unit_length_size.
	(_bfd_dwarf2_find_nearest_line): Support more than one comp
	unit.

	* elf-eh-frame.c (read_unsigned_leb128): Moved to ...
	(read_signed_leb128): Moved to ...
	* libbfd.c: Here.

	* libbfd-in.h (read_unsigned_leb128): New prototype.
	(read_signed_leb128): Likewise.
	* libbfd.h: Regenerated.

--- bfd/dwarf2.c.leb128	2005-01-05 09:07:58.000000000 -0800
+++ bfd/dwarf2.c	2005-01-11 17:35:51.327669595 -0800
@@ -155,6 +155,12 @@ struct comp_unit
   /* TRUE if there is a line number table associated with this comp. unit.  */
   int stmtlist;
 
+  /* The offset into .debug_info of the debug info table.  */
+  bfd_vma unit_offset;
+
+  /* The total length of the comp unit.  */
+  bfd_vma unit_length;
+
   /* The offset into .debug_line of the line number table.  */
   unsigned long line_offset;
 
@@ -321,67 +327,6 @@ read_indirect_string (struct comp_unit* 
   return buf;
 }
 
-static unsigned int
-read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
-		      char *buf,
-		      unsigned int *bytes_read_ptr)
-{
-  unsigned int  result;
-  unsigned int  num_read;
-  int           shift;
-  unsigned char byte;
-
-  result   = 0;
-  shift    = 0;
-  num_read = 0;
-
-  do
-    {
-      byte = bfd_get_8 (abfd, buf);
-      buf ++;
-      num_read ++;
-      result |= ((byte & 0x7f) << shift);
-      shift += 7;
-    }
-  while (byte & 0x80);
-
-  * bytes_read_ptr = num_read;
-
-  return result;
-}
-
-static int
-read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
-		    char *buf,
-		    unsigned int * bytes_read_ptr)
-{
-  int           result;
-  int           shift;
-  int           num_read;
-  unsigned char byte;
-
-  result = 0;
-  shift = 0;
-  num_read = 0;
-
-  do
-    {
-      byte = bfd_get_8 (abfd, buf);
-      buf ++;
-      num_read ++;
-      result |= ((byte & 0x7f) << shift);
-      shift += 7;
-    }
-  while (byte & 0x80);
-
-  if ((shift < 32) && (byte & 0x40))
-    result |= -(1 << shift);
-
-  * bytes_read_ptr = num_read;
-
-  return result;
-}
-
 /* END VERBATIM */
 
 static bfd_uint64_t
@@ -1332,7 +1277,7 @@ find_abstract_instance_name (struct comp
   struct attribute attr;
   char *name = 0;
 
-  info_ptr = unit->stash->info_ptr_unit + die_ref;
+  info_ptr = unit->stash->info_ptr_unit + unit->unit_offset + die_ref;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
 
@@ -1478,6 +1423,8 @@ static struct comp_unit *
 parse_comp_unit (bfd *abfd,
 		 struct dwarf2_debug *stash,
 		 bfd_vma unit_length,
+		 unsigned int unit_length_size,
+		 bfd_vma unit_offset,
 		 unsigned int offset_size)
 {
   struct comp_unit* unit;
@@ -1558,6 +1505,8 @@ parse_comp_unit (bfd *abfd,
   unit->abbrevs = abbrevs;
   unit->end_ptr = end_ptr;
   unit->stash = stash;
+  unit->unit_length = unit_length + unit_length_size;
+  unit->unit_offset = unit_offset;
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
@@ -1755,6 +1704,8 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 
   struct comp_unit* each;
 
+  bfd_vma unit_offset;
+
   stash = *pinfo;
   addr = offset;
   if (section->output_section)
@@ -1839,11 +1790,18 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
     return FALSE;
 
   /* Check the previously read comp. units first.  */
+  unit_offset = 0;
   for (each = stash->all_comp_units; each; each = each->next_unit)
-    if (comp_unit_contains_address (each, addr))
-      return comp_unit_find_nearest_line (each, addr, filename_ptr,
-					  functionname_ptr, linenumber_ptr,
-					  stash);
+    {
+      /* The comp. unit list may not be in the ascending order.  */
+      bfd_vma offset = each->unit_length + each->unit_offset;
+      if (offset > unit_offset)
+	unit_offset = offset;
+      if (comp_unit_contains_address (each, addr))
+	return comp_unit_find_nearest_line (each, addr, filename_ptr,
+					    functionname_ptr,
+					    linenumber_ptr, stash);
+    }
 
   /* Read each remaining comp. units checking each as they are read.  */
   while (stash->info_ptr < stash->info_ptr_end)
@@ -1851,6 +1809,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
       bfd_vma length;
       bfd_boolean found;
       unsigned int offset_size = addr_size;
+      unsigned int length_size;
 
       length = read_4_bytes (abfd, stash->info_ptr);
       /* A 0xffffff length is the DWARF3 way of indicating we use
@@ -1859,7 +1818,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 	{
 	  offset_size = 8;
 	  length = read_8_bytes (abfd, stash->info_ptr + 4);
-	  stash->info_ptr += 12;
+	  length_size = 12;
 	}
       /* A zero length is the IRIX way of indicating 64-bit offsets,
 	 mostly because the 64-bit length will generally fit in 32
@@ -1868,7 +1827,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 	{
 	  offset_size = 8;
 	  length = read_4_bytes (abfd, stash->info_ptr + 4);
-	  stash->info_ptr += 8;
+	  length_size = 8;
 	}
       /* In the absence of the hints above, we assume addr_size-sized
 	 offsets, for backward-compatibility with pre-DWARF3 64-bit
@@ -1876,16 +1835,22 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
       else if (addr_size == 8)
 	{
 	  length = read_8_bytes (abfd, stash->info_ptr);
-	  stash->info_ptr += 8;
+	  length_size = 8;
 	}
       else
-	stash->info_ptr += 4;
+	length_size = 4;
+	
+      stash->info_ptr += length_size;
 
       if (length > 0)
 	{
-	  each = parse_comp_unit (abfd, stash, length, offset_size);
+	  each = parse_comp_unit (abfd, stash, length, length_size,
+				  unit_offset, offset_size);
 	  stash->info_ptr += length;
 
+	  /* Get the offset of the next comp unit.  */
+	  unit_offset = each->unit_offset + each->unit_length;
+
 	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
 	      == stash->sec->size)
 	    {
@@ -1924,6 +1889,9 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 		}
 	    }
 	}
+      else 
+	/* Update to the offset of the next comp unit.  */
+	unit_offset += length_size;
     }
 
   return FALSE;
--- bfd/elf-eh-frame.c.leb128	2004-11-16 09:59:14.000000000 -0800
+++ bfd/elf-eh-frame.c	2005-01-11 11:41:02.000000000 -0800
@@ -26,64 +26,6 @@
 
 #define EH_FRAME_HDR_SIZE 8
 
-/* Helper function for reading uleb128 encoded data.  */
-
-static bfd_vma
-read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
-		      char *buf,
-		      unsigned int *bytes_read_ptr)
-{
-  bfd_vma result;
-  unsigned int num_read;
-  int shift;
-  unsigned char byte;
-
-  result = 0;
-  shift = 0;
-  num_read = 0;
-  do
-    {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
-      buf++;
-      num_read++;
-      result |= (((bfd_vma) byte & 0x7f) << shift);
-      shift += 7;
-    }
-  while (byte & 0x80);
-  *bytes_read_ptr = num_read;
-  return result;
-}
-
-/* Helper function for reading sleb128 encoded data.  */
-
-static bfd_signed_vma
-read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
-		    char *buf,
-		    unsigned int * bytes_read_ptr)
-{
-  bfd_vma result;
-  int shift;
-  int num_read;
-  unsigned char byte;
-
-  result = 0;
-  shift = 0;
-  num_read = 0;
-  do
-    {
-      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
-      buf ++;
-      num_read ++;
-      result |= (((bfd_vma) byte & 0x7f) << shift);
-      shift += 7;
-    }
-  while (byte & 0x80);
-  if (byte & 0x40)
-    result |= (((bfd_vma) -1) << (shift - 7)) << 7;
-  *bytes_read_ptr = num_read;
-  return result;
-}
-
 #define read_uleb128(VAR, BUF)					\
 do								\
   {								\
--- bfd/libbfd-in.h.leb128	2004-10-11 09:36:15.000000000 -0700
+++ bfd/libbfd-in.h	2005-01-11 11:43:33.000000000 -0800
@@ -686,3 +686,6 @@ extern void bfd_section_already_linked_t
   (bfd_boolean (*) (struct bfd_section_already_linked_hash_entry *,
 		    void *), void *);
 
+extern bfd_vma read_unsigned_leb128 (bfd *, char *, unsigned int *);
+extern bfd_signed_vma read_signed_leb128 (bfd *, char *, unsigned int *);
+
--- bfd/libbfd.c.leb128	2004-08-13 08:00:10.000000000 -0700
+++ bfd/libbfd.c	2005-01-11 11:37:17.000000000 -0800
@@ -860,3 +860,61 @@ warn_deprecated (const char *what,
       mask |= ~(size_t) func;
     }
 }
+
+/* Helper function for reading uleb128 encoded data.  */
+
+bfd_vma
+read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+		      char *buf,
+		      unsigned int *bytes_read_ptr)
+{
+  bfd_vma result;
+  unsigned int num_read;
+  int shift;
+  unsigned char byte;
+
+  result = 0;
+  shift = 0;
+  num_read = 0;
+  do
+    {
+      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      buf++;
+      num_read++;
+      result |= (((bfd_vma) byte & 0x7f) << shift);
+      shift += 7;
+    }
+  while (byte & 0x80);
+  *bytes_read_ptr = num_read;
+  return result;
+}
+
+/* Helper function for reading sleb128 encoded data.  */
+
+bfd_signed_vma
+read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+		    char *buf,
+		    unsigned int * bytes_read_ptr)
+{
+  bfd_vma result;
+  int shift;
+  int num_read;
+  unsigned char byte;
+
+  result = 0;
+  shift = 0;
+  num_read = 0;
+  do
+    {
+      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+      buf ++;
+      num_read ++;
+      result |= (((bfd_vma) byte & 0x7f) << shift);
+      shift += 7;
+    }
+  while (byte & 0x80);
+  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
+    result |= (((bfd_vma) -1) << shift);
+  *bytes_read_ptr = num_read;
+  return result;
+}


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