Commit 6910a50ae5

Jakub Konka <kubkon@jakubkonka.com>
2023-09-13 00:31:41
elf: add u64 to usize casts where required
1 parent 1a6d12e
Changed files (4)
src/link/Elf/Atom.zig
@@ -51,7 +51,7 @@ pub fn inputShdr(self: Atom, elf_file: *Elf) elf.Elf64_Shdr {
     return object.shdrs.items[self.input_section_index];
 }
 
-pub fn codeInObject(self: Atom, elf_file: *Elf) []const u8 {
+pub fn codeInObject(self: Atom, elf_file: *Elf) error{Overflow}![]const u8 {
     const object = elf_file.file(self.file_index).?.object;
     return object.shdrContents(self.input_section_index);
 }
@@ -60,7 +60,7 @@ pub fn codeInObject(self: Atom, elf_file: *Elf) []const u8 {
 /// Caller owns the memory.
 pub fn codeInObjectUncompressAlloc(self: Atom, elf_file: *Elf) ![]u8 {
     const gpa = elf_file.base.allocator;
-    const data = self.codeInObject(elf_file);
+    const data = try self.codeInObject(elf_file);
     const shdr = self.inputShdr(elf_file);
     if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) {
         const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
@@ -70,7 +70,8 @@ pub fn codeInObjectUncompressAlloc(self: Atom, elf_file: *Elf) ![]u8 {
                 var zlib_stream = std.compress.zlib.decompressStream(gpa, stream.reader()) catch
                     return error.InputOutput;
                 defer zlib_stream.deinit();
-                const decomp = try gpa.alloc(u8, chdr.ch_size);
+                const size = std.math.cast(usize, chdr.ch_size) orelse return error.Overflow;
+                const decomp = try gpa.alloc(u8, size);
                 const nread = zlib_stream.reader().readAll(decomp) catch return error.InputOutput;
                 if (nread != decomp.len) {
                     return error.InputOutput;
@@ -288,7 +289,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
     self.* = .{};
 }
 
-pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
+pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
     return switch (elf_file.file(self.file_index).?) {
         .zig_module => |x| x.relocs.items[self.relocs_section_index].items,
         .object => |x| x.getRelocs(self.relocs_section_index),
@@ -314,7 +315,7 @@ pub fn freeRelocs(self: Atom, elf_file: *Elf) void {
 
 pub fn scanRelocs(self: Atom, elf_file: *Elf, undefs: anytype) !void {
     const file_ptr = elf_file.file(self.file_index).?;
-    const rels = self.relocs(elf_file);
+    const rels = try self.relocs(elf_file);
     var i: usize = 0;
     while (i < rels.len) : (i += 1) {
         const rel = rels[i];
@@ -407,7 +408,7 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void {
     var stream = std.io.fixedBufferStream(code);
     const cwriter = stream.writer();
 
-    for (self.relocs(elf_file)) |rel| {
+    for (try self.relocs(elf_file)) |rel| {
         const r_type = rel.r_type();
         if (r_type == elf.R_X86_64_NONE) continue;
 
src/link/Elf/eh_frame.zig
@@ -20,9 +20,9 @@ pub const Fde = struct {
         return base + fde.out_offset;
     }
 
-    pub fn data(fde: Fde, elf_file: *Elf) []const u8 {
+    pub fn data(fde: Fde, elf_file: *Elf) error{Overflow}![]const u8 {
         const object = elf_file.file(fde.file_index).?.object;
-        const contents = object.shdrContents(fde.input_section_index);
+        const contents = try object.shdrContents(fde.input_section_index);
         return contents[fde.offset..][0..fde.calcSize()];
     }
 
@@ -39,17 +39,17 @@ pub const Fde = struct {
         return fde.size + 4;
     }
 
-    pub fn atom(fde: Fde, elf_file: *Elf) *Atom {
+    pub fn atom(fde: Fde, elf_file: *Elf) error{Overflow}!*Atom {
         const object = elf_file.file(fde.file_index).?.object;
-        const rel = fde.relocs(elf_file)[0];
+        const rel = (try fde.relocs(elf_file))[0];
         const sym = object.symtab[rel.r_sym()];
         const atom_index = object.atoms.items[sym.st_shndx];
         return elf_file.atom(atom_index).?;
     }
 
-    pub fn relocs(fde: Fde, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
+    pub fn relocs(fde: Fde, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
         const object = elf_file.file(fde.file_index).?.object;
-        return object.getRelocs(fde.rel_section_index)[fde.rel_index..][0..fde.rel_num];
+        return (try object.getRelocs(fde.rel_section_index))[fde.rel_index..][0..fde.rel_num];
     }
 
     pub fn format(
@@ -88,11 +88,15 @@ pub const Fde = struct {
         const fde = ctx.fde;
         const elf_file = ctx.elf_file;
         const base_addr = fde.address(elf_file);
+        const atom_name = if (fde.atom(elf_file)) |atom_ptr|
+            atom_ptr.name(elf_file)
+        else |_|
+            "";
         try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{
             base_addr + fde.out_offset,
             fde.calcSize(),
             fde.cie_index,
-            fde.atom(elf_file).name(elf_file),
+            atom_name,
         });
         if (!fde.alive) try writer.writeAll(" : [*]");
     }
@@ -119,9 +123,9 @@ pub const Cie = struct {
         return base + cie.out_offset;
     }
 
-    pub fn data(cie: Cie, elf_file: *Elf) []const u8 {
+    pub fn data(cie: Cie, elf_file: *Elf) error{Overflow}![]const u8 {
         const object = elf_file.file(cie.file_index).?.object;
-        const contents = object.shdrContents(cie.input_section_index);
+        const contents = try object.shdrContents(cie.input_section_index);
         return contents[cie.offset..][0..cie.calcSize()];
     }
 
@@ -129,16 +133,16 @@ pub const Cie = struct {
         return cie.size + 4;
     }
 
-    pub fn relocs(cie: Cie, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
+    pub fn relocs(cie: Cie, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
         const object = elf_file.file(cie.file_index).?.object;
-        return object.getRelocs(cie.rel_section_index)[cie.rel_index..][0..cie.rel_num];
+        return (try object.getRelocs(cie.rel_section_index))[cie.rel_index..][0..cie.rel_num];
     }
 
-    pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) bool {
-        if (!std.mem.eql(u8, cie.data(elf_file), other.data(elf_file))) return false;
+    pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) error{Overflow}!bool {
+        if (!std.mem.eql(u8, try cie.data(elf_file), try other.data(elf_file))) return false;
 
-        const cie_relocs = cie.relocs(elf_file);
-        const other_relocs = other.relocs(elf_file);
+        const cie_relocs = try cie.relocs(elf_file);
+        const other_relocs = try other.relocs(elf_file);
         if (cie_relocs.len != other_relocs.len) return false;
 
         for (cie_relocs, other_relocs) |cie_rel, other_rel| {
@@ -315,10 +319,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
         for (object.cies.items) |cie| {
             if (!cie.alive) continue;
 
-            const contents = try gpa.dupe(u8, cie.data(elf_file));
+            const contents = try gpa.dupe(u8, try cie.data(elf_file));
             defer gpa.free(contents);
 
-            for (cie.relocs(elf_file)) |rel| {
+            for (try cie.relocs(elf_file)) |rel| {
                 const sym = object.symbol(rel.r_sym(), elf_file);
                 try resolveReloc(cie, sym, rel, elf_file, contents);
             }
@@ -333,7 +337,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
         for (object.fdes.items) |fde| {
             if (!fde.alive) continue;
 
-            const contents = try gpa.dupe(u8, fde.data(elf_file));
+            const contents = try gpa.dupe(u8, try fde.data(elf_file));
             defer gpa.free(contents);
 
             std.mem.writeIntLittle(
@@ -342,7 +346,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
                 @as(i32, @truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset)))),
             );
 
-            for (fde.relocs(elf_file)) |rel| {
+            for (try fde.relocs(elf_file)) |rel| {
                 const sym = object.symbol(rel.r_sym(), elf_file);
                 try resolveReloc(fde, sym, rel, elf_file, contents);
             }
@@ -391,7 +395,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
         for (object.fdes.items) |fde| {
             if (!fde.alive) continue;
 
-            const relocs = fde.relocs(elf_file);
+            const relocs = try fde.relocs(elf_file);
             assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips...
             const rel = relocs[0];
             const sym = object.symbol(rel.r_sym(), elf_file);
src/link/Elf/Object.zig
@@ -54,12 +54,13 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
 
     const gpa = elf_file.base.allocator;
 
+    const shoff = math.cast(usize, self.header.?.e_shoff) orelse return error.Overflow;
     const shdrs = @as(
         [*]align(1) const elf.Elf64_Shdr,
-        @ptrCast(self.data.ptr + self.header.?.e_shoff),
+        @ptrCast(self.data.ptr + shoff),
     )[0..self.header.?.e_shnum];
     try self.shdrs.appendUnalignedSlice(gpa, shdrs);
-    try self.strings.buffer.appendSlice(gpa, self.shdrContents(self.header.?.e_shstrndx));
+    try self.strings.buffer.appendSlice(gpa, try self.shdrContents(self.header.?.e_shstrndx));
 
     const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {
         elf.SHT_SYMTAB => break @as(u16, @intCast(i)),
@@ -70,10 +71,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
         const shdr = shdrs[index];
         self.first_global = shdr.sh_info;
 
-        const symtab = self.shdrContents(index);
+        const symtab = try self.shdrContents(index);
         const nsyms = @divExact(symtab.len, @sizeOf(elf.Elf64_Sym));
         self.symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(symtab.ptr))[0..nsyms];
-        self.strtab = self.shdrContents(@as(u16, @intCast(shdr.sh_link)));
+        self.strtab = try self.shdrContents(@as(u16, @intCast(shdr.sh_link)));
     }
 
     try self.initAtoms(elf_file);
@@ -114,7 +115,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
                 };
 
                 const shndx = @as(u16, @intCast(i));
-                const group_raw_data = self.shdrContents(shndx);
+                const group_raw_data = try self.shdrContents(shndx);
                 const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32));
                 const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
 
@@ -177,7 +178,7 @@ fn addAtom(self: *Object, shdr: elf.Elf64_Shdr, shndx: u16, name: [:0]const u8,
     self.atoms.items[shndx] = atom_index;
 
     if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) {
-        const data = self.shdrContents(shndx);
+        const data = try self.shdrContents(shndx);
         const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
         atom.size = chdr.ch_size;
         atom.alignment = math.log2_int(u64, chdr.ch_addralign);
@@ -294,8 +295,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void {
     };
 
     const gpa = elf_file.base.allocator;
-    const raw = self.shdrContents(shndx);
-    const relocs = self.getRelocs(relocs_shndx);
+    const raw = try self.shdrContents(shndx);
+    const relocs = try self.getRelocs(relocs_shndx);
     const fdes_start = self.fdes.items.len;
     const cies_start = self.cies.items.len;
 
@@ -403,7 +404,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
     }
 
     for (self.cies.items) |cie| {
-        for (cie.relocs(elf_file)) |rel| {
+        for (try cie.relocs(elf_file)) |rel| {
             const sym = elf_file.symbol(self.symbols.items[rel.r_sym()]);
             if (sym.flags.import) {
                 if (sym.type(elf_file) != elf.STT_FUNC)
@@ -656,10 +657,12 @@ pub fn globals(self: *Object) []const Symbol.Index {
     return self.symbols.items[start..];
 }
 
-pub fn shdrContents(self: *Object, index: u32) []const u8 {
+pub fn shdrContents(self: *Object, index: u32) error{Overflow}![]const u8 {
     assert(index < self.shdrs.items.len);
     const shdr = self.shdrs.items[index];
-    return self.data[shdr.sh_offset..][0..shdr.sh_size];
+    const offset = math.cast(usize, shdr.sh_offset) orelse return error.Overflow;
+    const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
+    return self.data[offset..][0..size];
 }
 
 fn getString(self: *Object, off: u32) [:0]const u8 {
@@ -667,8 +670,8 @@ fn getString(self: *Object, off: u32) [:0]const u8 {
     return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0);
 }
 
-pub fn comdatGroupMembers(self: *Object, index: u16) []align(1) const u32 {
-    const raw = self.shdrContents(index);
+pub fn comdatGroupMembers(self: *Object, index: u16) error{Overflow}![]align(1) const u32 {
+    const raw = try self.shdrContents(index);
     const nmembers = @divExact(raw.len, @sizeOf(u32));
     const members = @as([*]align(1) const u32, @ptrCast(raw.ptr))[1..nmembers];
     return members;
@@ -678,8 +681,8 @@ pub fn asFile(self: *Object) File {
     return .{ .object = self };
 }
 
-pub fn getRelocs(self: *Object, shndx: u32) []align(1) const elf.Elf64_Rela {
-    const raw = self.shdrContents(shndx);
+pub fn getRelocs(self: *Object, shndx: u32) error{Overflow}![]align(1) const elf.Elf64_Rela {
+    const raw = try self.shdrContents(shndx);
     const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela));
     return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num];
 }
@@ -819,7 +822,8 @@ fn formatComdatGroups(
         const cg = elf_file.comdatGroup(cg_index);
         const cg_owner = elf_file.comdatGroupOwner(cg.owner);
         if (cg_owner.file != object.index) continue;
-        for (object.comdatGroupMembers(cg.shndx)) |shndx| {
+        const cg_members = object.comdatGroupMembers(cg.shndx) catch continue;
+        for (cg_members) |shndx| {
             const atom_index = object.atoms.items[shndx];
             const atom = elf_file.atom(atom_index) orelse continue;
             try writer.print("    atom({d}) : {s}\n", .{ atom_index, atom.name(elf_file) });
src/link/Elf.zig
@@ -1088,7 +1088,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
             if (!atom_ptr.alive) continue;
             const shdr = &self.shdrs.items[atom_ptr.output_section_index];
             const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;
-            const code = try gpa.alloc(u8, atom_ptr.size);
+            const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow;
+            const code = try gpa.alloc(u8, size);
             defer gpa.free(code);
             const amt = try self.base.file.?.preadAll(code, file_offset);
             if (amt != code.len) return error.InputOutput;
@@ -3145,7 +3146,7 @@ fn writeSymtab(self: *Elf) !void {
         .p32 => @sizeOf(elf.Elf32_Sym),
         .p64 => @sizeOf(elf.Elf64_Sym),
     };
-    const nsyms = @divExact(shdr.sh_size, sym_size);
+    const nsyms = math.cast(usize, @divExact(shdr.sh_size, sym_size)) orelse return error.Overflow;
 
     log.debug("writing {d} symbols at 0x{x}", .{ nsyms, shdr.sh_offset });