in maxas/MaxAs/Cubin.pm [558:635]
sub updateSize
{
my ($cubin, $sec, $newSize, $updatePrgSize) = @_;
my $elfHdr = $cubin->{elfHdr};
my $class = $elfHdr->{fileClass};
# update section header
my $delta = $newSize - $sec->{size};
$sec->{size} = $newSize;
# update symtab section
if ($sec->{SymbolEnt})
{
$sec->{SymbolEnt}{size} = $newSize;
my $symSection = $cubin->{'.symtab'};
$symSection->{Data} = '';
foreach my $symEnt (@{$symSection->{SymTab}})
{
$symSection->{Data} .= unpack "H*", pack $symHdrT[$class], @{$symEnt}{@{$symHdrC[$class]}};
}
}
my $pos = $elfHdr->{ehSize};
my %sizeMap;
# update section header offsets
foreach my $secHdr (@{$cubin->{secHdrs}})
{
# skip first header
next if $secHdr->{align} == 0;
# NOBITS data sections are size 0
my $size = $secHdr->{type} == 8 ? 0 : $secHdr->{size};
# Add any needed padding between sections
my $pad = $pos % $secHdr->{align};
if ($pad > 0)
{
$pos += $secHdr->{align} - $pad;
}
# map old offset to new
$sizeMap{$secHdr->{offset}} = $pos;
# update offset
$secHdr->{offset} = $pos;
# advance position by size
$pos += $size;
}
# compute total section header size
my $shSize = $elfHdr->{phOffset} - $elfHdr->{shOffset};
# map old offset to new
$sizeMap{$elfHdr->{shOffset}} = $pos;
$sizeMap{$elfHdr->{phOffset}} = $pos + $shSize;
$elfHdr->{shOffset} = $pos;
$elfHdr->{phOffset} = $pos + $shSize;
# update program header offsets and sizes
foreach my $prgHdr (@{$cubin->{prgHdrs}})
{
# Not sure how best to adjust these so just assume they'll track other offsets.
$prgHdr->{offset} = $sizeMap{$prgHdr->{offset}};
# If the kernel sizes changes, also update the associated ProgramHeader.
# Note that this size is the kernel size plus any constant section sizes.
if ($updatePrgSize && $prgHdr->{type} == 1 &&
$sec->{offset} >= $prgHdr->{offset} &&
$sec->{offset} < $prgHdr->{offset} + $prgHdr->{fileSize} + $delta)
{
$prgHdr->{fileSize} += $delta;
$prgHdr->{memSize} += $delta;
}
}
}