[llvm] r340423 - [WebAssembly] Ensure relocation entries are ordered by offset

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 22 10:27:31 PDT 2018


Author: sbc
Date: Wed Aug 22 10:27:31 2018
New Revision: 340423

URL: http://llvm.org/viewvc/llvm-project?rev=340423&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Object/WasmObjectFile.cpp

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=340423&r1=340422&r2=340423&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Wed Aug 22 10:27:31 2018
@@ -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);

Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=340423&r1=340422&r2=340423&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Wed Aug 22 10:27:31 2018
@@ -602,10 +602,15 @@ Error WasmObjectFile::parseRelocSection(
   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:




More information about the llvm-commits mailing list