Example #1
0
// hasBeenBound: returns true if the runtime linker has bound the
// function symbol corresponding to the relocation entry in at the address
// specified by entry and base_addr.  If it has been bound, then the callee 
// function is returned in "target_pdf", else it returns false.
bool PCProcess::hasBeenBound(const relocationEntry &entry, 
			   func_instance *&target_pdf, Address base_addr) {

    if (isTerminated()) return false;

    // if the relocationEntry has not been bound yet, then the value
    // at rel_addr is the address of the instruction immediately following
    // the first instruction in the PLT entry (which is at the target_addr) 
    // The PLT entries are never modified, instead they use an indirrect 
    // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the 
    // function symbol is bound by the runtime linker, it changes the address
    // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry

    Address got_entry = entry.rel_addr() + base_addr;
    Address bound_addr = 0;
    if(!readDataSpace((const void*)got_entry, sizeof(Address), 
			&bound_addr, true)){
        sprintf(errorLine, "read error in process::hasBeenBound addr 0x%x, pid=%d\n (readDataSpace returns 0)",(unsigned)got_entry,getPid());
	logLine(errorLine);
	print_read_error_info(entry, target_pdf, base_addr);
        return false;
    }

    if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
        // the callee function has been bound by the runtime linker
	// find the function and return it
        target_pdf = findOneFuncByAddr(bound_addr);
	if(!target_pdf){
            return false;
	}
        return true;	
    }
    return false;
}
Example #2
0
void print_read_error_info(const relocationEntry entry, 
      func_instance *&target_pdf, Address base_addr) {

    sprintf(errorLine, "  entry      : target_addr 0x%x\n",
	    (unsigned)entry.target_addr());
    logLine(errorLine);
    sprintf(errorLine, "               rel_addr 0x%x\n", (unsigned)entry.rel_addr());
    logLine(errorLine);
    sprintf(errorLine, "               name %s\n", (entry.name()).c_str());
    logLine(errorLine);

    if (target_pdf) {
      sprintf(errorLine, "  target_pdf : symTabName %s\n",
	      (target_pdf->symTabName()).c_str());
      logLine(errorLine);    
      sprintf(errorLine , "              prettyName %s\n",
	      (target_pdf->symTabName()).c_str());
      logLine(errorLine);
      /*
      // Size bad. <smack>
      sprintf(errorLine , "              size %i\n",
      target_pdf->getSize());
      logLine(errorLine);
      */
      sprintf(errorLine , "              addr 0x%x\n",
	      (unsigned)target_pdf->addr());
      logLine(errorLine);
    }
    sprintf(errorLine, "  base_addr  0x%x\n", (unsigned)base_addr);
    logLine(errorLine);
}
Example #3
0
/* Required by linux.C */
bool process::hasBeenBound( const relocationEntry &entry, int_function * & target_pdf, Address base_addr ) {
  /* A PLT entry always looks up a function descriptor in the FD table in the .IA_64.pltoff section; if
     the function hasn't been bound yet, that FD's function pointer will point to another PLT entry.
     (Which will jump to the first, special PLT entry that calls the linker.) 
	   
     The relocation entry points directly to the descriptor, so only a single indirection is necessary. */
	   
  Address gotAddress = entry.rel_addr() + base_addr;
  assert( gotAddress % 16 == 0 );
  // /* DEBUG */ fprintf( stderr, "hasBeenBound(): checking entry at 0x%lx\n", gotAddress );

  Address functionAddress;
  if( ! this->readDataSpace( (const void *)gotAddress, 8, (void *) & functionAddress, true ) ) {
    fprintf( stderr, "%s: failed to read from GOT (0x%lx)\n", __FUNCTION__, gotAddress );
    return false;
  }
  // /* DEBUG */ fprintf( stderr, "hasBeenBound(): checking function address 0x%lx\n", functionAddress );
	
  /* Do the look up.  We're skipping a potential optimization here (checking to see if
     functionAddress is in the PLT first) for simplicitly. */
  target_pdf = this->findFuncByAddr( functionAddress );
  // /* DEBUG */ fprintf( stderr, "hasBeenBound(): found int_function at %p\n", target_pdf );
  return ( target_pdf != NULL );
} /* end hasBeenBound() */
Example #4
0
bool emitElfUtils::updateRelocation(Symtab *obj, relocationEntry &rel, int library_adjust) {
    // Currently, only verified on x86 and x86_64 -- this may work on other architectures
    Region *targetRegion = obj->findEnclosingRegion(rel.rel_addr());
    if( NULL == targetRegion ) {
        rewrite_printf("Failed to find enclosing Region for relocation");
        return false;
    }

    // Used to update a Region
    /*switch( rel.getCategory( obj->getAddressWidth() ))
    {
        case relocationEntry::relative:
            rel.setAddend(rel.addend() + library_adjust);
            break;

        case relocationEntry::jump_slot:
            if( !adjustValInRegion(targetRegion,
                        rel.rel_addr() - targetRegion->getDiskOffset(),
                        addressWidth, library_adjust) )
            {
                rewrite_printf("Failed to update relocation\n");
                return false;
            }
            break;

        case relocationEntry::absolute:
            break;

        default:
            fprintf(stderr, "Undefined relocation category.\n");
            assert(0);
    }*/

    unsigned addressWidth = obj->getAddressWidth();
    if( addressWidth == 8 ) {
        switch(rel.getRelType()) {
            case R_AARCH64_RELATIVE:
                rel.setAddend(rel.addend() + library_adjust);
                break;
            case R_AARCH64_JUMP_SLOT:
                if( !adjustValInRegion(targetRegion,
                           rel.rel_addr() - targetRegion->getDiskOffset(),
                           addressWidth, library_adjust) )
                {
                    rewrite_printf("Failed to update relocation\n");
                    return false;
                }
                break;
            case R_AARCH64_GLOB_DAT:
                break;
            default:
                //fprintf(stderr, "Unimplemented relType for architecture: %d\n", rel.getRelType());
                //assert(0);
                break;
        }
    }

    // XXX The GOT also holds a pointer to the DYNAMIC segment -- this is currently not
    // updated. However, this appears to be unneeded for regular shared libraries.

    // From the SYS V ABI x86 supplement
    // "The table's entry zero is reserved to hold the address of the dynamic structure,
    // referenced with the symbol _DYNAMIC. This allows a program, such as the
    // dynamic linker, to find its own dynamic structure without having yet processed
    // its relocation entries. This is especially important for the dynamic linker, because
    // it must initialize itself without relying on other programs to relocate its memory
    // image."

    // In order to implement this, would have determine the final address of a new .dynamic
    // section before outputting the patched GOT data -- this will require some refactoring.

    //rewrite_printf("WARNING: updateRelocation is not implemented on this architecture\n");
    //(void) obj; (void) rel; (void) library_adjust; //silence warnings

    return true;
}