[cooja] ContikiMoteType: Introduce abstract SectionParser

Should encapsulate and decrease both redundancy and code duplication
This commit is contained in:
Enrico Joerns 2014-07-29 21:21:39 +02:00
parent f4979ffeeb
commit c5ff3555a0
2 changed files with 270 additions and 332 deletions

View File

@ -43,6 +43,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Vector; import java.util.Vector;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -72,6 +73,7 @@ import org.contikios.cooja.mote.memory.ArrayMemory;
import org.contikios.cooja.mote.memory.MemoryInterface; import org.contikios.cooja.mote.memory.MemoryInterface;
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; import org.contikios.cooja.mote.memory.MemoryInterface.Symbol;
import org.contikios.cooja.mote.memory.MemoryLayout; import org.contikios.cooja.mote.memory.MemoryLayout;
import org.contikios.cooja.mote.memory.UnknownVariableException;
import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.mote.memory.VarMemory;
import org.contikios.cooja.util.StringUtils; import org.contikios.cooja.util.StringUtils;
@ -405,38 +407,35 @@ public class ContikiMoteType implements MoteType {
*/ */
boolean useCommand = Boolean.parseBoolean(Cooja.getExternalToolsSetting("PARSE_WITH_COMMAND", "false")); boolean useCommand = Boolean.parseBoolean(Cooja.getExternalToolsSetting("PARSE_WITH_COMMAND", "false"));
int dataSectionRelAddr = -1, dataSectionSize = -1; SectionParser dataSecParser;
int bssSectionRelAddr = -1, bssSectionSize = -1; SectionParser bssSecParser;
int commonSectionRelAddr = -1, commonSectionSize = -1; SectionParser commonSecParser;
int readonlySectionRelAddr = -1, readonlySectionSize = -1; SectionParser readonlySecParser = null;
HashMap<String, Symbol> addresses = new HashMap<String, Symbol>(); HashMap<String, Symbol> variables = new HashMap<>();
if (useCommand) { if (useCommand) {
/* Parse command output */ /* Parse command output */
String[] output = loadCommandData(getContikiFirmwareFile()); String[] output = loadCommandData(getContikiFirmwareFile());
if (output == null) { if (output == null) {
throw new MoteTypeCreationException("No parse command output loaded"); throw new MoteTypeCreationException("No parse command output loaded");
} }
boolean parseOK = parseCommandData(output, addresses);
if (!parseOK) {
logger.fatal("Command output parsing failed");
throw new MoteTypeCreationException("Command output parsing failed");
}
dataSectionRelAddr = parseCommandDataSectionAddr(output); dataSecParser = new CommandSectionParser(
dataSectionSize = parseCommandDataSectionSize(output); output,
bssSectionRelAddr = parseCommandBssSectionAddr(output); Cooja.getExternalToolsSetting("COMMAND_DATA_START"),
bssSectionSize = parseCommandBssSectionSize(output); Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE"));
commonSectionRelAddr = parseCommandCommonSectionAddr(output); bssSecParser = new CommandSectionParser(
commonSectionSize = parseCommandCommonSectionSize(output); output,
Cooja.getExternalToolsSetting("COMMAND_BSS_START"),
try { Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE"));
readonlySectionRelAddr = parseCommandReadonlySectionAddr(output); commonSecParser = new CommandSectionParser(
readonlySectionSize = parseCommandReadonlySectionSize(output); output,
} catch (Exception e) { Cooja.getExternalToolsSetting("COMMAND_COMMON_START"),
readonlySectionRelAddr = -1; Cooja.getExternalToolsSetting("COMMAND_COMMON_SIZE"));
readonlySectionSize = -1; readonlySecParser = new CommandSectionParser(
} output,
Cooja.getExternalToolsSetting("^([0-9A-Fa-f]*)[ \t]t[ \t].text$"),
Cooja.getExternalToolsSetting("")); // XXX
} else { } else {
/* Parse map file */ /* Parse map file */
@ -449,63 +448,32 @@ public class ContikiMoteType implements MoteType {
logger.fatal("No map data could be loaded"); logger.fatal("No map data could be loaded");
throw new MoteTypeCreationException("No map data could be loaded: " + mapFile); throw new MoteTypeCreationException("No map data could be loaded: " + mapFile);
} }
boolean parseOK = parseMapFileData(mapData, addresses);
if (!parseOK) {
logger.fatal("Map data parsing failed");
throw new MoteTypeCreationException("Map data parsing failed: " + mapFile);
}
dataSectionRelAddr = parseMapDataSectionAddr(mapData); dataSecParser = new MapSectionParser(
dataSectionSize = parseMapDataSectionSize(mapData); mapData,
bssSectionRelAddr = parseMapBssSectionAddr(mapData); Cooja.getExternalToolsSetting("MAPFILE_DATA_START"),
bssSectionSize = parseMapBssSectionSize(mapData); Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE"));
commonSectionRelAddr = parseMapCommonSectionAddr(mapData); bssSecParser = new MapSectionParser(
commonSectionSize = parseMapCommonSectionSize(mapData); mapData,
readonlySectionRelAddr = -1; Cooja.getExternalToolsSetting("MAPFILE_BSS_START"),
readonlySectionSize = -1; Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE"));
commonSecParser = new MapSectionParser(
mapData,
Cooja.getExternalToolsSetting("MAPFILE_COMMON_START"),
Cooja.getExternalToolsSetting("MAPFILE_COMMON_SIZE"));
readonlySecParser = null;
} }
if (dataSectionRelAddr >= 0) {
logger.info(getContikiFirmwareFile().getName()
+ ": data section at 0x" + Integer.toHexString(dataSectionRelAddr)
+ " (" + dataSectionSize + " == 0x" + Integer.toHexString(dataSectionSize) + " bytes)");
} else {
logger.fatal(getContikiFirmwareFile().getName() + ": no data section found");
}
if (bssSectionRelAddr >= 0) {
logger.info(getContikiFirmwareFile().getName()
+ ": BSS section at 0x" + Integer.toHexString(bssSectionRelAddr)
+ " (" + bssSectionSize + " == 0x" + Integer.toHexString(bssSectionSize) + " bytes)");
} else {
logger.fatal(getContikiFirmwareFile().getName() + ": no BSS section found");
}
if (commonSectionRelAddr >= 0) {
logger.info(getContikiFirmwareFile().getName()
+ ": common section at 0x" + Integer.toHexString(commonSectionRelAddr)
+ " (" + commonSectionSize + " == 0x" + Integer.toHexString(commonSectionSize) + " bytes)");
} else {
logger.info(getContikiFirmwareFile().getName() + ": no common section found");
}
if (readonlySectionRelAddr >= 0) {
logger.info(getContikiFirmwareFile().getName()
+ ": readonly section at 0x" + Integer.toHexString(readonlySectionRelAddr)
+ " (" + readonlySectionSize + " == 0x" + Integer.toHexString(readonlySectionSize) + " bytes)");
} else {
logger.warn(getContikiFirmwareFile().getName() + ": no readonly section found");
}
if (addresses.isEmpty()) {
throw new MoteTypeCreationException("Library variables parsing failed");
}
if (dataSectionRelAddr <= 0 || dataSectionSize <= 0
|| bssSectionRelAddr <= 0 || bssSectionSize <= 0) {
throw new MoteTypeCreationException("Library section addresses parsing failed");
}
try { try {
Map<String, Symbol> vars = bssSecParser.getSymbols();
for (Symbol s : vars.values()) {
if (s.name.equals("referenceVar")) {
/* Relative <-> absolute addresses offset */ /* Relative <-> absolute addresses offset */
int referenceVar = (int) addresses.get("referenceVar").addr; int referenceVar = (int) s.addr;
myCoreComm.setReferenceAddress(referenceVar); myCoreComm.setReferenceAddress(referenceVar);
}
}
} catch (Exception e) { } catch (Exception e) {
throw new MoteTypeCreationException("JNI call error: " + e.getMessage(), e); throw new MoteTypeCreationException("JNI call error: " + e.getMessage(), e);
} }
@ -518,42 +486,185 @@ public class ContikiMoteType implements MoteType {
* Contiki's and Cooja's address spaces */ * Contiki's and Cooja's address spaces */
int offset; int offset;
{ {
SectionMoteMemory tmp = new SectionMoteMemory(addresses, 0); SectionMoteMemory tmp = new SectionMoteMemory(variables, 0);
VarMemory varMem = new VarMemory(tmp); VarMemory varMem = new VarMemory(tmp);
byte[] data = new byte[dataSectionSize]; tmp.addMemorySection("tmp.data", dataSecParser.parse());
getCoreMemory(dataSectionRelAddr, dataSectionSize, data);
tmp.addMemorySection("data", new ArrayMemory(dataSectionRelAddr, MemoryLayout.getNative(), data, null)); tmp.addMemorySection("tmp.bss", bssSecParser.parse());
byte[] bss = new byte[bssSectionSize];
getCoreMemory(bssSectionRelAddr, bssSectionSize, bss); try {
tmp.addMemorySection("bss", new ArrayMemory(bssSectionRelAddr, MemoryLayout.getNative(), bss, null)); int referenceVar = (int) varMem.getVariable("referenceVar").addr;
myCoreComm.setReferenceAddress(referenceVar);
} catch (UnknownVariableException e) {
throw new MoteTypeCreationException("JNI call error: " + e.getMessage(), e);
}
getCoreMemory(tmp);
offset = varMem.getIntValueOf("referenceVar"); offset = varMem.getIntValueOf("referenceVar");
logger.info(getContikiFirmwareFile().getName() logger.info(getContikiFirmwareFile().getName()
+ ": offsetting Cooja mote address space: " + offset); + ": offsetting Cooja mote address space: " + Long.toHexString(offset));
} }
/* Create initial memory: data+bss+optional common */ /* Create initial memory: data+bss+optional common */
initialMemory = new SectionMoteMemory(addresses, offset); initialMemory = new SectionMoteMemory(variables, offset);
byte[] initialDataSection = new byte[dataSectionSize]; initialMemory.addMemorySection("data", dataSecParser.parse());
getCoreMemory(dataSectionRelAddr, dataSectionSize, initialDataSection);
initialMemory.addMemorySection("data", new ArrayMemory(dataSectionRelAddr, MemoryLayout.getNative(), initialDataSection, null));
byte[] initialBssSection = new byte[bssSectionSize]; initialMemory.addMemorySection("bss", bssSecParser.parse());
getCoreMemory(bssSectionRelAddr, bssSectionSize, initialBssSection);
initialMemory.addMemorySection("bss", new ArrayMemory(bssSectionRelAddr, MemoryLayout.getNative(), initialBssSection, null));
if (commonSectionRelAddr >= 0 && commonSectionSize > 0) { initialMemory.addMemorySection("common", commonSecParser.parse());
byte[] initialCommonSection = new byte[commonSectionSize];
getCoreMemory(commonSectionRelAddr, commonSectionSize, initialCommonSection); if (readonlySecParser != null) {
initialMemory.addMemorySection("common", new ArrayMemory(commonSectionRelAddr, MemoryLayout.getNative(), initialCommonSection, null)); initialMemory.addMemorySection("readonly", readonlySecParser.parse());
} }
/* Read "read-only" memory */ getCoreMemory(initialMemory);
if (readonlySectionRelAddr >= 0 && readonlySectionSize > 0) { }
byte[] readonlySection = new byte[readonlySectionSize];
getCoreMemory(readonlySectionRelAddr, readonlySectionSize, readonlySection); public static abstract class SectionParser {
initialMemory.addMemorySection("readonly", new ArrayMemory(readonlySectionRelAddr, MemoryLayout.getNative(), readonlySection, true, null));
private final String[] mapFileData;
public SectionParser(String[] mapFileData) {
this.mapFileData = mapFileData;
}
public String[] getData() {
return mapFileData;
}
public abstract int parseAddr();
public abstract int parseSize();
abstract Map<String, Symbol> getSymbols();
protected int parseFirstHexInt(String regexp, String[] data) {
String retString = getFirstMatchGroup(data, regexp, 1);
if (retString == null || retString.equals("")) {
return -1;
}
return Integer.parseInt(retString.trim(), 16);
}
public MemoryInterface parse() {
int mapSectionAddr = parseAddr();
int mapSectionSize = parseSize();
if (mapSectionAddr < 0 || mapSectionSize <= 0) {
return null;
}
Map<String, Symbol> variables = getMapFileVarsInRange(
getData(),
mapSectionAddr,
mapSectionAddr + mapSectionSize);
if (variables == null || variables.isEmpty()) {
logger.warn("Map data symbol parsing failed");
}
logger.info(String.format("Parsed section at 0x%x ( %d == 0x%x bytes)",
// getContikiFirmwareFile().getName(),
mapSectionAddr,
mapSectionSize,
mapSectionSize));
return new ArrayMemory(
mapSectionAddr,
mapSectionSize,
MemoryLayout.getNative(),
variables);
}
}
/**
* Parses Map file for seciton data.
*/
public static class MapSectionParser extends SectionParser {
private final String startRegExp;
private final String sizeRegExp;
public MapSectionParser(String[] mapFileData, String startRegExp, String sizeRegExp) {
super(mapFileData);
this.startRegExp = startRegExp;
this.sizeRegExp = sizeRegExp;
}
@Override
public int parseAddr() {
if (startRegExp == null) {
return -1;
}
return parseFirstHexInt(startRegExp, getData());
}
@Override
public int parseSize() {
if (sizeRegExp == null) {
return -1;
}
return parseFirstHexInt(sizeRegExp, getData());
}
@Override
public Map<String, Symbol> getSymbols() {
return getMapFileVarsInRange(
getData(),
parseAddr(),
parseAddr() + parseSize());
}
}
/**
* Parses command output for section data.
*/
public static class CommandSectionParser extends SectionParser {
private final String startRegExp;
private final String sizeRegExp;
public CommandSectionParser(String[] mapFileData, String startRegExp, String sizeRegExp) {
super(mapFileData);
this.startRegExp = startRegExp;
this.sizeRegExp = sizeRegExp;
}
@Override
public int parseAddr() {
if (startRegExp == null) {
return -1;
}
return parseFirstHexInt(startRegExp, getData());
}
@Override
public int parseSize() {
if (sizeRegExp == null) {
return -1;
}
int start = parseAddr();
if (start < 0) {
return -1;
}
int end = parseFirstHexInt(sizeRegExp, getData());
if (end < 0) {
return -1;
}
return end - start;
}
@Override
public Map<String, Symbol> getSymbols() {
return parseCommandVariables(getData());
} }
} }
@ -610,46 +721,19 @@ public class ContikiMoteType implements MoteType {
myCoreComm.setMemory(relAddr, length, mem); myCoreComm.setMemory(relAddr, length, mem);
} }
/**
* Parses specified map file data for variable name to addresses mappings. The
* mappings are added to the given properties object.
*
* @param mapFileData
* Contents of entire map file
* @param varAddresses
* Properties that should contain the name to addresses mappings.
*/
public static boolean parseMapFileData(String[] mapFileData, HashMap<String, Symbol> varAddresses) {
String[] varNames = getMapFileVarNames(mapFileData);
if (varNames == null || varNames.length == 0) {
return false;
}
for (String varName : varNames) {
int varAddress = getMapFileVarAddress(mapFileData, varName);
if (varAddress > 0) {
varAddresses.put(varName, new Symbol(Symbol.Type.VARIABLE, varName, varAddress, 1));
} else {
logger.warn("Parsed Contiki variable '" + varName
+ "' but could not find address");
}
}
return true;
}
/** /**
* Parses parse command output for variable name to addresses mappings. * Parses parse command output for variable name to addresses mappings.
* The mappings are written to the given properties object. * The mappings are written to the given properties object.
* *
* TODO: need InRange version!
*
* @param output Command output * @param output Command output
* @param addresses Variable addresses mappings * @return
*/ */
public static boolean parseCommandData(String[] output, HashMap<String, Symbol> addresses) { public static Map<String, Symbol> parseCommandVariables(String[] output) {
int nrNew = 0, nrOld = 0, nrMismatch = 0; int nrNew = 0, nrOld = 0, nrMismatch = 0;
HashMap<String, Symbol> addresses = new HashMap<>();
Pattern pattern Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS"));
= Pattern.compile(Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS"));
for (String line : output) { for (String line : output) {
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
@ -659,6 +743,7 @@ public class ContikiMoteType implements MoteType {
String symbol = matcher.group(2); String symbol = matcher.group(2);
int address = Integer.parseInt(matcher.group(1), 16); int address = Integer.parseInt(matcher.group(1), 16);
/* XXX needs to be checked */
if (!addresses.containsKey(symbol)) { if (!addresses.containsKey(symbol)) {
nrNew++; nrNew++;
addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, address, 1)); addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, address, 1));
@ -682,7 +767,7 @@ public class ContikiMoteType implements MoteType {
logger.debug("Command response parsing summary: Added " + nrNew logger.debug("Command response parsing summary: Added " + nrNew
+ " variables. Found " + nrOld + " old variables"); + " variables. Found " + nrOld + " old variables");
}*/ }*/
return (nrNew + nrOld) > 0; return addresses;
} }
@Override @Override
@ -754,6 +839,9 @@ public class ContikiMoteType implements MoteType {
} }
private static String getFirstMatchGroup(String[] lines, String regexp, int groupNr) { private static String getFirstMatchGroup(String[] lines, String regexp, int groupNr) {
if (regexp == null) {
return null;
}
Pattern pattern = Pattern.compile(regexp); Pattern pattern = Pattern.compile(regexp);
for (String line : lines) { for (String line : lines) {
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
@ -764,34 +852,11 @@ public class ContikiMoteType implements MoteType {
return null; return null;
} }
/** private static Map<String, Symbol> getMapFileVarsInRange(
* Returns all variable names in both data and BSS section by parsing the map String[] lines,
* file. These values should not be trusted completely as the parsing may int startAddress,
* fail. int endAddress) {
* Map<String, Symbol> varNames = new HashMap<>();
* @return Variable names found in the data and bss section
*/
public static String[] getMapFileVarNames(String[] mapFileData) {
ArrayList<String> varNames = new ArrayList<>();
String[] dataVariables = getAllVariableNames(
mapFileData,
parseMapDataSectionAddr(mapFileData),
parseMapDataSectionAddr(mapFileData) + parseMapDataSectionSize(mapFileData));
varNames.addAll(Arrays.asList(dataVariables));
String[] bssVariables = getAllVariableNames(
mapFileData,
parseMapBssSectionAddr(mapFileData),
parseMapBssSectionAddr(mapFileData) + parseMapBssSectionSize(mapFileData));
varNames.addAll(Arrays.asList(bssVariables));
return varNames.toArray(new String[0]);
}
private static String[] getAllVariableNames(String[] lines,
int startAddress, int endAddress) {
ArrayList<String> varNames = new ArrayList<>();
Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("MAPFILE_VAR_NAME")); Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("MAPFILE_VAR_NAME"));
for (String line : lines) { for (String line : lines) {
@ -799,11 +864,16 @@ public class ContikiMoteType implements MoteType {
if (matcher.find()) { if (matcher.find()) {
if (Integer.decode(matcher.group(1)).intValue() >= startAddress if (Integer.decode(matcher.group(1)).intValue() >= startAddress
&& Integer.decode(matcher.group(1)).intValue() <= endAddress) { && Integer.decode(matcher.group(1)).intValue() <= endAddress) {
varNames.add(matcher.group(2)); String varName = matcher.group(2);
varNames.put(varName, new Symbol(
Symbol.Type.VARIABLE,
varName,
getMapFileVarAddress(lines, varName),
getMapFileVarSize(lines, varName)));
} }
} }
} }
return varNames.toArray(new String[0]); return varNames;
} }
/** /**
@ -841,156 +911,6 @@ public class ContikiMoteType implements MoteType {
return -1; return -1;
} }
private static int parseFirstHexInt(String regexp, String[] data) {
String retString
= getFirstMatchGroup(data, regexp, 1);
if (retString != null) {
return Integer.parseInt(retString.trim(), 16);
} else {
return -1;
}
}
public static int parseMapDataSectionAddr(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_DATA_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapDataSectionSize(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapBssSectionAddr(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_BSS_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapBssSectionSize(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapCommonSectionAddr(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_COMMON_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapCommonSectionSize(String[] mapFileData) {
String regexp = Cooja.getExternalToolsSetting("MAPFILE_COMMON_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseCommandDataSectionAddr(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_DATA_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, output);
}
public static int parseCommandDataSectionSize(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_DATA_END", "");
if (regexp.equals("")) {
return -1;
}
int start = parseCommandDataSectionAddr(output);
if (start < 0) {
return -1;
}
int end = parseFirstHexInt(regexp, output);
if (end < 0) {
return -1;
}
return end - start;
}
public static int parseCommandBssSectionAddr(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_BSS_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, output);
}
public static int parseCommandBssSectionSize(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_BSS_END", "");
if (regexp.equals("")) {
return -1;
}
int start = parseCommandBssSectionAddr(output);
if (start < 0) {
return -1;
}
int end = parseFirstHexInt(regexp, output);
if (end < 0) {
return -1;
}
return end - start;
}
public static int parseCommandCommonSectionAddr(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_COMMON_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, output);
}
public static int parseCommandCommonSectionSize(String[] output) {
String regexp = Cooja.getExternalToolsSetting("COMMAND_COMMON_END", "");
if (regexp.equals("")) {
return -1;
}
int start = parseCommandCommonSectionAddr(output);
if (start < 0) {
return -1;
}
int end = parseFirstHexInt(regexp, output);
if (end < 0) {
return -1;
}
return end - start;
}
private static int parseCommandReadonlySectionAddr(String[] output) {
return parseFirstHexInt("^([0-9A-Fa-f]*)[ \t]t[ \t].text$", output);
}
private static int parseCommandReadonlySectionSize(String[] output) {
int start = parseCommandReadonlySectionAddr(output);
if (start < 0) {
return -1;
}
/* Extract the last specified address, assuming that the interval covers all the memory */
String last = output[output.length - 1];
int lastAddress = Integer.parseInt(last.split("[ \t]")[0], 16);
return lastAddress - start;
}
private static int getRelVarAddr(String mapFileData[], String varName) { private static int getRelVarAddr(String mapFileData[], String varName) {
String regExp String regExp
= Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") = Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1")

View File

@ -68,6 +68,7 @@ import org.contikios.cooja.Cooja;
import org.contikios.cooja.MoteType.MoteTypeCreationException; import org.contikios.cooja.MoteType.MoteTypeCreationException;
import org.contikios.cooja.mote.memory.SectionMoteMemory; import org.contikios.cooja.mote.memory.SectionMoteMemory;
import org.contikios.cooja.contikimote.ContikiMoteType; import org.contikios.cooja.contikimote.ContikiMoteType;
import org.contikios.cooja.contikimote.ContikiMoteType.SectionParser;
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol; import org.contikios.cooja.mote.memory.MemoryInterface.Symbol;
import org.contikios.cooja.mote.memory.VarMemory; import org.contikios.cooja.mote.memory.VarMemory;
@ -760,17 +761,25 @@ public class ConfigurationWizard extends JDialog {
testOutput.addMessage("### Parsing map file data for addresses"); testOutput.addMessage("### Parsing map file data for addresses");
addresses = new HashMap<String, Symbol>(); addresses = new HashMap<String, Symbol>();
boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses); // boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
if (!parseOK) { // if (!parseOK) {
testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR); // testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR);
return false; // return false;
} // }
testOutput.addMessage("### Validating section addresses"); testOutput.addMessage("### Validating section addresses");
relDataSectionAddr = ContikiMoteType.parseMapDataSectionAddr(mapData); SectionParser dataSecParser = new ContikiMoteType.MapSectionParser(
dataSectionSize = ContikiMoteType.parseMapDataSectionSize(mapData); mapData,
relBssSectionAddr = ContikiMoteType.parseMapBssSectionAddr(mapData); Cooja.getExternalToolsSetting("MAPFILE_DATA_START"),
bssSectionSize = ContikiMoteType.parseMapBssSectionSize(mapData); Cooja.getExternalToolsSetting("MAPFILE_DATA_SIZE"));
SectionParser bssSecParser = new ContikiMoteType.MapSectionParser(
mapData,
Cooja.getExternalToolsSetting("MAPFILE_BSS_START"),
Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE"));
relDataSectionAddr = dataSecParser.parseAddr();
dataSectionSize = dataSecParser.parseSize();
relBssSectionAddr = bssSecParser.parseAddr();
bssSectionSize = bssSecParser.parseSize();
testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr));
testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize));
testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr));
@ -840,17 +849,26 @@ public class ConfigurationWizard extends JDialog {
testOutput.addMessage("### Parsing command output for addresses"); testOutput.addMessage("### Parsing command output for addresses");
addresses = new HashMap<String, Symbol>(); addresses = new HashMap<String, Symbol>();
boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses); // boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses);
if (!parseOK) { // if (!parseOK) {
testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR); // testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR);
return false; // return false;
} // }
testOutput.addMessage("### Validating section addresses"); testOutput.addMessage("### Validating section addresses");
relDataSectionAddr = ContikiMoteType.parseCommandDataSectionAddr(commandData); SectionParser dataSecParser = new ContikiMoteType.CommandSectionParser(
dataSectionSize = ContikiMoteType.parseCommandDataSectionSize(commandData); commandData,
relBssSectionAddr = ContikiMoteType.parseCommandBssSectionAddr(commandData); Cooja.getExternalToolsSetting("COMMAND_DATA_START"),
bssSectionSize = ContikiMoteType.parseCommandBssSectionSize(commandData); Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE"));
SectionParser bssSecParser = new ContikiMoteType.CommandSectionParser(
commandData,
Cooja.getExternalToolsSetting("COMMAND_BSS_START"),
Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE"));
relDataSectionAddr = dataSecParser.parseAddr();
dataSectionSize = dataSecParser.parseSize();
relBssSectionAddr = bssSecParser.parseAddr();
bssSectionSize = bssSecParser.parseSize();
testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr));
testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize));
testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr));