Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Ghidra/Features/Decompiler/src/decompile/cpp/address.hh
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,18 @@ inline bool Range::contains(const Address &addr) const {
/// \return a value appropriate for masking off the first \e size bytes
inline uintb calc_mask(int4 size) { return uintbmasks[((uint4)size) < 8 ? size : 8]; }

/// \param size of the integer in bytes
/// \return largest unsigned integer value for given size
inline uintb calc_uint_max(int4 size) { return calc_mask(size); }

/// \param size of the integer in bytes
/// \return largest signed integer value for given size
inline uintb calc_int_max(int4 size) { return calc_mask(size) >> 1; }

/// \param size of the integer in bytes
/// \return smallest signed integer value for given size
inline uintb calc_int_min(int4 size) { return (uintb)1 << (size * 8 - 1); }

/// Perform a CPUI_INT_RIGHT on the given val
/// \param val is the value to shift
/// \param sa is the number of bits to shift
Expand Down
14 changes: 8 additions & 6 deletions Ghidra/Features/Decompiler/src/decompile/cpp/funcdata_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,8 @@ bool Funcdata::replaceLessequal(PcodeOp *op)
{
Varnode *vn;
int4 i;
intb val,diff;
uintb val;
intb diff;

if ((vn=op->getIn(0))->isConstant()) {
diff = -1;
Expand All @@ -1044,15 +1045,16 @@ bool Funcdata::replaceLessequal(PcodeOp *op)
else
return false;

val = sign_extend(vn->getOffset(),8*vn->getSize()-1);
val = vn->getOffset();
if (op->code() == CPUI_INT_SLESSEQUAL) {
if ((val<0)&&(val+diff>0)) return false; // Check for sign overflow
if ((val>0)&&(val+diff<0)) return false;
// Check for signed overflow
if ((diff == -1) && (val == calc_int_min(vn->getSize()))) return false;
if ((diff == 1) && (val == calc_int_max(vn->getSize()))) return false;
opSetOpcode(op,CPUI_INT_SLESS);
}
else { // Check for unsigned overflow
if ((diff==-1)&&(val==0)) return false;
if ((diff==1)&&(val==-1)) return false;
if ((diff == -1) && (val == 0)) return false;
if ((diff == 1) && (val == calc_uint_max(vn->getSize()))) return false;
opSetOpcode(op,CPUI_INT_LESS);
}
uintb res = (val+diff) & calc_mask(vn->getSize());
Expand Down