İkili Linux'ta SSE4 veya AVX gerektirip gerektirmediğini kontrol etme


20

Linux'ta, /proc/cpuinfomakinenin sahip olduğu tüm CPU bayraklarını basit bir şekilde kontrol etmenizi sağlar.
Genellikle, bir program bir makinenin komut kümesinin üst kümesini gerektiriyorsa, bunu belirlemenin en kolay yolu programı çalıştırmak ve bir SIGILLsinyal yükseltip yükseltmediğini görmektir .

Ama benim durumumda, tüm işlemcilerim en az SSE4.1 ve AVX'i destekliyor.
Yani, bir ikili içinde özel talimatlar olup olmadığını kontrol etmenin basit bir yolu var mı?


Belki hangi komut setlerinin etkinleştirileceğini seçmenize izin veren emülatörler vardır. QEMU şu anda AVX'i desteklemediğinden, burada beklendiği gibi "çalışmayabilir": superuser.com/questions/453786/how-do-i-get-avx-support-in-qemu || superuser.com/questions/548740/…
Ciro Santilli 事件 改造 中心 法轮功 六四 事件

2
objdump --disassemblesökme işlemini gerçekleştirir. objdumpAnımsatıcıların bir listesini oluşturmak için kullanabilirsiniz . Binutils'in bir parçası olduğu için GNU Linux sistemlerinde kullanılabilir. Ayrıca, ek talimatlar mevcut olabilir ama olmayabilir yürütülecek. Programın çalışma zamanı korumaları olabilir.
jww

@jww: heemm, evet ama montajda programlamak için 600'den fazla opcode öğrenmekle ilgili değil, her yerde yürütülebilir bir dosyaya sahip olmaktan rahatsız oluyorum.
user2284570

Neyi kullanabileceğinizi (ve kullanamayacağınızı) öğrenmek zorundasınız. Bu sizin sorumluluğunuzda. -mavxDerleyicinin yalnızca AVX ISA'dan seçilmesini sağlamak için derleme yapabileceğinizi düşünüyoruz , ancak onu kaldırmanın yolları var. Örneğin, satır içi derleyici genellikle derleyicinin ISA denetimlerini kaldırır.
jww

@jww: ve ikili dosya kapalı bir kaynaksa (bir anlamda kaynak kodu oluşturulduktan sonra silinirse) özel bir komut dosyası / derleyici tarafından paylaşılan nesne oluşturma?
user2284570

Yanıtlar:


11

Rust'da bunu yapmaya çalışan bir program çektim. Belgesiz ve çok kırılgan olmasına rağmen işe yaradığını düşünüyorum:

https://github.com/pkgw/elfx86exts

Örnek kullanım:

$ cd elfx86exts
$ cargo build
[things happen]
$ cargo run -- /bin/ls
   Compiling elfx86exts v0.1.0 (file:///home/peter/sw/elfx86exts)
    Finished dev [unoptimized + debuginfo] target(s) in 1.9 secs
     Running `target/debug/elfx86exts /bin/ls`
MODE64
CMOV
SSE2
SSE1

Bu paketten (sürüm: 1.8.0-5) libtensorflow.so (sha224: 8f665acf0f455d5056014dfa2d48c22ab6cf83eb073842e8304878d0) üzerinde çalıştırmayı denedim ve tüm bilgisayarımı dondu.
Philippe

@Philippe Lütfen GitHub'da sorun açın! Bu tür konuları tartışmak için daha iyi bir yer olduğunu düşünüyorum.
Peter

Tamam, github'ınızda bir sorun yarattım.
Philippe

18

GCC optimizasyon süreçlerini anlamaya ve bu işlem sırasında hangi talimatların kullanıldığını veya kullanılmadığını öğrenmeye çalışırken aynı soruna çarptım. Çok sayıda çalışma kodu ile dost olmadığım için, demonte koddaki belirli (örneğin SSE3) talimatları görselleştirmenin veya en azından bu talimatların olup olmadığı ve kaç tane gibi minimum istatistik yazdırmanın bir yolunu arıyordum ikili.

Mevcut bir çözüm bulamadım, ancak Jonathan Ben-Avraham'ın cevabı, büyük (ve hatta kısmen yapılandırılmış) bir işletme kodu kaynağına işaret ettiği için çok yararlı oldu. Bu verilere dayanarak, belirli komut kümelerini görselleştirebilen veya grepçıktısıyla beslendiğinde bunlarla ilgili istatistikleri yazdırabilen bir Bash komut dosyası yazdım objdump.

İşlem kodlarının listesi, daha sonra basitçe adlandırdığım ana dosyaya (daha iyi okunabilirlik amacıyla) dahil olan bağımsız bir Bash komut dosyasına dönüştürüldü opcode. İçinde işlem kodları yana gas.vim( Shirk en vimsözdizimi tanımları Jonathan'ın cevabını,) sistematik olarak farklı CPU mimarileri göre (görünüşte) gruplandırıldı, bu bölünmeyi korumak ve bir yapmaya çalıştı Mimarlık> komut kümesi eşlemesi; Şimdi bunun iyi bir fikir olup olmadığından emin değilim. Haritalama doğru değil ve hatta orijinalinde bazı değişiklikler yapmak zorunda kaldımgas.vimgruplama. Mimariyle ilgili öğretim setleri benim asıl amacım olmadığından, sadece internette açıklanan büyük mimarilerin öğretim setlerini oluşturmaya çalıştım, ancak üreticilerin belgelerine başvurmadan. AMD mimarileri benim için hiç güvenilir görünmüyor (3DNow! Ve SSE5 gibi komut setleri hariç). Bununla birlikte, bir başkasının incelemesi ve düzeltmesi / iyileştirmesi ve diğerlerine bazı belirsiz sonuçlar vermesi için çeşitli mimarilerin talimat setleri kodunu burada bırakmaya karar verdim.

Adlı ana dosyanın başlangıcı opcode:

#!/bin/bash
#
# Searches disassembled code for specific instructions.
#
# Opcodes obtained from: https://github.com/Shirk/vim-gas/blob/master/syntax/gas.vim
#
# List of opcodes has been obtained using the following commands and making a few modifications:
#   echo '#!/bin/bash' > Opcode_list
#   wget -q -O- https://raw.githubusercontent.com/Shirk/vim-gas/master/syntax/gas.vim \
#    | grep -B1 -E 'syn keyword gasOpcode_|syn match   gasOpcode' | \
#    sed -e '/^--$/d' -e 's/"-- Section:/\n#/g' \
#    -e 's/syn keyword gasOpcode_\([^\t]*\)*\(\t\)*\(.*\)/Opcode_\1="\${Opcode_\1} \3"/g' \
#    -e 's/Opcode_PENT_3DNOW/Opcode_ATHLON_3DNOW/g' -e 's/\\//g' \
#    -e 's/syn match   gasOpcode_\([^\t]*\)*.*\/<\(.*\)>\//Opcode_\1="\${Opcode_\1} \2"/g' \
#    >> Opcode_list
#
# Modify file Opcode_list replacing all occurrences of:
#   * Opcode_Base within the section "Tejas New Instructions (SSSE3)" with Opcode_SSSE3
#   * Opcode_Base within the section "Willamette MMX instructions (SSE2 SIMD Integer Instructions)"
#                                        with Opcode_WILLAMETTE_Base

# return values
EXIT_FOUND=0
EXIT_NOT_FOUND=1
EXIT_USAGE=2

# settings
InstSet_Base=""
Recursive=false
Count_Matching=false
Leading_Separator='\s'
Trailing_Separator='(\s|$)' # $ matches end of line for non-parametric instructions like nop
Case_Insensitive=false
Invert=false
Verbose=false
Stop_After=0
Line_Numbers=false
Leading_Context=0
Trailing_Context=0

source Opcode_list   # include opcodes from a separate file

# GAS-specific opcodes (unofficial names) belonging to the x64 instruction set.
# They are generated by GNU tools (e.g. GDB, objdump) and specify a variant of ordinal opcodes like NOP and MOV.
# If you do not want these opcodes to be recognized by this script, comment out the following line.
Opcode_X64_GAS="nopw nopl movabs"


# instruction sets
InstSet_X86="8086_Base 186_Base 286_Base 386_Base 486_Base PENT_Base P6_Base KATMAI_Base WILLAMETTE_Base PENTM_Base"
InstSet_IA64="IA64_Base"
InstSet_X64="PRESCOTT_Base X64_Base X86_64_Base NEHALEM_Base X64_GAS"
InstSet_MMX="PENT_MMX KATMAI_MMX X64_MMX"
InstSet_MMX2="KATMAI_MMX2"
InstSet_3DNOW="ATHLON_3DNOW"
InstSet_SSE="KATMAI_SSE P6_SSE X64_SSE"
InstSet_SSE2="SSE2 X64_SSE2"
InstSet_SSE3="PRESCOTT_SSE3"
InstSet_SSSE3="SSSE3"
InstSet_VMX="VMX X64_VMX"
InstSet_SSE4_1="SSE41 X64_SSE41"
InstSet_SSE4_2="SSE42 X64_SSE42"
InstSet_SSE4A="AMD_SSE4A"
InstSet_SSE5="AMD_SSE5"
InstSet_FMA="FUTURE_FMA"
InstSet_AVX="SANDYBRIDGE_AVX"

InstSetDep_X64="X86"
InstSetDep_MMX2="MMX"
InstSetDep_SSE2="SSE"
InstSetDep_SSE3="SSE2"
InstSetDep_SSSE3="SSE3"
InstSetDep_SSE4_1="SSSE3"
InstSetDep_SSE4_2="SSE4_1"
InstSetDep_SSE4A="SSE3"
InstSetDep_SSE5="FMA AVX" # FIXME not reliable

InstSetList="X86 IA64 X64 MMX MMX2 3DNOW SSE SSE2 SSE3 SSSE3 VMX SSE4_1 SSE4_2 SSE4A SSE5 FMA AVX"


# architectures
Arch_8086="8086_Base"
Arch_186="186_Base"
Arch_286="286_Base"
Arch_386="386_Base"
Arch_486="486_Base"
Arch_Pentium="PENT_Base PENT_MMX" # Pentium = P5 architecture
Arch_Athlon="ATHLON_3DNOW"
Arch_Deschutes="P6_Base P6_SSE" # Pentium II
Arch_Katmai="KATMAI_Base KATMAI_MMX KATMAI_MMX2 KATMAI_SSE" # Pentium III
Arch_Willamette="WILLAMETTE_Base SSE2" # original Pentium IV (x86)
Arch_PentiumM="PENTM_Base"
Arch_Prescott="PRESCOTT_Base X64_Base X86_64_Base X64_SSE2 PRESCOTT_SSE3 VMX X64_VMX X64_GAS" # later Pentium IV (x64) with SSE3 (Willamette only implemented SSE2 instructions) and VT (VT-x, aka VMX)
Arch_P6=""
Arch_Barcelona="ATHLON_3DNOW AMD_SSE4A"
Arch_IA64="IA64_Base" # 64-bit Itanium RISC processor; incompatible with x64 architecture
Arch_Penryn="SSSE3 SSE41 X64_SSE41" # later (45nm) Core 2 with SSE4.1
Arch_Nehalem="NEHALEM_Base SSE42 X64_SSE42" # Core i#
Arch_SandyBridge="SANDYBRIDGE_AVX"
Arch_Haswell="FUTURE_FMA"
Arch_Bulldozer="AMD_SSE5"

ArchDep_8086=""
ArchDep_186="8086"
ArchDep_286="186"
ArchDep_386="286"
ArchDep_486="386"
ArchDep_Pentium="486"
ArchDep_Athlon="Pentium" # FIXME not reliable
ArchDep_Deschutes="Pentium"
ArchDep_Katmai="Deschutes"
ArchDep_Willamette="Katmai"
ArchDep_PentiumM="Willamette" # FIXME Pentium M is a Pentium III modification (with SSE2). Does it support also WILLAMETTE_Base instructions?
ArchDep_Prescott="Willamette"
ArchDep_P6="Prescott" # P6 started with Pentium Pro; FIXME Pentium Pro did not support MMX instructions (introduced again in Pentium II aka Deschutes)
ArchDep_Barcelona="Prescott" # FIXME not reliable
ArchDep_IA64=""
ArchDep_Penryn="P6"
ArchDep_Nehalem="Penryn"
ArchDep_SandyBridge="Nehalem"
ArchDep_Haswell="SandyBridge"
ArchDep_Bulldozer="Haswell" # FIXME not reliable

ArchList="8086 186 286 386 486 Pentium Athlon Deschutes Katmai Willamette PentiumM Prescott P6 Barcelona IA64 Penryn Nehalem SandyBridge Haswell Bulldozer"

27 Ekim 2014 tarihinden itibaren Opcode_listverilen talimatlar kullanılarak oluşturulan ve değiştirilen bir dosya örneği http://pastebin.com/yx4rCxqs adresindeopcode bulunabilir . Bu dosyayı doğrudan satır yerine ekleyebilirsiniz . Stack Exchange bana böyle büyük bir cevap göndermeme izin vermedi çünkü bu kodu koydu.opcodesource Opcode_list

Son olarak, opcodegerçek mantığa sahip dosyanın geri kalanı :

usage() {
    echo "Usage: $0 OPTIONS"
    echo ""
    echo "  -r      set instruction sets recursively according to dependency tree (must precede -a or -s)"
    echo "  -a      set architecture"
    echo "  -s      set instruction set"
    echo "  -L      show list of available architectures"
    echo "  -l      show list of available instruction sets"
    echo "  -i      show base instruction sets of current instruction set (requires -a and/or -s)"
    echo "  -I      show instructions in current instruction set (requires -a and/or -s)"
    echo "  -c      print number of matching instructions instead of normal output"
    echo "  -f      find instruction set of the following instruction (regex allowed)"
    echo "  -d      set leading opcode separator (default '$Leading_Separator')"
    echo "  -D      set trailing opcode separator (default '$Trailing_Separator')"
    echo "  -C      case-insensitive"
    echo "  -v      invert the sense of matching"
    echo "  -V      print all lines, not just the highlighted"
    echo "  -m      stop searching after n matched instructions"
    echo "  -n      print line numbers within the original input"
    echo "  -B      print n instructions of leading context"
    echo "  -A      print n instructions of trailing context"
    echo "  -h      print this help"
    echo
    echo "Multiple architectures and instruction sets can be used."
    echo
    echo "Typical usage is:"
    echo "  objdump -M intel -d FILE | $0 OPTIONS"
    echo "  objdump -M intel -d FILE | $0 -s SSE2 -s SSE3 -V                    Highlight SSE2 and SSE3 within FILE."
    echo "  objdump -M intel -d FILE | tail -n +8 | $0 -r -a Haswell -v -m 1    Find first unknown instruction."
    echo "  $0 -C -f ADDSD                                                      Find which instruction set an opcode belongs to."
    echo "  $0 -f .*fma.*                                                       Find all matching instructions and their instruction sets."
    echo
    echo "The script uses Intel opcode syntax. When used in conjunction with objdump, \`-M intel' must be set in order to prevent opcode translation using AT&T syntax."
    echo
    echo "BE AWARE THAT THE LIST OF KNOWN INSTRUCTIONS OR INSTRUCTIONS SUPPORTED BY PARTICULAR ARCHITECTURES (ESPECIALLY AMD'S) IS ONLY TENTATIVE AND MAY CONTAIN MISTAKES!"
    kill -TRAP $TOP_PID
}

list_contains() {   # Returns 0 if $2 is in array $1, 1 otherwise.
    local e
    for e in $1; do
        [ "$e" = "$2" ] && return 0
    done
    return 1
}

build_instruction_set() {   # $1 = enum { Arch, InstSet }, $2 = architecture or instruction set as obtained using -L or -l, $3 = "architecture"/"instruction set" to be used in error message
    local e
    list_contains "`eval echo \\\$${1}List`" "$2" || (echo "$2 is not a valid $3."; usage)      # Test if the architecture/instruction set is valid.
    if [ -n "`eval echo \\\$${1}_${2}`" ]; then                                                 # Add the instruction set(s) if any.
        for e in `eval echo \\\$${1}_${2}`; do                                                  # Skip duplicates.
            list_contains "$InstSet_Base" $e || InstSet_Base="$e $InstSet_Base"
        done
    fi
    if [ $Recursive = true ]; then
        for a in `eval echo \\\$${1}Dep_$2`; do
            build_instruction_set $1 $a "$3"
        done
    fi
    InstSet_Base="`echo $InstSet_Base | sed 's/$ *//'`"                                         # Remove trailing space.
}

trap "exit $EXIT_USAGE" TRAP    # Allow usage() function to abort script execution.
export TOP_PID=$$               # PID of executing process.

# Parse command line arguments.
while getopts ":ra:s:LliIcf:Fd:D:CvVm:nB:A:h" o; do
    case $o in
        r) Recursive=true ;;
        a) build_instruction_set Arch "$OPTARG" "architecture" ;;
        s) build_instruction_set InstSet "$OPTARG" "instruction set" ;;
        L) echo $ArchList; exit $EXIT_USAGE ;;
        l) echo $InstSetList; exit $EXIT_USAGE ;;
        i)
            if [ -n "$InstSet_Base" ]; then
                echo $InstSet_Base
                exit $EXIT_USAGE
            else
                echo -e "No instruction set or architecture set.\n"
                usage
            fi
            ;;
        I)
            if [ -n "$InstSet_Base" ]; then
                for s in $InstSet_Base; do
                    echo -ne "\e[31;1m$s:\e[0m "
                    eval echo "\$Opcode_$s"
                done
                exit $EXIT_USAGE
            else
                echo -e "No instruction set or architecture set.\n"
                usage
            fi
            ;;
        c) Count_Matching=true ;;
        f)
            # Unlike architectures, instruction sets are disjoint.
            Found=false
            for s in $InstSetList; do
                for b in `eval echo \\\$InstSet_$s`; do
                    Found_In_Base=false
                    for i in `eval echo \\\$Opcode_$b`; do
                        if [[ "$i" =~ ^$OPTARG$ ]]; then
                            $Found_In_Base || echo -ne "Instruction set \e[33;1m$s\e[0m (base instruction set \e[32;1m$b\e[0m):"
                            echo -ne " \e[31;1m$i\e[0m"
                            Found_In_Base=true
                            Found=true
                        fi
                    done
                    $Found_In_Base && echo ""
                done
            done
            if [ $Found = false ]; then
                echo -e "Operation code \e[31;1m$OPTARG\e[0m has not been found in the database of known instructions." \
                "Perhaps it is translated using other than Intel syntax. If obtained from objdump, check if the \`-M intel' flag is set." \
                "Be aware that the search is case sensitive by default (you may use the -C flag, otherwise only lower case opcodes are accepted)."
                exit $EXIT_NOT_FOUND
            else
                exit $EXIT_FOUND
            fi
            ;;
        d) Leading_Separator="$OPTARG" ;;
        D) Trailing_Separator="$OPTARG" ;;
        C) Case_Insensitive=true ;;
        v) Invert=true ;;
        V) Verbose=true ;;
        m) Stop_After=$OPTARG ;;
        n) Line_Numbers=true ;;
        B) Leading_Context=$OPTARG ;;
        A) Trailing_Context=$OPTARG ;;
        h) usage ;;
        \?)
            echo -e "Unknown option: -$OPTARG\n"
            usage
            ;;
    esac
done
shift $((OPTIND-1))
[ -n "$1" ] && echo -e "Unknown command line parameter: $1\n" && usage
[ -z "$InstSet_Base" ] && usage

# Create list of grep parameters.
Grep_Params="--color=auto -B $Leading_Context -A $Trailing_Context"
[ $Count_Matching = true ] && Grep_Params="$Grep_Params -c"
[ $Case_Insensitive = true ] && Grep_Params="$Grep_Params -i"
[ $Invert = true ] && Grep_Params="$Grep_Params -v"
[ $Stop_After -gt 0 ] && Grep_Params="$Grep_Params -m $Stop_After"
[ $Line_Numbers = true ] && Grep_Params="$Grep_Params -n"

# Build regular expression for use in grep.
RegEx=""
for s in $InstSet_Base; do
    eval RegEx=\"$RegEx \$Opcode_$s\"
done
# Add leading and trailing opcode separators to prevent false positives.
RegEx="$Leading_Separator`echo $RegEx | sed "s/ /$(echo "$Trailing_Separator"|sed 's/[\/&]/\\\&/g')|$(echo "$Leading_Separator"|sed 's/[\/&]/\\\&/g')/g"`$Trailing_Separator"

[ $Verbose = true -a $Count_Matching = false ] && RegEx="$RegEx|\$"

# The actual search.
grep $Grep_Params -E "$RegEx" && exit $EXIT_FOUND || exit $EXIT_NOT_FOUND

Arama sorgunuz çok büyükse (örn. Haswell talimat seti ve -ranahtarla - bu yüzlerce talimat içerir), hesaplama yavaş ilerleyebilir ve bu basit komut dosyasının amaçlanmadığı büyük girdilerde uzun sürebilir. .

Kullanım hakkında ayrıntılı bilgi için danışın

./opcode -h

opcodeKomut dosyasının tamamı (Opcode_list dahil) http://pastebin.com/A8bAuHAP adresinde bulunabilir .

Aracı iyileştirmekten ve yaptığım hataları düzeltmekten çekinmeyin. Son olarak, Shirk gas.vimdosyasını kullanma konusundaki harika fikri için Jonathan Ben-Avraham'a teşekkür etmek istiyorum .

DÜZENLEME: Komut dosyası artık bir işlem kodunun hangi komut kümesine ait olduğunu bulabiliyor (normal ifade kullanılabilir).


9

İlk olarak, ikili kodunuzu ayrıştırın:

objdump -d binary > binary.asm

Ardından , montaj dosyasında tüm SSE4 talimatlarını bulun:

awk '/[ \t](mpsadbw|phminposuw|pmulld|pmuldq|dpps|dppd|blendps|blendpd|blendvps|blendvpd|pblendvb|pblenddw|pminsb|pmaxsb|pminuw|pmaxuw|pminud|pmaxud|pminsd|pmaxsd|roundps|roundss|roundpd|roundsd|insertps|pinsrb|pinsrd|pinsrq|extractps|pextrb|pextrd|pextrw|pextrq|pmovsxbw|pmovzxbw|pmovsxbd|pmovzxbd|pmovsxbq|pmovzxbq|pmovsxwd|pmovzxwd|pmovsxwq|pmovzxwq|pmovsxdq|pmovzxdq|ptest|pcmpeqq|pcmpgtq|packusdw|pcmpestri|pcmpestrm|pcmpistri|pcmpistrm|crc32|popcnt|movntdqa|extrq|insertq|movntsd|movntss|lzcnt)[ \t]/' binary.asm

(Not: CRC32 yorumlarla eşleşebilir.)

En yaygın AVX talimatlarını bulun (AVX2, AVX-512 ailesi ve bazı FMA gibi skaler dahil vfmadd132pd):

awk '/[ \t](vmovapd|vmulpd|vaddpd|vsubpd|vfmadd213pd|vfmadd231pd|vfmadd132pd|vmulsd|vaddsd|vmosd|vsubsd|vbroadcastss|vbroadcastsd|vblendpd|vshufpd|vroundpd|vroundsd|vxorpd|vfnmadd231pd|vfnmadd213pd|vfnmadd132pd|vandpd|vmaxpd|vmovmskpd|vcmppd|vpaddd|vbroadcastf128|vinsertf128|vextractf128|vfmsub231pd|vfmsub132pd|vfmsub213pd|vmaskmovps|vmaskmovpd|vpermilps|vpermilpd|vperm2f128|vzeroall|vzeroupper|vpbroadcastb|vpbroadcastw|vpbroadcastd|vpbroadcastq|vbroadcasti128|vinserti128|vextracti128|vpminud|vpmuludq|vgatherdpd|vgatherqpd|vgatherdps|vgatherqps|vpgatherdd|vpgatherdq|vpgatherqd|vpgatherqq|vpmaskmovd|vpmaskmovq|vpermps|vpermd|vpermpd|vpermq|vperm2i128|vpblendd|vpsllvd|vpsllvq|vpsrlvd|vpsrlvq|vpsravd|vblendmpd|vblendmps|vpblendmd|vpblendmq|vpblendmb|vpblendmw|vpcmpd|vpcmpud|vpcmpq|vpcmpuq|vpcmpb|vpcmpub|vpcmpw|vpcmpuw|vptestmd|vptestmq|vptestnmd|vptestnmq|vptestmb|vptestmw|vptestnmb|vptestnmw|vcompresspd|vcompressps|vpcompressd|vpcompressq|vexpandpd|vexpandps|vpexpandd|vpexpandq|vpermb|vpermw|vpermt2b|vpermt2w|vpermi2pd|vpermi2ps|vpermi2d|vpermi2q|vpermi2b|vpermi2w|vpermt2ps|vpermt2pd|vpermt2d|vpermt2q|vshuff32x4|vshuff64x2|vshuffi32x4|vshuffi64x2|vpmultishiftqb|vpternlogd|vpternlogq|vpmovqd|vpmovsqd|vpmovusqd|vpmovqw|vpmovsqw|vpmovusqw|vpmovqb|vpmovsqb|vpmovusqb|vpmovdw|vpmovsdw|vpmovusdw|vpmovdb|vpmovsdb|vpmovusdb|vpmovwb|vpmovswb|vpmovuswb|vcvtps2udq|vcvtpd2udq|vcvttps2udq|vcvttpd2udq|vcvtss2usi|vcvtsd2usi|vcvttss2usi|vcvttsd2usi|vcvtps2qq|vcvtpd2qq|vcvtps2uqq|vcvtpd2uqq|vcvttps2qq|vcvttpd2qq|vcvttps2uqq|vcvttpd2uqq|vcvtudq2ps|vcvtudq2pd|vcvtusi2ps|vcvtusi2pd|vcvtusi2sd|vcvtusi2ss|vcvtuqq2ps|vcvtuqq2pd|vcvtqq2pd|vcvtqq2ps|vgetexppd|vgetexpps|vgetexpsd|vgetexpss|vgetmantpd|vgetmantps|vgetmantsd|vgetmantss|vfixupimmpd|vfixupimmps|vfixupimmsd|vfixupimmss|vrcp14pd|vrcp14ps|vrcp14sd|vrcp14ss|vrndscaleps|vrndscalepd|vrndscaless|vrndscalesd|vrsqrt14pd|vrsqrt14ps|vrsqrt14sd|vrsqrt14ss|vscalefps|vscalefpd|vscalefss|vscalefsd|valignd|valignq|vdbpsadbw|vpabsq|vpmaxsq|vpmaxuq|vpminsq|vpminuq|vprold|vprolvd|vprolq|vprolvq|vprord|vprorvd|vprorq|vprorvq|vpscatterdd|vpscatterdq|vpscatterqd|vpscatterqq|vscatterdps|vscatterdpd|vscatterqps|vscatterqpd|vpconflictd|vpconflictq|vplzcntd|vplzcntq|vpbroadcastmb2q|vpbroadcastmw2d|vexp2pd|vexp2ps|vrcp28pd|vrcp28ps|vrcp28sd|vrcp28ss|vrsqrt28pd|vrsqrt28ps|vrsqrt28sd|vrsqrt28ss|vgatherpf0dps|vgatherpf0qps|vgatherpf0dpd|vgatherpf0qpd|vgatherpf1dps|vgatherpf1qps|vgatherpf1dpd|vgatherpf1qpd|vscatterpf0dps|vscatterpf0qps|vscatterpf0dpd|vscatterpf0qpd|vscatterpf1dps|vscatterpf1qps|vscatterpf1dpd|vscatterpf1qpd|vfpclassps|vfpclasspd|vfpclassss|vfpclasssd|vrangeps|vrangepd|vrangess|vrangesd|vreduceps|vreducepd|vreducess|vreducesd|vpmovm2d|vpmovm2q|vpmovm2b|vpmovm2w|vpmovd2m|vpmovq2m|vpmovb2m|vpmovw2m|vpmullq|vpmadd52luq|vpmadd52huq|v4fmaddps|v4fmaddss|v4fnmaddps|v4fnmaddss|vp4dpwssd|vp4dpwssds|vpdpbusd|vpdpbusds|vpdpwssd|vpdpwssds|vpcompressb|vpcompressw|vpexpandb|vpexpandw|vpshld|vpshldv|vpshrd|vpshrdv|vpopcntd|vpopcntq|vpopcntb|vpopcntw|vpshufbitqmb|gf2p8affineinvqb|gf2p8affineqb|gf2p8mulb|vpclmulqdq|vaesdec|vaesdeclast|vaesenc|vaesenclast)[ \t]/' binary.asm

NOT: gawkve ile test edilmiştir nawk.


6

Ne yazık ki, bu tarih itibariyle belirli bir yürütülebilir dosyadan gerekli talimat setini algılayan iyi bilinen bir yardımcı program yok gibi görünüyor.

X86 için önerebileceğim en iyi objdump -d, ELF ikili dosyasında çalıştırılabilir bölümleri Gnu Assemply diline ( gas) ayırmaktır . Daha sonra montaj kod dosyası aracılığıyla Shirk vimsözdizimi tanımlarını kullanın veya Shirk dosyasında gördüğünüz grepherhangi bir gasOpcode_SSE41veya gasOpcode_SANDYBRIDGE_AVXtalimat için montajcı kodunu görsel olarak tarayın gas.vim.

Derleme dili dosyası, program derlendiğinde derleyicinin oluşturduğu makine düzeyindeki talimatları ("opcodes") içerir. Program SSE veya AVX talimatları için derleme zamanı bayraklarıyla derlenmişse ve derleyici herhangi bir SSE veya AVX talimatı yayınladıysa, tarafından üretilen sökme listesinde bir veya daha fazla SSE veya AVX opcodesini görmelisiniz objdump -d.

Örneğin grep vroundsdb, birleştirme kodu dosyası üzerinde yapar ve bir eşleşme bulursanız, ikili dosyanın yürütülmesi için AVX özelliklerinin gerekli olduğunu bilirsiniz.

Shirk gas.vimdosyasından da görebileceğiniz gibi, x86 için alt mimariye özgü birkaç talimat var , bu yüzden grepher alt mimari için tüm opcode ping yapmak sıkıcı olurdu. Bunu yapmak için bir C, Perl veya Python programı yazmak, özellikle ARM, PPC ve diğer mimariler için birisini bulabilirseniz Açık Kaynak projesi için mükemmel bir fikir olabilir.


Gazın amacı nedir: Bu programın ne olduğunu bulamadım?
user2284570

@ user2284570: Yorumunuzla ilgili cevabı düzenledim. HTH.
Jonathan Ben-Avraham

Sse4.2 + AVX + 3DNOW yüzlerce talimatı temsil eder. Her biri için bir arama başlatmak uzun zaman alacak ...
user2284570

@ user2284570: Evet, bundan bahsettim. Bunu düzenli olarak yapmanız gerekiyorsa Shirk'e dayanan bir Perl betiği yazmak daha iyi olacaktır gas.vim. Eğer bu bir kerelik bir problemse OTOH, alt mimarileri ayırt eden opcodların kalıplarını kolayca öğrenebilirsiniz.
Jonathan Ben-Avraham

Ben opcodes ile başa çıkmak için bir kütüphane başlamak için harika bir şey olacağını tahmin ...
user2284570

2

Jonathan Ben-Avrahams ve Kyselejsyrečeks'e dayanan bazı python yardımcı senaryolarını yazdım ve cevaplar bir cevap verdi. Bu kaba bir senaryo ama işi hallediyor.

https://gist.github.com/SleepProgger/d4f5e0a0ea2b9456e6c7ecf256629396 gas.vim dosyasını otomatik olarak indirir ve dönüştürür ve geldikleri özellik kümesi de dahil olmak üzere kullanılan tüm (isteğe bağlı olmayan) işlemleri boşaltma işlemini destekler. Ayrıca, özellik kümesi aramayı op destekler.

Tries to detect which CPU features where used in a given binary.

positional arguments:
  executable            The executable to analyze or the command to lookup if
                        -l is set.

optional arguments:
  -h, --help            show this help message and exit
  -j JSON_SPECS, --json-specs JSON_SPECS
                        json file containing a command to feature mapping.
  -o JSON_OUTPUT, --json-output JSON_OUTPUT
                        json file to save the command to feature mapping
                        parsed from an gas.vim file. Defaults to same folder
                        as this scipt/specs.json
  -g GAS, --gas GAS     gas.vim file to convert to feature mapping.
  -nw, --no-json-save   Do not save converted mapping from gas.vim file.
  -b, --include-base    Include base instructions in the search.
  -l, --lookup-op       Lookup arch and feature for given command. Can be
                        regex.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.