diff options
-rw-r--r-- | lib/MC/MCAssembler.cpp | 14 | ||||
-rw-r--r-- | test/MC/MachO/reloc-pcrel.s | 62 |
2 files changed, 71 insertions, 5 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index b3e8114b42..cf02cc15c5 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -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; diff --git a/test/MC/MachO/reloc-pcrel.s b/test/MC/MachO/reloc-pcrel.s new file mode 100644 index 0000000000..fff7cc0ada --- /dev/null +++ b/test/MC/MachO/reloc-pcrel.s @@ -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 |