From 292e8785e7fe859de20e9fb402fdcc979280e043 Mon Sep 17 00:00:00 2001 From: Xiaozhu Meng Date: Fri, 2 Dec 2016 09:38:24 -0600 Subject: [PATCH 01/12] Fix findMain analysis: we should analyze the first instruction before the call --- dataflowAPI/rose/x86_64InstructionSemantics.h | 14 ++--- dyninstAPI/src/image.C | 54 +++++++------------ 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/dataflowAPI/rose/x86_64InstructionSemantics.h b/dataflowAPI/rose/x86_64InstructionSemantics.h index ee0d36547f..906b147afb 100644 --- a/dataflowAPI/rose/x86_64InstructionSemantics.h +++ b/dataflowAPI/rose/x86_64InstructionSemantics.h @@ -2259,19 +2259,19 @@ struct X86_64InstructionSemantics { policy.writeGPR(x86_gpr_sp, newSp); break; } - +*/ case x86_call: { ROSE_ASSERT(operands.size() == 1); - ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32); - ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_32); - Word(32) oldSp = policy.readGPR(x86_gpr_sp); - Word(32) newSp = policy.add(oldSp, number<32>(-4)); + ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_64); + ROSE_ASSERT(insn->get_operandSize() == x86_insnsize_64); + Word(64) oldSp = policy.readGPR(x86_gpr_sp); + Word(64) newSp = policy.add(oldSp, number<64>(-4)); policy.writeMemory(x86_segreg_ss, newSp, policy.readIP(), policy.true_()); - policy.writeIP(policy.filterCallTarget(read32(operands[0]))); + policy.writeIP(policy.filterCallTarget(read64(operands[0]))); policy.writeGPR(x86_gpr_sp, newSp); break; } - +/* case x86_ret: { ROSE_ASSERT(operands.size() <= 1); ROSE_ASSERT(insn->get_addressSize() == x86_insnsize_32); diff --git a/dyninstAPI/src/image.C b/dyninstAPI/src/image.C index 0a11d03d96..d035401bc4 100644 --- a/dyninstAPI/src/image.C +++ b/dyninstAPI/src/image.C @@ -463,6 +463,7 @@ class FindMainVisitor : public ASTVisitor virtual ASTPtr visit(DataflowAPI::VariableAST* v) { + /* If we visit a variable node, we can't do any analysis */ hardFault = true; resolved = false; @@ -698,52 +699,35 @@ int image::findMain() Block* b = e->src(); assert(b); - /* Get the address of the last instruction in the block (the call) */ - Address insn_addr = b->lastInsnAddr(); - void* insn_raw = region->getPtrToInstruction(insn_addr); + Block::Insns insns; + b->getInsns(insns); + if (insns.size() < 2) { + startup_printf("%s[%u]: should have at least two instructions\n", FILE__, __LINE__); + return -1; + } - /* Make sure insn_raw is valid */ - if(!insn_raw) - { - startup_printf("%s[%u]: Error: no instruction pointer in region.\n", - FILE__, __LINE__); - return -1; - } - - /* Needed to get the size of the call instruction */ - instruction insn; - insn.setInstruction((const unsigned char*)insn_raw); - - /* We also need the instructionAPI representation of the call instruction */ - InstructionAPI::InstructionDecoder* decoder = NULL; - if(mode_64) - { - decoder = new InstructionAPI::InstructionDecoder( - insn_raw, insn.size(), Dyninst::Arch_x86_64); - } else { - decoder = new InstructionAPI::InstructionDecoder( - insn_raw, insn.size(), Dyninst::Arch_x86); - } - - /* Decode just the call instruction */ - InstructionAPI::Instruction::Ptr insn_ptr = decoder->decode( - (const unsigned char*)insn_raw); + // To get the secont to last instruction, which loads the address of main + auto iit = insns.end(); + --iit; + --iit; /* Let's get the assignment for this instruction. */ std::vector assignments; Dyninst::AssignmentConverter assign_convert(true, false); - assign_convert.convert(insn_ptr, insn_addr, func, b, assignments); + assign_convert.convert(iit->second, iit->first, func, b, assignments); if(assignments.size() >= 1) { - Assignment::Ptr assignment = *assignments.begin(); - - std::pair res = DataflowAPI::SymEval::expand(assignment, false); - AST::Ptr ast = res.first; + + Assignment::Ptr assignment = assignments[0]; + std::pair res = DataflowAPI::SymEval::expand(assignment, false); + AST::Ptr ast = res.first; if(!ast) { /* expand failed */ mainAddress = 0x0; + startup_printf("%s[%u]: cannot expand %s from instruction %s\n", FILE__, __LINE__, assignment->format().c_str(), assignment->insn()->format().c_str()); } else { + startup_printf("%s[%u]: try to visit %s\n", FILE__, __LINE__, ast->format().c_str()); FindMainVisitor fmv; ast->accept(&fmv); if(fmv.resolved) @@ -751,6 +735,8 @@ int image::findMain() mainAddress = fmv.target; } else { mainAddress = 0x0; + startup_printf("%s[%u]: FindMainVisitor cannot find main address in %s\n", FILE__, __LINE__, ast->format().c_str()); + } } } From 950ad53085eb91d07cc4a9cabace8c6af95615ec Mon Sep 17 00:00:00 2001 From: Matt Morehouse Date: Mon, 5 Dec 2016 16:15:18 -0600 Subject: [PATCH 02/12] Add StackAnalysis handling for pushing memory values on stack. --- dataflowAPI/src/stackanalysis.C | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dataflowAPI/src/stackanalysis.C b/dataflowAPI/src/stackanalysis.C index 59fe6d4977..320e25afda 100644 --- a/dataflowAPI/src/stackanalysis.C +++ b/dataflowAPI/src/stackanalysis.C @@ -1237,6 +1237,37 @@ void StackAnalysis::handlePushPop(Instruction::Ptr insn, Block *block, // Get pushed immediate long immVal = readExpr->eval().convert(); xferFuncs.push_back(TransferFunc::absFunc(writtenLoc, immVal)); + } else if (dynamic_cast(readExpr.get())) { + // Extract the read address expression + std::vector addrExpr; + readExpr->getChildren(addrExpr); + assert(addrExpr.size() == 1); + + // Try to determine the read memory address + StateEvalVisitor visitor; + if (intervals_ == NULL) { + visitor = StateEvalVisitor(off, insn, NULL); + } else { + visitor = StateEvalVisitor(off, insn, + &(*intervals_)[block][off]); + } + addrExpr[0]->apply(&visitor); + if (visitor.isDefined()) { + Absloc readLoc; + std::pair resultPair = visitor.getResult(); + if (resultPair.second) { + // We have a stack slot + readLoc = Absloc(resultPair.first, 0, NULL); + } else { + // We have a static address + readLoc = Absloc(resultPair.first); + } + xferFuncs.push_back(TransferFunc::copyFunc(readLoc, + writtenLoc)); + } else { + // Unknown read address. Assume top. + xferFuncs.push_back(TransferFunc::retopFunc(writtenLoc)); + } } else { assert(false); } From 00ff697c3d7895fbdc9f6274d2abc50d3cf89dd5 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Wed, 7 Dec 2016 15:56:22 -0600 Subject: [PATCH 03/12] Warning cleanup --- symtabAPI/src/Object-elf.C | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/symtabAPI/src/Object-elf.C b/symtabAPI/src/Object-elf.C index 90a6f9de64..f287d55ef6 100644 --- a/symtabAPI/src/Object-elf.C +++ b/symtabAPI/src/Object-elf.C @@ -1105,7 +1105,7 @@ bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp, } else if (plt_entry_size_ == 16) { // New style secure PLT - Region *plt = NULL, *relplt = NULL, *dynamic = NULL, + Region *plt = NULL, *dynamic = NULL, *got = NULL, *glink = NULL; unsigned int glink_addr = 0; unsigned int stub_addr = 0; @@ -4375,13 +4375,11 @@ void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module) /* The 'lines' returned are actually interval markers; the code generated from lineNo runs from lineAddr up to but not including the lineAddr of the next line. */ - bool isPreviousValid = false; Offset baseAddr = getBaseAddress(); Dwarf_Addr cu_high_pc = 0; dwarf_highpc(cuDIE, &cu_high_pc, NULL); - bool needs_followup = false; /* Iterate over this CU's source lines. */ open_statement current_statement; for ( int i = 0; i < lineCount; i++ ) From 1e6160925d108cc69cad70b09a201a5572bcf8a4 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Wed, 16 Nov 2016 13:58:10 -0600 Subject: [PATCH 04/12] Auto-detect RTlib name on Unix-ish based on library paths --- cmake/warnings.cmake | 18 ++++----- dyninstAPI/src/addressSpace.h | 2 +- dyninstAPI/src/binaryEdit.h | 2 +- dyninstAPI/src/dynProcess.h | 1 + dyninstAPI/src/unix.C | 76 ++++++++++++++++++++++------------- symtabAPI/src/Symtab.C | 30 ++++---------- 6 files changed, 68 insertions(+), 61 deletions(-) diff --git a/cmake/warnings.cmake b/cmake/warnings.cmake index 8bf13ac962..51a9892479 100644 --- a/cmake/warnings.cmake +++ b/cmake/warnings.cmake @@ -1,12 +1,12 @@ if (CMAKE_COMPILER_IS_GNUCXX) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wpointer-arith -Wcast-qual") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wpointer-arith -Wcast-qual -Woverloaded-virtual") -if (CMAKE_C_COMPILER_ID MATCHES GNU) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align -Wno-non-template-friend -Wno-unused-local-typedefs -Wno-deprecated-declarations") -endif (CMAKE_C_COMPILER_ID MATCHES GNU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wpointer-arith -Wcast-qual") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wpointer-arith -Wcast-qual -Woverloaded-virtual") + if (CMAKE_C_COMPILER_ID MATCHES GNU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align -Wno-non-template-friend -Wno-unused-local-typedefs -Wno-deprecated-declarations") + endif() elseif (MSVC) -message(STATUS "TODO: Set up custom warning flags for MSVC") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4251 /wd4091 /wd4503") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4091 /wd4503") + message(STATUS "TODO: Set up custom warning flags for MSVC") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4251 /wd4091 /wd4503") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4091 /wd4503") endif() diff --git a/dyninstAPI/src/addressSpace.h b/dyninstAPI/src/addressSpace.h index 233022549e..5c63ce980f 100644 --- a/dyninstAPI/src/addressSpace.h +++ b/dyninstAPI/src/addressSpace.h @@ -186,7 +186,7 @@ class AddressSpace : public InstructionSource { virtual void addTrap(Address from, Address to, codeGen &gen) = 0; virtual void removeTrap(Address from) = 0; - bool getDyninstRTLibName(); + virtual bool getDyninstRTLibName(); // InstructionSource virtual bool isValidAddress(const Address) const; diff --git a/dyninstAPI/src/binaryEdit.h b/dyninstAPI/src/binaryEdit.h index 5340ff3867..fc6d06192c 100644 --- a/dyninstAPI/src/binaryEdit.h +++ b/dyninstAPI/src/binaryEdit.h @@ -191,6 +191,7 @@ class BinaryEdit : public AddressSpace { virtual void addTrap(Address from, Address to, codeGen &gen); virtual void removeTrap(Address /*from*/) {}; + static bool getResolvedLibraryPath(const std::string &filename, std::vector &paths); private: Address highWaterMark_; @@ -200,7 +201,6 @@ class BinaryEdit : public AddressSpace { static bool getStatFileDescriptor(const std::string &file, fileDescriptor &desc); - static bool getResolvedLibraryPath(const std::string &filename, std::vector &paths); bool inferiorMallocStatic(unsigned size); diff --git a/dyninstAPI/src/dynProcess.h b/dyninstAPI/src/dynProcess.h index dbaf3d863b..c6d1433637 100644 --- a/dyninstAPI/src/dynProcess.h +++ b/dyninstAPI/src/dynProcess.h @@ -101,6 +101,7 @@ class PCProcess : public AddressSpace { ~PCProcess(); static std::string createExecPath(const std::string &file, const std::string &dir); + virtual bool getDyninstRTLibName(); bool continueProcess(); bool stopProcess(); diff --git a/dyninstAPI/src/unix.C b/dyninstAPI/src/unix.C index 33e339b56d..4df53f04aa 100644 --- a/dyninstAPI/src/unix.C +++ b/dyninstAPI/src/unix.C @@ -37,7 +37,7 @@ #include "dynProcess.h" #include "dynThread.h" #include "function.h" - +#include "binaryEdit.h" #include "common/src/pathName.h" #include @@ -298,10 +298,36 @@ void PCProcess::redirectFds(int stdin_fd, int stdout_fd, int stderr_fd, if( stderr_fd != 2 ) fds.insert(std::make_pair(stderr_fd, 2)); } +bool PCProcess::getDyninstRTLibName() +{ + startup_printf("Begin getDyninstRTLibName\n"); + bool use_abi_rt = false; +#if defined(arch_64bit) + use_abi_rt = (getAddressWidth() == 4); +#endif + + std::vector rt_paths; + std::string rt_base = "libdyninstAPI_RT"; + if(use_abi_rt) rt_base += "_m32"; + rt_base += ".so"; + if(!BinaryEdit::getResolvedLibraryPath(rt_base, rt_paths) || rt_paths.empty()) + { + startup_printf("%s[%d]: Could not find libdyninstAPI_RT.so in search path\n", FILE__, __LINE__); + return false; + } + for(auto i = rt_paths.begin(); + i != rt_paths.end(); + ++i) + { + startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); + } + dyninstRT_name = rt_paths[0]; + return true; +} + bool PCProcess::setEnvPreload(std::vector &envp, std::string fileName) { const unsigned int ERROR_CODE = 101; bool use_abi_rt = false; - (void)fileName; // unused #if defined(arch_64bit) SymtabAPI::Symtab *symt_obj; @@ -311,32 +337,26 @@ bool PCProcess::setEnvPreload(std::vector &envp, std::string fileNa use_abi_rt = (symt_obj->getAddressWidth() == 4); #endif - const char *rt_lib_name = getenv("DYNINSTAPI_RT_LIB"); - if( rt_lib_name == NULL ) { - showErrorCallback(ERROR_CODE, std::string("setEnvPreload: DYNINSTAPI_RT_LIB is undefined")); - proccontrol_printf("%s[%d]: DYNINSTAPI_RT_LIB is undefined\n"); - return false; + std::vector rt_paths; + std::string rt_base = "libdyninstAPI_RT"; + if(use_abi_rt) rt_base += "_m32"; + rt_base += ".so"; + if(!BinaryEdit::getResolvedLibraryPath(rt_base, rt_paths) || rt_paths.empty()) + { + startup_printf("%s[%d]: Could not find libdyninstAPI_RT.so in search path\n", FILE__, __LINE__); + return false; } - - std::string full_name; - if (use_abi_rt) { - const char *slash = P_strrchr(rt_lib_name, '/'); - if (!slash) - slash = P_strrchr(rt_lib_name, '\\'); - if (!slash) - return false; - const char *dot = P_strchr(slash, '.'); - if (!dot) - return false; - full_name = std::string(rt_lib_name, dot - rt_lib_name) + - std::string("_m32") + - std::string(dot); - rt_lib_name = full_name.c_str(); + for(auto i = rt_paths.begin(); + i != rt_paths.end(); + ++i) + { + startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); } + std::string rt_lib_name = rt_paths[0]; // Check to see if the library given exists. - if (access(rt_lib_name, R_OK)) { - std::string msg = std::string("Runtime library ") + std::string(rt_lib_name) + + if (access(rt_lib_name.c_str(), R_OK)) { + std::string msg = std::string("Runtime library ") + rt_lib_name + std::string(" does not exist or cannot be accessed!"); cerr << msg << endl; showErrorCallback(ERROR_CODE, msg); @@ -359,13 +379,13 @@ bool PCProcess::setEnvPreload(std::vector &envp, std::string fileNa if (ldPreloadVal == envp.end()) { // Not found, append an entry std::string ld_preload = std::string(var_name) + std::string("=") + - std::string(rt_lib_name); + rt_lib_name; startup_printf("LD_PRELOAD=%s\n", ld_preload.c_str()); envp.push_back(ld_preload); } else { // Found, modify envs in-place std::string ld_preload = *ldPreloadVal + std::string(":") + - std::string(rt_lib_name); + rt_lib_name; startup_printf("LD_PRELOAD=%s\n", ld_preload.c_str()); *ldPreloadVal = ld_preload; } @@ -389,11 +409,11 @@ bool PCProcess::setEnvPreload(std::vector &envp, std::string fileNa // Append to existing var ld_preload = std::string(var_name) + std::string("=") + std::string(ld_preload_orig) + std::string(":") + - std::string(rt_lib_name); + rt_lib_name; } else { // Define a new var ld_preload = std::string(var_name) + std::string("=") + - std::string(rt_lib_name); + rt_lib_name; } envp.push_back(ld_preload); } diff --git a/symtabAPI/src/Symtab.C b/symtabAPI/src/Symtab.C index a87483bd5b..989bbbf4ec 100644 --- a/symtabAPI/src/Symtab.C +++ b/symtabAPI/src/Symtab.C @@ -1269,6 +1269,9 @@ Symtab::Symtab(std::string filename, bool defensive_bin, bool &err) : obj_private = new Object(mf, defensive_bin, symtab_log_perror, true, this); if (obj_private->hasError()) { + create_printf("%s[%d]: WARNING: creating symtab for %s, " + "Object ctor failed\n", FILE__, __LINE__, + filename.c_str()); err = true; return; } @@ -2115,31 +2118,14 @@ bool Symtab::openFile(Symtab *&obj, std::string filename, def_t def_binary) { if (filename.find("/proc") == std::string::npos) allSymtabs.push_back(obj); - - -#if defined (cap_serialization) -#if 0 - serialize_printf("%s[%d]: doing bin-serialize for %s\n", - FILE__, __LINE__, filename.c_str()); - - if (!obj->exportBin(filename)) - { - serialize_printf("%s[%d]: failed to export symtab\n", FILE__, __LINE__); - } - else - serialize_printf("%s[%d]: did bin-serialize for %s\n", - FILE__, __LINE__, filename.c_str()); -#endif -#endif - - } - else - { + } + else + { create_printf("%s[%d]: WARNING: failed to open symtab for %s\n", - FILE__, __LINE__, filename.c_str()); + FILE__, __LINE__, filename.c_str()); delete obj; obj = NULL; - } + } // returns true on success (not an error) return !err; From aa159537bfd6a1c5ae3807dd73d173ebd98732e2 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Thu, 8 Dec 2016 15:34:45 -0600 Subject: [PATCH 05/12] Fix statically linked rewriting crash? --- dyninstAPI/src/linux.C | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dyninstAPI/src/linux.C b/dyninstAPI/src/linux.C index 251bffa888..8101ac6957 100644 --- a/dyninstAPI/src/linux.C +++ b/dyninstAPI/src/linux.C @@ -219,12 +219,14 @@ bool BinaryEdit::getResolvedLibraryPath(const string &filename, std::vector ldconfig(popen("/sbin/ldconfig -p", "r"), pclose); + // apparently ubuntu doesn't like pclosing NULL, so a shared pointer custom + // destructor is out. Ugh. + FILE* ldconfig = popen("/sbin/ldconfig -p", "r"); if (ldconfig) { - if(!fgets(buffer, 512, ldconfig.get())) { // ignore first line + if(!fgets(buffer, 512, ldconfig)) { // ignore first line return false; } - while (fgets(buffer, 512, ldconfig.get()) != NULL) { + while (fgets(buffer, 512, ldconfig) != NULL) { pos = buffer; while (*pos == ' ' || *pos == '\t') pos++; key = pos; @@ -240,6 +242,7 @@ bool BinaryEdit::getResolvedLibraryPath(const string &filename, std::vector Date: Thu, 8 Dec 2016 15:34:54 -0600 Subject: [PATCH 06/12] Warning cleanup --- symtabAPI/src/Object-elf.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symtabAPI/src/Object-elf.C b/symtabAPI/src/Object-elf.C index f287d55ef6..d49e793a8b 100644 --- a/symtabAPI/src/Object-elf.C +++ b/symtabAPI/src/Object-elf.C @@ -1105,7 +1105,7 @@ bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp, } else if (plt_entry_size_ == 16) { // New style secure PLT - Region *plt = NULL, *dynamic = NULL, + Region *plt = NULL, *relplt = NULL, *dynamic = NULL, *got = NULL, *glink = NULL; unsigned int glink_addr = 0; unsigned int stub_addr = 0; From df6b4ff956e07d5c23c4188a8c1c82f0f5b5ad18 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Thu, 8 Dec 2016 16:10:01 -0600 Subject: [PATCH 07/12] Add windows-ish implementation for process-level getRTLibName. --- dyninstAPI/src/pdwinnt.C | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/dyninstAPI/src/pdwinnt.C b/dyninstAPI/src/pdwinnt.C index 9de53ca015..8351ee08db 100644 --- a/dyninstAPI/src/pdwinnt.C +++ b/dyninstAPI/src/pdwinnt.C @@ -34,6 +34,7 @@ #include "common/src/headers.h" #include "dyninstAPI/src/os.h" #include "dyninstAPI/src/addressSpace.h" +#include "binaryEdit.h" #include "common/src/stats.h" #include "common/src/Types.h" #include "dyninstAPI/src/debug.h" @@ -1057,3 +1058,30 @@ void OS::get_sigaction_names(std::vector &names) { //names.push_back("signal"); } + +bool PCProcess::getDyninstRTLibName() +{ + startup_printf("Begin getDyninstRTLibName\n"); + bool use_abi_rt = false; +#if defined(arch_64bit) + use_abi_rt = (getAddressWidth() == 4); +#endif + + std::vector rt_paths; + std::string rt_base = "dyninstAPI_RT"; + if(use_abi_rt) rt_base += "_m32"; + rt_base += ".dll"; + if(!BinaryEdit::getResolvedLibraryPath(rt_base, rt_paths) || rt_paths.empty()) + { + startup_printf("%s[%d]: Could not find %s in search path\n", FILE__, __LINE__. rt_base.c_str()); + return false; + } + for(auto i = rt_paths.begin(); + i != rt_paths.end(); + ++i) + { + startup_printf("%s[%d]: Candidate RTLib is %s\n", FILE__, __LINE__, i->c_str()); + } + dyninstRT_name = rt_paths[0]; + return true; +} From 731a0099ede1540d96f10e3654c48a3fb5a04ad4 Mon Sep 17 00:00:00 2001 From: mneumann Date: Tue, 13 Dec 2016 14:16:38 +0100 Subject: [PATCH 08/12] Fix omitting leading 0's when concatenating hex bytes in stringstream --- elf/src/Elf_X.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elf/src/Elf_X.C b/elf/src/Elf_X.C index 03eb6d99c0..9a3671c0a9 100644 --- a/elf/src/Elf_X.C +++ b/elf/src/Elf_X.C @@ -1692,7 +1692,7 @@ bool Elf_X::findDebugFile(std::string origfilename, string &output_name, char* & buildid_path << "/usr/lib/debug/.build-id/" << hex << setfill('0') << setw(2) << (unsigned)desc[0] << '/'; for (unsigned long j = 1; j < note.n_descsz(); ++j) - buildid_path << (unsigned)desc[j]; + buildid_path << setw(2) << (unsigned)desc[j]; buildid_path << ".debug"; debugFileFromBuildID = buildid_path.str(); break; From 7c4a32a2c278eb248e7998eed2d4fbc56bf52571 Mon Sep 17 00:00:00 2001 From: John Detter Date: Wed, 14 Dec 2016 12:28:58 -0600 Subject: [PATCH 09/12] Build fixes for Windows --- dyninstAPI/src/pdwinnt.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dyninstAPI/src/pdwinnt.C b/dyninstAPI/src/pdwinnt.C index 8351ee08db..2a92360c9c 100644 --- a/dyninstAPI/src/pdwinnt.C +++ b/dyninstAPI/src/pdwinnt.C @@ -1073,7 +1073,7 @@ bool PCProcess::getDyninstRTLibName() rt_base += ".dll"; if(!BinaryEdit::getResolvedLibraryPath(rt_base, rt_paths) || rt_paths.empty()) { - startup_printf("%s[%d]: Could not find %s in search path\n", FILE__, __LINE__. rt_base.c_str()); + startup_printf("%s[%d]: Could not find %s in search path\n", FILE__, __LINE__, rt_base.c_str()); return false; } for(auto i = rt_paths.begin(); From ea3c0c6d4360eedccf8b59414f9dd0c96b565383 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Mon, 19 Dec 2016 10:35:44 -0600 Subject: [PATCH 10/12] Fixes to reduce quantity of stack analysis required (we were performing it by default when performing any absloc/absregion analysis) and to ensure stack analysis performed during relocation gets cleaned up afterward. --- dataflowAPI/h/AbslocInterface.h | 4 ++-- dataflowAPI/h/stackanalysis.h | 4 +++- dataflowAPI/src/AbslocInterface.C | 4 ++++ dataflowAPI/src/stackanalysis.C | 23 +++++++++++++++++++ dyninstAPI/src/Relocation/CFG/RelocGraph.C | 9 +++++++- .../Transformers/Movement-analysis.C | 2 +- .../Transformers/Movement-analysis.h | 2 +- dyninstAPI/src/hybridOverwrites.C | 2 +- dyninstAPI/src/image.C | 2 -- parseAPI/src/Function.C | 2 +- 10 files changed, 44 insertions(+), 10 deletions(-) diff --git a/dataflowAPI/h/AbslocInterface.h b/dataflowAPI/h/AbslocInterface.h index 5aca3adb55..9bf93b9c5d 100644 --- a/dataflowAPI/h/AbslocInterface.h +++ b/dataflowAPI/h/AbslocInterface.h @@ -51,7 +51,7 @@ namespace Dyninst { class AbsRegionConverter { public: - DATAFLOW_EXPORT AbsRegionConverter(bool cache, bool stack = true) : + DATAFLOW_EXPORT AbsRegionConverter(bool cache, bool stack) : cacheEnabled_(cache), stackAnalysisEnabled_(stack) {}; // Definition: the first AbsRegion represents the expression. @@ -122,7 +122,7 @@ class AbsRegionConverter { class AssignmentConverter { public: - DATAFLOW_EXPORT AssignmentConverter(bool cache, bool stack = true) : cacheEnabled_(cache), aConverter(false, stack) {}; + DATAFLOW_EXPORT AssignmentConverter(bool cache, bool stack) : cacheEnabled_(cache), aConverter(false, stack) {}; DATAFLOW_EXPORT void convert(InstructionAPI::Instruction::Ptr insn, const Address &addr, diff --git a/dataflowAPI/h/stackanalysis.h b/dataflowAPI/h/stackanalysis.h index 0f2f19cded..1c58066be0 100644 --- a/dataflowAPI/h/stackanalysis.h +++ b/dataflowAPI/h/stackanalysis.h @@ -348,7 +348,9 @@ class StackAnalysis { const std::map &fs, const std::set
&toppable = std::set
()); - DATAFLOW_EXPORT Height find(ParseAPI::Block *, Address addr, Absloc loc); + DATAFLOW_EXPORT virtual ~StackAnalysis(); + + DATAFLOW_EXPORT Height find(ParseAPI::Block *, Address addr, Absloc loc); DATAFLOW_EXPORT Height findSP(ParseAPI::Block *, Address addr); DATAFLOW_EXPORT Height findFP(ParseAPI::Block *, Address addr); DATAFLOW_EXPORT void findDefinedHeights(ParseAPI::Block* b, Address addr, diff --git a/dataflowAPI/src/AbslocInterface.C b/dataflowAPI/src/AbslocInterface.C index 19827b4863..0dd41c439a 100644 --- a/dataflowAPI/src/AbslocInterface.C +++ b/dataflowAPI/src/AbslocInterface.C @@ -301,6 +301,10 @@ AbsRegion AbsRegionConverter::stack(Address addr, ParseAPI::Function *func, ParseAPI::Block *block, bool push) { + if(!stackAnalysisEnabled_) { +// std::cerr << "Stack analysis disabled, returning Stack absregion" << std::endl; + return AbsRegion(Absloc::Stack); + } long spHeight = 0; bool stackExists = getCurrentStackHeight(func, block, diff --git a/dataflowAPI/src/stackanalysis.C b/dataflowAPI/src/stackanalysis.C index a0c7cd3290..5c98227e14 100644 --- a/dataflowAPI/src/stackanalysis.C +++ b/dataflowAPI/src/stackanalysis.C @@ -3529,3 +3529,26 @@ void StackAnalysis::bottomBaseSubReg(const MachRegister ®, } } } + +StackAnalysis::~StackAnalysis() { + // delete func; + + callResolutionMap.clear(); + functionSummaries.clear(); + toppableFunctions.clear(); + + // SP effect tracking +// delete blockEffects; // Pointer so we can make it an annotation +// delete insnEffects; // Pointer so we can make it an annotation +// delete callEffects; // Pointer so we can make it an annotation + + blockInputs.clear(); + blockOutputs.clear(); + + blockSummaryInputs.clear(); + blockSummaryOutputs.clear(); + +// delete intervals_; // Pointer so we can make it an annotation + + funcCleanAmounts.clear(); +} diff --git a/dyninstAPI/src/Relocation/CFG/RelocGraph.C b/dyninstAPI/src/Relocation/CFG/RelocGraph.C index 983705faed..a7bc6b151d 100644 --- a/dyninstAPI/src/Relocation/CFG/RelocGraph.C +++ b/dyninstAPI/src/Relocation/CFG/RelocGraph.C @@ -40,13 +40,20 @@ RelocGraph::~RelocGraph() { for (Edges::iterator iter = edges.begin(); iter != edges.end(); ++iter) { delete *iter; } - + std::set funcs_to_clean; RelocBlock *cur = head; while (cur) { RelocBlock *next = cur->next(); + funcs_to_clean.insert(cur->func()); delete cur; cur = next; } + for(auto f = funcs_to_clean.begin(); + f != funcs_to_clean.end(); + ++f) + { + if(*f) (*f)->freeStackMod(); + } } void RelocGraph::addRelocBlock(RelocBlock *t) { diff --git a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C index b97f20d94f..4b0c65819e 100644 --- a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C +++ b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C @@ -376,7 +376,7 @@ Graph::Ptr PCSensitiveTransformer::forwardSlice(Assignment::Ptr ptr, parse_block *block, parse_func *func) { M_A_Predicates pred; - Slicer slicer(ptr, block, func); + Slicer slicer(ptr, block, func, false, false); Graph::Ptr g = slicer.forwardSlice(pred); return g; diff --git a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.h b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.h index cb7ec35140..8ecb06fa2b 100644 --- a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.h +++ b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.h @@ -97,7 +97,7 @@ class PCSensitiveTransformer : public Transformer { virtual bool process(RelocBlock *, RelocGraph *); PCSensitiveTransformer(AddressSpace *as, PriorityMap &p) - : aConverter(false), addrSpace(as), priMap(p), + : aConverter(false, false), addrSpace(as), priMap(p), Sens_(0), extSens_(0), intSens_(0), thunk_(0), overApprox_(0), adhoc(as) {}; virtual ~PCSensitiveTransformer() {}; diff --git a/dyninstAPI/src/hybridOverwrites.C b/dyninstAPI/src/hybridOverwrites.C index 8a18ffe15e..e609e70d69 100644 --- a/dyninstAPI/src/hybridOverwrites.C +++ b/dyninstAPI/src/hybridOverwrites.C @@ -1343,7 +1343,7 @@ bool HybridAnalysisOW::isRealStore(Address insnAddr, block_instance *block, Address image_addr = func->lowlevel_func()->addrToOffset(insnAddr); std::vector assignments; - AssignmentConverter aConverter(false); + AssignmentConverter aConverter(false, false); aConverter.convert(insn, image_addr, imgfunc, block->llb(), assignments); for (std::vector::const_iterator a_iter = assignments.begin(); diff --git a/dyninstAPI/src/image.C b/dyninstAPI/src/image.C index d035401bc4..68c7d473c0 100644 --- a/dyninstAPI/src/image.C +++ b/dyninstAPI/src/image.C @@ -621,7 +621,6 @@ int image::findMain() // p += (eAddr - eStart); // } - bool mode_64 = false; switch(linkedFile->getAddressWidth()) { case 4: // 32-bit... @@ -630,7 +629,6 @@ int image::findMain() ia32_set_mode_64(false); break; case 8: - mode_64 = true; startup_printf("%s[%u]: setting 64-bit mode\n", FILE__,__LINE__); ia32_set_mode_64(true); diff --git a/parseAPI/src/Function.C b/parseAPI/src/Function.C index 7394c4c097..8db08a1eb3 100644 --- a/parseAPI/src/Function.C +++ b/parseAPI/src/Function.C @@ -560,7 +560,7 @@ Function::tampersStack(bool recalculate) return _tamper; } assert(_cache_valid); - AssignmentConverter converter(true); + AssignmentConverter converter(true, true); vector assgns; ST_Predicates preds; _tamper = TAMPER_UNSET; From 9b6f0b4aa0567d979b05d6b53f991626d8317919 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Mon, 19 Dec 2016 10:59:29 -0600 Subject: [PATCH 11/12] Fix Windows build --- dyninstAPI/src/MemoryEmulator/memEmulatorTransformer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dyninstAPI/src/MemoryEmulator/memEmulatorTransformer.h b/dyninstAPI/src/MemoryEmulator/memEmulatorTransformer.h index 63bbe8067f..1e65f8ee94 100644 --- a/dyninstAPI/src/MemoryEmulator/memEmulatorTransformer.h +++ b/dyninstAPI/src/MemoryEmulator/memEmulatorTransformer.h @@ -56,7 +56,7 @@ class MemEmulatorTransformer : public Transformer { virtual bool process(RelocBlock *, RelocGraph *); MemEmulatorTransformer() : - aConverter(false) {}; + aConverter(false, false) {}; virtual ~MemEmulatorTransformer() {}; From 769ec4878f5590eace3d38acd6d5b3ece5815683 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Mon, 19 Dec 2016 15:08:30 -0600 Subject: [PATCH 12/12] Treat calls as non-sensitive in normal mode. --- dyninstAPI/src/Relocation/Transformers/Movement-analysis.C | 1 + 1 file changed, 1 insertion(+) diff --git a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C index 4b0c65819e..88d7c893cd 100644 --- a/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C +++ b/dyninstAPI/src/Relocation/Transformers/Movement-analysis.C @@ -279,6 +279,7 @@ bool PCSensitiveTransformer::isPCSensitive(Instruction::Ptr insn, const block_instance *block, AssignList &sensitiveAssignments) { if (!(insn->getOperation().getID() == e_call)) return false; + if(func->obj()->hybridMode() == BPatch_normalMode) return false; // FIXME for loopnz instruction Absloc pc = Absloc::makePC(func->ifunc()->isrc()->getArch());