aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2020-03-26 09:28:08 -0600
committerTom Tromey <tom@tromey.com>2020-03-26 09:28:20 -0600
commit0df7ad3a675692fcc75c85c43e475015b87a297e (patch)
treec0393ec9b1527e4ae97e23c90e7310d1461bc9f6 /gdb
parent86c0bb4c57111422b30da6b1b20256bd3a06778a (diff)
downloadgdb-0df7ad3a675692fcc75c85c43e475015b87a297e.zip
gdb-0df7ad3a675692fcc75c85c43e475015b87a297e.tar.gz
gdb-0df7ad3a675692fcc75c85c43e475015b87a297e.tar.bz2
Move more code to line-header.c
This moves some more code out of read.c and into line-header.c. dwarf_decode_line_header is split into two -- the part remaining in read.c handles interfacing to the dwarf2_cu; while the part in line-header.c (more or less) purely handles the actual decoding. gdb/ChangeLog 2020-03-26 Tom Tromey <tom@tromey.com> * dwarf2/line-header.h (dwarf_decode_line_header): Declare. * dwarf2/read.c (dwarf2_statement_list_fits_in_line_number_section_complaint): Move to line-header.c. (read_checked_initial_length_and_offset, read_formatted_entries): Likewise. (dwarf_decode_line_header): Split into two. * dwarf2/line-header.c (dwarf2_statement_list_fits_in_line_number_section_complaint): Move from read.c. (read_checked_initial_length_and_offset, read_formatted_entries): Likewise. (dwarf_decode_line_header): New function, split from read.c.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/dwarf2/line-header.c335
-rw-r--r--gdb/dwarf2/line-header.h14
-rw-r--r--gdb/dwarf2/read.c332
4 files changed, 368 insertions, 329 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5e25a9b..bc524e1 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,21 @@
2020-03-26 Tom Tromey <tom@tromey.com>
+ * dwarf2/line-header.h (dwarf_decode_line_header): Declare.
+ * dwarf2/read.c
+ (dwarf2_statement_list_fits_in_line_number_section_complaint):
+ Move to line-header.c.
+ (read_checked_initial_length_and_offset, read_formatted_entries):
+ Likewise.
+ (dwarf_decode_line_header): Split into two.
+ * dwarf2/line-header.c
+ (dwarf2_statement_list_fits_in_line_number_section_complaint):
+ Move from read.c.
+ (read_checked_initial_length_and_offset, read_formatted_entries):
+ Likewise.
+ (dwarf_decode_line_header): New function, split from read.c.
+
+2020-03-26 Tom Tromey <tom@tromey.com>
+
* dwarf2/read.h (struct dwarf2_per_objfile) <read_line_string>:
Declare method.
* dwarf2/read.c (read_attribute_value): Update.
diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index f417f2d..58749e9 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -18,6 +18,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "dwarf2/comp-unit.h"
+#include "dwarf2/leb.h"
#include "dwarf2/line-header.h"
#include "dwarf2/read.h"
#include "complaints.h"
@@ -112,3 +114,336 @@ line_header::file_full_name (int file, const char *comp_dir) const
else
return file_file_name (file);
}
+
+static void
+dwarf2_statement_list_fits_in_line_number_section_complaint (void)
+{
+ complaint (_("statement list doesn't fit in .debug_line section"));
+}
+
+/* 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
+ *OFFSET_SIZE.
+ If the initial length size is not equivalent to that specified in
+ CU_HEADER then issue a complaint.
+ This is useful when reading non-comp-unit headers. */
+
+static LONGEST
+read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read,
+ unsigned int *offset_size)
+{
+ LONGEST length = read_initial_length (abfd, buf, bytes_read);
+
+ gdb_assert (cu_header->initial_length_size == 4
+ || cu_header->initial_length_size == 8
+ || cu_header->initial_length_size == 12);
+
+ if (cu_header->initial_length_size != *bytes_read)
+ complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
+
+ *offset_size = (*bytes_read == 4) ? 4 : 8;
+ return length;
+}
+
+/* Read directory or file name entry format, starting with byte of
+ format count entries, ULEB128 pairs of entry formats, ULEB128 of
+ entries count and the entries themselves in the described entry
+ format. */
+
+static void
+read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ bfd *abfd, const gdb_byte **bufp,
+ struct line_header *lh,
+ const struct comp_unit_head *cu_header,
+ void (*callback) (struct line_header *lh,
+ const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length))
+{
+ gdb_byte format_count, formati;
+ ULONGEST data_count, datai;
+ const gdb_byte *buf = *bufp;
+ const gdb_byte *format_header_data;
+ unsigned int bytes_read;
+
+ format_count = read_1_byte (abfd, buf);
+ buf += 1;
+ format_header_data = buf;
+ for (formati = 0; formati < format_count; formati++)
+ {
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ }
+
+ data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ for (datai = 0; datai < data_count; datai++)
+ {
+ const gdb_byte *format = format_header_data;
+ struct file_entry fe;
+
+ for (formati = 0; formati < format_count; formati++)
+ {
+ ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+
+ ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+
+ gdb::optional<const char *> string;
+ gdb::optional<unsigned int> uint;
+
+ switch (form)
+ {
+ case DW_FORM_string:
+ string.emplace (read_direct_string (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_line_strp:
+ string.emplace
+ (dwarf2_per_objfile->read_line_string (buf,
+ cu_header,
+ &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_data1:
+ uint.emplace (read_1_byte (abfd, buf));
+ buf += 1;
+ break;
+
+ case DW_FORM_data2:
+ uint.emplace (read_2_bytes (abfd, buf));
+ buf += 2;
+ break;
+
+ case DW_FORM_data4:
+ uint.emplace (read_4_bytes (abfd, buf));
+ buf += 4;
+ break;
+
+ case DW_FORM_data8:
+ uint.emplace (read_8_bytes (abfd, buf));
+ buf += 8;
+ break;
+
+ case DW_FORM_data16:
+ /* This is used for MD5, but file_entry does not record MD5s. */
+ buf += 16;
+ break;
+
+ case DW_FORM_udata:
+ uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_block:
+ /* It is valid only for DW_LNCT_timestamp which is ignored by
+ current GDB. */
+ break;
+ }
+
+ switch (content_type)
+ {
+ case DW_LNCT_path:
+ if (string.has_value ())
+ fe.name = *string;
+ break;
+ case DW_LNCT_directory_index:
+ if (uint.has_value ())
+ fe.d_index = (dir_index) *uint;
+ break;
+ case DW_LNCT_timestamp:
+ if (uint.has_value ())
+ fe.mod_time = *uint;
+ break;
+ case DW_LNCT_size:
+ if (uint.has_value ())
+ fe.length = *uint;
+ break;
+ case DW_LNCT_MD5:
+ break;
+ default:
+ complaint (_("Unknown format content type %s"),
+ pulongest (content_type));
+ }
+ }
+
+ callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
+ }
+
+ *bufp = buf;
+}
+
+/* See line-header.h. */
+
+line_header_up
+dwarf_decode_line_header (sect_offset sect_off, bool is_dwz,
+ struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ const struct comp_unit_head *cu_header)
+{
+ const gdb_byte *line_ptr;
+ unsigned int bytes_read, offset_size;
+ int i;
+ const char *cur_dir, *cur_file;
+
+ bfd *abfd = section->get_bfd_owner ();
+
+ /* Make sure that at least there's room for the total_length field.
+ That could be 12 bytes long, but we're just going to fudge that. */
+ if (to_underlying (sect_off) + 4 >= section->size)
+ {
+ dwarf2_statement_list_fits_in_line_number_section_complaint ();
+ return 0;
+ }
+
+ line_header_up lh (new line_header ());
+
+ lh->sect_off = sect_off;
+ lh->offset_in_dwz = is_dwz;
+
+ line_ptr = section->buffer + to_underlying (sect_off);
+
+ /* Read in the header. */
+ lh->total_length =
+ read_checked_initial_length_and_offset (abfd, line_ptr, cu_header,
+ &bytes_read, &offset_size);
+ line_ptr += bytes_read;
+
+ const gdb_byte *start_here = line_ptr;
+
+ if (line_ptr + lh->total_length > (section->buffer + section->size))
+ {
+ dwarf2_statement_list_fits_in_line_number_section_complaint ();
+ return 0;
+ }
+ lh->statement_program_end = start_here + lh->total_length;
+ lh->version = read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ if (lh->version > 5)
+ {
+ /* This is a version we don't understand. The format could have
+ changed in ways we don't handle properly so just punt. */
+ complaint (_("unsupported version in .debug_line section"));
+ return NULL;
+ }
+ if (lh->version >= 5)
+ {
+ gdb_byte segment_selector_size;
+
+ /* Skip address size. */
+ read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ segment_selector_size = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ if (segment_selector_size != 0)
+ {
+ complaint (_("unsupported segment selector size %u "
+ "in .debug_line section"),
+ segment_selector_size);
+ return NULL;
+ }
+ }
+ lh->header_length = read_offset (abfd, line_ptr, offset_size);
+ line_ptr += offset_size;
+ lh->statement_program_start = line_ptr + lh->header_length;
+ lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ if (lh->version >= 4)
+ {
+ lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+ else
+ lh->maximum_ops_per_instruction = 1;
+
+ if (lh->maximum_ops_per_instruction == 0)
+ {
+ lh->maximum_ops_per_instruction = 1;
+ complaint (_("invalid maximum_ops_per_instruction "
+ "in `.debug_line' section"));
+ }
+
+ lh->default_is_stmt = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_base = read_1_signed_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->line_range = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->opcode_base = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
+
+ lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
+ for (i = 1; i < lh->opcode_base; ++i)
+ {
+ lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+
+ if (lh->version >= 5)
+ {
+ /* Read directory table. */
+ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+ cu_header,
+ [] (struct line_header *header, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ header->add_include_dir (name);
+ });
+
+ /* Read file name table. */
+ read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
+ cu_header,
+ [] (struct line_header *header, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ header->add_file_name (name, d_index, mod_time, length);
+ });
+ }
+ else
+ {
+ /* Read directory table. */
+ while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ lh->add_include_dir (cur_dir);
+ }
+ line_ptr += bytes_read;
+
+ /* Read file name table. */
+ while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ unsigned int mod_time, length;
+ dir_index d_index;
+
+ line_ptr += bytes_read;
+ d_index = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+
+ lh->add_file_name (cur_file, d_index, mod_time, length);
+ }
+ line_ptr += bytes_read;
+ }
+
+ if (line_ptr > (section->buffer + section->size))
+ complaint (_("line number info header doesn't "
+ "fit in `.debug_line' section"));
+
+ return lh;
+}
diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h
index 30bc37f..700aadd 100644
--- a/gdb/dwarf2/line-header.h
+++ b/gdb/dwarf2/line-header.h
@@ -195,4 +195,18 @@ file_entry::include_dir (const line_header *lh) const
return lh->include_dir_at (d_index);
}
+/* Read the statement program header starting at SECT_OFF in SECTION.
+ Return line_header. Returns nullptr if there is a problem reading
+ the header, e.g., if it has a version we don't understand.
+
+ NOTE: the strings in the include directory and file name tables of
+ the returned object point into the dwarf line section buffer,
+ and must not be freed. */
+
+extern line_header_up dwarf_decode_line_header
+ (sect_offset sect_off, bool is_dwz,
+ struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ const struct comp_unit_head *cu_header);
+
#endif /* DWARF2_LINE_HEADER_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index dbd5b6a..ff5fa74 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1239,10 +1239,6 @@ static void read_attribute_reprocess (const struct die_reader_specs *reader,
static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index);
-static LONGEST read_checked_initial_length_and_offset
- (bfd *, const gdb_byte *, const struct comp_unit_head *,
- unsigned int *, unsigned int *);
-
static sect_offset read_abbrev_offset
(struct dwarf2_per_objfile *dwarf2_per_objfile,
struct dwarf2_section_info *, sect_offset);
@@ -1674,12 +1670,6 @@ static void free_line_header_voidp (void *arg);
/* Various complaints about symbol reading that don't abort the process. */
static void
-dwarf2_statement_list_fits_in_line_number_section_complaint (void)
-{
- complaint (_("statement list doesn't fit in .debug_line section"));
-}
-
-static void
dwarf2_debug_line_missing_file_complaint (void)
{
complaint (_(".debug_line section has line data without a file"));
@@ -18730,33 +18720,6 @@ read_attribute (const struct die_reader_specs *reader,
need_reprocess);
}
-/* 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
- *OFFSET_SIZE.
- If the initial length size is not equivalent to that specified in
- CU_HEADER then issue a complaint.
- This is useful when reading non-comp-unit headers. */
-
-static LONGEST
-read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
- const struct comp_unit_head *cu_header,
- unsigned int *bytes_read,
- unsigned int *offset_size)
-{
- LONGEST length = read_initial_length (abfd, buf, bytes_read);
-
- gdb_assert (cu_header->initial_length_size == 4
- || cu_header->initial_length_size == 8
- || cu_header->initial_length_size == 12);
-
- if (cu_header->initial_length_size != *bytes_read)
- complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
-
- *offset_size = (*bytes_read == 4) ? 4 : 8;
- return length;
-}
-
/* Return pointer to string at .debug_str offset STR_OFFSET. */
static const char *
@@ -19217,140 +19180,6 @@ get_debug_line_section (struct dwarf2_cu *cu)
return section;
}
-/* Read directory or file name entry format, starting with byte of
- format count entries, ULEB128 pairs of entry formats, ULEB128 of
- entries count and the entries themselves in the described entry
- format. */
-
-static void
-read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
- bfd *abfd, const gdb_byte **bufp,
- struct line_header *lh,
- const struct comp_unit_head *cu_header,
- void (*callback) (struct line_header *lh,
- const char *name,
- dir_index d_index,
- unsigned int mod_time,
- unsigned int length))
-{
- gdb_byte format_count, formati;
- ULONGEST data_count, datai;
- const gdb_byte *buf = *bufp;
- const gdb_byte *format_header_data;
- unsigned int bytes_read;
-
- format_count = read_1_byte (abfd, buf);
- buf += 1;
- format_header_data = buf;
- for (formati = 0; formati < format_count; formati++)
- {
- read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- }
-
- data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
- buf += bytes_read;
- for (datai = 0; datai < data_count; datai++)
- {
- const gdb_byte *format = format_header_data;
- struct file_entry fe;
-
- for (formati = 0; formati < format_count; formati++)
- {
- ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
- format += bytes_read;
-
- ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read);
- format += bytes_read;
-
- gdb::optional<const char *> string;
- gdb::optional<unsigned int> uint;
-
- switch (form)
- {
- case DW_FORM_string:
- string.emplace (read_direct_string (abfd, buf, &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_line_strp:
- string.emplace
- (dwarf2_per_objfile->read_line_string (buf,
- cu_header,
- &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_data1:
- uint.emplace (read_1_byte (abfd, buf));
- buf += 1;
- break;
-
- case DW_FORM_data2:
- uint.emplace (read_2_bytes (abfd, buf));
- buf += 2;
- break;
-
- case DW_FORM_data4:
- uint.emplace (read_4_bytes (abfd, buf));
- buf += 4;
- break;
-
- case DW_FORM_data8:
- uint.emplace (read_8_bytes (abfd, buf));
- buf += 8;
- break;
-
- case DW_FORM_data16:
- /* This is used for MD5, but file_entry does not record MD5s. */
- buf += 16;
- break;
-
- case DW_FORM_udata:
- uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
- buf += bytes_read;
- break;
-
- case DW_FORM_block:
- /* It is valid only for DW_LNCT_timestamp which is ignored by
- current GDB. */
- break;
- }
-
- switch (content_type)
- {
- case DW_LNCT_path:
- if (string.has_value ())
- fe.name = *string;
- break;
- case DW_LNCT_directory_index:
- if (uint.has_value ())
- fe.d_index = (dir_index) *uint;
- break;
- case DW_LNCT_timestamp:
- if (uint.has_value ())
- fe.mod_time = *uint;
- break;
- case DW_LNCT_size:
- if (uint.has_value ())
- fe.length = *uint;
- break;
- case DW_LNCT_MD5:
- break;
- default:
- complaint (_("Unknown format content type %s"),
- pulongest (content_type));
- }
- }
-
- callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
- }
-
- *bufp = buf;
-}
-
/* Read the statement program header starting at OFFSET in
.debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
@@ -19364,12 +19193,7 @@ read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile,
static line_header_up
dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
{
- const gdb_byte *line_ptr;
- unsigned int bytes_read, offset_size;
- int i;
- const char *cur_dir, *cur_file;
struct dwarf2_section_info *section;
- bfd *abfd;
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
@@ -19384,159 +19208,9 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
return 0;
}
- /* We can't do this until we know the section is non-empty.
- Only then do we know we have such a section. */
- abfd = section->get_bfd_owner ();
-
- /* Make sure that at least there's room for the total_length field.
- That could be 12 bytes long, but we're just going to fudge that. */
- if (to_underlying (sect_off) + 4 >= section->size)
- {
- dwarf2_statement_list_fits_in_line_number_section_complaint ();
- return 0;
- }
-
- line_header_up lh (new line_header ());
-
- lh->sect_off = sect_off;
- lh->offset_in_dwz = cu->per_cu->is_dwz;
-
- line_ptr = section->buffer + to_underlying (sect_off);
-
- /* Read in the header. */
- lh->total_length =
- read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header,
- &bytes_read, &offset_size);
- line_ptr += bytes_read;
-
- const gdb_byte *start_here = line_ptr;
-
- if (line_ptr + lh->total_length > (section->buffer + section->size))
- {
- dwarf2_statement_list_fits_in_line_number_section_complaint ();
- return 0;
- }
- lh->statement_program_end = start_here + lh->total_length;
- lh->version = read_2_bytes (abfd, line_ptr);
- line_ptr += 2;
- if (lh->version > 5)
- {
- /* This is a version we don't understand. The format could have
- changed in ways we don't handle properly so just punt. */
- complaint (_("unsupported version in .debug_line section"));
- return NULL;
- }
- if (lh->version >= 5)
- {
- gdb_byte segment_selector_size;
-
- /* Skip address size. */
- read_1_byte (abfd, line_ptr);
- line_ptr += 1;
-
- segment_selector_size = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- if (segment_selector_size != 0)
- {
- complaint (_("unsupported segment selector size %u "
- "in .debug_line section"),
- segment_selector_size);
- return NULL;
- }
- }
- lh->header_length = read_offset (abfd, line_ptr, offset_size);
- line_ptr += offset_size;
- lh->statement_program_start = line_ptr + lh->header_length;
- lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- if (lh->version >= 4)
- {
- lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- }
- else
- lh->maximum_ops_per_instruction = 1;
-
- if (lh->maximum_ops_per_instruction == 0)
- {
- lh->maximum_ops_per_instruction = 1;
- complaint (_("invalid maximum_ops_per_instruction "
- "in `.debug_line' section"));
- }
-
- lh->default_is_stmt = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->line_base = read_1_signed_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->line_range = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->opcode_base = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
-
- lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
- for (i = 1; i < lh->opcode_base; ++i)
- {
- lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
- line_ptr += 1;
- }
-
- if (lh->version >= 5)
- {
- /* Read directory table. */
- read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
- &cu->header,
- [] (struct line_header *header, const char *name,
- dir_index d_index, unsigned int mod_time,
- unsigned int length)
- {
- header->add_include_dir (name);
- });
-
- /* Read file name table. */
- read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
- &cu->header,
- [] (struct line_header *header, const char *name,
- dir_index d_index, unsigned int mod_time,
- unsigned int length)
- {
- header->add_file_name (name, d_index, mod_time, length);
- });
- }
- else
- {
- /* Read directory table. */
- while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
- {
- line_ptr += bytes_read;
- lh->add_include_dir (cur_dir);
- }
- line_ptr += bytes_read;
-
- /* Read file name table. */
- while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
- {
- unsigned int mod_time, length;
- dir_index d_index;
-
- line_ptr += bytes_read;
- d_index = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
- mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
- length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
-
- lh->add_file_name (cur_file, d_index, mod_time, length);
- }
- line_ptr += bytes_read;
- }
-
- if (line_ptr > (section->buffer + section->size))
- complaint (_("line number info header doesn't "
- "fit in `.debug_line' section"));
-
- return lh;
+ return dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz,
+ dwarf2_per_objfile, section,
+ &cu->header);
}
/* Subroutine of dwarf_decode_lines to simplify it.