{"id":364,"date":"2020-11-25T09:46:03","date_gmt":"2020-11-25T08:46:03","guid":{"rendered":"http:\/\/kronotai.com\/wordpress\/?p=364"},"modified":"2020-11-25T09:46:03","modified_gmt":"2020-11-25T08:46:03","slug":"how-good-do-decompilers-support-x87-instructions","status":"publish","type":"post","link":"https:\/\/kronotai.com\/wordpress\/2020\/11\/25\/how-good-do-decompilers-support-x87-instructions\/","title":{"rendered":"How good do decompilers support x87 instructions?"},"content":{"rendered":"\n\t\t\t\t<![CDATA[Welcome to another round of testing various decompilers. Todays test <a href=\"https:\/\/github.com\/rfalke\/decompiler-subjects\/blob\/master\/from_holdec\/i386_x87_fpu\/ia32_elf\/subject.exe\">subject.exe<\/a>\u00a0is a hand written program which tests all the x87 FPU instructions. As usual the motivation is to test other decompilers but also to have a good test case\/demo for my own decompiler. The contests are:\n<ul>\n<li>reko version\u00a0<a class=\"f6 link-gray text-mono ml-2 d-none d-lg-inline\" href=\"https:\/\/github.com\/uxmal\/reko\/commit\/b08e86ba8dbf5fa07b0b81fbedf0e184f7dccd3c\" data-pjax=\"\">b08e86b<\/a><\/li>\n<li>retdec version\u00a0<a class=\"f6 link-gray text-mono ml-2 d-none d-lg-inline\" href=\"https:\/\/github.com\/avast\/retdec\/commit\/31ffc7c8003813b6b91755f2b62937967a708d78\" data-pjax=\"\">31ffc7c<\/a><\/li>\n<li>ghidra version\u00a09.1.2_PUBLIC<\/li>\n<\/ul>\n<h1>reko<\/h1>\nLooking at the <a href=\"https:\/\/github.com\/rfalke\/decompiler-subjects\/blob\/master\/from_holdec\/i386_x87_fpu\/ia32_elf\/by_reko.c\">output<\/a>\u00a0one can see:\n<ul>\n<li>high: reko doesn&#8217;t load constant values (neither float nor int) from read-only sections<\/li>\n<li>reko doesn&#8217;t evaluate functions like pow or fabs with constant arguments<\/li>\n<li>reko doesn&#8217;t perform basic arithmetic operations like 1.0+1.0<\/li>\n<li>fbstp is decompiled as a cast but the operation is more complex<\/li>\n<li>The output of FCMOV (<code>if (Test(LT,SLICE(SLICE(dwArg04, byte, 8), bool, 1)))<\/code>) is a bit too magic for me<\/li>\n<li>fcmovu for unordered is unfinished (seeing only P). Also fcmovnu is the same as fcmovu<\/li>\n<li>looks like\u00a0fcmovnb is decompiled as\u00a0fcmovb<\/li>\n<li>fcom uses a magic cond() function<\/li>\n<li>additional noise in integer code in the fcom function<\/li>\n<li>output for fcomi and ftst is incomplete<\/li>\n<li>fist and frndint doesn&#8217;t respect rounding mode<\/li>\n<li>wrong parameter values for fpatan<\/li>\n<li>looping because of partial remainder looks wrong<\/li>\n<li>leaves unused calls for fptan, fsincos, fxtract<\/li>\n<li>wrong parameter used for fyl2x<\/li>\n<li>modelling of the status word is incorrect\/not easy to understand<\/li>\n<\/ul>\n12 issues on <a href=\"https:\/\/github.com\/uxmal\/reko\/issues?q=is%3Aissue+author%3Arfalke+x87\">github<\/a>\n<h1>retdec<\/h1>\n<ul>\n<li>wrong modelling of f2xm1<\/li>\n<li>doesn&#8217;t evaluate functions like pow or fabs with constant arguments<\/li>\n<li>confusing use of\u00a0float80_t for fbst<\/li>\n<li>wrong decompilation of fbld<\/li>\n<li>missing code for fcom and ftst<\/li>\n<li>gets confused in fcomi, fptan and fsincos<\/li>\n<li>fist and frndint doesn&#8217;t respect rounding mode<\/li>\n<li>fld for 32bit floats loads wrong number<\/li>\n<li>bad modeling of fpatan with only one parameter<\/li>\n<li>incorrect implementation of fprem1<\/li>\n<li>doesn&#8217;t model C2 change of fprem<\/li>\n<li>missing memory write for 32bit fst<\/li>\n<li>missing slot is inf for fxam<\/li>\n<li>multiple copies of __pseudo functions for fxtract<\/li>\n<li>superfluous calls in fxtract<\/li>\n<li>modelling of the status word is incorrect\/not easy to understand<\/li>\n<\/ul>\n16 issues on <a href=\"https:\/\/github.com\/avast\/retdec\/issues?q=is%3Aissue+author%3Arfalke+x87\">github<\/a>\n<h1>ghidra<\/h1>\n<ul>\n<li>displays floating point arguments to printf as hex<\/li>\n<li>fbst is a simple assignment<\/li>\n<li>fbld is incomplete<\/li>\n<li>fcom and fcomi doesn&#8217;t test for unordered<\/li>\n<li>doesn&#8217;t evaluate functions like fcos with constant arguments<\/li>\n<li>fist and frndint doesn&#8217;t respect rounding mode<\/li>\n<li>fld a 80bit float doesn&#8217;t work<\/li>\n<li>fprem and fprem1 not working<\/li>\n<li>doesn&#8217;t model that fprem updates the status word<\/li>\n<li>fxtract,fyl2x, fyl2xp1 is just identity<\/li>\n<li>modelling of the status word is incorrect\/not easy to understand<\/li>\n<\/ul>\n10 issues on <a href=\"https:\/\/github.com\/NationalSecurityAgency\/ghidra\/issues?q=is%3Aissue+author%3Arfalke+x87\">github<\/a>\u00a0and <a href=\"https:\/\/github.com\/NationalSecurityAgency\/ghidra\/issues\/2146\">an older one<\/a>\n<h1>Summary<\/h1>\nAll examined decompilers model the x87 instructions to a certain degree which is probably good enough for common binaries. There are however in all decompilers x87 details which are not supported: rounding modes, handling of unordered compares and the BCD format.\n\u00a0\n<p><![CDATA[\n<\/p]]><\/p>\n\n\n<p class=\"bla\">Thank you for reading and please send questions or feedback via email to holdec@kronotai.com or contact me on <a href=\"https:\/\/twitter.com\/holdecd\">Twitter<\/a>.<\/p>\n]]>\t\t","protected":false},"excerpt":{"rendered":"<p>\t\t\t\t<![CDATA[]]>\t\t <a href=\"https:\/\/kronotai.com\/wordpress\/2020\/11\/25\/how-good-do-decompilers-support-x87-instructions\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[21,25,43],"class_list":["post-364","post","type-post","status-publish","format-standard","hentry","category-decompiler","tag-fpu","tag-i386","tag-x87"],"_links":{"self":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts\/364","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/comments?post=364"}],"version-history":[{"count":0,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts\/364\/revisions"}],"wp:attachment":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/media?parent=364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/categories?post=364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/tags?post=364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}