Merge remote-tracking branch 'origin/GP-3994_dev747368_dwarf_func_range--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-11-06 15:17:30 -05:00
commit 97cef47945
2 changed files with 46 additions and 22 deletions

View File

@ -15,7 +15,7 @@
*/
package ghidra.app.util.bin.format.dwarf4;
import static ghidra.app.util.bin.format.dwarf4.encoding.DWARFTag.DW_TAG_formal_parameter;
import static ghidra.app.util.bin.format.dwarf4.encoding.DWARFTag.*;
import java.io.IOException;
import java.util.*;
@ -864,11 +864,29 @@ public class DIEAggregate {
* Parses a range list from the debug_ranges section.
* See DWARF4 Section 2.17.3 (Non-Contiguous Address Ranges).
* <p>
* The returned list of ranges is sorted.
*
* @param attribute attribute ie. {@link DWARFAttribute#DW_AT_ranges}
* @return list of ranges, in order
* @throws IOException if an I/O error occurs
*/
public List<DWARFRange> parseDebugRange(int attribute) throws IOException {
List<DWARFRange> result = readRange(attribute);
Collections.sort(result);
return result;
}
/**
* Parses a range list from the debug_ranges section.
* See DWARF4 Section 2.17.3 (Non-Contiguous Address Ranges).
* <p>
* The returned list is not sorted.
*
* @param attribute attribute ie. {@link DWARFAttribute#DW_AT_ranges}
* @return list of ranges
* @throws IOException if an I/O error occurs
*/
public List<DWARFRange> parseDebugRange(int attribute) throws IOException {
public List<DWARFRange> readRange(int attribute) throws IOException {
byte pointerSize = getCompilationUnit().getPointerSize();
BinaryReader reader = getCompilationUnit().getProgram().getDebugRanges();
@ -903,7 +921,6 @@ public class DIEAggregate {
// Add the range to the list
ranges.add(new DWARFRange(baseAddress + beginning, baseAddress + ending));
}
Collections.sort(ranges);
return ranges;
}

View File

@ -16,7 +16,7 @@
package ghidra.app.util.bin.format.dwarf4.next;
import static ghidra.app.util.bin.format.dwarf4.encoding.DWARFAttribute.*;
import static ghidra.app.util.bin.format.dwarf4.encoding.DWARFTag.DW_TAG_unspecified_parameters;
import static ghidra.app.util.bin.format.dwarf4.encoding.DWARFTag.*;
import java.io.IOException;
import java.util.*;
@ -75,14 +75,17 @@ public class DWARFFunction {
*/
public static DWARFFunction read(DIEAggregate diea)
throws IOException, DWARFExpressionException {
if (isBadSubprogramDef(diea)) {
if (diea.isDanglingDeclaration()) {
return null;
}
Address funcAddr = getFuncEntry(diea);
if (funcAddr == null) {
return null;
}
DWARFProgram prog = diea.getProgram();
DWARFDataTypeManager dwarfDTM = prog.getDwarfDTM();
Address funcAddr = prog.getCodeAddress(diea.getLowPC(0));
DWARFFunction dfunc = new DWARFFunction(diea, prog.getName(diea), funcAddr);
dfunc.namespace = dfunc.name.getParentNamespace(prog.getGhidraProgram());
@ -334,25 +337,29 @@ public class DWARFFunction {
name, address, params, sourceInfo, localVarErrors, retval);
}
private static boolean isBadSubprogramDef(DIEAggregate diea) {
if (diea.isDanglingDeclaration() || !diea.hasAttribute(DW_AT_low_pc)) {
return true;
}
// fetch the low_pc attribute directly instead of calling diea.getLowPc() to avoid
// any fixups applied by lower level code
DWARFNumericAttribute attr =
diea.getAttribute(DW_AT_low_pc, DWARFNumericAttribute.class);
if (attr != null && attr.getUnsignedValue() == 0) {
return true;
}
return false;
}
private void appendComment(Address address, int commentType, String comment, String sep) {
DWARFUtil.appendComment(getProgram().getGhidraProgram(), address, commentType, "", comment,
sep);
}
//---------------------------------------------------------------------------------------------
private static Address getFuncEntry(DIEAggregate diea) throws IOException {
// TODO: dw_at_entry_pc is also sometimes available, typically in things like inlined_subroutines
DWARFProgram dprog = diea.getProgram();
DWARFNumericAttribute lowpcAttr =
diea.getAttribute(DW_AT_low_pc, DWARFNumericAttribute.class);
if (lowpcAttr != null && lowpcAttr.getUnsignedValue() != 0) {
return dprog.getCodeAddress(
lowpcAttr.getUnsignedValue() + dprog.getProgramBaseAddressFixup());
}
if (diea.hasAttribute(DW_AT_ranges)) {
List<DWARFRange> bodyRanges = diea.readRange(DW_AT_ranges);
if (!bodyRanges.isEmpty()) {
return dprog.getCodeAddress(bodyRanges.get(0).getFrom());
}
}
return null;
}
}