913 Commits

Author SHA1 Message Date
Andrew Kelley
b6d6152e65 link: avoid creating stage2 llvm module when using stage1 2022-01-04 00:11:45 -07:00
Andrew Kelley
ff66a18555 linker: fix build-obj and -fno-emit-bin
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-03 20:03:22 -07:00
Andrew Kelley
d94303be2b stage2: introduce renameTmpIntoCache into the linker API
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-03 14:49:35 -07:00
Andrew Kelley
e3bed8d81d stage2: introduce CacheMode
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-02 13:16:17 -07:00
Luuk de Gram
b9a0401e23
wasm: Implement @ptrToInt and fix indirect function call
- 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-01 12:59:43 +01:00
Luuk de Gram
f644c8b047
wasm: Implement array_to_slice and bug fixes:
- 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.
2022-01-01 12:59:18 +01:00
Luuk de Gram
e061d75cdf wasm-linker: Implement symbol names emitting
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-23 01:47:45 +01:00
Andrew Kelley
06d751dbb3 link/wasm: fix regression of wrong assertion
Fixes typo introduced in 2cbeb85a96af25f2718a604aa2bec4f76dd85018.
2021-12-21 18:43:19 -07:00
Andrew Kelley
2cbeb85a96 stage2: error check for mixing --import-table and --export-table
is moved from the linker to the frontend. This is a follow-up from
4cb2f11693b1bf13770b8ad6a8b8a1e37101a516.
2021-12-21 18:21:42 -07:00
Andrew Kelley
8b6ea9ffe7 C backend: implement ret_addr 2021-12-21 14:32:02 -07:00
Luuk de Gram
4cb2f11693 wasm-linker: Implement the --export-table and --import-table flags.
This implements the flags for both the linker frontend as well as the self-hosted linker.

Closes #5790
2021-12-21 12:38:50 -08:00
Ersikan
e15a267668 elf: Put constant data in the .rodata section
Allocate a new program header and a new section to accomodate the read-only data
section ".rodata".

Separate TextBlock into multiple TextBlockList, to separate decl in different
sections.

If a Decl is not a function, it is added to the .rodata section.
2021-12-21 11:33:12 -08:00
Jakub Konka
a08137330c macho: handle -install_name option for dylibs/MachO
The status quo for the `build.zig` build system is preserved in
the sense that, if the user does not explicitly override
`dylib.setInstallName(...);` in their build script, the default
of `@rpath/libname.dylib` applies. However, should they want to
override the default behaviour, they can either:

1) unset it with

```dylib.setIntallName(null);```

2) set it to an explicit string with

```dylib.setInstallName("somename.dylib");```

When it comes to the command line however, the default is not to
use `@rpath` for the install name when creating a dylib. The user
will now be required to explicitly specify the `@rpath` as part
of the desired install name should they choose so like so:

1) with `build-lib`

```
zig build-lib -dynamic foo.zig -install_name @rpath/libfoo.dylib
```

2) with `cc`

```
zig cc -shared foo.c -o libfoo.dylib -Wl,"-install_name=@rpath/libfoo.dylib"
```
2021-12-18 17:55:53 -08:00
Jacob G-W
9a8fdbe0a0 plan9 linker: fix off by 1 error 2021-12-18 17:54:20 -08:00
Jakub Konka
510357355a stage2: fix premature atom deinit in macho linker 2021-12-15 17:28:48 +01:00
Jakub Konka
3ff05b79b9 macho: handle TLS imported from dylib
This is a missing feature which requires `__thread_ptrs` section
to be synthesised for any extern reference to a global TLS variable.
2021-12-15 08:59:20 +01:00
Jakub Konka
2e7a48d6bf macho: fix section size calculation when no prealloc
Add test for common symbol alignment.
2021-12-15 08:59:20 +01:00
Jakub Konka
ab328aca33 macho: put LC_* consts in a typed enum(u32) LC
repeat for `PLATFORM_*` and `TOOL_*` sets
2021-12-15 08:59:20 +01:00
Luuk de Gram
50201e1c30 wasm-linker: Allow specifying symbols to be exported
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-14 14:02:23 -08:00
Jakub Konka
4ce6208750 macho: if lib or framework not found, wait until syms resolved
This way, we will inform the user that there are unresolved symbols
in addition to missing library/framework as requested on the linker
line. If all symbols were resolved on the other hand, we still
flag up that the library/framework cannot be found.

Example behaviour:

```
$ zig cc hello.c -framework MyFoundation --verbose
warning(link): framework not found for '-framework MyFoundation'
warning(link): Framework search paths:
warning(link):   /Library/Frameworks
warning(link):   /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks
thread 1079397 panic: attempt to unwrap error: FrameworkNotFound
...stack trace...
```

and

```
❯ zig cc hello.c -lWAT --verbose
warning(link): library not found for '-lWAT'
warning(link): Library search paths:
warning(link):   /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
warning(link):   /usr/local/lib
thread 1079824 panic: attempt to unwrap error: LibraryNotFound
...stack trace...
```
2021-12-12 13:53:59 +01:00
Jakub Konka
1abae06432 Merge branch 'framework-not-found' of git://github.com/motiejus/zig into motiejus-framework-not-found 2021-12-12 13:31:26 +01:00
Jakub Konka
dbfcebf8d8 macho: allow undefined symbols in dylibs
We now respect both `-fallow-shlib-undefined` and
`-Wl,"-undefined=dynamic_lookup"` flags. This is the first step
towards solving issues #8180 and #3000. We currently do not expose
any other ld64 equivalent flag for `-undefined` flag - we basically
throw an error should the user specify a different flag. Support for
those is conditional on closing #8180. As a result of this change,
it is now possible to generate a valid native Node.js addon with Zig
for macOS.
2021-12-12 00:32:03 +01:00
Motiejus Jakštys
82a7069344 macho: fail if requested -framework is not found
If `-framework` is requested, but not found, the linker will err
instead of creating a strange executable.

https://github.com/ziglang/zig/issues/10299#issuecomment-990404953

Refs #9542
Refs #10299
Refs #10158
2021-12-11 10:40:57 +02:00
Jakub Konka
828f61e8df macho: move all helpers from commands.zig into std.macho
This way we will finally be able to share common parsing logic
between different Zig components and 3rd party packages.
2021-12-10 18:18:28 +01:00
Jakub Konka
81e7d8505c macho: move helper functions to libstd
Helper functions such as `commands.sectionName`, etc. should really
belong in `std.macho.section_64` extern struct.
2021-12-10 11:56:51 +01:00
Jakub Konka
64e2bfaa23 macho: write out LC_FUNCTION_START data 2021-12-08 23:24:40 +01:00
Jakub Konka
98e36ea6b9 macho: handle non-extern UNSIGNED relocs on arm64 2021-12-08 20:48:12 +01:00
Jakub Konka
f0ec70edd1 macho: do not write null symbols into undef symbols section
Also, skip creating stub entries for resolved globally defined
regular symbols.
2021-12-08 16:58:29 +01:00
Andrew Kelley
83a6681955 link: fix build for 32-bit targets
This wasn't caught by the CI checks because this function is is only
called for the `use_stage1` codepath.
2021-12-07 17:03:29 -07:00
Jakub Konka
71d19318e7 macho: do not preserve temp symbol names
and do not write out local symbol in MachO's symbol table if global
symbol exists with the same name.
2021-12-06 00:09:51 +01:00
Jakub Konka
3ac973c706 macho: fix incremental codepath for linking objects 2021-12-06 00:00:50 +01:00
Jakub Konka
124e942714 macho: refactor logging and function names 2021-12-05 23:26:30 +01:00
Jakub Konka
397a11c107 macho: sort sections when linking stage1 binary 2021-12-05 22:46:53 +01:00
Jakub Konka
c86f2402d0 macho: don't prealloc sections when stage1 2021-12-05 22:46:46 +01:00
Luuk de Gram
9e03cf9489 wasm: Initial behavior tests succeeding
- 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-05 12:19:01 -08:00
Andrew Kelley
f7cbd92e6c Revert "Merge pull request #10270 from Luukdegram/behaviour-tests"
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-04 21:55:50 -07:00
Luuk de Gram
96a4692f94
wasm: Correctly load slice value on stack 2021-12-04 19:22:08 +01:00
Luuk de Gram
1777fb25bc
wasm: Implement WrapErrorUnionErr(payload) 2021-12-04 19:22:07 +01:00
Lee Cannon
066eaa5e9c
allocgate: change resize to return optional instead of error 2021-11-30 23:45:01 +00:00
Lee Cannon
1093b09a98
allocgate: renamed getAllocator function to allocator 2021-11-30 23:32:47 +00:00
Lee Cannon
75548b50ff
allocgate: stage 1 and 2 building 2021-11-30 23:32:47 +00:00
Lee Cannon
85de022c56
allocgate: std Allocator interface refactor 2021-11-30 23:32:47 +00:00
Jakub Konka
86fe47235e macho: move nlist_64 type/flags helpers to std.macho 2021-11-30 13:59:33 +01:00
Jakub Konka
2873e19366 macho: ignore undefined symbols marked for discarding
If a symbol is undefined after we tried resolving it in static and
dynamic libraries, and it is annotated with N_DESC_DISCARDED flag,
we simply ignore it rather than flagging an undefined symbol error.
2021-11-30 10:22:26 +01:00
Andrew Kelley
902df103c6 std lib API deprecations for the upcoming 0.9.0 release
See #3811
2021-11-30 00:13:07 -07:00
Jakub Konka
da0ea909bc macho: POINTER_TO_GOT signals a need for a GOT entry
It also signals the need for GOT indirection (unless it can
be optimised away via link-time constant optimisation).
2021-11-29 11:51:27 -08:00
Jakub Konka
7a7df392d1
Merge pull request #10240 from Luukdegram/stage2-wasm-behaviour
Stage2: wasm - Implement 'zig test'
2021-11-29 10:52:04 +01:00
Jakub Konka
58a552aaf9 macho: save all undef symbols even if null 2021-11-28 20:48:54 +01:00
Jakub Konka
7e27ab0947 macho: fix parsing addend for non-extern SIGNED_X reloc
If `r_extern == 0` (the relocation is non-extern, meaning it targets
a specific memory offset within the object's section) and if the
relocation type signifies that the relocation requires correction
for RIP such as SIGNED_1, then we need to subtract the correction,
here 1 for SIGNED_1, from the calculated addend value as it's
implicitly included.
2021-11-28 20:35:00 +01:00
Luuk de Gram
dd49eca342
wasm: Implement 'zig test'
- This implements the required codegen for decl types such as pointers, arrays, structs and more.
- Wasm's start function can now use both a 'u8' and 'void' as return type. This will help us with writing tests
using the stage2 testing backend. (Until all tests of behavioural tests pass).
- Now correctly generates relocations for function pointers.
- Also implements unwrapping error union error, as well as return pointers.
2021-11-28 20:25:33 +01:00