W systemie Linux /proc/cpuinfo
umożliwia sprawdzenie wszystkich flag procesora, które ma maszyna w prosty sposób.
Zwykle, jeśli program wymaga nadzbioru zestawu instrukcji maszyny, najłatwiejszym sposobem ustalenia tego jest uruchomienie go i sprawdzenie, czy wywołuje SIGILLsygnał.
Ale w moim przypadku wszystkie moje procesory obsługują co najmniej SSE4.1 i AVX.
Czy istnieje prosty sposób sprawdzenia, czy plik binarny zawiera specjalne instrukcje?
objdump --disassemble
wykonuje demontaż. Możesz użyćobjdump
do wygenerowania listy mnemoników. Jest częścią Binutils, więc jest dostępny w systemach GNU Linux. Ponadto dodatkowe instrukcje mogą być obecne, ale mogą nie zostać wykonane. Program może mieć strażników środowiska wykonawczego.-mavx
aby kompilator wybierał tylko z AVX ISA, ale istnieją sposoby, aby go ominąć. Na przykład asembler wbudowany może zwykle ominąć kontrole ISA kompilatora.Odpowiedzi:
Uderzyłem w program Rust, który próbuje to zrobić. Myślę, że to działa, chociaż jest nieudokumentowane i okropnie kruche:
https://github.com/pkgw/elfx86exts
Przykładowe użycie:
źródło
Zetknąłem się z tym samym problemem, gdy próbowałem zrozumieć procesy optymalizacji GCC i dowiedzieć się, które instrukcje zostały lub nie zostały użyte podczas tego procesu. Ponieważ nie jestem przyjazny z ogromną liczbą kodów operacji, szukałem sposobu na wizualizację konkretnych (powiedzmy SSE3) instrukcji w zdemontowanym kodzie lub przynajmniej wydrukowania niektórych minimalnych statystyk, takich jak to, czy i ile tych instrukcji jest w pliku binarnym.
Nie znalazłem żadnego istniejącego rozwiązania, ale odpowiedź Jonathana Ben-Avrahama okazała się bardzo przydatna, ponieważ wskazuje na świetne (a nawet częściowo ustrukturyzowane) źródło kodów operacji. Na podstawie tych danych napisałem skrypt Bash, który może wizualizować określone zestawy instrukcji lub drukować statystyki na ich temat,
grep
gdy są zasilane danymi wyjściowymiobjdump
.Lista kodów operacji została przekonwertowana na samodzielny skrypt Bash, który jest następnie dołączany (w celu lepszej czytelności) do głównego pliku, który po prostu nazwałem
opcode
. Ponieważ w opcodesgas.vim
( uchylać wvim
definicjach składniowych , od odpowiedzi Jonathana) były systematycznie grupowane (pozornie) według różnych architekturach procesora, starałem się zachować ten podział i złożyć zestaw architecture-> instrukcji mapowania; Nie jestem teraz pewien, czy to był dobry pomysł. Mapowanie nie jest dokładne i musiałem nawet wprowadzić pewne zmiany w oryginalegas.vim
grupowanie. Ponieważ zestawy instrukcji związane z architekturą nie były moim pierwotnym zamiarem, starałem się jedynie konstruować zestawy instrukcji głównych architektur opisanych w Internecie, ale bez konsultacji z dokumentacją producentów. Architektury AMD wcale nie wydają mi się wiarygodne (z wyjątkiem zestawów instrukcji takich jak 3DNow! I SSE5). Jednak postanowiłem zostawić kod dla zestawów instrukcji różnych architektur tutaj, aby ktoś mógł je zbadać i poprawić / poprawić i dać innym pewne wstępne wyniki.Początek głównego pliku o nazwie
opcode
:Przykład
Opcode_list
pliku wygenerowanego i zmodyfikowanego zgodnie z instrukcjamiopcode
z 27 października 2014 r. Można znaleźć na stronie http://pastebin.com/yx4rCxqs . Możesz wstawić ten plik bezpośrednioopcode
w miejscesource Opcode_list
wiersza. Udostępniłem ten kod, ponieważ Stack Exchange nie pozwala mi wysłać tak dużej odpowiedzi.Wreszcie reszta
opcode
pliku z rzeczywistą logiką:Należy pamiętać, że jeśli zapytanie jest zbyt duże (np. Z zestawem instrukcji Haswella i
-r
przełącznikiem - obejmuje to setki instrukcji), obliczenia mogą przebiegać powoli i zajmować dużo czasu na dużych danych wejściowych, dla których ten prosty skrypt nie był przeznaczony .Szczegółowe informacje na temat użytkowania znajdują się w
Cały
opcode
skrypt (z dołączoną Opcode_list) można znaleźć na stronie http://pastebin.com/A8bAuHAP .Ulepsz narzędzie i napraw błędy, które mogłem popełnić. Na koniec chciałbym podziękować Jonathanowi Ben-Avrahamowi za jego świetny pomysł na wykorzystanie
gas.vim
pliku Shirka .EDYCJA: Skrypt może teraz znaleźć zestaw instrukcji, do którego należy kod operacji (można użyć wyrażenia regularnego).
źródło
Najpierw dekompiluj swój plik binarny:
Następnie znajdź wszystkie instrukcje SSE4 w pliku zespołu:
(Uwaga: CRC32 może pasować do komentarzy.)
Znajdź najczęstsze instrukcje AVX (w tym skalar, w tym AVX2, rodzina AVX-512 i niektóre podobne do FMA
vfmadd132pd
):UWAGA: przetestowano za pomocą
gawk
inawk
.źródło
Niestety, wydaje się, że na dzień dzisiejszy nie ma dobrze znanego narzędzia wykrywającego wymagany zestaw instrukcji z danego pliku wykonywalnego.
Najlepsze, co mogę zasugerować dla x86, to użycie
objdump -d
binarnego ELF do dezasemblacji sekcji wykonywalnych na język Gnu Assemply (gas
). Następnie użyj definicji składni Shirka,vim
aby albogrep
przejrzeć plik kodu asemblera, albo wizualnie przeskanować kod asemblera w poszukiwaniu którejkolwiek z instrukcjigasOpcode_SSE41
lubgasOpcode_SANDYBRIDGE_AVX
instrukcji widocznych wgas.vim
pliku Shirka .Plik języka asemblera zawiera instrukcje na poziomie komputera („opcodes”), które kompilator wygenerował podczas kompilacji programu. Jeśli program został skompilowany z flagami czasu kompilacji instrukcji SSE lub AVX, a kompilator wyemitował instrukcje SSE lub AVX, to na liście dezasemblacji utworzonej przez powinien pojawić się jeden lub więcej kodów operacyjnych SSE lub AVX
objdump -d
.Na przykład, jeśli zrobisz to
grep vroundsdb
w pliku kodu asemblera i znajdziesz dopasowanie, to wiesz, że plik binarny wymaga do działania możliwości AVX.Jak widać z
gas.vim
pliku Shirka, jest kilka instrukcji specyficznych dla pod-architektury dla x86, więcgrep
pingowanie wszystkich kodów operacyjnych dla każdej pod-architektury byłoby z pewnością nużące. Napisanie w tym celu programu C, Perl lub Python może być doskonałym pomysłem na projekt Open Source, szczególnie jeśli możesz znaleźć kogoś, kto rozszerzy go o ARM, PPC i inne architektury.źródło
gas.vim
. OTOH, jeśli jest to problem jednorazowy, możesz łatwo nauczyć się wzorców kodów rozróżniających poszczególne pod-architektury.Dałem napisanie skryptu narzędzia python opartego na Jonathanie Ben-Avrahamsie i Kyselejsyrečeksie odpowiedzi. Jest to prymitywny skrypt, ale wykonuje zadanie.
https://gist.github.com/SleepProgger/d4f5e0a0ea2b9456e6c7ecf256629396 Automatycznie pobiera i konwertuje plik gas.vim oraz obsługuje zrzut wszystkich używanych (opcjonalnych nie podstawowych) operacji, w tym zestawu funkcji, z którego pochodzą. Dodatkowo obsługuje op do wyszukiwania zestawu funkcji.
źródło