mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-06 08:02:18 +00:00
[LTO] Create Undefined Bitcode symbol when we drop a comdat member.
Differential Revision: http://reviews.llvm.org/D19389 llvm-svn: 267181
This commit is contained in:
parent
9598f10104
commit
9f8efffe29
@ -458,16 +458,19 @@ static uint8_t getGvVisibility(const GlobalValue *GV) {
|
||||
}
|
||||
|
||||
SymbolBody *
|
||||
BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
|
||||
BitcodeFile::createBody(const DenseSet<const Comdat *> &KeptComdats,
|
||||
const IRObjectFile &Obj,
|
||||
const BasicSymbolRef &Sym) {
|
||||
const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl());
|
||||
if (GV)
|
||||
if (const Comdat *C = GV->getComdat())
|
||||
if (!KeptComdats.count(C))
|
||||
return nullptr;
|
||||
const BasicSymbolRef &Sym,
|
||||
const GlobalValue *GV) {
|
||||
SmallString<64> Name;
|
||||
raw_svector_ostream OS(Name);
|
||||
Sym.printName(OS);
|
||||
StringRef NameRef = Saver.save(StringRef(Name));
|
||||
SymbolBody *Body;
|
||||
|
||||
uint32_t Flags = Sym.getFlags();
|
||||
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
|
||||
|
||||
uint8_t Visibility;
|
||||
if (GV)
|
||||
Visibility = getGvVisibility(GV);
|
||||
@ -476,28 +479,37 @@ BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
|
||||
// protected visibility.
|
||||
Visibility = STV_DEFAULT;
|
||||
|
||||
SmallString<64> Name;
|
||||
raw_svector_ostream OS(Name);
|
||||
Sym.printName(OS);
|
||||
StringRef NameRef = Saver.save(StringRef(Name));
|
||||
if (GV)
|
||||
if (const Comdat *C = GV->getComdat())
|
||||
if (!KeptComdats.count(C)) {
|
||||
Body = new (Alloc)
|
||||
UndefinedBitcode(NameRef, IsWeak, Visibility);
|
||||
return Body;
|
||||
}
|
||||
|
||||
const Module &M = Obj.getModule();
|
||||
SymbolBody *Body;
|
||||
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
|
||||
if (Flags & BasicSymbolRef::SF_Undefined) {
|
||||
Body = new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility);
|
||||
} else if (Flags & BasicSymbolRef::SF_Common) {
|
||||
if (Flags & BasicSymbolRef::SF_Undefined)
|
||||
return new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility);
|
||||
if (Flags & BasicSymbolRef::SF_Common) {
|
||||
// FIXME: Set SF_Common flag correctly for module asm symbols, and expose
|
||||
// size and alignment.
|
||||
assert(GV);
|
||||
const DataLayout &DL = M.getDataLayout();
|
||||
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
|
||||
Body = new (Alloc)
|
||||
return new (Alloc)
|
||||
DefinedCommon(NameRef, Size, GV->getAlignment(),
|
||||
IsWeak ? STB_WEAK : STB_GLOBAL, Visibility, /*Type*/ 0);
|
||||
} else {
|
||||
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
|
||||
}
|
||||
return new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
|
||||
}
|
||||
|
||||
SymbolBody *
|
||||
BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
|
||||
const IRObjectFile &Obj,
|
||||
const BasicSymbolRef &Sym) {
|
||||
const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl());
|
||||
SymbolBody *Body = createBody(KeptComdats, Obj, Sym, GV);
|
||||
|
||||
// FIXME: Expose a thread-local flag for module asm symbols.
|
||||
if (GV) {
|
||||
if (GV->isThreadLocal())
|
||||
|
@ -226,6 +226,11 @@ private:
|
||||
createSymbolBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
|
||||
const llvm::object::IRObjectFile &Obj,
|
||||
const llvm::object::BasicSymbolRef &Sym);
|
||||
SymbolBody *
|
||||
createBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
|
||||
const llvm::object::IRObjectFile &Obj,
|
||||
const llvm::object::BasicSymbolRef &Sym,
|
||||
const llvm::GlobalValue *GV);
|
||||
};
|
||||
|
||||
// .so file.
|
||||
|
5
lld/test/ELF/lto/Inputs/comdat.s
Normal file
5
lld/test/ELF/lto/Inputs/comdat.s
Normal file
@ -0,0 +1,5 @@
|
||||
.section .text.f,"axG",@progbits,c,comdat
|
||||
.globl foo
|
||||
|
||||
foo:
|
||||
retq
|
40
lld/test/ELF/lto/comdat2.ll
Normal file
40
lld/test/ELF/lto/comdat2.ll
Normal file
@ -0,0 +1,40 @@
|
||||
; RUN: llvm-as %s -o %t.o
|
||||
; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
|
||||
; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
|
||||
; RUN: llvm-readobj -t %t.so | FileCheck %s
|
||||
; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared
|
||||
; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
|
||||
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
$c = comdat any
|
||||
|
||||
define protected void @foo() comdat($c) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: Symbol {
|
||||
; CHECK: Name: foo
|
||||
; CHECK-NEXT: Value: 0x1000
|
||||
; CHECK-NEXT: Size: 1
|
||||
; CHECK-NEXT: Binding: Global
|
||||
; CHECK-NEXT: Type: Function
|
||||
; CHECK-NEXT: Other [
|
||||
; CHECK-NEXT: STV_PROTECTED
|
||||
; CHECK-NEXT: ]
|
||||
; CHECK-NEXT: Section: .text
|
||||
; CHECK-NEXT: }
|
||||
|
||||
; OTHER: Symbol {
|
||||
; OTHER: Name: foo
|
||||
; OTHER-NEXT: Value: 0x1000
|
||||
; OTHER-NEXT: Size: 0
|
||||
; OTHER-NEXT: Binding: Global
|
||||
; OTHER-NEXT: Type: None
|
||||
; OTHER-NEXT: Other [
|
||||
; OTHER-NEXT: STV_PROTECTED
|
||||
; OTHER-NEXT: ]
|
||||
; OTHER-NEXT: Section: .text
|
||||
; OTHER-NEXT: }
|
Loading…
Reference in New Issue
Block a user