class MemoryRegionInfo;
class ResumeActionList;
-struct SVR4LibraryInfo {
- std::string name;
- lldb::addr_t link_map;
- lldb::addr_t base_addr;
- lldb::addr_t ld_addr;
- lldb::addr_t next;
-};
-
// NativeProcessProtocol
class NativeProcessProtocol {
public:
virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
- virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
- GetLoadedSVR4Libraries() {
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Not implemented");
- }
-
virtual bool IsAlive() const;
virtual size_t UpdateThreads() = 0;
self,
inferior_args=None,
inferior_sleep_seconds=3,
- inferior_exe_path=None,
- inferior_env=None):
+ inferior_exe_path=None):
"""Prep the debug monitor, the inferior, and the expected packet stream.
Handle the separate cases of using the debug monitor in attach-to-inferior mode
# Build the expected protocol stream
self.add_no_ack_remote_stream()
- if inferior_env:
- for name, value in inferior_env.items():
- self.add_set_environment_packets(name, value)
if self._inferior_startup == self._STARTUP_LAUNCH:
self.add_verified_launch_packets(launch_args)
{"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$", "capture": {1: "process_info_raw"}}],
True)
- def add_set_environment_packets(self, name, value):
- self.test_sequence.add_log_lines(
- ["read packet: $QEnvironment:" + name + "=" + value + "#00",
- "send packet: $OK#00",
- ], True)
-
_KNOWN_PROCESS_INFO_KEYS = [
"pid",
"parent-pid",
"error"])
self.assertIsNotNone(val)
- mem_region_dict["name"] = seven.unhexlify(mem_region_dict.get("name", ""))
# Return the dictionary of key-value pairs for the memory region.
return mem_region_dict
return context
- def continue_process_and_wait_for_stop(self):
- self.test_sequence.add_log_lines(
- [
- "read packet: $vCont;c#a8",
- {
- "direction": "send",
- "regex": r"^\$T([0-9a-fA-F]{2})(.*)#[0-9a-fA-F]{2}$",
- "capture": {1: "stop_signo", 2: "stop_key_val_text"},
- },
- ],
- True,
- )
- context = self.expect_gdbremote_sequence()
- self.assertIsNotNone(context)
- return self.parse_interrupt_packets(context)
-
def select_modifiable_register(self, reg_infos):
"""Find a register that can be read/written freely."""
PREFERRED_REGISTER_NAMES = set(["rax", ])
+++ /dev/null
-LEVEL = ../../../make
-
-LIB_PREFIX := svr4lib
-LD_EXTRAS := -L. -l$(LIB_PREFIX)_a -l$(LIB_PREFIX)_b\"
-CXX_SOURCES := main.cpp
-USE_LIBDL := 1
-MAKE_DSYM := NO
-
-include $(LEVEL)/Makefile.rules
-
-a.out: $(LIB_PREFIX)_a $(LIB_PREFIX)_b_quote
-
-svr4lib_%:
- $(MAKE) VPATH=$(SRCDIR) -I $(SRCDIR) -f "$(SRCDIR)/$(LIB_PREFIX)_$*.mk"
-
-clean::
- $(MAKE) -f $(SRCDIR)/$(LIB_PREFIX)_a.mk clean
+++ /dev/null
-import xml.etree.ElementTree as ET
-
-import gdbremote_testcase
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-
-
-class TestGdbRemoteLibrariesSvr4Support(gdbremote_testcase.GdbRemoteTestCaseBase):
-
- mydir = TestBase.compute_mydir(__file__)
-
- FEATURE_NAME = "qXfer:libraries-svr4:read"
-
- def setup_test(self):
- self.init_llgs_test()
- self.build()
- self.set_inferior_startup_launch()
- env = {}
- env[self.dylibPath] = self.getBuildDir()
- self.prep_debug_monitor_and_inferior(inferior_env=env)
- self.continue_process_and_wait_for_stop()
-
- def get_expected_libs(self):
- return ["libsvr4lib_a.so", 'libsvr4lib_b".so']
-
- def has_libraries_svr4_support(self):
- self.add_qSupported_packets()
- context = self.expect_gdbremote_sequence()
- self.assertIsNotNone(context)
- features = self.parse_qSupported_response(context)
- return self.FEATURE_NAME in features and features[self.FEATURE_NAME] == "+"
-
- def get_libraries_svr4_data(self):
- # Start up llgs and inferior, and check for libraries-svr4 support.
- if not self.has_libraries_svr4_support():
- self.skipTest("libraries-svr4 not supported")
-
- # Grab the libraries-svr4 data.
- self.reset_test_sequence()
- self.test_sequence.add_log_lines(
- [
- "read packet: $qXfer:libraries-svr4:read::0,ffff:#00",
- {
- "direction": "send",
- "regex": re.compile(
- r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
- ),
- "capture": {1: "response_type", 2: "content_raw"},
- },
- ],
- True,
- )
-
- context = self.expect_gdbremote_sequence()
- self.assertIsNotNone(context)
-
- # Ensure we end up with all libraries-svr4 data in one packet.
- self.assertEqual(context.get("response_type"), "l")
-
- # Decode binary data.
- content_raw = context.get("content_raw")
- self.assertIsNotNone(content_raw)
- return content_raw
-
- def get_libraries_svr4_xml(self):
- libraries_svr4 = self.get_libraries_svr4_data()
- xml_root = None
- try:
- xml_root = ET.fromstring(libraries_svr4)
- except xml.etree.ElementTree.ParseError:
- pass
- self.assertIsNotNone(xml_root, "Malformed libraries-svr4 XML")
- return xml_root
-
- def libraries_svr4_well_formed(self):
- xml_root = self.get_libraries_svr4_xml()
- self.assertEqual(xml_root.tag, "library-list-svr4")
- for child in xml_root:
- self.assertEqual(child.tag, "library")
- self.assertItemsEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"])
-
- def libraries_svr4_has_correct_load_addr(self):
- xml_root = self.get_libraries_svr4_xml()
- for child in xml_root:
- name = child.attrib.get("name")
- base_name = os.path.basename(name)
- if os.path.basename(name) not in self.get_expected_libs():
- continue
- load_addr = int(child.attrib.get("l_addr"), 16)
- self.reset_test_sequence()
- self.add_query_memory_region_packets(load_addr)
- context = self.expect_gdbremote_sequence()
- mem_region = self.parse_memory_region_packet(context)
- self.assertEqual(load_addr, int(mem_region.get("start", 0), 16))
- self.assertEqual(
- os.path.realpath(name), os.path.realpath(mem_region.get("name", ""))
- )
-
- def libraries_svr4_libs_present(self):
- xml_root = self.get_libraries_svr4_xml()
- libraries_svr4_names = []
- for child in xml_root:
- name = child.attrib.get("name")
- libraries_svr4_names.append(os.path.realpath(name))
- for lib in self.get_expected_libs():
- self.assertIn(self.getBuildDir() + "/" + lib, libraries_svr4_names)
-
- @llgs_test
- @skipUnlessPlatform(["linux", "android", "netbsd"])
- def test_supports_libraries_svr4(self):
- self.setup_test()
- self.assertTrue(self.has_libraries_svr4_support())
-
- @llgs_test
- @skipUnlessPlatform(["linux", "android", "netbsd"])
- def test_libraries_svr4_well_formed(self):
- self.setup_test()
- self.libraries_svr4_well_formed()
-
- @llgs_test
- @skipUnlessPlatform(["linux", "android", "netbsd"])
- def test_libraries_svr4_load_addr(self):
- self.setup_test()
- self.libraries_svr4_has_correct_load_addr()
-
- @llgs_test
- @skipUnlessPlatform(["linux", "android", "netbsd"])
- def test_libraries_svr4_libs_present(self):
- self.setup_test()
- self.libraries_svr4_libs_present()
+++ /dev/null
-//===-- main.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
-//
-//===----------------------------------------------------------------------===//
-
-int main(int argc, char **argv) {
- // Perform a null pointer access.
- int *const null_int_ptr = nullptr;
- *null_int_ptr = 0xDEAD;
-
- return 0;
-}
+++ /dev/null
-//===-- main.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
-//
-//===----------------------------------------------------------------------===//
-
-int svr4lib_a() { return 42; }
+++ /dev/null
-LEVEL = ../../../make
-
-LIB_PREFIX := svr4lib
-
-DYLIB_NAME := $(LIB_PREFIX)_a
-DYLIB_CXX_SOURCES := $(LIB_PREFIX)_a.cpp
-DYLIB_ONLY := YES
-
-include $(LEVEL)/Makefile.rules
+++ /dev/null
-//===-- main.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
-//
-//===----------------------------------------------------------------------===//
-
-int svr4lib_b_quote() { return 42; }
+++ /dev/null
-LEVEL = ../../../make
-
-LIB_PREFIX := svr4lib
-
-DYLIB_NAME := $(LIB_PREFIX)_b\"
-DYLIB_CXX_SOURCES := $(LIB_PREFIX)_b_quote.cpp
-DYLIB_ONLY := YES
-
-include $(LEVEL)/Makefile.rules
m_processor_trace_monitor.erase(iter);
return error;
-}
\ No newline at end of file
+}
#ifndef liblldb_NativeProcessNetBSD_H_
#define liblldb_NativeProcessNetBSD_H_
-#include "Plugins/Process/POSIX/NativeProcessELF.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "NativeThreadNetBSD.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
namespace process_netbsd {
/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
-class NativeProcessNetBSD : public NativeProcessELF {
+class NativeProcessNetBSD : public NativeProcessProtocol {
public:
class Factory : public NativeProcessProtocol::Factory {
public:
return LLDB_INVALID_ADDRESS;
}
-template <typename T>
-llvm::Expected<SVR4LibraryInfo>
-NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) {
- ELFLinkMap<T> link_map;
- size_t bytes_read;
- auto error =
- ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read);
- if (!error.Success())
- return error.ToError();
-
- char name_buffer[PATH_MAX];
- error = ReadMemory(link_map.l_name, &name_buffer, sizeof(name_buffer),
- bytes_read);
- if (bytes_read == 0)
- return error.ToError();
- name_buffer[PATH_MAX - 1] = '\0';
-
- SVR4LibraryInfo info;
- info.name = std::string(name_buffer);
- info.link_map = link_map_addr;
- info.base_addr = link_map.l_addr;
- info.ld_addr = link_map.l_ld;
- info.next = link_map.l_next;
-
- return info;
-}
-
-llvm::Expected<std::vector<SVR4LibraryInfo>>
-NativeProcessELF::GetLoadedSVR4Libraries() {
- // Address of DT_DEBUG.d_ptr which points to r_debug
- lldb::addr_t info_address = GetSharedLibraryInfoAddress();
- if (info_address == LLDB_INVALID_ADDRESS)
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Invalid shared library info address");
- // Address of r_debug
- lldb::addr_t address = 0;
- size_t bytes_read;
- auto status =
- ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read);
- if (!status.Success())
- return status.ToError();
- if (address == 0)
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Invalid r_debug address");
- // Read r_debug.r_map
- lldb::addr_t link_map = 0;
- status = ReadMemory(address + GetAddressByteSize(), &link_map,
- GetAddressByteSize(), bytes_read);
- if (!status.Success())
- return status.ToError();
- if (address == 0)
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Invalid link_map address");
-
- std::vector<SVR4LibraryInfo> library_list;
- while (link_map) {
- llvm::Expected<SVR4LibraryInfo> info =
- GetAddressByteSize() == 8 ? ReadSVR4LibraryInfo<uint64_t>(link_map)
- : ReadSVR4LibraryInfo<uint32_t>(link_map);
- if (!info)
- return info.takeError();
- if (!info->name.empty() && info->base_addr != 0)
- library_list.push_back(*info);
- link_map = info->next;
- }
-
- return library_list;
-}
-
-} // namespace lldb_private
+} // namespace lldb_private
\ No newline at end of file
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
lldb::addr_t GetELFImageInfoAddress();
- llvm::Expected<std::vector<SVR4LibraryInfo>>
- GetLoadedSVR4Libraries() override;
-
- template <typename T>
- llvm::Expected<SVR4LibraryInfo>
- ReadSVR4LibraryInfo(lldb::addr_t link_map_addr);
-
std::unique_ptr<AuxVector> m_aux_vector;
llvm::Optional<lldb::addr_t> m_shared_library_info_addr;
};
#if defined(__linux__) || defined(__NetBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
- response.PutCString(";qXfer:libraries-svr4:read+");
#endif
return SendPacketNoLock(response.GetString());
return std::move(*buffer_or_error);
}
- if (object == "libraries-svr4") {
- auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries();
- if (!library_list)
- return library_list.takeError();
-
- StreamString response;
- response.Printf("<library-list-svr4 version=\"1.0\">");
- for (auto const &library : *library_list) {
- response.Printf("<library name=\"%s\" ",
- XMLEncodeAttributeValue(library.name.c_str()).c_str());
- response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map);
- response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr);
- response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr);
- }
- response.Printf("</library-list-svr4>");
- return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
- }
-
return llvm::make_error<PacketUnimplementedError>(
"Xfer object not supported");
}
return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
}
-
-std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
- llvm::StringRef value) {
- std::string result;
- for (const char &c : value) {
- switch (c) {
- case '\'':
- result += "'";
- break;
- case '"':
- result += """;
- break;
- case '<':
- result += "<";
- break;
- case '>':
- result += ">";
- break;
- default:
- result += c;
- break;
- }
- }
- return result;
-}
\ No newline at end of file
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
ReadXferObject(llvm::StringRef object, llvm::StringRef annex);
- static std::string XMLEncodeAttributeValue(llvm::StringRef value);
-
private:
void HandleInferiorState_Exited(NativeProcessProtocol *process);