From 4075cb26687ec6bbd5bab31b6b33f692a3ed3108 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 8 Feb 2020 13:40:54 -0700 Subject: [PATCH] Unify read_initial_length implementations There are two implementations of read_initial_length in gdb. This merges them and moves the resulting function to leb.c. 2020-02-08 Tom Tromey * 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/ChangeLog b/gdb/ChangeLog index 6bce0eb8159..b8d744e134c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2020-02-08 Tom Tromey + + * 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. + 2020-02-08 Tom Tromey * dwarf2/loc.c (dwarf2_find_location_expression) diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index 8cf136e5019..db8e5cd25f3 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -1475,24 +1475,6 @@ const struct objfile_key> 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 474ed4d9b49..4ff2a4ca326 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -1277,8 +1277,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 *); @@ -19016,68 +19014,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.30.2