mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2 macho: move PIE fixups to link file; fix tests
This commit is contained in:
parent
c749b78df5
commit
64eae8f392
@ -2601,7 +2601,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
}).toU32());
|
||||
// adr x28, #8
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
try macho_file.pie_fixups.append(self.bin_file.allocator, .{
|
||||
.address = addr,
|
||||
.start = self.code.items.len,
|
||||
.len = 4,
|
||||
@ -2626,7 +2626,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
}).toU32());
|
||||
// adr x28, #8
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
try macho_file.pie_fixups.append(self.bin_file.allocator, .{
|
||||
.address = addr,
|
||||
.start = self.code.items.len,
|
||||
.len = 4,
|
||||
@ -2838,7 +2838,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
// later in the linker.
|
||||
if (reg.id() == 0) { // %rax is special-cased
|
||||
try self.code.ensureCapacity(self.code.items.len + 5);
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
try macho_file.pie_fixups.append(self.bin_file.allocator, .{
|
||||
.address = x,
|
||||
.start = self.code.items.len,
|
||||
.len = 5,
|
||||
@ -2855,7 +2855,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
try self.code.ensureCapacity(self.code.items.len + 10);
|
||||
// push %rax
|
||||
self.code.appendSliceAssumeCapacity(&[_]u8{0x50});
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
try macho_file.pie_fixups.append(self.bin_file.allocator, .{
|
||||
.address = x,
|
||||
.start = self.code.items.len,
|
||||
.len = 5,
|
||||
|
||||
@ -175,6 +175,22 @@ libsystem_cmd_dirty: bool = false,
|
||||
text_block_free_list: std.ArrayListUnmanaged(*TextBlock) = .{},
|
||||
/// Pointer to the last allocated text block
|
||||
last_text_block: ?*TextBlock = null,
|
||||
/// A list of all PIE fixups required for this run of the linker.
|
||||
/// Warning, this is currently NOT thread-safe. See the TODO below.
|
||||
/// TODO Move this list inside `updateDecl` where it should be allocated
|
||||
/// prior to calling `generateSymbol`, and then immediately deallocated
|
||||
/// rather than sitting in the global scope.
|
||||
pie_fixups: std.ArrayListUnmanaged(PieFixup) = .{},
|
||||
|
||||
pub const PieFixup = struct {
|
||||
/// Target address we wanted to address in absolute terms.
|
||||
address: u64,
|
||||
/// Where in the byte stream we should perform the fixup.
|
||||
start: usize,
|
||||
/// The length of the byte stream. For x86_64, this will be
|
||||
/// variable. For aarch64, it will be fixed at 4 bytes.
|
||||
len: usize,
|
||||
};
|
||||
|
||||
/// `alloc_num / alloc_den` is the factor of padding when allocating.
|
||||
const alloc_num = 4;
|
||||
@ -215,20 +231,10 @@ pub const TextBlock = struct {
|
||||
/// Unlike in Elf, we need to store the size of this symbol as part of
|
||||
/// the TextBlock since macho.nlist_64 lacks this information.
|
||||
size: u64,
|
||||
/// List of PIE fixups in the code.
|
||||
/// This is a table of all position-relative positions that will need fixups
|
||||
/// after codegen when linker assigns addresses to GOT entries.
|
||||
pie_fixups: std.ArrayListUnmanaged(PieFixup) = .{},
|
||||
/// Points to the previous and next neighbours
|
||||
prev: ?*TextBlock,
|
||||
next: ?*TextBlock,
|
||||
|
||||
pub const PieFixup = struct {
|
||||
address: u64,
|
||||
start: usize,
|
||||
len: usize,
|
||||
};
|
||||
|
||||
pub const empty = TextBlock{
|
||||
.local_sym_index = 0,
|
||||
.offset_table_index = undefined,
|
||||
@ -237,14 +243,6 @@ pub const TextBlock = struct {
|
||||
.next = null,
|
||||
};
|
||||
|
||||
pub fn addPieFixup(self: *TextBlock, alloc: *Allocator, fixup: PieFixup) !void {
|
||||
return self.pie_fixups.append(alloc, fixup);
|
||||
}
|
||||
|
||||
fn deinit(self: *TextBlock, alloc: *Allocator) void {
|
||||
self.pie_fixups.deinit(alloc);
|
||||
}
|
||||
|
||||
/// Returns how much room there is to grow in virtual address space.
|
||||
/// File offset relocation happens transparently, so it is not included in
|
||||
/// this calculation.
|
||||
@ -849,9 +847,7 @@ fn darwinArchString(arch: std.Target.Cpu.Arch) []const u8 {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *MachO) void {
|
||||
for (self.text_block_free_list.items) |tb| {
|
||||
tb.deinit(self.base.allocator);
|
||||
}
|
||||
self.pie_fixups.deinit(self.base.allocator);
|
||||
self.text_block_free_list.deinit(self.base.allocator);
|
||||
self.offset_table.deinit(self.base.allocator);
|
||||
self.offset_table_free_list.deinit(self.base.allocator);
|
||||
@ -894,9 +890,7 @@ fn freeTextBlock(self: *MachO, text_block: *TextBlock) void {
|
||||
if (!already_have_free_list_node and prev.freeListEligible(self.*)) {
|
||||
// The free list is heuristics, it doesn't have to be perfect, so we can ignore
|
||||
// the OOM here.
|
||||
self.text_block_free_list.append(self.base.allocator, prev) catch {
|
||||
prev.deinit(self.base.allocator);
|
||||
};
|
||||
self.text_block_free_list.append(self.base.allocator, prev) catch {};
|
||||
}
|
||||
} else {
|
||||
text_block.prev = null;
|
||||
@ -1018,7 +1012,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
|
||||
|
||||
// Perform PIE fixups (if any)
|
||||
const got_section = self.sections.items[self.got_section_index.?];
|
||||
while (decl.link.macho.pie_fixups.popOrNull()) |fixup| {
|
||||
while (self.pie_fixups.popOrNull()) |fixup| {
|
||||
const target_addr = fixup.address;
|
||||
const this_addr = symbol.n_value + fixup.start;
|
||||
if (self.base.options.target.cpu.arch == .x86_64) {
|
||||
@ -1761,7 +1755,7 @@ fn writeCodeSignature(self: *MachO) !void {
|
||||
}
|
||||
|
||||
fn writeExportTrie(self: *MachO) !void {
|
||||
assert(self.global_symbols.items.len > 0);
|
||||
if (self.global_symbols.items.len == 0) return;
|
||||
|
||||
var trie: Trie = .{};
|
||||
defer trie.deinit(self.base.allocator);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user