Skip to content

Commit

Permalink
Merge pull request #1343 from pjonsson/contikimote-simpliify-2
Browse files Browse the repository at this point in the history
ContikiMoteType: speed up variable parsing on Linux
  • Loading branch information
nfi authored Oct 4, 2023
2 parents 3753349 + d68d973 commit 7f8327e
Showing 1 changed file with 16 additions and 61 deletions.
77 changes: 16 additions & 61 deletions java/org/contikios/cooja/contikimote/ContikiMoteType.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Symbol> 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
Expand All @@ -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<String, Symbol> 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;
Expand All @@ -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));
}
Expand Down Expand Up @@ -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<String, Symbol> parseSymbols(Map<String, Symbol> 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<String, Symbol> parseSymbols(Map<String, Symbol> inVars) {
private static class MapSectionParser {
static Map<String, Symbol> parseSymbols(String readelfData) {
Map<String, Symbol> 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
Expand All @@ -396,10 +370,6 @@ public Map<String, Symbol> parseSymbols(Map<String, Symbol> 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();
Expand All @@ -416,23 +386,8 @@ public Map<String, Symbol> parseSymbols(Map<String, Symbol> 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<String, Symbol> parseSymbols(Map<String, Symbol> inVars) {
if (inVars != null) {
return inVars;
}
private static class CommandSectionParser {
static Map<String, Symbol> parseSymbols(String[] mapFileData) {
HashMap<String, Symbol> addresses = new HashMap<>();
/* Replace "<SECTION>" in regex by section specific regex */
Pattern pattern = Pattern.compile(
Expand Down

0 comments on commit 7f8327e

Please sign in to comment.