summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2016-08-11 20:37:02 +0000
committerPete Cooper <peter_cooper@apple.com>2016-08-11 20:37:02 +0000
commit21f475e1c4fe5120400afdf3aef7c0ef0311134c (patch)
treeed7b292293b859c00f87d3281f91b4ed9f598475 /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
parent2698cbb4f1b3de7527510b1d9c1d47853ca0f585 (diff)
downloadbcm5719-llvm-21f475e1c4fe5120400afdf3aef7c0ef0311134c.tar.gz
bcm5719-llvm-21f475e1c4fe5120400afdf3aef7c0ef0311134c.zip
Generate slightly more compressed binding opcodes when entries are the same as last time.
We already had logic for binding opcodes had the same addend as last time. This adds the cases where the ordinal, symbol name, type, and segment offsets are the same as the last emitted ordinal. This gets us one step closer to emitting rebase opcodes as compressed as ld64 can manage. llvm-svn: 278405
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp49
1 files changed, 37 insertions, 12 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 8cca2a217c4..188ad3b9367 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -1192,19 +1192,44 @@ void MachOFileLayout::buildRebaseInfo() {
void MachOFileLayout::buildBindInfo() {
// TODO: compress bind info.
uint64_t lastAddend = 0;
+ int lastOrdinal = 0x80000000;
+ StringRef lastSymbolName;
+ BindType lastType = (BindType)0;
+ Hex32 lastSegOffset = ~0U;
+ uint8_t lastSegIndex = (uint8_t)~0U;
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
- | entry.segIndex);
- _bindingInfo.append_uleb128(entry.segOffset);
- if (entry.ordinal > 0)
- _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
- (entry.ordinal & 0xF));
- else
- _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
- (entry.ordinal & 0xF));
- _bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
- _bindingInfo.append_string(entry.symbolName);
+ if (entry.ordinal != lastOrdinal) {
+ if (entry.ordinal <= 0)
+ _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
+ (entry.ordinal & BIND_IMMEDIATE_MASK));
+ else if (entry.ordinal <= BIND_IMMEDIATE_MASK)
+ _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
+ entry.ordinal);
+ else {
+ _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
+ _bindingInfo.append_uleb128(entry.ordinal);
+ }
+ lastOrdinal = entry.ordinal;
+ }
+
+ if (lastSymbolName != entry.symbolName) {
+ _bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
+ _bindingInfo.append_string(entry.symbolName);
+ lastSymbolName = entry.symbolName;
+ }
+
+ if (lastType != entry.kind) {
+ _bindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
+ lastType = entry.kind;
+ }
+
+ if (lastSegIndex != entry.segIndex || lastSegOffset != entry.segOffset) {
+ _bindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+ | entry.segIndex);
+ _bindingInfo.append_uleb128(entry.segOffset);
+ lastSegIndex = entry.segIndex;
+ lastSegOffset = entry.segOffset;
+ }
if (entry.addend != lastAddend) {
_bindingInfo.append_byte(BIND_OPCODE_SET_ADDEND_SLEB);
_bindingInfo.append_sleb128(entry.addend);
OpenPOWER on IntegriCloud