00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "common/h/headers.h"
00032 #include "common/src/addrtranslate-sysv.h"
00033 #include "common/h/freebsdKludges.h"
00034
00035 #include <cstdio>
00036
00037 #include <sys/types.h>
00038 #include <sys/ptrace.h>
00039 #include <sys/wait.h>
00040 #include <errno.h>
00041 #include <unistd.h>
00042
00043 using namespace Dyninst;
00044
00045 class ProcessReaderPtrace : public ProcessReader {
00046 protected:
00047 int pid;
00048 public:
00049 ProcessReaderPtrace(int pid_);
00050 virtual bool start();
00051 virtual bool ReadMem(Address inTraced, void *inSelf, unsigned amount);
00052 virtual bool GetReg(MachRegister , MachRegisterVal &) {
00053 assert(0);
00054 return false;
00055 }
00056 virtual bool done();
00057
00058 virtual ~ProcessReaderPtrace();
00059 };
00060
00061 bool ProcessReaderPtrace::start() {
00062 if( 0 != ptrace(PT_ATTACH, pid, (caddr_t)1, 0) ) {
00063 translate_printf("[%s:%u] - Failed to attach to process %u: %s\n",
00064 __FILE__, __LINE__, pid, strerror(errno));
00065 return false;
00066 }
00067
00068 int status;
00069 while(true) {
00070 int result = (long) waitpid(pid, &status, 0);
00071 if (result == -1 && errno == EINTR) {
00072 continue;
00073 } else if (result == -1 || WIFEXITED(status) || WIFSIGNALED(status)) {
00074 translate_printf("[%s:%u] - Failed to stop process %u: %s\n",
00075 __FILE__, __LINE__, pid, strerror(errno));
00076 done();
00077 return false;
00078 } else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGSTOP
00079 || WSTOPSIG(status) == SIGTRAP) ) {
00080 break;
00081 } else if (WIFSTOPPED(status) && WSTOPSIG(status) != SIGSTOP) {
00082 if( 0 != ptrace(PT_CONTINUE, pid, (caddr_t)1, WSTOPSIG(status)) ) {
00083 translate_printf("[%s:%u] - Failed to continue process %u: %s\n"
00084 __FILE__, __LINE__, pid, strerror(errno));
00085 done();
00086 return false;
00087 }
00088 } else {
00089 translate_printf("[%s:%u] - Unknown error encountered for process %u: %s\n",
00090 __FILE__, __LINE__, pid, strerror(errno));
00091 done();
00092 return false;
00093 }
00094 }
00095
00096 return true;
00097 }
00098
00099 bool ProcessReaderPtrace::done()
00100 {
00101 return ( 0 != ptrace(PT_DETACH, pid, (caddr_t)1, 0) ) ? true : false;
00102 }
00103
00104 ProcessReaderPtrace::ProcessReaderPtrace(int pid_) :
00105 pid(pid_)
00106 {
00107 }
00108
00109 ProcessReaderPtrace::~ProcessReaderPtrace()
00110 {
00111 }
00112
00113 bool ProcessReaderPtrace::ReadMem(Address inTraced, void *inSelf, unsigned amount) {
00114 bool result = PtraceBulkRead(inTraced, amount, inSelf, pid);
00115 if( !result ) {
00116 translate_printf("[%s:%u] - Failed to read memory from process: %s\n",
00117 __FILE__, __LINE__, strerror(errno));
00118 }
00119
00120 return result;
00121 }
00122
00123
00124
00125 ProcessReader *AddressTranslateSysV::createDefaultDebugger(int pid)
00126 {
00127 return new ProcessReaderPtrace(pid);
00128 }
00129
00130
00131 bool AddressTranslateSysV::setInterpreter() {
00132 if( interpreter ) return true;
00133
00134 string l_exec = getExecName();
00135 if( l_exec.empty() ) {
00136 return false;
00137 }
00138
00139 FCNode *exe = files.getNode(l_exec, symfactory);
00140 if( !exe ) {
00141 translate_printf("[%s:%u] - Failed to get FCNode for %s\n",
00142 __FILE__, __LINE__, l_exec.c_str());
00143 return false;
00144 }
00145
00146 if( exe->getInterpreter().empty() ) {
00147 translate_printf("[%s:%u] - No interpreter found\n",
00148 __FILE__, __LINE__);
00149 return true;
00150 }
00151
00152 interpreter = files.getNode(exe->getInterpreter(), symfactory);
00153 if( interpreter ) interpreter->markInterpreter();
00154 else{
00155 translate_printf("[%s:%u] - Failed to set interpreter for %s\n",
00156 __FILE__, __LINE__, l_exec.c_str());
00157 return false;
00158 }
00159
00160 return true;
00161 }
00162
00163 bool AddressTranslateSysV::setAddressSize() {
00164 if (address_size) return true;
00165
00166 if( (address_size = sysctl_computeAddrWidth(pid)) == -1 ) {
00167 address_size = 0;
00168 return false;
00169 }
00170
00171 return true;
00172 }
00173
00174 bool AddressTranslateSysV::setInterpreterBase() {
00175 if( set_interp_base ) return true;
00176
00177 string l_exec = getExecName();
00178 if( l_exec.empty() ) {
00179 return false;
00180 }
00181
00182 FCNode *exe = files.getNode(l_exec, symfactory);
00183 if( !exe ) {
00184 translate_printf("[%s:%u] - Failed to get FCNode for %s\n",
00185 __FILE__, __LINE__, l_exec.c_str());
00186 return false;
00187 }
00188
00189 unsigned maps_size;
00190 map_entries *maps = getVMMaps(pid, maps_size);
00191 if( !maps ) {
00192 translate_printf("[%s:%u] - Failed to get VM maps\n",
00193 __FILE__, __LINE__);
00194 return false;
00195 }
00196
00197 string interp_name = exe->getInterpreter();
00198 for(unsigned i = 0; i < maps_size; ++i) {
00199 if( string(maps[i].path) == interp_name ) {
00200 interpreter_base = maps[i].start;
00201 set_interp_base = true;
00202 break;
00203 }
00204 }
00205 free(maps);
00206
00207 if( !set_interp_base ) {
00208 translate_printf("[%s:%u] - Failed to locate interpreter in memory map\n",
00209 __FILE__, __LINE__);
00210 return false;
00211 }
00212
00213 return true;
00214 }
00215
00216 string AddressTranslateSysV::getExecName() {
00217 if( exec_name.empty() ) {
00218 char *pathname = sysctl_getExecPathname(pid);
00219 if( NULL != pathname ) {
00220 exec_name = std::string(pathname);
00221
00222 free(pathname);
00223 }
00224 }
00225 return exec_name;
00226 }
00227
00228 LoadedLib *AddressTranslateSysV::getAOut()
00229 {
00230
00231 LoadedLib *ll = new LoadedLib(getExecName(), 0);
00232 ll->setFactory(symfactory);
00233 return ll;
00234 }