Skip to content

Commit

Permalink
Merge remote-tracking branch
Browse files Browse the repository at this point in the history
'origin/GP-1192_dev747368_DWARF_PE--SQUASHED' (Closes #1267)
  • Loading branch information
ryanmkurtz committed Aug 19, 2021
2 parents 224283e + 7895906 commit 81d8ed1
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 23 deletions.
Expand Up @@ -108,16 +108,20 @@ public class DWARFCompilationUnit {
* from the debug_info section and the debug_abbr section and its compileUnit DIE (ie.
* the first DIE right after the header).
* <p>
* Returns NULL if there was an ignorable error while reading the compilation unit (and
* Returns {@code NULL} if there was an ignorable error while reading the compilation unit (and
* leaves the input stream at the next compilation unit to read), otherwise throws
* an IOException if there was an unrecoverable error.
* <p>
* Also returns {@code NULL} (and leaves the stream at EOF) if the remainder of the stream
* is filled with null bytes.
*
* @param dwarfProgram the dwarf program.
* @param debugInfoBR the debug info binary reader.
* @param debugAbbrBR the debug abbreviation binary reader
* @param cuNumber the compilation unit number
* @param monitor the current task monitor
* @return the read compilation unit.
* @return the read compilation unit, or null if the compilation unit was bad/empty and should
* be ignored
* @throws DWARFException if an invalid or unsupported DWARF version is read.
* @throws IOException if the length of the compilation unit is invalid.
* @throws CancelledException if the task has been canceled.
Expand All @@ -129,6 +133,19 @@ public static DWARFCompilationUnit readCompilationUnit(DWARFProgram dwarfProgram
long startOffset = debugInfoBR.getPointerIndex();
LengthResult lengthInfo =
DWARFUtil.readLength(debugInfoBR, dwarfProgram.getGhidraProgram());
if (lengthInfo.length == 0) {
if (isAllZerosUntilEOF(debugInfoBR)) {
// hack to handle trailing padding at end of section. (similar to the check for
// unexpectedTerminator in readDIEs(), when padding occurs inside the bounds
// of the compile unit's range after the end of the root DIE's children)
debugInfoBR.setPointerIndex(debugInfoBR.length());
return null;
}
else {
throw new DWARFException(
"Invalid DWARF length 0 at 0x" + Long.toHexString(startOffset));
}
}

long endOffset = debugInfoBR.getPointerIndex() + lengthInfo.length;
short version = debugInfoBR.readNextShort();
Expand Down Expand Up @@ -177,6 +194,16 @@ else if (firstDIEOffset == endOffset) {
}
}

private static boolean isAllZerosUntilEOF(BinaryReader reader) throws IOException {
reader = reader.clone();
while (reader.getPointerIndex() < reader.length()) {
if (reader.readNextByte() != 0) {
return false;
}
}
return true;
}

/**
* This ctor is public only for junit tests. Do not use directly.
*
Expand Down
Expand Up @@ -15,11 +15,12 @@
*/
package ghidra.app.util.bin.format.dwarf4;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FilenameUtils;

import ghidra.app.util.bin.BinaryReader;
Expand Down Expand Up @@ -69,6 +70,10 @@ public static DWARFLine read(DIEAggregate diea) throws IOException, DWARFExcepti
LengthResult lengthInfo = DWARFUtil.readLength(reader, dProg.getGhidraProgram());
result.unit_length = lengthInfo.length;
result.format = lengthInfo.format;
if (result.unit_length == 0) {
throw new DWARFException(
"Invalid DWARFLine length 0 at 0x" + Long.toHexString(stmtListOffset));
}

// A version number for this line number information section
result.version = reader.readNextUnsignedShort();
Expand Down
Expand Up @@ -15,13 +15,14 @@
*/
package ghidra.app.util.bin.format.dwarf4;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.dwarf4.attribs.DWARFAttributeValue;
import ghidra.app.util.bin.format.dwarf4.attribs.DWARFNumericAttribute;
Expand Down Expand Up @@ -584,13 +585,13 @@ private LengthResult(long length, int format) {
*
* @param reader {@link BinaryReader} stream to read from
* @param program Ghidra {@link Program}
* @return new {@link LengthResult}, never null
* @return new {@link LengthResult}, never null; length == 0 should be checked for and treated
* specially
* @throws IOException if io error
* @throws DWARFException if invalid values
*/
public static LengthResult readLength(BinaryReader reader, Program program)
throws IOException, DWARFException {
long startOffset = reader.getPointerIndex();
long length = reader.readNextUnsignedInt();
int format;

Expand All @@ -617,8 +618,8 @@ else if (length == 0) {
format = DWARFCompilationUnit.DWARF_64;
}
else {
throw new DWARFException(
"Invalid DWARF length 0 at 0x" + Long.toHexString(startOffset));
// length 0 signals an error to caller
format = DWARFCompilationUnit.DWARF_32; // doesn't matter
}
}
else {
Expand Down
Expand Up @@ -15,9 +15,10 @@
*/
package ghidra.app.util.bin.format.dwarf4.next;

import java.util.*;

import java.io.Closeable;
import java.io.IOException;
import java.util.*;

import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
Expand All @@ -28,8 +29,7 @@
import ghidra.app.util.bin.format.dwarf4.encoding.*;
import ghidra.app.util.bin.format.dwarf4.expression.DWARFExpressionException;
import ghidra.app.util.bin.format.dwarf4.next.sectionprovider.*;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.app.util.opinion.MachoLoader;
import ghidra.app.util.opinion.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.CategoryPath;
Expand Down Expand Up @@ -67,15 +67,17 @@ public class DWARFProgram implements Closeable {
* @return boolean true if program has DWARF info, false if not
*/
public static boolean isDWARF(Program program) {
String format = program.getExecutableFormat();

if (ElfLoader.ELF_NAME.equals(format) &&
DWARFSectionProviderFactory.createSectionProviderFor(program) != null) {
return true;
}
if (MachoLoader.MACH_O_NAME.equals(format) &&
DSymSectionProvider.getDSYMForProgram(program) != null) {
return true;
String format = Objects.requireNonNullElse(program.getExecutableFormat(), "");

switch (format) {
case ElfLoader.ELF_NAME:
case PeLoader.PE_NAME:
try (DWARFSectionProvider dsp =
DWARFSectionProviderFactory.createSectionProviderFor(program)) {
return dsp != null;
}
case MachoLoader.MACH_O_NAME:
return DSymSectionProvider.getDSYMForProgram(program) != null;
}
return false;
}
Expand Down

0 comments on commit 81d8ed1

Please sign in to comment.