diff options
| author | Nick Kledzik <kledzik@apple.com> | 2014-07-24 23:06:56 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2014-07-24 23:06:56 +0000 |
| commit | 21921375cc23d4958560b3280c2684c9c52baa62 (patch) | |
| tree | 0eb10637cd0350312f9a2d326b95f7b735c87e73 /lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp | |
| parent | 8ec1474f7f5f1673f6ea0bc47bdbded62fefde0e (diff) | |
| download | bcm5719-llvm-21921375cc23d4958560b3280c2684c9c52baa62.tar.gz bcm5719-llvm-21921375cc23d4958560b3280c2684c9c52baa62.zip | |
[mach-o] Add support for LC_DATA_IN_CODE
Sometimes compilers emit data into code sections (e.g. constant pools or
jump tables). These runs of data can throw off disassemblers. The solution
in mach-o is that ranges of data-in-code are encoded into a table pointed to
by the LC_DATA_IN_CODE load command.
The way the data-in-code information is encoded into lld's Atom model is that
that start and end of each data run is marked with a Reference whose offset
is the start/end of the data run. For arm, the switch back to code also marks
whether it is thumb or arm code.
llvm-svn: 213901
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index 01d4343e9fa..9dfab0ea78c 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -71,6 +71,28 @@ public: void addAdditionalReferences(MachODefinedAtom &atom) override; + bool isDataInCodeTransition(Reference::KindValue refKind) override { + switch (refKind) { + case modeThumbCode: + case modeArmCode: + case modeData: + return true; + default: + return false; + break; + } + } + + Reference::KindValue dataInCodeTransitionStart( + const MachODefinedAtom &atom) override { + return modeData; + } + + Reference::KindValue dataInCodeTransitionEnd( + const MachODefinedAtom &atom) override { + return atom.isThumb() ? modeThumbCode : modeArmCode; + } + bool isThumbFunction(const DefinedAtom &atom) override; private: @@ -82,6 +104,7 @@ private: modeThumbCode, /// Content starting at this offset is thumb. modeArmCode, /// Content starting at this offset is arm. + modeData, /// Content starting at this offset is data. // Kinds found in mach-o .o files: thumb_b22, /// ex: bl _foo @@ -143,6 +166,7 @@ ArchHandler_arm::~ArchHandler_arm() { } const Registry::KindStrings ArchHandler_arm::_sKindStrings[] = { LLD_KIND_STRING_ENTRY(modeThumbCode), LLD_KIND_STRING_ENTRY(modeArmCode), + LLD_KIND_STRING_ENTRY(modeData), LLD_KIND_STRING_ENTRY(thumb_b22), LLD_KIND_STRING_ENTRY(thumb_movw), LLD_KIND_STRING_ENTRY(thumb_movt), @@ -735,6 +759,8 @@ void ArchHandler_arm::applyFixupFinal(const Reference &ref, uint8_t *location, case modeArmCode: thumbMode = false; break; + case modeData: + break; case thumb_b22: assert(thumbMode); displacement = (targetAddress - (fixupAddress + 4)) + ref.addend(); @@ -868,6 +894,8 @@ void ArchHandler_arm::applyFixupRelocatable(const Reference &ref, case modeArmCode: thumbMode = false; break; + case modeData: + break; case thumb_b22: assert(thumbMode); if (useExternalReloc) @@ -971,6 +999,8 @@ void ArchHandler_arm::appendSectionRelocations( switch (ref.kindValue()) { case modeThumbCode: case modeArmCode: + case modeData: + break; // Do nothing. break; case thumb_b22: @@ -1174,7 +1204,7 @@ bool ArchHandler_arm::isThumbFunction(const DefinedAtom &atom) { return false; if (ref->kindNamespace() != Reference::KindNamespace::mach_o) continue; - assert(ref->kindArch() == Reference::KindArch::ARM); + assert(ref->kindArch() == Reference::KindArch::ARM); if (ref->kindValue() == modeThumbCode) return true; } |

