935 Commits

Author SHA1 Message Date
Jakub Konka
5eaac2fb99 macho: do not write out ZEROFILL physically to file
Prior to this change, `__DATA,__bss` and `__DATA,__thread_bss` would
get actually, physically written out to the output file, unnecessarily
filling the output file with 0s.
2022-01-20 02:21:58 -05:00
Andrew Kelley
fd6d1fe015 stage2: improvements to entry point handling
* rename `entry` to `entry_symbol_name` for the zig build API
 * integrate with `zig cc` command line options
 * integrate with COFF linking with LLD
 * integrate with self-hosted ELF linker
 * don't put it in the hash for MachO since it is ignored
2022-01-19 11:41:08 -07:00
Kenta Iwasaki
5ae3e4e9bd lld: allow for entrypoint symbol name to be set
This commit enables for the entrypoint symbol to be set when linking ELF
or WebAssembly modules with lld using the Zig compiler.
2022-01-19 11:22:10 -07:00
Andrew Kelley
30efcf22d7 stage2: implement @prefetch
This reverts commit f423b5949b8722d4b290f57c3d06d015e39217b0,
re-instating commit d48e4245b68bf25c7f41804a5012ac157a5ee546.
2022-01-18 11:59:09 -07:00
Andrew Kelley
f423b5949b Revert "stage2: implement @prefetch"
This reverts commit d48e4245b68bf25c7f41804a5012ac157a5ee546.

I have no idea why this is failing Drone CI, but in a branch, reverting
this commit solved the problem.
2022-01-18 10:47:02 -07:00
Andrew Kelley
d48e4245b6 stage2: implement @prefetch 2022-01-15 15:18:25 -07:00
Jakub Konka
b3471ef300 macho: code signature needs to be 16 bytes aligned 2022-01-14 22:32:33 +01:00
Andrew Kelley
75b6637d60
Merge pull request #10584 from ziglang/macho-rustc-fixes
zld: a couple of fixes which result in better rustc support
2022-01-13 22:09:42 -05:00
Jakub Konka
e945619728 macho: remove todo from getMatchingSectionDecl 2022-01-13 21:15:17 +01:00
Jakub Konka
5cde5f947f Introduce LinkObject with must_link field 2022-01-13 20:02:11 +01:00
Jakub Konka
a8564df9ed zld: parse addend from BRANCH reloc on x86_64
As usual, MachO, full of surprises!
2022-01-13 20:02:11 +01:00
Jakub Konka
16c55b15cb zld: support -Wl,-force_load=archive_path flag
This actually enables using `zig cc` as a linker for `cargo test`
with `serde_derive`.
2022-01-13 20:02:11 +01:00
Jakub Konka
f9f792ab70 zld: fix num nlist calc when there's no dynsymtab
Handle `__DATA,.rustc` section containing `rustc` metadata - this
is required to get crates like `serde_derive` link properly.
Note to self: this special section has to be copied __verbatim__
from the relocatable object file - this includes preserving its size
even though unpadded according the section's required alignment.
2022-01-13 20:02:11 +01:00
Luuk de Gram
975049e96e
wasm-ld: Append --stack-first by default
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-11 20:35:44 +01:00
Luuk de Gram
f767f8e3dc
wasm: Place the stack at the start of memory 2022-01-11 20:21:22 +01:00
Jakub Konka
a615425b51 Merge branch 'linker-eport-symbols' of github.com:Luukdegram/zig into Luukdegram-linker-eport-symbols 2022-01-11 11:30:53 +01:00
Jakub Konka
a4e6291fbd
stage2: enable zig test on x86_64-macos (#10551)
* stage2: put decls in different MachO sections

Use `getDeclVAddrWithReloc` when targeting MachO backend rather than
`getDeclVAddr` - this fn returns a zero vaddr and instead creates a
relocation on the linker side which will get automatically updated
whenever the target decl is moved in memory. This fn also records
a rebase of the target pointer so that its value is correctly slid
in presence of ASLR.

This commit enables `zig test` on x86_64-macos.

* stage2: fix output section selection for type,val pairs
2022-01-10 16:02:07 +01:00
Luuk de Gram
247b638ccf
Pass --allow-unknown-exports to wasmtime
Also skip exporting non-function symbols when we're building a WASI command using the stage2 llvm backend.
2022-01-07 18:35:08 +01:00
Jacob G-W
398c0b10e4 Plan9: fix amount to say included line count is
Not sure why this was working before...
2022-01-06 22:58:53 -05:00
Jacob G-W
ab400ad624 Plan9: implement getDeclVAddr 2022-01-06 22:47:27 -05:00
Luuk de Gram
6d951aff7e
wasm-linker: Only export symbols notated as such
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-06 20:19:47 +01:00
Jacob G-W
b47530b9fe plan9: fix .z symbol in debuginfo
This allows the `acid` debugger on
plan9 to be used to debug a zig source
file without patching `acid`!

The patch adds a second `z` symbol. This z
symbol has a value of 0, which means that it
pops the history stack. We put a very large
number for the value of the second symbol because
it has to be at least as large as the linecount of
the file. The debuginfo format is meant to be used
with c files, where the stack would look something
like this:
```
->  Line: 0x1 (1)  Name: 0x1/0x2/0x3/0xe/0x13/0x1b (/sys/src/libc/port/malloc.c)
->  Line: 0x2 (2)  Name: 0x1/0x6/0x7/0x8 (/amd64/include/u.h)
->  Line: 0x4f (79)  Name:  ()
->  Line: 0x50 (80)  Name: 0x1/0x2/0x7/0x9 (/sys/include/libc.h)
->  Line: 0x358 (856)  Name:  ()
->  Line: 0x359 (857)  Name: 0x1/0x2/0x7/0x1c (/sys/include/pool.h)
->  Line: 0x392 (914)  Name:  ()
->  Line: 0x393 (915)  Name: 0x1/0x2/0x7/0x1d (/sys/include/tos.h)
->  Line: 0x3ab (939)  Name:  ()
->  Line: 0x4eb (1259)  Name:  ()
```
however in zig, we do not use includes and .h files,
so we only need the first and last items in the stack:
the source file that the symbols belong to, and the pop
symbol with a null name and a value of the total linecount of the
preprocessed source. Since there is no preprocessing in zig, we
just make the linecount very large. There do not appear to be
any downsides to this approach. If this causes a bug in the future,
a simple fix would be to make the pop symbol just have the value
of how many newlines are in the source file.
2022-01-06 13:17:00 +01:00
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