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; } }
/* ============================================================================= * 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() */