MC/Mach-O: For PCrel relocations, we need to compensate for the PCrel adjustment when determining if we need a scattered relocation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98082 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2010-03-09 21:27:58 +00:00
parent aef9d7af69
commit f3a066f7c3
2 changed files with 71 additions and 5 deletions

View File

@ -504,15 +504,21 @@ public:
MCAsmFixup &Fixup,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
MCValue Target;
if (!Fixup.Value->EvaluateAsRelocatable(Target))
llvm_report_error("expected relocatable expression");
// If this is a difference or a local symbol plus an offset, then we need a
// scattered relocation entry.
// If this is a difference or a defined symbol plus an offset, then we need
// a scattered relocation entry.
uint32_t Offset = Target.getConstant();
if (IsPCRel)
Offset += 1 << Log2Size;
if (Target.getSymB() ||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
Target.getConstant()))
Offset))
return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
SymbolMap, Relocs);
@ -520,8 +526,6 @@ public:
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned IsExtern = 0;
unsigned Type = 0;

View File

@ -0,0 +1,62 @@
// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
// CHECK: # Relocation 0
// CHECK: (('word-0', 0xe4000045),
// CHECK: ('word-1', 0x4)),
// CHECK: # Relocation 1
// CHECK: (('word-0', 0xe1000000),
// CHECK: ('word-1', 0x6)),
// CHECK: # Relocation 2
// CHECK: (('word-0', 0x40),
// CHECK: ('word-1', 0xd000002)),
// CHECK: # Relocation 3
// CHECK: (('word-0', 0x3b),
// CHECK: ('word-1', 0xd000002)),
// CHECK: # Relocation 4
// CHECK: (('word-0', 0x36),
// CHECK: ('word-1', 0xd000002)),
// CHECK: # Relocation 5
// CHECK: (('word-0', 0xe0000031),
// CHECK: ('word-1', 0x4)),
// CHECK: # Relocation 6
// CHECK: (('word-0', 0xe000002c),
// CHECK: ('word-1', 0x4)),
// CHECK: # Relocation 7
// CHECK: (('word-0', 0x27),
// CHECK: ('word-1', 0x5000001)),
// CHECK: # Relocation 8
// CHECK: (('word-0', 0xe0000022),
// CHECK: ('word-1', 0x2)),
// CHECK: # Relocation 9
// CHECK: (('word-0', 0xe000001d),
// CHECK: ('word-1', 0x2)),
// CHECK: # Relocation 10
// CHECK: (('word-0', 0x18),
// CHECK: ('word-1', 0x5000001)),
// CHECK-NEXT: ])
xorl %eax,%eax
.globl _a
_a:
xorl %eax,%eax
_b:
xorl %eax,%eax
L0:
xorl %eax,%eax
L1:
call L0
call L0 - 1
call L0 + 1
call _a
call _a - 1
call _a + 1
call _b
call _b - 1
call _b + 1
call _c
call _c - 1
call _c + 1
// call _a - L0
call _b - L0