| ... | ... | @@ -202,16 +202,14 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 202 | 202 | try self.resolveSymbols(); |
| 203 | 203 | // self.printSymbols(); |
| 204 | 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 | 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 | 213 | // try self.writeStubHelperCommon(); |
| 216 | 214 | // try self.resolveRelocsAndWriteSections(); |
| 217 | 215 | // try self.flush(); |
| ... | ... | @@ -797,7 +795,7 @@ fn sortSections(self: *Zld) !void { |
| 797 | 795 | |
| 798 | 796 | fn allocateTextSegment(self: *Zld) !void { |
| 799 | 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 | 800 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; |
| 803 | 801 | seg.inner.fileoff = 0; |
| ... | ... | @@ -848,7 +846,7 @@ fn allocateTextSegment(self: *Zld) !void { |
| 848 | 846 | |
| 849 | 847 | fn allocateDataConstSegment(self: *Zld) !void { |
| 850 | 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 | 851 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 854 | 852 | seg.inner.fileoff = text_seg.inner.fileoff + text_seg.inner.filesize; |
| ... | ... | @@ -863,7 +861,7 @@ fn allocateDataConstSegment(self: *Zld) !void { |
| 863 | 861 | |
| 864 | 862 | fn allocateDataSegment(self: *Zld) !void { |
| 865 | 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 | 866 | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 869 | 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 | 904 | } |
| 907 | 905 | |
| 908 | 906 | fn allocateSymbols(self: *Zld) !void { |
| 909 | | for (self.objects.items) |*object, object_id| { |
| 910 | | for (object.locals.items()) |*entry| { |
| 911 | | const source_sym = object.symtab.items[entry.value.index.?]; |
| 912 | | const source_sect_id = source_sym.n_sect - 1; |
| 907 | for (self.objects.items) |object, object_id| { |
| 908 | for (object.symbols.items) |sym| { |
| 909 | const reg = sym.cast(Symbol.Regular) orelse continue; |
| 913 | 910 | |
| 914 | 911 | // TODO I am more and more convinced we should store the mapping as part of the Object struct. |
| 915 | 912 | const target_mapping = self.mappings.get(.{ |
| 916 | 913 | .object_id = @intCast(u16, object_id), |
| 917 | | .source_sect_id = source_sect_id, |
| 914 | .source_sect_id = reg.section, |
| 918 | 915 | }) orelse { |
| 919 | 916 | if (self.unhandled_sections.get(.{ |
| 920 | 917 | .object_id = @intCast(u16, object_id), |
| 921 | | .source_sect_id = source_sect_id, |
| 918 | .source_sect_id = reg.section, |
| 922 | 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 | 922 | return error.SectionNotMappedForSymbol; |
| 926 | 923 | }; |
| 927 | 924 | |
| 928 | 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 | 927 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| 931 | 928 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; |
| 932 | 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 | 934 | // TODO there might be a more generic way of doing this. |
| 938 | | var n_sect: u8 = 0; |
| 935 | var section: u8 = 0; |
| 939 | 936 | for (self.load_commands.items) |cmd, cmd_id| { |
| 940 | 937 | if (cmd != .Segment) break; |
| 941 | 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 | 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; |
| 949 | | entry.value.section = n_sect; |
| 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 | | }); |
| 945 | reg.address = address; |
| 946 | reg.section = section; |
| 998 | 947 | } |
| 999 | 948 | } |
| 1000 | 949 | } |