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/Types.h"
00032 #include "common/h/wtxKludges.h"
00033 #include "common/h/pathName.h"
00034 #include "symtabAPI/h/Symtab.h"
00035 #include <elf.h>
00036
00037 HWTX wtxh = NULL;
00038 wtx_state_t wtx_state = WTX_UNKNOWN;
00039 std::vector<WTX_MODULE_INFO *> wtxDynLoadedMods;
00040 dyn_hash_map<std::string, WTX_MODULE_INFO *> wtxMods;
00041 dyn_hash_map<Address, Dyninst::SymtabAPI::relocationEntry> wtxReloc;
00042
00043 bool wtxDisconnect(void)
00044 {
00045 if (wtx_state < WTX_CONNECTED) {
00046 fprintf(stderr, "Error: Attempt to disconnect while not connected.\n");
00047 return false;
00048 }
00049
00050 STATUS result = wtxToolDetach(wtxh);
00051 if (result == WTX_OK) {
00052 wtx_state = WTX_INITIALIZED;
00053 } else {
00054 fprintf(stderr, "Error on wtxToolDetach(): %s\n", wtxErrMsgGet(wtxh));
00055 fprintf(stderr, "Forcing disconnection by terminating WTX handle.\n");
00056 }
00057
00058 result = wtxTerminate(wtxh);
00059 if (result != WTX_OK) {
00060 fprintf(stderr, "Error on wtxTerminate(): %s\n", wtxErrMsgGet(wtxh));
00061 return false;
00062 }
00063
00064 wtx_state = WTX_UNKNOWN;
00065 return true;
00066 }
00067
00068 void setAgentMode(WTX_AGENT_MODE_TYPE )
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078 }
00079
00080 bool wtxReadMem(const void *inTarget, u_int nbytes, void *inSelf)
00081 {
00082 if (wtx_state < WTX_CONNECTED) {
00083 fprintf(stderr, "Attempting to read target memory while disconnected.\n");
00084 return false;
00085 }
00086
00087 UINT32 result = wtxMemRead(wtxh,
00088 0x0,
00089 (WTX_TGT_ADDR_T)inTarget,
00090 inSelf,
00091 nbytes,
00092 WTX_MEM_CACHE_BYPASS);
00093 if (result == static_cast<UINT32>( WTX_ERROR ))
00094 fprintf(stderr, "wtxMemRead() error: %s\n", wtxErrMsgGet(wtxh));
00095 return (result != static_cast<UINT32>( WTX_ERROR ));
00096 }
00097
00098 bool wtxWriteMem(void *inTarget, u_int nbytes, const void *inSelf)
00099 {
00100 if (wtx_state < WTX_CONNECTED) {
00101 fprintf(stderr, "Attempting to write target memory while disconnected.\n");
00102 return false;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 UINT32 result = wtxMemWrite(wtxh,
00112 0x0,
00113 const_cast<void *>(inSelf),
00114 (WTX_TGT_ADDR_T)inTarget,
00115 nbytes,
00116 WTX_MEM_CACHE_BYPASS);
00117 if (result == static_cast<UINT32>( WTX_ERROR )) {
00118 fprintf(stderr, "wtxMemWrite() error: %s\n", wtxErrMsgGet(wtxh));
00119 return false;
00120 }
00121
00122 result = wtxCacheTextUpdate(wtxh, (WTX_TGT_ADDR_T)inTarget, nbytes);
00123 if (result == static_cast<UINT32>( WTX_ERROR )) {
00124 fprintf(stderr, "wtxCacheTextUpdate() error: %s\n",
00125 wtxErrMsgGet(wtxh));
00126 return false;
00127 }
00128
00129 return true;
00130 }
00131
00132 bool wtxFindSymbol(const char *name, WTX_SYMBOL_TYPE type, WTX_TGT_ID_T modId,
00133 Address &addr)
00134 {
00135 WTX_SYM_FIND_CRITERIA crit;
00136
00137 if (wtx_state < WTX_CONNECTED) {
00138
00139
00140
00141
00142 return false;
00143 }
00144
00145 memset(&crit, 0, sizeof(WTX_SYM_FIND_CRITERIA));
00146 crit.options = WTX_SYM_FIND_BY_EXACT_NAME;
00147 crit.pdId = 0x0;
00148 crit.findName = const_cast<char *>(name);
00149
00150 if (type) {
00151 crit.options = crit.options | WTX_SYM_FILTER_ON_TYPE;
00152 crit.type = type;
00153 }
00154
00155 if (modId) {
00156 crit.options = crit.options | WTX_SYM_FILTER_ON_MODULE_NAME;
00157 crit.moduleId = modId;
00158 }
00159
00160 WTX_SYMBOL *sym = wtxSymFind(wtxh, &crit);
00161 if (sym) {
00162 addr = sym->value;
00163 wtxResultFree(wtxh, sym);
00164 return true;
00165 }
00166 return false;
00167 }
00168
00169 bool wtxFindFunction(const char *name, WTX_TGT_ID_T modId, Address &addr)
00170 {
00171 return wtxFindSymbol(name, WTX_SYMBOL_TEXT, modId, addr);
00172 }
00173
00174 bool wtxFindVariable(const char *name, WTX_TGT_ID_T modId, Address &addr)
00175 {
00176 return (wtxFindSymbol(name, WTX_SYMBOL_DATA, modId, addr) ||
00177 wtxFindSymbol(name, WTX_SYMBOL_BSS, modId, addr) ||
00178 wtxFindSymbol(name, WTX_SYMBOL_COMM, modId, addr));
00179 }
00180
00181 bool wtxSuspendTask(WTX_TGT_ID_T ctxID)
00182 {
00183 WTX_CONTEXT ctx;
00184 ctx.contextType = WTX_CONTEXT_TASK;
00185 ctx.contextId = ctxID;
00186 ctx.contextSubId = 0;
00187
00188 STATUS result = wtxContextSuspend(wtxh, &ctx);
00189 if (result != WTX_OK) {
00190 fprintf(stderr, "Error on wtxContextSuspend(): %s\n", wtxErrMsgGet(wtxh));
00191 return false;
00192 }
00193 return true;
00194 }
00195
00196 #if defined(arch_power)
00197 bool relocationTarget(const Address addr, Address *target)
00198 {
00199 if (wtxReloc.count(addr) && target) {
00200
00201 WTX_SYMBOL_TYPE any = (WTX_SYMBOL_TYPE)0x0;
00202 if (wtxFindSymbol(wtxReloc[addr].name().c_str(), any, 0x0, *target)) {
00203
00204 switch (wtxReloc[addr].getRelType()) {
00205 case R_PPC_ADDR16_HA:
00206 *target = (*target >> 16) + ((*target & 0x8000) ? 1 : 0);
00207 break;
00208 case R_PPC_ADDR16_LO:
00209 *target = *target & 0xFFFF;
00210 break;
00211 default:
00212 break;
00213 }
00214 return true;
00215 }
00216 }
00217 return false;
00218 }
00219
00220 #elif defined(arch_x86)
00221 bool relocationTarget(const Address addr, Address *target)
00222 {
00223 if (wtxReloc.count(addr) && target) {
00224 wtxFindSymbol(wtxReloc[addr].name().c_str(),
00225 (WTX_SYMBOL_TYPE)0x0,
00226 0x0,
00227 *target);
00228 return true;
00229 }
00230 return false;
00231 }
00232 #endif
00233
00234 WTX_MODULE_INFO *wtxLoadObject(const std::string &objname)
00235 {
00236
00237 std::string shortname = objname;
00238
00239
00240 if (wtxMods.count(shortname)) return wtxMods[shortname];
00241
00242 WTX_MODULE_FILE_DESC desc;
00243 memset(&desc, 0, sizeof(WTX_MODULE_FILE_DESC));
00244 desc.filename = const_cast<char *>(objname.c_str());
00245 desc.loadFlag = WTX_LOAD_ALL_SYMBOLS;
00246
00247 WTX_MODULE_INFO *info;
00248 info = wtxObjModuleLoad(wtxh, 0, &desc, WTX_LOAD_FROM_TOOL);
00249 if (info == NULL) {
00250 fprintf(stderr, "Error on wtxObjModuleLoad(): %s\n", wtxErrMsgGet(wtxh));
00251 wtxDisconnect();
00252 return NULL;
00253 }
00254 wtxDynLoadedMods.push_back(info);
00255 wtxMods[shortname] = info;
00256
00257 return info;
00258 }
00259
00260 void printEventpoints(void)
00261 {
00262 WTX_EVTPT_LIST *pts = wtxEventpointListGet(wtxh);
00263 if (!pts) {
00264 fprintf(stderr, "Error on wtxEventpointListGet(): %s\n", wtxErrMsgGet(wtxh));
00265 return;
00266 }
00267
00268 fprintf(stderr, "------------------------------------\n");
00269 fprintf(stderr, "%d eventpoints.\n\n", pts->nEvtpt);
00270 for (unsigned int i = 0; i < pts->nEvtpt; ++i) {
00271 fprintf(stderr, "[%d] evtpt:{ event:{ type:%d narg:%d } ctxid:0x%lx action:{ type:0x%x arg:%d } tool:0x%lx ptnum:%d\n", i,
00272 pts->pEvtptInfo[i].wtxEvtpt.event.eventType,
00273 pts->pEvtptInfo[i].wtxEvtpt.event.numArgs,
00274 pts->pEvtptInfo[i].wtxEvtpt.context.contextId,
00275 pts->pEvtptInfo[i].wtxEvtpt.action.actionType,
00276 pts->pEvtptInfo[i].wtxEvtpt.action.actionArg,
00277 pts->pEvtptInfo[i].toolId,
00278 pts->pEvtptInfo[i].evtptNum);
00279 }
00280 fprintf(stderr, "------------------------------------\n");
00281 }
00282
00283 void printModuleInfo(WTX_MODULE_INFO *info)
00284 {
00285 unsigned i;
00286 fprintf(stderr, "protection domain ID: 0x%x\n", (unsigned int)info->pdId);
00287 fprintf(stderr, "module ID: 0x%x\n", (unsigned int)info->moduleId);
00288 fprintf(stderr, "module name: %s\n", info->moduleName);
00289 fprintf(stderr, "object file format: 0x%x\n", (unsigned int)info->format);
00290 fprintf(stderr, "load flags: 0x%x\n", (unsigned int)info->loadFlag);
00291 fprintf(stderr, "component init/term routine: 0x%x\n", (unsigned int)info->vxCompRtn);
00292 fprintf(stderr, "user-supplied init routine: 0x%x\n", (unsigned int)info->userInitRtn);
00293 fprintf(stderr, "memory used by common symbols: 0x%x\n", (unsigned int)info->commTotalSize);
00294 fprintf(stderr, "Number of sections: %d\n", (int)info->nSections);
00295 for (i = 0; i < info->nSections; ++i) {
00296 fprintf(stderr, "\tSection: 0x%x Name: %s Type: 0x%x Flags: 0x%x BaseAddr: 0x%x Partition: 0x%x Len: 0x%x Sum: 0x%x\n",
00297 (unsigned int)info->section[i].id,
00298 info->section[i].name,
00299 (unsigned int)info->section[i].type,
00300 (unsigned int)info->section[i].flags,
00301 (unsigned int)info->section[i].baseAddr,
00302 (unsigned int)info->section[i].partId,
00303 (unsigned int)info->section[i].length,
00304 (unsigned int)info->section[i].checksum);
00305 }
00306 fprintf(stderr, "Group: 0x%x\n", (unsigned int)info->group);
00307 fprintf(stderr, "Number of segments: %d\n", (int)info->nSegments);
00308 for (i = 0; i < info->nSegments; ++i) {
00309 fprintf(stderr, "\tType: 0x%x Addr: 0x%x Len: 0x%x Flags: 0x%x\n",
00310 (unsigned int)info->segment[i].type,
00311 (unsigned int)info->segment[i].addr,
00312 (unsigned int)info->segment[i].length,
00313 (unsigned int)info->segment[i].flags);
00314 }
00315 }
00316