mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
[WebAssembly] Use section index in relocation section header
Rather than referring to sections my their code, use the absolute index of the target section within the module. See https://github.com/WebAssembly/tool-conventions/issues/52 Differential Revision: https://reviews.llvm.org/D45980 llvm-svn: 330749
This commit is contained in:
parent
7ac9e5d337
commit
7ccbb03639
@ -212,9 +212,6 @@ private:
|
||||
const WasmSection &getWasmSection(DataRefImpl Ref) const;
|
||||
const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
|
||||
|
||||
WasmSection* findCustomSectionByName(StringRef Name);
|
||||
WasmSection* findSectionByType(uint32_t Type);
|
||||
|
||||
const uint8_t *getPtr(size_t Offset) const;
|
||||
Error parseSection(WasmSection &Sec);
|
||||
Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr,
|
||||
|
@ -50,6 +50,7 @@ struct SectionBookkeeping {
|
||||
uint64_t SizeOffset;
|
||||
// Where the contents of the section starts (after the header).
|
||||
uint64_t ContentsOffset;
|
||||
uint32_t Index;
|
||||
};
|
||||
|
||||
// The signature of a wasm function, in a struct capable of being used as a
|
||||
@ -188,9 +189,11 @@ class WasmObjectWriter : public MCObjectWriter {
|
||||
|
||||
// Relocations for fixing up references in the code section.
|
||||
std::vector<WasmRelocationEntry> CodeRelocations;
|
||||
uint32_t CodeSectionIndex;
|
||||
|
||||
// Relocations for fixing up references in the data section.
|
||||
std::vector<WasmRelocationEntry> DataRelocations;
|
||||
uint32_t DataSectionIndex;
|
||||
|
||||
// Index values to use for fixing up call_indirect type indices.
|
||||
// Maps function symbols to the index of the type of the function
|
||||
@ -213,6 +216,7 @@ class WasmObjectWriter : public MCObjectWriter {
|
||||
std::vector<WasmCustomSection> CustomSections;
|
||||
unsigned NumFunctionImports = 0;
|
||||
unsigned NumGlobalImports = 0;
|
||||
uint32_t SectionCount;
|
||||
|
||||
// TargetObjectWriter wrappers.
|
||||
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
|
||||
@ -280,8 +284,8 @@ private:
|
||||
void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
ArrayRef<WasmFunction> Functions);
|
||||
void writeDataSection();
|
||||
void writeCodeRelocSection();
|
||||
void writeDataRelocSection();
|
||||
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
|
||||
ArrayRef<WasmRelocationEntry> Relocations);
|
||||
void writeLinkingMetaDataSection(
|
||||
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
|
||||
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
|
||||
@ -292,10 +296,9 @@ private:
|
||||
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
|
||||
uint64_t ContentsOffset);
|
||||
|
||||
void writeRelocations(ArrayRef<WasmRelocationEntry> Relocations);
|
||||
uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
|
||||
uint32_t getFunctionType(const MCSymbolWasm& Symbol);
|
||||
uint32_t registerFunctionType(const MCSymbolWasm& Symbol);
|
||||
uint32_t getFunctionType(const MCSymbolWasm &Symbol);
|
||||
uint32_t registerFunctionType(const MCSymbolWasm &Symbol);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -316,6 +319,7 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section,
|
||||
|
||||
// The position where the section starts, for measuring its size.
|
||||
Section.ContentsOffset = getStream().tell();
|
||||
Section.Index = SectionCount++;
|
||||
}
|
||||
|
||||
void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section,
|
||||
@ -622,25 +626,6 @@ void WasmObjectWriter::applyRelocations(
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the portions of the relocation records that the linker will
|
||||
// need to handle.
|
||||
void WasmObjectWriter::writeRelocations(
|
||||
ArrayRef<WasmRelocationEntry> Relocations) {
|
||||
raw_pwrite_stream &Stream = getStream();
|
||||
for (const WasmRelocationEntry& RelEntry : Relocations) {
|
||||
|
||||
uint64_t Offset = RelEntry.Offset +
|
||||
RelEntry.FixupSection->getSectionOffset();
|
||||
uint32_t Index = getRelocationIndexValue(RelEntry);
|
||||
|
||||
write8(RelEntry.Type);
|
||||
encodeULEB128(Offset, Stream);
|
||||
encodeULEB128(Index, Stream);
|
||||
if (RelEntry.hasAddend())
|
||||
encodeSLEB128(RelEntry.Addend, Stream);
|
||||
}
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeTypeSection(
|
||||
ArrayRef<WasmFunctionType> FunctionTypes) {
|
||||
if (FunctionTypes.empty())
|
||||
@ -787,6 +772,7 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
|
||||
|
||||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_CODE);
|
||||
CodeSectionIndex = Section.Index;
|
||||
|
||||
encodeULEB128(Functions.size(), getStream());
|
||||
|
||||
@ -814,6 +800,7 @@ void WasmObjectWriter::writeDataSection() {
|
||||
|
||||
SectionBookkeeping Section;
|
||||
startSection(Section, wasm::WASM_SEC_DATA);
|
||||
DataSectionIndex = Section.Index;
|
||||
|
||||
encodeULEB128(DataSegments.size(), getStream()); // count
|
||||
|
||||
@ -833,38 +820,33 @@ void WasmObjectWriter::writeDataSection() {
|
||||
endSection(Section);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeCodeRelocSection() {
|
||||
void WasmObjectWriter::writeRelocSection(
|
||||
uint32_t SectionIndex, StringRef Name,
|
||||
ArrayRef<WasmRelocationEntry> Relocations) {
|
||||
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
|
||||
// for descriptions of the reloc sections.
|
||||
|
||||
if (CodeRelocations.empty())
|
||||
if (Relocations.empty())
|
||||
return;
|
||||
|
||||
SectionBookkeeping Section;
|
||||
startCustomSection(Section, "reloc.CODE");
|
||||
startCustomSection(Section, std::string("reloc.") + Name.str());
|
||||
|
||||
encodeULEB128(wasm::WASM_SEC_CODE, getStream());
|
||||
encodeULEB128(CodeRelocations.size(), getStream());
|
||||
raw_pwrite_stream &Stream = getStream();
|
||||
|
||||
writeRelocations(CodeRelocations);
|
||||
encodeULEB128(SectionIndex, Stream);
|
||||
encodeULEB128(Relocations.size(), Stream);
|
||||
for (const WasmRelocationEntry& RelEntry : Relocations) {
|
||||
uint64_t Offset = RelEntry.Offset +
|
||||
RelEntry.FixupSection->getSectionOffset();
|
||||
uint32_t Index = getRelocationIndexValue(RelEntry);
|
||||
|
||||
endSection(Section);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeDataRelocSection() {
|
||||
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
|
||||
// for descriptions of the reloc sections.
|
||||
|
||||
if (DataRelocations.empty())
|
||||
return;
|
||||
|
||||
SectionBookkeeping Section;
|
||||
startCustomSection(Section, "reloc.DATA");
|
||||
|
||||
encodeULEB128(wasm::WASM_SEC_DATA, getStream());
|
||||
encodeULEB128(DataRelocations.size(), getStream());
|
||||
|
||||
writeRelocations(DataRelocations);
|
||||
write8(RelEntry.Type);
|
||||
encodeULEB128(Offset, Stream);
|
||||
encodeULEB128(Index, Stream);
|
||||
if (RelEntry.hasAddend())
|
||||
encodeSLEB128(RelEntry.Addend, Stream);
|
||||
}
|
||||
|
||||
endSection(Section);
|
||||
}
|
||||
@ -1350,8 +1332,8 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
writeDataSection();
|
||||
writeUserCustomSections(CustomSections);
|
||||
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
|
||||
writeCodeRelocSection();
|
||||
writeDataRelocSection();
|
||||
writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
|
||||
writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
|
||||
|
||||
// TODO: Translate the .comment section to the output.
|
||||
// TODO: Translate debug sections to the output.
|
||||
|
@ -524,38 +524,15 @@ Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr,
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
WasmSection* WasmObjectFile::findCustomSectionByName(StringRef Name) {
|
||||
for (WasmSection& Section : Sections) {
|
||||
if (Section.Type == wasm::WASM_SEC_CUSTOM && Section.Name == Name)
|
||||
return &Section;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WasmSection* WasmObjectFile::findSectionByType(uint32_t Type) {
|
||||
assert(Type != wasm::WASM_SEC_CUSTOM);
|
||||
for (WasmSection& Section : Sections) {
|
||||
if (Section.Type == Type)
|
||||
return &Section;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
|
||||
const uint8_t *End) {
|
||||
uint8_t SectionCode = readUint8(Ptr);
|
||||
WasmSection* Section = nullptr;
|
||||
if (SectionCode == wasm::WASM_SEC_CUSTOM) {
|
||||
StringRef Name = readString(Ptr);
|
||||
Section = findCustomSectionByName(Name);
|
||||
} else {
|
||||
Section = findSectionByType(SectionCode);
|
||||
}
|
||||
if (!Section)
|
||||
return make_error<GenericBinaryError>("Invalid section code",
|
||||
uint32_t SectionIndex = readVaruint32(Ptr);
|
||||
if (SectionIndex >= Sections.size())
|
||||
return make_error<GenericBinaryError>("Invalid section index",
|
||||
object_error::parse_failed);
|
||||
WasmSection& Section = Sections[SectionIndex];
|
||||
uint32_t RelocCount = readVaruint32(Ptr);
|
||||
uint32_t EndOffset = Section->Content.size();
|
||||
uint32_t EndOffset = Section.Content.size();
|
||||
while (RelocCount--) {
|
||||
wasm::WasmRelocation Reloc = {};
|
||||
Reloc.Type = readVaruint32(Ptr);
|
||||
@ -604,7 +581,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
|
||||
return make_error<GenericBinaryError>("Bad relocation offset",
|
||||
object_error::parse_failed);
|
||||
|
||||
Section->Relocations.push_back(Reloc);
|
||||
Section.Relocations.push_back(Reloc);
|
||||
}
|
||||
if (Ptr != End)
|
||||
return make_error<GenericBinaryError>("Reloc section ended prematurely",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -27,7 +27,8 @@ public:
|
||||
int writeWasm(raw_ostream &OS);
|
||||
|
||||
private:
|
||||
int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec);
|
||||
int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
|
||||
uint32_t SectionIndex);
|
||||
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section);
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section);
|
||||
@ -420,8 +421,8 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WasmWriter::writeRelocSection(raw_ostream &OS,
|
||||
WasmYAML::Section &Sec) {
|
||||
int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
|
||||
uint32_t SectionIndex) {
|
||||
StringRef Name;
|
||||
switch (Sec.Type) {
|
||||
case wasm::WASM_SEC_CODE:
|
||||
@ -436,7 +437,7 @@ int WasmWriter::writeRelocSection(raw_ostream &OS,
|
||||
}
|
||||
|
||||
writeStringRef(Name, OS);
|
||||
writeUint8(OS, Sec.Type);
|
||||
encodeULEB128(SectionIndex, OS);
|
||||
encodeULEB128(Sec.Relocations.size(), OS);
|
||||
|
||||
for (auto Reloc: Sec.Relocations) {
|
||||
@ -522,14 +523,17 @@ int WasmWriter::writeWasm(raw_ostream &OS) {
|
||||
}
|
||||
|
||||
// write reloc sections for any section that have relocations
|
||||
uint32_t SectionIndex = 0;
|
||||
for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
|
||||
if (Sec->Relocations.empty())
|
||||
if (Sec->Relocations.empty()) {
|
||||
SectionIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
writeUint8(OS, wasm::WASM_SEC_CUSTOM);
|
||||
std::string OutString;
|
||||
raw_string_ostream StringStream(OutString);
|
||||
writeRelocSection(StringStream, *Sec);
|
||||
writeRelocSection(StringStream, *Sec, SectionIndex++);
|
||||
StringStream.flush();
|
||||
|
||||
encodeULEB128(OutString.size(), OS);
|
||||
|
Loading…
Reference in New Issue
Block a user