From 3f97e0f53cd9592277f545331aa295564ecd39fc Mon Sep 17 00:00:00 2001
From: Robert Ricci <ricci@cs.utah.edu>
Date: Tue, 5 Apr 2005 06:54:23 +0000
Subject: [PATCH] Import set-mote-id, with soome local changes, from the TinyOS
 source.

---
 mote/GNUmakefile.in |   2 +-
 mote/set-mote-id    | 131 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100755 mote/set-mote-id

diff --git a/mote/GNUmakefile.in b/mote/GNUmakefile.in
index bd52eb7a6f..a8fd16c71e 100644
--- a/mote/GNUmakefile.in
+++ b/mote/GNUmakefile.in
@@ -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
diff --git a/mote/set-mote-id b/mote/set-mote-id
new file mode 100755
index 0000000000..0fcb3fb18c
--- /dev/null
+++ b/mote/set-mote-id
@@ -0,0 +1,131 @@
+#!/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";
+}
+
-- 
GitLab