| ... | @@ -147,6 +147,7 @@ thunks: std.ArrayListUnmanaged(Thunk) = .empty, | ... | @@ -147,6 +147,7 @@ thunks: std.ArrayListUnmanaged(Thunk) = .empty, |
| 147 | | 147 | |
| 148 | /// List of output merge sections with deduped contents. | 148 | /// List of output merge sections with deduped contents. |
| 149 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty, | 149 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty, |
| | 150 | comment_merge_section_index: ?MergeSection.Index = null, |
| 150 | | 151 | |
| 151 | first_eflags: ?elf.Elf64_Word = null, | 152 | first_eflags: ?elf.Elf64_Word = null, |
| 152 | | 153 | |
| ... | @@ -2790,6 +2791,7 @@ fn checkDuplicates(self: *Elf) !void { | ... | @@ -2790,6 +2791,7 @@ fn checkDuplicates(self: *Elf) !void { |
| 2790 | | 2791 | |
| 2791 | pub fn addCommentString(self: *Elf) !void { | 2792 | pub 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 | } |
| 2807 | | 2810 | |
| 2808 | pub fn resolveMergeSections(self: *Elf) !void { | 2811 | pub 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 | } |
| 2933 | | 2936 | |
| 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 | } |
| 2943 | | 2946 | |
| 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 | } |
| 2951 | | 2956 | |
| 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 | } |
| 2973 | | 2978 | |
| 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 | } |
| 2991 | | 3000 | |
| 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 | } |
| 3001 | | 3010 | |
| 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 | } |
| 3029 | | 3038 | |
| 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 | } |
| 3094 | | 3117 | |
| 3095 | try self.initSymtab(); | 3118 | try self.initSymtab(); |