Merge remote-tracking branch 'origin/GP-4196_dev747368_golang_sourcefile'

This commit is contained in:
Ryan Kurtz
2025-01-02 03:49:59 -05:00
6 changed files with 96 additions and 7 deletions

View File

@@ -234,6 +234,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
GoSourceFileInfo sfi = null;
if (analyzerOptions.outputSourceInfo && (sfi = funcdata.getSourceFileInfo()) != null) {
markupSession.appendComment(func, "Golang source: ", sfi.getDescription());
funcdata.markupSourceFileInfo();
}
if (funcdata.getFlags().isEmpty() /* dont try to get arg info for ASM funcs*/) {

View File

@@ -18,10 +18,13 @@ package ghidra.app.util.bin.format.dwarf;
import java.io.IOException;
import java.util.*;
import org.apache.commons.io.FilenameUtils;
import ghidra.app.plugin.core.datamgr.util.DataTypeUtils;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.dwarf.line.DWARFLine.SourceFileAddr;
import ghidra.app.util.bin.format.dwarf.line.DWARFLineProgramExecutor;
import ghidra.app.util.bin.format.golang.GoConstants;
import ghidra.framework.store.LockException;
import ghidra.program.database.sourcemap.SourceFile;
import ghidra.program.model.address.Address;
@@ -40,6 +43,9 @@ import utility.function.Dummy;
* {@link DWARFImportOptions}.
*/
public class DWARFImporter {
private static final Set<String> SOURCEFILENAMES_IGNORE =
Set.of(GoConstants.GOLANG_AUTOGENERATED_FILENAME);
private DWARFProgram prog;
private DWARFDataTypeManager dwarfDTM;
private TaskMonitor monitor;
@@ -202,7 +208,9 @@ public class DWARFImporter {
monitor.checkCancelled();
monitor.increment(1);
SourceFileAddr sfa = sourceInfo.get(i);
if (sfa.isEndSequence()) {
if (SOURCEFILENAMES_IGNORE.contains(sfa.fileName()) ||
SOURCEFILENAMES_IGNORE.contains(FilenameUtils.getName(sfa.fileName())) ||
sfa.isEndSequence()) {
continue;
}
Address addr = prog.getCodeAddress(sfa.address());

View File

@@ -247,7 +247,7 @@ public class DWARFLine {
private int address_size;
private int segment_selector_size;
private long opcodes_start = -1; // offset where line number program opcodes start
private long opcodes_start; // offset where line number program opcodes start
private DWARFLine() {
// empty, use #read()

View File

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

View File

@@ -19,12 +19,19 @@ import java.io.IOException;
import java.util.*;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.golang.GoConstants;
import ghidra.app.util.bin.format.golang.rtti.types.GoMethod.GoMethodInfo;
import ghidra.app.util.bin.format.golang.structmapping.*;
import ghidra.formats.gfilesystem.FSUtilities;
import ghidra.framework.store.LockException;
import ghidra.program.database.sourcemap.SourceFile;
import ghidra.program.model.address.*;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.model.sourcemap.SourceFileManager;
import ghidra.util.Msg;
import ghidra.util.NumericUtilities;
import ghidra.util.exception.CancelledException;
@@ -361,6 +368,61 @@ public class GoFuncData implements StructureMarkup<GoFuncData> {
return null;
}
String fileName = getSourceFilename(fileno);
return fileName != null ? new GoSourceFileInfo(fileName, lineNum) : null;
}
public void markupSourceFileInfo() {
GoModuledata moduledata = getModuledata();
if (moduledata == null) {
return;
}
Program program = programContext.getProgram();
SourceFileManager sfman = program.getSourceFileManager();
try {
GoPcValueEvaluator fileEval = new GoPcValueEvaluator(this, pcfile);
GoPcValueEvaluator lineEval = new GoPcValueEvaluator(this, pcln);
long startpc = entry;
long prevFilenum = -1;
int lineNum;
while ((lineNum = lineEval.evalNext()) > 0) {
int fileNum = fileEval.eval(startpc);
if (fileNum < 0) {
break;
}
fileEval.reset();
if (fileNum != prevFilenum) {
prevFilenum = fileNum;
String fileName = getSourceFilename(fileNum);
if (!GoConstants.GOLANG_AUTOGENERATED_FILENAME.equals(fileName)) {
fileName = FSUtilities.normalizeNativePath(fileName);
Address startAddr = programContext.getCodeAddress(startpc);
long len = lineEval.getPC() - startpc;
try {
SourceFile sourceFile = new SourceFile(fileName);
sfman.addSourceFile(sourceFile);
sfman.addSourceMapEntry(sourceFile, lineNum, startAddr, len);
}
catch (AddressOverflowException e) {
Msg.error(this, "Failed to add source file mapping", e);
}
}
}
startpc = lineEval.getPC();
}
}
catch (LockException | IOException e) {
Msg.error(this, "Failed to set source file info", e);
}
}
private String getSourceFilename(int fileno) throws IOException {
GoModuledata moduledata = getModuledata();
long fileoff;
GoSlice cutab = moduledata.getCutab();
GoSlice filetab = moduledata.getFiletab();
@@ -376,7 +438,7 @@ public class GoFuncData implements StructureMarkup<GoFuncData> {
String fileName = fileoff >= 0 // -1 == no value
? nameSlice.getElementReader(1, (int) fileoff).readNextUtf8String()
: null;
return fileName != null ? new GoSourceFileInfo(fileName, lineNum) : null;
return fileName;
}
/**

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,6 +30,7 @@ public class GoPcValueEvaluator {
private final int pcquantum;
private final long funcEntry;
private final BinaryReader reader;
private final long startPosition;
private int value = -1;
private long pc;
@@ -47,11 +48,22 @@ public class GoPcValueEvaluator {
this.pcquantum = moduledata.getGoBinary().getMinLC();
this.reader = moduledata.getPcValueTable().getElementReader(1, (int) offset);
this.startPosition = reader.getPointerIndex();
this.funcEntry = func.getFuncAddress().getOffset();
this.pc = funcEntry;
}
public long getPC() {
return pc;
}
public void reset() {
reader.setPointerIndex(startPosition);
value = -1;
pc = funcEntry;
}
/**
* Returns the largest PC value calculated when evaluating the result of the table's sequence.
*
@@ -79,6 +91,10 @@ public class GoPcValueEvaluator {
return value;
}
public int evalNext() throws IOException {
return eval(pc);
}
/**
* Returns the set of all values for each unique pc section.
*