| ... | @@ -174,25 +174,6 @@ shstrtab_section_index: ?u32 = null, | ... | @@ -174,25 +174,6 @@ shstrtab_section_index: ?u32 = null, |
| 174 | strtab_section_index: ?u32 = null, | 174 | strtab_section_index: ?u32 = null, |
| 175 | symtab_section_index: ?u32 = null, | 175 | symtab_section_index: ?u32 = null, |
| 176 | | 176 | |
| 177 | // Linker-defined symbols | | |
| 178 | dynamic_index: ?Symbol.Index = null, | | |
| 179 | ehdr_start_index: ?Symbol.Index = null, | | |
| 180 | init_array_start_index: ?Symbol.Index = null, | | |
| 181 | init_array_end_index: ?Symbol.Index = null, | | |
| 182 | fini_array_start_index: ?Symbol.Index = null, | | |
| 183 | fini_array_end_index: ?Symbol.Index = null, | | |
| 184 | preinit_array_start_index: ?Symbol.Index = null, | | |
| 185 | preinit_array_end_index: ?Symbol.Index = null, | | |
| 186 | got_index: ?Symbol.Index = null, | | |
| 187 | plt_index: ?Symbol.Index = null, | | |
| 188 | end_index: ?Symbol.Index = null, | | |
| 189 | gnu_eh_frame_hdr_index: ?Symbol.Index = null, | | |
| 190 | dso_handle_index: ?Symbol.Index = null, | | |
| 191 | rela_iplt_start_index: ?Symbol.Index = null, | | |
| 192 | rela_iplt_end_index: ?Symbol.Index = null, | | |
| 193 | global_pointer_index: ?Symbol.Index = null, | | |
| 194 | start_stop_indexes: std.ArrayListUnmanaged(u32) = .{}, | | |
| 195 | | | |
| 196 | /// An array of symbols parsed across all input files. | 177 | /// An array of symbols parsed across all input files. |
| 197 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, | 178 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 198 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, | 179 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -484,7 +465,6 @@ pub fn deinit(self: *Elf) void { | ... | @@ -484,7 +465,6 @@ pub fn deinit(self: *Elf) void { |
| 484 | self.symbols_extra.deinit(gpa); | 465 | self.symbols_extra.deinit(gpa); |
| 485 | self.symbols_free_list.deinit(gpa); | 466 | self.symbols_free_list.deinit(gpa); |
| 486 | self.resolver.deinit(gpa); | 467 | self.resolver.deinit(gpa); |
| 487 | self.start_stop_indexes.deinit(gpa); | | |
| 488 | | 468 | |
| 489 | for (self.thunks.items) |*th| { | 469 | for (self.thunks.items) |*th| { |
| 490 | th.deinit(gpa); | 470 | th.deinit(gpa); |
| ... | @@ -1287,7 +1267,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1287,7 +1267,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1287 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); | 1267 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 1288 | self.files.set(index, .{ .linker_defined = .{ .index = index } }); | 1268 | self.files.set(index, .{ .linker_defined = .{ .index = index } }); |
| 1289 | self.linker_defined_index = index; | 1269 | self.linker_defined_index = index; |
| 1290 | const object = self.file(index).?.linker_defined; | 1270 | const object = self.linkerDefinedPtr().?; |
| 1291 | try object.init(gpa); | 1271 | try object.init(gpa); |
| 1292 | } | 1272 | } |
| 1293 | | 1273 | |
| ... | @@ -1327,7 +1307,9 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1327,7 +1307,9 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1327 | try self.finalizeMergeSections(); | 1307 | try self.finalizeMergeSections(); |
| 1328 | try self.initOutputSections(); | 1308 | try self.initOutputSections(); |
| 1329 | try self.initMergeSections(); | 1309 | try self.initMergeSections(); |
| 1330 | try self.addLinkerDefinedSymbols(); | 1310 | if (self.linkerDefinedPtr()) |obj| { |
| | 1311 | try obj.initSymbols(self); |
| | 1312 | } |
| 1331 | self.claimUnresolved(); | 1313 | self.claimUnresolved(); |
| 1332 | | 1314 | |
| 1333 | // Scan and create missing synthetic entries such as GOT indirection. | 1315 | // Scan and create missing synthetic entries such as GOT indirection. |
| ... | @@ -1353,7 +1335,9 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1353,7 +1335,9 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1353 | try self.sortPhdrs(); | 1335 | try self.sortPhdrs(); |
| 1354 | try self.allocateNonAllocSections(); | 1336 | try self.allocateNonAllocSections(); |
| 1355 | self.allocateSpecialPhdrs(); | 1337 | self.allocateSpecialPhdrs(); |
| 1356 | self.allocateLinkerDefinedSymbols(); | 1338 | if (self.linkerDefinedPtr()) |obj| { |
| | 1339 | obj.allocateSymbols(self); |
| | 1340 | } |
| 1357 | | 1341 | |
| 1358 | // Dump the state for easy debugging. | 1342 | // Dump the state for easy debugging. |
| 1359 | // State can be dumped via `--debug-log link_state`. | 1343 | // State can be dumped via `--debug-log link_state`. |
| ... | @@ -3063,205 +3047,6 @@ pub fn deleteExport( | ... | @@ -3063,205 +3047,6 @@ pub fn deleteExport( |
| 3063 | return self.zigObjectPtr().?.deleteExport(self, exported, name); | 3047 | return self.zigObjectPtr().?.deleteExport(self, exported, name); |
| 3064 | } | 3048 | } |
| 3065 | | 3049 | |
| 3066 | fn addLinkerDefinedSymbols(self: *Elf) !void { | | |
| 3067 | const comp = self.base.comp; | | |
| 3068 | const gpa = comp.gpa; | | |
| 3069 | | | |
| 3070 | const linker_defined_index = self.linker_defined_index orelse return; | | |
| 3071 | const linker_defined = self.file(linker_defined_index).?.linker_defined; | | |
| 3072 | self.dynamic_index = try linker_defined.addGlobal("_DYNAMIC", self); | | |
| 3073 | self.ehdr_start_index = try linker_defined.addGlobal("__ehdr_start", self); | | |
| 3074 | self.init_array_start_index = try linker_defined.addGlobal("__init_array_start", self); | | |
| 3075 | self.init_array_end_index = try linker_defined.addGlobal("__init_array_end", self); | | |
| 3076 | self.fini_array_start_index = try linker_defined.addGlobal("__fini_array_start", self); | | |
| 3077 | self.fini_array_end_index = try linker_defined.addGlobal("__fini_array_end", self); | | |
| 3078 | self.preinit_array_start_index = try linker_defined.addGlobal("__preinit_array_start", self); | | |
| 3079 | self.preinit_array_end_index = try linker_defined.addGlobal("__preinit_array_end", self); | | |
| 3080 | self.got_index = try linker_defined.addGlobal("_GLOBAL_OFFSET_TABLE_", self); | | |
| 3081 | self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self); | | |
| 3082 | self.end_index = try linker_defined.addGlobal("_end", self); | | |
| 3083 | | | |
| 3084 | if (comp.link_eh_frame_hdr) { | | |
| 3085 | self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self); | | |
| 3086 | } | | |
| 3087 | | | |
| 3088 | if (self.globalByName("__dso_handle")) |index| { | | |
| 3089 | if (self.symbol(index).file(self) == null) | | |
| 3090 | self.dso_handle_index = try linker_defined.addGlobal("__dso_handle", self); | | |
| 3091 | } | | |
| 3092 | | | |
| 3093 | self.rela_iplt_start_index = try linker_defined.addGlobal("__rela_iplt_start", self); | | |
| 3094 | self.rela_iplt_end_index = try linker_defined.addGlobal("__rela_iplt_end", self); | | |
| 3095 | | | |
| 3096 | for (self.shdrs.items) |shdr| { | | |
| 3097 | if (self.getStartStopBasename(shdr)) |name| { | | |
| 3098 | try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2); | | |
| 3099 | | | |
| 3100 | const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); | | |
| 3101 | defer gpa.free(start); | | |
| 3102 | const stop = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); | | |
| 3103 | defer gpa.free(stop); | | |
| 3104 | | | |
| 3105 | self.start_stop_indexes.appendAssumeCapacity(try linker_defined.addGlobal(start, self)); | | |
| 3106 | self.start_stop_indexes.appendAssumeCapacity(try linker_defined.addGlobal(stop, self)); | | |
| 3107 | } | | |
| 3108 | } | | |
| 3109 | | | |
| 3110 | if (self.getTarget().cpu.arch.isRISCV() and self.isEffectivelyDynLib()) { | | |
| 3111 | self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self); | | |
| 3112 | } | | |
| 3113 | | | |
| 3114 | linker_defined.resolveSymbols(self); | | |
| 3115 | } | | |
| 3116 | | | |
| 3117 | fn allocateLinkerDefinedSymbols(self: *Elf) void { | | |
| 3118 | const comp = self.base.comp; | | |
| 3119 | const link_mode = comp.config.link_mode; | | |
| 3120 | | | |
| 3121 | // _DYNAMIC | | |
| 3122 | if (self.dynamic_section_index) |shndx| { | | |
| 3123 | const shdr = &self.shdrs.items[shndx]; | | |
| 3124 | const symbol_ptr = self.symbol(self.dynamic_index.?); | | |
| 3125 | symbol_ptr.value = @intCast(shdr.sh_addr); | | |
| 3126 | symbol_ptr.output_section_index = shndx; | | |
| 3127 | } | | |
| 3128 | | | |
| 3129 | // __ehdr_start | | |
| 3130 | { | | |
| 3131 | const symbol_ptr = self.symbol(self.ehdr_start_index.?); | | |
| 3132 | symbol_ptr.value = @intCast(self.image_base); | | |
| 3133 | symbol_ptr.output_section_index = 1; | | |
| 3134 | } | | |
| 3135 | | | |
| 3136 | // __init_array_start, __init_array_end | | |
| 3137 | if (self.sectionByName(".init_array")) |shndx| { | | |
| 3138 | const start_sym = self.symbol(self.init_array_start_index.?); | | |
| 3139 | const end_sym = self.symbol(self.init_array_end_index.?); | | |
| 3140 | const shdr = &self.shdrs.items[shndx]; | | |
| 3141 | start_sym.output_section_index = shndx; | | |
| 3142 | start_sym.value = @intCast(shdr.sh_addr); | | |
| 3143 | end_sym.output_section_index = shndx; | | |
| 3144 | end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size); | | |
| 3145 | } | | |
| 3146 | | | |
| 3147 | // __fini_array_start, __fini_array_end | | |
| 3148 | if (self.sectionByName(".fini_array")) |shndx| { | | |
| 3149 | const start_sym = self.symbol(self.fini_array_start_index.?); | | |
| 3150 | const end_sym = self.symbol(self.fini_array_end_index.?); | | |
| 3151 | const shdr = &self.shdrs.items[shndx]; | | |
| 3152 | start_sym.output_section_index = shndx; | | |
| 3153 | start_sym.value = @intCast(shdr.sh_addr); | | |
| 3154 | end_sym.output_section_index = shndx; | | |
| 3155 | end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size); | | |
| 3156 | } | | |
| 3157 | | | |
| 3158 | // __preinit_array_start, __preinit_array_end | | |
| 3159 | if (self.sectionByName(".preinit_array")) |shndx| { | | |
| 3160 | const start_sym = self.symbol(self.preinit_array_start_index.?); | | |
| 3161 | const end_sym = self.symbol(self.preinit_array_end_index.?); | | |
| 3162 | const shdr = &self.shdrs.items[shndx]; | | |
| 3163 | start_sym.output_section_index = shndx; | | |
| 3164 | start_sym.value = @intCast(shdr.sh_addr); | | |
| 3165 | end_sym.output_section_index = shndx; | | |
| 3166 | end_sym.value = @intCast(shdr.sh_addr + shdr.sh_size); | | |
| 3167 | } | | |
| 3168 | | | |
| 3169 | // _GLOBAL_OFFSET_TABLE_ | | |
| 3170 | if (self.getTarget().cpu.arch == .x86_64) { | | |
| 3171 | if (self.got_plt_section_index) |shndx| { | | |
| 3172 | const shdr = self.shdrs.items[shndx]; | | |
| 3173 | const sym = self.symbol(self.got_index.?); | | |
| 3174 | sym.value = @intCast(shdr.sh_addr); | | |
| 3175 | sym.output_section_index = shndx; | | |
| 3176 | } | | |
| 3177 | } else { | | |
| 3178 | if (self.got_section_index) |shndx| { | | |
| 3179 | const shdr = self.shdrs.items[shndx]; | | |
| 3180 | const sym = self.symbol(self.got_index.?); | | |
| 3181 | sym.value = @intCast(shdr.sh_addr); | | |
| 3182 | sym.output_section_index = shndx; | | |
| 3183 | } | | |
| 3184 | } | | |
| 3185 | | | |
| 3186 | // _PROCEDURE_LINKAGE_TABLE_ | | |
| 3187 | if (self.plt_section_index) |shndx| { | | |
| 3188 | const shdr = &self.shdrs.items[shndx]; | | |
| 3189 | const symbol_ptr = self.symbol(self.plt_index.?); | | |
| 3190 | symbol_ptr.value = @intCast(shdr.sh_addr); | | |
| 3191 | symbol_ptr.output_section_index = shndx; | | |
| 3192 | } | | |
| 3193 | | | |
| 3194 | // __dso_handle | | |
| 3195 | if (self.dso_handle_index) |index| { | | |
| 3196 | const shdr = &self.shdrs.items[1]; | | |
| 3197 | const symbol_ptr = self.symbol(index); | | |
| 3198 | symbol_ptr.value = @intCast(shdr.sh_addr); | | |
| 3199 | symbol_ptr.output_section_index = 0; | | |
| 3200 | } | | |
| 3201 | | | |
| 3202 | // __GNU_EH_FRAME_HDR | | |
| 3203 | if (self.eh_frame_hdr_section_index) |shndx| { | | |
| 3204 | const shdr = &self.shdrs.items[shndx]; | | |
| 3205 | const symbol_ptr = self.symbol(self.gnu_eh_frame_hdr_index.?); | | |
| 3206 | symbol_ptr.value = @intCast(shdr.sh_addr); | | |
| 3207 | symbol_ptr.output_section_index = shndx; | | |
| 3208 | } | | |
| 3209 | | | |
| 3210 | // __rela_iplt_start, __rela_iplt_end | | |
| 3211 | if (self.rela_dyn_section_index) |shndx| blk: { | | |
| 3212 | if (link_mode != .static or comp.config.pie) break :blk; | | |
| 3213 | const shdr = &self.shdrs.items[shndx]; | | |
| 3214 | const end_addr = shdr.sh_addr + shdr.sh_size; | | |
| 3215 | const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); | | |
| 3216 | const start_sym = self.symbol(self.rela_iplt_start_index.?); | | |
| 3217 | const end_sym = self.symbol(self.rela_iplt_end_index.?); | | |
| 3218 | start_sym.value = @intCast(start_addr); | | |
| 3219 | start_sym.output_section_index = shndx; | | |
| 3220 | end_sym.value = @intCast(end_addr); | | |
| 3221 | end_sym.output_section_index = shndx; | | |
| 3222 | } | | |
| 3223 | | | |
| 3224 | // _end | | |
| 3225 | { | | |
| 3226 | const end_symbol = self.symbol(self.end_index.?); | | |
| 3227 | for (self.shdrs.items, 0..) |shdr, shndx| { | | |
| 3228 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) { | | |
| 3229 | end_symbol.value = @intCast(shdr.sh_addr + shdr.sh_size); | | |
| 3230 | end_symbol.output_section_index = @intCast(shndx); | | |
| 3231 | } | | |
| 3232 | } | | |
| 3233 | } | | |
| 3234 | | | |
| 3235 | // __start_*, __stop_* | | |
| 3236 | { | | |
| 3237 | var index: usize = 0; | | |
| 3238 | while (index < self.start_stop_indexes.items.len) : (index += 2) { | | |
| 3239 | const start = self.symbol(self.start_stop_indexes.items[index]); | | |
| 3240 | const name = start.name(self); | | |
| 3241 | const stop = self.symbol(self.start_stop_indexes.items[index + 1]); | | |
| 3242 | const shndx = self.sectionByName(name["__start_".len..]).?; | | |
| 3243 | const shdr = &self.shdrs.items[shndx]; | | |
| 3244 | start.value = @intCast(shdr.sh_addr); | | |
| 3245 | start.output_section_index = shndx; | | |
| 3246 | stop.value = @intCast(shdr.sh_addr + shdr.sh_size); | | |
| 3247 | stop.output_section_index = shndx; | | |
| 3248 | } | | |
| 3249 | } | | |
| 3250 | | | |
| 3251 | // __global_pointer$ | | |
| 3252 | if (self.global_pointer_index) |index| { | | |
| 3253 | const sym = self.symbol(index); | | |
| 3254 | if (self.sectionByName(".sdata")) |shndx| { | | |
| 3255 | const shdr = self.shdrs.items[shndx]; | | |
| 3256 | sym.value = @intCast(shdr.sh_addr + 0x800); | | |
| 3257 | sym.output_section_index = shndx; | | |
| 3258 | } else { | | |
| 3259 | sym.value = 0; | | |
| 3260 | sym.output_section_index = 0; | | |
| 3261 | } | | |
| 3262 | } | | |
| 3263 | } | | |
| 3264 | | | |
| 3265 | fn checkDuplicates(self: *Elf) !void { | 3050 | fn checkDuplicates(self: *Elf) !void { |
| 3266 | const gpa = self.base.comp.gpa; | 3051 | const gpa = self.base.comp.gpa; |
| 3267 | | 3052 | |
| ... | @@ -4964,9 +4749,8 @@ pub fn writeSymtab(self: *Elf) !void { | ... | @@ -4964,9 +4749,8 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4964 | file_ptr.writeSymtab(self); | 4749 | file_ptr.writeSymtab(self); |
| 4965 | } | 4750 | } |
| 4966 | | 4751 | |
| 4967 | if (self.linker_defined_index) |index| { | 4752 | if (self.linkerDefinedPtr()) |obj| { |
| 4968 | const file_ptr = self.file(index).?; | 4753 | obj.asFile().writeSymtab(self); |
| 4969 | file_ptr.writeSymtab(self); | | |
| 4970 | } | 4754 | } |
| 4971 | | 4755 | |
| 4972 | if (self.zig_got_section_index) |_| { | 4756 | if (self.zig_got_section_index) |_| { |
| ... | @@ -5529,7 +5313,7 @@ fn sortRelaDyn(self: *Elf) void { | ... | @@ -5529,7 +5313,7 @@ fn sortRelaDyn(self: *Elf) void { |
| 5529 | mem.sort(elf.Elf64_Rela, self.rela_dyn.items, self, Sort.lessThan); | 5313 | mem.sort(elf.Elf64_Rela, self.rela_dyn.items, self, Sort.lessThan); |
| 5530 | } | 5314 | } |
| 5531 | | 5315 | |
| 5532 | fn calcNumIRelativeRelocs(self: *Elf) usize { | 5316 | pub fn calcNumIRelativeRelocs(self: *Elf) usize { |
| 5533 | var count: usize = self.num_ifunc_dynrelocs; | 5317 | var count: usize = self.num_ifunc_dynrelocs; |
| 5534 | | 5318 | |
| 5535 | for (self.got.entries.items) |entry| { | 5319 | for (self.got.entries.items) |entry| { |
| ... | @@ -5551,7 +5335,7 @@ pub fn isCIdentifier(name: []const u8) bool { | ... | @@ -5551,7 +5335,7 @@ pub fn isCIdentifier(name: []const u8) bool { |
| 5551 | return true; | 5335 | return true; |
| 5552 | } | 5336 | } |
| 5553 | | 5337 | |
| 5554 | fn getStartStopBasename(self: *Elf, shdr: elf.Elf64_Shdr) ?[]const u8 { | 5338 | pub fn getStartStopBasename(self: *Elf, shdr: elf.Elf64_Shdr) ?[]const u8 { |
| 5555 | const name = self.getShString(shdr.sh_name); | 5339 | const name = self.getShString(shdr.sh_name); |
| 5556 | if (shdr.sh_flags & elf.SHF_ALLOC != 0 and name.len > 0) { | 5340 | if (shdr.sh_flags & elf.SHF_ALLOC != 0 and name.len > 0) { |
| 5557 | if (isCIdentifier(name)) return name; | 5341 | if (isCIdentifier(name)) return name; |
| ... | @@ -5709,6 +5493,11 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject { | ... | @@ -5709,6 +5493,11 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject { |
| 5709 | return self.file(index).?.zig_object; | 5493 | return self.file(index).?.zig_object; |
| 5710 | } | 5494 | } |
| 5711 | | 5495 | |
| | 5496 | pub fn linkerDefinedPtr(self: *Elf) ?*LinkerDefined { |
| | 5497 | const index = self.linker_defined_index orelse return null; |
| | 5498 | return self.file(index).?.linker_defined; |
| | 5499 | } |
| | 5500 | |
| 5712 | pub fn getOrCreateMergeSection(self: *Elf, name: [:0]const u8, flags: u64, @"type": u32) !MergeSection.Index { | 5501 | pub fn getOrCreateMergeSection(self: *Elf, name: [:0]const u8, flags: u64, @"type": u32) !MergeSection.Index { |
| 5713 | const gpa = self.base.comp.gpa; | 5502 | const gpa = self.base.comp.gpa; |
| 5714 | const out_name = name: { | 5503 | const out_name = name: { |