summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-07-24 23:06:56 +0000
committerNick Kledzik <kledzik@apple.com>2014-07-24 23:06:56 +0000
commit21921375cc23d4958560b3280c2684c9c52baa62 (patch)
tree0eb10637cd0350312f9a2d326b95f7b735c87e73 /lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
parent8ec1474f7f5f1673f6ea0bc47bdbded62fefde0e (diff)
downloadbcm5719-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.cpp32
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;
}
OpenPOWER on IntegriCloud