diff --git a/llvm/include/llvm/BinaryFormat/SFrame.h b/llvm/include/llvm/BinaryFormat/SFrame.h index 7b58043c60363..095db18b9c254 100644 --- a/llvm/include/llvm/BinaryFormat/SFrame.h +++ b/llvm/include/llvm/BinaryFormat/SFrame.h @@ -117,7 +117,6 @@ template struct FDEInfo { Info = ((PAuthKey & 1) << 5) | ((static_cast(FDE) & 1) << 4) | (static_cast(FRE) & 0xf); } - uint8_t getFuncInfo() const { return Info; } }; template struct FuncDescEntry { @@ -156,7 +155,6 @@ template struct FREInfo { Info = ((RA & 1) << 7) | ((static_cast(Sz) & 3) << 5) | ((N & 0xf) << 1) | (static_cast(Reg) & 1); } - uint8_t getFREInfo() const { return Info; } }; template struct FrameRowEntry { diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index 58363f0b671e2..1625355323692 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -168,7 +168,6 @@ class LLVM_ABI MCAsmBackend { virtual bool relaxAlign(MCFragment &F, unsigned &Size) { return false; } virtual bool relaxDwarfLineAddr(MCFragment &) const { return false; } virtual bool relaxDwarfCFA(MCFragment &) const { return false; } - virtual bool relaxSFrameCFA(MCFragment &) const { return false; } // Defined by linker relaxation targets to possibly emit LEB128 relocations // and set Value at the relocated location. diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 6e1d6421b8d33..1316d8669239d 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -117,7 +117,6 @@ class MCAssembler { void relaxBoundaryAlign(MCBoundaryAlignFragment &BF); void relaxDwarfLineAddr(MCFragment &F); void relaxDwarfCallFrameFragment(MCFragment &F); - void relaxSFrameFragment(MCFragment &DF); public: /// Construct a new assembler instance. diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 1899cb6331c6f..b9e813b9b0d28 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -150,9 +150,6 @@ class MCObjectStreamer : public MCStreamer { MCSymbol *EndLabel = nullptr) override; void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label, SMLoc Loc); - void emitSFrameCalculateFuncOffset(const MCSymbol *FunCabsel, - const MCSymbol *FREBegin, - MCFragment *FDEFrag, SMLoc Loc); void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc) override; diff --git a/llvm/include/llvm/MC/MCSFrame.h b/llvm/include/llvm/MC/MCSFrame.h index 694aec55aefeb..8f182a86d1ab1 100644 --- a/llvm/include/llvm/MC/MCSFrame.h +++ b/llvm/include/llvm/MC/MCSFrame.h @@ -16,14 +16,9 @@ #ifndef LLVM_MC_MCSFRAME_H #define LLVM_MC_MCSFRAME_H -#include "llvm/ADT/SmallVector.h" -#include - namespace llvm { -class MCContext; class MCObjectStreamer; -class MCFragment; class MCSFrameEmitter { public: @@ -31,15 +26,6 @@ class MCSFrameEmitter { // // \param Streamer - Emit into this stream. static void emit(MCObjectStreamer &Streamer); - - // Encode the FRE's function offset. - // - // \param C - Context. - // \param Offset - Offset to encode. - // \param Out - Destination of the encoding. - // \param FDEFrag - Frag that specifies the encoding format. - static void encodeFuncOffset(MCContext &C, uint64_t Offset, - SmallVectorImpl &Out, MCFragment *FDEFrag); }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index a26e6cfb2158a..12389d623e588 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -59,7 +59,6 @@ class MCFragment { FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_SFrame, FT_BoundaryAlign, FT_SymbolId, FT_CVInlineLines, @@ -144,12 +143,6 @@ class MCFragment { // .loc dwarf directives. int64_t LineDelta; } dwarf; - struct { - // This FRE describes unwind info at AddrDelta from function start. - const MCExpr *AddrDelta; - // Fragment that records how many bytes of AddrDelta to emit. - MCFragment *FDEFragment; - } sframe; } u{}; public: @@ -303,24 +296,6 @@ class MCFragment { assert(Kind == FT_Dwarf); u.dwarf.LineDelta = LineDelta; } - - //== FT_SFrame functions - const MCExpr &getSFrameAddrDelta() const { - assert(Kind == FT_SFrame); - return *u.sframe.AddrDelta; - } - void setSFrameAddrDelta(const MCExpr *E) { - assert(Kind == FT_SFrame); - u.sframe.AddrDelta = E; - } - MCFragment *getSFrameFDE() const { - assert(Kind == FT_SFrame); - return u.sframe.FDEFragment; - } - void setSFrameFDE(MCFragment *F) { - assert(Kind == FT_SFrame); - u.sframe.FDEFragment = F; - } }; // MCFragment subclasses do not use the fixed-size part or variable-size tail of diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index cee281597cfed..b1031d7822604 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -22,7 +22,6 @@ #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSFrame.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" @@ -200,7 +199,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const { case MCFragment::FT_LEB: case MCFragment::FT_Dwarf: case MCFragment::FT_DwarfFrame: - case MCFragment::FT_SFrame: case MCFragment::FT_CVInlineLines: case MCFragment::FT_CVDefRange: return F.getSize(); @@ -401,7 +399,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, case MCFragment::FT_LEB: case MCFragment::FT_Dwarf: case MCFragment::FT_DwarfFrame: - case MCFragment::FT_SFrame: case MCFragment::FT_CVInlineLines: case MCFragment::FT_CVDefRange: { if (F.getKind() == MCFragment::FT_Data) @@ -917,24 +914,6 @@ void MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) { F.clearVarFixups(); } -void MCAssembler::relaxSFrameFragment(MCFragment &F) { - assert(F.getKind() == MCFragment::FT_SFrame); - MCContext &C = getContext(); - int64_t Value; - bool Abs = F.getSFrameAddrDelta().evaluateAsAbsolute(Value, *this); - if (!Abs) { - C.reportError(F.getSFrameAddrDelta().getLoc(), - "invalid CFI advance_loc expression in sframe"); - F.setSFrameAddrDelta(MCConstantExpr::create(0, C)); - return; - } - - SmallVector Data; - MCSFrameEmitter::encodeFuncOffset(Context, Value, Data, F.getSFrameFDE()); - F.setVarContents(Data); - F.clearVarFixups(); -} - bool MCAssembler::relaxFragment(MCFragment &F) { auto Size = computeFragmentSize(F); switch (F.getKind()) { @@ -953,9 +932,6 @@ bool MCAssembler::relaxFragment(MCFragment &F) { case MCFragment::FT_DwarfFrame: relaxDwarfCallFrameFragment(F); break; - case MCFragment::FT_SFrame: - relaxSFrameFragment(F); - break; case MCFragment::FT_BoundaryAlign: relaxBoundaryAlign(static_cast(F)); break; diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp index 85d1c5888f1da..21da79bb0aa30 100644 --- a/llvm/lib/MC/MCFragment.cpp +++ b/llvm/lib/MC/MCFragment.cpp @@ -53,7 +53,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { case MCFragment::FT_Org: OS << "Org"; break; case MCFragment::FT_Dwarf: OS << "Dwarf"; break; case MCFragment::FT_DwarfFrame: OS << "DwarfCallFrame"; break; - case MCFragment::FT_SFrame: OS << "SFrame"; break; case MCFragment::FT_LEB: OS << "LEB"; break; case MCFragment::FT_BoundaryAlign: OS<<"BoundaryAlign"; break; case MCFragment::FT_SymbolId: OS << "SymbolId"; break; @@ -80,8 +79,7 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { case MCFragment::FT_Align: case MCFragment::FT_LEB: case MCFragment::FT_Dwarf: - case MCFragment::FT_DwarfFrame: - case MCFragment::FT_SFrame: { + case MCFragment::FT_DwarfFrame: { if (isLinkerRelaxable()) OS << " LinkerRelaxable"; auto Fixed = getContents(); @@ -131,7 +129,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { OS << " LineDelta:" << getDwarfLineDelta(); break; case MCFragment::FT_DwarfFrame: - case MCFragment::FT_SFrame: OS << " AddrDelta:"; getDwarfAddrDelta().print(OS, nullptr); break; diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 701a0836d2c70..59265bc8595ba 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -583,19 +583,6 @@ void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, newFragment(); } -void MCObjectStreamer::emitSFrameCalculateFuncOffset(const MCSymbol *FuncBase, - const MCSymbol *FREBegin, - MCFragment *FDEFrag, - SMLoc Loc) { - assert(FuncBase && "No function base address"); - assert(FREBegin && "FRE doesn't describe a location"); - auto *F = getCurrentFragment(); - F->Kind = MCFragment::FT_SFrame; - F->setSFrameAddrDelta(buildSymbolDiff(*this, FREBegin, FuncBase, Loc)); - F->setSFrameFDE(FDEFrag); - newFragment(); -} - void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, diff --git a/llvm/lib/MC/MCSFrame.cpp b/llvm/lib/MC/MCSFrame.cpp index e8252d4d76b61..a0d6c80ab72ea 100644 --- a/llvm/lib/MC/MCSFrame.cpp +++ b/llvm/lib/MC/MCSFrame.cpp @@ -14,7 +14,6 @@ #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" using namespace llvm; @@ -34,70 +33,10 @@ struct SFrameFRE { size_t CFAOffset = 0; size_t FPOffset = 0; size_t RAOffset = 0; - FREInfo Info; + bool FromFP = false; bool CFARegSet = false; SFrameFRE(const MCSymbol *Start) : Label(Start) {} - - void emitOffset(MCObjectStreamer &S, FREOffset OffsetSize, size_t Offset) { - switch (OffsetSize) { - case (FREOffset::B1): - S.emitInt8(Offset); - return; - case (FREOffset::B2): - S.emitInt16(Offset); - return; - case (FREOffset::B4): - S.emitInt32(Offset); - return; - } - } - - void emit(MCObjectStreamer &S, const MCSymbol *FuncBegin, - MCFragment *FDEFrag) { - S.emitSFrameCalculateFuncOffset(FuncBegin, Label, FDEFrag, SMLoc()); - - // fre_cfa_base_reg_id already set during parsing - - // fre_offset_count - unsigned RegsTracked = 1; // always track the cfa. - if (FPOffset != 0) - RegsTracked++; - if (RAOffset != 0) - RegsTracked++; - Info.setOffsetCount(RegsTracked); - - // fre_offset_size - if (isInt<8>(CFAOffset) && isInt<8>(FPOffset) && isInt<8>(RAOffset)) - Info.setOffsetSize(FREOffset::B1); - else if (isInt<16>(CFAOffset) && isInt<16>(FPOffset) && isInt<16>(RAOffset)) - Info.setOffsetSize(FREOffset::B2); - else { - assert(isInt<32>(CFAOffset) && isInt<32>(FPOffset) && - isInt<32>(RAOffset) && "Offset too big for sframe"); - Info.setOffsetSize(FREOffset::B4); - } - - // No support for fre_mangled_ra_p yet. - Info.setReturnAddressSigned(false); - - // sframe_fre_info_word - S.emitInt8(Info.getFREInfo()); - - // FRE Offsets - [[maybe_unused]] unsigned OffsetsEmitted = 1; - emitOffset(S, Info.getOffsetSize(), CFAOffset); - if (FPOffset) { - OffsetsEmitted++; - emitOffset(S, Info.getOffsetSize(), FPOffset); - } - if (RAOffset) { - OffsetsEmitted++; - emitOffset(S, Info.getOffsetSize(), RAOffset); - } - assert(OffsetsEmitted == RegsTracked && - "Didn't emit the right number of offsets"); - } }; // High-level structure to track info needed to emit a sframe_func_desc_entry @@ -107,13 +46,11 @@ struct SFrameFDE { const MCDwarfFrameInfo &DFrame; // Label where this FDE's FREs start. MCSymbol *FREStart; - // Frag where this FDE is emitted. - MCFragment *Frag; // Unwinding fres SmallVector FREs; SFrameFDE(const MCDwarfFrameInfo &DF, MCSymbol *FRES) - : DFrame(DF), FREStart(FRES), Frag(nullptr) {} + : DFrame(DF), FREStart(FRES) {} void emit(MCObjectStreamer &S, const MCSymbol *FRESubSectionStart) { MCContext &C = S.getContext(); @@ -137,21 +74,13 @@ struct SFrameFDE { S.emitInt32(0); // sfde_func_num_fres - S.emitInt32(FREs.size()); + // TODO: When we actually emit fres, replace 0 with FREs.size() + S.emitInt32(0); // sfde_func_info word - - // All FREs within an FDE share the same sframe::FREType::AddrX. The value - // of 'X' is determined by the FRE with the largest offset, which is the - // last. This offset isn't known until relax time, so emit a frag which can - // calculate that now. - // - // At relax time, this FDE frag calculates the proper AddrX value (as well - // as the rest of the FDE FuncInfo word). Subsequent FRE frags will read it - // from this frag and emit the proper number of bytes. - Frag = S.getCurrentFragment(); - S.emitSFrameCalculateFuncOffset(DFrame.Begin, FREs.back().Label, nullptr, - SMLoc()); + FDEInfo I; + I.setFuncInfo(0 /* No pauth key */, FDEType::PCInc, FREType::Addr1); + S.emitInt8(I.Info); // sfde_func_rep_size. Not relevant in non-PCMASK fdes. S.emitInt8(0); @@ -167,16 +96,13 @@ struct SFrameFDE { class SFrameEmitterImpl { MCObjectStreamer &Streamer; SmallVector FDEs; - uint32_t TotalFREs; ABI SFrameABI; // Target-specific convenience variables to detect when a CFI instruction // references these registers. Unlike in dwarf frame descriptions, they never - // escape into the sframe section itself. TODO: These should be retrieved from - // the target. + // escape into the sframe section itself. unsigned SPReg; unsigned FPReg; unsigned RAReg; - int8_t FixedRAOffset; MCSymbol *FDESubSectionStart; MCSymbol *FRESubSectionStart; MCSymbol *FRESubSectionEnd; @@ -184,12 +110,12 @@ class SFrameEmitterImpl { bool setCFARegister(SFrameFRE &FRE, const MCCFIInstruction &I) { if (I.getRegister() == SPReg) { FRE.CFARegSet = true; - FRE.Info.setBaseRegister(BaseReg::SP); + FRE.FromFP = false; return true; } if (I.getRegister() == FPReg) { FRE.CFARegSet = true; - FRE.Info.setBaseRegister(BaseReg::FP); + FRE.FromFP = true; return true; } Streamer.getContext().reportWarning( @@ -256,8 +182,7 @@ class SFrameEmitterImpl { } public: - SFrameEmitterImpl(MCObjectStreamer &Streamer) - : Streamer(Streamer), TotalFREs(0) { + SFrameEmitterImpl(MCObjectStreamer &Streamer) : Streamer(Streamer) { assert(Streamer.getContext() .getObjectFileInfo() ->getSFrameABIArch() @@ -270,7 +195,6 @@ class SFrameEmitterImpl { SPReg = 31; RAReg = 29; FPReg = 30; - FixedRAOffset = 0; break; case ABI::AMD64EndianLittle: SPReg = 7; @@ -278,7 +202,6 @@ class SFrameEmitterImpl { // MCDwarfFrameInfo constructor. RAReg = static_cast(INT_MAX); FPReg = 6; - FixedRAOffset = -8; break; } @@ -296,16 +219,10 @@ class SFrameEmitterImpl { bool equalIgnoringLocation(const SFrameFRE &Left, const SFrameFRE &Right) { return Left.CFAOffset == Right.CFAOffset && Left.FPOffset == Right.FPOffset && Left.RAOffset == Right.RAOffset && - Left.Info.getFREInfo() == Right.Info.getFREInfo() && - Left.CFARegSet == Right.CFARegSet; + Left.FromFP == Right.FromFP && Left.CFARegSet == Right.CFARegSet; } void buildSFDE(const MCDwarfFrameInfo &DF) { - // Functions with zero size can happen with assembler macros and - // machine-generated code. They don't need unwind info at all, so - // no need to warn. - if (atSameLocation(DF.Begin, DF.End)) - return; bool Valid = true; SFrameFDE FDE(DF, Streamer.getContext().createTempSymbol()); // This would have been set via ".cfi_return_column", but @@ -360,11 +277,8 @@ class SFrameEmitterImpl { LastLabel = L; } } - - if (Valid) { + if (Valid) FDEs.push_back(FDE); - TotalFREs += FDE.FREs.size(); - } } void emitPreamble() { @@ -380,12 +294,13 @@ class SFrameEmitterImpl { // sfh_cfa_fixed_fp_offset Streamer.emitInt8(0); // sfh_cfa_fixed_ra_offset - Streamer.emitInt8(FixedRAOffset); + Streamer.emitInt8(0); // sfh_auxhdr_len Streamer.emitInt8(0); // shf_num_fdes Streamer.emitInt32(FDEs.size()); // shf_num_fres + uint32_t TotalFREs = 0; Streamer.emitInt32(TotalFREs); // shf_fre_len @@ -407,11 +322,8 @@ class SFrameEmitterImpl { void emitFREs() { Streamer.emitLabel(FRESubSectionStart); - for (auto &FDE : FDEs) { + for (auto &FDE : FDEs) Streamer.emitLabel(FDE.FREStart); - for (auto &FRE : FDE.FREs) - FRE.emit(Streamer, FDE.DFrame.Begin, FDE.Frag); - } Streamer.emitLabel(FRESubSectionEnd); } }; @@ -447,55 +359,3 @@ void MCSFrameEmitter::emit(MCObjectStreamer &Streamer) { Emitter.emitFDEs(); Emitter.emitFREs(); } - -void MCSFrameEmitter::encodeFuncOffset(MCContext &C, uint64_t Offset, - SmallVectorImpl &Out, - MCFragment *FDEFrag) { - // If encoding into the FDE Frag itself, generate the sfde_func_info. - if (FDEFrag == nullptr) { - // sfde_func_info - - // Offset is the difference between the function start label and the final - // FRE's offset, which is the max offset for this FDE. - FDEInfo I; - I.Info = 0; - if (isUInt<8>(Offset)) - I.setFREType(FREType::Addr1); - else if (isUInt<16>(Offset)) - I.setFREType(FREType::Addr2); - else { - assert(isUInt<32>(Offset)); - I.setFREType(FREType::Addr4); - } - I.setFDEType(FDEType::PCInc); - // TODO: When we support pauth keys, this will need to be retrieved - // from the frag itself. - I.setPAuthKey(0); - - Out.push_back(I.getFuncInfo()); - return; - } - - const auto &FDEData = FDEFrag->getVarContents(); - FDEInfo I; - I.Info = FDEData.back(); - FREType T = I.getFREType(); - llvm::endianness E = C.getAsmInfo()->isLittleEndian() - ? llvm::endianness::little - : llvm::endianness::big; - // sfre_start_address - switch (T) { - case FREType::Addr1: - assert(isUInt<8>(Offset) && "Miscalculated Sframe FREType"); - support::endian::write(Out, Offset, E); - break; - case FREType::Addr2: - assert(isUInt<16>(Offset) && "Miscalculated Sframe FREType"); - support::endian::write(Out, Offset, E); - break; - case FREType::Addr4: - assert(isUInt<32>(Offset) && "Miscalculated Sframe FREType"); - support::endian::write(Out, Offset, E); - break; - } -} diff --git a/llvm/test/MC/ELF/cfi-sframe-encoding.s b/llvm/test/MC/ELF/cfi-sframe-encoding.s deleted file mode 100644 index e13e11c51c05a..0000000000000 --- a/llvm/test/MC/ELF/cfi-sframe-encoding.s +++ /dev/null @@ -1,87 +0,0 @@ -// TODO: Add other architectures as they gain sframe support -// REQUIRES: x86-registered-target -// RUN: llvm-mc --assemble --filetype=obj --gsframe -triple x86_64 %s -o %t.o -// RUN: llvm-readelf --sframe %t.o | FileCheck %s - -// Tests selection for the proper FDE AddrX encoding at the boundaries -// between uint8_t, uint16_t, and uint32_t. The first FRE always fits -// anywhere, because its address-offset is zero. The last FRE -// determines the smallest AddrX it is possible to use. Align -// functions to 1024 to make it easier to interpet offsets. - - .cfi_sections .sframe - - .align 1024 -fde0_uses_addr1: -// CHECK: FuncDescEntry [0] { -// CHECK: Start FRE Offset: 0x0 -// CHECK-NEXT: Num FREs: 2 -// CHECK: FRE Type: Addr1 (0x0) - .cfi_startproc -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x0 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 8 -// CHECK-NEXT: RA Offset: -8 -// CHECK-NEXT: } - .fill 0xFF - .cfi_def_cfa_offset 16 -// CHECK-NEXT: Frame Row Entry { -// CHECK-NEXT: Start Address: 0xFF -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 16 -// CHECK-NEXT: RA Offset: -8 - nop - .cfi_endproc - - .align 1024 -fde1_uses_addr2: -// CHECK: FuncDescEntry [1] { -// CHECK: Start FRE Offset: 0x6 -// CHECK-NEXT: Num FREs: 2 -// CHECK: FRE Type: Addr2 (0x1) - .cfi_startproc -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x400 - .fill 0xFF + 1 - .cfi_def_cfa_offset 16 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x500 - .cfi_endproc - -.align 1024 -fde2_uses_addr2: -// CHECK: FuncDescEntry [2] { -// CHECK: Start FRE Offset: 0xE -// CHECK-NEXT: Num FREs: 2 -// CHECK: FRE Type: Addr2 (0x1) - .cfi_startproc -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x800 - .fill 0xFFFF - .cfi_def_cfa_offset 16 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x107FF - nop - .cfi_endproc - - .align 1024 -fde3_uses_addr4: -// CHECK: FuncDescEntry [3] { -// CHECK: Start FRE Offset: 0x16 -// CHECK-NEXT: Num FREs: 2 -// CHECK: FRE Type: Addr4 (0x2) - .cfi_startproc -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x10800 - .fill 0xFFFF + 1 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x20800 - .cfi_def_cfa_offset 16 - nop - .cfi_endproc - diff --git a/llvm/test/MC/ELF/cfi-sframe-fre-cases.s b/llvm/test/MC/ELF/cfi-sframe-fre-cases.s deleted file mode 100644 index 61ed58f8a9d0e..0000000000000 --- a/llvm/test/MC/ELF/cfi-sframe-fre-cases.s +++ /dev/null @@ -1,114 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: llvm-mc --assemble --filetype=obj --gsframe -triple x86_64 %s -o %t.o -// RUN: llvm-readelf --sframe %t.o | FileCheck %s - -// Tests selection for the proper FRE::BX encoding at the boundaries -// between int8_t, int16_t, and int32_t. Ensures the largest offset -// between CFA, RA, and FP governs. Align functions to 1024 to make it -// easier to interpet offsets. Some directives require alignment, so -// it isn't always possible to test exact boundaries. - -// Also, check that irrelevant cfi directives don't create new fres, -// or affect the current ones. Checking the Start Address ensures that -// the proper FRE gets the proper checks. Using .long makes addresses -// architecture independent. - - .align 1024 -fde4_fre_offset_sizes: -// CHECK: FuncDescEntry [0] { -// CHECK: Start FRE Offset: 0 -// CHECK: FRE Type: Addr1 (0x0) - .cfi_startproc -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x0 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 8 -// CHECK-NEXT: RA Offset: -8 - .long 0 -// Uninteresting register no new fre, no effect on cfa - .cfi_offset 0, 8 - .long 0 - .cfi_def_cfa_offset 0x78 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x8 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 120 -// CHECK-NEXT: RA Offset: -8 - .long 0 -// Uninteresting register no new fre, no effect on cfa - .cfi_rel_offset 1, 8 - .long 0 - .cfi_def_cfa_offset 0x80 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x10 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B2 (0x1) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 128 -// CHECK-NEXT: RA Offset: -8 - .long 0 -// Uninteresting register no new fre, no effect on cfa - .cfi_val_offset 1, 8 - .long 0 - .cfi_def_cfa_offset 0x7FFF -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x18 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B2 (0x1) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 32767 -// CHECK-NEXT: RA Offset: -8 - .long 0 - .cfi_def_cfa_offset 0x8000 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x1C -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B4 (0x2) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 32768 -// CHECK-NEXT: RA Offset: -8 - .long 0 - .cfi_def_cfa_offset 0x8 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x20 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 8 -// CHECK-NEXT: RA Offset: -8 - .long 0 - .cfi_adjust_cfa_offset 0x8 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x24 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: SP (0x1) -// CHECK-NEXT: CFA Offset: 16 -// CHECK-NEXT: RA Offset: -8 - .long 0 - .cfi_def_cfa_register 6 # switch to fp -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x28 -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B1 (0x0) -// CHECK-NEXT: Base Register: FP (0x0) -// CHECK-NEXT: CFA Offset: 16 -// CHECK-NEXT: RA Offset: -8 - .long 0 - .cfi_offset 7, 32 - # sp not the cfa but with large offset still changes encoding. - .cfi_offset 6, 0x7FF8 -// CHECK: Frame Row Entry { -// CHECK-NEXT: Start Address: 0x2C -// CHECK-NEXT: Return Address Signed: No -// CHECK-NEXT: Offset Size: B2 (0x1) -// CHECK-NEXT: Base Register: FP (0x0) -// CHECK-NEXT: CFA Offset: 16 -// CHECK-NEXT: RA Offset: -8 -// CHECK-NEXT: FP Offset: 32760 - .long 0 - .cfi_endproc diff --git a/llvm/test/MC/ELF/cfi-sframe.s b/llvm/test/MC/ELF/cfi-sframe.s index 28ee3cbf33b16..ecf77bc3ea6b3 100644 --- a/llvm/test/MC/ELF/cfi-sframe.s +++ b/llvm/test/MC/ELF/cfi-sframe.s @@ -4,35 +4,27 @@ // RUN: llvm-readelf --sframe %t.o | FileCheck %s .cfi_sections .sframe -f0: - .cfi_startproc # FRE 0 +f1: + .cfi_startproc // FRE 0 nop - .cfi_def_cfa_offset 16 # FRE 1 - .cfi_def_cfa_offset 8 # location didn't change. No new FRE, but new offset. + .cfi_def_cfa_offset 16 // FRE 1 + .cfi_def_cfa_offset 8 // location didn't change. No new FRE, but new offset. nop - .cfi_def_cfa_offset 8 # offset didn't change. No new FRE. + .cfi_def_cfa_offset 8 // offset didn't change. No new FRE. nop - .cfi_def_cfa_offset 16 # FRE 2. new location, new offset. + .cfi_def_cfa_offset 16 // FRE 2. new location, new offset. nop - .cfi_register 0, 1 # Uninteresting register. No new FRE. + .cfi_register 0, 1 // Uninteresting register. No new FRE. nop .cfi_endproc -f1: +f2: .cfi_startproc nop nop .cfi_endproc -f2: - .cfi_startproc - .cfi_endproc - -f3: - .cfi_startproc simple - .cfi_endproc - // CHECK: SFrame section '.sframe' { // CHECK-NEXT: Header { // CHECK-NEXT: Magic: 0xDEE2 @@ -40,11 +32,11 @@ f3: // CHECK-NEXT: Flags [ (0x4) // CHECK: ABI: AMD64EndianLittle (0x3) // CHECK-NEXT: CFA fixed FP offset (unused): 0 -// CHECK-NEXT: CFA fixed RA offset: -8 +// CHECK-NEXT: CFA fixed RA offset: 0 // CHECK-NEXT: Auxiliary header length: 0 // CHECK-NEXT: Num FDEs: 2 -// CHECK-NEXT: Num FREs: 4 -// CHECK-NEXT: FRE subsection length: 12 +// CHECK-NEXT: Num FREs: 0 +// CHECK-NEXT: FRE subsection length: 0 // CHECK-NEXT: FDE subsection offset: 0 // CHECK-NEXT: FRE subsection offset: 40 // CHECK: Function Index [ @@ -56,7 +48,7 @@ f3: // CHECK-NEXT: } // CHECK-NEXT: Size: 0x5 // CHECK-NEXT: Start FRE Offset: 0x0 -// CHECK-NEXT: Num FREs: 3 +// CHECK-NEXT: Num FREs: 0 // CHECK-NEXT: Info { // CHECK-NEXT: FRE Type: Addr1 (0x0) // CHECK-NEXT: FDE Type: PCInc (0x0) @@ -64,18 +56,18 @@ f3: // CHECK-NEXT: } // CHECK-NEXT: Repetitive block size (unused): 0x0 // CHECK-NEXT: Padding2: 0x0 - -// Contents of FREs are tested elsewhere - -// CHECK: FuncDescEntry [1] { +// CHECK-NEXT: FREs [ +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: FuncDescEntry [1] { // CHECK-NEXT: PC { // CHECK-NEXT: Relocation: {{.*}}PC32{{.*}} // CHECK-NEXT: Symbol Name: .text // CHECK-NEXT: Start Address: {{.*}} // CHECK-NEXT: } // CHECK-NEXT: Size: 0x2 -// CHECK-NEXT: Start FRE Offset: 0x9 -// CHECK-NEXT: Num FREs: 1 +// CHECK-NEXT: Start FRE Offset: 0x0 +// CHECK-NEXT: Num FREs: 0 // CHECK-NEXT: Info { // CHECK-NEXT: FRE Type: Addr1 (0x0) // CHECK-NEXT: FDE Type: PCInc (0x0) @@ -83,5 +75,8 @@ f3: // CHECK-NEXT: } // CHECK-NEXT: Repetitive block size (unused): 0x0 // CHECK-NEXT: Padding2: 0x0 - - +// CHECK-NEXT: FREs [ +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }