Last active
November 2, 2017 09:53
-
-
Save mskvortsov/5eaf3ac7d81da38b6e7e61b562153cab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/ObjWriter/objwriter.cpp b/lib/ObjWriter/objwriter.cpp | |
index 5024c55..c2f302c 100644 | |
--- a/lib/ObjWriter/objwriter.cpp | |
+++ b/lib/ObjWriter/objwriter.cpp | |
@@ -303,6 +303,15 @@ void ObjectWriter::EmitIntValue(uint64_t Value, unsigned Size) { | |
void ObjectWriter::EmitSymbolDef(const char *SymbolName) { | |
MCSymbol *Sym = OutContext->getOrCreateSymbol(Twine(SymbolName)); | |
Streamer->EmitSymbolAttribute(Sym, MCSA_Global); | |
+ | |
+ // A Thumb2 function symbol should be marked with an appropriate ELF | |
+ // attribute to make later computation of a relocation address value correct | |
+ if (GetTriple().getArch() == Triple::thumb && | |
+ GetTriple().getObjectFormat() == Triple::ELF && | |
+ Streamer->getCurrentSectionOnly()->getKind().isText()) { | |
+ Streamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); | |
+ } | |
+ | |
Streamer->EmitLabel(Sym); | |
} | |
@@ -317,6 +326,51 @@ ObjectWriter::GetSymbolRefExpr(const char *SymbolName, | |
int ObjectWriter::EmitSymbolRef(const char *SymbolName, | |
RelocType RelocationType, int Delta) { | |
+ if (GetTriple().getArch() == Triple::thumb) | |
+ { | |
+ const MCExpr *TargetExpr = | |
+ GetSymbolRefExpr(SymbolName, MCSymbolRefExpr::VK_None); | |
+ if (Delta != 0) { | |
+ TargetExpr = MCBinaryExpr::createAdd(TargetExpr, | |
+ MCConstantExpr::create(Delta, *OutContext), *OutContext); | |
+ } | |
+ | |
+ MCDataFragment *DF = Streamer->getOrCreateDataFragment(); | |
+ unsigned Offset = DF->getContents().size(); | |
+ const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, *OutContext); | |
+ | |
+ switch (RelocationType) | |
+ { | |
+ case RelocType::IMAGE_REL_BASED_REL32: | |
+ // If the fixup is pc-relative, we need to bias the value to be relative | |
+ // to the start of the field, not the end of the field | |
+ TargetExpr = MCBinaryExpr::createSub( | |
+ TargetExpr, MCConstantExpr::create(4, *OutContext), *OutContext); | |
+ Streamer->EmitValueImpl(TargetExpr, 4, SMLoc(), true); | |
+ return 4; | |
+ | |
+ case RelocType::IMAGE_REL_BASED_HIGHLOW: | |
+ Streamer->EmitValueImpl(TargetExpr, 4, SMLoc()); | |
+ return 4; | |
+ | |
+ case RelocType::IMAGE_REL_BASED_THUMB_MOV32: | |
+ Streamer->EmitRelocDirective(*OffsetExpr, "R_ARM_THM_MOVW_ABS_NC", | |
+ TargetExpr, SMLoc()); | |
+ OffsetExpr = MCConstantExpr::create(Offset + 4, *OutContext); | |
+ Streamer->EmitRelocDirective(*OffsetExpr, "R_ARM_THM_MOVT_ABS", | |
+ TargetExpr, SMLoc()); | |
+ return 8; | |
+ | |
+ case RelocType::IMAGE_REL_BASED_THUMB_BRANCH24: | |
+ Streamer->EmitRelocDirective(*OffsetExpr, "R_ARM_THM_JUMP24", TargetExpr, | |
+ SMLoc()); | |
+ return 4; | |
+ | |
+ default: | |
+ assert(false && "EmitSymbolRef: unknown RelocationType!"); | |
+ } | |
+ } | |
+ | |
bool IsPCRelative = false; | |
int Size = 0; | |
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; | |
diff --git a/lib/ObjWriter/objwriter.h b/lib/ObjWriter/objwriter.h | |
index c4a07b3..ee145c6 100644 | |
--- a/lib/ObjWriter/objwriter.h | |
+++ b/lib/ObjWriter/objwriter.h | |
@@ -34,8 +34,10 @@ enum CustomSectionAttributes : int32_t { | |
enum class RelocType { | |
IMAGE_REL_BASED_ABSOLUTE = 0x00, | |
IMAGE_REL_BASED_HIGHLOW = 0x03, | |
+ IMAGE_REL_BASED_THUMB_MOV32 = 0x07, | |
IMAGE_REL_BASED_DIR64 = 0x0A, | |
IMAGE_REL_BASED_REL32 = 0x10, | |
+ IMAGE_REL_BASED_THUMB_BRANCH24 = 0x13, | |
}; | |
class ObjectWriter { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | |
index 40bf545e832..d9725556b5a 100644 | |
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | |
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | |
@@ -48,6 +48,14 @@ public: | |
}; | |
} // end anonymous namespace | |
+Optional<MCFixupKind> ARMAsmBackend::getFixupKind(StringRef Name) const { | |
+ return StringSwitch<Optional<MCFixupKind>>(Name) | |
+ .Case("R_ARM_THM_MOVW_ABS_NC", (MCFixupKind)ARM::fixup_t2_movw_lo16) | |
+ .Case("R_ARM_THM_MOVT_ABS", (MCFixupKind)ARM::fixup_t2_movt_hi16) | |
+ .Case("R_ARM_THM_JUMP24", (MCFixupKind)ARM::fixup_arm_thumb_blx) | |
+ .Default(MCAsmBackend::getFixupKind(Name)); | |
+} | |
+ | |
const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { | |
const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = { | |
// This table *must* be in the order that the fixup_* kinds are defined in | |
@@ -369,6 +377,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, | |
case FK_Data_2: | |
case FK_Data_4: | |
return Value; | |
+ case FK_PCRel_4: | |
+ return Value; | |
case FK_SecRel_2: | |
return Value; | |
case FK_SecRel_4: | |
@@ -785,6 +795,9 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { | |
case ARM::fixup_t2_movw_lo16: | |
return 4; | |
+ case FK_PCRel_4: | |
+ return 4; | |
+ | |
case FK_SecRel_2: | |
return 2; | |
case FK_SecRel_4: | |
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | |
index 2ddedb5d610..7488ef3670a 100644 | |
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | |
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | |
@@ -36,6 +36,7 @@ public: | |
bool hasNOP() const { return STI->getFeatureBits()[ARM::HasV6T2Ops]; } | |
+ Optional<MCFixupKind> getFixupKind(StringRef Name) const override; | |
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; | |
/// processFixupValue - Target hook to process the literal value of a fixup | |
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | |
index e1fa2457182..f0cd80a2d28 100644 | |
--- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | |
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | |
@@ -103,6 +103,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, | |
break; | |
} | |
break; | |
+ case FK_PCRel_4: | |
+ Type = ELF::R_ARM_REL32; | |
+ break; | |
case ARM::fixup_arm_blx: | |
case ARM::fixup_arm_uncondbl: | |
switch (Modifier) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment