aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf/relocatable.zig
AgeCommit message (Collapse)Author
2025-09-08fix linker code writing undefined memory to the output fileAndrew Kelley
missing `extern` on a struct. but also all these instances that call pwriteAll with a `@ptrCast` are endianness bugs. this should be changed to use File.Writer and call writeSliceEndian instead. this commit fixes one immediate problem but does not fix everything.
2025-08-28link.Elf: update to not use GenericWriterAndrew Kelley
2025-08-11std.ArrayList: make unmanaged the defaultAndrew Kelley
2025-07-07compiler: update a bunch of format stringsAndrew Kelley
2025-06-06Elf: support non-comdat groupsJacob Young
I haven't actually found any documentation about these, but apparently groups aren't always comdats.
2025-02-22zig build fmtAndrew Kelley
2025-01-15macho linker conforms to explicit error sets, againAndrew Kelley
2025-01-15wasm linker: aggressive DODificationAndrew Kelley
The goals of this branch are to: * compile faster when using the wasm linker and backend * enable saving compiler state by directly copying in-memory linker state to disk. * more efficient compiler memory utilization * introduce integer type safety to wasm linker code * generate better WebAssembly code * fully participate in incremental compilation * do as much work as possible outside of flush(), while continuing to do linker garbage collection. * avoid unnecessary heap allocations * avoid unnecessary indirect function calls In order to accomplish this goals, this removes the ZigObject abstraction, as well as Symbol and Atom. These abstractions resulted in overly generic code, doing unnecessary work, and needless complications that simply go away by creating a better in-memory data model and emitting more things lazily. For example, this makes wasm codegen emit MIR which is then lowered to wasm code during linking, with optimal function indexes etc, or relocations are emitted if outputting an object. Previously, this would always emit relocations, which are fully unnecessary when emitting an executable, and required all function calls to use the maximum size LEB encoding. This branch introduces the concept of the "prelink" phase which occurs after all object files have been parsed, but before any Zcu updates are sent to the linker. This allows the linker to fully parse all objects into a compact memory model, which is guaranteed to be complete when Zcu code is generated. This commit is not a complete implementation of all these goals; it is not even passing semantic analysis.
2024-10-29link/Elf: ensure we always sort all relocations by r_offset in -r modeJakub Konka
According to a comment in mold, this is the expected (and desired) condition by the linkers, except for some architectures (RISCV and Loongarch) where this condition does not have to upheld. If you follow the changes in this patch and in particular doc comments I have linked the comment/code in mold that explains and implements this. I have also modified `testEhFrameRelocatable` test to now test both cases such that `zig ld -r a.o b.o -o c.o` and `zig ld -r b.o a.o -o d.o`. In both cases, `c.o` and `d.o` should produce valid object files which was not the case before this patch.
2024-10-23use unstable sort in relocatable writeSyntheticSectionsAndrew Kelley
unstable sort is always better if you have no ties
2024-10-23unify parsing codepaths between relocatable and nonAndrew Kelley
2024-10-23move linker input file parsing to the compilation pipelineAndrew Kelley
2024-10-23link.Elf: untangle parseObject and parseArchiveAndrew Kelley
from link.Elf, so that they can be used earlier in the pipeline
2024-10-23rework linker inputsAndrew Kelley
* Compilation.objects changes to Compilation.link_inputs which stores objects, archives, windows resources, shared objects, and strings intended to be put directly into the dynamic section. Order is now preserved between all of these kinds of linker inputs. If it is determined the order does not matter for a particular kind of linker input, that item should be moved to a different array. * rename system_libs to windows_libs * untangle library lookup from CLI types * when doing library lookup, instead of using access syscalls, go ahead and open the files and keep the handles around for passing to the cache system and the linker. * during library lookup and cache file hashing, use positioned reads to avoid affecting the file seek position. * library directories are opened in the CLI and converted to Directory objects, warnings emitted for those that cannot be opened.
2024-10-12link.Elf: eliminate an O(N^2) algorithm in flush()Andrew Kelley
Make shared_objects a StringArrayHashMap so that deduping does not need to happen in flush. That deduping code also was using an O(N^2) algorithm, which is not allowed in this codebase. There is another violation of this rule in resolveSymbols but this commit does not address it. This required reworking shared object parsing, breaking it into independent components so that we could access soname earlier. Shared object parsing had a few problems that I noticed and fixed in this commit: * Many instances of incorrect use of align(1). * `shnum * @sizeOf(elf.Elf64_Shdr)` can overflow based on user data. * `@divExact` can cause illegal behavior based on user data. * Strange versyms logic that wasn't present in mold nor lld. The logic was not commented and there is no git blame information in ziglang/zig nor kubkon/zld. I changed it to match mold and lld instead. * Use of ArrayList for slices of memory that are never resized. * finding DT_VERDEFNUM in a different loop than finding DT_SONAME. Ultimately I think we should follow mold's lead and ignore this integer, relying on null termination instead. * Doing logic based on VER_FLG_BASE rather than ignoring it like mold and LLD do. No comment explaining why the behavior is different. * Mutating the original ELF symbols rather than only storing the mangled name on the new Symbol struct. I noticed something that I didn't try to address in this commit: Symbol stores a lot of redundant information that is already present in the ELF symbols. I suspect that the codebase could benefit from reworking Symbol to not store redundant information. Additionally: * Add some type safety to std.elf. * Eliminate 1-3 file system reads for determining the kind of input files, by taking advantage of file name extension and handling error codes properly. * Move more error handling methods to link.Diags and make them infallible and thread-safe * Make the data dependencies obvious in the parameters of parseSharedObject. It's now clear that the first two steps (Header and Parsed) can be done during the main Compilation pipeline, rather than waiting for flush().
2024-10-11link: consolidate diagnosticsAndrew Kelley
By organizing linker diagnostics into this struct, it becomes possible to share more code between linker backends, and more importantly it becomes possible to pass only the Diag struct to some functions, rather than passing the entire linker state object in. This makes data dependencies more obvious, making it easier to rearrange code and to multithread. Also fix MachO code abusing an atomic variable. Not only was it using the wrong atomic operation, it is unnecessary additional state since the state is already being protected by a mutex.
2024-10-11link.Elf.sortShdrs: tease out data dependenciesAndrew Kelley
In order to reduce the logic that happens in flush() we need to see which data is being accessed by all this logic, so we can see which operations depend on each other.
2024-10-11link.Elf: group section indexesAndrew Kelley
so they cannot be forgotten when updating them after sorting them.
2024-10-10link: fix false positive crtbegin/crtend detectionAndrew Kelley
Embrace the Path abstraction, doing more operations based on directory handles rather than absolute file paths. Most of the diff noise here comes from this one. Fix sorting of crtbegin/crtend atoms. Previously it would look at all path components for those strings. Make the C runtime path detection partially a pure function, and move some logic to glibc.zig where it belongs.
2024-10-09elf: clean up how we create un-allocated sectionsJakub Konka
2024-10-09elf: change how we manage debug atoms in Dwarf linkerJakub Konka
2024-10-09elf: do not re-allocate AtomLists unless dirtiedJakub Konka
2024-10-09elf: track atoms within AtomList with array hash mapJakub Konka
2024-10-08link.Elf: avoid needless file system reads in flush()Andrew Kelley
flush() must not do anything more than necessary. Determining the type of input files must be done only once, before flush. Fortunately, we don't even need any file system accesses to do this since that information is statically known in most cases, and in the rest of the cases can be determined by file extension alone. This commit also updates the nearby code to conform to the convention for error handling where there is exactly one error code to represent the fact that error messages have already been emitted. This had the side effect of improving the error message for a linker script parse error. "positionals" is not a linker concept; it is a command line interface concept. Zig's linker implementation should not mention "positionals". This commit deletes that array list in favor of directly making function calls, eliminating that heap allocation during flush().
2024-09-04elf: rename SectionChunk into AtomList and store as part of SectionJakub Konka
2024-09-04elf: fix emitting static lib when ZigObject is presentJakub Konka
2024-09-04elf: misc .eh_frame management fixesJakub Konka
2024-09-04elf: copy existing data when allocating other alloc sections in relocatable modeJakub Konka
2024-09-04elf: do not create .eh_frame section if ZigObject already did so in ↵Jakub Konka
relocatable mode
2024-09-04elf: init rela sections in a separate pass for ZigObjectJakub Konka
2024-09-04elf: emit relocs for self-hosted generated .eh_frame sectionJakub Konka
2024-09-04elf: fix relocatable modeJakub Konka
2024-09-04elf: allocate atom chunks using allocateChunk mechanics in objectsJakub Konka
2024-09-04elf: remove isDebugSection helperJakub Konka
2024-08-27Dwarf: implement .eh_frameJacob Young
2024-08-26Merge pull request #21212 from ziglang/elf-incrAndrew Kelley
elf: cleanups, cleanups, cleanups
2024-08-25elf: store atom refs for rela sections until we can do betterJakub Konka
2024-08-25elf: simplify output section symbol trackingJakub Konka
2024-08-25elf: streamline sections containerJakub Konka
2024-08-23link: Rename InvalidCpuArch error to InvalidMachineType.Alex Rønne Petersen
2024-08-21elf: refactor tracking debug section sizesJakub Konka
2024-08-21elf: allow for concatenating atoms to merge sectionsJakub Konka
2024-08-16Dwarf: rework self-hosted debug info from scratchJacob Young
This is in preparation for incremental and actually being able to debug executables built by the x86_64 backend.
2024-08-07elf: fix compile errorsJakub Konka
2024-07-30elf: do not store merge section output section name in strings bufferJakub Konka
2024-07-30elf: simplify output section tracking for symbolsJakub Konka
2024-07-30elf: remove obsolete flags from atomJakub Konka
2024-07-30elf: resolve COMDATs in more parallel-friendly wayJakub Konka
2024-07-30elf: move ownership of atoms into objectsJakub Konka
2024-07-30elf: move ownership of comdat groups to ObjectJakub Konka