<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63449>63449</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[WebAssembly] Add an LLVM and linker feature to control indirect function table layout
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
SingleAccretion
</td>
</tr>
</table>
<pre>
### Summary
This is a proposal for a feature that would allow frontends to control, in a limited way, how the linker should lay out the indirect
function table. The intent of the feature is to enable implementing zero-cost mapping between functions. If we can agree on an acceptable design and the proposed value, I would be the one responsible for implementing it.
### Use cases
The primary motivation for the feature is exploiting the indirection provided by table-based indirect invocation to imbue function pointers with additional information, for example:
1) If this function pointer has value R, it points to a special "kind" of method X.
2) Given a function pointer Y, get an associated pointer Z using simple arithmetic. This technique is a powerful primitive for implementing various "function pointer -> data" reverse mappings.
A concrete use case motivating this is the implementation of `RhGetCodeTarget` in [NativeAOT-LLVM](https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM), which maps special methods known as "unboxing stubs" to their callees. On native targets, this is implemented via disassembling the machine code produced for these methods, which is, naturally, not possible in WASM. We could of course produce an additional mapping table, but that would have unnecessary size overhead.
### Requirements
The requirement for the feature is that an LLVM module producer must be able to guarantee that, given a function Y, function Z will be placed at some - known at compile time - offset R from it. Y and Z need not be defined in this same module, however, for the NAOT-LLVM use case, we currently only need support for the case where one module defines the entire mapping, though I can imagine it is a constraint that could be cumbersome for other producers.
### Design
The proposed design is to add an intrinsic global, say `@llvm.wasm.indirect_function_table_map`, like `@llvm.used` and friends, with the type `[N x ptr]`, where the elements would be functions (and only functions - note this excludes `null`s).
At object emission time, this global would be serialized into the linking metadata (this would require an extension to the linking format) and at final link time the linker would, before constructing the indirect function table, copy functions from the maps to it as-is. This would allow duplicates in the final table, however, if the function was present in the map, the linker would not add another and instead take the last index it saw. Maps from different object files would be placed into the table in an undefined but deterministic order.
### Open questions
1) Is this compatible, in the sense that the offset property would be maintained within a single shared library, with dynamic linking (I am not familiar with how it works)? If not, can it be made so?
2) How should the map be encoded in the linking metadata? My idea was to "embed" the map into the symbol table, using symbol flags to indicate its start and end.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx8V9GS0zoS_RrPS9ekMs4kM_OQhwE2d6m6QBWwy15eqLbVjntHloxaTiZ8_VZLtpOBy1ZREGyp1Tqnz-k2ivDeEW2L9ati_eYKh9j6sP3Ebm_psa4DRfbuqvLmtC3KVf4Dn4auw3Aqlm-K5WP--3PLAiyA0Affe0ELjQ-A0BDGIRDEFiMc_WANoLX-CE3wLpIzAtFD7V0M3hbla2AHCJY7jmTgiCd91vojxJbAsnuiANKmOBZP4IeY3rAzHKiOkNNpBldr5hCxsrSAz2lJJBfBN2nDlBen88npOuCut9SRi-z28IOCv669ROiw7_VJRfFI5GCKLgt428CRoEYHuA9E4B3o77qmPh0NhhRhQGfSsRkdMnBAO5De7e2ISkVpgXcEgaT3Tlj3K4ov0uK4uAT-zMq_RBMRkpe86JmsdEHnIx8wwaJRf0KBnnvrOR1xCaiu7oM_sCED1SkDel2h3mEGnd3B1zly9MBdNdAMEvRekQ8CR44toDGsj9ECu8aHLm1TIDQneka9a7Ea078pygfFOGp5_RwRWpSMI3xMlRPzm8QogvRUM1ooyvKJnSnKUrnvKLbewH9GEEs94A8-kFbdLwf8pWH3FBOnIr5m1KqcXn-FQRQvSQQBBo5tR5FrLTgtLKpbx98HGpXhjxSawSZCOPLhb9g9YGA_iCb9SzbXxeofYDCiXiXQgYLQVJvyoigeVVAqXoJhrIqZ_cRvFmvieTo90-cbKDbLj-0fFF97Q58x7CkWm6XKsli_eo-a9uOHz9d__vnvd8X6TVHetzH2ooyVu6Lc7Tm2Q7WofVeUO-Ojo1iUuzC4yB1ZrIpyFwNRUe7G2ivK3U9RyweF_dhy3er1ZGYycyfw5PxRCVGUBlf550RCHCpRZKLXi3GAGq0lkgV8cODSERDTfUTjTyDMAKgoGcGwoAh1lZ2k0GHdsiOovUkCNkNNZpKQIpvTOifN6bfT66G1ycGc1-KUrGl28OXx07sFfNGgKn7f6A_lc4yfKu4slcmBkvo0XpV8b7bUFg8Eg3NUk4hqXfgHgT9QaAnNbwzjI30fOKS7_-IZ4fzu78wiHY0OlC_ovBnsnHmAbpCodpb8L3rYDxjQRcpNIEnqZ8Eloc3_-wpHtlZD9BYVa4wgviO4nqiPUPuuZ43P6blvGqEIH7WtdOqR8Ffy3K_giEyCv1Izbtgl48r0C3Y0pj-2GVXVZEZ65_dTVc5CSjQT1EMI5KI9gXf2lE-Roe99OAOWdHdsKWRbH3HKSWT1qerDLOJcln7Yt_A29RTucK-VxzE7SO2dxIDsRvLrqXPUQ1dRSBjp4T62FGZC5Df8v0mt6dduMXaosXPlBonGKN_sYmAnXMPe-gpTwxY8qWcUt0trD93iiNItps7wbeL0W6rcbx32urR8DZaf6HLbIGTUZ5S0JrAOBglp7RmKVDz1ef361Xt4hj4GdZ8cK0Oc8MxSlnNPnXs1FOW9Bk90nZ9ea21QLgd6ru1gSPQcN1hbbJZSlA8vrTWCr_6rTY86FkktjzuaHSXjcj5fKDBa_pGqLltTGmNUzR1FVD_X1NLmvGvUnuJNz5GcjH31cmvunNq89E4YoWH1CX2dJXExLqWoyTSo8YHGKhrqX3o9vBybdEvt-0u0krqyJ_apLjgCyjXL2PEuBzwz9JZrjCRZbzTmOMe-kBuPQ9l0_hEF-kCi9jNu1tJJIL-8V5J2rs5c9YoHO4mEBiI-jUigaCBDz5qx4HEB7_QG6T6Gm4ZCmg0zsw1buiih0YRm-vJgx2nSG9zkKerIhiKFjh1L5Bp8MBR-o70PPTn4PpAkXC_X5JFHcjWpy2HkEbARCSEn40CdJsZsfapbCvF0zrtTo8CUnMooDdaSJnuQFgMZsFwFHeQnoZmTw47rucqK8v4tYJcwbrBjyxjySp3IWbtPeFKJFKudjmnOJ3tP1hVzCoZAfLHaXYxb__THaYQfidWl5LS_mumSP2tET3h3AjaEqTqi1-5PXUVpspsCzSTJqav8RbGNk1p-2ljc5_J1JpUocBSQiCGm-iFnFldmuzIPqwe8ou3N5v7udrVeL8urdrvBO1zelOuKloSId7cNre_vm3q93JT3m-XdFW_LZblabsryplyul8tF3Wxqc3N3U6JZ3d4-3BW3S-qQ7SI5nw_7KxYZaLvRt1cWK7IyfZGFrS66roa9qFWyRDlvixxt-nb7QtVjHlpOxfoNPGa3Tn1L7zMKZv4Wmz-4fid9_bbyQ7wagt3-n_lOExn_ue6DV_EU5S5dRopyl-7zvwAAAP__mmP80A">