summaryrefslogtreecommitdiff
path: root/winsup/cygwin/dllfixdbg
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/dllfixdbg')
-rwxr-xr-xwinsup/cygwin/dllfixdbg75
1 files changed, 75 insertions, 0 deletions
diff --git a/winsup/cygwin/dllfixdbg b/winsup/cygwin/dllfixdbg
new file mode 100755
index 00000000000..f97be0ca6b1
--- /dev/null
+++ b/winsup/cygwin/dllfixdbg
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+# Copyright 2006, 2007 Red Hat, Inc.
+#
+# 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.
+#
+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, '-R', '.gnu_debuglink_overlay', '--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');
+ $idx = $section{'.gnu_debuglink'}{-idx} if defined($section{'.gnu_debuglink'}{-idx});
+ } elsif ($name eq '.gnu_debuglink_overlay') {
+ push (@objcopy, '-R', '.gnu_debuglink_overlay');
+ $section{'.gnu_debuglink'}{-idx} = $idx;
+ 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";
+ }
+}