Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 22c4f95

Browse files
authored
[lld][WebAssembly] Improve merging multiple occurrences of an undefined symbol (#178550)
This change renames `setImportAttributes` to `updateExistingUndefined` which better defines what it does. We also now call this function for all different symbol types. In addition we preserve the `NO_STRIP` symbol attribute if any undefined reference is tagged as such. This is partial fix for #174676, although there seems to be anther crash that occurs after this issue is fixed.
1 parent 69c0f92 commit 22c4f95

2 files changed

Lines changed: 61 additions & 17 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Verify that the `no_strip` attribute on undefined symbols is preserved
2+
# as long as one of the undefined references is `no_strip`.
3+
# The indirect function table is created by the linker in the case that
4+
# the __indirect_function_table symbol is live (i.e. marked as no_strip).
5+
# This test verifies that the undefined symbol is NO_STRIP, even if the first
6+
# undefined reference is not NO_STRIP.
7+
#
8+
# RUN: split-file %s %t
9+
# RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown -o %t/main.o %t/main.s
10+
# RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown -o %t/other.o %t/other.s
11+
#
12+
# RUN: wasm-ld %t/main.o %t/other.o -o %t.wasm
13+
# RUN: obj2yaml %t.wasm | FileCheck %s
14+
#
15+
# RUN: wasm-ld %t/other.o %t/main.o -o %t2.wasm
16+
# RUN: obj2yaml %t2.wasm | FileCheck %s
17+
18+
#--- main.s
19+
.globl __indirect_function_table
20+
.tabletype __indirect_function_table, funcref
21+
.no_dead_strip __indirect_function_table
22+
23+
.globl _start
24+
_start:
25+
.functype _start () -> ()
26+
end_function
27+
28+
#--- other.s
29+
# This file contains a reference to __indirect_function_table that is not
30+
# marked as `.no_dead_strip`.
31+
.globl __indirect_function_table
32+
.tabletype __indirect_function_table, funcref
33+
34+
# CHECK: - Type: TABLE
35+
# CHECK-NEXT: Tables:
36+
# CHECK-NEXT: - Index: 0
37+
# CHECK-NEXT: ElemType: FUNCREF
38+
# CHECK-NEXT: Limits:
39+
# CHECK-NEXT: Flags: [ HAS_MAX ]
40+
# CHECK-NEXT: Minimum: 0x1
41+
# CHECK-NEXT: Maximum: 0x1

lld/wasm/SymbolTable.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -582,11 +582,10 @@ Symbol *SymbolTable::addDefinedTable(StringRef name, uint32_t flags,
582582
// With LTO these attributes are not available when the bitcode is read and only
583583
// become available when the LTO object is read. In this case we silently
584584
// replace the empty attributes with the valid ones.
585-
template <typename T>
586-
static void setImportAttributes(T *existing,
587-
std::optional<StringRef> importName,
588-
std::optional<StringRef> importModule,
589-
uint32_t flags, InputFile *file) {
585+
static void
586+
updateExistingUndefined(Symbol *existing, uint32_t flags, InputFile *file,
587+
std::optional<StringRef> importName = {},
588+
std::optional<StringRef> importModule = {}) {
590589
if (importName) {
591590
if (!existing->importName)
592591
existing->importName = importName;
@@ -612,6 +611,10 @@ static void setImportAttributes(T *existing,
612611
if (existing->isWeak() && binding != WASM_SYMBOL_BINDING_WEAK) {
613612
existing->flags = (existing->flags & ~WASM_SYMBOL_BINDING_MASK) | binding;
614613
}
614+
615+
// Certain flags such as NO_STRIP should be maintianed if either old or
616+
// new symbol is marked as such.
617+
existing->flags |= flags & WASM_SYMBOL_NO_STRIP;
615618
}
616619

617620
Symbol *SymbolTable::addUndefinedFunction(StringRef name,
@@ -675,12 +678,10 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
675678
replaceSym();
676679
}
677680
if (existingUndefined) {
678-
setImportAttributes(existingUndefined, importName, importModule, flags,
679-
file);
681+
updateExistingUndefined(existingUndefined, flags, file, importName,
682+
importModule);
680683
if (isCalledDirectly)
681684
existingUndefined->isCalledDirectly = true;
682-
if (s->isWeak())
683-
s->flags = flags;
684685
}
685686
}
686687

@@ -707,8 +708,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
707708
lazy->extract();
708709
} else if (s->isDefined()) {
709710
checkDataType(s, file);
710-
} else if (s->isWeak()) {
711-
s->flags = flags;
711+
} else {
712+
updateExistingUndefined(s, flags, file);
712713
}
713714
return s;
714715
}
@@ -734,8 +735,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
734735
lazy->extract();
735736
else if (s->isDefined())
736737
checkGlobalType(s, file, type);
737-
else if (s->isWeak())
738-
s->flags = flags;
738+
else
739+
updateExistingUndefined(s, flags, file);
739740
return s;
740741
}
741742

@@ -760,8 +761,8 @@ Symbol *SymbolTable::addUndefinedTable(StringRef name,
760761
lazy->extract();
761762
else if (s->isDefined())
762763
checkTableType(s, file, type);
763-
else if (s->isWeak())
764-
s->flags = flags;
764+
else
765+
updateExistingUndefined(s, flags, file);
765766
return s;
766767
}
767768

@@ -786,12 +787,13 @@ Symbol *SymbolTable::addUndefinedTag(StringRef name,
786787
lazy->extract();
787788
else if (s->isDefined())
788789
checkTagType(s, file, sig);
789-
else if (s->isWeak())
790-
s->flags = flags;
790+
else
791+
updateExistingUndefined(s, flags, file);
791792
return s;
792793
}
793794

794795
TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
796+
LLVM_DEBUG(llvm::dbgs() << "createUndefinedIndirectFunctionTable\n");
795797
WasmLimits limits{0, 0, 0, 0}; // Set by the writer.
796798
WasmTableType *type = make<WasmTableType>();
797799
type->ElemType = ValType::FUNCREF;
@@ -806,6 +808,7 @@ TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
806808
}
807809

808810
TableSymbol *SymbolTable::createDefinedIndirectFunctionTable(StringRef name) {
811+
LLVM_DEBUG(llvm::dbgs() << "createDefinedIndirectFunctionTable\n");
809812
const uint32_t invalidIndex = -1;
810813
WasmLimits limits{0, 0, 0, 0}; // Set by the writer.
811814
WasmTableType type{ValType::FUNCREF, limits};

0 commit comments

Comments
 (0)