40
40
import ghidra .program .model .address .Address ;
41
41
import ghidra .program .model .address .AddressOverflowException ;
42
42
import ghidra .program .model .address .AddressSpace ;
43
+ import ghidra .program .model .data .DataTypeConflictHandler ;
44
+ import ghidra .program .model .data .ProgramBasedDataTypeManager ;
45
+ import ghidra .program .model .data .StructureDataType ;
46
+ import ghidra .program .model .data .UnsignedLongDataType ;
47
+ import ghidra .program .model .listing .Listing ;
43
48
import ghidra .program .model .listing .Program ;
44
49
import ghidra .program .model .mem .Memory ;
45
50
import ghidra .program .model .mem .MemoryBlock ;
46
51
import ghidra .program .model .mem .MemoryConflictException ;
52
+ import ghidra .program .model .symbol .Namespace ;
53
+ import ghidra .program .model .symbol .SourceType ;
54
+ import ghidra .program .model .symbol .SymbolTable ;
55
+ import ghidra .program .model .util .CodeUnitInsertionException ;
47
56
import ghidra .util .Msg ;
57
+ import ghidra .util .exception .DuplicateNameException ;
58
+ import ghidra .util .exception .InvalidInputException ;
48
59
import io .svdparser .SvdAddressBlock ;
49
60
import io .svdparser .SvdDevice ;
50
61
import io .svdparser .SvdParserException ;
51
62
import io .svdparser .SvdPeripheral ;
63
+ import io .svdparser .SvdRegister ;
52
64
import svd .MemoryUtils .MemRangeRelation ;
53
65
54
66
//@formatter:off
@@ -149,6 +161,14 @@ private String getPeriphBlockName(SvdPeripheral periph, SvdAddressBlock block) {
149
161
}
150
162
151
163
private void processBlock (JComponent parentComponent , Program program , BlockInfo blockInfo ) {
164
+ boolean memOk = processBlockMemory (parentComponent , program , blockInfo );
165
+ if (memOk ) {
166
+ processBlockSymbol (program , blockInfo );
167
+ processBlockDataTypes (program , blockInfo );
168
+ }
169
+ }
170
+
171
+ private boolean processBlockMemory (JComponent parentComponent , Program program , BlockInfo blockInfo ) {
152
172
Memory memory = program .getMemory ();
153
173
MemoryBlock [] collidingMemoryBlocks = MemoryUtils .getBlockCollidingMemoryBlocks (memory , blockInfo .block );
154
174
if (collidingMemoryBlocks .length == 0 ) {
@@ -160,7 +180,9 @@ private void processBlock(JComponent parentComponent, Program program, BlockInfo
160
180
Msg .showWarn (getClass (), null , "Load SVD" , "Could not create a region for " + blockInfo .name + "@"
161
181
+ String .format ("0x%08x" , blockInfo .block .getAddress ()) + "+"
162
182
+ String .format ("0x%08x" , blockInfo .block .getSize ()) + ". It conflicts with an existing region!" );
183
+ return false ;
163
184
}
185
+ return true ;
164
186
}
165
187
166
188
private void createMemoryBlock (Program program , BlockInfo blockInfo ) {
@@ -295,4 +317,87 @@ private void updateMatchingMemoryBlock(JComponent parentComponent, Program progr
295
317
program .endTransaction (transactionId , ok );
296
318
}
297
319
}
320
+
321
+ private void processBlockSymbol (Program program , BlockInfo blockInfo ) {
322
+ // Calculate address of the block...
323
+ AddressSpace addrSpace = program .getAddressFactory ().getDefaultAddressSpace ();
324
+ Address addr = addrSpace .getAddress (blockInfo .block .getAddress ().longValue ());
325
+
326
+ // Create a symbol name...
327
+ SymbolTable symTable = program .getSymbolTable ();
328
+ Namespace namespace = getOrCreateNamespace (program , "Peripherals" );
329
+ int transactionId = program .startTransaction ("SVD " + blockInfo .name + " symtable creation" );
330
+ boolean ok = false ;
331
+ try {
332
+ symTable .createLabel (addr , blockInfo .name .replace ('/' , '_' ), namespace , SourceType .IMPORTED );
333
+ ok = true ;
334
+ } catch (InvalidInputException e ) {
335
+ // TODO Auto-generated catch block
336
+ e .printStackTrace ();
337
+ }
338
+ program .endTransaction (transactionId , ok );
339
+ }
340
+
341
+ private Namespace getOrCreateNamespace (Program program , String name ) {
342
+ SymbolTable symTable = program .getSymbolTable ();
343
+ Namespace namespace = symTable .getNamespace (name , null );
344
+ if (namespace != null )
345
+ return namespace ;
346
+
347
+ int transactionId = program .startTransaction ("SVD " + name + " namespace creation" );
348
+ boolean ok = false ;
349
+ try {
350
+ namespace = symTable .createNameSpace (null , name , SourceType .IMPORTED );
351
+ ok = true ;
352
+ } catch (DuplicateNameException | InvalidInputException e ) {
353
+ // TODO Auto-generated catch block
354
+ e .printStackTrace ();
355
+ }
356
+ program .endTransaction (transactionId , ok );
357
+ return namespace ;
358
+ }
359
+
360
+ private void processBlockDataTypes (Program program , BlockInfo blockInfo ) {
361
+ StructureDataType struct = createPeripheralBlockDataType (blockInfo );
362
+
363
+ // Add struct to the data type manager...
364
+ ProgramBasedDataTypeManager dataTypeManager = program .getDataTypeManager ();
365
+ int transactionId = program .startTransaction ("SVD " + blockInfo .name + " data type creation" );
366
+ boolean ok = false ;
367
+ try {
368
+ dataTypeManager .addDataType (struct , DataTypeConflictHandler .REPLACE_HANDLER );
369
+ ok = true ;
370
+ } catch (IllegalArgumentException e ) {
371
+ e .printStackTrace ();
372
+ }
373
+ program .endTransaction (transactionId , ok );
374
+
375
+ // Calculate address of the block...
376
+ AddressSpace addrSpace = program .getAddressFactory ().getDefaultAddressSpace ();
377
+ Address addr = addrSpace .getAddress (blockInfo .block .getAddress ().longValue ());
378
+
379
+ // Add data type to listing...
380
+ Listing listing = program .getListing ();
381
+ transactionId = program .startTransaction ("SVD " + blockInfo .name + " data type listing placement" );
382
+ ok = false ;
383
+ try {
384
+ listing .createData (addr , struct );
385
+ ok = true ;
386
+ } catch (CodeUnitInsertionException e ) {
387
+ // TODO Auto-generated catch block
388
+ e .printStackTrace ();
389
+ }
390
+ program .endTransaction (transactionId , ok );
391
+ }
392
+
393
+ private StructureDataType createPeripheralBlockDataType (BlockInfo blockInfo ) {
394
+ String struct_name = blockInfo .name .replace ('/' , '_' ) + "_reg_t" ;
395
+ StructureDataType struct = new StructureDataType (struct_name , blockInfo .block .getSize ().intValue ());
396
+ for (SvdPeripheral periph : blockInfo .peripherals )
397
+ for (SvdRegister reg : periph .getRegisters ())
398
+ if (reg .getOffset () < blockInfo .block .getSize ())
399
+ struct .replaceAtOffset (reg .getOffset (), new UnsignedLongDataType (), reg .getSize () / 8 ,
400
+ reg .getName (), reg .getDescription ());
401
+ return struct ;
402
+ }
298
403
}
0 commit comments