Skip to content

Commit 5b4b055

Browse files
committed
Merge remote-tracking branch 'origin/GP-4196_dev747368_golang_sourcefile'
2 parents aeb3f04 + b630c40 commit 5b4b055

File tree

6 files changed

+96
-7
lines changed

6 files changed

+96
-7
lines changed

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ private void markupGoFunctions(TaskMonitor monitor) throws IOException, Cancelle
234234
GoSourceFileInfo sfi = null;
235235
if (analyzerOptions.outputSourceInfo && (sfi = funcdata.getSourceFileInfo()) != null) {
236236
markupSession.appendComment(func, "Golang source: ", sfi.getDescription());
237+
funcdata.markupSourceFileInfo();
237238
}
238239

239240
if (funcdata.getFlags().isEmpty() /* dont try to get arg info for ASM funcs*/) {

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/DWARFImporter.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
import java.io.IOException;
1919
import java.util.*;
2020

21+
import org.apache.commons.io.FilenameUtils;
22+
2123
import ghidra.app.plugin.core.datamgr.util.DataTypeUtils;
2224
import ghidra.app.util.bin.BinaryReader;
2325
import ghidra.app.util.bin.format.dwarf.line.DWARFLine.SourceFileAddr;
2426
import ghidra.app.util.bin.format.dwarf.line.DWARFLineProgramExecutor;
27+
import ghidra.app.util.bin.format.golang.GoConstants;
2528
import ghidra.framework.store.LockException;
2629
import ghidra.program.database.sourcemap.SourceFile;
2730
import ghidra.program.model.address.Address;
@@ -40,6 +43,9 @@
4043
* {@link DWARFImportOptions}.
4144
*/
4245
public class DWARFImporter {
46+
private static final Set<String> SOURCEFILENAMES_IGNORE =
47+
Set.of(GoConstants.GOLANG_AUTOGENERATED_FILENAME);
48+
4349
private DWARFProgram prog;
4450
private DWARFDataTypeManager dwarfDTM;
4551
private TaskMonitor monitor;
@@ -202,7 +208,9 @@ private void addSourceLineInfo(BinaryReader reader)
202208
monitor.checkCancelled();
203209
monitor.increment(1);
204210
SourceFileAddr sfa = sourceInfo.get(i);
205-
if (sfa.isEndSequence()) {
211+
if (SOURCEFILENAMES_IGNORE.contains(sfa.fileName()) ||
212+
SOURCEFILENAMES_IGNORE.contains(FilenameUtils.getName(sfa.fileName())) ||
213+
sfa.isEndSequence()) {
206214
continue;
207215
}
208216
Address addr = prog.getCodeAddress(sfa.address());

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/line/DWARFLine.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static DirectoryEntryFormat read(BinaryReader reader) throws IOException, IOExce
247247
private int address_size;
248248
private int segment_selector_size;
249249

250-
private long opcodes_start = -1; // offset where line number program opcodes start
250+
private long opcodes_start; // offset where line number program opcodes start
251251

252252
private DWARFLine() {
253253
// empty, use #read()

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoConstants.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -37,5 +37,7 @@ public class GoConstants {
3737
public static final String GOLANG_ABI0_CALLINGCONVENTION_NAME = "abi0";
3838
public static final String GOLANG_DUFFZERO_CALLINGCONVENTION_NAME = "duffzero";
3939
public static final String GOLANG_DUFFCOPY_CALLINGCONVENTION_NAME = "duffcopy";
40+
41+
public static final String GOLANG_AUTOGENERATED_FILENAME = "<autogenerated>";
4042
}
4143

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoFuncData.java

+63-1
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@
1919
import java.util.*;
2020

2121
import ghidra.app.util.bin.BinaryReader;
22+
import ghidra.app.util.bin.format.golang.GoConstants;
2223
import ghidra.app.util.bin.format.golang.rtti.types.GoMethod.GoMethodInfo;
2324
import ghidra.app.util.bin.format.golang.structmapping.*;
25+
import ghidra.formats.gfilesystem.FSUtilities;
26+
import ghidra.framework.store.LockException;
27+
import ghidra.program.database.sourcemap.SourceFile;
2428
import ghidra.program.model.address.*;
2529
import ghidra.program.model.data.ArrayDataType;
2630
import ghidra.program.model.data.DataType;
2731
import ghidra.program.model.listing.Function;
32+
import ghidra.program.model.listing.Program;
33+
import ghidra.program.model.sourcemap.SourceFileManager;
34+
import ghidra.util.Msg;
2835
import ghidra.util.NumericUtilities;
2936
import ghidra.util.exception.CancelledException;
3037

@@ -361,6 +368,61 @@ public GoSourceFileInfo getSourceFileInfo() throws IOException {
361368
return null;
362369
}
363370

371+
String fileName = getSourceFilename(fileno);
372+
return fileName != null ? new GoSourceFileInfo(fileName, lineNum) : null;
373+
}
374+
375+
public void markupSourceFileInfo() {
376+
GoModuledata moduledata = getModuledata();
377+
if (moduledata == null) {
378+
return;
379+
}
380+
Program program = programContext.getProgram();
381+
SourceFileManager sfman = program.getSourceFileManager();
382+
383+
try {
384+
GoPcValueEvaluator fileEval = new GoPcValueEvaluator(this, pcfile);
385+
GoPcValueEvaluator lineEval = new GoPcValueEvaluator(this, pcln);
386+
387+
long startpc = entry;
388+
long prevFilenum = -1;
389+
int lineNum;
390+
while ((lineNum = lineEval.evalNext()) > 0) {
391+
int fileNum = fileEval.eval(startpc);
392+
if (fileNum < 0) {
393+
break;
394+
}
395+
fileEval.reset();
396+
397+
if (fileNum != prevFilenum) {
398+
prevFilenum = fileNum;
399+
String fileName = getSourceFilename(fileNum);
400+
if (!GoConstants.GOLANG_AUTOGENERATED_FILENAME.equals(fileName)) {
401+
fileName = FSUtilities.normalizeNativePath(fileName);
402+
403+
Address startAddr = programContext.getCodeAddress(startpc);
404+
long len = lineEval.getPC() - startpc;
405+
406+
try {
407+
SourceFile sourceFile = new SourceFile(fileName);
408+
sfman.addSourceFile(sourceFile);
409+
sfman.addSourceMapEntry(sourceFile, lineNum, startAddr, len);
410+
}
411+
catch (AddressOverflowException e) {
412+
Msg.error(this, "Failed to add source file mapping", e);
413+
}
414+
}
415+
}
416+
startpc = lineEval.getPC();
417+
}
418+
}
419+
catch (LockException | IOException e) {
420+
Msg.error(this, "Failed to set source file info", e);
421+
}
422+
}
423+
424+
private String getSourceFilename(int fileno) throws IOException {
425+
GoModuledata moduledata = getModuledata();
364426
long fileoff;
365427
GoSlice cutab = moduledata.getCutab();
366428
GoSlice filetab = moduledata.getFiletab();
@@ -376,7 +438,7 @@ public GoSourceFileInfo getSourceFileInfo() throws IOException {
376438
String fileName = fileoff >= 0 // -1 == no value
377439
? nameSlice.getElementReader(1, (int) fileoff).readNextUtf8String()
378440
: null;
379-
return fileName != null ? new GoSourceFileInfo(fileName, lineNum) : null;
441+
return fileName;
380442
}
381443

382444
/**

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/rtti/GoPcValueEvaluator.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,6 +30,7 @@ public class GoPcValueEvaluator {
3030
private final int pcquantum;
3131
private final long funcEntry;
3232
private final BinaryReader reader;
33+
private final long startPosition;
3334

3435
private int value = -1;
3536
private long pc;
@@ -47,11 +48,22 @@ public GoPcValueEvaluator(GoFuncData func, long offset) throws IOException {
4748

4849
this.pcquantum = moduledata.getGoBinary().getMinLC();
4950
this.reader = moduledata.getPcValueTable().getElementReader(1, (int) offset);
51+
this.startPosition = reader.getPointerIndex();
5052

5153
this.funcEntry = func.getFuncAddress().getOffset();
5254
this.pc = funcEntry;
5355
}
5456

57+
public long getPC() {
58+
return pc;
59+
}
60+
61+
public void reset() {
62+
reader.setPointerIndex(startPosition);
63+
value = -1;
64+
pc = funcEntry;
65+
}
66+
5567
/**
5668
* Returns the largest PC value calculated when evaluating the result of the table's sequence.
5769
*
@@ -79,6 +91,10 @@ public int eval(long targetPC) throws IOException {
7991
return value;
8092
}
8193

94+
public int evalNext() throws IOException {
95+
return eval(pc);
96+
}
97+
8298
/**
8399
* Returns the set of all values for each unique pc section.
84100
*

0 commit comments

Comments
 (0)