diff options
author | Hsiangkai Wang <hsiangkai@gmail.com> | 2019-07-18 14:47:34 +0000 |
---|---|---|
committer | Hsiangkai Wang <hsiangkai@gmail.com> | 2019-07-18 14:47:34 +0000 |
commit | e43ce1a958aa0c2da41961f77a4dbd7ff97487e0 (patch) | |
tree | b14e6d28e1643600d2b14cbeb6f939f68a35c787 /llvm/lib/MC/MCDwarf.cpp | |
parent | 48104ef7c9c653bbb732b66d7254957389fea337 (diff) | |
download | bcm5719-llvm-e43ce1a958aa0c2da41961f77a4dbd7ff97487e0.tar.gz bcm5719-llvm-e43ce1a958aa0c2da41961f77a4dbd7ff97487e0.zip |
[DebugInfo] Generate fixups as emitting DWARF .debug_frame/.eh_frame.
It is necessary to generate fixups in .debug_frame or .eh_frame as
relaxation is enabled due to the address delta may be changed after
relaxation.
There is an opcode with 6-bits data in debug frame encoding. So, we
also need 6-bits fixup types.
Differential Revision: https://reviews.llvm.org/D58335
llvm-svn: 366442
Diffstat (limited to 'llvm/lib/MC/MCDwarf.cpp')
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index aae6fdf9093..8456b3421bc 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1897,26 +1897,54 @@ void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer, } void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context, - uint64_t AddrDelta, - raw_ostream &OS) { + uint64_t AddrDelta, raw_ostream &OS, + uint32_t *Offset, uint32_t *Size) { // Scale the address delta by the minimum instruction length. AddrDelta = ScaleAddrDelta(Context, AddrDelta); + bool WithFixups = false; + if (Offset && Size) + WithFixups = true; + support::endianness E = Context.getAsmInfo()->isLittleEndian() ? support::little : support::big; if (AddrDelta == 0) { + if (WithFixups) { + *Offset = 0; + *Size = 0; + } } else if (isUIntN(6, AddrDelta)) { uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta; - OS << Opcode; + if (WithFixups) { + *Offset = OS.tell(); + *Size = 6; + OS << uint8_t(dwarf::DW_CFA_advance_loc); + } else + OS << Opcode; } else if (isUInt<8>(AddrDelta)) { OS << uint8_t(dwarf::DW_CFA_advance_loc1); - OS << uint8_t(AddrDelta); + if (WithFixups) { + *Offset = OS.tell(); + *Size = 8; + OS.write_zeros(1); + } else + OS << uint8_t(AddrDelta); } else if (isUInt<16>(AddrDelta)) { OS << uint8_t(dwarf::DW_CFA_advance_loc2); - support::endian::write<uint16_t>(OS, AddrDelta, E); + if (WithFixups) { + *Offset = OS.tell(); + *Size = 16; + OS.write_zeros(2); + } else + support::endian::write<uint16_t>(OS, AddrDelta, E); } else { assert(isUInt<32>(AddrDelta)); OS << uint8_t(dwarf::DW_CFA_advance_loc4); - support::endian::write<uint32_t>(OS, AddrDelta, E); + if (WithFixups) { + *Offset = OS.tell(); + *Size = 32; + OS.write_zeros(4); + } else + support::endian::write<uint32_t>(OS, AddrDelta, E); } } |