mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 02:46:11 +00:00

An empty output section specified in the `SECTIONS` command (e.g. `empty : { *(empty) }`) may be discarded. Due to phase ordering, we might define `__start_empty`/`__stop_empty` symbols with incorrect section indexes (usually benign, but could go out of bounds and cause `readelf -s` to print `BAD`). ``` finalizeSections addStartStopSymbols // __start_empty is defined // __start_empty is added to .symtab sortSections adjustOutputSections // `empty` is discarded writeSections // __start_empty is Defined with an invalid section index ``` Loaders use `st_value` members of the start/stop symbols and expect no "undefined symbol" linker error, but do not particularly care whether the symbols are defined or undefined. Let's retain the associated empty output section so that start/stop symbols will have correct section indexes. The approach allows us to remove `LinkerScript::isDiscarded` (https://reviews.llvm.org/D114179). Also delete the `findSection(".text")` special case from https://reviews.llvm.org/D46200, which is unnecessary even before this patch (`elfHeader` would be fine even with very large executables). Note: we should be careful not to unnecessarily retain .ARM.exidx, which would create an empty PT_ARM_EXIDX. ~40 tests would need to be updated. --- An alternative is to discard the empty output section and keep the start/stop symbols undefined. This approach needs more code and requires `LinkerScript::isDiscarded` before we discard empty sections in ``adjustOutputSections`. Pull Request: https://github.com/llvm/llvm-project/pull/96343
40 lines
1.3 KiB
ArmAsm
40 lines
1.3 KiB
ArmAsm
// REQUIRES: x86
|
|
// RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
|
// RUN: ld.lld %t.o -o %t
|
|
// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
|
// RUN: ld.lld -pie %t.o -o %t2
|
|
// RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck --check-prefix=PIE %s
|
|
|
|
.globl _start
|
|
_start:
|
|
call __preinit_array_start
|
|
call __preinit_array_end
|
|
call __init_array_start
|
|
call __init_array_end
|
|
call __fini_array_start
|
|
call __fini_array_end
|
|
|
|
/// Due to __init_array_start/__init_array_end, .init_array is retained.
|
|
|
|
// CHECK: Disassembly of section .text:
|
|
// CHECK-EMPTY:
|
|
// CHECK-NEXT: <_start>:
|
|
// CHECK-NEXT: 201120: callq 0x200000
|
|
// CHECK-NEXT: callq 0x200000
|
|
// CHECK-NEXT: callq 0x200000
|
|
// CHECK-NEXT: callq 0x200000
|
|
// CHECK-NEXT: callq 0x200000
|
|
// CHECK-NEXT: callq 0x200000
|
|
|
|
// In position-independent binaries, they resolve to .text too.
|
|
|
|
// PIE: Disassembly of section .text:
|
|
// PIE-EMPTY:
|
|
// PIE-NEXT: <_start>:
|
|
// PIE-NEXT: 1210: callq 0x0
|
|
// PIE-NEXT: callq 0x0
|
|
// PIE-NEXT: callq 0x0
|
|
// PIE-NEXT: callq 0x0
|
|
// PIE-NEXT: callq 0x0
|
|
// PIE-NEXT: callq 0x0
|