Commit 216a5594f6

Jakub Konka <kubkon@jakubkonka.com>
2024-02-13 17:24:46
elf: use u32 for all section indexes
1 parent e401930
src/link/Elf/Atom.zig
@@ -17,7 +17,7 @@ alignment: Alignment = .@"1",
 input_section_index: u32 = 0,
 
 /// Index of the output section.
-output_section_index: u16 = 0,
+output_section_index: u32 = 0,
 
 /// Index of the input section containing this atom's relocs.
 relocs_section_index: u32 = 0,
@@ -77,7 +77,7 @@ pub fn relocsShndx(self: Atom) ?u32 {
     return self.relocs_section_index;
 }
 
-pub fn outputShndx(self: Atom) ?u16 {
+pub fn outputShndx(self: Atom) ?u32 {
     if (self.output_section_index == 0) return null;
     return self.output_section_index;
 }
src/link/Elf/Object.zig
@@ -126,7 +126,7 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil
     try self.strtab.appendSlice(allocator, shstrtab);
 
     const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {
-        elf.SHT_SYMTAB => break @as(u16, @intCast(i)),
+        elf.SHT_SYMTAB => break @as(u32, @intCast(i)),
         else => {},
     } else null;
 
@@ -223,7 +223,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
             => {},
 
             else => {
-                const shndx = @as(u16, @intCast(i));
+                const shndx = @as(u32, @intCast(i));
                 if (self.skipShdr(shndx, elf_file)) continue;
                 try self.addAtom(allocator, handle, shdr, shndx, elf_file);
             },
@@ -268,7 +268,7 @@ fn addAtom(self: *Object, allocator: Allocator, handle: std.fs.File, shdr: elf.E
     }
 }
 
-fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u16 {
+fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u32 {
     const name = blk: {
         const name = self.getString(shdr.sh_name);
         if (elf_file.base.isRelocatable()) break :blk name;
@@ -316,7 +316,7 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{O
     return out_shndx;
 }
 
-fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool {
+fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool {
     const comp = elf_file.base.comp;
     const shdr = self.shdrs.items[index];
     const name = self.getString(shdr.sh_name);
@@ -673,7 +673,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
 
         var sh_flags: u32 = elf.SHF_ALLOC | elf.SHF_WRITE;
         if (is_tls) sh_flags |= elf.SHF_TLS;
-        const shndx = @as(u16, @intCast(self.shdrs.items.len));
+        const shndx = @as(u32, @intCast(self.shdrs.items.len));
         const shdr = try self.shdrs.addOne(gpa);
         const sh_size = math.cast(usize, this_sym.st_size) orelse return error.Overflow;
         shdr.* = .{
src/link/Elf/Symbol.zig
@@ -15,7 +15,7 @@ file_index: File.Index = 0,
 atom_index: Atom.Index = 0,
 
 /// Assigned output section index for this atom.
-output_section_index: u16 = 0,
+output_section_index: u32 = 0,
 
 /// Index of the source symbol this symbol references.
 /// Use `elfSym` to pull the source symbol from the relevant file.
@@ -37,7 +37,7 @@ pub fn isAbs(symbol: Symbol, elf_file: *Elf) bool {
         file_ptr != .linker_defined;
 }
 
-pub fn outputShndx(symbol: Symbol) ?u16 {
+pub fn outputShndx(symbol: Symbol) ?u32 {
     if (symbol.output_section_index == 0) return null;
     return symbol.output_section_index;
 }
@@ -237,12 +237,12 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
         if (file_ptr == .shared_object) break :blk elf.STB_GLOBAL;
         break :blk esym.st_bind();
     };
-    const st_shndx = blk: {
-        if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;
+    const st_shndx: u16 = blk: {
+        if (symbol.flags.has_copy_rel) break :blk @intCast(elf_file.copy_rel_section_index.?);
         if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;
         if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
         if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;
-        break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;
+        break :blk @intCast(symbol.outputShndx() orelse elf.SHN_UNDEF);
     };
     const st_value = blk: {
         if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file);
src/link/Elf/synthetic_sections.zig
@@ -388,7 +388,7 @@ pub const ZigGotSection = struct {
                 .st_name = st_name,
                 .st_info = elf.STT_OBJECT,
                 .st_other = 0,
-                .st_shndx = elf_file.zig_got_section_index.?,
+                .st_shndx = @intCast(elf_file.zig_got_section_index.?),
                 .st_value = st_value,
                 .st_size = st_size,
             };
@@ -813,7 +813,7 @@ pub const GotSection = struct {
                 .st_name = st_name,
                 .st_info = elf.STT_OBJECT,
                 .st_other = 0,
-                .st_shndx = elf_file.got_section_index.?,
+                .st_shndx = @intCast(elf_file.got_section_index.?),
                 .st_value = st_value,
                 .st_size = st_size,
             };
@@ -953,7 +953,7 @@ pub const PltSection = struct {
                 .st_name = st_name,
                 .st_info = elf.STT_FUNC,
                 .st_other = 0,
-                .st_shndx = elf_file.plt_section_index.?,
+                .st_shndx = @intCast(elf_file.plt_section_index.?),
                 .st_value = sym.pltAddress(elf_file),
                 .st_size = 16,
             };
@@ -1082,7 +1082,7 @@ pub const PltGotSection = struct {
                 .st_name = st_name,
                 .st_info = elf.STT_FUNC,
                 .st_other = 0,
-                .st_shndx = elf_file.plt_got_section_index.?,
+                .st_shndx = @intCast(elf_file.plt_got_section_index.?),
                 .st_value = sym.pltGotAddress(elf_file),
                 .st_size = 16,
             };
@@ -1132,7 +1132,7 @@ pub const CopyRelSection = struct {
         }
     }
 
-    pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u16, elf_file: *Elf) !void {
+    pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {
         const shdr = &elf_file.shdrs.items[shndx];
         for (copy_rel.symbols.items) |sym_index| {
             const symbol = elf_file.symbol(sym_index);
src/link/Elf/ZigObject.zig
@@ -840,7 +840,7 @@ fn getDeclShdrIndex(
     elf_file: *Elf,
     decl: *const Module.Decl,
     code: []const u8,
-) error{OutOfMemory}!u16 {
+) error{OutOfMemory}!u32 {
     _ = self;
     const mod = elf_file.base.comp.module.?;
     const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
@@ -894,7 +894,7 @@ fn updateDeclCode(
     elf_file: *Elf,
     decl_index: InternPool.DeclIndex,
     sym_index: Symbol.Index,
-    shdr_index: u16,
+    shdr_index: u32,
     code: []const u8,
     stt_bits: u8,
 ) !void {
@@ -993,7 +993,7 @@ fn updateTlv(
     elf_file: *Elf,
     decl_index: InternPool.DeclIndex,
     sym_index: Symbol.Index,
-    shndx: u16,
+    shndx: u32,
     code: []const u8,
 ) !void {
     const gpa = elf_file.base.comp.gpa;
@@ -1334,7 +1334,7 @@ fn lowerConst(
     name: []const u8,
     tv: TypedValue,
     required_alignment: InternPool.Alignment,
-    output_section_index: u16,
+    output_section_index: u32,
     src_loc: Module.SrcLoc,
 ) !LowerConstResult {
     const gpa = elf_file.base.comp.gpa;
src/link/Elf.zig
@@ -138,40 +138,40 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
 
 /// Tracked section headers with incremental updates to Zig object.
 /// .rela.* sections are only used when emitting a relocatable object file.
-zig_text_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,
-
-debug_info_section_index: ?u16 = null,
-debug_abbrev_section_index: ?u16 = null,
-debug_str_section_index: ?u16 = null,
-debug_aranges_section_index: ?u16 = null,
-debug_line_section_index: ?u16 = null,
-
-copy_rel_section_index: ?u16 = null,
-dynamic_section_index: ?u16 = null,
-dynstrtab_section_index: ?u16 = null,
-dynsymtab_section_index: ?u16 = null,
-eh_frame_section_index: ?u16 = null,
-eh_frame_rela_section_index: ?u16 = null,
-eh_frame_hdr_section_index: ?u16 = null,
-hash_section_index: ?u16 = null,
-gnu_hash_section_index: ?u16 = null,
-got_section_index: ?u16 = null,
-got_plt_section_index: ?u16 = null,
-interp_section_index: ?u16 = null,
-plt_section_index: ?u16 = null,
-plt_got_section_index: ?u16 = null,
-rela_dyn_section_index: ?u16 = null,
-rela_plt_section_index: ?u16 = null,
-versym_section_index: ?u16 = null,
-verneed_section_index: ?u16 = null,
-
-shstrtab_section_index: ?u16 = null,
-strtab_section_index: ?u16 = null,
-symtab_section_index: ?u16 = null,
+zig_text_section_index: ?u32 = null,
+zig_data_rel_ro_section_index: ?u32 = null,
+zig_data_section_index: ?u32 = null,
+zig_bss_section_index: ?u32 = null,
+zig_got_section_index: ?u32 = null,
+
+debug_info_section_index: ?u32 = null,
+debug_abbrev_section_index: ?u32 = null,
+debug_str_section_index: ?u32 = null,
+debug_aranges_section_index: ?u32 = null,
+debug_line_section_index: ?u32 = null,
+
+copy_rel_section_index: ?u32 = null,
+dynamic_section_index: ?u32 = null,
+dynstrtab_section_index: ?u32 = null,
+dynsymtab_section_index: ?u32 = null,
+eh_frame_section_index: ?u32 = null,
+eh_frame_rela_section_index: ?u32 = null,
+eh_frame_hdr_section_index: ?u32 = null,
+hash_section_index: ?u32 = null,
+gnu_hash_section_index: ?u32 = null,
+got_section_index: ?u32 = null,
+got_plt_section_index: ?u32 = null,
+interp_section_index: ?u32 = null,
+plt_section_index: ?u32 = null,
+plt_got_section_index: ?u32 = null,
+rela_dyn_section_index: ?u32 = null,
+rela_plt_section_index: ?u32 = null,
+versym_section_index: ?u32 = null,
+verneed_section_index: ?u32 = null,
+
+shstrtab_section_index: ?u32 = null,
+strtab_section_index: ?u32 = null,
+symtab_section_index: ?u32 = null,
 
 // Linker-defined symbols
 dynamic_index: ?Symbol.Index = null,
@@ -931,7 +931,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
     try self.base.file.?.pwriteAll(&[1]u8{0}, end_pos);
 }
 
-pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
+pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
     const shdr = &self.shdrs.items[shdr_index];
     const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null;
     const is_zerofill = shdr.sh_type == elf.SHT_NOBITS;
@@ -981,7 +981,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
 
 pub fn growNonAllocSection(
     self: *Elf,
-    shdr_index: u16,
+    shdr_index: u32,
     needed_size: u64,
     min_alignment: u32,
     requires_file_copy: bool,
@@ -1018,7 +1018,7 @@ pub fn growNonAllocSection(
     self.markDirty(shdr_index);
 }
 
-pub fn markDirty(self: *Elf, shdr_index: u16) void {
+pub fn markDirty(self: *Elf, shdr_index: u32) void {
     const zig_object = self.zigObjectPtr().?;
     if (zig_object.dwarf) |_| {
         if (self.debug_info_section_index.? == shdr_index) {
@@ -2969,7 +2969,7 @@ pub fn writeElfHeader(self: *Elf) !void {
     mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);
     index += 2;
 
-    mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_section_index.?, endian);
+    mem.writeInt(u16, hdr_buf[index..][0..2], @intCast(self.shstrtab_section_index.?), endian);
     index += 2;
 
     assert(index == e_ehsize);
@@ -3709,7 +3709,7 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
     }
 }
 
-fn shdrRank(self: *Elf, shndx: u16) u8 {
+fn shdrRank(self: *Elf, shndx: u32) u8 {
     const shdr = self.shdrs.items[shndx];
     const name = self.getShString(shdr.sh_name);
     const flags = shdr.sh_flags;
@@ -3759,7 +3759,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 {
 
 pub fn sortShdrs(self: *Elf) !void {
     const Entry = struct {
-        shndx: u16,
+        shndx: u32,
 
         pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool {
             return elf_file.shdrRank(lhs.shndx) < elf_file.shdrRank(rhs.shndx);
@@ -3770,15 +3770,15 @@ pub fn sortShdrs(self: *Elf) !void {
     var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len);
     defer entries.deinit();
     for (0..self.shdrs.items.len) |shndx| {
-        entries.appendAssumeCapacity(.{ .shndx = @as(u16, @intCast(shndx)) });
+        entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) });
     }
 
     mem.sort(Entry, entries.items, self, Entry.lessThan);
 
-    const backlinks = try gpa.alloc(u16, entries.items.len);
+    const backlinks = try gpa.alloc(u32, entries.items.len);
     defer gpa.free(backlinks);
     for (entries.items, 0..) |entry, i| {
-        backlinks[entry.shndx] = @as(u16, @intCast(i));
+        backlinks[entry.shndx] = @intCast(i);
     }
 
     const slice = try self.shdrs.toOwnedSlice(gpa);
@@ -3792,10 +3792,10 @@ pub fn sortShdrs(self: *Elf) !void {
     try self.resetShdrIndexes(backlinks);
 }
 
-fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void {
+fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
     const gpa = self.base.comp.gpa;
 
-    for (&[_]*?u16{
+    for (&[_]*?u32{
         &self.eh_frame_section_index,
         &self.eh_frame_rela_section_index,
         &self.eh_frame_hdr_section_index,
@@ -4191,7 +4191,7 @@ pub fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void {
     // virtual and file offsets. However, the simple one will do for one
     // as we are more interested in quick turnaround and compatibility
     // with `findFreeSpace` mechanics than anything else.
-    const Cover = std.ArrayList(u16);
+    const Cover = std.ArrayList(u32);
     const gpa = self.base.comp.gpa;
     var covers: [max_number_of_object_segments]Cover = undefined;
     for (&covers) |*cover| {
@@ -4347,7 +4347,7 @@ pub fn allocateNonAllocSections(self: *Elf) !void {
 }
 
 fn allocateSpecialPhdrs(self: *Elf) void {
-    for (&[_]struct { ?u16, ?u16 }{
+    for (&[_]struct { ?u16, ?u32 }{
         .{ self.phdr_interp_index, self.interp_section_index },
         .{ self.phdr_dynamic_index, self.dynamic_section_index },
         .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index },
@@ -4370,7 +4370,7 @@ fn allocateSpecialPhdrs(self: *Elf) void {
     if (self.phdr_tls_index) |index| {
         const slice = self.shdrs.items;
         const phdr = &self.phdrs.items[index];
-        var shndx: u16 = 0;
+        var shndx: u32 = 0;
         while (shndx < slice.len) {
             const shdr = slice[shndx];
             if (shdr.sh_flags & elf.SHF_TLS == 0) {
@@ -5138,8 +5138,8 @@ const CsuObjects = struct {
     }
 };
 
-pub fn isZigSection(self: Elf, shndx: u16) bool {
-    inline for (&[_]?u16{
+pub fn isZigSection(self: Elf, shndx: u32) bool {
+    inline for (&[_]?u32{
         self.zig_text_section_index,
         self.zig_data_rel_ro_section_index,
         self.zig_data_section_index,
@@ -5153,8 +5153,8 @@ pub fn isZigSection(self: Elf, shndx: u16) bool {
     return false;
 }
 
-pub fn isDebugSection(self: Elf, shndx: u16) bool {
-    inline for (&[_]?u16{
+pub fn isDebugSection(self: Elf, shndx: u32) bool {
+    inline for (&[_]?u32{
         self.debug_info_section_index,
         self.debug_abbrev_section_index,
         self.debug_str_section_index,
@@ -5192,7 +5192,7 @@ fn addPhdr(self: *Elf, opts: struct {
     return index;
 }
 
-pub fn addRelaShdr(self: *Elf, name: [:0]const u8, shndx: u16) !u16 {
+pub fn addRelaShdr(self: *Elf, name: [:0]const u8, shndx: u32) !u32 {
     const entsize: u64 = switch (self.ptr_width) {
         .p32 => @sizeOf(elf.Elf32_Rela),
         .p64 => @sizeOf(elf.Elf64_Rela),
@@ -5223,9 +5223,9 @@ pub const AddSectionOpts = struct {
     offset: u64 = 0,
 };
 
-pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 {
+pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 {
     const gpa = self.base.comp.gpa;
-    const index = @as(u16, @intCast(self.shdrs.items.len));
+    const index = @as(u32, @intCast(self.shdrs.items.len));
     const shdr = try self.shdrs.addOne(gpa);
     shdr.* = .{
         .sh_name = try self.insertShString(opts.name),
@@ -5242,10 +5242,10 @@ pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 {
     return index;
 }
 
-pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 {
+pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 {
     for (self.shdrs.items, 0..) |*shdr, i| {
         const this_name = self.getShString(shdr.sh_name);
-        if (mem.eql(u8, this_name, name)) return @as(u16, @intCast(i));
+        if (mem.eql(u8, this_name, name)) return @intCast(i);
     } else return null;
 }