| ... | ... | @@ -36,6 +36,7 @@ phdr_load_rw_index: ?u16 = null, |
| 36 | 36 | |
| 37 | 37 | entry_addr: ?u64 = null, |
| 38 | 38 | page_size: u32, |
| 39 | default_sym_version: elf.Elf64_Versym, |
| 39 | 40 | |
| 40 | 41 | /// .shstrtab buffer |
| 41 | 42 | shstrtab: StringTable(.strtab) = .{}, |
| ... | ... | @@ -57,6 +58,23 @@ shstrtab_section_index: ?u16 = null, |
| 57 | 58 | strtab_section_index: ?u16 = null, |
| 58 | 59 | symtab_section_index: ?u16 = null, |
| 59 | 60 | |
| 61 | // Linker-defined symbols |
| 62 | dynamic_index: ?Symbol.Index = null, |
| 63 | ehdr_start_index: ?Symbol.Index = null, |
| 64 | init_array_start_index: ?Symbol.Index = null, |
| 65 | init_array_end_index: ?Symbol.Index = null, |
| 66 | fini_array_start_index: ?Symbol.Index = null, |
| 67 | fini_array_end_index: ?Symbol.Index = null, |
| 68 | preinit_array_start_index: ?Symbol.Index = null, |
| 69 | preinit_array_end_index: ?Symbol.Index = null, |
| 70 | got_index: ?Symbol.Index = null, |
| 71 | plt_index: ?Symbol.Index = null, |
| 72 | end_index: ?Symbol.Index = null, |
| 73 | gnu_eh_frame_hdr_index: ?Symbol.Index = null, |
| 74 | dso_handle_index: ?Symbol.Index = null, |
| 75 | rela_iplt_start_index: ?Symbol.Index = null, |
| 76 | rela_iplt_end_index: ?Symbol.Index = null, |
| 77 | |
| 60 | 78 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 61 | 79 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 62 | 80 | resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| ... | ... | @@ -188,6 +206,10 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf { |
| 188 | 206 | .sparc64 => 0x2000, |
| 189 | 207 | else => 0x1000, |
| 190 | 208 | }; |
| 209 | const default_sym_version: elf.Elf64_Versym = if (options.output_mode == .Lib and options.link_mode == .Dynamic) |
| 210 | elf.VER_NDX_GLOBAL |
| 211 | else |
| 212 | elf.VER_NDX_LOCAL; |
| 191 | 213 | |
| 192 | 214 | var dwarf: ?Dwarf = if (!options.strip and options.module != null) |
| 193 | 215 | Dwarf.init(gpa, &self.base, options.target) |
| ... | ... | @@ -204,6 +226,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf { |
| 204 | 226 | .dwarf = dwarf, |
| 205 | 227 | .ptr_width = ptr_width, |
| 206 | 228 | .page_size = page_size, |
| 229 | .default_sym_version = default_sym_version, |
| 207 | 230 | }; |
| 208 | 231 | const use_llvm = options.use_llvm; |
| 209 | 232 | if (use_llvm) { |
| ... | ... | @@ -987,11 +1010,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 987 | 1010 | // corresponds to the Zig source code. |
| 988 | 1011 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 989 | 1012 | |
| 990 | | self.linker_defined_index = blk: { |
| 991 | | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 992 | | self.files.set(index, .{ .linker_defined = .{ .index = index } }); |
| 993 | | break :blk index; |
| 1013 | const compiler_rt_path: ?[]const u8 = blk: { |
| 1014 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 1015 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| 1016 | break :blk null; |
| 994 | 1017 | }; |
| 1018 | _ = compiler_rt_path; |
| 995 | 1019 | |
| 996 | 1020 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 997 | 1021 | // Most lazy symbols can be updated on first use, but |
| ... | ... | @@ -1023,6 +1047,16 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1023 | 1047 | try dw.flushModule(module); |
| 1024 | 1048 | } |
| 1025 | 1049 | |
| 1050 | if (self.linker_defined_index == null) { |
| 1051 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| 1052 | self.files.set(index, .{ .linker_defined = .{ .index = index } }); |
| 1053 | self.linker_defined_index = index; |
| 1054 | } |
| 1055 | |
| 1056 | try self.addLinkerDefinedSymbols(); |
| 1057 | |
| 1058 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| 1059 | // the relocations. |
| 1026 | 1060 | { |
| 1027 | 1061 | var it = self.relocs.iterator(); |
| 1028 | 1062 | while (it.next()) |entry| { |
| ... | ... | @@ -2682,6 +2716,54 @@ pub fn deleteDeclExport( |
| 2682 | 2716 | sym_index.* = 0; |
| 2683 | 2717 | } |
| 2684 | 2718 | |
| 2719 | fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 2720 | const linker_defined_index = self.linker_defined_index orelse return; |
| 2721 | const linker_defined = self.file(linker_defined_index).?.linker_defined; |
| 2722 | self.dynamic_index = try linker_defined.addGlobal("_DYNAMIC", self); |
| 2723 | self.ehdr_start_index = try linker_defined.addGlobal("__ehdr_start", self); |
| 2724 | self.init_array_start_index = try linker_defined.addGlobal("__init_array_start", self); |
| 2725 | self.init_array_end_index = try linker_defined.addGlobal("__init_array_end", self); |
| 2726 | self.fini_array_start_index = try linker_defined.addGlobal("__fini_array_start", self); |
| 2727 | self.fini_array_end_index = try linker_defined.addGlobal("__fini_array_end", self); |
| 2728 | self.preinit_array_start_index = try linker_defined.addGlobal("__preinit_array_start", self); |
| 2729 | self.preinit_array_end_index = try linker_defined.addGlobal("__preinit_array_end", self); |
| 2730 | self.got_index = try linker_defined.addGlobal("_GLOBAL_OFFSET_TABLE_", self); |
| 2731 | self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self); |
| 2732 | self.end_index = try linker_defined.addGlobal("_end", self); |
| 2733 | |
| 2734 | if (self.base.options.eh_frame_hdr) { |
| 2735 | self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self); |
| 2736 | } |
| 2737 | |
| 2738 | if (self.globalByName("__dso_handle")) |index| { |
| 2739 | if (self.symbol(index).file(self) == null) |
| 2740 | self.dso_handle_index = try linker_defined.addGlobal("__dso_handle", self); |
| 2741 | } |
| 2742 | |
| 2743 | self.rela_iplt_start_index = try linker_defined.addGlobal("__rela_iplt_start", self); |
| 2744 | self.rela_iplt_end_index = try linker_defined.addGlobal("__rela_iplt_end", self); |
| 2745 | |
| 2746 | // for (self.objects.items) |index| { |
| 2747 | // const object = self.getFile(index).?.object; |
| 2748 | // for (object.atoms.items) |atom_index| { |
| 2749 | // if (self.getStartStopBasename(atom_index)) |name| { |
| 2750 | // const gpa = self.base.allocator; |
| 2751 | // try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2); |
| 2752 | |
| 2753 | // const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 2754 | // defer gpa.free(start); |
| 2755 | // const stop = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name}); |
| 2756 | // defer gpa.free(stop); |
| 2757 | |
| 2758 | // self.start_stop_indexes.appendAssumeCapacity(try internal.addSyntheticGlobal(start, self)); |
| 2759 | // self.start_stop_indexes.appendAssumeCapacity(try internal.addSyntheticGlobal(stop, self)); |
| 2760 | // } |
| 2761 | // } |
| 2762 | // } |
| 2763 | |
| 2764 | linker_defined.resolveSymbols(self); |
| 2765 | } |
| 2766 | |
| 2685 | 2767 | fn updateSymtabSize(self: *Elf) !void { |
| 2686 | 2768 | var sizes = SymtabSize{}; |
| 2687 | 2769 | |
| ... | ... | @@ -3193,7 +3275,7 @@ pub fn getOrPutGlobal(self: *Elf, name_off: u32) !GetOrPutGlobalResult { |
| 3193 | 3275 | }; |
| 3194 | 3276 | } |
| 3195 | 3277 | |
| 3196 | | pub fn getGlobalByName(self: *Elf, name: []const u8) ?Symbol.Index { |
| 3278 | pub fn globalByName(self: *Elf, name: []const u8) ?Symbol.Index { |
| 3197 | 3279 | const name_off = self.strtab.getOffset(name) orelse return null; |
| 3198 | 3280 | return self.resolver.get(name_off); |
| 3199 | 3281 | } |