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) = .{},
5757/// Tracked loadable segments during incremental linking.
5858/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
5959phdr_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
6361/// Special program headers
6462/// PT_PHDR
......@@ -123,7 +121,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
123121/// Tracked section headers with incremental updates to Zig object.
124122/// .rela.* sections are only used when emitting a relocatable object file.
125123zig_text_section_index: ?u32 = null,
126zig_data_rel_ro_section_index: ?u32 = null,
127124
128125debug_info_section_index: ?u32 = null,
129126debug_abbrev_section_index: ?u32 = null,
......@@ -3360,7 +3357,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
33603357
33613358 for (&[_]*?u16{
33623359 &self.phdr_zig_load_re_index,
3363 &self.phdr_zig_load_ro_index,
33643360 &self.phdr_table_index,
33653361 &self.phdr_table_load_index,
33663362 &self.phdr_interp_index,
......@@ -3487,7 +3483,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
34873483 &self.versym_section_index,
34883484 &self.verneed_section_index,
34893485 &self.zig_text_section_index,
3490 &self.zig_data_rel_ro_section_index,
34913486 &self.debug_info_section_index,
34923487 &self.debug_abbrev_section_index,
34933488 &self.debug_str_section_index,
......@@ -3588,6 +3583,7 @@ fn updateSectionSizes(self: *Elf) !void {
35883583 if (self.zigObjectPtr()) |zo| blk: {
35893584 const sym_index = for ([_]?Symbol.Index{
35903585 zo.data_index,
3586 zo.data_relro_index,
35913587 zo.bss_index,
35923588 }) |maybe_idx| {
35933589 if (maybe_idx) |idx| break idx;
......@@ -3932,6 +3928,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
39323928 if (self.zigObjectPtr()) |zo| blk: {
39333929 const existing_size = for ([_]?Symbol.Index{
39343930 zo.data_index,
3931 zo.data_relro_index,
39353932 zo.eh_frame_index,
39363933 }) |maybe_sym_index| {
39373934 const sect_sym_index = maybe_sym_index orelse continue;
......@@ -4105,6 +4102,7 @@ fn writeAtoms(self: *Elf) !void {
41054102 } else if (self.zigObjectPtr()) |zo| base_offset: {
41064103 const sym_index = for ([_]?Symbol.Index{
41074104 zo.data_index,
4105 zo.data_relro_index,
41084106 zo.eh_frame_index,
41094107 }) |maybe_idx| {
41104108 if (maybe_idx) |idx| break idx;
......@@ -4818,7 +4816,6 @@ pub fn isEffectivelyDynLib(self: Elf) bool {
48184816pub fn isZigSection(self: Elf, shndx: u32) bool {
48194817 inline for (&[_]?u32{
48204818 self.zig_text_section_index,
4821 self.zig_data_rel_ro_section_index,
48224819 }) |index| {
48234820 if (index == shndx) return true;
48244821 }
src/link/Elf/ZigObject.zig+59-42
......@@ -62,6 +62,8 @@ debug_rnglists_index: ?Symbol.Index = null,
6262eh_frame_index: ?Symbol.Index = null,
6363bss_index: ?Symbol.Index = null,
6464data_index: ?Symbol.Index = null,
65data_relro_index: ?Symbol.Index = null,
66rodata_index: ?Symbol.Index = null,
6567
6668pub const global_symbol_bit: u32 = 0x80000000;
6769pub const symbol_mask: u32 = 0x7fffffff;
......@@ -121,21 +123,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
121123 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
122124 });
123125 }
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 }
139126 }
140127
141128 if (elf_file.zig_text_section_index == null) {
......@@ -159,27 +146,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
159146 }
160147 }
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
183149 switch (comp.config.debug_format) {
184150 .strip => {},
185151 .dwarf => |v| {
......@@ -1083,6 +1049,20 @@ pub fn lowerUav(
10831049 return .{ .mcv = .{ .load_symbol = metadata.symbol_index } };
10841050 }
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
10861066 var name_buf: [32]u8 = undefined;
10871067 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
10881068 @intFromEnum(uav),
......@@ -1093,7 +1073,7 @@ pub fn lowerUav(
10931073 name,
10941074 val,
10951075 uav_alignment,
1096 elf_file.zig_data_rel_ro_section_index.?,
1076 osec,
10971077 src_loc,
10981078 ) catch |err| switch (err) {
10991079 error.OutOfMemory => return error.OutOfMemory,
......@@ -1240,7 +1220,19 @@ fn getNavShdrIndex(
12401220 .offset = std.math.maxInt(u64),
12411221 });
12421222 }
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 }
12441236 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
12451237 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
12461238 .Debug, .ReleaseSafe => {
......@@ -1253,7 +1245,12 @@ fn getNavShdrIndex(
12531245 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12541246 .offset = std.math.maxInt(u64),
12551247 });
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 );
12571254 return osec;
12581255 },
12591256 .ReleaseFast, .ReleaseSmall => {
......@@ -1293,7 +1290,12 @@ fn getNavShdrIndex(
12931290 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
12941291 .offset = std.math.maxInt(u64),
12951292 });
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 );
12971299 return osec;
12981300}
12991301
......@@ -1702,7 +1704,19 @@ fn updateLazySymbol(
17021704
17031705 const output_section_index = switch (sym.kind) {
17041706 .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 },
17061720 };
17071721 const local_sym = self.symbol(symbol_index);
17081722 local_sym.name_offset = name_str_index;
......@@ -2003,7 +2017,10 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
20032017 }
20042018 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| {
20072024 const sect_sym_index = maybe_sym_index orelse continue;
20082025 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
20092026 if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;