aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCFixup.h4
-rw-r--r--include/llvm/MC/MCObjectStreamer.h1
-rw-r--r--include/llvm/Support/ELF.h16
-rw-r--r--lib/MC/ELFObjectWriter.cpp9
-rw-r--r--lib/MC/ELFObjectWriter.h2
-rw-r--r--lib/MC/MCAsmBackend.cpp16
-rw-r--r--lib/MC/MCObjectStreamer.cpp10
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp8
8 files changed, 59 insertions, 7 deletions
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index 6fde797e40..740427083d 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -26,6 +26,10 @@ enum MCFixupKind {
FK_PCRel_2, ///< A two-byte pc relative fixup.
FK_PCRel_4, ///< A four-byte pc relative fixup.
FK_PCRel_8, ///< A eight-byte pc relative fixup.
+ FK_GPRel_1, ///< A one-byte gp relative fixup.
+ FK_GPRel_2, ///< A two-byte gp relative fixup.
+ FK_GPRel_4, ///< A four-byte gp relative fixup.
+ FK_GPRel_8, ///< A eight-byte gp relative fixup.
FirstTargetFixupKind = 128,
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index f897e64f44..01d254a49c 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -77,6 +77,7 @@ public:
unsigned PointerSize);
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label);
+ virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void Finish();
/// @}
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index c5b85e2e6a..a3906b1dba 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -599,7 +599,23 @@ enum {
R_ARM_THM_TLS_DESCSEQ32 = 0x82
};
+// Mips Specific e_flags
+enum {
+ EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
+ EF_MIPS_PIC = 0x00000002, // Position independent code
+ EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
+ EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
+ EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
+ EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
+ EF_MIPS_ARCH_4 = 0x30000000, // MIPS4 instruction set
+ EF_MIPS_ARCH_5 = 0x40000000, // MIPS5 instruction set
+ EF_MIPS_ARCH_32 = 0x60000000, // MIPS32 instruction set
+ EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+ EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant
+};
+
// ELF Relocation types for Mips
+// .
enum {
R_MIPS_NONE = 0,
R_MIPS_16 = 1,
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 4491d4b16b..bd28069a31 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -1825,6 +1825,12 @@ MipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
MipsELFObjectWriter::~MipsELFObjectWriter() {}
+// FIXME: get the real EABI Version from the Triple.
+void MipsELFObjectWriter::WriteEFlags() {
+ Write32(ELF::EF_MIPS_NOREORDER |
+ ELF::EF_MIPS_ARCH_32R2);
+}
+
unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel,
@@ -1840,6 +1846,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
case FK_Data_4:
Type = ELF::R_MIPS_32;
break;
+ case FK_GPRel_4:
+ Type = ELF::R_MIPS_GPREL32;
+ break;
case Mips::fixup_Mips_GPREL16:
Type = ELF::R_MIPS_GPREL16;
break;
diff --git a/lib/MC/ELFObjectWriter.h b/lib/MC/ELFObjectWriter.h
index ca6cdfc5ce..78382065db 100644
--- a/lib/MC/ELFObjectWriter.h
+++ b/lib/MC/ELFObjectWriter.h
@@ -442,6 +442,8 @@ class ELFObjectWriter : public MCObjectWriter {
bool IsLittleEndian);
virtual ~MipsELFObjectWriter();
+ virtual void WriteEFlags();
+
protected:
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp
index 2c150f456c..936ed55e54 100644
--- a/lib/MC/MCAsmBackend.cpp
+++ b/lib/MC/MCAsmBackend.cpp
@@ -21,14 +21,18 @@ MCAsmBackend::~MCAsmBackend() {
const MCFixupKindInfo &
MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
static const MCFixupKindInfo Builtins[] = {
- { "FK_Data_1", 0, 8, 0 },
- { "FK_Data_2", 0, 16, 0 },
- { "FK_Data_4", 0, 32, 0 },
- { "FK_Data_8", 0, 64, 0 },
- { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel },
+ { "FK_Data_1", 0, 8, 0 },
+ { "FK_Data_2", 0, 16, 0 },
+ { "FK_Data_4", 0, 32, 0 },
+ { "FK_Data_8", 0, 64, 0 },
+ { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel },
{ "FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
- { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel }
+ { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
+ { "FK_GPRel_1", 0, 8, 0 },
+ { "FK_GPRel_2", 0, 16, 0 },
+ { "FK_GPRel_4", 0, 32, 0 },
+ { "FK_GPRel_8", 0, 64, 0 }
};
assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index a04ae0812a..90c957f7be 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -245,6 +245,16 @@ void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
EmitFill(Res, Value, 0);
}
+// Associate GPRel32 fixup with data and resize data area
+void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ DF->addFixup(MCFixup::Create(DF->getContents().size(),
+ Value,
+ FK_GPRel_4));
+ DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
void MCObjectStreamer::Finish() {
// Dump out the dwarf file & directory tables and line tables.
if (getContext().hasDwarfFiles())
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 4f017d0b20..7bc5fe4a6e 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -58,6 +58,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
switch (Kind) {
default:
break;
+ case FK_GPRel_4:
case FK_Data_4:
Value &= 0xffffffff;
break;
@@ -68,6 +69,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case Mips::fixup_Mips_PC16:
Value &= 0x0000ffff;
break;
+ case Mips::fixup_Mips_HI16:
+ Value >>= 16;
+ break;
}
return Value;
@@ -104,15 +108,17 @@ public:
llvm_unreachable("Unknown fixup kind!");
case Mips::fixup_Mips_GOT16: // This will be fixed up at link time
break;
+ case FK_GPRel_4:
case FK_Data_4:
case Mips::fixup_Mips_26:
case Mips::fixup_Mips_LO16:
case Mips::fixup_Mips_PC16:
+ case Mips::fixup_Mips_HI16:
// For each byte of the fragment that the fixup touches, mask i
// the fixup value. The Value has been "split up" into the appr
// bitfields above.
for (unsigned i = 0; i != 4; ++i) // FIXME - Need to support 2 and 8 bytes
- Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+ Data[Offset + i] += uint8_t((Value >> (i * 8)) & 0xff);
break;
}
}