From: Pete Cooper Date: Thu, 11 Aug 2016 20:37:02 +0000 (+0000) Subject: Generate slightly more compressed binding opcodes when entries are the same as last... X-Git-Tag: llvmorg-4.0.0-rc1~12693 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=21f475e1c4fe5120400afdf3aef7c0ef0311134c;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index 8cca2a2..188ad3b 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 8b1942e..ad87ee6 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: ''