[llvm] [WebAssembly] Support multiple `.init_array` fragments when writing Wasm objects (PR #111008)

George Stagg via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 03:59:05 PDT 2024


================
@@ -1769,6 +1769,11 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
       WS.setIndex(InvalidIndex);
       continue;
     }
+    // Contents of .init_array sections are handled elsewhere.
+    if (WS.isDefined() &&
+        WS.getSection().getName().starts_with(".init_array")) {
----------------
georgestagg wrote:

Yes, the following C code does so:

```
#import <stdio.h>

void init1() { puts("init1"); }
__attribute__((section(".init_array"))) void (*p_init[3])(void) = { &init1, &init1, &init1 };

int main() { return 0; }
```

Under (e.g.) Linux, a list of pointers is written to the `.init_array` section and a symbol `p_init` points to the sequence.

```
$ clang -c symbol.c -o symbol.o
$ obj2yaml symbol.o
[...]
Symbols:
[...]
  - Name:            p_init
    Type:            STT_OBJECT
    Section:         .init_array
    Binding:         STB_GLOBAL
    Size:            0x18
```

However, with a WebAssembly object this does not make as much sense. `WasmObjectWriter.cpp` converts the sequence of pointers in `.init_array` section into entries in the `WASM_INIT_FUNC` subsection of the custom `linking` section instead. There they are no longer written as a list of pointers, but indexes into a table.

So, this particular change makes it so that the `p_init` symbol is not written into the WebAssembly object file. In the current version a symbol is actually written, but it is broken in any case since it points to the incorrect section (leading to the `invalid data segment index: 0` bug shown in the OP).

https://github.com/llvm/llvm-project/pull/111008


More information about the llvm-commits mailing list