From 7e246a47f9b7452ba2741891fa3a5ee48007b0d1 Mon Sep 17 00:00:00 2001 From: Nick Kledzik Date: Fri, 18 Jul 2014 01:05:35 +0000 Subject: [PATCH] [mach-o] Add support for x86 pointers which use scattered relocations llvm-svn: 213344 --- lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp | 24 +++++-- lld/test/mach-o/parse-relocs-x86.yaml | 89 ++++++++++++++++++-------- 2 files changed, 83 insertions(+), 30 deletions(-) diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp index ae59a95..b54c00e 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp @@ -252,6 +252,16 @@ ArchHandler_x86::getReferenceInfo(const Relocation &reloc, targetAddress = readU32(swap, fixupContent); return atomFromAddress(reloc.symbol, targetAddress, target, addend); break; + case GENERIC_RELOC_VANILLA | rScattered | rLength4: + // ex: .long _foo+n (and _foo defined) + perms = inAtom->permissions(); + *kind = + ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? abs32 + : pointer32; + if (E ec = atomFromAddress(0, reloc.value, target, addend)) + return ec; + *addend = readU32(swap, fixupContent) - reloc.value; + break; default: return make_dynamic_error_code(Twine("unsupported i386 relocation type")); } @@ -486,10 +496,15 @@ void ArchHandler_x86::appendSectionRelocations( case abs32: if (useExternalReloc) appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, - GENERIC_RELOC_VANILLA | rExtern | rLength4); - else - appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, + GENERIC_RELOC_VANILLA | rExtern | rLength4); + else { + if (ref.addend() != 0) + appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()), + GENERIC_RELOC_VANILLA | rScattered | rLength4); + else + appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, GENERIC_RELOC_VANILLA | rLength4); + } break; case funcRel32: appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()), @@ -500,7 +515,8 @@ void ArchHandler_x86::appendSectionRelocations( case delta32: appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()), GENERIC_RELOC_SECTDIFF | rScattered | rLength4); - appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) + ref.offsetInAtom(), + appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) + + ref.offsetInAtom(), GENERIC_RELOC_PAIR | rScattered | rLength4); break; case lazyPointer: diff --git a/lld/test/mach-o/parse-relocs-x86.yaml b/lld/test/mach-o/parse-relocs-x86.yaml index bc0df00..3fc22ae 100644 --- a/lld/test/mach-o/parse-relocs-x86.yaml +++ b/lld/test/mach-o/parse-relocs-x86.yaml @@ -20,6 +20,7 @@ #L1: # movl _undef, %eax # movl _x, %eax +# movl _x+4, %eax # movl _x-L1(%eax), %eax # movl _x+4-L1(%eax), %eax # @@ -29,7 +30,9 @@ # .data #_x: # .long _undef +# .long _undef+7 # .long _foo +# .long _foo+3 # .long _test - . # .long _test+3 - . # @@ -46,37 +49,44 @@ sections: attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] address: 0x0000000000000000 content: [ 0xE8, 0xFB, 0xFF, 0xFF, 0xFF, 0xE8, 0xF8, 0xFF, - 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 ] + 0xFF, 0xFF, 0xE8, 0x2C, 0x00, 0x00, 0x00, 0xE8, + 0x29, 0x00, 0x00, 0x00, 0x66, 0xE8, 0xE8, 0xFF, + 0x66, 0xE8, 0x1F, 0x00, 0x66, 0xE8, 0x1D, 0x00, + 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x3C, 0x00, + 0x00, 0x00, 0xA1, 0x40, 0x00, 0x00, 0x00, 0x8B, + 0x80, 0x1C, 0x00, 0x00, 0x00, 0x8B, 0x80, 0x20, + 0x00, 0x00, 0x00, 0xC3 ] relocations: - - offset: 0x00000032 + - offset: 0x00000037 scattered: true type: GENERIC_RELOC_LOCAL_SECTDIFF length: 2 pc-rel: false - value: 0x00000037 + value: 0x0000003C - offset: 0x00000000 scattered: true type: GENERIC_RELOC_PAIR length: 2 pc-rel: false value: 0x00000020 - - offset: 0x0000002C + - offset: 0x00000031 scattered: true type: GENERIC_RELOC_LOCAL_SECTDIFF length: 2 pc-rel: false - value: 0x00000037 + value: 0x0000003C - offset: 0x00000000 scattered: true type: GENERIC_RELOC_PAIR length: 2 pc-rel: false value: 0x00000020 + - offset: 0x0000002B + scattered: true + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + value: 0x0000003C - offset: 0x00000026 type: GENERIC_RELOC_VANILLA length: 2 @@ -94,7 +104,7 @@ sections: type: GENERIC_RELOC_VANILLA length: 1 pc-rel: true - value: 0x00000036 + value: 0x0000003B - offset: 0x0000001A type: GENERIC_RELOC_VANILLA length: 1 @@ -112,7 +122,7 @@ sections: type: GENERIC_RELOC_VANILLA length: 2 pc-rel: true - value: 0x00000036 + value: 0x0000003B - offset: 0x0000000B type: GENERIC_RELOC_VANILLA length: 2 @@ -135,11 +145,12 @@ sections: section: __data type: S_REGULAR attributes: [ ] - address: 0x0000000000000037 - content: [ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, - 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF ] + address: 0x000000000000003C + content: [ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, + 0xB4, 0xFF, 0xFF, 0xFF, 0xB3, 0xFF, 0xFF, 0xFF ] relocations: - - offset: 0x0000000C + - offset: 0x00000014 scattered: true type: GENERIC_RELOC_LOCAL_SECTDIFF length: 2 @@ -150,8 +161,8 @@ sections: type: GENERIC_RELOC_PAIR length: 2 pc-rel: false - value: 0x00000043 - - offset: 0x00000008 + value: 0x00000050 + - offset: 0x00000010 scattered: true type: GENERIC_RELOC_LOCAL_SECTDIFF length: 2 @@ -162,13 +173,25 @@ sections: type: GENERIC_RELOC_PAIR length: 2 pc-rel: false - value: 0x0000003F - - offset: 0x00000004 + value: 0x0000004C + - offset: 0x0000000C + scattered: true + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + value: 0x0000003B + - offset: 0x00000008 type: GENERIC_RELOC_VANILLA length: 2 pc-rel: false extern: false symbol: 1 + - offset: 0x00000004 + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + extern: true + symbol: 3 - offset: 0x00000000 type: GENERIC_RELOC_VANILLA length: 2 @@ -183,11 +206,11 @@ local-symbols: - name: _foo type: N_SECT sect: 1 - value: 0x0000000000000036 + value: 0x000000000000003B - name: _x type: N_SECT sect: 2 - value: 0x0000000000000037 + value: 0x000000000000003C undefined-symbols: - name: _undef type: N_UNDF @@ -202,14 +225,24 @@ undefined-symbols: # CHECK: - kind: pointer32 # CHECK: offset: 0 # CHECK: target: _undef +# CHECK-NOT: addend: # CHECK: - kind: pointer32 # CHECK: offset: 4 +# CHECK: target: _undef +# CHECK: addend: 7 +# CHECK: - kind: pointer32 +# CHECK: offset: 8 # CHECK: target: _foo +# CHECK-NOT: addend: +# CHECK: - kind: pointer32 +# CHECK: offset: 12 +# CHECK: target: _foo +# CHECK: addend: 3 # CHECK: - kind: delta32 -# CHECK: offset: 8 +# CHECK: offset: 16 # CHECK: target: _test # CHECK: - kind: delta32 -# CHECK: offset: 12 +# CHECK: offset: 20 # CHECK: target: _test # CHECK: addend: 3 # CHECK: - name: _test @@ -248,12 +281,16 @@ undefined-symbols: # CHECK: - kind: abs32 # CHECK: offset: 38 # CHECK: target: _x +# CHECK: - kind: abs32 +# CHECK: offset: 43 +# CHECK: target: _x +# CHECK: addend: 4 # CHECK: - kind: funcRel32 -# CHECK: offset: 44 +# CHECK: offset: 49 # CHECK: target: _x # CHECK: addend: -32 # CHECK: - kind: funcRel32 -# CHECK: offset: 50 +# CHECK: offset: 55 # CHECK: target: _x # CHECK: addend: -28 -- 2.7.4