aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm.zig
AgeCommit message (Collapse)Author
2022-02-23wasm-linker: Implement `updateDeclExports`Luuk de Gram
We now correctly implement exporting decls. This means it is possible to export a decl with a different name than the decl that is doing the export. This also sets the symbols with the correct flags, so when we emit a relocatable object file, a linker can correctly resolve symbols and/or export the symbol to the host environment. This commit also includes fixes to ensure relocations have the correct offset to how other linkers will expect the offset, rather than what we use internally. Other linkers accept the offset, relative to the section. Internally we use an offset relative to the atom.
2022-02-23wasm-linker: Emit relocations for object filesLuuk de Gram
When generating a relocatable object file, we now emit a custom "reloc.CODE" and "reloc.DATA" section which will contain the relocations for each section. Using a new symbol location -> Atom mapping, we can now easily find the corresponding `Atom` from a symbol. This can be used to construct the symbol table, as well as easier access to a target atom when performing a relocation for a data symbol.
2022-02-23wasm-linker: Do not merge data segments for objLuuk de Gram
When creating a relocatable object file, we do no longer perform the following actions: - Merge data segments - Calculate stack size - Relocations We now also make the stack pointer symbol `undefined` for this use case as well as add the symbol as an import.
2022-02-23wasm-linker: Emit segment infoLuuk de Gram
When creating a relocatable object file, also emit the segment information
2022-02-23wasm-linker: Emit symbol table for object fileLuuk de Gram
When creating a relocatable object file, emit the symbol table. We do this by iterating over all atoms, and finding the corresponding symbols of those. This provides us all the meta information such as size, and offset as well. This data is required for defined data symbols. When we emit an object file, the "Names" section does not have to be emitted, as all symbol names are already in the symbol table, so the names section is redundant.
2022-02-23stage1-wasm: implement shared memoryxReveres
2022-02-17wasm-linker: Simplify symbol namesLuuk de Gram
No longer duplicate the symbol name and instead take the pointer from the decl itself. Also fix 32bit build
2022-02-17wasm-linker: Fix symbol resolving and relocsLuuk de Gram
- Correctly get discard symbol by first checking if it was discarded or not. - Remove imports if extern symbols were resolved by an object file. - Correctly relocate data symbols by ensuring the atom is from the correct file. - Fix the `Names` section by using the resolved symbols, rather than the ones defined in Zig code.
2022-02-17wasm-linker: Allocate atoms and handle importsLuuk de Gram
We now correctly allocate and create atoms for symbols from other object files. Imports are now also resolved and appended when required. Besides those changes, we now duplicate all symbol names, so we can correctly generate unique names for unnamed constants. TODO: String interning
2022-02-17wasm-linker: Implement section mergingLuuk de Gram
This implements the merging of all sections, to generate a valid wasm binary where all symbols have been resolved and their respective sections have been merged into the final binary.
2022-02-17wasm-linker: Add Object file parsingLuuk de Gram
This upstreams the object file parsing from zwld, bringing us closer to being able to link stage2 code with object files/C-code as well as replacing lld with the self-hosted linker once feature complete.
2022-02-16link: avoid double close on openPath errorAndrew Kelley
2022-02-10wasm: Implement 'field_ptr' constantsLuuk de Gram
This implements the `field_ptr` value for pointers. As the value only provides us with the index, we must calculate the offset from the container type using said index. (i.e. the offset from a struct field at index 2). Besides this, small miscellaneous fixes/updates were done to get remaining behavior tests passing: - We start the function table index at 1, so unresolved function pointers don't can be null-checked properly. - Implement genTypedValue for floats up to f64. - Fix zero-sized arguments by only creating `args` for non-zero-sized types. - lowerConstant now works for all decl_ref's. - lowerConstant properly lowers optional pointers, so `null` pointers are lowered to `0`.
2022-02-08wasm: update test runnerLuuk de Gram
This updates the test runner for stage2 to emit to stdout with the passed, skipped and failed tests similar to the LLVM backend. Another change to this is the start function, as it's now more in line with stage1's. The stage2 test infrastructure for wasm/wasi has been updated to reflect this as well.
2022-02-06stage2: pass proper can_exit_early value to LLDAndrew Kelley
and adjust the warning message for invoking LLD twice in the same process.
2022-02-06Avoid depending on child process execution when not supported by host OSCody Tapscott
In accordance with the requesting issue (#10750): - `zig test` skips any tests that it cannot spawn, returning success - `zig run` and `zig build` exit with failure, reporting the command the cannot be run - `zig clang`, `zig ar`, etc. already punt directly to the appropriate clang/lld main(), even before this change - Native `libc` Detection is not supported Additionally, `exec()` and related Builder functions error at run-time, reporting the command that cannot be run
2022-02-03wasm: Implement elem_ptrLuuk de Gram
This implements lowering elem_ptr for decl's and constants. To generate the correct pointer, we perform a relocation by using the addend that represents the offset. The offset is calculated by taking the element's size and multiplying that by the index. For constants this generates a single immediate instruction, and for decl's this generates a single pointer address.
2022-01-28link: ELF, COFF, WASM: honor the "must_link" flag of positionalsAndrew Kelley
Previously only the MachO linker was honoring the flag.
2022-01-26zig cc: add --hash-style linker parameterAndrew Kelley
This is only relevant for ELF files. I also fixed a bug where passing a zig source file to `zig cc` would incorrectly punt to clang because it thought there were no positional arguments.
2022-01-25link: Elf, Wasm: forward strip flag when linking with LLDAndrew Kelley
2022-01-24stage2: rework a lot of stuffAndrew Kelley
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
2022-01-19wasm: Re-use genTypedValue for constantsLuuk de Gram
When a constant will be passed by reference, such as a struct, we will call into genTypedValue to lower the constant to bytes and store them into the `rodata` section. We will then return the address of this constant as a `WValue`. This change means we will have all constants lowered during compilation time, and no longer have to sacrifice runtime to lower them onto the stack.
2022-01-19wasm: Split funcgen and declgenLuuk de Gram
This allows us to get rid of unused fields when generating code for non-function decls. We can now create seperate instances of `DeclGen` which in turn can then be used to generate the code for a constant. Besides those reasons, it will be much easier to switch to the generic purpose `codegen.zig` that any backend should use. Allowing us to deduplicate this code.
2022-01-19wasm-linker: Allow for creation of local symbolsLuuk de Gram
The backend can create annonymous local symbols. This can be used for constants that will be passed by reference so it will not have to be lowered to the stack, and then stored into the data section. This also means it's valid to return a pointer to a constant array. Those local symbols that are created, will be managed by the parent decl. Free'ing the parent decl, will also free all of its locals. When a local symbol was created, the index of said symbol will be returned and saved in the `memory` tag of a `WValue` which is then memoized. This means that each 'emit' of this WValue will create a relocation for that constant/symbol and the actual pointer value will be set after relocation phase.
2022-01-19lld: allow for entrypoint symbol name to be setKenta Iwasaki
This commit enables for the entrypoint symbol to be set when linking ELF or WebAssembly modules with lld using the Zig compiler.
2022-01-13Introduce LinkObject with must_link fieldJakub Konka
2022-01-11wasm-ld: Append `--stack-first` by defaultLuuk de Gram
By placing the stack at the start of the memory section, we prevent the runtime from silently overwriting the global declarations and instead trap. We do however, allow users to overwrite this behavior by setting the global-base, which puts the stack at the end of the memory section and the static data at the base that was specified. The reason a user would want to do this, is when they are sure the stack will not overflow and they want to decrease the binary size as the offsets to the static memory are generally smaller. (Having the stack in front, means that accessing the memory after the stack has a bigger offset when loading/storing from memory).
2022-01-11wasm: Place the stack at the start of memoryLuuk de Gram
2022-01-07Pass `--allow-unknown-exports` to wasmtimeLuuk de Gram
Also skip exporting non-function symbols when we're building a WASI command using the stage2 llvm backend.
2022-01-06wasm-linker: Only export symbols notated as suchLuuk de Gram
This exposes a function from stage2 to stage1 to append symbols to automatically export them. This happends under the following conditions: - Target is wasm - User has not provided --export/--rdynamic flags themselves.
2022-01-04link: avoid creating stage2 llvm module when using stage1Andrew Kelley
2022-01-03linker: fix build-obj and -fno-emit-binAndrew Kelley
This commit fixes two problems: * `zig build-obj` regressed from the cache-mode branch. It would crash because it assumed that dirname on the emit bin path would not be null. This assumption was invalid when outputting to the current working directory - a pretty common use case for `zig build-obj`. * When using the LLVM backend, `-fno-emit-bin` combined with any other kind of emitting, such as `-femit-asm`, emitted nothing. Both issues are now fixed.
2022-01-03stage2: introduce renameTmpIntoCache into the linker APIAndrew Kelley
Doc comments reproduced here: This function is called by the frontend before flush(). It communicates that `options.bin_file.emit` directory needs to be renamed from `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`. The frontend would like to simply perform a file system rename, however, some linker backends care about the file paths of the objects they are linking. So this function call tells linker backends to rename the paths of object files to observe the new directory path. Linker backends which do not have this requirement can fall back to the simple implementation at the bottom of this function. This function is only called when CacheMode is `whole`. This solves stack trace regressions on Windows and macOS because the linker backends do not observe object file paths until flush().
2022-01-02stage2: introduce CacheModeAndrew Kelley
The two CacheMode values are `whole` and `incremental`. `incremental` is what we had before; `whole` is new. Whole cache mode uses everything as inputs to the cache hash; and when a hit occurs it skips everything including linking. This is ideal for when source files change rarely and for backends that do not have good incremental compilation support, for example compiler-rt or libc compiled with LLVM with optimizations on. This is the main motivation for the additional mode, so that we can have LLVM-optimized compiler-rt/libc builds, without waiting for the LLVM backend every single time Zig is invoked. Incremental cache mode hashes only the input file path and a few target options, intentionally relying on collisions to locate already-existing build artifacts which can then be incrementally updated. The bespoke logic for caching stage1 backend build artifacts is removed since we now have a global caching mechanism for when we want to cache the entire compilation, *including* linking. Previously we had to get "creative" with libs.txt and a special byte in the hash id to communicate flags, so that when the cached artifacts were re-linked, we had this information from stage1 even though we didn't actually run it. Now that `CacheMode.whole` includes linking, this extra information does not need to be preserved for cache hits. So although this changeset introduces complexity, it also removes complexity. The main trickiness here comes from the inherent differences between the two modes: `incremental` wants a directory immediately to operate on, while `whole` doesn't know the output directory until the compilation is complete. This commit deals with this problem mostly inside `update()`, where, on a cache miss, it replaces `zig_cache_artifact_directory` with a temporary directory, and then renames it into place once the compilation is complete. Items remaining before this branch can be merged: * [ ] make sure these things make it into the cache manifest: - @import files - @embedFile files - we already add dep files from c but make sure the main .c files make it in there too, not just the included files * [ ] double check that the emit paths of other things besides the binary are working correctly. * [ ] test `-fno-emit-bin` + `-fstage1` * [ ] test `-femit-bin=foo` + `-fstage1` * [ ] implib emit directory copies bin_file_emit directory in create() and needs to be adjusted to be overridden as well. * [ ] make sure emit-h is handled correctly in the cache hash * [ ] Cache: detect duplicate files added to the manifest Some preliminary performance measurements of wall clock time and peak RSS used: stage1 behavior (1077 tests), llvm backend, release build: * cold global cache: 4.6s, 1.1 GiB * warm global cache: 3.4s, 980 MiB stage2 master branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 191 MiB * warm global cache: 0.40s, 128 MiB stage2 this branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 179 MiB * warm global cache: 0.27s, 90 MiB
2022-01-01wasm: Implement @ptrToInt and fix indirect function callLuuk de Gram
- Previously the table index and function type index were switched. This commit swaps them. - This also emits the correct indirect function calls count when importing the function table
2022-01-01wasm: Implement `array_to_slice` and bug fixes:Luuk de Gram
- Add method to easily create local for virtual stack - Ensure function pointers are passed correctly - Correctly handle slices as return types and values - Fix wrapping error sets/payloads. - Handle ptr-like optionals correctly, by using address '0' as null. - Implement `array_to_slice` - linker: Always emit a table, so call_indirect inside bodies do not fail if there's no table. TODO: Only do this when we emit a call_indirect but the relocation cannot be resolved.
2021-12-23wasm-linker: Implement symbol names emittingLuuk de Gram
The linker will now emit names for all function, global and data segment symbols. This increases the ability to debug wasm modules tremendously as tools like wasm2wat can use this information to generate named functions, globals etc, rather than placeholders such as $f1.
2021-12-21link/wasm: fix regression of wrong assertionAndrew Kelley
Fixes typo introduced in 2cbeb85a96af25f2718a604aa2bec4f76dd85018.
2021-12-21stage2: error check for mixing --import-table and --export-tableAndrew Kelley
is moved from the linker to the frontend. This is a follow-up from 4cb2f11693b1bf13770b8ad6a8b8a1e37101a516.
2021-12-21wasm-linker: Implement the --export-table and --import-table flags.Luuk de Gram
This implements the flags for both the linker frontend as well as the self-hosted linker. Closes #5790
2021-12-14wasm-linker: Allow specifying symbols to be exportedLuuk de Gram
Notating a symbol to be exported in code will only tell the linker where to find this symbol, so other object files can find it. However, this does not mean said symbol will also be exported to the host environment. Currently, we 'fix' this by force exporting every single symbol that is visible. This creates bigger binaries and means host environments have access to symbols that they perhaps shouldn't have. Now, users can tell Zig which symbols are to be exported, meaning all other symbols that are not specified will not be exported. Another change is we now support `-rdynamic` in the wasm linker as well, meaning all symbols will be put in the dynamic symbol table. This is the same behavior as with ELF. This means there's a 3rd strategy users will have to build their wasm binary.
2021-12-05wasm: Initial behavior tests succeedingLuuk de Gram
- Correctly load slice value on stack - Implement WrapErrorUnionErr and payload - Implement trunc, fix sliceLen and write undefined - Implement slice as return type and argument Note: This also fixes a memory leak for inferred error sets, and for usingnamespace
2021-12-04Revert "Merge pull request #10270 from Luukdegram/behaviour-tests"Andrew Kelley
This reverts commit 725267f7c20f0ba588b472048a8c1fe1a328c714, reversing changes made to 2dae860de3494f97c9477af9282fe0131ff5c4cb. This test is failing: ```zig pub fn main() u8 { var e = foo(); const i = e catch 69; return i; } fn foo() anyerror!u8 { return 5; } ``` It's returning 69 instead of the expected value 5.
2021-12-04wasm: Correctly load slice value on stackLuuk de Gram
2021-12-04wasm: Implement WrapErrorUnionErr(payload)Luuk de Gram
2021-11-30allocgate: renamed getAllocator function to allocatorLee Cannon
2021-11-30allocgate: stage 1 and 2 buildingLee Cannon
2021-11-30allocgate: std Allocator interface refactorLee Cannon
2021-11-28wasm-link: Implement indirect function tableLuuk de Gram
The function table contains all function pointers that are called by using call_indirect. During codegen, we create a relocation where the linker will resolve the correct index into the table and stores this value within the data section at the location of the pointer.
2021-11-27wasm-linker: Link into binary during flushLuuk de Gram
This contains a few additions: - Proper stack pointer calculation keeping alignment in mind. - Setting up memory layout (including user flags). - Export or import memory - Handle 'easy' linker tasks during incremental compilation, while offloading heavy-tracking/computation tasks to `flush()` - This architecture allows us to easily integrate with the rest of 'zwld' to implement linking stage2 code with external object files.