GP-5755 Fix Apple KDK DWARF section name lookup, atomic type and source

file npe

Apple Macho binaries truncate section names to 16 chars, DWARF 5
introduced a section (debug_str_offsets) that has a name longer than 16
(along with the macho "__" prefix).

Add support for ignoring atomic_type, and some checking for missing
source file names.
This commit is contained in:
dev747368 2025-06-10 16:44:56 -04:00
parent f9a7a3d6ce
commit e2fa4aaa7b
4 changed files with 33 additions and 13 deletions

View file

@ -173,6 +173,7 @@ public class DWARFDataTypeImporter {
case DW_TAG_restrict_type: case DW_TAG_restrict_type:
case DW_TAG_shared_type: case DW_TAG_shared_type:
case DW_TAG_APPLE_ptrauth_type: case DW_TAG_APPLE_ptrauth_type:
case DW_TAG_atomic_type:
result = makeDataTypeForConst(diea); result = makeDataTypeForConst(diea);
break; break;
case DW_TAG_enumeration_type: case DW_TAG_enumeration_type:

View file

@ -41,6 +41,8 @@ public class DWARFImportSummary {
int exprReadError; int exprReadError;
Set<String> typeRemappings = new HashSet<>(); Set<String> typeRemappings = new HashSet<>();
int paramZeroLenDataType; int paramZeroLenDataType;
public int badSourceFileCount;
Set<Integer> dwarfVers = new HashSet<>(); Set<Integer> dwarfVers = new HashSet<>();
int compUnitCount; int compUnitCount;
int dieCount; int dieCount;
@ -136,6 +138,9 @@ public class DWARFImportSummary {
if (exprReadError > 0) { if (exprReadError > 0) {
Msg.error(this, "DWARF expression failed to read: " + exprReadError); Msg.error(this, "DWARF expression failed to read: " + exprReadError);
} }
if (badSourceFileCount > 0) {
Msg.error(this, "DWARF source file info errors: %d".formatted(badSourceFileCount));
}
} }
private <T extends Comparable<T>> List<T> getSortedSet(Set<T> set) { private <T extends Comparable<T>> List<T> getSortedSet(Set<T> set) {

View file

@ -282,8 +282,13 @@ public class DWARFLine {
if (cu.getDWARFVersion() >= 5 && (row.file < cu.getLine().getNumFiles())) { if (cu.getDWARFVersion() >= 5 && (row.file < cu.getLine().getNumFiles())) {
md5 = cu.getLine().getFile(row.file).getMD5(); md5 = cu.getLine().getFile(row.file).getMD5();
} }
results.add(new SourceFileAddr(row.address, getFilePath(row.file, true), md5, String filePath = getFilePath(row.file, true);
row.line, row.isEndSequence)); if (filePath != null) {
results.add(new SourceFileAddr(row.address, filePath, md5, row.line,
row.isEndSequence));
} else {
cu.getProgram().getImportSummary().badSourceFileCount++;
}
} }
return results; return results;

View file

@ -15,11 +15,11 @@
*/ */
package ghidra.app.util.bin.format.dwarf.sectionprovider; package ghidra.app.util.bin.format.dwarf.sectionprovider;
import java.util.HashMap;
import java.util.Map;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.AccessMode;
import java.util.HashMap;
import java.util.Map;
import ghidra.app.util.bin.*; import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.macho.*; import ghidra.app.util.bin.format.macho.*;
@ -35,7 +35,7 @@ import ghidra.util.task.TaskMonitor;
public class DSymSectionProvider implements DWARFSectionProvider { public class DSymSectionProvider implements DWARFSectionProvider {
private MachHeader machHeader; private MachHeader machHeader;
private Map<String, Section> machSectionsByName = new HashMap<>(); private Map<String, Section> machSectionsByName = new HashMap<>();
private RandomAccessByteProvider provider; private FileByteProvider provider;
public static File getDSYMForProgram(Program program) { public static File getDSYMForProgram(Program program) {
@ -63,7 +63,7 @@ public class DSymSectionProvider implements DWARFSectionProvider {
} }
public DSymSectionProvider(File dsymFile) throws IOException, MachException { public DSymSectionProvider(File dsymFile) throws IOException, MachException {
this.provider = new RandomAccessByteProvider(dsymFile); this.provider = new FileByteProvider(dsymFile, null, AccessMode.READ);
machHeader = new MachHeader(provider); machHeader = new MachHeader(provider);
machHeader.parse(); machHeader.parse();
@ -78,11 +78,20 @@ public class DSymSectionProvider implements DWARFSectionProvider {
public ByteProvider getSectionAsByteProvider(String sectionName, TaskMonitor monitor) public ByteProvider getSectionAsByteProvider(String sectionName, TaskMonitor monitor)
throws IOException { throws IOException {
Section s = machSectionsByName.get(sectionName); Section s = findSectionByName(sectionName);
return (s != null) ? new ByteProviderWrapper(provider, return (s != null) ? new ByteProviderWrapper(provider,
machHeader.getStartIndex() + s.getOffset(), s.getSize()) : null; machHeader.getStartIndex() + s.getOffset(), s.getSize()) : null;
} }
private Section findSectionByName(String name) {
Section section = machSectionsByName.get(name);
if (section == null &&
name.length() > 14 /* max macho section name length - 2 for leading "__" */) {
section = machSectionsByName.get(name.substring(0, 14));
}
return section;
}
@Override @Override
public void close() { public void close() {
FSUtilities.uncheckedClose(provider, null); FSUtilities.uncheckedClose(provider, null);
@ -91,7 +100,7 @@ public class DSymSectionProvider implements DWARFSectionProvider {
@Override @Override
public boolean hasSection(String... sectionNames) { public boolean hasSection(String... sectionNames) {
for (String sectionName : sectionNames) { for (String sectionName : sectionNames) {
if (machSectionsByName.get(sectionName) == null) { if (findSectionByName(sectionName) == null) {
return false; return false;
} }
} }