Fix bug in .eh_frame/.debug_frame PC offset calculation for DW_EH_PE_pcrel

This fixes the following bugs:
https://bugs.llvm.org/show_bug.cgi?id=27249
https://bugs.llvm.org/show_bug.cgi?id=46414

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D100328
This commit is contained in:
Alex Orlov 2021-04-15 15:06:20 +04:00
parent 6adebe3fd2
commit 49cbf4cd85
5 changed files with 22 additions and 13 deletions

View File

@ -12,7 +12,7 @@
// CHECK-NEXT: Code alignment factor: 1
// CHECK-NEXT: Data alignment factor: -8
// CHECK-NEXT: Return address column: 16
// CHECK-NEXT: Personality Address: 0000000000001029
// CHECK-NEXT: Personality Address: 000000000000127c
// CHECK-NEXT: Augmentation data:
// CHECK: DW_CFA_def_cfa: reg7 +8
@ -21,9 +21,9 @@
// CHECK-NEXT: DW_CFA_nop:
/// FIXME Handle relocation correctly
// CHECK: 00000020 00000014 00000024 FDE cie=00000000 pc=0000103c...0000103c
// CHECK: 00000020 00000014 00000024 FDE cie=00000000 pc=0000127c...0000127c
// CHECK-NEXT: Format: DWARF32
// CHECK-NEXT: LSDA Address: 000000000000100b
// CHECK-NEXT: LSDA Address: 000000000000127c
// CHECK-NEXT: DW_CFA_nop:
// CHECK-NEXT: DW_CFA_nop:
// CHECK-NEXT: DW_CFA_nop:

View File

@ -15,6 +15,7 @@ namespace llvm {
struct DWARFSection {
StringRef Data;
uint64_t Address = 0;
};
struct SectionName {

View File

@ -823,6 +823,8 @@ Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
if (DebugFrame)
return DebugFrame.get();
const DWARFSection &DS = DObj->getFrameSection();
// There's a "bug" in the DWARFv3 standard with respect to the target address
// size within debug frame sections. While DWARF is supposed to be independent
// of its container, FDEs have fields with size being "target address size",
@ -832,10 +834,11 @@ Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
// provides this information). This problem is fixed in DWARFv4
// See this dwarf-discuss discussion for more details:
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
isLittleEndian(), DObj->getAddressSize());
auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false);
if (Error E = DF->parse(debugFrameData))
DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
DObj->getAddressSize());
auto DF =
std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false, DS.Address);
if (Error E = DF->parse(DebugFrameData))
return std::move(E);
DebugFrame.swap(DF);
@ -846,11 +849,13 @@ Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
if (EHFrame)
return EHFrame.get();
DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
isLittleEndian(), DObj->getAddressSize());
const DWARFSection &DS = DObj->getEHFrameSection();
DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
DObj->getAddressSize());
auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true);
if (Error E = DF->parse(debugFrameData))
auto DF =
std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true, DS.Address);
if (Error E = DF->parse(DebugFrameData))
return std::move(E);
DebugFrame.swap(DF);
return DebugFrame.get();
@ -1707,6 +1712,9 @@ public:
if (Name == "debug_ranges") {
// FIXME: Use the other dwo range section when we emit it.
RangesDWOSection.Data = Data;
} else if (Name == "debug_frame" || Name == "eh_frame") {
if (DWARFSection *S = mapNameToDWARFSection(Name))
S->Address = Section.getAddress();
}
} else if (InfoSectionMap *Sections =
StringSwitch<InfoSectionMap *>(Name)

View File

@ -9,7 +9,7 @@ CHECK-NOT: pc
RUN: llvm-dwarfdump %p/../../dsymutil/Inputs/basic1.macho.x86_64.o \
RUN: -eh-frame=0x00000018 | FileCheck %s --check-prefix=EH
EH: .eh_frame contents:
EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=fffffffffffffd20...fffffffffffffd44
EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=00000000...00000024
EH-NEXT: Format: DWARF32
EH-NEXT: DW_CFA_advance_loc: 1
EH-NOT: pc

View File

@ -12,7 +12,7 @@
# CHECK: DW_CFA_def_cfa: reg31 +0
# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=00000000...00000020
# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=00000050...00000070
# CHECK: DW_CFA_advance_loc: 8
# CHECK: DW_CFA_def_cfa_offset: +16
# CHECK: DW_CFA_offset: reg30 -8