| ... | ... | @@ -174,25 +174,6 @@ shstrtab_section_index: ?u32 = null, |
| 174 | 174 | strtab_section_index: ?u32 = null, |
| 175 | 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 | 177 | /// An array of symbols parsed across all input files. |
| 197 | 178 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 198 | 179 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| ... | ... | @@ -484,7 +465,6 @@ pub fn deinit(self: *Elf) void { |
| 484 | 465 | self.symbols_extra.deinit(gpa); |
| 485 | 466 | self.symbols_free_list.deinit(gpa); |
| 486 | 467 | self.resolver.deinit(gpa); |
| 487 | | self.start_stop_indexes.deinit(gpa); |
| 488 | 468 | |
| 489 | 469 | for (self.thunks.items) |*th| { |
| 490 | 470 | th.deinit(gpa); |
| ... | ... | @@ -1287,7 +1267,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1287 | 1267 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 1288 | 1268 | self.files.set(index, .{ .linker_defined = .{ .index = index } }); |
| 1289 | 1269 | self.linker_defined_index = index; |
| 1290 | | const object = self.file(index).?.linker_defined; |
| 1270 | const object = self.linkerDefinedPtr().?; |
| 1291 | 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 | 1307 | try self.finalizeMergeSections(); |
| 1328 | 1308 | try self.initOutputSections(); |
| 1329 | 1309 | try self.initMergeSections(); |
| 1330 | | try self.addLinkerDefinedSymbols(); |
| 1310 | if (self.linkerDefinedPtr()) |obj| { |
| 1311 | try obj.initSymbols(self); |
| 1312 | } |
| 1331 | 1313 | self.claimUnresolved(); |
| 1332 | 1314 | |
| 1333 | 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 | 1335 | try self.sortPhdrs(); |
| 1354 | 1336 | try self.allocateNonAllocSections(); |
| 1355 | 1337 | self.allocateSpecialPhdrs(); |
| 1356 | | self.allocateLinkerDefinedSymbols(); |
| 1338 | if (self.linkerDefinedPtr()) |obj| { |
| 1339 | obj.allocateSymbols(self); |
| 1340 | } |
| 1357 | 1341 | |
| 1358 | 1342 | // Dump the state for easy debugging. |
| 1359 | 1343 | // State can be dumped via `--debug-log link_state`. |
| ... | ... | @@ -3063,205 +3047,6 @@ pub fn deleteExport( |
| 3063 | 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 | 3050 | fn checkDuplicates(self: *Elf) !void { |
| 3266 | 3051 | const gpa = self.base.comp.gpa; |
| 3267 | 3052 | |
| ... | ... | @@ -4964,9 +4749,8 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4964 | 4749 | file_ptr.writeSymtab(self); |
| 4965 | 4750 | } |
| 4966 | 4751 | |
| 4967 | | if (self.linker_defined_index) |index| { |
| 4968 | | const file_ptr = self.file(index).?; |
| 4969 | | file_ptr.writeSymtab(self); |
| 4752 | if (self.linkerDefinedPtr()) |obj| { |
| 4753 | obj.asFile().writeSymtab(self); |
| 4970 | 4754 | } |
| 4971 | 4755 | |
| 4972 | 4756 | if (self.zig_got_section_index) |_| { |
| ... | ... | @@ -5529,7 +5313,7 @@ fn sortRelaDyn(self: *Elf) void { |
| 5529 | 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 | 5317 | var count: usize = self.num_ifunc_dynrelocs; |
| 5534 | 5318 | |
| 5535 | 5319 | for (self.got.entries.items) |entry| { |
| ... | ... | @@ -5551,7 +5335,7 @@ pub fn isCIdentifier(name: []const u8) bool { |
| 5551 | 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 | 5339 | const name = self.getShString(shdr.sh_name); |
| 5556 | 5340 | if (shdr.sh_flags & elf.SHF_ALLOC != 0 and name.len > 0) { |
| 5557 | 5341 | if (isCIdentifier(name)) return name; |
| ... | ... | @@ -5709,6 +5493,11 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject { |
| 5709 | 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 | 5501 | pub fn getOrCreateMergeSection(self: *Elf, name: [:0]const u8, flags: u64, @"type": u32) !MergeSection.Index { |
| 5713 | 5502 | const gpa = self.base.comp.gpa; |
| 5714 | 5503 | const out_name = name: { |