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
205 lines
6.8 KiB
C++
205 lines
6.8 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 LOCATION_H
|
|
#define LOCATION_H
|
|
|
|
|
|
#include "CFG.h"
|
|
#include "CodeObject.h"
|
|
|
|
|
|
#include "InstructionDecoder.h"
|
|
#include "Instruction.h"
|
|
|
|
#include <string>
|
|
#include <assert.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace Dyninst{
|
|
namespace ParseAPI{
|
|
|
|
struct EntrySite {
|
|
Function *func;
|
|
Block *block;
|
|
EntrySite(Function *f, Block *b) : func(f), block(b) {}
|
|
};
|
|
struct CallSite {
|
|
Function *func;
|
|
Block *block;
|
|
CallSite(Function *f, Block *b) : func(f), block(b) {}
|
|
};
|
|
struct ExitSite {
|
|
Function *func;
|
|
Block *block;
|
|
ExitSite(Function *f, Block *b) : func(f), block(b) {}
|
|
};
|
|
|
|
struct EdgeLoc{
|
|
Function *func;
|
|
Edge *edge;
|
|
EdgeLoc(Function *f, Edge *e): func(f), edge(e) {}
|
|
};
|
|
|
|
struct BlockSite{
|
|
Function *func;
|
|
Block *block;
|
|
BlockSite(Function *f, Block *b): func(f), block(b) {}
|
|
};
|
|
|
|
typedef std::vector<std::pair<InstructionAPI::Instruction, Offset> > InsnVec;
|
|
|
|
static void getInsnInstances(Block *block,
|
|
InsnVec &insns) {
|
|
Offset off = block->start();
|
|
const unsigned char *ptr = (const unsigned char *)block->region()->getPtrToInstruction(off);
|
|
if (ptr == NULL) return;
|
|
InstructionAPI::InstructionDecoder d(ptr, block->size(), block->obj()->cs()->getArch());
|
|
while (off < block->end()) {
|
|
insns.push_back(std::make_pair(d.decode(), off));
|
|
off += insns.back().first.size();
|
|
}
|
|
}
|
|
|
|
|
|
struct InsnLoc {
|
|
Block *const block;
|
|
const Offset offset;
|
|
InstructionAPI::Instruction insn;
|
|
InsnLoc(Block *const b, Offset o, const InstructionAPI::Instruction& i) :
|
|
block(b), offset(o), insn(i) {}
|
|
};
|
|
|
|
|
|
|
|
struct Location {
|
|
|
|
Location() : func(NULL), block(NULL), offset(0), edge(NULL), untrusted(false), type(illegal_) {}
|
|
// Function
|
|
Location(Function *f) : func(f), block(NULL), offset(0), edge(NULL), untrusted(false), type(function_) {}
|
|
Location(EntrySite e) : func(e.func), block(e.block), offset(0), edge(NULL), untrusted(false), type(entry_) {}
|
|
Location(CallSite c) : func(c.func), block(c.block), offset(0), edge(NULL), untrusted(false), type(call_) {}
|
|
Location(ExitSite e) : func(e.func), block(e.block), offset(0), edge(NULL), untrusted(false), type(exit_) {}
|
|
// A block in a particular function
|
|
Location(Function *f, Block *b) : func(f), block(b), offset(0), edge(NULL), untrusted(true), type(blockInstance_) {}
|
|
// A block of a function
|
|
Location(BlockSite b): func(b.func), block(b.block), offset(0), edge(NULL), untrusted(false), type(blockInstance_) {}
|
|
// A trusted instruction (in a particular function)
|
|
Location(Function *f, InsnLoc l) : func(f), block(l.block), offset(l.offset), insn(l.insn), edge(NULL), untrusted(false), type(instructionInstance_) {}
|
|
// An untrusted (raw) instruction (in a particular function)
|
|
Location(Function *f, Block *b, Offset o, InstructionAPI::Instruction i) : func(f), block(b), offset(o), insn(i), edge(NULL), untrusted(true), type(instructionInstance_) {}
|
|
// An edge (in a particular function)
|
|
Location(Function *f, Edge *e) : func(f), block(NULL), offset(0), edge(e), untrusted(true), type(edge_) {}
|
|
Location(EdgeLoc e): func(e.func), block(NULL), offset(0), edge(e.edge), untrusted(false), type(edge_){}
|
|
// A block in general
|
|
Location(Block *b) : func(NULL), block(b), offset(0), edge(NULL), untrusted(false), type(block_) {}
|
|
// A trusted instruction in general
|
|
Location(InsnLoc l) : func(NULL), block(l.block), offset(l.offset), insn(l.insn), edge(NULL), untrusted(false), type(instruction_) {}
|
|
// An untrusted (raw) instruction
|
|
Location(Block *b, Offset o) : func(NULL), block(b), offset(o), edge(NULL), untrusted(true), type(instruction_) {}
|
|
// An edge
|
|
Location(Edge *e) : func(NULL), block(NULL), offset(0), edge(e), untrusted(false), type(edge_) {}
|
|
|
|
typedef enum {
|
|
function_,
|
|
block_,
|
|
blockInstance_,
|
|
instruction_,
|
|
instructionInstance_,
|
|
edge_,
|
|
entry_,
|
|
call_,
|
|
exit_,
|
|
illegal_ } type_t;
|
|
|
|
bool legal(type_t t) { return t == type; }
|
|
|
|
InsnLoc insnLoc() { return InsnLoc(block, offset, insn); }
|
|
|
|
bool isValid(){
|
|
if (untrusted){
|
|
InsnVec insns;
|
|
switch (type){
|
|
case blockInstance_:
|
|
return func->contains(block);
|
|
case instructionInstance_:
|
|
if (!func->contains(block)) return false;
|
|
getInsnInstances(block, insns);
|
|
for (InsnVec::iterator iter = insns.begin(); iter != insns.end(); ++iter)
|
|
if (iter->second == offset) return true;
|
|
return false;
|
|
case edge_:{
|
|
Function::blocklist blk = func->blocks();
|
|
for (Function::blocklist::iterator blockIter = blk.begin(); blockIter != blk.end(); ++blockIter){
|
|
Intraproc epred;
|
|
const Block::edgelist& target_edges = (*blockIter) -> targets();
|
|
if(std::find(dyncompat::make_filter_iterator(epred, target_edges.begin(), target_edges.end()),
|
|
dyncompat::make_filter_iterator(epred, target_edges.end(), target_edges.end()),
|
|
edge)
|
|
!= dyncompat::make_filter_iterator(epred, target_edges.end(), target_edges.end()))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
case instruction_:
|
|
getInsnInstances(block, insns);
|
|
for (InsnVec::iterator iter = insns.begin(); iter != insns.end(); ++iter)
|
|
if (iter->second == offset) return true;
|
|
return false;
|
|
case function_:
|
|
case block_:
|
|
case entry_:
|
|
case call_:
|
|
case exit_:
|
|
case illegal_: assert(0);
|
|
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Function *const func;
|
|
Block *const block;
|
|
const Offset offset;
|
|
InstructionAPI::Instruction insn;
|
|
Edge *const edge;
|
|
const bool untrusted;
|
|
const type_t type;
|
|
|
|
|
|
};
|
|
|
|
} //ParseAPI
|
|
} //Dyninst
|
|
|
|
#endif
|