[WebAssembly] Expose the offset of each data segment

Summary:
This allows tools like lld that process relocations
to apply data relocation correctly. This information
is required because relocation are stored as section
offset.

Subscribers: jfb, dschuff, jgravelle-google, aheejin

Differential Revision: https://reviews.llvm.org/D35234

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307741 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sam Clegg 2017-07-12 00:24:54 +00:00
parent 4cdc883934
commit c9c28d96fa
10 changed files with 31 additions and 19 deletions

View File

@ -94,7 +94,7 @@ struct WasmFunction {
}; };
struct WasmDataSegment { struct WasmDataSegment {
uint32_t Index; uint32_t MemoryIndex;
WasmInitExpr Offset; WasmInitExpr Offset;
ArrayRef<uint8_t> Content; ArrayRef<uint8_t> Content;
}; };

View File

@ -69,8 +69,7 @@ public:
#endif #endif
}; };
class WasmSection { struct WasmSection {
public:
WasmSection() = default; WasmSection() = default;
uint32_t Type = 0; // Section type (See below) uint32_t Type = 0; // Section type (See below)
@ -80,6 +79,11 @@ public:
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
}; };
struct WasmSegment {
uint32_t SectionOffset;
wasm::WasmDataSegment Data;
};
class WasmObjectFile : public ObjectFile { class WasmObjectFile : public ObjectFile {
public: public:
@ -110,7 +114,7 @@ public:
return ElemSegments; return ElemSegments;
} }
const std::vector<wasm::WasmDataSegment>& dataSegments() const { const std::vector<WasmSegment>& dataSegments() const {
return DataSegments; return DataSegments;
} }
@ -210,7 +214,7 @@ private:
std::vector<wasm::WasmImport> Imports; std::vector<wasm::WasmImport> Imports;
std::vector<wasm::WasmExport> Exports; std::vector<wasm::WasmExport> Exports;
std::vector<wasm::WasmElemSegment> ElemSegments; std::vector<wasm::WasmElemSegment> ElemSegments;
std::vector<wasm::WasmDataSegment> DataSegments; std::vector<WasmSegment> DataSegments;
std::vector<wasm::WasmFunction> Functions; std::vector<wasm::WasmFunction> Functions;
std::vector<WasmSymbol> Symbols; std::vector<WasmSymbol> Symbols;
ArrayRef<uint8_t> CodeSection; ArrayRef<uint8_t> CodeSection;

View File

@ -98,7 +98,8 @@ struct Relocation {
}; };
struct DataSegment { struct DataSegment {
uint32_t Index; uint32_t MemoryIndex;
uint32_t SectionOffset;
wasm::WasmInitExpr Offset; wasm::WasmInitExpr Offset;
yaml::BinaryRef Content; yaml::BinaryRef Content;
}; };

View File

@ -675,15 +675,17 @@ Error WasmObjectFile::parseElemSection(const uint8_t *Ptr, const uint8_t *End) {
} }
Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) { Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) {
const uint8_t *Start = Ptr;
uint32_t Count = readVaruint32(Ptr); uint32_t Count = readVaruint32(Ptr);
DataSegments.reserve(Count); DataSegments.reserve(Count);
while (Count--) { while (Count--) {
wasm::WasmDataSegment Segment; WasmSegment Segment;
Segment.Index = readVaruint32(Ptr); Segment.Data.MemoryIndex = readVaruint32(Ptr);
if (Error Err = readInitExpr(Segment.Offset, Ptr)) if (Error Err = readInitExpr(Segment.Data.Offset, Ptr))
return Err; return Err;
uint32_t Size = readVaruint32(Ptr); uint32_t Size = readVaruint32(Ptr);
Segment.Content = ArrayRef<uint8_t>(Ptr, Size); Segment.Data.Content = ArrayRef<uint8_t>(Ptr, Size);
Segment.SectionOffset = Ptr - Start;
Ptr += Size; Ptr += Size;
DataSegments.push_back(Segment); DataSegments.push_back(Segment);
} }

View File

@ -345,7 +345,8 @@ void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
void MappingTraits<WasmYAML::DataSegment>::mapping( void MappingTraits<WasmYAML::DataSegment>::mapping(
IO &IO, WasmYAML::DataSegment &Segment) { IO &IO, WasmYAML::DataSegment &Segment) {
IO.mapRequired("Index", Segment.Index); IO.mapOptional("SectionOffset", Segment.SectionOffset);
IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
IO.mapRequired("Offset", Segment.Offset); IO.mapRequired("Offset", Segment.Offset);
IO.mapRequired("Content", Segment.Content); IO.mapRequired("Content", Segment.Content);
} }

View File

@ -13,7 +13,8 @@
; CHECK: Index: 0 ; CHECK: Index: 0
; CHECK: Offset: 0x0000000E ; CHECK: Offset: 0x0000000E
; CHECK: Segments: ; CHECK: Segments:
; CHECK: - Index: 0 ; CHECK: - SectionOffset: 6
; CHECK: MemoryIndex: 0
; CHECK: Offset: ; CHECK: Offset:
; CHECK: Opcode: I32_CONST ; CHECK: Opcode: I32_CONST
; CHECK: Value: 0 ; CHECK: Value: 0

View File

@ -46,7 +46,8 @@
; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000001E ; CHECK-NEXT: Offset: 0x0000001E
; CHECK-NEXT: Segments: ; CHECK-NEXT: Segments:
; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset: ; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Value: 0

View File

@ -8,7 +8,7 @@ Sections:
- Initial: 0x00000003 - Initial: 0x00000003
- Type: DATA - Type: DATA
Segments: Segments:
- Index: 0 - MemoryIndex: 0
Offset: Offset:
Opcode: I32_CONST Opcode: I32_CONST
Value: 4 Value: 4
@ -38,7 +38,8 @@ Sections:
# CHECK-NEXT: Offset: 0x00000006 # CHECK-NEXT: Offset: 0x00000006
# CHECK-NEXT: Addend: -6 # CHECK-NEXT: Addend: -6
# CHECK-NEXT: Segments: # CHECK-NEXT: Segments:
# CHECK-NEXT: - Index: 0 # CHECK-NEXT: - SectionOffset: 6
# CHECK-NEXT: MemoryIndex: 0
# CHECK-NEXT: Offset: # CHECK-NEXT: Offset:
# CHECK-NEXT: Opcode: I32_CONST # CHECK-NEXT: Opcode: I32_CONST
# CHECK-NEXT: Value: 4 # CHECK-NEXT: Value: 4

View File

@ -236,9 +236,10 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
auto DataSec = make_unique<WasmYAML::DataSection>(); auto DataSec = make_unique<WasmYAML::DataSection>();
for (auto &Segment : Obj.dataSegments()) { for (auto &Segment : Obj.dataSegments()) {
WasmYAML::DataSegment Seg; WasmYAML::DataSegment Seg;
Seg.Index = Segment.Index; Seg.SectionOffset = Segment.SectionOffset;
Seg.Offset = Segment.Offset; Seg.MemoryIndex = Segment.Data.MemoryIndex;
Seg.Content = yaml::BinaryRef(Segment.Content); Seg.Offset = Segment.Data.Offset;
Seg.Content = yaml::BinaryRef(Segment.Data.Content);
DataSec->Segments.push_back(Seg); DataSec->Segments.push_back(Seg);
} }
S = std::move(DataSec); S = std::move(DataSec);

View File

@ -338,7 +338,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::DataSection &Section) { WasmYAML::DataSection &Section) {
encodeULEB128(Section.Segments.size(), OS); encodeULEB128(Section.Segments.size(), OS);
for (auto &Segment : Section.Segments) { for (auto &Segment : Section.Segments) {
encodeULEB128(Segment.Index, OS); encodeULEB128(Segment.MemoryIndex, OS);
writeInitExpr(Segment.Offset, OS); writeInitExpr(Segment.Offset, OS);
encodeULEB128(Segment.Content.binary_size(), OS); encodeULEB128(Segment.Content.binary_size(), OS);
Segment.Content.writeAsBinary(OS); Segment.Content.writeAsBinary(OS);