aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO/Object.zig46
-rw-r--r--src/link/MachO/Zld.zig23
-rw-r--r--src/link/MachO/reloc.zig4
3 files changed, 40 insertions, 33 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig
index abd5a39a69..b53a31af56 100644
--- a/src/link/MachO/Object.zig
+++ b/src/link/MachO/Object.zig
@@ -431,30 +431,27 @@ const TextBlockParser = struct {
else
max_align;
- const alias_only_indices = if (aliases.items.len > 0) blk: {
- var out = std.ArrayList(u32).init(self.allocator);
- try out.ensureTotalCapacity(aliases.items.len);
- for (aliases.items) |alias| {
- out.appendAssumeCapacity(alias.index);
-
- const sym = self.zld.locals.items[alias.index];
- const reg = &sym.payload.regular;
- reg.segment_id = self.match.seg;
- reg.section_id = self.match.sect;
- }
- break :blk out.toOwnedSlice();
- } else null;
-
const block = try self.allocator.create(TextBlock);
errdefer self.allocator.destroy(block);
block.* = TextBlock.init(self.allocator);
block.local_sym_index = senior_nlist.index;
- block.aliases = alias_only_indices;
block.code = try self.allocator.dupe(u8, code);
block.size = size;
block.alignment = actual_align;
+ if (aliases.items.len > 0) {
+ try block.aliases.ensureTotalCapacity(aliases.items.len);
+ for (aliases.items) |alias| {
+ block.aliases.appendAssumeCapacity(alias.index);
+
+ const sym = self.zld.locals.items[alias.index];
+ const reg = &sym.payload.regular;
+ reg.segment_id = self.match.seg;
+ reg.section_id = self.match.sect;
+ }
+ }
+
const relocs = filterRelocs(self.relocs, start_addr, end_addr);
if (relocs.len > 0) {
try self.object.parseRelocs(self.zld, relocs, block, start_addr);
@@ -617,7 +614,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
const tsect = &tseg.sections.items[match.sect];
const new_alignment = math.max(tsect.@"align", block.alignment);
const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
- const new_size = mem.alignForwardGeneric(u64, tsect.size + block.size, new_alignment_pow_2);
+ const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
tsect.size = new_size;
tsect.@"align" = new_alignment;
@@ -653,6 +650,19 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
}
}
+ if (reg.address == sect.addr) {
+ if (self.sections_as_symbols.get(sect_id)) |alias| {
+ // Add alias.
+ const local_sym_index = @intCast(u32, zld.locals.items.len);
+ const reg_alias = &alias.payload.regular;
+ reg_alias.segment_id = match.seg;
+ reg_alias.section_id = match.sect;
+ reg_alias.local_sym_index = local_sym_index;
+ try block.aliases.append(local_sym_index);
+ try zld.locals.append(zld.allocator, alias);
+ }
+ }
+
// Update target section's metadata
// TODO should we update segment's size here too?
// How does it tie with incremental space allocs?
@@ -660,7 +670,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
const tsect = &tseg.sections.items[match.sect];
const new_alignment = math.max(tsect.@"align", block.alignment);
const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
- const new_size = mem.alignForwardGeneric(u64, tsect.size + block.size, new_alignment_pow_2);
+ const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
tsect.size = new_size;
tsect.@"align" = new_alignment;
@@ -764,7 +774,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
const tsect = &tseg.sections.items[match.sect];
const new_alignment = math.max(tsect.@"align", block.alignment);
const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
- const new_size = mem.alignForwardGeneric(u64, tsect.size + block.size, new_alignment_pow_2);
+ const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
tsect.size = new_size;
tsect.@"align" = new_alignment;
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index 995269440f..40ab52f062 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -125,7 +125,7 @@ pub const Output = struct {
pub const TextBlock = struct {
allocator: *Allocator,
local_sym_index: u32,
- aliases: ?[]u32 = null,
+ aliases: std.ArrayList(u32),
references: std.AutoArrayHashMap(u32, void),
contained: ?[]SymbolAtOffset = null,
code: []u8,
@@ -146,6 +146,7 @@ pub const TextBlock = struct {
return .{
.allocator = allocator,
.local_sym_index = undefined,
+ .aliases = std.ArrayList(u32).init(allocator),
.references = std.AutoArrayHashMap(u32, void).init(allocator),
.code = undefined,
.relocs = std.ArrayList(Relocation).init(allocator),
@@ -157,9 +158,7 @@ pub const TextBlock = struct {
}
pub fn deinit(self: *TextBlock) void {
- if (self.aliases) |aliases| {
- self.allocator.free(aliases);
- }
+ self.aliases.deinit();
self.references.deinit();
if (self.contained) |contained| {
self.allocator.free(contained);
@@ -179,9 +178,9 @@ pub const TextBlock = struct {
pub fn print_this(self: *const TextBlock, zld: *Zld) void {
log.warn("TextBlock", .{});
log.warn(" {}: {}", .{ self.local_sym_index, zld.locals.items[self.local_sym_index] });
- if (self.aliases) |aliases| {
+ if (self.aliases.items.len > 0) {
log.warn(" aliases:", .{});
- for (aliases) |index| {
+ for (self.aliases.items) |index| {
log.warn(" {}: {}", .{ index, zld.locals.items[index] });
}
}
@@ -1082,12 +1081,10 @@ fn allocateTextBlocks(self: *Zld) !void {
});
// Update each alias (if any)
- if (block.aliases) |aliases| {
- for (aliases) |index| {
- const alias_sym = self.locals.items[index];
- assert(alias_sym.payload == .regular);
- alias_sym.payload.regular.address = base_addr;
- }
+ for (block.aliases.items) |index| {
+ const alias_sym = self.locals.items[index];
+ assert(alias_sym.payload == .regular);
+ alias_sym.payload.regular.address = base_addr;
}
// Update each symbol contained within the TextBlock
@@ -1623,7 +1620,7 @@ fn resolveSymbols(self: *Zld) !void {
const tsect = &tseg.sections.items[match.sect];
const new_alignment = math.max(tsect.@"align", block.alignment);
const new_alignment_pow_2 = try math.powi(u32, 2, new_alignment);
- const new_size = mem.alignForwardGeneric(u64, tsect.size + block.size, new_alignment_pow_2);
+ const new_size = mem.alignForwardGeneric(u64, tsect.size, new_alignment_pow_2) + block.size;
tsect.size = new_size;
tsect.@"align" = new_alignment;
diff --git a/src/link/MachO/reloc.zig b/src/link/MachO/reloc.zig
index 2008d53e3f..d92d047cd9 100644
--- a/src/link/MachO/reloc.zig
+++ b/src/link/MachO/reloc.zig
@@ -878,9 +878,9 @@ pub const Parser = struct {
if (rel.r_extern == 0) {
const source_sym = self.zld.locals.items[self.block.local_sym_index].payload.regular;
- const source_addr = source_sym.address + parsed.offset + @intCast(u32, addend) + 4;
+ const source_addr = source_sym.address + parsed.offset + 4;
const target_sym = parsed.target.payload.regular;
- addend = @intCast(i64, source_addr) - @intCast(i64, target_sym.address);
+ addend = @intCast(i64, source_addr) + addend - @intCast(i64, target_sym.address);
}
parsed.payload = .{