Di Linux, /proc/cpuinfo
memungkinkan seseorang untuk memeriksa semua flag CPU yang dimiliki mesin dengan cara yang sederhana.
Biasanya, jika suatu program membutuhkan superset dari set instruksi mesin, cara termudah untuk menentukan ini adalah dengan menjalankannya dan melihat apakah itu menimbulkan SIGILLsinyal.
Tetapi dalam kasus saya, semua prosesor saya mendukung setidaknya SSE4.1 dan AVX.
Jadi, apakah ada cara sederhana untuk memeriksa apakah biner memiliki instruksi khusus di dalamnya?
objdump --disassemble
melakukan pembongkaran. Anda dapat menggunakanobjdump
untuk membuat daftar mnemonik. Ini adalah bagian dari Binutils, jadi tersedia di sistem Linux GNU. Juga, instruksi tambahan mungkin ada tetapi tidak dapat dieksekusi. Program bisa memiliki penjaga runtime.-mavx
untuk memastikan kompiler hanya memilih dari AVX ISA, tetapi ada cara untuk menghindarinya. Sebagai contoh, assembler inline biasanya dapat menghindari pemeriksaan ISA kompiler.Jawaban:
Saya menghentikan program di Rust yang mencoba melakukan ini. Saya pikir itu berhasil, meskipun tidak terdokumentasi dan sangat rapuh:
https://github.com/pkgw/elfx86exts
Contoh penggunaan:
sumber
Saya mengalami masalah yang sama ketika saya mencoba memahami proses optimasi GCC dan untuk mengetahui instruksi mana yang telah atau belum digunakan selama proses ini. Karena saya tidak ramah dengan sejumlah besar kode operasi, saya mencari cara untuk memvisualisasikan instruksi spesifik (misalkan SSE3) dalam kode yang dibongkar, atau setidaknya mencetak beberapa statistik minimal seperti apakah dan berapa banyak instruksi ini yang ada dalam biner.
Saya belum menemukan solusi yang ada, tetapi jawaban Jonathan Ben-Avraham terbukti sangat berguna, karena menunjukkan sumber kode operasi yang hebat (dan bahkan sebagian terstruktur). Berdasarkan data ini, saya telah menulis skrip Bash yang dapat memvisualisasikan set instruksi khusus atau mencetak statistik tentang mereka menggunakan
grep
ketika diumpankan dengan output dariobjdump
.Daftar kode operasi telah diubah menjadi skrip Bash mandiri yang kemudian dimasukkan (untuk tujuan keterbacaan yang lebih baik) dalam file utama yang saya beri nama sederhana
opcode
. Karena opcodes dalamgas.vim
( definisi sintaksis Shirkvim
, dari jawaban Jonathan) dikelompokkan secara sistematis (tampaknya) menurut arsitektur CPU yang berbeda, saya mencoba mempertahankan divisi ini dan membuat pemetaan kumpulan instruksi arsitektur-> ; Saya tidak yakin sekarang apakah itu ide yang bagus. Pemetaannya tidak akurat dan saya bahkan harus membuat beberapa perubahan pada aslinyagas.vim
pengelompokan. Karena set instruksi yang berhubungan dengan arsitektur bukan niat asli saya, saya mencoba hanya untuk membangun set instruksi arsitektur utama yang dijelaskan di Internet, tetapi tanpa berkonsultasi dengan dokumentasi pabrik. Arsitektur AMD sepertinya tidak bisa diandalkan sama sekali bagi saya (kecuali set instruksi seperti 3DNow! Dan SSE5). Namun, saya memutuskan untuk meninggalkan kode untuk set instruksi dari berbagai arsitektur di sini untuk orang lain untuk memeriksa dan memperbaiki / memberikan hasil tentatif kepada orang lain.Awal dari file utama bernama
opcode
:Contoh
Opcode_list
file yang dibuat dan dimodifikasi menggunakan instruksi padaopcode
27 Oktober 2014, dapat ditemukan di http://pastebin.com/yx4rCxqs . Anda dapat memasukkan file ini tepatopcode
di tempatsource Opcode_list
baris. Saya telah mengeluarkan kode ini karena Stack Exchange tidak akan membiarkan saya mengirim jawaban sebesar itu.Akhirnya, sisa
opcode
file dengan logika aktual:Perlu diketahui bahwa jika permintaan pencarian Anda terlalu besar (mis., Dengan set instruksi Haswell dan
-r
sakelar - ini termasuk ratusan instruksi), perhitungannya dapat berjalan perlahan dan membutuhkan waktu lama pada input besar yang tidak dimaksudkan untuk skrip sederhana ini. .Untuk informasi rinci tentang penggunaan, konsultasikan
Seluruh
opcode
skrip (dengan menyertakan Opcode_list) dapat ditemukan di http://pastebin.com/A8bAuHAP .Jangan ragu untuk meningkatkan alat dan untuk memperbaiki kesalahan yang mungkin saya buat. Terakhir, saya ingin mengucapkan terima kasih kepada Jonathan Ben-Avraham atas ide bagusnya menggunakan
gas.vim
file Shirk .EDIT: Script sekarang dapat menemukan instruksi yang mengatur kode operasi milik (ekspresi reguler dapat digunakan).
sumber
Pertama, dekompilasi biner Anda:
Kemudian temukan semua instruksi SSE4 di file assembly:
(Catatan: CRC32 mungkin cocok dengan komentar.)
Temukan instruksi AVX paling umum (termasuk skalar, termasuk AVX2, AVX-512 family dan beberapa sejenis FMA
vfmadd132pd
):CATATAN: diuji dengan
gawk
dannawk
.sumber
Sayangnya tidak ada utilitas yang dikenal pada tanggal ini yang mendeteksi set instruksi yang diperlukan dari executable yang diberikan.
Yang terbaik yang dapat saya sarankan untuk x86 adalah menggunakan
objdump -d
pada biner ELF untuk membongkar bagian yang dapat dieksekusi ke dalam bahasa Gnu Assemply (gas
). Kemudian gunakan definisi sintaks Shirkvim
baikgrep
melalui file kode assembly atau secara visual memindai kode assembler untuk salah satugasOpcode_SSE41
ataugasOpcode_SANDYBRIDGE_AVX
instruksi yang Anda lihat dalamgas.vim
file Shirk .File bahasa rakitan berisi instruksi tingkat mesin ("opcodes") yang dihasilkan oleh kompiler ketika program dikompilasi. Jika program dikompilasi dengan flag waktu kompilasi untuk instruksi SSE atau AVX, dan kompiler memancarkan instruksi SSE atau AVX, maka Anda akan melihat satu atau lebih opcode SSE atau AVX dalam daftar pembongkaran yang diproduksi oleh
objdump -d
.Misalnya, jika Anda melakukannya
grep vroundsdb
pada file kode rakitan dan menemukan kecocokan, maka Anda tahu bahwa file biner memerlukan kemampuan AVX untuk mengeksekusi.Ada beberapa instruksi spesifik sub-arsitektur untuk x86, seperti yang dapat Anda lihat dari
gas.vim
file Shirk , Jadigrep
ping untuk semua opcode untuk setiap sub-arsitektur akan terasa membosankan. Menulis program C, Perl atau Python untuk melakukan ini bisa menjadi ide bagus untuk proyek Open Source, terutama jika Anda dapat menemukan seseorang untuk memperpanjangnya untuk ARM, PPC dan arsitektur lainnya.sumber
gas.vim
. OTOH jika ini adalah masalah sekali tembak, maka Anda dapat dengan mudah mempelajari pola opcode yang membedakan antara sub-arsitektur.Saya memberi menulis beberapa skrip utilitas python berdasarkan Jonathan Ben-Avrahams dan Kyselejsyrečeks menjawab pergi. Ini naskah kasar tetapi menyelesaikan pekerjaan.
https://gist.github.com/SleepProgger/d4f5e0a0ea2b9456e6c7ecf256629396 Secara otomatis mengunduh dan mengonversi file gas.vim dan mendukung pembuangan semua operasi yang digunakan (opsional non-dasar) termasuk fitur set dari mana asalnya. Selain itu mendukung operasi pencarian set ke fitur.
sumber