Previously we used single arraylists for each debug section for debug
information that was generated from Zig code. (e.i. `Module` is available).
This information is now stored in Atoms, similarly to debug information
from object files. This will allow us to link them together and resolve
debug relocations.
This correctly performs a relocation for debug sections.
The result is that the wasm-linker can now correctly create
a binary from object files while preserving all debug information.
We now link relocatable debug sections with the correct
section symbol and then allocate and resolve the debug atoms
before writing them into the final binary.
Although this does perform the relocation, the actual relocations
are not done correctly yet.
Rather than storing the name of a debug section into the structure
`RelocatableData`, we use the `index` field as an offset into the
debug names table. This means we do not have to store an extra 16 bytes
for non-debug sections which can be massive for object files where each
data symbol has its own data section. The name of a debug section
can then be retrieved again when needed by using the offset and
then reading until the 0-delimiter.
Currently, `zig build-exe -fno-emit-bin --verbose-air src/main.zig`
results in no output at all. With this refactor, it dumps AIR
and then exits without invoking LLVM, as expected
This means we can request ASLR on by default as other COFF linkers
do. Currently, we write the base relocations in bulk, however,
given that there is a mechanism for padding in place in PE/COFF
I believe there might be room for making it an incremental operation
(write base relocation whenever we add/update a pointer that would
require it).
When instantiating a generic function, there is a period of time where
the function is inserted into monomorphed_funcs map, but is not yet
initialized. Despite semantic analysis being single-threaded, generic
function instantiation can happen recursively, meaning that the hash
and equality functions for monomorphed_funcs entries are potentially
invoked for an uninitialized function.
This problem was mitigated by pre-setting the hash field on the newly
allocated function, however it did not solve the problem for hash
collisions in which case the equality function would be invoked. That it
was solved for hash() but not eql() explains why the problem was
difficult to observe. I tested this patch by temporarily sabotaging the
hash and making it always return 0.
This fix is centered on adding a new field to Module.Fn which is the one
checked by eql() and is populated pre-initialization.
closes#12643
This is problematic because in practice it depends on whether the
compiler backend supports it too, as evidenced by the TODO comment about
LLVM not supporting some architectures that in fact do support tail
calls.
Instead this logic is organized strategically in src/target.zig, part of
the internal compiler source code, and the behavior tests in question
duplicate some logic for deciding whether to proceed with the test.
The proper place to expose this flag is in `@import("builtin")` - the
generated source file - so that third party compilers can advertise
whether they support tail calls.
This also fixes performing relocations for data symbols
of which the target symbol exists in an external object file.
We do this by checking if the target symbol was discarded,
and if so: get the new location so that we can find the
corresponding atom that belongs to said new location. Previously
it would always assume the symbol would live in the same file
as the atom/symbol that is doing the relocation.
Generate symbols for extern variables and try to resolve them.
Unresolved 'data' symbols generate an error as they cannot be
exported from the Wasm runtime into a Wasm module. This means,
they can only be resolved by other object files such as from other
Zig or C code compiled to Wasm.