[llvm] r313817 - [WebAssembly] Add support for local symbol bindings

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 20 14:17:04 PDT 2017


Author: sbc
Date: Wed Sep 20 14:17:04 2017
New Revision: 313817

URL: http://llvm.org/viewvc/llvm-project?rev=313817&view=rev
Log:
[WebAssembly] Add support for local symbol bindings

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

Added:
    llvm/trunk/test/tools/llvm-nm/wasm/local-symbols.ll
Modified:
    llvm/trunk/include/llvm/BinaryFormat/Wasm.h
    llvm/trunk/include/llvm/Object/Wasm.h
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Object/WasmObjectFile.cpp
    llvm/trunk/test/MC/WebAssembly/unnamed-data.ll
    llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test
    llvm/trunk/tools/llvm-cfi-verify/CMakeLists.txt
    llvm/trunk/tools/obj2yaml/wasm2yaml.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Wasm.h?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Wasm.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h Wed Sep 20 14:17:04 2017
@@ -188,8 +188,12 @@ enum : unsigned {
   WASM_SEGMENT_NAMES  = 0x5,
 };
 
+const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
+
 enum : unsigned {
-  WASM_SYMBOL_FLAG_WEAK = 0x1,
+  WASM_SYMBOL_BINDING_GLOBAL = 0x0,
+  WASM_SYMBOL_BINDING_WEAK   = 0x1,
+  WASM_SYMBOL_BINDING_LOCAL  = 0x2,
 };
 
 #define WASM_RELOC(name, value) name = value,

Modified: llvm/trunk/include/llvm/Object/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Wasm.h?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Wasm.h (original)
+++ llvm/trunk/include/llvm/Object/Wasm.h Wed Sep 20 14:17:04 2017
@@ -56,7 +56,19 @@ public:
   uint32_t ElementIndex;
 
   bool isWeak() const {
-    return Flags & wasm::WASM_SYMBOL_FLAG_WEAK;
+    return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
+  }
+
+  bool isGlobal() const {
+    return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
+  }
+
+  bool isLocal() const {
+    return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
+  }
+
+  unsigned getBinding() const {
+    return Flags & wasm::WASM_SYMBOL_BINDING_MASK;
   }
 
   void print(raw_ostream &Out) const {
@@ -132,6 +144,7 @@ public:
   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
 
   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+  uint64_t getWasmSymbolValue(const WasmSymbol& Sym) const;
   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Wed Sep 20 14:17:04 2017
@@ -280,11 +280,11 @@ private:
                         uint32_t NumFuncImports);
   void writeCodeRelocSection();
   void writeDataRelocSection();
-  void writeLinkingMetaDataSection(ArrayRef<WasmDataSegment> Segments,
-                                   uint32_t DataSize, uint32_t DataAlignment,
-                                   ArrayRef<StringRef> WeakSymbols,
-                                   bool HasStackPointer,
-                                   uint32_t StackPointerGlobal);
+  void writeLinkingMetaDataSection(
+      ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
+      uint32_t DataAlignment,
+      SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
+      bool HasStackPointer, uint32_t StackPointerGlobal);
 
   uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
   void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
@@ -914,7 +914,8 @@ void WasmObjectWriter::writeDataRelocSec
 
 void WasmObjectWriter::writeLinkingMetaDataSection(
     ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
-    uint32_t DataAlignment, ArrayRef<StringRef> WeakSymbols,
+    uint32_t DataAlignment,
+    SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags,
     bool HasStackPointer, uint32_t StackPointerGlobal) {
   SectionBookkeeping Section;
   startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
@@ -926,12 +927,12 @@ void WasmObjectWriter::writeLinkingMetaD
     endSection(SubSection);
   }
 
-  if (WeakSymbols.size() != 0) {
+  if (SymbolFlags.size() != 0) {
     startSection(SubSection, wasm::WASM_SYMBOL_INFO);
-    encodeULEB128(WeakSymbols.size(), getStream());
-    for (const StringRef Export: WeakSymbols) {
-      writeString(Export);
-      encodeULEB128(wasm::WASM_SYMBOL_FLAG_WEAK, getStream());
+    encodeULEB128(SymbolFlags.size(), getStream());
+    for (auto Pair: SymbolFlags) {
+      writeString(Pair.first);
+      encodeULEB128(Pair.second, getStream());
     }
     endSection(SubSection);
   }
@@ -993,7 +994,7 @@ void WasmObjectWriter::writeObject(MCAss
   SmallVector<uint32_t, 4> TableElems;
   SmallVector<WasmImport, 4> Imports;
   SmallVector<WasmExport, 4> Exports;
-  SmallVector<StringRef, 4> WeakSymbols;
+  SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags;
   SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
   unsigned NumFuncImports = 0;
   SmallVector<WasmDataSegment, 4> DataSegments;
@@ -1164,7 +1165,7 @@ void WasmObjectWriter::writeObject(MCAss
                  << " isVariable=" << WS.isVariable() << "\n");
 
     if (WS.isWeak())
-      WeakSymbols.push_back(WS.getName());
+      SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_WEAK);
 
     if (WS.isVariable())
       continue;
@@ -1235,7 +1236,7 @@ void WasmObjectWriter::writeObject(MCAss
     }
 
     // If the symbol is visible outside this translation unit, export it.
-    if ((WS.isExternal() && WS.isDefined(/*SetUsed=*/false))) {
+    if (WS.isDefined(/*SetUsed=*/false)) {
       WasmExport Export;
       Export.FieldName = WS.getName();
       Export.Index = Index;
@@ -1245,6 +1246,8 @@ void WasmObjectWriter::writeObject(MCAss
         Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
       DEBUG(dbgs() << "  -> export " << Exports.size() << "\n");
       Exports.push_back(Export);
+      if (!WS.isExternal())
+        SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
     }
   }
 
@@ -1254,6 +1257,7 @@ void WasmObjectWriter::writeObject(MCAss
   for (const MCSymbol &S : Asm.symbols()) {
     if (!S.isVariable())
       continue;
+
     assert(S.isDefined(/*SetUsed=*/false));
 
     // Find the target symbol of this weak alias and export that index
@@ -1273,6 +1277,9 @@ void WasmObjectWriter::writeObject(MCAss
       Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
     DEBUG(dbgs() << "  -> export " << Exports.size() << "\n");
     Exports.push_back(Export);
+
+    if (!WS.isExternal())
+      SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
   }
 
   // Add types for indirect function calls.
@@ -1301,7 +1308,7 @@ void WasmObjectWriter::writeObject(MCAss
   writeCodeRelocSection();
   writeDataRelocSection();
   writeLinkingMetaDataSection(DataSegments, DataSize, DataAlignment,
-                              WeakSymbols, HasStackPointer, StackPointerGlobal);
+                              SymbolFlags, HasStackPointer, StackPointerGlobal);
 
   // TODO: Translate the .comment section to the output.
   // TODO: Translate debug sections to the output.

Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Wed Sep 20 14:17:04 2017
@@ -767,15 +767,17 @@ uint32_t WasmObjectFile::getSymbolFlags(
   const WasmSymbol &Sym = getWasmSymbol(Symb);
 
   DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
-  if (Sym.Flags & wasm::WASM_SYMBOL_FLAG_WEAK)
+  if (Sym.isWeak())
     Result |= SymbolRef::SF_Weak;
+  else if (Sym.isGlobal())
+    Result |= SymbolRef::SF_Global;
 
   switch (Sym.Type) {
   case WasmSymbol::SymbolType::FUNCTION_IMPORT:
     Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
     break;
   case WasmSymbol::SymbolType::FUNCTION_EXPORT:
-    Result |= SymbolRef::SF_Global | SymbolRef::SF_Executable;
+    Result |= SymbolRef::SF_Executable;
     break;
   case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
     Result |= SymbolRef::SF_Executable;
@@ -785,7 +787,6 @@ uint32_t WasmObjectFile::getSymbolFlags(
     Result |= SymbolRef::SF_Undefined;
     break;
   case WasmSymbol::SymbolType::GLOBAL_EXPORT:
-    Result |= SymbolRef::SF_Global;
     break;
   }
 
@@ -820,8 +821,7 @@ Expected<uint64_t> WasmObjectFile::getSy
   return getSymbolValue(Symb);
 }
 
-uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
-  const WasmSymbol& Sym = getWasmSymbol(Symb);
+uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
   switch (Sym.Type) {
   case WasmSymbol::SymbolType::FUNCTION_IMPORT:
   case WasmSymbol::SymbolType::GLOBAL_IMPORT:
@@ -842,6 +842,10 @@ uint64_t WasmObjectFile::getSymbolValueI
   llvm_unreachable("invalid symbol type");
 }
 
+uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
+  return getWasmSymbolValue(getWasmSymbol(Symb));
+}
+
 uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
   llvm_unreachable("not yet implemented");
   return 0;

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=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/unnamed-data.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/unnamed-data.ll Wed Sep 20 14:17:04 2017
@@ -26,11 +26,17 @@
 ; CHECK-NEXT:           Value:           16
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
-; CHECK-NEXT:         InitExpr:        
+; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           24
 ; CHECK-NEXT:   - Type:            EXPORT
-; CHECK-NEXT:     Exports:         
+; CHECK-NEXT:     Exports:
+; CHECK-NEXT:       - Name:            .L.str1
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:       - Name:            .L.str2
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:       - Name:            a
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
@@ -74,6 +80,11 @@
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     DataSize:        28
 ; CHECK-NEXT:     DataAlignment:   8
+; CHECK-NEXT:     SymbolInfo:      
+; CHECK-NEXT:       - Name:            .L.str1
+; CHECK-NEXT:         Flags:           2
+; CHECK-NEXT:       - Name:            .L.str2
+; CHECK-NEXT:         Flags:           2
 ; CHECK-NEXT:     SegmentNames:    
 ; CHECK-NEXT:       - Index:       0
 ; CHECK-NEXT:         Name:        .rodata..L.str1
@@ -83,4 +94,4 @@
 ; CHECK-NEXT:         Name:        .data.a
 ; CHECK-NEXT:       - Index:       3
 ; CHECK-NEXT:         Name:        .data.b
-; CHECK-NEXT: ...
+; CHECK_NEXT:   ...

Added: llvm/trunk/test/tools/llvm-nm/wasm/local-symbols.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/wasm/local-symbols.ll?rev=313817&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/wasm/local-symbols.ll (added)
+++ llvm/trunk/test/tools/llvm-nm/wasm/local-symbols.ll Wed Sep 20 14:17:04 2017
@@ -0,0 +1,8 @@
+; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm -o %t.o %s
+; RUN: llvm-nm %t.o | FileCheck %s
+
+ at foo = internal global i32 1, align 4
+ at bar = global i32 1, align 4
+
+; CHECK: 00000004 D bar
+; CHECK: 00000000 d foo

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=313817&r1=313816&r2=313817&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 20 14:17:04 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: 00000000 g     F name	puts
+CHECK-NEXT: 00000001 g     F name	SomeOtherFunction
+CHECK-NEXT: 00000002 g     F name	main
+CHECK-NEXT: 00000000 g     F IMPORT	puts
+CHECK-NEXT: 00000000 g     F IMPORT	SomeOtherFunction
 CHECK-NEXT: 00000002 g     F EXPORT	main
 CHECK-NEXT: 00000010 g       EXPORT	var
 

Modified: llvm/trunk/tools/llvm-cfi-verify/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/CMakeLists.txt?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-cfi-verify/CMakeLists.txt Wed Sep 20 14:17:04 2017
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   AllTargetsDisassemblers
   AllTargetsInfos
   MC
+  Object
   MCParser
   Object
   Support

Modified: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/wasm2yaml.cpp?rev=313817&r1=313816&r2=313817&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp Wed Sep 20 14:17:04 2017
@@ -54,16 +54,11 @@ std::unique_ptr<WasmYAML::CustomSection>
   if (WasmSec.Name == "name") {
     std::unique_ptr<WasmYAML::NameSection> NameSec = make_unique<WasmYAML::NameSection>();
     for (const object::SymbolRef& Sym: Obj.symbols()) {
-      uint32_t Flags = Sym.getFlags();
-      // Skip over symbols that come from imports or exports
-      if (Flags &
-          (object::SymbolRef::SF_Global | object::SymbolRef::SF_Undefined))
-        continue;
-      Expected<StringRef> NameOrError = Sym.getName();
-      if (!NameOrError)
+      const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
+      if (Symbol.Type != object::WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME)
         continue;
       WasmYAML::NameEntry NameEntry;
-      NameEntry.Name = *NameOrError;
+      NameEntry.Name = Symbol.Name;
       NameEntry.Index = Sym.getValue();
       NameSec->FunctionNames.push_back(NameEntry);
     }




More information about the llvm-commits mailing list