[lld] [llvm] [Symbolizer] Support for Missing Line Numbers. (PR #82240)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 01:15:07 PDT 2024
https://github.com/ampandey-1995 updated https://github.com/llvm/llvm-project/pull/82240
>From 6008be54e78613c62a53434cffe50ae263e944a8 Mon Sep 17 00:00:00 2001
From: Amit Pandey <amit.pandey at amd.com>
Date: Wed, 14 Feb 2024 16:31:48 +0530
Subject: [PATCH 1/6] Support for Missing Line Numbers.
LLVM Symbolizer attempt to symbolize addresses of optimized binaries
reports missing line numbers for some cases. It maybe due to compiler
which sometimes cannot map an instruction to line number due to
optimizations. Symbolizer should handle those cases gracefully.
Adding an option '-approximate-line-info=<before/after>' to symbolizer
so as to report the nearest non-zero line number.
---
bolt/lib/Core/BinaryFunction.cpp | 3 +-
lld/Common/DWARF.cpp | 3 +-
llvm/docs/CommandGuide/llvm-symbolizer.rst | 4 +
llvm/include/llvm/DebugInfo/DIContext.h | 8 +-
.../llvm/DebugInfo/DWARF/DWARFDebugLine.h | 16 +-
.../llvm/DebugInfo/Symbolize/Symbolize.h | 2 +
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 10 +-
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 35 ++++-
llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 8 +-
.../llvm-symbolizer/approximate-line-info.s | 142 ++++++++++++++++++
llvm/tools/llvm-symbolizer/Opts.td | 1 +
.../tools/llvm-symbolizer/llvm-symbolizer.cpp | 8 +
12 files changed, 215 insertions(+), 25 deletions(-)
create mode 100644 llvm/test/tools/llvm-symbolizer/approximate-line-info.s
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index ce4dd29f542b0d..5963722b4135bc 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -192,7 +192,8 @@ static SMLoc findDebugLineInformationForInstructionAt(
SMLoc NullResult = DebugLineTableRowRef::NULL_ROW.toSMLoc();
uint32_t RowIndex = LineTable->lookupAddress(
- {Address, object::SectionedAddress::UndefSection});
+ {Address, object::SectionedAddress::UndefSection},
+ DILineInfoSpecifier::ApproximateLineKind::None);
if (RowIndex == LineTable->UnknownRowIndex)
return NullResult;
diff --git a/lld/Common/DWARF.cpp b/lld/Common/DWARF.cpp
index 2cd8ca4575dee5..8e1e9c6e530157 100644
--- a/lld/Common/DWARF.cpp
+++ b/lld/Common/DWARF.cpp
@@ -93,7 +93,8 @@ std::optional<DILineInfo> DWARFCache::getDILineInfo(uint64_t offset,
DILineInfo info;
for (const llvm::DWARFDebugLine::LineTable *lt : lineTables) {
if (lt->getFileLineInfoForAddress(
- {offset, sectionIndex}, nullptr,
+ {offset, sectionIndex},
+ DILineInfoSpecifier::ApproximateLineKind::None, nullptr,
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, info))
return info;
}
diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst
index 59c0ab6d196ace..ee60d97babcbc7 100644
--- a/llvm/docs/CommandGuide/llvm-symbolizer.rst
+++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst
@@ -216,6 +216,10 @@ OPTIONS
This can be used to perform lookups as if the object were relocated by the
offset.
+.. option:: --approximate-line-info=<before/after>
+
+ Search the object to find the approximate non-zero line numbers nearest to for a given address.
+
.. option:: --basenames, -s
Print just the file's name without any directories, instead of the
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index b75dc8db54336b..eb4ff761119db5 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -152,14 +152,16 @@ struct DILineInfoSpecifier {
RelativeFilePath,
AbsoluteFilePath
};
+ enum ApproximateLineKind { None, Before, After };
using FunctionNameKind = DINameKind;
-
FileLineInfoKind FLIKind;
FunctionNameKind FNKind;
+ ApproximateLineKind ALKind;
DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::RawValue,
- FunctionNameKind FNKind = FunctionNameKind::None)
- : FLIKind(FLIKind), FNKind(FNKind) {}
+ FunctionNameKind FNKind = FunctionNameKind::None,
+ ApproximateLineKind ALKind = ApproximateLineKind::None)
+ : FLIKind(FLIKind), FNKind(FNKind), ALKind(ALKind) {}
inline bool operator==(const DILineInfoSpecifier &RHS) const {
return FLIKind == RHS.FLIKind && FNKind == RHS.FNKind;
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index ce3bae6a1760c2..cb3531b75730f1 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -240,7 +240,9 @@ class DWARFDebugLine {
/// Returns the index of the row with file/line info for a given address,
/// or UnknownRowIndex if there is no such row.
- uint32_t lookupAddress(object::SectionedAddress Address) const;
+ uint32_t
+ lookupAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind) const;
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size,
std::vector<uint32_t> &Result) const;
@@ -266,10 +268,10 @@ class DWARFDebugLine {
/// Fills the Result argument with the file and line information
/// corresponding to Address. Returns true on success.
- bool getFileLineInfoForAddress(object::SectionedAddress Address,
- const char *CompDir,
- DILineInfoSpecifier::FileLineInfoKind Kind,
- DILineInfo &Result) const;
+ bool getFileLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind, const char *CompDir,
+ DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const;
/// Extracts directory name by its Entry in include directories table
/// in prologue. Returns true on success.
@@ -301,7 +303,9 @@ class DWARFDebugLine {
getSourceByIndex(uint64_t FileIndex,
DILineInfoSpecifier::FileLineInfoKind Kind) const;
- uint32_t lookupAddressImpl(object::SectionedAddress Address) const;
+ uint32_t
+ lookupAddressImpl(object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind) const;
bool lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size,
std::vector<uint32_t> &Result) const;
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 11a169cfc20a69..7b560f4b7dbb2f 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -44,6 +44,7 @@ using namespace object;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
+using ApproximateLineKind = DILineInfoSpecifier::ApproximateLineKind;
class CachedBinary;
@@ -52,6 +53,7 @@ class LLVMSymbolizer {
struct Options {
FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName;
FileLineInfoKind PathStyle = FileLineInfoKind::AbsoluteFilePath;
+ ApproximateLineKind ApproximateLineNumbers = ApproximateLineKind::None;
bool UseSymbolTable = true;
bool Demangle = true;
bool RelativeAddresses = false;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index b7297c18da7c99..9bf7dbd0acc109 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1742,8 +1742,8 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
if (Spec.FLIKind != FileLineInfoKind::None) {
if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
LineTable->getFileLineInfoForAddress(
- {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
- Spec.FLIKind, Result);
+ {Address.Address, Address.SectionIndex}, Spec.ALKind,
+ CU->getCompilationDir(), Spec.FLIKind, Result);
}
}
@@ -1838,7 +1838,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
DILineInfo Frame;
LineTable = getLineTableForUnit(CU);
if (LineTable && LineTable->getFileLineInfoForAddress(
- {Address.Address, Address.SectionIndex},
+ {Address.Address, Address.SectionIndex}, Spec.ALKind,
CU->getCompilationDir(), Spec.FLIKind, Frame))
InliningInfo.addFrame(Frame);
}
@@ -1865,8 +1865,8 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
// For the topmost routine, get file/line info from line table.
if (LineTable)
LineTable->getFileLineInfoForAddress(
- {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
- Spec.FLIKind, Frame);
+ {Address.Address, Address.SectionIndex}, Spec.ALKind,
+ CU->getCompilationDir(), Spec.FLIKind, Frame);
} else {
// Otherwise, use call file, call line and call column from
// previous DIE in inlined chain.
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 572628f45fc23a..f32c69abe5a0d6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1313,10 +1313,11 @@ uint32_t DWARFDebugLine::LineTable::findRowInSeq(
}
uint32_t DWARFDebugLine::LineTable::lookupAddress(
- object::SectionedAddress Address) const {
+ object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind) const {
// Search for relocatable addresses
- uint32_t Result = lookupAddressImpl(Address);
+ uint32_t Result = lookupAddressImpl(Address, LineKind);
if (Result != UnknownRowIndex ||
Address.SectionIndex == object::SectionedAddress::UndefSection)
@@ -1324,11 +1325,12 @@ uint32_t DWARFDebugLine::LineTable::lookupAddress(
// Search for absolute addresses
Address.SectionIndex = object::SectionedAddress::UndefSection;
- return lookupAddressImpl(Address);
+ return lookupAddressImpl(Address, LineKind);
}
uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
- object::SectionedAddress Address) const {
+ object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind) const {
// First, find an instruction sequence containing the given address.
DWARFDebugLine::Sequence Sequence;
Sequence.SectionIndex = Address.SectionIndex;
@@ -1337,7 +1339,24 @@ uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
DWARFDebugLine::Sequence::orderByHighPC);
if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
return UnknownRowIndex;
- return findRowInSeq(*It, Address);
+
+ uint32_t RowIndex = findRowInSeq(*It, Address);
+ if (LineKind == DILineInfoSpecifier::ApproximateLineKind::Before) {
+ for (auto SeqInst = Sequence.HighPC; SeqInst >= It->LowPC; --SeqInst) {
+ if (Rows[RowIndex].Line)
+ break;
+ Address.Address--;
+ RowIndex = findRowInSeq(*It, Address);
+ }
+ } else if (LineKind == DILineInfoSpecifier::ApproximateLineKind::After) {
+ for (auto SeqInst = Sequence.HighPC; SeqInst < It->HighPC; ++SeqInst) {
+ if (Rows[RowIndex].Line)
+ break;
+ Address.Address++;
+ RowIndex = findRowInSeq(*It, Address);
+ }
+ }
+ return RowIndex;
}
bool DWARFDebugLine::LineTable::lookupAddressRange(
@@ -1477,10 +1496,12 @@ bool DWARFDebugLine::Prologue::getFileNameByIndex(
}
bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
- object::SectionedAddress Address, const char *CompDir,
+ object::SectionedAddress Address,
+ DILineInfoSpecifier::ApproximateLineKind LineKind, const char *CompDir,
FileLineInfoKind Kind, DILineInfo &Result) const {
// Get the index of row we're looking for in the line table.
- uint32_t RowIndex = lookupAddress(Address);
+ uint32_t RowIndex = lookupAddress(Address, LineKind);
+
if (RowIndex == -1U)
return false;
// Take file number and line/column from the row.
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 5f29226c14b705..18be137d91d694 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -71,7 +71,9 @@ LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier,
ModuleOffset.Address += Info->getModulePreferredBase();
DILineInfo LineInfo = Info->symbolizeCode(
- ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
+ ModuleOffset,
+ DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions,
+ Opts.ApproximateLineNumbers),
Opts.UseSymbolTable);
if (Opts.Demangle)
LineInfo.FunctionName = DemangleName(LineInfo.FunctionName, Info);
@@ -116,7 +118,9 @@ Expected<DIInliningInfo> LLVMSymbolizer::symbolizeInlinedCodeCommon(
ModuleOffset.Address += Info->getModulePreferredBase();
DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
- ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
+ ModuleOffset,
+ DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions,
+ Opts.ApproximateLineNumbers),
Opts.UseSymbolTable);
if (Opts.Demangle) {
for (int i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
diff --git a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
new file mode 100644
index 00000000000000..b7d56b0e64534c
--- /dev/null
+++ b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
@@ -0,0 +1,142 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -g -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: llvm-symbolizer --obj=%t.o 0xa | FileCheck --check-prefix=APPROX-NONE %s
+# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before 0xa | FileCheck --check-prefix=APPROX-BEFORE %s
+# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=after 0xa | FileCheck --check-prefix=APPROX-AFTER %s
+
+# APPROX-NONE: main
+# APPROX-NONE-NEXT: /home/ampandey/test-hip/main.c:0:6
+# APPROX-BEFORE: main
+# APPROX-BEFORE-NEXT: /home/ampandey/test-hip/main.c:4:6
+# APPROX-AFTER: main
+# APPROX-AFTER-NEXT: /home/ampandey/test-hip/main.c:8:2
+
+## Generated from C Code
+##
+## int foo = 0;
+## int x=89;
+## int main() {
+## if(x)
+## return foo;
+## else
+## return x;
+## }
+##
+## clang -S -O3 -gline-tables-only --target=x86_64-pc-linux
+
+ .text
+ .file "main.c"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 0 "/home/ampandey/test-hip" "main.c" md5 0x26c3fbaea8e6febaf09ef44d37ec5ecc
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 0 4 6 prologue_end # main.c:4:6
+ movl x(%rip), %eax
+ testl %eax, %eax
+ je .LBB0_2
+# %bb.1: # %entry
+ .loc 0 0 6 is_stmt 0 # main.c:0:6
+ movl foo(%rip), %eax
+.LBB0_2: # %entry
+ .loc 0 8 2 is_stmt 1 # main.c:8:2
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .type foo, at object # @foo
+ .bss
+ .globl foo
+ .p2align 2, 0x0
+foo:
+ .long 0 # 0x0
+ .size foo, 4
+
+ .type x, at object # @x
+ .data
+ .globl x
+ .p2align 2, 0x0
+x:
+ .long 89 # 0x59
+ .size x, 4
+
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x17 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 29 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"", at progbits
+ .long 16 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 19.0.0git (git at github.com:ampandey-1995/llvm-project.git 6751baed8d1ee8c5fd12fe5a06aa67275fc1ebf6)" # string offset=0
+.Linfo_string1:
+ .asciz "main.c" # string offset=113
+.Linfo_string2:
+ .asciz "/home/ampandey/test-hip" # string offset=120
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .ident "clang version 19.0.0git (git at github.com:ampandey-1995/llvm-project.git 6751baed8d1ee8c5fd12fe5a06aa67275fc1ebf6)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
diff --git a/llvm/tools/llvm-symbolizer/Opts.td b/llvm/tools/llvm-symbolizer/Opts.td
index edc80bfe59673b..80ec4721c45e00 100644
--- a/llvm/tools/llvm-symbolizer/Opts.td
+++ b/llvm/tools/llvm-symbolizer/Opts.td
@@ -17,6 +17,7 @@ def grp_mach_o : OptionGroup<"kind">,
HelpText<"llvm-symbolizer Mach-O Specific Options">;
def addresses : F<"addresses", "Show address before line information">;
+defm approximate_line_info : Eq<"approximate-line-info","Find approximate non-zero line number information nearest to given address.">,Values<"<before/after>">;
defm adjust_vma
: Eq<"adjust-vma", "Add specified offset to object file addresses">,
MetaVarName<"<offset>">;
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index b98bdbc388faf2..530dbdfd5c8b5e 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -482,6 +482,14 @@ int llvm_symbolizer_main(int argc, char **argv, const llvm::ToolContext &) {
} else {
Opts.PathStyle = DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath;
}
+ StringRef ApproximateLineKindVal =
+ Args.getLastArgValue(OPT_approximate_line_info_EQ);
+ Opts.ApproximateLineNumbers =
+ ApproximateLineKindVal == "before"
+ ? DILineInfoSpecifier::ApproximateLineKind::Before
+ : ApproximateLineKindVal == "after"
+ ? DILineInfoSpecifier::ApproximateLineKind::After
+ : DILineInfoSpecifier::ApproximateLineKind::None;
Opts.DebugFileDirectory = Args.getAllArgValues(OPT_debug_file_directory_EQ);
Opts.DefaultArch = Args.getLastArgValue(OPT_default_arch_EQ).str();
Opts.Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, !IsAddr2Line);
>From f74442de0e15979dcc7f72c128c351b250371a70 Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Mon, 19 Feb 2024 17:40:53 +0530
Subject: [PATCH 2/6] Clean up some unused variables.
---
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index f32c69abe5a0d6..5b7d9ebeef715f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1340,21 +1340,23 @@ uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
return UnknownRowIndex;
- uint32_t RowIndex = findRowInSeq(*It, Address);
+ uint32_t RowIndex;
if (LineKind == DILineInfoSpecifier::ApproximateLineKind::Before) {
- for (auto SeqInst = Sequence.HighPC; SeqInst >= It->LowPC; --SeqInst) {
+ for (auto SeqInst = Sequence.HighPC; SeqInst >= It->LowPC;) {
+ RowIndex = findRowInSeq(*It, Address);
if (Rows[RowIndex].Line)
break;
- Address.Address--;
- RowIndex = findRowInSeq(*It, Address);
+ Address.Address = --SeqInst;
}
} else if (LineKind == DILineInfoSpecifier::ApproximateLineKind::After) {
- for (auto SeqInst = Sequence.HighPC; SeqInst < It->HighPC; ++SeqInst) {
+ for (auto SeqInst = Sequence.HighPC; SeqInst <= It->HighPC;) {
+ RowIndex = findRowInSeq(*It, Address);
if (Rows[RowIndex].Line)
break;
- Address.Address++;
- RowIndex = findRowInSeq(*It, Address);
+ Address.Address = ++SeqInst;
}
+ } else {
+ RowIndex = findRowInSeq(*It, Address);
}
return RowIndex;
}
>From 15c52d48ae7420cc24b0c24c5c5f79a5fc0029ca Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Thu, 22 Feb 2024 21:44:04 +0530
Subject: [PATCH 3/6] Addressing Comments
Update the command guide,help output. Adding (approximate) tag to for
approximated line information output.
---
llvm/docs/CommandGuide/llvm-symbolizer.rst | 20 ++++++++++++++--
llvm/include/llvm/DebugInfo/DIContext.h | 2 ++
.../llvm/DebugInfo/DWARF/DWARFDebugLine.h | 4 ++--
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 24 ++++++++++++-------
llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp | 12 +++++++---
.../llvm-symbolizer/approximate-line-info.s | 20 +++++++++++++---
.../output-style-json-code.test | 14 +++++------
llvm/test/tools/llvm-symbolizer/source.ll | 2 +-
8 files changed, 71 insertions(+), 27 deletions(-)
diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst
index ee60d97babcbc7..64e14a63861c6e 100644
--- a/llvm/docs/CommandGuide/llvm-symbolizer.rst
+++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst
@@ -207,6 +207,17 @@ Example 7 - Addresses as symbol names:
foz
/tmp/test.h:1:0
+Example 8 - Addresses having approximate line info:
+
+.. code-block:: console
+
+ $ llvm-symbolizer --obj=test.elf --approximate-line-info=before 0xa
+ main
+ /home/ampandey/test-hip/main.c:4:6 (approximate)
+ $ llvm-symbolizer --obj=test.elf --approximate-line-info=after 0xa
+ main
+ /home/ampandey/test-hip/main.c:8:2 (approximate)
+
OPTIONS
-------
@@ -216,9 +227,11 @@ OPTIONS
This can be used to perform lookups as if the object were relocated by the
offset.
-.. option:: --approximate-line-info=<before/after>
+.. option:: --approximate-line-info=<before|after>
- Search the object to find the approximate non-zero line numbers nearest to for a given address.
+ Print the approximate non-zero line number nearest to an input address.
+ Nearest lookup is performed by querying the line-table structure for an
+ address having non-zero line information with close proxmity.
.. option:: --basenames, -s
@@ -374,6 +387,7 @@ OPTIONS
"ModuleName": "inlined.elf",
"Symbol": [
{
+ "Approximate": false,
"Column": 18,
"Discriminator": 0,
"FileName": "/tmp/test.cpp",
@@ -384,6 +398,7 @@ OPTIONS
"StartLine": 9
},
{
+ "Approximate": false,
"Column": 0,
"Discriminator": 0,
"FileName": "/tmp/test.cpp",
@@ -400,6 +415,7 @@ OPTIONS
"ModuleName": "inlined.elf",
"Symbol": [
{
+ "Approximate": false,
"Column": 3,
"Discriminator": 0,
"FileName": "/tmp/test.cpp",
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index eb4ff761119db5..fb18f6d124a493 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -30,6 +30,7 @@ namespace llvm {
/// A format-neutral container for source line information.
struct DILineInfo {
+ static constexpr const char *const ApproxString = "(approximate)";
// DILineInfo contains "<invalid>" for function/filename it cannot fetch.
static constexpr const char *const BadString = "<invalid>";
// Use "??" instead of "<invalid>" to make our output closer to addr2line.
@@ -50,6 +51,7 @@ struct DILineInfo {
// DWARF-specific.
uint32_t Discriminator = 0;
+ bool IsApproximatedLine = 0;
DILineInfo()
: FileName(BadString), FunctionName(BadString), StartFileName(BadString) {
}
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index cb3531b75730f1..5a60dadf9269e7 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -240,7 +240,7 @@ class DWARFDebugLine {
/// Returns the index of the row with file/line info for a given address,
/// or UnknownRowIndex if there is no such row.
- uint32_t
+ std::pair<uint32_t, bool>
lookupAddress(object::SectionedAddress Address,
DILineInfoSpecifier::ApproximateLineKind LineKind) const;
@@ -303,7 +303,7 @@ class DWARFDebugLine {
getSourceByIndex(uint64_t FileIndex,
DILineInfoSpecifier::FileLineInfoKind Kind) const;
- uint32_t
+ std::pair<uint32_t, bool>
lookupAddressImpl(object::SectionedAddress Address,
DILineInfoSpecifier::ApproximateLineKind LineKind) const;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 5b7d9ebeef715f..71d4552259ded9 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1312,14 +1312,14 @@ uint32_t DWARFDebugLine::LineTable::findRowInSeq(
return RowPos - Rows.begin();
}
-uint32_t DWARFDebugLine::LineTable::lookupAddress(
+std::pair<uint32_t, bool> DWARFDebugLine::LineTable::lookupAddress(
object::SectionedAddress Address,
DILineInfoSpecifier::ApproximateLineKind LineKind) const {
// Search for relocatable addresses
- uint32_t Result = lookupAddressImpl(Address, LineKind);
+ std::pair<uint32_t, bool> Result = lookupAddressImpl(Address, LineKind);
- if (Result != UnknownRowIndex ||
+ if (Result.first != UnknownRowIndex ||
Address.SectionIndex == object::SectionedAddress::UndefSection)
return Result;
@@ -1328,7 +1328,7 @@ uint32_t DWARFDebugLine::LineTable::lookupAddress(
return lookupAddressImpl(Address, LineKind);
}
-uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
+std::pair<uint32_t, bool> DWARFDebugLine::LineTable::lookupAddressImpl(
object::SectionedAddress Address,
DILineInfoSpecifier::ApproximateLineKind LineKind) const {
// First, find an instruction sequence containing the given address.
@@ -1338,14 +1338,17 @@ uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
SequenceIter It = llvm::upper_bound(Sequences, Sequence,
DWARFDebugLine::Sequence::orderByHighPC);
if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
- return UnknownRowIndex;
+ return {UnknownRowIndex, false};
- uint32_t RowIndex;
+ uint32_t RowIndex = UnknownRowIndex;
+ bool SecondAttempt = false;
if (LineKind == DILineInfoSpecifier::ApproximateLineKind::Before) {
for (auto SeqInst = Sequence.HighPC; SeqInst >= It->LowPC;) {
RowIndex = findRowInSeq(*It, Address);
if (Rows[RowIndex].Line)
break;
+ if (!SecondAttempt)
+ SecondAttempt = true;
Address.Address = --SeqInst;
}
} else if (LineKind == DILineInfoSpecifier::ApproximateLineKind::After) {
@@ -1353,12 +1356,14 @@ uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
RowIndex = findRowInSeq(*It, Address);
if (Rows[RowIndex].Line)
break;
+ if (!SecondAttempt)
+ SecondAttempt = true;
Address.Address = ++SeqInst;
}
} else {
RowIndex = findRowInSeq(*It, Address);
}
- return RowIndex;
+ return {RowIndex, SecondAttempt};
}
bool DWARFDebugLine::LineTable::lookupAddressRange(
@@ -1502,8 +1507,8 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
DILineInfoSpecifier::ApproximateLineKind LineKind, const char *CompDir,
FileLineInfoKind Kind, DILineInfo &Result) const {
// Get the index of row we're looking for in the line table.
- uint32_t RowIndex = lookupAddress(Address, LineKind);
-
+ auto &&RowIndexValue = lookupAddress(Address, LineKind);
+ uint32_t RowIndex = RowIndexValue.first;
if (RowIndex == -1U)
return false;
// Take file number and line/column from the row.
@@ -1514,6 +1519,7 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
Result.Column = Row.Column;
Result.Discriminator = Row.Discriminator;
Result.Source = getSourceByIndex(Row.File, Kind);
+ Result.IsApproximatedLine = RowIndexValue.second;
return true;
}
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 716312f26e0bac..bce29d1e18a7dd 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -131,14 +131,17 @@ void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
void LLVMPrinter::printSimpleLocation(StringRef Filename,
const DILineInfo &Info) {
- OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
+ OS << Filename << ':' << Info.Line << ':' << Info.Column
+ << (Info.IsApproximatedLine ? (" " + Twine(Info.ApproxString)) : "")
+ << '\n';
printContext(
SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}
void GNUPrinter::printSimpleLocation(StringRef Filename,
const DILineInfo &Info) {
- OS << Filename << ':' << Info.Line;
+ OS << Filename << ':' << Info.Line
+ << (Info.IsApproximatedLine ? (" " + Twine(Info.ApproxString)) : "");
if (Info.Discriminator)
OS << " (discriminator " << Info.Discriminator << ')';
OS << '\n';
@@ -158,6 +161,8 @@ void PlainPrinterBase::printVerbose(StringRef Filename,
OS << " Column: " << Info.Column << '\n';
if (Info.Discriminator)
OS << " Discriminator: " << Info.Discriminator << '\n';
+ if (Info.IsApproximatedLine)
+ OS << " Approximate: " << Info.IsApproximatedLine << '\n';
}
void LLVMPrinter::printStartAddress(const DILineInfo &Info) {
@@ -308,7 +313,8 @@ static json::Object toJSON(const DILineInfo &LineInfo) {
LineInfo.FileName != DILineInfo::BadString ? LineInfo.FileName : ""},
{"Line", LineInfo.Line},
{"Column", LineInfo.Column},
- {"Discriminator", LineInfo.Discriminator}});
+ {"Discriminator", LineInfo.Discriminator},
+ {"Approximate", LineInfo.IsApproximatedLine}});
}
void JSONPrinter::print(const Request &Request, const DILineInfo &Info) {
diff --git a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
index b7d56b0e64534c..26e595c83cdf8a 100644
--- a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
+++ b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
@@ -1,16 +1,30 @@
# REQUIRES: x86-registered-target
# RUN: llvm-mc -g -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
-# RUN: llvm-symbolizer --obj=%t.o 0xa | FileCheck --check-prefix=APPROX-NONE %s
+# RUN: llvm-symbolizer --obj=%t.o 0xa | FileCheck --check-prefixes=APPROX-NONE %s
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before 0xa | FileCheck --check-prefix=APPROX-BEFORE %s
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=after 0xa | FileCheck --check-prefix=APPROX-AFTER %s
+# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before 0xa 0x10 | FileCheck --check-prefixes=APPROX-BEFORE,NO-APPROX %s
+# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before --verbose 0xa | FileCheck --check-prefix=APPROX-VERBOSE %s
+# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before --output-style=JSON 0xa | FileCheck --check-prefix=APPROX-JSON %s
# APPROX-NONE: main
# APPROX-NONE-NEXT: /home/ampandey/test-hip/main.c:0:6
# APPROX-BEFORE: main
-# APPROX-BEFORE-NEXT: /home/ampandey/test-hip/main.c:4:6
+# APPROX-BEFORE-NEXT: /home/ampandey/test-hip/main.c:4:6 (approximate)
# APPROX-AFTER: main
-# APPROX-AFTER-NEXT: /home/ampandey/test-hip/main.c:8:2
+# APPROX-AFTER-NEXT: /home/ampandey/test-hip/main.c:8:2 (approximate)
+# NO-APPROX: main
+# NO-APPROX-NEXT: /home/ampandey/test-hip/main.c:8:2
+
+#APPROX-VERBOSE: main
+#APPROX-VERBOSE-NEXT: Filename: /home/ampandey/test-hip/main.c
+#APPROX-VERBOSE-NEXT: Function start address: 0x0
+#APPROX-VERBOSE-NEXT: Line: 4
+#APPROX-VERBOSE-NEXT: Column: 6
+#APPROX-VERBOSE-NEXT: Approximate: 1
+
+#APPROX-JSON: [{"Address":"0xa","ModuleName":"{{.*}}/test/tools/llvm-symbolizer/Output/approximate-line-info.s.tmp.o","Symbol":[{"Approximate":true,"Column":6,"Discriminator":0,"FileName":"/home/ampandey/test-hip/main.c","FunctionName":"main","Line":4,"StartAddress":"0x0","StartFileName":"","StartLine":0}]}]
## Generated from C Code
##
diff --git a/llvm/test/tools/llvm-symbolizer/output-style-json-code.test b/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
index 0e0e61c0bf119a..d6410eeae22016 100644
--- a/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
+++ b/llvm/test/tools/llvm-symbolizer/output-style-json-code.test
@@ -12,12 +12,12 @@
## Expected a list with one empty object with default values.
# RUN: llvm-symbolizer --output-style=JSON -e %p/Inputs/addr.exe 0x10000000 | \
# RUN: FileCheck %s --check-prefix=NOT-FOUND --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-# NOT-FOUND:[{"Address":"0x10000000","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}]
+# NOT-FOUND:[{"Address":"0x10000000","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"","FunctionName":"","Line":0,"StartAddress":"","StartFileName":"","StartLine":0}]}]
## Check a non-zero discriminator.
# RUN: llvm-symbolizer --output-style=JSON --obj=%p/Inputs/discrim 0x400575 | \
# RUN: FileCheck %s --check-prefix=DISCRIM --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-# DISCRIM:[{"Address":"0x400575","ModuleName":"{{.*}}/Inputs/discrim","Symbol":[{"Column":17,"Discriminator":2,"FileName":"/tmp{{/|\\\\}}discrim.c","FunctionName":"foo","Line":5,"StartAddress":"0x400560","StartFileName":"/tmp{{/|\\\\}}discrim.c","StartLine":4}]}]
+# DISCRIM:[{"Address":"0x400575","ModuleName":"{{.*}}/Inputs/discrim","Symbol":[{"Approximate":false,"Column":17,"Discriminator":2,"FileName":"/tmp{{/|\\\\}}discrim.c","FunctionName":"foo","Line":5,"StartAddress":"0x400560","StartFileName":"/tmp{{/|\\\\}}discrim.c","StartLine":4}]}]
## In case of stdin input the output will contain a single JSON object for each input string.
@@ -27,7 +27,7 @@
## Invalid first argument before any valid one.
# NO-INLINES:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"something"}
## Resolve valid address.
-# NO-INLINES-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2}]}
+# NO-INLINES-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Approximate":false,"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2}]}
## Invalid argument after a valid one.
# NO-INLINES-NEXT:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"some"}
@@ -37,7 +37,7 @@
## Invalid first argument before any valid one.
# INLINE:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"something"}
## Resolve valid address.
-# INLINE-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
+# INLINE-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Approximate":false,"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
# INLINE-NEXT:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"some"}
@@ -48,7 +48,7 @@
## Invalid first argument before any valid one.
# INLINE-A2L:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"something"}
## Resolve valid address.
-# INLINE-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
+# INLINE-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Approximate":false,"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inctwo","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"inc","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"main","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
# INLINE-A2L:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"some"}
@@ -58,11 +58,11 @@
## Invalid first argument before any valid one.
# NO-FUNC-A2L:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"something"}
## Resolve valid address.
-# NO-FUNC-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
+# NO-FUNC-A2L-NEXT:{"Address":"0x40054d","ModuleName":"{{.*}}/Inputs/addr.exe","Symbol":[{"Approximate":false,"Column":3,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":3,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":2},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":7,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":6},{"Approximate":false,"Column":0,"Discriminator":0,"FileName":"/tmp{{/|\\\\}}x.c","FunctionName":"","Line":14,"StartAddress":"0x400540","StartFileName":"/tmp{{/|\\\\}}x.c","StartLine":12}]}
## Invalid argument after a valid one.
# NO-FUNC-A2L-NEXT:{"Loc":[],"ModuleName":"{{.*}}/Inputs/addr.exe","SymName":"some"}
## When a module offset is specified by a symbol, more than one source location can be found.
# RUN: llvm-symbolizer --output-style=JSON --no-inlines -e %p/Inputs/symbols.so "static_func" | \
# RUN: FileCheck %s --check-prefix=MULTIPLE --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-# MULTIPLE:[{"Loc":[{"Column":24,"Discriminator":0,"FileName":"/tmp/dbginfo{{/|\\\\}}symbols.part3.c","FunctionName":"static_func","Line":4,"StartAddress":"0x121d","StartFileName":"/tmp/dbginfo{{/|\\\\}}symbols.part3.c","StartLine":4},{"Column":24,"Discriminator":0,"FileName":"/tmp/dbginfo{{/|\\\\}}symbols.part4.c","FunctionName":"static_func","Line":4,"StartAddress":"0x125f","StartFileName":"/tmp/dbginfo{{/|\\\\}}symbols.part4.c","StartLine":4}],"ModuleName":"{{.*}}Inputs/symbols.so","SymName":"static_func"}]
+# MULTIPLE:[{"Loc":[{"Approximate":false,"Column":24,"Discriminator":0,"FileName":"/tmp/dbginfo{{/|\\\\}}symbols.part3.c","FunctionName":"static_func","Line":4,"StartAddress":"0x121d","StartFileName":"/tmp/dbginfo{{/|\\\\}}symbols.part3.c","StartLine":4},{"Approximate":false,"Column":24,"Discriminator":0,"FileName":"/tmp/dbginfo{{/|\\\\}}symbols.part4.c","FunctionName":"static_func","Line":4,"StartAddress":"0x125f","StartFileName":"/tmp/dbginfo{{/|\\\\}}symbols.part4.c","StartLine":4}],"ModuleName":"{{.*}}Inputs/symbols.so","SymName":"static_func"}]
diff --git a/llvm/test/tools/llvm-symbolizer/source.ll b/llvm/test/tools/llvm-symbolizer/source.ll
index 8a12c858126897..7f7072ee90b514 100644
--- a/llvm/test/tools/llvm-symbolizer/source.ll
+++ b/llvm/test/tools/llvm-symbolizer/source.ll
@@ -22,7 +22,7 @@
;; Check JSON style output.
; RUN: llvm-symbolizer --print-source-context-lines=3 --obj=%t.o 0 --output-style=JSON | \
; RUN: FileCheck %s --check-prefix=JSON --strict-whitespace --match-full-lines --implicit-check-not={{.}}
-; JSON:[{"Address":"0x0","ModuleName":"{{.*}}.o","Symbol":[{"Column":13,"Discriminator":0,"FileName":"/source.c","FunctionName":"foo","Line":3,"Source":"2 : // Line 2\n3 >: void foo() {}\n4 : // Line 4\n","StartAddress":"0x0","StartFileName":"/source.c","StartLine":3}]}]
+; JSON:[{"Address":"0x0","ModuleName":"{{.*}}.o","Symbol":[{"Approximate":false,"Column":13,"Discriminator":0,"FileName":"/source.c","FunctionName":"foo","Line":3,"Source":"2 : // Line 2\n3 >: void foo() {}\n4 : // Line 4\n","StartAddress":"0x0","StartFileName":"/source.c","StartLine":3}]}]
;; Generated from the following source:
;; // Line 1
>From 6eb8d50fd36c3e8e9bfb99d30c4f351272480898 Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Thu, 22 Feb 2024 22:08:20 +0530
Subject: [PATCH 4/6] Fix Typos.
---
bolt/lib/Core/BinaryFunction.cpp | 3 ++-
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 2 +-
llvm/test/tools/llvm-symbolizer/approximate-line-info.s | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 5963722b4135bc..8390c67315f70a 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -191,9 +191,10 @@ static SMLoc findDebugLineInformationForInstructionAt(
"Cannot fit instruction debug line information into SMLoc's pointer");
SMLoc NullResult = DebugLineTableRowRef::NULL_ROW.toSMLoc();
- uint32_t RowIndex = LineTable->lookupAddress(
+ auto RowIndexValue = LineTable->lookupAddress(
{Address, object::SectionedAddress::UndefSection},
DILineInfoSpecifier::ApproximateLineKind::None);
+ uint32_t RowIndex = RowIndexValue.first;
if (RowIndex == LineTable->UnknownRowIndex)
return NullResult;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 71d4552259ded9..9d44812909c79c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1507,7 +1507,7 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
DILineInfoSpecifier::ApproximateLineKind LineKind, const char *CompDir,
FileLineInfoKind Kind, DILineInfo &Result) const {
// Get the index of row we're looking for in the line table.
- auto &&RowIndexValue = lookupAddress(Address, LineKind);
+ auto RowIndexValue = lookupAddress(Address, LineKind);
uint32_t RowIndex = RowIndexValue.first;
if (RowIndex == -1U)
return false;
diff --git a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
index 26e595c83cdf8a..9d3db5ef1b1e02 100644
--- a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
+++ b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
@@ -1,7 +1,7 @@
# REQUIRES: x86-registered-target
# RUN: llvm-mc -g -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
-# RUN: llvm-symbolizer --obj=%t.o 0xa | FileCheck --check-prefixes=APPROX-NONE %s
+# RUN: llvm-symbolizer --obj=%t.o 0xa | FileCheck --check-prefix=APPROX-NONE %s
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before 0xa | FileCheck --check-prefix=APPROX-BEFORE %s
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=after 0xa | FileCheck --check-prefix=APPROX-AFTER %s
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before 0xa 0x10 | FileCheck --check-prefixes=APPROX-BEFORE,NO-APPROX %s
>From 45ef7f9b553b28b1d630f53fc868633021dfffed Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Wed, 13 Mar 2024 10:43:28 +0530
Subject: [PATCH 5/6] Addressing Comments of @dwblaike
1. Simplifying loop logic.
2. Adding logic to search non-zero line information only upto function
boundaries.
---
llvm/docs/CommandGuide/llvm-symbolizer.rst | 2 +-
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 29 ++++++++++-----------
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst
index 64e14a63861c6e..76d155b49d00a7 100644
--- a/llvm/docs/CommandGuide/llvm-symbolizer.rst
+++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst
@@ -231,7 +231,7 @@ OPTIONS
Print the approximate non-zero line number nearest to an input address.
Nearest lookup is performed by querying the line-table structure for an
- address having non-zero line information with close proxmity.
+ address having non-zero line information with close proximity.
.. option:: --basenames, -s
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 9d44812909c79c..23ed45b1d81c27 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1340,30 +1340,29 @@ std::pair<uint32_t, bool> DWARFDebugLine::LineTable::lookupAddressImpl(
if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
return {UnknownRowIndex, false};
- uint32_t RowIndex = UnknownRowIndex;
- bool SecondAttempt = false;
+ uint32_t RowIndex = UnknownRowIndex;bool IsApproximate = false;
if (LineKind == DILineInfoSpecifier::ApproximateLineKind::Before) {
- for (auto SeqInst = Sequence.HighPC; SeqInst >= It->LowPC;) {
+ while (Address.Address >= It->LowPC) {
RowIndex = findRowInSeq(*It, Address);
- if (Rows[RowIndex].Line)
+ if(RowIndex!=UnknownRowIndex && Rows[RowIndex].Line)
break;
- if (!SecondAttempt)
- SecondAttempt = true;
- Address.Address = --SeqInst;
- }
+ IsApproximate = true;
+ if(RowIndex!=UnknownRowIndex && Rows[RowIndex].PrologueEnd)break;
+ --Address.Address;
+ }
} else if (LineKind == DILineInfoSpecifier::ApproximateLineKind::After) {
- for (auto SeqInst = Sequence.HighPC; SeqInst <= It->HighPC;) {
+ while (Address.Address <= It->HighPC) {
RowIndex = findRowInSeq(*It, Address);
- if (Rows[RowIndex].Line)
+ if (RowIndex!=UnknownRowIndex && Rows[RowIndex].Line)
break;
- if (!SecondAttempt)
- SecondAttempt = true;
- Address.Address = ++SeqInst;
- }
+ IsApproximate = true;
+ if(RowIndex!=UnknownRowIndex && Rows[RowIndex].EpilogueBegin)break;
+ ++Address.Address;
+ }
} else {
RowIndex = findRowInSeq(*It, Address);
}
- return {RowIndex, SecondAttempt};
+ return {RowIndex, IsApproximate};
}
bool DWARFDebugLine::LineTable::lookupAddressRange(
>From c13722007cd3cd696338470f297d18e3fb31914e Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Wed, 13 Mar 2024 13:42:52 +0530
Subject: [PATCH 6/6] Fix Clang Format warning.
---
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 17 ++++++++++-------
.../llvm-symbolizer/approximate-line-info.s | 16 ++++++++--------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 23ed45b1d81c27..dae29ae4ef7e16 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1340,25 +1340,28 @@ std::pair<uint32_t, bool> DWARFDebugLine::LineTable::lookupAddressImpl(
if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
return {UnknownRowIndex, false};
- uint32_t RowIndex = UnknownRowIndex;bool IsApproximate = false;
+ uint32_t RowIndex = UnknownRowIndex;
+ bool IsApproximate = false;
if (LineKind == DILineInfoSpecifier::ApproximateLineKind::Before) {
while (Address.Address >= It->LowPC) {
RowIndex = findRowInSeq(*It, Address);
- if(RowIndex!=UnknownRowIndex && Rows[RowIndex].Line)
+ if (RowIndex != UnknownRowIndex && Rows[RowIndex].Line)
break;
IsApproximate = true;
- if(RowIndex!=UnknownRowIndex && Rows[RowIndex].PrologueEnd)break;
+ if (RowIndex != UnknownRowIndex && Rows[RowIndex].PrologueEnd)
+ break;
--Address.Address;
- }
+ }
} else if (LineKind == DILineInfoSpecifier::ApproximateLineKind::After) {
while (Address.Address <= It->HighPC) {
RowIndex = findRowInSeq(*It, Address);
- if (RowIndex!=UnknownRowIndex && Rows[RowIndex].Line)
+ if (RowIndex != UnknownRowIndex && Rows[RowIndex].Line)
break;
IsApproximate = true;
- if(RowIndex!=UnknownRowIndex && Rows[RowIndex].EpilogueBegin)break;
+ if (RowIndex != UnknownRowIndex && Rows[RowIndex].EpilogueBegin)
+ break;
++Address.Address;
- }
+ }
} else {
RowIndex = findRowInSeq(*It, Address);
}
diff --git a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
index 9d3db5ef1b1e02..ad046f4c4d9448 100644
--- a/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
+++ b/llvm/test/tools/llvm-symbolizer/approximate-line-info.s
@@ -9,22 +9,22 @@
# RUN: llvm-symbolizer --obj=%t.o --approximate-line-info=before --output-style=JSON 0xa | FileCheck --check-prefix=APPROX-JSON %s
# APPROX-NONE: main
-# APPROX-NONE-NEXT: /home/ampandey/test-hip/main.c:0:6
+# APPROX-NONE-NEXT: /tmp/test/main.c:0:6
# APPROX-BEFORE: main
-# APPROX-BEFORE-NEXT: /home/ampandey/test-hip/main.c:4:6 (approximate)
+# APPROX-BEFORE-NEXT: /tmp/test/main.c:4:6 (approximate)
# APPROX-AFTER: main
-# APPROX-AFTER-NEXT: /home/ampandey/test-hip/main.c:8:2 (approximate)
+# APPROX-AFTER-NEXT: /tmp/test/main.c:8:2 (approximate)
# NO-APPROX: main
-# NO-APPROX-NEXT: /home/ampandey/test-hip/main.c:8:2
+# NO-APPROX-NEXT: /tmp/test/main.c:8:2
#APPROX-VERBOSE: main
-#APPROX-VERBOSE-NEXT: Filename: /home/ampandey/test-hip/main.c
+#APPROX-VERBOSE-NEXT: Filename: /tmp/test/main.c
#APPROX-VERBOSE-NEXT: Function start address: 0x0
#APPROX-VERBOSE-NEXT: Line: 4
#APPROX-VERBOSE-NEXT: Column: 6
#APPROX-VERBOSE-NEXT: Approximate: 1
-#APPROX-JSON: [{"Address":"0xa","ModuleName":"{{.*}}/test/tools/llvm-symbolizer/Output/approximate-line-info.s.tmp.o","Symbol":[{"Approximate":true,"Column":6,"Discriminator":0,"FileName":"/home/ampandey/test-hip/main.c","FunctionName":"main","Line":4,"StartAddress":"0x0","StartFileName":"","StartLine":0}]}]
+#APPROX-JSON: [{"Address":"0xa","ModuleName":"{{.*}}/test/tools/llvm-symbolizer/Output/approximate-line-info.s.tmp.o","Symbol":[{"Approximate":true,"Column":6,"Discriminator":0,"FileName":"/tmp/test/main.c","FunctionName":"main","Line":4,"StartAddress":"0x0","StartFileName":"","StartLine":0}]}]
## Generated from C Code
##
@@ -46,7 +46,7 @@
.type main, at function
main: # @main
.Lfunc_begin0:
- .file 0 "/home/ampandey/test-hip" "main.c" md5 0x26c3fbaea8e6febaf09ef44d37ec5ecc
+ .file 0 "/tmp/test" "main.c" md5 0x26c3fbaea8e6febaf09ef44d37ec5ecc
.cfi_startproc
# %bb.0: # %entry
.loc 0 4 6 prologue_end # main.c:4:6
@@ -135,7 +135,7 @@ x:
.Linfo_string1:
.asciz "main.c" # string offset=113
.Linfo_string2:
- .asciz "/home/ampandey/test-hip" # string offset=120
+ .asciz "/tmp/test" # string offset=120
.section .debug_str_offsets,"", at progbits
.long .Linfo_string0
.long .Linfo_string1
More information about the llvm-commits
mailing list