Skip to content

Commit

Permalink
macho: implement pruning of unused segments and sections
Browse files Browse the repository at this point in the history
This is a prelude to a more elaborate work which will implement
`-dead_strip` flag - garbage collection of unreachable atoms. Here,
when sorting sections, we also check that the section is actually
populated with some atoms, and if not, we exclude it from the final
linked image. This can happen when we do not import any symbols
from dynamic libraries in which case we will not be populating
the stubs sections or the GOT table, implying we can skip allocating
those sections. Furthermore, we also make a check that a segment
is actually occupied too, with the exception of `__TEXT` segment
which is non-optional given that it wraps the header and load commands
and thus is required by the `dyld` to perform dynamic linking, and
`__PAGEZERO` which is generally non-optional when the linked image
is an executable. For any other segment, if its section count is
zero, we mark it as dead and skip allocating it and generating
a load command for it.

This commit also includes some minor improvements to the linker such
as refactoring of the segment allocating codepaths, skipping
`__PAGEZERO` generation for dylibs, and skipping generation of zero-sized
atoms for special symbols such as `__mh_execute_header` and `___dso_handle`.
These special symbols are only allocated local and global symbol pair
and their VM addresses is set to the start of the `__TEXT` segment,
but no `Atom` is created, as it's not necessary given that they never
carry any machine code.

Finally, we now always force-link against `libSystem` which turns out
to be required for `dyld` to properly handle `LC_MAIN` load command
on older macOS versions such as 10.15.7.
  • Loading branch information
kubkon committed Jul 1, 2022
1 parent ee01dd4 commit b79884e
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 335 deletions.
3 changes: 3 additions & 0 deletions lib/std/macho.zig
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@ pub const relocation_info = packed struct {
pub const LC_REQ_DYLD = 0x80000000;

pub const LC = enum(u32) {
/// No load command - invalid
NONE = 0x0,

/// segment of this file to be mapped
SEGMENT = 0x1,

Expand Down
Loading

0 comments on commit b79884e

Please sign in to comment.