From 814261c1deb101c87ff1c4c2e387a552301f57f9 Mon Sep 17 00:00:00 2001 From: Peter Edwards Date: Mon, 25 Apr 2022 13:38:29 +0100 Subject: [PATCH] Let CoreReader cons take a Process argument instead of CoreProcess I intend to reuse CoreReader for something nefarious --- dead.cc | 36 +++++++++++++++++++----------------- libpstack/proc.h | 5 +++-- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/dead.cc b/dead.cc index 2a3ee66..831fc65 100644 --- a/dead.cc +++ b/dead.cc @@ -7,7 +7,7 @@ CoreProcess::CoreProcess(Elf::Object::sptr exec, Elf::Object::sptr core, const PstackOptions &options, Dwarf::ImageCache &imageCache) - : Process(std::move(exec), std::make_shared(this), options, imageCache) + : Process(std::move(exec), std::make_shared(this, core), options, imageCache) , coreImage(std::move(core)) { } @@ -28,7 +28,7 @@ CoreProcess::load(const PstackOptions &options) void CoreReader::describe(std::ostream &os) const { - os << *p->coreImage->io; + os << *core->io; } static size_t @@ -38,7 +38,7 @@ readFromHdr(const Elf::Object &obj, const Elf::Phdr *hdr, Elf::Off addr, Elf::Off rv; Elf::Off off = addr - hdr->p_vaddr; // offset in header of our ptr. if (off < hdr->p_filesz) { - // some of the data is in the file: read min of what we need and // that. + // some of the data is in the file: read min of what we need and that. Elf::Off fileSize = std::min(hdr->p_filesz - off, size); rv = obj.io->read(hdr->p_offset + off, fileSize, ptr); if (rv != fileSize) @@ -64,24 +64,26 @@ CoreReader::read(Off remoteAddr, size_t size, char *ptr) const { Elf::Off start = remoteAddr; while (size != 0) { - auto obj = p->coreImage; Elf::Off zeroes = 0; - // Locate "remoteAddr" in the core file - auto hdr = obj->getSegmentForAddress(remoteAddr); - if (hdr != nullptr) { - // The start address appears in the core (or is defaulted from it) - size_t rc = readFromHdr(*obj, hdr, remoteAddr, ptr, size, &zeroes); - remoteAddr += rc; - ptr += rc; - size -= rc; - if (rc != 0 && zeroes == 0) - // we got some data from the header, and there's nothing to default - continue; + if (core) { + // Locate "remoteAddr" in the core file + const Elf::Phdr * hdr = core->getSegmentForAddress(remoteAddr); + if (hdr != nullptr) { + // The start address appears in the core (or is defaulted from it) + size_t rc = readFromHdr(*core, hdr, remoteAddr, ptr, size, &zeroes); + remoteAddr += rc; + ptr += rc; + size -= rc; + if (rc != 0 && zeroes == 0) + // we got some data from the header, and there's nothing to default + continue; + } } - // Either no data in core, or it was incomplete to this point: search loaded objects. Elf::Off loadAddr; + const Elf::Phdr *hdr; + Elf::Object::sptr obj; std::tie(loadAddr, obj, hdr) = p->findSegment(remoteAddr); if (hdr != nullptr) { // header in an object - try reading from here. @@ -104,7 +106,7 @@ CoreReader::read(Off remoteAddr, size_t size, char *ptr) const return remoteAddr - start; } -CoreReader::CoreReader(CoreProcess *p_) : p(p_) { } +CoreReader::CoreReader(Process *p_, Elf::Object::sptr core_) : p(p_), core(core_) { } bool CoreProcess::getRegs(lwpid_t pid, Elf::CoreRegisters *reg) diff --git a/libpstack/proc.h b/libpstack/proc.h index 4a7530b..761e71c 100644 --- a/libpstack/proc.h +++ b/libpstack/proc.h @@ -246,11 +246,12 @@ class LiveProcess : public Process { class CoreProcess; class CoreReader : public Reader { - CoreProcess *p; + Process *p; + Elf::Object::sptr core; protected: virtual size_t read(Off remoteAddr, size_t size, char *ptr) const override; public: - CoreReader (CoreProcess *); + CoreReader (Process *, Elf::Object::sptr); virtual void describe(std::ostream &os) const override; Off size() const override { return std::numeric_limits::max(); } std::string filename() const override { return "process memory"; }