| ... | @@ -209,10 +209,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { | ... | @@ -209,10 +209,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 209 | try self.allocateDataSegment(); | 209 | try self.allocateDataSegment(); |
| 210 | self.allocateLinkeditSegment(); | 210 | self.allocateLinkeditSegment(); |
| 211 | try self.allocateSymbols(); | 211 | try self.allocateSymbols(); |
| 212 | return error.Unfinished; | 212 | try self.writeStubHelperCommon(); |
| 213 | // try self.writeStubHelperCommon(); | 213 | try self.resolveRelocsAndWriteSections(); |
| 214 | // try self.resolveRelocsAndWriteSections(); | 214 | try self.flush(); |
| 215 | // try self.flush(); | | |
| 216 | } | 215 | } |
| 217 | | 216 | |
| 218 | fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | 217 | fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| ... | @@ -268,7 +267,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -268,7 +267,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 268 | continue; | 267 | continue; |
| 269 | } | 268 | } |
| 270 | | 269 | |
| 271 | log.debug("unexpected input file of unknown type '{s}'", .{file_name}); | 270 | log.warn("unexpected input file of unknown type '{s}'", .{file_name}); |
| 272 | } | 271 | } |
| 273 | | 272 | |
| 274 | // Based on our classification, proceed with parsing. | 273 | // Based on our classification, proceed with parsing. |
| ... | @@ -326,7 +325,7 @@ fn mapAndUpdateSections( | ... | @@ -326,7 +325,7 @@ fn mapAndUpdateSections( |
| 326 | .target_sect_id = target_sect_id, | 325 | .target_sect_id = target_sect_id, |
| 327 | .offset = @intCast(u32, offset), | 326 | .offset = @intCast(u32, offset), |
| 328 | }); | 327 | }); |
| 329 | log.debug("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{ | 328 | log.warn("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{ |
| 330 | object.name, | 329 | object.name, |
| 331 | parseName(&source_sect.segname), | 330 | parseName(&source_sect.segname), |
| 332 | parseName(&source_sect.sectname), | 331 | parseName(&source_sect.sectname), |
| ... | @@ -556,7 +555,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -556,7 +555,7 @@ fn updateMetadata(self: *Zld) !void { |
| 556 | }); | 555 | }); |
| 557 | }, | 556 | }, |
| 558 | else => { | 557 | else => { |
| 559 | log.debug("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); | 558 | log.warn("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); |
| 560 | }, | 559 | }, |
| 561 | } | 560 | } |
| 562 | } | 561 | } |
| ... | @@ -581,7 +580,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -581,7 +580,7 @@ fn updateMetadata(self: *Zld) !void { |
| 581 | const segname = parseName(&source_sect.segname); | 580 | const segname = parseName(&source_sect.segname); |
| 582 | const sectname = parseName(&source_sect.sectname); | 581 | const sectname = parseName(&source_sect.sectname); |
| 583 | | 582 | |
| 584 | log.debug("section '{s}/{s}' will be unmapped", .{ segname, sectname }); | 583 | log.warn("section '{s}/{s}' will be unmapped", .{ segname, sectname }); |
| 585 | | 584 | |
| 586 | try self.unhandled_sections.putNoClobber(self.allocator, .{ | 585 | try self.unhandled_sections.putNoClobber(self.allocator, .{ |
| 587 | .object_id = object_id, | 586 | .object_id = object_id, |
| ... | @@ -978,8 +977,8 @@ fn writeStubHelperCommon(self: *Zld) !void { | ... | @@ -978,8 +977,8 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 978 | code[9] = 0xff; | 977 | code[9] = 0xff; |
| 979 | code[10] = 0x25; | 978 | code[10] = 0x25; |
| 980 | { | 979 | { |
| 981 | const dyld_stub_binder = self.got_entries.get("dyld_stub_binder").?; | 980 | const dyld_stub_binder = self.imports.get("dyld_stub_binder").?; |
| 982 | const addr = (got.addr + dyld_stub_binder.index * @sizeOf(u64)); | 981 | const addr = (got.addr + dyld_stub_binder.got_index.? * @sizeOf(u64)); |
| 983 | const displacement = try math.cast(u32, addr - stub_helper.addr - code_size); | 982 | const displacement = try math.cast(u32, addr - stub_helper.addr - code_size); |
| 984 | mem.writeIntLittle(u32, code[11..], displacement); | 983 | mem.writeIntLittle(u32, code[11..], displacement); |
| 985 | } | 984 | } |
| ... | @@ -1022,9 +1021,9 @@ fn writeStubHelperCommon(self: *Zld) !void { | ... | @@ -1022,9 +1021,9 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 1022 | code[10] = 0xbf; | 1021 | code[10] = 0xbf; |
| 1023 | code[11] = 0xa9; | 1022 | code[11] = 0xa9; |
| 1024 | binder_blk_outer: { | 1023 | binder_blk_outer: { |
| 1025 | const dyld_stub_binder = self.got_entries.get("dyld_stub_binder").?; | 1024 | const dyld_stub_binder = self.imports.get("dyld_stub_binder").?; |
| 1026 | const this_addr = stub_helper.addr + 3 * @sizeOf(u32); | 1025 | const this_addr = stub_helper.addr + 3 * @sizeOf(u32); |
| 1027 | const target_addr = (got.addr + dyld_stub_binder.index * @sizeOf(u64)); | 1026 | const target_addr = (got.addr + dyld_stub_binder.got_index.? * @sizeOf(u64)); |
| 1028 | binder_blk: { | 1027 | binder_blk: { |
| 1029 | const displacement = math.divExact(u64, target_addr - this_addr, 4) catch |_| break :binder_blk; | 1028 | const displacement = math.divExact(u64, target_addr - this_addr, 4) catch |_| break :binder_blk; |
| 1030 | const literal = math.cast(u18, displacement) catch |_| break :binder_blk; | 1029 | const literal = math.cast(u18, displacement) catch |_| break :binder_blk; |
| ... | @@ -1075,8 +1074,9 @@ fn writeStubHelperCommon(self: *Zld) !void { | ... | @@ -1075,8 +1074,9 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 1075 | } | 1074 | } |
| 1076 | }; | 1075 | }; |
| 1077 | | 1076 | |
| 1078 | for (self.stubs.items()) |entry| { | 1077 | for (self.stubs.items) |sym| { |
| 1079 | const index = entry.value; | 1078 | // TODO weak bound pointers |
| | 1079 | const index = sym.stubs_index orelse unreachable; |
| 1080 | try self.writeLazySymbolPointer(index); | 1080 | try self.writeLazySymbolPointer(index); |
| 1081 | try self.writeStub(index); | 1081 | try self.writeStub(index); |
| 1082 | try self.writeStubInStubHelper(index); | 1082 | try self.writeStubInStubHelper(index); |
| ... | @@ -1099,7 +1099,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { | ... | @@ -1099,7 +1099,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 1099 | var buf: [@sizeOf(u64)]u8 = undefined; | 1099 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 1100 | mem.writeIntLittle(u64, &buf, end); | 1100 | mem.writeIntLittle(u64, &buf, end); |
| 1101 | const off = la_symbol_ptr.offset + index * @sizeOf(u64); | 1101 | const off = la_symbol_ptr.offset + index * @sizeOf(u64); |
| 1102 | log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); | 1102 | log.warn("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 1103 | try self.file.?.pwriteAll(&buf, off); | 1103 | try self.file.?.pwriteAll(&buf, off); |
| 1104 | } | 1104 | } |
| 1105 | | 1105 | |
| ... | @@ -1112,7 +1112,7 @@ fn writeStub(self: *Zld, index: u32) !void { | ... | @@ -1112,7 +1112,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 1112 | const stub_off = stubs.offset + index * stubs.reserved2; | 1112 | const stub_off = stubs.offset + index * stubs.reserved2; |
| 1113 | const stub_addr = stubs.addr + index * stubs.reserved2; | 1113 | const stub_addr = stubs.addr + index * stubs.reserved2; |
| 1114 | const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64); | 1114 | const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64); |
| 1115 | log.debug("writing stub at 0x{x}", .{stub_off}); | 1115 | log.warn("writing stub at 0x{x}", .{stub_off}); |
| 1116 | var code = try self.allocator.alloc(u8, stubs.reserved2); | 1116 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 1117 | defer self.allocator.free(code); | 1117 | defer self.allocator.free(code); |
| 1118 | switch (self.arch.?) { | 1118 | switch (self.arch.?) { |
| ... | @@ -1413,7 +1413,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1413,7 +1413,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1413 | | 1413 | |
| 1414 | fn resolveRelocsAndWriteSections(self: *Zld) !void { | 1414 | fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1415 | for (self.objects.items) |object, object_id| { | 1415 | for (self.objects.items) |object, object_id| { |
| 1416 | log.debug("relocating object {s}", .{object.name}); | 1416 | log.warn("relocating object {s}", .{object.name}); |
| 1417 | | 1417 | |
| 1418 | for (object.sections.items) |sect, source_sect_id| { | 1418 | for (object.sections.items) |sect, source_sect_id| { |
| 1419 | if (sect.inner.flags == macho.S_MOD_INIT_FUNC_POINTERS or | 1419 | if (sect.inner.flags == macho.S_MOD_INIT_FUNC_POINTERS or |
| ... | @@ -1422,14 +1422,14 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1422,14 +1422,14 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1422 | const segname = parseName(&sect.inner.segname); | 1422 | const segname = parseName(&sect.inner.segname); |
| 1423 | const sectname = parseName(&sect.inner.sectname); | 1423 | const sectname = parseName(&sect.inner.sectname); |
| 1424 | | 1424 | |
| 1425 | log.debug("relocating section '{s},{s}'", .{ segname, sectname }); | 1425 | log.warn("relocating section '{s},{s}'", .{ segname, sectname }); |
| 1426 | | 1426 | |
| 1427 | // Get mapping | 1427 | // Get mapping |
| 1428 | const target_mapping = self.mappings.get(.{ | 1428 | const target_mapping = self.mappings.get(.{ |
| 1429 | .object_id = @intCast(u16, object_id), | 1429 | .object_id = @intCast(u16, object_id), |
| 1430 | .source_sect_id = @intCast(u16, source_sect_id), | 1430 | .source_sect_id = @intCast(u16, source_sect_id), |
| 1431 | }) orelse { | 1431 | }) orelse { |
| 1432 | log.debug("no mapping for {s},{s}; skipping", .{ segname, sectname }); | 1432 | log.warn("no mapping for {s},{s}; skipping", .{ segname, sectname }); |
| 1433 | continue; | 1433 | continue; |
| 1434 | }; | 1434 | }; |
| 1435 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; | 1435 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| ... | @@ -1482,11 +1482,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1482,11 +1482,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1482 | // TLV is handled via a separate offset mechanism. | 1482 | // TLV is handled via a separate offset mechanism. |
| 1483 | // Calculate the offset to the initializer. | 1483 | // Calculate the offset to the initializer. |
| 1484 | if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { | 1484 | if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { |
| 1485 | const sym = object.symtab.items[rel.target.symbol]; | | |
| 1486 | const sym_name = object.getString(sym.n_strx); | | |
| 1487 | | | |
| 1488 | // TODO we don't want to save offset to tlv_bootstrap | 1485 | // TODO we don't want to save offset to tlv_bootstrap |
| 1489 | if (mem.eql(u8, sym_name, "__tlv_bootstrap")) break :tlv; | 1486 | if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv; |
| 1490 | | 1487 | |
| 1491 | const base_addr = blk: { | 1488 | const base_addr = blk: { |
| 1492 | if (self.tlv_data_section_index) |index| { | 1489 | if (self.tlv_data_section_index) |index| { |
| ... | @@ -1505,10 +1502,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1505,10 +1502,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1505 | .got_page, .got_page_off, .got_load, .got => { | 1502 | .got_page, .got_page_off, .got_load, .got => { |
| 1506 | const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 1503 | const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1507 | const got = dc_seg.sections.items[self.got_section_index.?]; | 1504 | const got = dc_seg.sections.items[self.got_section_index.?]; |
| 1508 | const sym = object.symtab.items[rel.target.symbol]; | 1505 | const final = rel.target.symbol.getTopmostAlias(); |
| 1509 | const sym_name = object.getString(sym.n_strx); | 1506 | args.target_addr = got.addr + final.got_index.? * @sizeOf(u64); |
| 1510 | const entry = self.got_entries.get(sym_name) orelse unreachable; | | |
| 1511 | args.target_addr = got.addr + entry.index * @sizeOf(u64); | | |
| 1512 | }, | 1507 | }, |
| 1513 | else => |tt| { | 1508 | else => |tt| { |
| 1514 | if (tt == .signed and rel.target == .section) { | 1509 | if (tt == .signed and rel.target == .section) { |
| ... | @@ -1523,7 +1518,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1523,7 +1518,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1523 | } | 1518 | } |
| 1524 | } | 1519 | } |
| 1525 | | 1520 | |
| 1526 | log.debug("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ | 1521 | log.warn("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ |
| 1527 | segname, | 1522 | segname, |
| 1528 | sectname, | 1523 | sectname, |
| 1529 | object.name, | 1524 | object.name, |
| ... | @@ -1535,7 +1530,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1535,7 +1530,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1535 | target_sect.flags == macho.S_THREAD_LOCAL_ZEROFILL or | 1530 | target_sect.flags == macho.S_THREAD_LOCAL_ZEROFILL or |
| 1536 | target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) | 1531 | target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) |
| 1537 | { | 1532 | { |
| 1538 | log.debug("zeroing out '{s},{s}' from 0x{x} to 0x{x}", .{ | 1533 | log.warn("zeroing out '{s},{s}' from 0x{x} to 0x{x}", .{ |
| 1539 | parseName(&target_sect.segname), | 1534 | parseName(&target_sect.segname), |
| 1540 | parseName(&target_sect.sectname), | 1535 | parseName(&target_sect.sectname), |
| 1541 | target_sect_off, | 1536 | target_sect_off, |
| ... | @@ -1555,58 +1550,27 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1555,58 +1550,27 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1555 | } | 1550 | } |
| 1556 | | 1551 | |
| 1557 | fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) !u64 { | 1552 | fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) !u64 { |
| 1558 | const object = self.objects.items[object_id]; | | |
| 1559 | const target_addr = blk: { | 1553 | const target_addr = blk: { |
| 1560 | switch (target) { | 1554 | switch (target) { |
| 1561 | .symbol => |sym_id| { | 1555 | .symbol => |sym| { |
| 1562 | const sym = object.symtab.items[sym_id]; | 1556 | const final = sym.getTopmostAlias(); |
| 1563 | const sym_name = object.getString(sym.n_strx); | 1557 | if (final.cast(Symbol.Regular)) |reg| { |
| 1564 | | 1558 | log.warn(" | regular '{s}'", .{sym.name}); |
| 1565 | if (Symbol.isSect(sym)) { | 1559 | break :blk reg.address; |
| 1566 | log.debug(" | local symbol '{s}'", .{sym_name}); | 1560 | } else if (final.cast(Symbol.Proxy)) |proxy| { |
| 1567 | if (object.locals.get(sym_name)) |local| { | 1561 | if (mem.eql(u8, sym.name, "__tlv_bootstrap")) { |
| 1568 | break :blk local.address; | 1562 | log.warn(" | symbol '__tlv_bootstrap'", .{}); |
| 1569 | } | 1563 | const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1570 | // For temp locals, i.e., symbols prefixed with l... we relocate | 1564 | const tlv = segment.sections.items[self.tlv_section_index.?]; |
| 1571 | // based on section addressing. | 1565 | break :blk tlv.addr; |
| 1572 | const source_sect_id = sym.n_sect - 1; | | |
| 1573 | const target_mapping = self.mappings.get(.{ | | |
| 1574 | .object_id = object_id, | | |
| 1575 | .source_sect_id = source_sect_id, | | |
| 1576 | }) orelse unreachable; | | |
| 1577 | | | |
| 1578 | const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment; | | |
| 1579 | const source_sect = source_seg.sections.items[source_sect_id]; | | |
| 1580 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; | | |
| 1581 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; | | |
| 1582 | const target_addr = target_sect.addr + target_mapping.offset; | | |
| 1583 | break :blk sym.n_value - source_sect.addr + target_addr; | | |
| 1584 | } else if (self.symtab.get(sym_name)) |global| { | | |
| 1585 | switch (global.tag) { | | |
| 1586 | .weak, .strong => { | | |
| 1587 | log.debug(" | global symbol '{s}'", .{sym_name}); | | |
| 1588 | break :blk global.address; | | |
| 1589 | }, | | |
| 1590 | .import => { | | |
| 1591 | if (self.stubs.get(sym_name)) |index| { | | |
| 1592 | log.debug(" | symbol stub '{s}'", .{sym_name}); | | |
| 1593 | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | | |
| 1594 | const stubs = segment.sections.items[self.stubs_section_index.?]; | | |
| 1595 | break :blk stubs.addr + index * stubs.reserved2; | | |
| 1596 | } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { | | |
| 1597 | log.debug(" | symbol '__tlv_bootstrap'", .{}); | | |
| 1598 | const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 1599 | const tlv = segment.sections.items[self.tlv_section_index.?]; | | |
| 1600 | break :blk tlv.addr; | | |
| 1601 | } else { | | |
| 1602 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); | | |
| 1603 | return error.FailedToResolveRelocationTarget; | | |
| 1604 | } | | |
| 1605 | }, | | |
| 1606 | else => unreachable, | | |
| 1607 | } | 1566 | } |
| | 1567 | |
| | 1568 | log.warn(" | symbol stub '{s}'", .{sym.name}); |
| | 1569 | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| | 1570 | const stubs = segment.sections.items[self.stubs_section_index.?]; |
| | 1571 | break :blk stubs.addr + proxy.base.stubs_index.? * stubs.reserved2; |
| 1608 | } else { | 1572 | } else { |
| 1609 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); | 1573 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym.name}); |
| 1610 | return error.FailedToResolveRelocationTarget; | 1574 | return error.FailedToResolveRelocationTarget; |
| 1611 | } | 1575 | } |
| 1612 | }, | 1576 | }, |
| ... | @@ -2071,10 +2035,10 @@ fn flush(self: *Zld) !void { | ... | @@ -2071,10 +2035,10 @@ fn flush(self: *Zld) !void { |
| 2071 | var initializers = std.ArrayList(u64).init(self.allocator); | 2035 | var initializers = std.ArrayList(u64).init(self.allocator); |
| 2072 | defer initializers.deinit(); | 2036 | defer initializers.deinit(); |
| 2073 | | 2037 | |
| 2074 | // TODO sort the initializers globally | | |
| 2075 | for (self.objects.items) |object| { | 2038 | for (self.objects.items) |object| { |
| 2076 | for (object.initializers.items) |initializer| { | 2039 | for (object.initializers.items) |initializer| { |
| 2077 | try initializers.append(initializer.target_addr); | 2040 | const address = initializer.cast(Symbol.Regular).?.address; |
| | 2041 | try initializers.append(address); |
| 2078 | } | 2042 | } |
| 2079 | } | 2043 | } |
| 2080 | | 2044 | |
| ... | @@ -2128,17 +2092,18 @@ fn writeGotEntries(self: *Zld) !void { | ... | @@ -2128,17 +2092,18 @@ fn writeGotEntries(self: *Zld) !void { |
| 2128 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2092 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2129 | const sect = seg.sections.items[self.got_section_index.?]; | 2093 | const sect = seg.sections.items[self.got_section_index.?]; |
| 2130 | | 2094 | |
| 2131 | var buffer = try self.allocator.alloc(u8, self.got_entries.items().len * @sizeOf(u64)); | 2095 | var buffer = try self.allocator.alloc(u8, self.got_entries.items.len * @sizeOf(u64)); |
| 2132 | defer self.allocator.free(buffer); | 2096 | defer self.allocator.free(buffer); |
| 2133 | | 2097 | |
| 2134 | var stream = std.io.fixedBufferStream(buffer); | 2098 | var stream = std.io.fixedBufferStream(buffer); |
| 2135 | var writer = stream.writer(); | 2099 | var writer = stream.writer(); |
| 2136 | | 2100 | |
| 2137 | for (self.got_entries.items()) |entry| { | 2101 | for (self.got_entries.items) |sym| { |
| 2138 | try writer.writeIntLittle(u64, entry.value.target_addr); | 2102 | const address: u64 = if (sym.cast(Symbol.Regular)) |reg| reg.address else 0; |
| | 2103 | try writer.writeIntLittle(u64, address); |
| 2139 | } | 2104 | } |
| 2140 | | 2105 | |
| 2141 | log.debug("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len }); | 2106 | log.warn("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len }); |
| 2142 | | 2107 | |
| 2143 | try self.file.?.pwriteAll(buffer, sect.offset); | 2108 | try self.file.?.pwriteAll(buffer, sect.offset); |
| 2144 | } | 2109 | } |
| ... | @@ -2148,7 +2113,8 @@ fn setEntryPoint(self: *Zld) !void { | ... | @@ -2148,7 +2113,8 @@ fn setEntryPoint(self: *Zld) !void { |
| 2148 | // entrypoint. For now, assume default of `_main`. | 2113 | // entrypoint. For now, assume default of `_main`. |
| 2149 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2114 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2150 | const text = seg.sections.items[self.text_section_index.?]; | 2115 | const text = seg.sections.items[self.text_section_index.?]; |
| 2151 | const entry_sym = self.symtab.get("_main") orelse return error.MissingMainEntrypoint; | 2116 | const sym = self.globals.get("_main") orelse return error.MissingMainEntrypoint; |
| | 2117 | const entry_sym = sym.cast(Symbol.Regular) orelse unreachable; |
| 2152 | const ec = &self.load_commands.items[self.main_cmd_index.?].Main; | 2118 | const ec = &self.load_commands.items[self.main_cmd_index.?].Main; |
| 2153 | ec.entryoff = @intCast(u32, entry_sym.address - seg.inner.vmaddr); | 2119 | ec.entryoff = @intCast(u32, entry_sym.address - seg.inner.vmaddr); |
| 2154 | } | 2120 | } |
| ... | @@ -2161,24 +2127,21 @@ fn writeRebaseInfoTable(self: *Zld) !void { | ... | @@ -2161,24 +2127,21 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 2161 | pointers.appendSliceAssumeCapacity(self.local_rebases.items); | 2127 | pointers.appendSliceAssumeCapacity(self.local_rebases.items); |
| 2162 | | 2128 | |
| 2163 | if (self.got_section_index) |idx| { | 2129 | if (self.got_section_index) |idx| { |
| 2164 | // TODO this should be cleaned up! | | |
| 2165 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2130 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2166 | const sect = seg.sections.items[idx]; | 2131 | const sect = seg.sections.items[idx]; |
| 2167 | const base_offset = sect.addr - seg.inner.vmaddr; | 2132 | const base_offset = sect.addr - seg.inner.vmaddr; |
| 2168 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); | 2133 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| 2169 | | 2134 | |
| 2170 | for (self.got_entries.items()) |entry| { | 2135 | for (self.got_entries.items) |sym| { |
| 2171 | if (entry.value.tag == .import) continue; | 2136 | if (sym.@"type" == .proxy) continue; |
| 2172 | | | |
| 2173 | try pointers.append(.{ | 2137 | try pointers.append(.{ |
| 2174 | .offset = base_offset + entry.value.index * @sizeOf(u64), | 2138 | .offset = base_offset + sym.got_index.? * @sizeOf(u64), |
| 2175 | .segment_id = segment_id, | 2139 | .segment_id = segment_id, |
| 2176 | }); | 2140 | }); |
| 2177 | } | 2141 | } |
| 2178 | } | 2142 | } |
| 2179 | | 2143 | |
| 2180 | if (self.mod_init_func_section_index) |idx| { | 2144 | if (self.mod_init_func_section_index) |idx| { |
| 2181 | // TODO audit and investigate this. | | |
| 2182 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2145 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2183 | const sect = seg.sections.items[idx]; | 2146 | const sect = seg.sections.items[idx]; |
| 2184 | const base_offset = sect.addr - seg.inner.vmaddr; | 2147 | const base_offset = sect.addr - seg.inner.vmaddr; |
| ... | @@ -2202,10 +2165,10 @@ fn writeRebaseInfoTable(self: *Zld) !void { | ... | @@ -2202,10 +2165,10 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 2202 | const base_offset = sect.addr - seg.inner.vmaddr; | 2165 | const base_offset = sect.addr - seg.inner.vmaddr; |
| 2203 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); | 2166 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); |
| 2204 | | 2167 | |
| 2205 | try pointers.ensureCapacity(pointers.items.len + self.stubs.items().len); | 2168 | try pointers.ensureCapacity(pointers.items.len + self.stubs.items.len); |
| 2206 | for (self.stubs.items()) |entry| { | 2169 | for (self.stubs.items) |sym| { |
| 2207 | pointers.appendAssumeCapacity(.{ | 2170 | pointers.appendAssumeCapacity(.{ |
| 2208 | .offset = base_offset + entry.value * @sizeOf(u64), | 2171 | .offset = base_offset + sym.stubs_index.? * @sizeOf(u64), |
| 2209 | .segment_id = segment_id, | 2172 | .segment_id = segment_id, |
| 2210 | }); | 2173 | }); |
| 2211 | } | 2174 | } |
| ... | @@ -2226,7 +2189,7 @@ fn writeRebaseInfoTable(self: *Zld) !void { | ... | @@ -2226,7 +2189,7 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 2226 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); | 2189 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); |
| 2227 | seg.inner.filesize += dyld_info.rebase_size; | 2190 | seg.inner.filesize += dyld_info.rebase_size; |
| 2228 | | 2191 | |
| 2229 | log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); | 2192 | log.warn("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); |
| 2230 | | 2193 | |
| 2231 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); | 2194 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); |
| 2232 | } | 2195 | } |
| ... | @@ -2241,21 +2204,16 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2241,21 +2204,16 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2241 | const base_offset = sect.addr - seg.inner.vmaddr; | 2204 | const base_offset = sect.addr - seg.inner.vmaddr; |
| 2242 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); | 2205 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| 2243 | | 2206 | |
| 2244 | for (self.got_entries.items()) |entry| { | 2207 | for (self.got_entries.items) |sym| { |
| 2245 | if (entry.value.tag == .local) continue; | 2208 | if (sym.cast(Symbol.Proxy)) |proxy| { |
| 2246 | | 2209 | const dylib_ordinal = proxy.dylib + 1; |
| 2247 | const dylib_ordinal = dylib_ordinal: { | 2210 | try pointers.append(.{ |
| 2248 | const sym = self.symtab.get(entry.key) orelse continue; // local indirection | 2211 | .offset = base_offset + proxy.base.got_index.? * @sizeOf(u64), |
| 2249 | if (sym.tag != .import) continue; // local indirection | 2212 | .segment_id = segment_id, |
| 2250 | break :dylib_ordinal sym.file.? + 1; | 2213 | .dylib_ordinal = dylib_ordinal, |
| 2251 | }; | 2214 | .name = proxy.base.name, |
| 2252 | | 2215 | }); |
| 2253 | try pointers.append(.{ | 2216 | } |
| 2254 | .offset = base_offset + entry.value.index * @sizeOf(u64), | | |
| 2255 | .segment_id = segment_id, | | |
| 2256 | .dylib_ordinal = dylib_ordinal, | | |
| 2257 | .name = entry.key, | | |
| 2258 | }); | | |
| 2259 | } | 2217 | } |
| 2260 | } | 2218 | } |
| 2261 | | 2219 | |
| ... | @@ -2265,14 +2223,15 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2265,14 +2223,15 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2265 | const base_offset = sect.addr - seg.inner.vmaddr; | 2223 | const base_offset = sect.addr - seg.inner.vmaddr; |
| 2266 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); | 2224 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); |
| 2267 | | 2225 | |
| 2268 | const sym = self.symtab.get("__tlv_bootstrap") orelse unreachable; | 2226 | const sym = self.imports.get("__tlv_bootstrap") orelse unreachable; |
| 2269 | const dylib_ordinal = sym.file.? + 1; | 2227 | const proxy = sym.cast(Symbol.Proxy) orelse unreachable; |
| | 2228 | const dylib_ordinal = proxy.dylib + 1; |
| 2270 | | 2229 | |
| 2271 | try pointers.append(.{ | 2230 | try pointers.append(.{ |
| 2272 | .offset = base_offset, | 2231 | .offset = base_offset, |
| 2273 | .segment_id = segment_id, | 2232 | .segment_id = segment_id, |
| 2274 | .dylib_ordinal = dylib_ordinal, | 2233 | .dylib_ordinal = dylib_ordinal, |
| 2275 | .name = "__tlv_bootstrap", | 2234 | .name = proxy.base.name, |
| 2276 | }); | 2235 | }); |
| 2277 | } | 2236 | } |
| 2278 | | 2237 | |
| ... | @@ -2289,7 +2248,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2289,7 +2248,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2289 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 2248 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2290 | seg.inner.filesize += dyld_info.bind_size; | 2249 | seg.inner.filesize += dyld_info.bind_size; |
| 2291 | | 2250 | |
| 2292 | log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); | 2251 | log.warn("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); |
| 2293 | | 2252 | |
| 2294 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); | 2253 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 2295 | } | 2254 | } |
| ... | @@ -2304,20 +2263,16 @@ fn writeLazyBindInfoTable(self: *Zld) !void { | ... | @@ -2304,20 +2263,16 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 2304 | const base_offset = sect.addr - seg.inner.vmaddr; | 2263 | const base_offset = sect.addr - seg.inner.vmaddr; |
| 2305 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); | 2264 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); |
| 2306 | | 2265 | |
| 2307 | try pointers.ensureCapacity(self.stubs.items().len); | 2266 | try pointers.ensureCapacity(self.stubs.items.len); |
| 2308 | | | |
| 2309 | for (self.stubs.items()) |entry| { | | |
| 2310 | const dylib_ordinal = dylib_ordinal: { | | |
| 2311 | const sym = self.symtab.get(entry.key) orelse unreachable; | | |
| 2312 | assert(sym.tag == .import); | | |
| 2313 | break :dylib_ordinal sym.file.? + 1; | | |
| 2314 | }; | | |
| 2315 | | 2267 | |
| | 2268 | for (self.stubs.items) |sym| { |
| | 2269 | const proxy = sym.cast(Symbol.Proxy) orelse unreachable; |
| | 2270 | const dylib_ordinal = proxy.dylib + 1; |
| 2316 | pointers.appendAssumeCapacity(.{ | 2271 | pointers.appendAssumeCapacity(.{ |
| 2317 | .offset = base_offset + entry.value * @sizeOf(u64), | 2272 | .offset = base_offset + sym.stubs_index.? * @sizeOf(u64), |
| 2318 | .segment_id = segment_id, | 2273 | .segment_id = segment_id, |
| 2319 | .dylib_ordinal = dylib_ordinal, | 2274 | .dylib_ordinal = dylib_ordinal, |
| 2320 | .name = entry.key, | 2275 | .name = sym.name, |
| 2321 | }); | 2276 | }); |
| 2322 | } | 2277 | } |
| 2323 | } | 2278 | } |
| ... | @@ -2335,7 +2290,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { | ... | @@ -2335,7 +2290,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 2335 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 2290 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2336 | seg.inner.filesize += dyld_info.lazy_bind_size; | 2291 | seg.inner.filesize += dyld_info.lazy_bind_size; |
| 2337 | | 2292 | |
| 2338 | log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); | 2293 | log.warn("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); |
| 2339 | | 2294 | |
| 2340 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); | 2295 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); |
| 2341 | try self.populateLazyBindOffsetsInStubHelper(buffer); | 2296 | try self.populateLazyBindOffsetsInStubHelper(buffer); |
| ... | @@ -2386,7 +2341,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { | ... | @@ -2386,7 +2341,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { |
| 2386 | else => {}, | 2341 | else => {}, |
| 2387 | } | 2342 | } |
| 2388 | } | 2343 | } |
| 2389 | assert(self.stubs.items().len <= offsets.items.len); | 2344 | assert(self.stubs.items.len <= offsets.items.len); |
| 2390 | | 2345 | |
| 2391 | const stub_size: u4 = switch (self.arch.?) { | 2346 | const stub_size: u4 = switch (self.arch.?) { |
| 2392 | .x86_64 => 10, | 2347 | .x86_64 => 10, |
| ... | @@ -2399,9 +2354,10 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { | ... | @@ -2399,9 +2354,10 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { |
| 2399 | else => unreachable, | 2354 | else => unreachable, |
| 2400 | }; | 2355 | }; |
| 2401 | var buf: [@sizeOf(u32)]u8 = undefined; | 2356 | var buf: [@sizeOf(u32)]u8 = undefined; |
| 2402 | for (self.stubs.items()) |entry| { | 2357 | for (self.stubs.items) |sym| { |
| 2403 | const placeholder_off = self.stub_helper_stubs_start_off.? + entry.value * stub_size + off; | 2358 | const index = sym.stubs_index orelse unreachable; |
| 2404 | mem.writeIntLittle(u32, &buf, offsets.items[entry.value]); | 2359 | const placeholder_off = self.stub_helper_stubs_start_off.? + index * stub_size + off; |
| | 2360 | mem.writeIntLittle(u32, &buf, offsets.items[index]); |
| 2405 | try self.file.?.pwriteAll(&buf, placeholder_off); | 2361 | try self.file.?.pwriteAll(&buf, placeholder_off); |
| 2406 | } | 2362 | } |
| 2407 | } | 2363 | } |
| ... | @@ -2413,12 +2369,13 @@ fn writeExportInfo(self: *Zld) !void { | ... | @@ -2413,12 +2369,13 @@ fn writeExportInfo(self: *Zld) !void { |
| 2413 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2369 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2414 | | 2370 | |
| 2415 | // TODO export items for dylibs | 2371 | // TODO export items for dylibs |
| 2416 | const sym = self.symtab.get("_main") orelse return error.MissingMainEntrypoint; | 2372 | const sym = self.globals.get("_main") orelse return error.MissingMainEntrypoint; |
| 2417 | assert(sym.address >= text_segment.inner.vmaddr); | 2373 | const reg = sym.cast(Symbol.Regular) orelse unreachable; |
| | 2374 | assert(reg.address >= text_segment.inner.vmaddr); |
| 2418 | | 2375 | |
| 2419 | try trie.put(.{ | 2376 | try trie.put(.{ |
| 2420 | .name = "_main", | 2377 | .name = sym.name, |
| 2421 | .vmaddr_offset = sym.address - text_segment.inner.vmaddr, | 2378 | .vmaddr_offset = reg.address - text_segment.inner.vmaddr, |
| 2422 | .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, | 2379 | .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, |
| 2423 | }); | 2380 | }); |
| 2424 | | 2381 | |
| ... | @@ -2437,7 +2394,7 @@ fn writeExportInfo(self: *Zld) !void { | ... | @@ -2437,7 +2394,7 @@ fn writeExportInfo(self: *Zld) !void { |
| 2437 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); | 2394 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2438 | seg.inner.filesize += dyld_info.export_size; | 2395 | seg.inner.filesize += dyld_info.export_size; |
| 2439 | | 2396 | |
| 2440 | log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); | 2397 | log.warn("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| 2441 | | 2398 | |
| 2442 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); | 2399 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); |
| 2443 | } | 2400 | } |
| ... | @@ -2446,7 +2403,7 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -2446,7 +2403,7 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2446 | var stabs = std.ArrayList(macho.nlist_64).init(self.allocator); | 2403 | var stabs = std.ArrayList(macho.nlist_64).init(self.allocator); |
| 2447 | defer stabs.deinit(); | 2404 | defer stabs.deinit(); |
| 2448 | | 2405 | |
| 2449 | for (self.objects.items) |object, object_id| { | 2406 | for (self.objects.items) |object| { |
| 2450 | const tu_path = object.tu_path orelse continue; | 2407 | const tu_path = object.tu_path orelse continue; |
| 2451 | const tu_mtime = object.tu_mtime orelse continue; | 2408 | const tu_mtime = object.tu_mtime orelse continue; |
| 2452 | const dirname = std.fs.path.dirname(tu_path) orelse "./"; | 2409 | const dirname = std.fs.path.dirname(tu_path) orelse "./"; |
| ... | @@ -2475,39 +2432,42 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -2475,39 +2432,42 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2475 | .n_value = 0, //tu_mtime, TODO figure out why precalculated mtime value doesn't work | 2432 | .n_value = 0, //tu_mtime, TODO figure out why precalculated mtime value doesn't work |
| 2476 | }); | 2433 | }); |
| 2477 | | 2434 | |
| 2478 | for (object.stabs.items) |stab| { | 2435 | for (object.symbols.items) |sym| { |
| 2479 | const entry = object.locals.items()[stab.symbol]; | 2436 | if (sym.@"type" != .regular) continue; |
| 2480 | const sym = entry.value; | 2437 | const reg = sym.cast(Symbol.Regular) orelse unreachable; |
| | 2438 | |
| | 2439 | if (reg.isTemp() or reg.stab == null) continue; |
| | 2440 | const stab = reg.stab orelse unreachable; |
| 2481 | | 2441 | |
| 2482 | switch (stab.tag) { | 2442 | switch (stab.kind) { |
| 2483 | .function => { | 2443 | .function => { |
| 2484 | try stabs.append(.{ | 2444 | try stabs.append(.{ |
| 2485 | .n_strx = 0, | 2445 | .n_strx = 0, |
| 2486 | .n_type = macho.N_BNSYM, | 2446 | .n_type = macho.N_BNSYM, |
| 2487 | .n_sect = sym.section, | 2447 | .n_sect = reg.section, |
| 2488 | .n_desc = 0, | 2448 | .n_desc = 0, |
| 2489 | .n_value = sym.address, | 2449 | .n_value = reg.address, |
| 2490 | }); | 2450 | }); |
| 2491 | try stabs.append(.{ | 2451 | try stabs.append(.{ |
| 2492 | .n_strx = try self.makeString(sym.name), | 2452 | .n_strx = try self.makeString(sym.name), |
| 2493 | .n_type = macho.N_FUN, | 2453 | .n_type = macho.N_FUN, |
| 2494 | .n_sect = sym.section, | 2454 | .n_sect = reg.section, |
| 2495 | .n_desc = 0, | 2455 | .n_desc = 0, |
| 2496 | .n_value = sym.address, | 2456 | .n_value = reg.address, |
| 2497 | }); | 2457 | }); |
| 2498 | try stabs.append(.{ | 2458 | try stabs.append(.{ |
| 2499 | .n_strx = 0, | 2459 | .n_strx = 0, |
| 2500 | .n_type = macho.N_FUN, | 2460 | .n_type = macho.N_FUN, |
| 2501 | .n_sect = 0, | 2461 | .n_sect = 0, |
| 2502 | .n_desc = 0, | 2462 | .n_desc = 0, |
| 2503 | .n_value = stab.size.?, | 2463 | .n_value = stab.size, |
| 2504 | }); | 2464 | }); |
| 2505 | try stabs.append(.{ | 2465 | try stabs.append(.{ |
| 2506 | .n_strx = 0, | 2466 | .n_strx = 0, |
| 2507 | .n_type = macho.N_ENSYM, | 2467 | .n_type = macho.N_ENSYM, |
| 2508 | .n_sect = sym.section, | 2468 | .n_sect = reg.section, |
| 2509 | .n_desc = 0, | 2469 | .n_desc = 0, |
| 2510 | .n_value = stab.size.?, | 2470 | .n_value = stab.size, |
| 2511 | }); | 2471 | }); |
| 2512 | }, | 2472 | }, |
| 2513 | .global => { | 2473 | .global => { |
| ... | @@ -2523,9 +2483,9 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -2523,9 +2483,9 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2523 | try stabs.append(.{ | 2483 | try stabs.append(.{ |
| 2524 | .n_strx = try self.makeString(sym.name), | 2484 | .n_strx = try self.makeString(sym.name), |
| 2525 | .n_type = macho.N_STSYM, | 2485 | .n_type = macho.N_STSYM, |
| 2526 | .n_sect = sym.section, | 2486 | .n_sect = reg.section, |
| 2527 | .n_desc = 0, | 2487 | .n_desc = 0, |
| 2528 | .n_value = sym.address, | 2488 | .n_value = reg.address, |
| 2529 | }); | 2489 | }); |
| 2530 | }, | 2490 | }, |
| 2531 | } | 2491 | } |
| ... | @@ -2551,7 +2511,7 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -2551,7 +2511,7 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2551 | | 2511 | |
| 2552 | const stabs_off = symtab.symoff; | 2512 | const stabs_off = symtab.symoff; |
| 2553 | const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64); | 2513 | const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2554 | log.debug("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); | 2514 | log.warn("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); |
| 2555 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); | 2515 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); |
| 2556 | | 2516 | |
| 2557 | linkedit.inner.filesize += stabs_size; | 2517 | linkedit.inner.filesize += stabs_size; |
| ... | @@ -2561,27 +2521,6 @@ fn writeDebugInfo(self: *Zld) !void { | ... | @@ -2561,27 +2521,6 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2561 | dysymtab.nlocalsym = symtab.nsyms; | 2521 | dysymtab.nlocalsym = symtab.nsyms; |
| 2562 | } | 2522 | } |
| 2563 | | 2523 | |
| 2564 | fn populateStringTable(self: *Zld) !void { | | |
| 2565 | for (self.objects.items) |*object| { | | |
| 2566 | for (object.symtab.items) |*sym| { | | |
| 2567 | switch (sym.tag) { | | |
| 2568 | .undef, .import => continue, | | |
| 2569 | else => {}, | | |
| 2570 | } | | |
| 2571 | const sym_name = object.getString(sym.inner.n_strx); | | |
| 2572 | const n_strx = try self.makeString(sym_name); | | |
| 2573 | sym.inner.n_strx = n_strx; | | |
| 2574 | } | | |
| 2575 | } | | |
| 2576 | | | |
| 2577 | for (self.symtab.items()) |*entry| { | | |
| 2578 | if (entry.value.tag != .import) continue; | | |
| 2579 | | | |
| 2580 | const n_strx = try self.makeString(entry.key); | | |
| 2581 | entry.value.inner.n_strx = n_strx; | | |
| 2582 | } | | |
| 2583 | } | | |
| 2584 | | | |
| 2585 | fn writeSymbolTable(self: *Zld) !void { | 2524 | fn writeSymbolTable(self: *Zld) !void { |
| 2586 | const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | 2525 | const seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2587 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 2526 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| ... | @@ -2589,56 +2528,52 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2589,56 +2528,52 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2589 | var locals = std.ArrayList(macho.nlist_64).init(self.allocator); | 2528 | var locals = std.ArrayList(macho.nlist_64).init(self.allocator); |
| 2590 | defer locals.deinit(); | 2529 | defer locals.deinit(); |
| 2591 | | 2530 | |
| | 2531 | var exports = std.ArrayList(macho.nlist_64).init(self.allocator); |
| | 2532 | defer exports.deinit(); |
| | 2533 | |
| 2592 | for (self.objects.items) |object| { | 2534 | for (self.objects.items) |object| { |
| 2593 | for (object.locals.items()) |entry| { | 2535 | for (object.symbols.items) |sym| { |
| 2594 | const sym = entry.value; | 2536 | const final = sym.getTopmostAlias(); |
| 2595 | if (sym.tag != .local) continue; | 2537 | if (final.@"type" != .regular) continue; |
| 2596 | | 2538 | |
| 2597 | try locals.append(.{ | 2539 | const reg = final.cast(Symbol.Regular) orelse unreachable; |
| 2598 | .n_strx = try self.makeString(sym.name), | 2540 | if (reg.isTemp()) continue; |
| 2599 | .n_type = macho.N_SECT, | 2541 | |
| 2600 | .n_sect = sym.section, | 2542 | switch (reg.linkage) { |
| 2601 | .n_desc = 0, | 2543 | .translation_unit => { |
| 2602 | .n_value = sym.address, | 2544 | try locals.append(.{ |
| 2603 | }); | 2545 | .n_strx = try self.makeString(sym.name), |
| | 2546 | .n_type = macho.N_SECT, |
| | 2547 | .n_sect = reg.section, |
| | 2548 | .n_desc = 0, |
| | 2549 | .n_value = reg.address, |
| | 2550 | }); |
| | 2551 | }, |
| | 2552 | else => { |
| | 2553 | try exports.append(.{ |
| | 2554 | .n_strx = try self.makeString(sym.name), |
| | 2555 | .n_type = macho.N_SECT | macho.N_EXT, |
| | 2556 | .n_sect = reg.section, |
| | 2557 | .n_desc = 0, |
| | 2558 | .n_value = reg.address, |
| | 2559 | }); |
| | 2560 | }, |
| | 2561 | } |
| 2604 | } | 2562 | } |
| 2605 | } | 2563 | } |
| 2606 | | 2564 | |
| 2607 | var exports = std.ArrayList(macho.nlist_64).init(self.allocator); | | |
| 2608 | defer exports.deinit(); | | |
| 2609 | | | |
| 2610 | var undefs = std.ArrayList(macho.nlist_64).init(self.allocator); | 2565 | var undefs = std.ArrayList(macho.nlist_64).init(self.allocator); |
| 2611 | defer undefs.deinit(); | 2566 | defer undefs.deinit(); |
| 2612 | | 2567 | |
| 2613 | var undefs_ids = std.StringHashMap(u32).init(self.allocator); | 2568 | for (self.imports.items()) |entry| { |
| 2614 | defer undefs_ids.deinit(); | | |
| 2615 | | | |
| 2616 | var undef_id: u32 = 0; | | |
| 2617 | for (self.symtab.items()) |entry| { | | |
| 2618 | const sym = entry.value; | 2569 | const sym = entry.value; |
| 2619 | switch (sym.tag) { | 2570 | try undefs.append(.{ |
| 2620 | .weak, .strong => { | 2571 | .n_strx = try self.makeString(sym.name), |
| 2621 | try exports.append(.{ | 2572 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 2622 | .n_strx = try self.makeString(sym.name), | 2573 | .n_sect = 0, |
| 2623 | .n_type = macho.N_SECT | macho.N_EXT, | 2574 | .n_desc = macho.N_SYMBOL_RESOLVER | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY, |
| 2624 | .n_sect = sym.section, | 2575 | .n_value = 0, |
| 2625 | .n_desc = 0, | 2576 | }); |
| 2626 | .n_value = sym.address, | | |
| 2627 | }); | | |
| 2628 | }, | | |
| 2629 | .import => { | | |
| 2630 | try undefs.append(.{ | | |
| 2631 | .n_strx = try self.makeString(sym.name), | | |
| 2632 | .n_type = macho.N_UNDF | macho.N_EXT, | | |
| 2633 | .n_sect = 0, | | |
| 2634 | .n_desc = macho.N_SYMBOL_RESOLVER | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY, | | |
| 2635 | .n_value = 0, | | |
| 2636 | }); | | |
| 2637 | try undefs_ids.putNoClobber(sym.name, undef_id); | | |
| 2638 | undef_id += 1; | | |
| 2639 | }, | | |
| 2640 | else => unreachable, | | |
| 2641 | } | | |
| 2642 | } | 2577 | } |
| 2643 | | 2578 | |
| 2644 | const nlocals = locals.items.len; | 2579 | const nlocals = locals.items.len; |
| ... | @@ -2647,17 +2582,17 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2647,17 +2582,17 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2647 | | 2582 | |
| 2648 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); | 2583 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2649 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | 2584 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| 2650 | log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); | 2585 | log.warn("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); |
| 2651 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); | 2586 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); |
| 2652 | | 2587 | |
| 2653 | const exports_off = locals_off + locals_size; | 2588 | const exports_off = locals_off + locals_size; |
| 2654 | const exports_size = nexports * @sizeOf(macho.nlist_64); | 2589 | const exports_size = nexports * @sizeOf(macho.nlist_64); |
| 2655 | log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); | 2590 | log.warn("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); |
| 2656 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); | 2591 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); |
| 2657 | | 2592 | |
| 2658 | const undefs_off = exports_off + exports_size; | 2593 | const undefs_off = exports_off + exports_size; |
| 2659 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); | 2594 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 2660 | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); | 2595 | log.warn("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 2661 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); | 2596 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); |
| 2662 | | 2597 | |
| 2663 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); | 2598 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); |
| ... | @@ -2678,8 +2613,8 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2678,8 +2613,8 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2678 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2613 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2679 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 2614 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2680 | | 2615 | |
| 2681 | const nstubs = @intCast(u32, self.stubs.items().len); | 2616 | const nstubs = @intCast(u32, self.stubs.items.len); |
| 2682 | const ngot_entries = @intCast(u32, self.got_entries.items().len); | 2617 | const ngot_entries = @intCast(u32, self.got_entries.items.len); |
| 2683 | | 2618 | |
| 2684 | dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); | 2619 | dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); |
| 2685 | dysymtab.nindirectsyms = nstubs * 2 + ngot_entries; | 2620 | dysymtab.nindirectsyms = nstubs * 2 + ngot_entries; |
| ... | @@ -2687,7 +2622,7 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2687,7 +2622,7 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2687 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); | 2622 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); |
| 2688 | seg.inner.filesize += needed_size; | 2623 | seg.inner.filesize += needed_size; |
| 2689 | | 2624 | |
| 2690 | log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{ | 2625 | log.warn("writing indirect symbol table from 0x{x} to 0x{x}", .{ |
| 2691 | dysymtab.indirectsymoff, | 2626 | dysymtab.indirectsymoff, |
| 2692 | dysymtab.indirectsymoff + needed_size, | 2627 | dysymtab.indirectsymoff + needed_size, |
| 2693 | }); | 2628 | }); |
| ... | @@ -2699,25 +2634,25 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2699,25 +2634,25 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2699 | var writer = stream.writer(); | 2634 | var writer = stream.writer(); |
| 2700 | | 2635 | |
| 2701 | stubs.reserved1 = 0; | 2636 | stubs.reserved1 = 0; |
| 2702 | for (self.stubs.items()) |entry| { | 2637 | for (self.stubs.items) |sym| { |
| 2703 | const id = undefs_ids.get(entry.key) orelse unreachable; | 2638 | const id = self.imports.getIndex(sym.name) orelse unreachable; |
| 2704 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2639 | try writer.writeIntLittle(u32, dysymtab.iundefsym + @intCast(u32, id)); |
| 2705 | } | 2640 | } |
| 2706 | | 2641 | |
| 2707 | got.reserved1 = nstubs; | 2642 | got.reserved1 = nstubs; |
| 2708 | for (self.got_entries.items()) |entry| { | 2643 | for (self.got_entries.items) |sym| { |
| 2709 | if (entry.value.tag == .import) { | 2644 | if (sym.@"type" == .proxy) { |
| 2710 | const id = undefs_ids.get(entry.key) orelse unreachable; | 2645 | const id = self.imports.getIndex(sym.name) orelse unreachable; |
| 2711 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2646 | try writer.writeIntLittle(u32, dysymtab.iundefsym + @intCast(u32, id)); |
| 2712 | } else { | 2647 | } else { |
| 2713 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); | 2648 | try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL); |
| 2714 | } | 2649 | } |
| 2715 | } | 2650 | } |
| 2716 | | 2651 | |
| 2717 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; | 2652 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 2718 | for (self.stubs.items()) |entry| { | 2653 | for (self.stubs.items) |sym| { |
| 2719 | const id = undefs_ids.get(entry.key) orelse unreachable; | 2654 | const id = self.imports.getIndex(sym.name) orelse unreachable; |
| 2720 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2655 | try writer.writeIntLittle(u32, dysymtab.iundefsym + @intCast(u32, id)); |
| 2721 | } | 2656 | } |
| 2722 | | 2657 | |
| 2723 | try self.file.?.pwriteAll(buf, dysymtab.indirectsymoff); | 2658 | try self.file.?.pwriteAll(buf, dysymtab.indirectsymoff); |
| ... | @@ -2730,7 +2665,7 @@ fn writeStringTable(self: *Zld) !void { | ... | @@ -2730,7 +2665,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2730 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); | 2665 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); |
| 2731 | seg.inner.filesize += symtab.strsize; | 2666 | seg.inner.filesize += symtab.strsize; |
| 2732 | | 2667 | |
| 2733 | log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); | 2668 | log.warn("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 2734 | | 2669 | |
| 2735 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); | 2670 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 2736 | | 2671 | |
| ... | @@ -2776,7 +2711,7 @@ fn writeDataInCode(self: *Zld) !void { | ... | @@ -2776,7 +2711,7 @@ fn writeDataInCode(self: *Zld) !void { |
| 2776 | dice_cmd.datasize = datasize; | 2711 | dice_cmd.datasize = datasize; |
| 2777 | seg.inner.filesize += datasize; | 2712 | seg.inner.filesize += datasize; |
| 2778 | | 2713 | |
| 2779 | log.debug("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize }); | 2714 | log.warn("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize }); |
| 2780 | | 2715 | |
| 2781 | try self.file.?.pwriteAll(buf.items, fileoff); | 2716 | try self.file.?.pwriteAll(buf.items, fileoff); |
| 2782 | } | 2717 | } |
| ... | @@ -2797,7 +2732,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { | ... | @@ -2797,7 +2732,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 2797 | seg.inner.filesize += needed_size; | 2732 | seg.inner.filesize += needed_size; |
| 2798 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); | 2733 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2799 | | 2734 | |
| 2800 | log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); | 2735 | log.warn("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); |
| 2801 | | 2736 | |
| 2802 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file | 2737 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 2803 | // except for code signature data. | 2738 | // except for code signature data. |
| ... | @@ -2823,7 +2758,7 @@ fn writeCodeSignature(self: *Zld) !void { | ... | @@ -2823,7 +2758,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 2823 | var stream = std.io.fixedBufferStream(buffer); | 2758 | var stream = std.io.fixedBufferStream(buffer); |
| 2824 | try code_sig.write(stream.writer()); | 2759 | try code_sig.write(stream.writer()); |
| 2825 | | 2760 | |
| 2826 | log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); | 2761 | log.warn("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); |
| 2827 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); | 2762 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); |
| 2828 | } | 2763 | } |
| 2829 | | 2764 | |
| ... | @@ -2841,7 +2776,7 @@ fn writeLoadCommands(self: *Zld) !void { | ... | @@ -2841,7 +2776,7 @@ fn writeLoadCommands(self: *Zld) !void { |
| 2841 | } | 2776 | } |
| 2842 | | 2777 | |
| 2843 | const off = @sizeOf(macho.mach_header_64); | 2778 | const off = @sizeOf(macho.mach_header_64); |
| 2844 | log.debug("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); | 2779 | log.warn("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2845 | try self.file.?.pwriteAll(buffer, off); | 2780 | try self.file.?.pwriteAll(buffer, off); |
| 2846 | } | 2781 | } |
| 2847 | | 2782 | |
| ... | @@ -2879,7 +2814,7 @@ fn writeHeader(self: *Zld) !void { | ... | @@ -2879,7 +2814,7 @@ fn writeHeader(self: *Zld) !void { |
| 2879 | for (self.load_commands.items) |cmd| { | 2814 | for (self.load_commands.items) |cmd| { |
| 2880 | header.sizeofcmds += cmd.cmdsize(); | 2815 | header.sizeofcmds += cmd.cmdsize(); |
| 2881 | } | 2816 | } |
| 2882 | log.debug("writing Mach-O header {}", .{header}); | 2817 | log.warn("writing Mach-O header {}", .{header}); |
| 2883 | try self.file.?.pwriteAll(mem.asBytes(&header), 0); | 2818 | try self.file.?.pwriteAll(mem.asBytes(&header), 0); |
| 2884 | } | 2819 | } |
| 2885 | | 2820 | |
| ... | @@ -2892,13 +2827,13 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { | ... | @@ -2892,13 +2827,13 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 2892 | | 2827 | |
| 2893 | fn makeString(self: *Zld, bytes: []const u8) !u32 { | 2828 | fn makeString(self: *Zld, bytes: []const u8) !u32 { |
| 2894 | if (self.strtab_dir.get(bytes)) |offset| { | 2829 | if (self.strtab_dir.get(bytes)) |offset| { |
| 2895 | log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset }); | 2830 | log.warn("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset }); |
| 2896 | return offset; | 2831 | return offset; |
| 2897 | } | 2832 | } |
| 2898 | | 2833 | |
| 2899 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); | 2834 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); |
| 2900 | const offset = @intCast(u32, self.strtab.items.len); | 2835 | const offset = @intCast(u32, self.strtab.items.len); |
| 2901 | log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); | 2836 | log.warn("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2902 | self.strtab.appendSliceAssumeCapacity(bytes); | 2837 | self.strtab.appendSliceAssumeCapacity(bytes); |
| 2903 | self.strtab.appendAssumeCapacity(0); | 2838 | self.strtab.appendAssumeCapacity(0); |
| 2904 | try self.strtab_dir.putNoClobber(self.allocator, try self.allocator.dupe(u8, bytes), offset); | 2839 | try self.strtab_dir.putNoClobber(self.allocator, try self.allocator.dupe(u8, bytes), offset); |