diff options
author | Nick Kledzik <kledzik@apple.com> | 2014-07-02 23:52:22 +0000 |
---|---|---|
committer | Nick Kledzik <kledzik@apple.com> | 2014-07-02 23:52:22 +0000 |
commit | de0860aae4b2723f1a66005a07de2ea244faa082 (patch) | |
tree | 3123be3233d76ed8c45053a26f5271e4942bf303 | |
parent | bcb70eee1a38a6676ef9f9aa60575df2cec23219 (diff) | |
download | bcm5719-llvm-de0860aae4b2723f1a66005a07de2ea244faa082.tar.gz bcm5719-llvm-de0860aae4b2723f1a66005a07de2ea244faa082.zip |
[mach-o] add parsing of x86 relocations
llvm-svn: 212239
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h | 3 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 38 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp | 191 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.h | 57 | ||||
-rw-r--r-- | lld/test/mach-o/parse-cfstring32.yaml | 24 | ||||
-rw-r--r-- | lld/test/mach-o/parse-non-lazy-pointers.yaml | 13 | ||||
-rw-r--r-- | lld/test/mach-o/parse-relocs-x86.yaml | 190 |
7 files changed, 480 insertions, 36 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h index 8041fc4ea1d..5a61314b3d6 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h @@ -182,6 +182,9 @@ inline void swapStruct(llvm::MachO::nlist_64 &sym) { +inline uint16_t read16(bool swap, uint16_t value) { + return (swap ? getSwappedBytes(value) : value); +} inline uint32_t read32(bool swap, uint32_t value) { return (swap ? getSwappedBytes(value) : value); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 5846c3e12e9..8fb834d8b7d 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -438,10 +438,25 @@ std::error_code convertRelocs(const Section §ion, if (sectIndex > normalizedFile.sections.size()) return make_dynamic_error_code(Twine("out of range section " "index (") + Twine(sectIndex) + ")"); - const Section § = normalizedFile.sections[sectIndex-1]; + const Section *sect = nullptr; + if (sectIndex == 0) { + for (const Section &s : normalizedFile.sections) { + uint64_t sAddr = s.address; + if ((sAddr <= addr) && (addr < sAddr+s.content.size())) { + sect = &s; + break; + } + } + if (!sect) { + return make_dynamic_error_code(Twine("address (" + Twine(addr) + + ") is not in any section")); + } + } else { + sect = &normalizedFile.sections[sectIndex-1]; + } uint32_t offsetInTarget; - uint64_t offsetInSect = addr - sect.address; - *atom = file.findAtomCoveringAddress(sect, offsetInSect, &offsetInTarget); + uint64_t offsetInSect = addr - sect->address; + *atom = file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget); *addend = offsetInTarget; return std::error_code(); }; @@ -534,7 +549,7 @@ std::error_code convertRelocs(const Section §ion, + " (r_address=" + Twine::utohexstr(reloc.offset) + ", r_type=" + Twine(reloc.type) + ", r_extern=" + Twine(reloc.isExtern) - + ", r_length=" + Twine(reloc.length) + + ", r_length=" + Twine((int)reloc.length) + ", r_pcrel=" + Twine(reloc.pcRel) + (!reloc.scattered ? (Twine(", r_symbolnum=") + Twine(reloc.symbol)) : (Twine(", r_scattered=1, r_value=") @@ -542,7 +557,17 @@ std::error_code convertRelocs(const Section §ion, + ")" ); } else { // Instantiate an lld::Reference object and add to its atom. - inAtom->addReference(offsetInAtom, kind, target, addend); + Reference::KindArch arch = Reference::KindArch::all; + switch (normalizedFile.arch ) { + case lld::MachOLinkingContext::arch_x86_64: + arch = Reference::KindArch::x86_64; + break; + case lld::MachOLinkingContext::arch_x86: + arch = Reference::KindArch::x86; + break; + } + + inAtom->addReference(offsetInAtom, kind, target, addend, arch); } } return std::error_code(); @@ -580,7 +605,8 @@ normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path, } // TEMP BEGIN: until all KindHandlers switched to new interface. - if (normalizedFile.arch != lld::MachOLinkingContext::arch_x86_64) + if ((normalizedFile.arch != lld::MachOLinkingContext::arch_x86_64) && + (normalizedFile.arch != lld::MachOLinkingContext::arch_x86)) return std::unique_ptr<File>(std::move(file)); // TEMP END diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp index fe9caec5c7d..28cacf307ab 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp @@ -76,6 +76,23 @@ KindHandler::RelocPattern KindHandler::relocPattern(const Relocation &reloc) { return result; } +int16_t KindHandler::readS16(bool swap, const uint8_t *addr) { + return read16(swap, *reinterpret_cast<const uint16_t*>(addr)); +} + +int32_t KindHandler::readS32(bool swap, const uint8_t *addr) { + return read32(swap, *reinterpret_cast<const uint32_t*>(addr)); +} + +uint32_t KindHandler::readU32(bool swap, const uint8_t *addr) { + return read32(swap, *reinterpret_cast<const uint32_t*>(addr)); +} + +int64_t KindHandler::readS64(bool swap, const uint8_t *addr) { + return read64(swap, *reinterpret_cast<const uint64_t*>(addr)); +} + + bool KindHandler::isPairedReloc(const Relocation &reloc) { llvm_unreachable("abstract"); } @@ -87,13 +104,13 @@ KindHandler::getReferenceInfo(const Relocation &reloc, uint64_t fixupAddress, bool swap, FindAtomBySectionAndAddress atomFromAddress, FindAtomBySymbolIndex atomFromSymbolIndex, - Reference::KindValue *kind, - const lld::Atom **target, + Reference::KindValue *kind, + const lld::Atom **target, Reference::Addend *addend) { llvm_unreachable("abstract"); } -std::error_code +std::error_code KindHandler::getPairReferenceInfo(const normalized::Relocation &reloc1, const normalized::Relocation &reloc2, const DefinedAtom *inAtom, @@ -101,8 +118,8 @@ KindHandler::getPairReferenceInfo(const normalized::Relocation &reloc1, uint64_t fixupAddress, bool swap, FindAtomBySectionAndAddress atomFromAddress, FindAtomBySymbolIndex atomFromSymbolIndex, - Reference::KindValue *kind, - const lld::Atom **target, + Reference::KindValue *kind, + const lld::Atom **target, Reference::Addend *addend) { llvm_unreachable("abstract"); } @@ -169,13 +186,6 @@ bool KindHandler_x86_64::isPairedReloc(const Relocation &reloc) { return (reloc.type == X86_64_RELOC_SUBTRACTOR); } -static int32_t readS32(bool swap, const uint8_t *addr) { - return read32(swap, *reinterpret_cast<const uint32_t*>(addr)); -} - -static int64_t readS64(bool swap, const uint8_t *addr) { - return read64(swap, *reinterpret_cast<const uint64_t*>(addr)); -} Reference::KindValue KindHandler_x86_64::kindFromReloc(const Relocation &reloc) { @@ -400,29 +410,166 @@ KindHandler_x86::~KindHandler_x86() { } const Registry::KindStrings KindHandler_x86::kindStrings[] = { - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_BRANCH32), - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_ABS32), - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_FUNC_REL32), - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_POINTER32), - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_TARGET), - LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_IMMEDIATE), + LLD_KIND_STRING_ENTRY(invalid), + LLD_KIND_STRING_ENTRY(branch32), + LLD_KIND_STRING_ENTRY(branch16), + LLD_KIND_STRING_ENTRY(abs32), + LLD_KIND_STRING_ENTRY(funcRel32), + LLD_KIND_STRING_ENTRY(pointer32), + LLD_KIND_STRING_ENTRY(delta32), + LLD_KIND_STRING_ENTRY(lazyPointer), + LLD_KIND_STRING_ENTRY(lazyImmediateLocation), LLD_KIND_STRING_END }; bool KindHandler_x86::isCallSite(const Reference &ref) { - return (ref.kindValue() == LLD_X86_RELOC_BRANCH32); + return (ref.kindValue() == branch32); } bool KindHandler_x86::isPointer(const Reference &ref) { - return (ref.kindValue() == LLD_X86_RELOC_POINTER32); + return (ref.kindValue() == pointer32); } bool KindHandler_x86::isLazyImmediate(const Reference &ref) { - return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET); + return (ref.kindValue() == lazyImmediateLocation); } bool KindHandler_x86::isLazyTarget(const Reference &ref) { - return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET); + return (ref.kindValue() == lazyPointer); +} + + +bool KindHandler_x86::isPairedReloc(const Relocation &reloc) { + if (!reloc.scattered) + return false; + return (reloc.type == GENERIC_RELOC_LOCAL_SECTDIFF) || + (reloc.type == GENERIC_RELOC_SECTDIFF); +} + + +std::error_code +KindHandler_x86::getReferenceInfo(const Relocation &reloc, + const DefinedAtom *inAtom, + uint32_t offsetInAtom, + uint64_t fixupAddress, bool swap, + FindAtomBySectionAndAddress atomFromAddress, + FindAtomBySymbolIndex atomFromSymbolIndex, + Reference::KindValue *kind, + const lld::Atom **target, + Reference::Addend *addend) { + typedef std::error_code E; + DefinedAtom::ContentPermissions perms; + const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom]; + uint64_t targetAddress; + switch (relocPattern(reloc)) { + case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength4: + // ex: call _foo (and _foo undefined) + *kind = branch32; + if (E ec = atomFromSymbolIndex(reloc.symbol, target)) + return ec; + *addend = fixupAddress + 4 + readS32(swap, fixupContent); + break; + case GENERIC_RELOC_VANILLA | rPcRel | rLength4: + // ex: call _foo (and _foo defined) + *kind = branch32; + targetAddress = fixupAddress + 4 + readS32(swap, fixupContent); + return atomFromAddress(reloc.symbol, targetAddress, target, addend); + break; + case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2: + // ex: callw _foo (and _foo undefined) + *kind = branch16; + if (E ec = atomFromSymbolIndex(reloc.symbol, target)) + return ec; + *addend = fixupAddress + 2 + readS16(swap, fixupContent); + break; + case GENERIC_RELOC_VANILLA | rPcRel | rLength2: + // ex: callw _foo (and _foo defined) + *kind = branch16; + targetAddress = fixupAddress + 2 + readS16(swap, fixupContent); + return atomFromAddress(reloc.symbol, targetAddress, target, addend); + break; + case GENERIC_RELOC_VANILLA | rExtern | rLength4: + // ex: movl _foo, %eax (and _foo undefined) + // ex: .long _foo (and _foo undefined) + perms = inAtom->permissions(); + *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) + ? abs32 : pointer32; + if (E ec = atomFromSymbolIndex(reloc.symbol, target)) + return ec; + *addend = readU32(swap, fixupContent); + break; + case GENERIC_RELOC_VANILLA | rLength4: + // ex: movl _foo, %eax (and _foo defined) + // ex: .long _foo (and _foo defined) + perms = inAtom->permissions(); + *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) + ? abs32 : pointer32; + targetAddress = readU32(swap, fixupContent); + return atomFromAddress(reloc.symbol, targetAddress, target, addend); + break; + default: + return make_dynamic_error_code(Twine("unsupported i386 relocation type")); + } + return std::error_code(); +} + + +std::error_code +KindHandler_x86::getPairReferenceInfo(const normalized::Relocation &reloc1, + const normalized::Relocation &reloc2, + const DefinedAtom *inAtom, + uint32_t offsetInAtom, + uint64_t fixupAddress, bool swap, + FindAtomBySectionAndAddress atomFromAddr, + FindAtomBySymbolIndex atomFromSymbolIndex, + Reference::KindValue *kind, + const lld::Atom **target, + Reference::Addend *addend) { + const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom]; + std::error_code ec; + DefinedAtom::ContentPermissions perms = inAtom->permissions(); + uint32_t fromAddress; + uint32_t toAddress; + uint32_t value; + const lld::Atom *fromTarget; + Reference::Addend offsetInTo; + Reference::Addend offsetInFrom; + switch(relocPattern(reloc1) << 16 | relocPattern(reloc2)) { + case ((GENERIC_RELOC_SECTDIFF | rScattered | rLength4) << 16 | + GENERIC_RELOC_PAIR | rScattered | rLength4): + case ((GENERIC_RELOC_LOCAL_SECTDIFF | rScattered | rLength4) << 16 | + GENERIC_RELOC_PAIR | rScattered | rLength4): + toAddress = reloc1.value; + fromAddress = reloc2.value; + value = readS32(swap, fixupContent); + ec = atomFromAddr(0, toAddress, target, &offsetInTo); + if (ec) + return ec; + ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom); + if (ec) + return ec; + if (fromTarget != inAtom) + return make_dynamic_error_code(Twine("SECTDIFF relocation where " + "subtrahend label is not in atom")); + *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) + ? funcRel32 : delta32; + if (*kind == funcRel32) { + // SECTDIFF relocations are used in i386 codegen where the function + // prolog does a CALL to the next instruction which POPs the return + // address into EBX which becomes the pic-base register. The POP + // instruction is label the used for the subtrahend in expressions. + // The funcRel32 kind represents the 32-bit delta to some symbol from + // the start of the function (atom) containing the funcRel32. + uint32_t ta = fromAddress + value - toAddress; + *addend = ta - offsetInFrom; + } else { + *addend= fromAddress + value - toAddress; + } + return std::error_code(); + break; + default: + return make_dynamic_error_code(Twine("unsupported i386 relocation type")); + } } void KindHandler_x86::applyFixup(Reference::KindNamespace ns, diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h index 994c384f099..46bf585dedb 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h @@ -125,7 +125,11 @@ protected: rLength8 = 0x0300 }; static RelocPattern relocPattern(const normalized::Relocation &reloc); - + + static int16_t readS16(bool swap, const uint8_t *addr); + static int32_t readS32(bool swap, const uint8_t *addr); + static uint32_t readU32(bool swap, const uint8_t *addr); + static int64_t readS64(bool swap, const uint8_t *addr); }; @@ -216,12 +220,61 @@ public: bool isPointer(const Reference &) override; bool isLazyImmediate(const Reference &) override; bool isLazyTarget(const Reference &) override; - virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch, + bool isPairedReloc(const normalized::Relocation &) override; + std::error_code getReferenceInfo(const normalized::Relocation &reloc, + const DefinedAtom *inAtom, + uint32_t offsetInAtom, + uint64_t fixupAddress, bool swap, + FindAtomBySectionAndAddress atomFromAddress, + FindAtomBySymbolIndex atomFromSymbolIndex, + Reference::KindValue *kind, + const lld::Atom **target, + Reference::Addend *addend) override; + std::error_code + getPairReferenceInfo(const normalized::Relocation &reloc1, + const normalized::Relocation &reloc2, + const DefinedAtom *inAtom, + uint32_t offsetInAtom, + uint64_t fixupAddress, bool swap, + FindAtomBySectionAndAddress atomFromAddress, + FindAtomBySymbolIndex atomFromSymbolIndex, + Reference::KindValue *kind, + const lld::Atom **target, + Reference::Addend *addend) override; + + void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch, Reference::KindValue kindValue, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress) override; + +private: + friend class X86LazyPointerAtom; + friend class X86StubHelperAtom; + friend class X86StubAtom; + friend class X86StubHelperCommonAtom; + friend class X86NonLazyPointerAtom; + + enum : Reference::KindValue { + invalid, /// for error condition + + // Kinds found in mach-o .o files: + branch32, /// ex: call _foo + branch16, /// ex: callw _foo + abs32, /// ex: movl _foo, %eax + funcRel32, /// ex: movl _foo-L1(%eax), %eax + pointer32, /// ex: .long _foo + delta32, /// ex: .long _foo - . + + // Kinds introduced by Passes: + lazyPointer, /// Location contains a lazy pointer. + lazyImmediateLocation, /// Location contains immediate value used in stub. + }; + + }; + + class KindHandler_arm : public KindHandler { public: static const Registry::KindStrings kindStrings[]; diff --git a/lld/test/mach-o/parse-cfstring32.yaml b/lld/test/mach-o/parse-cfstring32.yaml index 8f4b041655a..657e733a779 100644 --- a/lld/test/mach-o/parse-cfstring32.yaml +++ b/lld/test/mach-o/parse-cfstring32.yaml @@ -39,7 +39,7 @@ sections: length: 2 pc-rel: false extern: true - symbol: 1 + symbol: 0 - offset: 0x00000008 type: GENERIC_RELOC_VANILLA length: 2 @@ -51,7 +51,7 @@ sections: length: 2 pc-rel: false extern: true - symbol: 1 + symbol: 0 undefined-symbols: - name: ___CFConstantStringClassReference type: N_UNDF @@ -60,19 +60,35 @@ undefined-symbols: ... # CHECK: defined-atoms: -# CHECK: - scope: hidden +# CHECK: - ref-name: [[STR1:L[L0-9]+]] +# CHECK: scope: hidden # CHECK: type: c-string # CHECK: content: [ 68, 65, 6C, 6C, 6F, 00 ] # CHECK: merge: by-content -# CHECK: - scope: hidden +# CHECK: - ref-name: [[STR2:L[L0-9]+]] +# CHECK: scope: hidden # CHECK: type: c-string # CHECK: content: [ 74, 68, 65, 72, 65, 00 ] # CHECK: merge: by-content # CHECK: - scope: hidden # CHECK: type: cfstring # CHECK: merge: by-content +# CHECK: references: +# CHECK: - kind: pointer32 +# CHECK: offset: 0 +# CHECK: target: ___CFConstantStringClassReference +# CHECK: - kind: pointer32 +# CHECK: offset: 8 +# CHECK: target: [[STR1]] # CHECK: - scope: hidden # CHECK: type: cfstring # CHECK: merge: by-content +# CHECK: references: +# CHECK: - kind: pointer32 +# CHECK: offset: 0 +# CHECK: target: ___CFConstantStringClassReference +# CHECK: - kind: pointer32 +# CHECK: offset: 8 +# CHECK: target: [[STR2]] # CHECK:undefined-atoms: # CHECK: - name: ___CFConstantStringClassReference diff --git a/lld/test/mach-o/parse-non-lazy-pointers.yaml b/lld/test/mach-o/parse-non-lazy-pointers.yaml index afdf2e68ace..0b0ec5cf36e 100644 --- a/lld/test/mach-o/parse-non-lazy-pointers.yaml +++ b/lld/test/mach-o/parse-non-lazy-pointers.yaml @@ -71,11 +71,13 @@ undefined-symbols: # CHECK:defined-atoms: -# CHECK: - scope: hidden +# CHECK: - ref-name: [[GOT1:L[L0-9]+]] +# CHECK: scope: hidden # CHECK: type: got # CHECK: content: [ 00, 00, 00, 00 ] # CHECK: merge: by-content -# CHECK: - scope: hidden +# CHECK: - ref-name: [[GOT2:L[L0-9]+]] +# CHECK: scope: hidden # CHECK: type: got # CHECK: content: [ 00, 00, 00, 00 ] # CHECK: merge: by-content @@ -83,6 +85,13 @@ undefined-symbols: # CHECK: scope: global # CHECK: content: [ 55, 89, E5, E8, 00, 00, 00, 00, 59, 8D, 81, 14, # CHECK: 00, 00, 00, 8D, 81, 18, 00, 00, 00, 5D, C3 ] +# CHECK: references: +# CHECK: - kind: funcRel32 +# CHECK: offset: 11 +# CHECK: target: [[GOT1]] +# CHECK: - kind: funcRel32 +# CHECK: offset: 17 +# CHECK: target: [[GOT2]] # CHECK: - name: _foo # CHECK: content: [ 55, 89, E5, 5D, C3 ] diff --git a/lld/test/mach-o/parse-relocs-x86.yaml b/lld/test/mach-o/parse-relocs-x86.yaml new file mode 100644 index 00000000000..c9feb244d75 --- /dev/null +++ b/lld/test/mach-o/parse-relocs-x86.yaml @@ -0,0 +1,190 @@ +# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s +# +# Test parsing of x86 relocations. +# +# .text +# +#_test: +# call _undef +# call _undef+2 +# callw _undef +#L1: +# movl _undef, %eax +# movl _x, %eax +# movl _x-L1(%eax), %eax +# movl _x+4-L1(%eax), %eax +# +# .data +#_x: +# .long _undef +# .long _test - . +# .long _test+3 - . +# + +--- !mach-o +arch: x86 +file-type: MH_OBJECT +flags: [ ] +OS: unknown +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + 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 ] + relocations: + - offset: 0x00000020 + scattered: true + type: GENERIC_RELOC_LOCAL_SECTDIFF + length: 2 + pc-rel: false + value: 0x00000024 + - offset: 0x00000000 + scattered: true + type: GENERIC_RELOC_PAIR + length: 2 + pc-rel: false + value: 0x0000000E + - offset: 0x0000001A + scattered: true + type: GENERIC_RELOC_LOCAL_SECTDIFF + length: 2 + pc-rel: false + value: 0x00000024 + - offset: 0x00000000 + scattered: true + type: GENERIC_RELOC_PAIR + length: 2 + pc-rel: false + value: 0x0000000E + - offset: 0x00000014 + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + extern: false + symbol: 2 + - offset: 0x0000000F + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + extern: true + symbol: 2 + - offset: 0x0000000C + type: GENERIC_RELOC_VANILLA + length: 1 + pc-rel: true + extern: true + symbol: 2 + - offset: 0x00000006 + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: true + extern: true + symbol: 2 + - offset: 0x00000001 + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: true + extern: true + symbol: 2 + - segment: __DATA + section: __data + type: S_REGULAR + attributes: [ ] + address: 0x0000000000000024 + content: [ 0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xFF, 0xFF, + 0xD7, 0xFF, 0xFF, 0xFF ] + relocations: + - offset: 0x00000008 + scattered: true + type: GENERIC_RELOC_LOCAL_SECTDIFF + length: 2 + pc-rel: false + value: 0x00000000 + - offset: 0x00000000 + scattered: true + type: GENERIC_RELOC_PAIR + length: 2 + pc-rel: false + value: 0x0000002C + - offset: 0x00000004 + scattered: true + type: GENERIC_RELOC_LOCAL_SECTDIFF + length: 2 + pc-rel: false + value: 0x00000000 + - offset: 0x00000000 + scattered: true + type: GENERIC_RELOC_PAIR + length: 2 + pc-rel: false + value: 0x00000028 + - offset: 0x00000000 + type: GENERIC_RELOC_VANILLA + length: 2 + pc-rel: false + extern: true + symbol: 2 +local-symbols: + - name: _test + type: N_SECT + sect: 1 + value: 0x0000000000000000 + - name: _x + type: N_SECT + sect: 2 + value: 0x0000000000000024 +undefined-symbols: + - name: _undef + type: N_UNDF + scope: [ N_EXT ] + value: 0x0000000000000000 +... + +# CHECK: defined-atoms: +# CHECK: - name: _x +# CHECK: type: data +# CHECK: references: +# CHECK: - kind: pointer32 +# CHECK: offset: 0 +# CHECK: target: _undef +# CHECK: - kind: delta32 +# CHECK: offset: 4 +# CHECK: target: _test +# CHECK: - kind: delta32 +# CHECK: offset: 8 +# CHECK: target: _test +# CHECK: addend: 3 +# CHECK: - name: _test +# CHECK: references: +# CHECK: - kind: branch32 +# CHECK: offset: 1 +# CHECK: target: _undef +# CHECK-NOT: addend: +# CHECK: - kind: branch32 +# CHECK: offset: 6 +# CHECK: target: _undef +# CHECK: addend: 2 +# CHECK: - kind: branch16 +# CHECK: offset: 12 +# CHECK: target: _undef +# CHECK: - kind: abs32 +# CHECK: offset: 15 +# CHECK: target: _undef +# CHECK: - kind: abs32 +# CHECK: offset: 20 +# CHECK: target: _x +# CHECK: - kind: funcRel32 +# CHECK: offset: 26 +# CHECK: target: _x +# CHECK: addend: -14 +# CHECK: - kind: funcRel32 +# CHECK: offset: 32 +# CHECK: target: _x +# CHECK: addend: -10 + |