authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-24 10:46:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-25 17:54:50+02:00
log62c282ba4699bd00d0cb74b3253bac7a925eae68
treed7f76b3cee61f29ef503c8fa8b81014933a66d8d
parent4ceefca14be313e91a248fdc532e37edf4a02a51

elf: do not re-create synthetic sections if already created


2 files changed, 107 insertions(+), 83 deletions(-)

src/link/Elf.zig+106-83
......@@ -147,6 +147,7 @@ thunks: std.ArrayListUnmanaged(Thunk) = .empty,
147147
148148/// List of output merge sections with deduped contents.
149149merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty,
150comment_merge_section_index: ?MergeSection.Index = null,
150151
151152first_eflags: ?elf.Elf64_Word = null,
152153
......@@ -2790,6 +2791,7 @@ fn checkDuplicates(self: *Elf) !void {
27902791
27912792pub fn addCommentString(self: *Elf) !void {
27922793 const gpa = self.base.comp.gpa;
2794 if (self.comment_merge_section_index != null) return;
27932795 const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS);
27942796 const msec = self.mergeSection(msec_index);
27952797 const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string);
......@@ -2803,6 +2805,7 @@ pub fn addCommentString(self: *Elf) !void {
28032805 msub.entsize = 1;
28042806 msub.alive = true;
28052807 res.sub.* = msub_index;
2808 self.comment_merge_section_index = msec_index;
28062809}
28072810
28082811pub fn resolveMergeSections(self: *Elf) !void {
......@@ -2920,7 +2923,7 @@ fn initSyntheticSections(self: *Elf) !void {
29202923 .offset = std.math.maxInt(u64),
29212924 });
29222925 }
2923 if (comp.link_eh_frame_hdr) {
2926 if (comp.link_eh_frame_hdr and self.eh_frame_hdr_section_index == null) {
29242927 self.eh_frame_hdr_section_index = try self.addSection(.{
29252928 .name = try self.insertShString(".eh_frame_hdr"),
29262929 .type = elf.SHT_PROGBITS,
......@@ -2931,7 +2934,7 @@ fn initSyntheticSections(self: *Elf) !void {
29312934 }
29322935 }
29332936
2934 if (self.got.entries.items.len > 0) {
2937 if (self.got.entries.items.len > 0 and self.got_section_index == null) {
29352938 self.got_section_index = try self.addSection(.{
29362939 .name = try self.insertShString(".got"),
29372940 .type = elf.SHT_PROGBITS,
......@@ -2941,13 +2944,15 @@ fn initSyntheticSections(self: *Elf) !void {
29412944 });
29422945 }
29432946
2944 self.got_plt_section_index = try self.addSection(.{
2945 .name = try self.insertShString(".got.plt"),
2946 .type = elf.SHT_PROGBITS,
2947 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
2948 .addralign = @alignOf(u64),
2949 .offset = std.math.maxInt(u64),
2950 });
2947 if (self.got_plt_section_index == null) {
2948 self.got_plt_section_index = try self.addSection(.{
2949 .name = try self.insertShString(".got.plt"),
2950 .type = elf.SHT_PROGBITS,
2951 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
2952 .addralign = @alignOf(u64),
2953 .offset = std.math.maxInt(u64),
2954 });
2955 }
29512956
29522957 const needs_rela_dyn = blk: {
29532958 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0)
......@@ -2960,7 +2965,7 @@ fn initSyntheticSections(self: *Elf) !void {
29602965 }
29612966 break :blk false;
29622967 };
2963 if (needs_rela_dyn) {
2968 if (needs_rela_dyn and self.rela_dyn_section_index == null) {
29642969 self.rela_dyn_section_index = try self.addSection(.{
29652970 .name = try self.insertShString(".rela.dyn"),
29662971 .type = elf.SHT_RELA,
......@@ -2972,24 +2977,28 @@ fn initSyntheticSections(self: *Elf) !void {
29722977 }
29732978
29742979 if (self.plt.symbols.items.len > 0) {
2975 self.plt_section_index = try self.addSection(.{
2976 .name = try self.insertShString(".plt"),
2977 .type = elf.SHT_PROGBITS,
2978 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
2979 .addralign = 16,
2980 .offset = std.math.maxInt(u64),
2981 });
2982 self.rela_plt_section_index = try self.addSection(.{
2983 .name = try self.insertShString(".rela.plt"),
2984 .type = elf.SHT_RELA,
2985 .flags = elf.SHF_ALLOC,
2986 .addralign = @alignOf(elf.Elf64_Rela),
2987 .entsize = @sizeOf(elf.Elf64_Rela),
2988 .offset = std.math.maxInt(u64),
2989 });
2980 if (self.plt_section_index == null) {
2981 self.plt_section_index = try self.addSection(.{
2982 .name = try self.insertShString(".plt"),
2983 .type = elf.SHT_PROGBITS,
2984 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
2985 .addralign = 16,
2986 .offset = std.math.maxInt(u64),
2987 });
2988 }
2989 if (self.rela_plt_section_index == null) {
2990 self.rela_plt_section_index = try self.addSection(.{
2991 .name = try self.insertShString(".rela.plt"),
2992 .type = elf.SHT_RELA,
2993 .flags = elf.SHF_ALLOC,
2994 .addralign = @alignOf(elf.Elf64_Rela),
2995 .entsize = @sizeOf(elf.Elf64_Rela),
2996 .offset = std.math.maxInt(u64),
2997 });
2998 }
29902999 }
29913000
2992 if (self.plt_got.symbols.items.len > 0) {
3001 if (self.plt_got.symbols.items.len > 0 and self.plt_got_section_index == null) {
29933002 self.plt_got_section_index = try self.addSection(.{
29943003 .name = try self.insertShString(".plt.got"),
29953004 .type = elf.SHT_PROGBITS,
......@@ -2999,7 +3008,7 @@ fn initSyntheticSections(self: *Elf) !void {
29993008 });
30003009 }
30013010
3002 if (self.copy_rel.symbols.items.len > 0) {
3011 if (self.copy_rel.symbols.items.len > 0 and self.copy_rel_section_index == null) {
30033012 self.copy_rel_section_index = try self.addSection(.{
30043013 .name = try self.insertShString(".copyrel"),
30053014 .type = elf.SHT_NOBITS,
......@@ -3017,7 +3026,7 @@ fn initSyntheticSections(self: *Elf) !void {
30173026 if (self.base.isStatic() and !comp.config.pie) break :blk false;
30183027 break :blk target.dynamic_linker.get() != null;
30193028 };
3020 if (needs_interp) {
3029 if (needs_interp and self.interp_section_index == null) {
30213030 self.interp_section_index = try self.addSection(.{
30223031 .name = try self.insertShString(".interp"),
30233032 .type = elf.SHT_PROGBITS,
......@@ -3028,68 +3037,82 @@ fn initSyntheticSections(self: *Elf) !void {
30283037 }
30293038
30303039 if (self.isEffectivelyDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {
3031 self.dynstrtab_section_index = try self.addSection(.{
3032 .name = try self.insertShString(".dynstr"),
3033 .flags = elf.SHF_ALLOC,
3034 .type = elf.SHT_STRTAB,
3035 .entsize = 1,
3036 .addralign = 1,
3037 .offset = std.math.maxInt(u64),
3038 });
3039 self.dynamic_section_index = try self.addSection(.{
3040 .name = try self.insertShString(".dynamic"),
3041 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
3042 .type = elf.SHT_DYNAMIC,
3043 .entsize = @sizeOf(elf.Elf64_Dyn),
3044 .addralign = @alignOf(elf.Elf64_Dyn),
3045 .offset = std.math.maxInt(u64),
3046 });
3047 self.dynsymtab_section_index = try self.addSection(.{
3048 .name = try self.insertShString(".dynsym"),
3049 .flags = elf.SHF_ALLOC,
3050 .type = elf.SHT_DYNSYM,
3051 .addralign = @alignOf(elf.Elf64_Sym),
3052 .entsize = @sizeOf(elf.Elf64_Sym),
3053 .info = 1,
3054 .offset = std.math.maxInt(u64),
3055 });
3056 self.hash_section_index = try self.addSection(.{
3057 .name = try self.insertShString(".hash"),
3058 .flags = elf.SHF_ALLOC,
3059 .type = elf.SHT_HASH,
3060 .addralign = 4,
3061 .entsize = 4,
3062 .offset = std.math.maxInt(u64),
3063 });
3064 self.gnu_hash_section_index = try self.addSection(.{
3065 .name = try self.insertShString(".gnu.hash"),
3066 .flags = elf.SHF_ALLOC,
3067 .type = elf.SHT_GNU_HASH,
3068 .addralign = 8,
3069 .offset = std.math.maxInt(u64),
3070 });
3071
3072 const needs_versions = for (self.dynsym.entries.items) |entry| {
3073 const sym = self.symbol(entry.ref).?;
3074 if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true;
3075 } else false;
3076 if (needs_versions) {
3077 self.versym_section_index = try self.addSection(.{
3078 .name = try self.insertShString(".gnu.version"),
3040 if (self.dynstrtab_section_index == null) {
3041 self.dynstrtab_section_index = try self.addSection(.{
3042 .name = try self.insertShString(".dynstr"),
30793043 .flags = elf.SHF_ALLOC,
3080 .type = elf.SHT_GNU_VERSYM,
3081 .addralign = @alignOf(elf.Elf64_Versym),
3082 .entsize = @sizeOf(elf.Elf64_Versym),
3044 .type = elf.SHT_STRTAB,
3045 .entsize = 1,
3046 .addralign = 1,
30833047 .offset = std.math.maxInt(u64),
30843048 });
3085 self.verneed_section_index = try self.addSection(.{
3086 .name = try self.insertShString(".gnu.version_r"),
3049 }
3050 if (self.dynamic_section_index == null) {
3051 self.dynamic_section_index = try self.addSection(.{
3052 .name = try self.insertShString(".dynamic"),
3053 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
3054 .type = elf.SHT_DYNAMIC,
3055 .entsize = @sizeOf(elf.Elf64_Dyn),
3056 .addralign = @alignOf(elf.Elf64_Dyn),
3057 .offset = std.math.maxInt(u64),
3058 });
3059 }
3060 if (self.dynsymtab_section_index == null) {
3061 self.dynsymtab_section_index = try self.addSection(.{
3062 .name = try self.insertShString(".dynsym"),
30873063 .flags = elf.SHF_ALLOC,
3088 .type = elf.SHT_GNU_VERNEED,
3089 .addralign = @alignOf(elf.Elf64_Verneed),
3064 .type = elf.SHT_DYNSYM,
3065 .addralign = @alignOf(elf.Elf64_Sym),
3066 .entsize = @sizeOf(elf.Elf64_Sym),
3067 .info = 1,
30903068 .offset = std.math.maxInt(u64),
30913069 });
30923070 }
3071 if (self.hash_section_index == null) {
3072 self.hash_section_index = try self.addSection(.{
3073 .name = try self.insertShString(".hash"),
3074 .flags = elf.SHF_ALLOC,
3075 .type = elf.SHT_HASH,
3076 .addralign = 4,
3077 .entsize = 4,
3078 .offset = std.math.maxInt(u64),
3079 });
3080 }
3081 if (self.gnu_hash_section_index == null) {
3082 self.gnu_hash_section_index = try self.addSection(.{
3083 .name = try self.insertShString(".gnu.hash"),
3084 .flags = elf.SHF_ALLOC,
3085 .type = elf.SHT_GNU_HASH,
3086 .addralign = 8,
3087 .offset = std.math.maxInt(u64),
3088 });
3089 }
3090
3091 const needs_versions = for (self.dynsym.entries.items) |entry| {
3092 const sym = self.symbol(entry.ref).?;
3093 if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true;
3094 } else false;
3095 if (needs_versions) {
3096 if (self.versym_section_index == null) {
3097 self.versym_section_index = try self.addSection(.{
3098 .name = try self.insertShString(".gnu.version"),
3099 .flags = elf.SHF_ALLOC,
3100 .type = elf.SHT_GNU_VERSYM,
3101 .addralign = @alignOf(elf.Elf64_Versym),
3102 .entsize = @sizeOf(elf.Elf64_Versym),
3103 .offset = std.math.maxInt(u64),
3104 });
3105 }
3106 if (self.verneed_section_index == null) {
3107 self.verneed_section_index = try self.addSection(.{
3108 .name = try self.insertShString(".gnu.version_r"),
3109 .flags = elf.SHF_ALLOC,
3110 .type = elf.SHT_GNU_VERNEED,
3111 .addralign = @alignOf(elf.Elf64_Verneed),
3112 .offset = std.math.maxInt(u64),
3113 });
3114 }
3115 }
30933116 }
30943117
30953118 try self.initSymtab();
src/link/Elf/LinkerDefined.zig+1
......@@ -145,6 +145,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
145145 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);
146146
147147 for (slice.items(.shdr)) |shdr| {
148 // TODO use getOrPut for incremental so that we don't create duplicates
148149 if (elf_file.getStartStopBasename(shdr)) |name| {
149150 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
150151 defer gpa.free(start_name);