[lld] r321088 - [WebAssembly] Add support for writing out init functions in linking section

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 09:09:45 PST 2017


Author: sbc
Date: Tue Dec 19 09:09:45 2017
New Revision: 321088

URL: http://llvm.org/viewvc/llvm-project?rev=321088&view=rev
Log:
[WebAssembly] Add support for writing out init functions in linking section

This change add support for init functions in the linking
section, but only in -r/--relocatable mode.

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

Added:
    lld/trunk/test/wasm/Inputs/global-ctor-dtor.ll
    lld/trunk/test/wasm/init-fini.ll
Modified:
    lld/trunk/wasm/OutputSections.cpp
    lld/trunk/wasm/OutputSections.h
    lld/trunk/wasm/Writer.cpp

Added: lld/trunk/test/wasm/Inputs/global-ctor-dtor.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/Inputs/global-ctor-dtor.ll?rev=321088&view=auto
==============================================================================
--- lld/trunk/test/wasm/Inputs/global-ctor-dtor.ll (added)
+++ lld/trunk/test/wasm/Inputs/global-ctor-dtor.ll Tue Dec 19 09:09:45 2017
@@ -0,0 +1,14 @@
+define hidden void @myctor() {
+entry:
+  ret void
+}
+
+define hidden void @mydtor() {
+entry:
+  %ptr = alloca i32
+  ret void
+}
+
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @myctor, i8* null }]
+
+ at llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @mydtor, i8* null }]

Added: lld/trunk/test/wasm/init-fini.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/init-fini.ll?rev=321088&view=auto
==============================================================================
--- lld/trunk/test/wasm/init-fini.ll (added)
+++ lld/trunk/test/wasm/init-fini.ll Tue Dec 19 09:09:45 2017
@@ -0,0 +1,99 @@
+; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s
+; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/global-ctor-dtor.ll -o %t.global-ctor-dtor.o
+
+define hidden void @func1() {
+entry:
+  ret void
+}
+
+define hidden void @func2() {
+entry:
+  ret void
+}
+
+define void @__cxa_atexit() {
+  ret void
+}
+
+define hidden void @_start() {
+entry:
+  ret void
+}
+
+ at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func1, i8* null }]
+
+ at llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func2, i8* null }]
+
+; RUN: lld -flavor wasm %t.o %t.global-ctor-dtor.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; CHECK:          Name:            linking
+; CHECK-NEXT:     DataSize:        0
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            name
+; CHECK-NEXT:     FunctionNames:   
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            func1
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Name:            func2
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Name:            __cxa_atexit
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Name:            _start
+; CHECK-NEXT:       - Index:           4
+; CHECK-NEXT:         Name:            .Lcall_dtors
+; CHECK-NEXT:       - Index:           5
+; CHECK-NEXT:         Name:            .Lregister_call_dtors
+; CHECK-NEXT:       - Index:           6
+; CHECK-NEXT:         Name:            .Lbitcast
+; CHECK-NEXT:       - Index:           7
+; CHECK-NEXT:         Name:            myctor
+; CHECK-NEXT:       - Index:           8
+; CHECK-NEXT:         Name:            mydtor
+; CHECK-NEXT:       - Index:           9
+; CHECK-NEXT:         Name:            .Lcall_dtors
+; CHECK-NEXT:       - Index:           10
+; CHECK-NEXT:         Name:            .Lregister_call_dtors
+; CHECK-NEXT: ...
+
+
+; RUN: lld -flavor wasm -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm
+; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
+
+; RELOC:          Name:            linking
+; RELOC-NEXT:     DataSize:        0
+; RELOC-NEXT:     InitFunctions:   
+; RELOC-NEXT:       - Priority:        65535
+; RELOC-NEXT:         FunctionIndex:   0
+; RELOC-NEXT:       - Priority:        65535
+; RELOC-NEXT:         FunctionIndex:   5
+; RELOC-NEXT:       - Priority:        65535
+; RELOC-NEXT:         FunctionIndex:   7
+; RELOC-NEXT:       - Priority:        65535
+; RELOC-NEXT:         FunctionIndex:   10
+; RELOC-NEXT:   - Type:            CUSTOM
+; RELOC-NEXT:     Name:            name
+; RELOC-NEXT:     FunctionNames:   
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Name:            func1
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Name:            func2
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Name:            __cxa_atexit
+; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:         Name:            _start
+; RELOC-NEXT:       - Index:           4
+; RELOC-NEXT:         Name:            .Lcall_dtors
+; RELOC-NEXT:       - Index:           5
+; RELOC-NEXT:         Name:            .Lregister_call_dtors
+; RELOC-NEXT:       - Index:           6
+; RELOC-NEXT:         Name:            .Lbitcast
+; RELOC-NEXT:       - Index:           7
+; RELOC-NEXT:         Name:            myctor
+; RELOC-NEXT:       - Index:           8
+; RELOC-NEXT:         Name:            mydtor
+; RELOC-NEXT:       - Index:           9
+; RELOC-NEXT:         Name:            .Lcall_dtors
+; RELOC-NEXT:       - Index:           10
+; RELOC-NEXT:         Name:            .Lregister_call_dtors
+; RELOC-NEXT: ...

Modified: lld/trunk/wasm/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.cpp?rev=321088&r1=321087&r2=321088&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.cpp (original)
+++ lld/trunk/wasm/OutputSections.cpp Tue Dec 19 09:09:45 2017
@@ -176,10 +176,17 @@ static void calcRelocations(const ObjFil
   }
 }
 
+std::string OutputSection::getSectionName() {
+  return sectionTypeToString(Type);
+}
+
+std::string SubSection::getSectionName() {
+  return std::string("subsection <type=") + std::to_string(Type) + ">";
+}
+
 void OutputSection::createHeader(size_t BodySize) {
   raw_string_ostream OS(Header);
-  debugWrite(OS.tell(),
-             "section type [" + Twine(sectionTypeToString(Type)) + "]");
+  debugWrite(OS.tell(), "section type [" + Twine(getSectionName()) + "]");
   writeUleb128(OS, Type, nullptr);
   writeUleb128(OS, BodySize, "section size");
   OS.flush();

Modified: lld/trunk/wasm/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.h?rev=321088&r1=321087&r2=321088&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.h (original)
+++ lld/trunk/wasm/OutputSections.h Tue Dec 19 09:09:45 2017
@@ -37,6 +37,8 @@ public:
 
   virtual ~OutputSection() = default;
 
+  std::string getSectionName();
+
   void setOffset(size_t NewOffset) {
     log("setOffset: " + toString(this) + " -> " + Twine(NewOffset));
     Offset = NewOffset;
@@ -97,6 +99,8 @@ class SubSection : public SyntheticSecti
 public:
   explicit SubSection(uint32_t Type) : SyntheticSection(Type) {}
 
+  std::string getSectionName();
+
   void writeToStream(raw_ostream &OS) {
     writeBytes(OS, Header.data(), Header.size());
     writeBytes(OS, Body.data(), Body.size());

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=321088&r1=321087&r2=321088&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Tue Dec 19 09:09:45 2017
@@ -398,7 +398,10 @@ void Writer::createLinkingSection() {
   DataSizeSubSection.finalizeContents();
   DataSizeSubSection.writeToStream(OS);
 
-  if (Segments.size() && Config->Relocatable) {
+  if (!Config->Relocatable)
+    return;
+
+  if (Segments.size()) {
     SubSection SubSection(WASM_SEGMENT_INFO);
     writeUleb128(SubSection.getStream(), Segments.size(), "num data segments");
     for (const OutputSegment *S : Segments) {
@@ -408,6 +411,28 @@ void Writer::createLinkingSection() {
     }
     SubSection.finalizeContents();
     SubSection.writeToStream(OS);
+  }
+
+  std::vector<WasmInitFunc> InitFunctions;
+  for (ObjFile *File : Symtab->ObjectFiles) {
+    const WasmLinkingData &L = File->getWasmObj()->linkingData();
+    InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size());
+    for (const WasmInitFunc &F : L.InitFunctions) {
+      InitFunctions.emplace_back(WasmInitFunc{
+          F.Priority, File->relocateFunctionIndex(F.FunctionIndex)});
+    }
+  }
+
+  if (!InitFunctions.empty()) {
+    SubSection SubSection(WASM_INIT_FUNCS);
+    writeUleb128(SubSection.getStream(), InitFunctions.size(),
+                 "num init functionsw");
+    for (const WasmInitFunc &F : InitFunctions) {
+      writeUleb128(SubSection.getStream(), F.Priority, "priority");
+      writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index");
+    }
+    SubSection.finalizeContents();
+    SubSection.writeToStream(OS);
   }
 }
 




More information about the llvm-commits mailing list