| ... | @@ -252,9 +252,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { | ... | @@ -252,9 +252,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 252 | try self.populateMetadata(); | 252 | try self.populateMetadata(); |
| 253 | try self.parseInputFiles(files); | 253 | try self.parseInputFiles(files); |
| 254 | try self.resolveImports(); | 254 | try self.resolveImports(); |
| 255 | self.allocateTextSegment(); | 255 | try self.allocateTextSegment(); |
| 256 | self.allocateDataSegment(); | 256 | try self.allocateDataSegment(); |
| 257 | self.allocateLinkeditSegment(); | 257 | try self.allocateLinkeditSegment(); |
| 258 | try self.writeStubHelperCommon(); | 258 | try self.writeStubHelperCommon(); |
| 259 | try self.resolveSymbols(); | 259 | try self.resolveSymbols(); |
| 260 | try self.doRelocs(); | 260 | try self.doRelocs(); |
| ... | @@ -317,13 +317,20 @@ fn parseObjectFile(self: *Zld, object: *const Object) !void { | ... | @@ -317,13 +317,20 @@ fn parseObjectFile(self: *Zld, object: *const Object) !void { |
| 317 | if (mem.eql(u8, sectname, "__thread_vars")) { | 317 | if (mem.eql(u8, sectname, "__thread_vars")) { |
| 318 | self.tlv_section_index = sect_index; | 318 | self.tlv_section_index = sect_index; |
| 319 | } | 319 | } |
| | 320 | log.warn("{s} align 0x{x}", .{ sectname, sect.@"align" }); |
| | 321 | const alignment = switch (sect.flags) { |
| | 322 | macho.S_4BYTE_LITERALS => 2, |
| | 323 | macho.S_8BYTE_LITERALS => 3, |
| | 324 | macho.S_16BYTE_LITERALS => 4, |
| | 325 | else => sect.@"align", |
| | 326 | }; |
| 320 | try seg.append(self.allocator, .{ | 327 | try seg.append(self.allocator, .{ |
| 321 | .sectname = makeStaticString(&sect.sectname), | 328 | .sectname = makeStaticString(&sect.sectname), |
| 322 | .segname = makeStaticString(&sect.segname), | 329 | .segname = makeStaticString(&sect.segname), |
| 323 | .addr = 0, | 330 | .addr = 0, |
| 324 | .size = 0, | 331 | .size = 0, |
| 325 | .offset = 0, | 332 | .offset = 0, |
| 326 | .@"align" = sect.@"align", | 333 | .@"align" = alignment, |
| 327 | .reloff = 0, | 334 | .reloff = 0, |
| 328 | .nreloc = 0, | 335 | .nreloc = 0, |
| 329 | .flags = sect.flags, | 336 | .flags = sect.flags, |
| ... | @@ -429,7 +436,7 @@ fn resolveImports(self: *Zld) !void { | ... | @@ -429,7 +436,7 @@ fn resolveImports(self: *Zld) !void { |
| 429 | }); | 436 | }); |
| 430 | } | 437 | } |
| 431 | | 438 | |
| 432 | fn allocateTextSegment(self: *Zld) void { | 439 | fn allocateTextSegment(self: *Zld) !void { |
| 433 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 440 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 434 | const nexterns = @intCast(u32, self.lazy_imports.items().len); | 441 | const nexterns = @intCast(u32, self.lazy_imports.items().len); |
| 435 | | 442 | |
| ... | @@ -450,10 +457,16 @@ fn allocateTextSegment(self: *Zld) void { | ... | @@ -450,10 +457,16 @@ fn allocateTextSegment(self: *Zld) void { |
| 450 | sizeofcmds += lc.cmdsize(); | 457 | sizeofcmds += lc.cmdsize(); |
| 451 | } | 458 | } |
| 452 | | 459 | |
| 453 | self.allocateSegment(self.text_segment_cmd_index.?, 0, sizeofcmds, true); | 460 | try self.allocateSegment( |
| | 461 | self.text_segment_cmd_index.?, |
| | 462 | 0, |
| | 463 | // sizeofcmds + 10 * 4 * @sizeOf(u32), |
| | 464 | 3140, |
| | 465 | true, |
| | 466 | ); |
| 454 | } | 467 | } |
| 455 | | 468 | |
| 456 | fn allocateDataSegment(self: *Zld) void { | 469 | fn allocateDataSegment(self: *Zld) !void { |
| 457 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 470 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 458 | const nonlazy = @intCast(u32, self.nonlazy_imports.items().len); | 471 | const nonlazy = @intCast(u32, self.nonlazy_imports.items().len); |
| 459 | const lazy = @intCast(u32, self.lazy_imports.items().len); | 472 | const lazy = @intCast(u32, self.lazy_imports.items().len); |
| ... | @@ -470,16 +483,16 @@ fn allocateDataSegment(self: *Zld) void { | ... | @@ -470,16 +483,16 @@ fn allocateDataSegment(self: *Zld) void { |
| 470 | | 483 | |
| 471 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 484 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 472 | const offset = text_seg.inner.fileoff + text_seg.inner.filesize; | 485 | const offset = text_seg.inner.fileoff + text_seg.inner.filesize; |
| 473 | self.allocateSegment(self.data_segment_cmd_index.?, offset, 0, false); | 486 | try self.allocateSegment(self.data_segment_cmd_index.?, offset, 0, false); |
| 474 | } | 487 | } |
| 475 | | 488 | |
| 476 | fn allocateLinkeditSegment(self: *Zld) void { | 489 | fn allocateLinkeditSegment(self: *Zld) !void { |
| 477 | const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 490 | const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 478 | const offset = data_seg.inner.fileoff + data_seg.inner.filesize; | 491 | const offset = data_seg.inner.fileoff + data_seg.inner.filesize; |
| 479 | self.allocateSegment(self.linkedit_segment_cmd_index.?, offset, 0, false); | 492 | try self.allocateSegment(self.linkedit_segment_cmd_index.?, offset, 0, false); |
| 480 | } | 493 | } |
| 481 | | 494 | |
| 482 | fn allocateSegment(self: *Zld, index: u16, offset: u64, start: u64, reverse: bool) void { | 495 | fn allocateSegment(self: *Zld, index: u16, offset: u64, start: u64, reverse: bool) !void { |
| 483 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; | 496 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; |
| 484 | const seg = &self.load_commands.items[index].Segment; | 497 | const seg = &self.load_commands.items[index].Segment; |
| 485 | | 498 | |
| ... | @@ -495,23 +508,27 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64, start: u64, reverse: boo | ... | @@ -495,23 +508,27 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64, start: u64, reverse: boo |
| 495 | seg.inner.filesize = aligned_size; | 508 | seg.inner.filesize = aligned_size; |
| 496 | | 509 | |
| 497 | // Allocate section offsets | 510 | // Allocate section offsets |
| 498 | if (reverse) { | 511 | // if (reverse) { |
| 499 | var end_off: u64 = seg.inner.fileoff + seg.inner.filesize; | 512 | // var end_off: u64 = seg.inner.fileoff + seg.inner.filesize; |
| 500 | var count: usize = seg.sections.items.len; | 513 | // var count: usize = seg.sections.items.len; |
| 501 | while (count > 0) : (count -= 1) { | 514 | // while (count > 0) : (count -= 1) { |
| 502 | const sec = &seg.sections.items[count - 1]; | 515 | // const sec = &seg.sections.items[count - 1]; |
| 503 | end_off -= mem.alignForwardGeneric(u64, sec.size, @sizeOf(u32)); // TODO Should we always align to 4? | 516 | // const alignment = math.max(@alignOf(u32), try std.math.powi(u32, 2, sec.@"align")); |
| 504 | sec.offset = @intCast(u32, end_off); | 517 | // log.warn("{s} 0x{x} alignment = 0x{x}", .{ parseName(&sec.sectname), sec.@"align", alignment }); |
| 505 | sec.addr = base_vmaddr + end_off; | 518 | // end_off -= mem.alignForwardGeneric(u64, sec.size, alignment); |
| 506 | } | 519 | // sec.offset = @intCast(u32, end_off); |
| 507 | } else { | 520 | // sec.addr = base_vmaddr + end_off; |
| 508 | var next_off: u64 = seg.inner.fileoff; | 521 | // } |
| 509 | for (seg.sections.items) |*sect| { | 522 | // } else { |
| 510 | sect.offset = @intCast(u32, next_off); | 523 | var next_off: u64 = seg.inner.fileoff + start; |
| 511 | sect.addr = base_vmaddr + next_off; | 524 | for (seg.sections.items) |*sect| { |
| 512 | next_off += mem.alignForwardGeneric(u64, sect.size, @sizeOf(u32)); // TODO Should we always align to 4? | 525 | const alignment = math.max(@alignOf(u32), try std.math.powi(u32, 2, sect.@"align")); |
| 513 | } | 526 | log.warn("{s} 0x{x} alignment = 0x{x}", .{ parseName(&sect.sectname), sect.@"align", alignment }); |
| 514 | } | 527 | sect.offset = @intCast(u32, next_off); |
| | 528 | sect.addr = base_vmaddr + next_off; |
| | 529 | next_off += mem.alignForwardGeneric(u64, sect.size, alignment); |
| | 530 | } |
| | 531 | // } |
| 515 | } | 532 | } |
| 516 | | 533 | |
| 517 | fn writeStubHelperCommon(self: *Zld) !void { | 534 | fn writeStubHelperCommon(self: *Zld) !void { |
| ... | @@ -552,33 +569,48 @@ fn writeStubHelperCommon(self: *Zld) !void { | ... | @@ -552,33 +569,48 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 552 | break :blk stub_helper.offset + code_size; | 569 | break :blk stub_helper.offset + code_size; |
| 553 | }, | 570 | }, |
| 554 | .aarch64 => { | 571 | .aarch64 => { |
| 555 | var code: [4 * @sizeOf(u32)]u8 = undefined; | 572 | var code: [6 * @sizeOf(u32)]u8 = undefined; |
| 556 | { | 573 | { |
| 557 | const target_addr = data.addr + data.size - @sizeOf(u64); | 574 | const target_addr = data.addr + data.size - @sizeOf(u64); |
| 558 | const displacement = @bitCast(u21, try math.cast(i21, target_addr - stub_helper.addr)); | 575 | const displacement = @bitCast(u21, try math.cast(i21, target_addr - stub_helper.addr)); |
| 559 | // adr x17, disp | 576 | // adr x17, disp |
| 560 | mem.writeIntLittle(u32, code[0..4], Arm64.adr(17, displacement).toU32()); | 577 | mem.writeIntLittle(u32, code[0..4], Arm64.adr(17, displacement).toU32()); |
| | 578 | // TODO check if adr is enough and expand into adrp + add if not. |
| | 579 | // nop in case we need to expand adr for adrp followed by add. |
| | 580 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.nop().toU32()); |
| 561 | } | 581 | } |
| 562 | // stp x16, x17, [sp, #-16]! | 582 | // stp x16, x17, [sp, #-16]! |
| 563 | code[4] = 0xf0; | 583 | code[8] = 0xf0; |
| 564 | code[5] = 0x47; | 584 | code[9] = 0x47; |
| 565 | code[6] = 0xbf; | 585 | code[10] = 0xbf; |
| 566 | code[7] = 0xa9; | 586 | code[11] = 0xa9; |
| 567 | { | 587 | binder: { |
| 568 | const dyld_stub_binder = self.nonlazy_imports.get("dyld_stub_binder").?; | 588 | const dyld_stub_binder = self.nonlazy_imports.get("dyld_stub_binder").?; |
| 569 | const addr = (got.addr + dyld_stub_binder.index * @sizeOf(u64)); | 589 | const addr = (got.addr + dyld_stub_binder.index * @sizeOf(u64)); |
| 570 | const displacement = try math.divExact(u64, addr - stub_helper.addr - 2 * @sizeOf(u32), 4); | 590 | const displacement = math.divExact(u64, addr - stub_helper.addr - 3 * @sizeOf(u32), 4) catch |_| { |
| 571 | const literal = try math.cast(u19, displacement); | 591 | log.warn("0x{x}", .{addr - stub_helper.addr - 3 * @sizeOf(u32)}); |
| | 592 | // Pad with nop to please division. |
| | 593 | // nop |
| | 594 | mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.nop().toU32()); |
| | 595 | // ldr x16, label |
| | 596 | const disp = try math.divExact(u64, addr - stub_helper.addr - 4 * @sizeOf(u32), 4); |
| | 597 | const literal = try math.cast(u19, disp); // TODO use adrp + add if we exceed the range. |
| | 598 | mem.writeIntLittle(u32, code[16..20], Arm64.ldr(16, literal, 1).toU32()); |
| | 599 | break :binder; |
| | 600 | }; |
| | 601 | const literal = try math.cast(u19, displacement); // TODO use adrp + add if we exceed the range. |
| 572 | // ldr x16, label | 602 | // ldr x16, label |
| 573 | mem.writeIntLittle(u32, code[8..12], Arm64.ldr(16, literal, 1).toU32()); | 603 | mem.writeIntLittle(u32, code[12..16], Arm64.ldr(16, literal, 1).toU32()); |
| | 604 | // nop |
| | 605 | mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.nop().toU32()); |
| 574 | } | 606 | } |
| 575 | // br x16 | 607 | // br x16 |
| 576 | code[12] = 0x00; | 608 | code[20] = 0x00; |
| 577 | code[13] = 0x02; | 609 | code[21] = 0x02; |
| 578 | code[14] = 0x1f; | 610 | code[22] = 0x1f; |
| 579 | code[15] = 0xd6; | 611 | code[23] = 0xd6; |
| 580 | try self.file.?.pwriteAll(&code, stub_helper.offset); | 612 | try self.file.?.pwriteAll(&code, stub_helper.offset); |
| 581 | break :blk stub_helper.offset + 4 * @sizeOf(u32); | 613 | break :blk stub_helper.offset + 6 * @sizeOf(u32); |
| 582 | }, | 614 | }, |
| 583 | else => unreachable, | 615 | else => unreachable, |
| 584 | } | 616 | } |
| ... | @@ -635,12 +667,14 @@ fn writeStub(self: *Zld, index: u32) !void { | ... | @@ -635,12 +667,14 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 635 | }, | 667 | }, |
| 636 | .aarch64 => { | 668 | .aarch64 => { |
| 637 | assert(la_ptr_addr >= stub_addr); | 669 | assert(la_ptr_addr >= stub_addr); |
| 638 | const displacement = try math.divExact(u64, la_ptr_addr - stub_addr, 4); | 670 | const displacement = try math.divExact(u64, la_ptr_addr - stub_addr - @sizeOf(u32), 4); |
| 639 | const literal = try math.cast(u19, displacement); | 671 | const literal = try math.cast(u19, displacement); |
| | 672 | // nop |
| | 673 | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.nop().toU32()); |
| 640 | // ldr x16, literal | 674 | // ldr x16, literal |
| 641 | mem.writeIntLittle(u32, code[0..4], Arm64.ldr(16, literal, 1).toU32()); | 675 | mem.writeIntLittle(u32, code[4..8], Arm64.ldr(16, literal, 1).toU32()); |
| 642 | // br x16 | 676 | // br x16 |
| 643 | mem.writeIntLittle(u32, code[4..8], Arm64.br(16).toU32()); | 677 | mem.writeIntLittle(u32, code[8..12], Arm64.br(16).toU32()); |
| 644 | }, | 678 | }, |
| 645 | else => unreachable, | 679 | else => unreachable, |
| 646 | } | 680 | } |
| ... | @@ -722,7 +756,8 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -722,7 +756,8 @@ fn resolveSymbols(self: *Zld) !void { |
| 722 | const sym_name = object.getString(sym.n_strx); | 756 | const sym_name = object.getString(sym.n_strx); |
| 723 | | 757 | |
| 724 | if (isLocal(&sym) and self.locals.get(sym_name) != null) { | 758 | if (isLocal(&sym) and self.locals.get(sym_name) != null) { |
| 725 | log.warn("symbol '{s}' already exists; skipping", .{sym_name}); | 759 | log.warn("local symbol '{s}' defined multiple times; removing", .{sym_name}); |
| | 760 | self.locals.swapRemoveAssertDiscard(sym_name); |
| 726 | continue; | 761 | continue; |
| 727 | } | 762 | } |
| 728 | | 763 | |
| ... | @@ -978,12 +1013,6 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -978,12 +1013,6 @@ fn doRelocs(self: *Zld) !void { |
| 978 | const this_page = @intCast(i32, this_addr >> 12); | 1013 | const this_page = @intCast(i32, this_addr >> 12); |
| 979 | const target_page = @intCast(i32, ta >> 12); | 1014 | const target_page = @intCast(i32, ta >> 12); |
| 980 | const pages = @bitCast(u21, @intCast(i21, target_page - this_page)); | 1015 | const pages = @bitCast(u21, @intCast(i21, target_page - this_page)); |
| 981 | if (pages == 0) { | | |
| 982 | // No need to execute adrp. Instead, replace with a nop. | | |
| 983 | log.warn(" | replacing ADRP with NOP", .{}); | | |
| 984 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); | | |
| 985 | continue; | | |
| 986 | } | | |
| 987 | log.warn(" | moving by {} pages", .{pages}); | 1016 | log.warn(" | moving by {} pages", .{pages}); |
| 988 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Address), inst); | 1017 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Address), inst); |
| 989 | parsed.immhi = @truncate(u19, pages >> 2); | 1018 | parsed.immhi = @truncate(u19, pages >> 2); |
| ... | @@ -1000,12 +1029,6 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1000,12 +1029,6 @@ fn doRelocs(self: *Zld) !void { |
| 1000 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); | 1029 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.Add), inst); |
| 1001 | const ta = if (addend) |a| target_addr + a else target_addr; | 1030 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 1002 | const narrowed = @truncate(u12, ta); | 1031 | const narrowed = @truncate(u12, ta); |
| 1003 | if (narrowed == 0) { | | |
| 1004 | // No need to execute add. Instead, replace with a nop. | | |
| 1005 | log.warn(" | replacing ADD with NOP", .{}); | | |
| 1006 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); | | |
| 1007 | continue; | | |
| 1008 | } | | |
| 1009 | parsed.offset = narrowed; | 1032 | parsed.offset = narrowed; |
| 1010 | } else { | 1033 | } else { |
| 1011 | log.warn(" | detected LDR/STR opcode", .{}); | 1034 | log.warn(" | detected LDR/STR opcode", .{}); |
| ... | @@ -1013,20 +1036,18 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1013,20 +1036,18 @@ fn doRelocs(self: *Zld) !void { |
| 1013 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); | 1036 | var parsed = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); |
| 1014 | const ta = if (addend) |a| target_addr + a else target_addr; | 1037 | const ta = if (addend) |a| target_addr + a else target_addr; |
| 1015 | const narrowed = @truncate(u12, ta); | 1038 | const narrowed = @truncate(u12, ta); |
| 1016 | if (narrowed == 0) { | 1039 | const offset: u12 = blk: { |
| 1017 | // No need to execute ldr/str. Instead, replace with a nop. | 1040 | if (parsed.size == 0) { |
| 1018 | log.warn(" | replacing LDR/STR with NOP", .{}); | 1041 | break :blk narrowed; |
| 1019 | mem.writeIntLittle(u32, inst, aarch64.Instruction.nop().toU32()); | 1042 | } else { |
| 1020 | continue; | 1043 | const denom: u4 = try math.powi(u4, 2, parsed.size); |
| 1021 | } | 1044 | const offf = math.divExact(u12, narrowed, denom) catch |_| { |
| 1022 | const denom: u12 = if (parsed.size == 1) 8 else 4; | 1045 | log.warn(" | narrowed 0x{x}", .{narrowed}); |
| 1023 | const offset = math.divExact(u12, narrowed, denom) catch |_| { | 1046 | log.warn(" | denom 0x{x}", .{denom}); |
| 1024 | // If we are here, then this means we are not able to divide the offset | 1047 | continue; |
| 1025 | // exactly by the required denominator. Therefore, we will use add instead of | 1048 | }; |
| 1026 | // ldr as we expect ldr to follow this instruction nonetheless. | 1049 | break :blk offf; |
| 1027 | // TODO I believe ldr/str can only occur for GOT_LOAD_PAGEOFF12. | 1050 | } |
| 1028 | mem.writeIntLittle(u32, inst, Arm64.add(parsed.rn, parsed.rn, narrowed, parsed.size).toU32()); | | |
| 1029 | continue; | | |
| 1030 | }; | 1051 | }; |
| 1031 | parsed.offset = offset; | 1052 | parsed.offset = offset; |
| 1032 | } | 1053 | } |
| ... | @@ -1046,7 +1067,7 @@ fn doRelocs(self: *Zld) !void { | ... | @@ -1046,7 +1067,7 @@ fn doRelocs(self: *Zld) !void { |
| 1046 | break :blk .{ .rt = curr.rt, .rn = curr.rn, .size = curr.size }; | 1067 | break :blk .{ .rt = curr.rt, .rn = curr.rn, .size = curr.size }; |
| 1047 | } else { | 1068 | } else { |
| 1048 | const curr = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); | 1069 | const curr = mem.bytesAsValue(meta.TagPayload(Arm64, Arm64.LoadRegister), inst); |
| 1049 | break :blk .{ .rt = curr.rt, .rn = curr.rn, .size = curr.size }; | 1070 | break :blk .{ .rt = curr.rt, .rn = curr.rn, .size = @truncate(u1, curr.size) }; |
| 1050 | } | 1071 | } |
| 1051 | }; | 1072 | }; |
| 1052 | const ta = if (addend) |a| target_addr + a else target_addr; | 1073 | const ta = if (addend) |a| target_addr + a else target_addr; |
| ... | @@ -1145,6 +1166,7 @@ fn relocTargetAddr(self: *Zld, object: Object, rel: macho.relocation_info, next_ | ... | @@ -1145,6 +1166,7 @@ fn relocTargetAddr(self: *Zld, object: Object, rel: macho.relocation_info, next_ |
| 1145 | .segname = source_sect.segname, | 1166 | .segname = source_sect.segname, |
| 1146 | .sectname = source_sect.sectname, | 1167 | .sectname = source_sect.sectname, |
| 1147 | }).?; | 1168 | }).?; |
| | 1169 | log.warn(" | symbol local to object", .{}); |
| 1148 | break :blk target_space.address + sym.n_value - source_sect.addr; | 1170 | break :blk target_space.address + sym.n_value - source_sect.addr; |
| 1149 | } else if (isImport(&sym)) { | 1171 | } else if (isImport(&sym)) { |
| 1150 | // Relocate to either the artifact's local symbol, or an import from | 1172 | // Relocate to either the artifact's local symbol, or an import from |
| ... | @@ -1267,7 +1289,7 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -1267,7 +1289,7 @@ fn populateMetadata(self: *Zld) !void { |
| 1267 | }; | 1289 | }; |
| 1268 | const stub_size: u4 = switch (self.arch.?) { | 1290 | const stub_size: u4 = switch (self.arch.?) { |
| 1269 | .x86_64 => 6, | 1291 | .x86_64 => 6, |
| 1270 | .aarch64 => 2 * @sizeOf(u32), | 1292 | .aarch64 => 3 * @sizeOf(u32), |
| 1271 | else => unreachable, // unhandled architecture type | 1293 | else => unreachable, // unhandled architecture type |
| 1272 | }; | 1294 | }; |
| 1273 | try text_seg.append(self.allocator, .{ | 1295 | try text_seg.append(self.allocator, .{ |
| ... | @@ -1298,7 +1320,7 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -1298,7 +1320,7 @@ fn populateMetadata(self: *Zld) !void { |
| 1298 | .aarch64 => 2, | 1320 | .aarch64 => 2, |
| 1299 | else => unreachable, // unhandled architecture type | 1321 | else => unreachable, // unhandled architecture type |
| 1300 | }; | 1322 | }; |
| 1301 | const stub_helper_size: u5 = switch (self.arch.?) { | 1323 | const stub_helper_size: u6 = switch (self.arch.?) { |
| 1302 | .x86_64 => 15, | 1324 | .x86_64 => 15, |
| 1303 | .aarch64 => 6 * @sizeOf(u32), | 1325 | .aarch64 => 6 * @sizeOf(u32), |
| 1304 | else => unreachable, | 1326 | else => unreachable, |