diff --git a/tools/cooja/config/external_tools.config b/tools/cooja/config/external_tools.config index 18ad0be46..89d9c4f7d 100644 --- a/tools/cooja/config/external_tools.config +++ b/tools/cooja/config/external_tools.config @@ -25,7 +25,6 @@ PATH_JAVAC = javac DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_socket;[CONTIKI_DIR]/tools/cooja/apps/collect-view;[CONTIKI_DIR]/tools/cooja/apps/powertracker PARSE_WITH_COMMAND=false -PARSE_COMMAND=nm -a $(LIBFILE) MAPFILE_DATA_START = ^.data[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$ MAPFILE_DATA_SIZE = ^.data[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$ MAPFILE_BSS_START = ^.bss[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$ @@ -35,11 +34,19 @@ MAPFILE_VAR_ADDRESS_1 = ^[ \t]*0x([0-9A-Fa-f]*)[ \t]* MAPFILE_VAR_ADDRESS_2 = [ \t]*$ MAPFILE_VAR_SIZE_1 = ^ MAPFILE_VAR_SIZE_2 = [ \t]*(0x[0-9A-Fa-f]*)[ \t]*[^ ]*[ \t]*$ -COMMAND_VAR_NAME_ADDRESS = ^([0-9A-Fa-f][0-9A-Fa-f]*)[ \t][^Tt][ \t]([^ ._][^ ]*) -COMMAND_DATA_START = ^([0-9A-Fa-f]*)[ \t]d[ \t].data$ -COMMAND_DATA_END = ^([0-9A-Fa-f]*)[ \t]A[ \t]_edata$ -COMMAND_BSS_START = ^([0-9A-Fa-f]*)[ \t]A[ \t]__bss_start$ -COMMAND_BSS_END = ^([0-9A-Fa-f]*)[ \t]A[ \t]_end$ + +PARSE_COMMAND=nm -aP $(LIBFILE) +COMMAND_VAR_NAME_ADDRESS_SIZE = ^([^.].*?)
([0-9a-fA-F]+) ([0-9a-fA-F])* +COMMAND_VAR_SEC_DATA = [DdGg] +COMMAND_VAR_SEC_BSS = [Bb] +COMMAND_VAR_SEC_COMMON = [C] +COMMAND_VAR_SEC_READONLY = [Rr] +COMMAND_DATA_START = ^.data[ \t]d[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_DATA_END = ^_edata[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_BSS_START = ^__bss_start[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_BSS_END = ^_end[ \t]A[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_READONLY_START = ^.rodata[ \t]r[ \t]([0-9A-Fa-f]*)[ \t]*$ +COMMAND_READONLY_END = ^.eh_frame_hdr[ \t]r[ \t]([0-9A-Fa-f]*)[ \t]*$ VISUALIZER_DEFAULT_SKINS=\ org.contikios.cooja.plugins.skins.IDVisualizerSkin;\ diff --git a/tools/cooja/java/org/contikios/cooja/Cooja.java b/tools/cooja/java/org/contikios/cooja/Cooja.java index 4d1770b6b..055cb46f4 100644 --- a/tools/cooja/java/org/contikios/cooja/Cooja.java +++ b/tools/cooja/java/org/contikios/cooja/Cooja.java @@ -274,7 +274,7 @@ public class Cooja extends Observable { "MAPFILE_VAR_SIZE_1", "MAPFILE_VAR_SIZE_2", "PARSE_COMMAND", - "COMMAND_VAR_NAME_ADDRESS", + "COMMAND_VAR_NAME_ADDRESS_SIZE", "COMMAND_DATA_START", "COMMAND_DATA_END", "COMMAND_BSS_START", "COMMAND_BSS_END", "COMMAND_COMMON_START", "COMMAND_COMMON_END", diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java index 46d94ddf9..f587003f0 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/ContikiMoteType.java @@ -51,6 +51,7 @@ import java.util.regex.Pattern; import javax.swing.JComponent; import javax.swing.JLabel; +import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jdom.Element; @@ -426,19 +427,24 @@ public class ContikiMoteType implements MoteType { dataSecParser = new CommandSectionParser( output, Cooja.getExternalToolsSetting("COMMAND_DATA_START"), - Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE")); + Cooja.getExternalToolsSetting("COMMAND_DATA_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_DATA")); bssSecParser = new CommandSectionParser( output, Cooja.getExternalToolsSetting("COMMAND_BSS_START"), - Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE")); + Cooja.getExternalToolsSetting("COMMAND_BSS_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_BSS")); commonSecParser = new CommandSectionParser( output, Cooja.getExternalToolsSetting("COMMAND_COMMON_START"), - Cooja.getExternalToolsSetting("COMMAND_COMMON_SIZE")); - readonlySecParser = new CommandSectionParser( + Cooja.getExternalToolsSetting("COMMAND_COMMON_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_COMMON")); + /* XXX Currently Cooja tries to sync readonly memory */ + readonlySecParser = null;/* new CommandSectionParser( output, - Cooja.getExternalToolsSetting("^([0-9A-Fa-f]*)[ \t]t[ \t].text$"), - Cooja.getExternalToolsSetting("")); // XXX + Cooja.getExternalToolsSetting("COMMAND_READONLY_START"), + Cooja.getExternalToolsSetting("COMMAND_READONLY_END"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_READONLY"));*/ } else { /* Parse map file */ @@ -526,11 +532,13 @@ public class ContikiMoteType implements MoteType { } /** - * + * Abstract base class for concrete section parser class. */ public static abstract class SectionParser { private final String[] mapFileData; + protected int startAddr; + protected int size; public SectionParser(String[] mapFileData) { this.mapFileData = mapFileData; @@ -540,9 +548,17 @@ public class ContikiMoteType implements MoteType { return mapFileData; } - public abstract int parseStartAddr(); + public int getStartAddr() { + return startAddr; + } - public abstract int parseSize(); + public int getSize() { + return size; + } + + protected abstract void parseStartAddr(); + + protected abstract void parseSize(); abstract Map parseSymbols(); @@ -559,24 +575,33 @@ public class ContikiMoteType implements MoteType { public MemoryInterface parse() { /* Parse start address and size of section */ - int mapSectionAddr = parseStartAddr(); - int mapSectionSize = parseSize(); + parseStartAddr(); + parseSize(); - if (mapSectionAddr < 0 || mapSectionSize <= 0) { + if (getStartAddr() < 0 || getSize() <= 0) { return null; } Map variables = parseSymbols(); logger.info(String.format("Parsed section at 0x%x ( %d == 0x%x bytes)", -// getContikiFirmwareFile().getName(), - mapSectionAddr, - mapSectionSize, - mapSectionSize)); + getStartAddr(), + getSize(), + getSize())); + + if (logger.isDebugEnabled()) { + for (String var : variables.keySet()) { + logger.debug(String.format("Found Symbol: %s, 0x%x, %d", + var, + variables.get(var).addr, + variables.get(var).size)); + } + } + return new ArrayMemory( - mapSectionAddr, - mapSectionSize, + getStartAddr(), + getSize(), MemoryLayout.getNative(), variables); } @@ -598,19 +623,21 @@ public class ContikiMoteType implements MoteType { } @Override - public int parseStartAddr() { - if (startRegExp == null) { - return -1; + protected void parseStartAddr() { + if (startRegExp == null || startRegExp.equals("")) { + startAddr = -1; + return; } - return parseFirstHexInt(startRegExp, getData()); + startAddr = parseFirstHexInt(startRegExp, getData()); } @Override - public int parseSize() { - if (sizeRegExp == null) { - return -1; + protected void parseSize() { + if (sizeRegExp == null || sizeRegExp.equals("")) { + size = -1; + return; } - return parseFirstHexInt(sizeRegExp, getData()); + size = parseFirstHexInt(sizeRegExp, getData()); } @Override @@ -621,8 +648,8 @@ public class ContikiMoteType implements MoteType { for (String line : getData()) { Matcher matcher = pattern.matcher(line); if (matcher.find()) { - if (Integer.decode(matcher.group(1)).intValue() >= parseStartAddr() - && Integer.decode(matcher.group(1)).intValue() <= parseStartAddr() + parseSize()) { + if (Integer.decode(matcher.group(1)).intValue() >= getStartAddr() + && Integer.decode(matcher.group(1)).intValue() <= getStartAddr() + getSize()) { String varName = matcher.group(2); varNames.put(varName, new Symbol( Symbol.Type.VARIABLE, @@ -685,59 +712,82 @@ public class ContikiMoteType implements MoteType { public static class CommandSectionParser extends SectionParser { private final String startRegExp; - private final String sizeRegExp; + private final String endRegExp; + private final String sectionRegExp; - public CommandSectionParser(String[] mapFileData, String startRegExp, String sizeRegExp) { + /** + * Creates SectionParser based on output of configurable command. + * + * @param mapFileData Map file lines as array of String + * @param startRegExp Regular expression for parsing start of section + * @param endRegExp Regular expression for parsing end of section + * @param sectionRegExp Reqular expression describing symbol table section identifier (e.g. '[Rr]' for readonly) + * Will be used to replaced '
'in 'COMMAND_VAR_NAME_ADDRESS_SIZE' + */ + public CommandSectionParser(String[] mapFileData, String startRegExp, String endRegExp, String sectionRegExp) { super(mapFileData); this.startRegExp = startRegExp; - this.sizeRegExp = sizeRegExp; + this.endRegExp = endRegExp; + this.sectionRegExp = sectionRegExp; } @Override - public int parseStartAddr() { - if (startRegExp == null) { - return -1; + protected void parseStartAddr() { + if (startRegExp == null || startRegExp.equals("")) { + startAddr = -1; + return; } - return parseFirstHexInt(startRegExp, getData()); + startAddr = parseFirstHexInt(startRegExp, getData()); } @Override - public int parseSize() { - if (sizeRegExp == null) { - return -1; + public void parseSize() { + if (endRegExp == null || endRegExp.equals("")) { + size = -1; + return; } - int start = parseStartAddr(); - if (start < 0) { - return -1; + if (getStartAddr() < 0) { + size = -1; + return; } - int end = parseFirstHexInt(sizeRegExp, getData()); + int end = parseFirstHexInt(endRegExp, getData()); if (end < 0) { - return -1; + size = -1; + return; } - return end - start; + size = end - getStartAddr(); } @Override public Map parseSymbols() { HashMap addresses = new HashMap<>(); - Pattern pattern = Pattern.compile(Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS")); + /* Replace "
" in regexp by section specific regex */ + Pattern pattern = Pattern.compile( + Cooja.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS_SIZE") + .replace("
", sectionRegExp)); for (String line : getData()) { Matcher matcher = pattern.matcher(line); if (matcher.find()) { /* Line matched variable address */ - String symbol = matcher.group(2); - int address = Integer.parseInt(matcher.group(1), 16); + String symbol = matcher.group(1); + int varAddr = Integer.parseInt(matcher.group(2), 16); + int varSize; + if (matcher.group(3) != null) { + varSize = Integer.parseInt(matcher.group(3), 16); + } else { + varSize = -1; + } /* XXX needs to be checked */ if (!addresses.containsKey(symbol)) { - addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, address, 1)); + addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, varAddr, varSize)); } else { int oldAddress = (int) addresses.get(symbol).addr; - if (oldAddress != address) { + if (oldAddress != varAddr) { /*logger.warn("Warning, command response not matching previous entry of: " + varName);*/ } diff --git a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java index cdb7ef8c3..340a3471f 100644 --- a/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java +++ b/tools/cooja/java/org/contikios/cooja/dialogs/ConfigurationWizard.java @@ -776,10 +776,12 @@ public class ConfigurationWizard extends JDialog { mapData, Cooja.getExternalToolsSetting("MAPFILE_BSS_START"), Cooja.getExternalToolsSetting("MAPFILE_BSS_SIZE")); - relDataSectionAddr = dataSecParser.parseStartAddr(); - dataSectionSize = dataSecParser.parseSize(); - relBssSectionAddr = bssSecParser.parseStartAddr(); - bssSectionSize = bssSecParser.parseSize(); + dataSecParser.parse(); + bssSecParser.parse(); + relDataSectionAddr = dataSecParser.getStartAddr(); + dataSectionSize = dataSecParser.getSize(); + relBssSectionAddr = bssSecParser.getStartAddr(); + bssSectionSize = bssSecParser.getSize(); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr)); @@ -859,16 +861,20 @@ public class ConfigurationWizard extends JDialog { SectionParser dataSecParser = new ContikiMoteType.CommandSectionParser( commandData, Cooja.getExternalToolsSetting("COMMAND_DATA_START"), - Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE")); + Cooja.getExternalToolsSetting("COMMAND_DATA_SIZE"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_DATA")); SectionParser bssSecParser = new ContikiMoteType.CommandSectionParser( commandData, Cooja.getExternalToolsSetting("COMMAND_BSS_START"), - Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE")); + Cooja.getExternalToolsSetting("COMMAND_BSS_SIZE"), + Cooja.getExternalToolsSetting("COMMAND_VAR_SEC_BSS")); - relDataSectionAddr = dataSecParser.parseStartAddr(); - dataSectionSize = dataSecParser.parseSize(); - relBssSectionAddr = bssSecParser.parseStartAddr(); - bssSectionSize = bssSecParser.parseSize(); + dataSecParser.parse(); + bssSecParser.parse(); + relDataSectionAddr = dataSecParser.getStartAddr(); + dataSectionSize = dataSecParser.getSize(); + relBssSectionAddr = bssSecParser.getStartAddr(); + bssSectionSize = bssSecParser.getSize(); testOutput.addMessage("Data section address: 0x" + Integer.toHexString(relDataSectionAddr)); testOutput.addMessage("Data section size: 0x" + Integer.toHexString(dataSectionSize)); testOutput.addMessage("BSS section address: 0x" + Integer.toHexString(relBssSectionAddr));