MCStreamer: Add helpers and eliminate direct MCFragment operations
To facilitate optimizing the MCFragment internals, we don't want users to access MCFragment directly.
This commit is contained in:
parent
6ebc42322c
commit
63b9cbd6e4
@ -83,10 +83,12 @@ public:
|
||||
// Add a fragment with a variable-size tail and start a new empty fragment.
|
||||
void insert(MCFragment *F);
|
||||
|
||||
void addFixup(const MCExpr *Value, MCFixupKind Kind, uint32_t Offset = 0);
|
||||
// Add a new fragment to the current section without a variable-size tail.
|
||||
void newFragment();
|
||||
|
||||
void appendContents(size_t Num, char Elt);
|
||||
void addFixup(const MCExpr *Value, MCFixupKind Kind);
|
||||
|
||||
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
|
||||
virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F,
|
||||
uint64_t Offset);
|
||||
|
@ -438,6 +438,7 @@ public:
|
||||
assert(!CurFrag || CurFrag->getKind() == MCFragment::FT_Data);
|
||||
return CurFrag;
|
||||
}
|
||||
size_t getCurFragOffset() const { return getCurrentFragment()->Offset; }
|
||||
/// Save the current and previous section on the section stack.
|
||||
void pushSection() {
|
||||
SectionStack.push_back(
|
||||
|
@ -58,10 +58,12 @@ void MCObjectStreamer::insert(MCFragment *F) {
|
||||
newFragment();
|
||||
}
|
||||
|
||||
void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind,
|
||||
uint32_t Offset) {
|
||||
CurFrag->addFixup(
|
||||
MCFixup::create(CurFrag->getFixedSize() + Offset, Value, Kind));
|
||||
void MCObjectStreamer::appendContents(size_t Num, char Elt) {
|
||||
CurFrag->appendContents(Num, Elt);
|
||||
}
|
||||
|
||||
void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind) {
|
||||
CurFrag->addFixup(MCFixup::create(CurFrag->getFixedSize(), Value, Kind));
|
||||
}
|
||||
|
||||
// As a compile-time optimization, avoid allocating and evaluating an MCExpr
|
||||
|
@ -318,15 +318,13 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
|
||||
|
||||
// Emit the epilog instructions.
|
||||
if (EnableUnwindV2) {
|
||||
MCFragment *DF = OS->getCurrentFragment();
|
||||
|
||||
bool IsLast = true;
|
||||
for (const auto &Epilog : llvm::reverse(info->EpilogMap)) {
|
||||
if (IsLast) {
|
||||
IsLast = false;
|
||||
uint8_t Flags = LastEpilogIsAtEnd ? 0x01 : 0;
|
||||
streamer.emitInt8(EpilogSize);
|
||||
streamer.emitInt8((Flags << 4) | Win64EH::UOP_Epilog);
|
||||
OS->emitInt8(EpilogSize);
|
||||
OS->emitInt8((Flags << 4) | Win64EH::UOP_Epilog);
|
||||
|
||||
if (LastEpilogIsAtEnd)
|
||||
continue;
|
||||
@ -337,9 +335,8 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
|
||||
// layout has been completed.
|
||||
auto *MCE = MCUnwindV2EpilogTargetExpr::create(*info, Epilog.second,
|
||||
EpilogSize, context);
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_2);
|
||||
DF->addFixup(Fixup);
|
||||
DF->appendContents(2, 0);
|
||||
OS->addFixup(MCE, FK_Data_2);
|
||||
OS->appendContents(2, 0);
|
||||
}
|
||||
}
|
||||
if (AddPaddingEpilogCode)
|
||||
|
@ -278,35 +278,28 @@ void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
|
||||
|
||||
void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCFragment *DF = getCurrentFragment();
|
||||
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
|
||||
DF->addFixup(Fixup);
|
||||
DF->appendContents(2, 0);
|
||||
addFixup(SRE, FK_SecRel_2);
|
||||
appendContents(2, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
|
||||
uint64_t Offset) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCFragment *DF = getCurrentFragment();
|
||||
// Create Symbol A for the relocation relative reference.
|
||||
const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
|
||||
// Add the constant offset, if given.
|
||||
if (Offset)
|
||||
MCE = MCBinaryExpr::createAdd(
|
||||
MCE, MCConstantExpr::create(Offset, getContext()), getContext());
|
||||
// Build the secrel32 relocation.
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
|
||||
// Record the relocation.
|
||||
DF->addFixup(Fixup);
|
||||
addFixup(MCE, FK_SecRel_4);
|
||||
// Emit 4 bytes (zeros) to the object file.
|
||||
DF->appendContents(4, 0);
|
||||
appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
|
||||
int64_t Offset) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCFragment *DF = getCurrentFragment();
|
||||
// Create Symbol A for the relocation relative reference.
|
||||
const MCExpr *MCE = MCSymbolRefExpr::create(
|
||||
Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
|
||||
@ -314,40 +307,29 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
|
||||
if (Offset)
|
||||
MCE = MCBinaryExpr::createAdd(
|
||||
MCE, MCConstantExpr::create(Offset, getContext()), getContext());
|
||||
// Build the imgrel relocation.
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
|
||||
// Record the relocation.
|
||||
DF->addFixup(Fixup);
|
||||
addFixup(MCE, FK_Data_4);
|
||||
// Emit 4 bytes (zeros) to the object file.
|
||||
DF->appendContents(4, 0);
|
||||
appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCFragment *DF = getCurrentFragment();
|
||||
// Create Symbol for section number.
|
||||
const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create(
|
||||
*Symbol, this->getWriter(), getContext());
|
||||
// Build the relocation.
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
|
||||
// Record the relocation.
|
||||
DF->addFixup(Fixup);
|
||||
addFixup(MCE, FK_Data_4);
|
||||
// Emit 4 bytes (zeros) to the object file.
|
||||
DF->appendContents(4, 0);
|
||||
appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCFragment *DF = getCurrentFragment();
|
||||
// Create Symbol for section offset.
|
||||
const MCExpr *MCE =
|
||||
MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext());
|
||||
// Build the relocation.
|
||||
MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
|
||||
// Record the relocation.
|
||||
DF->addFixup(Fixup);
|
||||
addFixup(MCE, FK_Data_4);
|
||||
// Emit 4 bytes (zeros) to the object file.
|
||||
DF->appendContents(4, 0);
|
||||
appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
|
||||
|
@ -1033,45 +1033,40 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitGPRel32Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_GPREL32));
|
||||
DF->appendContents(4, 0);
|
||||
auto &S = getStreamer();
|
||||
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
|
||||
S.appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_GPREL32));
|
||||
DF->appendContents(8, 0);
|
||||
auto &S = getStreamer();
|
||||
// fixup_Mips_GPREL32 desginates R_MIPS_GPREL32+R_MIPS_64 on MIPS64.
|
||||
S.addFixup(Value, Mips::fixup_Mips_GPREL32);
|
||||
S.appendContents(8, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDTPRel32Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_DTPREL32));
|
||||
DF->appendContents(4, 0);
|
||||
auto &S = getStreamer();
|
||||
S.addFixup(Value, Mips::fixup_Mips_DTPREL32);
|
||||
S.appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDTPRel64Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_DTPREL64));
|
||||
DF->appendContents(8, 0);
|
||||
auto &S = getStreamer();
|
||||
S.addFixup(Value, Mips::fixup_Mips_DTPREL64);
|
||||
S.appendContents(8, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitTPRel32Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_TPREL32));
|
||||
DF->appendContents(4, 0);
|
||||
auto &S = getStreamer();
|
||||
S.addFixup(Value, Mips::fixup_Mips_TPREL32);
|
||||
S.appendContents(4, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitTPRel64Value(const MCExpr *Value) {
|
||||
MCFragment *DF = getStreamer().getCurrentFragment();
|
||||
DF->addFixup(MCFixup::create(DF->getContents().size(), Value,
|
||||
Mips::fixup_Mips_TPREL64));
|
||||
DF->appendContents(8, 0);
|
||||
auto &S = getStreamer();
|
||||
S.addFixup(Value, Mips::fixup_Mips_TPREL64);
|
||||
S.appendContents(8, 0);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user