Files
TheRock/rocm-systems/projects/rocprofiler-systems/external/dyninst/parseAPI/h/ParseCallback.h
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

275 lines
8.4 KiB
C++

/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _PARSE_CALLBACK_H_
#define _PARSE_CALLBACK_H_
/** A ParseCallback allows extenders of this library to
receive notifications during parsing of a variety of events.
An implementer can choose to override one, several, or all of
the methods in order to receive appropriate notification
during parsing.
**/
#include <list>
#include <stddef.h>
#include <utility>
#include <vector>
#include "InstructionAdapter.h"
#include "dyntypes.h"
namespace Dyninst {
namespace ParseAPI {
class Function;
class Block;
class Edge;
class ParseCallbackManager;
class ParseCallback {
friend class ParseCallbackManager;
public:
ParseCallback() { }
virtual ~ParseCallback() { }
/*
* Notify when control transfers have run `off the rails'
*/
struct default_details {
default_details(unsigned char*b,size_t s, bool ib) : ibuf(b), isize(s), isbranch(ib) { }
unsigned char * ibuf;
size_t isize;
bool isbranch;
};
/*
* Notify for interprocedural control transfers
*/
struct interproc_details {
typedef enum {
ret,
call,
branch_interproc, // tail calls, branches to plts
syscall,
unresolved
} type_t;
unsigned char * ibuf;
size_t isize;
type_t type;
union {
struct {
Address target;
bool absolute_address;
bool dynamic_call;
} call;
struct {
Address target;
bool absolute_address;
bool dynamic;
} unres;
} data;
};
struct insn_details {
InsnAdapter::InstructionAdapter * insn;
};
typedef enum {
source,
target } edge_type_t;
// Callbacks
protected:
virtual void interproc_cf(Function*,Block *,Address,interproc_details*) { }
/*
* Allow examination of every instruction processed during parsing.
*/
virtual void instruction_cb(Function*,Block *,Address,insn_details*) { }
/*
* Notify about inconsistent parse data (overlapping blocks).
* The blocks are *not* guaranteed to be finished parsing at
* the time the callback is fired.
*/
virtual void overlapping_blocks(Block*,Block*) { }
/*
* Defensive-mode notifications:
* - Notify when a function's parse is finalized so Dyninst can
save its initial return status
* - Notify every time a block is split, after the initial parse
* of the function
* - Notify of the x86 obfuscation that performs a short jmp -1 (eb ff)
* so that dyninst can patch the opcode with a nop (0x90), which will
* keep code generation from doing bad things
*/
virtual void newfunction_retstatus(Function*) { }
virtual void patch_nop_jump(Address) { }
virtual bool updateCodeBytes(Address) { return false; }
virtual void abruptEnd_cf(Address, Block *,default_details*) { }
// returns the load address of the code object containing an absolute address
virtual bool absAddr(Address /*absolute*/,
Address & /*loadAddr*/,
CodeObject *& /*containerObject*/)
{ return false; }
virtual bool hasWeirdInsns(const Function*) const { return false; }
virtual void foundWeirdInsns(Function*) {}
// User override time
// (orig, new split block)
virtual void split_block_cb(Block *, Block *) {}
virtual void destroy_cb(Block *) {}
virtual void destroy_cb(Edge *) {}
virtual void destroy_cb(Function *) {}
virtual void remove_edge_cb(Block *, Edge *, edge_type_t) {}
virtual void add_edge_cb(Block *, Edge *, edge_type_t) {}
virtual void remove_block_cb(Function *, Block *) {}
virtual void add_block_cb(Function *, Block *) {}
virtual void modify_edge_cb(Edge *, Block *, ParseCallback::edge_type_t) {}
virtual void function_discovery_cb(Function*) {}
private:
};
// And the wrapper class used by CodeObject.
class ParseCallbackManager {
public:
ParseCallbackManager(ParseCallback *b) : inBatch_(false) { if (b) registerCallback(b); }
virtual ~ParseCallbackManager();
typedef std::list<ParseCallback *> Callbacks;
typedef Callbacks::iterator iterator;
typedef Callbacks::const_iterator const_iterator;
void registerCallback(ParseCallback *a);
void unregisterCallback(ParseCallback *a);
const_iterator begin() const { return cbs_.begin(); }
const_iterator end() const { return cbs_.end(); }
iterator begin() { return cbs_.begin(); }
iterator end() { return cbs_.end(); }
void batch_begin();
void batch_end(CFGFactory *fact); // fact provided so we can safely delete
// Batch-compatible methods
void destroy(Block *, CFGFactory *fact);
void destroy(Edge *, CFGFactory *fact);
void destroy(Function *, CFGFactory *fact);
void removeEdge(Block *, Edge *, ParseCallback::edge_type_t);
void addEdge(Block *, Edge *, ParseCallback::edge_type_t);
void removeBlock(Function *, Block *);
void addBlock(Function *, Block *);
void splitBlock(Block *, Block *);
void modifyEdge(Edge *, Block *, ParseCallback::edge_type_t);
void interproc_cf(Function*,Block *,Address,ParseCallback::interproc_details*);
void instruction_cb(Function*,Block *,Address,ParseCallback::insn_details*);
void overlapping_blocks(Block*,Block*);
void newfunction_retstatus(Function*);
void patch_nop_jump(Address);
bool updateCodeBytes(Address);
void abruptEnd_cf(Address, Block *,ParseCallback::default_details*);
bool absAddr(Address /*absolute*/,
Address & /*loadAddr*/,
CodeObject *& /*containerObject*/);
bool hasWeirdInsns(const Function*);
void foundWeirdInsns(Function*);
void split_block_cb(Block *, Block *);
void discover_function(Function*);
private:
// Named the same as ParseCallback to make the code
// more readable.
void destroy_cb(Block *);
void destroy_cb(Edge *);
void destroy_cb(Function *);
void remove_edge_cb(Block *, Edge *, ParseCallback::edge_type_t);
void add_edge_cb(Block *, Edge *, ParseCallback::edge_type_t);
void remove_block_cb(Function *, Block *);
void add_block_cb(Function *, Block *);
void modify_edge_cb(Edge *, Block *, ParseCallback::edge_type_t);
private:
Callbacks cbs_;
bool inBatch_;
typedef enum { removed, added } mod_t;
struct BlockMod {
Block *block;
Edge *edge;
ParseCallback::edge_type_t type;
mod_t action;
BlockMod(Block *b, Edge *e, ParseCallback::edge_type_t t, mod_t m) : block(b), edge(e), type(t), action(m) {}
};
struct EdgeMod {
Edge *edge;
Block *block;
ParseCallback::edge_type_t action;
EdgeMod(Edge *e, Block *b, ParseCallback::edge_type_t t) :
edge(e), block(b), action(t) {}
};
struct FuncMod {
Function *func;
Block *block;
mod_t action;
FuncMod(Function *f, Block *b, mod_t m) : func(f), block(b), action(m) {}
};
typedef std::pair<Block *, Block *> BlockSplit;
std::vector<Edge *> destroyedEdges_;
std::vector<Block *> destroyedBlocks_;
std::vector<Function *> destroyedFunctions_;
std::vector<BlockMod> blockMods_;
std::vector<EdgeMod> edgeMods_;
std::vector<FuncMod> funcMods_;
std::vector<BlockSplit> blockSplits_;
};
}
}
#endif