From a813e1da2e084d4e4d67652bead14d57811ae746 Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Mon, 20 Mar 2023 21:31:51 +0000 Subject: [PATCH] GP-3175 fix DWARF importer to handle Apple specific DWARF records Also fix filename lookup to look in the same compUnit as the fileNum attribute. Also fix NPE in DataTypeUtilities.isSameKindBuiltInDataType() --- .../util/bin/format/dwarf4/DIEAggregate.java | 21 +++++++++++++++++++ .../bin/format/dwarf4/DWARFCompileUnit.java | 10 +++++++++ .../app/util/bin/format/dwarf4/DWARFLine.java | 11 ++++++++++ .../dwarf4/encoding/DWARFAttribute.java | 8 +++++++ .../bin/format/dwarf4/encoding/DWARFTag.java | 2 ++ .../dwarf4/next/DWARFDataTypeImporter.java | 1 + .../format/dwarf4/next/DWARFSourceInfo.java | 7 +++---- .../database/data/DataTypeUtilities.java | 2 +- 8 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java index 63fa871324..582a85ad35 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DIEAggregate.java @@ -432,6 +432,27 @@ public class DIEAggregate { return getRef(DWARFAttribute.DW_AT_type); } + /** + * Returns the name of the source file this item was declared in (DW_AT_decl_file) + * + * @return name of file this item was declared in, or null if info not available + */ + public String getSourceFile() { + AttrInfo attrInfo = findAttribute(DWARFAttribute.DW_AT_decl_file); + if (attrInfo == null) { + return null; + } + DWARFNumericAttribute attr = attrInfo.getValue(DWARFNumericAttribute.class); + if (attr == null) { + return null; + } + int fileNum = (int) attr.getUnsignedValue(); + DWARFCompileUnit dcu = attrInfo.die.getCompilationUnit().getCompileUnit(); + return dcu.isValidFileIndex(fileNum) + ? dcu.getFileByIndex(fileNum) + : null; + } + /** * Return a list of children that are of a specific DWARF type. *

diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFCompileUnit.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFCompileUnit.java index 2709aa7ace..513553932f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFCompileUnit.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFCompileUnit.java @@ -144,6 +144,16 @@ public class DWARFCompileUnit { return this.line.getFile(index, this.comp_dir); } + /** + * Checks validity of a file index number. + * + * @param index file number, 1..N + * @return boolean true if index is a valid file number, false otherwise + */ + public boolean isValidFileIndex(int index) { + return line.isValidFileIndex(index); + } + /** * Get the producer of the compile unit * @return the producer of the compile unit diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFLine.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFLine.java index 52207659a0..d59f400acf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFLine.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/DWARFLine.java @@ -190,6 +190,17 @@ public class DWARFLine { "Negative file index was given: " + Integer.toString(index)); } + /** + * Returns true if file exists. + * + * @param index file number, excluding 0 + * @return boolean true if file exists + */ + public boolean isValidFileIndex(int index) { + index--; + return 0 <= index && index < file_names.size(); + } + @Override public String toString() { StringBuffer buffer = new StringBuffer(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFAttribute.java index 7d5668e188..df99a4f544 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFAttribute.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFAttribute.java @@ -157,6 +157,14 @@ public final class DWARFAttribute { public static final int DW_AT_GNU_pubtypes = 0x2135; // end GNU DebugFission + // Apple proprietary tags + public static final int DW_AT_APPLE_ptrauth_key = 0x3e04; + public static final int DW_AT_APPLE_ptrauth_address_discriminated = 0x3e05; + public static final int DW_AT_APPLE_ptrauth_extra_discriminator = 0x3e06; + public static final int DW_AT_APPLE_omit_frame_ptr = 0x3fe7; + public static final int DW_AT_APPLE_optimized = 0x3fe1; + // end Apple proprietary tags + public static String toString(long value) { return DWARFUtil.toString(DWARFAttribute.class, value); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFTag.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFTag.java index b52d572444..b7016c7ad4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFTag.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/encoding/DWARFTag.java @@ -98,4 +98,6 @@ public final class DWARFTag public static final int DW_TAG_gnu_call_site_parameter = 0x410a; public static final int DW_TAG_hi_user = 0xffff; + public static final int DW_TAG_APPLE_ptrauth_type = 0x4300; // Apple proprietary + } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeImporter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeImporter.java index c12112fa52..b8e65b5d56 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeImporter.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeImporter.java @@ -175,6 +175,7 @@ public class DWARFDataTypeImporter { case DWARFTag.DW_TAG_volatile_type: case DWARFTag.DW_TAG_restrict_type: case DWARFTag.DW_TAG_shared_type: + case DWARFTag.DW_TAG_APPLE_ptrauth_type: result = makeDataTypeForConst(diea); break; case DWARFTag.DW_TAG_enumeration_type: diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFSourceInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFSourceInfo.java index 6150242ef6..f90806876b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFSourceInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFSourceInfo.java @@ -34,12 +34,11 @@ public class DWARFSourceInfo { * @return new {@link DWARFSourceInfo} with filename:linenum info, or null if no info present in DIEA. */ public static DWARFSourceInfo create(DIEAggregate diea) { - int fileNum = (int) diea.getUnsignedLong(DWARFAttribute.DW_AT_decl_file, -1); + String file = diea.getSourceFile(); int lineNum = (int) diea.getUnsignedLong(DWARFAttribute.DW_AT_decl_line, -1); - return (fileNum != -1 && lineNum != -1) - ? new DWARFSourceInfo( - diea.getCompilationUnit().getCompileUnit().getFileByIndex(fileNum), lineNum) + return (file != null && lineNum != -1) + ? new DWARFSourceInfo(file, lineNum) : null; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java index 1e5f2ab47e..91f137e655 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java @@ -285,7 +285,7 @@ public class DataTypeUtilities { DataType dataType2) { if (dataType1 instanceof BuiltIn) { // Same kind if both types share a common BuiltIn implementation - Class baseClass = dataType1.getClass().getSuperclass(); + Class baseClass = dataType1.getClass(); Class superClass; while ((superClass = baseClass.getSuperclass()) != BuiltIn.class) { baseClass = superClass;