Commit Graph
387 Commits
Author SHA1 Message Date
Matthew Lugg 31500242f0 link: rework export API
The old API fundamentally did not make sense, because the frontend does
not track exports incrementally: it only knows the set of referenced
exports at the end of each incremental update. Attempting to represent
this as an incremental add/remove-style API was just a lie. It was also
buggy; `deleteExport` was called from the main thread, leading to races
in incremental compilation if `deleteExport` was actually implemented!

We also exposed data in an unnecessarily complicated way which did not
benefit most linkers. The only one which actually cared about knowing
all exports for a given nav/uav upfront was the C linker (which here I
have written to reconstruct that data), and even it can probably be
refactored at some point to avoid that.

So, replace the export API with a simpler one, where all the frontend
does is tell the linker about every `Zcu.Export.Index` which is alive,
just before calling `flush`. In theory this information could actually
be passed into `flush`, but using a separate function made for a simpler
implementation in practice.

Resolves: https://github.com/ziglang/zig/issues/23616
2026-08-16 10:29:59 +02:00
kcbanner d94b3e7691 Coff: fix incorrect section offset calculations when writing section relocation tables 2026-06-23 22:05:25 -04:00
kcbanner e2c587ae54 objdump: when redacting ordinals, show weak external alias as relative to the WEAK_EXTERNAL symbol
objdump: dump the filename for file aux symbols
test/link: remove the text attribute on the snapshots folder to avoid changing snapshot line endings
2026-06-23 00:27:17 -04:00
kcbanner c0b07b144b test/link: fixup tls snapshots 2026-06-23 00:27:17 -04:00
kcbanner 0bacbd4daa test/link: add tls test 2026-06-23 00:27:17 -04:00
kcbanner ae41a2b8ac Coff: fix .ctor / .dtor generation, the length fields need to be their own nodes, otherwise child nodes will overwrite them
test/link: add .ctor / .dtor tests for mingw
test/link: include optimize_mode in the target, and only enable .Debug targets for now
2026-06-23 00:27:17 -04:00
kcbanner 537d7b7427 Coff: rework symbol table generation
Instead of popping from the end of a map of pending symbols, use the map as the storage and flush symbols in order. This simplifies the weak external flow, and keeps the symbol table in a more intuitive order. Also, .sti is no longer in Value, which means that it won't collide with .node_offset if an imported symbol is later exported.
2026-06-23 00:27:17 -04:00
kcbanner bd50917c0d Coff: emit weak externals 2026-06-23 00:27:17 -04:00
kcbanner 1b95427715 Coff: add support for .is_dll_import
x86_64: emit the correct encodings for loading / calling .is_dll_import externs
Coff: fix emitting an empty import directory
objdump: add --exports=sort for sorting implibs in snapshots (self-hosted outputs members in a different order than llvm)
objdump: fix some missed redactions / filters / elements calls
test: add dllimport standalone test
2026-06-23 00:27:17 -04:00
kcbanner 72bc140ad1 test/link: separate out shared lib tests
- Fixup snapshot naming
- Fixup verifyObjdumps so we can dump other artifacts
- Add llvm link_targets for comparison
2026-06-23 00:27:17 -04:00
kcbanner 344d0ab72c Coff: handle relocations of absolute symbols
test/link: add absolute symbol tests
2026-06-23 00:27:16 -04:00
kcbanner c14bc1bbe0 Coff: fixup alignment of second linker member accessors
test/link: update emit-static-lib test to check array relocs
2026-06-23 00:27:16 -04:00
kcbanner e20860765e test/link: rework test case names to show the target
Prior to this, it was hard to track down commands to reproduce failing tests in --verbose output
2026-06-23 00:27:16 -04:00
kcbanner de297890e3 test/link: add emit-static-lib 2026-06-23 00:27:16 -04:00
kcbanner 1c6d19b0ff tests: more work on the linker snapshot testing framework
build: add the ability to test the output of a Run step against a snapshot
objdump:  add --redact, --omit-element, --snapshot, and --only-symbol
2026-06-23 00:27:14 -04:00
Andrew Kelley e7d74e49b0 declare linker test bankruptcy
The active contributors and maintainers of Zig's linker code have
generally found the current linker test harness to be cumbersome. The
tests require a lot of maintenance, but do not provide a lot of
coverage, and when they fail it is painful to troubleshoot.

Furthermore, as part of working on #31691, I don't want to port over the
CheckObject step, because I don't like the code anyway.

The plan forward is to start enhancing `zig objdump` to assist in
linker development, as well as using it as the basis for snapshot
testing.

We absolutely need linker test coverage, but we need to try to improve
these things about the next attempt:
* less effort to create and maintain tests
* less CPU overhead - we should be able to add a lot of tests without
  adding a lot of CI time.
* more helpful failures. A failed linker test should provide the next
  steps a developer can take to understand why the test failed.
* a goal of porting over all of LLD's test suite, or at least the good
  ones.

I'm not going to open an issue to track the lost linker test coverage,
because there was already so much lack of coverage for linker stuff.

However I will open issues to track this lost coverage:
* the deleted checks from test/standalone/glibc_compat/build.zig
* the deleted checks from test/standalone/compiler_rt_panic/build.zig
* the deleted checks from test/standalone/ios/build.zig
2026-04-26 00:15:07 +02:00
squidy239 4c3877069d remove various workarounds for issues that are now fixed (#31567)
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31567
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: squidy239 <sachabarsayuracko@gmail.com>
Co-committed-by: squidy239 <sachabarsayuracko@gmail.com>
2026-03-20 19:58:33 +01:00
Mathias Lafeldt 2207c62bb5 MachO: fix dynamic lookup of undefined symbols at runtime
Ensures `MH_NOUNDEFS` is not set when dynamic lookup is enabled for
undefined symbols via `linker_allow_shlib_undefined`.
2026-01-21 00:31:21 +01:00
Vladislav Shabanov 63f345a75a link.MachO: support sdata4 pointer encoding (#30846)
Fixes https://codeberg.org/ziglang/zig/issues/30669

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30846
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: Vladislav Shabanov <vshabanov88@gmail.com>
Co-committed-by: Vladislav Shabanov <vshabanov88@gmail.com>
2026-01-15 19:48:16 +01:00
Andrew Kelley 6ece10f63d update test-link to new std.Io API 2025-12-23 22:15:12 -08:00
Andrew Kelley bee8005fe6 std.heap.DebugAllocator: never detect TTY config
instead, allow the user to set it as a field.

this fixes a bug where leak printing and error printing would run tty
config detection for stderr, and then emit a log, which is not necessary
going to print to stderr.

however, the nice defaults are gone; the user must explicitly assign the
tty_config field during initialization or else the logging will not have
color.

related: https://github.com/ziglang/zig/issues/24510
2025-12-23 22:15:08 -08:00
Andrew Kelley a91c6dc71d test: std.fs.File -> std.Io.File 2025-12-23 22:15:08 -08:00
Alex Rønne Petersen a8e77b7a05 test: disable test-link on big-endian hosts
https://github.com/ziglang/zig/issues/25961
2025-11-19 01:42:45 +01:00
skewb1k 26db54d69b zig fmt: fix extra whitespace in StructInit with multiline strings
68d2f68ed introduced special handling for StructInit fields
containing multiline strings to prevent inserting whitespace after =.
However, this logic didn't handle cases without a trailing comma,
which resulted in unwanted trailing whitespace.
2025-11-05 14:07:30 +02:00
Alex Rønne Petersen 66193e72d3 test: disable test-link macho on FreeBSD
See also d6d1fef.

https://github.com/ziglang/zig/issues/25323
2025-10-11 00:40:42 +02:00
alexrp b2d2b441b2 test: disable test-link on FreeBSD
https://github.com/ziglang/zig/issues/25323
2025-09-22 01:37:32 +02:00
Jacob Young 09bc118c9f Elf: implement linksection
Closes #24330
2025-09-17 21:16:23 -07:00
Alex Rønne Petersen a5bb7108a9 test: move glibc_compat from link to standalone tests
This is not really testing the linker.
2025-09-16 23:39:29 +02:00
Alex Rønne Petersen ab1946de92 test: remove @cImport usage in interdependent_static_c_libs 2025-09-16 23:39:29 +02:00
Carl Åstholm 154bd2fd05 Migrate from deprecated Step.Compile APIs 2025-07-26 12:06:43 +02:00
Carl Åstholm b92b55ab8e Update test build.zig.zon files to conform to the new manifest rules 2025-07-20 18:28:36 +02:00
Andrew Kelley d8e26275f2 update standalone and incremental tests to new API 2025-07-07 22:43:53 -07:00
Andrew Kelley 0e37ff0d59 std.fmt: breaking API changes
added adapter to AnyWriter and GenericWriter to help bridge the gap
between old and new API

make std.testing.expectFmt work at compile-time

std.fmt no longer has a dependency on std.unicode. Formatted printing
was never properly unicode-aware. Now it no longer pretends to be.

Breakage/deprecations:
* std.fs.File.reader -> std.fs.File.deprecatedReader
* std.fs.File.writer -> std.fs.File.deprecatedWriter
* std.io.GenericReader -> std.io.Reader
* std.io.GenericWriter -> std.io.Writer
* std.io.AnyReader -> std.io.Reader
* std.io.AnyWriter -> std.io.Writer
* std.fmt.format -> std.fmt.deprecatedFormat
* std.fmt.fmtSliceEscapeLower -> std.ascii.hexEscape
* std.fmt.fmtSliceEscapeUpper -> std.ascii.hexEscape
* std.fmt.fmtSliceHexLower -> {x}
* std.fmt.fmtSliceHexUpper -> {X}
* std.fmt.fmtIntSizeDec -> {B}
* std.fmt.fmtIntSizeBin -> {Bi}
* std.fmt.fmtDuration -> {D}
* std.fmt.fmtDurationSigned -> {D}
* {} -> {f} when there is a format method
* format method signature
  - anytype -> *std.io.Writer
  - inferred error set -> error{WriteFailed}
  - options -> (deleted)
* std.fmt.Formatted
  - now takes context type explicitly
  - no fmt string
2025-07-07 22:43:51 -07:00
Alex Rønne Petersen 80c3de40b3 test: Properly limit glibc_compat versions based on the host 2025-07-01 23:03:15 +02:00
Jacob Young 917640810e Target: pass and use locals by pointer instead of by value
This struct is larger than 256 bytes and code that copies it
consistently shows up in profiles of the compiler.
2025-06-19 11:45:06 -04:00
Jacob Young df4068cabd Build: change how the target is printed in step names
e.g. `x86_64-windows.win10...win11_dt-gnu` -> `x86_64-windows-gnu`

When the OS version is the default this is redundant with checking the
default in the standard library.
2025-06-19 11:45:06 -04:00
mlugg a3abaaee0c test-link: correct expected object file name
The name of the ZCU object file emitted by the LLVM backend has been
changed in this branch from e.g. `foo.o` to `foo_zcu.o`. This is to
avoid name clashes. This commit just updates a link test which started
failing because the object name in a linker error changed.
2025-06-12 17:51:29 +01:00
mlugg 437059f37c tests: avoid loading 16 MiB onto the stack
Currently, Zig semantically loads an array as a temporary when indexing
it. This means it cannot be guaranteed that only the requested element
is loaded; in particular, our self-hosted backends do not elide the load
of the full array, so this test case was crashing on self-hosted.
2025-06-06 23:42:15 -07:00
Alex Rønne Petersen b3537d0f4a compiler: Allow configuring UBSan mode at the module level.
* Accept -fsanitize-c=trap|full in addition to the existing form.
* Accept -f(no-)sanitize-trap=undefined in zig cc.
* Change type of std.Build.Module.sanitize_c to std.zig.SanitizeC.
* Add some missing Compilation.Config fields to the cache.

Closes #23216.
2025-04-26 22:54:34 +02:00
Alex Rønne Petersen 5c57e90ffb test: Disable test-elf-ld-script-path-error for now.
https://github.com/ziglang/zig/issues/23125
2025-03-08 07:04:27 +01:00
Linus Groh 79460d4a3e Remove uses of deprecated callconv aliases 2025-03-05 03:01:43 +00:00
David Rubin ca83f52fd9 ubsan: update wording 2025-02-25 11:22:33 -08:00
David Rubin 44d3b5a6e4 build: add comments explaining why we disable ubsan 2025-02-25 11:22:33 -08:00
David Rubin 35b9db3b15 correct some bugs 2025-02-25 11:22:33 -08:00
Andrew Kelley eb3c7f5706 zig build fmt 2025-02-22 17:09:20 -08:00
Andrew Kelley 61b69a418d Merge pull request #22659 from ifreund/linker-script-fix
link: fix ambiguous names in linker scripts
2025-02-22 18:18:24 -05:00
Alex Rønne Petersen f87b443af1 link.MachO: Add support for the -x flag (discard local symbols).
This can also be extended to ELF later as it means roughly the same thing there.

This addresses the main issue in #21721 but as I don't have a macOS machine to
do further testing on, I can't confirm whether zig cc is able to pass the entire
cgo test suite after this commit. It can, however, cross-compile a basic program
that uses cgo to x86_64-macos-none which previously failed due to lack of -x
support. Unlike previously, the resulting symbol table does not contain local
symbols (such as C static functions).

I believe this satisfies the related donor bounty: https://ziglang.org/news/second-donor-bounty
2025-02-22 06:35:19 +01:00
Isaac Freund 819716b59f link: fix ambiguous names in linker scripts
Currently zig fails to build while linking the system LLVM/C++ libraries
on my Chimera Linux system due to the fact that libc++.so is a linker
script with the following contents:

INPUT(libc++.so.1 -lc++abi -lunwind)

Prior to this commit, zig would try to convert "ambiguous names" in
linker scripts such as libc++.so.1 in this example into -lfoo style
flags. This fails in this case due to the so version number as zig
checks for exactly the .so suffix.

Furthermore, I do not think that this conversion is semantically correct
since converting libfoo.so to -lfoo could theoretically end up resulting
in libfoo.a getting linked which seems wrong when a different file is
specified in the linker script.

With this patch, this attempted conversion is removed. Instead, zig
always first checks if the exact file/path in the linker script exists
relative to the current working directory.

If the file is classified as a library (including versioned shared
objects such as libfoo.so.1), zig then falls back to checking if
the exact file/path in the linker script exists relative to each
directory in the library search path, selecting the first match or
erroring out if none is found.

This behavior fixes the regression that prevents building zig while
linking the system LLVM/C++ libraries on Chimera Linux.
2025-02-10 23:19:48 +01:00
BratishkaErik 941677e083 std.Build: add addLibrary function (#22554)
Acts as a replacement for `addSharedLibrary` and `addStaticLibrary`, but
linking mode can be changed more easily in build.zig, for example:

In library:
```zig
const linkage = b.option(std.builtin.LinkMode, "linkage", "Link mode for a foo_bar library") orelse .static; // or other default

const lib = b.addLibrary(.{
    .linkage = linkage,
    .name = "foo_bar",
    .root_module = mod,
});
```

In consumer:
```zig
const dep_foo_bar = b.dependency("foo_bar", .{
    .target = target,
    .optimize = optimize,
    .linkage = .static // or dynamic
});

mod.linkLibrary(dep_foor_bar.artifact("foo_bar"));
```

It also matches nicely with `linkLibrary` name.

Signed-off-by: Eric Joldasov <bratishkaerik@landless-city.net>
2025-01-22 02:29:21 +00:00
Andrew Kelley f5485a52bc reject crti.o/crtn.o, embrace the future
crti.o/crtn.o is a legacy strategy for calling constructor functions
upon object loading that has been superseded by the
init_array/fini_array mechanism.

Zig code depends on neither, since the language intentionally has no way
to initialize data at runtime, but alas the Zig linker still must
support this feature since popular languages depend on it.

Anyway, the way it works is that crti.o has the machine code prelude of
two functions called _init and _fini, each in their own section with the
respective name. crtn.o has the machine code instructions comprising the
exitlude for each function. In between, objects use the .init and .fini
link section to populate the function body.

This function is then expected to be called upon object initialization
and deinitialization.

This mechanism is depended on by libc, for example musl and glibc, but
only for older ISAs. By the time the libcs gained support for newer
ISAs, they had moved on to the init_array/fini_array mechanism instead.

For the Zig linker, we are trying to move the linker towards
order-independent objects which is incompatible with the legacy
crti/crtn mechanism.

Therefore, this commit drops support entirely for crti/crtn mechanism,
which is necessary since the other commits in this branch make it
nondeterministic in which order the libc objects and the other link
inputs are sent to the linker.

The linker is still expected to produce a deterministic output, however,
by ignoring object input order for the purposes of symbol resolution.
2025-01-20 20:59:52 -08:00