summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-08-22 17:27:31 +0000
committerSam Clegg <sbc@chromium.org>2018-08-22 17:27:31 +0000
commitf77dc2a8d1d7bdd433d04ba2386d860f31a4f358 (patch)
tree466d7eff31ce266626c7f368b000ed53fc6dd4d2
parent4fc7e6a1e95e022f9f42c6a616f21828e65f68b1 (diff)
downloadbcm5719-llvm-f77dc2a8d1d7bdd433d04ba2386d860f31a4f358.tar.gz
bcm5719-llvm-f77dc2a8d1d7bdd433d04ba2386d860f31a4f358.zip
[WebAssembly] Ensure relocation entries are ordered by offset
wasm-lld expects relocation entries to be sorted by offset. In most cases llvm produces them in order, but the CODE section (which combines many MCSections) is an exception because we order the functions in Symbol order, not in section order. What is more, its not clear weather `recordRelocation` is guaranteed to be called in offset order so this sort of most likely needed in the general case too. Differential Revision: https://reviews.llvm.org/D51065 llvm-svn: 340423
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp22
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp5
2 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 5a979d36e81..f6c5a874e7c 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -306,7 +306,7 @@ private:
ArrayRef<WasmFunction> Functions);
void writeDataSection();
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations);
+ std::vector<WasmRelocationEntry>& Relocations);
void writeLinkingMetaDataSection(
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
@@ -892,19 +892,31 @@ void WasmObjectWriter::writeDataSection() {
void WasmObjectWriter::writeRelocSection(
uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations) {
+ std::vector<WasmRelocationEntry>& Relocs) {
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
// for descriptions of the reloc sections.
- if (Relocations.empty())
+ if (Relocs.empty())
return;
+ // First, ensure the relocations are sorted in offset order. In general they
+ // should already be sorted since `recordRelocation` is called in offset
+ // order, but for the code section we combine many MC sections into single
+ // wasm section, and this order is determined by the order of Asm.Symbols()
+ // not the sections order.
+ std::stable_sort(
+ Relocs.begin(), Relocs.end(),
+ [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) {
+ return (A.Offset + A.FixupSection->getSectionOffset()) <
+ (B.Offset + B.FixupSection->getSectionOffset());
+ });
+
SectionBookkeeping Section;
startCustomSection(Section, std::string("reloc.") + Name.str());
encodeULEB128(SectionIndex, W.OS);
- encodeULEB128(Relocations.size(), W.OS);
- for (const WasmRelocationEntry& RelEntry : Relocations) {
+ encodeULEB128(Relocs.size(), W.OS);
+ for (const WasmRelocationEntry& RelEntry : Relocs) {
uint64_t Offset = RelEntry.Offset +
RelEntry.FixupSection->getSectionOffset();
uint32_t Index = getRelocationIndexValue(RelEntry);
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 1b32ae8afd9..f75dbfc3014 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -602,10 +602,15 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
WasmSection& Section = Sections[SectionIndex];
uint32_t RelocCount = readVaruint32(Ctx);
uint32_t EndOffset = Section.Content.size();
+ uint32_t PreviousOffset = 0;
while (RelocCount--) {
wasm::WasmRelocation Reloc = {};
Reloc.Type = readVaruint32(Ctx);
Reloc.Offset = readVaruint32(Ctx);
+ if (Reloc.Offset < PreviousOffset)
+ return make_error<GenericBinaryError>("Relocations not in offset order",
+ object_error::parse_failed);
+ PreviousOffset = Reloc.Offset;
Reloc.Index = readVaruint32(Ctx);
switch (Reloc.Type) {
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
OpenPOWER on IntegriCloud