mirror of
https://github.com/ziglang/zig.git
synced 2026-01-29 18:55:29 +00:00
elf: fix overflowing designated capacity when writing COMDAT groups
This commit is contained in:
parent
6e797d8648
commit
08882234d1
@ -4797,7 +4797,11 @@ fn writeAtomsObject(self: *Elf) !void {
|
||||
return error.Overflow;
|
||||
const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow;
|
||||
|
||||
log.debug("writing atom({d}) at 0x{x}", .{ atom_index, sh_offset + offset });
|
||||
log.debug("writing atom({d}) from 0x{x} to 0x{x}", .{
|
||||
atom_index,
|
||||
sh_offset + offset,
|
||||
sh_offset + offset + size,
|
||||
});
|
||||
|
||||
// TODO decompress directly into provided buffer
|
||||
const out_code = buffer[offset..][0..size];
|
||||
@ -5048,6 +5052,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
if (!atom_ptr.flags.alive) continue;
|
||||
try atom_ptr.writeRelocs(self, &relocs);
|
||||
}
|
||||
assert(relocs.items.len == num_relocs);
|
||||
|
||||
const SortRelocs = struct {
|
||||
pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool {
|
||||
@ -5058,6 +5063,12 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
|
||||
mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan);
|
||||
|
||||
log.debug("writing {s} from 0x{x} to 0x{x}", .{
|
||||
self.getShString(shdr.sh_name),
|
||||
shdr.sh_offset,
|
||||
shdr.sh_offset + shdr.sh_size,
|
||||
});
|
||||
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
|
||||
}
|
||||
|
||||
@ -5067,6 +5078,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try eh_frame.writeEhFrameObject(self, buffer.writer());
|
||||
log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{
|
||||
shdr.sh_offset,
|
||||
shdr.sh_offset + shdr.sh_size,
|
||||
});
|
||||
assert(buffer.items.len == sh_size);
|
||||
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
if (self.eh_frame_rela_section_index) |shndx| {
|
||||
@ -5075,6 +5091,11 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try eh_frame.writeEhFrameRelocs(self, buffer.writer());
|
||||
assert(buffer.items.len == sh_size);
|
||||
log.debug("writing .rela.eh_frame from 0x{x} to 0x{x}", .{
|
||||
shdr.sh_offset,
|
||||
shdr.sh_offset + shdr.sh_size,
|
||||
});
|
||||
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
|
||||
@ -5091,6 +5112,11 @@ fn writeComdatGroups(self: *Elf) !void {
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try cgs.write(self, buffer.writer());
|
||||
assert(buffer.items.len == sh_size);
|
||||
log.debug("writing COMDAT group from 0x{x} to 0x{x}", .{
|
||||
shdr.sh_offset,
|
||||
shdr.sh_offset + shdr.sh_size,
|
||||
});
|
||||
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
}
|
||||
@ -5098,6 +5124,7 @@ fn writeComdatGroups(self: *Elf) !void {
|
||||
fn writeShStrtab(self: *Elf) !void {
|
||||
if (self.shstrtab_section_index) |index| {
|
||||
const shdr = self.shdrs.items[index];
|
||||
log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size });
|
||||
try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset);
|
||||
}
|
||||
}
|
||||
@ -5112,7 +5139,15 @@ fn writeSymtab(self: *Elf) !void {
|
||||
};
|
||||
const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow;
|
||||
|
||||
log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset });
|
||||
log.debug("writing {d} symbols in .symtab from 0x{x} to 0x{x}", .{
|
||||
nsyms,
|
||||
symtab_shdr.sh_offset,
|
||||
symtab_shdr.sh_offset + symtab_shdr.sh_size,
|
||||
});
|
||||
log.debug("writing .strtab from 0x{x} to 0x{x}", .{
|
||||
strtab_shdr.sh_offset,
|
||||
strtab_shdr.sh_offset + strtab_shdr.sh_size,
|
||||
});
|
||||
|
||||
try self.symtab.resize(gpa, nsyms);
|
||||
const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
|
||||
@ -5185,55 +5220,6 @@ fn writeSymtab(self: *Elf) !void {
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
|
||||
}
|
||||
|
||||
fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
|
||||
const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
|
||||
const sym_size: u64 = switch (self.ptr_width) {
|
||||
.p32 => @sizeOf(elf.Elf32_Sym),
|
||||
.p64 => @sizeOf(elf.Elf64_Sym),
|
||||
};
|
||||
const nsyms = math.cast(usize, @divExact(symtab_shdr.sh_size, sym_size)) orelse return error.Overflow;
|
||||
|
||||
log.debug("writing {d} symbols at 0x{x}", .{ nsyms, symtab_shdr.sh_offset });
|
||||
|
||||
try self.symtab.resize(gpa, nsyms);
|
||||
const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
|
||||
try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
|
||||
|
||||
self.writeSectionSymbols();
|
||||
zig_object.asFile().writeSymtab(self);
|
||||
|
||||
const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
|
||||
switch (self.ptr_width) {
|
||||
.p32 => {
|
||||
const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len);
|
||||
defer gpa.free(buf);
|
||||
|
||||
for (buf, self.symtab.items) |*out, sym| {
|
||||
out.* = .{
|
||||
.st_name = sym.st_name,
|
||||
.st_info = sym.st_info,
|
||||
.st_other = sym.st_other,
|
||||
.st_shndx = sym.st_shndx,
|
||||
.st_value = @as(u32, @intCast(sym.st_value)),
|
||||
.st_size = @as(u32, @intCast(sym.st_size)),
|
||||
};
|
||||
if (foreign_endian) mem.byteSwapAllFields(elf.Elf32_Sym, out);
|
||||
}
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), symtab_shdr.sh_offset);
|
||||
},
|
||||
.p64 => {
|
||||
if (foreign_endian) {
|
||||
for (self.symtab.items) |*sym| mem.byteSwapAllFields(elf.Elf64_Sym, sym);
|
||||
}
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), symtab_shdr.sh_offset);
|
||||
},
|
||||
}
|
||||
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
|
||||
}
|
||||
|
||||
fn writeSectionSymbols(self: *Elf) void {
|
||||
var ilocal: u32 = 1;
|
||||
for (self.output_sections.keys()) |shndx| {
|
||||
|
||||
@ -1527,7 +1527,7 @@ pub const ComdatGroupSection = struct {
|
||||
const cg = elf_file.comdatGroup(cgs.cg_index);
|
||||
const object = cgs.file(elf_file).?.object;
|
||||
const members = object.comdatGroupMembers(cg.shndx);
|
||||
try writeInt(@as(u32, elf.GRP_COMDAT), elf_file, writer);
|
||||
try writer.writeInt(u32, elf.GRP_COMDAT, .little);
|
||||
for (members) |shndx| {
|
||||
const shdr = object.shdrs.items[shndx];
|
||||
switch (shdr.sh_type) {
|
||||
@ -1535,12 +1535,12 @@ pub const ComdatGroupSection = struct {
|
||||
const atom_index = object.atoms.items[shdr.sh_info];
|
||||
const atom = elf_file.atom(atom_index).?;
|
||||
const rela = elf_file.output_rela_sections.get(atom.outputShndx().?).?;
|
||||
try writeInt(rela.shndx, elf_file, writer);
|
||||
try writer.writeInt(u32, rela.shndx, .little);
|
||||
},
|
||||
else => {
|
||||
const atom_index = object.atoms.items[shndx];
|
||||
const atom = elf_file.atom(atom_index).?;
|
||||
try writeInt(atom.outputShndx().?, elf_file, writer);
|
||||
try writer.writeInt(u32, atom.outputShndx().?, .little);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user