Index: llvm/trunk/include/llvm/BinaryFormat/Wasm.h =================================================================== --- llvm/trunk/include/llvm/BinaryFormat/Wasm.h +++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h @@ -101,7 +101,7 @@ uint32_t CodeSectionOffset; uint32_t Size; StringRef Name; // from the "linking" or "names" section - StringRef Comdat; // from the "comdat info" section + uint32_t Comdat; // from the "comdat info" section }; struct WasmDataSegment { @@ -111,7 +111,7 @@ StringRef Name; uint32_t Alignment; uint32_t Flags; - StringRef Comdat; // from the "comdat info" section + uint32_t Comdat; // from the "comdat info" section }; struct WasmElemSegment { @@ -160,6 +160,7 @@ struct WasmLinkingData { std::vector InitFunctions; + std::vector Comdats; std::vector SymbolTable; }; Index: llvm/trunk/include/llvm/Object/Wasm.h =================================================================== --- llvm/trunk/include/llvm/Object/Wasm.h +++ llvm/trunk/include/llvm/Object/Wasm.h @@ -141,7 +141,6 @@ ArrayRef elements() const { return ElemSegments; } ArrayRef dataSegments() const { return DataSegments; } ArrayRef functions() const { return Functions; } - ArrayRef comdats() const { return Comdats; } ArrayRef debugNames() const { return DebugNames; } uint32_t startFunction() const { return StartFunction; } uint32_t getNumImportedGlobals() const { return NumImportedGlobals; } @@ -255,7 +254,6 @@ std::vector DataSegments; std::vector Functions; std::vector Symbols; - std::vector Comdats; std::vector DebugNames; uint32_t StartFunction = -1; bool HasLinkingSection = false; Index: llvm/trunk/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/WasmObjectFile.cpp +++ llvm/trunk/lib/Object/WasmObjectFile.cpp @@ -485,12 +485,12 @@ { uint32_t ComdatCount = readVaruint32(Ptr); StringSet<> ComdatSet; - while (ComdatCount--) { + for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) { StringRef Name = readString(Ptr); if (Name.empty() || !ComdatSet.insert(Name).second) return make_error("Bad/duplicate COMDAT name " + Twine(Name), object_error::parse_failed); - Comdats.emplace_back(Name); + LinkingData.Comdats.emplace_back(Name); uint32_t Flags = readVaruint32(Ptr); if (Flags != 0) return make_error("Unsupported COMDAT flags", @@ -508,19 +508,19 @@ if (Index >= DataSegments.size()) return make_error("COMDAT data index out of range", object_error::parse_failed); - if (!DataSegments[Index].Data.Comdat.empty()) + if (DataSegments[Index].Data.Comdat != UINT32_MAX) return make_error("Data segment in two COMDATs", object_error::parse_failed); - DataSegments[Index].Data.Comdat = Name; + DataSegments[Index].Data.Comdat = ComdatIndex; break; case wasm::WASM_COMDAT_FUNCTION: if (!isDefinedFunctionIndex(Index)) return make_error("COMDAT function index out of range", object_error::parse_failed); - if (!getDefinedFunction(Index).Comdat.empty()) + if (getDefinedFunction(Index).Comdat != UINT32_MAX) return make_error("Function in two COMDATs", object_error::parse_failed); - getDefinedFunction(Index).Comdat = Name; + getDefinedFunction(Index).Comdat = ComdatIndex; break; } } @@ -878,6 +878,8 @@ uint32_t BodySize = FunctionEnd - Ptr; Function.Body = ArrayRef(Ptr, BodySize); + // This will be set later when reading in the linking metadata section. + Function.Comdat = UINT32_MAX; Ptr += BodySize; assert(Ptr == FunctionEnd); Functions.push_back(Function); @@ -924,8 +926,11 @@ return Err; uint32_t Size = readVaruint32(Ptr); Segment.Data.Content = ArrayRef(Ptr, Size); + // The rest of these Data fields are set later, when reading in the linking + // metadata section. Segment.Data.Alignment = 0; Segment.Data.Flags = 0; + Segment.Data.Comdat = UINT32_MAX; Segment.SectionOffset = Ptr - Start; Ptr += Size; DataSegments.push_back(Segment); Index: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp =================================================================== --- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp +++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp @@ -62,15 +62,12 @@ CustomSec = std::move(NameSec); } else if (WasmSec.Name == "linking") { std::unique_ptr LinkingSec = make_unique(); - std::map ComdatIndexes; - for (StringRef ComdatName : Obj.comdats()) { - ComdatIndexes[ComdatName] = LinkingSec->Comdats.size(); + ArrayRef Comdats = Obj.linkingData().Comdats; + for (StringRef ComdatName : Comdats) LinkingSec->Comdats.emplace_back(WasmYAML::Comdat{ComdatName, {}}); - } for (auto &Func : Obj.functions()) { - if (!Func.Comdat.empty()) { - auto &Comdat = LinkingSec->Comdats[ComdatIndexes[Func.Comdat]]; - Comdat.Entries.emplace_back( + if (Func.Comdat != UINT32_MAX) { + LinkingSec->Comdats[Func.Comdat].Entries.emplace_back( WasmYAML::ComdatEntry{wasm::WASM_COMDAT_FUNCTION, Func.Index}); } } @@ -84,9 +81,8 @@ SegmentInfo.Flags = Segment.Data.Flags; LinkingSec->SegmentInfos.push_back(SegmentInfo); } - if (!Segment.Data.Comdat.empty()) { - auto &Comdat = LinkingSec->Comdats[ComdatIndexes[Segment.Data.Comdat]]; - Comdat.Entries.emplace_back( + if (Segment.Data.Comdat != UINT32_MAX) { + LinkingSec->Comdats[Segment.Data.Comdat].Entries.emplace_back( WasmYAML::ComdatEntry{wasm::WASM_COMDAT_DATA, SegmentIndex}); } SegmentIndex++;