HANDLER_DEF_END

HANDLER_DEF_BEGIN(pop_rm1632_handler) {
  uint32_t prefixes = get_prefixes( &context->code, &context->eip );
  assert( context->code[0] == 0x8F );

  uint32_t displacement = INT32_MAX;
  uint32_t *dest;

  dest = (uint32_t *)get_rm( &context->code[1], context->general_purpose_registers, &displacement, table);

  switch( GETEXTOPCODE(context->code[1]) ) {
  case 6:
    {
      if ( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE ) {
        uint16_t *stack = (uint16_t *)get_real_address( context->esp, table, WRITE, false );
        *((uint16_t *)dest) = *stack;
        context->esp+=sizeof(uint16_t);
      } else {
        uint32_t *stack = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
        *dest = *stack;
        context->esp+=sizeof(uint32_t);
      }
      context->eip += displacement+1;
      context->code += displacement+1;
    }
    break;
  default:
    log_message( ERROR, "Undefined extended opcode for 0x8F (POP rm1632)");
    assert(0);
    break;
  }
}
Exemplo n.º 2
0
/* =============================================================================
 * ud_decode() - Instruction decoder. Returns the number of bytes decoded.
 * =============================================================================
 */
unsigned int ud_decode( struct ud* u )
{
  inp_start(u);

  if ( clear_insn( u ) ) {
    ; /* error */
  } else if ( get_prefixes( u ) != 0 ) {
    ; /* error */
  } else if ( search_itab( u ) != 0 ) {
    ; /* error */
  } else if ( do_mode( u ) != 0 ) {
    ; /* error */
  } else if ( disasm_operands( u ) != 0 ) {
    ; /* error */
  } else if ( resolve_mnemonic( u ) != 0 ) {
    ; /* error */
  }

  /* Handle decode error. */
  if ( u->error ) {
    /* clear out the decode data. */
    clear_insn( u );
    /* mark the sequence of bytes as invalid. */
    u->itab_entry = & ie_invalid;
    u->mnemonic = u->itab_entry->mnemonic;
  } 

  u->insn_offset = u->pc; /* set offset of instruction */
  u->insn_fill = 0;   /* set translation buffer index to 0 */
  u->pc += u->inp_ctr;    /* move program counter by bytes decoded */
  gen_hex( u );       /* generate hex code */

  /* return number of bytes disassembled. */
  return u->inp_ctr;
}
HANDLER_DEF_END
HANDLER_DEF_BEGIN(pop_r1632_handler) {
  uint32_t prefixes = get_prefixes( &context->code, &context->eip );

  uint32_t *stack = (uint32_t *)get_real_address( context->esp, table, WRITE, false );

  if( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE )
    context->esp+=sizeof(uint16_t);
  else
    context->esp+=sizeof(uint32_t);

  switch( context->code[0] ) {
  case 0x58:
  case 0x59:
  case 0x5A:
  case 0x5B:
  case 0x5C:
  case 0x5D:
  case 0x5E:
  case 0x5F:
    if( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE )
      *((uint16_t *)&GETREG(context,context->code[0]-0x58)) = *stack;
    else
      GETREG(context,context->code[0]-0x58) = *stack;
    break;
  default:
    log_message( ERROR, "Invalid opcode for POP r");
    assert(0);
    break;
  }

  context->eip++;
  context->code++;

}
HANDLER_DEF_END
  HANDLER_DEF_BEGIN(callpush_rm1632_handler) {
    uint32_t prefixes = get_prefixes( &context->code, &context->eip );
    assert( context->code[0] == 0xFF );

    uint32_t value;
    uint32_t displacement = INT32_MAX;
    unsigned char *dest;

    dest = (unsigned char*)get_rm( &context->code[1], context->general_purpose_registers, &displacement, table);
    value = *((uint32_t *)dest);

    if ( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE )
      value &= 0xFFFF;

    switch( GETEXTOPCODE(context->code[1]) ) {
    case 2:
      {
        dest = (unsigned char*)get_real_address(value, table, EXECUTE, false);
        if ( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE ) {
          context->esp-=sizeof(uint16_t);
          context->eip += displacement+1;
          uint16_t *stack = (uint16_t *)get_real_address( context->esp, table, WRITE, false );
          *stack = (uint16_t)context->eip;
        } else {
          context->esp-=sizeof(uint32_t);
          context->eip += displacement+1;
          uint32_t *stack = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
          *stack = context->eip;
        }
        context->eip = value;
        context->code = dest;
      }
      break;
    case 6:
      {
        if ( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE ) {
          context->esp-=sizeof(uint16_t);
          uint16_t *stack = (uint16_t *)get_real_address( context->esp, table, WRITE, false );
          *stack = (uint16_t)value;
        } else {
          context->esp-=sizeof(uint32_t);
          uint32_t *stack = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
          *stack = value;
        }
        context->eip += displacement+1;
        context->code += displacement+1;
      }
      break;
    default:
      log_message( ERROR, "Undefined extended opcode for 0xFF (CALL rm1632,PUSH rm1632)");
      assert(0);
      break;
    }
}
HANDLER_DEF_END
HANDLER_DEF_BEGIN(push_r1632_handler) {
  uint32_t prefixes = get_prefixes( &context->code, &context->eip );
  uint32_t to_push;
  switch( context->code[0] ) {
  case 0x50:
  case 0x51:
  case 0x52:
  case 0x53:
  case 0x54:
  case 0x55:
  case 0x56:
  case 0x57:
    to_push = GETREG(context,context->code[0]-0x50);
    break;
  case 0x0E:
    to_push = context->cs;
    break;
  case 0x16:
    to_push = context->ss;
    break;
  case 0x1E:
    to_push = context->ds;
    break;
  case 0x06:
    to_push = context->es;
    break;
  default:
    log_message( ERROR, "Invalid opcode for PUSH r1632");
    assert(0);
    break;
  }

  if( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE ) {
    context->esp-=sizeof(uint16_t);
    uint16_t *stack = (uint16_t *)get_real_address( context->esp, table, WRITE, false );
    *stack = to_push;
  } else {
    uint32_t *stack = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
    context->esp-=sizeof(uint32_t);
    *stack = to_push;
  }
  context->eip++;
  context->code++;
  
}
HANDLER_DEF_END
  HANDLER_DEF_BEGIN(jmp_rm1632_handler){
    uint32_t prefixes = get_prefixes( &context->code, &context->eip );
    uint32_t displacement;
    uint32_t dest_address;
    if( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE )
      dest_address = (int16_t)*((int16_t *)get_rm( &context->code[1], context->general_purpose_registers, &displacement, table));
    else
      dest_address = *((int32_t *)get_rm( &context->code[1], context->general_purpose_registers, &displacement, table));

    dest_address += context->eip + displacement + 1;
    unsigned char *dest = get_real_address( dest_address, table, EXECUTE, false );
    if( dest == NULL ) {
      log_message( ERROR, "Invalid destination address for JMP rm1632" );
      assert(0);
    }

    context->eip = dest_address;
    context->code = dest;
}
HANDLER_DEF_END

  HANDLER_DEF_BEGIN(push_imm1632_handler){
    uint32_t prefixes = get_prefixes( &context->code, &context->eip);
    assert( context->code[0] == 68 );

    if( prefixes & PREFIX_OPERAND_SIZE_OVERRIDE ){
      context->esp-=sizeof(uint16_t);
      uint32_t *dest = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
      *((uint16_t *)(dest)) = *((uint16_t *)(&context->code[1]));
      context->eip+=3;
      context->code+=3;
    } else {
      context->esp-=sizeof(uint32_t);
      uint32_t *dest = (uint32_t *)get_real_address( context->esp, table, WRITE, false );
      *dest = *((uint32_t *)(&context->code[1]));
      context->eip+=5;
      context->code+=5;
    }
}
int install_from_cwd(Options *op)
{
    Package *p;
    CommandList *c;
    int ret;
    int ran_pre_install_hook = FALSE;
    HookScriptStatus res;

    static const char* edit_your_xf86config =
        "Please update your XF86Config or xorg.conf file as "
        "appropriate; see the file /usr/share/doc/"
        "NVIDIA_GLX-1.0/README.txt for details.";

    /*
     * validate the manifest file in the cwd, and process it, building
     * a Package struct
     */
    
    if ((p = parse_manifest(op)) == NULL) goto failed;

    if (!op->x_files_packaged) {
        edit_your_xf86config = "";
    }

    ui_set_title(op, "%s (%s)", p->description, p->version);
    
    /* 
     * warn the user if "legacy" GPUs are installed in this system
     * and if no supported GPU is found, at all.
     */

    check_for_nvidia_graphics_devices(op, p);

    /* check that we are not running any X server */

    if (!check_for_running_x(op)) goto failed;

    /* make sure the kernel module is unloaded */
    
    if (!check_for_unloaded_kernel_module(op)) goto failed;
    
    /* ask the user to accept the license */
    
    if (!get_license_acceptance(op)) goto exit_install;
    
    ui_log(op, "Installing NVIDIA driver version %s.", p->version);

    /*
     * determine the current NVIDIA version (if any); ask the user if
     * they really want to overwrite the existing installation
     */

    if (!check_for_existing_driver(op, p)) goto exit_install;

    /*
     * check to see if an alternate method of installation is already installed
     * or is available, but not installed; ask the user if they really want to
     * install anyway despite the presence/availability of an alternate install.
     */

    if (!check_for_alternate_install(op)) goto exit_install;

    /* run the distro preinstall hook */

    res = run_distro_hook(op, "pre-install");
    if (res == HOOK_SCRIPT_FAIL) {
        if (ui_multiple_choice(op, CONTINUE_ABORT_CHOICES,
                               NUM_CONTINUE_ABORT_CHOICES,
                               CONTINUE_CHOICE, /* Default choice */
                               "The distribution-provided pre-install "
                               "script failed!  Are you sure you want "
                               "to continue?") == ABORT_CHOICE) {
            goto failed;
        }
    } else if (res == HOOK_SCRIPT_SUCCESS) {
        if (ui_multiple_choice(op, CONTINUE_ABORT_CHOICES,
                               NUM_CONTINUE_ABORT_CHOICES,
                               CONTINUE_CHOICE, /* Default choice */
                               "The distribution-provided pre-install script "
                               "completed successfully. If this is the first "
                               "time you have run the installer, this script "
                               "may have helped disable Nouveau, but a reboot "
                               "may be required first.  "
                               "Would you like to continue, or would you "
                               "prefer to abort installation to reboot the "
                               "system?") == ABORT_CHOICE) {
            goto exit_install;
        }
        ran_pre_install_hook = TRUE;
    }

    /* fail if the nouveau driver is currently in use */

    if (!check_for_nouveau(op)) goto failed;

    /* ask if we should install the UVM kernel module */

    should_install_uvm(op, p);

    /* attempt to build the kernel modules for the target kernel */

    if (!op->no_kernel_module) {
        if (!install_kernel_modules(op, p)) {
            goto failed;
        }
    } else {
        ui_warn(op, "You specified the '--no-kernel-module' command line "
                "option, nvidia-installer will not install a kernel "
                "module as part of this driver installation, and it will "
                "not remove existing NVIDIA kernel modules not part of "
                "an earlier NVIDIA driver installation.  Please ensure "
                "that an NVIDIA kernel module matching this driver version "
                "is installed seperately.");

        /* no_kernel_module should imply no DKMS */

        if (op->dkms) {
            ui_warn(op, "You have specified both the '--no-kernel-module' "
                    "and the '--dkms' command line options. The '--dkms' "
                    "option will be ignored.");
            op->dkms = FALSE;
        }
    }
    
    /*
     * if we are only installing the kernel module, then remove
     * everything else from the package; otherwise do some
     * OpenGL-specific stuff
     */

    if (op->kernel_module_only) {
        remove_non_kernel_module_files_from_package(op, p);
    } else {

        /* ask for the XFree86 and OpenGL installation prefixes. */
    
        if (!get_prefixes(op)) goto failed;

        /* ask if we should install the OpenGL header files */

        should_install_opengl_headers(op, p);

        /*
         * select the appropriate TLS class, modifying the package as
         * necessary.
         */
    
        select_tls_class(op, p);

        /*
         * if the package contains any libGL.la or .desktop files,
         * process them (perform some search and replacing so
         * that they reflect the correct installation path, etc)
         * and add them to the package list (files to be installed).
         */
        
        process_libGL_la_files(op, p);
        process_dot_desktop_files(op, p);

#if defined(NV_X86_64)
        /*
         * ask if we should install the 32bit compatibility files on
         * this machine.
         */

        should_install_compat32_files(op, p);
#endif /* NV_X86_64 */
    }

    if (op->no_opengl_files) {
        remove_opengl_files_from_package(op, p);
    }

    /*
     * now that we have the installation prefixes, build the
     * destination for each file to be installed
     */
    
    if (!set_destinations(op, p)) goto failed;

    /*
     * if we are installing OpenGL libraries, ensure that a symlink gets
     * installed to /usr/lib/libGL.so.1. add_libgl_abi_symlink() sets its own
     * destination, so it must be called after set_destinations().
     */
    if (!op->kernel_module_only && !op->no_opengl_files) {
        add_libgl_abi_symlink(op, p);
    }
    
    /*
     * uninstall the existing driver; this needs to be done before
     * building the command list.
     *
     * XXX if we uninstall now, then build the command list, and
     * then ask the user if they really want to execute the
     * command list, if the user decides not to execute the
     * command list, they'll be left with no driver installed.
     */

    if (!op->kernel_module_only) {
        if (!run_existing_uninstaller(op)) goto failed;
    }

    if (!check_libglvnd_files(op, p)) {
        goto failed;
    }

    /* build a list of operations to execute to do the install */
    
    if ((c = build_command_list(op, p)) == NULL) goto failed;

    /* call the ui to get approval for the list of commands */
    
    if (!ui_approve_command_list(op, c, "%s", p->description)) {
        goto exit_install;
    }
    
    /* initialize the backup log file */

    if (!op->kernel_module_only) {
        if (!init_backup(op, p)) goto failed;
    }

    /* execute the command list */

    if (!do_install(op, p, c)) goto failed;

    /* Register, build, and install the module with DKMS, if requested */

    if (op->dkms && !dkms_install_module(op, p->version, get_kernel_name(op)))
        goto failed;

    /*
     * Leave the RM loaded in case an X server with OutputClass-based driver
     * matching is being used.
     */

    if (!op->no_kernel_module || op->dkms) {
        if (!load_kernel_module(op, p->kernel_modules[0].module_name)) {
            goto failed;
        }
    }

    /* run the distro postinstall script */

    run_distro_hook(op, "post-install");

    /*
     * check that everything is installed properly (post-install
     * sanity check)
     */

    check_installed_files_from_package(op, p);

    if (!check_runtime_configuration(op, p)) goto failed;
    
    /* done */

    if (op->kernel_module_only || op->no_nvidia_xconfig_question) {

        ui_message(op, "Installation of the kernel module for the %s "
                   "(version %s) is now complete.",
                   p->description, p->version);
    } else {
        
        /* ask the user if they would like to run nvidia-xconfig */
        
        const char *msg = "Would you like to run the nvidia-xconfig utility "
                          "to automatically update your X configuration file "
                          "so that the NVIDIA X driver will be used when you "
                          "restart X?  Any pre-existing X configuration "
                          "file will be backed up.";
        
        ret = run_nvidia_xconfig(op, FALSE, msg, op->run_nvidia_xconfig);
        
        if (ret) {
            ui_message(op, "Your X configuration file has been successfully "
                       "updated.  Installation of the %s (version: %s) is now "
                       "complete.", p->description, p->version);
        } else {
            ui_message(op, "Installation of the %s (version: %s) is now "
                       "complete.  %s", p->description,
                       p->version, edit_your_xf86config);
        }
    }
    
    free_package(p);

    return TRUE;
    
 failed:

    /*
     * something bad happened during installation; print an error
     * message and return FALSE
     */
    
    if (op->logging) {
        ui_error(op, "Installation has failed.  Please see the file '%s' "
                 "for details.  You may find suggestions on fixing "
                 "installation problems in the README available on the "
                 "Linux driver download page at www.nvidia.com.",
                 op->log_file_name);
    } else {
        ui_error(op, "Installation has failed.  You may find suggestions "
                 "on fixing installation problems in the README available "
                 "on the Linux driver download page at www.nvidia.com.");
    }

    if (ran_pre_install_hook)
        run_distro_hook(op, "failed-install");

    /* fall through into exit_install... */

 exit_install:

    /*
     * we are exiting installation; this can happen for reasons that
     * do not merit the error message (e.g., the user declined the
     * license agreement)
     */
    
    free_package(p);
    
    return FALSE;

} /* install_from_cwd() */