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,...@@ -147,6 +147,7 @@ thunks: std.ArrayListUnmanaged(Thunk) = .empty,
147147
148/// List of output merge sections with deduped contents.148/// List of output merge sections with deduped contents.
149merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty,149merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty,
150comment_merge_section_index: ?MergeSection.Index = null,
150151
151first_eflags: ?elf.Elf64_Word = null,152first_eflags: ?elf.Elf64_Word = null,
152153
...@@ -2790,6 +2791,7 @@ fn checkDuplicates(self: *Elf) !void {...@@ -2790,6 +2791,7 @@ fn checkDuplicates(self: *Elf) !void {
27902791
2791pub fn addCommentString(self: *Elf) !void {2792pub fn addCommentString(self: *Elf) !void {
2792 const gpa = self.base.comp.gpa;2793 const gpa = self.base.comp.gpa;
2794 if (self.comment_merge_section_index != null) return;
2793 const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS);2795 const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS);
2794 const msec = self.mergeSection(msec_index);2796 const msec = self.mergeSection(msec_index);
2795 const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string);2797 const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string);
...@@ -2803,6 +2805,7 @@ pub fn addCommentString(self: *Elf) !void {...@@ -2803,6 +2805,7 @@ pub fn addCommentString(self: *Elf) !void {
2803 msub.entsize = 1;2805 msub.entsize = 1;
2804 msub.alive = true;2806 msub.alive = true;
2805 res.sub.* = msub_index;2807 res.sub.* = msub_index;
2808 self.comment_merge_section_index = msec_index;
2806}2809}
28072810
2808pub fn resolveMergeSections(self: *Elf) !void {2811pub fn resolveMergeSections(self: *Elf) !void {
...@@ -2920,7 +2923,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -2920,7 +2923,7 @@ fn initSyntheticSections(self: *Elf) !void {
2920 .offset = std.math.maxInt(u64),2923 .offset = std.math.maxInt(u64),
2921 });2924 });
2922 }2925 }
2923 if (comp.link_eh_frame_hdr) {2926 if (comp.link_eh_frame_hdr and self.eh_frame_hdr_section_index == null) {
2924 self.eh_frame_hdr_section_index = try self.addSection(.{2927 self.eh_frame_hdr_section_index = try self.addSection(.{
2925 .name = try self.insertShString(".eh_frame_hdr"),2928 .name = try self.insertShString(".eh_frame_hdr"),
2926 .type = elf.SHT_PROGBITS,2929 .type = elf.SHT_PROGBITS,
...@@ -2931,7 +2934,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -2931,7 +2934,7 @@ fn initSyntheticSections(self: *Elf) !void {
2931 }2934 }
2932 }2935 }
29332936
2934 if (self.got.entries.items.len > 0) {2937 if (self.got.entries.items.len > 0 and self.got_section_index == null) {
2935 self.got_section_index = try self.addSection(.{2938 self.got_section_index = try self.addSection(.{
2936 .name = try self.insertShString(".got"),2939 .name = try self.insertShString(".got"),
2937 .type = elf.SHT_PROGBITS,2940 .type = elf.SHT_PROGBITS,
...@@ -2941,13 +2944,15 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -2941,13 +2944,15 @@ fn initSyntheticSections(self: *Elf) !void {
2941 });2944 });
2942 }2945 }
29432946
2944 self.got_plt_section_index = try self.addSection(.{2947 if (self.got_plt_section_index == null) {
2945 .name = try self.insertShString(".got.plt"),2948 self.got_plt_section_index = try self.addSection(.{
2946 .type = elf.SHT_PROGBITS,2949 .name = try self.insertShString(".got.plt"),
2947 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,2950 .type = elf.SHT_PROGBITS,
2948 .addralign = @alignOf(u64),2951 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
2949 .offset = std.math.maxInt(u64),2952 .addralign = @alignOf(u64),
2950 });2953 .offset = std.math.maxInt(u64),
2954 });
2955 }
29512956
2952 const needs_rela_dyn = blk: {2957 const needs_rela_dyn = blk: {
2953 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0)2958 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 {...@@ -2960,7 +2965,7 @@ fn initSyntheticSections(self: *Elf) !void {
2960 }2965 }
2961 break :blk false;2966 break :blk false;
2962 };2967 };
2963 if (needs_rela_dyn) {2968 if (needs_rela_dyn and self.rela_dyn_section_index == null) {
2964 self.rela_dyn_section_index = try self.addSection(.{2969 self.rela_dyn_section_index = try self.addSection(.{
2965 .name = try self.insertShString(".rela.dyn"),2970 .name = try self.insertShString(".rela.dyn"),
2966 .type = elf.SHT_RELA,2971 .type = elf.SHT_RELA,
...@@ -2972,24 +2977,28 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -2972,24 +2977,28 @@ fn initSyntheticSections(self: *Elf) !void {
2972 }2977 }
29732978
2974 if (self.plt.symbols.items.len > 0) {2979 if (self.plt.symbols.items.len > 0) {
2975 self.plt_section_index = try self.addSection(.{2980 if (self.plt_section_index == null) {
2976 .name = try self.insertShString(".plt"),2981 self.plt_section_index = try self.addSection(.{
2977 .type = elf.SHT_PROGBITS,2982 .name = try self.insertShString(".plt"),
2978 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,2983 .type = elf.SHT_PROGBITS,
2979 .addralign = 16,2984 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
2980 .offset = std.math.maxInt(u64),2985 .addralign = 16,
2981 });2986 .offset = std.math.maxInt(u64),
2982 self.rela_plt_section_index = try self.addSection(.{2987 });
2983 .name = try self.insertShString(".rela.plt"),2988 }
2984 .type = elf.SHT_RELA,2989 if (self.rela_plt_section_index == null) {
2985 .flags = elf.SHF_ALLOC,2990 self.rela_plt_section_index = try self.addSection(.{
2986 .addralign = @alignOf(elf.Elf64_Rela),2991 .name = try self.insertShString(".rela.plt"),
2987 .entsize = @sizeOf(elf.Elf64_Rela),2992 .type = elf.SHT_RELA,
2988 .offset = std.math.maxInt(u64),2993 .flags = elf.SHF_ALLOC,
2989 });2994 .addralign = @alignOf(elf.Elf64_Rela),
2995 .entsize = @sizeOf(elf.Elf64_Rela),
2996 .offset = std.math.maxInt(u64),
2997 });
2998 }
2990 }2999 }
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) {
2993 self.plt_got_section_index = try self.addSection(.{3002 self.plt_got_section_index = try self.addSection(.{
2994 .name = try self.insertShString(".plt.got"),3003 .name = try self.insertShString(".plt.got"),
2995 .type = elf.SHT_PROGBITS,3004 .type = elf.SHT_PROGBITS,
...@@ -2999,7 +3008,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -2999,7 +3008,7 @@ fn initSyntheticSections(self: *Elf) !void {
2999 });3008 });
3000 }3009 }
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) {
3003 self.copy_rel_section_index = try self.addSection(.{3012 self.copy_rel_section_index = try self.addSection(.{
3004 .name = try self.insertShString(".copyrel"),3013 .name = try self.insertShString(".copyrel"),
3005 .type = elf.SHT_NOBITS,3014 .type = elf.SHT_NOBITS,
...@@ -3017,7 +3026,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -3017,7 +3026,7 @@ fn initSyntheticSections(self: *Elf) !void {
3017 if (self.base.isStatic() and !comp.config.pie) break :blk false;3026 if (self.base.isStatic() and !comp.config.pie) break :blk false;
3018 break :blk target.dynamic_linker.get() != null;3027 break :blk target.dynamic_linker.get() != null;
3019 };3028 };
3020 if (needs_interp) {3029 if (needs_interp and self.interp_section_index == null) {
3021 self.interp_section_index = try self.addSection(.{3030 self.interp_section_index = try self.addSection(.{
3022 .name = try self.insertShString(".interp"),3031 .name = try self.insertShString(".interp"),
3023 .type = elf.SHT_PROGBITS,3032 .type = elf.SHT_PROGBITS,
...@@ -3028,68 +3037,82 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -3028,68 +3037,82 @@ fn initSyntheticSections(self: *Elf) !void {
3028 }3037 }
30293038
3030 if (self.isEffectivelyDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {3039 if (self.isEffectivelyDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {
3031 self.dynstrtab_section_index = try self.addSection(.{3040 if (self.dynstrtab_section_index == null) {
3032 .name = try self.insertShString(".dynstr"),3041 self.dynstrtab_section_index = try self.addSection(.{
3033 .flags = elf.SHF_ALLOC,3042 .name = try self.insertShString(".dynstr"),
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"),
3079 .flags = elf.SHF_ALLOC,3043 .flags = elf.SHF_ALLOC,
3080 .type = elf.SHT_GNU_VERSYM,3044 .type = elf.SHT_STRTAB,
3081 .addralign = @alignOf(elf.Elf64_Versym),3045 .entsize = 1,
3082 .entsize = @sizeOf(elf.Elf64_Versym),3046 .addralign = 1,
3083 .offset = std.math.maxInt(u64),3047 .offset = std.math.maxInt(u64),
3084 });3048 });
3085 self.verneed_section_index = try self.addSection(.{3049 }
3086 .name = try self.insertShString(".gnu.version_r"),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"),
3087 .flags = elf.SHF_ALLOC,3063 .flags = elf.SHF_ALLOC,
3088 .type = elf.SHT_GNU_VERNEED,3064 .type = elf.SHT_DYNSYM,
3089 .addralign = @alignOf(elf.Elf64_Verneed),3065 .addralign = @alignOf(elf.Elf64_Sym),
3066 .entsize = @sizeOf(elf.Elf64_Sym),
3067 .info = 1,
3090 .offset = std.math.maxInt(u64),3068 .offset = std.math.maxInt(u64),
3091 });3069 });
3092 }3070 }
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 }
3093 }3116 }
30943117
3095 try self.initSymtab();3118 try self.initSymtab();
src/link/Elf/LinkerDefined.zig+1
...@@ -145,6 +145,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -145,6 +145,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
145 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);145 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);
146146
147 for (slice.items(.shdr)) |shdr| {147 for (slice.items(.shdr)) |shdr| {
148 // TODO use getOrPut for incremental so that we don't create duplicates
148 if (elf_file.getStartStopBasename(shdr)) |name| {149 if (elf_file.getStartStopBasename(shdr)) |name| {
149 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});150 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
150 defer gpa.free(start_name);151 defer gpa.free(start_name);