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.<br><br><div class="gmail_quote">


On 11 May 2011 15:53, Jason W Kim <span dir="ltr"><<a href="mailto:jason.w.kim.2009@gmail.com" target="_blank">jason.w.kim.2009@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


Author: jasonwkim<br>
Date: Wed May 11 17:53:06 2011<br>
New Revision: 131205<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=131205&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=131205&view=rev</a><br>
Log:<br>
Address the last bit of relocation flag related divergence betweeen<br>
LLVM and binutils.<br>
<br>
With this patch, there are no functional differences between the .o<br>
produced directly from LLVM versus the .s to .o via GNU as, for relocation tags<br>
at least, for both PIC and non-PIC modes.<br>
<br>
Because some non-PIC reloc tags are used (legally) on PIC, so IsPCRel flag is<br>
necessary but not sufficient to determine whether the overall codegen mode is<br>
PIC or not. Why is this necessary? There is an incompatibility of how relocs<br>
are emitted in the .rodata section.  Binutils PIC likes to emit certain relocs<br>
as section relative offsets.  Non-PIC does not do this.<br>
<br>
So I added a hidden switch on the ELFObjectwriter "-arm-elf-force-pic" which<br>
forces the objectwriter to pretend that all relocs are for PIC mode.<br>
<br>
<br>
Todo: Activate ForceARMElfPIC to true if -relocation-model=pic is selected<br>
on llc.<br>
<br>
Todo: There are probably more issues for PIC mode on ARM/MC/ELF...<br>
<br>
Todo: Existing tests in MC/ARM/elf-reloc*.ll need to be converted over to .s<br>
tests as well as expanded to cover the gamut.<br>
<br>
<br>
Modified:<br>
    llvm/trunk/lib/MC/ELFObjectWriter.cpp<br>
    llvm/trunk/lib/MC/ELFObjectWriter.h<br>
<br>
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=131205&r1=131204&r2=131205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=131205&r1=131204&r2=131205&view=diff</a><br>



==============================================================================<br>
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)<br>
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed May 11 17:53:06 2011<br>
@@ -25,6 +25,8 @@<br>
 #include "llvm/Support/ELF.h"<br>
 #include "llvm/Target/TargetAsmBackend.h"<br>
 #include "llvm/ADT/StringSwitch.h"<br>
+#include "llvm/Support/CommandLine.h"<br>
+#include "llvm/ADT/Statistic.h"<br>
<br>
 #include "../Target/X86/X86FixupKinds.h"<br>
 #include "../Target/ARM/ARMFixupKinds.h"<br>
@@ -32,6 +34,16 @@<br>
 #include <vector><br>
 using namespace llvm;<br>
<br>
+#undef  DEBUG_TYPE<br>
+#define DEBUG_TYPE "reloc-info"<br>
+<br>
+// Emulate the wierd behavior of GNU-as for relocation types<br>
+namespace llvm {<br>
+cl::opt<bool><br>
+ForceARMElfPIC("arm-elf-force-pic", cl::Hidden, cl::init(false),<br>
+               cl::desc("Force ELF emitter to emit PIC style relocations"));<br>
+}<br>
+<br>
 bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {<br>
   const MCFixupKindInfo &FKI =<br>
     Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);<br>
@@ -319,7 +331,9 @@<br>
<br>
 const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,<br>
                                                const MCValue &Target,<br>
-                                               const MCFragment &F) const {<br>
+                                               const MCFragment &F,<br>
+                                               const MCFixup &Fixup,<br>
+                                               bool IsPCRel) const {<br>
   const MCSymbol &Symbol = Target.getSymA()->getSymbol();<br>
   const MCSymbol &ASymbol = Symbol.AliasedSymbol();<br>
   const MCSymbol *Renamed = Renames.lookup(&Symbol);<br>
@@ -342,7 +356,7 @@<br>
   const SectionKind secKind = Section.getKind();<br>
<br>
   if (secKind.isBSS())<br>
-    return ExplicitRelSym(Asm, Target, F, true);<br>
+    return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);<br>
<br>
   if (secKind.isThreadLocal()) {<br>
     if (Renamed)<br>
@@ -365,13 +379,14 @@<br>
<br>
   if (Section.getFlags() & ELF::SHF_MERGE) {<br>
     if (Target.getConstant() == 0)<br>
-      return NULL;<br>
+      return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);<br>
     if (Renamed)<br>
       return Renamed;<br>
     return &Symbol;<br>
   }<br>
<br>
-  return ExplicitRelSym(Asm, Target, F, false);<br>
+  return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);<br>
+<br>
 }<br>
<br>
<br>
@@ -390,7 +405,7 @@<br>
   if (!Target.isAbsolute()) {<br>
     const MCSymbol &Symbol = Target.getSymA()->getSymbol();<br>
     const MCSymbol &ASymbol = Symbol.AliasedSymbol();<br>
-    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);<br>
+    RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);<br>
<br>
     if (const MCSymbolRefExpr *RefB = Target.getSymB()) {<br>
       const MCSymbol &SymbolB = RefB->getSymbol();<br>
@@ -1261,32 +1276,93 @@<br>
<br>
 // In ARM, _MergedGlobals and other most symbols get emitted directly.<br>
 // I.e. not as an offset to a section symbol.<br>
-// This code is a first-cut approximation of what ARM/gcc does.<br>
+// This code is an approximation of what ARM/gcc does.<br>
+<br>
+STATISTIC(PCRelCount, "Total number of PIC Relocations");<br>
+STATISTIC(NonPCRelCount, "Total number of non-PIC relocations");<br>
<br>
 const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,<br>
                                                    const MCValue &Target,<br>
                                                    const MCFragment &F,<br>
-                                                   bool IsBSS) const {<br>
+                                                   const MCFixup &Fixup,<br>
+                                                   bool IsPCRel) const {<br>
   const MCSymbol &Symbol = Target.getSymA()->getSymbol();<br>
   bool EmitThisSym = false;<br>
<br>
-  if (IsBSS) {<br>
-    EmitThisSym = StringSwitch<bool>(Symbol.getName())<br>
-      .Case("_MergedGlobals", true)<br>
-      .Default(false);<br>
+  const MCSectionELF &Section =<br>
+    static_cast<const MCSectionELF&>(Symbol.getSection());<br>
+  const SectionKind secKind = Section.getKind();<br>
+  const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();<br>
+  MCSymbolRefExpr::VariantKind Kind2;<br>
+  Kind2 = Target.getSymB() ?  Target.getSymB()->getKind() :<br>
+    MCSymbolRefExpr::VK_None;<br>
+  bool InNormalSection = true;<br>
+  unsigned RelocType = 0;<br>
+  RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);<br>
+<br>
+  DEBUG(dbgs() << "considering symbol "<br>
+        << Section.getSectionName() << "/"<br>
+        << Symbol.getName() << "/"<br>
+        << " Rel:" << (unsigned)RelocType<br>
+        << " Kind: " << (int)Kind << "/" << (int)Kind2<br>
+        << " Tmp:"<br>
+        << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"<br>
+        << Symbol.isVariable() << "/" << Symbol.isTemporary()<br>
+        << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n");<br>
+<br>
+  if (IsPCRel || ForceARMElfPIC) { ++PCRelCount;<br>
+    switch (RelocType) {<br>
+    default:<br>
+      // Most relocation types are emitted as explicit symbols<br>
+      InNormalSection =<br>
+        StringSwitch<bool>(Section.getSectionName())<br>
+        .Case(".data.rel.ro.local", false)<br>
+        .Case(".data.rel", false)<br>
+        .Case(".bss", false)<br>
+        .Default(true);<br>
+      EmitThisSym = true;<br>
+      break;<br>
+    case ELF::R_ARM_ABS32:<br>
+      // But things get strange with R_ARM_ABS32<br>
+      // In this case, most things that go in .rodata show up<br>
+      // as section relative relocations<br>
+      InNormalSection =<br>
+        StringSwitch<bool>(Section.getSectionName())<br>
+        .Case(".data.rel.ro.local", false)<br>
+        .Case(".data.rel", false)<br>
+        .Case(".rodata", false)<br>
+        .Case(".bss", false)<br>
+        .Default(true);<br>
+      EmitThisSym = false;<br>
+      break;<br>
+    }<br>
   } else {<br>
-    EmitThisSym = StringSwitch<bool>(Symbol.getName())<br>
-      .Case("_MergedGlobals", true)<br>
-      .StartsWith(".L.str", true)<br>
-      .Default(false);<br>
+    NonPCRelCount++;<br>
+    InNormalSection =<br>
+      StringSwitch<bool>(Section.getSectionName())<br>
+      .Case(".data.rel.ro.local", false)<br>
+      .Case(".rodata", false)<br>
+      .Case(".data.rel", false)<br>
+      .Case(".bss", false)<br>
+      .Default(true);<br>
+<br>
+    switch (RelocType) {<br>
+    default: EmitThisSym = true; break;<br>
+    case ELF::R_ARM_ABS32: EmitThisSym = false; break;<br>
+    }<br>
   }<br>
+<br>
   if (EmitThisSym)<br>
     return &Symbol;<br>
-  if (! Symbol.isTemporary())<br>
+  if (! Symbol.isTemporary() && InNormalSection) {<br>
     return &Symbol;<br>
+  }<br>
   return NULL;<br>
 }<br>
<br>
+// Need to examine the Fixup when determining whether to<br>
+// emit the relocation as an explicit symbol or as a section relative<br>
+// offset<br>
 unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,<br>
                                           const MCFixup &Fixup,<br>
                                           bool IsPCRel,<br>
@@ -1295,6 +1371,20 @@<br>
   MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?<br>
     MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();<br>
<br>
+  unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel);<br>
+<br>
+  if (RelocNeedsGOT(Modifier))<br>
+    NeedsGOT = true;<br>
+<br>
+  return Type;<br>
+}<br>
+<br>
+unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,<br>
+                                               const MCFixup &Fixup,<br>
+                                               bool IsPCRel) const  {<br>
+  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?<br>
+    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();<br>
+<br>
   unsigned Type = 0;<br>
   if (IsPCRel) {<br>
     switch ((unsigned)Fixup.getKind()) {<br>
@@ -1303,7 +1393,7 @@<br>
       switch (Modifier) {<br>
       default: llvm_unreachable("Unsupported Modifier");<br>
       case MCSymbolRefExpr::VK_None:<br>
-        Type = ELF::R_ARM_BASE_PREL;<br>
+        Type = ELF::R_ARM_REL32;<br>
         break;<br>
       case MCSymbolRefExpr::VK_ARM_TLSGD:<br>
         assert(0 && "unimplemented");<br>
@@ -1399,9 +1489,6 @@<br>
     }<br>
   }<br>
<br>
-  if (RelocNeedsGOT(Modifier))<br>
-    NeedsGOT = true;<br>
-<br>
   return Type;<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/MC/ELFObjectWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.h?rev=131205&r1=131204&r2=131205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.h?rev=131205&r1=131204&r2=131205&view=diff</a><br>



==============================================================================<br>
--- llvm/trunk/lib/MC/ELFObjectWriter.h (original)<br>
+++ llvm/trunk/lib/MC/ELFObjectWriter.h Wed May 11 17:53:06 2011<br>
@@ -140,15 +140,18 @@<br>
     unsigned ShstrtabIndex;<br>
<br>
<br>
-    const MCSymbol *SymbolToReloc(const MCAssembler &Asm,<br>
-                                  const MCValue &Target,<br>
-                                  const MCFragment &F) const;<br>
+    virtual const MCSymbol *SymbolToReloc(const MCAssembler &Asm,<br>
+                                          const MCValue &Target,<br>
+                                          const MCFragment &F,<br>
+                                          const MCFixup &Fixup,<br>
+                                          bool IsPCRel) const;<br>
<br>
     // For arch-specific emission of explicit reloc symbol<br>
     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,<br>
                                            const MCValue &Target,<br>
                                            const MCFragment &F,<br>
-                                           bool IsBSS) const {<br>
+                                           const MCFixup &Fixup,<br>
+                                           bool IsPCRel) const {<br>
       return NULL;<br>
     }<br>
<br>
@@ -380,11 +383,16 @@<br>
     virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,<br>
                                            const MCValue &Target,<br>
                                            const MCFragment &F,<br>
-                                           bool IsBSS) const;<br>
+                                           const MCFixup &Fixup,<br>
+                                           bool IsPCRel) const;<br>
<br>
     virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,<br>
                                   bool IsPCRel, bool IsRelocWithSymbol,<br>
                                   int64_t Addend);<br>
+  private:<br>
+    unsigned GetRelocTypeInner(const MCValue &Target,<br>
+                               const MCFixup &Fixup, bool IsPCRel) const;<br>
+<br>
   };<br>
<br>
   //===- MBlazeELFObjectWriter -------------------------------------------===//<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>