updated tests - references to actual COOJA code

This commit is contained in:
fros4943 2007-09-10 14:07:12 +00:00
parent 9100b5710b
commit 95186aebcb
7 changed files with 452 additions and 394 deletions

View file

@ -3,22 +3,19 @@
<project name="COOJA Simulator - JNI Tests" default="about" basedir="."> <project name="COOJA Simulator - JNI Tests" default="about" basedir=".">
<property environment="env"/> <property environment="env"/>
<!-- CONFIGURATION -->
<!-- Change these until all tests pass! -->
<!-- The working configuration must manually be entered in COOJA -->
<property name="PATH_C_COMPILER" value="gcc"/>
<property name="COMPILER_ARGS" value="-Wall -D_JNI_IMPLEMENTATION_ -I'$(JAVA_HOME)/include' -I'$(JAVA_HOME)/include/win32'"/>
<property name="LINK_COMMAND_1" value="gcc -shared -Wl,-Map=$(MAPFILE) -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -o $(LIBFILE)"/>
<property name="LINK_COMMAND_2" value=""/>
<target name="help"> <target name="help">
<echo> <echo>
Cygwin users may try: Linux users with the GNU toolchain often can use:
COMPILER_ARGS = -mno-cygwin -I....../jdk1.5.0/include -I....../jdk1.5.0/include/win32 COMPILER_ARGS = [PENDING]
LINKER_ARGS_1 = --add-stdcall-alias /usr/lib/mingw/dllcrt2.o LINK_COMMAND_1 = [PENDING]
LINKER_ARGS_2 = -L/usr/lib/mingw -lmingw32 -lmingwex -lmsvcrt LINK_COMMAND_2 = [PENDING]
Note for Windows users with recent Cygwin: Cygwin users may try:
COMPILER_ARGS = [PENDING]
LINK_COMMAND_1 = [PENDING]
LINK_COMMAND_2 = [PENDING]
Windows users with recent Cygwin:
In recent (early 2007) MinGW-Cygwin versions, the JNI support has been removed/limited. In recent (early 2007) MinGW-Cygwin versions, the JNI support has been removed/limited.
This may cause COOJA not to be able to load libraries generated using gcc's -mno-cygwin flag. This may cause COOJA not to be able to load libraries generated using gcc's -mno-cygwin flag.
One possible solution is to download "real" MinGW (http://www.mingw.org), and install it separately One possible solution is to download "real" MinGW (http://www.mingw.org), and install it separately
@ -27,6 +24,7 @@ from Cygwin (for example in c:\mingw). Try using the following settings:
COMPILER_ARGS = -Wall -D_JNI_IMPLEMENTATION_ -I'$(JAVA_HOME)/include' -I'$(JAVA_HOME)/include/win32' COMPILER_ARGS = -Wall -D_JNI_IMPLEMENTATION_ -I'$(JAVA_HOME)/include' -I'$(JAVA_HOME)/include/win32'
LINK_COMMAND_1 = gcc -shared -Wl,-Map=$(MAPFILE) -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -o $(LIBFILE) LINK_COMMAND_1 = gcc -shared -Wl,-Map=$(MAPFILE) -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -o $(LIBFILE)
LINK_COMMAND_2 = LINK_COMMAND_2 =
</echo> </echo>
</target> </target>
@ -37,9 +35,13 @@ The COOJA Simulator - JNI Tests
These tests can be used to help understand COOJA errors, and to configure COOJA for new users. These tests can be used to help understand COOJA errors, and to configure COOJA for new users.
For COOJA to compile JNI libraries successfully, tests 2-5 must be completed. For COOJA to compile JNI libraries successfully, tests 2-5 must be completed.
In level3, only level3a or level3b is necessary to pass.
You may have to change the configuration (4 properties) in this file (build.xml). You may have to change the configuration in the file 'exttools.cfg'.
When all tests pass, the settings should be entered into the COOJA External tool settings dialog. When all tests pass, these settings should be entered into the COOJA External tool settings dialog.
Before running the tests, the COOJA JAR file must be created:
> ant compile_cooja
To run the first test: To run the first test:
> ant level2 > ant level2
@ -48,25 +50,22 @@ For more information including configuration examples:
> ant help > ant help
> ant level2 > ant level2
Runs JNI test level 2:
[compilation test] [compilation test]
Compiles level2.c to level2.library, using both c compiler and linker. Compiles level2.c to level2.library, using both c compiler and linker.
Java class loads the library and calls a simple native function. Java class loads the library and calls a simple native function.
> ant level3 > ant level3a
Runs JNI test level 3: [address parsing using map file]
[map file parsing test]
Compiles java + c. > ant level3b
The map file is parsed, and information about data+bss sections is outputted. [address parsing using nm]
> ant level4 > ant level4
Runs JNI test level 4:
[fetching reference var] [fetching reference var]
Calculates offset between relative (mapfile) and absolute memory. Calculates offset between relative and absolute memory.
A simple native function increases two counters (from both data and bss sections). A simple native function increases two counters (from both data and bss sections).
> ant level5 > ant level5
Runs JNI test level 5:
[fetches and restores memory segments - the final test] [fetches and restores memory segments - the final test]
A simple native function increases two counters (from both data and bss sections). A simple native function increases two counters (from both data and bss sections).
The current memory (data+bss sections) is fetched and restored between function calls. The current memory (data+bss sections) is fetched and restored between function calls.
@ -96,6 +95,7 @@ For more information including configuration examples:
<property name="MAPFILE" value="${LEVEL}.map"/> <property name="MAPFILE" value="${LEVEL}.map"/>
<property name="ARFILE" value="${LEVEL}.a"/> <property name="ARFILE" value="${LEVEL}.a"/>
<property file="exttools.cfg"/>
<property name="COMPILE_COMMAND" value="${PATH_C_COMPILER} ${COMPILER_ARGS} -c ${SRCFILE} -o ${OBJFILE}"/> <property name="COMPILE_COMMAND" value="${PATH_C_COMPILER} ${COMPILER_ARGS} -c ${SRCFILE} -o ${OBJFILE}"/>
<property name="LINKER_COMMAND" value="${LINK_COMMAND_1} ${OBJFILE} ${LINK_COMMAND_2}"/> <property name="LINKER_COMMAND" value="${LINK_COMMAND_1} ${OBJFILE} ${LINK_COMMAND_2}"/>
@ -134,6 +134,10 @@ For more information including configuration examples:
</exec> </exec>
</target> </target>
<target name="compile_cooja" depends="init">
<ant dir="../../" antfile="build.xml" target="jar"/>
</target>
<target name="level2" depends="init"> <target name="level2" depends="init">
<property name="LEVEL" value="level2"/> <property name="LEVEL" value="level2"/>
<antcall target="compile_library" inheritall="true"/> <antcall target="compile_library" inheritall="true"/>
@ -142,28 +146,56 @@ For more information including configuration examples:
<java fork="yes" dir="${LEVEL}" classname="Level2"/> <java fork="yes" dir="${LEVEL}" classname="Level2"/>
</target> </target>
<target name="level3" depends="init"> <target name="level3a" depends="init">
<property name="LEVEL" value="level3"/> <property name="LEVEL" value="level3a"/>
<antcall target="compile_library" inheritall="true"/> <antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/> <javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level3"/> <java fork="yes" dir="${LEVEL}" classname="Level3a">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target>
<target name="level3b" depends="init">
<property name="LEVEL" value="level3b"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level3b">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target> </target>
<target name="level4" depends="init"> <target name="level4" depends="init">
<property name="LEVEL" value="level4"/> <property name="LEVEL" value="level4"/>
<antcall target="compile_library" inheritall="true"/> <antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/> <javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level4"/> <java fork="yes" dir="${LEVEL}" classname="Level4">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target> </target>
<target name="level5" depends="init"> <target name="level5" depends="init">
<property name="LEVEL" value="level5"/> <property name="LEVEL" value="level5"/>
<antcall target="compile_library" inheritall="true"/> <antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/> <javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level5"/> <java fork="yes" dir="${LEVEL}" classname="Level5">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target> </target>
</project> </project>

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: Level2.java,v 1.1 2006/08/21 12:13:00 fros4943 Exp $ * $Id: Level2.java,v 1.2 2007/09/10 14:07:12 fros4943 Exp $
*/ */
import java.io.*; import java.io.*;
@ -34,15 +34,14 @@ import java.io.*;
public class Level2 { public class Level2 {
static { static {
System.err.println("JAVA Level2 static> loading library now"); System.out.println("Loading library now");
System.load(new File("level2.library").getAbsolutePath()); System.load(new File("level2.library").getAbsolutePath());
System.err.println("JAVA Level2 static> done loading library");
} }
private native void test(); private native void test();
public Level2() { public Level2() {
System.err.println("JAVA Level2 constructor()> running native test function"); System.err.println("Calling native test function");
test(); test();
} }

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: level2.c,v 1.1 2006/08/21 12:13:00 fros4943 Exp $ * $Id: level2.c,v 1.2 2007/09/10 14:07:12 fros4943 Exp $
*/ */
#include <jni.h> #include <jni.h>
@ -35,6 +35,6 @@
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_Level2_test(JNIEnv *env, jobject obj) Java_Level2_test(JNIEnv *env, jobject obj)
{ {
fprintf(stderr, "C test()> Level 2 OK!\n"); fprintf(stderr, "Level 2 OK!\n");
fflush(stderr); fflush(stderr);
} }

View file

@ -26,63 +26,138 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: Level4.java,v 1.1 2006/08/21 12:12:59 fros4943 Exp $ * $Id: Level4.java,v 1.2 2007/09/10 14:07:12 fros4943 Exp $
*/ */
import java.io.*; import java.io.*;
import java.util.Properties;
import java.util.Vector; import java.util.Vector;
import java.util.regex.Matcher; import org.apache.log4j.xml.DOMConfigurator;
import java.util.regex.Pattern;
import se.sics.cooja.GUI;
import se.sics.cooja.contikimote.ContikiMoteType;
public class Level4 { public class Level4 {
private final File externalToolsSettingsFile = new File("../exttools.cfg");
static { static {
System.load(new File("level4.library").getAbsolutePath()); System.load(new File("level4.library").getAbsolutePath());
} }
final static private String bssSectionAddrRegExp =
"^.bss[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$";
final static private String bssSectionSizeRegExp =
"^.bss[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$";
final static private String dataSectionAddrRegExp =
"^.data[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$";
final static private String dataSectionSizeRegExp =
"^.data[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$";
final static private String varAddressRegExpPrefix =
"^[ \t]*0x([0-9A-Fa-f]*)[ \t]*";
final static private String varAddressRegExpSuffix =
"[ \t]*$";
final static private String varNameRegExp =
"^[ \t]*(0x[0-9A-Fa-f]*)[ \t]*([^ ]*)[ \t]*$";
final static private String varSizeRegExpPrefix =
"^";
final static private String varSizeRegExpSuffix =
"[ \t]*(0x[0-9A-Fa-f]*)[ \t]*[^ ]*[ \t]*$";
private native void doCount(); private native void doCount();
private native int getRefAddress(); private native int getRefAddress();
public Level4() { public Level4() {
File mapFile = new File("level4.map"); // Configure logger
DOMConfigurator.configure(GUI.class.getResource("/" + GUI.LOG_CONFIG_FILE));
// Check that map file exists // Load configuration
System.out.println("Loading COOJA configuration");
GUI.externalToolsUserSettingsFile = externalToolsSettingsFile;
GUI.loadExternalToolsDefaultSettings();
GUI.loadExternalToolsUserSettings();
// Should we parse addresses using map file or nm?
boolean useNm = Boolean.parseBoolean(GUI.getExternalToolsSetting("PARSE_WITH_NM", "false"));
Properties addresses = new Properties();
int relDataSectionAddr = -1;
int dataSectionSize = -1;
int relBssSectionAddr = -1;
int bssSectionSize = -1;
if (useNm) {
// Parse nm output
System.out.println("Parsing using nm");
File libFile = new File("level4.library");
if (!libFile.exists()) {
System.err.println("Library file " + libFile.getAbsolutePath() + " could not be found!");
System.exit(1);
}
Vector<String> nmData = ContikiMoteType.loadNmData(libFile);
if (nmData == null) {
System.err.println("No nm data could be loaded");
System.exit(1);
}
boolean parseOK = ContikiMoteType.parseNmData(nmData, addresses);
if (!parseOK) {
System.err.println("Nm data parsing failed");
System.exit(1);
}
relDataSectionAddr = ContikiMoteType.loadNmRelDataSectionAddr(nmData);
dataSectionSize = ContikiMoteType.loadNmDataSectionSize(nmData);
relBssSectionAddr = ContikiMoteType.loadNmRelBssSectionAddr(nmData);
bssSectionSize = ContikiMoteType.loadNmBssSectionSize(nmData);
} else {
// Parse map file
System.out.println("Parsing using map file");
File mapFile = new File("level4.map");
if (!mapFile.exists()) { if (!mapFile.exists()) {
System.err.println("No map file could be loaded"); System.err.println("No map file could be loaded");
System.exit(1); System.exit(1);
} }
Vector<String> mapContents = loadMapFile(mapFile); Vector<String> mapData = ContikiMoteType.loadMapFile(mapFile);
if (mapData == null) {
System.err.println("No map data could be loaded");
System.exit(1);
}
int relDataSectionAddr = loadRelDataSectionAddr(mapContents); boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
int dataSectionSize = (int) loadDataSectionSize(mapContents); if (!parseOK) {
int relBssSectionAddr = loadRelBssSectionAddr(mapContents); System.err.println("Map data parsing failed");
int bssSectionSize = (int) loadBssSectionSize(mapContents); System.exit(1);
}
int referenceAddress = getRefAddress(); relDataSectionAddr = ContikiMoteType.loadRelDataSectionAddr(mapData);
System.err.println("Reference address: 0x" + Integer.toHexString(referenceAddress)); dataSectionSize = ContikiMoteType.loadDataSectionSize(mapData);
relBssSectionAddr = ContikiMoteType.loadRelBssSectionAddr(mapData);
bssSectionSize = ContikiMoteType.loadBssSectionSize(mapData);
}
int offsetRelToAbs = referenceAddress - getRelVarAddr(mapContents, "ref_var"); String varName;
System.err.println("Offset relative-absolute: 0x" + Integer.toHexString(offsetRelToAbs)); varName = "initialized_counter";
if (!addresses.containsKey(varName)) {
System.err.println("Could not find address of: " + varName);
System.exit(1);
}
varName = "uninitialized_counter";
if (!addresses.containsKey(varName)) {
System.err.println("Could not find address of: " + varName);
System.exit(1);
}
varName = "ref_var";
if (!addresses.containsKey(varName)) {
System.err.println("Could not find address of: " + varName);
System.exit(1);
}
if (relDataSectionAddr < 0) {
System.err.println("Data segment address < 0: 0x" + Integer.toHexString(relDataSectionAddr));
System.exit(1);
}
if (relBssSectionAddr < 0) {
System.err.println("BSS segment address < 0: 0x" + Integer.toHexString(relBssSectionAddr));
System.exit(1);
}
if (dataSectionSize <= 0) {
System.err.println("Data segment size <= 0: 0x" + Integer.toHexString(dataSectionSize));
System.exit(1);
}
if (bssSectionSize <= 0) {
System.err.println("BSS segment size <= 0: 0x" + Integer.toHexString(bssSectionSize));
System.exit(1);
}
int absRefAddress = getRefAddress();
System.out.println("Absolute reference address: 0x" + Integer.toHexString(absRefAddress));
int relRefAddress = (Integer) addresses.get("ref_var");
System.out.println("Relative reference address: 0x" + Integer.toHexString(relRefAddress));
int offsetRelToAbs = absRefAddress - relRefAddress;
System.out.println("Offset relative-absolute: 0x" + Integer.toHexString(offsetRelToAbs));
doCount(); doCount();
doCount(); doCount();
@ -93,82 +168,6 @@ public class Level4 {
System.err.println("Level 4 OK!"); System.err.println("Level 4 OK!");
} }
private static int getRelVarAddr(Vector<String> mapContents, String varName) {
String regExp = varAddressRegExpPrefix + varName + varAddressRegExpSuffix;
String retString = getFirstMatchGroup(mapContents, regExp, 1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
private static Vector<String> loadMapFile(File mapFile) {
Vector<String> mapContents = new Vector<String>();
try {
BufferedReader in =
new BufferedReader(
new InputStreamReader(
new FileInputStream(mapFile)));
while (in.ready())
{
mapContents.add(in.readLine());
}
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e);
return null;
} catch (IOException e) {
System.err.println("IO error: " + e);
return null;
}
return mapContents;
}
private static int loadRelDataSectionAddr(Vector<String> mapFile) {
String retString = getFirstMatchGroup(mapFile, dataSectionAddrRegExp, 1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
private static int loadDataSectionSize(Vector<String> mapFile) {
String retString = getFirstMatchGroup(mapFile, dataSectionSizeRegExp, 1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
private static int loadRelBssSectionAddr(Vector<String> mapFile) {
String retString = getFirstMatchGroup(mapFile, bssSectionAddrRegExp, 1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
private static int loadBssSectionSize(Vector<String> mapFile) {
String retString = getFirstMatchGroup(mapFile, bssSectionSizeRegExp, 1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
private static String getFirstMatchGroup(Vector<String> lines, String regexp, int groupNr) {
Pattern pattern = Pattern.compile(regexp);
for (int i=0; i < lines.size(); i++) {
Matcher matcher = pattern.matcher(lines.elementAt(i));
if (matcher.find()) {
return matcher.group(groupNr);
}
}
return null;
}
public static void main(String[] args) { public static void main(String[] args) {
new Level4(); new Level4();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: level4.c,v 1.1 2006/08/21 12:12:59 fros4943 Exp $ * $Id: level4.c,v 1.2 2007/09/10 14:07:12 fros4943 Exp $
*/ */
#include <jni.h> #include <jni.h>
@ -40,8 +40,8 @@ int uninitialized_counter;
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_Level4_doCount(JNIEnv *env, jobject obj) Java_Level4_doCount(JNIEnv *env, jobject obj)
{ {
fprintf(stderr, ">> DATA_counter=\t%i\tBSS_counter=\t%i\n", initialized_counter++, uninitialized_counter++); printf(">> DATA_counter=\t%i\tBSS_counter=\t%i\n", initialized_counter++, uninitialized_counter++);
fflush(stderr); fflush(stdout);
} }
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_Level4_getRefAddress(JNIEnv *env, jobject obj) Java_Level4_getRefAddress(JNIEnv *env, jobject obj)

View file

@ -26,193 +26,224 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: Level5.java,v 1.2 2007/01/11 14:28:26 fros4943 Exp $ * $Id: Level5.java,v 1.3 2007/09/10 14:07:12 fros4943 Exp $
*/ */
import java.io.*; import java.io.*;
import java.util.Properties;
import java.util.Vector; import java.util.Vector;
import java.util.regex.Matcher; import org.apache.log4j.xml.DOMConfigurator;
import java.util.regex.Pattern;
import se.sics.cooja.GUI;
import se.sics.cooja.SectionMoteMemory;
import se.sics.cooja.contikimote.ContikiMoteType;
public class Level5 { public class Level5 {
private final File externalToolsSettingsFile = new File("../exttools.cfg");
static { static {
System.load(new File("level5.library").getAbsolutePath()); System.load(new File("level5.library").getAbsolutePath());
} }
final static private String bssSectionAddrRegExp =
"^.bss[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$";
final static private String bssSectionSizeRegExp =
"^.bss[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$";
final static private String dataSectionAddrRegExp =
"^.data[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$";
final static private String dataSectionSizeRegExp =
"^.data[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$";
final static private String varAddressRegExpPrefix =
"^[ \t]*0x([0-9A-Fa-f]*)[ \t]*";
final static private String varAddressRegExpSuffix =
"[ \t]*$";
final static private String varNameRegExp =
"^[ \t]*(0x[0-9A-Fa-f]*)[ \t]*([^ ]*)[ \t]*$";
final static private String varSizeRegExpPrefix =
"^";
final static private String varSizeRegExpSuffix =
"[ \t]*(0x[0-9A-Fa-f]*)[ \t]*[^ ]*[ \t]*$";
private native void doCount(); private native void doCount();
private native int getRefAddress(); private native int getRefAddress();
private native byte[] getMemory(int start, int length); public native void getMemory(int start, int length, byte[] mem);
private native void setMemory(int start, int length, byte[] mem); public native void setMemory(int start, int length, byte[] mem);
private int javaDataCounter = 1; private int javaDataCounter = 1;
private int javaBssCounter = 0; private int javaBssCounter = 0;
public Level5() { public Level5() {
File mapFile = new File("level5.map");
// Check that map file exists // Configure logger
DOMConfigurator.configure(GUI.class.getResource("/" + GUI.LOG_CONFIG_FILE));
// Load configuration
System.out.println("Loading COOJA configuration");
GUI.externalToolsUserSettingsFile = externalToolsSettingsFile;
GUI.loadExternalToolsDefaultSettings();
GUI.loadExternalToolsUserSettings();
// Should we parse addresses using map file or nm?
boolean useNm = Boolean.parseBoolean(GUI.getExternalToolsSetting("PARSE_WITH_NM", "false"));
Properties addresses = new Properties();
int relDataSectionAddr = -1;
int dataSectionSize = -1;
int relBssSectionAddr = -1;
int bssSectionSize = -1;
if (useNm) {
// Parse nm output
System.out.println("Parsing using nm");
File libFile = new File("level5.library");
if (!libFile.exists()) {
System.err.println("Library file " + libFile.getAbsolutePath() + " could not be found!");
System.exit(1);
}
Vector<String> nmData = ContikiMoteType.loadNmData(libFile);
if (nmData == null) {
System.err.println("No nm data could be loaded");
System.exit(1);
}
boolean parseOK = ContikiMoteType.parseNmData(nmData, addresses);
if (!parseOK) {
System.err.println("Nm data parsing failed");
System.exit(1);
}
relDataSectionAddr = ContikiMoteType.loadNmRelDataSectionAddr(nmData);
dataSectionSize = ContikiMoteType.loadNmDataSectionSize(nmData);
relBssSectionAddr = ContikiMoteType.loadNmRelBssSectionAddr(nmData);
bssSectionSize = ContikiMoteType.loadNmBssSectionSize(nmData);
} else {
// Parse map file
System.out.println("Parsing using map file");
File mapFile = new File("level5.map");
if (!mapFile.exists()) { if (!mapFile.exists()) {
System.err.println("No map file could be loaded"); System.err.println("No map file could be loaded");
System.exit(1); System.exit(1);
} }
Vector<String> mapContents = loadMapFile(mapFile); Vector<String> mapData = ContikiMoteType.loadMapFile(mapFile);
if (mapData == null) {
int relDataSectionAddr = loadRelDataSectionAddr(mapContents); System.err.println("No map data could be loaded");
int dataSectionSize = (int) loadDataSectionSize(mapContents); System.exit(1);
int relBssSectionAddr = loadRelBssSectionAddr(mapContents);
int bssSectionSize = (int) loadBssSectionSize(mapContents);
int referenceAddress = getRefAddress();
int offsetRelToAbs = referenceAddress - getRelVarAddr(mapContents, "ref_var");
System.err.println("\n\n--- RUNNING DO_COUNT 5 TIMES ---");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.err.println("\n\n--- CHECKPOINT #1: JAVA COUNTERS SHOULD EQUAL C ---");
System.err.println(">> JavaDATA_counter=\t" + javaDataCounter + "\tJavaBSS_counter=\t" + javaBssCounter);
System.err.println("\n\n--- FETCHING AND SAVING MEMORY ---");
byte[] savedDataSection = getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize);
byte[] savedBssSection = getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize);
System.err.println("data section size:\t" + savedDataSection.length + " = " + "0x" + Integer.toHexString(savedDataSection.length));
System.err.println("bss section size:\t" + savedBssSection.length + " = " + "0x" + Integer.toHexString(savedBssSection.length));
System.err.println("\n\n--- RUNNING DO_COUNT 3 TIMES ---");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.err.println("\n\n--- CHECKPOINT #2: JAVA COUNTERS SHOULD EQUAL C ---");
System.err.println(">> JavaDATA_counter=\t" + javaDataCounter + "\tJavaBSS_counter=\t" + javaBssCounter);
System.err.println("\n\n--- RESTORING MEMORY: DATA ---");
setMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, savedDataSection); javaDataCounter -= 3;
System.err.println("\n\n--- RUNNING DO_COUNT 3 TIMES ---");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.err.println("\n\n--- CHECKPOINT #3: JAVA COUNTERS SHOULD EQUAL C ---");
System.err.println(">> JavaDATA_counter=\t" + javaDataCounter + "\tJavaBSS_counter=\t" + javaBssCounter);
System.err.println("\n\n--- RESTORING MEMORY: BSS ---");
setMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, savedBssSection); javaBssCounter -= 6;
System.err.println("\n\n--- RUNNING DO_COUNT 3 TIMES ---");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.err.println("\n\n--- CHECKPOINT #4: JAVA COUNTERS SHOULD EQUAL C ---");
System.err.println(">> JavaDATA_counter=\t" + javaDataCounter + "\tJavaBSS_counter=\t" + javaBssCounter);
System.err.println("Level 5 OK!");
} }
private static int getRelVarAddr(Vector<String> mapContents, String varName) { boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
String regExp = varAddressRegExpPrefix + varName + varAddressRegExpSuffix; if (!parseOK) {
String retString = getFirstMatchGroup(mapContents, regExp, 1); System.err.println("Map data parsing failed");
System.exit(1);
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
} }
private static Vector<String> loadMapFile(File mapFile) { relDataSectionAddr = ContikiMoteType.loadRelDataSectionAddr(mapData);
Vector<String> mapContents = new Vector<String>(); dataSectionSize = ContikiMoteType.loadDataSectionSize(mapData);
relBssSectionAddr = ContikiMoteType.loadRelBssSectionAddr(mapData);
try { bssSectionSize = ContikiMoteType.loadBssSectionSize(mapData);
BufferedReader in =
new BufferedReader(
new InputStreamReader(
new FileInputStream(mapFile)));
while (in.ready())
{
mapContents.add(in.readLine());
}
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e);
return null;
} catch (IOException e) {
System.err.println("IO error: " + e);
return null;
} }
return mapContents; int absRefAddress = getRefAddress();
int relRefAddress = (Integer) addresses.get("ref_var");
int offsetRelToAbs = absRefAddress - relRefAddress;
System.out.println("Creating section memory");
byte[] initialDataSection = new byte[dataSectionSize];
byte[] initialBssSection = new byte[bssSectionSize];
getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
SectionMoteMemory memory = new SectionMoteMemory(addresses);
memory.setMemorySegment(relDataSectionAddr, initialDataSection);
memory.setMemorySegment(relBssSectionAddr, initialBssSection);
int dataCounter, bssCounter;
System.out.print("Checking initial values: ");
dataCounter = memory.getIntValueOf("initialized_counter");
bssCounter = memory.getIntValueOf("uninitialized_counter");
if (dataCounter != javaDataCounter || bssCounter != javaBssCounter) {
System.out.println("FAILED!");
} else {
System.out.println("OK!");
} }
private static int loadRelDataSectionAddr(Vector<String> mapFile) { System.out.println("Increasing counters 5 times");
String retString = getFirstMatchGroup(mapFile, dataSectionAddrRegExp, 1); doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
if (retString != null) System.out.print("Checking increased values: ");
return Integer.parseInt(retString.trim(), 16); getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
else return 0; getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
memory.setMemorySegment(relDataSectionAddr, initialDataSection);
memory.setMemorySegment(relBssSectionAddr, initialBssSection);
dataCounter = memory.getIntValueOf("initialized_counter");
bssCounter = memory.getIntValueOf("uninitialized_counter");
if (dataCounter != javaDataCounter || bssCounter != javaBssCounter) {
System.out.println("FAILED!");
System.exit(1);
} else {
System.out.println("OK!");
} }
private static int loadDataSectionSize(Vector<String> mapFile) { System.out.println("Storing both memory segments now");
String retString = getFirstMatchGroup(mapFile, dataSectionSizeRegExp, 1); byte[] savedDataSection = new byte[dataSectionSize];
byte[] savedBssSection = new byte[bssSectionSize];
int savedDataCounter = dataCounter;
int savedBssCounter = bssCounter;
getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, savedDataSection);
getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, savedBssSection);
if (retString != null) System.out.println("Increasing counters 3 times");
return Integer.parseInt(retString.trim(), 16); doCount(); javaDataCounter++; javaBssCounter++;
else return 0; doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.out.print("Checking increased values: ");
getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
memory.setMemorySegment(relDataSectionAddr, initialDataSection);
memory.setMemorySegment(relBssSectionAddr, initialBssSection);
dataCounter = memory.getIntValueOf("initialized_counter");
bssCounter = memory.getIntValueOf("uninitialized_counter");
if (dataCounter != javaDataCounter || bssCounter != javaBssCounter) {
System.out.println("FAILED!");
System.exit(1);
} else {
System.out.println("OK!");
} }
private static int loadRelBssSectionAddr(Vector<String> mapFile) { System.out.println("Restoring data segment");
String retString = getFirstMatchGroup(mapFile, bssSectionAddrRegExp, 1); setMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, savedDataSection);
javaDataCounter = savedDataCounter;
if (retString != null) System.out.println("Increasing counters 3 times");
return Integer.parseInt(retString.trim(), 16); doCount(); javaDataCounter++; javaBssCounter++;
else return 0; doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
System.out.print("Checking reset data counter: ");
getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
memory.setMemorySegment(relDataSectionAddr, initialDataSection);
memory.setMemorySegment(relBssSectionAddr, initialBssSection);
dataCounter = memory.getIntValueOf("initialized_counter");
bssCounter = memory.getIntValueOf("uninitialized_counter");
if (dataCounter != javaDataCounter || bssCounter != javaBssCounter) {
System.out.println("FAILED!");
System.exit(1);
} else {
System.out.println("OK!");
} }
private static int loadBssSectionSize(Vector<String> mapFile) { System.out.println("Restoring bss segment");
String retString = getFirstMatchGroup(mapFile, bssSectionSizeRegExp, 1); setMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, savedBssSection);
javaBssCounter = savedBssCounter;
if (retString != null) System.out.print("Checking reset bss counter: ");
return Integer.parseInt(retString.trim(), 16); getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
else return 0; getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
memory.setMemorySegment(relDataSectionAddr, initialDataSection);
memory.setMemorySegment(relBssSectionAddr, initialBssSection);
dataCounter = memory.getIntValueOf("initialized_counter");
bssCounter = memory.getIntValueOf("uninitialized_counter");
if (dataCounter != javaDataCounter || bssCounter != javaBssCounter) {
System.out.println("FAILED!");
System.exit(1);
} else {
System.out.println("OK!");
} }
private static String getFirstMatchGroup(Vector<String> lines, String regexp, int groupNr) { System.out.println("\n");
Pattern pattern = Pattern.compile(regexp); System.out.println("Reading and writing memory segments via JNI successfully");
for (int i=0; i < lines.size(); i++) { System.out.println("Level 5 OK!");
Matcher matcher = pattern.matcher(lines.elementAt(i));
if (matcher.find()) {
return matcher.group(groupNr);
} }
}
return null;
}
public static void main(String[] args) { public static void main(String[] args) {
new Level5(); new Level5();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: level5.c,v 1.2 2007/01/11 14:27:26 fros4943 Exp $ * $Id: level5.c,v 1.3 2007/09/10 14:07:12 fros4943 Exp $
*/ */
#include <jni.h> #include <jni.h>
@ -41,8 +41,8 @@ int uninitialized_counter;
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_Level5_doCount(JNIEnv *env, jobject obj) Java_Level5_doCount(JNIEnv *env, jobject obj)
{ {
fprintf(stderr, ">> DATA_counter=\t%i\tBSS_counter=\t%i\n", ++initialized_counter, ++uninitialized_counter); printf(">> DATA_counter=\t%i\tBSS_counter=\t%i\n", ++initialized_counter, ++uninitialized_counter);
fflush(stderr); fflush(stdout);
} }
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_Level5_getRefAddress(JNIEnv *env, jobject obj) Java_Level5_getRefAddress(JNIEnv *env, jobject obj)
@ -50,13 +50,10 @@ Java_Level5_getRefAddress(JNIEnv *env, jobject obj)
return (jint) &ref_var; return (jint) &ref_var;
} }
JNIEXPORT jbyteArray JNICALL JNIEXPORT void JNICALL
Java_Level5_getMemory(JNIEnv *env, jobject obj, jint start, jint length) Java_Level5_getMemory(JNIEnv *env, jobject obj, jint start, jint length, jbyteArray mem_arr)
{ {
jbyteArray ret=(*env)->NewByteArray(env, length); (*env)->SetByteArrayRegion(env, mem_arr, 0, (size_t) length, (jbyte *) start);
(*env)->SetByteArrayRegion(env, ret, 0, (size_t) length, (jbyte *) start);
return (ret);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL