authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-10 08:30:25+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-10 09:13:35+02:00
log96bb81b6ef0896d0b63c54bfd5d1ac0fa267d68a
tree8d751f4925f3c05ff04dca9db3560af21593ef5f
parent88aec4a1ee49088685b16d744f35c902c4900a09

zld: moving target seg,sect mapping into Object.Section


2 files changed, 94 insertions(+), 118 deletions(-)

src/link/MachO/Object.zig+5
......@@ -54,6 +54,11 @@ pub const Section = struct {
5454 inner: macho.section_64,
5555 code: []u8,
5656 relocs: ?[]*Relocation,
57 target_map: ?struct {
58 segment_id: u16,
59 section_id: u16,
60 offset: u32,
61 } = null,
5762
5863 pub fn deinit(self: *Section, allocator: *Allocator) void {
5964 allocator.free(self.code);
src/link/MachO/Zld.zig+89-118
......@@ -95,9 +95,6 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{},
9595
9696stub_helper_stubs_start_off: ?u64 = null,
9797
98mappings: std.AutoHashMapUnmanaged(MappingKey, SectionMapping) = .{},
99unhandled_sections: std.AutoHashMapUnmanaged(MappingKey, u0) = .{},
100
10198const TlvOffset = struct {
10299 source_addr: u64,
103100 offset: u64,
......@@ -107,18 +104,6 @@ const TlvOffset = struct {
107104 }
108105};
109106
110const MappingKey = struct {
111 object_id: u16,
112 source_sect_id: u16,
113};
114
115pub const SectionMapping = struct {
116 source_sect_id: u16,
117 target_seg_id: u16,
118 target_sect_id: u16,
119 offset: u32,
120};
121
122107/// Default path to dyld
123108const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld";
124109
......@@ -159,9 +144,6 @@ pub fn deinit(self: *Zld) void {
159144 }
160145 self.dylibs.deinit(self.allocator);
161146
162 self.mappings.deinit(self.allocator);
163 self.unhandled_sections.deinit(self.allocator);
164
165147 self.globals.deinit(self.allocator);
166148 self.imports.deinit(self.allocator);
167149 self.unresolved.deinit(self.allocator);
......@@ -407,46 +389,39 @@ fn parseLibs(self: *Zld, libs: []const []const u8) !void {
407389
408390fn mapAndUpdateSections(
409391 self: *Zld,
410 object_id: u16,
392 object: *Object,
411393 source_sect_id: u16,
412394 target_seg_id: u16,
413395 target_sect_id: u16,
414396) !void {
415 const object = self.objects.items[object_id];
416 const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
417 const source_sect = source_seg.sections.items[source_sect_id];
397 const source_sect = &object.sections.items[source_sect_id];
418398 const target_seg = &self.load_commands.items[target_seg_id].Segment;
419399 const target_sect = &target_seg.sections.items[target_sect_id];
420400
421401 const alignment = try math.powi(u32, 2, target_sect.@"align");
422402 const offset = mem.alignForwardGeneric(u64, target_sect.size, alignment);
423 const size = mem.alignForwardGeneric(u64, source_sect.size, alignment);
424 const key = MappingKey{
425 .object_id = object_id,
426 .source_sect_id = source_sect_id,
427 };
428 try self.mappings.putNoClobber(self.allocator, key, .{
429 .source_sect_id = source_sect_id,
430 .target_seg_id = target_seg_id,
431 .target_sect_id = target_sect_id,
432 .offset = @intCast(u32, offset),
433 });
434 log.debug("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{
435 object.name,
436 parseName(&source_sect.segname),
437 parseName(&source_sect.sectname),
403 const size = mem.alignForwardGeneric(u64, source_sect.inner.size, alignment);
404
405 log.debug("{s}: '{s},{s}' mapped to '{s},{s}' from 0x{x} to 0x{x}", .{
406 object.name.?,
407 parseName(&source_sect.inner.segname),
408 parseName(&source_sect.inner.sectname),
438409 parseName(&target_sect.segname),
439410 parseName(&target_sect.sectname),
440411 offset,
441412 offset + size,
442413 });
443414
415 source_sect.target_map = .{
416 .segment_id = target_seg_id,
417 .section_id = target_sect_id,
418 .offset = @intCast(u32, offset),
419 };
444420 target_sect.size = offset + size;
445421}
446422
447423fn updateMetadata(self: *Zld) !void {
448 for (self.objects.items) |object, id| {
449 const object_id = @intCast(u16, id);
424 for (self.objects.items) |object| {
450425 const object_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
451426 const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
452427 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
......@@ -699,19 +674,14 @@ fn updateMetadata(self: *Zld) !void {
699674 for (object_seg.sections.items) |source_sect, sect_id| {
700675 const source_sect_id = @intCast(u16, sect_id);
701676 if (self.getMatchingSection(source_sect)) |res| {
702 try self.mapAndUpdateSections(object_id, source_sect_id, res.seg, res.sect);
677 try self.mapAndUpdateSections(object, source_sect_id, res.seg, res.sect);
703678 continue;
704679 }
705680
706 const segname = parseName(&source_sect.segname);
707 const sectname = parseName(&source_sect.sectname);
708
709 log.debug("section '{s}/{s}' will be unmapped", .{ segname, sectname });
710
711 try self.unhandled_sections.putNoClobber(self.allocator, .{
712 .object_id = object_id,
713 .source_sect_id = source_sect_id,
714 }, 0);
681 log.debug("section '{s},{s}' will be unmapped", .{
682 parseName(&source_sect.segname),
683 parseName(&source_sect.sectname),
684 });
715685 }
716686 }
717687
......@@ -954,18 +924,34 @@ fn sortSections(self: *Zld) !void {
954924 }
955925 }
956926
957 var it = self.mappings.valueIterator();
958 while (it.next()) |mapping| {
959 if (self.text_segment_cmd_index.? == mapping.target_seg_id) {
960 const new_index = text_index_mapping.get(mapping.target_sect_id) orelse unreachable;
961 mapping.target_sect_id = new_index;
962 } else if (self.data_const_segment_cmd_index.? == mapping.target_seg_id) {
963 const new_index = data_const_index_mapping.get(mapping.target_sect_id) orelse unreachable;
964 mapping.target_sect_id = new_index;
965 } else if (self.data_segment_cmd_index.? == mapping.target_seg_id) {
966 const new_index = data_index_mapping.get(mapping.target_sect_id) orelse unreachable;
967 mapping.target_sect_id = new_index;
968 } else unreachable;
927 for (self.objects.items) |object| {
928 for (object.sections.items) |*sect| {
929 const target_map = sect.target_map orelse continue;
930
931 const new_index = blk: {
932 if (self.text_segment_cmd_index.? == target_map.segment_id) {
933 break :blk text_index_mapping.get(target_map.section_id) orelse unreachable;
934 } else if (self.data_const_segment_cmd_index.? == target_map.segment_id) {
935 break :blk data_const_index_mapping.get(target_map.section_id) orelse unreachable;
936 } else if (self.data_segment_cmd_index.? == target_map.segment_id) {
937 break :blk data_index_mapping.get(target_map.section_id) orelse unreachable;
938 } else unreachable;
939 };
940
941 log.debug("remapping in {s}: '{s},{s}': {} => {}", .{
942 object.name.?,
943 parseName(&sect.inner.segname),
944 parseName(&sect.inner.sectname),
945 target_map.section_id,
946 new_index,
947 });
948
949 sect.target_map = .{
950 .segment_id = target_map.segment_id,
951 .section_id = new_index,
952 .offset = target_map.offset,
953 };
954 }
969955 }
970956}
971957
......@@ -1080,30 +1066,24 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void {
10801066}
10811067
10821068fn allocateSymbols(self: *Zld) !void {
1083 for (self.objects.items) |object, object_id| {
1069 for (self.objects.items) |object| {
10841070 for (object.symbols.items) |sym| {
10851071 const reg = sym.cast(Symbol.Regular) orelse continue;
10861072
1087 // TODO I am more and more convinced we should store the mapping as part of the Object struct.
1088 const target_mapping = self.mappings.get(.{
1089 .object_id = @intCast(u16, object_id),
1090 .source_sect_id = reg.section,
1091 }) orelse {
1092 if (self.unhandled_sections.get(.{
1093 .object_id = @intCast(u16, object_id),
1094 .source_sect_id = reg.section,
1095 }) != null) continue;
1096
1097 log.err("section not mapped for symbol '{s}'", .{sym.name});
1098 return error.SectionNotMappedForSymbol;
1073 const source_sect = &object.sections.items[reg.section];
1074 const target_map = source_sect.target_map orelse {
1075 log.debug("section '{s},{s}' not mapped for symbol '{s}'", .{
1076 parseName(&source_sect.inner.segname),
1077 parseName(&source_sect.inner.sectname),
1078 sym.name,
1079 });
1080 continue;
10991081 };
11001082
1101 const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
1102 const source_sect = source_seg.sections.items[reg.section];
1103 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
1104 const target_sect = target_seg.sections.items[target_mapping.target_sect_id];
1105 const target_addr = target_sect.addr + target_mapping.offset;
1106 const address = reg.address - source_sect.addr + target_addr;
1083 const target_seg = self.load_commands.items[target_map.segment_id].Segment;
1084 const target_sect = target_seg.sections.items[target_map.section_id];
1085 const target_addr = target_sect.addr + target_map.offset;
1086 const address = reg.address - source_sect.inner.addr + target_addr;
11071087
11081088 log.debug("resolving symbol '{s}' at 0x{x}", .{ sym.name, address });
11091089
......@@ -1111,8 +1091,8 @@ fn allocateSymbols(self: *Zld) !void {
11111091 var section: u8 = 0;
11121092 for (self.load_commands.items) |cmd, cmd_id| {
11131093 if (cmd != .Segment) break;
1114 if (cmd_id == target_mapping.target_seg_id) {
1115 section += @intCast(u8, target_mapping.target_sect_id) + 1;
1094 if (cmd_id == target_map.segment_id) {
1095 section += @intCast(u8, target_map.section_id) + 1;
11161096 break;
11171097 }
11181098 section += @intCast(u8, cmd.Segment.sections.items.len);
......@@ -1602,10 +1582,10 @@ fn resolveStubsAndGotEntries(self: *Zld) !void {
16021582}
16031583
16041584fn resolveRelocsAndWriteSections(self: *Zld) !void {
1605 for (self.objects.items) |object, object_id| {
1585 for (self.objects.items) |object| {
16061586 log.debug("relocating object {s}", .{object.name});
16071587
1608 for (object.sections.items) |sect, source_sect_id| {
1588 for (object.sections.items) |sect| {
16091589 if (sect.inner.flags == macho.S_MOD_INIT_FUNC_POINTERS or
16101590 sect.inner.flags == macho.S_MOD_TERM_FUNC_POINTERS) continue;
16111591
......@@ -1614,18 +1594,15 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
16141594
16151595 log.debug("relocating section '{s},{s}'", .{ segname, sectname });
16161596
1617 // Get mapping
1618 const target_mapping = self.mappings.get(.{
1619 .object_id = @intCast(u16, object_id),
1620 .source_sect_id = @intCast(u16, source_sect_id),
1621 }) orelse {
1622 log.debug("no mapping for {s},{s}; skipping", .{ segname, sectname });
1597 // Get target mapping
1598 const target_map = sect.target_map orelse {
1599 log.debug("no mapping for '{s},{s}'; skipping", .{ segname, sectname });
16231600 continue;
16241601 };
1625 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
1626 const target_sect = target_seg.sections.items[target_mapping.target_sect_id];
1627 const target_sect_addr = target_sect.addr + target_mapping.offset;
1628 const target_sect_off = target_sect.offset + target_mapping.offset;
1602 const target_seg = self.load_commands.items[target_map.segment_id].Segment;
1603 const target_sect = target_seg.sections.items[target_map.section_id];
1604 const target_sect_addr = target_sect.addr + target_map.offset;
1605 const target_sect_off = target_sect.offset + target_map.offset;
16291606
16301607 if (sect.relocs) |relocs| {
16311608 for (relocs) |rel| {
......@@ -1638,11 +1615,11 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
16381615
16391616 switch (rel.@"type") {
16401617 .unsigned => {
1641 args.target_addr = try self.relocTargetAddr(@intCast(u16, object_id), rel.target);
1618 args.target_addr = try self.relocTargetAddr(object, rel.target);
16421619
16431620 const unsigned = rel.cast(reloc.Unsigned) orelse unreachable;
16441621 if (unsigned.subtractor) |subtractor| {
1645 args.subtractor = try self.relocTargetAddr(@intCast(u16, object_id), subtractor);
1622 args.subtractor = try self.relocTargetAddr(object, subtractor);
16461623 }
16471624 if (rel.target == .section) {
16481625 const source_sect = object.sections.items[rel.target.section];
......@@ -1652,14 +1629,14 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
16521629
16531630 rebases: {
16541631 var hit: bool = false;
1655 if (target_mapping.target_seg_id == self.data_segment_cmd_index.?) {
1632 if (target_map.segment_id == self.data_segment_cmd_index.?) {
16561633 if (self.data_section_index) |index| {
1657 if (index == target_mapping.target_sect_id) hit = true;
1634 if (index == target_map.section_id) hit = true;
16581635 }
16591636 }
1660 if (target_mapping.target_seg_id == self.data_const_segment_cmd_index.?) {
1637 if (target_map.segment_id == self.data_const_segment_cmd_index.?) {
16611638 if (self.data_const_section_index) |index| {
1662 if (index == target_mapping.target_sect_id) hit = true;
1639 if (index == target_map.section_id) hit = true;
16631640 }
16641641 }
16651642
......@@ -1667,7 +1644,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
16671644
16681645 try self.local_rebases.append(self.allocator, .{
16691646 .offset = source_addr - target_seg.inner.vmaddr,
1670 .segment_id = target_mapping.target_seg_id,
1647 .segment_id = target_map.segment_id,
16711648 });
16721649 }
16731650 // TLV is handled via a separate offset mechanism.
......@@ -1705,7 +1682,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
17051682 args.source_source_sect_addr = sect.inner.addr;
17061683 args.source_target_sect_addr = source_sect.inner.addr;
17071684 }
1708 args.target_addr = try self.relocTargetAddr(@intCast(u16, object_id), rel.target);
1685 args.target_addr = try self.relocTargetAddr(object, rel.target);
17091686 },
17101687 }
17111688
......@@ -1744,7 +1721,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
17441721 }
17451722}
17461723
1747fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) !u64 {
1724fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.Target) !u64 {
17481725 const target_addr = blk: {
17491726 switch (target) {
17501727 .symbol => |sym| {
......@@ -1770,13 +1747,11 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)
17701747 }
17711748 },
17721749 .section => |sect_id| {
1773 const target_mapping = self.mappings.get(.{
1774 .object_id = object_id,
1775 .source_sect_id = sect_id,
1776 }) orelse unreachable;
1777 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
1778 const target_sect = target_seg.sections.items[target_mapping.target_sect_id];
1779 break :blk target_sect.addr + target_mapping.offset;
1750 const source_sect = object.sections.items[sect_id];
1751 const target_map = source_sect.target_map orelse unreachable;
1752 const target_seg = self.load_commands.items[target_map.segment_id].Segment;
1753 const target_sect = target_seg.sections.items[target_map.section_id];
1754 break :blk target_sect.addr + target_map.offset;
17801755 },
17811756 }
17821757 };
......@@ -2901,20 +2876,16 @@ fn writeDataInCode(self: *Zld) !void {
29012876
29022877 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
29032878 const text_sect = text_seg.sections.items[self.text_section_index.?];
2904 for (self.objects.items) |object, object_id| {
2905 const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
2906 const source_sect = source_seg.sections.items[object.text_section_index.?];
2907 const target_mapping = self.mappings.get(.{
2908 .object_id = @intCast(u16, object_id),
2909 .source_sect_id = object.text_section_index.?,
2910 }) orelse continue;
2879 for (self.objects.items) |object| {
2880 const source_sect = object.sections.items[object.text_section_index.?];
2881 const target_map = source_sect.target_map orelse continue;
29112882
29122883 try buf.ensureCapacity(
29132884 buf.items.len + object.data_in_code_entries.items.len * @sizeOf(macho.data_in_code_entry),
29142885 );
29152886 for (object.data_in_code_entries.items) |dice| {
29162887 const new_dice: macho.data_in_code_entry = .{
2917 .offset = text_sect.offset + target_mapping.offset + dice.offset,
2888 .offset = text_sect.offset + target_map.offset + dice.offset,
29182889 .length = dice.length,
29192890 .kind = dice.kind,
29202891 };