aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp112
1 files changed, 68 insertions, 44 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
index 357654615e00..354de8fd7b4b 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
@@ -16,8 +16,11 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbolMachO.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -135,44 +138,41 @@ void ARMMachObjectWriter::recordARMScatteredHalfRelocation(
uint32_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
if (FixupOffset & 0xff000000) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "can not encode offset '0x" +
- utohexstr(FixupOffset) +
- "' in resulting scattered relocation.");
+ reportError(Fixup.getLoc(), "can not encode offset '0x" +
+ utohexstr(FixupOffset) +
+ "' in resulting scattered relocation.");
return;
}
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
+ unsigned IsPCRel = Fixup.isPCRel();
unsigned Type = MachO::ARM_RELOC_HALF;
// See <reloc.h>.
- const MCSymbol *A = &Target.getSymA()->getSymbol();
+ const MCSymbol *A = Target.getAddSym();
if (!A->getFragment()) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "symbol '" + A->getName() +
- "' can not be undefined in a subtraction expression");
+ reportError(Fixup.getLoc(),
+ "symbol '" + A->getName() +
+ "' can not be undefined in a subtraction expression");
return;
}
- uint32_t Value = Writer->getSymbolAddress(*A, Asm);
+ uint32_t Value = Writer->getSymbolAddress(*A);
uint32_t Value2 = 0;
uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent());
FixedValue += SecAddr;
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
- const MCSymbol *SB = &B->getSymbol();
-
+ if (const MCSymbol *SB = Target.getSubSym()) {
if (!SB->getFragment()) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "symbol '" + B->getSymbol().getName() +
- "' can not be undefined in a subtraction expression");
+ reportError(Fixup.getLoc(),
+ "symbol '" + SB->getName() +
+ "' can not be undefined in a subtraction expression");
return;
}
// Select the appropriate difference relocation type.
Type = MachO::ARM_RELOC_HALF_SECTDIFF;
- Value2 = Writer->getSymbolAddress(B->getSymbol(), Asm);
+ Value2 = Writer->getSymbolAddress(*SB);
FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent());
}
@@ -192,7 +192,7 @@ void ARMMachObjectWriter::recordARMScatteredHalfRelocation(
// relocation entry in the low 16 bits of r_address field.
unsigned ThumbBit = 0;
unsigned MovtBit = 0;
- switch (Fixup.getTargetKind()) {
+ switch (Fixup.getKind()) {
default: break;
case ARM::fixup_arm_movt_hi16:
MovtBit = 1;
@@ -245,44 +245,42 @@ void ARMMachObjectWriter::recordARMScatteredRelocation(
uint32_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
if (FixupOffset & 0xff000000) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "can not encode offset '0x" +
- utohexstr(FixupOffset) +
- "' in resulting scattered relocation.");
+ reportError(Fixup.getLoc(), "can not encode offset '0x" +
+ utohexstr(FixupOffset) +
+ "' in resulting scattered relocation.");
return;
}
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
+ unsigned IsPCRel = Fixup.isPCRel();
// See <reloc.h>.
- const MCSymbol *A = &Target.getSymA()->getSymbol();
+ const MCSymbol *A = Target.getAddSym();
if (!A->getFragment()) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "symbol '" + A->getName() +
- "' can not be undefined in a subtraction expression");
+ reportError(Fixup.getLoc(),
+ "symbol '" + A->getName() +
+ "' can not be undefined in a subtraction expression");
return;
}
- uint32_t Value = Writer->getSymbolAddress(*A, Asm);
+ uint32_t Value = Writer->getSymbolAddress(*A);
uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent());
FixedValue += SecAddr;
uint32_t Value2 = 0;
- if (const MCSymbolRefExpr *B = Target.getSymB()) {
+ if (const MCSymbol *SB = Target.getSubSym()) {
assert(Type == MachO::ARM_RELOC_VANILLA && "invalid reloc for 2 symbols");
- const MCSymbol *SB = &B->getSymbol();
if (!SB->getFragment()) {
- Asm.getContext().reportError(Fixup.getLoc(),
- "symbol '" + B->getSymbol().getName() +
- "' can not be undefined in a subtraction expression");
+ reportError(Fixup.getLoc(),
+ "symbol '" + SB->getName() +
+ "' can not be undefined in a subtraction expression");
return;
}
// Select the appropriate difference relocation type.
Type = MachO::ARM_RELOC_SECTDIFF;
- Value2 = Writer->getSymbolAddress(B->getSymbol(), Asm);
+ Value2 = Writer->getSymbolAddress(*SB);
FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent());
}
@@ -360,7 +358,7 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {
- unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
+ unsigned IsPCRel = Fixup.isPCRel();
unsigned Log2Size;
unsigned RelocType = MachO::ARM_RELOC_VANILLA;
if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) {
@@ -368,14 +366,14 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
// relocation type for the fixup kind. This happens when it's a fixup that's
// expected to always be resolvable at assembly time and not have any
// relocations needed.
- Asm.getContext().reportError(Fixup.getLoc(), "unsupported relocation type");
+ reportError(Fixup.getLoc(), "unsupported relocation type");
return;
}
// If this is a difference or a defined symbol plus an offset, then we need a
// scattered relocation entry. Differences always require scattered
// relocations.
- if (Target.getSymB()) {
+ if (Target.getSubSym()) {
if (RelocType == MachO::ARM_RELOC_HALF)
return recordARMScatteredHalfRelocation(Writer, Asm, Fragment, Fixup,
Target, FixedValue);
@@ -384,9 +382,7 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
}
// Get the symbol data, if any.
- const MCSymbol *A = nullptr;
- if (Target.getSymA())
- A = &Target.getSymA()->getSymbol();
+ const MCSymbol *A = Target.getAddSym();
// FIXME: For other platforms, we need to use scattered relocations for
// internal relocations with offsets. If this is an internal relocation with
@@ -416,9 +412,17 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
} else {
// Resolve constant variables.
if (A->isVariable()) {
- int64_t Res;
- if (A->getVariableValue()->evaluateAsAbsolute(
- Res, Asm, Writer->getSectionAddressMap())) {
+ MCValue Val;
+ bool Relocatable =
+ A->getVariableValue()->evaluateAsRelocatable(Val, &Asm);
+ int64_t Res = Val.getConstant();
+ bool isAbs = Val.isAbsolute();
+ if (Relocatable && Val.getAddSym() && Val.getSubSym()) {
+ Res += Writer->getSymbolAddress(*Val.getAddSym()) -
+ Writer->getSymbolAddress(*Val.getSubSym());
+ isAbs = true;
+ }
+ if (isAbs) {
FixedValue = Res;
return;
}
@@ -461,7 +465,7 @@ void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
// PAIR. I.e. it's correct that we insert the high bits of the addend in the
// MOVW case here. relocation entries.
uint32_t Value = 0;
- switch (Fixup.getTargetKind()) {
+ switch (Fixup.getKind()) {
default: break;
case ARM::fixup_arm_movw_lo16:
case ARM::fixup_t2_movw_lo16:
@@ -489,3 +493,23 @@ llvm::createARMMachObjectWriter(bool Is64Bit, uint32_t CPUType,
uint32_t CPUSubtype) {
return std::make_unique<ARMMachObjectWriter>(Is64Bit, CPUType, CPUSubtype);
}
+
+namespace {
+class ARMTargetMachOStreamer : public ARMTargetStreamer {
+public:
+ ARMTargetMachOStreamer(MCStreamer &S) : ARMTargetStreamer(S) {}
+ MCObjectStreamer &getStreamer() {
+ return static_cast<MCObjectStreamer &>(Streamer);
+ }
+ void emitThumbFunc(MCSymbol *Symbol) override {
+ // Remember that the function is a thumb function. Fixup and relocation
+ // values will need adjusted.
+ getStreamer().getAssembler().setIsThumbFunc(Symbol);
+ cast<MCSymbolMachO>(Symbol)->setThumbFunc();
+ }
+};
+} // namespace
+
+MCTargetStreamer *llvm::createARMObjectTargetMachOStreamer(MCStreamer &S) {
+ return new ARMTargetMachOStreamer(S);
+}