| ... | ... | @@ -147,6 +147,7 @@ thunks: std.ArrayListUnmanaged(Thunk) = .empty, |
| 147 | 147 | |
| 148 | 148 | /// List of output merge sections with deduped contents. |
| 149 | 149 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .empty, |
| 150 | comment_merge_section_index: ?MergeSection.Index = null, |
| 150 | 151 | |
| 151 | 152 | first_eflags: ?elf.Elf64_Word = null, |
| 152 | 153 | |
| ... | ... | @@ -568,19 +569,6 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align |
| 568 | 569 | if (maybe_phdr) |phdr| phdr.p_filesz = needed_size; |
| 569 | 570 | } |
| 570 | 571 | shdr.sh_size = needed_size; |
| 571 | | |
| 572 | | if (maybe_phdr) |phdr| { |
| 573 | | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); |
| 574 | | if (needed_size > mem_capacity) { |
| 575 | | var err = try self.base.addErrorWithNotes(2); |
| 576 | | try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{phndx.?}); |
| 577 | | try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{}); |
| 578 | | try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{}); |
| 579 | | } |
| 580 | | |
| 581 | | phdr.p_memsz = needed_size; |
| 582 | | } |
| 583 | | |
| 584 | 572 | self.markDirty(shdr_index); |
| 585 | 573 | } |
| 586 | 574 | |
| ... | ... | @@ -1047,6 +1035,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1047 | 1035 | try self.updateMergeSectionSizes(); |
| 1048 | 1036 | try self.updateSectionSizes(); |
| 1049 | 1037 | |
| 1038 | try self.addLoadPhdrs(); |
| 1050 | 1039 | try self.allocatePhdrTable(); |
| 1051 | 1040 | try self.allocateAllocSections(); |
| 1052 | 1041 | try self.sortPhdrs(); |
| ... | ... | @@ -2790,6 +2779,7 @@ fn checkDuplicates(self: *Elf) !void { |
| 2790 | 2779 | |
| 2791 | 2780 | pub fn addCommentString(self: *Elf) !void { |
| 2792 | 2781 | const gpa = self.base.comp.gpa; |
| 2782 | if (self.comment_merge_section_index != null) return; |
| 2793 | 2783 | const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS); |
| 2794 | 2784 | const msec = self.mergeSection(msec_index); |
| 2795 | 2785 | const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string); |
| ... | ... | @@ -2803,6 +2793,7 @@ pub fn addCommentString(self: *Elf) !void { |
| 2803 | 2793 | msub.entsize = 1; |
| 2804 | 2794 | msub.alive = true; |
| 2805 | 2795 | res.sub.* = msub_index; |
| 2796 | self.comment_merge_section_index = msec_index; |
| 2806 | 2797 | } |
| 2807 | 2798 | |
| 2808 | 2799 | pub fn resolveMergeSections(self: *Elf) !void { |
| ... | ... | @@ -2920,7 +2911,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2920 | 2911 | .offset = std.math.maxInt(u64), |
| 2921 | 2912 | }); |
| 2922 | 2913 | } |
| 2923 | | if (comp.link_eh_frame_hdr) { |
| 2914 | if (comp.link_eh_frame_hdr and self.eh_frame_hdr_section_index == null) { |
| 2924 | 2915 | self.eh_frame_hdr_section_index = try self.addSection(.{ |
| 2925 | 2916 | .name = try self.insertShString(".eh_frame_hdr"), |
| 2926 | 2917 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -2931,7 +2922,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2931 | 2922 | } |
| 2932 | 2923 | } |
| 2933 | 2924 | |
| 2934 | | if (self.got.entries.items.len > 0) { |
| 2925 | if (self.got.entries.items.len > 0 and self.got_section_index == null) { |
| 2935 | 2926 | self.got_section_index = try self.addSection(.{ |
| 2936 | 2927 | .name = try self.insertShString(".got"), |
| 2937 | 2928 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -2941,13 +2932,15 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2941 | 2932 | }); |
| 2942 | 2933 | } |
| 2943 | 2934 | |
| 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 | | }); |
| 2935 | if (self.got_plt_section_index == null) { |
| 2936 | self.got_plt_section_index = try self.addSection(.{ |
| 2937 | .name = try self.insertShString(".got.plt"), |
| 2938 | .type = elf.SHT_PROGBITS, |
| 2939 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 2940 | .addralign = @alignOf(u64), |
| 2941 | .offset = std.math.maxInt(u64), |
| 2942 | }); |
| 2943 | } |
| 2951 | 2944 | |
| 2952 | 2945 | const needs_rela_dyn = blk: { |
| 2953 | 2946 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0) |
| ... | ... | @@ -2960,7 +2953,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2960 | 2953 | } |
| 2961 | 2954 | break :blk false; |
| 2962 | 2955 | }; |
| 2963 | | if (needs_rela_dyn) { |
| 2956 | if (needs_rela_dyn and self.rela_dyn_section_index == null) { |
| 2964 | 2957 | self.rela_dyn_section_index = try self.addSection(.{ |
| 2965 | 2958 | .name = try self.insertShString(".rela.dyn"), |
| 2966 | 2959 | .type = elf.SHT_RELA, |
| ... | ... | @@ -2972,24 +2965,28 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2972 | 2965 | } |
| 2973 | 2966 | |
| 2974 | 2967 | 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 | | }); |
| 2968 | if (self.plt_section_index == null) { |
| 2969 | self.plt_section_index = try self.addSection(.{ |
| 2970 | .name = try self.insertShString(".plt"), |
| 2971 | .type = elf.SHT_PROGBITS, |
| 2972 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, |
| 2973 | .addralign = 16, |
| 2974 | .offset = std.math.maxInt(u64), |
| 2975 | }); |
| 2976 | } |
| 2977 | if (self.rela_plt_section_index == null) { |
| 2978 | self.rela_plt_section_index = try self.addSection(.{ |
| 2979 | .name = try self.insertShString(".rela.plt"), |
| 2980 | .type = elf.SHT_RELA, |
| 2981 | .flags = elf.SHF_ALLOC, |
| 2982 | .addralign = @alignOf(elf.Elf64_Rela), |
| 2983 | .entsize = @sizeOf(elf.Elf64_Rela), |
| 2984 | .offset = std.math.maxInt(u64), |
| 2985 | }); |
| 2986 | } |
| 2990 | 2987 | } |
| 2991 | 2988 | |
| 2992 | | if (self.plt_got.symbols.items.len > 0) { |
| 2989 | if (self.plt_got.symbols.items.len > 0 and self.plt_got_section_index == null) { |
| 2993 | 2990 | self.plt_got_section_index = try self.addSection(.{ |
| 2994 | 2991 | .name = try self.insertShString(".plt.got"), |
| 2995 | 2992 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -2999,7 +2996,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2999 | 2996 | }); |
| 3000 | 2997 | } |
| 3001 | 2998 | |
| 3002 | | if (self.copy_rel.symbols.items.len > 0) { |
| 2999 | if (self.copy_rel.symbols.items.len > 0 and self.copy_rel_section_index == null) { |
| 3003 | 3000 | self.copy_rel_section_index = try self.addSection(.{ |
| 3004 | 3001 | .name = try self.insertShString(".copyrel"), |
| 3005 | 3002 | .type = elf.SHT_NOBITS, |
| ... | ... | @@ -3017,7 +3014,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3017 | 3014 | if (self.base.isStatic() and !comp.config.pie) break :blk false; |
| 3018 | 3015 | break :blk target.dynamic_linker.get() != null; |
| 3019 | 3016 | }; |
| 3020 | | if (needs_interp) { |
| 3017 | if (needs_interp and self.interp_section_index == null) { |
| 3021 | 3018 | self.interp_section_index = try self.addSection(.{ |
| 3022 | 3019 | .name = try self.insertShString(".interp"), |
| 3023 | 3020 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -3028,68 +3025,82 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3028 | 3025 | } |
| 3029 | 3026 | |
| 3030 | 3027 | 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"), |
| 3028 | if (self.dynstrtab_section_index == null) { |
| 3029 | self.dynstrtab_section_index = try self.addSection(.{ |
| 3030 | .name = try self.insertShString(".dynstr"), |
| 3079 | 3031 | .flags = elf.SHF_ALLOC, |
| 3080 | | .type = elf.SHT_GNU_VERSYM, |
| 3081 | | .addralign = @alignOf(elf.Elf64_Versym), |
| 3082 | | .entsize = @sizeOf(elf.Elf64_Versym), |
| 3032 | .type = elf.SHT_STRTAB, |
| 3033 | .entsize = 1, |
| 3034 | .addralign = 1, |
| 3083 | 3035 | .offset = std.math.maxInt(u64), |
| 3084 | 3036 | }); |
| 3085 | | self.verneed_section_index = try self.addSection(.{ |
| 3086 | | .name = try self.insertShString(".gnu.version_r"), |
| 3037 | } |
| 3038 | if (self.dynamic_section_index == null) { |
| 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 | } |
| 3048 | if (self.dynsymtab_section_index == null) { |
| 3049 | self.dynsymtab_section_index = try self.addSection(.{ |
| 3050 | .name = try self.insertShString(".dynsym"), |
| 3087 | 3051 | .flags = elf.SHF_ALLOC, |
| 3088 | | .type = elf.SHT_GNU_VERNEED, |
| 3089 | | .addralign = @alignOf(elf.Elf64_Verneed), |
| 3052 | .type = elf.SHT_DYNSYM, |
| 3053 | .addralign = @alignOf(elf.Elf64_Sym), |
| 3054 | .entsize = @sizeOf(elf.Elf64_Sym), |
| 3055 | .info = 1, |
| 3090 | 3056 | .offset = std.math.maxInt(u64), |
| 3091 | 3057 | }); |
| 3092 | 3058 | } |
| 3059 | if (self.hash_section_index == null) { |
| 3060 | self.hash_section_index = try self.addSection(.{ |
| 3061 | .name = try self.insertShString(".hash"), |
| 3062 | .flags = elf.SHF_ALLOC, |
| 3063 | .type = elf.SHT_HASH, |
| 3064 | .addralign = 4, |
| 3065 | .entsize = 4, |
| 3066 | .offset = std.math.maxInt(u64), |
| 3067 | }); |
| 3068 | } |
| 3069 | if (self.gnu_hash_section_index == null) { |
| 3070 | self.gnu_hash_section_index = try self.addSection(.{ |
| 3071 | .name = try self.insertShString(".gnu.hash"), |
| 3072 | .flags = elf.SHF_ALLOC, |
| 3073 | .type = elf.SHT_GNU_HASH, |
| 3074 | .addralign = 8, |
| 3075 | .offset = std.math.maxInt(u64), |
| 3076 | }); |
| 3077 | } |
| 3078 | |
| 3079 | const needs_versions = for (self.dynsym.entries.items) |entry| { |
| 3080 | const sym = self.symbol(entry.ref).?; |
| 3081 | if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true; |
| 3082 | } else false; |
| 3083 | if (needs_versions) { |
| 3084 | if (self.versym_section_index == null) { |
| 3085 | self.versym_section_index = try self.addSection(.{ |
| 3086 | .name = try self.insertShString(".gnu.version"), |
| 3087 | .flags = elf.SHF_ALLOC, |
| 3088 | .type = elf.SHT_GNU_VERSYM, |
| 3089 | .addralign = @alignOf(elf.Elf64_Versym), |
| 3090 | .entsize = @sizeOf(elf.Elf64_Versym), |
| 3091 | .offset = std.math.maxInt(u64), |
| 3092 | }); |
| 3093 | } |
| 3094 | if (self.verneed_section_index == null) { |
| 3095 | self.verneed_section_index = try self.addSection(.{ |
| 3096 | .name = try self.insertShString(".gnu.version_r"), |
| 3097 | .flags = elf.SHF_ALLOC, |
| 3098 | .type = elf.SHT_GNU_VERNEED, |
| 3099 | .addralign = @alignOf(elf.Elf64_Verneed), |
| 3100 | .offset = std.math.maxInt(u64), |
| 3101 | }); |
| 3102 | } |
| 3103 | } |
| 3093 | 3104 | } |
| 3094 | 3105 | |
| 3095 | 3106 | try self.initSymtab(); |
| ... | ... | @@ -3136,36 +3147,38 @@ pub fn initShStrtab(self: *Elf) !void { |
| 3136 | 3147 | fn initSpecialPhdrs(self: *Elf) !void { |
| 3137 | 3148 | comptime assert(max_number_of_special_phdrs == 5); |
| 3138 | 3149 | |
| 3139 | | if (self.interp_section_index != null) { |
| 3150 | if (self.interp_section_index != null and self.phdr_interp_index == null) { |
| 3140 | 3151 | self.phdr_interp_index = try self.addPhdr(.{ |
| 3141 | 3152 | .type = elf.PT_INTERP, |
| 3142 | 3153 | .flags = elf.PF_R, |
| 3143 | 3154 | .@"align" = 1, |
| 3144 | 3155 | }); |
| 3145 | 3156 | } |
| 3146 | | if (self.dynamic_section_index != null) { |
| 3157 | if (self.dynamic_section_index != null and self.phdr_dynamic_index == null) { |
| 3147 | 3158 | self.phdr_dynamic_index = try self.addPhdr(.{ |
| 3148 | 3159 | .type = elf.PT_DYNAMIC, |
| 3149 | 3160 | .flags = elf.PF_R | elf.PF_W, |
| 3150 | 3161 | }); |
| 3151 | 3162 | } |
| 3152 | | if (self.eh_frame_hdr_section_index != null) { |
| 3163 | if (self.eh_frame_hdr_section_index != null and self.phdr_gnu_eh_frame_index == null) { |
| 3153 | 3164 | self.phdr_gnu_eh_frame_index = try self.addPhdr(.{ |
| 3154 | 3165 | .type = elf.PT_GNU_EH_FRAME, |
| 3155 | 3166 | .flags = elf.PF_R, |
| 3156 | 3167 | }); |
| 3157 | 3168 | } |
| 3158 | | self.phdr_gnu_stack_index = try self.addPhdr(.{ |
| 3159 | | .type = elf.PT_GNU_STACK, |
| 3160 | | .flags = elf.PF_W | elf.PF_R, |
| 3161 | | .memsz = self.base.stack_size, |
| 3162 | | .@"align" = 1, |
| 3163 | | }); |
| 3169 | if (self.phdr_gnu_stack_index == null) { |
| 3170 | self.phdr_gnu_stack_index = try self.addPhdr(.{ |
| 3171 | .type = elf.PT_GNU_STACK, |
| 3172 | .flags = elf.PF_W | elf.PF_R, |
| 3173 | .memsz = self.base.stack_size, |
| 3174 | .@"align" = 1, |
| 3175 | }); |
| 3176 | } |
| 3164 | 3177 | |
| 3165 | 3178 | const has_tls = for (self.sections.items(.shdr)) |shdr| { |
| 3166 | 3179 | if (shdr.sh_flags & elf.SHF_TLS != 0) break true; |
| 3167 | 3180 | } else false; |
| 3168 | | if (has_tls) { |
| 3181 | if (has_tls and self.phdr_tls_index == null) { |
| 3169 | 3182 | self.phdr_tls_index = try self.addPhdr(.{ |
| 3170 | 3183 | .type = elf.PT_TLS, |
| 3171 | 3184 | .flags = elf.PF_R, |
| ... | ... | @@ -3704,27 +3717,19 @@ fn getMaxNumberOfPhdrs() u64 { |
| 3704 | 3717 | return num; |
| 3705 | 3718 | } |
| 3706 | 3719 | |
| 3707 | | /// Calculates how many segments (PT_LOAD progam headers) are required |
| 3708 | | /// to cover the set of sections. |
| 3709 | | /// We permit a maximum of 3**2 number of segments. |
| 3710 | | fn calcNumberOfSegments(self: *Elf) usize { |
| 3711 | | var covers: [9]bool = [_]bool{false} ** 9; |
| 3720 | fn addLoadPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 3712 | 3721 | for (self.sections.items(.shdr)) |shdr| { |
| 3713 | 3722 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3714 | 3723 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3715 | 3724 | const flags = shdrToPhdrFlags(shdr.sh_flags); |
| 3716 | | covers[flags - 1] = true; |
| 3717 | | } |
| 3718 | | var count: usize = 0; |
| 3719 | | for (covers) |cover| { |
| 3720 | | if (cover) count += 1; |
| 3725 | if (self.getPhdr(.{ .flags = flags, .type = elf.PT_LOAD }) == null) { |
| 3726 | _ = try self.addPhdr(.{ .flags = flags, .type = elf.PT_LOAD }); |
| 3727 | } |
| 3721 | 3728 | } |
| 3722 | | return count; |
| 3723 | 3729 | } |
| 3724 | 3730 | |
| 3725 | 3731 | /// Allocates PHDR table in virtual memory and in file. |
| 3726 | 3732 | fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { |
| 3727 | | const new_load_segments = self.calcNumberOfSegments(); |
| 3728 | 3733 | const phdr_table = &self.phdrs.items[self.phdr_table_index.?]; |
| 3729 | 3734 | const phdr_table_load = &self.phdrs.items[self.phdr_table_load_index.?]; |
| 3730 | 3735 | |
| ... | ... | @@ -3736,7 +3741,7 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { |
| 3736 | 3741 | .p32 => @sizeOf(elf.Elf32_Phdr), |
| 3737 | 3742 | .p64 => @sizeOf(elf.Elf64_Phdr), |
| 3738 | 3743 | }; |
| 3739 | | const needed_size = (self.phdrs.items.len + new_load_segments) * phsize; |
| 3744 | const needed_size = self.phdrs.items.len * phsize; |
| 3740 | 3745 | const available_space = self.allocatedSize(phdr_table.p_offset); |
| 3741 | 3746 | |
| 3742 | 3747 | if (needed_size > available_space) { |
| ... | ... | @@ -3879,15 +3884,14 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3879 | 3884 | |
| 3880 | 3885 | const first = slice.items(.shdr)[cover.items[0]]; |
| 3881 | 3886 | var new_offset = try self.findFreeSpace(filesz, @"align"); |
| 3882 | | const phndx = try self.addPhdr(.{ |
| 3883 | | .type = elf.PT_LOAD, |
| 3884 | | .offset = new_offset, |
| 3885 | | .addr = first.sh_addr, |
| 3886 | | .memsz = memsz, |
| 3887 | | .filesz = filesz, |
| 3888 | | .@"align" = @"align", |
| 3889 | | .flags = shdrToPhdrFlags(first.sh_flags), |
| 3890 | | }); |
| 3887 | const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).?; |
| 3888 | const phdr = &self.phdrs.items[phndx]; |
| 3889 | phdr.p_offset = new_offset; |
| 3890 | phdr.p_vaddr = first.sh_addr; |
| 3891 | phdr.p_paddr = first.sh_addr; |
| 3892 | phdr.p_memsz = memsz; |
| 3893 | phdr.p_filesz = filesz; |
| 3894 | phdr.p_align = @"align"; |
| 3891 | 3895 | |
| 3892 | 3896 | for (cover.items) |shndx| { |
| 3893 | 3897 | const shdr = &slice.items(.shdr)[shndx]; |
| ... | ... | @@ -4102,6 +4106,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4102 | 4106 | nlocals += @intCast(self.sections.slice().len); |
| 4103 | 4107 | |
| 4104 | 4108 | if (self.requiresThunks()) for (self.thunks.items) |*th| { |
| 4109 | th.output_symtab_ctx.reset(); |
| 4105 | 4110 | th.output_symtab_ctx.ilocal = nlocals; |
| 4106 | 4111 | th.calcSymtabSize(self); |
| 4107 | 4112 | nlocals += th.output_symtab_ctx.nlocals; |
| ... | ... | @@ -4113,6 +4118,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4113 | 4118 | const ctx = switch (file_ptr) { |
| 4114 | 4119 | inline else => |x| &x.output_symtab_ctx, |
| 4115 | 4120 | }; |
| 4121 | ctx.reset(); |
| 4116 | 4122 | ctx.ilocal = nlocals; |
| 4117 | 4123 | ctx.iglobal = nglobals; |
| 4118 | 4124 | try file_ptr.updateSymtabSize(self); |
| ... | ... | @@ -4122,6 +4128,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4122 | 4128 | } |
| 4123 | 4129 | |
| 4124 | 4130 | if (self.got_section_index) |_| { |
| 4131 | self.got.output_symtab_ctx.reset(); |
| 4125 | 4132 | self.got.output_symtab_ctx.ilocal = nlocals; |
| 4126 | 4133 | self.got.updateSymtabSize(self); |
| 4127 | 4134 | nlocals += self.got.output_symtab_ctx.nlocals; |
| ... | ... | @@ -4129,6 +4136,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4129 | 4136 | } |
| 4130 | 4137 | |
| 4131 | 4138 | if (self.plt_section_index) |_| { |
| 4139 | self.plt.output_symtab_ctx.reset(); |
| 4132 | 4140 | self.plt.output_symtab_ctx.ilocal = nlocals; |
| 4133 | 4141 | self.plt.updateSymtabSize(self); |
| 4134 | 4142 | nlocals += self.plt.output_symtab_ctx.nlocals; |
| ... | ... | @@ -4136,6 +4144,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4136 | 4144 | } |
| 4137 | 4145 | |
| 4138 | 4146 | if (self.plt_got_section_index) |_| { |
| 4147 | self.plt_got.output_symtab_ctx.reset(); |
| 4139 | 4148 | self.plt_got.output_symtab_ctx.ilocal = nlocals; |
| 4140 | 4149 | self.plt_got.updateSymtabSize(self); |
| 4141 | 4150 | nlocals += self.plt_got.output_symtab_ctx.nlocals; |
| ... | ... | @@ -4334,6 +4343,9 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4334 | 4343 | |
| 4335 | 4344 | try self.symtab.resize(gpa, nsyms); |
| 4336 | 4345 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4346 | // TODO we could resize instead and in ZigObject/Object always access as slice |
| 4347 | self.strtab.clearRetainingCapacity(); |
| 4348 | self.strtab.appendAssumeCapacity(0); |
| 4337 | 4349 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4338 | 4350 | |
| 4339 | 4351 | for (slice.items(.shdr), 0..) |shdr, shndx| { |
| ... | ... | @@ -4714,7 +4726,20 @@ pub fn isEffectivelyDynLib(self: Elf) bool { |
| 4714 | 4726 | }; |
| 4715 | 4727 | } |
| 4716 | 4728 | |
| 4717 | | pub fn addPhdr(self: *Elf, opts: struct { |
| 4729 | fn getPhdr(self: *Elf, opts: struct { |
| 4730 | type: u32 = 0, |
| 4731 | flags: u32 = 0, |
| 4732 | }) ?u16 { |
| 4733 | for (self.phdrs.items, 0..) |phdr, phndx| { |
| 4734 | if (self.phdr_table_load_index) |index| { |
| 4735 | if (phndx == index) continue; |
| 4736 | } |
| 4737 | if (phdr.p_type == opts.type and phdr.p_flags == opts.flags) return @intCast(phndx); |
| 4738 | } |
| 4739 | return null; |
| 4740 | } |
| 4741 | |
| 4742 | fn addPhdr(self: *Elf, opts: struct { |
| 4718 | 4743 | type: u32 = 0, |
| 4719 | 4744 | flags: u32 = 0, |
| 4720 | 4745 | @"align": u64 = 0, |
| ... | ... | @@ -5305,7 +5330,7 @@ fn fmtDumpState( |
| 5305 | 5330 | { |
| 5306 | 5331 | try writer.writeAll("atom lists\n"); |
| 5307 | 5332 | for (slice.items(.shdr), slice.items(.atom_list_2), 0..) |shdr, atom_list, shndx| { |
| 5308 | | try writer.print("shdr({d}) : {s} : {}", .{ shndx, self.getShString(shdr.sh_name), atom_list.fmt(self) }); |
| 5333 | try writer.print("shdr({d}) : {s} : {}\n", .{ shndx, self.getShString(shdr.sh_name), atom_list.fmt(self) }); |
| 5309 | 5334 | } |
| 5310 | 5335 | } |
| 5311 | 5336 | |
| ... | ... | @@ -5437,6 +5462,14 @@ pub const SymtabCtx = struct { |
| 5437 | 5462 | nlocals: u32 = 0, |
| 5438 | 5463 | nglobals: u32 = 0, |
| 5439 | 5464 | strsize: u32 = 0, |
| 5465 | |
| 5466 | pub fn reset(ctx: *SymtabCtx) void { |
| 5467 | ctx.ilocal = 0; |
| 5468 | ctx.iglobal = 0; |
| 5469 | ctx.nlocals = 0; |
| 5470 | ctx.nglobals = 0; |
| 5471 | ctx.strsize = 0; |
| 5472 | } |
| 5440 | 5473 | }; |
| 5441 | 5474 | |
| 5442 | 5475 | pub const null_sym = elf.Elf64_Sym{ |