| ... | ... | @@ -42,30 +42,28 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void { |
| 42 | 42 | try self.strtab.append(allocator, 0); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | | pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 46 | | const newSymbolAssumeCapacity = struct { |
| 47 | | fn newSymbolAssumeCapacity(ld: *LinkerDefined, name_off: u32, ef: *Elf) Symbol.Index { |
| 48 | | const esym_index: u32 = @intCast(ld.symtab.items.len); |
| 49 | | const esym = ld.symtab.addOneAssumeCapacity(); |
| 50 | | esym.* = .{ |
| 51 | | .st_name = name_off, |
| 52 | | .st_info = elf.STB_GLOBAL << 4, |
| 53 | | .st_other = @intFromEnum(elf.STV.HIDDEN), |
| 54 | | .st_shndx = elf.SHN_ABS, |
| 55 | | .st_value = 0, |
| 56 | | .st_size = 0, |
| 57 | | }; |
| 58 | | const index = ld.addSymbolAssumeCapacity(); |
| 59 | | const symbol = &ld.symbols.items[index]; |
| 60 | | symbol.name_offset = name_off; |
| 61 | | symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{}); |
| 62 | | symbol.ref = .{ .index = 0, .file = 0 }; |
| 63 | | symbol.esym_index = esym_index; |
| 64 | | symbol.version_index = ef.default_sym_version; |
| 65 | | return index; |
| 66 | | } |
| 67 | | }.newSymbolAssumeCapacity; |
| 45 | fn newSymbolAssumeCapacity(self: *LinkerDefined, name_off: u32, elf_file: *Elf) Symbol.Index { |
| 46 | const esym_index: u32 = @intCast(self.symtab.items.len); |
| 47 | const esym = self.symtab.addOneAssumeCapacity(); |
| 48 | esym.* = .{ |
| 49 | .st_name = name_off, |
| 50 | .st_info = elf.STB_GLOBAL << 4, |
| 51 | .st_other = @intFromEnum(elf.STV.HIDDEN), |
| 52 | .st_shndx = elf.SHN_ABS, |
| 53 | .st_value = 0, |
| 54 | .st_size = 0, |
| 55 | }; |
| 56 | const index = self.addSymbolAssumeCapacity(); |
| 57 | const symbol = &self.symbols.items[index]; |
| 58 | symbol.name_offset = name_off; |
| 59 | symbol.extra_index = self.addSymbolExtraAssumeCapacity(.{}); |
| 60 | symbol.ref = .{ .index = 0, .file = 0 }; |
| 61 | symbol.esym_index = esym_index; |
| 62 | symbol.version_index = elf_file.default_sym_version; |
| 63 | return index; |
| 64 | } |
| 68 | 65 | |
| 66 | pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 69 | 67 | const gpa = elf_file.base.comp.gpa; |
| 70 | 68 | |
| 71 | 69 | var nsyms: usize = 0; |
| ... | ... | @@ -93,18 +91,6 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 93 | 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 | 94 | try self.symtab.ensureTotalCapacityPrecise(gpa, nsyms); |
| 109 | 95 | try self.symbols.ensureTotalCapacityPrecise(gpa, nsyms); |
| 110 | 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 | 99 | @memset(self.symbols_resolver.items, 0); |
| 114 | 100 | |
| 115 | 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); |
| 120 | | self.ehdr_start_index = newSymbolAssumeCapacity(self, 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); |
| 122 | | self.init_array_end_index = newSymbolAssumeCapacity(self, 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); |
| 124 | | self.fini_array_end_index = newSymbolAssumeCapacity(self, 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); |
| 126 | | self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"), elf_file); |
| 127 | | self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file); |
| 128 | | self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file); |
| 129 | | self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"), elf_file); |
| 105 | self.dynamic_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_DYNAMIC"), elf_file); |
| 106 | self.ehdr_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__ehdr_start"), elf_file); |
| 107 | self.init_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__init_array_start"), elf_file); |
| 108 | self.init_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__init_array_end"), elf_file); |
| 109 | self.fini_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__fini_array_start"), elf_file); |
| 110 | self.fini_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__fini_array_end"), elf_file); |
| 111 | self.preinit_array_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__preinit_array_start"), elf_file); |
| 112 | self.preinit_array_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__preinit_array_end"), elf_file); |
| 113 | self.got_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file); |
| 114 | self.plt_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file); |
| 115 | self.end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "_end"), elf_file); |
| 130 | 116 | |
| 131 | 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); |
| 136 | | self.rela_iplt_start_index = newSymbolAssumeCapacity(self, 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); |
| 121 | self.dso_handle_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__dso_handle"), elf_file); |
| 122 | self.rela_iplt_start_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__rela_iplt_start"), elf_file); |
| 123 | self.rela_iplt_end_index = self.newSymbolAssumeCapacity(try self.addString(gpa, "__rela_iplt_end"), elf_file); |
| 138 | 124 | |
| 139 | 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| { |
| 144 | | const object = elf_file.file(index).?.object; |
| 145 | | for (object.shdrs.items) |shdr| { |
| 146 | | if (object.getStartStopBasename(shdr)) |name| { |
| 147 | | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 148 | | defer gpa.free(start_name); |
| 149 | | const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); |
| 150 | | defer gpa.free(stop_name); |
| 151 | | const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name), elf_file); |
| 152 | | const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name), elf_file); |
| 153 | | self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop }); |
| 140 | try self.start_stop_indexes.ensureTotalCapacityPrecise(gpa, nsyms); |
| 141 | try self.symtab.ensureUnusedCapacity(gpa, nsyms); |
| 142 | try self.symbols.ensureUnusedCapacity(gpa, nsyms); |
| 143 | try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra)); |
| 144 | try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms); |
| 145 | |
| 146 | for (elf_file.shdrs.items) |shdr| { |
| 147 | if (elf_file.getStartStopBasename(shdr)) |name| { |
| 148 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 149 | defer gpa.free(start_name); |
| 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 | } |