[30/38] Unify read_initial_length implementations

Message ID 20200123005710.7978-31-tom@tromey.com
State New
Headers show
Series
  • Start reorganization of DWARF code
Related show

Commit Message

Tom Tromey Jan. 23, 2020, 12:57 a.m.
There are two implementations of read_initial_length in gdb.  This
merges them and moves the resulting function to leb.c.

2020-01-22  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (read_initial_length): Move to leb.c.
	* dwarf2/leb.h (read_initial_length): Declare.
	* dwarf2/leb.c (read_initial_length): Move from read.c.  Add
	handle_nonstd parameter.
	* dwarf2/frame.c (read_initial_length): Remove.
	(decode_frame_entry_1): Update.

Change-Id: I34d37bad0f8a584bfa781432cba25e05e1bd5750
---
 gdb/ChangeLog      |  9 +++++++
 gdb/dwarf2/frame.c | 20 +--------------
 gdb/dwarf2/leb.c   | 27 +++++++++++++++++++
 gdb/dwarf2/leb.h   | 41 +++++++++++++++++++++++++++++
 gdb/dwarf2/read.c  | 64 ----------------------------------------------
 5 files changed, 78 insertions(+), 83 deletions(-)

-- 
2.17.2

Comments

Fangrui Song via Gdb-patches Jan. 27, 2020, 1:21 p.m. | #1
On Thu, Jan 23, 2020, 02:00 Tom Tromey <tom@tromey.com> wrote:

> There are two implementations of read_initial_length in gdb.  This

> merges them and moves the resulting function to leb.c.

>

> 2020-01-22  Tom Tromey  <tom@tromey.com>

>

>         * dwarf2/read.c (read_initial_length): Move to leb.c.

>         * dwarf2/leb.h (read_initial_length): Declare.

>         * dwarf2/leb.c (read_initial_length): Move from read.c.  Add

>         handle_nonstd parameter.

>         * dwarf2/frame.c (read_initial_length): Remove.

>         (decode_frame_entry_1): Update.

>

> Change-Id: I34d37bad0f8a584bfa781432cba25e05e1bd5750

> ---

>  gdb/ChangeLog      |  9 +++++++

>  gdb/dwarf2/frame.c | 20 +--------------

>  gdb/dwarf2/leb.c   | 27 +++++++++++++++++++

>  gdb/dwarf2/leb.h   | 41 +++++++++++++++++++++++++++++

>  gdb/dwarf2/read.c  | 64 ----------------------------------------------

>  5 files changed, 78 insertions(+), 83 deletions(-)

>

> diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c

> index 7f57c28be2c..2d928670c6b 100644

> --- a/gdb/dwarf2/frame.c

> +++ b/gdb/dwarf2/frame.c

> @@ -1475,24 +1475,6 @@ const struct objfile_key<dwarf2_fde_table,

>                          gdb::noop_deleter<dwarf2_fde_table>>

>    dwarf2_frame_objfile_data;

>

> -

> -static ULONGEST

> -read_initial_length (bfd *abfd, const gdb_byte *buf,

> -                    unsigned int *bytes_read_ptr)

> -{

> -  ULONGEST result;

> -

> -  result = bfd_get_32 (abfd, buf);

> -  if (result == 0xffffffff)

> -    {

> -      result = bfd_get_64 (abfd, buf + 4);

> -      *bytes_read_ptr = 12;

> -    }

> -  else

> -    *bytes_read_ptr = 4;

> -

> -  return result;

> -}

>

>

>  /* Pointer encoding helper functions.  */

> @@ -1744,7 +1726,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const

> gdb_byte *start,

>    uint64_t uleb128;

>

>    buf = start;

> -  length = read_initial_length (unit->abfd, buf, &bytes_read);

> +  length = read_initial_length (unit->abfd, buf, &bytes_read, false);

>    buf += bytes_read;

>    end = buf + (size_t) length;

>

> diff --git a/gdb/dwarf2/leb.c b/gdb/dwarf2/leb.c

> index d26b48b381c..ef7314ed2b3 100644

> --- a/gdb/dwarf2/leb.c

> +++ b/gdb/dwarf2/leb.c

> @@ -83,3 +83,30 @@ read_signed_leb128 (bfd *abfd, const gdb_byte *buf,

>    *bytes_read_ptr = num_read;

>    return result;

>  }

> +

> +/* See leb.h.  */

> +

> +LONGEST

> +read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int

> *bytes_read,

> +                    bool handle_nonstd)

> +{

> +  LONGEST length = bfd_get_32 (abfd, buf);

> +

> +  if (length == 0xffffffff)

> +    {

> +      length = bfd_get_64 (abfd, buf + 4);

> +      *bytes_read = 12;

> +    }

> +  else if (handle_nonstd && length == 0)

> +    {

> +      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */

> +      length = bfd_get_64 (abfd, buf);

> +      *bytes_read = 8;

> +    }

> +  else

> +    {

> +      *bytes_read = 4;

> +    }

> +

> +  return length;

> +}

> diff --git a/gdb/dwarf2/leb.h b/gdb/dwarf2/leb.h

> index b17ab881ba2..29fdffebfec 100644

> --- a/gdb/dwarf2/leb.h

> +++ b/gdb/dwarf2/leb.h

> @@ -89,4 +89,45 @@ extern LONGEST read_signed_leb128 (bfd *, const

> gdb_byte *, unsigned int *);

>

>  extern ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned

> int *);

>

> +/* Read the initial length from a section.  The (draft) DWARF 3



Maybe it's time to remove the "draft" part about dwarf 3? :)

+   specification allows the initial length to take up either 4 bytes
> +   or 12 bytes.  If the first 4 bytes are 0xffffffff, then the next 8

> +   bytes describe the length and all offsets will be 8 bytes in length

> +   instead of 4.

> +

> +   An older, non-standard 64-bit format is also handled by this

> +   function.  The older format in question stores the initial length

> +   as an 8-byte quantity without an escape value.  Lengths greater

> +   than 2^32 aren't very common which means that the initial 4 bytes

> +   is almost always zero.  Since a length value of zero doesn't make

> +   sense for the 32-bit format, this initial zero can be considered to

> +   be an escape value which indicates the presence of the older 64-bit

> +   format.  As written, the code can't detect (old format) lengths

> +   greater than 4GB.  If it becomes necessary to handle lengths

> +   somewhat larger than 4GB, we could allow other small values (such

> +   as the non-sensical values of 1, 2, and 3) to also be used as

> +   escape values indicating the presence of the old format.

> +

> +   The value returned via bytes_read should be used to increment the

> +   relevant pointer after calling read_initial_length().

> +

> +   [ Note:  read_initial_length() and read_offset() are based on the

> +     document entitled "DWARF Debugging Information Format", revision

> +     3, draft 8, dated November 19, 2001.  This document was obtained

> +     from:

> +

> +       http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf

> +

> +     This document is only a draft and is subject to change.  (So beware.)

> +



I wonder if this could be updated to a final version.

+     Details regarding the older, non-standard 64-bit format were
> +     determined empirically by examining 64-bit ELF files produced by

> +     the SGI toolchain on an IRIX 6.5 machine.

> +

> +     - Kevin, July 16, 2002

> +   ] */

> +extern LONGEST read_initial_length (bfd *abfd, const gdb_byte *buf,

> +                                   unsigned int *bytes_read,

> +                                   bool handle_nonstd = true);

> +

>  #endif /* GDB_DWARF2_LEB_H */

> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c

> index f0d39ddb7f8..65e39b22b4f 100644

> --- a/gdb/dwarf2/read.c

> +++ b/gdb/dwarf2/read.c

> @@ -1282,8 +1282,6 @@ static CORE_ADDR read_addr_index (struct dwarf2_cu

> *cu, unsigned int addr_index)

>  static CORE_ADDR read_address (bfd *, const gdb_byte *ptr, struct

> dwarf2_cu *,

>                                unsigned int *);

>

> -static LONGEST read_initial_length (bfd *, const gdb_byte *, unsigned int

> *);

> -

>  static LONGEST read_checked_initial_length_and_offset

>    (bfd *, const gdb_byte *, const struct comp_unit_head *,

>     unsigned int *, unsigned int *);

> @@ -19061,68 +19059,6 @@ read_address (bfd *abfd, const gdb_byte *buf,

> struct dwarf2_cu *cu,

>    return retval;

>  }

>

> -/* Read the initial length from a section.  The (draft) DWARF 3

> -   specification allows the initial length to take up either 4 bytes

> -   or 12 bytes.  If the first 4 bytes are 0xffffffff, then the next 8

> -   bytes describe the length and all offsets will be 8 bytes in length

> -   instead of 4.

> -

> -   An older, non-standard 64-bit format is also handled by this

> -   function.  The older format in question stores the initial length

> -   as an 8-byte quantity without an escape value.  Lengths greater

> -   than 2^32 aren't very common which means that the initial 4 bytes

> -   is almost always zero.  Since a length value of zero doesn't make

> -   sense for the 32-bit format, this initial zero can be considered to

> -   be an escape value which indicates the presence of the older 64-bit

> -   format.  As written, the code can't detect (old format) lengths

> -   greater than 4GB.  If it becomes necessary to handle lengths

> -   somewhat larger than 4GB, we could allow other small values (such

> -   as the non-sensical values of 1, 2, and 3) to also be used as

> -   escape values indicating the presence of the old format.

> -

> -   The value returned via bytes_read should be used to increment the

> -   relevant pointer after calling read_initial_length().

> -

> -   [ Note:  read_initial_length() and read_offset() are based on the

> -     document entitled "DWARF Debugging Information Format", revision

> -     3, draft 8, dated November 19, 2001.  This document was obtained

> -     from:

> -

> -       http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf

> -

> -     This document is only a draft and is subject to change.  (So beware.)

> -

> -     Details regarding the older, non-standard 64-bit format were

> -     determined empirically by examining 64-bit ELF files produced by

> -     the SGI toolchain on an IRIX 6.5 machine.

> -

> -     - Kevin, July 16, 2002

> -   ] */

> -

> -static LONGEST

> -read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int

> *bytes_read)

> -{

> -  LONGEST length = bfd_get_32 (abfd, buf);

> -

> -  if (length == 0xffffffff)

> -    {

> -      length = bfd_get_64 (abfd, buf + 4);

> -      *bytes_read = 12;

> -    }

> -  else if (length == 0)

> -    {

> -      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */

> -      length = bfd_get_64 (abfd, buf);

> -      *bytes_read = 8;

> -    }

> -  else

> -    {

> -      *bytes_read = 4;

> -    }

> -

> -  return length;

> -}

> -

>  /* Cover function for read_initial_length.

>     Returns the length of the object at BUF, and stores the size of the

>     initial length in *BYTES_READ and stores the size that offsets will be

> in

> --

> 2.17.2

>

>
Tom Tromey Jan. 28, 2020, 12:49 a.m. | #2
>>>>> "Christian" == Christian Biesinger <cbiesinger@google.com> writes:


Christian>  +/* Read the initial length from a section.  The (draft) DWARF 3

Christian> Maybe it's time to remove the "draft" part about dwarf 3? :)

I'll tack on a separate patch to fix up the comment.
Thanks for pointing this out.

Tom

Patch

diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 7f57c28be2c..2d928670c6b 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -1475,24 +1475,6 @@  const struct objfile_key<dwarf2_fde_table,
 			 gdb::noop_deleter<dwarf2_fde_table>>
   dwarf2_frame_objfile_data;
 
-
-static ULONGEST
-read_initial_length (bfd *abfd, const gdb_byte *buf,
-		     unsigned int *bytes_read_ptr)
-{
-  ULONGEST result;
-
-  result = bfd_get_32 (abfd, buf);
-  if (result == 0xffffffff)
-    {
-      result = bfd_get_64 (abfd, buf + 4);
-      *bytes_read_ptr = 12;
-    }
-  else
-    *bytes_read_ptr = 4;
-
-  return result;
-}
 
 
 /* Pointer encoding helper functions.  */
@@ -1744,7 +1726,7 @@  decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
   uint64_t uleb128;
 
   buf = start;
-  length = read_initial_length (unit->abfd, buf, &bytes_read);
+  length = read_initial_length (unit->abfd, buf, &bytes_read, false);
   buf += bytes_read;
   end = buf + (size_t) length;
 
diff --git a/gdb/dwarf2/leb.c b/gdb/dwarf2/leb.c
index d26b48b381c..ef7314ed2b3 100644
--- a/gdb/dwarf2/leb.c
+++ b/gdb/dwarf2/leb.c
@@ -83,3 +83,30 @@  read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
   *bytes_read_ptr = num_read;
   return result;
 }
+
+/* See leb.h.  */
+
+LONGEST
+read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read,
+		     bool handle_nonstd)
+{
+  LONGEST length = bfd_get_32 (abfd, buf);
+
+  if (length == 0xffffffff)
+    {
+      length = bfd_get_64 (abfd, buf + 4);
+      *bytes_read = 12;
+    }
+  else if (handle_nonstd && length == 0)
+    {
+      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */
+      length = bfd_get_64 (abfd, buf);
+      *bytes_read = 8;
+    }
+  else
+    {
+      *bytes_read = 4;
+    }
+
+  return length;
+}
diff --git a/gdb/dwarf2/leb.h b/gdb/dwarf2/leb.h
index b17ab881ba2..29fdffebfec 100644
--- a/gdb/dwarf2/leb.h
+++ b/gdb/dwarf2/leb.h
@@ -89,4 +89,45 @@  extern LONGEST read_signed_leb128 (bfd *, const gdb_byte *, unsigned int *);
 
 extern ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned int *);
 
+/* Read the initial length from a section.  The (draft) DWARF 3
+   specification allows the initial length to take up either 4 bytes
+   or 12 bytes.  If the first 4 bytes are 0xffffffff, then the next 8
+   bytes describe the length and all offsets will be 8 bytes in length
+   instead of 4.
+
+   An older, non-standard 64-bit format is also handled by this
+   function.  The older format in question stores the initial length
+   as an 8-byte quantity without an escape value.  Lengths greater
+   than 2^32 aren't very common which means that the initial 4 bytes
+   is almost always zero.  Since a length value of zero doesn't make
+   sense for the 32-bit format, this initial zero can be considered to
+   be an escape value which indicates the presence of the older 64-bit
+   format.  As written, the code can't detect (old format) lengths
+   greater than 4GB.  If it becomes necessary to handle lengths
+   somewhat larger than 4GB, we could allow other small values (such
+   as the non-sensical values of 1, 2, and 3) to also be used as
+   escape values indicating the presence of the old format.
+
+   The value returned via bytes_read should be used to increment the
+   relevant pointer after calling read_initial_length().
+
+   [ Note:  read_initial_length() and read_offset() are based on the
+     document entitled "DWARF Debugging Information Format", revision
+     3, draft 8, dated November 19, 2001.  This document was obtained
+     from:
+
+	http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf
+
+     This document is only a draft and is subject to change.  (So beware.)
+
+     Details regarding the older, non-standard 64-bit format were
+     determined empirically by examining 64-bit ELF files produced by
+     the SGI toolchain on an IRIX 6.5 machine.
+
+     - Kevin, July 16, 2002
+   ] */
+extern LONGEST read_initial_length (bfd *abfd, const gdb_byte *buf,
+				    unsigned int *bytes_read,
+				    bool handle_nonstd = true);
+
 #endif /* GDB_DWARF2_LEB_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f0d39ddb7f8..65e39b22b4f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1282,8 +1282,6 @@  static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 static CORE_ADDR read_address (bfd *, const gdb_byte *ptr, struct dwarf2_cu *,
 			       unsigned int *);
 
-static LONGEST read_initial_length (bfd *, const gdb_byte *, unsigned int *);
-
 static LONGEST read_checked_initial_length_and_offset
   (bfd *, const gdb_byte *, const struct comp_unit_head *,
    unsigned int *, unsigned int *);
@@ -19061,68 +19059,6 @@  read_address (bfd *abfd, const gdb_byte *buf, struct dwarf2_cu *cu,
   return retval;
 }
 
-/* Read the initial length from a section.  The (draft) DWARF 3
-   specification allows the initial length to take up either 4 bytes
-   or 12 bytes.  If the first 4 bytes are 0xffffffff, then the next 8
-   bytes describe the length and all offsets will be 8 bytes in length
-   instead of 4.
-
-   An older, non-standard 64-bit format is also handled by this
-   function.  The older format in question stores the initial length
-   as an 8-byte quantity without an escape value.  Lengths greater
-   than 2^32 aren't very common which means that the initial 4 bytes
-   is almost always zero.  Since a length value of zero doesn't make
-   sense for the 32-bit format, this initial zero can be considered to
-   be an escape value which indicates the presence of the older 64-bit
-   format.  As written, the code can't detect (old format) lengths
-   greater than 4GB.  If it becomes necessary to handle lengths
-   somewhat larger than 4GB, we could allow other small values (such
-   as the non-sensical values of 1, 2, and 3) to also be used as
-   escape values indicating the presence of the old format.
-
-   The value returned via bytes_read should be used to increment the
-   relevant pointer after calling read_initial_length().
-
-   [ Note:  read_initial_length() and read_offset() are based on the
-     document entitled "DWARF Debugging Information Format", revision
-     3, draft 8, dated November 19, 2001.  This document was obtained
-     from:
-
-	http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf
-
-     This document is only a draft and is subject to change.  (So beware.)
-
-     Details regarding the older, non-standard 64-bit format were
-     determined empirically by examining 64-bit ELF files produced by
-     the SGI toolchain on an IRIX 6.5 machine.
-
-     - Kevin, July 16, 2002
-   ] */
-
-static LONGEST
-read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read)
-{
-  LONGEST length = bfd_get_32 (abfd, buf);
-
-  if (length == 0xffffffff)
-    {
-      length = bfd_get_64 (abfd, buf + 4);
-      *bytes_read = 12;
-    }
-  else if (length == 0)
-    {
-      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */
-      length = bfd_get_64 (abfd, buf);
-      *bytes_read = 8;
-    }
-  else
-    {
-      *bytes_read = 4;
-    }
-
-  return length;
-}
-
 /* Cover function for read_initial_length.
    Returns the length of the object at BUF, and stores the size of the
    initial length in *BYTES_READ and stores the size that offsets will be in