diff options
Diffstat (limited to 'winsup/cygwin/dllfixdbg')
-rwxr-xr-x | winsup/cygwin/dllfixdbg | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/winsup/cygwin/dllfixdbg b/winsup/cygwin/dllfixdbg new file mode 100755 index 0000000..1e467d3 --- /dev/null +++ b/winsup/cygwin/dllfixdbg @@ -0,0 +1,65 @@ +#!/usr/bin/perl +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; +xit 0, @objcopy, '--only-keep-debug', $dll, $dbg; +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'); + } elsif ($name eq '.gnu_debuglink_overlay') { + push (@objcopy, '-R', '.gnu_debuglink_overlay'); + $section{'.gnu_debuglink'}{-idx} = $idx if $section{'.gnu_debuglink'}; + 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}); +} +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"; + } +} |