Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

terminat0r



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
 
#!/usr/bin/perl -w
#
# (C) Copyright M. D Mackey 2004. This program may be freely modified and redistributed,  
# but I would appreciate feedback to mark\@swallowtail\.org.
#
# A short program to patch an executable compiled with the Intel Fortran Compiler.
# Run with -h for help/
#
# The patch removes the check for the string "GenuineIntel" in the  
# CPUID flags of the processor, thus making SSE/SSE2 code work on AMD chips that
# support it.
#
# Tested on executables compiled with compiler versions 7.1.040, 8.1.028 and 9.0.024,  
# and should work on other builds.
#
# Creates a backup file before changing anything, so should be easy to undo if
# things go wrong.
#
# If you want to check for a successful patch, do
#
# objdump -d <executable>~ > old
# objdump -d <executable> > new
#  
# and examine the differences between 'old' and 'new'. Three lines
# should have changed in __intel_cpu_indicator_init:
#
# 81 fa 47 65 6e 75          cmp    $0x756e6547,%edx
# ...
# 81 fa 69 6e 65 49          cmp    $0x49656e69,%edx
# ...
# 81 fa 6e 74 65 6c          cmp    $0x6c65746e,%edx
#
# (these check for "GenuineIntel"). These lines should all be changed to  
# f7 c2 00 00 00 00          testl  $0x00000000,%edx
#
# (the registers might be %eax, %ebx, %ecx or %edx, depending on compiler version)
 
use strict;
use Getopt::Std;
 
# Handle options
my(%opts);
my($ok)=getopts('Hhb:v',\%opts);
usage() if ($opts{h} or $opts{H} or !$ok or !@ARGV);
my($backup)="~";
$backup=$opts{b} if ($opts{b});
my($verbose)=$opts{v};
 
my($file);
foreach $file (@ARGV) {
  print STDERR "Patching file $_...\n" if ($verbose);
   
  # Check backup file
  if ($backup and -e "$file$backup") {
    warn("Error: backup file '$file$backup' for '$file' already exists, so not patching!");
    next;
  }
 
  open(FILE,$file) or die("Couldn't open file '$file': $!");
  binmode(FILE);
  my($contents)=join('',<FILE>); # Shlurp up file into one long binary string
  close(FILE);
 
  my($unp)=unpack('H*',$contents); # Unpack into a sequence of hex bytes
 
  my($count);
 
  # Try patching "cmp    $0x756e6547,%eax" to "test   $0x00000000,%eax" etc
  $count+=($unp=~s/3d47656e75/a900000000/g);
  $count+=($unp=~s/3d696e6549/a900000000/g);
  $count+=($unp=~s/3d6e74656c/a900000000/g);
 
  # Now try patching "cmp    $0x756e6547,%ebx" to "testl  $0x00000000,%ebx" etc
  $count+=($unp=~s/81fb47656e75/f7c300000000/g);
  $count+=($unp=~s/81fb696e6549/f7c300000000/g);
  $count+=($unp=~s/81fb6e74656c/f7c300000000/g);
 
  # Now try patching "cmp    $0x756e6547,%ecx" to "testl  $0x00000000,%ecx" etc
  $count+=($unp=~s/81f947656e75/f7c100000000/g);
  $count+=($unp=~s/81f9696e6549/f7c100000000/g);
  $count+=($unp=~s/81f96e74656c/f7c100000000/g);
 
  # Now try patching "cmp    $0x756e6547,%edx" to "testl  $0x00000000,%edx" etc
  $count+=($unp=~s/81fa47656e75/f7c200000000/g);
  $count+=($unp=~s/81fa696e6549/f7c200000000/g);
  $count+=($unp=~s/81fa6e74656c/f7c200000000/g);
 
  # Now try patching "cmp    $0x756e6547,%ebp" to "testl  $0x00000000,%ebp" etc
  $count+=($unp=~s/81fd47656e75/f7c500000000/g);
  $count+=($unp=~s/81fd696e6549/f7c500000000/g);
  $count+=($unp=~s/81fd6e74656c/f7c500000000/g);
 
  # Now try patching "cmp    $0x756e6547,%esi" to "testl  $0x00000000,%esi" etc
  $count+=($unp=~s/81fe47656e75/f7c600000000/g);
  $count+=($unp=~s/81fe696e6549/f7c600000000/g);
  $count+=($unp=~s/81fe6e74656c/f7c600000000/g);
 
  # Now try patching "cmp    $0x756e6547,%edi" to "testl  $0x00000000,%edi" etc
  $count+=($unp=~s/81ff47656e75/f7c700000000/g);
  $count+=($unp=~s/81ff696e6549/f7c700000000/g);
  $count+=($unp=~s/81ff6e74656c/f7c700000000/g);
 
#intel ifort 11.1 compiler
#  52cfb8:       81 7d f0 47 65 6e 75    cmpl   $0x756e6547,-0x10(%rbp)
#  52cfbf:       75 16                   jne    52cfd7 <__intel_cpu_indicator_init+0x97>
#  52cfc1:       81 7d e8 69 6e 65 49    cmpl   $0x49656e69,-0x18(%rbp)
#  52cfc8:       75 0d                   jne    52cfd7 <__intel_cpu_indicator_init+0x97>
#  52cfca:       81 7d e0 6e 74 65 6c    cmpl   $0x6c65746e,-0x20(%rbp)
#  52cfd1:       75 04                   jne    52cfd7 <__intel_cpu_indicator_init+0x97>
  $count+=($unp=~s/817df047656e75/f745f000000000/g);
  $count+=($unp=~s/817de8696e6549/f745e800000000/g);
  $count+=($unp=~s/817de06e74656c/f745e000000000/g);
 
 
 
  next if (!$count); # Don't patch if no substitutions made
  if ($count % 3) {  # Number of substitutions must be a multiple of 3!
    warn "WARNING: $count lines were to be patched in '$file': should be a multiple of 3! Skipping this file.\n";
    next;
  }
  print STDERR "Patching $file in $count places...";
  die "Error: wanted to create temp file '$file.$$.tmp' but it already exists!" if (-e "$file.$$.tmp");
  open(OUTPUT,">$file.$$.tmp") or die("Can't create temporary output file '$file.$$.tmp':$!");
  binmode(OUTPUT);
  print OUTPUT pack('H*',$unp);
  close(OUTPUT) or die "Can't close file '$file.$$.tmp'";
 
  `chmod --reference="$file" "$file.$$.tmp"`; # chmod to original file's mode
 
  # Rename original file to backup
  if ($backup) {
    rename($file,"$file$backup") or die("Couldn't rename '$file' to '$file$backup': $!\n");
  }
  rename("$file.$$.tmp",$file) or die("Couldn't rename '$file.$$.tmp' to '$file': $!\n");
  if ($backup) {
    print STDERR "Patch operation for '$file' successful, original file at '$file$backup'\n" if ($verbose);
  } else {
    print STDERR "Patch operation for '$file' successful, no backup created\n" if ($verbose);
  }
}
exit(0);
 
sub usage {
  print STDERR <<EOUSAGE;
 
Usage: intel_check_executable_patch.pl [options] <filename> [<filename>...]
 
Options:
    -b <suffix>    Use the supplied suffix to name the backup file. The
            default is '~', and setting this to '' disables backups.
    -v         Be more verbose.
 
Some versions of the Intel Fortran Compiler produce code which checks whether
the CPU is made by Intel or not, and disables MMX/SSE/SSE2 code if it isn't.  
This program patches executables produced by the Intel compiler to remove this  
check, so that e.g. programs compiled with -axW will use SSE2 code on Athlon  
64 chips.
 
This script was tested against ifc versions 7.1.040, 8.1.028 and 9.0.024 and  
should work on other version 7 to 9 releases.  The patch process will almost
certainly work with executables compiled with the Intel C compiler as well, and
with Windows executables as well as Linux binaries, but has not been extensively  
tested on these, so be careful! If you do test this on icc-compiled
executables, then please let me know how it goes!
 
Patched files are backed up (by default to 'filename~'), see the -b flag to  
change this.
 
This program is provided with NO WARRANTY: please check that the patched executables
behaves as you would expect! I can't really foresee any problems that could reasonably
be caused by the use of this patch, but you never know .
 
# If you want to check for a successful patch, do
#
# objdump -d <executable>~ > old
# objdump -d <executable> > new
#  
# and examine the differences between 'old' and 'new'. Three lines
# should have changed in __intel_cpu_indicator_init:
#
# 81 fa 47 65 6e 75          cmp    $0x756e6547,%edx
# ...
# 81 fa 69 6e 65 49          cmp    $0x49656e69,%edx
# ...
# 81 fa 6e 74 65 6c          cmp    $0x6c65746e,%edx
#
# (these check for "GenuineIntel"). These lines should all be changed to  
# f7 c2 00 00 00 00          testl  $0x00000000,%edx
#
# (the registers might be %eax, %ebx, %ecx or %edx, depending on compiler version)
 
 
EOUSAGE
  exit(1);
}
 
 


Всего записей: 2084 | Зарегистр. 31-03-2002 | Отправлено: 13:23 26-04-2010
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru