44
44
import ghidra .framework .cmd .Command ;
45
45
import ghidra .framework .model .DomainFile ;
46
46
import ghidra .framework .plugintool .PluginTool ;
47
+ import ghidra .program .database .mem .AddressSourceInfo ;
47
48
import ghidra .program .database .symbol .CodeSymbol ;
48
49
import ghidra .program .database .symbol .FunctionSymbol ;
49
50
import ghidra .program .model .address .*;
50
51
import ghidra .program .model .listing .*;
52
+ import ghidra .program .model .mem .Memory ;
51
53
import ghidra .program .model .symbol .*;
52
54
import ghidra .program .util .*;
53
55
import ghidra .util .Msg ;
@@ -65,6 +67,8 @@ public class CodeBrowserClipboardProvider extends ByteCopier
65
67
new ClipboardType (DataFlavor .stringFlavor , "Address" );
66
68
public static final ClipboardType ADDRESS_TEXT_WITH_OFFSET_TYPE =
67
69
new ClipboardType (DataFlavor .stringFlavor , "Address w/ Offset" );
70
+ public static final ClipboardType BYTE_SOURCE_OFFSET_TYPE =
71
+ new ClipboardType (DataFlavor .stringFlavor , "Byte Source Offset" );
68
72
public static final ClipboardType CODE_TEXT_TYPE =
69
73
new ClipboardType (DataFlavor .stringFlavor , "Formatted Code" );
70
74
public static final ClipboardType LABELS_COMMENTS_TYPE =
@@ -94,6 +98,7 @@ private static List<ClipboardType> createCopyTypesList() {
94
98
list .add (CPP_BYTE_ARRAY_TYPE );
95
99
list .add (ADDRESS_TEXT_TYPE );
96
100
list .add (ADDRESS_TEXT_WITH_OFFSET_TYPE );
101
+ list .add (BYTE_SOURCE_OFFSET_TYPE );
97
102
98
103
return list ;
99
104
}
@@ -221,6 +226,9 @@ public Transferable copySpecial(ClipboardType copyType, TaskMonitor monitor) {
221
226
else if (copyType == ADDRESS_TEXT_WITH_OFFSET_TYPE ) {
222
227
return copySymbolString (monitor );
223
228
}
229
+ else if (copyType == BYTE_SOURCE_OFFSET_TYPE ) {
230
+ return copyByteSourceOffset (monitor );
231
+ }
224
232
else if (copyType == CODE_TEXT_TYPE ) {
225
233
return copyCode (monitor );
226
234
}
@@ -382,6 +390,29 @@ else if (delta > 0) {
382
390
return createStringTransferable (StringUtils .join (strings , "\n " ));
383
391
}
384
392
393
+ private Transferable copyByteSourceOffset (TaskMonitor monitor ) {
394
+ AddressSetView addrs = getSelectedAddresses ();
395
+ Memory currentMemory = currentProgram .getMemory ();
396
+ List <String > strings = new ArrayList <>();
397
+ AddressIterator addresses = addrs .getAddresses (true );
398
+ while (addresses .hasNext () && !monitor .isCancelled ()) {
399
+ AddressSourceInfo addressSourceInfo = currentMemory .getAddressSourceInfo (addresses .next ());
400
+ if (addressSourceInfo != null ) {
401
+ long fileOffset = addressSourceInfo .getFileOffset ();
402
+ String fileOffsetString ;
403
+
404
+ if (fileOffset == -1 ) {
405
+ fileOffsetString = "<NO_OFFSET>" ;
406
+ } else {
407
+ fileOffsetString = String .format ("%x" , addressSourceInfo .getFileOffset ());
408
+ }
409
+
410
+ strings .add (fileOffsetString );
411
+ }
412
+ }
413
+ return createStringTransferable (StringUtils .join (strings , "\n " ));
414
+ }
415
+
385
416
protected Transferable copyCode (TaskMonitor monitor ) {
386
417
387
418
AddressSetView addressSet = getSelectedAddresses ();
0 commit comments