Source

Magic Lantern / remake-elf

Full commit
#!/usr/bin/perl
#
# Re-generate an ELF file at the specified offset
# with the symbols provided from the IDA Pro dump.
#
# (c) 2009 Trammell Hudson <hudson@osresearch.net>
# Based on stubs_2_elf.S by chr
#
use warnings;
use strict;
use Getopt::Long;
use File::Temp qw/ tempfile tempdir /;

my $base	= 0;
my $output	= "a.out";
my $cc		= $ENV{CC} || "arm-elf-gcc";
my $relative	= 0;

GetOptions(
	"b|base=o"		=> \$base,
	"o|output=s"		=> \$output,
	"c|cc=s"		=> \$cc,
	"r|relative+"		=> \$relative,
) or die "$0: Unknown option\n";

my $image = shift
	or die "$0: Image must be specified!\n";

my $syms = shift;


# Convert the base back into hex notation
$base = sprintf "0x%08x", $base;

my $dir = tempdir( CLEANUP => 1 );
my ($fh,$asm_file) = tempfile( DIR => $dir, SUFFIX => ".S" );

sub _ { local $_ = shift; s/^\| //msg; return $_ }

#
# Output the preamble of the temporary .S file
#
print $fh _(<<"");
| /*
| * Generated file from $image.
| * Do not edit!
| */
| .text
| .org 0
| .align 2
| .globl _start
| here = .
| #define NSTUB(addr,name) name = here + addr - $base
| _start:
| .text


unless( $syms )
{
	warn "$0: No syms specified (ignored)\n";
} else {
	open SYMS, "<", $syms
		or die "$0: Unable to open syms file '$syms': $!\n";

	#
	# Parse the symbol dump from IDA Pro and output
	# code into the .S file to define stubs for each of the
	# entities.
	#
	while( <SYMS> )
	{
		my ($addr,$name) = /^\s*0001:([0-9A-Fa-f]+)\s+([^\s]+)\s*$/
                        	or next;
		$addr = hex($addr);
		$addr += hex($base) if $relative;

		printf $fh "NSTUB( 0x%08x, %s )\n", $addr, $name;
	}
}


#
# Include the ROM dump into the ELF file
#
print $fh _(<<"");
| blob:
| .incbin "$image"
| end:

close SYMS;
close $fh;

#
# Call $CC to compile the assembly file
#
system $cc,
	"-Wl,-N,-Ttext,$base",
	"-nostdlib",
	"-o"	=> $output,
	$asm_file;