[LLDB] Set the right address size on output DataExtractors from ObjectFile

If filling in a DataExtractor from an ObjectFile, e.g. via the
ReadSectionData method, the output DataExtractor gets the address
size from the m_data member.

ObjectFile's m_data member is initialized without knowledge about
the address size (so the address size is set based on the host's
sizeof(void*), and at that point within ObjectFile's constructor,
virtual methods implemented in subclasses (like GetAddressByteSize())
can't be called, therefore fix it up when filling in external
DataExtractors.

This makes sure that line tables from executables with a different
address size are parsed properly; previously this tripped up
DWARFDebugLine::LineTable::parse for 32 bit executables on a 64 bit
host, as the address size in the line table (4) didn't match the
one set in the DWARFDataExtractor.

Differential Revision: https://reviews.llvm.org/D70848
This commit is contained in:
Martin Storsjö 2019-11-29 13:28:25 +02:00
parent afd5d91281
commit 7d019d1a3b
2 changed files with 62 additions and 1 deletions

View File

@ -477,7 +477,13 @@ size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
DataExtractor &data) const {
// The entire file has already been mmap'ed into m_data, so just copy from
// there as the back mmap buffer will be shared with shared pointers.
return data.SetData(m_data, offset, length);
size_t ret = data.SetData(m_data, offset, length);
// DataExtractor::SetData copies the address byte size from m_data, but
// m_data's address byte size is only set from sizeof(void*), and we can't
// access subclasses GetAddressByteSize() when setting up m_data in the
// constructor.
data.SetAddressByteSize(GetAddressByteSize());
return ret;
}
size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,

View File

@ -0,0 +1,55 @@
# Test that lldb can read a line table for an architecture with a different
# address size than the one that of the host.
# REQUIRES: lld, x86
# RUN: llvm-mc -triple i686-windows-gnu %s -filetype=obj > %t.o
# RUN: lld-link %t.o -out:%t.exe -debug:dwarf -entry:entry -subsystem:console -lldmingw
# RUN: %lldb %t.exe -o "image dump line-table -v win-i386-line-table.c" -b | FileCheck %s
# CHECK: Line table for win-i386-line-table.c in `win-i386-line-table.s.tmp.exe
# CHECK: 0x00401000: /path/to/src/win-i386-line-table.c:2:1
# CHECK: 0x00401001: /path/to/src/win-i386-line-table.c:2:1
.text
.file "win-i386-line-table.c"
.globl _entry # -- Begin function entry
_entry: # @entry
.file 1 "/path/to/src" "win-i386-line-table.c"
.loc 1 1 0 # win-i386-line-table.c:1:0
.cfi_sections .debug_frame
.cfi_startproc
.loc 1 2 1 prologue_end # win-i386-line-table.c:2:1
retl
.cfi_endproc
# -- End function
.section .debug_str,"dr"
Linfo_string1:
.asciz "win-i386-line-table.c"
.section .debug_abbrev,"dr"
Lsection_abbrev:
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"dr"
Lsection_info:
Lcu_begin0:
.long Ldebug_info_end0-Ldebug_info_start0 # Length of Unit
Ldebug_info_start0:
.short 4 # DWARF version number
.secrel32 Lsection_abbrev # Offset Into Abbrev. Section
.byte 4 # Address Size (in bytes)
.byte 1 # Abbrev [1] 0xb:0x2d DW_TAG_compile_unit
.secrel32 Linfo_string1 # DW_AT_name
.secrel32 Lline_table_start0 # DW_AT_stmt_list
.byte 0 # End Of Children Mark
Ldebug_info_end0:
.section .debug_line,"dr"
Lline_table_start0: