summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-11-11 01:31:18 +0000
committerNick Kledzik <kledzik@apple.com>2014-11-11 01:31:18 +0000
commitf373c77f50451ff585b507cce05705632553d13a (patch)
treefb6cedffaeed828aae6c4b445d7c849823f78d7e /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
parenta041610f11e9be018e125a5789e3ea258659dab4 (diff)
downloadbcm5719-llvm-f373c77f50451ff585b507cce05705632553d13a.tar.gz
bcm5719-llvm-f373c77f50451ff585b507cce05705632553d13a.zip
[mach-o] Fix lazy binding offsets
The way lazy binding works in mach-o is that the linker generates a helper function and has the stub (PLT) initially jump to it. The helper function pushes an extra parameter then jumps into dyld. The extra parameter is an offset into the lazy binding info where dyld will find the information about which symbol to bind and way lazy binding pointer to update. llvm-svn: 221654
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 543b60fe8bc..102b185df52 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -125,6 +125,12 @@ private:
void append_uleb128(uint64_t value) {
llvm::encodeULEB128(value, _ostream);
}
+ void append_uleb128Fixed(uint64_t value, unsigned byteCount) {
+ unsigned min = llvm::getULEB128Size(value);
+ assert(min <= byteCount);
+ unsigned pad = byteCount - min;
+ llvm::encodeULEB128(value, _ostream, pad);
+ }
void append_sleb128(int64_t value) {
llvm::encodeSLEB128(value, _ostream);
}
@@ -999,6 +1005,7 @@ void MachOFileLayout::buildRebaseInfo() {
void MachOFileLayout::buildBindInfo() {
// TODO: compress bind info.
+ uint64_t lastAddend = 0;
for (const BindLocation& entry : _file.bindingInfo) {
_bindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
_bindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
@@ -1007,9 +1014,10 @@ void MachOFileLayout::buildBindInfo() {
_bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | entry.ordinal);
_bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
_bindingInfo.append_string(entry.symbolName);
- if (entry.addend != 0) {
+ if (entry.addend != lastAddend) {
_bindingInfo.append_byte(BIND_OPCODE_SET_ADDEND_SLEB);
_bindingInfo.append_sleb128(entry.addend);
+ lastAddend = entry.addend;
}
_bindingInfo.append_byte(BIND_OPCODE_DO_BIND);
}
@@ -1022,11 +1030,12 @@ void MachOFileLayout::buildLazyBindInfo() {
_lazyBindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
_lazyBindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
| entry.segIndex);
- _lazyBindingInfo.append_uleb128(entry.segOffset);
+ _lazyBindingInfo.append_uleb128Fixed(entry.segOffset, 5);
_lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | entry.ordinal);
_lazyBindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
_lazyBindingInfo.append_string(entry.symbolName);
_lazyBindingInfo.append_byte(BIND_OPCODE_DO_BIND);
+ _lazyBindingInfo.append_byte(BIND_OPCODE_DONE);
}
_lazyBindingInfo.append_byte(BIND_OPCODE_DONE);
_lazyBindingInfo.align(_is64 ? 8 : 4);
OpenPOWER on IntegriCloud