[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