Index: include/lldb/Core/Module.h
===================================================================
--- include/lldb/Core/Module.h
+++ include/lldb/Core/Module.h
@@ -680,7 +680,8 @@
/// data the symbol vendor provides.
void ParseAllDebugSymbols();
- bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr);
+ bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr,
+ bool allow_section_end = false);
/// Resolve the symbol context for the given address.
///
Index: include/lldb/Core/Section.h
===================================================================
--- include/lldb/Core/Section.h
+++ include/lldb/Core/Section.h
@@ -71,6 +71,14 @@
FindSectionContainingFileAddress(lldb::addr_t addr,
uint32_t depth = UINT32_MAX) const;
+ /// Look up the given file address in the contained sections. Return a
+ /// section-relative Address object if a section is found. if
+ /// allow_section_end is true, an address pointing past the end of a section
+ /// is permitted and resolved relative to the section which ends at the given
+ /// address.
+ llvm::Optional
ResolveFileAddress(lldb::addr_t file_addr,
+ bool allow_section_end) const;
+
// Get the number of sections in this list only
size_t GetSize() const { return m_sections.size(); }
@@ -122,7 +130,11 @@
static int Compare(const Section &a, const Section &b);
- bool ContainsFileAddress(lldb::addr_t vm_addr) const;
+ /// Return true iff this section contains the given file address. If
+ /// allow_section_end is true, the function returns true also for address
+ /// pointing past the end of the section.
+ bool ContainsFileAddress(lldb::addr_t vm_addr,
+ bool allow_section_end = false) const;
SectionList &GetChildren() { return m_children; }
Index: lit/SymbolFile/DWARF/debug-line-basic.s
===================================================================
--- lit/SymbolFile/DWARF/debug-line-basic.s
+++ lit/SymbolFile/DWARF/debug-line-basic.s
@@ -1,7 +1,7 @@
# REQUIRES: lld, x86
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o
-# RUN: ld.lld -z separate-code %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: %lldb %t -o "image dump line-table -v a.c" -o exit | FileCheck %s
Index: lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s
===================================================================
--- lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s
+++ lit/SymbolFile/DWARF/dir-separator-no-comp-dir-relative-name.s
@@ -5,7 +5,7 @@
# REQUIRES: lld, x86
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o
-# RUN: ld.lld -z separate-code %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: %lldb %t -s %S/Inputs/dir-separator-no-comp-dir-relative-name.lldbinit -o exit | FileCheck %s
# CHECK-LABEL: image dump line-table a.c
Index: lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s
===================================================================
--- lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s
+++ lit/SymbolFile/DWARF/dir-separator-no-comp-dir.s
@@ -4,7 +4,7 @@
# REQUIRES: lld, x86
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o
-# RUN: ld.lld -z separate-code %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: %lldb %t -s %S/Inputs/dir-separator-windows.lldbinit -o exit | FileCheck %s
# CHECK-LABEL: image dump line-table a.c
Index: lit/SymbolFile/DWARF/dir-separator-posix.s
===================================================================
--- lit/SymbolFile/DWARF/dir-separator-posix.s
+++ lit/SymbolFile/DWARF/dir-separator-posix.s
@@ -4,7 +4,7 @@
# REQUIRES: lld, x86
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o
-# RUN: ld.lld -z separate-code %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: %lldb %t -s %S/Inputs/dir-separator-posix.lldbinit -o exit | FileCheck %s
# CHECK-LABEL: image dump line-table a.c
Index: lit/SymbolFile/DWARF/dir-separator-windows.s
===================================================================
--- lit/SymbolFile/DWARF/dir-separator-windows.s
+++ lit/SymbolFile/DWARF/dir-separator-windows.s
@@ -4,7 +4,7 @@
# REQUIRES: lld, x86
# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj > %t.o
-# RUN: ld.lld -z separate-code %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: %lldb %t -s %S/Inputs/dir-separator-windows.lldbinit -o exit | FileCheck %s
# CHECK-LABEL: image dump line-table a.c
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp
+++ source/Core/Module.cpp
@@ -423,15 +423,21 @@
return cu_sp;
}
-bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
+bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr,
+ bool allow_section_end) {
std::lock_guard guard(m_mutex);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")",
vm_addr);
SectionList *section_list = GetSectionList();
- if (section_list)
- return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
+ if (!section_list)
+ return false;
+ if (llvm::Optional addr =
+ section_list->ResolveFileAddress(vm_addr, allow_section_end)) {
+ so_addr = *addr;
+ return true;
+ }
return false;
}
Index: source/Core/Section.cpp
===================================================================
--- source/Core/Section.cpp
+++ source/Core/Section.cpp
@@ -267,12 +267,13 @@
return true;
}
-bool Section::ContainsFileAddress(addr_t vm_addr) const {
+bool Section::ContainsFileAddress(addr_t vm_addr,
+ bool allow_section_end) const {
const addr_t file_addr = GetFileAddress();
if (file_addr != LLDB_INVALID_ADDRESS && !IsThreadSpecific()) {
if (file_addr <= vm_addr) {
const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
- return offset < GetByteSize();
+ return offset < GetByteSize() + (allow_section_end ? 1 : 0);
}
}
return false;
@@ -586,6 +587,20 @@
return sect_sp;
}
+llvm::Optional
+SectionList::ResolveFileAddress(addr_t file_addr,
+ bool allow_section_end) const {
+ for (const SectionSP §ion_sp : m_sections) {
+ if (section_sp->ContainsFileAddress(file_addr, allow_section_end)) {
+ Address addr;
+ section_sp->ResolveContainedAddress(
+ file_addr - section_sp->GetFileAddress(), addr, allow_section_end);
+ return addr;
+ }
+ }
+ return llvm::None;
+}
+
bool SectionList::ContainsSection(user_id_t sect_id) const {
return FindSectionByID(sect_id).get() != nullptr;
}
Index: source/Symbol/LineTable.cpp
===================================================================
--- source/Symbol/LineTable.cpp
+++ source/Symbol/LineTable.cpp
@@ -244,9 +244,9 @@
if (idx < m_entries.size()) {
const Entry &entry = m_entries[idx];
ModuleSP module_sp(m_comp_unit->GetModule());
- if (module_sp &&
- module_sp->ResolveFileAddress(entry.file_addr,
- line_entry.range.GetBaseAddress())) {
+ if (module_sp && module_sp->ResolveFileAddress(
+ entry.file_addr, line_entry.range.GetBaseAddress(),
+ /*allow_section_end = */ entry.is_terminal_entry)) {
if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
line_entry.range.SetByteSize(m_entries[idx + 1].file_addr -
entry.file_addr);
Index: unittests/Core/CMakeLists.txt
===================================================================
--- unittests/Core/CMakeLists.txt
+++ unittests/Core/CMakeLists.txt
@@ -1,5 +1,6 @@
add_lldb_unittest(LLDBCoreTests
MangledTest.cpp
+ ModuleTest.cpp
RichManglingContextTest.cpp
StreamCallbackTest.cpp
UniqueCStringMapTest.cpp
@@ -18,5 +19,6 @@
set(test_inputs
mangled-function-names.yaml
+ resolve-file-address.yaml
)
add_unittest_inputs(LLDBCoreTests "${test_inputs}")
Index: unittests/Core/Inputs/resolve-file-address.yaml
===================================================================
--- /dev/null
+++ unittests/Core/Inputs/resolve-file-address.yaml
@@ -0,0 +1,12 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ Size: 0x100
Index: unittests/Core/ModuleTest.cpp
===================================================================
--- /dev/null
+++ unittests/Core/ModuleTest.cpp
@@ -0,0 +1,69 @@
+//===-- ModuleTest.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Module.h"
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
+#include "TestingSupport/TestUtilities.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/HostInfo.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+class ModuleTest : public testing::Test {
+public:
+ static void SetUpTestCase() {
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ ObjectFileELF::Initialize();
+ SymbolFileSymtab::Initialize();
+ }
+
+ static void TearDownTestCase() {
+ SymbolFileSymtab::Terminate();
+ ObjectFileELF::Terminate();
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ }
+};
+} // namespace
+
+llvm::Optional resolveFileAddress(Module &M, addr_t FileAddr,
+ bool AllowSectionEnd) {
+ Address A;
+ if (M.ResolveFileAddress(FileAddr, A, AllowSectionEnd))
+ return A;
+ return llvm::None;
+}
+
+TEST_F(ModuleTest, ResolveFileAddress) {
+ llvm::SmallString<128> Obj;
+ ASSERT_EQ(llvm::sys::fs::createTemporaryFile("resolve-file-address-%%%%%%",
+ "obj", Obj),
+ std::error_code());
+ llvm::FileRemover Deleter(Obj);
+ ASSERT_THAT_ERROR(ReadYAMLObjectFile("resolve-file-address.yaml", Obj),
+ llvm::Succeeded());
+
+ ModuleSpec Spec{FileSpec(Obj)};
+ Spec.GetSymbolFileSpec().SetFile(Obj, FileSpec::Style::native);
+ auto M = std::make_shared(Spec);
+
+ ASSERT_TRUE(M->GetSectionList());
+ SectionSP S = M->GetSectionList()->FindSectionByName(ConstString(".text"));
+ ASSERT_TRUE(S);
+
+ EXPECT_EQ(resolveFileAddress(*M, 0x1000, false), Address(S, 0));
+ EXPECT_EQ(resolveFileAddress(*M, 0x1100, false), llvm::None);
+ EXPECT_EQ(resolveFileAddress(*M, 0x1100, true), Address(S, 0x100));
+}