diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler.cpp --- a/lld/lib/ReaderWriter/MachO/ArchHandler.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler.cpp @@ -135,7 +135,7 @@ return read32(addr, isBig); } - int64_t ArchHandler::readS64(const uint8_t *addr, bool isBig) { +int64_t ArchHandler::readS64(const uint8_t *addr, bool isBig) { return read64(addr, isBig); } diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -181,6 +181,20 @@ FindAddressForAtom addressForAtom, normalized::Relocations &relocs) override; + bool isDataInCodeTransition(Reference::KindValue refKind) override { + return refKind == modeCode || refKind == modeData; + } + + Reference::KindValue dataInCodeTransitionStart( + const MachODefinedAtom &atom) override { + return modeData; + } + + Reference::KindValue dataInCodeTransitionEnd( + const MachODefinedAtom &atom) override { + return modeCode; + } + private: static const Registry::KindStrings _sKindStrings[]; static const StubInfo _sStubInfo; @@ -188,6 +202,9 @@ enum X86_64Kind: Reference::KindValue { invalid, /// for error condition + modeCode, /// Content starting at this offset is code. + modeData, /// Content starting at this offset is data. + // Kinds found in mach-o .o files: branch32, /// ex: call _foo ripRel32, /// ex: movq _foo(%rip), %rax @@ -242,24 +259,34 @@ }; const Registry::KindStrings ArchHandler_x86_64::_sKindStrings[] = { - LLD_KIND_STRING_ENTRY(invalid), LLD_KIND_STRING_ENTRY(branch32), - LLD_KIND_STRING_ENTRY(ripRel32), LLD_KIND_STRING_ENTRY(ripRel32Minus1), - LLD_KIND_STRING_ENTRY(ripRel32Minus2), LLD_KIND_STRING_ENTRY(ripRel32Minus4), + LLD_KIND_STRING_ENTRY(invalid), + LLD_KIND_STRING_ENTRY(modeCode), + LLD_KIND_STRING_ENTRY(modeData), + LLD_KIND_STRING_ENTRY(branch32), + LLD_KIND_STRING_ENTRY(ripRel32), + LLD_KIND_STRING_ENTRY(ripRel32Minus1), + LLD_KIND_STRING_ENTRY(ripRel32Minus2), + LLD_KIND_STRING_ENTRY(ripRel32Minus4), LLD_KIND_STRING_ENTRY(ripRel32Anon), LLD_KIND_STRING_ENTRY(ripRel32Minus1Anon), LLD_KIND_STRING_ENTRY(ripRel32Minus2Anon), LLD_KIND_STRING_ENTRY(ripRel32Minus4Anon), LLD_KIND_STRING_ENTRY(ripRel32GotLoad), LLD_KIND_STRING_ENTRY(ripRel32GotLoadNowLea), - LLD_KIND_STRING_ENTRY(ripRel32Got), LLD_KIND_STRING_ENTRY(ripRel32Tlv), + LLD_KIND_STRING_ENTRY(ripRel32Got), + LLD_KIND_STRING_ENTRY(ripRel32Tlv), LLD_KIND_STRING_ENTRY(lazyPointer), LLD_KIND_STRING_ENTRY(lazyImmediateLocation), - LLD_KIND_STRING_ENTRY(pointer64), LLD_KIND_STRING_ENTRY(pointer64Anon), - LLD_KIND_STRING_ENTRY(delta32), LLD_KIND_STRING_ENTRY(delta64), - LLD_KIND_STRING_ENTRY(delta32Anon), LLD_KIND_STRING_ENTRY(delta64Anon), + LLD_KIND_STRING_ENTRY(pointer64), + LLD_KIND_STRING_ENTRY(pointer64Anon), + LLD_KIND_STRING_ENTRY(delta32), + LLD_KIND_STRING_ENTRY(delta64), + LLD_KIND_STRING_ENTRY(delta32Anon), + LLD_KIND_STRING_ENTRY(delta64Anon), LLD_KIND_STRING_ENTRY(negDelta64), LLD_KIND_STRING_ENTRY(negDelta32), - LLD_KIND_STRING_ENTRY(imageOffset), LLD_KIND_STRING_ENTRY(imageOffsetGot), + LLD_KIND_STRING_ENTRY(imageOffset), + LLD_KIND_STRING_ENTRY(imageOffsetGot), LLD_KIND_STRING_ENTRY(unwindFDEToFunction), LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame), LLD_KIND_STRING_ENTRY(tlvInitSectionOffset), @@ -601,6 +628,8 @@ case negDelta32: *loc32 = fixupAddress - targetAddress + ref.addend(); return; + case modeCode: + case modeData: case lazyPointer: // Do nothing return; @@ -720,6 +749,8 @@ case unwindInfoToEhFrame: llvm_unreachable("fixup implies __unwind_info"); return; + case modeCode: + case modeData: case unwindFDEToFunction: // Do nothing for now return; @@ -743,6 +774,9 @@ assert(ref.kindArch() == Reference::KindArch::x86_64); uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom(); switch (static_cast(ref.kindValue())) { + case modeCode: + case modeData: + return; case branch32: appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, X86_64_RELOC_BRANCH | rPcRel | rExtern | rLength4); diff --git a/lld/test/mach-o/parse-data-in-code-x86_64.yaml b/lld/test/mach-o/parse-data-in-code-x86_64.yaml new file mode 100644 --- /dev/null +++ b/lld/test/mach-o/parse-data-in-code-x86_64.yaml @@ -0,0 +1,77 @@ +# RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \ +# RUN: && ld64.lld -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s +# +# Test parsing LC_DATA_IN_CODE +# +# + +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] + address: 0x0000000000000000 + content: [ 0x90, 0x90, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x03, 0x00, + 0x00, 0x00 ] +local-symbols: + - name: _func1 + type: N_SECT + sect: 1 + value: 0x0000000000000000 + - name: _func2 + type: N_SECT + sect: 1 + value: 0x000000000000000B +dataInCode: + - offset: 0x00000002 + length: 0x0008 + kind: DICE_KIND_JUMP_TABLE32 + - offset: 0x0000000E + length: 0x0004 + kind: DICE_KIND_JUMP_TABLE32 +... + + + +# CHECK: defined-atoms: +# CHECK: - name: _func1 +# CHECK: references: +# CHECK: - kind: modeData +# CHECK: offset: 2 +# CHECK: addend: 4 +# CHECK: - kind: modeCode +# CHECK: offset: 10 +# CHECK: - name: _func2 +# CHECK: references: +# CHECK: - kind: modeData +# CHECK: offset: 3 +# CHECK: addend: 4 +# CHECK-NOT: - kind: modeData + + + + +# +#_func1: +# nop +# nop +# .data_region jt32 +# .long 1 +# .long 2 +# .end_data_region +# nop +# +# +# _func2: +# nop +# nop +# nop +# .data_region jt32 +# .long 3 +# .end_data_region +#