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/MachONormalizedFileBinaryReader.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/MachONormalizedFileBinaryReader.cpp')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 29 |
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); } |

