[WebAssembly] Add support for weak symbols in the binary format

This also introduces the updated format for the
"linking" section which can represent extra
symbol information.  See:
https://github.com/WebAssembly/tool-conventions/pull/10

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

llvm-svn: 305769
diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index d4d978f..ad0075c 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -14,6 +14,7 @@
 #include "llvm/Support/YAMLTraits.h"
 
 using namespace llvm;
+using object::WasmSection;
 
 namespace {
 
@@ -22,10 +23,16 @@
 
 public:
   WasmDumper(const object::WasmObjectFile &O) : Obj(O) {}
+
   ErrorOr<WasmYAML::Object *> dump();
+
+  std::unique_ptr<WasmYAML::CustomSection>
+  dumpCustomSection(const WasmSection &WasmSec);
 };
 
-WasmYAML::Table make_table(const wasm::WasmTable &Table) {
+} // namespace
+
+static WasmYAML::Table make_table(const wasm::WasmTable &Table) {
   WasmYAML::Table T;
   T.ElemType = Table.ElemType;
   T.TableLimits.Flags = Table.Limits.Flags;
@@ -34,7 +41,7 @@
   return T;
 }
 
-WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
+static WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
   WasmYAML::Limits L;
   L.Flags = Limits.Flags;
   L.Initial = Limits.Initial;
@@ -42,6 +49,42 @@
   return L;
 }
 
+std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
+  std::unique_ptr<WasmYAML::CustomSection> CustomSec;
+  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)
+        continue;
+      WasmYAML::NameEntry NameEntry;
+      NameEntry.Name = *NameOrError;
+      NameEntry.Index = Sym.getValue();
+      NameSec->FunctionNames.push_back(NameEntry);
+    }
+    CustomSec = std::move(NameSec);
+  } else if (WasmSec.Name == "linking") {
+    std::unique_ptr<WasmYAML::LinkingSection> LinkingSec = make_unique<WasmYAML::LinkingSection>();
+    for (const object::SymbolRef& Sym: Obj.symbols()) {
+      const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
+      if (Symbol.Flags != 0) {
+        WasmYAML::SymbolInfo Info = { Symbol.Name, Symbol.Flags };
+        LinkingSec->SymbolInfos.push_back(Info);
+      }
+    }
+    CustomSec = std::move(LinkingSec);
+  } else {
+    CustomSec = make_unique<WasmYAML::CustomSection>(WasmSec.Name);
+  }
+  CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
+  return CustomSec;
+}
+
 ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
   auto Y = make_unique<WasmYAML::Object>();
 
@@ -50,7 +93,7 @@
 
   // Dump sections
   for (const auto &Sec : Obj.sections()) {
-    const object::WasmSection &WasmSec = Obj.getWasmSection(Sec);
+    const WasmSection &WasmSec = Obj.getWasmSection(Sec);
     std::unique_ptr<WasmYAML::Section> S;
     switch (WasmSec.Type) {
     case wasm::WASM_SEC_CUSTOM: {
@@ -59,27 +102,7 @@
         // being represented as a custom section in the YAML output.
         continue;
       }
-      auto CustomSec = make_unique<WasmYAML::CustomSection>();
-      CustomSec->Name = WasmSec.Name;
-      if (CustomSec->Name == "name") {
-        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)
-            continue;
-          WasmYAML::NameEntry NameEntry;
-          NameEntry.Name = *NameOrError;
-          NameEntry.Index = Sym.getValue();
-          CustomSec->FunctionNames.push_back(NameEntry);
-        }
-      } else {
-        CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
-      }
-      S = std::move(CustomSec);
+      S = dumpCustomSection(WasmSec);
       break;
     }
     case wasm::WASM_SEC_TYPE: {
@@ -237,8 +260,6 @@
   return Y.release();
 }
 
-} // namespace
-
 std::error_code wasm2yaml(raw_ostream &Out, const object::WasmObjectFile &Obj) {
   WasmDumper Dumper(Obj);
   ErrorOr<WasmYAML::Object *> YAMLOrErr = Dumper.dump();