Единственный способ, которым я смог заставить это работать, это изменить сам файл ядра, чтобы иметь дополнительный заголовок/раздел программы, содержащий новые данные.
В теории я считаю, что objcopy должен быть в состоянии сделать это, но после многих испытаний мне не удалось заставить его работать. Вместо этого я приступил к написанию скрипта perl, который изменил основной файл.
Вот сценарий для тех из вас застрял в подобной ситуации (обратите внимание, что это для основных файлов ELF на i386 арку):
#!/usr/bin/perl
my @elfHeader = (
[ident => 'A16'],
[e_type => 'v'],
[e_machine => 'v'],
[e_version => 'V'],
[e_entry => 'V'],
[e_phoff => 'V'],
[e_shoff => 'V'],
[e_flags => 'V'],
[e_ehsize => 'v'],
[e_phentsize => 'v'],
[e_phnum => 'v'],
[e_shentsize => 'v'],
[e_shnum => 'v'],
[e_shstrndx => 'v']
);
my @progHeader = (
[ptype => 'V'],
[poffset => 'V'],
[pvaddr => 'V'],
[ppaddr => 'V'],
[pfilesz => 'V'],
[pmemsz => 'V'],
[pflags => 'V'],
[palign => 'V'],
);
my ($core, $dataFile, $outFile) = @ARGV;
main();
sub main {
my @stat = stat($core);
my $coreSize = $stat[7];
@stat = stat($dataFile);
my $dfSize = $stat[7];
my ($in, $out, $df);
open($in, "", $outFile) || die("Couldn't open $outFile: $!");
my $buf;
my $bytes = sysread($in, $buf, 52);
my $hdr = unpackStruct(\@elfHeader, $buf);
# Fix the elf header to have an additional program header
my $phNum = $hdr->{e_phnum};
$hdr->{e_phnum}++;
# Fix the header to point to a new location for the program headers (at the end of the file)
my $phOff = $hdr->{e_phoff};
$hdr->{e_phoff} = $coreSize;
# Read in the full program header table
my $phTable;
sysseek($in, $phOff, 0);
my $readSize = $hdr->{e_phentsize} * $phNum;
$bytes = sysread($in, $phTable, $readSize);
# Add an additional entry to the end of the ph table
my $entry = packStruct(\@progHeader, {ptype => 1,
poffset => $coreSize + $hdr->{e_phentsize} * $hdr->{e_phnum},
pvaddr => 0x80f95000,
ppaddr => 0,
pfilesz => $dfSize,
pmemsz => $dfSize,
pflags => 7,
palign => 4096});
$phTable .= $entry;
# Form the new elf header
my $elf = packStruct(\@elfHeader, $hdr);
# Output the new header
syswrite($out, $elf, length($elf));
# Copy the full core file after the header
sysseek($in, 52, 0);
copyData($in, $out, $coreSize - 52);
# Output the new program table
syswrite($out, $phTable, length($phTable));
# Add the data on the end
copyData($df, $out, $dfSize);
}
sub copyData {
my ($in, $out, $numBytes) = @_;
my $buf;
while ($numBytes > 0) {
my $readBytes = sysread($in, $buf, 8192);
syswrite($out, $buf, $readBytes);
$numBytes -= $readBytes;
}
}
sub unpackStruct {
my ($fields, $data) = @_;
my $unpack;
map {$unpack .= $_->[1]} @{$fields};
my @vals = unpack($unpack, $data);
my %res;
foreach my $field (@{$fields}) {
$res{$field->[0]} = shift(@vals);
}
return \%res;
}
sub packStruct {
my ($fields, $data) = @_;
my $pack;
map {$pack .= $_->[1]} @{$fields};
my @vals;
foreach my $field (@{$fields}) {
push(@vals, $data->{$field->[0]})
}
my $res = pack($pack, @vals);
return $res;
}
Извините, если я не был ясен: я просто используя файл ядра, но система не была установка, чтобы сохранить mmapped части памяти. Эта память mmapped, потому что это большой кусок физически отображенной непрерывной ОЗУ. После сбоя эта часть ОЗУ была сохранена в файле. Я хочу загрузить этот файл в GDB, чтобы мне не пришлось вручную сопоставлять эти данные с datastructures. objcopy для увеличения основного файла выглядит многообещающим, но я еще не получил его на работу. – efunneko