| ... | @@ -42,30 +42,28 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void { | ... | @@ -42,30 +42,28 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void { |
| 42 | try self.strtab.append(allocator, 0); | 42 | try self.strtab.append(allocator, 0); |
| 43 | } | 43 | } |
| 44 | | 44 | |
| 45 | pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | 45 | fn newSymbolAssumeCapacity(self: *LinkerDefined, name_off: u32, elf_file: *Elf) Symbol.Index { |
| 46 | const newSymbolAssumeCapacity = struct { | 46 | const esym_index: u32 = @intCast(self.symtab.items.len); |
| 47 | fn newSymbolAssumeCapacity(ld: *LinkerDefined, name_off: u32, ef: *Elf) Symbol.Index { | 47 | const esym = self.symtab.addOneAssumeCapacity(); |
| 48 | const esym_index: u32 = @intCast(ld.symtab.items.len); | 48 | esym.* = .{ |
| 49 | const esym = ld.symtab.addOneAssumeCapacity(); | 49 | .st_name = name_off, |
| 50 | esym.* = .{ | 50 | .st_info = elf.STB_GLOBAL << 4, |
| 51 | .st_name = name_off, | 51 | .st_other = @intFromEnum(elf.STV.HIDDEN), |
| 52 | .st_info = elf.STB_GLOBAL << 4, | 52 | .st_shndx = elf.SHN_ABS, |
| 53 | .st_other = @intFromEnum(elf.STV.HIDDEN), | 53 | .st_value = 0, |
| 54 | .st_shndx = elf.SHN_ABS, | 54 | .st_size = 0, |
| 55 | .st_value = 0, | 55 | }; |
| 56 | .st_size = 0, | 56 | const index = self.addSymbolAssumeCapacity(); |
| 57 | }; | 57 | const symbol = &self.symbols.items[index]; |
| 58 | const index = ld.addSymbolAssumeCapacity(); | 58 | symbol.name_offset = name_off; |
| 59 | const symbol = &ld.symbols.items[index]; | 59 | symbol.extra_index = self.addSymbolExtraAssumeCapacity(.{}); |
| 60 | symbol.name_offset = name_off; | 60 | symbol.ref = .{ .index = 0, .file = 0 }; |
| 61 | symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{}); | 61 | symbol.esym_index = esym_index; |
| 62 | symbol.ref = .{ .index = 0, .file = 0 }; | 62 | symbol.version_index = elf_file.default_sym_version; |
| 63 | symbol.esym_index = esym_index; | 63 | return index; |
| 64 | symbol.version_index = ef.default_sym_version; | 64 | } |
| 65 | return index; | | |
| 66 | } | | |
| 67 | }.newSymbolAssumeCapacity; | | |
| 68 | | 65 | |
| | 66 | pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 69 | const gpa = elf_file.base.comp.gpa; | 67 | const gpa = elf_file.base.comp.gpa; |
| 70 | | 68 | |
| 71 | var nsyms: usize = 0; | 69 | var nsyms: usize = 0; |
| ... | @@ -93,18 +91,6 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | ... | @@ -93,18 +91,6 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 93 | nsyms += 1; // __global_pointer$ | 91 | nsyms += 1; // __global_pointer$ |
| 94 | } | 92 | } |
| 95 | | 93 | |
| 96 | var start_stop_count: usize = 0; | | |
| 97 | for (elf_file.objects.items) |index| { | | |
| 98 | const object = elf_file.file(index).?.object; | | |
| 99 | for (object.shdrs.items) |shdr| { | | |
| 100 | if (object.getStartStopBasename(shdr)) |_| { | | |
| 101 | start_stop_count += 2; // __start_, __stop_ | | |
| 102 | } | | |
| 103 | } | | |
| 104 | } | | |
| 105 | nsyms += start_stop_count; | | |
| 106 | | | |
| 107 | try self.start_stop_indexes.ensureTotalCapacityPrecise(gpa, start_stop_count); | | |
| 108 | try self.symtab.ensureTotalCapacityPrecise(gpa, nsyms); | 94 | try self.symtab.ensureTotalCapacityPrecise(gpa, nsyms); |
| 109 | try self.symbols.ensureTotalCapacityPrecise(gpa, nsyms); | 95 | try self.symbols.ensureTotalCapacityPrecise(gpa, nsyms); |
| 110 | try self.symbols_extra.ensureTotalCapacityPrecise(gpa, nsyms * @sizeOf(Symbol.Extra)); | 96 | try self.symbols_extra.ensureTotalCapacityPrecise(gpa, nsyms * @sizeOf(Symbol.Extra)); |
| ... | @@ -113,44 +99,67 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | ... | @@ -113,44 +99,67 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 113 | @memset(self.symbols_resolver.items, 0); | 99 | @memset(self.symbols_resolver.items, 0); |
| 114 | | 100 | |
| 115 | if (elf_file.entry_name) |name| { | 101 | if (elf_file.entry_name) |name| { |
| 116 | self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, name), elf_file); | 102 | self.entry_index = self.newSymbolAssumeCapacity(try self.addString(gpa, name), elf_file); |
| 117 | } | 103 | } |
| 118 | | 104 | |
| 119 | self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"), elf_file); | 105 | self.dynamic_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_DYNAMIC"), elf_file); |
| 120 | self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"), elf_file); | 106 | self.ehdr_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__ehdr_start"), elf_file); |
| 121 | self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"), elf_file); | 107 | self.init_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__init_array_start"), elf_file); |
| 122 | self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"), elf_file); | 108 | self.init_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__init_array_end"), elf_file); |
| 123 | self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"), elf_file); | 109 | self.fini_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__fini_array_start"), elf_file); |
| 124 | self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"), elf_file); | 110 | self.fini_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__fini_array_end"), elf_file); |
| 125 | self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"), elf_file); | 111 | self.preinit_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__preinit_array_start"), elf_file); |
| 126 | self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"), elf_file); | 112 | self.preinit_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__preinit_array_end"), elf_file); |
| 127 | self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file); | 113 | self.got_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file); |
| 128 | self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file); | 114 | self.plt_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file); |
| 129 | self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"), elf_file); | 115 | self.end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_end"), elf_file); |
| 130 | | 116 | |
| 131 | if (elf_file.base.comp.link_eh_frame_hdr) { | 117 | if (elf_file.base.comp.link_eh_frame_hdr) { |
| 132 | self.gnu_eh_frame_hdr_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__GNU_EH_FRAME_HDR"), elf_file); | 118 | self.gnu_eh_frame_hdr_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__GNU_EH_FRAME_HDR"), elf_file); |
| 133 | } | 119 | } |
| 134 | | 120 | |
| 135 | self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"), elf_file); | 121 | self.dso_handle_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__dso_handle"), elf_file); |
| 136 | self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"), elf_file); | 122 | self.rela_iplt_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__rela_iplt_start"), elf_file); |
| 137 | self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"), elf_file); | 123 | self.rela_iplt_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__rela_iplt_end"), elf_file); |
| 138 | | 124 | |
| 139 | if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) { | 125 | if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) { |
| 140 | self.global_pointer_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__global_pointer$"), elf_file); | 126 | self.global_pointer_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__global_pointer$"), elf_file); |
| | 127 | } |
| | 128 | } |
| | 129 | |
| | 130 | pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| | 131 | const gpa = elf_file.base.comp.gpa; |
| | 132 | |
| | 133 | var nsyms: usize = 0; |
| | 134 | for (elf_file.shdrs.items) |shdr| { |
| | 135 | if (elf_file.getStartStopBasename(shdr)) |_| { |
| | 136 | nsyms += 2; // __start_, __stop_ |
| | 137 | } |
| 141 | } | 138 | } |
| 142 | | 139 | |
| 143 | for (elf_file.objects.items) |index| { | 140 | try self.start_stop_indexes.ensureTotalCapacityPrecise(gpa, nsyms); |
| 144 | const object = elf_file.file(index).?.object; | 141 | try self.symtab.ensureUnusedCapacity(gpa, nsyms); |
| 145 | for (object.shdrs.items) |shdr| { | 142 | try self.symbols.ensureUnusedCapacity(gpa, nsyms); |
| 146 | if (object.getStartStopBasename(shdr)) |name| { | 143 | try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra)); |
| 147 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); | 144 | try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms); |
| 148 | defer gpa.free(start_name); | 145 | |
| 149 | const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); | 146 | for (elf_file.shdrs.items) |shdr| { |
| 150 | defer gpa.free(stop_name); | 147 | if (elf_file.getStartStopBasename(shdr)) |name| { |
| 151 | const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name), elf_file); | 148 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 152 | const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name), elf_file); | 149 | defer gpa.free(start_name); |
| 153 | self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop }); | 150 | const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); |
| | 151 | defer gpa.free(stop_name); |
| | 152 | |
| | 153 | for (&[_][]const u8{ start_name, stop_name }) |nn| { |
| | 154 | const index = self.newSymbolAssumeCapacity(try self.addString(gpa, nn), elf_file); |
| | 155 | self.start_stop_indexes.appendAssumeCapacity(index); |
| | 156 | const gop = try elf_file.resolver.getOrPut(gpa, .{ |
| | 157 | .index = index, |
| | 158 | .file = self.index, |
| | 159 | }, elf_file); |
| | 160 | assert(!gop.found_existing); |
| | 161 | gop.ref.* = .{ .index = index, .file = self.index }; |
| | 162 | self.symbols_resolver.appendAssumeCapacity(gop.index); |
| 154 | } | 163 | } |
| 155 | } | 164 | } |
| 156 | } | 165 | } |