From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id C71B0385E009; Thu, 26 Mar 2020 15:33:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C71B0385E009 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Move more code to line-header.c X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: 86c0bb4c57111422b30da6b1b20256bd3a06778a X-Git-Newrev: 0df7ad3a675692fcc75c85c43e475015b87a297e Message-Id: <20200326153339.C71B0385E009@sourceware.org> Date: Thu, 26 Mar 2020 15:33:39 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Mar 2020 15:33:39 -0000 https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0df7ad3a675692fcc75c85c43e475015b87a297e commit 0df7ad3a675692fcc75c85c43e475015b87a297e Author: Tom Tromey Date: Thu Mar 26 09:28:08 2020 -0600 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 * 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. Diff: --- gdb/ChangeLog | 16 +++ gdb/dwarf2/line-header.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/dwarf2/line-header.h | 14 ++ gdb/dwarf2/read.c | 332 +--------------------------------------------- 4 files changed, 368 insertions(+), 329 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5e25a9befb5..bc524e1133e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2020-03-26 Tom Tromey + + * 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 * dwarf2/read.h (struct dwarf2_per_objfile) : diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c index f417f2d0fae..58749e9594b 100644 --- a/gdb/dwarf2/line-header.c +++ b/gdb/dwarf2/line-header.c @@ -18,6 +18,8 @@ along with this program. If not, see . */ #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 string; + gdb::optional 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 30bc37fb85a..700aaddacf7 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 dbd5b6a4802..ff5fa74997c 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); @@ -1673,12 +1669,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) { @@ -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 string; - gdb::optional 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.