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 {...@@ -410,7 +410,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
410 switch (rel.type) {410 switch (rel.type) {
411 .branch => {411 .branch => {
412 const symbol = rel.getTargetSymbol(macho_file);412 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) {
414 symbol.flags.stubs = true;414 symbol.flags.stubs = true;
415 if (symbol.flags.weak) {415 if (symbol.flags.weak) {
416 macho_file.binds_to_weak = true;416 macho_file.binds_to_weak = true;
...@@ -426,7 +426,8 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {...@@ -426,7 +426,8 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
426 => {426 => {
427 const symbol = rel.getTargetSymbol(macho_file);427 const symbol = rel.getTargetSymbol(macho_file);
428 if (symbol.flags.import or428 if (symbol.flags.import or
429 (symbol.flags.@"export" and (symbol.flags.weak or symbol.flags.interposable)) or429 (symbol.flags.@"export" and symbol.flags.weak) or
430 symbol.flags.interposable or
430 macho_file.getTarget().cpu.arch == .aarch64) // TODO relax on arm64431 macho_file.getTarget().cpu.arch == .aarch64) // TODO relax on arm64
431 {432 {
432 symbol.flags.needs_got = true;433 symbol.flags.needs_got = true;
...@@ -456,7 +457,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {...@@ -456,7 +457,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
456 .{ self.getName(macho_file), symbol.getName(macho_file) },457 .{ self.getName(macho_file), symbol.getName(macho_file) },
457 );458 );
458 }459 }
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) {
460 symbol.flags.tlv_ptr = true;461 symbol.flags.tlv_ptr = true;
461 if (symbol.flags.weak) {462 if (symbol.flags.weak) {
462 macho_file.binds_to_weak = true;463 macho_file.binds_to_weak = true;
...@@ -480,13 +481,11 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {...@@ -480,13 +481,11 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
480 }481 }
481 continue;482 continue;
482 }483 }
483 if (symbol.flags.@"export") {484 if (symbol.flags.@"export" and symbol.flags.weak) {
484 if (symbol.flags.weak) {485 dynrel_ctx.weak_bind_relocs += 1;
485 dynrel_ctx.weak_bind_relocs += 1;486 macho_file.binds_to_weak = true;
486 macho_file.binds_to_weak = true;487 } else if (symbol.flags.interposable) {
487 } else if (symbol.flags.interposable) {488 dynrel_ctx.bind_relocs += 1;
488 dynrel_ctx.bind_relocs += 1;
489 }
490 }489 }
491 }490 }
492 dynrel_ctx.rebase_relocs += 1;491 dynrel_ctx.rebase_relocs += 1;
...@@ -635,12 +634,10 @@ fn resolveRelocInner(...@@ -635,12 +634,10 @@ fn resolveRelocInner(
635 }634 }
636 return;635 return;
637 }636 }
638 if (sym.flags.@"export") {637 if (sym.flags.@"export" and sym.flags.weak) {
639 if (sym.flags.weak) {638 macho_file.weak_bind.entries.appendAssumeCapacity(entry);
640 macho_file.weak_bind.entries.appendAssumeCapacity(entry);639 } else if (sym.flags.interposable) {
641 } else if (sym.flags.interposable) {640 macho_file.bind.entries.appendAssumeCapacity(entry);
642 macho_file.bind.entries.appendAssumeCapacity(entry);
643 }
644 }641 }
645 }642 }
646 macho_file.rebase.entries.appendAssumeCapacity(.{643 macho_file.rebase.entries.appendAssumeCapacity(.{
src/link/MachO/synthetic.zig+35-39
...@@ -337,9 +337,8 @@ pub const StubsHelperSection = struct {...@@ -337,9 +337,8 @@ pub const StubsHelperSection = struct {
337 var s: usize = preambleSize(cpu_arch);337 var s: usize = preambleSize(cpu_arch);
338 for (macho_file.stubs.symbols.items) |sym_index| {338 for (macho_file.stubs.symbols.items) |sym_index| {
339 const sym = macho_file.getSymbol(sym_index);339 const sym = macho_file.getSymbol(sym_index);
340 if ((sym.flags.import and !sym.flags.weak) or (!sym.flags.weak and sym.flags.interposable)) {340 if (sym.flags.weak) continue;
341 s += entrySize(cpu_arch);341 s += entrySize(cpu_arch);
342 }
343 }342 }
344 return s;343 return s;
345 }344 }
...@@ -358,35 +357,34 @@ pub const StubsHelperSection = struct {...@@ -358,35 +357,34 @@ pub const StubsHelperSection = struct {
358 var idx: usize = 0;357 var idx: usize = 0;
359 for (macho_file.stubs.symbols.items) |sym_index| {358 for (macho_file.stubs.symbols.items) |sym_index| {
360 const sym = macho_file.getSymbol(sym_index);359 const sym = macho_file.getSymbol(sym_index);
361 if ((sym.flags.import and !sym.flags.weak) or (!sym.flags.weak and sym.flags.interposable)) {360 if (sym.flags.weak) continue;
362 const offset = macho_file.lazy_bind.offsets.items[idx];361 const offset = macho_file.lazy_bind.offsets.items[idx];
363 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);362 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);
364 const target: i64 = @intCast(sect.addr);363 const target: i64 = @intCast(sect.addr);
365 switch (cpu_arch) {364 switch (cpu_arch) {
366 .x86_64 => {365 .x86_64 => {
367 try writer.writeByte(0x68);366 try writer.writeByte(0x68);
368 try writer.writeInt(u32, offset, .little);367 try writer.writeInt(u32, offset, .little);
369 try writer.writeByte(0xe9);368 try writer.writeByte(0xe9);
370 try writer.writeInt(i32, @intCast(target - source - 6 - 4), .little);369 try writer.writeInt(i32, @intCast(target - source - 6 - 4), .little);
371 },370 },
372 .aarch64 => {371 .aarch64 => {
373 const literal = blk: {372 const literal = blk: {
374 const div_res = try std.math.divExact(u64, entry_size - @sizeOf(u32), 4);373 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;374 break :blk std.math.cast(u18, div_res) orelse return error.Overflow;
376 };375 };
377 try writer.writeInt(u32, aarch64.Instruction.ldrLiteral(376 try writer.writeInt(u32, aarch64.Instruction.ldrLiteral(
378 .w16,377 .w16,
379 literal,378 literal,
380 ).toU32(), .little);379 ).toU32(), .little);
381 const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse380 const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse
382 return error.Overflow;381 return error.Overflow;
383 try writer.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);382 try writer.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);
384 try writer.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });383 try writer.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });
385 },384 },
386 else => unreachable,385 else => unreachable,
387 }
388 idx += 1;
389 }386 }
387 idx += 1;
390 }388 }
391 }389 }
392390
...@@ -500,17 +498,15 @@ pub const LaSymbolPtrSection = struct {...@@ -500,17 +498,15 @@ pub const LaSymbolPtrSection = struct {
500 var stub_helper_idx: u32 = 0;498 var stub_helper_idx: u32 = 0;
501 for (macho_file.stubs.symbols.items) |sym_index| {499 for (macho_file.stubs.symbols.items) |sym_index| {
502 const sym = macho_file.getSymbol(sym_index);500 const sym = macho_file.getSymbol(sym_index);
503 const value: u64 = if (sym.flags.@"export")501 if (sym.flags.weak) {
504 sym.getAddress(.{ .stubs = false }, macho_file)502 const value = sym.getAddress(.{ .stubs = false }, macho_file);
505 else if (sym.flags.weak)503 try writer.writeInt(u64, @intCast(value), .little);
506 @as(u64, 0)504 } else {
507 else value: {
508 const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) +505 const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) +
509 StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx;506 StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx;
510 stub_helper_idx += 1;507 stub_helper_idx += 1;
511 break :value value;508 try writer.writeInt(u64, @intCast(value), .little);
512 };509 }
513 try writer.writeInt(u64, @intCast(value), .little);
514 }510 }
515 }511 }
516};512};