aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCAssembler.cpp43
-rw-r--r--llvm/lib/MC/MCCodeView.cpp2
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp20
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp10
-rw-r--r--llvm/lib/MC/MCSection.cpp6
5 files changed, 55 insertions, 26 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 8500fd1..5c8e904 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -59,7 +59,8 @@ STATISTIC(EmittedFillFragments,
"Number of emitted assembler fragments - fill");
STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");
STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");
-STATISTIC(evaluateFixup, "Number of evaluated fixups");
+STATISTIC(Fixups, "Number of fixups");
+STATISTIC(FixupEvalForRelax, "Number of fixup evaluations for relaxation");
STATISTIC(ObjectBytes, "Number of emitted object file bytes");
STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
@@ -140,9 +141,9 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
MCValue &Target, uint64_t &Value,
- bool RecordReloc,
- MutableArrayRef<char> Contents) const {
- ++stats::evaluateFixup;
+ bool RecordReloc, uint8_t *Data) const {
+ if (RecordReloc)
+ ++stats::Fixups;
// FIXME: This code has some duplication with recordRelocation. We should
// probably merge the two into a single callback that tries to evaluate a
@@ -185,7 +186,7 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
if (IsResolved && mc::isRelocRelocation(Fixup.getKind()))
IsResolved = false;
- getBackend().applyFixup(F, Fixup, Target, Contents, Value, IsResolved);
+ getBackend().applyFixup(F, Fixup, Target, Data, Value, IsResolved);
return true;
}
@@ -703,21 +704,25 @@ void MCAssembler::layout() {
for (MCFixup &Fixup : F.getFixups()) {
uint64_t FixedValue;
MCValue Target;
+ assert(mc::isRelocRelocation(Fixup.getKind()) ||
+ Fixup.getOffset() <= F.getFixedSize());
+ auto *Data =
+ reinterpret_cast<uint8_t *>(Contents.data() + Fixup.getOffset());
evaluateFixup(F, Fixup, Target, FixedValue,
- /*RecordReloc=*/true, Contents);
+ /*RecordReloc=*/true, Data);
}
- if (F.getVarFixups().size()) {
- // In the variable part, fixup offsets are relative to the fixed part's
- // start. Extend the variable contents to the left to account for the
- // fixed part size.
- Contents = MutableArrayRef(F.getParent()->ContentStorage)
- .slice(F.VarContentStart - Contents.size(), F.getSize());
- for (MCFixup &Fixup : F.getVarFixups()) {
- uint64_t FixedValue;
- MCValue Target;
- evaluateFixup(F, Fixup, Target, FixedValue,
- /*RecordReloc=*/true, Contents);
- }
+ // In the variable part, fixup offsets are relative to the fixed part's
+ // start.
+ for (MCFixup &Fixup : F.getVarFixups()) {
+ uint64_t FixedValue;
+ MCValue Target;
+ assert(mc::isRelocRelocation(Fixup.getKind()) ||
+ (Fixup.getOffset() >= F.getFixedSize() &&
+ Fixup.getOffset() <= F.getSize()));
+ auto *Data = reinterpret_cast<uint8_t *>(
+ F.getVarContents().data() + (Fixup.getOffset() - F.getFixedSize()));
+ evaluateFixup(F, Fixup, Target, FixedValue,
+ /*RecordReloc=*/true, Data);
}
}
}
@@ -735,7 +740,7 @@ void MCAssembler::Finish() {
bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
const MCFixup &Fixup) const {
- assert(getBackendPtr() && "Expected assembler backend");
+ ++stats::FixupEvalForRelax;
MCValue Target;
uint64_t Value;
bool Resolved = evaluateFixup(F, const_cast<MCFixup &>(Fixup), Target, Value,
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 7d528a5..3a5f01c 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -695,5 +695,7 @@ void CodeViewContext::encodeDefRange(const MCAssembler &Asm,
}
Frag.setVarContents(Contents);
+ assert(Fixups.size() < 256 && "Store fixups outside of MCFragment's VarFixup "
+ "storage if the number ever exceeds 256");
Frag.setVarFixups(Fixups);
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 0069d12..393eed1 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -537,6 +537,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
EHFrameSection =
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
+ CallGraphSection = Ctx->getELFSection(".callgraph", ELF::SHT_PROGBITS, 0);
+
StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
PseudoProbeSection = Ctx->getELFSection(".pseudo_probe", DebugSecType, 0);
@@ -1121,6 +1123,24 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
}
MCSection *
+MCObjectFileInfo::getCallGraphSection(const MCSection &TextSec) const {
+ if (Ctx->getObjectFileType() != MCContext::IsELF)
+ return CallGraphSection;
+
+ const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+ unsigned Flags = ELF::SHF_LINK_ORDER;
+ StringRef GroupName;
+ if (const MCSymbol *Group = ElfSec.getGroup()) {
+ GroupName = Group->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+
+ return Ctx->getELFSection(".callgraph", ELF::SHT_PROGBITS, Flags, 0,
+ GroupName, true, ElfSec.getUniqueID(),
+ cast<MCSymbolELF>(TextSec.getBeginSymbol()));
+}
+
+MCSection *
MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
if ((Ctx->getObjectFileType() != MCContext::IsELF) ||
Ctx->getTargetTriple().isPS4())
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index e82393a..200e29a 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -56,9 +56,9 @@ static_assert(FragBlockSize >= sizeof(MCFragment) + NewFragHeadroom);
MCFragment *MCObjectStreamer::allocFragSpace(size_t Headroom) {
auto Size = std::max(FragBlockSize, sizeof(MCFragment) + Headroom);
FragSpace = Size - sizeof(MCFragment);
- auto Chunk = std::unique_ptr<char[]>(new char[Size]);
- auto *F = reinterpret_cast<MCFragment *>(Chunk.get());
- FragStorage.push_back(std::move(Chunk));
+ auto Block = std::unique_ptr<uint8_t[]>(new uint8_t[Size]);
+ auto *F = reinterpret_cast<MCFragment *>(Block.get());
+ FragStorage.push_back(std::move(Block));
return F;
}
@@ -113,9 +113,9 @@ void MCObjectStreamer::appendContents(ArrayRef<char> Contents) {
FragSpace -= Contents.size();
}
-void MCObjectStreamer::appendContents(size_t Num, char Elt) {
+void MCObjectStreamer::appendContents(size_t Num, uint8_t Elt) {
ensureHeadroom(Num);
- MutableArrayRef<char> Data(getCurFragEnd(), Num);
+ MutableArrayRef<uint8_t> Data(getCurFragEnd(), Num);
llvm::fill(Data, Elt);
CurFrag->FixedSize += Num;
FragSpace -= Num;
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 4f28267..27ca131 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -83,12 +83,14 @@ void MCFragment::appendFixups(ArrayRef<MCFixup> Fixups) {
}
void MCFragment::setVarFixups(ArrayRef<MCFixup> Fixups) {
+ assert(Fixups.size() < 256 &&
+ "variable-size tail cannot have more than 256 fixups");
auto &S = getParent()->FixupStorage;
- if (VarFixupStart + Fixups.size() > VarFixupEnd) {
+ if (Fixups.size() > VarFixupSize) {
VarFixupStart = S.size();
S.resize_for_overwrite(S.size() + Fixups.size());
}
- VarFixupEnd = VarFixupStart + Fixups.size();
+ VarFixupSize = Fixups.size();
// Source fixup offsets are relative to the variable part's start. Add the
// fixed part size to make them relative to the fixed part's start.
std::transform(Fixups.begin(), Fixups.end(), S.begin() + VarFixupStart,