diff --git a/java/org/contikios/cooja/contikimote/ContikiMoteType.java b/java/org/contikios/cooja/contikimote/ContikiMoteType.java index 9abeeadc8..9e597dfc0 100644 --- a/java/org/contikios/cooja/contikimote/ContikiMoteType.java +++ b/java/org/contikios/cooja/contikimote/ContikiMoteType.java @@ -276,18 +276,18 @@ public boolean loadMoteFirmware(boolean vis) throws MoteTypeCreationException { } command = command.replace("$(LIBFILE)", firmwareFile.getName().replace(File.separatorChar, '/')); - SectionParser dataSecParser; - SectionParser bssSecParser = null; - SectionParser commonSecParser = null; - + Map variables; if (useCommand) { - String[] output = loadCommandData(command, firmwareFile, vis); - dataSecParser = new CommandSectionParser(output); - bssSecParser = new CommandSectionParser(output); - commonSecParser = new CommandSectionParser(output); + var output = loadCommandData(command, firmwareFile, vis); + variables = CommandSectionParser.parseSymbols(output); } else { - var symbols = String.join("\n", loadCommandData(command, firmwareFile, vis)); - dataSecParser = new MapSectionParser(symbols); + var sb = new StringBuilder(); + for (var s : loadCommandData(command, firmwareFile, vis)) { + if (s.contains("OBJECT")) { // Lines that define variables. + sb.append(s).append("\n"); + } + } + variables = MapSectionParser.parseSymbols(sb.toString()); } /* We first need the value of Contiki's referenceVar, which tells us the @@ -296,13 +296,6 @@ public boolean loadMoteFirmware(boolean vis) throws MoteTypeCreationException { * * This offset will be used in Cooja in the memory abstraction to match * Contiki's and Cooja's address spaces */ - Map variables = dataSecParser.parseSymbols(null); - if (bssSecParser != null) { - variables = bssSecParser.parseSymbols(variables); - } - if (commonSecParser != null) { - variables = commonSecParser.parseSymbols(variables); - } long offset; try { offset = myCoreComm.getReferenceAddress() - variables.get("referenceVar").addr; @@ -322,7 +315,7 @@ public boolean loadMoteFirmware(boolean vis) throws MoteTypeCreationException { getMemory(myCoreComm.getDataStartAddress(), myCoreComm.getDataSize(), offsetVariables)); initialMemory.addMemorySection("bss", getMemory(myCoreComm.getBssStartAddress(), myCoreComm.getBssSize(), offsetVariables)); - if (commonSecParser != null) { + if (useCommand) { initialMemory.addMemorySection("common", getMemory(myCoreComm.getCommonStartAddress(), myCoreComm.getCommonSize(), offsetVariables)); } @@ -360,34 +353,15 @@ public File getExpectedFirmwareFile(String name) { return new File(new File(name).getParentFile(), "build/cooja/" + identifier + "." + getMoteType()); } - /** - * Abstract base class for concrete section parser class. - */ - interface SectionParser { - Map parseSymbols(Map inVars); - } - /** * Parses Map file for section data. */ - private static class MapSectionParser implements SectionParser { - private final String readelfData; - - MapSectionParser(String readelfData) { - this.readelfData = readelfData; - } - - @Override - public Map parseSymbols(Map inVars) { + private static class MapSectionParser { + static Map parseSymbols(String readelfData) { Map varNames = new HashMap<>(); try (var s = new Scanner(readelfData)) { - s.nextLine(); // Skip first blank line. while (s.hasNext()) { - var symbolNum = s.next(); - if (!symbolNum.endsWith(":") || "Num:".equals(symbolNum)) { - s.nextLine(); // Skip until line starts with "1:" token. - continue; - } + s.next(); // Scanner.nextLong() is really slow, get the next token and parse it. var addr = Long.parseLong(s.next(), 16); // Size is output in decimal if below 100000, hex otherwise. The command line option --sym-base=10 gives @@ -396,10 +370,6 @@ public Map parseSymbols(Map inVars) { var hex = sizeString.startsWith("0x"); var size = Integer.parseInt(hex ? sizeString.substring(2) : sizeString, hex ? 16 : 10); var type = s.next(); - if (!"OBJECT".equals(type)) { - s.nextLine(); // Skip lines that do not define variables. - continue; - } // Skip 3 tokens that are not required. s.next(); s.next(); @@ -416,23 +386,8 @@ public Map parseSymbols(Map inVars) { /** * Parses command output for section data. */ - private static class CommandSectionParser implements SectionParser { - private final String[] mapFileData; - - /** - * Creates SectionParser based on output of configurable command. - * - * @param mapFileData Map file lines as array of String - */ - CommandSectionParser(String[] mapFileData) { - this.mapFileData = mapFileData; - } - - @Override - public Map parseSymbols(Map inVars) { - if (inVars != null) { - return inVars; - } + private static class CommandSectionParser { + static Map parseSymbols(String[] mapFileData) { HashMap addresses = new HashMap<>(); /* Replace "
" in regex by section specific regex */ Pattern pattern = Pattern.compile(