[llvm] r312674 - [WebAssembly] Only treat imports/exports as symbols when reading relocatable object files

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 6 15:05:42 PDT 2017


Author: sbc
Date: Wed Sep  6 15:05:41 2017
New Revision: 312674

URL: http://llvm.org/viewvc/llvm-project?rev=312674&view=rev
Log:
[WebAssembly] Only treat imports/exports as symbols when reading relocatable object files

This change only treats imported and exports functions and globals
as symbol table entries the object has a "linking" section (i.e. it is
relocatable object file).

In this case all globals must be of type I32 and initialized with
i32.const.  This was previously being assumed but not checked for and
was causing a failure on big endian machines due to using the wrong
value of then union.

See: https://bugs.llvm.org/show_bug.cgi?id=34487

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

Modified:
    llvm/trunk/include/llvm/Object/Wasm.h
    llvm/trunk/lib/Object/WasmObjectFile.cpp
    llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
    llvm/trunk/test/MC/WebAssembly/unnamed-data.ll
    llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml
    llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml
    llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml
    llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test
    llvm/trunk/test/tools/llvm-readobj/symbols.test

Modified: llvm/trunk/include/llvm/Object/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Wasm.h?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Wasm.h (original)
+++ llvm/trunk/include/llvm/Object/Wasm.h Wed Sep  6 15:05:41 2017
@@ -204,6 +204,8 @@ private:
   Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
                           const uint8_t *End);
 
+  void populateSymbolTable();
+
   wasm::WasmObjectHeader Header;
   std::vector<WasmSection> Sections;
   std::vector<wasm::WasmSignature> Signatures;
@@ -223,6 +225,8 @@ private:
   wasm::WasmLinkingData LinkingData;
   uint32_t NumImportedGlobals = 0;
   uint32_t NumImportedFunctions = 0;
+  uint32_t ImportSection = 0;
+  uint32_t ExportSection = 0;
 
   StringMap<uint32_t> SymbolMap;
 };

Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Wed Sep  6 15:05:41 2017
@@ -300,9 +300,69 @@ Error WasmObjectFile::parseNameSection(c
   return Error::success();
 }
 
+void WasmObjectFile::populateSymbolTable() {
+  // Add imports to symbol table
+  size_t ImportIndex = 0;
+  for (const wasm::WasmImport& Import : Imports) {
+    switch (Import.Kind) {
+    case wasm::WASM_EXTERNAL_GLOBAL:
+      assert(Import.Global.Type == wasm::WASM_TYPE_I32);
+      SymbolMap.try_emplace(Import.Field, Symbols.size());
+      Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
+                           ImportSection, ImportIndex);
+      DEBUG(dbgs() << "Adding import: " << Symbols.back()
+                   << " sym index:" << Symbols.size() << "\n");
+      break;
+    case wasm::WASM_EXTERNAL_FUNCTION:
+      SymbolMap.try_emplace(Import.Field, Symbols.size());
+      Symbols.emplace_back(Import.Field,
+                           WasmSymbol::SymbolType::FUNCTION_IMPORT,
+                           ImportSection, ImportIndex);
+      DEBUG(dbgs() << "Adding import: " << Symbols.back()
+                   << " sym index:" << Symbols.size() << "\n");
+      break;
+    default:
+      break;
+    }
+    ImportIndex++;
+  }
+
+  // Add exports to symbol table
+  size_t ExportIndex = 0;
+  for (const wasm::WasmExport& Export : Exports) {
+    if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
+        Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
+      WasmSymbol::SymbolType ExportType =
+          Export.Kind == wasm::WASM_EXTERNAL_FUNCTION
+              ? WasmSymbol::SymbolType::FUNCTION_EXPORT
+              : WasmSymbol::SymbolType::GLOBAL_EXPORT;
+      auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size());
+      if (Pair.second) {
+        Symbols.emplace_back(Export.Name, ExportType,
+                             ExportSection, ExportIndex);
+        DEBUG(dbgs() << "Adding export: " << Symbols.back()
+                     << " sym index:" << Symbols.size() << "\n");
+      } else {
+        uint32_t SymIndex = Pair.first->second;
+        Symbols[SymIndex] =
+            WasmSymbol(Export.Name, ExportType, ExportSection, ExportIndex);
+        DEBUG(dbgs() << "Replacing existing symbol:  " << Symbols[SymIndex]
+                     << " sym index:" << SymIndex << "\n");
+      }
+    }
+    ExportIndex++;
+  }
+}
+
 Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
                                           const uint8_t *End) {
   HasLinkingSection = true;
+
+  // Only populate the symbol table with imports and exports if the object
+  // has a linking section (i.e. its a relocatable object file). Otherwise
+  // the global might not represent symbols at all.
+  populateSymbolTable();
+
   while (Ptr < End) {
     uint8_t Type = readVarint7(Ptr);
     uint32_t Size = readVaruint32(Ptr);
@@ -463,6 +523,7 @@ Error WasmObjectFile::parseTypeSection(c
 }
 
 Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) {
+  ImportSection = Sections.size();
   uint32_t Count = readVaruint32(Ptr);
   Imports.reserve(Count);
   for (uint32_t i = 0; i < Count; i++) {
@@ -474,31 +535,20 @@ Error WasmObjectFile::parseImportSection
     case wasm::WASM_EXTERNAL_FUNCTION:
       NumImportedFunctions++;
       Im.SigIndex = readVaruint32(Ptr);
-      SymbolMap.try_emplace(Im.Field, Symbols.size());
-      Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT,
-                           Sections.size(), i);
-      DEBUG(dbgs() << "Adding import: " << Symbols.back()
-                   << " sym index:" << Symbols.size() << "\n");
       break;
     case wasm::WASM_EXTERNAL_GLOBAL:
       NumImportedGlobals++;
       Im.Global.Type = readVarint7(Ptr);
       Im.Global.Mutable = readVaruint1(Ptr);
-      SymbolMap.try_emplace(Im.Field, Symbols.size());
-      Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
-                           Sections.size(), i);
-      DEBUG(dbgs() << "Adding import: " << Symbols.back()
-                   << " sym index:" << Symbols.size() << "\n");
       break;
     case wasm::WASM_EXTERNAL_MEMORY:
       Im.Memory = readLimits(Ptr);
       break;
     case wasm::WASM_EXTERNAL_TABLE:
       Im.Table = readTable(Ptr);
-      if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC) {
+      if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC)
         return make_error<GenericBinaryError>("Invalid table element type",
                                               object_error::parse_failed);
-      }
       break;
     default:
       return make_error<GenericBinaryError>(
@@ -570,6 +620,7 @@ Error WasmObjectFile::parseGlobalSection
 }
 
 Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) {
+  ExportSection = Sections.size();
   uint32_t Count = readVaruint32(Ptr);
   Exports.reserve(Count);
   for (uint32_t i = 0; i < Count; i++) {
@@ -577,23 +628,18 @@ Error WasmObjectFile::parseExportSection
     Ex.Name = readString(Ptr);
     Ex.Kind = readUint8(Ptr);
     Ex.Index = readVaruint32(Ptr);
-    WasmSymbol::SymbolType ExportType;
-    bool MakeSymbol = false;
     switch (Ex.Kind) {
     case wasm::WASM_EXTERNAL_FUNCTION:
-      ExportType = WasmSymbol::SymbolType::FUNCTION_EXPORT;
       if (Ex.Index >= FunctionTypes.size() + NumImportedFunctions)
         return make_error<GenericBinaryError>("Invalid function export",
                                               object_error::parse_failed);
-      MakeSymbol = true;
       break;
-    case wasm::WASM_EXTERNAL_GLOBAL:
-      ExportType = WasmSymbol::SymbolType::GLOBAL_EXPORT;
+    case wasm::WASM_EXTERNAL_GLOBAL: {
       if (Ex.Index >= Globals.size() + NumImportedGlobals)
         return make_error<GenericBinaryError>("Invalid global export",
                                               object_error::parse_failed);
-      MakeSymbol = true;
       break;
+    }
     case wasm::WASM_EXTERNAL_MEMORY:
     case wasm::WASM_EXTERNAL_TABLE:
       break;
@@ -601,20 +647,6 @@ Error WasmObjectFile::parseExportSection
       return make_error<GenericBinaryError>(
           "Unexpected export kind", object_error::parse_failed);
     }
-    if (MakeSymbol) {
-      auto Pair = SymbolMap.try_emplace(Ex.Name, Symbols.size());
-      if (Pair.second) {
-        Symbols.emplace_back(Ex.Name, ExportType,
-                             Sections.size(), i);
-        DEBUG(dbgs() << "Adding export: " << Symbols.back()
-                     << " sym index:" << Symbols.size() << "\n");
-      } else {
-        uint32_t SymIndex = Pair.first->second;
-        Symbols[SymIndex] = WasmSymbol(Ex.Name, ExportType, Sections.size(), i);
-        DEBUG(dbgs() << "Replacing existing symbol:  " << Symbols[SymIndex]
-                     << " sym index:" << SymIndex << "\n");
-      }
-    }
     Exports.push_back(Ex);
   }
   if (Ptr != End)
@@ -791,6 +823,8 @@ uint64_t WasmObjectFile::getSymbolValueI
     uint32_t GlobalIndex = Exports[Sym.ElementIndex].Index - NumImportedGlobals;
     assert(GlobalIndex < Globals.size());
     const wasm::WasmGlobal& Global = Globals[GlobalIndex];
+    // WasmSymbols correspond only to I32_CONST globals
+    assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
     return Global.InitExpr.Value.Int32;
   }
   case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:

Modified: llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/WasmYAML.cpp?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/WasmYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/WasmYAML.cpp Wed Sep  6 15:05:41 2017
@@ -59,7 +59,7 @@ static void sectionMapping(IO &IO, WasmY
   IO.mapRequired("Name", Section.Name);
   IO.mapRequired("DataSize", Section.DataSize);
   IO.mapRequired("DataAlignment", Section.DataAlignment);
-  IO.mapRequired("SymbolInfo", Section.SymbolInfos);
+  IO.mapOptional("SymbolInfo", Section.SymbolInfos);
 }
 
 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {

Modified: llvm/trunk/test/MC/WebAssembly/unnamed-data.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/unnamed-data.ll?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/unnamed-data.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/unnamed-data.ll Wed Sep  6 15:05:41 2017
@@ -56,5 +56,4 @@
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     DataSize:        28
 ; CHECK-NEXT:     DataAlignment:   8
-; CHECK-NEXT:     SymbolInfo:      
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml (original)
+++ llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml Wed Sep  6 15:05:41 2017
@@ -24,12 +24,12 @@ Sections:
       - Type:        I32
         Mutable:     false
         InitExpr:
-          Opcode:          I64_CONST
+          Opcode:          I32_CONST
           Value:           64
       - Type:        I32
         Mutable:     false
         InitExpr:
-          Opcode:          I64_CONST
+          Opcode:          I32_CONST
           Value:           1024
   - Type:            IMPORT
     Imports:
@@ -50,6 +50,10 @@ Sections:
       - Name:            bar
         Kind:            GLOBAL
         Index:           0x00000003
+  - Type:            CUSTOM
+    Name:            "linking"
+    DataSize:        0
+    DataAlignment:   0
 
 # CHECK:      00000400 D bar
 # CHECK-NEXT:          U fimport

Modified: llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml (original)
+++ llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml Wed Sep  6 15:05:41 2017
@@ -20,6 +20,10 @@ Sections:
         Kind:            GLOBAL
         GlobalType:      I32
         GlobalMutable:   false
+  - Type:            CUSTOM
+    Name:            "linking"
+    DataSize:        0
+    DataAlignment:   0
 
 # CHECK:    U bar
 # CHECK:    U foo

Modified: llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml (original)
+++ llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml Wed Sep  6 15:05:41 2017
@@ -35,12 +35,12 @@ Sections:
       - Type:        I32
         Mutable:     false
         InitExpr:
-          Opcode:          I64_CONST
+          Opcode:          I32_CONST
           Value:           64
       - Type:        I32
         Mutable:     false
         InitExpr:
-          Opcode:          I64_CONST
+          Opcode:          I32_CONST
           Value:           1024
   - Type:            EXPORT
     Exports:

Modified: llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test (original)
+++ llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test Wed Sep  6 15:05:41 2017
@@ -1,11 +1,11 @@
 RUN: llvm-objdump -t %p/../Inputs/trivial.obj.wasm | FileCheck %s
 
 CHECK:      SYMBOL TABLE:
+CHECK-NEXT: 00000000 l     F name	puts
+CHECK-NEXT: 00000001 l     F name	SomeOtherFunction
+CHECK-NEXT: 00000002 l     F name	main
 CHECK-NEXT: 00000000 l     F IMPORT	puts
 CHECK-NEXT: 00000000 l     F IMPORT	SomeOtherFunction
 CHECK-NEXT: 00000002 g     F EXPORT	main
 CHECK-NEXT: 00000010 g       EXPORT	var
-CHECK-NEXT: 00000000 l     F name	puts
-CHECK-NEXT: 00000001 l     F name	SomeOtherFunction
-CHECK-NEXT: 00000002 l     F name	main
 

Modified: llvm/trunk/test/tools/llvm-readobj/symbols.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/symbols.test?rev=312674&r1=312673&r2=312674&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/symbols.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/symbols.test Wed Sep  6 15:05:41 2017
@@ -74,32 +74,32 @@ ELF-NEXT:   }
 WASM:      Symbols [
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: puts
-WASM-NEXT:     Type: FUNCTION_IMPORT (0x0)
+WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: SomeOtherFunction
-WASM-NEXT:     Type: FUNCTION_IMPORT (0x0)
+WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: main
-WASM-NEXT:     Type: FUNCTION_EXPORT (0x1)
+WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: puts
-WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
+WASM-NEXT:     Type: FUNCTION_IMPORT (0x0)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: SomeOtherFunction
-WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
+WASM-NEXT:     Type: FUNCTION_IMPORT (0x0)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT:   Symbol {
 WASM-NEXT:     Name: main
-WASM-NEXT:     Type: DEBUG_FUNCTION_NAME (0x4)
+WASM-NEXT:     Type: FUNCTION_EXPORT (0x1)
 WASM-NEXT:     Flags: 0x0
 WASM-NEXT:   }
 WASM-NEXT: ]




More information about the llvm-commits mailing list