Skip to content

Commit

Permalink
Add support for PowerPCEabiGCC
Browse files Browse the repository at this point in the history
Changed the rigth file

Fixed bad filename
  • Loading branch information
ErikBogg committed Mar 5, 2019
1 parent 38cbe83 commit ac2b7fc
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}
```
Valid values for `parserType` are `GCC` and `TI`. Valid values for `scale` are `DEFAULT`, `KILO`, `MEGA` and `GIGA`.
Valid values for `parserType` are `GCC`, 'PowerPCEabiGcc' and `TI`. Valid values for `scale` are `DEFAULT`, `KILO`, `MEGA` and `GIGA`.
```
job ('mmap_GEN'){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static javaposse.jobdsl.plugin.ContextExtensionPoint.executeInContext;
import net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.gcc.GccMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.ti.TexasInstrumentsMemoryMapParser;

public class MemoryMapJobDslContext implements Context {
Expand Down Expand Up @@ -46,7 +47,7 @@ public void scale(String value) {
}

List<AbstractMemoryMapParser> parsers = new ArrayList<>();
List<String> parserTypes = Arrays.asList("GCC", "TI");
List<String> parserTypes = Arrays.asList("GCC", "PowerPCEabiGcc", "TI");

public void parser(String parserType, String parserUniqueName, String commandFile, String mapFile, Runnable closure) {
checkArgument(parserTypes.contains(parserType), "Parser type must be one of " + parserTypes);
Expand All @@ -58,6 +59,9 @@ public void parser(String parserType, String parserUniqueName, String commandFil
case "GCC":
parser = new GccMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, showBytesOnGraphs, context.graphConfigurations);
break;
case "PowerPCEabiGcc":
parser = new PowerPCEabiGccMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, showBytesOnGraphs, context.graphConfigurations);
break;
case "TI":
parser = new TexasInstrumentsMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, context.graphConfigurations, showBytesOnGraphs);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfigurationDescriptor;
import net.praqma.jenkins.memorymap.parser.gcc.GccMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.ti.TexasInstrumentsMemoryMapParser;
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemory;
import org.apache.commons.collections.ListUtils;
Expand All @@ -63,6 +64,8 @@
@JsonSubTypes({
@Type(value = TexasInstrumentsMemoryMapParser.class, name = "TexasInstrumentsMemoryMapParser")
,
@Type(value = PowerPCEabiGccMemoryMapParser.class, name = "PowerPCEabiGccMemoryMapParser")
,
@Type(value = GccMemoryMapParser.class, name = "GccMemoryMapParser")})

public abstract class AbstractMemoryMapParser implements Describable<AbstractMemoryMapParser>, ExtensionPoint, Serializable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
package net.praqma.jenkins.memorymap.parser.powerpceabigcc;

import hudson.AbortException;
import hudson.Extension;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
import net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser;
import net.praqma.jenkins.memorymap.parser.MemoryMapParserDescriptor;
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemory;
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemoryItem;
import net.praqma.jenkins.memorymap.util.HexUtils;
import net.praqma.jenkins.memorymap.util.HexUtils.HexifiableString;
import net.praqma.jenkins.memorymap.util.MemoryMapMemorySelectionError;
import net.sf.json.JSONObject;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* @author Praqma
*/
public class PowerPCEabiGccMemoryMapParser extends AbstractMemoryMapParser implements Serializable {

private static final Pattern MEM_SECTIONS = Pattern.compile("^\\s*(\\S+)(?=.*:)", Pattern.MULTILINE);
private static final Pattern COMMENT_BLOCKS = Pattern.compile("\\/\\*[\\s\\S]*?\\*\\/");
private static final Logger LOG = Logger.getLogger(PowerPCEabiGccMemoryMapParser.class.getName());

@DataBoundConstructor
public PowerPCEabiGccMemoryMapParser(String parserUniqueName, String mapFile, String configurationFile, Integer wordSize, Boolean bytesOnGraph, List<MemoryMapGraphConfiguration> graphConfiguration) {
super(parserUniqueName, mapFile, configurationFile, wordSize, bytesOnGraph, graphConfiguration);
}

/**
* Strip any c-style block comments, e.g slash-star to star-slash.
* <b>Note:</b> this function down not correctly handle nested comment
* blocks.
* <b>Note:</b> this function is a bit greedy, and will incorrectly strip
* comments inside strings, but this shouldn't be a problem for memory
* config files.
*
* @param seq The content of a file that might contain c-style
* block-comments
* @return The same content, that has now had all block-comments stripped
* out.
*/
public static CharSequence stripComments(CharSequence seq) {
Matcher commentMatcher = COMMENT_BLOCKS.matcher(seq);
return commentMatcher.replaceAll("");
}

/**
* Parses the MEMORY section of the GCC file. Throws an abort exception
* which will be shown in the Jenkins console log.
*
* @param seq The content of the map file
* @return a list of the defined MEMORY in the map file
* @throws hudson.AbortException when a illegal value of memory found
*
*/
public MemoryMapConfigMemory getMemory(CharSequence seq) throws AbortException {

Pattern allMemory = Pattern.compile("^\\s*(\\S+).*?(?:ORIGIN|org|o)\\s*=\\s*\\(([^,]*)\\).*?(?:LENGTH|len|l)\\s*\\=\\s*([^\\s]*.*)", Pattern.MULTILINE);
Matcher match = allMemory.matcher(seq);
MemoryMapConfigMemory memory = new MemoryMapConfigMemory();
while (match.find()) {
String sectionName = match.group(1);
String sectionAddress = match.group(2).replace("(", "").replace(")", "").replace(" ", "");
String sectionLength = match.group(3).replace("(", "").replace(")", "").replace(" ", "");

sectionAddress = getHexSum(sectionAddress);
sectionLength = getHexSum(sectionLength);

try {
String hexLength = new HexUtils.HexifiableString(sectionLength).toValidHexString().rawString;
MemoryMapConfigMemoryItem item = new MemoryMapConfigMemoryItem(sectionName, sectionAddress, hexLength);
memory.add(item);
} catch (Throwable ex) {
logger.log(Level.SEVERE, "Unable to convert %s to a valid hex string.", ex);
throw new AbortException(String.format("Unable to convert %s to a valid hex string.", sectionLength));
}
}
return memory;
}

private static String getHexSum(String group)
{
Long sum = Long.valueOf(0L);

String buff = group.replace("0x", "");
try
{
String[] groupPluses = buff.split("\\+");
if (groupPluses.length > 0) {
for (String str1 : groupPluses)
{
String[] minusGroup = str1.split("\\-");
if (minusGroup.length > 0) {
for (int i = 0; i < minusGroup.length; i++) {
if (i == 0) {
sum = Long.valueOf(sum.longValue() + Long.parseLong(minusGroup[i], 16));
} else {
sum = Long.valueOf(sum.longValue() - Long.parseLong(minusGroup[i], 16));
}
}
} else {
sum = Long.valueOf(sum.longValue() + Long.parseLong(str1, 16));
}
}
} else {
sum = Long.valueOf(sum.longValue() + Long.parseLong(group, 16));
}
}
catch (NumberFormatException ex)
{
return group;
}
return "0x" + Long.toHexString(sum.longValue());
}

/*
* SECTIONS {
* ---
* secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
{ contents } >region =fill
...
}
*
*/
public List<MemoryMapConfigMemoryItem> getSections(CharSequence m) {
List<MemoryMapConfigMemoryItem> items = new ArrayList<>();

Pattern section = Pattern.compile("SECTIONS\\s?\\r?\\n?\\{([\\s\\S]*)\\n\\}", Pattern.MULTILINE);

Matcher sectionMatched = section.matcher(m);
String sectionString = null;

while (sectionMatched.find()) {
sectionString = sectionMatched.group(1);
}

//Find the good stuff (SECTION): *SECTIONS\n\{(.*)\n\}
Matcher fm = MEM_SECTIONS.matcher(sectionString);

while (fm.find()) {
MemoryMapConfigMemoryItem it = new MemoryMapConfigMemoryItem(fm.group(1), "0");
items.add(it);
}
return items;
}

public PowerPCEabiGccMemoryMapParser() {
super();
}

public Pattern getLinePatternForMapFile(String sectionName) {
return Pattern.compile(String.format("^(%s)(\\s+)(\\w+)(\\s+)(\\w+)(\\w*)", sectionName), Pattern.MULTILINE);
}

private static class MemoryMapMemItemComparator implements Comparator<MemoryMapConfigMemoryItem>, Serializable {
@Override
public int compare(MemoryMapConfigMemoryItem t, MemoryMapConfigMemoryItem t1) {
long vt = new HexifiableString(t.getOrigin()).getLongValue();
long vt1 = new HexifiableString(t1.getOrigin()).getLongValue();
return (vt < vt1 ? -1 : (vt == vt1 ? 1 : 0));
}
}

/**
* Given an item with length == null. Look down in the list. If we find an
* item whose length is not null, set the items length to that
*
* @param memory the memory list
* @return a more complete configuration, where i have better values
*/
public MemoryMapConfigMemory guessLengthOfSections(MemoryMapConfigMemory memory) {
Collections.sort(memory, new MemoryMapMemItemComparator());

for (MemoryMapConfigMemoryItem item : memory) {
if (item.getLength() == null) {
int itemIndex = memory.indexOf(item);
for (int i = itemIndex; i > 1; i--) {
if (memory.get(i).getLength() != null) {
item.setParent(memory.get(i));
break;
}
}

}
}
return memory;
}

@Override
public MemoryMapConfigMemory parseMapFile(File f, MemoryMapConfigMemory configuration) throws IOException {
CharSequence sequence = createCharSequenceFromFile(f);

for (MemoryMapConfigMemoryItem item : configuration) {
Matcher m = getLinePatternForMapFile(item.getName()).matcher(sequence);
while (m.find()) {
item.setOrigin(m.group(3));
item.setUsed(m.group(5));
}
}

configuration = guessLengthOfSections(configuration);

return configuration;
}

@Override
public MemoryMapConfigMemory parseConfigFile(File f) throws IOException {
//Collect sections from both the MEMORY and the SECTIONS areas from the command file.
//The memory are the top level components, sections belong to one of these sections
CharSequence stripped = stripComments(createCharSequenceFromFile(f));

MemoryMapConfigMemory memConfig = getMemory(stripped);
memConfig.addAll(getSections(stripped));
for (MemoryMapGraphConfiguration g : getGraphConfiguration()) {
for (String gItem : g.itemizeGraphDataList()) {
for (String gSplitItem : gItem.split("\\+")) {
//We will fail if the name of the data section does not match any of the named items in the map file.
if (!memConfig.containsSectionWithName(gSplitItem)) {
throw new MemoryMapMemorySelectionError(String.format("The memory section named %s not found in map file%nAvailable sections are:%n%s", gSplitItem, memConfig.getItemNames()));
}
}
}
}
return memConfig;
}

@Override
public int getDefaultWordSize() {
return 8;
}

@Symbol("powerPCEabiGccParser")
@Extension
public static final class DescriptorImpl extends MemoryMapParserDescriptor<PowerPCEabiGccMemoryMapParser> {

@Override
public String getDisplayName() {
return "PowerPCEabiGcc";
}

@Override
public AbstractMemoryMapParser newInstance(StaplerRequest req, JSONObject formData, AbstractMemoryMapParser instance) throws FormException {
PowerPCEabiGccMemoryMapParser parser = (PowerPCEabiGccMemoryMapParser) instance;
save();
return parser;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<st:include class="net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser" page="config.jelly"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* The MIT License
*
* Copyright 2019 Praqma.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package net.praqma.jenkins.integration;

import java.util.Arrays;
import java.util.HashMap;
import java.util.UUID;
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

/**
*
* @author thi
*/
public class PowerPCEabiGccMemoryMapParserIT {

@Rule
public JenkinsRule jenkins = new JenkinsRule();

@Test
public void powerpceabigcc_testUsageValues() throws Exception {
MemoryMapGraphConfiguration graphConfiguration = new MemoryMapGraphConfiguration(".text+.rodata", "432");
PowerPCEabiGccMemoryMapParser parser = createParser(graphConfiguration);
parser.setMapFile("prom.map");
parser.setConfigurationFile("prom.ld");

HashMap<String, String> expectedValues = new HashMap<>();
expectedValues.put(".text", "0x10a008");
expectedValues.put(".rodata", "0x33fd7");

TestUtils.testUsageValues(jenkins, parser, "powerpceabigcc.zip", expectedValues);
}

private PowerPCEabiGccMemoryMapParser createParser(MemoryMapGraphConfiguration... graphConfiguration) {
return new PowerPCEabiGccMemoryMapParser(UUID.randomUUID().toString(), null, null, 8, true, Arrays.asList(graphConfiguration));
}
}
Binary file not shown.

0 comments on commit ac2b7fc

Please sign in to comment.