summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp5
-rw-r--r--llvm/test/MC/MachO/x86_32-scattered-reloc-fallback.s27
2 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index eb7c0b1a996..0f16621b852 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -362,6 +362,7 @@ bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,
MCValue Target,
unsigned Log2Size,
uint64_t &FixedValue) {
+ uint64_t OriginalFixedValue = FixedValue;
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
unsigned Type = MachO::GENERIC_RELOC_VANILLA;
@@ -431,8 +432,10 @@ bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,
// symbol, things can go badly.
//
// Required for 'as' compatibility.
- if (FixupOffset > 0xffffff)
+ if (FixupOffset > 0xffffff) {
+ FixedValue = OriginalFixedValue;
return false;
+ }
}
MachO::any_relocation_info MRE;
diff --git a/llvm/test/MC/MachO/x86_32-scattered-reloc-fallback.s b/llvm/test/MC/MachO/x86_32-scattered-reloc-fallback.s
new file mode 100644
index 00000000000..3de52b4228d
--- /dev/null
+++ b/llvm/test/MC/MachO/x86_32-scattered-reloc-fallback.s
@@ -0,0 +1,27 @@
+// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s
+
+// rdar://15526046
+
+.text
+.globl _main
+_main:
+ .space 0x01020f55, 0x90
+bug:
+ movl $0, _key64b_9+4
+.section __TEXT, __padding
+ .space 0x515b91, 0
+.data
+ .space 0xa70, 0
+.globl _key64b_9
+_key64b_9:
+ .long 1
+ .long 2
+
+// The movl instruction above should produce this encoding where the address
+// of _key64b_9 is at 0x01537560. This is testing falling back from using a
+// scattered relocation to a normal relocation because the offset from the
+// start of the section is more than 24-bits. But need to get the item to
+// be relocated, in this case _key64b_9+4, value correct in the instruction.
+// 01020f55 c7056475530100000000 movl $0x0, 0x1537564
+
+// CHECK: 90c70564 75530100 000000')
OpenPOWER on IntegriCloud