* dllfixdbg: Accommodate newer binutils which put the gnu_debuglink at the end rather than at the beginning.
		
			
				
	
	
		
			76 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/perl
 | |
| # Copyright 2006 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, '-j', '.stab', '-j', '.stabstr', $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";
 | |
|     }
 | |
| }
 |