summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.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/MachONormalizedFileBinaryReader.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/MachONormalizedFileBinaryReader.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
index c96f325173c..27162450d64 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
@@ -229,6 +229,8 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb,
return ec;
// Walk load commands looking for segments/sections and the symbol table.
+ const data_in_code_entry *dataInCode = nullptr;
+ uint32_t dataInCodeSize = 0;
ec = forEachLoadCommand(lcRange, lcCount, swap, is64,
[&] (uint32_t cmd, uint32_t size, const char* lc) -> bool {
if (is64) {
@@ -387,21 +389,32 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb,
f->localSymbols.push_back(sout);
}
}
- }
- if (cmd == LC_ID_DYLIB) {
+ } else if (cmd == LC_ID_DYLIB) {
const dylib_command *dl = reinterpret_cast<const dylib_command*>(lc);
- dylib_command tempDL;
- if (swap) {
- tempDL = *dl; swapStruct(tempDL); dl = &tempDL;
- }
-
- f->installName = lc + dl->dylib.name;
+ f->installName = lc + read32(swap, dl->dylib.name);
+ } else if (cmd == LC_DATA_IN_CODE) {
+ const linkedit_data_command *ldc =
+ reinterpret_cast<const linkedit_data_command*>(lc);
+ dataInCode = reinterpret_cast<const data_in_code_entry*>(
+ start + read32(swap, ldc->dataoff));
+ dataInCodeSize = read32(swap, ldc->datasize);
}
return false;
});
if (ec)
return ec;
+ if (dataInCode) {
+ // Convert on-disk data_in_code_entry array to DataInCode vector.
+ for (unsigned i=0; i < dataInCodeSize/sizeof(data_in_code_entry); ++i) {
+ DataInCode entry;
+ entry.offset = read32(swap, dataInCode[i].offset);
+ entry.length = read16(swap, dataInCode[i].length);
+ entry.kind = (DataRegionType)read16(swap, dataInCode[i].kind);
+ f->dataInCode.push_back(entry);
+ }
+ }
+
return std::move(f);
}
OpenPOWER on IntegriCloud