From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21946 invoked by uid 1002); 12 Aug 2003 11:55:32 -0000 Mailing-List: contact gentoo-dev-help@gentoo.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@gentoo.org Received: (qmail 3404 invoked from network); 12 Aug 2003 11:55:32 -0000 Date: Tue, 12 Aug 2003 11:55:17 +0000 From: Tavis Ormandy To: gentoo-dev@gentoo.org Message-ID: <20030812115517.GA18146@sdf.lonestar.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="pWyiEgJYm5f9v55/" Content-Disposition: inline User-Agent: Mutt/1.5.3i Subject: [gentoo-dev] Script to test instruction set. X-Archives-Salt: 2f2d5c6e-c719-4efc-bb0c-090acf53bc42 X-Archives-Hash: 5dc5085424df8af2a81f2c5c0e6529cc --pWyiEgJYm5f9v55/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hey, this is an x86 port of a script i wrote (with some help from wwoods) to identify what processor an alpha binary would work on. I think its pretty cool, and had some good feedback so im posting it here :) Example: $ ./analyse-x86 /bin/ls Checking vendor_id string...GenuineIntel Disassembling /bin/ls, please wait... i486: 0 i586: 0 ppro: 15 mmx: 0 sse: 8 sse2: 0 /bin/ls will run on Pentium III (pentium3) or higher processor. -- ------------------------------------- taviso@sdf.lonestar.org | finger me for my gpg key. ------------------------------------------------------- --pWyiEgJYm5f9v55/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename=analyse-x86 Content-Transfer-Encoding: quoted-printable #!/bin/sh # Tavis Ormandy 2003 # Improvments by Will Woods # # Identify instruction set used in binary. # # initialize everything to zero. eval {i486,i586,ppro,mmx,sse,sse2,amd,amd2,cpuid}=3D0 # unfortunately there are mnemonic collissions between vendor sets # so check vendor_id string, and enable relevant sets. printf "Checking vendor_id string..." if ! test "${1%=3D*}" =3D=3D "--vendor"; then case "`grep -Em1 '^vendor_id.*: ' /proc/cpuinfo | cut -d" " -f2`" in *GenuineIntel*) vendor=3Dintel; printf "GenuineIntel\n";; *AuthenticAMD*) vendor=3Damd; printf "AuthenticAMD\n";; *CyrixInstead*) vendor=3Dcyrix; printf "CyrixInstead\n";; *GenuineTMx86*) vendor=3Dtransmeta; printf "GenuineTMx86\n";; *) vendor=3Dother; printf "other\n";; esac else # allow vendor to be overridden vendor=3D${1#*=3D}; shift printf "%s\n" $vendor fi # quick sanity tests. if ! test "$1"; then printf "usage: %s [--vendor=3Dintel|amd|cyrix|transmeta] /path/to/binary\n= " $0 1>&2 exit 1 elif ! test -e "$1"; then=20 printf "error: %s does not exist.\n" "$1" 1>&2 exit 1 elif ! test -r "$1"; then printf "error: cant read %s.\n" "$1" 1>&2 exit 1 fi printf "Disassembling %s, please wait...\n" $1 # initialize screen output case "$vendor" in *intel*) printf "i486: %4u i586: %4u ppro: %4u mmx: %4u sse: %4u sse2: %4u= \r" \ $i486 $i586 $ppro $mmx $sse $sse2;; *amd*) printf "i486: %4u i586: %4u mmx: %4u sse: %4u 3dnow: %4u ext3dnow: = %4u\r" \ $i486 $i586 $mmx $sse $amd $amd2;; *cyrix*) printf "i486: %4u i586: %4u mmx: %4u\r" \ $i486 $i586 $mmx;; *transmeta*) printf "i486: %4u i586: %4u mmx: %4u\r" \ $i486 $i586 $mmx;; *) printf "i486: %4u i586: %4u ppro: %4u mmx: %4u sse: %4u sse2: %4u\r" \ $i486 $i586 $ppro $mmx $sse $sse2;; esac # do the disassembling. objdump -d $1 | cut -f3 | cut -d" " -f1 | ( while read instruction; do case "$instruction" in "cmpxchg"|"xadd"|"bswap"|"invd"|"wbinvd"|"invlpg") let ++i486; print=3D1= ;; "rdmsr"|"wrmsr"|"rdtsc"|"cmpxch8B"|"rsm") let ++i586; print=3D1;; "cmovcc"|"fcmovcc"|"fcomi"|"fcomip"|"fucomi"|"fucomip"|"rdpmc"|"ud2") le= t ++ppro; print=3D1;; "emms"|"movd"|"movq"|"packsswb"|"packssdw"|"packuswb"|"paddb"|"paddw"|"p= addd"|"paddsb"|"paddsw"|"paddusb"|"paddusw"|"pand"|"pandn"|"pcmpeqb"|"pcmpe= qw"|"pcmpeqd"|"pcmpgtb"|"pcmpgtw"|"pcmpgtd"|"pmaddwd"|"pmulhw"|"pmullw"|"po= r"|"psllw"|"pslld"|"psllq"|"psraw"|"psrad"|"psrlw"|"psrld"|"psrlq"|"psubb"|= "psubw"|"psubd"|"psubsb"|"psubsw"|"psubusb"|"psubusw"|"punpckhbw"|"punpckhw= d"|"punpckhdq"|"punpcklbw"|"punpcklwd"|"punpckldq"|"pxor") let ++mmx; print= =3D1;; "addps"|"addss"|"andnps"|"andps"|"cmpps"|"cmpss"|"comiss"|"cvtpi2ps"|"cv= tps2pi"|"cvtsi2ss"|"cvtss2si"|"cvttps2pi"|"cvttss2si"|"divps"|"divss"|"fxrs= tor"|"fxsave"|"ldmxcsr"|"maxps"|"maxss"|"minps"|"minss"|"movaps"|"movhlps"|= "movhps"|"movlhps"|"movlps"|"movmskps"|"movss"|"movups"|"mulps"|"mulss"|"or= ps"|"pavgb"|"pavgw"|"psadbw"|"rcpps"|"rcpss"|"rsqrtps"|"rsqrtss"|"shufps"|"= sqrtps"|"sqrtss"|"stmxcsr"|"subps"|"subss"|"ucomiss"|"unpckhps"|"unpcklps"|= "xorps"|"pextrw"|"pinsrw"|"pmaxsw"|"pmaxub"|"pminsw"|"pminub"|"pmovmskb"|"p= mulhuw"|"pshufw"|"maskmovq"|"movntps"|"movntq"|"prefetch"|"sfence") let ++s= se; print=3D1;; "addpd"|"addsd"|"andnpd"|"andpd"|"clflush"|"cmppd"|"cmpsd"|"comisd"|"cvt= dq2pd"|"cvtdq2ps"|"cvtpd2pi"|"cvtpd2pq"|"cvtpd2ps"|"cvtpi2pd"|"cvtps2dq"|"c= vtps2pd"|"cvtsd2si"|"cvtsd2ss"|"cvtsi2sd"|"cvtss2sd"|"cvttpd2pi"|"cvttpd2dq= "|"cvttps2dq"|"cvttsd2si"|"divpd"|"divsd"|"lfence"|"maskmovdqu"|"maxpd"|"ma= xsd"|"mfence"|"minpd"|"minsd"|"movapd"|"movd"|"movdq2q"|"movdqa"|"movdqu"|"= movhpd"|"movlpd"|"movmskpd"|"movntdq"|"movnti"|"movntpd"|"movq"|"movq2dq"|"= movsd"|"movupd"|"mulpd"|"mulsd"|"orpd"|"packsswb"|"packssdw"|"packuswb"|"pa= ddb"|"paddw"|"paddd"|"paddq"|"paddq"|"paddsb"|"paddsw"|"paddusb"|"paddusw"|= "pand"|"pandn"|"pause"|"pavgb"|"pavgw"|"pcmpeqb"|"pcmpeqw"|"pcmpeqd"|"pcmpg= tb"|"pcmpgtw"|"pcmpgtd"|"pextrw"|"pinsrw"|"pmaddwd"|"pmaxsw"|"pmaxub"|"pmin= sw"|"pminub"|"pmovmskb"|"pmulhw"|"pmulhuw"|"pmullw"|"pmuludq"|"pmuludq"|"po= r"|"psadbw"|"pshufd"|"pshufhw"|"pshuflw"|"pslldq"|"psllw"|"pslld"|"psllq"|"= psraw"|"psrad"|"psrldq"|"psrlw"|"psrld"|"psrlq"|"psubb"|"psubw"|"psubd"|"ps= ubq"|"psubq"|"psubsb"|"psubsw"|"psubusb"|"psubusw"|"psubsb"|"punpckhbw"|"pu= npckhwd"|"punpckhdq"|"punpckhqdq"|"punpcklbw"|"punpcklwd"|"punpckldq"|"punp= cklqdq"|"pxor"|"shufpd"|"sqrtpd"|"sqrtsd"|"subpd"|"subsd"|"ucomisd"|"unpckh= pd"|"unpcklpd"|"xorpd") let ++sse2; print=3D1;; "pavgusb"|"pfadd"|"pfsub"|"pfsubr"|"pfacc"|"pfcmpge"|"pfcmpgt"|"pfcmpeq"= |"pfmin"|"pfmax"|"pi2fw"|"pi2fd"|"pf2iw"|"pf2id"|"pfrcp"|"pfrsqrt"|"pfmul"|= "pfrcpit1"|"pfrsqit1"|"pfrcpit2"|"pmulhrw"|"pswapw"|"femms"|"prefetch") let= ++amd; print=3D1;; "pf2iw"|"pfnacc"|"pfpnacc"|"pi2fw"|"pswapd"|"maskmovq"|"movntq"|"pavgb"|= "pavgw"|"pextrw"|"pinsrw"|"pmaxsw"|"pmaxub"|"pminsw"|"pminub"|"pmovmskb"|"p= mulhuw"|"prefetchnta"|"prefetcht0"|"prefetcht1"|"prefetcht2"|"psadbw"|"pshu= fw"|"sfence") let ++amd2; print=3D1;; "cpuid") let ++cpuid ++i586; print=3D1;; esac # check if screen needs updating. if test "$print"; then case "$vendor" in *intel*) printf "i486: %4u i586: %4u ppro: %4u mmx: %4u sse: %4u sse2: %= 4u\r" \ $i486 $i586 $ppro $mmx $sse $sse2;; *amd*) printf "i486: %4u i586: %4u mmx: %4u sse: %4u 3dnow: %4u ext3dnow= : %4u\r" \ $i486 $i586 $mmx $sse $amd $amd2;; *cyrix*) printf "i486: %4u i586: %4u mmx: %4u\r" \ $i486 $i586 $mmx;; *transmeta*) printf "i486: %4u i586: %4u mmx: %4u\r" \ $i486 $i586 $mmx;; *) printf "i486: %4u i586: %4u ppro: %4u mmx: %4u sse: %4u sse2: %4u\r" \ $i486 $i586 $ppro $mmx $sse $sse2;; esac=09 unset print fi done=20 # print a newline echo # cpuid instruction could mean the application checks to see # if an instruction is supported before executing it. This might=20 # mean it will work on anything over a pentium. if test $cpuid -gt 0; then printf "\nThis binary was found to contain the cpuid instruction.\n" printf "It may be able to conditionally execute instructions if\n" printf "they are supported on the host (i586+).\n\n" fi # print minimum required processor, if there are collissions # use the vendor to decide what to print. if test $sse2 -gt 0; then=20 subarch=3D"Pentium IV (pentium4)" elif test $sse -gt 0; then=20 if test "$vendor" =3D=3D "intel"; then subarch=3D"Pentium III (pentium3)" elif test "$vendor" =3D=3D "amd"; then subarch=3D"AMD Athlon 4 (athlon-4)" else subarch=3D"Pentium III (pentium3)" fi elif test "$vendor" =3D=3D "amd" -a $amd2 -gt 0; then subarch=3D"AMD Athlon (athlon)" elif test "$vendor" =3D=3D "amd" -a $amd -gt 0; then subarch=3D"AMD K6 III (k6-3)" elif test $mmx -gt 0; then=20 if test "$vendor" =3D=3D "intel"; then if $ppro -gt 0; then subarch=3D"Pentium II (pentium2)" else subarch=3D"Intel Pentium MMX [P55C] (pentium-mmx)" fi elif test "$vendor" =3D=3D "amd"; then subarch=3D"AMD K6 (k6)" elif test "$vendor" =3D=3D "cyrix"; then subarch=3D"Cyrix 6x86MX / MII (pentium-mmx)" else subarch=3D"Intel Pentium MMX [P55C] (pentium-mmx)" fi elif test $ppro -gt 0; then subarch=3D"Pentium Pro (i686 or pentiumpro)" elif test $i586 -gt 0; then subarch=3D"Pentium or compatible (i586) (i586 or pentium)" elif test $i486 -gt 0; then subarch=3D"80486 or comaptible (i486)" else subarch=3D"80386 or compatible (i386)" fi # print message and exit. printf "%s will run on %s or higher processor.\n" "$1" "$subarch"; ) --pWyiEgJYm5f9v55/ Content-Type: text/plain; charset=us-ascii -- gentoo-dev@gentoo.org mailing list --pWyiEgJYm5f9v55/--