[llvm-commits] [llvm] r131205 - in /llvm/trunk/lib/MC: ELFObjectWriter.cpp ELFObjectWriter.h
Jason Kim
jasonwkim at google.com
Wed May 18 16:45:13 PDT 2011
On Wed, May 18, 2011 at 2:11 PM, Nick Lewycky <nlewycky at google.com> wrote:
> 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.
I'll get you a test case - its in PNaCl land and requires comparing
the text differences from multiple .o files for he MC.o versus
MC.s->gas->.o path
Thanks
>
> 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
>
>
More information about the llvm-commits
mailing list