GP-6905 skip DWARF source file info elements based on addr 0

Some toolchains leave information about dead/removed code in the
sourcefile data.  The sourcefile elements are based off an absolute
address value of '0', which typically is not valid in fully linked
binaries.
This commit is contained in:
dev747368
2026-06-02 21:12:15 +00:00
parent c2e68990d8
commit e6991cb0de
6 changed files with 42 additions and 7 deletions
@@ -743,10 +743,14 @@ public class DIEAggregate {
DWARFAttribute lowPc = findAttribute(DW_AT_low_pc);
if (lowPc != null && lowPc.getValue() instanceof DWARFNumericAttribute lowPcAttrVal) {
try {
// TODO: previous code excluded lowPc values that were == 0 as invalid.
long rawLowPc = lowPcAttrVal.getUnsignedValue();
long lowPcOffset = getDIEContainer().getAddress(lowPc.getAttributeForm(), rawLowPc,
getCompilationUnit());
if (lowPcOffset == 0 && getProgram().isAddr0Tombstone()) {
return DWARFRange.EMPTY;
}
long highPcOffset = lowPcOffset;
DWARFAttribute highPc = findAttribute(DW_AT_high_pc);
@@ -41,6 +41,7 @@ public class DWARFImportSummary {
int paramZeroLenDataType;
public int badSourceFileCount;
public int numEnumsCreated;
public int tombstonedSourceLineEntrySkippedCount;
Set<Integer> dwarfVers = new HashSet<>();
int compUnitCount;
@@ -121,6 +121,7 @@ public class DWARFProgram implements Closeable {
private DWARFImportSummary importSummary = new DWARFImportSummary();
private DWARFSectionProvider sectionProvider;
protected long programBaseAddressFixup;
protected boolean addr0IsTombstone;
private Charset charset;
private int maxDNICacheSize = 50;
@@ -594,6 +595,9 @@ public class DWARFProgram implements Closeable {
public void setProgramBaseAddressFixup(long programBaseAddressFixup) {
this.programBaseAddressFixup = programBaseAddressFixup;
this.addr0IsTombstone = !program.getMemory()
.getExecuteSet()
.contains(getCodeAddress(0 + programBaseAddressFixup));
}
public AddressRange getAddressRange(DWARFRange range, boolean isCode) {
@@ -622,6 +626,10 @@ public class DWARFProgram implements Closeable {
return realZero.equals(addr);
}
public boolean isAddr0Tombstone() {
return addr0IsTombstone;
}
public boolean stackGrowsNegative() {
return stackGrowsNegative;
}
@@ -268,7 +268,7 @@ public class DWARFLine {
DWARFLineProgramExecutor lpe = new DWARFLineProgramExecutor(
cu.getDIEContainer().getDebugLineReader().clone(opcodes_start), endOffset,
cu.getPointerSize(), opcode_base, line_base, line_range, minimum_instruction_length,
default_is_stmt);
default_is_stmt, cu.getProgram().isAddr0Tombstone());
return lpe;
}
@@ -286,6 +286,12 @@ public class DWARFLine {
try (DWARFLineProgramExecutor lpe = getLineProgramExecutor(cu)) {
List<SourceFileAddr> results = new ArrayList<>();
for (DWARFLineProgramState row : lpe.allRows()) {
if (row.tombstone) {
// skips elements that were based on tombstoned/dead code that wasn't included
// in final binary
cu.getProgram().getImportSummary().tombstonedSourceLineEntrySkippedCount++;
continue;
}
try {
DWARFFile file = getFile(row.file);
results.add(new SourceFileAddr(row.address, file.getPathName(this),
@@ -40,10 +40,11 @@ public final class DWARFLineProgramExecutor implements Closeable {
private final int lineBase;
private final int minInstrLen;
private final boolean defaultIsStatement;
private final boolean addr0IsTombstone;
public DWARFLineProgramExecutor(BinaryReader reader, long streamEnd, int pointerSize,
int opcodeBase, int lineBase, int lineRange, int minInstrLen,
boolean defaultIsStatement) {
boolean defaultIsStatement, boolean addr0IsTombstone) {
this.reader = reader;
this.streamEnd = streamEnd;
this.pointerSize = pointerSize;
@@ -52,6 +53,7 @@ public final class DWARFLineProgramExecutor implements Closeable {
this.lineRange = lineRange;
this.minInstrLen = minInstrLen;
this.defaultIsStatement = defaultIsStatement;
this.addr0IsTombstone = addr0IsTombstone;
}
@Override
@@ -161,6 +163,13 @@ public final class DWARFLineProgramExecutor implements Closeable {
break;
case DW_LNE_set_address:
state.address = reader.readNextUnsignedValue(pointerSize);
// set tombstone flag when an absolute 0 is set for the address. (will not catch
// relative offsets that evaluate to 0, but that is not a pattern that has been seen)
// Following instructions that have relative offset changes to the address value
// will inherit this value in each row object that is cloned
state.tombstone = addr0IsTombstone && (state.address == 0);
operands = List.of(state.address);
break;
case DW_LNE_define_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.
@@ -63,6 +63,12 @@ public class DWARFLineProgramState {
public long discriminator;
/**
* A boolean indicating that the row is based on instructions that are likely attached to a
* dead / tombstoned location.
*/
public boolean tombstone;
public DWARFLineProgramState(boolean defaultIsStatement) {
this.isStatement = defaultIsStatement;
}
@@ -79,6 +85,7 @@ public class DWARFLineProgramState {
this.epilogueBegin = other.epilogueBegin;
this.isa = other.isa;
this.discriminator = other.discriminator;
this.tombstone = other.tombstone;
}
public boolean isSameFileLine(DWARFLineProgramState other) {
@@ -88,9 +95,9 @@ public class DWARFLineProgramState {
@Override
public String toString() {
return String.format(
"DWARFLineProgramState [address=%s, file=%s, line=%s, column=%s, isStatement=%s, isBasicBlock=%s, isEndSequence=%s, prologueEnd=%s, epilogueBegin=%s, isa=%s, discriminator=%s]",
"DWARFLineProgramState [address=%s, file=%s, line=%s, column=%s, isStatement=%s, isBasicBlock=%s, isEndSequence=%s, prologueEnd=%s, epilogueBegin=%s, isa=%s, discriminator=%s, tombstone=%s]",
address, file, line, column, isStatement, isBasicBlock, isEndSequence, prologueEnd,
epilogueBegin, isa, discriminator);
epilogueBegin, isa, discriminator, tombstone);
}
}