# 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: ...
; 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: ...
# 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: ...
; 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: ...
; 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
; 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
; 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: ...
; 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: ...
# 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 \
# 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: ...
; 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 \
; 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
; 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
; 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
; 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
; 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: ...
; 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: ...
# 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
; 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: ...
; 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
; 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: ...
...
# SPECIFIED: - Type: CUSTOM
-# SPECIFIED-NEXT: Name: target_features
+# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
# 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
# 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
# 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
...
# SPECIFIED: - Type: CUSTOM
-# SPECIFIED-NEXT: Name: target_features
+# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
# 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
# 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
# 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
# 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
...
# SPECIFIED: - Type: CUSTOM
-# SPECIFIED-NEXT: Name: target_features
+# SPECIFIED: Name: target_features
# SPECIFIED-NEXT: Features:
# SPECIFIED-NEXT: - Prefix: USED
# SPECIFIED-NEXT: Name: bar
# 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
# 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
# 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
; 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: ...
; 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: ...
; 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
; 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: ...
; 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: ...
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;
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");
-
- // 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");
+ unsigned count = numNamedFunctions();
+ if (count) {
+ SubSection sub(WASM_NAMES_FUNCTION);
+ writeUleb128(sub.os, count, "name count");
+
+ // 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");
+ 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) {
}
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 {
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 {
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 {
};
};
-struct WasmFunctionName {
+enum class NameType {
+ FUNCTION,
+ GLOBAL
+};
+
+struct WasmDebugName {
+ NameType Type;
uint32_t Index;
StringRef Name;
};
enum : unsigned {
WASM_NAMES_FUNCTION = 0x1,
WASM_NAMES_LOCAL = 0x2,
+ WASM_NAMES_GLOBAL = 0x7,
};
// Kind codes used in the custom "linking" section
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; }
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;
}
std::vector<NameEntry> FunctionNames;
+ std::vector<NameEntry> GlobalNames;
};
struct LinkingSection : CustomSection {
}
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);
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;
}
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();
+ }
}
void WasmWriter::writeSectionContent(raw_ostream &OS,
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) {
} 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") {