From 88e2268a344a0ab3df455af08f32c2c354ea55a4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 19 Jul 2021 18:13:52 -0700 Subject: [PATCH] Revert D106128 "[lld-macho] Use DO_BIND_ADD_ADDR_IMM_SCALED for bind opcodes" This reverts commit 321b2bef098553ec648e4174aae92c63a6e1a810. `for (BindIR *p = &opcodes[0]; p->opcode != BIND_OPCODE_DONE; ++p) {` has a heap-buffer-overflow with test/MachO/bind-opcodes. --- lld/MachO/SyntheticSections.cpp | 20 ------- lld/test/MachO/bind-opcodes.s | 130 ++++++++-------------------------------- 2 files changed, 24 insertions(+), 126 deletions(-) diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 47a9b2b..d65cc9c 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -360,23 +360,6 @@ static void optimizeOpcodes(std::vector &opcodes) { if (i == opcodes.size()) opcodes[pWrite] = opcodes[i - 1]; opcodes.resize(pWrite + 1); - - // Pass 3: Use immediate encodings - // Every binding is the size of one pointer. If the next binding is a - // multiple of wordSize away that is within BIND_IMMEDIATE_MASK, the - // opcode can be scaled by wordSize into a single byte and dyld will - // expand it to the correct address. - for (BindIR *p = &opcodes[0]; p->opcode != BIND_OPCODE_DONE; ++p) { - // It's unclear why the check needs to be less than BIND_IMMEDIATE_MASK, - // but ld64 currently does this. This could be a potential bug, but - // for now, perform the same behavior to prevent mysterious bugs. - if ((p->opcode == BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB) && - ((p->data / target->wordSize) < BIND_IMMEDIATE_MASK) && - ((p->data % target->wordSize) == 0)) { - p->opcode = BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED; - p->data /= target->wordSize; - } - } } static void flushOpcodes(const BindIR &op, raw_svector_ostream &os) { @@ -400,9 +383,6 @@ static void flushOpcodes(const BindIR &op, raw_svector_ostream &os) { encodeULEB128(op.consecutiveCount, os); encodeULEB128(op.data, os); break; - case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: - os << static_cast(op.opcode | op.data); - break; default: llvm_unreachable("cannot bind to an unrecognized symbol"); } diff --git a/lld/test/MachO/bind-opcodes.s b/lld/test/MachO/bind-opcodes.s index 0f8467a..b313afb 100644 --- a/lld/test/MachO/bind-opcodes.s +++ b/lld/test/MachO/bind-opcodes.s @@ -1,16 +1,15 @@ -# REQUIRES: x86, arm +# REQUIRES: x86 # RUN: rm -rf %t; split-file %s %t # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo.s -o %t/foo.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin --defsym PTR64=0 %t/test.s -o %t/test.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o # RUN: %lld -O2 -dylib %t/foo.o -o %t/libfoo.dylib -# RUN: %lld -O2 -lSystem %t/test.o %t/libfoo.dylib -o %t/test-x86_64 +# RUN: %lld -O2 -lSystem %t/test.o %t/libfoo.dylib -o %t/test -## Test (64-bit): +## Test: ## 1/ We emit exactly one BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM per symbol. ## 2/ Combine BIND_OPCODE_DO_BIND and BIND_OPCODE_ADD_ADDR_ULEB pairs. ## 3/ Compact BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB -## 4/ Use BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED if possible. -# RUN: obj2yaml %t/test-x86_64 | FileCheck %s +# RUN: obj2yaml %t/test | FileCheck %s # CHECK: BindOpcodes: # CHECK-NEXT: Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM @@ -55,8 +54,9 @@ # CHECK-NEXT: Imm: 0 # CHECK-NEXT: ULEBExtraData: [ 0xFFFFFFFFFFFFEFD0 ] # CHECK-NEXT: Symbol: '' -# CHECK-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED -# CHECK-NEXT: Imm: 1 +# CHECK-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB +# CHECK-NEXT: Imm: 0 +# CHECK-NEXT: ULEBExtraData: [ 0x8 ] # CHECK-NEXT: Symbol: '' # CHECK-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB # CHECK-NEXT: Imm: 0 @@ -69,86 +69,16 @@ # CHECK-NEXT: Imm: 0 # CHECK-NEXT: Symbol: '' -# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-darwin %t/foo.s -o %t/foo.o -# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-darwin --defsym PTR32=0 %t/test.s -o %t/test.o -# RUN: %lld -arch arm64_32 -O2 -dylib %t/foo.o -o %t/libfoo.dylib -# RUN: %lld -arch arm64_32 -O2 -dylib %t/test.o %t/libfoo.dylib -o %t/libtest-arm64_32.dylib - -## Test (32-bit): -## 1/ We emit exactly one BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM per symbol. -## 2/ Combine BIND_OPCODE_DO_BIND and BIND_OPCODE_ADD_ADDR_ULEB pairs. -## 3/ Compact BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB -## 4/ Use BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED if possible. -# RUN: obj2yaml %t/libtest-arm64_32.dylib | FileCheck %s --check-prefix=CHECK32 - -# CHECK32: BindOpcodes: -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: Symbol: _foo -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_TYPE_IMM -# CHECK32-NEXT: Imm: 1 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM -# CHECK32-NEXT: Imm: 1 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB -# CHECK32-NEXT: Imm: 1 -# CHECK32-NEXT: ULEBExtraData: [ 0x0 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: ULEBExtraData: [ 0x2, 0x4 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_ADDEND_SLEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: SLEBExtraData: [ 1 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: ULEBExtraData: [ 0x1004 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_ADDEND_SLEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: SLEBExtraData: [ 0 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: Symbol: _bar -# CHECK32-NEXT: Opcode: BIND_OPCODE_SET_TYPE_IMM -# CHECK32-NEXT: Imm: 1 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_ADD_ADDR_ULEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: ULEBExtraData: [ 0xFFFFFFFFFFFFEFE8 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED -# CHECK32-NEXT: Imm: 1 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: ULEBExtraData: [ 0x1004 ] -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DO_BIND -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: Symbol: '' -# CHECK32-NEXT: Opcode: BIND_OPCODE_DONE -# CHECK32-NEXT: Imm: 0 -# CHECK32-NEXT: Symbol: '' - -# RUN: llvm-objdump --macho --bind %t/test-x86_64 | FileCheck %s -D#PTR=8 --check-prefix=BIND -# RUN: llvm-objdump --macho --bind %t/libtest-arm64_32.dylib | FileCheck %s -D#PTR=4 --check-prefix=BIND +# RUN: llvm-objdump --macho --bind %t/test | FileCheck %s --check-prefix=BIND # BIND: Bind table: -# BIND-NEXT: segment section address type addend dylib symbol -# BIND-NEXT: __DATA __data 0x[[#%X,DATA:]] pointer 0 libfoo _foo -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + mul(PTR, 2)]] pointer 0 libfoo _foo -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + mul(PTR, 4)]] pointer 1 libfoo _foo -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + 4096 + mul(PTR, 6)]] pointer 0 libfoo _foo -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + PTR]] pointer 0 libfoo _bar -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + mul(PTR, 3)]] pointer 0 libfoo _bar -# BIND-NEXT: __DATA __data 0x[[#%.8X,DATA + 4096 + mul(PTR, 5)]] pointer 0 libfoo _bar +# BIND-NEXT: segment section address type addend dylib symbol +# BIND-NEXT: __DATA __data 0x100001000 pointer 0 libfoo _foo +# BIND-NEXT: __DATA __data 0x100001010 pointer 0 libfoo _foo +# BIND-NEXT: __DATA __data 0x100001020 pointer 1 libfoo _foo +# BIND-NEXT: __DATA __data 0x100002030 pointer 0 libfoo _foo +# BIND-NEXT: __DATA __data 0x100001008 pointer 0 libfoo _bar +# BIND-NEXT: __DATA __data 0x100001018 pointer 0 libfoo _bar +# BIND-NEXT: __DATA __data 0x100002028 pointer 0 libfoo _bar # BIND-EMPTY: #--- foo.s @@ -159,27 +89,15 @@ _bar: .space 4 #--- test.s -.ifdef PTR64 -.macro ptr val - .quad \val -.endm -.endif - -.ifdef PTR32 -.macro ptr val - .int \val -.endm -.endif - .data -ptr _foo -ptr _bar -ptr _foo -ptr _bar -ptr _foo+1 +.quad _foo +.quad _bar +.quad _foo +.quad _bar +.quad _foo+1 .zero 0x1000 -ptr _bar -ptr _foo +.quad _bar +.quad _foo .globl _main .text -- 2.7.4