1
0
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:
Sam Clegg 2020-12-08 21:47:19 -08:00
parent 99ada595aa
commit cee0963ebc
6 changed files with 40 additions and 12 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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;
} }

View File

@ -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();
} }
} }

View File

@ -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) {

View File

@ -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);