| ... | @@ -202,16 +202,14 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { | ... | @@ -202,16 +202,14 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 202 | try self.resolveSymbols(); | 202 | try self.resolveSymbols(); |
| 203 | // self.printSymbols(); | 203 | // self.printSymbols(); |
| 204 | try self.resolveStubsAndGotEntries(); | 204 | try self.resolveStubsAndGotEntries(); |
| | 205 | try self.updateMetadata(); |
| | 206 | try self.sortSections(); |
| | 207 | try self.allocateTextSegment(); |
| | 208 | try self.allocateDataConstSegment(); |
| | 209 | try self.allocateDataSegment(); |
| | 210 | self.allocateLinkeditSegment(); |
| | 211 | try self.allocateSymbols(); |
| 205 | return error.Unfinished; | 212 | return error.Unfinished; |
| 206 | // try self.updateMetadata(); | | |
| 207 | // try self.sortSections(); | | |
| 208 | // try self.allocateTextSegment(); | | |
| 209 | // try self.allocateDataConstSegment(); | | |
| 210 | // try self.allocateDataSegment(); | | |
| 211 | // self.allocateLinkeditSegment(); | | |
| 212 | // try self.allocateSymbols(); | | |
| 213 | // try self.allocateStubsAndGotEntries(); | | |
| 214 | // try self.allocateCppStatics(); | | |
| 215 | // try self.writeStubHelperCommon(); | 213 | // try self.writeStubHelperCommon(); |
| 216 | // try self.resolveRelocsAndWriteSections(); | 214 | // try self.resolveRelocsAndWriteSections(); |
| 217 | // try self.flush(); | 215 | // try self.flush(); |
| ... | @@ -797,7 +795,7 @@ fn sortSections(self: *Zld) !void { | ... | @@ -797,7 +795,7 @@ fn sortSections(self: *Zld) !void { |
| 797 | | 795 | |
| 798 | fn allocateTextSegment(self: *Zld) !void { | 796 | fn allocateTextSegment(self: *Zld) !void { |
| 799 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 797 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 800 | const nstubs = @intCast(u32, self.stubs.items().len); | 798 | const nstubs = @intCast(u32, self.stubs.items.len); |
| 801 | | 799 | |
| 802 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; | 800 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; |
| 803 | seg.inner.fileoff = 0; | 801 | seg.inner.fileoff = 0; |
| ... | @@ -848,7 +846,7 @@ fn allocateTextSegment(self: *Zld) !void { | ... | @@ -848,7 +846,7 @@ fn allocateTextSegment(self: *Zld) !void { |
| 848 | | 846 | |
| 849 | fn allocateDataConstSegment(self: *Zld) !void { | 847 | fn allocateDataConstSegment(self: *Zld) !void { |
| 850 | const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 848 | const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 851 | const nentries = @intCast(u32, self.got_entries.items().len); | 849 | const nentries = @intCast(u32, self.got_entries.items.len); |
| 852 | | 850 | |
| 853 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 851 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 854 | seg.inner.fileoff = text_seg.inner.fileoff + text_seg.inner.filesize; | 852 | seg.inner.fileoff = text_seg.inner.fileoff + text_seg.inner.filesize; |
| ... | @@ -863,7 +861,7 @@ fn allocateDataConstSegment(self: *Zld) !void { | ... | @@ -863,7 +861,7 @@ fn allocateDataConstSegment(self: *Zld) !void { |
| 863 | | 861 | |
| 864 | fn allocateDataSegment(self: *Zld) !void { | 862 | fn allocateDataSegment(self: *Zld) !void { |
| 865 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 863 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 866 | const nstubs = @intCast(u32, self.stubs.items().len); | 864 | const nstubs = @intCast(u32, self.stubs.items.len); |
| 867 | | 865 | |
| 868 | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 866 | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 869 | seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize; | 867 | seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize; |
| ... | @@ -906,95 +904,46 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { | ... | @@ -906,95 +904,46 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { |
| 906 | } | 904 | } |
| 907 | | 905 | |
| 908 | fn allocateSymbols(self: *Zld) !void { | 906 | fn allocateSymbols(self: *Zld) !void { |
| 909 | for (self.objects.items) |*object, object_id| { | 907 | for (self.objects.items) |object, object_id| { |
| 910 | for (object.locals.items()) |*entry| { | 908 | for (object.symbols.items) |sym| { |
| 911 | const source_sym = object.symtab.items[entry.value.index.?]; | 909 | const reg = sym.cast(Symbol.Regular) orelse continue; |
| 912 | const source_sect_id = source_sym.n_sect - 1; | | |
| 913 | | 910 | |
| 914 | // TODO I am more and more convinced we should store the mapping as part of the Object struct. | 911 | // TODO I am more and more convinced we should store the mapping as part of the Object struct. |
| 915 | const target_mapping = self.mappings.get(.{ | 912 | const target_mapping = self.mappings.get(.{ |
| 916 | .object_id = @intCast(u16, object_id), | 913 | .object_id = @intCast(u16, object_id), |
| 917 | .source_sect_id = source_sect_id, | 914 | .source_sect_id = reg.section, |
| 918 | }) orelse { | 915 | }) orelse { |
| 919 | if (self.unhandled_sections.get(.{ | 916 | if (self.unhandled_sections.get(.{ |
| 920 | .object_id = @intCast(u16, object_id), | 917 | .object_id = @intCast(u16, object_id), |
| 921 | .source_sect_id = source_sect_id, | 918 | .source_sect_id = reg.section, |
| 922 | }) != null) continue; | 919 | }) != null) continue; |
| 923 | | 920 | |
| 924 | log.err("section not mapped for symbol '{s}'", .{entry.value.name}); | 921 | log.err("section not mapped for symbol '{s}'", .{sym.name}); |
| 925 | return error.SectionNotMappedForSymbol; | 922 | return error.SectionNotMappedForSymbol; |
| 926 | }; | 923 | }; |
| 927 | | 924 | |
| 928 | const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment; | 925 | const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 929 | const source_sect = source_seg.sections.items[source_sect_id]; | 926 | const source_sect = source_seg.sections.items[reg.section]; |
| 930 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; | 927 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| 931 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; | 928 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; |
| 932 | const target_addr = target_sect.addr + target_mapping.offset; | 929 | const target_addr = target_sect.addr + target_mapping.offset; |
| 933 | const n_value = source_sym.n_value - source_sect.addr + target_addr; | 930 | const address = reg.address - source_sect.addr + target_addr; |
| 934 | | 931 | |
| 935 | log.debug("resolving local symbol '{s}' at 0x{x}", .{ entry.value.name, n_value }); | 932 | log.warn("resolving symbol '{s}' at 0x{x}", .{ sym.name, address }); |
| 936 | | 933 | |
| 937 | // TODO there might be a more generic way of doing this. | 934 | // TODO there might be a more generic way of doing this. |
| 938 | var n_sect: u8 = 0; | 935 | var section: u8 = 0; |
| 939 | for (self.load_commands.items) |cmd, cmd_id| { | 936 | for (self.load_commands.items) |cmd, cmd_id| { |
| 940 | if (cmd != .Segment) break; | 937 | if (cmd != .Segment) break; |
| 941 | if (cmd_id == target_mapping.target_seg_id) { | 938 | if (cmd_id == target_mapping.target_seg_id) { |
| 942 | n_sect += @intCast(u8, target_mapping.target_sect_id) + 1; | 939 | section += @intCast(u8, target_mapping.target_sect_id) + 1; |
| 943 | break; | 940 | break; |
| 944 | } | 941 | } |
| 945 | n_sect += @intCast(u8, cmd.Segment.sections.items.len); | 942 | section += @intCast(u8, cmd.Segment.sections.items.len); |
| 946 | } | 943 | } |
| 947 | | 944 | |
| 948 | entry.value.address = n_value; | 945 | reg.address = address; |
| 949 | entry.value.section = n_sect; | 946 | reg.section = section; |
| 950 | } | | |
| 951 | } | | |
| 952 | | | |
| 953 | for (self.symtab.items()) |*entry| { | | |
| 954 | if (entry.value.tag == .import) continue; | | |
| 955 | | | |
| 956 | const object_id = entry.value.file orelse unreachable; | | |
| 957 | const object = self.objects.items[object_id]; | | |
| 958 | const local = object.locals.get(entry.key) orelse unreachable; | | |
| 959 | | | |
| 960 | log.debug("resolving {} symbol '{s}' at 0x{x}", .{ entry.value.tag, entry.key, local.address }); | | |
| 961 | | | |
| 962 | entry.value.address = local.address; | | |
| 963 | entry.value.section = local.section; | | |
| 964 | } | | |
| 965 | } | | |
| 966 | | | |
| 967 | fn allocateStubsAndGotEntries(self: *Zld) !void { | | |
| 968 | for (self.got_entries.items()) |*entry| { | | |
| 969 | if (entry.value.tag == .import) continue; | | |
| 970 | | | |
| 971 | const object = self.objects.items[entry.value.file]; | | |
| 972 | entry.value.target_addr = target_addr: { | | |
| 973 | if (object.locals.get(entry.key)) |local| { | | |
| 974 | break :target_addr local.address; | | |
| 975 | } | | |
| 976 | const global = self.symtab.get(entry.key) orelse unreachable; | | |
| 977 | break :target_addr global.address; | | |
| 978 | }; | | |
| 979 | | | |
| 980 | log.debug("resolving GOT entry '{s}' at 0x{x}", .{ | | |
| 981 | entry.key, | | |
| 982 | entry.value.target_addr, | | |
| 983 | }); | | |
| 984 | } | | |
| 985 | } | | |
| 986 | | | |
| 987 | fn allocateCppStatics(self: *Zld) !void { | | |
| 988 | for (self.objects.items) |*object| { | | |
| 989 | for (object.initializers.items) |*initializer| { | | |
| 990 | const sym = object.symtab.items[initializer.symbol]; | | |
| 991 | const sym_name = object.getString(sym.n_strx); | | |
| 992 | initializer.target_addr = object.locals.get(sym_name).?.address; | | |
| 993 | | | |
| 994 | log.debug("resolving C++ initializer '{s}' at 0x{x}", .{ | | |
| 995 | sym_name, | | |
| 996 | initializer.target_addr, | | |
| 997 | }); | | |
| 998 | } | 947 | } |
| 999 | } | 948 | } |
| 1000 | } | 949 | } |