mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 23:51:56 +00:00
Reland "[WebAssembly] Add support for visibility flag""
Subscribers: jfb, dschuff, jgravelle-google, aheejin, sunfish Differential Revision: https://reviews.llvm.org/D40773 llvm-svn: 319627
This commit is contained in:
parent
a2b35dac03
commit
4b27c0554c
@ -4,13 +4,13 @@ target triple = "wasm32-unknown-unknown-wasm"
|
||||
@indirect_bar = hidden local_unnamed_addr global i32 ()* @bar, align 4
|
||||
|
||||
; Function Attrs: norecurse nounwind readnone
|
||||
define hidden i32 @bar() #0 {
|
||||
define i32 @bar() #0 {
|
||||
entry:
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @call_bar_indirect() local_unnamed_addr #1 {
|
||||
define void @call_bar_indirect() local_unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = load i32 ()*, i32 ()** @indirect_bar, align 4
|
||||
%call = tail call i32 %0() #2
|
||||
|
14
lld/test/wasm/Inputs/hidden.ll
Normal file
14
lld/test/wasm/Inputs/hidden.ll
Normal file
@ -0,0 +1,14 @@
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
; Function Attrs: norecurse nounwind readnone
|
||||
define hidden i32 @archiveHidden() #0 {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; Function Attrs: norecurse nounwind readnone
|
||||
define i32 @archiveDefault() #1 {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
@ -2,7 +2,7 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
; Function Attrs: norecurse nounwind readnone
|
||||
define hidden i32 @ret32(float %arg) #0 {
|
||||
define i32 @ret32(float %arg) #0 {
|
||||
entry:
|
||||
ret i32 0
|
||||
; ptrtoint (i32 (float)* @ret32 to i32)
|
||||
|
@ -1,7 +1,7 @@
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
define hidden i64 @ret64(double %arg) local_unnamed_addr #0 {
|
||||
define i64 @ret64(double %arg) local_unnamed_addr #0 {
|
||||
entry:
|
||||
ret i64 1
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ entry:
|
||||
|
||||
@bar = weak alias i32 (), i32 ()* @foo
|
||||
|
||||
define hidden i32 @call_bar() #0 {
|
||||
define i32 @call_bar() #0 {
|
||||
entry:
|
||||
%call = call i32 @bar()
|
||||
ret i32 %call
|
||||
|
@ -11,16 +11,16 @@
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
@indirect_func = hidden local_unnamed_addr global i32 ()* @foo, align 4
|
||||
@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
|
||||
|
||||
; Function Attrs: norecurse nounwind readnone
|
||||
define hidden i32 @foo() #0 {
|
||||
define i32 @foo() #0 {
|
||||
entry:
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @_start() local_unnamed_addr #1 {
|
||||
define void @_start() local_unnamed_addr #1 {
|
||||
entry:
|
||||
%0 = load i32 ()*, i32 ()** @indirect_func, align 4
|
||||
%call = tail call i32 %0() #2
|
||||
@ -63,6 +63,9 @@ entry:
|
||||
; CHECK-NEXT: - Name: memory
|
||||
; CHECK-NEXT: Kind: MEMORY
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 3
|
||||
; CHECK-NEXT: - Name: bar
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 0
|
||||
@ -72,9 +75,6 @@ entry:
|
||||
; CHECK-NEXT: - Name: foo
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 2
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 3
|
||||
; CHECK: - Type: ELEM
|
||||
; CHECK-NEXT: Segments:
|
||||
; CHECK-NEXT: - Offset:
|
||||
|
@ -7,7 +7,7 @@
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
define hidden void @entry() local_unnamed_addr #0 {
|
||||
define void @entry() local_unnamed_addr #0 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
46
lld/test/wasm/visibility-hidden.ll
Normal file
46
lld/test/wasm/visibility-hidden.ll
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s
|
||||
; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/hidden.ll -o %t2.o
|
||||
; RUN: llvm-ar rcs %t2.a %t2.o
|
||||
; RUN: lld -flavor wasm %t.o %t2.a -o %t.wasm
|
||||
; RUN: obj2yaml %t.wasm | FileCheck %s
|
||||
|
||||
; Test that hidden symbols are not exported, whether pulled in from an archive
|
||||
; or directly.
|
||||
|
||||
define hidden i32 @objectHidden() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define i32 @objectDefault() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @archiveHidden()
|
||||
declare i32 @archiveDefault()
|
||||
|
||||
define i32 @_start() {
|
||||
entry:
|
||||
%call1 = call i32 @objectHidden()
|
||||
%call2 = call i32 @objectDefault()
|
||||
%call3 = call i32 @archiveHidden()
|
||||
%call4 = call i32 @archiveDefault()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; CHECK: - Type: EXPORT
|
||||
; CHECK-NEXT: Exports:
|
||||
; CHECK-NEXT: - Name: memory
|
||||
; CHECK-NEXT: Kind: MEMORY
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 2
|
||||
; CHECK-NEXT: - Name: archiveDefault
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 4
|
||||
; CHECK-NEXT: - Name: objectDefault
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Type:
|
@ -53,12 +53,12 @@ entry:
|
||||
; CHECK-NEXT: - Name: memory
|
||||
; CHECK-NEXT: Kind: MEMORY
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: bar
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Name: bar
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: foo
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 2
|
||||
|
@ -47,12 +47,12 @@ entry:
|
||||
; CHECK-NEXT: - Name: memory
|
||||
; CHECK-NEXT: Kind: MEMORY
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: bar
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: bar
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Name: foo
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
|
@ -9,16 +9,16 @@
|
||||
|
||||
declare extern_weak i32 @foo()
|
||||
|
||||
define hidden i8* @get_address_of_foo() #0 {
|
||||
define i8* @get_address_of_foo() #0 {
|
||||
entry:
|
||||
ret i8* bitcast (i32 ()* @foo to i8*)
|
||||
}
|
||||
|
||||
define hidden i32* @get_address_of_global_var() #0 {
|
||||
define i32* @get_address_of_global_var() #0 {
|
||||
ret i32* @global_var
|
||||
}
|
||||
|
||||
define hidden i32 @_start() #0 {
|
||||
define i32 @_start() #0 {
|
||||
entry:
|
||||
%0 = load i32, i32* @global_var, align 4
|
||||
ret i32 %0
|
||||
@ -57,15 +57,15 @@ entry:
|
||||
; CHECK-NEXT: - Name: memory
|
||||
; CHECK-NEXT: Kind: MEMORY
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 2
|
||||
; CHECK-NEXT: - Name: get_address_of_foo
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 0
|
||||
; CHECK-NEXT: - Name: get_address_of_global_var
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Name: _start
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 2
|
||||
; CHECK-NEXT: - Type: ELEM
|
||||
; CHECK-NEXT: Segments:
|
||||
; CHECK-NEXT: - Offset:
|
||||
|
@ -74,6 +74,8 @@ void Symbol::update(Kind K, InputFile *F, const WasmSymbol *WasmSym,
|
||||
|
||||
bool Symbol::isWeak() const { return Sym && Sym->isWeak(); }
|
||||
|
||||
bool Symbol::isHidden() const { return Sym && Sym->isHidden(); }
|
||||
|
||||
std::string lld::toString(wasm::Symbol &Sym) {
|
||||
return wasm::displayName(Sym.getName());
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
bool isGlobal() const { return !isFunction(); }
|
||||
bool isLocal() const { return IsLocal; }
|
||||
bool isWeak() const;
|
||||
bool isHidden() const;
|
||||
|
||||
// Returns the symbol name.
|
||||
StringRef getName() const { return Name; }
|
||||
|
@ -259,22 +259,26 @@ void Writer::createTableSection() {
|
||||
void Writer::createExportSection() {
|
||||
// Memory is and main function are exported for executables.
|
||||
bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
|
||||
bool ExportMain = !Config->Relocatable;
|
||||
bool ExportOther = true; // Config->Relocatable;
|
||||
bool ExportOther = true; // ??? TODO Config->Relocatable;
|
||||
bool ExportHidden = Config->Relocatable;
|
||||
Symbol *EntrySym = Symtab->find(Config->Entry);
|
||||
bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
|
||||
|
||||
uint32_t NumExports = 0;
|
||||
|
||||
if (ExportMemory)
|
||||
++NumExports;
|
||||
|
||||
if (ExportMain && !ExportOther)
|
||||
if (ExportEntry)
|
||||
++NumExports;
|
||||
|
||||
if (ExportOther) {
|
||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||
for (Symbol *Sym : File->getSymbols()) {
|
||||
if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
|
||||
Sym->WrittenToSymtab)
|
||||
(Sym->isHidden() && !ExportHidden) || Sym->WrittenToSymtab)
|
||||
continue;
|
||||
if (Sym == EntrySym)
|
||||
continue;
|
||||
Sym->WrittenToSymtab = true;
|
||||
++NumExports;
|
||||
@ -298,27 +302,21 @@ void Writer::createExportSection() {
|
||||
writeExport(OS, MemoryExport);
|
||||
}
|
||||
|
||||
if (ExportMain) {
|
||||
Symbol *Sym = Symtab->find(Config->Entry);
|
||||
if (Sym->isDefined()) {
|
||||
if (!Sym->isFunction())
|
||||
fatal("entry point is not a function: " + Sym->getName());
|
||||
|
||||
if (!ExportOther) {
|
||||
WasmExport MainExport;
|
||||
MainExport.Name = Config->Entry;
|
||||
MainExport.Kind = WASM_EXTERNAL_FUNCTION;
|
||||
MainExport.Index = Sym->getOutputIndex();
|
||||
writeExport(OS, MainExport);
|
||||
}
|
||||
}
|
||||
if (ExportEntry) {
|
||||
WasmExport EntryExport;
|
||||
EntryExport.Name = Config->Entry;
|
||||
EntryExport.Kind = WASM_EXTERNAL_FUNCTION;
|
||||
EntryExport.Index = EntrySym->getOutputIndex();
|
||||
writeExport(OS, EntryExport);
|
||||
}
|
||||
|
||||
if (ExportOther) {
|
||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||
for (Symbol *Sym : File->getSymbols()) {
|
||||
if (!Sym->isFunction() || Sym->isLocal() | Sym->isUndefined() ||
|
||||
!Sym->WrittenToSymtab)
|
||||
if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
|
||||
(Sym->isHidden() && !ExportHidden) || !Sym->WrittenToSymtab)
|
||||
continue;
|
||||
if (Sym == EntrySym)
|
||||
continue;
|
||||
Sym->WrittenToSymtab = false;
|
||||
log("Export: " + Sym->getName());
|
||||
@ -332,9 +330,6 @@ void Writer::createExportSection() {
|
||||
writeExport(OS, Export);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sbc): Export local symbols too, Even though they are not part
|
||||
// of the symbol table?
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user