aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm.zig
AgeCommit message (Collapse)Author
2022-12-28WebAssembly: don't append `--export` for functionsLuuk de Gram
No longer automatically append the `--export` flag for each exported function unconditionally. This was essentially a hack to prevent binary bloat caused by compiler-rt symbols being always included in the final binary as they were exported and therefore not garbage- collected. This is no longer needed as we now support the ability to set the visibility of exports. This essentially reverts 6d951aff7e32b1b0252d341e66517a9a9ee98a2d
2022-12-25WebAssembly: do not link with --allow-undefined unconditionallyFrank Denis
In #1622, when targeting WebAsembly, the --allow-undefined flag became unconditionally added to the linker. This is not always desirable. First, this is error prone. Code with references to unkown symbols will link just fine, but then fail at run-time. This behavior is inconsistent with all other targets. For freestanding wasm applications, and applications that only use WASI, undefined references are better reported at compile-time. This behavior is also inconsistent with clang itself. Autoconf and cmake scripts checking for function presence think that all tested functions exist, but then resulting application cannot run. For example, this is one of the reasons compilation of Ruby 3.2.0 to WASI fails with zig cc, while it works out of the box with clang. But all applications checking for symbol existence before compilation are affected. This reverts the behavior to the one Zig had before #1622, and introduces an `import_symbols` flag to ignore undefined symbols, assuming that the webassembly runtime will define them.
2022-12-19wasm-linker: consolidate writing to fileLuuk de Gram
This merges the paths from flushModule and linkWithZld to a single function that will write the entire WebAssembly module to the file. This reduces the chance of mistakes as we do not have to duplicate the logic. A similar action may be needed later for linkWithLLD.
2022-12-18wasm-linker: Add caching + more into zld pathLuuk de Gram
2022-12-18wasm-linker: Fix relocations for alias'd atomsLuuk de Gram
When an atom has one or multiple aliasses, we we could not find the target atom from the alias'd symbol. This is solved by ensuring that we also insert each alias symbol in the symbol-atom map.
2022-12-16wasm-linker: Fix archive symbols parsingLuuk de Gram
When parsing the table of contents containing the symbols and their positions we initially used the index within the map to retrieve the offset. However, during resizing of the underlaying array this would invalidate those indexes which meant incorrect offsets were being stored for symbols. We now use the current symbol index to also get the index into the symbol position instead.
2022-12-14wasm-linker: Export data symbols as globalLuuk de Gram
When a data symbol is required to be exported, we instead generate a global that will be exported. This global is immutable and contains the address of the data symbol.
2022-12-13wasm-linker: Create separate path for one-shotLuuk de Gram
When invoking the self-hosted linker using `-fno-LLD` while using the LLVM backend or invoking it as a linker, we create a seperate path. This path will link the object file generated by LLVM and the supplied object files just once, allowing to simplify the implementation between incremental and regular linking.
2022-12-09dwarf: resolve all relative paths when generating include_dirs and ↵Jakub Konka
file_names lists
2022-12-09dwarf: track source files via *const Module.File pointersJakub Konka
2022-12-06remove `-fstage1` optionAndrew Kelley
After this commit, the self-hosted compiler does not offer the option to use stage1 as a backend anymore.
2022-12-05dwarf: reuse getDbgInfoAtom helper in all of Dwarf.zigJakub Konka
We need to access it outside of `DeclState` too so why not reuse the helper anyway.
2022-11-30wasm: enable behavior tests for packed structsLuuk de Gram
2022-11-30codegen: support generating packed structsLuuk de Gram
2022-11-29std.mem.Allocator: allow shrink to failAndrew Kelley
closes #13535
2022-11-19linker: fail the compilation if there were linker errorsCasey Banner
There was no check for linker errors after flushing, which meant that if the link failed the build would continue and try to copy the non-existant exe, and also write the manifest as if it had succeeded. Also adds parsing of lld output, which is surfaced at the end of the compilation with the other errors instead of via stderr
2022-10-25use fixed-size arrays for feature listsLuuk de Gram
Considering all possible features are known by the linker during compile-time, we can create arrays on the stack instead of dynamically allocating hash maps. We use a simple bitset to determine whether a feature is enabled or not, and from which object file it originates. This allows us to make feature validation slightly faster and use less runtime memory. In the future this could be enhanced further by having a single array instead with a more sophisticated bitset.
2022-10-25wasm-linker: seperate linker -and cpu featuresLuuk de Gram
The list of features a Wasm object/binary file can emit can differ from the list of cpu features. The reason for this is because the "target_features" section also contains linker features. An example of this is the "shared-mem" feature, which is a feature for the linker and not that of the cpu target as defined by LLVM.
2022-10-25wasm-linker: emit `target_features` sectionLuuk de Gram
When the result is not being stripped, we emit the `target_features` section based on all the used features. This includes features inferred from linked object files. Considering we know all possible features upfront, we can use an array and therefore do not have to dynamically allocate memory. Using this trick we can also easily order all features based the same ordering as found in `std.Target.wasm` which is the same ordering used by LLVM and the like.
2022-10-25wasm-linker: validate feature compatibilityLuuk de Gram
Verifies disallowed and used/required features. After verifying, all errors will be emit to notify the user about incompatible features. When the user did not define any featureset, we infer the features from the linked objects instead.
2022-10-24link: add an explicit error set for flush() and flushModule()Andrew Kelley
This makes it easier to understand how control flow should happen in various cases; already just by doing this it is revealed that UndefinedSymbol and UndefinedSymbolReference should be merged, and that MissingMainEntrypoint should be removed in favor of the ErrorFlags mechanism thath we already have for missing the main entrypoint. The main motivation for this change, however, is preventing a compile error when there is conditional compilation inside linker implementations, causing the flush() error set to depend on compilation options. With this change, the error set is fixed, and, notably, the `-Donly-c` flag no longer has compilation errors due to this error set.
2022-10-08wasm-linker: convert relocation addend to i32Luuk de Gram
Addends in relocations are signed integers as theoretically it could be a negative number. As Atom's offsets are relative to their parent section, the relocation value should still result in a postive number. For this reason, the final result is stored as an unsigned integer. Also, rather than using `null` for relocations that do not support addends. We set the value to 0 for those that do not support addends, and have to call `addendIsPresent` to determine if an addend exists or not. This means each Relocation costs 4 bytes less than before, saving memory while linking.
2022-10-08CheckObjectStep: parsing and dumping producersLuuk de Gram
2022-10-08wasm-linker: generate 'producers' sectionLuuk de Gram
The `producers` section contains meta data of the binary and/or object file. It *can* contain the source language, the tool it was processed by, and/or the SDK that was used to produce the file. For now, we always set the language and processed-by fields to Zig. In the future we will parse linked object files to detect their producers sections and append (if different) their language, SDK and processed-by fields.
2022-09-13Merge remote-tracking branch 'origin/master' into llvm15Andrew Kelley
2022-09-12wasm-linker: reset file pointer for incrementalLuuk de Gram
On each invocation of `flush()` the file pointer is moved. This means that rather than overwriting the binary file, we're appending to the file. With this commit, we're resetting said pointer to '0' and overwrite the existing binary in incremental mode.
2022-09-12wasm-linker: rename self to descriptive nameLuuk de Gram
2022-09-12wasm-linker: write to file at onceLuuk de Gram
Rather than writing to the file using a writer, we now first write to an arraylist and store the binary in memory. Once the full binary data was written, we write all data to disk at once. This reduces the amount of syscalls tremendously, increasing the performance of the linker in exchange for increased memory usage during flush.
2022-09-12wasm-linker: write magic bytes only on successLuuk de Gram
By writing them at the very end, we can easily detect where the writing of the binary went wrong as tools will indicate the missing of the magic bytes.
2022-09-09Merge remote-tracking branch 'origin/master' into llvm15Andrew Kelley
2022-09-09Merge pull request #12772 from ziglang/coff-basic-importsJakub Konka
coff: implement enough of the incremental linker to pass behavior and incremental tests on Windows
2022-09-08wasm: temporarily save curr file pointer before pwriting on WinJakub Konka
This is a temporary workaround to an unclear platform-dependence behavior we have in libstd for `std.fs.File` abstraction. See https://github.com/ziglang/zig/issues/12783 for more information.
2022-09-07macho+wasm: unify and clean up closing file handlesJakub Konka
2022-09-07wasm-linker: support incremental debug infoLuuk de Gram
Although the wasm-linker previously already supported debug information in incremental-mode, this was no longer working as-is with the addition of supporting object-file-parsed debug information. This commit implements the Zig-created debug information structure from scratch which is a lot more robust and also allows being linked with debug information from other object files.
2022-09-07wasm-linker: Mix Zig -and Object debug atomsLuuk de Gram
When linking a Zig-compilation with an object file, we allow mixing the debug atoms to make sure debug information is preserved from object files. By default, we now always initialize all debug sections if the `strip` flag is unset. This also fixes relocations for debug information as previously the offset of an atom wasn't calculated, and neither was the code size itself which meant that debug lines were off and file names from other object files were missing.
2022-09-07wasm-linker: use Atoms for zig debug infoLuuk de Gram
Previously we used single arraylists for each debug section for debug information that was generated from Zig code. (e.i. `Module` is available). This information is now stored in Atoms, similarly to debug information from object files. This will allow us to link them together and resolve debug relocations.
2022-09-07wasm-linker: perform debug relocationsLuuk de Gram
This correctly performs a relocation for debug sections. The result is that the wasm-linker can now correctly create a binary from object files while preserving all debug information.
2022-09-07wasm-linker: write debug sections from objectsLuuk de Gram
We now link relocatable debug sections with the correct section symbol and then allocate and resolve the debug atoms before writing them into the final binary. Although this does perform the relocation, the actual relocations are not done correctly yet.
2022-09-07wasm-linker: create atoms from debug sectionsLuuk de Gram
2022-09-07wasm/Object: parse debug sections into reloc dataLuuk de Gram
Rather than storing the name of a debug section into the structure `RelocatableData`, we use the `index` field as an offset into the debug names table. This means we do not have to store an extra 16 bytes for non-debug sections which can be massive for object files where each data symbol has its own data section. The name of a debug section can then be retrieved again when needed by using the offset and then reading until the 0-delimiter.
2022-09-06Merge remote-tracking branch 'origin/master' into llvm15Andrew Kelley
2022-08-30Merge remote-tracking branch 'origin/master' into llvm15Andrew Kelley
2022-08-30link/Wasm: handle extern variablesLuuk de Gram
Generate symbols for extern variables and try to resolve them. Unresolved 'data' symbols generate an error as they cannot be exported from the Wasm runtime into a Wasm module. This means, they can only be resolved by other object files such as from other Zig or C code compiled to Wasm.
2022-08-29wasm-lld: set stack size to 1MB by defaultLuuk de Gram
Regardless of the build mode (build-exe, build-lib), always set the default stack size to 1MB. Previously, this was only done when using build-exe, making the inconsistancy confusing. The user can still override this behavior by providing the `--stack <size>` flag.
2022-08-29Merge remote-tracking branch 'origin/master' into llvm15Andrew Kelley
2022-08-22stage2+stage1: remove type parameter from bit builtinsVeikka Tuominen
Closes #12529 Closes #12511 Closes #6835
2022-08-20wasm/Object: parse using the correct file sizeLuuk de Gram
When an object file is being parsed from within an archive file, we provide the object file size to ensure we do not read past the object file. This is because follow up object files can exist there, as well as an LF character to notate the end of the file was reached. Such a character is invalid within the object file. This also fixes a bug in getting the function/global type for defined globals/functions from object files as it was missing the substraction with the import count of the respective type.
2022-08-19make self-hosted the default compilerAndrew Kelley
stage1 is available behind the -fstage1 flag. closes #89
2022-08-18std.Target gains ObjectFormat fieldAndrew Kelley
2022-08-18link/Wasm: improve symbol resolutionLuuk de Gram
This adds additional checks during symbol resolution: - Ensures function signatures match when a symbol will be replaced. - Ensures global types match when the symbol is being replaced. - When both symbols are undefined, ensures they have a matching module name. Those changes ensure the result will pass the validator when the runtime compiles the Wasm module. Additionally, this also slightly changes the behavior when both the existing symbol and new symbol are both defined. Rather than always resulting in a collision, it only results in a collision when both are also weak. Else, the non-weak symbol will be picked.