mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Merge pull request #16788 from xxxbxxx/objcopy-step
build/ObjCopy: strip debug info to a separate elf file
This commit is contained in:
parent
2d4e24dd6b
commit
1b88ce3b0c
2 changed files with 78 additions and 25 deletions
|
|
@ -17,22 +17,40 @@ pub const base_id: Step.Id = .objcopy;
|
||||||
pub const RawFormat = enum {
|
pub const RawFormat = enum {
|
||||||
bin,
|
bin,
|
||||||
hex,
|
hex,
|
||||||
|
elf,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Strip = enum {
|
||||||
|
none,
|
||||||
|
debug,
|
||||||
|
debug_and_symbols,
|
||||||
};
|
};
|
||||||
|
|
||||||
step: Step,
|
step: Step,
|
||||||
input_file: std.Build.LazyPath,
|
input_file: std.Build.LazyPath,
|
||||||
basename: []const u8,
|
basename: []const u8,
|
||||||
output_file: std.Build.GeneratedFile,
|
output_file: std.Build.GeneratedFile,
|
||||||
|
output_file_debug: ?std.Build.GeneratedFile,
|
||||||
|
|
||||||
format: ?RawFormat,
|
format: ?RawFormat,
|
||||||
only_section: ?[]const u8,
|
only_section: ?[]const u8,
|
||||||
pad_to: ?u64,
|
pad_to: ?u64,
|
||||||
|
strip: Strip,
|
||||||
|
compress_debug: bool,
|
||||||
|
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
basename: ?[]const u8 = null,
|
basename: ?[]const u8 = null,
|
||||||
format: ?RawFormat = null,
|
format: ?RawFormat = null,
|
||||||
only_section: ?[]const u8 = null,
|
only_section: ?[]const u8 = null,
|
||||||
pad_to: ?u64 = null,
|
pad_to: ?u64 = null,
|
||||||
|
|
||||||
|
compress_debug: bool = false,
|
||||||
|
strip: Strip = .none,
|
||||||
|
|
||||||
|
/// Put the stripped out debug sections in a separate file.
|
||||||
|
/// note: the `basename` is baked into the elf file to specify the link to the separate debug file.
|
||||||
|
/// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
|
||||||
|
extract_to_separate_file: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(
|
pub fn create(
|
||||||
|
|
@ -51,10 +69,12 @@ pub fn create(
|
||||||
.input_file = input_file,
|
.input_file = input_file,
|
||||||
.basename = options.basename orelse input_file.getDisplayName(),
|
.basename = options.basename orelse input_file.getDisplayName(),
|
||||||
.output_file = std.Build.GeneratedFile{ .step = &self.step },
|
.output_file = std.Build.GeneratedFile{ .step = &self.step },
|
||||||
|
.output_file_debug = if (options.strip != .none and options.extract_to_separate_file) std.Build.GeneratedFile{ .step = &self.step } else null,
|
||||||
.format = options.format,
|
.format = options.format,
|
||||||
.only_section = options.only_section,
|
.only_section = options.only_section,
|
||||||
.pad_to = options.pad_to,
|
.pad_to = options.pad_to,
|
||||||
|
.strip = options.strip,
|
||||||
|
.compress_debug = options.compress_debug,
|
||||||
};
|
};
|
||||||
input_file.addStepDependencies(&self.step);
|
input_file.addStepDependencies(&self.step);
|
||||||
return self;
|
return self;
|
||||||
|
|
@ -66,6 +86,9 @@ pub const getOutputSource = getOutput;
|
||||||
pub fn getOutput(self: *const ObjCopy) std.Build.LazyPath {
|
pub fn getOutput(self: *const ObjCopy) std.Build.LazyPath {
|
||||||
return .{ .generated = &self.output_file };
|
return .{ .generated = &self.output_file };
|
||||||
}
|
}
|
||||||
|
pub fn getOutputSeparatedDebug(self: *const ObjCopy) ?std.Build.LazyPath {
|
||||||
|
return if (self.output_file_debug) |*file| .{ .generated = file } else null;
|
||||||
|
}
|
||||||
|
|
||||||
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||||
const b = step.owner;
|
const b = step.owner;
|
||||||
|
|
@ -83,6 +106,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||||
man.hash.addOptionalBytes(self.only_section);
|
man.hash.addOptionalBytes(self.only_section);
|
||||||
man.hash.addOptional(self.pad_to);
|
man.hash.addOptional(self.pad_to);
|
||||||
man.hash.addOptional(self.format);
|
man.hash.addOptional(self.format);
|
||||||
|
man.hash.add(self.compress_debug);
|
||||||
|
man.hash.add(self.strip);
|
||||||
|
man.hash.add(self.output_file_debug != null);
|
||||||
|
|
||||||
if (try step.cacheHit(&man)) {
|
if (try step.cacheHit(&man)) {
|
||||||
// Cache hit, skip subprocess execution.
|
// Cache hit, skip subprocess execution.
|
||||||
|
|
@ -90,12 +116,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||||
self.output_file.path = try b.cache_root.join(b.allocator, &.{
|
self.output_file.path = try b.cache_root.join(b.allocator, &.{
|
||||||
"o", &digest, self.basename,
|
"o", &digest, self.basename,
|
||||||
});
|
});
|
||||||
|
if (self.output_file_debug) |*file| {
|
||||||
|
file.path = try b.cache_root.join(b.allocator, &.{
|
||||||
|
"o", &digest, b.fmt("{s}.debug", .{self.basename}),
|
||||||
|
});
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const digest = man.final();
|
const digest = man.final();
|
||||||
const full_dest_path = try b.cache_root.join(b.allocator, &.{ "o", &digest, self.basename });
|
|
||||||
const cache_path = "o" ++ fs.path.sep_str ++ digest;
|
const cache_path = "o" ++ fs.path.sep_str ++ digest;
|
||||||
|
const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, self.basename });
|
||||||
|
const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{self.basename}) });
|
||||||
b.cache_root.handle.makePath(cache_path) catch |err| {
|
b.cache_root.handle.makePath(cache_path) catch |err| {
|
||||||
return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) });
|
return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) });
|
||||||
};
|
};
|
||||||
|
|
@ -106,13 +138,25 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||||
if (self.only_section) |only_section| {
|
if (self.only_section) |only_section| {
|
||||||
try argv.appendSlice(&.{ "-j", only_section });
|
try argv.appendSlice(&.{ "-j", only_section });
|
||||||
}
|
}
|
||||||
|
switch (self.strip) {
|
||||||
|
.none => {},
|
||||||
|
.debug => try argv.appendSlice(&.{"--strip-debug"}),
|
||||||
|
.debug_and_symbols => try argv.appendSlice(&.{"--strip-all"}),
|
||||||
|
}
|
||||||
if (self.pad_to) |pad_to| {
|
if (self.pad_to) |pad_to| {
|
||||||
try argv.appendSlice(&.{ "--pad-to", b.fmt("{d}", .{pad_to}) });
|
try argv.appendSlice(&.{ "--pad-to", b.fmt("{d}", .{pad_to}) });
|
||||||
}
|
}
|
||||||
if (self.format) |format| switch (format) {
|
if (self.format) |format| switch (format) {
|
||||||
.bin => try argv.appendSlice(&.{ "-O", "binary" }),
|
.bin => try argv.appendSlice(&.{ "-O", "binary" }),
|
||||||
.hex => try argv.appendSlice(&.{ "-O", "hex" }),
|
.hex => try argv.appendSlice(&.{ "-O", "hex" }),
|
||||||
|
.elf => try argv.appendSlice(&.{ "-O", "elf" }),
|
||||||
};
|
};
|
||||||
|
if (self.compress_debug) {
|
||||||
|
try argv.appendSlice(&.{"--compress-debug-sections"});
|
||||||
|
}
|
||||||
|
if (self.output_file_debug != null) {
|
||||||
|
try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})});
|
||||||
|
}
|
||||||
|
|
||||||
try argv.appendSlice(&.{ full_src_path, full_dest_path });
|
try argv.appendSlice(&.{ full_src_path, full_dest_path });
|
||||||
|
|
||||||
|
|
@ -120,5 +164,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||||
_ = try step.evalZigProcess(argv.items, prog_node);
|
_ = try step.evalZigProcess(argv.items, prog_node);
|
||||||
|
|
||||||
self.output_file.path = full_dest_path;
|
self.output_file.path = full_dest_path;
|
||||||
|
if (self.output_file_debug) |*file| file.path = full_dest_path_debug;
|
||||||
try man.writeManifest();
|
try man.writeManifest();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,6 @@ pub fn cmdObjCopy(
|
||||||
fatal("unable to open '{s}': {s}", .{ input, @errorName(err) });
|
fatal("unable to open '{s}': {s}", .{ input, @errorName(err) });
|
||||||
defer in_file.close();
|
defer in_file.close();
|
||||||
|
|
||||||
var out_file = try fs.cwd().createFile(output, .{});
|
|
||||||
defer out_file.close();
|
|
||||||
|
|
||||||
const elf_hdr = std.elf.Header.read(in_file) catch |err| switch (err) {
|
const elf_hdr = std.elf.Header.read(in_file) catch |err| switch (err) {
|
||||||
error.InvalidElfMagic => fatal("not an ELF file: '{s}'", .{input}),
|
error.InvalidElfMagic => fatal("not an ELF file: '{s}'", .{input}),
|
||||||
else => fatal("unable to read '{s}': {s}", .{ input, @errorName(err) }),
|
else => fatal("unable to read '{s}': {s}", .{ input, @errorName(err) }),
|
||||||
|
|
@ -126,6 +123,17 @@ pub fn cmdObjCopy(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mode = mode: {
|
||||||
|
if (out_fmt != .elf or !only_keep_debug)
|
||||||
|
break :mode fs.File.default_mode;
|
||||||
|
if (in_file.stat()) |stat|
|
||||||
|
break :mode stat.mode
|
||||||
|
else |_|
|
||||||
|
break :mode fs.File.default_mode;
|
||||||
|
};
|
||||||
|
var out_file = try fs.cwd().createFile(output, .{ .mode = mode });
|
||||||
|
defer out_file.close();
|
||||||
|
|
||||||
switch (out_fmt) {
|
switch (out_fmt) {
|
||||||
.hex, .raw => {
|
.hex, .raw => {
|
||||||
if (strip_debug or strip_all or only_keep_debug)
|
if (strip_debug or strip_all or only_keep_debug)
|
||||||
|
|
@ -345,7 +353,7 @@ const BinaryElfOutput = struct {
|
||||||
|
|
||||||
const shstrtab_shdr = (try section_headers.next()).?;
|
const shstrtab_shdr = (try section_headers.next()).?;
|
||||||
|
|
||||||
const buffer = try allocator.alloc(u8, @as(usize, @intCast(shstrtab_shdr.sh_size)));
|
const buffer = try allocator.alloc(u8, @intCast(shstrtab_shdr.sh_size));
|
||||||
errdefer allocator.free(buffer);
|
errdefer allocator.free(buffer);
|
||||||
|
|
||||||
const num_read = try elf_file.preadAll(buffer, shstrtab_shdr.sh_offset);
|
const num_read = try elf_file.preadAll(buffer, shstrtab_shdr.sh_offset);
|
||||||
|
|
@ -363,7 +371,7 @@ const BinaryElfOutput = struct {
|
||||||
|
|
||||||
newSection.binaryOffset = 0;
|
newSection.binaryOffset = 0;
|
||||||
newSection.elfOffset = section.sh_offset;
|
newSection.elfOffset = section.sh_offset;
|
||||||
newSection.fileSize = @as(usize, @intCast(section.sh_size));
|
newSection.fileSize = @intCast(section.sh_size);
|
||||||
newSection.segment = null;
|
newSection.segment = null;
|
||||||
|
|
||||||
newSection.name = if (self.shstrtab) |shstrtab|
|
newSection.name = if (self.shstrtab) |shstrtab|
|
||||||
|
|
@ -382,7 +390,7 @@ const BinaryElfOutput = struct {
|
||||||
|
|
||||||
newSegment.physicalAddress = if (phdr.p_paddr != 0) phdr.p_paddr else phdr.p_vaddr;
|
newSegment.physicalAddress = if (phdr.p_paddr != 0) phdr.p_paddr else phdr.p_vaddr;
|
||||||
newSegment.virtualAddress = phdr.p_vaddr;
|
newSegment.virtualAddress = phdr.p_vaddr;
|
||||||
newSegment.fileSize = @as(usize, @intCast(phdr.p_filesz));
|
newSegment.fileSize = @intCast(phdr.p_filesz);
|
||||||
newSegment.elfOffset = phdr.p_offset;
|
newSegment.elfOffset = phdr.p_offset;
|
||||||
newSegment.binaryOffset = 0;
|
newSegment.binaryOffset = 0;
|
||||||
newSegment.firstSection = null;
|
newSegment.firstSection = null;
|
||||||
|
|
@ -478,8 +486,8 @@ const HexWriter = struct {
|
||||||
const MAX_PAYLOAD_LEN: u8 = 16;
|
const MAX_PAYLOAD_LEN: u8 = 16;
|
||||||
|
|
||||||
fn addressParts(address: u16) [2]u8 {
|
fn addressParts(address: u16) [2]u8 {
|
||||||
const msb = @as(u8, @truncate(address >> 8));
|
const msb: u8 = @truncate(address >> 8);
|
||||||
const lsb = @as(u8, @truncate(address));
|
const lsb: u8 = @truncate(address);
|
||||||
return [2]u8{ msb, lsb };
|
return [2]u8{ msb, lsb };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,14 +516,14 @@ const HexWriter = struct {
|
||||||
|
|
||||||
fn Data(address: u32, data: []const u8) Record {
|
fn Data(address: u32, data: []const u8) Record {
|
||||||
return Record{
|
return Record{
|
||||||
.address = @as(u16, @intCast(address % 0x10000)),
|
.address = @intCast(address % 0x10000),
|
||||||
.payload = .{ .Data = data },
|
.payload = .{ .Data = data },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Address(address: u32) Record {
|
fn Address(address: u32) Record {
|
||||||
assert(address > 0xFFFF);
|
assert(address > 0xFFFF);
|
||||||
const segment = @as(u16, @intCast(address / 0x10000));
|
const segment: u16 = @intCast(address / 0x10000);
|
||||||
if (address > 0xFFFFF) {
|
if (address > 0xFFFFF) {
|
||||||
return Record{
|
return Record{
|
||||||
.address = 0,
|
.address = 0,
|
||||||
|
|
@ -540,7 +548,7 @@ const HexWriter = struct {
|
||||||
fn checksum(self: Record) u8 {
|
fn checksum(self: Record) u8 {
|
||||||
const payload_bytes = self.getPayloadBytes();
|
const payload_bytes = self.getPayloadBytes();
|
||||||
|
|
||||||
var sum: u8 = @as(u8, @intCast(payload_bytes.len));
|
var sum: u8 = @intCast(payload_bytes.len);
|
||||||
const parts = addressParts(self.address);
|
const parts = addressParts(self.address);
|
||||||
sum +%= parts[0];
|
sum +%= parts[0];
|
||||||
sum +%= parts[1];
|
sum +%= parts[1];
|
||||||
|
|
@ -574,10 +582,10 @@ const HexWriter = struct {
|
||||||
var buf: [MAX_PAYLOAD_LEN]u8 = undefined;
|
var buf: [MAX_PAYLOAD_LEN]u8 = undefined;
|
||||||
var bytes_read: usize = 0;
|
var bytes_read: usize = 0;
|
||||||
while (bytes_read < segment.fileSize) {
|
while (bytes_read < segment.fileSize) {
|
||||||
const row_address = @as(u32, @intCast(segment.physicalAddress + bytes_read));
|
const row_address: u32 = @intCast(segment.physicalAddress + bytes_read);
|
||||||
|
|
||||||
const remaining = segment.fileSize - bytes_read;
|
const remaining = segment.fileSize - bytes_read;
|
||||||
const to_read = @as(usize, @intCast(@min(remaining, MAX_PAYLOAD_LEN)));
|
const to_read: usize = @intCast(@min(remaining, MAX_PAYLOAD_LEN));
|
||||||
const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read);
|
const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read);
|
||||||
if (did_read < to_read) return error.UnexpectedEOF;
|
if (did_read < to_read) return error.UnexpectedEOF;
|
||||||
|
|
||||||
|
|
@ -593,7 +601,7 @@ const HexWriter = struct {
|
||||||
try Record.Address(address).write(self.out_file);
|
try Record.Address(address).write(self.out_file);
|
||||||
}
|
}
|
||||||
try record.write(self.out_file);
|
try record.write(self.out_file);
|
||||||
self.prev_addr = @as(u32, @intCast(record.address + data.len));
|
self.prev_addr = @intCast(record.address + data.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeEOF(self: HexWriter) File.WriteError!void {
|
fn writeEOF(self: HexWriter) File.WriteError!void {
|
||||||
|
|
@ -814,7 +822,7 @@ fn ElfFile(comptime is_64: bool) type {
|
||||||
const need_strings = (idx == header.shstrndx);
|
const need_strings = (idx == header.shstrndx);
|
||||||
|
|
||||||
if (need_data or need_strings) {
|
if (need_data or need_strings) {
|
||||||
const buffer = try allocator.alignedAlloc(u8, section_memory_align, @as(usize, @intCast(section.section.sh_size)));
|
const buffer = try allocator.alignedAlloc(u8, section_memory_align, @intCast(section.section.sh_size));
|
||||||
const bytes_read = try in_file.preadAll(buffer, section.section.sh_offset);
|
const bytes_read = try in_file.preadAll(buffer, section.section.sh_offset);
|
||||||
if (bytes_read != section.section.sh_size) return error.TRUNCATED_ELF;
|
if (bytes_read != section.section.sh_size) return error.TRUNCATED_ELF;
|
||||||
section.payload = buffer;
|
section.payload = buffer;
|
||||||
|
|
@ -935,7 +943,7 @@ fn ElfFile(comptime is_64: bool) type {
|
||||||
const update = §ions_update[self.raw_elf_header.e_shstrndx];
|
const update = §ions_update[self.raw_elf_header.e_shstrndx];
|
||||||
|
|
||||||
const name: []const u8 = ".gnu_debuglink";
|
const name: []const u8 = ".gnu_debuglink";
|
||||||
const new_offset = @as(u32, @intCast(strtab.payload.?.len));
|
const new_offset: u32 = @intCast(strtab.payload.?.len);
|
||||||
const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1);
|
const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1);
|
||||||
@memcpy(buf[0..new_offset], strtab.payload.?);
|
@memcpy(buf[0..new_offset], strtab.payload.?);
|
||||||
@memcpy(buf[new_offset..][0..name.len], name);
|
@memcpy(buf[new_offset..][0..name.len], name);
|
||||||
|
|
@ -965,7 +973,7 @@ fn ElfFile(comptime is_64: bool) type {
|
||||||
update.payload = payload;
|
update.payload = payload;
|
||||||
update.section = section.section;
|
update.section = section.section;
|
||||||
update.section.?.sh_addralign = @alignOf(Elf_Chdr);
|
update.section.?.sh_addralign = @alignOf(Elf_Chdr);
|
||||||
update.section.?.sh_size = @as(Elf_OffSize, @intCast(payload.len));
|
update.section.?.sh_size = @intCast(payload.len);
|
||||||
update.section.?.sh_flags |= elf.SHF_COMPRESSED;
|
update.section.?.sh_flags |= elf.SHF_COMPRESSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1032,7 +1040,7 @@ fn ElfFile(comptime is_64: bool) type {
|
||||||
dest.sh_info = sections_update[src.sh_info].remap_idx;
|
dest.sh_info = sections_update[src.sh_info].remap_idx;
|
||||||
|
|
||||||
if (payload) |data|
|
if (payload) |data|
|
||||||
dest.sh_size = @as(Elf_OffSize, @intCast(data.len));
|
dest.sh_size = @intCast(data.len);
|
||||||
|
|
||||||
const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign;
|
const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign;
|
||||||
dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign);
|
dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign);
|
||||||
|
|
@ -1110,7 +1118,7 @@ fn ElfFile(comptime is_64: bool) type {
|
||||||
.sh_flags = 0,
|
.sh_flags = 0,
|
||||||
.sh_addr = 0,
|
.sh_addr = 0,
|
||||||
.sh_offset = eof_offset,
|
.sh_offset = eof_offset,
|
||||||
.sh_size = @as(Elf_OffSize, @intCast(payload.len)),
|
.sh_size = @intCast(payload.len),
|
||||||
.sh_link = elf.SHN_UNDEF,
|
.sh_link = elf.SHN_UNDEF,
|
||||||
.sh_info = elf.SHN_UNDEF,
|
.sh_info = elf.SHN_UNDEF,
|
||||||
.sh_addralign = 4,
|
.sh_addralign = 4,
|
||||||
|
|
@ -1232,7 +1240,7 @@ const ElfFileHelper = struct {
|
||||||
fused_cmd = null;
|
fused_cmd = null;
|
||||||
}
|
}
|
||||||
if (data.out_offset > offset) {
|
if (data.out_offset > offset) {
|
||||||
consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@as(usize, @intCast(data.out_offset - offset))], .out_offset = offset } });
|
consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(data.out_offset - offset)], .out_offset = offset } });
|
||||||
}
|
}
|
||||||
consolidated.appendAssumeCapacity(cmd);
|
consolidated.appendAssumeCapacity(cmd);
|
||||||
offset = data.out_offset + data.data.len;
|
offset = data.out_offset + data.data.len;
|
||||||
|
|
@ -1249,7 +1257,7 @@ const ElfFileHelper = struct {
|
||||||
} else {
|
} else {
|
||||||
consolidated.appendAssumeCapacity(prev);
|
consolidated.appendAssumeCapacity(prev);
|
||||||
if (range.out_offset > offset) {
|
if (range.out_offset > offset) {
|
||||||
consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@as(usize, @intCast(range.out_offset - offset))], .out_offset = offset } });
|
consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(range.out_offset - offset)], .out_offset = offset } });
|
||||||
}
|
}
|
||||||
fused_cmd = cmd;
|
fused_cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
@ -1286,7 +1294,7 @@ const ElfFileHelper = struct {
|
||||||
var section_reader = std.io.limitedReader(in_file.reader(), size);
|
var section_reader = std.io.limitedReader(in_file.reader(), size);
|
||||||
|
|
||||||
// allocate as large as decompressed data. if the compression doesn't fit, keep the data uncompressed.
|
// allocate as large as decompressed data. if the compression doesn't fit, keep the data uncompressed.
|
||||||
const compressed_data = try allocator.alignedAlloc(u8, 8, @as(usize, @intCast(size)));
|
const compressed_data = try allocator.alignedAlloc(u8, 8, @intCast(size));
|
||||||
var compressed_stream = std.io.fixedBufferStream(compressed_data);
|
var compressed_stream = std.io.fixedBufferStream(compressed_data);
|
||||||
|
|
||||||
try compressed_stream.writer().writeAll(prefix);
|
try compressed_stream.writer().writeAll(prefix);
|
||||||
|
|
@ -1317,7 +1325,7 @@ const ElfFileHelper = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const compressed_len = @as(usize, @intCast(compressed_stream.getPos() catch unreachable));
|
const compressed_len: usize = @intCast(compressed_stream.getPos() catch unreachable);
|
||||||
const data = allocator.realloc(compressed_data, compressed_len) catch compressed_data;
|
const data = allocator.realloc(compressed_data, compressed_len) catch compressed_data;
|
||||||
return data[0..compressed_len];
|
return data[0..compressed_len];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue