authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-29 20:56:12+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
log848535535d88641a97c6f364cc78171743d7ae81
tree6ca6bfac0f6fcec3eac89c920aa99954343820dc
parent0b92404ddf71c72664d2d4dd252e211a9678492d

elf: allocate .data.rel.ro and .rodata in ZigObject similarly to .eh_frame


2 files changed, 62 insertions(+), 48 deletions(-)

src/link/Elf.zig+3-6
...@@ -57,8 +57,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},...@@ -57,8 +57,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
57/// Tracked loadable segments during incremental linking.57/// Tracked loadable segments during incremental linking.
58/// The index into the program headers of a PT_LOAD program header with Read and Execute flags58/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
59phdr_zig_load_re_index: ?u16 = null,59phdr_zig_load_re_index: ?u16 = null,
60/// The index into the program headers of a PT_LOAD program header with Read flag
61phdr_zig_load_ro_index: ?u16 = null,
6260
63/// Special program headers61/// Special program headers
64/// PT_PHDR62/// PT_PHDR
...@@ -123,7 +121,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},...@@ -123,7 +121,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
123/// Tracked section headers with incremental updates to Zig object.121/// Tracked section headers with incremental updates to Zig object.
124/// .rela.* sections are only used when emitting a relocatable object file.122/// .rela.* sections are only used when emitting a relocatable object file.
125zig_text_section_index: ?u32 = null,123zig_text_section_index: ?u32 = null,
126zig_data_rel_ro_section_index: ?u32 = null,
127124
128debug_info_section_index: ?u32 = null,125debug_info_section_index: ?u32 = null,
129debug_abbrev_section_index: ?u32 = null,126debug_abbrev_section_index: ?u32 = null,
...@@ -3360,7 +3357,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {...@@ -3360,7 +3357,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
33603357
3361 for (&[_]*?u16{3358 for (&[_]*?u16{
3362 &self.phdr_zig_load_re_index,3359 &self.phdr_zig_load_re_index,
3363 &self.phdr_zig_load_ro_index,
3364 &self.phdr_table_index,3360 &self.phdr_table_index,
3365 &self.phdr_table_load_index,3361 &self.phdr_table_load_index,
3366 &self.phdr_interp_index,3362 &self.phdr_interp_index,
...@@ -3487,7 +3483,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {...@@ -3487,7 +3483,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
3487 &self.versym_section_index,3483 &self.versym_section_index,
3488 &self.verneed_section_index,3484 &self.verneed_section_index,
3489 &self.zig_text_section_index,3485 &self.zig_text_section_index,
3490 &self.zig_data_rel_ro_section_index,
3491 &self.debug_info_section_index,3486 &self.debug_info_section_index,
3492 &self.debug_abbrev_section_index,3487 &self.debug_abbrev_section_index,
3493 &self.debug_str_section_index,3488 &self.debug_str_section_index,
...@@ -3588,6 +3583,7 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3588,6 +3583,7 @@ fn updateSectionSizes(self: *Elf) !void {
3588 if (self.zigObjectPtr()) |zo| blk: {3583 if (self.zigObjectPtr()) |zo| blk: {
3589 const sym_index = for ([_]?Symbol.Index{3584 const sym_index = for ([_]?Symbol.Index{
3590 zo.data_index,3585 zo.data_index,
3586 zo.data_relro_index,
3591 zo.bss_index,3587 zo.bss_index,
3592 }) |maybe_idx| {3588 }) |maybe_idx| {
3593 if (maybe_idx) |idx| break idx;3589 if (maybe_idx) |idx| break idx;
...@@ -3932,6 +3928,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3932,6 +3928,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3932 if (self.zigObjectPtr()) |zo| blk: {3928 if (self.zigObjectPtr()) |zo| blk: {
3933 const existing_size = for ([_]?Symbol.Index{3929 const existing_size = for ([_]?Symbol.Index{
3934 zo.data_index,3930 zo.data_index,
3931 zo.data_relro_index,
3935 zo.eh_frame_index,3932 zo.eh_frame_index,
3936 }) |maybe_sym_index| {3933 }) |maybe_sym_index| {
3937 const sect_sym_index = maybe_sym_index orelse continue;3934 const sect_sym_index = maybe_sym_index orelse continue;
...@@ -4105,6 +4102,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4105,6 +4102,7 @@ fn writeAtoms(self: *Elf) !void {
4105 } else if (self.zigObjectPtr()) |zo| base_offset: {4102 } else if (self.zigObjectPtr()) |zo| base_offset: {
4106 const sym_index = for ([_]?Symbol.Index{4103 const sym_index = for ([_]?Symbol.Index{
4107 zo.data_index,4104 zo.data_index,
4105 zo.data_relro_index,
4108 zo.eh_frame_index,4106 zo.eh_frame_index,
4109 }) |maybe_idx| {4107 }) |maybe_idx| {
4110 if (maybe_idx) |idx| break idx;4108 if (maybe_idx) |idx| break idx;
...@@ -4818,7 +4816,6 @@ pub fn isEffectivelyDynLib(self: Elf) bool {...@@ -4818,7 +4816,6 @@ pub fn isEffectivelyDynLib(self: Elf) bool {
4818pub fn isZigSection(self: Elf, shndx: u32) bool {4816pub fn isZigSection(self: Elf, shndx: u32) bool {
4819 inline for (&[_]?u32{4817 inline for (&[_]?u32{
4820 self.zig_text_section_index,4818 self.zig_text_section_index,
4821 self.zig_data_rel_ro_section_index,
4822 }) |index| {4819 }) |index| {
4823 if (index == shndx) return true;4820 if (index == shndx) return true;
4824 }4821 }
src/link/Elf/ZigObject.zig+59-42
...@@ -62,6 +62,8 @@ debug_rnglists_index: ?Symbol.Index = null,...@@ -62,6 +62,8 @@ debug_rnglists_index: ?Symbol.Index = null,
62eh_frame_index: ?Symbol.Index = null,62eh_frame_index: ?Symbol.Index = null,
63bss_index: ?Symbol.Index = null,63bss_index: ?Symbol.Index = null,
64data_index: ?Symbol.Index = null,64data_index: ?Symbol.Index = null,
65data_relro_index: ?Symbol.Index = null,
66rodata_index: ?Symbol.Index = null,
6567
66pub const global_symbol_bit: u32 = 0x80000000;68pub const global_symbol_bit: u32 = 0x80000000;
67pub const symbol_mask: u32 = 0x7fffffff;69pub const symbol_mask: u32 = 0x7fffffff;
...@@ -121,21 +123,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -121,21 +123,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
121 .flags = elf.PF_X | elf.PF_R | elf.PF_W,123 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
122 });124 });
123 }125 }
124
125 if (elf_file.phdr_zig_load_ro_index == null) {
126 const alignment = elf_file.page_size;
127 const filesz: u64 = 1024;
128 const off = try elf_file.findFreeSpace(filesz, alignment);
129 elf_file.phdr_zig_load_ro_index = try elf_file.addPhdr(.{
130 .type = elf.PT_LOAD,
131 .offset = off,
132 .filesz = filesz,
133 .addr = if (ptr_size >= 4) 0xc000000 else 0xa000,
134 .memsz = filesz,
135 .@"align" = alignment,
136 .flags = elf.PF_R | elf.PF_W,
137 });
138 }
139 }126 }
140127
141 if (elf_file.zig_text_section_index == null) {128 if (elf_file.zig_text_section_index == null) {
...@@ -159,27 +146,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -159,27 +146,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
159 }146 }
160 }147 }
161148
162 if (elf_file.zig_data_rel_ro_section_index == null) {
163 elf_file.zig_data_rel_ro_section_index = try elf_file.addSection(.{
164 .name = try elf_file.insertShString(".data.rel.ro.zig"),
165 .type = elf.SHT_PROGBITS,
166 .addralign = 1,
167 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
168 .offset = std.math.maxInt(u64),
169 });
170 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_rel_ro_section_index.?];
171 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_rel_ro_section_index.?];
172 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index);
173 if (elf_file.base.isRelocatable()) {
174 _ = try elf_file.addRelaShdr(
175 try elf_file.insertShString(".rela.data.rel.ro.zig"),
176 elf_file.zig_data_rel_ro_section_index.?,
177 );
178 } else {
179 phndx.* = elf_file.phdr_zig_load_ro_index.?;
180 }
181 }
182
183 switch (comp.config.debug_format) {149 switch (comp.config.debug_format) {
184 .strip => {},150 .strip => {},
185 .dwarf => |v| {151 .dwarf => |v| {
...@@ -1083,6 +1049,20 @@ pub fn lowerUav(...@@ -1083,6 +1049,20 @@ pub fn lowerUav(
1083 return .{ .mcv = .{ .load_symbol = metadata.symbol_index } };1049 return .{ .mcv = .{ .load_symbol = metadata.symbol_index } };
1084 }1050 }
10851051
1052 const osec = if (self.data_relro_index) |sym_index|
1053 self.symbol(sym_index).atom(elf_file).?.output_section_index
1054 else osec: {
1055 const osec = try elf_file.addSection(.{
1056 .name = try elf_file.insertShString(".data.rel.ro"),
1057 .type = elf.SHT_PROGBITS,
1058 .addralign = 1,
1059 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1060 .offset = std.math.maxInt(u64),
1061 });
1062 self.data_relro_index = osec;
1063 break :osec osec;
1064 };
1065
1086 var name_buf: [32]u8 = undefined;1066 var name_buf: [32]u8 = undefined;
1087 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{1067 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1088 @intFromEnum(uav),1068 @intFromEnum(uav),
...@@ -1093,7 +1073,7 @@ pub fn lowerUav(...@@ -1093,7 +1073,7 @@ pub fn lowerUav(
1093 name,1073 name,
1094 val,1074 val,
1095 uav_alignment,1075 uav_alignment,
1096 elf_file.zig_data_rel_ro_section_index.?,1076 osec,
1097 src_loc,1077 src_loc,
1098 ) catch |err| switch (err) {1078 ) catch |err| switch (err) {
1099 error.OutOfMemory => return error.OutOfMemory,1079 error.OutOfMemory => return error.OutOfMemory,
...@@ -1240,7 +1220,19 @@ fn getNavShdrIndex(...@@ -1240,7 +1220,19 @@ fn getNavShdrIndex(
1240 .offset = std.math.maxInt(u64),1220 .offset = std.math.maxInt(u64),
1241 });1221 });
1242 }1222 }
1243 if (is_const) return elf_file.zig_data_rel_ro_section_index.?;1223 if (is_const) {
1224 if (self.data_relro_index) |symbol_index|
1225 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1226 const osec = try elf_file.addSection(.{
1227 .name = try elf_file.insertShString(".data.rel.ro"),
1228 .type = elf.SHT_PROGBITS,
1229 .addralign = 1,
1230 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1231 .offset = std.math.maxInt(u64),
1232 });
1233 self.data_relro_index = try self.addSectionSymbol(gpa, ".data.rel.ro", .@"1", osec);
1234 return osec;
1235 }
1244 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))1236 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
1245 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {1237 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
1246 .Debug, .ReleaseSafe => {1238 .Debug, .ReleaseSafe => {
...@@ -1253,7 +1245,12 @@ fn getNavShdrIndex(...@@ -1253,7 +1245,12 @@ fn getNavShdrIndex(
1253 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,1245 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1254 .offset = std.math.maxInt(u64),1246 .offset = std.math.maxInt(u64),
1255 });1247 });
1256 self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);1248 self.data_index = try self.addSectionSymbol(
1249 gpa,
1250 ".data",
1251 Atom.Alignment.fromNonzeroByteUnits(ptr_size),
1252 osec,
1253 );
1257 return osec;1254 return osec;
1258 },1255 },
1259 .ReleaseFast, .ReleaseSmall => {1256 .ReleaseFast, .ReleaseSmall => {
...@@ -1293,7 +1290,12 @@ fn getNavShdrIndex(...@@ -1293,7 +1290,12 @@ fn getNavShdrIndex(
1293 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,1290 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1294 .offset = std.math.maxInt(u64),1291 .offset = std.math.maxInt(u64),
1295 });1292 });
1296 self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);1293 self.data_index = try self.addSectionSymbol(
1294 gpa,
1295 ".data",
1296 Atom.Alignment.fromNonzeroByteUnits(ptr_size),
1297 osec,
1298 );
1297 return osec;1299 return osec;
1298}1300}
12991301
...@@ -1702,7 +1704,19 @@ fn updateLazySymbol(...@@ -1702,7 +1704,19 @@ fn updateLazySymbol(
17021704
1703 const output_section_index = switch (sym.kind) {1705 const output_section_index = switch (sym.kind) {
1704 .code => elf_file.zig_text_section_index.?,1706 .code => elf_file.zig_text_section_index.?,
1705 .const_data => elf_file.zig_data_rel_ro_section_index.?,1707 .const_data => if (self.rodata_index) |sym_index|
1708 self.symbol(sym_index).atom(elf_file).?.output_section_index
1709 else osec: {
1710 const osec = try elf_file.addSection(.{
1711 .name = try elf_file.insertShString(".rodata"),
1712 .type = elf.SHT_PROGBITS,
1713 .addralign = 1,
1714 .flags = elf.SHF_ALLOC,
1715 .offset = std.math.maxInt(u64),
1716 });
1717 self.rodata_index = try self.addSectionSymbol(gpa, ".rodata", .@"1", osec);
1718 break :osec osec;
1719 },
1706 };1720 };
1707 const local_sym = self.symbol(symbol_index);1721 const local_sym = self.symbol(symbol_index);
1708 local_sym.name_offset = name_str_index;1722 local_sym.name_offset = name_str_index;
...@@ -2003,7 +2017,10 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {...@@ -2003,7 +2017,10 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
2003 }2017 }
2004 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);2018 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);
20052019
2006 const sect_atom_ptr = for ([_]?Symbol.Index{self.data_index}) |maybe_sym_index| {2020 const sect_atom_ptr = for ([_]?Symbol.Index{
2021 self.data_index,
2022 self.data_relro_index,
2023 }) |maybe_sym_index| {
2007 const sect_sym_index = maybe_sym_index orelse continue;2024 const sect_sym_index = maybe_sym_index orelse continue;
2008 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;2025 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
2009 if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;2026 if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;