[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