Skip to content

Commit ac2b7fc

Browse files
committed
Add support for PowerPCEabiGCC
Changed the rigth file Fixed bad filename
1 parent 38cbe83 commit ac2b7fc

File tree

7 files changed

+337
-2
lines changed

7 files changed

+337
-2
lines changed

src/main/java/net/praqma/jenkins/memorymap/MemoryMapDslExtension.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
}
2727
```
2828
29-
Valid values for `parserType` are `GCC` and `TI`. Valid values for `scale` are `DEFAULT`, `KILO`, `MEGA` and `GIGA`.
29+
Valid values for `parserType` are `GCC`, 'PowerPCEabiGcc' and `TI`. Valid values for `scale` are `DEFAULT`, `KILO`, `MEGA` and `GIGA`.
3030
3131
```
3232
job ('mmap_GEN'){

src/main/java/net/praqma/jenkins/memorymap/MemoryMapJobDslContext.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static javaposse.jobdsl.plugin.ContextExtensionPoint.executeInContext;
1111
import net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser;
1212
import net.praqma.jenkins.memorymap.parser.gcc.GccMemoryMapParser;
13+
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
1314
import net.praqma.jenkins.memorymap.parser.ti.TexasInstrumentsMemoryMapParser;
1415

1516
public class MemoryMapJobDslContext implements Context {
@@ -46,7 +47,7 @@ public void scale(String value) {
4647
}
4748

4849
List<AbstractMemoryMapParser> parsers = new ArrayList<>();
49-
List<String> parserTypes = Arrays.asList("GCC", "TI");
50+
List<String> parserTypes = Arrays.asList("GCC", "PowerPCEabiGcc", "TI");
5051

5152
public void parser(String parserType, String parserUniqueName, String commandFile, String mapFile, Runnable closure) {
5253
checkArgument(parserTypes.contains(parserType), "Parser type must be one of " + parserTypes);
@@ -58,6 +59,9 @@ public void parser(String parserType, String parserUniqueName, String commandFil
5859
case "GCC":
5960
parser = new GccMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, showBytesOnGraphs, context.graphConfigurations);
6061
break;
62+
case "PowerPCEabiGcc":
63+
parser = new PowerPCEabiGccMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, showBytesOnGraphs, context.graphConfigurations);
64+
break;
6165
case "TI":
6266
parser = new TexasInstrumentsMemoryMapParser(parserUniqueName, mapFile, commandFile, wordSize, context.graphConfigurations, showBytesOnGraphs);
6367
break;

src/main/java/net/praqma/jenkins/memorymap/parser/AbstractMemoryMapParser.java

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
5252
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfigurationDescriptor;
5353
import net.praqma.jenkins.memorymap.parser.gcc.GccMemoryMapParser;
54+
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
5455
import net.praqma.jenkins.memorymap.parser.ti.TexasInstrumentsMemoryMapParser;
5556
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemory;
5657
import org.apache.commons.collections.ListUtils;
@@ -63,6 +64,8 @@
6364
@JsonSubTypes({
6465
@Type(value = TexasInstrumentsMemoryMapParser.class, name = "TexasInstrumentsMemoryMapParser")
6566
,
67+
@Type(value = PowerPCEabiGccMemoryMapParser.class, name = "PowerPCEabiGccMemoryMapParser")
68+
,
6669
@Type(value = GccMemoryMapParser.class, name = "GccMemoryMapParser")})
6770

6871
public abstract class AbstractMemoryMapParser implements Describable<AbstractMemoryMapParser>, ExtensionPoint, Serializable {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
package net.praqma.jenkins.memorymap.parser.powerpceabigcc;
2+
3+
import hudson.AbortException;
4+
import hudson.Extension;
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.io.Serializable;
8+
import java.util.ArrayList;
9+
import java.util.Collections;
10+
import java.util.Comparator;
11+
import java.util.List;
12+
import java.util.logging.Level;
13+
import java.util.logging.Logger;
14+
import java.util.regex.Matcher;
15+
import java.util.regex.Pattern;
16+
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
17+
import net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser;
18+
import net.praqma.jenkins.memorymap.parser.MemoryMapParserDescriptor;
19+
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemory;
20+
import net.praqma.jenkins.memorymap.result.MemoryMapConfigMemoryItem;
21+
import net.praqma.jenkins.memorymap.util.HexUtils;
22+
import net.praqma.jenkins.memorymap.util.HexUtils.HexifiableString;
23+
import net.praqma.jenkins.memorymap.util.MemoryMapMemorySelectionError;
24+
import net.sf.json.JSONObject;
25+
import org.jenkinsci.Symbol;
26+
import org.kohsuke.stapler.DataBoundConstructor;
27+
import org.kohsuke.stapler.StaplerRequest;
28+
29+
/**
30+
* @author Praqma
31+
*/
32+
public class PowerPCEabiGccMemoryMapParser extends AbstractMemoryMapParser implements Serializable {
33+
34+
private static final Pattern MEM_SECTIONS = Pattern.compile("^\\s*(\\S+)(?=.*:)", Pattern.MULTILINE);
35+
private static final Pattern COMMENT_BLOCKS = Pattern.compile("\\/\\*[\\s\\S]*?\\*\\/");
36+
private static final Logger LOG = Logger.getLogger(PowerPCEabiGccMemoryMapParser.class.getName());
37+
38+
@DataBoundConstructor
39+
public PowerPCEabiGccMemoryMapParser(String parserUniqueName, String mapFile, String configurationFile, Integer wordSize, Boolean bytesOnGraph, List<MemoryMapGraphConfiguration> graphConfiguration) {
40+
super(parserUniqueName, mapFile, configurationFile, wordSize, bytesOnGraph, graphConfiguration);
41+
}
42+
43+
/**
44+
* Strip any c-style block comments, e.g slash-star to star-slash.
45+
* <b>Note:</b> this function down not correctly handle nested comment
46+
* blocks.
47+
* <b>Note:</b> this function is a bit greedy, and will incorrectly strip
48+
* comments inside strings, but this shouldn't be a problem for memory
49+
* config files.
50+
*
51+
* @param seq The content of a file that might contain c-style
52+
* block-comments
53+
* @return The same content, that has now had all block-comments stripped
54+
* out.
55+
*/
56+
public static CharSequence stripComments(CharSequence seq) {
57+
Matcher commentMatcher = COMMENT_BLOCKS.matcher(seq);
58+
return commentMatcher.replaceAll("");
59+
}
60+
61+
/**
62+
* Parses the MEMORY section of the GCC file. Throws an abort exception
63+
* which will be shown in the Jenkins console log.
64+
*
65+
* @param seq The content of the map file
66+
* @return a list of the defined MEMORY in the map file
67+
* @throws hudson.AbortException when a illegal value of memory found
68+
*
69+
*/
70+
public MemoryMapConfigMemory getMemory(CharSequence seq) throws AbortException {
71+
72+
Pattern allMemory = Pattern.compile("^\\s*(\\S+).*?(?:ORIGIN|org|o)\\s*=\\s*\\(([^,]*)\\).*?(?:LENGTH|len|l)\\s*\\=\\s*([^\\s]*.*)", Pattern.MULTILINE);
73+
Matcher match = allMemory.matcher(seq);
74+
MemoryMapConfigMemory memory = new MemoryMapConfigMemory();
75+
while (match.find()) {
76+
String sectionName = match.group(1);
77+
String sectionAddress = match.group(2).replace("(", "").replace(")", "").replace(" ", "");
78+
String sectionLength = match.group(3).replace("(", "").replace(")", "").replace(" ", "");
79+
80+
sectionAddress = getHexSum(sectionAddress);
81+
sectionLength = getHexSum(sectionLength);
82+
83+
try {
84+
String hexLength = new HexUtils.HexifiableString(sectionLength).toValidHexString().rawString;
85+
MemoryMapConfigMemoryItem item = new MemoryMapConfigMemoryItem(sectionName, sectionAddress, hexLength);
86+
memory.add(item);
87+
} catch (Throwable ex) {
88+
logger.log(Level.SEVERE, "Unable to convert %s to a valid hex string.", ex);
89+
throw new AbortException(String.format("Unable to convert %s to a valid hex string.", sectionLength));
90+
}
91+
}
92+
return memory;
93+
}
94+
95+
private static String getHexSum(String group)
96+
{
97+
Long sum = Long.valueOf(0L);
98+
99+
String buff = group.replace("0x", "");
100+
try
101+
{
102+
String[] groupPluses = buff.split("\\+");
103+
if (groupPluses.length > 0) {
104+
for (String str1 : groupPluses)
105+
{
106+
String[] minusGroup = str1.split("\\-");
107+
if (minusGroup.length > 0) {
108+
for (int i = 0; i < minusGroup.length; i++) {
109+
if (i == 0) {
110+
sum = Long.valueOf(sum.longValue() + Long.parseLong(minusGroup[i], 16));
111+
} else {
112+
sum = Long.valueOf(sum.longValue() - Long.parseLong(minusGroup[i], 16));
113+
}
114+
}
115+
} else {
116+
sum = Long.valueOf(sum.longValue() + Long.parseLong(str1, 16));
117+
}
118+
}
119+
} else {
120+
sum = Long.valueOf(sum.longValue() + Long.parseLong(group, 16));
121+
}
122+
}
123+
catch (NumberFormatException ex)
124+
{
125+
return group;
126+
}
127+
return "0x" + Long.toHexString(sum.longValue());
128+
}
129+
130+
/*
131+
* SECTIONS {
132+
* ---
133+
* secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
134+
{ contents } >region =fill
135+
...
136+
}
137+
*
138+
*/
139+
public List<MemoryMapConfigMemoryItem> getSections(CharSequence m) {
140+
List<MemoryMapConfigMemoryItem> items = new ArrayList<>();
141+
142+
Pattern section = Pattern.compile("SECTIONS\\s?\\r?\\n?\\{([\\s\\S]*)\\n\\}", Pattern.MULTILINE);
143+
144+
Matcher sectionMatched = section.matcher(m);
145+
String sectionString = null;
146+
147+
while (sectionMatched.find()) {
148+
sectionString = sectionMatched.group(1);
149+
}
150+
151+
//Find the good stuff (SECTION): *SECTIONS\n\{(.*)\n\}
152+
Matcher fm = MEM_SECTIONS.matcher(sectionString);
153+
154+
while (fm.find()) {
155+
MemoryMapConfigMemoryItem it = new MemoryMapConfigMemoryItem(fm.group(1), "0");
156+
items.add(it);
157+
}
158+
return items;
159+
}
160+
161+
public PowerPCEabiGccMemoryMapParser() {
162+
super();
163+
}
164+
165+
public Pattern getLinePatternForMapFile(String sectionName) {
166+
return Pattern.compile(String.format("^(%s)(\\s+)(\\w+)(\\s+)(\\w+)(\\w*)", sectionName), Pattern.MULTILINE);
167+
}
168+
169+
private static class MemoryMapMemItemComparator implements Comparator<MemoryMapConfigMemoryItem>, Serializable {
170+
@Override
171+
public int compare(MemoryMapConfigMemoryItem t, MemoryMapConfigMemoryItem t1) {
172+
long vt = new HexifiableString(t.getOrigin()).getLongValue();
173+
long vt1 = new HexifiableString(t1.getOrigin()).getLongValue();
174+
return (vt < vt1 ? -1 : (vt == vt1 ? 1 : 0));
175+
}
176+
}
177+
178+
/**
179+
* Given an item with length == null. Look down in the list. If we find an
180+
* item whose length is not null, set the items length to that
181+
*
182+
* @param memory the memory list
183+
* @return a more complete configuration, where i have better values
184+
*/
185+
public MemoryMapConfigMemory guessLengthOfSections(MemoryMapConfigMemory memory) {
186+
Collections.sort(memory, new MemoryMapMemItemComparator());
187+
188+
for (MemoryMapConfigMemoryItem item : memory) {
189+
if (item.getLength() == null) {
190+
int itemIndex = memory.indexOf(item);
191+
for (int i = itemIndex; i > 1; i--) {
192+
if (memory.get(i).getLength() != null) {
193+
item.setParent(memory.get(i));
194+
break;
195+
}
196+
}
197+
198+
}
199+
}
200+
return memory;
201+
}
202+
203+
@Override
204+
public MemoryMapConfigMemory parseMapFile(File f, MemoryMapConfigMemory configuration) throws IOException {
205+
CharSequence sequence = createCharSequenceFromFile(f);
206+
207+
for (MemoryMapConfigMemoryItem item : configuration) {
208+
Matcher m = getLinePatternForMapFile(item.getName()).matcher(sequence);
209+
while (m.find()) {
210+
item.setOrigin(m.group(3));
211+
item.setUsed(m.group(5));
212+
}
213+
}
214+
215+
configuration = guessLengthOfSections(configuration);
216+
217+
return configuration;
218+
}
219+
220+
@Override
221+
public MemoryMapConfigMemory parseConfigFile(File f) throws IOException {
222+
//Collect sections from both the MEMORY and the SECTIONS areas from the command file.
223+
//The memory are the top level components, sections belong to one of these sections
224+
CharSequence stripped = stripComments(createCharSequenceFromFile(f));
225+
226+
MemoryMapConfigMemory memConfig = getMemory(stripped);
227+
memConfig.addAll(getSections(stripped));
228+
for (MemoryMapGraphConfiguration g : getGraphConfiguration()) {
229+
for (String gItem : g.itemizeGraphDataList()) {
230+
for (String gSplitItem : gItem.split("\\+")) {
231+
//We will fail if the name of the data section does not match any of the named items in the map file.
232+
if (!memConfig.containsSectionWithName(gSplitItem)) {
233+
throw new MemoryMapMemorySelectionError(String.format("The memory section named %s not found in map file%nAvailable sections are:%n%s", gSplitItem, memConfig.getItemNames()));
234+
}
235+
}
236+
}
237+
}
238+
return memConfig;
239+
}
240+
241+
@Override
242+
public int getDefaultWordSize() {
243+
return 8;
244+
}
245+
246+
@Symbol("powerPCEabiGccParser")
247+
@Extension
248+
public static final class DescriptorImpl extends MemoryMapParserDescriptor<PowerPCEabiGccMemoryMapParser> {
249+
250+
@Override
251+
public String getDisplayName() {
252+
return "PowerPCEabiGcc";
253+
}
254+
255+
@Override
256+
public AbstractMemoryMapParser newInstance(StaplerRequest req, JSONObject formData, AbstractMemoryMapParser instance) throws FormException {
257+
PowerPCEabiGccMemoryMapParser parser = (PowerPCEabiGccMemoryMapParser) instance;
258+
save();
259+
return parser;
260+
}
261+
}
262+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?jelly escape-by-default='true'?>
2+
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
3+
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
4+
<st:include class="net.praqma.jenkins.memorymap.parser.AbstractMemoryMapParser" page="config.jelly"/>
5+
</j:jelly>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2019 Praqma.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package net.praqma.jenkins.integration;
25+
26+
import java.util.Arrays;
27+
import java.util.HashMap;
28+
import java.util.UUID;
29+
import net.praqma.jenkins.memorymap.graph.MemoryMapGraphConfiguration;
30+
import net.praqma.jenkins.memorymap.parser.powerpceabigcc.PowerPCEabiGccMemoryMapParser;
31+
import org.junit.Rule;
32+
import org.junit.Test;
33+
import org.jvnet.hudson.test.JenkinsRule;
34+
35+
/**
36+
*
37+
* @author thi
38+
*/
39+
public class PowerPCEabiGccMemoryMapParserIT {
40+
41+
@Rule
42+
public JenkinsRule jenkins = new JenkinsRule();
43+
44+
@Test
45+
public void powerpceabigcc_testUsageValues() throws Exception {
46+
MemoryMapGraphConfiguration graphConfiguration = new MemoryMapGraphConfiguration(".text+.rodata", "432");
47+
PowerPCEabiGccMemoryMapParser parser = createParser(graphConfiguration);
48+
parser.setMapFile("prom.map");
49+
parser.setConfigurationFile("prom.ld");
50+
51+
HashMap<String, String> expectedValues = new HashMap<>();
52+
expectedValues.put(".text", "0x10a008");
53+
expectedValues.put(".rodata", "0x33fd7");
54+
55+
TestUtils.testUsageValues(jenkins, parser, "powerpceabigcc.zip", expectedValues);
56+
}
57+
58+
private PowerPCEabiGccMemoryMapParser createParser(MemoryMapGraphConfiguration... graphConfiguration) {
59+
return new PowerPCEabiGccMemoryMapParser(UUID.randomUUID().toString(), null, null, 8, true, Arrays.asList(graphConfiguration));
60+
}
61+
}
Binary file not shown.

0 commit comments

Comments
 (0)