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,30 +3,28 @@
<project name="COOJA Simulator - JNI Tests" default="about" basedir=".">
<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">
<echo>
Linux users with the GNU toolchain often can use:
COMPILER_ARGS = [PENDING]
LINK_COMMAND_1 = [PENDING]
LINK_COMMAND_2 = [PENDING]
Cygwin users may try:
COMPILER_ARGS = -mno-cygwin -I....../jdk1.5.0/include -I....../jdk1.5.0/include/win32
LINKER_ARGS_1 = --add-stdcall-alias /usr/lib/mingw/dllcrt2.o
LINKER_ARGS_2 = -L/usr/lib/mingw -lmingw32 -lmingwex -lmsvcrt
COMPILER_ARGS = [PENDING]
LINK_COMMAND_1 = [PENDING]
LINK_COMMAND_2 = [PENDING]
Note for Windows users with recent Cygwin:
Windows users with recent Cygwin:
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.
One possible solution is to download "real" MinGW (http://www.mingw.org), and install it separately
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'
LINK_COMMAND_1 = gcc -shared -Wl,-Map=$(MAPFILE) -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -o $(LIBFILE)
LINK_COMMAND_2 =
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_2 =
</echo>
</target>
@ -37,36 +35,37 @@ The COOJA Simulator - JNI Tests
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.
In level3, only level3a or level3b is necessary to pass.
You may have to change the configuration (4 properties) in this file (build.xml).
When all tests pass, the settings should be entered into the COOJA External tool settings dialog.
You may have to change the configuration in the file 'exttools.cfg'.
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:
> ant level2
> ant level2
For more information including configuration examples:
> ant help
> ant help
> ant level2
Runs JNI test level 2:
[compilation test]
Compiles level2.c to level2.library, using both c compiler and linker.
Java class loads the library and calls a simple native function.
> ant level3
Runs JNI test level 3:
[map file parsing test]
Compiles java + c.
The map file is parsed, and information about data+bss sections is outputted.
> ant level3a
[address parsing using map file]
> ant level3b
[address parsing using nm]
> ant level4
Runs JNI test level 4:
[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).
> ant level5
Runs JNI test level 5:
[fetches and restores memory segments - the final test]
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.
@ -75,95 +74,128 @@ For more information including configuration examples:
</target>
<target name="clean">
<delete>
<fileset dir="." includes="**/*.class" />
<fileset dir="." includes="**/*.library" />
<fileset dir="." includes="**/*.o" />
<fileset dir="." includes="**/*.map" />
<fileset dir="." includes="**/*.log" />
<fileset dir="." includes="build.temp" />
</delete>
</target>
<delete>
<fileset dir="." includes="**/*.class" />
<fileset dir="." includes="**/*.library" />
<fileset dir="." includes="**/*.o" />
<fileset dir="." includes="**/*.map" />
<fileset dir="." includes="**/*.log" />
<fileset dir="." includes="build.temp" />
</delete>
</target>
<target name="init">
<tstamp/>
</target>
<tstamp/>
</target>
<target name="compile_library" depends="init">
<property name="SRCFILE" value="${LEVEL}.c"/>
<property name="OBJFILE" value="${LEVEL}.o"/>
<property name="LIBFILE" value="${LEVEL}.library"/>
<property name="MAPFILE" value="${LEVEL}.map"/>
<property name="ARFILE" value="${LEVEL}.a"/>
<target name="compile_library" depends="init">
<property name="SRCFILE" value="${LEVEL}.c"/>
<property name="OBJFILE" value="${LEVEL}.o"/>
<property name="LIBFILE" value="${LEVEL}.library"/>
<property name="MAPFILE" value="${LEVEL}.map"/>
<property name="ARFILE" value="${LEVEL}.a"/>
<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 file="exttools.cfg"/>
<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}"/>
<propertyfile file="build.temp">
<entry key="COMPILE_EXEC" value="${COMPILE_COMMAND}"/>
<entry key="COMPILE_ARGS" value="${COMPILE_COMMAND}"/>
<entry key="LINKER_EXEC" value="${LINKER_COMMAND}"/>
<entry key="LINKER_ARGS" value="${LINKER_COMMAND}"/>
</propertyfile>
<replace file="build.temp" token="$(JAVA_HOME)" value="${env.JAVA_HOME}"/>
<replace file="build.temp" token="$(LIBFILE)" value="${LIBFILE}"/>
<replace file="build.temp" token="$(MAPFILE)" value="${MAPFILE}"/>
<replace file="build.temp" token="$(ARFILE)" value="${ARFILE}"/>
<replaceregexp
file="build.temp" match="COMPILE_EXEC=(\w*).*"
replace="COMPILE_EXEC=\1" byline="true"/>
<replaceregexp
file="build.temp" match="COMPILE_ARGS=\w*(.*)"
replace="COMPILE_ARGS=\1" byline="true"/>
<replaceregexp
file="build.temp" match="LINKER_EXEC=(\w*).*"
replace="LINKER_EXEC=\1" byline="true"/>
<replaceregexp
file="build.temp" match="LINKER_ARGS=\w*(.*)"
replace="LINKER_ARGS=\1" byline="true"/>
<property file="build.temp"/>
<propertyfile file="build.temp">
<entry key="COMPILE_EXEC" value="${COMPILE_COMMAND}"/>
<entry key="COMPILE_ARGS" value="${COMPILE_COMMAND}"/>
<entry key="LINKER_EXEC" value="${LINKER_COMMAND}"/>
<entry key="LINKER_ARGS" value="${LINKER_COMMAND}"/>
</propertyfile>
<replace file="build.temp" token="$(JAVA_HOME)" value="${env.JAVA_HOME}"/>
<replace file="build.temp" token="$(LIBFILE)" value="${LIBFILE}"/>
<replace file="build.temp" token="$(MAPFILE)" value="${MAPFILE}"/>
<replace file="build.temp" token="$(ARFILE)" value="${ARFILE}"/>
<replaceregexp
file="build.temp" match="COMPILE_EXEC=(\w*).*"
replace="COMPILE_EXEC=\1" byline="true"/>
<replaceregexp
file="build.temp" match="COMPILE_ARGS=\w*(.*)"
replace="COMPILE_ARGS=\1" byline="true"/>
<replaceregexp
file="build.temp" match="LINKER_EXEC=(\w*).*"
replace="LINKER_EXEC=\1" byline="true"/>
<replaceregexp
file="build.temp" match="LINKER_ARGS=\w*(.*)"
replace="LINKER_ARGS=\1" byline="true"/>
<property file="build.temp"/>
<echo message="EXECUTING: ${COMPILE_EXEC} ${COMPILE_ARGS}"/>
<exec dir="${LEVEL}" executable="${COMPILE_EXEC}" failonerror="true">
<arg line="${COMPILE_ARGS}"/>
</exec>
<echo message="EXECUTING: ${LINKER_EXEC} ${LINKER_ARGS}"/>
<exec dir="${LEVEL}" executable="${LINKER_EXEC}" failonerror="true">
<arg line="${LINKER_ARGS}"/>
</exec>
</target>
<exec dir="${LEVEL}" executable="${COMPILE_EXEC}" failonerror="true">
<arg line="${COMPILE_ARGS}"/>
</exec>
<echo message="EXECUTING: ${LINKER_EXEC} ${LINKER_ARGS}"/>
<exec dir="${LEVEL}" executable="${LINKER_EXEC}" failonerror="true">
<arg line="${LINKER_ARGS}"/>
</exec>
</target>
<target name="compile_cooja" depends="init">
<ant dir="../../" antfile="build.xml" target="jar"/>
</target>
<target name="level2" depends="init">
<property name="LEVEL" value="level2"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/>
<java fork="yes" dir="${LEVEL}" classname="Level2"/>
</target>
<target name="level2" depends="init">
<property name="LEVEL" value="level2"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/>
<java fork="yes" dir="${LEVEL}" classname="Level2"/>
</target>
<target name="level3" depends="init">
<property name="LEVEL" value="level3"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/>
<java fork="yes" dir="${LEVEL}" classname="Level3"/>
</target>
<target name="level3a" depends="init">
<property name="LEVEL" value="level3a"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level3a">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target>
<target name="level4" depends="init">
<property name="LEVEL" value="level4"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/>
<java fork="yes" dir="${LEVEL}" classname="Level4"/>
</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 name="level4" depends="init">
<property name="LEVEL" value="level4"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level4">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target>
<target name="level5" depends="init">
<property name="LEVEL" value="level5"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}"/>
<java fork="yes" dir="${LEVEL}" classname="Level5"/>
</target>
<property name="LEVEL" value="level5"/>
<antcall target="compile_library" inheritall="true"/>
<javac srcdir="${LEVEL}" destdir="${LEVEL}" classpath="../../dist/cooja.jar"/>
<java fork="yes" dir="${LEVEL}" classname="Level5">
<classpath>
<pathelement location="../../dist/cooja.jar"/>
<pathelement location="${LEVEL}"/>
</classpath>
</java>
</target>
</project>

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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.*;
@ -34,15 +34,14 @@ import java.io.*;
public class Level2 {
static {
System.err.println("JAVA Level2 static> loading library now");
System.out.println("Loading library now");
System.load(new File("level2.library").getAbsolutePath());
System.err.println("JAVA Level2 static> done loading library");
}
private native void test();
public Level2() {
System.err.println("JAVA Level2 constructor()> running native test function");
System.err.println("Calling native test function");
test();
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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>
@ -35,6 +35,6 @@
JNIEXPORT void JNICALL
Java_Level2_test(JNIEnv *env, jobject obj)
{
fprintf(stderr, "C test()> Level 2 OK!\n");
fprintf(stderr, "Level 2 OK!\n");
fflush(stderr);
}

View file

@ -26,63 +26,138 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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.util.Properties;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.xml.DOMConfigurator;
import se.sics.cooja.GUI;
import se.sics.cooja.contikimote.ContikiMoteType;
public class Level4 {
private final File externalToolsSettingsFile = new File("../exttools.cfg");
static {
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 int getRefAddress();
public Level4() {
File mapFile = new File("level4.map");
// Configure logger
DOMConfigurator.configure(GUI.class.getResource("/" + GUI.LOG_CONFIG_FILE));
// Check that map file exists
if (!mapFile.exists()) {
System.err.println("No map file could be loaded");
// 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()) {
System.err.println("No map file could be loaded");
System.exit(1);
}
Vector<String> mapData = ContikiMoteType.loadMapFile(mapFile);
if (mapData == null) {
System.err.println("No map data could be loaded");
System.exit(1);
}
boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
if (!parseOK) {
System.err.println("Map data parsing failed");
System.exit(1);
}
relDataSectionAddr = ContikiMoteType.loadRelDataSectionAddr(mapData);
dataSectionSize = ContikiMoteType.loadDataSectionSize(mapData);
relBssSectionAddr = ContikiMoteType.loadRelBssSectionAddr(mapData);
bssSectionSize = ContikiMoteType.loadBssSectionSize(mapData);
}
String varName;
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);
}
Vector<String> mapContents = loadMapFile(mapFile);
int relDataSectionAddr = loadRelDataSectionAddr(mapContents);
int dataSectionSize = (int) loadDataSectionSize(mapContents);
int relBssSectionAddr = loadRelBssSectionAddr(mapContents);
int bssSectionSize = (int) loadBssSectionSize(mapContents);
int referenceAddress = getRefAddress();
System.err.println("Reference address: 0x" + Integer.toHexString(referenceAddress));
int offsetRelToAbs = referenceAddress - getRelVarAddr(mapContents, "ref_var");
System.err.println("Offset relative-absolute: 0x" + Integer.toHexString(offsetRelToAbs));
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();
@ -93,82 +168,6 @@ public class Level4 {
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) {
new Level4();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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>
@ -40,8 +40,8 @@ int uninitialized_counter;
JNIEXPORT void JNICALL
Java_Level4_doCount(JNIEnv *env, jobject obj)
{
fprintf(stderr, ">> DATA_counter=\t%i\tBSS_counter=\t%i\n", initialized_counter++, uninitialized_counter++);
fflush(stderr);
printf(">> DATA_counter=\t%i\tBSS_counter=\t%i\n", initialized_counter++, uninitialized_counter++);
fflush(stdout);
}
JNIEXPORT jint JNICALL
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
* 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.util.Properties;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.xml.DOMConfigurator;
import se.sics.cooja.GUI;
import se.sics.cooja.SectionMoteMemory;
import se.sics.cooja.contikimote.ContikiMoteType;
public class Level5 {
private final File externalToolsSettingsFile = new File("../exttools.cfg");
static {
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 int getRefAddress();
private native byte[] getMemory(int start, int length);
private native void setMemory(int start, int length, byte[] mem);
public native void getMemory(int start, int length, byte[] mem);
public native void setMemory(int start, int length, byte[] mem);
private int javaDataCounter = 1;
private int javaBssCounter = 0;
public Level5() {
File mapFile = new File("level5.map");
// Check that map file exists
if (!mapFile.exists()) {
System.err.println("No map file could be loaded");
// 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()) {
System.err.println("No map file could be loaded");
System.exit(1);
}
Vector<String> mapData = ContikiMoteType.loadMapFile(mapFile);
if (mapData == null) {
System.err.println("No map data could be loaded");
System.exit(1);
}
boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
if (!parseOK) {
System.err.println("Map data parsing failed");
System.exit(1);
}
relDataSectionAddr = ContikiMoteType.loadRelDataSectionAddr(mapData);
dataSectionSize = ContikiMoteType.loadDataSectionSize(mapData);
relBssSectionAddr = ContikiMoteType.loadRelBssSectionAddr(mapData);
bssSectionSize = ContikiMoteType.loadBssSectionSize(mapData);
}
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!");
}
System.out.println("Increasing counters 5 times");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
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!");
}
Vector<String> mapContents = loadMapFile(mapFile);
System.out.println("Storing both memory segments now");
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);
int relDataSectionAddr = loadRelDataSectionAddr(mapContents);
int dataSectionSize = (int) loadDataSectionSize(mapContents);
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++;
System.out.println("Increasing counters 3 times");
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) {
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;
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!");
}
return mapContents;
}
private static int loadRelDataSectionAddr(Vector<String> mapFile) {
String retString = getFirstMatchGroup(mapFile, dataSectionAddrRegExp, 1);
System.out.println("Restoring data segment");
setMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, savedDataSection);
javaDataCounter = savedDataCounter;
if (retString != null)
return Integer.parseInt(retString.trim(), 16);
else return 0;
}
System.out.println("Increasing counters 3 times");
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
doCount(); javaDataCounter++; javaBssCounter++;
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);
}
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!");
}
return null;
}
System.out.println("Restoring bss segment");
setMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, savedBssSection);
javaBssCounter = savedBssCounter;
System.out.print("Checking reset bss 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!");
}
System.out.println("\n");
System.out.println("Reading and writing memory segments via JNI successfully");
System.out.println("Level 5 OK!");
}
public static void main(String[] args) {
new Level5();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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>
@ -41,8 +41,8 @@ int uninitialized_counter;
JNIEXPORT void JNICALL
Java_Level5_doCount(JNIEnv *env, jobject obj)
{
fprintf(stderr, ">> DATA_counter=\t%i\tBSS_counter=\t%i\n", ++initialized_counter, ++uninitialized_counter);
fflush(stderr);
printf(">> DATA_counter=\t%i\tBSS_counter=\t%i\n", ++initialized_counter, ++uninitialized_counter);
fflush(stdout);
}
JNIEXPORT jint JNICALL
Java_Level5_getRefAddress(JNIEnv *env, jobject obj)
@ -50,13 +50,10 @@ Java_Level5_getRefAddress(JNIEnv *env, jobject obj)
return (jint) &ref_var;
}
JNIEXPORT jbyteArray JNICALL
Java_Level5_getMemory(JNIEnv *env, jobject obj, jint start, jint length)
JNIEXPORT void JNICALL
Java_Level5_getMemory(JNIEnv *env, jobject obj, jint start, jint length, jbyteArray mem_arr)
{
jbyteArray ret=(*env)->NewByteArray(env, length);
(*env)->SetByteArrayRegion(env, ret, 0, (size_t) length, (jbyte *) start);
return (ret);
(*env)->SetByteArrayRegion(env, mem_arr, 0, (size_t) length, (jbyte *) start);
}
JNIEXPORT void JNICALL