mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
213 lines
8 KiB
C++
213 lines
8 KiB
C++
/* ###
|
|
* IP: GHIDRA
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef __SEMANTICS_HH__
|
|
#define __SEMANTICS_HH__
|
|
|
|
#include "context.hh"
|
|
#include "slaformat.hh"
|
|
|
|
namespace ghidra {
|
|
|
|
// We remap these opcodes for internal use during pcode generation
|
|
|
|
#define BUILD CPUI_MULTIEQUAL
|
|
#define DELAY_SLOT CPUI_INDIRECT
|
|
#define CROSSBUILD CPUI_PTRSUB
|
|
#define MACROBUILD CPUI_CAST
|
|
#define LABELBUILD CPUI_PTRADD
|
|
|
|
class Translate; // Forward declaration
|
|
class HandleTpl; // Forward declaration
|
|
class ConstTpl {
|
|
public:
|
|
enum const_type { real=0, handle=1, j_start=2, j_next=3, j_next2=4, j_curspace=5,
|
|
j_curspace_size=6, spaceid=7, j_relative=8,
|
|
j_flowref=9, j_flowref_size=10, j_flowdest=11, j_flowdest_size=12 };
|
|
enum v_field { v_space=0, v_offset=1, v_size=2, v_offset_plus=3 };
|
|
private:
|
|
const_type type;
|
|
union {
|
|
// uintb real; // an actual constant
|
|
AddrSpace *spaceid; // Id (pointer) for registered space
|
|
int4 handle_index; // Place holder for run-time determined value
|
|
} value;
|
|
uintb value_real;
|
|
v_field select; // Which part of handle to use as constant
|
|
public:
|
|
ConstTpl(void) { type = real; value_real = 0; }
|
|
ConstTpl(const ConstTpl &op2) {
|
|
type=op2.type; value=op2.value; value_real=op2.value_real; select=op2.select; }
|
|
ConstTpl(const_type tp,uintb val);
|
|
ConstTpl(const_type tp);
|
|
ConstTpl(AddrSpace *sid);
|
|
ConstTpl(const_type tp,int4 ht,v_field vf);
|
|
ConstTpl(const_type tp,int4 ht,v_field vf,uintb plus);
|
|
bool isConstSpace(void) const;
|
|
bool isUniqueSpace(void) const;
|
|
bool operator==(const ConstTpl &op2) const;
|
|
bool operator<(const ConstTpl &op2) const;
|
|
uintb getReal(void) const { return value_real; }
|
|
AddrSpace *getSpace(void) const { return value.spaceid; }
|
|
int4 getHandleIndex(void) const { return value.handle_index; }
|
|
const_type getType(void) const { return type; }
|
|
v_field getSelect(void) const { return select; }
|
|
uintb fix(const ParserWalker &walker) const;
|
|
AddrSpace *fixSpace(const ParserWalker &walker) const;
|
|
void transfer(const vector<HandleTpl *> ¶ms);
|
|
bool isZero(void) const { return ((type==real)&&(value_real==0)); }
|
|
void changeHandleIndex(const vector<int4> &handmap);
|
|
void fillinSpace(FixedHandle &hand,const ParserWalker &walker) const;
|
|
void fillinOffset(FixedHandle &hand,const ParserWalker &walker) const;
|
|
void encode(Encoder &encoder) const;
|
|
void decode(Decoder &decoder);
|
|
};
|
|
|
|
class VarnodeTpl {
|
|
friend class OpTpl;
|
|
friend class HandleTpl;
|
|
ConstTpl space,offset,size;
|
|
bool unnamed_flag;
|
|
public:
|
|
VarnodeTpl(int4 hand,bool zerosize);
|
|
VarnodeTpl(void) : space(), offset(), size() { unnamed_flag=false; }
|
|
VarnodeTpl(const ConstTpl &sp,const ConstTpl &off,const ConstTpl &sz);
|
|
VarnodeTpl(const VarnodeTpl &vn);
|
|
const ConstTpl &getSpace(void) const { return space; }
|
|
const ConstTpl &getOffset(void) const { return offset; }
|
|
const ConstTpl &getSize(void) const { return size; }
|
|
bool isDynamic(const ParserWalker &walker) const;
|
|
int4 transfer(const vector<HandleTpl *> ¶ms);
|
|
bool isZeroSize(void) const { return size.isZero(); }
|
|
bool operator<(const VarnodeTpl &op2) const;
|
|
void setOffset(uintb constVal) { offset = ConstTpl(ConstTpl::real,constVal); }
|
|
void setRelative(uintb constVal) { offset = ConstTpl(ConstTpl::j_relative,constVal); }
|
|
void setSize(const ConstTpl &sz ) { size = sz; }
|
|
bool isUnnamed(void) const { return unnamed_flag; }
|
|
void setUnnamed(bool val) { unnamed_flag = val; }
|
|
bool isLocalTemp(void) const;
|
|
bool isRelative(void) const { return (offset.getType() == ConstTpl::j_relative); }
|
|
void changeHandleIndex(const vector<int4> &handmap);
|
|
bool adjustTruncation(int4 sz,bool isbigendian);
|
|
void encode(Encoder &encoder) const;
|
|
void decode(Decoder &decoder);
|
|
};
|
|
|
|
class HandleTpl {
|
|
ConstTpl space;
|
|
ConstTpl size;
|
|
ConstTpl ptrspace;
|
|
ConstTpl ptroffset;
|
|
ConstTpl ptrsize;
|
|
ConstTpl temp_space;
|
|
ConstTpl temp_offset;
|
|
public:
|
|
HandleTpl(void) {}
|
|
HandleTpl(const VarnodeTpl *vn);
|
|
HandleTpl(const ConstTpl &spc,const ConstTpl &sz,const VarnodeTpl *vn,
|
|
AddrSpace *t_space,uintb t_offset);
|
|
const ConstTpl &getSpace(void) const { return space; }
|
|
const ConstTpl &getPtrSpace(void) const { return ptrspace; }
|
|
const ConstTpl &getPtrOffset(void) const { return ptroffset; }
|
|
const ConstTpl &getPtrSize(void) const { return ptrsize; }
|
|
const ConstTpl &getSize(void) const { return size; }
|
|
const ConstTpl &getTempSpace(void) const { return temp_space; }
|
|
const ConstTpl &getTempOffset(void) const { return temp_offset; }
|
|
void setSize(const ConstTpl &sz) { size = sz; }
|
|
void setPtrSize(const ConstTpl &sz) { ptrsize=sz; }
|
|
void setPtrOffset(uintb val) { ptroffset = ConstTpl(ConstTpl::real,val); }
|
|
void setTempOffset(uintb val) { temp_offset = ConstTpl(ConstTpl::real,val); }
|
|
void fix(FixedHandle &hand,const ParserWalker &walker) const;
|
|
void changeHandleIndex(const vector<int4> &handmap);
|
|
void encode(Encoder &encoder) const;
|
|
void decode(Decoder &decoder);
|
|
};
|
|
|
|
class OpTpl {
|
|
VarnodeTpl *output;
|
|
OpCode opc;
|
|
vector<VarnodeTpl *> input;
|
|
public:
|
|
OpTpl(void) {}
|
|
OpTpl(OpCode oc) { opc = oc; output = (VarnodeTpl *)0; }
|
|
~OpTpl(void);
|
|
VarnodeTpl *getOut(void) const { return output; }
|
|
int4 numInput(void) const { return input.size(); }
|
|
VarnodeTpl *getIn(int4 i) const { return input[i]; }
|
|
OpCode getOpcode(void) const { return opc; }
|
|
bool isZeroSize(void) const;
|
|
void setOpcode(OpCode o) { opc = o; }
|
|
void setOutput(VarnodeTpl *vt) { output = vt; }
|
|
void clearOutput(void) { delete output; output = (VarnodeTpl *)0; }
|
|
void addInput(VarnodeTpl *vt) { input.push_back(vt); }
|
|
void setInput(VarnodeTpl *vt,int4 slot) { input[slot] = vt; }
|
|
void removeInput(int4 index);
|
|
void changeHandleIndex(const vector<int4> &handmap);
|
|
void encode(Encoder &encoder) const;
|
|
void decode(Decoder &decoder);
|
|
};
|
|
|
|
class ConstructTpl {
|
|
friend class SleighCompile;
|
|
protected:
|
|
uint4 delayslot;
|
|
uint4 numlabels; // Number of label templates
|
|
vector<OpTpl *> vec;
|
|
HandleTpl *result;
|
|
void setOpvec(vector<OpTpl *> &opvec) { vec = opvec; }
|
|
void setNumLabels(uint4 val) { numlabels = val; }
|
|
public:
|
|
ConstructTpl(void) { delayslot=0; numlabels=0; result = (HandleTpl *)0; }
|
|
~ConstructTpl(void);
|
|
uint4 delaySlot(void) const { return delayslot; }
|
|
uint4 numLabels(void) const { return numlabels; }
|
|
const vector<OpTpl *> &getOpvec(void) const { return vec; }
|
|
HandleTpl *getResult(void) const { return result; }
|
|
bool addOp(OpTpl *ot);
|
|
bool addOpList(const vector<OpTpl *> &oplist);
|
|
void setResult(HandleTpl *t) { result = t; }
|
|
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
|
|
bool buildOnly(void) const;
|
|
void changeHandleIndex(const vector<int4> &handmap);
|
|
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
|
|
void setOutput(VarnodeTpl *vn,int4 index);
|
|
void deleteOps(const vector<int4> &indices);
|
|
void encode(Encoder &encoder,int4 sectionid) const;
|
|
int4 decode(Decoder &decoder);
|
|
};
|
|
|
|
class PcodeEmit; // Forward declaration for emitter
|
|
|
|
class PcodeBuilder { // SLEIGH specific pcode generator
|
|
uint4 labelbase;
|
|
uint4 labelcount;
|
|
protected:
|
|
ParserWalker *walker;
|
|
virtual void dump( OpTpl *op )=0;
|
|
public:
|
|
PcodeBuilder(uint4 lbcnt) { labelbase=labelcount=lbcnt; }
|
|
virtual ~PcodeBuilder(void) {}
|
|
|
|
uint4 getLabelBase(void) const { return labelbase; }
|
|
ParserWalker *getCurrentWalker() const { return walker; }
|
|
void build(ConstructTpl *construct,int4 secnum);
|
|
virtual void appendBuild(OpTpl *bld,int4 secnum)=0;
|
|
virtual void delaySlot(OpTpl *op)=0;
|
|
virtual void setLabel(OpTpl *op)=0;
|
|
virtual void appendCrossBuild(OpTpl *bld,int4 secnum)=0;
|
|
};
|
|
|
|
} // End namespace ghidra
|
|
#endif
|