authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:40:01+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:40:01+01:00
log47dd8d0cf76b4505c37490b81836b90844c50f8a
tree06584b74ba4398e4867f2fcdf897aa891b78b4c3
parent508ff1dd144b86e7e561636ebe4ad4410462981a

macho: clean up logic for deciding if needs __stub_helper


2 files changed, 48 insertions(+), 55 deletions(-)

src/link/MachO/Atom.zig+13-16
......@@ -410,7 +410,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
410410 switch (rel.type) {
411411 .branch => {
412412 const symbol = rel.getTargetSymbol(macho_file);
413 if (symbol.flags.import or (symbol.flags.@"export" and (symbol.flags.weak or symbol.flags.interposable))) {
413 if (symbol.flags.import or (symbol.flags.@"export" and symbol.flags.weak) or symbol.flags.interposable) {
414414 symbol.flags.stubs = true;
415415 if (symbol.flags.weak) {
416416 macho_file.binds_to_weak = true;
......@@ -426,7 +426,8 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
426426 => {
427427 const symbol = rel.getTargetSymbol(macho_file);
428428 if (symbol.flags.import or
429 (symbol.flags.@"export" and (symbol.flags.weak or symbol.flags.interposable)) or
429 (symbol.flags.@"export" and symbol.flags.weak) or
430 symbol.flags.interposable or
430431 macho_file.getTarget().cpu.arch == .aarch64) // TODO relax on arm64
431432 {
432433 symbol.flags.needs_got = true;
......@@ -456,7 +457,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
456457 .{ self.getName(macho_file), symbol.getName(macho_file) },
457458 );
458459 }
459 if (symbol.flags.import or (symbol.flags.@"export" and (symbol.flags.weak or symbol.flags.interposable))) {
460 if (symbol.flags.import or (symbol.flags.@"export" and symbol.flags.weak) or symbol.flags.interposable) {
460461 symbol.flags.tlv_ptr = true;
461462 if (symbol.flags.weak) {
462463 macho_file.binds_to_weak = true;
......@@ -480,13 +481,11 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
480481 }
481482 continue;
482483 }
483 if (symbol.flags.@"export") {
484 if (symbol.flags.weak) {
485 dynrel_ctx.weak_bind_relocs += 1;
486 macho_file.binds_to_weak = true;
487 } else if (symbol.flags.interposable) {
488 dynrel_ctx.bind_relocs += 1;
489 }
484 if (symbol.flags.@"export" and symbol.flags.weak) {
485 dynrel_ctx.weak_bind_relocs += 1;
486 macho_file.binds_to_weak = true;
487 } else if (symbol.flags.interposable) {
488 dynrel_ctx.bind_relocs += 1;
490489 }
491490 }
492491 dynrel_ctx.rebase_relocs += 1;
......@@ -635,12 +634,10 @@ fn resolveRelocInner(
635634 }
636635 return;
637636 }
638 if (sym.flags.@"export") {
639 if (sym.flags.weak) {
640 macho_file.weak_bind.entries.appendAssumeCapacity(entry);
641 } else if (sym.flags.interposable) {
642 macho_file.bind.entries.appendAssumeCapacity(entry);
643 }
637 if (sym.flags.@"export" and sym.flags.weak) {
638 macho_file.weak_bind.entries.appendAssumeCapacity(entry);
639 } else if (sym.flags.interposable) {
640 macho_file.bind.entries.appendAssumeCapacity(entry);
644641 }
645642 }
646643 macho_file.rebase.entries.appendAssumeCapacity(.{
src/link/MachO/synthetic.zig+35-39
......@@ -337,9 +337,8 @@ pub const StubsHelperSection = struct {
337337 var s: usize = preambleSize(cpu_arch);
338338 for (macho_file.stubs.symbols.items) |sym_index| {
339339 const sym = macho_file.getSymbol(sym_index);
340 if ((sym.flags.import and !sym.flags.weak) or (!sym.flags.weak and sym.flags.interposable)) {
341 s += entrySize(cpu_arch);
342 }
340 if (sym.flags.weak) continue;
341 s += entrySize(cpu_arch);
343342 }
344343 return s;
345344 }
......@@ -358,35 +357,34 @@ pub const StubsHelperSection = struct {
358357 var idx: usize = 0;
359358 for (macho_file.stubs.symbols.items) |sym_index| {
360359 const sym = macho_file.getSymbol(sym_index);
361 if ((sym.flags.import and !sym.flags.weak) or (!sym.flags.weak and sym.flags.interposable)) {
362 const offset = macho_file.lazy_bind.offsets.items[idx];
363 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);
364 const target: i64 = @intCast(sect.addr);
365 switch (cpu_arch) {
366 .x86_64 => {
367 try writer.writeByte(0x68);
368 try writer.writeInt(u32, offset, .little);
369 try writer.writeByte(0xe9);
370 try writer.writeInt(i32, @intCast(target - source - 6 - 4), .little);
371 },
372 .aarch64 => {
373 const literal = blk: {
374 const div_res = try std.math.divExact(u64, entry_size - @sizeOf(u32), 4);
375 break :blk std.math.cast(u18, div_res) orelse return error.Overflow;
376 };
377 try writer.writeInt(u32, aarch64.Instruction.ldrLiteral(
378 .w16,
379 literal,
380 ).toU32(), .little);
381 const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse
382 return error.Overflow;
383 try writer.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);
384 try writer.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });
385 },
386 else => unreachable,
387 }
388 idx += 1;
360 if (sym.flags.weak) continue;
361 const offset = macho_file.lazy_bind.offsets.items[idx];
362 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);
363 const target: i64 = @intCast(sect.addr);
364 switch (cpu_arch) {
365 .x86_64 => {
366 try writer.writeByte(0x68);
367 try writer.writeInt(u32, offset, .little);
368 try writer.writeByte(0xe9);
369 try writer.writeInt(i32, @intCast(target - source - 6 - 4), .little);
370 },
371 .aarch64 => {
372 const literal = blk: {
373 const div_res = try std.math.divExact(u64, entry_size - @sizeOf(u32), 4);
374 break :blk std.math.cast(u18, div_res) orelse return error.Overflow;
375 };
376 try writer.writeInt(u32, aarch64.Instruction.ldrLiteral(
377 .w16,
378 literal,
379 ).toU32(), .little);
380 const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse
381 return error.Overflow;
382 try writer.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);
383 try writer.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });
384 },
385 else => unreachable,
389386 }
387 idx += 1;
390388 }
391389 }
392390
......@@ -500,17 +498,15 @@ pub const LaSymbolPtrSection = struct {
500498 var stub_helper_idx: u32 = 0;
501499 for (macho_file.stubs.symbols.items) |sym_index| {
502500 const sym = macho_file.getSymbol(sym_index);
503 const value: u64 = if (sym.flags.@"export")
504 sym.getAddress(.{ .stubs = false }, macho_file)
505 else if (sym.flags.weak)
506 @as(u64, 0)
507 else value: {
501 if (sym.flags.weak) {
502 const value = sym.getAddress(.{ .stubs = false }, macho_file);
503 try writer.writeInt(u64, @intCast(value), .little);
504 } else {
508505 const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) +
509506 StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx;
510507 stub_helper_idx += 1;
511 break :value value;
512 };
513 try writer.writeInt(u64, @intCast(value), .little);
508 try writer.writeInt(u64, @intCast(value), .little);
509 }
514510 }
515511 }
516512};