[lld] b99147b - [lld][WebAssembly] Don't defined indirect function table in relocatable output

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 13:10:58 PST 2021


Author: Sam Clegg
Date: 2021-01-19T12:59:20-08:00
New Revision: b99147b4fa7b361fba4eeefdb443dca72b8ee87f

URL: https://github.com/llvm/llvm-project/commit/b99147b4fa7b361fba4eeefdb443dca72b8ee87f
DIFF: https://github.com/llvm/llvm-project/commit/b99147b4fa7b361fba4eeefdb443dca72b8ee87f.diff

LOG: [lld][WebAssembly] Don't defined indirect function table in relocatable output

Object files (and the output --relocatable) should never define
__indirect_function_table.  It should always be linker synthesized
with the final output executable.

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

Added: 
    

Modified: 
    lld/test/wasm/locals-duplicate.test
    lld/test/wasm/relocatable.ll
    lld/test/wasm/signature-mismatch.ll
    lld/test/wasm/weak-alias.ll
    lld/wasm/Driver.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/locals-duplicate.test b/lld/test/wasm/locals-duplicate.test
index cf9a148d4ab7..1d704ec2dff1 100644
--- a/lld/test/wasm/locals-duplicate.test
+++ b/lld/test/wasm/locals-duplicate.test
@@ -231,17 +231,19 @@
 ; RELOC-NEXT:         ParamTypes:      []
 ; RELOC-NEXT:         ReturnTypes:
 ; RELOC-NEXT:           - I32
+; RELOC-NEXT:  - Type:            IMPORT
+; RELOC-NEXT:    Imports:
+; RELOC-NEXT:      - Module:          env
+; RELOC-NEXT:        Field:           __indirect_function_table
+; RELOC-NEXT:        Kind:            TABLE
+; RELOC-NEXT:        Table:
+; RELOC-NEXT:          Index:           0
+; RELOC-NEXT:          ElemType:        FUNCREF
+; RELOC-NEXT:          Limits:
+; RELOC-NEXT:            Initial:         0x3
 ; RELOC-NEXT:   - Type:            FUNCTION
 ; RELOC-NEXT:     FunctionTypes:   [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 ; RELOC-NEXT:                        0, 0 ]
-; RELOC-NEXT:   - Type:            TABLE
-; RELOC-NEXT:     Tables:
-; RELOC-NEXT:       - Index:           0
-; RELOC-NEXT:         ElemType:        FUNCREF
-; RELOC-NEXT:         Limits:
-; RELOC-NEXT:           Flags:           [ HAS_MAX ]
-; RELOC-NEXT:           Initial:         0x7
-; RELOC-NEXT:           Maximum:         0x7
 ; RELOC-NEXT:   - Type:            MEMORY
 ; RELOC-NEXT:     Memories:
 ; RELOC-NEXT:       - Initial:         0x1
@@ -412,7 +414,7 @@
 ; RELOC-NEXT:       - Index:           8
 ; RELOC-NEXT:         Kind:            TABLE
 ; RELOC-NEXT:         Name:            __indirect_function_table
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Flags:           [ UNDEFINED, NO_STRIP ]
 ; RELOC-NEXT:         Table:           0
 ; RELOC-NEXT:       - Index:           9
 ; RELOC-NEXT:         Kind:            FUNCTION

diff  --git a/lld/test/wasm/relocatable.ll b/lld/test/wasm/relocatable.ll
index e8129da9ad3d..7de51a38f5c9 100644
--- a/lld/test/wasm/relocatable.ll
+++ b/lld/test/wasm/relocatable.ll
@@ -1,7 +1,10 @@
 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/hello.s -o %t.hello.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld -r -o %t.wasm %t.hello.o %t.o
-; RUN: obj2yaml %t.wasm | FileCheck %s
+; RUN: wasm-ld -r -o %t2.o %t.hello.o %t.o
+; RUN: obj2yaml %t2.o | FileCheck %s
+
+; Verify the resulting object can be used as linker input
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t2.o --export-table
 
 target triple = "wasm32-unknown-unknown"
 
@@ -32,6 +35,11 @@ entry:
 ; Test that __attribute__(used) (i.e NO_STRIP) is preserved in the relocated symbol table
 @llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @my_func to i8*)], section "llvm.metadata"
 
+define void @_start() {
+  ret void
+}
+
+
 ; CHECK:      --- !WASM
 ; CHECK-NEXT: FileHeader:
 ; CHECK-NEXT:   Version:         0x1
@@ -63,16 +71,16 @@ entry:
 ; CHECK-NEXT:         Field:           bar_import
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         SigIndex:        1
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           __indirect_function_table
+; CHECK-NEXT:         Kind:            TABLE
+; CHECK-NEXT:         Table:
+; CHECK-NEXT:           Index:           0
+; CHECK-NEXT:           ElemType:        FUNCREF
+; CHECK-NEXT:           Limits:
+; CHECK-NEXT:             Initial:         0x3
 ; CHECK-NEXT:   - Type:            FUNCTION
-; CHECK-NEXT:     FunctionTypes:   [ 2, 1, 1 ]
-; CHECK-NEXT:   - Type:            TABLE
-; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - Index:           0
-; CHECK-NEXT:         ElemType:        FUNCREF
-; CHECK-NEXT:         Limits:
-; CHECK-NEXT:           Flags:           [ HAS_MAX ]
-; CHECK-NEXT:           Initial:         0x4
-; CHECK-NEXT:           Maximum:         0x4
+; CHECK-NEXT:     FunctionTypes:   [ 2, 1, 1, 2 ]
 ; CHECK-NEXT:   - Type:            MEMORY
 ; CHECK-NEXT:     Memories:
 ; CHECK-NEXT:      - Initial:         0x1

diff  --git a/lld/test/wasm/signature-mismatch.ll b/lld/test/wasm/signature-mismatch.ll
index 65ce73910ffa..931ec9ef1234 100644
--- a/lld/test/wasm/signature-mismatch.ll
+++ b/lld/test/wasm/signature-mismatch.ll
@@ -82,7 +82,7 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr
 ; RELOC-NEXT:       - Index:           3
 ; RELOC-NEXT:         Kind:            TABLE
 ; RELOC-NEXT:         Name:            __indirect_function_table
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Flags:           [ UNDEFINED, NO_STRIP ]
 ; RELOC-NEXT:         Table:           0
 ; RELOC-NEXT:       - Index:           4
 ; RELOC-NEXT:         Kind:            FUNCTION

diff  --git a/lld/test/wasm/weak-alias.ll b/lld/test/wasm/weak-alias.ll
index 387501963d4b..90531fa135ff 100644
--- a/lld/test/wasm/weak-alias.ll
+++ b/lld/test/wasm/weak-alias.ll
@@ -149,16 +149,16 @@ entry:
 ; RELOC-NEXT:         Kind:            GLOBAL
 ; RELOC-NEXT:         GlobalType:      I32
 ; RELOC-NEXT:         GlobalMutable:   true
+; RELOC-NEXT:       - Module:          env
+; RELOC-NEXT:         Field:           __indirect_function_table
+; RELOC-NEXT:         Kind:            TABLE
+; RELOC-NEXT:         Table:
+; RELOC-NEXT:           Index:           0
+; RELOC-NEXT:           ElemType:        FUNCREF
+; RELOC-NEXT:           Limits:
+; RELOC-NEXT:             Initial:         0x1
 ; RELOC-NEXT:   - Type:            FUNCTION
 ; RELOC-NEXT:     FunctionTypes:   [ 0, 1, 1, 1, 1, 1 ]
-; RELOC-NEXT:   - Type:            TABLE
-; RELOC-NEXT:     Tables:
-; RELOC-NEXT:       - Index:           0
-; RELOC-NEXT:         ElemType:        FUNCREF
-; RELOC-NEXT:         Limits:
-; RELOC-NEXT:           Flags:           [ HAS_MAX ]
-; RELOC-NEXT:           Initial:         0x2
-; RELOC-NEXT:           Maximum:         0x2
 ; RELOC-NEXT:   - Type:            MEMORY
 ; RELOC-NEXT:     Memories:
 ; RELOC-NEXT:       - Initial:         0x0
@@ -279,7 +279,7 @@ entry:
 ; RELOC-NEXT:       - Index:           8
 ; RELOC-NEXT:         Kind:            TABLE
 ; RELOC-NEXT:         Name:            __indirect_function_table
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Flags:           [ UNDEFINED, NO_STRIP ]
 ; RELOC-NEXT:         Table:           0
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            name

diff  --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index b988f9fa7fd1..830e4bf1744f 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -817,22 +817,31 @@ static TableSymbol *createUndefinedIndirectFunctionTable(StringRef name) {
 }
 
 static TableSymbol *resolveIndirectFunctionTable() {
-  // Even though we may not need a table, if the user explicitly specified
-  // --import-table or --export-table, ensure a table is residualized.
-  if (config->importTable)
-    return createUndefinedIndirectFunctionTable(functionTableName);
-  if (config->exportTable)
-    return createDefinedIndirectFunctionTable(functionTableName);
-
-  // Otherwise, check to the symtab to find the indirect function table.
-  if (Symbol *sym = symtab->find(functionTableName)) {
-    if (sym->isLive()) {
-      if (auto *t = dyn_cast<TableSymbol>(sym)) {
-        return t->isDefined()
-                   ? t
-                   : createDefinedIndirectFunctionTable(functionTableName);
-      }
+  Symbol *existingTable = symtab->find(functionTableName);
+  if (existingTable) {
+    if (!isa<TableSymbol>(existingTable)) {
+      error(Twine("reserved symbol must be of type table: `") +
+            functionTableName + "`");
+      return nullptr;
     }
+    if (existingTable->isDefined()) {
+      error(Twine("reserved symbol must not be defined in input files: `") +
+            functionTableName + "`");
+      return nullptr;
+    }
+  }
+
+  if (config->importTable) {
+    if (existingTable)
+      return cast<TableSymbol>(existingTable);
+    else
+      return createUndefinedIndirectFunctionTable(functionTableName);
+  } else if ((existingTable && existingTable->isLive()) ||
+             config->exportTable) {
+    // A defined table is required.  Either because the user request an exported
+    // table or because the table symbol is already live.  The existing table is
+    // guaranteed to be undefined due to the check above.
+    return createDefinedIndirectFunctionTable(functionTableName);
   }
 
   // An indirect function table will only be present in the symbol table if
@@ -1029,11 +1038,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
   // Do size optimizations: garbage collection
   markLive();
 
-  // Provide the indirect funciton table if needed.
-  WasmSym::indirectFunctionTable = resolveIndirectFunctionTable();
+  if (!config->relocatable) {
+    // Provide the indirect funciton table if needed.
+    WasmSym::indirectFunctionTable = resolveIndirectFunctionTable();
 
-  if (errorCount())
-    return;
+    if (errorCount())
+      return;
+  }
 
   // Write the result to the file.
   writeResult();


        


More information about the llvm-commits mailing list