diff options
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 49 | ||||
| -rw-r--r-- | lld/test/mach-o/bind-opcodes.yaml | 22 |
2 files changed, 45 insertions, 26 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); diff --git a/lld/test/mach-o/bind-opcodes.yaml b/lld/test/mach-o/bind-opcodes.yaml index 8b1942e2713..ad87ee6df4d 100644 --- a/lld/test/mach-o/bind-opcodes.yaml +++ b/lld/test/mach-o/bind-opcodes.yaml @@ -88,37 +88,31 @@ undefined-symbols: # CHECK: BindOpcodes: -# CHECK: - Opcode: BIND_OPCODE_SET_TYPE_IMM -# CHECK: Imm: 1 -# CHECK: Symbol: '' -# CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB -# CHECK: Imm: 2 -# CHECK: ULEBExtraData: -# CHECK: - 0x0000000000000000 -# CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM # CHECK: Imm: 1 # CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # CHECK: Imm: 0 # CHECK: Symbol: dyld_stub_binder -# CHECK: - Opcode: BIND_OPCODE_DO_BIND -# CHECK: Imm: 0 -# CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_SET_TYPE_IMM # CHECK: Imm: 1 # CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB # CHECK: Imm: 2 # CHECK: ULEBExtraData: -# CHECK: - 0x0000000000000010 +# CHECK: - 0x0000000000000000 # CHECK: Symbol: '' -# CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM -# CHECK: Imm: 1 +# CHECK: - Opcode: BIND_OPCODE_DO_BIND +# CHECK: Imm: 0 # CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # CHECK: Imm: 0 # CHECK: Symbol: ___stdoutp +# CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB +# CHECK: Imm: 2 +# CHECK: ULEBExtraData: +# CHECK: - 0x0000000000000010 +# CHECK: Symbol: '' # CHECK: - Opcode: BIND_OPCODE_DO_BIND # CHECK: Imm: 0 # CHECK: Symbol: '' |

