aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCDwarf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCDwarf.cpp')
-rw-r--r--lib/MC/MCDwarf.cpp34
1 files changed, 28 insertions, 6 deletions
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 6e59a58b04..08d327ae8b 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -460,12 +460,7 @@ static void EmitFrameMoves(MCStreamer &streamer,
if (BaseLabel && Label) {
MCSymbol *ThisSym = Label;
if (ThisSym != BaseLabel) {
- // FIXME: We should relax this instead of using a DW_CFA_advance_loc4
- // for every address change!
- streamer.EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
- const MCExpr *Length = MakeStartMinusEndExpr(streamer, *BaseLabel,
- *ThisSym, 0);
- streamer.EmitValue(Length, 4);
+ streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
BaseLabel = ThisSym;
}
}
@@ -748,3 +743,30 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) {
if (fdeEnd)
streamer.EmitLabel(fdeEnd);
}
+
+void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
+ uint64_t AddrDelta) {
+ SmallString<256> Tmp;
+ raw_svector_ostream OS(Tmp);
+ MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS);
+ Streamer.EmitBytes(OS.str(), /*AddrSpace=*/0);
+}
+
+void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta,
+ raw_ostream &OS) {
+ // FIXME: Assumes the code alignment factor is 1.
+ if (isUIntN(6, AddrDelta)) {
+ uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
+ OS << Opcode;
+ } else if (isUInt<8>(AddrDelta)) {
+ OS << uint8_t(dwarf::DW_CFA_advance_loc1);
+ OS << uint8_t(AddrDelta);
+ } else if (isUInt<16>(AddrDelta)) {
+ OS << uint8_t(dwarf::DW_CFA_advance_loc2);
+ OS << uint16_t(AddrDelta);
+ } else {
+ assert(isUInt<32>(AddrDelta));
+ OS << uint8_t(dwarf::DW_CFA_advance_loc4);
+ OS << uint32_t(AddrDelta);
+ }
+}