do not edit — generated by btf.
git.druid.rocksindexdruid520kaboommk/trim-elf.pl

mk/trim-elf.pl


# truncates a linked elf64 executable right after the LAST byte any of
# its PT_LOAD segments' file data actually uses (there are two now --
# see user.ld's own comment on why -- but a bss-only
# segment contributes zero file bytes either way, so this already
# generalizes correctly without needing to special-case that),
# discarding the section header table and shstrtab entirely -- kaboom's
# elf loader (src/kernel/elf.nsc) only ever reads program headers and
# PT_LOAD segment data, so anything after that is pure overhead this
# kernel never looks at, and it's often enough to push a small
# userspace program over disk.pl's binary size cap for no reason
# (section headers + a small string table routinely add 200-400+ bytes
# to an otherwise-tiny binary).
use v5.16;
use strict;
use warnings;
 
die "usage: $0 in.elf out.elf\n" unless @ARGV == 2;
my ($in, $out) = @ARGV;
 
open(my $fh, '<:raw', $in) or die "$0: $in: $!\n";
my $data = do { local $/; <$fh>; };
close $fh;
 
my $e_phoff = unpack('Q<', substr($data, 32, 8));
my ($e_phentsize, $e_phnum) = unpack('v2', substr($data, 54, 4));
 
my $end = 0;
for my $i (0 .. $e_phnum - 1) {
	my $off = $e_phoff + $i * $e_phentsize;
	my $p_type = unpack('L<', substr($data, $off, 4));
	next unless $p_type == 1;  # PT_LOAD
	my $p_offset = unpack('Q<', substr($data, $off + 8, 8));
	my $p_filesz = unpack('Q<', substr($data, $off + 32, 8));
	my $seg_end = $p_offset + $p_filesz;
	$end = $seg_end if $seg_end > $end;
}
 
die "$0: $in: no PT_LOAD segment found\n" if $end == 0;
 
open(my $ofh, '>:raw', $out) or die "$0: $out: $!\n";
print $ofh substr($data, 0, $end);
close $ofh;
 
printf "%s: %d -> %d bytes\n", $in, length($data), $end;
powered by btf.