Commit abf6c20cb9

Jakub Konka <kubkon@jakubkonka.com>
2023-11-01 16:52:52
elf: rename .rodata to .data.rel.ro and remove allocateAllocSection helper
1 parent b1136a6
Changed files (2)
src/link/Elf/ZigObject.zig
@@ -510,7 +510,7 @@ pub fn lowerAnonDecl(
         name,
         tv,
         decl_alignment,
-        elf_file.zig_rodata_section_index.?,
+        elf_file.zig_data_rel_ro_section_index.?,
         src_loc,
     ) catch |err| switch (err) {
         error.OutOfMemory => return error.OutOfMemory,
@@ -622,7 +622,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In
         .Fn => elf_file.zig_text_section_index.?,
         else => blk: {
             if (decl.getOwnedVariable(mod)) |variable| {
-                if (variable.is_const) break :blk elf_file.zig_rodata_section_index.?;
+                if (variable.is_const) break :blk elf_file.zig_data_rel_ro_section_index.?;
                 if (variable.init.toValue().isUndefDeep(mod)) {
                     const mode = elf_file.base.options.optimize_mode;
                     if (mode == .Debug or mode == .ReleaseSafe) break :blk elf_file.zig_data_section_index.?;
@@ -636,7 +636,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In
                 if (is_all_zeroes) break :blk elf_file.zig_bss_section_index.?;
                 break :blk elf_file.zig_data_section_index.?;
             }
-            break :blk elf_file.zig_rodata_section_index.?;
+            break :blk elf_file.zig_data_rel_ro_section_index.?;
         },
     };
     return shdr_index;
@@ -937,7 +937,7 @@ fn updateLazySymbol(
 
     const output_section_index = switch (sym.kind) {
         .code => elf_file.zig_text_section_index.?,
-        .const_data => elf_file.zig_rodata_section_index.?,
+        .const_data => elf_file.zig_data_rel_ro_section_index.?,
     };
     const local_sym = elf_file.symbol(symbol_index);
     const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?;
@@ -991,7 +991,7 @@ pub fn lowerUnnamedConst(
         name,
         typed_value,
         typed_value.ty.abiAlignment(mod),
-        elf_file.zig_rodata_section_index.?,
+        elf_file.zig_data_rel_ro_section_index.?,
         decl.srcLoc(mod),
     )) {
         .ok => |sym_index| sym_index,
src/link/Elf.zig
@@ -104,7 +104,7 @@ zig_got: ZigGotSection = .{},
 
 /// Tracked section headers with incremental updates to Zig object
 zig_text_section_index: ?u16 = null,
-zig_rodata_section_index: ?u16 = null,
+zig_data_rel_ro_section_index: ?u16 = null,
 zig_data_section_index: ?u16 = null,
 zig_bss_section_index: ?u16 = null,
 zig_got_section_index: ?u16 = null,
@@ -484,40 +484,6 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 {
     return start;
 }
 
-const AllocateAllocSectionOpts = struct {
-    name: [:0]const u8,
-    phdr_index: u16,
-    alignment: u64 = 1,
-    flags: u64 = elf.SHF_ALLOC,
-    type: u32 = elf.SHT_PROGBITS,
-};
-
-pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfMemory}!u16 {
-    const gpa = self.base.allocator;
-    const phdr = &self.phdrs.items[opts.phdr_index];
-    const index = try self.addSection(.{
-        .name = opts.name,
-        .type = opts.type,
-        .flags = opts.flags,
-        .addralign = opts.alignment,
-        .offset = std.math.maxInt(u64),
-    });
-    const shdr = &self.shdrs.items[index];
-    try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index);
-    log.debug("allocating '{s}' in phdr({d}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
-        opts.name,
-        opts.phdr_index,
-        phdr.p_offset,
-        phdr.p_offset + phdr.p_filesz,
-        phdr.p_vaddr,
-        phdr.p_vaddr + phdr.p_memsz,
-    });
-    shdr.sh_addr = phdr.p_vaddr;
-    shdr.sh_offset = phdr.p_offset;
-    shdr.sh_size = phdr.p_memsz;
-    return index;
-}
-
 const AllocateNonAllocSectionOpts = struct {
     name: [:0]const u8,
     size: u64,
@@ -557,123 +523,193 @@ pub fn initMetadata(self: *Elf) !void {
 
     comptime assert(number_of_zig_segments == 5);
 
-    if (self.phdr_zig_load_re_index == null) {
-        const filesz = self.base.options.program_code_size_hint;
-        const off = self.findFreeSpace(filesz, self.page_size);
-        self.phdr_zig_load_re_index = try self.addPhdr(.{
-            .type = elf.PT_LOAD,
-            .offset = off,
-            .filesz = filesz,
-            .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000,
-            .memsz = filesz,
-            .@"align" = self.page_size,
-            .flags = elf.PF_X | elf.PF_R | elf.PF_W,
-        });
-    }
+    if (!self.isObject()) {
+        if (self.phdr_zig_load_re_index == null) {
+            const filesz = self.base.options.program_code_size_hint;
+            const off = self.findFreeSpace(filesz, self.page_size);
+            self.phdr_zig_load_re_index = try self.addPhdr(.{
+                .type = elf.PT_LOAD,
+                .offset = off,
+                .filesz = filesz,
+                .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000,
+                .memsz = filesz,
+                .@"align" = self.page_size,
+                .flags = elf.PF_X | elf.PF_R | elf.PF_W,
+            });
+        }
 
-    if (self.phdr_zig_got_index == null) {
-        // We really only need ptr alignment but since we are using PROGBITS, linux requires
-        // page align.
-        const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
-        const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
-        const off = self.findFreeSpace(filesz, alignment);
-        self.phdr_zig_got_index = try self.addPhdr(.{
-            .type = elf.PT_LOAD,
-            .offset = off,
-            .filesz = filesz,
-            .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000,
-            .memsz = filesz,
-            .@"align" = alignment,
-            .flags = elf.PF_R | elf.PF_W,
-        });
-    }
+        if (self.phdr_zig_got_index == null) {
+            // We really only need ptr alignment but since we are using PROGBITS, linux requires
+            // page align.
+            const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
+            const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
+            const off = self.findFreeSpace(filesz, alignment);
+            self.phdr_zig_got_index = try self.addPhdr(.{
+                .type = elf.PT_LOAD,
+                .offset = off,
+                .filesz = filesz,
+                .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000,
+                .memsz = filesz,
+                .@"align" = alignment,
+                .flags = elf.PF_R | elf.PF_W,
+            });
+        }
 
-    if (self.phdr_zig_load_ro_index == null) {
-        const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
-        const filesz: u64 = 1024;
-        const off = self.findFreeSpace(filesz, alignment);
-        self.phdr_zig_load_ro_index = try self.addPhdr(.{
-            .type = elf.PT_LOAD,
-            .offset = off,
-            .filesz = filesz,
-            .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000,
-            .memsz = filesz,
-            .@"align" = alignment,
-            .flags = elf.PF_R | elf.PF_W,
-        });
-    }
+        if (self.phdr_zig_load_ro_index == null) {
+            const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
+            const filesz: u64 = 1024;
+            const off = self.findFreeSpace(filesz, alignment);
+            self.phdr_zig_load_ro_index = try self.addPhdr(.{
+                .type = elf.PT_LOAD,
+                .offset = off,
+                .filesz = filesz,
+                .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000,
+                .memsz = filesz,
+                .@"align" = alignment,
+                .flags = elf.PF_R | elf.PF_W,
+            });
+        }
 
-    if (self.phdr_zig_load_rw_index == null) {
-        const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
-        const filesz: u64 = 1024;
-        const off = self.findFreeSpace(filesz, alignment);
-        self.phdr_zig_load_rw_index = try self.addPhdr(.{
-            .type = elf.PT_LOAD,
-            .offset = off,
-            .filesz = filesz,
-            .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000,
-            .memsz = filesz,
-            .@"align" = alignment,
-            .flags = elf.PF_R | elf.PF_W,
-        });
-    }
+        if (self.phdr_zig_load_rw_index == null) {
+            const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
+            const filesz: u64 = 1024;
+            const off = self.findFreeSpace(filesz, alignment);
+            self.phdr_zig_load_rw_index = try self.addPhdr(.{
+                .type = elf.PT_LOAD,
+                .offset = off,
+                .filesz = filesz,
+                .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000,
+                .memsz = filesz,
+                .@"align" = alignment,
+                .flags = elf.PF_R | elf.PF_W,
+            });
+        }
 
-    if (self.phdr_zig_load_zerofill_index == null) {
-        const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
-        self.phdr_zig_load_zerofill_index = try self.addPhdr(.{
-            .type = elf.PT_LOAD,
-            .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,
-            .memsz = 1024,
-            .@"align" = alignment,
-            .flags = elf.PF_R | elf.PF_W,
-        });
+        if (self.phdr_zig_load_zerofill_index == null) {
+            const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
+            self.phdr_zig_load_zerofill_index = try self.addPhdr(.{
+                .type = elf.PT_LOAD,
+                .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,
+                .memsz = 1024,
+                .@"align" = alignment,
+                .flags = elf.PF_R | elf.PF_W,
+            });
+        }
     }
 
     if (self.zig_text_section_index == null) {
-        self.zig_text_section_index = try self.allocateAllocSection(.{
+        self.zig_text_section_index = try self.addSection(.{
             .name = ".zig.text",
-            .phdr_index = self.phdr_zig_load_re_index.?,
+            .type = elf.SHT_PROGBITS,
             .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
+            .addralign = 1,
+            .offset = std.math.maxInt(u64),
         });
+        const shdr = &self.shdrs.items[self.zig_text_section_index.?];
+        if (self.phdr_zig_load_re_index) |phndx| {
+            const phdr = self.phdrs.items[phndx];
+            shdr.sh_addr = phdr.p_vaddr;
+            shdr.sh_offset = phdr.p_offset;
+            shdr.sh_size = phdr.p_memsz;
+            try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_text_section_index.?, phndx);
+        } else {
+            const size = self.base.options.program_code_size_hint;
+            const off = self.findFreeSpace(size, 1);
+            shdr.sh_offset = off;
+            shdr.sh_size = size;
+        }
         try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
     }
 
     if (self.zig_got_section_index == null) {
-        self.zig_got_section_index = try self.allocateAllocSection(.{
+        // TODO we don't actually need this section in a relocatable object file
+        self.zig_got_section_index = try self.addSection(.{
             .name = ".zig.got",
-            .phdr_index = self.phdr_zig_got_index.?,
-            .alignment = ptr_size,
+            .type = elf.SHT_PROGBITS,
+            .addralign = ptr_size,
             .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
+            .offset = std.math.maxInt(u64),
         });
+        const shdr = &self.shdrs.items[self.zig_got_section_index.?];
+        if (self.phdr_zig_got_index) |phndx| {
+            const phdr = self.phdrs.items[phndx];
+            shdr.sh_addr = phdr.p_vaddr;
+            shdr.sh_offset = phdr.p_offset;
+            shdr.sh_size = phdr.p_memsz;
+            try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_got_section_index.?, phndx);
+        } else {
+            const size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
+            const off = self.findFreeSpace(size, ptr_size);
+            shdr.sh_offset = off;
+            shdr.sh_size = size;
+        }
     }
 
-    if (self.zig_rodata_section_index == null) {
-        self.zig_rodata_section_index = try self.allocateAllocSection(.{
-            .name = ".zig.rodata",
-            .phdr_index = self.phdr_zig_load_ro_index.?,
+    if (self.zig_data_rel_ro_section_index == null) {
+        self.zig_data_rel_ro_section_index = try self.addSection(.{
+            .name = ".zig.data.rel.ro",
+            .type = elf.SHT_PROGBITS,
+            .addralign = 1,
             .flags = elf.SHF_ALLOC | elf.SHF_WRITE, // TODO rename this section to .data.rel.ro
+            .offset = std.math.maxInt(u64),
         });
-        try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_rodata_section_index.?, .{});
+        const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
+        if (self.phdr_zig_load_ro_index) |phndx| {
+            const phdr = self.phdrs.items[phndx];
+            shdr.sh_addr = phdr.p_vaddr;
+            shdr.sh_offset = phdr.p_offset;
+            shdr.sh_size = phdr.p_memsz;
+            try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, phndx);
+        } else {
+            const size: u64 = 1024;
+            const off = self.findFreeSpace(size, 1);
+            shdr.sh_offset = off;
+            shdr.sh_size = size;
+        }
+        try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{});
     }
 
     if (self.zig_data_section_index == null) {
-        self.zig_data_section_index = try self.allocateAllocSection(.{
+        self.zig_data_section_index = try self.addSection(.{
             .name = ".zig.data",
-            .phdr_index = self.phdr_zig_load_rw_index.?,
-            .alignment = ptr_size,
+            .type = elf.SHT_PROGBITS,
+            .addralign = ptr_size,
             .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
+            .offset = std.math.maxInt(u64),
         });
+        const shdr = &self.shdrs.items[self.zig_data_section_index.?];
+        if (self.phdr_zig_load_rw_index) |phndx| {
+            const phdr = self.phdrs.items[phndx];
+            shdr.sh_addr = phdr.p_vaddr;
+            shdr.sh_offset = phdr.p_offset;
+            shdr.sh_size = phdr.p_memsz;
+            try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_data_section_index.?, phndx);
+        } else {
+            const size: u64 = 1024;
+            const off = self.findFreeSpace(size, ptr_size);
+            shdr.sh_offset = off;
+            shdr.sh_size = size;
+        }
         try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{});
     }
 
     if (self.zig_bss_section_index == null) {
-        self.zig_bss_section_index = try self.allocateAllocSection(.{
+        self.zig_bss_section_index = try self.addSection(.{
             .name = ".zig.bss",
-            .phdr_index = self.phdr_zig_load_zerofill_index.?,
-            .alignment = ptr_size,
-            .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
             .type = elf.SHT_NOBITS,
+            .addralign = ptr_size,
+            .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
+            .offset = 0,
         });
+        const shdr = &self.shdrs.items[self.zig_bss_section_index.?];
+        if (self.phdr_zig_load_zerofill_index) |phndx| {
+            const phdr = self.phdrs.items[phndx];
+            shdr.sh_addr = phdr.p_vaddr;
+            shdr.sh_size = phdr.p_memsz;
+            try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx);
+        } else {
+            shdr.sh_size = 1024;
+        }
         try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{});
     }
 
@@ -3628,7 +3664,7 @@ fn sortShdrs(self: *Elf) !void {
         &self.verneed_section_index,
         &self.zig_text_section_index,
         &self.zig_got_section_index,
-        &self.zig_rodata_section_index,
+        &self.zig_data_rel_ro_section_index,
         &self.zig_data_section_index,
         &self.zig_bss_section_index,
         &self.debug_str_section_index,
@@ -4856,7 +4892,7 @@ pub fn isDynLib(self: Elf) bool {
 pub fn isZigSection(self: Elf, shndx: u16) bool {
     inline for (&[_]?u16{
         self.zig_text_section_index,
-        self.zig_rodata_section_index,
+        self.zig_data_rel_ro_section_index,
         self.zig_data_section_index,
         self.zig_bss_section_index,
         self.zig_got_section_index,