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>