Commit Graph

139 Commits

Author SHA1 Message Date
David Rubin
66a7c09def link: use target to determine risc-v eflag validity 2024-11-22 19:34:47 -05:00
Jakub Konka
6ff267dc26 link/Elf: ensure we always sort all relocations by r_offset in -r mode
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-29 17:27:42 -07:00
Andrew Kelley
de0f7fcf52 unify parsing codepaths between relocatable and non 2024-10-23 16:27:38 -07:00
Andrew Kelley
2dcfa72376 link.Elf: untangle parseObject and parseArchive
from link.Elf, so that they can be used earlier in the pipeline
2024-10-23 16:27:38 -07:00
Andrew Kelley
1ba3fc90be link.Elf: eliminate an O(N^2) algorithm in flush()
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-12 10:44:17 -07:00
Andrew Kelley
13fb68c064 link: consolidate diagnostics
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-11 10:36:19 -07:00
Andrew Kelley
7b69738a06 link.Elf: fix merge sections namespacing
`link.Elf.merge_section.MergeSection` -> `link.Elf.Merge.Section`
2024-10-11 10:33:54 -07:00
Andrew Kelley
2c4e05eda7 link.Elf: group section indexes
so they cannot be forgotten when updating them after sorting them.
2024-10-11 10:33:54 -07:00
Andrew Kelley
14c8e270bb link: fix false positive crtbegin/crtend detection
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-10 14:21:52 -07:00
Andrew Kelley
2e2927735d Merge pull request #21629 from ziglang/elf-incr
elf: more incremental progress
2024-10-09 17:43:17 -07:00
Andrew Kelley
c86a334d43 link.Elf.Object.initAtoms: reduce state access and indirection
The initAtoms function now only uses the `elf_file` parameter for
reporting linker error messages, making it easier to see that the
function has no data dependencies other than the Object struct itself,
making it easier to parallelize or otherwise move that logic around.

Also removed an indirect call via `addExtra` since we already know the
atom's file is the current Object instance. All calls to `Atom.addExtra`
should be audited for similar reasons.

Also removed unjustified use of `inline fn`.
2024-10-09 15:40:59 -07:00
Jakub Konka
9a15c3e1a1 elf: mark objects as dirty/not-dirty
This way we can track if we need to redo the object parsing or not.
2024-10-09 12:38:09 -07:00
Jakub Konka
7fead5d6dd elf: track atoms within AtomList with array hash map 2024-10-09 12:27:30 -07:00
Andrew Kelley
31d70cb1e1 link.Elf: avoid needless file system reads in flush()
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-10-08 18:02:59 -07:00
Jakub Konka
f4c4ca4b4c elf: fix condition for skipping symbols if atom is dead
Skipping the symbols too early when resolving would end up in the
linker not deduping CIEs fully.
2024-09-23 06:56:36 +02:00
Linus Groh
8588964972 Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Jakub Konka
d302a1068e elf: rename SectionChunk into AtomList and store as part of Section 2024-09-04 13:34:26 +02:00
Jakub Konka
64ad6eff16 elf: create back/forward links for atoms within section chunks 2024-09-04 13:34:26 +02:00
Jakub Konka
801f038c2c elf: do not pad placeholders coming from input object files
This is currently not entirely accurate since no padding will affect
the last-most atom of ZigObject that should be padded.
2024-09-04 13:34:26 +02:00
Jakub Konka
eeec50d251 elf: misc .eh_frame management fixes 2024-09-04 13:34:26 +02:00
Jakub Konka
2ef3e30e2d elf: emit relocs for self-hosted generated .eh_frame section 2024-09-04 13:34:26 +02:00
Jakub Konka
5cb51c10de elf: fix relocatable mode 2024-09-04 13:34:26 +02:00
Jakub Konka
6b53dc9461 elf: actually allocate atoms within each section chunk 2024-09-04 13:34:26 +02:00
Jakub Konka
f87a7251a3 elf: actually write allocated atoms in object files 2024-09-04 13:34:26 +02:00
Jakub Konka
45e46f0fb9 elf: allocate atom chunks using allocateChunk mechanics in objects 2024-09-04 13:34:25 +02:00
Jakub Konka
1ef96f05eb elf: introduce SectionChunk - a container of atoms per object file 2024-09-04 13:34:25 +02:00
Jakub Konka
d32af9ea2a elf: move initOutputSection into Elf from Object 2024-09-04 13:34:25 +02:00
mlugg
0fe3fd01dd std: update std.builtin.Type fields to follow naming conventions
The compiler actually doesn't need any functional changes for this: Sema
does reification based on the tag indices of `std.builtin.Type` already!
So, no zig1.wasm update is necessary.

This change is necessary to disallow name clashes between fields and
decls on a type, which is a prerequisite of #9938.
2024-08-28 08:39:59 +01:00
Andrew Kelley
d9147b91a6 Merge pull request #21212 from ziglang/elf-incr
elf: cleanups, cleanups, cleanups
2024-08-26 19:25:23 -07:00
Jakub Konka
20240e9cd5 elf: store atom refs for rela sections until we can do better 2024-08-25 10:20:15 +02:00
Jakub Konka
a9d3885ac7 elf: streamline sections container 2024-08-25 10:20:14 +02:00
Alex Rønne Petersen
fb6f5a30b2 link: Rename InvalidCpuArch error to InvalidMachineType. 2024-08-23 19:56:29 +02:00
Alex Rønne Petersen
a69f55a7cc std.{coff,elf}: Remove the {MachineType,EM}.toTargetCpuArch() functions.
These are fundamentally incapable of producing accurate information for reasons
I've laid out in #20771. Since our only use of these functions is to check that
object files have the correct machine type, and since #21020 made
`std.Target.to{Coff,Elf}Machine()` more accurate, just switch these checks over
to that and compare the machine type tags instead.

Closes #20771.
2024-08-23 19:56:24 +02:00
Jakub Konka
b058545970 elf: remove stale code 2024-08-07 10:21:03 +02:00
Jakub Konka
e99818c602 elf: start-stop resolution has to come after init output sections 2024-08-07 10:21:03 +02:00
Jakub Konka
835f1fc03f elf: fix off-by-one when referring to resolved table directly 2024-08-07 10:21:02 +02:00
Jakub Konka
137d43c0ea elf: get hello-world glibc working again 2024-08-07 10:21:02 +02:00
Jakub Konka
26da7c8207 elf: fix symbol resolution for Objects 2024-08-07 10:21:02 +02:00
Jakub Konka
8ca809d928 elf: move getStartStopBasename into Object 2024-08-07 10:21:02 +02:00
Jakub Konka
41e9b8b6c8 elf: fix compile errors 2024-08-07 10:21:02 +02:00
Jakub Konka
deeaa1bb0c elf: redo symbol mgmt and ownership in ZigObject 2024-08-07 10:21:02 +02:00
Jakub Konka
9fe69cc0b5 elf: move symbol ownership to SharedObject 2024-08-07 10:21:02 +02:00
Jakub Konka
d0367b0219 elf: move symbol ownership to Object 2024-08-07 10:21:02 +02:00
Jakub Konka
518c7908f0 elf: always create symbol extra 2024-08-07 10:21:02 +02:00
Jakub Konka
ef7bbcd80f elf: do not store merge section output section name in strings buffer 2024-07-30 10:00:50 +02:00
Jakub Konka
801c372098 elf: init output merge sections in a separate step 2024-07-30 10:00:50 +02:00
Jakub Konka
0701646beb elf: move merge subsections ownership into merge sections 2024-07-30 10:00:50 +02:00
Jakub Konka
24126f5382 elf: simplify output section tracking for symbols 2024-07-30 10:00:50 +02:00
Jakub Konka
e8d008a8a8 elf: atom is always assigned output section index 2024-07-30 10:00:50 +02:00
Jakub Konka
96c20adeee elf: remove obsolete flags from atom 2024-07-30 10:00:50 +02:00