aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2010-10-02 00:13:41 +0000
committerKevin Enderby <enderby@apple.com>2010-10-02 00:13:41 +0000
commit8c9aa922a94bd788ea061be7555fb5b1db3a5312 (patch)
treee323514b13a8df4681c7fd24b05b77bc44da23e3 /lib/MC
parent5f2d1fa0f7c484f319d20e7f1c04f110a4b86648 (diff)
downloadexternal_llvm-8c9aa922a94bd788ea061be7555fb5b1db3a5312.zip
external_llvm-8c9aa922a94bd788ea061be7555fb5b1db3a5312.tar.gz
external_llvm-8c9aa922a94bd788ea061be7555fb5b1db3a5312.tar.bz2
This adds a Darwin x86_64 relocation encoding for a subtraction expression
where both symbols are "local", that is non-external symbols, and there is no "base" for the symbols used in the expression, that is the section has no non-temporary symbols. This case looks like this: % cat local_reloc_A-B.s .long 0 LB: .long 1 .long LA - LB - 4 .long 2 LA: .long 3 which llvm-mc will not encode without this patch, generates a "unsupported local relocations in difference" error, but the Darwin assembler will encode with relocation entries like this: % otool -rv a.out l.out a.out: Relocation information (__TEXT,__text) 2 entries address pcrel length extern type scattered symbolnum/value 00000008 False long False SUB False 1 (__TEXT,__text) 00000008 False long False UNSIGND False 1 (__TEXT,__text) which is very similar to what is encoded when the symbols don't have the leading 'L' and they are not temporary symbols. Which llvm-mc and the Darwin assembler will encoded like this: Relocation information (__TEXT,__text) 2 entries address pcrel length extern type scattered symbolnum/value 00000008 False long True SUB False B 00000008 False long True UNSIGND False A This is the missing relocation encoding needed to allow the Mach-O x86 Dwarf file and line table to be emitted. So this patch also removes the TODO from the if() statement in MCMachOStreamer::Finish() that didn't call MCDwarfFileTable::Emit() for 64-bit targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115389 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCMachOStreamer.cpp10
-rw-r--r--lib/MC/MachObjectWriter.cpp42
2 files changed, 30 insertions, 22 deletions
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 42de0ae..a10a63e 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -441,15 +441,7 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
void MCMachOStreamer::Finish() {
// Dump out the dwarf file & directory tables and line tables.
- if (getContext().hasDwarfFiles() &&
- // TODO: This not enabled for 64-bit Mach-O targets. As there are needed
- // changes in the handling of 64-bit relocation entries for dwarf Mach-O
- // sections that need to made. Currently it gets
- // LLVM ERROR: unsupported local relocations in difference
- // due dealing with "a-b" expressions made up for dwarf line entries
- // because the line section has no non-local symbols thus it can't find
- // an atom symbol for the base.
- getAssembler().getBackend().getPointerSize() != 8) {
+ if (getContext().hasDwarfFiles()) {
const MCSection *DwarfLineSection = getContext().getMachOSection("__DWARF",
"__debug_line",
MCSectionMachO::S_ATTR_DEBUG,
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 689aabc..4bb0535 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -616,22 +616,32 @@ public:
if (IsPCRel)
report_fatal_error("unsupported pc-relative relocation of difference");
- // We don't currently support any situation where one or both of the
- // symbols would require a local relocation. This is almost certainly
- // unused and may not be possible to encode correctly.
- if (!A_Base || !B_Base)
- report_fatal_error("unsupported local relocations in difference");
+ // The support for the situation where one or both of the symbols would
+ // require a local relocation is handled just like if the symbols were
+ // external. This is certainly used in the case of debug sections where
+ // the section has only temporary symbols and thus the symbols don't have
+ // base symbols. This is encoded using the section ordinal and
+ // non-extern relocation entries.
// Darwin 'as' doesn't emit correct relocations for this (it ends up with
- // a single SIGNED relocation); reject it for now.
- if (A_Base == B_Base)
+ // a single SIGNED relocation); reject it for now. Except the case where
+ // both symbols don't have a base, equal but both NULL.
+ if (A_Base == B_Base && A_Base)
report_fatal_error("unsupported relocation with identical base");
- Value += Layout.getSymbolAddress(&A_SD) - Layout.getSymbolAddress(A_Base);
- Value -= Layout.getSymbolAddress(&B_SD) - Layout.getSymbolAddress(B_Base);
+ Value += Layout.getSymbolAddress(&A_SD) -
+ (A_Base == NULL ? 0 : Layout.getSymbolAddress(A_Base));
+ Value -= Layout.getSymbolAddress(&B_SD) -
+ (B_Base == NULL ? 0 : Layout.getSymbolAddress(B_Base));
- Index = A_Base->getIndex();
- IsExtern = 1;
+ if (A_Base) {
+ Index = A_Base->getIndex();
+ IsExtern = 1;
+ }
+ else {
+ Index = A_SD.getFragment()->getParent()->getOrdinal() + 1;
+ IsExtern = 0;
+ }
Type = RIT_X86_64_Unsigned;
MachRelocationEntry MRE;
@@ -643,8 +653,14 @@ public:
(Type << 28));
Relocations[Fragment->getParent()].push_back(MRE);
- Index = B_Base->getIndex();
- IsExtern = 1;
+ if (B_Base) {
+ Index = B_Base->getIndex();
+ IsExtern = 1;
+ }
+ else {
+ Index = B_SD.getFragment()->getParent()->getOrdinal() + 1;
+ IsExtern = 0;
+ }
Type = RIT_X86_64_Subtractor;
} else {
const MCSymbol *Symbol = &Target.getSymA()->getSymbol();