[llvm-commits] [llvm] r124996 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/MC/ARM/elf-reloc-01.ll test/MC/ARM/elf-reloc-02.ll test/MC/ARM/elf-reloc-03.ll
Jason W Kim
jason.w.kim.2009 at gmail.com
Sun Feb 6 17:11:15 PST 2011
Author: jasonwkim
Date: Sun Feb 6 19:11:15 2011
New Revision: 124996
URL: http://llvm.org/viewvc/llvm-project?rev=124996&view=rev
Log:
Teach ARM/MC/ELF about gcc compatible reloc output to get past odd linkage
failures with relocations.
The code committed is a first cut at compatibility for emitted relocations in
ELF .o.
Why do this? because existing ARM tools like emitting relocs symbols as
explicit relocations, not as section-offset relocs.
Result is that with these changes,
1) relocs are now substantially identical what to gcc outputs.
2) larger apps (including many spec2k tests) compile, cross-link, and pass
Added reminder fixme to tests for future conversion to .s form.
Added:
llvm/trunk/test/MC/ARM/elf-reloc-01.ll
llvm/trunk/test/MC/ARM/elf-reloc-02.ll
llvm/trunk/test/MC/ARM/elf-reloc-03.ll
Modified:
llvm/trunk/lib/MC/ELFObjectWriter.cpp
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=124996&r1=124995&r2=124996&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sun Feb 6 19:11:15 2011
@@ -30,6 +30,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ELF.h"
#include "llvm/Target/TargetAsmBackend.h"
+#include "llvm/ADT/StringSwitch.h"
#include "../Target/X86/X86FixupKinds.h"
#include "../Target/ARM/ARMFixupKinds.h"
@@ -189,6 +190,14 @@
const MCValue &Target,
const MCFragment &F) 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 {
+ return NULL;
+ }
+
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool hasRelocationAddend() const {
return TargetObjectWriter->hasRelocationAddend();
@@ -401,6 +410,11 @@
virtual void WriteEFlags();
protected:
+ virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ bool IsBSS) const;
+
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend);
@@ -704,7 +718,7 @@
const SectionKind secKind = Section.getKind();
if (secKind.isBSS())
- return NULL;
+ return ExplicitRelSym(Asm, Target, F, true);
if (secKind.isThreadLocal()) {
if (Renamed)
@@ -733,7 +747,7 @@
return &Symbol;
}
- return NULL;
+ return ExplicitRelSym(Asm, Target, F, false);
}
@@ -1490,6 +1504,34 @@
Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
}
+// 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.
+
+const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ bool IsBSS) const {
+ const MCSymbol &Symbol = Target.getSymA()->getSymbol();
+ bool EmitThisSym = false;
+
+ if (IsBSS) {
+ EmitThisSym = StringSwitch<bool>(Symbol.getName())
+ .Case("_MergedGlobals", true)
+ .Default(false);
+ } else {
+ EmitThisSym = StringSwitch<bool>(Symbol.getName())
+ .Case("_MergedGlobals", true)
+ .StartsWith(".L.str", true)
+ .Default(false);
+ }
+ if (EmitThisSym)
+ return &Symbol;
+ if (! Symbol.isTemporary())
+ return &Symbol;
+ return NULL;
+}
+
unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel,
@@ -1604,7 +1646,7 @@
if (RelocNeedsGOT(Modifier))
NeedsGOT = true;
-
+
return Type;
}
Added: llvm/trunk/test/MC/ARM/elf-reloc-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-01.ll?rev=124996&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/elf-reloc-01.ll (added)
+++ llvm/trunk/test/MC/ARM/elf-reloc-01.ll Sun Feb 6 19:11:15 2011
@@ -0,0 +1,71 @@
+;; RUN: llc -mtriple=armv7-linux-gnueabi -O3 \
+;; RUN: -mcpu=cortex-a8 -mattr=-neon -mattr=+vfp2 -arm-reserve-r9 \
+;; RUN: -filetype=obj %s -o - | \
+;; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s
+
+;; FIXME: This file needs to be in .s form!
+;; The args to llc are there to constrain the codegen only.
+;;
+;; Ensure no regression on ARM/gcc compatibility for
+;; emitting explicit symbol relocs for nonexternal symbols
+;; versus section symbol relocs (with offset) -
+;;
+;; Default llvm behavior is to emit as section symbol relocs nearly
+;; everything that is not an undefined external. Unfortunately, this
+;; diverges from what codesourcery ARM/gcc does!
+;;
+;; Tests that reloc to _MergedGlobals show up as explicit symbol reloc
+
+
+target triple = "armv7-none-linux-gnueabi"
+
+ at var_tls = thread_local global i32 1
+ at var_tls_double = thread_local global double 1.000000e+00
+ at var_static = internal global i32 1
+ at var_static_double = internal global double 1.000000e+00
+ at var_global = global i32 1
+ at var_global_double = global double 1.000000e+00
+
+declare i32 @mystrlen(i8* nocapture %s) nounwind
+
+declare void @myhextochar(i32 %n, i8* nocapture %buffer)
+
+declare void @__aeabi_read_tp() nounwind
+
+declare void @__nacl_read_tp() nounwind
+
+define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
+entry:
+ switch i32 %argc, label %bb3 [
+ i32 555, label %bb
+ i32 6666, label %bb2
+ ]
+
+bb: ; preds = %entry
+ volatile store i32 11, i32* @var_tls, align 4
+ volatile store double 2.200000e+01, double* @var_tls_double, align 8
+ volatile store i32 33, i32* @var_static, align 4
+ volatile store double 4.400000e+01, double* @var_static_double, align 8
+ volatile store i32 55, i32* @var_global, align 4
+ volatile store double 6.600000e+01, double* @var_global_double, align 8
+ br label %bb3
+
+bb2: ; preds = %entry
+ ret i32 add (i32 add (i32 add (i32 ptrtoint (i32* @var_tls to i32), i32 add (i32 ptrtoint (i32* @var_static to i32), i32 ptrtoint (i32* @var_global to i32))), i32 ptrtoint (double* @var_tls_double to i32)), i32 add (i32 ptrtoint (double* @var_static_double to i32), i32 ptrtoint (double* @var_global_double to i32)))
+
+bb3: ; preds = %bb, %entry
+ tail call void @exit(i32 55) noreturn nounwind
+ unreachable
+}
+
+declare void @exit(i32) noreturn nounwind
+
+
+;; OBJ: Symbol 0x00000002
+;; OBJ-NEXT: '_MergedGlobals'
+;; OBJ-NEXT: 'st_value', 0x00000010
+
+;; OBJ: Relocation 0x00000001
+;; OBJ-NEXT: 'r_offset',
+;; OBJ-NEXT: 'r_sym', 0x00000002
+;; OBJ-NEXT: 'r_type', 0x0000002b
Added: llvm/trunk/test/MC/ARM/elf-reloc-02.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-02.ll?rev=124996&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/elf-reloc-02.ll (added)
+++ llvm/trunk/test/MC/ARM/elf-reloc-02.ll Sun Feb 6 19:11:15 2011
@@ -0,0 +1,51 @@
+;; RUN: llc -mtriple=armv7-linux-gnueabi -O3 \
+;; RUN: -mcpu=cortex-a8 -mattr=-neon -mattr=+vfp2 -arm-reserve-r9 \
+;; RUN: -filetype=obj %s -o - | \
+;; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s
+
+;; FIXME: This file needs to be in .s form!
+;; The args to llc are there to constrain the codegen only.
+;;
+;; Ensure no regression on ARM/gcc compatibility for
+;; emitting explicit symbol relocs for nonexternal symbols
+;; versus section symbol relocs (with offset) -
+;;
+;; Default llvm behavior is to emit as section symbol relocs nearly
+;; everything that is not an undefined external. Unfortunately, this
+;; diverges from what codesourcery ARM/gcc does!
+;;
+;; Tests that reloc to .L.str* show up as explicit symbols
+
+target triple = "armv7-none-linux-gnueabi"
+
+ at .str = private constant [7 x i8] c"@null\0A\00", align 4
+ at .str1 = private constant [8 x i8] c"@write\0A\00", align 4
+ at .str2 = private constant [13 x i8] c"hello worldn\00", align 4
+ at .str3 = private constant [7 x i8] c"@exit\0A\00", align 4
+
+declare i32 @mystrlen(i8* nocapture %s) nounwind readonly
+
+declare void @myhextochar(i32 %n, i8* nocapture %buffer) nounwind
+
+define i32 @main() nounwind {
+entry:
+ %0 = tail call i32 (...)* @write(i32 1, i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 6) nounwind
+ %1 = tail call i32 (...)* @write(i32 1, i8* getelementptr inbounds ([8 x i8]* @.str1, i32 0, i32 0), i32 7) nounwind
+ %2 = tail call i32 (...)* @write(i32 1, i8* getelementptr inbounds ([13 x i8]* @.str2, i32 0, i32 0), i32 12) nounwind
+ %3 = tail call i32 (...)* @write(i32 1, i8* getelementptr inbounds ([7 x i8]* @.str3, i32 0, i32 0), i32 6) nounwind
+ tail call void @exit(i32 55) noreturn nounwind
+ unreachable
+}
+
+declare i32 @write(...)
+
+declare void @exit(i32) noreturn nounwind
+
+
+;; OBJ: Symbol 0x00000002
+;; OBJ-NEXT: '.L.str'
+
+;; OBJ: Relocation 0x00000000
+;; OBJ-NEXT: 'r_offset',
+;; OBJ-NEXT: 'r_sym', 0x00000002
+;; OBJ-NEXT: 'r_type', 0x0000002b
Added: llvm/trunk/test/MC/ARM/elf-reloc-03.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-03.ll?rev=124996&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/elf-reloc-03.ll (added)
+++ llvm/trunk/test/MC/ARM/elf-reloc-03.ll Sun Feb 6 19:11:15 2011
@@ -0,0 +1,98 @@
+;; RUN: llc -mtriple=armv7-linux-gnueabi -O3 \
+;; RUN: -mcpu=cortex-a8 -mattr=-neon -mattr=+vfp2 -arm-reserve-r9 \
+;; RUN: -filetype=obj %s -o - | \
+;; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s
+
+;; FIXME: This file needs to be in .s form!
+;; The args to llc are there to constrain the codegen only.
+;;
+;; Ensure no regression on ARM/gcc compatibility for
+;; emitting explicit symbol relocs for nonexternal symbols
+;; versus section symbol relocs (with offset) -
+;;
+;; Default llvm behavior is to emit as section symbol relocs nearly
+;; everything that is not an undefined external. Unfortunately, this
+;; diverges from what codesourcery ARM/gcc does!
+;;
+;; Verifies that internal constants appear as explict symbol relocs
+
+
+target triple = "armv7-none-linux-gnueabi"
+
+ at startval = global i32 5
+ at vtable = internal constant [10 x i32 (...)*] [i32 (...)* bitcast (i32 ()* @foo0 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo1 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo2 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo3 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo4 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo5 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo6 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo7 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo8 to i32 (...)*), i32 (...)* bitcast (i32 ()* @foo9 to i32 (...)*)]
+
+declare i32 @mystrlen(i8* nocapture %s) nounwind readonly
+
+declare void @myhextochar(i32 %n, i8* nocapture %buffer) nounwind
+
+define internal i32 @foo0() nounwind readnone {
+entry:
+ ret i32 0
+}
+
+define internal i32 @foo1() nounwind readnone {
+entry:
+ ret i32 1
+}
+
+define internal i32 @foo2() nounwind readnone {
+entry:
+ ret i32 2
+}
+
+define internal i32 @foo3() nounwind readnone {
+entry:
+ ret i32 3
+}
+
+define internal i32 @foo4() nounwind readnone {
+entry:
+ ret i32 4
+}
+
+define internal i32 @foo5() nounwind readnone {
+entry:
+ ret i32 55
+}
+
+define internal i32 @foo6() nounwind readnone {
+entry:
+ ret i32 6
+}
+
+define internal i32 @foo7() nounwind readnone {
+entry:
+ ret i32 7
+}
+
+define internal i32 @foo8() nounwind readnone {
+entry:
+ ret i32 8
+}
+
+define internal i32 @foo9() nounwind readnone {
+entry:
+ ret i32 9
+}
+
+define i32 @main() nounwind {
+entry:
+ %0 = load i32* @startval, align 4
+ %1 = getelementptr inbounds [10 x i32 (...)*]* @vtable, i32 0, i32 %0
+ %2 = load i32 (...)** %1, align 4
+ %3 = tail call i32 (...)* %2() nounwind
+ tail call void @exit(i32 %3) noreturn nounwind
+ unreachable
+}
+
+declare void @exit(i32) noreturn nounwind
+
+
+;; OBJ: Symbol 0x0000000c
+;; OBJ-NEXT: 'vtable'
+
+;; OBJ: Relocation 0x00000001
+;; OBJ-NEXT: 'r_offset',
+;; OBJ-NEXT: 'r_sym', 0x0000000c
+;; OBJ-NEXT: 'r_type', 0x0000002b
More information about the llvm-commits
mailing list