[lld] r213340 - [mach-o] Add support for x86 CALL instruction that uses a scattered relocation
Nick Kledzik
kledzik at apple.com
Thu Jul 17 17:37:52 PDT 2014
Author: kledzik
Date: Thu Jul 17 19:37:52 2014
New Revision: 213340
URL: http://llvm.org/viewvc/llvm-project?rev=213340&view=rev
Log:
[mach-o] Add support for x86 CALL instruction that uses a scattered relocation
Modified:
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
lld/trunk/test/mach-o/parse-relocs-x86.yaml
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=213340&r1=213339&r2=213340&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Thu Jul 17 19:37:52 2014
@@ -202,6 +202,14 @@ ArchHandler_x86::getReferenceInfo(const
targetAddress = fixupAddress + 4 + readS32(swap, fixupContent);
return atomFromAddress(reloc.symbol, targetAddress, target, addend);
break;
+ case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength4:
+ // ex: call _foo+n (and _foo defined)
+ *kind = branch32;
+ targetAddress = fixupAddress + 4 + readS32(swap, fixupContent);
+ if (E ec = atomFromAddress(0, reloc.value, target, addend))
+ return ec;
+ *addend = targetAddress - reloc.value;
+ break;
case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2:
// ex: callw _foo (and _foo undefined)
*kind = branch16;
@@ -215,6 +223,14 @@ ArchHandler_x86::getReferenceInfo(const
targetAddress = fixupAddress + 2 + readS16(swap, fixupContent);
return atomFromAddress(reloc.symbol, targetAddress, target, addend);
break;
+ case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength2:
+ // ex: callw _foo+n (and _foo defined)
+ *kind = branch16;
+ targetAddress = fixupAddress + 2 + readS16(swap, fixupContent);
+ if (E ec = atomFromAddress(0, reloc.value, target, addend))
+ return ec;
+ *addend = targetAddress - reloc.value;
+ break;
case GENERIC_RELOC_VANILLA | rExtern | rLength4:
// ex: movl _foo, %eax (and _foo undefined)
// ex: .long _foo (and _foo undefined)
@@ -370,12 +386,19 @@ void ArchHandler_x86::applyFixupRelocata
uint64_t inAtomAddress) {
int32_t *loc32 = reinterpret_cast<int32_t *>(location);
int16_t *loc16 = reinterpret_cast<int16_t *>(location);
+ bool useExternalReloc = useExternalRelocationTo(*ref.target());
switch (ref.kindValue()) {
case branch32:
- write32(*loc32, _swap, ref.addend() - (fixupAddress + 4));
+ if (useExternalReloc)
+ write32(*loc32, _swap, ref.addend() - (fixupAddress + 4));
+ else
+ write32(*loc32, _swap, (targetAddress - (fixupAddress+4)) + ref.addend());
break;
case branch16:
- write16(*loc16, _swap, ref.addend() - (fixupAddress + 2));
+ if (useExternalReloc)
+ write16(*loc16, _swap, ref.addend() - (fixupAddress + 2));
+ else
+ write16(*loc16, _swap, (targetAddress - (fixupAddress+2)) + ref.addend());
break;
case pointer32:
case abs32:
@@ -434,20 +457,30 @@ void ArchHandler_x86::appendSectionReloc
bool useExternalReloc = useExternalRelocationTo(*ref.target());
switch (ref.kindValue()) {
case branch32:
- if (useExternalReloc)
- appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
- GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength4);
- else
- appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
- GENERIC_RELOC_VANILLA | rPcRel | rLength4);
+ if (useExternalReloc) {
+ appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
+ GENERIC_RELOC_VANILLA | rExtern | rPcRel | rLength4);
+ } else {
+ if (ref.addend() != 0)
+ appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+ GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength4);
+ else
+ appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
+ GENERIC_RELOC_VANILLA | rPcRel | rLength4);
+ }
break;
case branch16:
- if (useExternalReloc)
- appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
- GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2);
- else
- appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
- GENERIC_RELOC_VANILLA | rPcRel | rLength2);
+ if (useExternalReloc) {
+ appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
+ GENERIC_RELOC_VANILLA | rExtern | rPcRel | rLength2);
+ } else {
+ if (ref.addend() != 0)
+ appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+ GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength2);
+ else
+ appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
+ GENERIC_RELOC_VANILLA | rPcRel | rLength2);
+ }
break;
case pointer32:
case abs32:
Modified: lld/trunk/test/mach-o/parse-relocs-x86.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-relocs-x86.yaml?rev=213340&r1=213339&r2=213340&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-relocs-x86.yaml (original)
+++ lld/trunk/test/mach-o/parse-relocs-x86.yaml Thu Jul 17 19:37:52 2014
@@ -12,16 +12,24 @@
#_test:
# call _undef
# call _undef+2
+# call _foo
+# call _foo+2
# callw _undef
+# callw _foo
+# callw _foo+2
#L1:
# movl _undef, %eax
# movl _x, %eax
# movl _x-L1(%eax), %eax
# movl _x+4-L1(%eax), %eax
#
+#_foo:
+# ret
+#
# .data
#_x:
# .long _undef
+# .long _foo
# .long _test - .
# .long _test+3 - .
#
@@ -29,7 +37,7 @@
--- !mach-o
arch: x86
file-type: MH_OBJECT
-flags: [ ]
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
OS: unknown
sections:
- segment: __TEXT
@@ -38,74 +46,100 @@ sections:
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
address: 0x0000000000000000
content: [ 0xE8, 0xFB, 0xFF, 0xFF, 0xFF, 0xE8, 0xF8, 0xFF,
- 0xFF, 0xFF, 0x66, 0xE8, 0xF2, 0xFF, 0xA1, 0x00,
- 0x00, 0x00, 0x00, 0xA1, 0x24, 0x00, 0x00, 0x00,
- 0x8B, 0x80, 0x16, 0x00, 0x00, 0x00, 0x8B, 0x80,
- 0x1A, 0x00, 0x00, 0x00 ]
+ 0xFF, 0xFF, 0xE8, 0x27, 0x00, 0x00, 0x00, 0xE8,
+ 0x24, 0x00, 0x00, 0x00, 0x66, 0xE8, 0xE8, 0xFF,
+ 0x66, 0xE8, 0x1A, 0x00, 0x66, 0xE8, 0x18, 0x00,
+ 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x37, 0x00,
+ 0x00, 0x00, 0x8B, 0x80, 0x17, 0x00, 0x00, 0x00,
+ 0x8B, 0x80, 0x1B, 0x00, 0x00, 0x00, 0xC3 ]
relocations:
- - offset: 0x00000020
+ - offset: 0x00000032
scattered: true
type: GENERIC_RELOC_LOCAL_SECTDIFF
length: 2
pc-rel: false
- value: 0x00000024
+ value: 0x00000037
- offset: 0x00000000
scattered: true
type: GENERIC_RELOC_PAIR
length: 2
pc-rel: false
- value: 0x0000000E
- - offset: 0x0000001A
+ value: 0x00000020
+ - offset: 0x0000002C
scattered: true
type: GENERIC_RELOC_LOCAL_SECTDIFF
length: 2
pc-rel: false
- value: 0x00000024
+ value: 0x00000037
- offset: 0x00000000
scattered: true
type: GENERIC_RELOC_PAIR
length: 2
pc-rel: false
- value: 0x0000000E
- - offset: 0x00000014
+ value: 0x00000020
+ - offset: 0x00000026
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: false
extern: false
symbol: 2
- - offset: 0x0000000F
+ - offset: 0x00000021
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x0000000C
+ symbol: 3
+ - offset: 0x0000001E
+ scattered: true
+ type: GENERIC_RELOC_VANILLA
+ length: 1
+ pc-rel: true
+ value: 0x00000036
+ - offset: 0x0000001A
+ type: GENERIC_RELOC_VANILLA
+ length: 1
+ pc-rel: true
+ extern: false
+ symbol: 1
+ - offset: 0x00000016
type: GENERIC_RELOC_VANILLA
length: 1
pc-rel: true
extern: true
- symbol: 2
+ symbol: 3
+ - offset: 0x00000010
+ scattered: true
+ type: GENERIC_RELOC_VANILLA
+ length: 2
+ pc-rel: true
+ value: 0x00000036
+ - offset: 0x0000000B
+ type: GENERIC_RELOC_VANILLA
+ length: 2
+ pc-rel: true
+ extern: false
+ symbol: 1
- offset: 0x00000006
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: true
extern: true
- symbol: 2
+ symbol: 3
- offset: 0x00000001
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: true
extern: true
- symbol: 2
+ symbol: 3
- segment: __DATA
section: __data
type: S_REGULAR
attributes: [ ]
- address: 0x0000000000000024
- content: [ 0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xFF, 0xFF,
- 0xD7, 0xFF, 0xFF, 0xFF ]
+ address: 0x0000000000000037
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
+ 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF ]
relocations:
- - offset: 0x00000008
+ - offset: 0x0000000C
scattered: true
type: GENERIC_RELOC_LOCAL_SECTDIFF
length: 2
@@ -116,8 +150,8 @@ sections:
type: GENERIC_RELOC_PAIR
length: 2
pc-rel: false
- value: 0x0000002C
- - offset: 0x00000004
+ value: 0x00000043
+ - offset: 0x00000008
scattered: true
type: GENERIC_RELOC_LOCAL_SECTDIFF
length: 2
@@ -128,22 +162,32 @@ sections:
type: GENERIC_RELOC_PAIR
length: 2
pc-rel: false
- value: 0x00000028
+ value: 0x0000003F
+ - offset: 0x00000004
+ type: GENERIC_RELOC_VANILLA
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 1
- offset: 0x00000000
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: false
extern: true
- symbol: 2
+ symbol: 3
local-symbols:
- name: _test
type: N_SECT
sect: 1
value: 0x0000000000000000
+ - name: _foo
+ type: N_SECT
+ sect: 1
+ value: 0x0000000000000036
- name: _x
type: N_SECT
sect: 2
- value: 0x0000000000000024
+ value: 0x0000000000000037
undefined-symbols:
- name: _undef
type: N_UNDF
@@ -158,12 +202,15 @@ undefined-symbols:
# CHECK: - kind: pointer32
# CHECK: offset: 0
# CHECK: target: _undef
-# CHECK: - kind: delta32
+# CHECK: - kind: pointer32
# CHECK: offset: 4
-# CHECK: target: _test
+# CHECK: target: _foo
# CHECK: - kind: delta32
# CHECK: offset: 8
# CHECK: target: _test
+# CHECK: - kind: delta32
+# CHECK: offset: 12
+# CHECK: target: _test
# CHECK: addend: 3
# CHECK: - name: _test
# CHECK: references:
@@ -175,21 +222,38 @@ undefined-symbols:
# CHECK: offset: 6
# CHECK: target: _undef
# CHECK: addend: 2
+# CHECK: - kind: branch32
+# CHECK: offset: 11
+# CHECK: target: _foo
+# CHECK-NOT: addend:
+# CHECK: - kind: branch32
+# CHECK: offset: 16
+# CHECK: target: _foo
+# CHECK: addend: 2
# CHECK: - kind: branch16
-# CHECK: offset: 12
+# CHECK: offset: 22
# CHECK: target: _undef
+# CHECK-NOT: addend:
+# CHECK: - kind: branch16
+# CHECK: offset: 26
+# CHECK: target: _foo
+# CHECK-NOT: addend:
+# CHECK: - kind: branch16
+# CHECK: offset: 30
+# CHECK: target: _foo
+# CHECK: addend: 2
# CHECK: - kind: abs32
-# CHECK: offset: 15
+# CHECK: offset: 33
# CHECK: target: _undef
# CHECK: - kind: abs32
-# CHECK: offset: 20
+# CHECK: offset: 38
# CHECK: target: _x
# CHECK: - kind: funcRel32
-# CHECK: offset: 26
+# CHECK: offset: 44
# CHECK: target: _x
-# CHECK: addend: -14
+# CHECK: addend: -32
# CHECK: - kind: funcRel32
-# CHECK: offset: 32
+# CHECK: offset: 50
# CHECK: target: _x
-# CHECK: addend: -10
+# CHECK: addend: -28
More information about the llvm-commits
mailing list