mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[WebAssembly] Add support for named data sections in wasm binaries
Followup to https://reviews.llvm.org/D91769 which added support for names globals. Differential Revision: https://reviews.llvm.org/D92909
This commit is contained in:
parent
99ada595aa
commit
cee0963ebc
@ -202,7 +202,8 @@ struct WasmSymbolInfo {
|
|||||||
|
|
||||||
enum class NameType {
|
enum class NameType {
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
GLOBAL
|
GLOBAL,
|
||||||
|
DATA_SEGMENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WasmDebugName {
|
struct WasmDebugName {
|
||||||
@ -313,9 +314,10 @@ enum : uint8_t {
|
|||||||
|
|
||||||
// Kind codes used in the custom "name" section
|
// Kind codes used in the custom "name" section
|
||||||
enum : unsigned {
|
enum : unsigned {
|
||||||
WASM_NAMES_FUNCTION = 0x1,
|
WASM_NAMES_FUNCTION = 1,
|
||||||
WASM_NAMES_LOCAL = 0x2,
|
WASM_NAMES_LOCAL = 2,
|
||||||
WASM_NAMES_GLOBAL = 0x7,
|
WASM_NAMES_GLOBAL = 7,
|
||||||
|
WASM_NAMES_DATA_SEGMENT = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Kind codes used in the custom "linking" section
|
// Kind codes used in the custom "linking" section
|
||||||
|
@ -222,6 +222,7 @@ struct NameSection : CustomSection {
|
|||||||
|
|
||||||
std::vector<NameEntry> FunctionNames;
|
std::vector<NameEntry> FunctionNames;
|
||||||
std::vector<NameEntry> GlobalNames;
|
std::vector<NameEntry> GlobalNames;
|
||||||
|
std::vector<NameEntry> DataSegmentNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LinkingSection : CustomSection {
|
struct LinkingSection : CustomSection {
|
||||||
|
@ -357,6 +357,7 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
|
|||||||
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
|
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
|
||||||
llvm::DenseSet<uint64_t> SeenFunctions;
|
llvm::DenseSet<uint64_t> SeenFunctions;
|
||||||
llvm::DenseSet<uint64_t> SeenGlobals;
|
llvm::DenseSet<uint64_t> SeenGlobals;
|
||||||
|
llvm::DenseSet<uint64_t> SeenSegments;
|
||||||
if (FunctionTypes.size() && !SeenCodeSection) {
|
if (FunctionTypes.size() && !SeenCodeSection) {
|
||||||
return make_error<GenericBinaryError>("Names must come after code section",
|
return make_error<GenericBinaryError>("Names must come after code section",
|
||||||
object_error::parse_failed);
|
object_error::parse_failed);
|
||||||
@ -368,11 +369,13 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
|
|||||||
const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
|
const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case wasm::WASM_NAMES_FUNCTION:
|
case wasm::WASM_NAMES_FUNCTION:
|
||||||
case wasm::WASM_NAMES_GLOBAL: {
|
case wasm::WASM_NAMES_GLOBAL:
|
||||||
|
case wasm::WASM_NAMES_DATA_SEGMENT: {
|
||||||
uint32_t Count = readVaruint32(Ctx);
|
uint32_t Count = readVaruint32(Ctx);
|
||||||
while (Count--) {
|
while (Count--) {
|
||||||
uint32_t Index = readVaruint32(Ctx);
|
uint32_t Index = readVaruint32(Ctx);
|
||||||
StringRef Name = readString(Ctx);
|
StringRef Name = readString(Ctx);
|
||||||
|
wasm::NameType nameType = wasm::NameType::FUNCTION;
|
||||||
if (Type == wasm::WASM_NAMES_FUNCTION) {
|
if (Type == wasm::WASM_NAMES_FUNCTION) {
|
||||||
if (!SeenFunctions.insert(Index).second)
|
if (!SeenFunctions.insert(Index).second)
|
||||||
return make_error<GenericBinaryError>(
|
return make_error<GenericBinaryError>(
|
||||||
@ -383,18 +386,24 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
|
|||||||
|
|
||||||
if (isDefinedFunctionIndex(Index))
|
if (isDefinedFunctionIndex(Index))
|
||||||
getDefinedFunction(Index).DebugName = Name;
|
getDefinedFunction(Index).DebugName = Name;
|
||||||
} else {
|
} else if (Type == wasm::WASM_NAMES_GLOBAL) {
|
||||||
|
nameType = wasm::NameType::GLOBAL;
|
||||||
if (!SeenGlobals.insert(Index).second)
|
if (!SeenGlobals.insert(Index).second)
|
||||||
return make_error<GenericBinaryError>("Global named more than once",
|
return make_error<GenericBinaryError>("Global named more than once",
|
||||||
object_error::parse_failed);
|
object_error::parse_failed);
|
||||||
if (!isValidGlobalIndex(Index) || Name.empty())
|
if (!isValidGlobalIndex(Index) || Name.empty())
|
||||||
return make_error<GenericBinaryError>("Invalid name entry",
|
return make_error<GenericBinaryError>("Invalid name entry",
|
||||||
object_error::parse_failed);
|
object_error::parse_failed);
|
||||||
|
} else {
|
||||||
|
nameType = wasm::NameType::DATA_SEGMENT;
|
||||||
|
if (!SeenSegments.insert(Index).second)
|
||||||
|
return make_error<GenericBinaryError>(
|
||||||
|
"Segment named more than once", object_error::parse_failed);
|
||||||
|
if (Index > DataSegments.size())
|
||||||
|
return make_error<GenericBinaryError>("Invalid named data segment",
|
||||||
|
object_error::parse_failed);
|
||||||
}
|
}
|
||||||
wasm::NameType T = Type == wasm::WASM_NAMES_FUNCTION
|
DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
|
||||||
? wasm::NameType::FUNCTION
|
|
||||||
: wasm::NameType::GLOBAL;
|
|
||||||
DebugNames.push_back(wasm::WasmDebugName{T, Index, Name});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,19 @@ void WasmWriter::writeSectionContent(raw_ostream &OS,
|
|||||||
writeStringRef(NameEntry.Name, SubSection.getStream());
|
writeStringRef(NameEntry.Name, SubSection.getStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubSection.done();
|
||||||
|
}
|
||||||
|
if (Section.DataSegmentNames.size()) {
|
||||||
|
writeUint8(OS, wasm::WASM_NAMES_DATA_SEGMENT);
|
||||||
|
|
||||||
|
SubSectionWriter SubSection(OS);
|
||||||
|
|
||||||
|
encodeULEB128(Section.DataSegmentNames.size(), SubSection.getStream());
|
||||||
|
for (const WasmYAML::NameEntry &NameEntry : Section.DataSegmentNames) {
|
||||||
|
encodeULEB128(NameEntry.Index, SubSection.getStream());
|
||||||
|
writeStringRef(NameEntry.Name, SubSection.getStream());
|
||||||
|
}
|
||||||
|
|
||||||
SubSection.done();
|
SubSection.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
|
|||||||
IO.mapRequired("Name", Section.Name);
|
IO.mapRequired("Name", Section.Name);
|
||||||
IO.mapOptional("FunctionNames", Section.FunctionNames);
|
IO.mapOptional("FunctionNames", Section.FunctionNames);
|
||||||
IO.mapOptional("GlobalNames", Section.GlobalNames);
|
IO.mapOptional("GlobalNames", Section.GlobalNames);
|
||||||
|
IO.mapOptional("DataSegmentNames", Section.DataSegmentNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
|
static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
|
||||||
|
@ -70,9 +70,11 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
|
|||||||
NameEntry.Index = Name.Index;
|
NameEntry.Index = Name.Index;
|
||||||
if (Name.Type == llvm::wasm::NameType::FUNCTION) {
|
if (Name.Type == llvm::wasm::NameType::FUNCTION) {
|
||||||
NameSec->FunctionNames.push_back(NameEntry);
|
NameSec->FunctionNames.push_back(NameEntry);
|
||||||
} else {
|
} else if (Name.Type == llvm::wasm::NameType::GLOBAL) {
|
||||||
assert(Name.Type == llvm::wasm::NameType::GLOBAL);
|
|
||||||
NameSec->GlobalNames.push_back(NameEntry);
|
NameSec->GlobalNames.push_back(NameEntry);
|
||||||
|
} else {
|
||||||
|
assert(Name.Type == llvm::wasm::NameType::DATA_SEGMENT);
|
||||||
|
NameSec->DataSegmentNames.push_back(NameEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CustomSec = std::move(NameSec);
|
CustomSec = std::move(NameSec);
|
||||||
|
Loading…
Reference in New Issue
Block a user