From: Akira Hatanaka Date: Wed, 23 Nov 2011 22:18:04 +0000 (+0000) Subject: This patch addresses gp relative fixups/relocations for jump tables. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=84bfc2f090639f933df06cc675c4385511516bef;p=oota-llvm.git This patch addresses gp relative fixups/relocations for jump tables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145112 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index 6fde797e40f..740427083d5 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 f897e64f445..01d254a49c8 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 c5b85e2e6a1..a3906b1dbab 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 4491d4b16b6..bd28069a315 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 ca6cdfc5ce1..78382065dbc 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 2c150f456cf..936ed55e54d 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 a04ae0812a3..90c957f7be8 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 4f017d0b203..7bc5fe4a6e4 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; } }