This fixes bootstrap of llvm-tblgen (with LTO) and PR27150. Slightly longer explanation follows. Emission of .init_array instead of .ctors is supported only on a subset of the Target LLVM supports. Codegen needs to be conservative and always emit .ctors unless instructed otherwise (based on target). If the dynamic linker sees .init_array it completely ignores what's inside .ctors and therefore some constructors are not called (and this causes llvm-tblgen to crash on startup). Teach LLD/LTO about the Codegen options so we end up always emitting .init_array and avoid this issue. In future, we might end up supporting mix of .ctors and .init_array in different input files if this shows up as a real-world use case. The way gold handles this case is mapping .ctors from input into .init_array in output. There's also another caveat because as far as I understand .ctors run in reverse order so when we do the copy/mapping we need to reverse copy in the output if there's more than one ctor. That's why I'd rather avoid this complicate logic unless there's a real need. An analogous reasoning holds for .dtors/.fini_array. llvm-svn: 265085
19 lines
631 B
LLVM
19 lines
631 B
LLVM
; REQUIRES: x86
|
|
; RUN: llvm-as %s -o %t.o
|
|
; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
|
|
; RUN: llvm-readobj -sections %t.so | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
|
|
define void @ctor() {
|
|
call void asm "nop", ""()
|
|
ret void
|
|
}
|
|
|
|
; The llvm.global_ctors should end up producing constructors.
|
|
; On x86-64 (linux) we should always emit .init_array and never .ctors.
|
|
; CHECK: Name: .init_array
|
|
; CHECK-NOT: Name: .ctors
|