public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: Support more than 1 comp unit
@ 2005-01-12  1:51 H. J. Lu
  2005-01-12  1:58 ` Daniel Jacobowitz
  0 siblings, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2005-01-12  1:51 UTC (permalink / raw)
  To: binutils

_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;
+}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Support more than 1 comp unit
  2005-01-12  1:51 PATCH: Support more than 1 comp unit H. J. Lu
@ 2005-01-12  1:58 ` Daniel Jacobowitz
  2005-01-12  4:18   ` H. J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2005-01-12  1:58 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Tue, Jan 11, 2005 at 05:50:43PM -0800, H. J. Lu wrote:
> _bfd_dwarf2_find_nearest_line doesn't support more than one comp unit.

That's obviously not true.  Could you be a little more specific about
what the problem is that you are trying to solve?

-- 
Daniel Jacobowitz

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Support more than 1 comp unit
  2005-01-12  1:58 ` Daniel Jacobowitz
@ 2005-01-12  4:18   ` H. J. Lu
  2005-01-12 17:26     ` H. J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2005-01-12  4:18 UTC (permalink / raw)
  To: binutils

On Tue, Jan 11, 2005 at 08:58:45PM -0500, Daniel Jacobowitz wrote:
> On Tue, Jan 11, 2005 at 05:50:43PM -0800, H. J. Lu wrote:
> > _bfd_dwarf2_find_nearest_line doesn't support more than one comp unit.
> 
> That's obviously not true.  Could you be a little more specific about
> what the problem is that you are trying to solve?
> 

dwarf2_debug has

  /* Preserve the original value of info_ptr for the current
     comp_unit so we can find a given entry by its reference. */
  char* info_ptr_unit;

which is used by find_abstract_instance_name:

	info_ptr = unit->stash->info_ptr_unit + die_ref;

The problem is there is only one info_ptr_unit per file for multiple
CUs. To work with more than one CU, info_ptr_unit has to be updated
for the current CU when find_abstract_instance_name is called. My
patch adds the CU offset to comp_unit, which can be used by
find_abstract_instance_name to adjust info_ptr_unit.

BTW, I have a testcase of a several MB ia64 libc_pic.os generated by
"ld -r".


H.J.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Support more than 1 comp unit
  2005-01-12  4:18   ` H. J. Lu
@ 2005-01-12 17:26     ` H. J. Lu
  2005-01-13 18:37       ` H. J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2005-01-12 17:26 UTC (permalink / raw)
  To: binutils

On Tue, Jan 11, 2005 at 08:18:18PM -0800, H. J. Lu wrote:
> On Tue, Jan 11, 2005 at 08:58:45PM -0500, Daniel Jacobowitz wrote:
> > On Tue, Jan 11, 2005 at 05:50:43PM -0800, H. J. Lu wrote:
> > > _bfd_dwarf2_find_nearest_line doesn't support more than one comp unit.
> > 
> > That's obviously not true.  Could you be a little more specific about
> > what the problem is that you are trying to solve?
> > 
> 
> dwarf2_debug has
> 
>   /* Preserve the original value of info_ptr for the current
>      comp_unit so we can find a given entry by its reference. */
>   char* info_ptr_unit;
> 
> which is used by find_abstract_instance_name:
> 
> 	info_ptr = unit->stash->info_ptr_unit + die_ref;
> 
> The problem is there is only one info_ptr_unit per file for multiple
> CUs. To work with more than one CU, info_ptr_unit has to be updated
> for the current CU when find_abstract_instance_name is called. My
> patch adds the CU offset to comp_unit, which can be used by
> find_abstract_instance_name to adjust info_ptr_unit.
> 
> BTW, I have a testcase of a several MB ia64 libc_pic.os generated by
> "ld -r".
> 

This is an updated patch. The last CU is alaway the first on the CU
list. We just need to get the next CU offset from it.


H.J.
----
2005-01-12  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 to get the
	current comp unit.
	(parse_comp_unit): Accept unit_length and unit_length_size.
	(_bfd_dwarf2_find_nearest_line): Record unit_offset for each
	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-12 08:44:56.195825163 -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,19 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
     return FALSE;
 
   /* Check the previously read comp. units first.  */
-  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);
+  each = stash->all_comp_units;
+  if (each)
+    {
+      /* The comp. unit list is in the descending order.  */
+      unit_offset = each->unit_length + each->unit_offset;
+      for (; 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);
+    }
+  else
+    unit_offset = 0;
 
   /* Read each remaining comp. units checking each as they are read.  */
   while (stash->info_ptr < stash->info_ptr_end)
@@ -1851,6 +1810,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 +1819,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 +1828,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 +1836,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 +1890,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;
+}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Support more than 1 comp unit
  2005-01-12 17:26     ` H. J. Lu
@ 2005-01-13 18:37       ` H. J. Lu
  2005-01-17 16:31         ` Nick Clifton
  0 siblings, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2005-01-13 18:37 UTC (permalink / raw)
  To: binutils

On Wed, Jan 12, 2005 at 09:26:28AM -0800, H. J. Lu wrote:
> On Tue, Jan 11, 2005 at 08:18:18PM -0800, H. J. Lu wrote:
> > On Tue, Jan 11, 2005 at 08:58:45PM -0500, Daniel Jacobowitz wrote:
> > > On Tue, Jan 11, 2005 at 05:50:43PM -0800, H. J. Lu wrote:
> > > > _bfd_dwarf2_find_nearest_line doesn't support more than one comp unit.
> > > 
> > > That's obviously not true.  Could you be a little more specific about
> > > what the problem is that you are trying to solve?
> > > 
> > 
> > dwarf2_debug has
> > 
> >   /* Preserve the original value of info_ptr for the current
> >      comp_unit so we can find a given entry by its reference. */
> >   char* info_ptr_unit;
> > 
> > which is used by find_abstract_instance_name:
> > 
> > 	info_ptr = unit->stash->info_ptr_unit + die_ref;
> > 
> > The problem is there is only one info_ptr_unit per file for multiple
> > CUs. To work with more than one CU, info_ptr_unit has to be updated
> > for the current CU when find_abstract_instance_name is called. My
> > patch adds the CU offset to comp_unit, which can be used by
> > find_abstract_instance_name to adjust info_ptr_unit.
> > 
> > BTW, I have a testcase of a several MB ia64 libc_pic.os generated by
> > "ld -r".
> > 
> 
> This is an updated patch. The last CU is alaway the first on the CU
> list. We just need to get the next CU offset from it.
> 
> 

The fix can be much simpler. We just need to change info_ptr_unit
from per file to per comp unit. This patch does that.


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

	* dwarf2.c (dwarf2_debug): Move info_ptr_unit to ...
	(comp_unit): Here.
	(read_unsigned_leb128): Removed.
	(read_signed_leb128): Removed.
	(find_abstract_instance_name): Updated.
	(parse_comp_unit): Accept info_ptr_unit.
	(_bfd_dwarf2_find_nearest_line): Set info_ptr_unit for each
	comp unit and pass it to parse_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-13 10:30:34.041879290 -0800
@@ -84,10 +84,6 @@ struct dwarf2_debug
      into a buffer yet.  */
   char* info_ptr;
 
-  /* Preserve the original value of info_ptr for the current
-     comp_unit so we can find a given entry by its reference. */
-  char* info_ptr_unit;
-
   /* Pointer to the end of the .debug_info section memory buffer.  */
   char* info_ptr_end;
 
@@ -155,6 +151,10 @@ struct comp_unit
   /* TRUE if there is a line number table associated with this comp. unit.  */
   int stmtlist;
 
+  /* Pointer to the current comp_unit so that we can find a given entry
+     by its reference.  */
+  char *info_ptr_unit;
+
   /* The offset into .debug_line of the line number table.  */
   unsigned long line_offset;
 
@@ -321,67 +321,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 +1271,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->info_ptr_unit + die_ref;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
 
@@ -1478,6 +1417,7 @@ static struct comp_unit *
 parse_comp_unit (bfd *abfd,
 		 struct dwarf2_debug *stash,
 		 bfd_vma unit_length,
+		 char *info_ptr_unit,
 		 unsigned int offset_size)
 {
   struct comp_unit* unit;
@@ -1558,6 +1498,7 @@ parse_comp_unit (bfd *abfd,
   unit->abbrevs = abbrevs;
   unit->end_ptr = end_ptr;
   unit->stash = stash;
+  unit->info_ptr_unit = info_ptr_unit;
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
@@ -1803,7 +1744,6 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
       if (stash->info_ptr == NULL)
 	return FALSE;
 
-      stash->info_ptr_unit = stash->info_ptr;
       stash->info_ptr_end = stash->info_ptr;
 
       for (msec = find_debug_info (abfd, NULL);
@@ -1851,6 +1791,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
       bfd_vma length;
       bfd_boolean found;
       unsigned int offset_size = addr_size;
+      char *info_ptr_unit = stash->info_ptr;
 
       length = read_4_bytes (abfd, stash->info_ptr);
       /* A 0xffffff length is the DWARF3 way of indicating we use
@@ -1883,7 +1824,8 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 
       if (length > 0)
 	{
-	  each = parse_comp_unit (abfd, stash, length, offset_size);
+	  each = parse_comp_unit (abfd, stash, length, info_ptr_unit,
+				  offset_size);
 	  stash->info_ptr += length;
 
 	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
--- bfd/elf-eh-frame.c.leb128	2004-11-16 09:59:14.000000000 -0800
+++ bfd/elf-eh-frame.c	2005-01-12 09:05:48.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-12 09:05:48.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-12 09:05:48.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;
+}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Support more than 1 comp unit
  2005-01-13 18:37       ` H. J. Lu
@ 2005-01-17 16:31         ` Nick Clifton
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2005-01-17 16:31 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi H. J.

> The fix can be much simpler. We just need to change info_ptr_unit
> from per file to per comp unit. This patch does that.

> 2005-01-13  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* dwarf2.c (dwarf2_debug): Move info_ptr_unit to ...
> 	(comp_unit): Here.
> 	(read_unsigned_leb128): Removed.
> 	(read_signed_leb128): Removed.
> 	(find_abstract_instance_name): Updated.
> 	(parse_comp_unit): Accept info_ptr_unit.
> 	(_bfd_dwarf2_find_nearest_line): Set info_ptr_unit for each
> 	comp unit and pass it to parse_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.

Approved - please apply.

Cheers
   Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-01-17 16:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-12  1:51 PATCH: Support more than 1 comp unit H. J. Lu
2005-01-12  1:58 ` Daniel Jacobowitz
2005-01-12  4:18   ` H. J. Lu
2005-01-12 17:26     ` H. J. Lu
2005-01-13 18:37       ` H. J. Lu
2005-01-17 16:31         ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).