Example #1
0
bool process::clearSyscallTrapInternal(syscallTrap *trappedSyscall) {
  // Decrement the reference count, and if it's 0 remove the trapped
  // system call
  assert(trappedSyscall->refcount > 0);
    
  trappedSyscall->refcount--;
  if (trappedSyscall->refcount > 0) {
    bperr( "Syscall still has refcount %d\n", 
	   trappedSyscall->refcount);
    return true;
  }
  bperr( "Removing trapped syscall at 0x%lx\n",
	 trappedSyscall->syscall_id);
  if (!writeDataSpace( (void *)trappedSyscall->syscall_id, 16, trappedSyscall->saved_insn))
    return false;
        
  // Now that we've reset the original behavior, remove this
  // entry from the vector
  pdvector<syscallTrap *> newSyscallTraps;
  for (unsigned iter = 0; iter < syscallTraps_.size(); iter++) {
    if (trappedSyscall != syscallTraps_[iter])
      newSyscallTraps.push_back(syscallTraps_[iter]);
  }
  syscallTraps_ = newSyscallTraps;

  delete trappedSyscall;
  return true;
} /* end clearSyscallTrapInternal() */
Example #2
0
// initialize: perform initialization tasks on a platform-specific level
bool dynamic_linking::initialize() {
    // First, initialize all platform-specific stuff
    r_debug_addr = 0;
    r_state = 0;
    // First, find if we're a dynamic executable
    pdstring dyn_str = pdstring("DYNAMIC");
    Symbol dyn_sym;
    if( ! proc->getSymbolInfo(dyn_str, dyn_sym)) {
        bperr( "Failed to find string DYNAMIC\n");
        return false; 
    }

    // step 2: find the base address and file descriptor of ld.so.1
    // Three-step process.
    // 1) Examine aux vector for address of the loader
    Address ld_base = 0;
    dyn_lwp *replwp = proc->getRepresentativeLWP();
    if(!(this->get_ld_base_addr(ld_base, replwp->auxv_fd()))) {
        return false;
    }
    
    // 2) Examine virtual address map for the name of the object (inode style)
    char ld_name[128+PRMAPSZ];
    if(!(this->get_ld_name(ld_name, ld_base, replwp->map_fd(),
                           proc->getPid()))) { 
        return false;
    }
    
    // 3) Open that file
    int ld_fd = -1;    
    ld_fd = open(ld_name, O_RDONLY, 0);
    if(ld_fd == -1) {
        perror("LD.SO");
        return false;
    } 

    // step 3: get its symbol table and find r_debug
    if (!(this->find_r_debug(ld_fd,ld_base))) { 
        return false;
    }

    if (!(this->find_dlopen(ld_fd,ld_base))) {
        bperr( "WARNING: we didn't find dlopen in ld.so.1\n");
    }

    P_close(ld_fd);

   dynlinked = true;

    return true;
}
Example #3
0
static void dumpMap(int proc_fd) 
{
  int ret;
  int numMaps;
  prmap_t *maps;

  ret = ioctl(proc_fd, PIOCNMAP, &numMaps);
  assert(ret == 0);

  bperr("%d segments mapped\n", numMaps);

  maps = (prmap_t *) calloc(sizeof(prmap_t), numMaps+1);

  ret = ioctl(proc_fd, PIOCMAP, maps);
  assert(ret == 0);

  for (int i = 0; i < numMaps; i++) {
        bperr("map %d:\n", i);
        bperr("    start: %lx\n", maps[i].pr_vaddr);
        bperr("    size: %lx\n", maps[i].pr_size);
        bperr("    protection: ");
        if (maps[i].pr_mflags & MA_READ) bperr("READ ");
        if (maps[i].pr_mflags & MA_WRITE) bperr("WRITE ");
        if (maps[i].pr_mflags & MA_EXEC) bperr("EXEC ");
  }
}
Example #4
0
//
// findVariable
//	scp	- a BPatch_point that defines the scope of the current search
//	name	- name of the variable to find.
//
BPatch_variableExpr *BPatch_image::findVariableInScope(BPatch_point &scp,
        const char *name)
{
    // Get the function to search for it's local variables.
    // XXX - should really use more detailed scoping info here - jkh 6/30/99
    BPatch_function *func = const_cast<BPatch_function *> (scp.getFunction());
    if (!func) {
        pdstring msg = pdstring("point passed to findVariable lacks a function\n address point type passed?");
        showErrorCallback(100, msg);
        return NULL;
    }
    BPatch_localVar *lv = func->findLocalVar(name);

    if (!lv) {
        // look for it in the parameter scope now
        lv = func->findLocalParam(name);
    }
    if (lv) {
        // create a local expr with the correct frame offset or absolute
        //   address if that is what is needed
        return new BPatch_variableExpr(proc, (void *) lv->getFrameOffset(),
                                       lv->getRegister(), lv->getType(), lv->getStorageClass(), &scp);
    }

    // finally check the global scope.
    // return findVariable(name);

    /* If we have something else to try, don't report errors on this failure. */
    bool reportErrors = true;
    char mangledName[100];
    func->getName( mangledName, 100 );
    char * lastScoping = NULL;
    if( strrchr( mangledName, ':' ) != NULL ) {
        reportErrors = false;
    }
    BPatch_variableExpr * gsVar = findVariable( name, reportErrors );

    if( gsVar == NULL ) {
        /* Try finding it with the function's scope prefixed. */

        if( (lastScoping = strrchr( mangledName, ':' )) != NULL ) {
            * (lastScoping + sizeof(char)) = '\0';
            char scopedName[200];
            memmove( scopedName, mangledName, strlen( mangledName ) );
            memmove( scopedName + strlen( mangledName ), name, strlen( name ) );
            scopedName[ strlen( mangledName ) + strlen( name ) ] = '\0';
            bperr( "Searching for scoped name '%s'\n", scopedName );
            gsVar = findVariable( scopedName );
        }
    }
    return gsVar;
}
Example #5
0
void insnCodeGen::generateBranch(codeGen &gen, long disp, bool link)
{
    if (ABS(disp) > MAX_BRANCH) {
	// Too far to branch, and no proc to register trap.
	fprintf(stderr, "ABS OFF: 0x%lx, MAX: 0x%lx\n",
           ABS(disp), (unsigned long) MAX_BRANCH);
	bperr( "Error: attempted a branch of 0x%lx\n", disp);
	logLine("a branch too far\n");
	showErrorCallback(52, "Internal error: branch too far");
	bperr( "Attempted to make a branch of offset 0x%lx\n", disp);
	assert(0);
    }

    instruction insn;
    IFORM_OP_SET(insn, Bop);
    IFORM_LI_SET(insn, disp >> 2);
    IFORM_AA_SET(insn, 0);
    if (link)
        IFORM_LK_SET(insn, 1);
    else
        IFORM_LK_SET(insn, 0);

    insnCodeGen::generate(gen,insn);
}
Example #6
0
void BPatch_typeArray::merge(BPatch_type *other) {
   // There are wierd cases where we may define an array with an element
   // that is a forward reference
   
   BPatch_typeArray *otherarray = dynamic_cast<BPatch_typeArray *>(other);

   if ( otherarray == NULL || this->ID != otherarray->ID || 
        this->arrayElem->getDataClass() != BPatch_dataUnknownType) {
      bperr( "Ignoring attempt to merge dissimilar types.\n" );
      return;
   }

   arrayElem->decrRefCount();
   otherarray->arrayElem->incrRefCount();
   arrayElem = otherarray->arrayElem;
}
Example #7
0
/*
 * BPatch_image::findModule
 *
 * Returns module with <name>, NULL if not found
 */
BPatch_module *BPatch_image::findModuleInt(const char *name, bool substring_match)
{
    if (!name) {
        bperr("%s[%d]:  findModule:  no module name provided\n",
              __FILE__, __LINE__);
        return NULL;
    }

    BPatch_module *target = NULL;

    char buf[512];
    for (unsigned int i = 0; i < modlist.size(); ++i) {
        BPatch_module *mod = modlist[i];
        assert(mod);
        mod->getName(buf, 512);
        if (substring_match)
            if (strstr(buf, name)) {
                target = mod;
                break;
            }
            else  //exact match required
                if (!strcmp(name, buf)) {
                    target = mod;
                    break;
                }
    }

    if (target)
        return target;

    // process::findModule does a wildcard match, not a substring match

    char *tmp = (char *) malloc(strlen(name) + 2);
    if(substring_match)
        sprintf(tmp, "*%s*", name);
    else
        sprintf(tmp, "%s", name);
    mapped_module *mod = proc->llproc->findModule(pdstring(tmp),substring_match);
    free(tmp);
    if (!mod) return false;

    target = findOrCreateModule(mod);

    return target;
}
Example #8
0
void BPatch_typeUnion::merge(BPatch_type *other) {
   // Merging is only for forward references
   assert(!fieldList.size());

   BPatch_typeUnion *otherunion = dynamic_cast<BPatch_typeUnion *>(other);

   if( otherunion == NULL || this->ID != otherunion->ID) {
      bperr( "Ignoring attempt to merge dissimilar types.\n" );
      return;
   }

   if (otherunion->name != NULL)
      name = strdup(otherunion->name);
   size = otherunion->size;

   fieldList = otherunion->fieldList;

   if (otherunion->derivedFieldList) {
      derivedFieldList = new BPatch_Vector<BPatch_field *>;
      *derivedFieldList = *otherunion->derivedFieldList;
   }
}
Example #9
0
void Object::load_object(bool sharedLibrary) {
    char* file = strdup(file_.c_str());
    bool        did_open = false, success=true, text_read=false;
    LDFILE      *ldptr = NULL;
    HDRR        sym_hdr;
    pCHDRR      sym_tab_ptr = NULL;
    long        index=0;
    SYMR        symbol;
    unsigned short sectindex=1;
    SCNHDR      secthead;
    filehdr     fhdr;
    unsigned 	nsymbols;
    pdvector<Symbol> allSymbols;
    pdvector<Address> all_addr(9, 0);
    pdvector<long> all_size(9, 0);
    pdvector<bool> all_dex(9, false);
    pdvector<long> all_disk(9, 0);

        if (!(ldptr = ldopen(file, ldptr))) {
            log_perror(err_func_, file);
	    success = false;
	    bperr("failed open\n");
	    free(file);
	    return;
        }
        did_open = true;

	if (TYPE(ldptr) != ALPHAMAGIC) {
	    bperr( "%s is not an alpha executable\n", file);
	    success = false;
	    bperr("failed magic region\n");
	    ldclose(ldptr);
	    free(file);
	    return;
        }

	// Read the text and data sections
	fhdr = HEADER(ldptr);
	unsigned short fmax = fhdr.f_nscns;

	dynamicallyLinked = false;

	// Life would be so much easier if there were a guaranteed order for
	// these sections.  But the man page makes no mention of it.
	while (sectindex < fmax) {
	  if (ldshread(ldptr, sectindex, &secthead) == SUCCESS) {
	    // cout << "Section: " << secthead.s_name << "\tStart: " << secthead.s_vaddr 
	    // << "\tEnd: " << secthead.s_vaddr + secthead.s_size << endl;

	    if (!P_strcmp(secthead.s_name, ".text")) {
	      code_len_ = (Word) secthead.s_size;
	      Word *buffer = new Word[code_len_+1];
	      code_ptr_ = buffer;
	      code_off_ = (Address) secthead.s_vaddr;
	      if (!obj_read_section(secthead, ldptr, buffer)) {
		success = false;
		bperr("failed text region\n");
		ldclose(ldptr);
		free(file);
		return;
	      }
	      text_read = true;
	    } else if (!P_strcmp(secthead.s_name, ".data")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_D_INDEX] = secthead.s_vaddr;
		all_size[K_D_INDEX] = secthead.s_size;
		all_dex[K_D_INDEX] = true;
		all_disk[K_D_INDEX] = secthead.s_scnptr;
	      } else {
		bperr("failed data region\n");
		success = false;
		ldclose(ldptr);
		free(file);
		return;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".xdata")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_XD_INDEX] = secthead.s_vaddr;
		all_size[K_XD_INDEX] = secthead.s_size;
		all_dex[K_XD_INDEX] = true;
		all_disk[K_XD_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".sdata")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_SD_INDEX] = secthead.s_vaddr;
		all_size[K_SD_INDEX] = secthead.s_size;
		all_dex[K_SD_INDEX] = true;
		all_disk[K_SD_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".rdata")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_RD_INDEX] = secthead.s_vaddr;
		all_size[K_RD_INDEX] = secthead.s_size;
		all_dex[K_RD_INDEX] = true;
		all_disk[K_RD_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".lit4")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_L4_INDEX] = secthead.s_vaddr;
		all_size[K_L4_INDEX] = secthead.s_size;
		all_dex[K_L4_INDEX] = true;
		all_disk[K_L4_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".lita")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_LA_INDEX] = secthead.s_vaddr;
		all_size[K_LA_INDEX] = secthead.s_size;
		all_dex[K_LA_INDEX] = true;
		all_disk[K_LA_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".rconst")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_RC_INDEX] = secthead.s_vaddr;
		all_size[K_RC_INDEX] = secthead.s_size;
		all_dex[K_RC_INDEX] = true;
		all_disk[K_RC_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strcmp(secthead.s_name, ".lit8")) {
	      if (secthead.s_vaddr && secthead.s_scnptr) {
		all_addr[K_L8_INDEX] = secthead.s_vaddr;
		all_size[K_L8_INDEX] = secthead.s_size;
		all_dex[K_L8_INDEX] = true;
		all_disk[K_L8_INDEX] = secthead.s_scnptr;
	      }
	    } else if (!P_strncmp(secthead.s_name, ".dynamic", 8)) {
	      // a section .dynamic implies the program is dynamically linked
	      dynamicallyLinked = true; 
	    }
	  } else {
	    success = false;
	    bperr("failed header region\n");
	    ldclose(ldptr);
	    free(file);
	    return;
	  }
	  sectindex++;
	}

	if (!text_read) { 
	  success = false;
	  bperr("failed text region\n");
	  ldclose(ldptr);
	  free(file);
	  return;
	}

	// I am assuming that .data comes before all other data sections
	// I will include all other contiguous data sections
	// Determine the size of the data section(s)
	if (all_disk[K_D_INDEX]) {
	    if (!find_data_region(all_addr, all_size, all_disk,
                                  data_len_, data_off_)) {
	      success = false;
	      bperr("failed find data region\n");
	      ldclose(ldptr);
	      free(file);
	      return;
	    }
	}

	// Now read in the data from the assorted data regions
	Word *buffer = new Word[data_len_+1];
	data_ptr_ = buffer;
	if (!read_data_region(all_addr, all_size, all_disk,
			      data_len_, data_off_, buffer, ldptr)) {
	  success = false;
          bperr("failed read data region\n");
	  ldclose(ldptr);
	  free(file);
	  return;
	}

	// COFF doesn't have segments, so the entire code/data sections are valid
	code_vldS_ = code_off_;
	code_vldE_ = code_off_ + code_len_;
	data_vldS_ = data_off_;
	data_vldE_ = data_off_ + code_len_;

        // Check for the symbol table
	if (!(sym_tab_ptr = PSYMTAB(ldptr))) {
	    success = false;
            bperr("failed check for symbol table - object may be strip'd!\n");
	    ldclose(ldptr);
	    free(file);
	    return;
	}

	// Read the symbol table
	sym_hdr = SYMHEADER(ldptr);
	if (sym_hdr.magic != magicSym) {
	    success = false;
            bperr("failed check for magic symbol\n");
	    ldclose(ldptr);
	    free(file);
	    return;
        }
	if (!(sym_tab_ptr = SYMTAB(ldptr))) {
	    success = false;
            bperr("failed read symbol table\n");
	    ldclose(ldptr);
	    free(file);
	    return;
	}
	if (LDSWAP(ldptr)) {
	  // These bytes are swapped
	  // supposedly libsex.a will unswap them
	  assert(0);
	}

	pdstring module = "DEFAULT_MODULE";
   if (sharedLibrary) {
      module = file_;
      allSymbols.push_back(Symbol(module, module, Symbol::PDST_MODULE, 
                                  Symbol::SL_GLOBAL, (Address) 0, false));
	} else {
      module = "DEFAULT_MODULE";
	}

   pdstring name = "DEFAULT_SYMBOL";
	int moduleEndIdx = -1;
	dictionary_hash<pdstring, int> fcnNames(pdstring::hash);

	while (ldtbread(ldptr, index, &symbol) == SUCCESS) {
	  // TODO -- when global?
	  Symbol::SymbolLinkage linkage = Symbol::SL_GLOBAL;
	  Symbol::SymbolType type = Symbol::PDST_UNKNOWN;
	  bool st_kludge = false;
	  bool sym_use = true;
	  char *name = ldgetname(ldptr, &symbol);
	  char prettyName[1024];

	switch(symbol.st) {
	case stProc:
	case stStaticProc:
		// Native C++ name demangling.
		MLD_demangle_string(name, prettyName, 1024,
				    MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
		if (strchr(prettyName, '('))
		    *strchr(prettyName, '(') = 0;
		name = prettyName;

		if (symbol.sc == scText && !fcnNames.defines(name)) {
			type = Symbol::PDST_FUNCTION;
			fcnNames[name] = 1;
		}
		else 
			sym_use = false;
		break;

	case stGlobal:
	case stConstant:
	case stStatic:
		switch(symbol.sc) {
		case scData:
		case scSData:
		case scBss:
		case scSBss:
		case scRData:
		case scRConst:
		case scTlsData:
		case scTlsBss:
			type = Symbol::PDST_OBJECT;
			break;
		default:
			sym_use = false;
		}
		break;

	case stLocal:
	case stParam:
		linkage = Symbol::SL_LOCAL;

		switch(symbol.sc) {
		case scAbs:
		case scRegister:
		case scVar:
		case scVarRegister:
		case scUnallocated:
			type = Symbol::PDST_OBJECT;
			break;

		case scData:
		case scSData:
		case scBss:
		case scSBss:
		case scRConst:
		case scRData:
			 //Parameter is static var. Don't know what to do
			if (symbol.st == stParam)
				type = Symbol::PDST_OBJECT;
			else
				sym_use = false;
			break;

		default:
			sym_use = false;
		}
		break;

	case stTypedef:
	case stBase: //Base class
	case stTag: //C++ class, structure or union
		if (symbol.sc == scInfo)
			type = Symbol::PDST_OBJECT;
		else
			sym_use = false;
		break;

	case stFile:
		if (!sharedLibrary) {
			module = ldgetname(ldptr, &symbol); assert(module.length());
			type   = Symbol::PDST_MODULE;
			moduleEndIdx = symbol.index - 1;
			//Detect the compiler type by searching libgcc.
			if (strstr(module.c_str(), "libgcc"))
				GCC_COMPILED = true;
		}
		break;

	case stLabel:
		// For stLabel/scText combinations, if the symbol address falls
		// within the text section and has a valid name, process it as
		// a function.
		if (symbol.sc == scText &&
		    code_vldS_ <= (unsigned) symbol.value && (unsigned) symbol.value < code_vldE_ &&
		    name && *name && !fcnNames.defines(name)) {
			// Native C++ name demangling.
		        // Keep this in sync with stProc case above.

			MLD_demangle_string(name, prettyName, 1024,
					    MLD_SHOW_DEMANGLED_NAME | MLD_NO_SPACES);
			if (strchr(prettyName, '('))
			    *strchr(prettyName, '(') = 0;
			name = prettyName;

			type = Symbol::PDST_FUNCTION;
			fcnNames[name] = 1;

		} else {
			sym_use = false;
		}
		break;

	case stEnd:
		if (index == moduleEndIdx)
			module = "DEFAULT_MODULE";
		sym_use = false;
		break;

	default:
		sym_use = false;
	}

	// Skip eCoff encoded stab string.  Functions and global variable
	// addresses will still be found via the external symbols.
	if (P_strchr(name, ':'))
	    sym_use = false;
	
	// cout << index << "\t" << name << "\t" << StName(symbol.st) << "\t" << ScName(symbol.sc) << "\t" << symbol.value << "\n";

	  index++;

	  if (sym_use) {
	    // cout << index << "\t" << module << "\t" << name << "\t" << type << "\t" << symbol.value << "\n";
	    allSymbols.push_back(Symbol(name, module, type, linkage,
				      (Address) symbol.value, st_kludge));
	  }

    } //while

    VECTOR_SORT(allSymbols,symbol_compare);
    // find the function boundaries
    nsymbols = allSymbols.size();

    //Insert global symbols
    for (unsigned u = 0; u < nsymbols; u++) {
	unsigned size = 0;
	if (allSymbols[u].type() == Symbol::PDST_FUNCTION) {
	    unsigned v = u+1;
	    while (v < nsymbols) {
		// The .ef below is a special symbol that gcc puts in to
                // mark the end of a function.
                if (allSymbols[v].addr() != allSymbols[u].addr() &&
                      (allSymbols[v].type() == Symbol::PDST_FUNCTION ||
                       allSymbols[v].name() == ".ef"))
                break;
                v++;
            }
	    if (v < nsymbols) {
                  size = (unsigned)allSymbols[v].addr()
                         - (unsigned)allSymbols[u].addr();
	    } else {
                size = (unsigned)(code_off_+code_len_)
                         - (unsigned)allSymbols[u].addr();
	    }
	}
	
	if (allSymbols[u].linkage() != Symbol::SL_LOCAL) {
		symbols_[allSymbols[u].name()].push_back( 
	   		Symbol(allSymbols[u].name(), allSymbols[u].module(), 
	      		allSymbols[u].type(), allSymbols[u].linkage(), 
	       		allSymbols[u].addr(), allSymbols[u].kludge(), size) ); 
	}
    }

    //Insert local symbols (Do we need this?)
    for (unsigned u = 0; u < nsymbols; u++) {
	if ( (allSymbols[u].linkage() == Symbol::SL_LOCAL) &&
		(!symbols_.defines(allSymbols[u].name())) ) {
		symbols_[allSymbols[u].name()].push_back( 
	   		Symbol(allSymbols[u].name(), allSymbols[u].module(), 
	      		allSymbols[u].type(), allSymbols[u].linkage(), 
	       		allSymbols[u].addr(), allSymbols[u].kludge(), 0) );
	}
    }
		
    if (did_open && (ldclose(ldptr) == FAILURE)) {
        log_perror(err_func_, "close");
    }
    free(file);

}
Example #10
0
// parseStabTypes:  parses type and variable info, does some init
// does NOT parse file-line info anymore, this is done later, upon request.
void BPatch_module::parseStabTypes() 
{
  stab_entry *stabptr;
  const char *next_stabstr;

  unsigned i;
  char *modName;
  pdstring temp;
  image * imgPtr=NULL;
  char *ptr, *ptr2, *ptr3;
  bool parseActive = false;

  pdstring* currentFunctionName = NULL;
  Address currentFunctionBase = 0;
  BPatch_variableExpr *commonBlockVar = NULL;
 char *commonBlockName;
  BPatch_typeCommon *commonBlock = NULL;
 int mostRecentLinenum = 0;

#if defined(TIMED_PARSE)
  struct timeval starttime;
  gettimeofday(&starttime, NULL);
  unsigned int pss_count = 0;
  double pss_dur = 0;
  unsigned int src_count = 0;
  double src_dur = 0;
  unsigned int fun_count = 0;
  double fun_dur = 0;
  struct timeval t1, t2;
#endif

  imgPtr = mod->obj()->parse_img();
  imgPtr->analyzeIfNeeded();
  const Object &objPtr = imgPtr->getObject();

  //Using the Object to get the pointers to the .stab and .stabstr
  // XXX - Elf32 specific needs to be in seperate file -- jkh 3/18/99
  stabptr = objPtr.get_stab_info();
  next_stabstr = stabptr->getStringBase();

  for (i=0; i<stabptr->count(); i++) {
    switch(stabptr->type(i)){
    case N_UNDF: /* start of object file */
      /* value contains offset of the next string table for next module */
      // assert(stabptr->nameIdx(i) == 1);
      stabptr->setStringBase(next_stabstr);
      next_stabstr = stabptr->getStringBase() + stabptr->val(i);

      //N_UNDF is the start of object file. It is time to 
      //clean source file name at this moment.
      /*
      if(currentSourceFile){
	delete currentSourceFile;
	currentSourceFile = NULL;
	delete absoluteDirectory;
	absoluteDirectory = NULL;
	delete currentFunctionName;
	currentFunctionName = NULL;
	currentFileInfo = NULL;
	currentFuncInfo = NULL;
      }
      */
      break;
      
    case N_ENDM: /* end of object file */
      break;

    case N_SO: /* compilation source or file name */
      /* bperr("Resetting CURRENT FUNCTION NAME FOR NEXT OBJECT FILE\n");*/
#ifdef TIMED_PARSE
      src_count++;
      gettimeofday(&t1, NULL);
#endif
      current_func_name = ""; // reset for next object file
      current_mangled_func_name = ""; // reset for next object file
      current_func = NULL;

      modName = const_cast<char*>(stabptr->name(i));
      // cerr << "checkpoint B" << endl;
      ptr = strrchr(modName, '/');
      //  cerr << "checkpoint C" << endl;
      if (ptr) {
	ptr++;
	modName = ptr;
      }

      if (!strcmp(modName, mod->fileName().c_str())) {
	parseActive = true;
        moduleTypes->clearNumberedTypes();
	BPatch_language lang;
	// language should be set in the constructor, this is probably redundant
	switch (stabptr->desc(i)) {
	case N_SO_FORTRAN:
	  lang = BPatch_fortran;
	  break;
	  
	case N_SO_F90:
	  lang = BPatch_fortran90;
	  break;
	  
	case N_SO_AS:
	  lang = BPatch_assembly;
	  break;
	  
	case N_SO_ANSI_C:
	case N_SO_C:
	  lang = BPatch_c;
	  break;
	  
	case N_SO_CC:
	  lang = BPatch_cPlusPlus;
	  break;
	  
	default:
	  lang = BPatch_unknownLanguage;
	  break;
	}
	if (BPatch_f90_demangled_stabstr != getLanguage())
	  setLanguage(lang);
      } else {
	parseActive = false;
      }

#ifdef TIMED_PARSE
	    gettimeofday(&t2, NULL);
	    src_dur += (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0;
	    //src_dur += (t2.tv_sec/1000 + t2.tv_usec*1000) - (t1.tv_sec/1000 + t1.tv_usec*1000) ;
#endif
	    break;
    case N_SLINE:
      mostRecentLinenum = stabptr->desc(i);
      break;
    default:
      break;
    }


    if(parseActive || mod->obj()->isSharedLib()) {
      BPatch_Vector<BPatch_function *> bpfv;
      switch(stabptr->type(i)){
      case N_FUN:
#ifdef TIMED_PARSE
	fun_count++;
	gettimeofday(&t1, NULL);
#endif
	//all we have to do with function stabs at this point is to assure that we have
	//properly set the var currentFunctionName for the later case of (parseActive)
        current_func = NULL;
        int currentEntry = i;
        int funlen = strlen(stabptr->name(currentEntry));
        ptr = new char[funlen+1];
        strcpy(ptr, stabptr->name(currentEntry));
        while(strlen(ptr) != 0 && ptr[strlen(ptr)-1] == '\\'){
            ptr[strlen(ptr)-1] = '\0';
            currentEntry++;
            strcat(ptr,stabptr->name(currentEntry));
        }
        
        char* colonPtr = NULL;
        if(currentFunctionName) delete currentFunctionName;
        if(!ptr || !(colonPtr = strchr(ptr,':')))
            currentFunctionName = NULL;
        else {
            char* tmp = new char[colonPtr-ptr+1];
            strncpy(tmp,ptr,colonPtr-ptr);
            tmp[colonPtr-ptr] = '\0';
            currentFunctionName = new pdstring(tmp);
            
            currentFunctionBase = 0;
            Symbol info;
            // Shouldn't this be a function name lookup?
            if (!proc->llproc->getSymbolInfo(*currentFunctionName,
                                             info))
                {
                    pdstring fortranName = *currentFunctionName + pdstring("_");
                    if (proc->llproc->getSymbolInfo(fortranName,info))
                        {
                            delete currentFunctionName;
                            currentFunctionName = new pdstring(fortranName);
                        }
                }
            
            currentFunctionBase = info.addr();

            delete[] tmp;
      		
	//	if(currentSourceFile && (currentFunctionBase > 0)){
	//	lineInformation->insertSourceFileName(
	//			*currentFunctionName,
	//			*currentSourceFile,
	//			&currentFileInfo,&currentFuncInfo);
	//}
      }
      //  used to be a symbol lookup here to find currentFunctionBase, do we need it?
      delete[] ptr;
#ifdef TIMED_PARSE
      gettimeofday(&t2, NULL);
      fun_dur += (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0;
      //fun_dur += (t2.tv_sec/1000 + t2.tv_usec*1000) - (t1.tv_sec/1000 + t1.tv_usec*1000);
#endif
      break;
      }
    if (!parseActive) continue;

    switch(stabptr->type(i)){
      case N_BCOMM:	{
	// begin Fortran named common block 
	commonBlockName = const_cast<char*>(stabptr->name(i));

	// find the variable for the common block
	BPatch_image *progam = (BPatch_image *) getObjParent();
	commonBlockVar = progam->findVariable(commonBlockName);
	if (!commonBlockVar) {
	  bperr("unable to find variable %s\n", commonBlockName);
	} else {
	  commonBlock = dynamic_cast<BPatch_typeCommon *>(const_cast<BPatch_type *> (commonBlockVar->getType()));
	  if (commonBlock == NULL) {
	    // its still the null type, create a new one for it
	    commonBlock = new BPatch_typeCommon(commonBlockName);
	    commonBlockVar->setType(commonBlock);
	    moduleTypes->addGlobalVariable(commonBlockName, commonBlock);
	  }
	  // reset field list
	  commonBlock->beginCommonBlock();
	}
	break;
      }
      
      case N_ECOMM: {
	// copy this set of fields
	
	assert(currentFunctionName);
	if (NULL == findFunction(currentFunctionName->c_str(), bpfv) || !bpfv.size()) {
	  bperr("unable to locate current function %s\n", currentFunctionName->c_str());
	} else {
	  if (bpfv.size() > 1) {
	    // warn if we find more than one function with this name
	    bperr("%s[%d]:  WARNING: found %d funcs matching name %s, using the first\n",
		   __FILE__, __LINE__, bpfv.size(), currentFunctionName->c_str());
	  }
	  
	  BPatch_function *func = bpfv[0];
	  commonBlock->endCommonBlock(func, commonBlockVar->getBaseAddr());
	}
	
	// update size if needed
	if (commonBlockVar)
	  commonBlockVar->setSize(commonBlock->getSize());
	commonBlockVar = NULL;
	commonBlock = NULL;
	break;
      }
      
      // case C_BINCL: -- what is the elf version of this jkh 8/21/01
      // case C_EINCL: -- what is the elf version of this jkh 8/21/01
      case 32:    // Global symbols -- N_GYSM 
      case 38:    // Global Static -- N_STSYM
      case N_FUN:
      case 128:   // typedefs and variables -- N_LSYM
      case 160:   // parameter variable -- N_PSYM 
    case 0xc6:  // position-independant local typedefs -- N_ISYM
    case 0xc8: // position-independant external typedefs -- N_ESYM
#ifdef TIMED_PARSE
	pss_count++;
	gettimeofday(&t1, NULL);
#endif
        if (stabptr->type(i) == N_FUN) current_func = NULL;
	ptr = const_cast<char *>(stabptr->name(i));
	while (ptr[strlen(ptr)-1] == '\\') {
	  //ptr[strlen(ptr)-1] = '\0';
	  ptr2 =  const_cast<char *>(stabptr->name(i+1));
	  ptr3 = (char *) malloc(strlen(ptr) + strlen(ptr2));
	  strcpy(ptr3, ptr);
	  ptr3[strlen(ptr)-1] = '\0';
	  strcat(ptr3, ptr2);
	  
	  ptr = ptr3;
	  i++;
	  // XXX - memory leak on multiple cont. lines
	}
	
	// bperr("stab #%d = %s\n", i, ptr);
	// may be nothing to parse - XXX  jdd 5/13/99
	if (nativeCompiler)
	  temp = parseStabString(this, mostRecentLinenum, (char *)ptr, stabptr->val(i), commonBlock);
	else
	  temp = parseStabString(this, stabptr->desc(i), (char *)ptr, stabptr->val(i), commonBlock);
	if (temp.length()) {
	  //Error parsing the stabstr, return should be \0
	  bperr( "Stab string parsing ERROR!! More to parse: %s\n",
		  temp.c_str());
	  bperr( "  symbol: %s\n", ptr);
	}
	
#ifdef TIMED_PARSE
	gettimeofday(&t2, NULL);
	pss_dur += (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0;
	//      pss_dur += (t2.tv_sec/1000 + t2.tv_usec*1000) - (t1.tv_sec/1000 + t1.tv_usec*1000);
#endif
	break;
      default:
	break;
      }
    }       		    
  }

#if defined(TIMED_PARSE)
  struct timeval endtime;
  gettimeofday(&endtime, NULL);
  unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
  unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
  unsigned long difftime = lendtime - lstarttime;
  double dursecs = difftime/(1000 );
  cout << __FILE__ << ":" << __LINE__ <<": parseTypes("<< mod->fileName()
       <<") took "<<dursecs <<" msecs" << endl;
  cout << "Breakdown:" << endl;
  cout << "     Functions: " << fun_count << " took " << fun_dur << "msec" << endl;
  cout << "     Sources: " << src_count << " took " << src_dur << "msec" << endl;
  cout << "     parseStabString: " << pss_count << " took " << pss_dur << "msec" << endl;
  cout << "     Total: " << pss_dur + fun_dur + src_dur 
       << " msec" << endl;
#endif
}
Example #11
0
// Gets the stab and stabstring section and parses it for types
// and variables
void BPatch_module::parseTypes()
{
    int i, j;
    int nlines;
    int nstabs;
    char* lines;
    SYMENT *syms;
    SYMENT *tsym;
    char *stringPool;
    char tempName[9];
    char *stabstr=NULL;
    union auxent *aux;
    image * imgPtr=NULL;
    pdstring funcName;
    Address staticBlockBaseAddr = 0;
    unsigned long linesfdptr;
    BPatch_typeCommon *commonBlock = NULL;
    BPatch_variableExpr *commonBlockVar = NULL;
    pdstring currentSourceFile;
    bool inCommonBlock = false;

#if defined(TIMED_PARSE)
  struct timeval starttime;
  gettimeofday(&starttime, NULL);
#endif

  imgPtr = mod->obj()->parse_img();
  
  const Object &objPtr = imgPtr->getObject();

  //Using the Object to get the pointers to the .stab and .stabstr
  objPtr.get_stab_info(stabstr, nstabs, syms, stringPool); 

    objPtr.get_line_info(nlines,lines,linesfdptr); 

    bool parseActive = true;
    //fprintf(stderr, "%s[%d]:  parseTypes for module %s: nstabs = %d\n", FILE__, __LINE__,mod->fileName().c_str(),nstabs);
    //int num_active = 0;

    for (i=0; i < nstabs; i++) {
      /* do the pointer addition by hand since sizeof(struct syment)
       *   seems to be 20 not 18 as it should be */
      SYMENT *sym = (SYMENT *) (((unsigned) syms) + i * SYMESZ);
      // SYMENT *sym = (SYMENT *) (((unsigned) syms) + i * sizeof(struct syment));


      if (sym->n_sclass == C_FILE) {
	 char *moduleName;
	 if (!sym->n_zeroes) {
	    moduleName = &stringPool[sym->n_offset];
	 } else {
	    memset(tempName, 0, 9);
	    strncpy(tempName, sym->n_name, 8);
	    moduleName = tempName;
	 }
	 /* look in aux records */
	 for (j=1; j <= sym->n_numaux; j++) {
	    aux = (union auxent *) ((char *) sym + j * SYMESZ);
	    if (aux->x_file._x.x_ftype == XFT_FN) {
		if (!aux->x_file._x.x_zeroes) {
                     moduleName = &stringPool[aux->x_file._x.x_offset];
                } else {
                     // x_fname is 14 bytes
                     memset(moduleName, 0, 15);
                     strncpy(moduleName, aux->x_file.x_fname, 14);
                }
	    }
	 }

	 currentSourceFile = pdstring(moduleName);
	 currentSourceFile = mod->processDirectories(currentSourceFile);

	 if (strrchr(moduleName, '/')) {
	     moduleName = strrchr(moduleName, '/');
	     moduleName++;
	 }

	 if (!strcmp(moduleName, mod->fileName().c_str())) {
		parseActive = true;
                // Clear out old types
                moduleTypes->clearNumberedTypes();
	 } else {
              parseActive = false;
	 }
      }

      if (!parseActive) continue;

      //num_active++;

      char *nmPtr;
      if (!sym->n_zeroes && ((sym->n_sclass & DBXMASK) ||
			     (sym->n_sclass == C_BINCL) ||
			     (sym->n_sclass == C_EINCL))) {
	  if (sym->n_offset < 3) {
	      if (sym->n_offset == 2 && stabstr[0]) {
		  nmPtr = &stabstr[0];
	      } else {
		  nmPtr = &stabstr[sym->n_offset];
	      }
	  } else if (!stabstr[sym->n_offset-3]) {
	      nmPtr = &stabstr[sym->n_offset];
	  } else {
	      /* has off by two error */
	      nmPtr = &stabstr[sym->n_offset-2];
	  }
#ifdef notdef
	  bperr("using nmPtr = %s\n", nmPtr);
	  bperr("got n_offset = (%d) %s\n", sym->n_offset, &stabstr[sym->n_offset]);
	  if (sym->n_offset>=2) 
	      bperr("got n_offset-2 = %s\n", &stabstr[sym->n_offset-2]);
	  if (sym->n_offset>=3) 
	      bperr("got n_offset-3 = %x\n", stabstr[sym->n_offset-3]);
	  if (sym->n_offset>=4) 
	      bperr("got n_offset-4 = %x\n", stabstr[sym->n_offset-4]);
#endif
      } else {
	  // names 8 or less chars on inline, not in stabstr
	  memset(tempName, 0, 9);
	  strncpy(tempName, sym->n_name, 8);
	  nmPtr = tempName;
      }

      if ((sym->n_sclass == C_BINCL) ||
	  (sym->n_sclass == C_EINCL) ||
	  (sym->n_sclass == C_FUN)) {
		funcName = nmPtr;
		/* The call to parseLineInformation(), below, used to modify the symbols passed to it. */
                if (funcName.find(":") < funcName.length())
                   funcName = funcName.substr(0,funcName.find(":"));

//		I'm not sure why we bother with this here, since we fetch line numbers in symtab.C anyway.
//		mod->parseLineInformation(proc->llproc, currentSourceFile, 
//					  funcName, sym,
//					  linesfdptr, lines, nlines);
      }

      if (sym->n_sclass & DBXMASK) {
	  if (sym->n_sclass == C_BCOMM) {
	      char *commonBlockName;

              inCommonBlock = true;
	      commonBlockName = nmPtr;

	      // find the variable for the common block
	      BPatch_image *progam = (BPatch_image *) getObjParent();
	      
	      commonBlockVar = progam->findVariable(commonBlockName);
	      if (!commonBlockVar) {
		  bperr("unable to find variable %s\n", commonBlockName);
	      } else {
		  commonBlock = 
		      dynamic_cast<BPatch_typeCommon *>(const_cast<BPatch_type *> (commonBlockVar->getType()));
		  if (commonBlock == NULL) {
		      // its still the null type, create a new one for it
		      commonBlock = new BPatch_typeCommon(commonBlockName);
		      commonBlockVar->setType(commonBlock);
		      moduleTypes->addGlobalVariable(commonBlockName, commonBlock);
		  }
		  // reset field list
		  commonBlock->beginCommonBlock();
	      }
	  } else if (sym->n_sclass == C_ECOMM) {
             inCommonBlock = false;
             if (commonBlock == NULL)
                continue;

	      // copy this set of fields
	    BPatch_Vector<BPatch_function *> bpmv;
   	    if (NULL == findFunction(funcName.c_str(), bpmv) || !bpmv.size()) {
	      bperr("unable to locate current function %s\n", funcName.c_str());
	      } else {
		BPatch_function *func = bpmv[0];
		commonBlock->endCommonBlock(func, commonBlockVar->getBaseAddr());
	      }

	      // update size if needed
	      if (commonBlockVar)
		  commonBlockVar->setSize(commonBlock->getSize());
	      commonBlockVar = NULL;
	      commonBlock = NULL;
	  } else if (sym->n_sclass == C_BSTAT) {
	      // begin static block
	      // find the variable for the common block
	      tsym = (SYMENT *) (((unsigned) syms) + sym->n_value * SYMESZ);

	      // We can't lookup the value by name, because the name might have been
	      // redefined later on (our lookup would then pick the last one)

	      // Since this whole function is AIX only, we're ok to get this info

	      staticBlockBaseAddr = tsym->n_value;

	      /*
	      char *staticName, tempName[9];
	      if (!tsym->n_zeroes) {
		  staticName = &stringPool[tsym->n_offset];
	      } else {
		  memset(tempName, 0, 9);
		  strncpy(tempName, tsym->n_name, 8);
		  staticName = tempName;
	      }
	      BPatch_image *progam = (BPatch_image *) getObjParent();

	      BPatch_variableExpr *staticBlockVar = progam->findVariable(staticName);
	      if (!staticBlockVar) {
		  bperr("unable to find static block %s\n", staticName);
		  staticBlockBaseAddr = 0;
	      } else {
		  staticBlockBaseAddr = (Address) staticBlockVar->getBaseAddr();
	      }
	      */

	  } else if (sym->n_sclass == C_ESTAT) {
	      staticBlockBaseAddr = 0;
	  }

          // There's a possibility that we were parsing a common block that
          // was never instantiated (meaning there's type info, but no
          // variable info

          if (inCommonBlock && commonBlock == NULL)
             continue;

	  if (staticBlockBaseAddr && (sym->n_sclass == C_STSYM)) {
              parseStabString(this, 0, nmPtr, 
		  sym->n_value+staticBlockBaseAddr, commonBlock);
	  } else {
              parseStabString(this, 0, nmPtr, sym->n_value, commonBlock);
	  }
      }
    }
#if defined(TIMED_PARSE)
  struct timeval endtime;
  gettimeofday(&endtime, NULL);
  unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
  unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
  unsigned long difftime = lendtime - lstarttime;
  double dursecs = difftime/(1000 );
  cout << __FILE__ << ":" << __LINE__ <<": parseTypes("<< mod->fileName()
       <<") took "<<dursecs <<" msecs" << endl;
#endif

//  fprintf(stderr, "%s[%d]:  parseTypes for %s, num_active = %d\n", FILE__, __LINE__, mod->fileName().c_str(), num_active);
}
Example #12
0
bool InternalThread::createThread()
{
    thread_printf("%s[%d]  welcome to createThread(%s)\n", __FILE__, __LINE__, idstr);
  if (isRunning()) {
     fprintf(stderr, "%s[%d]:  WARNING:  cannot create thread '%s'which is already running\n", 
             __FILE__, __LINE__, idstr);
     return true;
  }
  
  startupLock = new eventLock();
  startupLock->_Lock(__FILE__, __LINE__);

#if defined(os_windows)
  handler_thread = _beginthread(eventHandlerWrapper, 0, (void *) this);
  if (-1L == handler_thread) {
    bperr("%s[%d]:  _beginthread(...) failed\n", __FILE__, __LINE__);
    return false;
  }
#else  // Unixes

  int err = 0;
  pthread_attr_t handler_thread_attr;

  err = pthread_attr_init(&handler_thread_attr);
  if (err) {
    bperr("%s[%d]:  could not init async handler thread attributes: %s, %d\n",
          __FILE__, __LINE__, strerror(err), err);
    return false;
  }

  err = pthread_attr_setdetachstate(&handler_thread_attr, PTHREAD_CREATE_DETACHED);
  if (err) {
    bperr("%s[%d]:  could not set async handler thread attrixibcutes: %s, %d\n",
          __FILE__, __LINE__, strerror(err), err);
    return false;
  }

  try {
  err = pthread_create(&handler_thread, &handler_thread_attr,
                       &eventHandlerWrapper, (void *) this);
  if (err) {
    bperr("%s[%d]:  could not start async handler thread: %s, %d\n",
          __FILE__, __LINE__, strerror(err), err);
    fprintf(stderr,"%s[%d]:  could not start async handler thread: %s, %d\n",
          __FILE__, __LINE__, strerror(err), err);
    return false;
  }
  } catch(...) {
    assert(0);
  }

  err = pthread_attr_destroy(&handler_thread_attr);
  if (err) {
    bperr("%s[%d]:  could not destroy async handler attr: %s, %d\n",
          __FILE__, __LINE__, strerror(err), err);
    return false;
  }
#endif

  while (!_isRunning && (init_ok)) {
      thread_printf("%s[%d]:  createThread (%s) waiting for thread main to start\n", __FILE__, __LINE__, idstr);
      startupLock->_WaitForSignal(__FILE__, __LINE__);
      thread_printf("%s[%d]:  createThread (%s) got signal\n", __FILE__, __LINE__, idstr);
  }
  startupLock->_Unlock(__FILE__, __LINE__);

  thread_printf("%s[%d]: createThread returning %d\n", FILE__, __LINE__, init_ok);

  if (!init_ok) {
    return false;
  }
  return true;

}
Example #13
0
void mapped_module::parseLineInformation(process * /* proc */,
                                         pdstring * currentSourceFile,
                                         char * symbolName,
                                         SYMENT * sym,
                                         Address linesfdptr,
                                         char * lines,
                                         int nlines ) {
    union auxent * aux;
    pdvector<IncludeFileInfo> includeFiles;
    
    /* if it is beginning of include files then update the data structure
       that keeps the beginning of the include files. If the include files contain
       information about the functions and lines we have to keep it */
    if( sym->n_sclass == C_BINCL ) {
        includeFiles.push_back( IncludeFileInfo( (sym->n_value - linesfdptr)/LINESZ, symbolName ) );
    }
    /* similiarly if the include file contains function codes and line information
       we have to keep the last line information entry for this include file */
    else if( sym->n_sclass == C_EINCL ) {
        if( includeFiles.size() > 0 ) {
            includeFiles[includeFiles.size()-1].end = (sym->n_value-linesfdptr)/LINESZ;
        }
    }
    /* if the enrty is for a function than we have to collect all info
       about lines of the function */
    else if( sym->n_sclass == C_FUN ) {
        /* I have no idea what the old code did, except not work very well.
           Somebody who understands XCOFF should look at this. */
        int initialLine = 0;
        int initialLineIndex = 0;
        Address funcStartAddress = 0;
        Address funcEndAddress = 0;
        
        for( int j = -1; ; --j ) {
            SYMENT * extSym = (SYMENT *)( ((Address)sym) + (j * SYMESZ) );
            if( extSym->n_sclass == C_EXT || extSym->n_sclass == C_HIDEXT ) {
                aux = (union auxent *)( ((Address)extSym) + SYMESZ );
#ifndef __64BIT__
                initialLineIndex = ( aux->x_sym.x_fcnary.x_fcn.x_lnnoptr - linesfdptr )/LINESZ;
#endif
                funcStartAddress = extSym->n_value;
                break;
            } /* end if C_EXT found */
        } /* end search for C_EXT */
        
        /* access the line information now using the C_FCN entry*/
        SYMENT * bfSym = (SYMENT *)( ((Address)sym) + SYMESZ );
        if( bfSym->n_sclass != C_FCN ) {
            bperr("unable to process line info for %s\n", symbolName);
            return;
        }
        SYMENT * efSym = (SYMENT *)( ((Address)bfSym) + (2 * SYMESZ) );
        while (efSym->n_sclass != C_FCN)
           efSym = (SYMENT *) ( ((Address)efSym) + SYMESZ );
        funcEndAddress = efSym->n_value;
        
        aux = (union auxent *)( ((Address)bfSym) + SYMESZ );
        initialLine = aux->x_sym.x_misc.x_lnsz.x_lnno;
        
        pdstring whichFile = *currentSourceFile;
        for( unsigned int j = 0; j < includeFiles.size(); j++ ) {
            if(	( includeFiles[j].begin <= (unsigned)initialLineIndex )
            	&& ( includeFiles[j].end >= (unsigned)initialLineIndex ) ) {
                whichFile = includeFiles[j].name;
                break;
            }
        } /* end iteration of include files */
        
        int_function * currentFunction = obj()->findFuncByAddr( funcStartAddress + trueBaseAddress );
        if( currentFunction == NULL ) {
            /* Some addresses point to gdb-inaccessible memory; others have symbols (gdb will disassemble them)
               but the contents look like garbage, and may be data with symbol names.  (Who knows why.) */
            // fprintf( stderr, "%s[%d]: failed to find function containing address 0x%lx; line number information will be lost.\n", __FILE__, __LINE__, funcStartAddress + trueBaseAddress );
            return;
        }
        mapped_module * currentModule = currentFunction->mod();
        assert( currentModule != NULL );
        LineInformation & currentLineInformation = currentModule->lineInfo_;
        
        unsigned int previousLineNo = 0;
        Address previousLineAddr = 0;
        bool isPreviousValid = false;
        
        /* Iterate over this entry's lines. */
        for( int j = initialLineIndex + 1; j < nlines; j++ ) {
            LINENO * lptr = (LINENO *)( lines + (j * LINESZ) );
            if( ! lptr->l_lnno ) { break; }
            unsigned int lineNo = lptr->l_lnno + initialLine - 1;
            Address lineAddr = lptr->l_addr.l_paddr + trueBaseAddress;
            
            if( isPreviousValid ) {
                // /* DEBUG */ fprintf( stderr, "%s[%d]: adding %s:%d [0x%lx, 0x%lx).\n", __FILE__, __LINE__, whichFile.c_str(), previousLineNo, previousLineAddr, lineAddr );
                currentLineInformation.addLine( whichFile.c_str(), previousLineNo, previousLineAddr, lineAddr );
            }
            
            previousLineNo = lineNo;
            previousLineAddr = lineAddr;
            isPreviousValid = true;
        } /* end iteration over line information */
        
        if( isPreviousValid ) {
            /* Add the instruction (always 4 bytes on power) pointed at by the last entry.  We'd like to add a
               bigger range, but it's not clear how.  (If the function has inlined code, we won't know about
               it until we see the next section, so claiming "until the end of the function" will give bogus results.) */
            // /* DEBUG */ fprintf( stderr, "%s[%d]: adding %s:%d [0x%lx, 0x%lx).\n", __FILE__, __LINE__, whichFile.c_str(), previousLineNo, previousLineAddr, previousLineAddr + 4 );
           while (previousLineAddr < funcEndAddress) {
            currentLineInformation.addLine( whichFile.c_str(), previousLineNo, previousLineAddr, previousLineAddr + 4 );
            previousLineAddr += 4;
           }
        }
    } /* end if we found a C_FUN symbol */
} /* end parseLineInformation() */
Example #14
0
// processLinkMaps: get a list of all loaded objects in fileDescriptor form.
bool dynamic_linking::processLinkMaps(pdvector<fileDescriptor> &descs) {
    
    int proc_fd = proc->getRepresentativeLWP()->get_fd();
    if(!proc_fd){ return false;}

    // step 2: get the runtime loader table from the process
    Address ldr_base_addr;
    ldr_context first;
    ldr_module module;

    assert(proc->readDataSpace((const void*)LDR_BASE_ADDR,sizeof(Address), &ldr_base_addr, true));
    assert(proc->readDataSpace((const void*)ldr_base_addr,sizeof(ldr_context), &first, true));
    assert(proc->readDataSpace((const void *) first.head,sizeof(ldr_module), &module, true));
    
    while (module.next != first.head) {
      if (module.nregions == 0)
	{ 
	  assert(proc->readDataSpace((const void *) module.next,sizeof(ldr_module), &module,true));
	  continue;
        }
      pdstring obj_name = pdstring(readDataString(proc, module.name));
      ldr_region *regions;
      
      regions = (ldr_region *) malloc(module.nregions * sizeof(ldr_region));
      assert(proc->readDataSpace((const void *) module.regions, 
				 sizeof(ldr_region)*module.nregions, regions, true));
      
      long offset = regions[0].mapaddr - regions[0].vaddr;
#ifdef notdef
      if (offset) {
	bperr("*** shared lib at non-default offset **: ");
	bperr("    %s\n", obj_name.c_str());
	bperr("    offset = %ld\n", offset);
      } else {
	bperr("*** shared lib **: ");
	bperr("    %s\n", obj_name.c_str());
	bperr("    at = %ld\n", regions[0].mapaddr);
      }
#endif
      
      for (int i=0; i < module.nregions; i++) {
	long newoffset = regions[i].mapaddr - regions[i].vaddr;
	if (newoffset != offset) {
	  bperr( "shared lib regions have different offsets\n");
	}
	regions[i].name = (long unsigned) readDataString(proc,
							 (void *) regions[i].name);
	// bperr("  region %d (%s) ", i, regions[i].name);
	// bperr("addr = %lx, ", regions[i].vaddr);
	// bperr("mapped at = %lx, ", regions[i].mapaddr);
	// bperr("size = %x\n", regions[i].size);
      }
      descs.push_back(fileDescriptor(obj_name, 
				     offset,
				     offset,
				     true));

      free(regions);
      assert(proc->readDataSpace((const void *) module.next,sizeof(ldr_module), &module,true));
    }
    return true;
}
Example #15
0
/*
 * BPatch_image::findVariable
 *
 * Returns a BPatch_variableExpr* representing the given variable in the
 * application image.  If no such variable exists, returns NULL.
 *
 * name		The name of the variable to look up.
 *
 * First look for the name with an `_' prepended to it, and if that is not
 *   found try the original name.
 */
BPatch_variableExpr *BPatch_image::findVariableInt(const char *name, bool showError)
{
    pdvector<int_variable *> vars;
    process *llproc = proc->llproc;

    if (!llproc->findVarsByAll(name, vars)) {
        // _name?
        pdstring under_name = pdstring("_") + pdstring(name);
        if (!llproc->findVarsByAll(under_name, vars)) {
            // "default Namespace prefix?
            if (defaultNamespacePrefix) {
                pdstring prefix_name = pdstring(defaultNamespacePrefix) + pdstring(".") + pdstring(name);
                if (!llproc->findVarsByAll(prefix_name, vars)) {
                    if (showError) {
                        pdstring msg = pdstring("Unable to find variable: ") + pdstring(prefix_name);
                        showErrorCallback(100, msg);
                    }
                    return NULL;
                }
            } else {
                if (showError) {
                    pdstring msg = pdstring("Unable to find variable: ") + pdstring(name);
                    showErrorCallback(100, msg);
                }
                return NULL;
            }
        }
    }
    assert(vars.size());

    if (vars.size() > 1) {
        cerr << "Warning: found multiple matches for var " << name << endl;
    }

    int_variable *var = vars[0];

    BPatch_variableExpr *bpvar = AddrToVarExpr->hash[var->getAddress()];
    if (bpvar) {
        return bpvar;
    }
    // XXX - should this stuff really be by image ??? jkh 3/19/99
    BPatch_Vector<BPatch_module *> *mods = getModules();
    BPatch_type *type = NULL;

    // XXX look up the type off of the int_variable's module
    BPatch_module *module = NULL;
    for (unsigned int m = 0; m < mods->size(); m++) {
        if( (*mods)[m]->lowlevel_mod() == var->mod() ) {
            module = (*mods)[m];
            break;
        }
    }
    if(module) {
        type = module->getModuleTypes()->findVariableType(name);
    }
    else {
        bperr("findVariable: failed look up module %s\n",
              var->mod()->fileName().c_str());
    }
    if(!type) {
        //  if we can't find the type in the module, check the other modules
        //  (fixes prob on alpha) --  actually seems like most missing types
        //  end up in DEFAULT_MODULE
        for (unsigned int m = 0; m < mods->size(); m++) {
            BPatch_module *tm = (*mods)[m];
            type = tm->getModuleTypes()->findVariableType(name);
            if (type) {
#if 0
                char buf1[1024], buf2[1024];
                tm->getName(buf1, 1024);
                module->getName(buf2, 1024);
                fprintf(stderr, "%s[%d]:  found type for %s in module %s, not %s\n", FILE__, __LINE__, name, buf2, buf1);
#endif
                break;
            }

        }

        if (!type) {
            char buf[128];
            sprintf(buf, "%s[%d]:  cannot find type for var %s\n", FILE__, __LINE__, name);
            BPatch_reportError(BPatchWarning, 0, buf);
            type = BPatch::bpatch->type_Untyped;
        }
    }

    char *nameCopy = strdup(name);
    assert(nameCopy);
    BPatch_variableExpr *ret = new BPatch_variableExpr((char *) nameCopy,
            proc, (void *)var->getAddress(),
            type);
    AddrToVarExpr->hash[var->getAddress()] = ret;
    return ret;
}