[llvm-commits] [llvm] r131205 - in /llvm/trunk/lib/MC: ELFObjectWriter.cpp ELFObjectWriter.h
Nick Lewycky
nlewycky at google.com
Wed May 18 14:11:52 PDT 2011
Jason, do you have a testcase for this? I'd like to figure out how GNU as
knows what to do so that we can remove the flag, but I can't be sure I'm
looking at the right thing without a testcase.
On 11 May 2011 15:53, Jason W Kim <jason.w.kim.2009 at gmail.com> wrote:
> Author: jasonwkim
> Date: Wed May 11 17:53:06 2011
> New Revision: 131205
>
> URL: http://llvm.org/viewvc/llvm-project?rev=131205&view=rev
> Log:
> Address the last bit of relocation flag related divergence betweeen
> LLVM and binutils.
>
> With this patch, there are no functional differences between the .o
> produced directly from LLVM versus the .s to .o via GNU as, for relocation
> tags
> at least, for both PIC and non-PIC modes.
>
> Because some non-PIC reloc tags are used (legally) on PIC, so IsPCRel flag
> is
> necessary but not sufficient to determine whether the overall codegen mode
> is
> PIC or not. Why is this necessary? There is an incompatibility of how
> relocs
> are emitted in the .rodata section. Binutils PIC likes to emit certain
> relocs
> as section relative offsets. Non-PIC does not do this.
>
> So I added a hidden switch on the ELFObjectwriter "-arm-elf-force-pic"
> which
> forces the objectwriter to pretend that all relocs are for PIC mode.
>
>
> Todo: Activate ForceARMElfPIC to true if -relocation-model=pic is selected
> on llc.
>
> Todo: There are probably more issues for PIC mode on ARM/MC/ELF...
>
> Todo: Existing tests in MC/ARM/elf-reloc*.ll need to be converted over to
> .s
> tests as well as expanded to cover the gamut.
>
>
> Modified:
> llvm/trunk/lib/MC/ELFObjectWriter.cpp
> llvm/trunk/lib/MC/ELFObjectWriter.h
>
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=131205&r1=131204&r2=131205&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed May 11 17:53:06 2011
> @@ -25,6 +25,8 @@
> #include "llvm/Support/ELF.h"
> #include "llvm/Target/TargetAsmBackend.h"
> #include "llvm/ADT/StringSwitch.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/ADT/Statistic.h"
>
> #include "../Target/X86/X86FixupKinds.h"
> #include "../Target/ARM/ARMFixupKinds.h"
> @@ -32,6 +34,16 @@
> #include <vector>
> using namespace llvm;
>
> +#undef DEBUG_TYPE
> +#define DEBUG_TYPE "reloc-info"
> +
> +// Emulate the wierd behavior of GNU-as for relocation types
> +namespace llvm {
> +cl::opt<bool>
> +ForceARMElfPIC("arm-elf-force-pic", cl::Hidden, cl::init(false),
> + cl::desc("Force ELF emitter to emit PIC style
> relocations"));
> +}
> +
> bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned
> Kind) {
> const MCFixupKindInfo &FKI =
> Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
> @@ -319,7 +331,9 @@
>
> const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
> const MCValue &Target,
> - const MCFragment &F) const
> {
> + const MCFragment &F,
> + const MCFixup &Fixup,
> + bool IsPCRel) const {
> const MCSymbol &Symbol = Target.getSymA()->getSymbol();
> const MCSymbol &ASymbol = Symbol.AliasedSymbol();
> const MCSymbol *Renamed = Renames.lookup(&Symbol);
> @@ -342,7 +356,7 @@
> const SectionKind secKind = Section.getKind();
>
> if (secKind.isBSS())
> - return ExplicitRelSym(Asm, Target, F, true);
> + return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
>
> if (secKind.isThreadLocal()) {
> if (Renamed)
> @@ -365,13 +379,14 @@
>
> if (Section.getFlags() & ELF::SHF_MERGE) {
> if (Target.getConstant() == 0)
> - return NULL;
> + return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
> if (Renamed)
> return Renamed;
> return &Symbol;
> }
>
> - return ExplicitRelSym(Asm, Target, F, false);
> + return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
> +
> }
>
>
> @@ -390,7 +405,7 @@
> if (!Target.isAbsolute()) {
> const MCSymbol &Symbol = Target.getSymA()->getSymbol();
> const MCSymbol &ASymbol = Symbol.AliasedSymbol();
> - RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
> + RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
>
> if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
> const MCSymbol &SymbolB = RefB->getSymbol();
> @@ -1261,32 +1276,93 @@
>
> // In ARM, _MergedGlobals and other most symbols get emitted directly.
> // I.e. not as an offset to a section symbol.
> -// This code is a first-cut approximation of what ARM/gcc does.
> +// This code is an approximation of what ARM/gcc does.
> +
> +STATISTIC(PCRelCount, "Total number of PIC Relocations");
> +STATISTIC(NonPCRelCount, "Total number of non-PIC relocations");
>
> const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
> const MCValue &Target,
> const MCFragment &F,
> - bool IsBSS) const {
> + const MCFixup &Fixup,
> + bool IsPCRel) const {
> const MCSymbol &Symbol = Target.getSymA()->getSymbol();
> bool EmitThisSym = false;
>
> - if (IsBSS) {
> - EmitThisSym = StringSwitch<bool>(Symbol.getName())
> - .Case("_MergedGlobals", true)
> - .Default(false);
> + const MCSectionELF &Section =
> + static_cast<const MCSectionELF&>(Symbol.getSection());
> + const SectionKind secKind = Section.getKind();
> + const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
> + MCSymbolRefExpr::VariantKind Kind2;
> + Kind2 = Target.getSymB() ? Target.getSymB()->getKind() :
> + MCSymbolRefExpr::VK_None;
> + bool InNormalSection = true;
> + unsigned RelocType = 0;
> + RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);
> +
> + DEBUG(dbgs() << "considering symbol "
> + << Section.getSectionName() << "/"
> + << Symbol.getName() << "/"
> + << " Rel:" << (unsigned)RelocType
> + << " Kind: " << (int)Kind << "/" << (int)Kind2
> + << " Tmp:"
> + << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"
> + << Symbol.isVariable() << "/" << Symbol.isTemporary()
> + << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n");
> +
> + if (IsPCRel || ForceARMElfPIC) { ++PCRelCount;
> + switch (RelocType) {
> + default:
> + // Most relocation types are emitted as explicit symbols
> + InNormalSection =
> + StringSwitch<bool>(Section.getSectionName())
> + .Case(".data.rel.ro.local", false)
> + .Case(".data.rel", false)
> + .Case(".bss", false)
> + .Default(true);
> + EmitThisSym = true;
> + break;
> + case ELF::R_ARM_ABS32:
> + // But things get strange with R_ARM_ABS32
> + // In this case, most things that go in .rodata show up
> + // as section relative relocations
> + InNormalSection =
> + StringSwitch<bool>(Section.getSectionName())
> + .Case(".data.rel.ro.local", false)
> + .Case(".data.rel", false)
> + .Case(".rodata", false)
> + .Case(".bss", false)
> + .Default(true);
> + EmitThisSym = false;
> + break;
> + }
> } else {
> - EmitThisSym = StringSwitch<bool>(Symbol.getName())
> - .Case("_MergedGlobals", true)
> - .StartsWith(".L.str", true)
> - .Default(false);
> + NonPCRelCount++;
> + InNormalSection =
> + StringSwitch<bool>(Section.getSectionName())
> + .Case(".data.rel.ro.local", false)
> + .Case(".rodata", false)
> + .Case(".data.rel", false)
> + .Case(".bss", false)
> + .Default(true);
> +
> + switch (RelocType) {
> + default: EmitThisSym = true; break;
> + case ELF::R_ARM_ABS32: EmitThisSym = false; break;
> + }
> }
> +
> if (EmitThisSym)
> return &Symbol;
> - if (! Symbol.isTemporary())
> + if (! Symbol.isTemporary() && InNormalSection) {
> return &Symbol;
> + }
> return NULL;
> }
>
> +// Need to examine the Fixup when determining whether to
> +// emit the relocation as an explicit symbol or as a section relative
> +// offset
> unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
> const MCFixup &Fixup,
> bool IsPCRel,
> @@ -1295,6 +1371,20 @@
> MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
> MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
>
> + unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel);
> +
> + if (RelocNeedsGOT(Modifier))
> + NeedsGOT = true;
> +
> + return Type;
> +}
> +
> +unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
> + const MCFixup &Fixup,
> + bool IsPCRel) const {
> + MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
> + MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
> +
> unsigned Type = 0;
> if (IsPCRel) {
> switch ((unsigned)Fixup.getKind()) {
> @@ -1303,7 +1393,7 @@
> switch (Modifier) {
> default: llvm_unreachable("Unsupported Modifier");
> case MCSymbolRefExpr::VK_None:
> - Type = ELF::R_ARM_BASE_PREL;
> + Type = ELF::R_ARM_REL32;
> break;
> case MCSymbolRefExpr::VK_ARM_TLSGD:
> assert(0 && "unimplemented");
> @@ -1399,9 +1489,6 @@
> }
> }
>
> - if (RelocNeedsGOT(Modifier))
> - NeedsGOT = true;
> -
> return Type;
> }
>
>
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.h?rev=131205&r1=131204&r2=131205&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.h (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.h Wed May 11 17:53:06 2011
> @@ -140,15 +140,18 @@
> unsigned ShstrtabIndex;
>
>
> - const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
> - const MCValue &Target,
> - const MCFragment &F) const;
> + virtual const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
> + const MCValue &Target,
> + const MCFragment &F,
> + const MCFixup &Fixup,
> + bool IsPCRel) const;
>
> // For arch-specific emission of explicit reloc symbol
> virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
> const MCValue &Target,
> const MCFragment &F,
> - bool IsBSS) const {
> + const MCFixup &Fixup,
> + bool IsPCRel) const {
> return NULL;
> }
>
> @@ -380,11 +383,16 @@
> virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
> const MCValue &Target,
> const MCFragment &F,
> - bool IsBSS) const;
> + const MCFixup &Fixup,
> + bool IsPCRel) const;
>
> virtual unsigned GetRelocType(const MCValue &Target, const MCFixup
> &Fixup,
> bool IsPCRel, bool IsRelocWithSymbol,
> int64_t Addend);
> + private:
> + unsigned GetRelocTypeInner(const MCValue &Target,
> + const MCFixup &Fixup, bool IsPCRel) const;
> +
> };
>
> //===- MBlazeELFObjectWriter
> -------------------------------------------===//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110518/e9b6c5d8/attachment.html>
More information about the llvm-commits
mailing list