[llvm] 0cd7a32 - [NFC][DebugInfo] Refactor address advancing operations to share code
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 06:00:33 PDT 2020
Author: James Henderson
Date: 2020-03-09T12:59:43Z
New Revision: 0cd7a32522ffb93b936e51a95fac4f8f536cfe09
URL: https://github.com/llvm/llvm-project/commit/0cd7a32522ffb93b936e51a95fac4f8f536cfe09
DIFF: https://github.com/llvm/llvm-project/commit/0cd7a32522ffb93b936e51a95fac4f8f536cfe09.diff
LOG: [NFC][DebugInfo] Refactor address advancing operations to share code
This change is a preparatory change for subsequent commits.
Reviewed by: probinson
Differential Revision: https://reviews.llvm.org/D75188
Added:
Modified:
llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index eadb0f4b0e76..0eece9239f8a 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -367,6 +367,28 @@ class DWARFDebugLine {
void resetRowAndSequence();
void appendRowToMatrix();
+ /// Advance the address by the \p OperationAdvance value. \returns the
+ /// amount advanced by.
+ uint64_t advanceAddr(uint64_t OperationAdvance);
+
+ struct AddrAndAdjustedOpcode {
+ uint64_t AddrDelta;
+ uint8_t AdjustedOpcode;
+ };
+
+ /// Advance the address as required by the specified \p Opcode.
+ /// \returns the amount advanced by and the calculated adjusted opcode.
+ AddrAndAdjustedOpcode advanceAddrForOpcode(uint8_t Opcode);
+
+ struct AddrAndLineDelta {
+ uint64_t Address;
+ int32_t Line;
+ };
+
+ /// Advance the line and address as required by the specified special \p
+ /// Opcode. \returns the address and line delta.
+ AddrAndLineDelta handleSpecialOpcode(uint8_t Opcode);
+
/// Line table we're currently parsing.
struct LineTable *LineTable;
struct Row Row;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 3c1f48a7ce9e..d3421efa0df0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -566,6 +566,67 @@ Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
return LT;
}
+uint64_t DWARFDebugLine::ParsingState::advanceAddr(uint64_t OperationAdvance) {
+ uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength;
+ Row.Address.Address += AddrOffset;
+ return AddrOffset;
+}
+
+DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode
+DWARFDebugLine::ParsingState::advanceAddrForOpcode(uint8_t Opcode) {
+ assert(Opcode == DW_LNS_const_add_pc ||
+ Opcode >= LineTable->Prologue.OpcodeBase);
+ uint8_t OpcodeValue = Opcode;
+ if (Opcode == DW_LNS_const_add_pc)
+ OpcodeValue = 255;
+ uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
+ uint64_t OperationAdvance = AdjustedOpcode / LineTable->Prologue.LineRange;
+ uint64_t AddrOffset = advanceAddr(OperationAdvance);
+ return {AddrOffset, AdjustedOpcode};
+}
+
+DWARFDebugLine::ParsingState::AddrAndLineDelta
+DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode) {
+ // A special opcode value is chosen based on the amount that needs
+ // to be added to the line and address registers. The maximum line
+ // increment for a special opcode is the value of the line_base
+ // field in the header, plus the value of the line_range field,
+ // minus 1 (line base + line range - 1). If the desired line
+ // increment is greater than the maximum line increment, a standard
+ // opcode must be used instead of a special opcode. The "address
+ // advance" is calculated by dividing the desired address increment
+ // by the minimum_instruction_length field from the header. The
+ // special opcode is then calculated using the following formula:
+ //
+ // opcode = (desired line increment - line_base) +
+ // (line_range * address advance) + opcode_base
+ //
+ // If the resulting opcode is greater than 255, a standard opcode
+ // must be used instead.
+ //
+ // To decode a special opcode, subtract the opcode_base from the
+ // opcode itself to give the adjusted opcode. The amount to
+ // increment the address register is the result of the adjusted
+ // opcode divided by the line_range multiplied by the
+ // minimum_instruction_length field from the header. That is:
+ //
+ // address increment = (adjusted opcode / line_range) *
+ // minimum_instruction_length
+ //
+ // The amount to increment the line register is the line_base plus
+ // the result of the adjusted opcode modulo the line_range. That is:
+ //
+ // line increment = line_base + (adjusted opcode % line_range)
+
+ DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode AddrAdvanceResult =
+ advanceAddrForOpcode(Opcode);
+ int32_t LineOffset =
+ LineTable->Prologue.LineBase +
+ (AddrAdvanceResult.AdjustedOpcode % LineTable->Prologue.LineRange);
+ Row.Line += LineOffset;
+ return {AddrAdvanceResult.AddrDelta, LineOffset};
+}
+
Error DWARFDebugLine::LineTable::parse(
DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
const DWARFContext &Ctx, const DWARFUnit *U,
@@ -793,8 +854,7 @@ Error DWARFDebugLine::LineTable::parse(
// result to the address register of the state machine.
{
uint64_t AddrOffset =
- DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
- State.Row.Address.Address += AddrOffset;
+ State.advanceAddr(DebugLineData.getULEB128(OffsetPtr));
if (OS)
*OS << " (" << AddrOffset << ")";
}
@@ -849,13 +909,9 @@ Error DWARFDebugLine::LineTable::parse(
// than twice that range will it need to use both DW_LNS_advance_pc
// and a special opcode, requiring three or more bytes.
{
- uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
- uint64_t AddrOffset =
- (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
- State.Row.Address.Address += AddrOffset;
+ uint64_t AddrOffset = State.advanceAddrForOpcode(Opcode).AddrDelta;
if (OS)
- *OS
- << format(" (0x%16.16" PRIx64 ")", AddrOffset);
+ *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset);
}
break;
@@ -915,49 +971,11 @@ Error DWARFDebugLine::LineTable::parse(
break;
}
} else {
- // Special Opcodes
-
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base
- // field in the header, plus the value of the line_range field,
- // minus 1 (line base + line range - 1). If the desired line
- // increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The "address
- // advance" is calculated by dividing the desired address increment
- // by the minimum_instruction_length field from the header. The
- // special opcode is then calculated using the following formula:
- //
- // opcode = (desired line increment - line_base) +
- // (line_range * address advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode
- // must be used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the
- // opcode itself to give the adjusted opcode. The amount to
- // increment the address register is the result of the adjusted
- // opcode divided by the line_range multiplied by the
- // minimum_instruction_length field from the header. That is:
- //
- // address increment = (adjusted opcode / line_range) *
- // minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus
- // the result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
- uint64_t AddrOffset =
- (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
- int32_t LineOffset =
- Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
- State.Row.Line += LineOffset;
- State.Row.Address.Address += AddrOffset;
+ // Special Opcodes.
+ ParsingState::AddrAndLineDelta Delta = State.handleSpecialOpcode(Opcode);
if (OS) {
- *OS << "address += " << AddrOffset << ", line += " << LineOffset
+ *OS << "address += " << Delta.Address << ", line += " << Delta.Line
<< "\n";
OS->indent(12);
State.Row.dump(*OS);
More information about the llvm-commits
mailing list