[lld] r361476 - Reland: [WebAssembly] Add __start_/_stop_ symbols for data sections

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Thu May 23 03:06:03 PDT 2019


Author: sbc
Date: Thu May 23 03:06:03 2019
New Revision: 361476

URL: http://llvm.org/viewvc/llvm-project?rev=361476&view=rev
Log:
Reland: [WebAssembly] Add __start_/_stop_ symbols for data sections

This is a reland of rL361235.

Fixes https://bugs.llvm.org/show_bug.cgi?id=41565

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

Added:
    lld/trunk/test/wasm/startstop.ll
Modified:
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/SymbolTable.h
    lld/trunk/wasm/Writer.cpp

Added: lld/trunk/test/wasm/startstop.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/startstop.ll?rev=361476&view=auto
==============================================================================
--- lld/trunk/test/wasm/startstop.ll (added)
+++ lld/trunk/test/wasm/startstop.ll Thu May 23 03:06:03 2019
@@ -0,0 +1,57 @@
+; RUN: llc -filetype=obj -o %t.o %s
+; RUN: wasm-ld --no-gc-sections %t.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+ at foo = global i32 3, section "mysection", align 4
+ at bar = global i32 4, section "mysection", align 4
+
+ at __start_mysection = external global i8*
+ at __stop_mysection = external global i8*
+
+define i8** @get_start() {
+  ret i8** @__start_mysection
+}
+
+define i8** @get_end() {
+  ret i8** @__stop_mysection
+}
+
+define void @_start()  {
+entry:
+  ret void
+}
+; CHECK:        - Type:            CODE
+; CHECK-NEXT:     Functions:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Locals:          []
+; CHECK-NEXT:         Body:            0B
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Locals:          []
+; CHECK-NEXT:         Body:            4180888080000B
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Locals:          []
+; CHECK-NEXT:         Body:            4188888080000B
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Locals:          []
+; CHECK-NEXT:         Body:            0B
+; CHECK-NEXT:   - Type:            DATA
+; CHECK-NEXT:     Segments:
+; CHECK-NEXT:       - SectionOffset:   7
+; CHECK-NEXT:         InitFlags:       0
+; CHECK-NEXT:         Offset:
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           1024
+; CHECK-NEXT:         Content:         '0300000004000000'
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            name
+; CHECK-NEXT:     FunctionNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            __wasm_call_ctors
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Name:            get_start
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Name:            get_end
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Name:            _start

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=361476&r1=361475&r2=361476&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Thu May 23 03:06:03 2019
@@ -652,10 +652,6 @@ void LinkerDriver::link(ArrayRef<const c
     // Add synthetic dummies for weak undefined functions.  Must happen
     // after LTO otherwise functions may not yet have signatures.
     Symtab->handleWeakUndefines();
-
-    // Make sure we have resolved all symbols.
-    if (!Config->AllowUndefined)
-      Symtab->reportRemainingUndefines();
   }
 
   if (EntrySym)

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=361476&r1=361475&r2=361476&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Thu May 23 03:06:03 2019
@@ -198,6 +198,17 @@ DefinedFunction *SymbolTable::addSynthet
                                         Flags, nullptr, Function);
 }
 
+DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value,
+                                                uint32_t Flags) {
+  Symbol *S = find(Name);
+  if (!S || S->isDefined())
+    return nullptr;
+  LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n");
+  auto *rtn = replaceSymbol<DefinedData>(S, Name, Flags);
+  rtn->setVirtualAddress(Value);
+  return rtn;
+}
+
 DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
                                                  uint32_t Flags) {
   LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");

Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=361476&r1=361475&r2=361476&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Thu May 23 03:06:03 2019
@@ -81,6 +81,8 @@ public:
                                     InputGlobal *Global);
   DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
                                         InputFunction *Function);
+  DefinedData *addOptionalDataSymbol(StringRef Name, uint32_t Value,
+                                     uint32_t Flags);
 
   void handleSymbolVariants();
   void handleWeakUndefines();

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=361476&r1=361475&r2=361476&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Thu May 23 03:06:03 2019
@@ -73,6 +73,8 @@ private:
   void addSection(OutputSection *Sec);
 
   void addSections();
+  void addStartStopSymbols(const InputSegment *Seg);
+
   void createCustomSections();
   void createSyntheticSections();
   void finalizeSections();
@@ -293,6 +295,22 @@ void Writer::addSection(OutputSection *S
   OutputSections.push_back(Sec);
 }
 
+// If a section name is valid as a C identifier (which is rare because of
+// the leading '.'), linkers are expected to define __start_<secname> and
+// __stop_<secname> symbols. They are at beginning and end of the section,
+// respectively. This is not requested by the ELF standard, but GNU ld and
+// gold provide the feature, and used by many programs.
+void Writer::addStartStopSymbols(const InputSegment *Seg) {
+  StringRef S = Seg->getName();
+  LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n");
+  if (!isValidCIdentifier(S))
+    return;
+  uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset;
+  uint32_t Stop = Start + Seg->getSize();
+  Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0);
+  Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0);
+}
+
 void Writer::addSections() {
   addSection(Out.DylinkSec);
   addSection(Out.TypeSec);
@@ -724,21 +742,40 @@ void Writer::run() {
   populateTargetFeatures();
   log("-- calculateImports");
   calculateImports();
+  log("-- layoutMemory");
+  layoutMemory();
+
+  if (!Config->Relocatable) {
+    // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
+    // This has to be done after memory layout is performed.
+    for (const OutputSegment *Seg : Segments)
+      for (const InputSegment *S : Seg->InputSegments)
+        addStartStopSymbols(S);
+  }
+
   log("-- scanRelocations");
   scanRelocations();
   log("-- assignIndexes");
   assignIndexes();
   log("-- calculateInitFunctions");
   calculateInitFunctions();
-  log("-- calculateTypes");
-  calculateTypes();
-  log("-- layoutMemory");
-  layoutMemory();
+
   if (!Config->Relocatable) {
+    // Create linker synthesized functions
     if (Config->Pic)
       createApplyRelocationsFunction();
     createCallCtorsFunction();
+
+    // Make sure we have resolved all symbols.
+    if (!Config->AllowUndefined)
+      Symtab->reportRemainingUndefines();
+
+    if (errorCount())
+      return;
   }
+
+  log("-- calculateTypes");
+  calculateTypes();
   log("-- calculateExports");
   calculateExports();
   log("-- calculateCustomSections");




More information about the llvm-commits mailing list