Skip to content

Commit 3212faa

Browse files
committed
Adapt to changes in Rose.
Particularly the fact that RegisterDictionary objects are now passed as shared pointers.
1 parent 6b934de commit 3212faa

24 files changed

+172
-134
lines changed

libpharos/badcode.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015-2021 Carnegie Mellon University. See LICENSE file for terms.
1+
// Copyright 2015-2022 Carnegie Mellon University. See LICENSE file for terms.
22

33
#include "badcode.hpp"
44
#include "descriptors.hpp"
@@ -90,7 +90,7 @@ bool BadCodeMetrics::isBadCode(SgAsmStatementPtrList insns,
9090

9191
SymbolicRiscOperatorsPtr rops = SymbolicRiscOperators::instance(ds);
9292
size_t arch_bits = ds.get_arch_bits();
93-
DispatcherPtr dispatcher = RoseDispatcherX86::instance(rops, arch_bits, NULL);
93+
DispatcherPtr dispatcher = RoseDispatcherX86::instance(rops, arch_bits, {});
9494
RegisterDescriptor eiprd = dispatcher->findRegister("eip", arch_bits);
9595

9696
for (size_t q = 0; q < insns.size(); q++) {

libpharos/bua.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2018-2019 Carnegie Mellon University. See LICENSE file for terms.
1+
// Copyright 2018-2022 Carnegie Mellon University. See LICENSE file for terms.
22

33
#include "bua.hpp"
44
#include "descriptors.hpp"
@@ -258,6 +258,8 @@ FDG::FDG(DescriptorSet & ds)
258258
return !not_simple.exists(vertex);
259259
};
260260
auto vertices = g_.vertices();
261+
using std::begin;
262+
using std::end;
261263
for (auto v = begin(vertices); v != end(vertices); ++v) {
262264
if (is_simple(v)
263265
&& std::none_of(begin(v->inEdges()), end(v->inEdges()),
@@ -284,6 +286,8 @@ std::vector<FunctionDescriptor *> FDG::bottom_up_order() const
284286
auto vertices = g.vertices();
285287

286288
// Build a list of vertices that have no outgoing edges, and add them to the result vector
289+
using std::end;
290+
using std::begin;
287291
for (auto v = begin(vertices); v != end(vertices); ++v) {
288292
if (v->nOutEdges() == 0) {
289293
to_erase.push_back(v);

libpharos/convention.cpp

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015-2021 Carnegie Mellon University. See LICENSE file for terms.
1+
// Copyright 2015-2022 Carnegie Mellon University. See LICENSE file for terms.
22

33
#include <boost/optional.hpp>
44

@@ -226,7 +226,7 @@ bool RegisterUsage::check_saved_register(SgAsmX86Instruction *insn, RegisterDesc
226226
// that qualified as a save/restore pair and no evidence to the contrary (e..g having return
227227
// false already), then it's time to make the instructions as a save/restore pair.
228228
if (restore_insn) {
229-
GTRACE << "Saved register: reg=" << unparseX86Register(reg, NULL)
229+
GTRACE << "Saved register: reg=" << unparseX86Register(reg, {})
230230
<< " save=" << debug_instruction(insn)
231231
<< " restore=" << debug_instruction(restore_insn) << LEND;
232232
saved_registers.insert(SavedRegister(reg, insn, restore_insn));
@@ -284,8 +284,8 @@ void RegisterUsage::analyze_parameters() {
284284
const Addr2DUChainMap& dd = p->get_usedef().get_dependencies();
285285

286286
// Get a handle to the stack pointer register, because it's special.
287-
const RegisterDictionary regdict = fd->ds.get_regdict();
288-
RegisterDescriptor esp = regdict.find("esp");
287+
RegisterDictionaryPtrArg regdict = fd->ds.get_regdict();
288+
RegisterDescriptor esp = regdict->find("esp");
289289

290290
// This is for keeping track of which stack parameter deltas we've actually used, and which
291291
// which haven't. This might be duplicated work, and we've not saved this anywhere. Here is
@@ -404,11 +404,11 @@ void RegisterUsage::analyze_parameters() {
404404
// Strictly speaking, I think this means that skipping memory reads earlier could be
405405
// incorrect as well... :-(
406406

407-
RegisterDescriptor initial_reg = regdict.find(cmt.substr(0, clen - 2));
407+
RegisterDescriptor initial_reg = regdict->find(cmt.substr(0, clen - 2));
408408

409409
parameter_registers[initial_reg] = insn;
410410
GTRACE << "Function " << fd->address_string() << " uses register "
411-
<< unparseX86Register(initial_reg, NULL)
411+
<< unparseX86Register(initial_reg, {})
412412
<< " as parameter in " << debug_instruction(insn) << LEND;
413413
break;
414414
}
@@ -420,7 +420,7 @@ void RegisterUsage::analyze_parameters() {
420420
GTRACE << "Function " << fd->address_string() << " has parameters: ";
421421
for (const RegisterEvidenceMap::value_type& rpair : parameter_registers) {
422422
RegisterDescriptor reg = rpair.first;
423-
GTRACE << " " << unparseX86Register(reg, NULL);
423+
GTRACE << " " << unparseX86Register(reg, {});
424424
}
425425
GTRACE << LEND;
426426
}
@@ -448,12 +448,12 @@ void RegisterUsage::analyze_changed() {
448448

449449
RegisterSet all_changed_registers = routput->diff(rinput);
450450

451-
const RegisterDictionary regdict = fd->ds.get_regdict();
452-
RegisterDescriptor esp = regdict.find("esp");
453-
RegisterDescriptor ebp = regdict.find("ebp");
454-
RegisterDescriptor esi = regdict.find("esi");
455-
RegisterDescriptor edi = regdict.find("edi");
456-
RegisterDescriptor ebx = regdict.find("ebx");
451+
RegisterDictionaryPtrArg regdict = fd->ds.get_regdict();
452+
RegisterDescriptor esp = regdict->find("esp");
453+
RegisterDescriptor ebp = regdict->find("ebp");
454+
RegisterDescriptor esi = regdict->find("esi");
455+
RegisterDescriptor edi = regdict->find("edi");
456+
RegisterDescriptor ebx = regdict->find("ebx");
457457

458458
// It turns out that we can't enable this code properly because our system is just too
459459
// fragile. If we're incorrect in any low-level function, this propogates that failure
@@ -481,7 +481,7 @@ void RegisterUsage::analyze_changed() {
481481
// Warn about cases where we reject register changes based on calling convention assumptions.
482482
if (rd == ebp or rd == esi or rd == edi or rd == ebx) {
483483
GDEBUG << "Function " << fd->address_string() << " overwrites "
484-
<< unparseX86Register(rd, NULL)
484+
<< unparseX86Register(rd, {})
485485
<< " violating all known calling conventions." << LEND;
486486
}
487487
else {
@@ -491,7 +491,7 @@ void RegisterUsage::analyze_changed() {
491491

492492
GDEBUG << "Function " << fd->address_string() << " changed registers: ";
493493
for (RegisterDescriptor rd : changed_registers) {
494-
GDEBUG << " " << unparseX86Register(rd, NULL);
494+
GDEBUG << " " << unparseX86Register(rd, {});
495495
}
496496
GDEBUG << LEND;
497497
}
@@ -537,8 +537,8 @@ CallingConvention::CallingConvention(size_t word_size_, const std::string &name_
537537
assert(!name.empty());
538538
}
539539

540-
void CallingConvention::add_nonvolatile(const RegisterDictionary & dict, std::string rname) {
541-
RegisterDescriptor rd = dict.find(rname);
540+
void CallingConvention::add_nonvolatile(RegisterDictionaryPtrArg dict, std::string rname) {
541+
RegisterDescriptor rd = dict->find(rname);
542542
if (!rd.is_valid()) {
543543
GFATAL << "Unable to find non-volatile register '" << rname << "'." << LEND;
544544
assert(rd.is_valid());
@@ -578,13 +578,13 @@ void CallingConvention::report() const {
578578

579579
GTRACE << " Parameter regs: ";
580580
for (RegisterDescriptor rd : reg_params) {
581-
GTRACE << " " << unparseX86Register(rd, NULL);
581+
GTRACE << " " << unparseX86Register(rd, {});
582582
}
583583
GTRACE << LEND;
584584

585585
GTRACE << " Nonvolatile regs: ";
586586
for (RegisterDescriptor rd : nonvolatile) {
587-
GTRACE << " " << unparseX86Register(rd, NULL);
587+
GTRACE << " " << unparseX86Register(rd, {});
588588
}
589589
GTRACE << LEND;
590590
}
@@ -727,7 +727,7 @@ std::string ParameterDefinition::to_string() const {
727727
std::stringstream out;
728728
out << " num=" << d.num;
729729
if (is_reg()) {
730-
out << " reg=" << unparseX86Register(d.reg, NULL);
730+
out << " reg=" << unparseX86Register(d.reg, {});
731731
}
732732
else {
733733
out << " sd=" << d.stack_delta;
@@ -786,7 +786,7 @@ void ParameterDefinition::debug() const {
786786

787787
OINFO << " num=" << d.num;
788788
if (is_reg()) {
789-
OINFO << " reg=" << unparseX86Register(d.reg, NULL);
789+
OINFO << " reg=" << unparseX86Register(d.reg, {});
790790
}
791791
else {
792792
OINFO << " sd=" << d.stack_delta;
@@ -1110,7 +1110,7 @@ CallingConventionMatcher::match(const FunctionDescriptor* fd,
11101110
if (ru.changed_registers.find(rd) != ru.changed_registers.end()) {
11111111
GDEBUG << "Function " << fd->address_string() << " can't match "
11121112
<< cc.get_name() << " because non-volatile register "
1113-
<< unparseX86Register(rd, NULL) << " was changed." << LEND;
1113+
<< unparseX86Register(rd, {}) << " was changed." << LEND;
11141114
follows_nonvolatile_rule = false;
11151115
break;
11161116
}
@@ -1142,7 +1142,7 @@ CallingConventionMatcher::match(const FunctionDescriptor* fd,
11421142
static char const * allowed_registers[] =
11431143
{"esp", "df", "cs", "ds", "ss", "es", "gs", "fs", nullptr};
11441144
for (char const ** regname = allowed_registers; *regname; ++regname) {
1145-
RegisterDescriptor rd = regdict.find(*regname);
1145+
RegisterDescriptor rd = regdict->find(*regname);
11461146
if (temp_params.find(rd) != temp_params.end()) temp_params.erase(rd);
11471147
}
11481148

@@ -1166,7 +1166,7 @@ CallingConventionMatcher::match(const FunctionDescriptor* fd,
11661166
}
11671167
else {
11681168
GTRACE << "Function " << fd->address_string() << " does not use parameter register "
1169-
<< unparseX86Register(rd, NULL) << LEND;
1169+
<< unparseX86Register(rd, {}) << LEND;
11701170
// If there are function parameters that are passed in registers, but not actually
11711171
// used, then breaking here causes a premature end to the consideration of the
11721172
// remaining parameters in the calling convention, leaving any additional parameters
@@ -1183,7 +1183,7 @@ CallingConventionMatcher::match(const FunctionDescriptor* fd,
11831183
GTRACE << "Unmatched parameter registers: ";
11841184
for (const RegisterEvidenceMap::value_type& rpair : temp_params) {
11851185
RegisterDescriptor rd = rpair.first;
1186-
GTRACE << " " << unparseX86Register(rd, NULL);
1186+
GTRACE << " " << unparseX86Register(rd, {});
11871187
}
11881188
GTRACE << LEND;
11891189
continue;
@@ -1213,16 +1213,20 @@ CallingConventionMatcher::match(const FunctionDescriptor* fd,
12131213
CallingConventionMatcher::CallingConventionMatcher()
12141214
// It is presumes that the amd64 register dictionary is a superset of the 32-bit and 16-bit
12151215
// dictionaries
1216-
: regdict(*Rose::BinaryAnalysis::RegisterDictionary::dictionary_amd64())
1216+
#if PHAROS_ROSE_REGISTERDICTIONARY_PTR_HACK
1217+
: regdict(Rose::BinaryAnalysis::RegisterDictionary::instanceAmd64())
1218+
#else
1219+
: regdict(Rose::BinaryAnalysis::RegisterDictionary::dictionary_amd64())
1220+
#endif
12171221
{
12181222
// ================================================================================
12191223
// 16-bit calling conventions...
12201224
// ================================================================================
12211225
// Agner says 16-bit DOS and windows has SI, DI, BP and DS as nonvolatile.
12221226

1223-
RegisterDescriptor eax = regdict.find("eax");
1224-
RegisterDescriptor ecx = regdict.find("ecx");
1225-
RegisterDescriptor edx = regdict.find("edx");
1227+
RegisterDescriptor eax = regdict->find("eax");
1228+
RegisterDescriptor ecx = regdict->find("ecx");
1229+
RegisterDescriptor edx = regdict->find("edx");
12261230
//RegisterDescriptor st0 = regdict->find("st0");
12271231

12281232
// Agner says this list is correct for Windows & Unix
@@ -1341,18 +1345,18 @@ CallingConventionMatcher::CallingConventionMatcher()
13411345
// See earlier comment on clearing df being allowed.
13421346
nonvol.add_nonvolatile(regdict, "df");
13431347

1344-
RegisterDescriptor rax = regdict.find("rax");
1345-
RegisterDescriptor rdi = regdict.find("rdi");
1346-
RegisterDescriptor rsi = regdict.find("rsi");
1347-
RegisterDescriptor rcx = regdict.find("rcx");
1348-
RegisterDescriptor rdx = regdict.find("rdx");
1349-
RegisterDescriptor r8 = regdict.find("r8");
1350-
RegisterDescriptor r9 = regdict.find("r9");
1351-
1352-
RegisterDescriptor xmm0 = regdict.find("xmm0");
1353-
RegisterDescriptor xmm1 = regdict.find("xmm1");
1354-
RegisterDescriptor xmm2 = regdict.find("xmm2");
1355-
RegisterDescriptor xmm3 = regdict.find("xmm3");
1348+
RegisterDescriptor rax = regdict->find("rax");
1349+
RegisterDescriptor rdi = regdict->find("rdi");
1350+
RegisterDescriptor rsi = regdict->find("rsi");
1351+
RegisterDescriptor rcx = regdict->find("rcx");
1352+
RegisterDescriptor rdx = regdict->find("rdx");
1353+
RegisterDescriptor r8 = regdict->find("r8");
1354+
RegisterDescriptor r9 = regdict->find("r9");
1355+
1356+
RegisterDescriptor xmm0 = regdict->find("xmm0");
1357+
RegisterDescriptor xmm1 = regdict->find("xmm1");
1358+
RegisterDescriptor xmm2 = regdict->find("xmm2");
1359+
RegisterDescriptor xmm3 = regdict->find("xmm3");
13561360

13571361
cc = CallingConvention(64, "__x64call", "GNU C Compiler");
13581362
cc.set_stack_alignment(64);

libpharos/convention.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015-2019 Carnegie Mellon University. See LICENSE file for terms.
1+
// Copyright 2015-2019, 2022 Carnegie Mellon University. See LICENSE file for terms.
22

33
#ifndef Pharos_Convention_H
44
#define Pharos_Convention_H
@@ -205,7 +205,7 @@ class CallingConvention {
205205
void add_reg_param(RegisterDescriptor reg) { reg_params.push_back(reg); }
206206

207207
const RegisterSet& get_nonvolatile() const { return nonvolatile; }
208-
void add_nonvolatile(const RegisterDictionary & dict, std::string name);
208+
void add_nonvolatile(RegisterDictionaryPtrArg dict, std::string name);
209209
void add_nonvolatile(RegisterDescriptor rd);
210210
void add_nonvolatile(const RegisterSet& regs);
211211

@@ -614,7 +614,7 @@ using CallingConventionPtrVector = std::vector<const CallingConvention*>;
614614
class CallingConventionMatcher {
615615
private:
616616

617-
RegisterDictionary const & regdict;
617+
RegisterDictionaryPtr regdict;
618618
CallingConventionVector conventions;
619619

620620
public:
@@ -624,7 +624,7 @@ class CallingConventionMatcher {
624624
// Write information about each calling convention to the debug log stream.
625625
void report() const;
626626

627-
const RegisterDictionary & get_regdict() { return regdict; }
627+
RegisterDictionaryPtrArg get_regdict() { return regdict; }
628628
CallingConventionPtrVector match(const FunctionDescriptor* fd,
629629
bool allow_unused_parameters = true) const;
630630

libpharos/defuse.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015-2021 Carnegie Mellon University. See LICENSE file for terms.
1+
// Copyright 2015-2022 Carnegie Mellon University. See LICENSE file for terms.
22

33
#include <boost/algorithm/string.hpp>
44
#include <boost/tokenizer.hpp>
@@ -201,7 +201,7 @@ BlockAnalysis::record_dependencies(
201201
SymbolicValuePtr sv = cstate->read_register(rd);
202202

203203
if (aa.latest_writers.size() == 0) {
204-
std::string regname = unparseX86Register(rd, NULL);
204+
std::string regname = unparseX86Register(rd, {});
205205
SDEBUG << "Warning: Use of uninitialized register "
206206
<< regname << " by " << debug_instruction(insn) << LEND;
207207
Definition reg_def(NULL, aa);
@@ -692,23 +692,23 @@ DUAnalysis::DUAnalysis(DescriptorSet& ds_, FunctionDescriptor & f)
692692
SymbolicRiscOperatorsPtr rops;
693693

694694
SymbolicValuePtr proto = SymbolicValue::instance();
695-
const RegisterDictionary& regdict = ds.get_regdict();
695+
RegisterDictionaryPtrArg regdict = ds.get_regdict();
696696
if (rigor) {
697697
// This is the new bit that instantiates the list-based memory state instead of the map based state.
698-
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, &regdict);
698+
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, regdict);
699699
SymbolicMemoryListStatePtr mstate = SymbolicMemoryListState::instance();
700700
SymbolicStatePtr state = SymbolicState::instance(rstate, mstate);
701701
rops = SymbolicRiscOperators::instance(ds, state, &rops_callbacks);
702702
}
703703
else {
704-
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, &regdict);
704+
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, regdict);
705705
SymbolicMemoryMapStatePtr mstate = SymbolicMemoryMapState::instance();
706706
SymbolicStatePtr state = SymbolicState::instance(rstate, mstate);
707707
rops = SymbolicRiscOperators::instance(ds, state, &rops_callbacks);
708708
}
709709

710710
size_t arch_bits = ds.get_arch_bits();
711-
dispatcher = RoseDispatcherX86::instance(rops, arch_bits, NULL);
711+
dispatcher = RoseDispatcherX86::instance(rops, arch_bits, {});
712712

713713
// Configure the limit analysis. The func_limit instance is local, but we still need to
714714
// configure the global limits of the analysis of all functions as well.
@@ -927,7 +927,7 @@ void create_overwritten_register(SymbolicRiscOperatorsPtr rops,
927927
cd->set_return_value(value);
928928
// Add the return register to the "returns" parameter list as well.
929929
ParameterList& params = cd->get_rw_parameters();
930-
SDEBUG << "Creating return register parameter " << unparseX86Register(rd, NULL)
930+
SDEBUG << "Creating return register parameter " << unparseX86Register(rd, {})
931931
<< " with value " << *value << LEND;
932932
ParameterDefinition & rpd = params.create_return_reg(rd, value);
933933
// If the upstream parameters list has only a single return value, assume that this is it,
@@ -1092,7 +1092,7 @@ DUAnalysis::make_call_dependencies(SgAsmX86Instruction* insn, SymbolicStatePtr&
10921092
// Mark the register as overwritten.
10931093
SymbolicValuePtr rv = create_return_value(insn, rd.get_nbits(), false);
10941094
create_overwritten_register(rops, ds, rd, false, rv, cd, fparams);
1095-
GTRACE << "Setting changed register " << unparseX86Register(rd, NULL)
1095+
GTRACE << "Setting changed register " << unparseX86Register(rd, {})
10961096
<< " for insn " << addr_str(insn->get_address())
10971097
<< " to value=" << *(rops->read_register(rd)) << LEND;
10981098
// And we're done with this register...
@@ -1137,7 +1137,7 @@ DUAnalysis::make_call_dependencies(SgAsmX86Instruction* insn, SymbolicStatePtr&
11371137
// We'll handled non-register (memory) parameters a bit later (maybe).
11381138
if (not pd.is_reg()) continue;
11391139

1140-
SDEBUG << "Found register parameter: " << unparseX86Register(pd.get_register(), NULL)
1140+
SDEBUG << "Found register parameter: " << unparseX86Register(pd.get_register(), {})
11411141
<< " for call " << cd->address_string() << LEND;
11421142

11431143
// Create a dependency between the instructions that last modifier the value of the
@@ -1625,8 +1625,8 @@ DUAnalysis::update_output_state()
16251625
if (out_vertices.size() == 0) {
16261626
SERROR << "Function " << fd->address_string() << " has no out edges." << LEND;
16271627
SymbolicValuePtr proto = SymbolicValue::instance();
1628-
const RegisterDictionary& regdict = ds.get_regdict();
1629-
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, &regdict);
1628+
RegisterDictionaryPtrArg regdict = ds.get_regdict();
1629+
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, regdict);
16301630
SymbolicMemoryMapStatePtr mstate = SymbolicMemoryMapState::instance();
16311631
output_state = SymbolicState::instance(rstate, mstate);
16321632
output_valid = false;
@@ -1678,8 +1678,8 @@ DUAnalysis::update_output_state()
16781678
if (ret_blocks.size() == 0) {
16791679
SDEBUG << "Function " << fd->address_string() << " has no valid return blocks." << LEND;
16801680
SymbolicValuePtr proto = SymbolicValue::instance();
1681-
const RegisterDictionary& regdict = ds.get_regdict();
1682-
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, &regdict);
1681+
RegisterDictionaryPtrArg regdict = ds.get_regdict();
1682+
SymbolicRegisterStatePtr rstate = SymbolicRegisterState::instance(proto, regdict);
16831683
SymbolicMemoryMapStatePtr mstate = SymbolicMemoryMapState::instance();
16841684
output_state = SymbolicState::instance(rstate, mstate);
16851685
output_valid = false;

0 commit comments

Comments
 (0)