[WebAssembly] Add support for named globals in the object format.

Differential Revision: https://reviews.llvm.org/D91769
This commit is contained in:
Sam Clegg 2020-11-18 21:38:23 -08:00
parent ea7ab5a42c
commit 1827005cfc
34 changed files with 233 additions and 59 deletions

View File

@ -62,4 +62,7 @@ _start:
# CHECK-NEXT: FunctionNames:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: _start
# CHECK-NEXT: GlobalNames:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: __stack_pointer
# CHECK-NEXT: ...

View File

@ -153,4 +153,7 @@ define void @call_ptr(i64 (i64)* %arg) {
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Name: call_ptr
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -43,4 +43,7 @@ _start:
# CHECK-NEXT: Name: myctor
# CHECK-NEXT: - Index: 2
# CHECK-NEXT: Name: _start
# CHECK-NEXT: GlobalNames:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: __stack_pointer
# CHECK-NEXT: ...

View File

@ -54,4 +54,7 @@ define void @_start() {
; MANGLE-NEXT: Name: _Z3fooi
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: _start
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -29,6 +29,9 @@ target triple = "wasm32-unknown-unknown"
; MERGE-NEXT: FunctionNames:
; MERGE-NEXT: - Index: 0
; MERGE-NEXT: Name: __wasm_call_ctors
; MERGE-NEXT: GlobalNames:
; MERGE-NEXT: - Index: 0
; MERGE-NEXT: Name: __stack_pointer
; MERGE-NOT: - Index:
; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.o
@ -66,6 +69,9 @@ target triple = "wasm32-unknown-unknown"
; SEPARATE-NEXT: FunctionNames:
; SEPARATE-NEXT: - Index: 0
; SEPARATE-NEXT: Name: __wasm_call_ctors
; SEPARATE-NEXT: GlobalNames:
; SEPARATE-NEXT: - Index: 0
; SEPARATE-NEXT: Name: __stack_pointer
; SEPARATE-NOT: - Index:
; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive.wasm %t.passive.o

View File

@ -41,4 +41,7 @@ declare i32 @ret32(float) local_unnamed_addr #1
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: ret32
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -37,4 +37,7 @@ declare i32 @ret32(float) local_unnamed_addr #1
; CHECK-NEXT: Name: ret32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: _start
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -42,6 +42,11 @@ _start:
# CHECK-NEXT: Name: _start
# CHECK-NEXT: - Index: 2
# CHECK-NEXT: Name: use_undef_global
# CHECK-NEXT: GlobalNames:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: used_undef_global
# CHECK-NEXT: - Index: 1
# CHECK-NEXT: Name: __stack_pointer
# CHECK-NEXT: ...
# RUN: wasm-ld --no-gc-sections --allow-undefined \
@ -84,4 +89,11 @@ _start:
# NO-GC-NEXT: Name: _start
# NO-GC-NEXT: - Index: 5
# NO-GC-NEXT: Name: use_undef_global
# NO-GC-NEXT: GlobalNames:
# NO-GC-NEXT: - Index: 0
# NO-GC-NEXT: Name: unused_undef_global
# NO-GC-NEXT: - Index: 1
# NO-GC-NEXT: Name: used_undef_global
# NO-GC-NEXT: - Index: 2
# NO-GC-NEXT: Name: __stack_pointer
# NO-GC-NEXT: ...

View File

@ -82,6 +82,11 @@ entry:
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: use_global
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: used_global
; CHECK-NEXT: ...
; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \
@ -150,6 +155,13 @@ entry:
; NO-GC-NEXT: Name: _start
; NO-GC-NEXT: - Index: 4
; NO-GC-NEXT: Name: use_global
; NO-GC-NEXT: GlobalNames:
; NO-GC-NEXT: - Index: 0
; NO-GC-NEXT: Name: __stack_pointer
; NO-GC-NEXT: - Index: 1
; NO-GC-NEXT: Name: unused_global
; NO-GC-NEXT: - Index: 2
; NO-GC-NEXT: Name: used_global
; NO-GC-NEXT: ...
; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR

View File

@ -127,6 +127,9 @@ entry:
; CHECK-NEXT: Name: .Lcall_dtors.2002
; CHECK-NEXT: - Index: 22
; CHECK-NEXT: Name: .Lregister_call_dtors.2002
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...
; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm

View File

@ -21,6 +21,9 @@
; CHECK-NEXT: Name: ret64
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: ret32
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...
; NO-LOAD: Name: name
@ -31,6 +34,9 @@
; NO-LOAD-NEXT: Name: _start
; NO-LOAD-NEXT: - Index: 2
; NO-LOAD-NEXT: Name: ret64
; NO-LOAD-NEXT: GlobalNames:
; NO-LOAD-NEXT: - Index: 0
; NO-LOAD-NEXT: Name: __stack_pointer
; NO-LOAD-NEXT: ...
; Verify that referencing a symbol that is not found doesn't result in a link

View File

@ -94,4 +94,7 @@ entry:
; CHECK-NEXT: Name: baz
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: _start
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -209,6 +209,9 @@
; CHECK-NEXT: Name: get_func2B
; CHECK-NEXT: - Index: 17
; CHECK-NEXT: Name: get_func3B
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -40,7 +40,7 @@ somedata:
# CHECK-NEXT: 400 5a 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata)
# CHECK-NEXT: 400 5a 4 somedata
# CHECK-NEXT: - 60 12 CUSTOM(.debug_info)
# CHECK-NEXT: - 72 17 CUSTOM(name)
# CHECK-NEXT: - 72 2b CUSTOM(name)
# RUN: not wasm-ld %t1.o -o /dev/null -Map=/ 2>&1 \
# RUN: | FileCheck -check-prefix=FAIL %s

View File

@ -27,4 +27,7 @@ entry:
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: ret32
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -52,6 +52,9 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr
; YAML-NEXT: Name: ret32
; YAML-NEXT: - Index: 3
; YAML-NEXT: Name: call_ret32
; YAML-NEXT: GlobalNames:
; YAML-NEXT: - Index: 0
; YAML-NEXT: Name: __stack_pointer
; YAML-NEXT: ...
; RELOC: Name: linking

View File

@ -69,4 +69,7 @@ entry:
; CHECK-NEXT: FunctionNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: _start
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -36,7 +36,7 @@ Sections:
...
# SPECIFIED: - Type: CUSTOM
# SPECIFIED-NEXT: Name: target_features
# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
@ -47,7 +47,7 @@ Sections:
# SPECIFIED-NEXT: ...
# UNSPECIFIED: - Type: CUSTOM
# UNSPECIFIED-NEXT: Name: target_features
# UNSPECIFIED: Name: target_features
# UNSPECIFIED-NEXT: Features:
# UNSPECIFIED-NEXT: - Prefix: USED
# UNSPECIFIED-NEXT: Name: bar
@ -58,14 +58,14 @@ Sections:
# UNSPECIFIED-NEXT: ...
# DISALLOWED: - Type: CUSTOM
# DISALLOWED-NEXT: Name: target_features
# DISALLOWED: Name: target_features
# DISALLOWED-NEXT: Features:
# DISALLOWED-NEXT: - Prefix: USED
# DISALLOWED-NEXT: Name: bar
# DISALLOWED-NEXT: ...
# NONE: - Type: CUSTOM
# NONE-NEXT: Name: target_features
# NONE: Name: target_features
# NONE-NEXT: Features:
# NONE-NEXT: - Prefix: USED
# NONE-NEXT: Name: bar

View File

@ -22,7 +22,7 @@ Sections:
# EMPTY-NOT: target_features
# SPECIFIED: - Type: CUSTOM
# SPECIFIED-NEXT: Name: target_features
# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar

View File

@ -41,7 +41,7 @@ Sections:
...
# SPECIFIED: - Type: CUSTOM
# SPECIFIED-NEXT: Name: target_features
# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
@ -54,7 +54,7 @@ Sections:
# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-required.yaml.tmp1.o is not allowed.{{$}}
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
# UNSPECIFIED-NOCHECK: Name: target_features
# UNSPECIFIED-NOCHECK-NEXT: Features:
# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
# UNSPECIFIED-NOCHECK-NEXT: Name: bar
@ -65,7 +65,7 @@ Sections:
# UNSPECIFIED-NOCHECK-NEXT: ...
# REQUIRED: - Type: CUSTOM
# REQUIRED-NEXT: Name: target_features
# REQUIRED: Name: target_features
# REQUIRED-NEXT: Features:
# REQUIRED-NEXT: - Prefix: USED
# REQUIRED-NEXT: Name: foo
@ -74,7 +74,7 @@ Sections:
# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-required.yaml.tmp1.o is disallowed by {{.*}}target-feature-required.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
# DISALLOWED-NOCHECK: - Type: CUSTOM
# DISALLOWED-NOCHECK-NEXT: Name: target_features
# DISALLOWED-NOCHECK: Name: target_features
# DISALLOWED-NOCHECK-NEXT: Features:
# DISALLOWED-NOCHECK-NEXT: - Prefix: USED
# DISALLOWED-NOCHECK-NEXT: Name: foo
@ -83,7 +83,7 @@ Sections:
# NONE: Missing target feature 'foo' in {{.*}}target-feature-required.yaml.tmp.none.o, required by {{.*}}target-feature-required.yaml.tmp1.o. Use --no-check-features to suppress.{{$}}
# NONE-NOCHECK: - Type: CUSTOM
# NONE-NOCHECK-NEXT: Name: target_features
# NONE-NOCHECK: Name: target_features
# NONE-NOCHECK-NEXT: Features:
# NONE-NOCHECK-NEXT: - Prefix: USED
# NONE-NOCHECK-NEXT: Name: foo

View File

@ -43,7 +43,7 @@ Sections:
...
# SPECIFIED: - Type: CUSTOM
# SPECIFIED-NEXT: Name: target_features
# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
@ -56,7 +56,7 @@ Sections:
# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-used.yaml.tmp1.o is not allowed.{{$}}
# UNSPECIFIED-NOCHECK: - Type: CUSTOM
# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
# UNSPECIFIED-NOCHECK: Name: target_features
# UNSPECIFIED-NOCHECK-NEXT: Features:
# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
# UNSPECIFIED-NOCHECK-NEXT: Name: bar
@ -67,14 +67,14 @@ Sections:
# UNSPECIFIED-NOCHECK-NEXT: ...
# USED: - Type: CUSTOM
# USED-NEXT: Name: target_features
# USED: Name: target_features
# USED-NEXT: Features:
# USED-NEXT: - Prefix: USED
# USED-NEXT: Name: foo
# USED-NEXT: ...
# REQUIRED: - Type: CUSTOM
# REQUIRED-NEXT: Name: target_features
# REQUIRED: Name: target_features
# REQUIRED-NEXT: Features:
# REQUIRED-NEXT: - Prefix: USED
# REQUIRED-NEXT: Name: foo
@ -83,14 +83,14 @@ Sections:
# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-used.yaml.tmp1.o is disallowed by {{.*}}target-feature-used.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
# DISALLOWED-NOCHECK: - Type: CUSTOM
# DISALLOWED-NOCHECK-NEXT: Name: target_features
# DISALLOWED-NOCHECK: Name: target_features
# DISALLOWED-NOCHECK-NEXT: Features:
# DISALLOWED-NOCHECK-NEXT: - Prefix: USED
# DISALLOWED-NOCHECK-NEXT: Name: foo
# DISALLOWED-NOCHECK-NEXT: ...
# NONE: - Type: CUSTOM
# NONE-NEXT: Name: target_features
# NONE: Name: target_features
# NONE-NEXT: Features:
# NONE-NEXT: - Prefix: USED
# NONE-NEXT: Name: foo

View File

@ -96,4 +96,7 @@ define i32 @callWeakFuncs() {
; CHECK-NEXT: Name: 'undefined_weak:weakFunc3'
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: callWeakFuncs
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -129,4 +129,7 @@ entry:
; CHECK-NEXT: Name: call_alias_ptr
; CHECK-NEXT: - Index: 6
; CHECK-NEXT: Name: call_direct_ptr
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -121,6 +121,9 @@ entry:
; CHECK-NEXT: Name: call_alias_ptr
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: Name: call_direct_ptr
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...
; RUN: wasm-ld --relocatable %t.o %t2.o -o %t.reloc.o
@ -288,4 +291,7 @@ entry:
; RELOC-NEXT: Name: call_alias_ptr
; RELOC-NEXT: - Index: 5
; RELOC-NEXT: Name: call_direct_ptr
; RELOC-NEXT: GlobalNames:
; RELOC-NEXT: - Index: 0
; RELOC-NEXT: Name: __stack_pointer
; RELOC-NEXT: ...

View File

@ -115,4 +115,7 @@ entry:
; CHECK-NEXT: Name: exportWeak1
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: exportWeak2
; CHECK-NEXT: GlobalNames:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __stack_pointer
; CHECK-NEXT: ...

View File

@ -532,8 +532,9 @@ void LinkingSection::addToSymtab(Symbol *sym) {
symtabEntries.emplace_back(sym);
}
unsigned NameSection::numNames() const {
unsigned NameSection::numNamedFunctions() const {
unsigned numNames = out.importSec->getNumImportedFunctions();
for (const InputFunction *f : out.functionSec->inputFunctions)
if (!f->getName().empty() || !f->getDebugName().empty())
++numNames;
@ -541,32 +542,74 @@ unsigned NameSection::numNames() const {
return numNames;
}
unsigned NameSection::numNamedGlobals() const {
unsigned numNames = out.importSec->getNumImportedGlobals();
for (const InputGlobal *g : out.globalSec->inputGlobals)
if (!g->getName().empty())
++numNames;
numNames += out.globalSec->internalGotSymbols.size();
return numNames;
}
// Create the custom "name" section containing debug symbol names.
void NameSection::writeBody() {
SubSection sub(WASM_NAMES_FUNCTION);
writeUleb128(sub.os, numNames(), "name count");
unsigned count = numNamedFunctions();
if (count) {
SubSection sub(WASM_NAMES_FUNCTION);
writeUleb128(sub.os, count, "name count");
// Names must appear in function index order. As it happens importedSymbols
// and inputFunctions are numbered in order with imported functions coming
// first.
for (const Symbol *s : out.importSec->importedSymbols) {
if (auto *f = dyn_cast<FunctionSymbol>(s)) {
writeUleb128(sub.os, f->getFunctionIndex(), "func index");
writeStr(sub.os, toString(*s), "symbol name");
}
}
for (const InputFunction *f : out.functionSec->inputFunctions) {
if (!f->getName().empty()) {
writeUleb128(sub.os, f->getFunctionIndex(), "func index");
if (!f->getDebugName().empty()) {
writeStr(sub.os, f->getDebugName(), "symbol name");
} else {
writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name");
// Function names appear in function index order. As it happens
// importedSymbols and inputFunctions are numbered in order with imported
// functions coming first.
for (const Symbol *s : out.importSec->importedSymbols) {
if (auto *f = dyn_cast<FunctionSymbol>(s)) {
writeUleb128(sub.os, f->getFunctionIndex(), "func index");
writeStr(sub.os, toString(*s), "symbol name");
}
}
for (const InputFunction *f : out.functionSec->inputFunctions) {
if (!f->getName().empty()) {
writeUleb128(sub.os, f->getFunctionIndex(), "func index");
if (!f->getDebugName().empty()) {
writeStr(sub.os, f->getDebugName(), "symbol name");
} else {
writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name");
}
}
}
sub.writeTo(bodyOutputStream);
}
sub.writeTo(bodyOutputStream);
count = numNamedGlobals();
if (count) {
SubSection sub(WASM_NAMES_GLOBAL);
writeUleb128(sub.os, count, "name count");
for (const Symbol *s : out.importSec->importedSymbols) {
if (auto *g = dyn_cast<GlobalSymbol>(s)) {
writeUleb128(sub.os, g->getGlobalIndex(), "global index");
writeStr(sub.os, toString(*s), "symbol name");
}
}
for (const Symbol *s : out.importSec->gotSymbols) {
writeUleb128(sub.os, s->getGOTIndex(), "global index");
writeStr(sub.os, toString(*s), "symbol name");
}
for (const InputGlobal *g : out.globalSec->inputGlobals) {
if (!g->getName().empty()) {
writeUleb128(sub.os, g->getGlobalIndex(), "global index");
writeStr(sub.os, maybeDemangleSymbol(g->getName()), "symbol name");
}
}
for (Symbol *s : out.globalSec->internalGotSymbols) {
writeUleb128(sub.os, s->getGOTIndex(), "global index");
writeStr(sub.os, toString(*s), "symbol name");
}
sub.writeTo(bodyOutputStream);
}
}
void ProducersSection::addInfo(const WasmProducerInfo &info) {

View File

@ -119,13 +119,13 @@ public:
}
std::vector<const Symbol *> importedSymbols;
std::vector<const Symbol *> gotSymbols;
protected:
bool isSealed = false;
unsigned numImportedGlobals = 0;
unsigned numImportedFunctions = 0;
unsigned numImportedEvents = 0;
std::vector<const Symbol *> gotSymbols;
};
class FunctionSection : public SyntheticSection {
@ -221,11 +221,11 @@ public:
void generateRelocationCode(raw_ostream &os) const;
std::vector<const DefinedData *> dataAddressGlobals;
std::vector<InputGlobal *> inputGlobals;
std::vector<Symbol *> internalGotSymbols;
protected:
bool isSealed = false;
std::vector<InputGlobal *> inputGlobals;
std::vector<Symbol *> internalGotSymbols;
};
class ExportSection : public SyntheticSection {
@ -302,7 +302,9 @@ public:
return !config->stripDebug && !config->stripAll && numNames() > 0;
}
void writeBody() override;
unsigned numNames() const;
unsigned numNames() const { return numNamedGlobals() + numNamedFunctions(); }
unsigned numNamedGlobals() const;
unsigned numNamedFunctions() const;
};
class ProducersSection : public SyntheticSection {

View File

@ -195,7 +195,13 @@ struct WasmSymbolInfo {
};
};
struct WasmFunctionName {
enum class NameType {
FUNCTION,
GLOBAL
};
struct WasmDebugName {
NameType Type;
uint32_t Index;
StringRef Name;
};
@ -303,6 +309,7 @@ enum : uint8_t {
enum : unsigned {
WASM_NAMES_FUNCTION = 0x1,
WASM_NAMES_LOCAL = 0x2,
WASM_NAMES_GLOBAL = 0x7,
};
// Kind codes used in the custom "linking" section

View File

@ -149,7 +149,7 @@ public:
ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
ArrayRef<wasm::WasmFunctionName> debugNames() const { return DebugNames; }
ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
uint32_t startFunction() const { return StartFunction; }
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
uint32_t getNumImportedTables() const { return NumImportedTables; }
@ -284,7 +284,7 @@ private:
llvm::Optional<size_t> DataCount;
std::vector<wasm::WasmFunction> Functions;
std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmFunctionName> DebugNames;
std::vector<wasm::WasmDebugName> DebugNames;
uint32_t StartFunction = -1;
bool HasLinkingSection = false;
bool HasDylinkSection = false;

View File

@ -221,6 +221,7 @@ struct NameSection : CustomSection {
}
std::vector<NameEntry> FunctionNames;
std::vector<NameEntry> GlobalNames;
};
struct LinkingSection : CustomSection {

View File

@ -356,7 +356,8 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
}
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
llvm::DenseSet<uint64_t> Seen;
llvm::DenseSet<uint64_t> SeenFunctions;
llvm::DenseSet<uint64_t> SeenGlobals;
if (FunctionTypes.size() && !SeenCodeSection) {
return make_error<GenericBinaryError>("Names must come after code section",
object_error::parse_failed);
@ -367,20 +368,34 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
uint32_t Size = readVaruint32(Ctx);
const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
switch (Type) {
case wasm::WASM_NAMES_FUNCTION: {
case wasm::WASM_NAMES_FUNCTION:
case wasm::WASM_NAMES_GLOBAL: {
uint32_t Count = readVaruint32(Ctx);
while (Count--) {
uint32_t Index = readVaruint32(Ctx);
if (!Seen.insert(Index).second)
return make_error<GenericBinaryError>("Function named more than once",
object_error::parse_failed);
StringRef Name = readString(Ctx);
if (!isValidFunctionIndex(Index) || Name.empty())
return make_error<GenericBinaryError>("Invalid name entry",
object_error::parse_failed);
DebugNames.push_back(wasm::WasmFunctionName{Index, Name});
if (isDefinedFunctionIndex(Index))
getDefinedFunction(Index).DebugName = Name;
if (Type == wasm::WASM_NAMES_FUNCTION) {
if (!SeenFunctions.insert(Index).second)
return make_error<GenericBinaryError>(
"Function named more than once", object_error::parse_failed);
if (!isValidFunctionIndex(Index) || Name.empty())
return make_error<GenericBinaryError>("Invalid name entry",
object_error::parse_failed);
if (isDefinedFunctionIndex(Index))
getDefinedFunction(Index).DebugName = Name;
} else {
if (!SeenGlobals.insert(Index).second)
return make_error<GenericBinaryError>("Global named more than once",
object_error::parse_failed);
if (!isValidGlobalIndex(Index) || Name.empty())
return make_error<GenericBinaryError>("Invalid name entry",
object_error::parse_failed);
}
wasm::NameType T = Type == wasm::WASM_NAMES_FUNCTION
? wasm::NameType::FUNCTION
: wasm::NameType::GLOBAL;
DebugNames.push_back(wasm::WasmDebugName{T, Index, Name});
}
break;
}

View File

@ -268,6 +268,19 @@ void WasmWriter::writeSectionContent(raw_ostream &OS,
writeStringRef(NameEntry.Name, SubSection.getStream());
}
SubSection.done();
}
if (Section.GlobalNames.size()) {
writeUint8(OS, wasm::WASM_NAMES_GLOBAL);
SubSectionWriter SubSection(OS);
encodeULEB128(Section.GlobalNames.size(), SubSection.getStream());
for (const WasmYAML::NameEntry &NameEntry : Section.GlobalNames) {
encodeULEB128(NameEntry.Index, SubSection.getStream());
writeStringRef(NameEntry.Name, SubSection.getStream());
}
SubSection.done();
}
}

View File

@ -61,6 +61,7 @@ static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
IO.mapOptional("FunctionNames", Section.FunctionNames);
IO.mapOptional("GlobalNames", Section.GlobalNames);
}
static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {

View File

@ -65,11 +65,16 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
} else if (WasmSec.Name == "name") {
std::unique_ptr<WasmYAML::NameSection> NameSec =
std::make_unique<WasmYAML::NameSection>();
for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) {
for (const llvm::wasm::WasmDebugName &Name : Obj.debugNames()) {
WasmYAML::NameEntry NameEntry;
NameEntry.Name = Func.Name;
NameEntry.Index = Func.Index;
NameSec->FunctionNames.push_back(NameEntry);
NameEntry.Name = Name.Name;
NameEntry.Index = Name.Index;
if (Name.Type == llvm::wasm::NameType::FUNCTION) {
NameSec->FunctionNames.push_back(NameEntry);
} else {
assert(Name.Type == llvm::wasm::NameType::GLOBAL);
NameSec->GlobalNames.push_back(NameEntry);
}
}
CustomSec = std::move(NameSec);
} else if (WasmSec.Name == "linking") {