Commit 3f97e0f5 authored by Robert Ricci's avatar Robert Ricci

Import set-mote-id, with soome local changes, from the TinyOS

source.
parent bdb4be82
......@@ -11,7 +11,7 @@ SUBDIR = mote
include $(OBJDIR)/Makeconf
BIN_SCRIPTS = tbuisp tbsgmotepower newmote
BIN_SCRIPTS = tbuisp tbsgmotepower newmote set-mote-id
#
# Force dependencies on the scripts so that they will be rerun through
......
#!/usr/bin/perl -wT
# Copyright (c) 2002 Intel Corporation
# All rights reserved.
# Distributed under the Intel Open Source Licesnse
# From the TinyOS distribution
# Modified to run setuid for Emulab
#
# This program changes the mote ID of a TinyOS image. It is used to
# install a program for a specific mote.
use strict;
# un-taint path
$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# default to backward compatability mode
my $G_compat = 1;
while( @ARGV && $ARGV[0] =~ /^-/ ) {
my $opt = shift @ARGV;
if( $opt eq "--srec" ) { $G_compat = 1; }
elsif( $opt eq "--exe" ) { $G_compat = 0; }
else { die "Unknown command line option $opt\n"; }
}
# print usage if we have the wrong number of arguments
if( @ARGV < 3 ) {
if( $G_compat ) {
print "usage: set-mote-id [srec_in] [srec_out] [TOS_LOCAL_ADDRESS] ...\n";
} else {
print "usage: set-mote-id [exe_in] [exe_out] [TOS_LOCAL_ADDRESS] ...\n";
}
exit 0;
}
# get the args and default variables set up
my $exein = shift @ARGV;
my $exeout = shift @ARGV;
#
# Taint check filenames
#
if ($exein =~ /^([-\w\/.]+)$/) {
$exein = $1;
} else {
die("*** Tainted exein: $exein\n");
}
if ($exeout =~ /^([-\w\/.]+)$/) {
$exeout = $1;
} else {
die("*** Tainted exeout: $exeout\n");
}
my %user_symbols = ();
for my $value (@ARGV) {
my $name = 'TOS_LOCAL_ADDRESS';
($name,$value) = ($1,$2) if $value =~ /^([^=]+)=(.*)/;
$value = hex $value if $value =~ /^0x/;
$user_symbols{$name} = $value;
}
my $segment_vma = undef;
my $segment_lma = undef;
my $segment_off = undef;
# if in compatability mode, derive the names of the exes from the srecs
my $srecin = undef;
my $srecout = undef;
if( $G_compat ) {
$srecin = $exein;
$srecout = $exeout;
$exein =~ s/srec/exe/;
$exeout =~ s/srec/exe/;
}
# find the data section
open( SECTS, "avr-objdump -h $exein |" )
or die "Cannot extract section information: $!\n";
while(<SECTS>) {
if( /^\s*\d+\s+\.data\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
$segment_vma = hex $1;
$segment_lma = hex $2;
$segment_off = hex $3;
last;
}
}
close(SECTS);
die "Could not find data section in $exein, aborting.\n"
unless defined $segment_vma && defined $segment_lma && defined $segment_off;
# build a hash of all data segment symbols to their address and size
my %exe_symbols = ();
open( SYMBOL, "avr-objdump -t $exein |" )
or die "Cannot extract symbol information: $!\n";
while(<SYMBOL>) {
if( /^(\S+)\s+\S+\s+\S+\s+\.data\s+(\S+)\s+(\S+)\s*$/ ) {
$exe_symbols{$3} = { addr => hex($1), size => hex($2) };
}
}
close(SYMBOL);
# slurp the input exe
open (FILE_IN, "<$exein") or die "Could not open $exein: $!\n";
binmode FILE_IN;
my $exe = join("",<FILE_IN>);
close( FILE_IN );
# change the desired symbols at their file offsets
for my $symbol (sort keys %user_symbols) {
my $value = $user_symbols{$symbol};
if( defined $exe_symbols{$symbol} ) {
my $addr = $exe_symbols{$symbol}->{addr};
my $size = $exe_symbols{$symbol}->{size};
my $filepos = $segment_off + ($addr - $segment_vma);
my $bytes = substr( pack("V", $value) . ("\000" x $size), 0, $size );
substr( $exe, $filepos, $size ) = $bytes;
} else {
warn "Could not find symbol $symbol in $exein, ignoring symbol.\n";
}
}
# barf the output exe
open (FILE_OUT, ">$exeout") or die "Could not open $exeout: $!\n";
binmode FILE_OUT;
print FILE_OUT $exe;
close( FILE_OUT );
# if in compatability mode, convert the output exe to the output srec
if( $G_compat ) {
my $cmd = "avr-objcopy --output-target=srec $exeout $srecout";
system( $cmd ) == 0 or die "Command \"$cmd\" failed";
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment