2005-08-08 10:27:43 +08:00
|
|
|
#!/usr/bin/perl
|
2007-11-08 20:06:32 +08:00
|
|
|
# Copyright 2006, 2007 Red Hat, Inc.
|
2006-03-02 04:20:22 +08:00
|
|
|
#
|
|
|
|
# This file is part of Cygwin.
|
|
|
|
#
|
|
|
|
# This software is a copyrighted work licensed under the terms of the
|
|
|
|
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
# details.
|
|
|
|
#
|
2005-08-08 10:27:43 +08:00
|
|
|
use integer;
|
|
|
|
use strict;
|
|
|
|
sub xit($@);
|
|
|
|
my $strip = $ARGV[0] eq '-s';
|
|
|
|
shift if $strip;
|
|
|
|
my $objdump = shift;
|
|
|
|
my @objcopy = ((shift));
|
|
|
|
my $dll = shift;
|
|
|
|
my $dbg = shift;
|
2007-11-08 22:36:49 +08:00
|
|
|
xit 0, @objcopy, '-R', '.gnu_debuglink_overlay', '--only-keep-debug', $dll, $dbg;
|
2005-08-08 10:27:43 +08:00
|
|
|
xit 0, @objcopy, '-g', '--add-gnu-debuglink=' . $dbg, $dll;
|
|
|
|
open(OBJDUMP, '-|', "$objdump --headers $dll");
|
|
|
|
my %section;
|
|
|
|
while (<OBJDUMP>) {
|
|
|
|
my ($idx, $name, $size, $vma, $lma, $fileoff, $algn) = /^\s*(\d+)\s+(\.\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/;
|
|
|
|
if ($name eq '.gnu_debuglink') {
|
|
|
|
push(@objcopy, '--set-section-flag', '.gnu_debuglink=contents,readonly,debug,noload');
|
2006-07-15 03:33:55 +08:00
|
|
|
$idx = $section{'.gnu_debuglink'}{-idx} if defined($section{'.gnu_debuglink'}{-idx});
|
2005-08-08 10:27:43 +08:00
|
|
|
} elsif ($name eq '.gnu_debuglink_overlay') {
|
|
|
|
push (@objcopy, '-R', '.gnu_debuglink_overlay');
|
2006-07-15 03:33:55 +08:00
|
|
|
$section{'.gnu_debuglink'}{-idx} = $idx;
|
2005-08-08 10:27:43 +08:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
defined($idx) and
|
|
|
|
$section{$name} = {-idx=>int($idx), -size=>hex($size), -vma=>hex($vma), -lma=>hex($lma), -fileoff=>hex($fileoff),
|
|
|
|
-algn=>0x00001000};
|
|
|
|
}
|
|
|
|
close OBJDUMP;
|
|
|
|
my $vma;
|
|
|
|
for my $k (sort {$section{$a}{-idx} <=> $section{$b}{-idx}} keys %section) {
|
|
|
|
if ($strip && $k =~ /\.(?:stab|debug)/o) {
|
|
|
|
push(@objcopy, '-R', $k);
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
if (!defined($vma)) {
|
|
|
|
$vma = $section{$k}{-vma};
|
|
|
|
}
|
|
|
|
if ($vma != $section{$k}{-vma}) {
|
|
|
|
my $newvma = align($vma, $section{$k}{-algn});
|
|
|
|
if ($newvma != $vma) {
|
|
|
|
printf STDERR "$0: ERROR $k VMA 0x%08x != 0x%08x\n", $vma, $newvma;
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
push(@objcopy, '--change-section-address', sprintf "$k=0x%08x", $vma);
|
|
|
|
}
|
|
|
|
$vma = align($vma + $section{$k}{-size}, $section{$k}{-algn});
|
|
|
|
}
|
2006-07-15 03:33:55 +08:00
|
|
|
|
2005-08-08 10:27:43 +08:00
|
|
|
warn "$0: ERROR final VMA (" . sprintf("0x%08x", $vma) . ") not on 64K boundary\n" if $vma != align($vma, 64 * 1024);
|
|
|
|
push(@objcopy, $dll, @ARGV);
|
|
|
|
xit 1, @objcopy;
|
|
|
|
sub align {
|
|
|
|
my $n = $_[0];
|
|
|
|
my $align = $_[1] - 1;
|
|
|
|
return ($n + $align) & ~$align;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub xit($@) {
|
|
|
|
my $execit = shift;
|
|
|
|
print "+ @_\n";
|
|
|
|
if ($execit) {
|
|
|
|
exec @_ or die "$0: couldn't exec $_[0] - $!\n";
|
|
|
|
} else {
|
|
|
|
system @_ and die "$0: couldn't exec $_[0] - $!\n";
|
|
|
|
}
|
|
|
|
}
|