Compare commits
2577 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4113b6bd6 | |||
| 4988868e61 | |||
| 5a513ab16f | |||
| f1a9d1bec9 | |||
| 70a3acfded | |||
| 3ec6a3cce0 | |||
| dd0a8856cc | |||
| c51a1130b8 | |||
| 9851fba246 | |||
| 8054543671 | |||
| 17d0e897ba | |||
| a7940fd19b | |||
| 1fbd34035e | |||
| 945d9157fa | |||
| 915bfbd82e | |||
| ef01a73e8f | |||
| 7e4e6a3cb1 | |||
| ca97430db2 | |||
| 7530643d1d | |||
| 073cdb0d58 | |||
| 9a93b5d1c1 | |||
| 44ce469b84 | |||
| 4d8d330f21 | |||
| 793e1622ea | |||
| 92a33fa0cc | |||
| e8c49a2c35 | |||
| d2e9db7112 | |||
| b728b0e021 | |||
| a1ef410509 | |||
| 24b4ec42e7 | |||
| 52dde5789e | |||
| 730c6ce6c5 | |||
| 5ed1d5b2b3 | |||
| 23c70ec447 | |||
| e29e73a4e4 | |||
| 27289a7589 | |||
| e509bb87e9 | |||
| 5cec09966e | |||
| b5789fb321 | |||
| a1b0fd987f | |||
| a468b92e3a | |||
| ddf0b50c6d | |||
| 3af2b21869 | |||
| c4bfebeceb | |||
| d23484b9db | |||
| 071579b5b6 | |||
| ff9d577e46 | |||
| a25c20ee0b | |||
| ff75a462a4 | |||
| e0b6ff1924 | |||
| 1c5fae74e0 | |||
| 6f650ca16f | |||
| c2da21ba4e | |||
| 903ca50391 | |||
| 70f1ab8cb7 | |||
| 6998449715 | |||
| fb0f6c6a00 | |||
| dbde75028c | |||
| 90d86ea59e | |||
| 64891286ba | |||
| e52a3ceb48 | |||
| 8cce9cf641 | |||
| 896dff9619 | |||
| 84a0347df1 | |||
| fc5e44f391 | |||
| 8bf49aa4f2 | |||
| b8079bb6eb | |||
| 5dcad7a387 | |||
| 83e5f74b3d | |||
| 3d402134f5 | |||
| b8b64a3e0f | |||
| c0bf7bf9ab | |||
| 0144f81c28 | |||
| 78f4959521 | |||
| eff1ef2d70 | |||
| 782b07c752 | |||
| bd67677389 | |||
| 8c9e04daaf | |||
| bddc05e787 | |||
| a49d023bd0 | |||
| 7b06ba0b78 | |||
| 344b73dab0 | |||
| 0870514194 | |||
| 0a61ffea3a | |||
| fbc650791d | |||
| 4b41aa1226 | |||
| 3fd68d3ec6 | |||
| d41ceb0d31 | |||
| aee970e80b | |||
| ef8a24ba53 | |||
| 2edf91d315 | |||
| 9fe377b288 | |||
| 996ca8d17d | |||
| b356595eb5 | |||
| e4668e5328 | |||
| a846e483be | |||
| f6e3df69eb | |||
| 1a6c1f0589 | |||
| e3e5d8a3a5 | |||
| 505f6b7373 | |||
| 7d907d9d65 | |||
| d00ba4b465 | |||
| d4deb2a100 | |||
| 5999b0a959 | |||
| e2f1e6697a | |||
| baee96347d | |||
| f60d8f6d18 | |||
| d3300e9564 | |||
| 877390a2ba | |||
| 5afe2af365 | |||
| 5028d559c5 | |||
| deda4f1bae | |||
| 927a9d10a7 | |||
| ad96cee14c | |||
| f95bb4953f | |||
| 8c594de432 | |||
| 330ac2443c | |||
| ebe6272ac7 | |||
| 982e732b74 | |||
| 27de5f42bb | |||
| 37dff58289 | |||
| fc9d90c231 | |||
| 68b31d31c3 | |||
| f7f08be312 | |||
| d14901548a | |||
| 6ebdf92d40 | |||
| abced6720b | |||
| f4604db164 | |||
| 8327c390cf | |||
| bd251c0dbd | |||
| d04209d30f | |||
| 8782778eb3 | |||
| c8515ae862 | |||
| a2fa417af9 | |||
| 93f420939e | |||
| 88cd02d750 | |||
| a35e50c02a | |||
| 566c1eebd2 | |||
| 65c3195b39 | |||
| 76b0b4ce9c | |||
| 02b9ac9764 | |||
| 17b94cdfe5 | |||
| 83166e21a5 | |||
| b4ea89f9d6 | |||
| 00706f0ccc | |||
| 3798dde3aa | |||
| 5bf2258505 | |||
| 33b9c68677 | |||
| 58d9b00a0a | |||
| 7ef018fed0 | |||
| 3d9fc7ab53 | |||
| 3d6b2e4617 | |||
| 886e325cbf | |||
| 60bdffee84 | |||
| a9dc43f7fb | |||
| 0cc0e51d5d | |||
| 14d75b222f | |||
| b10d2b7365 | |||
| 8aa3679323 | |||
| 3403b87cb7 | |||
| d55fdf2205 | |||
| 7cb3f40dab | |||
| 65c362efce | |||
| 8065eebca3 | |||
| 7f062c7ca5 | |||
| 0adad4a053 | |||
| cb39e6e0b8 | |||
| 94eebc3ee5 | |||
| 5d5f4d1765 | |||
| ed0665407a | |||
| 3869a67180 | |||
| 7e75491e88 | |||
| ca33d66816 | |||
| 055e3db80a | |||
| 620ddf1228 | |||
| d71fe3eda0 | |||
| bff5049a98 | |||
| 536b2c2475 | |||
| 7a3033c150 | |||
| 05db054fb9 | |||
| 8aa445e2fc | |||
| 3658136b82 | |||
| 64419ca4f4 | |||
| 913cddec61 | |||
| 25e6a31004 | |||
| 3d58035b41 | |||
| b94a150685 | |||
| 22717c15af | |||
| cb07fc2abc | |||
| ea2a190bd1 | |||
| e6f3c1b3da | |||
| 22f732aa4e | |||
| 5e531d7cca | |||
| 0deae5f0b8 | |||
| 9ff4187fb3 | |||
| 6a1e70bf40 | |||
| d097218a45 | |||
| cc87a2c867 | |||
| b26ba9c4d3 | |||
| 88c94d1cc0 | |||
| 6cda0b6016 | |||
| 66dc1d90d8 | |||
| f7cab0cf71 | |||
| 83e2df4c46 | |||
| 31216ed1b2 | |||
| e9930bb2bc | |||
| c8a0540fd2 | |||
| a9b7a0cb27 | |||
| c0ff491972 | |||
| 146c105961 | |||
| 35fca2062e | |||
| 2c4e5c7a47 | |||
| e561da33bd | |||
| 5f6bdb0a8f | |||
| 6276a4a7c4 | |||
| 4fa50b96ad | |||
| 5aef158ff0 | |||
| 4054ac192a | |||
| febe8e4d9e | |||
| c924c32d54 | |||
| 743eb5cc26 | |||
| f4585cdf77 | |||
| c36977f0b1 | |||
| 44e4bd0b54 | |||
| 1427b8137a | |||
| a9cb354225 | |||
| b4db17ab3c | |||
| ba969fb9f2 | |||
| 87ac252c8d | |||
| ada9081ea2 | |||
| d6a29e582f | |||
| 03c4184067 | |||
| 0a82280f20 | |||
| a7fa2f87c5 | |||
| 3a11a5a82e | |||
| 08a38af553 | |||
| 043a54cf3e | |||
| 16c8f6d160 | |||
| 285472bc78 | |||
| a77adcd4c7 | |||
| cebd4392f2 | |||
| 64a3de5a7a | |||
| 261609f706 | |||
| 17cf73001c | |||
| ad566d793a | |||
| b499ed3d20 | |||
| de8de9c0f0 | |||
| 3b36dce5c2 | |||
| dcd8dfd5fc | |||
| 78f3b6297c | |||
| a49fe3b04a | |||
| f23cc7daa3 | |||
| cafd9d7ace | |||
| 1b6c120864 | |||
| 99afc50ebf | |||
| 3286f7c5ba | |||
| 72ccca9faf | |||
| 3c294d9721 | |||
| 1aff5f5bb7 | |||
| 937ae4c5e0 | |||
| 056865f59a | |||
| c58246b43c | |||
| 3495d1affd | |||
| b0ce072370 | |||
| 9f4d18baac | |||
| f65c8f8c6f | |||
| e0633b89bb | |||
| c3341ce4dc | |||
| 43f9b90c92 | |||
| 6ee45dcdcd | |||
| 344246725b | |||
| 57763ca1e2 | |||
| 40b7e24fcc | |||
| 9e0f16a629 | |||
| 33f4f3a5a1 | |||
| 07a3b75b3e | |||
| bdea2539d1 | |||
| ed3d7b0c45 | |||
| cba44c45fc | |||
| 07b533f95b | |||
| 7b0a79dec5 | |||
| befd01aa96 | |||
| 1cc263624d | |||
| 4daa2c1cde | |||
| 7081c57571 | |||
| 3757579ffc | |||
| 2962dc351b | |||
| c04c685469 | |||
| 72c9769953 | |||
| 42759b94bd | |||
| aa9e69f03e | |||
| 0f3939df15 | |||
| 62265a1bc9 | |||
| 76b2cec8ee | |||
| 3d82f0cfe1 | |||
| e5546bc8b0 | |||
| 6fc0a00ac8 | |||
| 3e5ba5c064 | |||
| 4c32a8e3d4 | |||
| 2ea316d754 | |||
| 548227a55b | |||
| a831a20910 | |||
| 811f66de84 | |||
| 84d806328b | |||
| 285d4c4c65 | |||
| 8506f5b17c | |||
| a87fd56b3e | |||
| f0cb30e2b9 | |||
| 038743c694 | |||
| 0e6cef99a0 | |||
| 92c925fe95 | |||
| 4562d5459d | |||
| 8393ded1b3 | |||
| b0dc483165 | |||
| 3c0ca81311 | |||
| 157a63a023 | |||
| 80e22a7e38 | |||
| ddf2da3d76 | |||
| 0e6478a60f | |||
| aed2c085b8 | |||
| a7592b2ca2 | |||
| 265c100845 | |||
| 84e8288f61 | |||
| c69b4561fb | |||
| 6db0af8d04 | |||
| 842d2cbb0d | |||
| 9fb64ded10 | |||
| 9d26713b1a | |||
| eb3c55b5cb | |||
| 896596f672 | |||
| e4de14612f | |||
| 1d2b276425 | |||
| 35c6a200ad | |||
| 90a7faa15e | |||
| 91f5fe1c0e | |||
| d48a7d303d | |||
| bb816f0c74 | |||
| 93abe97ea5 | |||
| 97cf29ffbb | |||
| ed35613d64 | |||
| f5ec8363b4 | |||
| 87956de092 | |||
| 0f9315383c | |||
| 3538d796a7 | |||
| 24f3824524 | |||
| 70b20d7d89 | |||
| 7b21a0620b | |||
| 3949af6d3c | |||
| d1f62e3ab4 | |||
| 6e644fa480 | |||
| 5bef968068 | |||
| 543cfe0a73 | |||
| 3ba91b8072 | |||
| a27a9e6000 | |||
| 7e839e6962 | |||
| 809a1b3dae | |||
| 9b80628f84 | |||
| a21a006fe9 | |||
| 54d16a458a | |||
| cfc5f42ef2 | |||
| e3d24238e4 | |||
| 56e7b36959 | |||
| f29791470f | |||
| 52d9b53b74 | |||
| 839a78f2e0 | |||
| 680ce0a7af | |||
| 06b0de9c77 | |||
| 76b0b7b1ae | |||
| fabda4df3a | |||
| fdcdaf596a | |||
| be44cefbe7 | |||
| c1050e624b | |||
| ae6d3b9bff | |||
| 25aa0e2e46 | |||
| 8f7578eef1 | |||
| 29ce4807fb | |||
| 41f6945be1 | |||
| 718ec468ff | |||
| d429801498 | |||
| 024091e6b5 | |||
| d849e9de98 | |||
| c0e40da2ab | |||
| dff3766501 | |||
| 2767ec54e1 | |||
| ac72c02793 | |||
| 69c51eee4d | |||
| ff5a4eeb96 | |||
| b48f870701 | |||
| 10807ebdc2 | |||
| 5d649f83ec | |||
| 65b25adceb | |||
| d615985b8a | |||
| b019440980 | |||
| 38ed4b2017 | |||
| 2ad0d51226 | |||
| e4a611bcae | |||
| f3728d99b9 | |||
| b87f60a917 | |||
| 28f26da6ab | |||
| d3e780d617 | |||
| d549c2b5c9 | |||
| f310ce376e | |||
| 553fc9b1fb | |||
| 6dde9f7dc0 | |||
| 3dca1175e5 | |||
| 09c5e38322 | |||
| fe6f1f0bb6 | |||
| 250c656b9e | |||
| 9a0b5b65b8 | |||
| 57b2fb4c62 | |||
| 099c3d829e | |||
| a1a6d02b6f | |||
| f2ad7fb9c4 | |||
| 1bcf709fcf | |||
| 47fc230893 | |||
| be05d85570 | |||
| f598fa13a9 | |||
| 568859d16f | |||
| b5ed0a637b | |||
| 17eff0aed4 | |||
| 0a3f048eed | |||
| 3cde897557 | |||
| 0500e7d016 | |||
| 778663ae69 | |||
| 636cefb9f3 | |||
| 1236776aa2 | |||
| 51a6a5cca5 | |||
| 3326c86e91 | |||
| b0dbc3fe39 | |||
| decc1efb74 | |||
| 2cf1c32d18 | |||
| fc6e3840b7 | |||
| 5e85c1a11b | |||
| 468bfce599 | |||
| 1e6e4043ed | |||
| 67564513d2 | |||
| ed2633bf95 | |||
| 3e70021406 | |||
| bf8dd31914 | |||
| d4e94f5086 | |||
| ae77fd60bb | |||
| e79c790264 | |||
| 46029bb8a0 | |||
| f74c225338 | |||
| c479fe32b3 | |||
| dc23ee0ad2 | |||
| a5c32db01b | |||
| d7142312c9 | |||
| 283ab0e7ea | |||
| b6dd61cea8 | |||
| 11970d276d | |||
| d618716ec1 | |||
| 4f0f977f04 | |||
| 2c4b1d8a8c | |||
| b2810c6deb | |||
| ceb2b56b71 | |||
| d14fa5f8a4 | |||
| 79263a52ac | |||
| ecb3f83e83 | |||
| f6aedb35ce | |||
| 3b7d25ac49 | |||
| e964d4acf3 | |||
| e306085b81 | |||
| b094ad4f2b | |||
| 19c6b969ab | |||
| acfda848cd | |||
| 52400e2561 | |||
| f62576a2be | |||
| 19bf9f59e9 | |||
| fadf7cfc7b | |||
| ec0c9399fa | |||
| 37b923245d | |||
| 38a676f6f7 | |||
| cd1df6f6b1 | |||
| 4a24fe8c53 | |||
| 6dac3dd248 | |||
| 37d393cbc8 | |||
| 27f155374a | |||
| 8102137ad7 | |||
| 9c46f4653f | |||
| 29b4752d0e | |||
| 2724039c09 | |||
| 6ae4e88475 | |||
| facabd68d7 | |||
| 18f043015e | |||
| ab259a1af9 | |||
| 1dd96a7628 | |||
| 1ee7ecb1f0 | |||
| 67548a4d9a | |||
| 9fbe95ad48 | |||
| 91c15b2475 | |||
| c9550b48d8 | |||
| a1d090a6fd | |||
| 4870765e1b | |||
| d8be2ed276 | |||
| 2b371e99bd | |||
| 005e39871b | |||
| 96dd9eeb44 | |||
| 65b06f6046 | |||
| 0515be4334 | |||
| e32de83758 | |||
| e767461f65 | |||
| 632c7c4826 | |||
| 7f9d381c7b | |||
| 4d5d6661d5 | |||
| b0b87eda02 | |||
| f63a673a8b | |||
| 290dd0c5d2 | |||
| 194bf2b852 | |||
| d6d5e7ae3d | |||
| 39a6cc4b5f | |||
| a24de15060 | |||
| eb021accd1 | |||
| 98a77dde00 | |||
| 854988bc5f | |||
| bfeed2ab9a | |||
| d11fc71e79 | |||
| f1703fa322 | |||
| 06675acc67 | |||
| 57ad6bc37d | |||
| 0192b0b7e4 | |||
| 3b098b845a | |||
| ac398f1ffe | |||
| 92dfb9c83c | |||
| 38d6cb090c | |||
| e93172bd33 | |||
| 30fcca4b64 | |||
| 4f6320d3aa | |||
| 62dbf8485f | |||
| 9331ed39d4 | |||
| 35dd9cfd22 | |||
| 0ac6c36af2 | |||
| 3c4b959f78 | |||
| a00687b092 | |||
| bb6b087862 | |||
| bfb438dc89 | |||
| cd3f69c290 | |||
| d54315392e | |||
| cfa8107ab9 | |||
| f4e5b29708 | |||
| d65fea1147 | |||
| 25a3c109c1 | |||
| b526eed346 | |||
| 59c6a71b72 | |||
| c7a2a0faa1 | |||
| bfb5ea50a9 | |||
| 149d84edca | |||
| 7636abc158 | |||
| 6eace187e7 | |||
| dd1838a7eb | |||
| dd928cf956 | |||
| 38be230467 | |||
| 1f747a28a9 | |||
| 1a7732b285 | |||
| f8ea416a4d | |||
| b9bf81d548 | |||
| 8975e2a6b5 | |||
| 394cd77bec | |||
| a9ac4b5e23 | |||
| 10e759f1f1 | |||
| 777d4f5279 | |||
| c65c882ecc | |||
| a66ee9fafd | |||
| 757401dd0c | |||
| 11e3770864 | |||
| fbb317e9c8 | |||
| 9d7698a359 | |||
| 44fd11f4dd | |||
| 8779113131 | |||
| 26cfd0a616 | |||
| 75e153dd99 | |||
| fa364d6ea3 | |||
| 13e5c13695 | |||
| 43b3b54197 | |||
| 3a16d4a12e | |||
| 50fc9235de | |||
| 70287d3c49 | |||
| 41e9f7985f | |||
| c3327977da | |||
| 905bfacf44 | |||
| 053e95033f | |||
| 5a1203be0d | |||
| 745fef7425 | |||
| c9d625a237 | |||
| 334731f56b | |||
| d5e7672a45 | |||
| e702aa0252 | |||
| 2684e815e0 | |||
| efbc93229a | |||
| 05539ad5b6 | |||
| 670aae2e11 | |||
| e6ff68dc2c | |||
| 641b116f04 | |||
| f81f7194ed | |||
| 161d20e614 | |||
| fc4dcd46db | |||
| 891dc87064 | |||
| b866631448 | |||
| 672d69c68a | |||
| 507c31ec14 | |||
| 65cc40bdda | |||
| 067895fa5f | |||
| 3f7f26c74b | |||
| 9a6b5940cf | |||
| 828f4a63bf | |||
| 707fb55625 | |||
| 8d41ae09c8 | |||
| 7ec0faca1e | |||
| 300fa29446 | |||
| 6981f7b3ae | |||
| 682a1e97e4 | |||
| 1d71dd3851 | |||
| 5edfda46e5 | |||
| d7754a97c7 | |||
| c79aa6ad8a | |||
| 525e091472 | |||
| 16f6de677d | |||
| 12c36bab6c | |||
| c429859cbf | |||
| dc76b2af97 | |||
| b75e7687f4 | |||
| ece5af2895 | |||
| 1aaa33552e | |||
| f622871eb0 | |||
| 060b01260d | |||
| 871f8a4793 | |||
| c54e03d0f2 | |||
| aaf3f75990 | |||
| 512a26cee4 | |||
| b4a793ed26 | |||
| 5d2c74008e | |||
| 7fafc68940 | |||
| d1af2af499 | |||
| a5206eb696 | |||
| 1ff0d137ab | |||
| 07aa65b55e | |||
| 0fadddec65 | |||
| 1bebe53cef | |||
| 43019c744c | |||
| c585774162 | |||
| 75e87a58da | |||
| 19e84fea62 | |||
| db39f9c4dc | |||
| dae45ae0d4 | |||
| efeffc6e01 | |||
| ebf0f2f68a | |||
| 09bd1d8c40 | |||
| 40653e40a4 | |||
| b3e4efbabe | |||
| 279101d464 | |||
| f571feee72 | |||
| 900afd1c8c | |||
| 08a72d5251 | |||
| 736a6cd955 | |||
| 75ce5e5df3 | |||
| eaf2143162 | |||
| f0bdb8dea1 | |||
| 60093cfff6 | |||
| 56bb7b53cb | |||
| 0cffeca102 | |||
| 937d4462ca | |||
| db5a39572c | |||
| ecc9c67e1f | |||
| 0901ce1b68 | |||
| be6e77379a | |||
| 726f5de778 | |||
| 98b835e0a7 | |||
| 04ffb641a6 | |||
| 1b7233b673 | |||
| eaa0f33473 | |||
| c03b382d61 | |||
| e633694255 | |||
| 278b25bad2 | |||
| f89f0838dc | |||
| b1729e3bcf | |||
| d1ab85a1a6 | |||
| 7f5b64c91a | |||
| 78b68283c4 | |||
| 9e3b1c9f8a | |||
| 5dc54c7adc | |||
| 320e5b850f | |||
| d8395d8c42 | |||
| a20c5a1e7f | |||
| 3bdfcaa541 | |||
| 7b2faf2016 | |||
| 42902dabac | |||
| 14521eb6dd | |||
| b9533f409c | |||
| 4df68aafd2 | |||
| c72ceaa979 | |||
| 8ac79ca0ad | |||
| e0bfaf1028 | |||
| b361b91ec7 | |||
| b5d1eba4c1 | |||
| ba447344d6 | |||
| 7b68aa7bdc | |||
| 5d15e57294 | |||
| 0bf8ff151e | |||
| 06fae05910 | |||
| f68ac8155b | |||
| 15484aa296 | |||
| 5b113a5041 | |||
| 1320e3efdb | |||
| d32f447bda | |||
| b74c4e4ac1 | |||
| 35333403ef | |||
| a627648249 | |||
| 127fd095e7 | |||
| f8934c09ff | |||
| 7a09c88e30 | |||
| 17526d1132 | |||
| ff7939c1c0 | |||
| 96c196b1be | |||
| adb0ca8250 | |||
| fa56a1d9cd | |||
| 3d691645a4 | |||
| e1edc5f50a | |||
| 4a8efd2e2f | |||
| 8d364c82e2 | |||
| c5059231dc | |||
| f584c91386 | |||
| b8d9c2b755 | |||
| 163377d1a0 | |||
| 8944e90175 | |||
| 33cdcb0e82 | |||
| ec870a5aeb | |||
| 0653bb5a72 | |||
| 43b6ff29e3 | |||
| a444a8a704 | |||
| 3fa18c1799 | |||
| 19147963b9 | |||
| 5056215a1f | |||
| 340b7614e2 | |||
| 8a1bd67a20 | |||
| a094df7b55 | |||
| cc893dfc11 | |||
| 8ef17da082 | |||
| 7993e619cd | |||
| 1ab8d5fb3f | |||
| 213ac3ac73 | |||
| 0a8876443a | |||
| f37a3bb9bb | |||
| 2632342f44 | |||
| 8efcf6f099 | |||
| 58343fc78d | |||
| 6c41a4c9c8 | |||
| 334be287fc | |||
| aa050e0001 | |||
| cc994326a0 | |||
| 58de07629e | |||
| 9f830e0c41 | |||
| c52d302f07 | |||
| 44049ecf30 | |||
| e1b5904196 | |||
| 88e692791a | |||
| f00667ad7d | |||
| 696d0eec64 | |||
| 513b00a30e | |||
| 0cb0dbf6d8 | |||
| 9f00515da4 | |||
| 72f31787f6 | |||
| cd686cb1d9 | |||
| d9657e9831 | |||
| 72f3e9b25a | |||
| 811b15a5b3 | |||
| ab00825f37 | |||
| e86d9179aa | |||
| 26d8e9c4c5 | |||
| 5f3ebc8a7f | |||
| 425b1b44bc | |||
| 39442e6282 | |||
| 99575e1010 | |||
| 64aa7540e2 | |||
| 3ff5dbd179 | |||
| e25d04fb12 | |||
| dd1d5a92d2 | |||
| c6e0aad40b | |||
| 99b795ceaa | |||
| 33dc60df26 | |||
| 619aeb54ff | |||
| 77ba43328b | |||
| 01a30752c7 | |||
| e56b748435 | |||
| bb4cbdff44 | |||
| 0b47e474a7 | |||
| 8e85680eb4 | |||
| fefce0d5c4 | |||
| 0ac3cb2329 | |||
| 708ab1dcd7 | |||
| 9b87ddb621 | |||
| 5dc4eb4b03 | |||
| a203c72281 | |||
| 6cf85cee6e | |||
| 1eb6a40fdd | |||
| 1bed77e4d3 | |||
| f2a68023fa | |||
| 8ccffc40e3 | |||
| dd8c1d0441 | |||
| f9f28ff176 | |||
| 3649041195 | |||
| c23c7a9379 | |||
| 9934e33b99 | |||
| 9e75fdda66 | |||
| d873a26f41 | |||
| 91aa5b55ab | |||
| 3f460a76ce | |||
| 7256ea3b32 | |||
| 4cdf77e16f | |||
| d89813e911 | |||
| 7c57b10cae | |||
| 8d1a98e03b | |||
| 65a2da4b40 | |||
| 02f6786b2a | |||
| 9da4f7a6dc | |||
| 510505a85c | |||
| 741cb3a136 | |||
| 9f5d67e27c | |||
| 93c6496ba8 | |||
| 779b648c5f | |||
| 9d5e06232d | |||
| b221c44466 | |||
| 665296f7cf | |||
| 39778d5f47 | |||
| 0af9bbb623 | |||
| fdec47a83d | |||
| 7ff913bbd2 | |||
| 94775bef9f | |||
| 3cf102334f | |||
| 627e733a30 | |||
| d31b80da5b | |||
| eb231b65f3 | |||
| 59e3b1f98d | |||
| 8b174bb272 | |||
| 4199a44bef | |||
| 777392c0fe | |||
| ede1fec5e7 | |||
| 16de3e78a5 | |||
| d7508d8c09 | |||
| 2a136c1c1d | |||
| 2578102be9 | |||
| dadee7acfb | |||
| 28f0bb4e11 | |||
| 824c8a8efb | |||
| 37f27a1262 | |||
| 2b8a7a492a | |||
| db56bbb11b | |||
| 82d26f04a4 | |||
| 5045f7eb42 | |||
| 82a6ccac4d | |||
| 2d74298001 | |||
| ce21254ed2 | |||
| 874250fe49 | |||
| c8a3acbba8 | |||
| 81e11987a2 | |||
| 668cefec2f | |||
| 212bc04257 | |||
| db401fd05e | |||
| bebe72481c | |||
| 2b9e83256d | |||
| 5763518cce | |||
| 3e4c5bab72 | |||
| bce109ab54 | |||
| 69ca635c4c | |||
| e0bf460993 | |||
| 29762a8a96 | |||
| c7ef08dc2d | |||
| 50a6698715 | |||
| 7dd2cdea1e | |||
| af87f7f2bf | |||
| 295889023f | |||
| feef2e38cf | |||
| 80d30aab32 | |||
| e910a9dc3e | |||
| 504224696c | |||
| e2acd666df | |||
| e5c0d998b7 | |||
| 63f6fef964 | |||
| 983eb6d676 | |||
| 98fedef1a1 | |||
| 75a769759d | |||
| 2354b01bad | |||
| c331b9f1e2 | |||
| afeaeeddec | |||
| ab7ef9f511 | |||
| d3ad6d25d8 | |||
| 2e29f9fa5f | |||
| 5d9f71bb13 | |||
| 82ed25bb44 | |||
| f57393c0e8 | |||
| b54cced19c | |||
| 60a0544314 | |||
| 283c1cf931 | |||
| fff53efc05 | |||
| 07d368adca | |||
| 13276d93fa | |||
| 79b1b1a586 | |||
| 2f083f3e56 | |||
| 73b0b4db9d | |||
| ca0e614b56 | |||
| 72613d06a5 | |||
| 48ad5513ff | |||
| 201d9f1346 | |||
| 1e8f1f49d0 | |||
| 65707900bc | |||
| 39c5be43aa | |||
| c4437cb293 | |||
| e2b86a49db | |||
| 8fe83be87f | |||
| 17167d4905 | |||
| 05ff7e35a1 | |||
| f67cec4752 | |||
| fd4882abcf | |||
| 0f42579e68 | |||
| 7398d8f68f | |||
| ec33109b22 | |||
| 2cfa4c1eb7 | |||
| a13b4d10d9 | |||
| 36e94e58d0 | |||
| d0a52bd483 | |||
| 38a1d3179b | |||
| 0d639d6386 | |||
| 4256057c27 | |||
| b720b47c12 | |||
| 55e4a4f086 | |||
| b4cb9f8b2f | |||
| 63298ebd6d | |||
| 73c816e468 | |||
| 0492e650ef | |||
| b8b94ee89e | |||
| 81176716d5 | |||
| 26e7ae00e9 | |||
| c75d7a685d | |||
| 4318cc22ee | |||
| 575cb720c6 | |||
| 5db34fbf92 | |||
| 7cfef2f6bf | |||
| 4603f1df4b | |||
| c69fcfff9d | |||
| 70f14101ed | |||
| a9803459ed | |||
| 43034e8e92 | |||
| ef547034f6 | |||
| e87fc60391 | |||
| 45e6e73d85 | |||
| be30c26dbb | |||
| 79e9b0762c | |||
| a9a806c418 | |||
| c7d8b6fed1 | |||
| a723efd225 | |||
| cf429dfce4 | |||
| 3fcd64a0c0 | |||
| 83cb38022b | |||
| 93c04d1f66 | |||
| 3c47898cf4 | |||
| 61e1366122 | |||
| a20636fd63 | |||
| aa8cdca0a9 | |||
| 6931a3aa70 | |||
| d001a63bce | |||
| 0d3377f48b | |||
| aeb04d97c8 | |||
| eb68ab91cd | |||
| ee242ba987 | |||
| 44a53736ff | |||
| 1b21fef081 | |||
| 5f9c50cd3e | |||
| 793d8c1d2e | |||
| 81f868a0c6 | |||
| dadbbbdc64 | |||
| bfd2153f2b | |||
| 077793fa5e | |||
| acad3c3000 | |||
| 3b4627e17e | |||
| 05976ee1a7 | |||
| c1311c78a3 | |||
| 717150b7f3 | |||
| a68c62d938 | |||
| c11f8a569a | |||
| 03436d2415 | |||
| 4ae75375e0 | |||
| 2721ef0636 | |||
| 7a232cb330 | |||
| 52f19ae330 | |||
| 275477f914 | |||
| 2ed6755d5d | |||
| 78c555b4a6 | |||
| a127125707 | |||
| f853f91c5b | |||
| e7ca5c54ff | |||
| 663d6b466b | |||
| 0e2a9de2b2 | |||
| 34df0d6ef1 | |||
| 540164849b | |||
| 252143d0bb | |||
| 480ab51650 | |||
| 972c76eb42 | |||
| e5aeea9ed2 | |||
| f204670008 | |||
| 651155c64d | |||
| 660aee6d22 | |||
| a646231630 | |||
| 1050de5171 | |||
| b7a5b9437a | |||
| 620955a724 | |||
| 2e64a277f8 | |||
| ea567a8b14 | |||
| be23f93ee6 | |||
| fcdf0e92c1 | |||
| 2d6987252e | |||
| 4a9c46253e | |||
| 5bcf9dd8af | |||
| 284adb203f | |||
| adafa841f7 | |||
| fdc5d25d03 | |||
| 294a7077de | |||
| 990d0ec543 | |||
| bb90c4dff4 | |||
| 00e3d992e8 | |||
| 937bfa4e49 | |||
| 1d9c211eed | |||
| 76ddf6b8da | |||
| 7f1f29b0d8 | |||
| 222471744f | |||
| cc100be26e | |||
| 966b571b7c | |||
| f3e710394a | |||
| bfd1f1fbfa | |||
| a09146b5e0 | |||
| bbf2b08f48 | |||
| e2dbc661f1 | |||
| 7626e09f66 | |||
| 248a6980cf | |||
| f956bfc797 | |||
| 6da79783ea | |||
| 22329e0ab2 | |||
| a94b0329c9 | |||
| be8601f8cc | |||
| bd441e83ae | |||
| 02bd9cc403 | |||
| c9f6a3583c | |||
| 076aaf829a | |||
| 85f0c5a445 | |||
| d5263a56ce | |||
| ef5b55b4d1 | |||
| d65e65b2b1 | |||
| 6aa641e5aa | |||
| 504839951a | |||
| d55746f62d | |||
| 144010295e | |||
| 181c752488 | |||
| bd4aca5c12 | |||
| ad6d73c875 | |||
| c5cc83d424 | |||
| fe949bdf67 | |||
| 766fe466d6 | |||
| 333a288248 | |||
| 613df414ed | |||
| be050693f2 | |||
| bf957f435e | |||
| 3a6f688265 | |||
| 1084a7896c | |||
| 9ea2b31541 | |||
| 09da986742 | |||
| cb70a5fef5 | |||
| 4fa6a6aeef | |||
| ab31e8dde9 | |||
| 53d7b5449f | |||
| d33a34f016 | |||
| f6ff5a2805 | |||
| 1518e5bc98 | |||
| 78f48d65d5 | |||
| b81ec224b7 | |||
| 4be6cfebcd | |||
| 98973dd8b9 | |||
| 1218b6ff2a | |||
| ba5c77c9e5 | |||
| cbaedffce2 | |||
| cb60603950 | |||
| 0a69e7803b | |||
| baa9090198 | |||
| e78a08b8fc | |||
| 7e5e6012df | |||
| 0a1d24d1d9 | |||
| 35555bfb8a | |||
| c9cb42df40 | |||
| 2be03028f4 | |||
| 214dd0a522 | |||
| 182e0796df | |||
| fb844a8ed1 | |||
| 6be3e747ca | |||
| 23f63e4196 | |||
| fd6837b267 | |||
| 1c29f921e0 | |||
| 1ab6e01de2 | |||
| 801618740c | |||
| 2469563b26 | |||
| 00139caf43 | |||
| 21d102c84f | |||
| f17d9967c2 | |||
| 0569ef37ba | |||
| 984334c9a1 | |||
| 34a25e61c7 | |||
| ed3f45953e | |||
| 80de11bc5b | |||
| c9fe84c9aa | |||
| 5f98bb0ab0 | |||
| d86d5314ba | |||
| 700c8730cf | |||
| b4429e1a42 | |||
| a8fa3ca5cf | |||
| 9aef7b0d6f | |||
| 2575eef3c0 | |||
| 8236276a90 | |||
| fdc68812c5 | |||
| 9db6d18d11 | |||
| f962afe146 | |||
| adcd569852 | |||
| d045b7f223 | |||
| 57cb6a7530 | |||
| baa1ed9be3 | |||
| 16af6e1a29 | |||
| 0af8998be6 | |||
| c32f517fa5 | |||
| 9131d5216f | |||
| fb14a7991d | |||
| ff53862dab | |||
| 49245a20c5 | |||
| 13bc031163 | |||
| 0c18c1c35c | |||
| 63dc19ce25 | |||
| 6871c2fc0a | |||
| 4ae3a8b2b0 | |||
| f2e562b5de | |||
| f7e2266c3f | |||
| 361a3056cb | |||
| ca0437556d | |||
| 51899957a9 | |||
| 7b0b760d78 | |||
| 4f5866b5a7 | |||
| a6b5033cf1 | |||
| a6296ecd67 | |||
| bb1df15958 | |||
| 249431f45f | |||
| cbe129795e | |||
| 2a135e245b | |||
| 05a0b3557a | |||
| c7cfe8b608 | |||
| 8d3e1d28a7 | |||
| 7841e15583 | |||
| dd164fbc86 | |||
| 23fe02e84a | |||
| 94e72238f2 | |||
| 8f7ac520eb | |||
| bd193201b2 | |||
| 8ced672d24 | |||
| f218812858 | |||
| 8a7b980fc0 | |||
| 385c9877f8 | |||
| 10df93536e | |||
| 6cad27896f | |||
| 052392d97b | |||
| ce6b5a0688 | |||
| 1879185e42 | |||
| a928a08f9d | |||
| 1805cb6857 | |||
| 6ce625b535 | |||
| 4702f12818 | |||
| 4f3054f07d | |||
| 0d7bd52e21 | |||
| c3466f579c | |||
| 7c105d7af5 | |||
| 924b229afb | |||
| 890d66ecf0 | |||
| 143049922b | |||
| e6ccef2cf1 | |||
| be61e9f584 | |||
| 89d0fda9fa | |||
| 6a85bab5da | |||
| c1a55b063e | |||
| 77c914bce5 | |||
| cc60f03b2e | |||
| cc9ccdbbd1 | |||
| 9dfc8f573c | |||
| 4e2fdb464a | |||
| 73b854874e | |||
| 0016512df1 | |||
| 527139978a | |||
| 47bc68fa6b | |||
| 972b670a64 | |||
| d7c416f243 | |||
| 3ace7a0468 | |||
| d305023f5e | |||
| 963392a5ae | |||
| 2f453acf5d | |||
| 4ae1576726 | |||
| 17bd0b3248 | |||
| a1ad1aee99 | |||
| a817ed0692 | |||
| 828a6cf07b | |||
| 962c35aa08 | |||
| b327645e64 | |||
| e1b42616a2 | |||
| f96638c42a | |||
| 6272152dfe | |||
| 030a200c08 | |||
| 994da63b4d | |||
| 2315bff280 | |||
| 98dddf93d8 | |||
| fd2939e18d | |||
| 80c27e0822 | |||
| b463f24eda | |||
| 2a849444db | |||
| 69e106c0c5 | |||
| 926481dace | |||
| a3b2cde58d | |||
| 30f37d2cc6 | |||
| c4d61dd9fe | |||
| 210870f840 | |||
| 4cb4bd38eb | |||
| 58c6d19f7c | |||
| f99ae94747 | |||
| 6868ca7953 | |||
| 87a5a4ef32 | |||
| c67a5d677c | |||
| 1ce6f0e6f4 | |||
| 740b4ff865 | |||
| 1059f62566 | |||
| df3193c1ee | |||
| 67860e3704 | |||
| 35fbb1ecb6 | |||
| c63a71ad42 | |||
| f33645f739 | |||
| d7ba31cab8 | |||
| 342b1b7d6c | |||
| 936013f60c | |||
| fdf2eddc73 | |||
| 4409753014 | |||
| 9172ae3d19 | |||
| e2f60adc95 | |||
| 1bb93d4fce | |||
| eb90eab632 | |||
| 0f4975fd7f | |||
| b5b1f06a11 | |||
| 86f8eb0930 | |||
| 91ad0e7572 | |||
| b034ee98fe | |||
| ded07f8781 | |||
| 849bdd87e1 | |||
| 643e48efd7 | |||
| 92f072cf70 | |||
| 95bf2e2e41 | |||
| 6a6c6d84eb | |||
| 08a689c81e | |||
| d1174385ef | |||
| cb5f590e10 | |||
| 5ed9c66ed9 | |||
| b8f52d14f4 | |||
| 5d295c24f0 | |||
| 8be9da8280 | |||
| 819c33fee2 | |||
| 75a2cc4ecb | |||
| e2833cf303 | |||
| 801de73dbe | |||
| 6a53c0b3d4 | |||
| 58b122d97d | |||
| 276b748aa6 | |||
| 23570097cf | |||
| 62a07df45e | |||
| 593a69ce25 | |||
| c33603e324 | |||
| 29fa358077 | |||
| 49766388bc | |||
| f23267bddd | |||
| 4484acf9d6 | |||
| 47ddace96a | |||
| 8aadbcd786 | |||
| 517bc9db0b | |||
| 16bfa7b846 | |||
| 570b2d0e88 | |||
| 2653a0749a | |||
| 3de0008543 | |||
| d4e2d7e8a8 | |||
| a9c08c6f52 | |||
| c2aa5c35f7 | |||
| 423f1a8758 | |||
| cc5f684e33 | |||
| b6646d319a | |||
| 3667fa4e44 | |||
| d1c80154f6 | |||
| 3c2bfc742e | |||
| d60fef753f | |||
| 70ed2d0d03 | |||
| 716d203a78 | |||
| 9719a7dd56 | |||
| c097233bf3 | |||
| 69a583281f | |||
| 8e90c9af2b | |||
| a784284b7f | |||
| 0509edf08d | |||
| 7ca20f424f | |||
| b74d51c2a8 | |||
| 58061cd121 | |||
| b8f6be5389 | |||
| 7c766b3313 | |||
| 91b81b587b | |||
| 780a4347b8 | |||
| 606ad08dd1 | |||
| 75c31dff1d | |||
| 473b90419f | |||
| f88b85e126 | |||
| b122f8e9d0 | |||
| cb8b1595a1 | |||
| 1bee919276 | |||
| 78b1da5c00 | |||
| bb8239ccda | |||
| 2a594ad0a7 | |||
| b05073550c | |||
| 37d6a34e58 | |||
| 4f0cba9bb6 | |||
| 4d1c754af9 | |||
| c1cfde21d7 | |||
| bb1f9cdecd | |||
| b259b0ca28 | |||
| 0051dfc84f | |||
| 9f294e6ce5 | |||
| 153ea8be03 | |||
| f3f7f97f8d | |||
| 9bb6854e64 | |||
| 4bba1e6cb7 | |||
| 597e8fe407 | |||
| 556c541ffb | |||
| 5963f18f7c | |||
| 0dac6b7be3 | |||
| 296ede780b | |||
| faaa19331a | |||
| 88cb5886f3 | |||
| 2fcc3f86c0 | |||
| 9362fde9eb | |||
| 56f4d781c1 | |||
| 7a3637ff5a | |||
| 2923c0968e | |||
| 98cfe99d65 | |||
| bdd97fe0b2 | |||
| 6b500bc83b | |||
| 92a12a2ec1 | |||
| 04d79040f9 | |||
| 3201ddc680 | |||
| 2f06de54c5 | |||
| 6489ec9bba | |||
| 1a5ba22fe7 | |||
| 8f9713ed53 | |||
| 90eb68b3b9 | |||
| 95fcbcb4f2 | |||
| b97688d119 | |||
| 5ea3627cab | |||
| d9288213ec | |||
| 614c86fb7d | |||
| 9f651ee40f | |||
| 774c8c3fd4 | |||
| b711d2f750 | |||
| 8a793d5942 | |||
| 99f52c60ed | |||
| 2c2e108301 | |||
| 563165e6ae | |||
| f1a31b4793 | |||
| 5e9b6bd69d | |||
| 9b990c4eae | |||
| 7a625a449a | |||
| c2b62359d5 | |||
| 6722e8972e | |||
| fefe7a3452 | |||
| 90a1322929 | |||
| d698eb69e2 | |||
| 0ef00e9b82 | |||
| 95cedb6640 | |||
| d736da4208 | |||
| be83788666 | |||
| 5a28a51abc | |||
| 8a84df752c | |||
| 85f53b210d | |||
| 5d13c6cd01 | |||
| 98a0d381e9 | |||
| e1d20fd0b5 | |||
| d1035ecd8f | |||
| 0e651facdd | |||
| 9fdddfc332 | |||
| 7d2913709c | |||
| 3623199e8d | |||
| e4b23f7a47 | |||
| f056ecdcd5 | |||
| 857a03a074 | |||
| a34deee4f5 | |||
| fc9c8ae482 | |||
| 08c63f06eb | |||
| bbff510ef1 | |||
| f747435952 | |||
| e6edad8f46 | |||
| 05e44b9644 | |||
| 16bb7ab841 | |||
| 9248f02557 | |||
| 9485a56af1 | |||
| 021c8db58a | |||
| 8ab180edf8 | |||
| ab35b685d4 | |||
| 86745721ee | |||
| c34fe09a79 | |||
| 1fa9ff2c05 | |||
| e8ef0cf63f | |||
| 8c84efb8fb | |||
| f3a7620ae8 | |||
| c7969ed5a5 | |||
| 900926c0ed | |||
| df94f4288a | |||
| 969efe687d | |||
| ee3f1292d0 | |||
| cacb239040 | |||
| 28d1789783 | |||
| 633eb98e34 | |||
| 4854c03096 | |||
| e853119c77 | |||
| 161a58bafb | |||
| f5fd94e815 | |||
| edde6210f1 | |||
| 507e19945e | |||
| 4a35bf32ea | |||
| e04bf9e4bc | |||
| c384d224c0 | |||
| 35427f998e | |||
| 1174da2bc3 | |||
| 11e8a47030 | |||
| 8c4e9bcf0d | |||
| 9dfd624901 | |||
| 79e65503a9 | |||
| 59f18b9d9f | |||
| fb3699fb89 | |||
| 9d2d59b5d2 | |||
| aefb2fa3c3 | |||
| e8aa80f904 | |||
| 990988f920 | |||
| 576d9a4e7e | |||
| 1d462ee424 | |||
| c9b09555c4 | |||
| 860b5bf967 | |||
| 5063480a38 | |||
| 3400ae9dbe | |||
| 3385264eb2 | |||
| 34646f1c6a | |||
| 50aa63a5a0 | |||
| 64557bee43 | |||
| 7c21c4513e | |||
| c6d6378005 | |||
| 4f6979967d | |||
| e633c51b50 | |||
| 143f0accef | |||
| b413f3da26 | |||
| 6eafa552bb | |||
| 7a0514d9b4 | |||
| 7e7565299e | |||
| ed34a089c6 | |||
| d14a2c5282 | |||
| f014406b65 | |||
| 58771ecca6 | |||
| 5d9dcb634b | |||
| 19c2c1edcf | |||
| 0430e7931e | |||
| bb8e607442 | |||
| e61ada944d | |||
| 46730315e3 | |||
| 4869142034 | |||
| 8e42e17bbf | |||
| 38c8b84a26 | |||
| c652626a37 | |||
| 06f6e47ebf | |||
| 403b180b1d | |||
| ee008acfbd | |||
| d149092ac0 | |||
| eafa136c69 | |||
| 402c885987 | |||
| 5e7e0508b9 | |||
| ff1d5fb794 | |||
| ad3f63b5c4 | |||
| a3e51e6dee | |||
| c1b9c79f54 | |||
| e0bc040b0a | |||
| 85eb4c7537 | |||
| 1f929d47d0 | |||
| 608662d73b | |||
| 7841d23e77 | |||
| b72dda4ada | |||
| c59c8a1ea2 | |||
| 1522293be0 | |||
| b37bc99330 | |||
| 7f905724b1 | |||
| 2bf5bb1625 | |||
| 08d3376740 | |||
| 7bace76176 | |||
| ef336dbcc6 | |||
| ca7217e717 | |||
| 3931cb7871 | |||
| 9e8de4abe5 | |||
| 26be845563 | |||
| 2f11a629fa | |||
| a295437e11 | |||
| 04597fb804 | |||
| f2f002409b | |||
| 509de877ca | |||
| 63aea4a7dc | |||
| 6470c748db | |||
| 25a6429e6a | |||
| 4fa1c2a97e | |||
| 9ad39d77cc | |||
| 92527126a8 | |||
| 02b4a4c974 | |||
| ede570be21 | |||
| 08627e9df5 | |||
| 6d9f3adc86 | |||
| 96433b4e39 | |||
| f4947cc2ae | |||
| 7b554d4f72 | |||
| 5b54544438 | |||
| ef78d23494 | |||
| ef8a7f330d | |||
| b72e0f3060 | |||
| 2a0bab938b | |||
| cd637629c4 | |||
| b9adfd801d | |||
| 69355514c9 | |||
| 33dc947c21 | |||
| 6de021d8d8 | |||
| 9be86621bf | |||
| a7a0876298 | |||
| 31b42345c3 | |||
| 1b172e729e | |||
| 3bf387a2d4 | |||
| 9f20bbb046 | |||
| 82af555974 | |||
| 50638b5213 | |||
| 650df95b72 | |||
| b2115a4162 | |||
| d67bf16a08 | |||
| a4c9b64224 | |||
| 8f572e5fe6 | |||
| e58873044b | |||
| 8ada92a69f | |||
| 3c8ed5c000 | |||
| c127d5b64a | |||
| 2d3bd0809a | |||
| eef955a9dd | |||
| e59ce39dc6 | |||
| 62815f5c3c | |||
| f496010273 | |||
| 143c4e3322 | |||
| e7f1e99a5e | |||
| 140a031515 | |||
| b7c91941b8 | |||
| 33f0b6da67 | |||
| ee18fe9bba | |||
| a51330cf07 | |||
| a67aed2744 | |||
| d979e19315 | |||
| 4c74d16795 | |||
| 6e541a432f | |||
| d8f47e248a | |||
| d1a869496b | |||
| f42a37555d | |||
| d9e019bd87 | |||
| ce194fa5d8 | |||
| b5bdf57636 | |||
| a3a81ce7c6 | |||
| 61f347401c | |||
| d985a4c250 | |||
| d31947e1f0 | |||
| e4659b7d7c | |||
| 8827a534db | |||
| ddf48b45a5 | |||
| 8eabb9b02f | |||
| 8a195a0b35 | |||
| 955206aaf0 | |||
| 082dd7d5ee | |||
| 90714cf624 | |||
| 61798d33f0 | |||
| 6e2a41cb26 | |||
| 515897e180 | |||
| fe4a8f33b1 | |||
| 304d848f53 | |||
| b5f738abf3 | |||
| 7ebed06393 | |||
| 2e56fe82bb | |||
| 32019c61aa | |||
| f7ffae565c | |||
| cd11bb1606 | |||
| 24c924d668 | |||
| 9be94e4b58 | |||
| 15e9d8c99d | |||
| 391f511094 | |||
| 5b53c11a6b | |||
| 9df4b6ea24 | |||
| a440564ba4 | |||
| 9583cfcc93 | |||
| c4a921283a | |||
| 4e05f087f9 | |||
| 40b506d2e0 | |||
| 263f384810 | |||
| d80c145a18 | |||
| 8848fe35f6 | |||
| 7a681bd20d | |||
| ed31fb184b | |||
| 360b94dd6c | |||
| 8524e73f59 | |||
| 940514e5ca | |||
| a4e47625ac | |||
| 7c16872a6e | |||
| 994c3c3552 | |||
| c34f496600 | |||
| 8bca8629be | |||
| 85fdd579d6 | |||
| e88d2ff88c | |||
| bdf08baebd | |||
| 3dcdd25177 | |||
| 491e8640b2 | |||
| b23b7ef85e | |||
| b167374f13 | |||
| cd1f6e733f | |||
| d3fc7687b8 | |||
| 17a83d58da | |||
| 18a8e1b6d6 | |||
| 2c23cbb359 | |||
| cdd58cf757 | |||
| a0df325659 | |||
| a59005e836 | |||
| 5da6a27e6b | |||
| ef97af71e3 | |||
| 6ed67f4532 | |||
| 1278d663b4 | |||
| 0395c7b407 | |||
| df3d15ffb3 | |||
| 6f673310d2 | |||
| 978c3eca23 | |||
| 20bc848bd6 | |||
| ce7f1292dc | |||
| d97ff8bb40 | |||
| 8a9b46d82f | |||
| 12e5703541 | |||
| 1b87fc2ee6 | |||
| ebd0c780a1 | |||
| bd976cd562 | |||
| 0e511c3e07 | |||
| 300d489408 | |||
| 024d081167 | |||
| 348173d3f1 | |||
| 23e3814f8a | |||
| b818e2c4b8 | |||
| 6adb3dc142 | |||
| 0e154cc759 | |||
| 9dce8d9bce | |||
| 0aa3b9c487 | |||
| dc7ab3ed30 | |||
| 254259b354 | |||
| 9651c70efd | |||
| 5840190ed5 | |||
| a807b88694 | |||
| 0db82e09e9 | |||
| e5865f171a | |||
| 166d198dcb | |||
| 445795f2ec | |||
| 6be4a87dac | |||
| 17c47053d6 | |||
| b4e18f7521 | |||
| fbe4d287c7 | |||
| 543fa3ae79 | |||
| 7cf855413c | |||
| f5d65dc0bc | |||
| 2f6211a1d9 | |||
| 513a57330a | |||
| 715ddf0620 | |||
| 6bb31e276e | |||
| b10f1df49f | |||
| f999519b13 | |||
| aedbf02830 | |||
| bd5479b250 | |||
| 9d14715652 | |||
| 72156fcf1b | |||
| 1c6eab00d1 | |||
| f9738c5b55 | |||
| 3b63083619 | |||
| d5d7d8bc84 | |||
| f26118cf5a | |||
| 5d6c4b475c | |||
| 2c4ef392f6 | |||
| 2a128fe772 | |||
| bb7d3ca3a1 | |||
| a2bdba7eda | |||
| e8aabc9980 | |||
| 9f554a14fd | |||
| 68a2b91ccb | |||
| 4089cc6e6f | |||
| 4e8848eeca | |||
| 8c6133c115 | |||
| 483db31acd | |||
| 35dae3dab7 | |||
| 8232aedf78 | |||
| d30a0a2e67 | |||
| d913fe508f | |||
| 4029903301 | |||
| 5db7e826d3 | |||
| 7f3e7da7c7 | |||
| 93cefde8fc | |||
| 02e7981e10 | |||
| 0ecec10af0 | |||
| 00b8cba987 | |||
| 8486bff918 | |||
| 5305eb5b8a | |||
| 377a3bb7de | |||
| 5a47e8d2c6 | |||
| 71f4cd7c85 | |||
| f7751684af | |||
| 59df1d39b2 | |||
| 7e5933e6a0 | |||
| 2cefd34bb7 | |||
| eac891dc3a | |||
| abd3599408 | |||
| 1bcd259c00 | |||
| c4e835266c | |||
| 685953f6a5 | |||
| 03fffbc724 | |||
| e1a8c932ee | |||
| 1aa2a6b054 | |||
| 1ad96c9c81 | |||
| f69199909f | |||
| d063e77040 | |||
| bf3ddeb1eb | |||
| fc261ad8cd | |||
| 90fc018295 | |||
| cdc01d9a69 | |||
| da7e76c07d | |||
| ba9118aa58 | |||
| fdce705e55 | |||
| 81268e7064 | |||
| f502f41359 | |||
| 34c9cfb6b0 | |||
| 6da1790c46 | |||
| d333c940da | |||
| c940d2906f | |||
| ac4b51ba85 | |||
| ea7a1ad2c7 | |||
| 45ddd6a68d | |||
| acd99364e0 | |||
| 14710dea55 | |||
| 5d3be8da1d | |||
| 3026821f9f | |||
| fba51dabd0 | |||
| c4da5e81fa | |||
| bc80d81432 | |||
| 67797efead | |||
| c7cb036536 | |||
| 0ccbc5f139 | |||
| 2a6bbcaf8f | |||
| d46a8438ba | |||
| cc9d19da19 | |||
| 6e6aa6fd6d | |||
| 61652a2989 | |||
| edd7503607 | |||
| c9d6dab401 | |||
| d303038bcb | |||
| 0a0e7c3b7c | |||
| 0b4ac35bc9 | |||
| c51864ca39 | |||
| a1cabd5a68 | |||
| 9c1bc99d7a | |||
| c05fedcb76 | |||
| e11beeae4b | |||
| 4749e0d71e | |||
| 1c01b77a71 | |||
| 1dd8ad3685 | |||
| d6f6350b54 | |||
| 4f3b85e604 | |||
| efd5bc24b0 | |||
| a1d5dfa1ac | |||
| 597c2ba180 | |||
| 2c2fb1b70b | |||
| fc1287659a | |||
| 1a76630594 | |||
| 322f682d32 | |||
| 0e329336fc | |||
| b33bdabbb6 | |||
| 27d30121ab | |||
| 345278f309 | |||
| 4953e77161 | |||
| 8d61e037f9 | |||
| 33a51e69bf | |||
| d5dd9bbf24 | |||
| 8772e52513 | |||
| 9e1631ad4f | |||
| 134b829d59 | |||
| 3df7d26101 | |||
| cf56086f06 | |||
| a72aca4379 | |||
| edb0b7519a | |||
| 3a3248c88c | |||
| 3f14b9dab7 | |||
| b1c07c22ce | |||
| 3b2c411274 | |||
| e418af1ccd | |||
| 7dc004acb3 | |||
| 2635472896 | |||
| 5c0340f9ae | |||
| c2c970ee33 | |||
| b52dabe091 | |||
| 3fa2db8d6f | |||
| 1e7950f671 | |||
| 8fde05191a | |||
| 2557de6c4e | |||
| 44328aee76 | |||
| f606b5879b | |||
| 83607119df | |||
| 9b86e68268 | |||
| d688a05ac7 | |||
| 97e975b4f6 | |||
| 9dd0e3ce4f | |||
| ca2293f6d3 | |||
| 0cd1ef0c7a | |||
| b0207ce524 | |||
| fab0c3b09d | |||
| 8b35dd3358 | |||
| cadcbb27eb | |||
| 297d44c614 | |||
| 22178f2224 | |||
| 554f8a376c | |||
| 4157affbd7 | |||
| 4b991203df | |||
| 38a265741c | |||
| 56eb02280f | |||
| ed900b0476 | |||
| 42206364e5 | |||
| 82d9bb8f51 | |||
| 923a9d3f9b | |||
| ae7660068b | |||
| f466c1d764 | |||
| 6e76f8ef3a | |||
| b3a8d02caf | |||
| 022ba32c1a | |||
| 8f5e89c900 | |||
| d335d7bafd | |||
| 1f51ef7df6 | |||
| ec082ee023 | |||
| a6bc271e0d | |||
| 791fd9199e | |||
| 9e8baf1914 | |||
| 64b7080532 | |||
| 8fd5479f32 | |||
| 04eb9c02c3 | |||
| 07b41b9bc3 | |||
| 8ebadfafe9 | |||
| 3283896e4b | |||
| b444bcf418 | |||
| 13034577fc | |||
| 9feefc2e7f | |||
| a5393e985d | |||
| e3fe0dc89b | |||
| 42d49e9d50 | |||
| 06eb244800 | |||
| 870cdfa51f | |||
| 93787c74ee | |||
| 945323fe15 | |||
| 5e41e69b27 | |||
| 9d14185f7d | |||
| 0f74162551 | |||
| 00b1ff1ff6 | |||
| 977024ea94 | |||
| 3534ed21d7 | |||
| ee093e5232 | |||
| 807ab8d19f | |||
| 81f3ff098f | |||
| 85a5759afb | |||
| 490e7a56a5 | |||
| e41c475671 | |||
| b0841268bd | |||
| b9b3b67b95 | |||
| 0d57d2cfe3 | |||
| 32de5d0d7f | |||
| 51eab2a4b7 | |||
| 93cf170253 | |||
| f7554374ab | |||
| b4870f62c9 | |||
| f1d713ebf6 | |||
| 4134a512b9 | |||
| cf998f945c | |||
| a7386238dd | |||
| 6b39d122a6 | |||
| a0582c5380 | |||
| 1f37112969 | |||
| 361958db76 | |||
| 8bc7880b19 | |||
| ceddf29586 | |||
| 3fc78e21bc | |||
| 48e00b371c | |||
| aee52d3880 | |||
| bd54499537 | |||
| e6da9e8d1a | |||
| 156ca03b67 | |||
| 3f4419b177 | |||
| 676f860d7d | |||
| 5ce93ae0c7 | |||
| 43231826b9 | |||
| 899b393fcc | |||
| 5c3e02d2f0 | |||
| a29064107e | |||
| 4cdc969801 | |||
| 68159d457e | |||
| daafc29d2b | |||
| 3c786acf2b | |||
| 53c3817d4d | |||
| 9109254488 | |||
| df19f0d5ec | |||
| 093362e479 | |||
| 7826a3652b | |||
| c27b7e52e1 | |||
| 6f79cbb2a6 | |||
| 6f33929f91 | |||
| 2e8b649195 | |||
| 3841be7e20 | |||
| 2c28521283 | |||
| 1c735cc204 | |||
| f0b13ae8e4 | |||
| b1a2f8fec0 | |||
| 83828aa8a3 | |||
| 4eb81b4d66 | |||
| 96d9968db5 | |||
| 2781e37ec0 | |||
| 6d61e773b5 | |||
| c5171114d1 | |||
| 0ca0a832de | |||
| aef54a4bfd | |||
| 4c473acfec | |||
| 0de41e97ac | |||
| 0e52ab3f90 | |||
| 797679b42c | |||
| 1bc8b6f46e | |||
| f322b580ff | |||
| 2b2f33e3f5 | |||
| ce29cd2fad | |||
| 0d5843f44e | |||
| e36e8e3b33 | |||
| e251a1ca19 | |||
| 4aedb00e43 | |||
| 10a0469221 | |||
| d3419acada | |||
| 65ea4117ca | |||
| 8b0101dcab | |||
| 188f67cfca | |||
| a89f4bd4b8 | |||
| 053c9dc0e1 | |||
| 493d9f1b9d | |||
| e28793f128 | |||
| ea2bddf245 | |||
| 763b3c05af | |||
| 473cfb54be | |||
| a7fd742c17 | |||
| b66ba140cb | |||
| 242f606a29 | |||
| 60a1214d7e | |||
| 189ab8c8e8 | |||
| 3765ca4e92 | |||
| df87d76070 | |||
| 8fbf0b406b | |||
| 633073803f | |||
| 104da198d3 | |||
| b3121e4534 | |||
| 3bb654cc85 | |||
| d2830db94d | |||
| ad6914b938 | |||
| 57ba965b93 | |||
| 544ec21fc2 | |||
| 1bb0fa1809 | |||
| ffa0efc898 | |||
| af6b4b8c27 | |||
| 3f7c1f966b | |||
| 535515f296 | |||
| 7af6c4b10e | |||
| 2076bef95b | |||
| 48ce1f1814 | |||
| 5151c8a505 | |||
| 44248f19b5 | |||
| 8d433f2580 | |||
| 272fe5488c | |||
| c97765de14 | |||
| 7acf150ac5 | |||
| 077bbdfc78 | |||
| 2fb38ce13a | |||
| 22dc183f25 | |||
| 3c492c3fc7 | |||
| d71db2978e | |||
| e4723e0bad | |||
| dc56c4e530 | |||
| 9579a51a8b | |||
| 71f897ebf5 | |||
| 09d9f71ae9 | |||
| c678ccdfb1 | |||
| bbbebe343b | |||
| 033cb4f0c2 | |||
| d750034b79 | |||
| a2063f0628 | |||
| acf2f2ffc4 | |||
| d14f484c4b | |||
| 695e515a65 | |||
| 61089feee7 | |||
| ddc9b10cd3 | |||
| f95c92b431 | |||
| eba65a94e6 | |||
| c28a0c6bb8 | |||
| d6bacd9b47 | |||
| 70b1657323 | |||
| 1ef08bd169 | |||
| da68cc6a78 | |||
| 45c75d42ad | |||
| d4e55af2c2 | |||
| 48791a329d | |||
| 9b26ebed75 | |||
| e2160fb6c9 | |||
| 345a1c64f9 | |||
| 7ad1e7756b | |||
| 90caf19e9e | |||
| 8d0b3b7d44 | |||
| 4c253d68d4 | |||
| 73d1b331f1 | |||
| af2fddfd6d | |||
| 3e065ead65 | |||
| 3774704326 | |||
| 4a1100b6a4 | |||
| 63dec77ed6 | |||
| 1d3a66f890 | |||
| c1da92ca22 | |||
| 13475002d7 | |||
| 5bb6f246ed | |||
| 89df7451ef | |||
| 1334d544f7 | |||
| 3fefaa7362 | |||
| 15d62f7b96 | |||
| 83e0aaa511 | |||
| ee06ce1148 | |||
| 16d6124bb4 | |||
| 1197beaa13 | |||
| 98b428a8be | |||
| 17f47d3c0a | |||
| a9cc3b2a89 | |||
| 199102c106 | |||
| c7d76fb7ab | |||
| ba9b86c0dc | |||
| 5de83a606e | |||
| 01a0c8672d | |||
| fa522c0ffc | |||
| 16241d010f | |||
| 9cb8fbf178 | |||
| bd7ef27628 | |||
| 42e520e841 | |||
| d8f9cd237f | |||
| 33065ecf04 | |||
| 718a1da262 | |||
| b89c3ebb42 | |||
| 9d7e44feff | |||
| e48a60a4f0 | |||
| 163e1907a4 | |||
| ac1ccaa246 | |||
| 53b45279ad | |||
| f80daf5de1 | |||
| 298ea1f0d3 | |||
| 1d13d8c4a0 | |||
| 2238c99b61 | |||
| 7d4dfbef2b | |||
| 759827b404 | |||
| fca627d1b0 | |||
| 404da18aed | |||
| 330fca722a | |||
| 8939cd120b | |||
| 63afeb7373 | |||
| 6ba68a6455 | |||
| 1579c74302 | |||
| 373ca15c71 | |||
| a8a3caed1c | |||
| cb35ba4543 | |||
| cdd152d015 | |||
| 83ce7dc62f | |||
| b182b50f24 | |||
| 71a9941b84 | |||
| c777da263e | |||
| 2cb7b56a41 | |||
| 52f9ef14b9 | |||
| 8d6c594240 | |||
| 7ad77ff540 | |||
| acede72e9b | |||
| 771fd732d1 | |||
| 2a79a69f59 | |||
| 8c0321697f | |||
| 0151b3f9b3 | |||
| 82a51f35ea | |||
| 35944cbfc1 | |||
| f0aef9b28b | |||
| ae37c3902c | |||
| d612585582 | |||
| 7ca14d209c | |||
| c37f582c10 | |||
| 6272fb3822 | |||
| 2582fbac59 | |||
| 5abb578e47 | |||
| 015ebf89a5 | |||
| c6724968f1 | |||
| 9fa1772ae4 | |||
| 4551937812 | |||
| 51ee664cae | |||
| fb611a98f9 | |||
| a3d5face38 | |||
| 424cd497d3 | |||
| d46eeffaaf | |||
| 6520f2061e | |||
| 5d93f86b4b | |||
| b3f63ce7ae | |||
| 56de770682 | |||
| 940341bc9d | |||
| 804a0ce601 | |||
| 41054a4c56 | |||
| 7b8e5d4180 | |||
| ca2369f1c1 | |||
| 129cb0b3cd | |||
| 632b2ae1ba | |||
| 18e55061e1 | |||
| e49b65723f | |||
| 8e52894763 | |||
| 07cba6c774 | |||
| 9cb639b505 | |||
| 4cf6eeeee2 | |||
| c0f692792f | |||
| bd77e0945b | |||
| f0eb171b2a | |||
| fb93662b5c | |||
| a26c982e93 | |||
| 7db3e98944 | |||
| 4a87834e04 | |||
| bf6ecaeeb9 | |||
| f70ef86dfa | |||
| cd3132667a | |||
| 1c459a7bea | |||
| 4f0bfeab4c | |||
| c5c9921b59 | |||
| 6b63aba1fc | |||
| 382331fb11 | |||
| caf9af7ae4 | |||
| 45d2adeb9c | |||
| 96708d7592 | |||
| 13090d1219 | |||
| 8ab229cca9 | |||
| 583cd078dc | |||
| aa2ac1bbb8 | |||
| 928b426672 | |||
| 6766b14415 | |||
| 9d0f9e967f | |||
| d7609088e5 | |||
| b2643b6926 | |||
| 07b65ca069 | |||
| 25727f7f99 | |||
| 880ae89307 | |||
| 1496df1989 | |||
| 7d8ae6b4b1 | |||
| 312d4cccaf | |||
| ce5f9f95ea | |||
| d9bf8a76d9 | |||
| f7a35fb9fe | |||
| 3ba691ded5 | |||
| 7a7277d56f | |||
| 76be5dd1d3 | |||
| 53dc63f3bc | |||
| 80da0bc9d5 | |||
| bce7af4e11 | |||
| 9da09b51ed | |||
| 86392f197f | |||
| 1c13046297 | |||
| fbc756b531 | |||
| 6c64b06453 | |||
| 241834029a | |||
| 5b8a9c0b47 | |||
| 037c29d24a | |||
| 893f26ac9a | |||
| d43f8e3100 | |||
| 2b42acf7b8 | |||
| f65b80ed42 | |||
| e84abbdc82 | |||
| 66269eabe9 | |||
| 36c0928483 | |||
| 9237e15adc | |||
| 0d3a2072b2 | |||
| aa2ee5dfc2 | |||
| b515fa39ec | |||
| 76e3f4eb92 | |||
| 4959e5c6c2 | |||
| 7082594bbc | |||
| 36dd35f238 | |||
| 9c9fb6a485 | |||
| 5438a4837b | |||
| 84996e8cb6 | |||
| 87a368a857 | |||
| 21412d93dd | |||
| 0b11ff22b4 | |||
| 8fafa78796 | |||
| c43158f8a2 | |||
| 92ad524947 | |||
| b362a61863 | |||
| 468fec38d7 | |||
| 89830a5ae0 | |||
| 5977c296bd | |||
| 47d5792d97 | |||
| 25d706a913 | |||
| 048236aaaa | |||
| d442c58fd1 | |||
| f890f6bb09 | |||
| 036d466790 | |||
| dee47ba2d8 | |||
| be96c28b77 | |||
| ad1c0f578e | |||
| c8f7b1b72c | |||
| c89702ae84 | |||
| 2d29a82250 | |||
| b36c65e654 | |||
| 09b072b908 | |||
| 0ae9fee350 | |||
| 1579182ed9 | |||
| 074671aa71 | |||
| 36b7c47247 | |||
| 424d5b3025 | |||
| 8a5d352733 | |||
| f383629282 | |||
| a6d717cb04 | |||
| 84a5753301 | |||
| 5d2d9c7e81 | |||
| 82801d1411 | |||
| 340c3963d8 | |||
| ef15cf9847 | |||
| 4d613ccfa7 | |||
| 43ce34d547 | |||
| eda074cd80 | |||
| a2396d82f6 | |||
| a38721db93 | |||
| a06e811717 | |||
| 86e534ff75 | |||
| 640d5b2dec | |||
| 57e9b27085 | |||
| c56eefc739 | |||
| cf28306997 | |||
| 10acf3ddd1 | |||
| fed3ed9f9a | |||
| 260138ba11 | |||
| 67f7e0089c | |||
| d4a22c7851 | |||
| 06cf986490 | |||
| adf9aa04ce | |||
| 69f66fbe52 | |||
| d061005c89 | |||
| f6ee8b9f04 | |||
| 31af22c2ff | |||
| c421e3f243 | |||
| 6e92902407 | |||
| 6256381dc3 | |||
| b247b051ea | |||
| afbd553622 | |||
| 36bc14e884 | |||
| 9c5d0ff2ff | |||
| cfa6c8ddf6 | |||
| 21924bf022 | |||
| eea33f6019 | |||
| 66d48ae808 | |||
| de9b9fd0b1 | |||
| ece7384be4 | |||
| 0c052e4506 | |||
| 1996a0a3d6 | |||
| 679ad9b8c6 | |||
| d4983731e7 | |||
| 4fec3c8f34 | |||
| 836fd2565f | |||
| 54618064a1 | |||
| 519e3e01ae | |||
| aec8f81358 | |||
| c1d6bf4366 | |||
| 9bf2b79d9e | |||
| 4d98408995 | |||
| 7b466388f9 | |||
| b926fb3c66 | |||
| 6c8d5c0d0e | |||
| 5a1d234260 | |||
| fd6d42c297 | |||
| 7310ad6e92 | |||
| 7e47b1348d | |||
| 1e3555a6b7 | |||
| 9a67ce5968 | |||
| 279d7955f8 | |||
| db977c0bf5 | |||
| ba6bc59818 | |||
| 6e8be0578c | |||
| 92f7d16b5e | |||
| 40bb3c2f5e | |||
| 56a6096221 | |||
| ee37b42a91 | |||
| 0806e61df4 | |||
| 279ffeeefa | |||
| 80c5ee2479 | |||
| 16208544e5 | |||
| 6afeb24fdb | |||
| e6357b81eb | |||
| dfc2efe8a6 | |||
| f28b96f431 | |||
| a10293f8f7 | |||
| b1f02f91d7 | |||
| e76fa45d86 | |||
| 06f43892a5 | |||
| a094332b0d | |||
| 7b8779f534 | |||
| 371bf20d19 | |||
| 0f633ddd15 | |||
| 7886ca7f5f | |||
| 9b4c11954d | |||
| a1b724f30a | |||
| 7c3b2fb9cc | |||
| acef68d67e | |||
| 7e393d5f1e | |||
| 955c31b165 | |||
| e307cd48ad | |||
| 25f8b9e451 | |||
| e8ba14a2c1 | |||
| 9670d3341c | |||
| cec9778fd5 | |||
| 7451db4a68 | |||
| e31777ec53 | |||
| 7aa0b3dc7a | |||
| e7b2d5dc01 | |||
| 47d728667d | |||
| e1f8989d54 | |||
| 1d8cb47830 | |||
| faaa7c37a9 | |||
| 0aff9d8df4 | |||
| 30c3f8c1ac | |||
| bcd2469e01 | |||
| 983c6ae73d | |||
| 6d8e1fe776 | |||
| 99b4921309 | |||
| 3c231c3c9e | |||
| 175c0a6236 | |||
| 0031ceb06c | |||
| e3cc5a63df | |||
| 3cb61402c2 | |||
| 5336c51199 | |||
| 52aa658aaa | |||
| d08a51d7e4 | |||
| d97a557ac3 | |||
| 8a68d9cded | |||
| b031f7e902 | |||
| 963ffecb96 | |||
| 8f8aaca818 | |||
| 801f92b7e7 | |||
| 44db45700e | |||
| 25902005f6 | |||
| ffec71e0d8 | |||
| 99a208110b | |||
| e56799c993 | |||
| 957eb300f8 | |||
| 626025d539 | |||
| 9e8a0a020f | |||
| 40f592eade | |||
| 5e899f0be4 | |||
| f2748284b1 | |||
| a15ce00934 | |||
| 9e3e80261b | |||
| c72c685434 | |||
| 0177a8d277 | |||
| b6a9b0a4c9 | |||
| f4f8bd8d42 | |||
| 6e4aeffc0c | |||
| dba256d384 | |||
| 910008e9e7 | |||
| 8cb9545c41 | |||
| 59c16da6fb | |||
| 630df5bbd2 | |||
| f550111400 | |||
| 77377195aa | |||
| 7e2e72bd40 | |||
| aa7a13bd02 | |||
| 5895058a17 | |||
| ffb60d5149 | |||
| 1e2cb279b0 | |||
| e7f766f5ba | |||
| 8de5aa9409 | |||
| bf28a4df49 | |||
| fe1a0ab371 | |||
| 01daccfaf7 | |||
| 94e861e298 | |||
| d36af2ed5c | |||
| 7104b33214 | |||
| 32998e5377 | |||
| af0c9ef092 | |||
| 3bc3b3d10e | |||
| f03f42ca4d | |||
| 79783abeb1 | |||
| 895b0bd602 | |||
| 2ee5ee92f8 | |||
| 3e619423b1 | |||
| b524e18bdf | |||
| 6aa4579db8 | |||
| 17fb86c0f1 | |||
| 62ecfe4873 | |||
| 04e55e6b9a | |||
| f432aa1090 | |||
| 7add104313 | |||
| 36de249066 | |||
| b7a54dcffd | |||
| 6bb28deab2 | |||
| 7f88d15c86 | |||
| 94c5014e23 | |||
| c5a8256500 | |||
| 5f39884bf7 | |||
| d96825a242 | |||
| 443a938091 | |||
| 6bc3197721 | |||
| 269cc91fd5 | |||
| c1ddea479d | |||
| 5f3a95962c | |||
| ee1a8e6a32 | |||
| eeae73296e | |||
| 4ca8357af4 | |||
| 8a5b8c87fb | |||
| 6ab04d7bbc | |||
| a5a1380636 | |||
| eeab1aef64 | |||
| 4e1c342e55 | |||
| d8ed259bce | |||
| 9f6cb5de4c | |||
| ba634118d7 | |||
| 63da091d36 | |||
| ad0dc88a33 | |||
| 147acf4b57 | |||
| 5085f3a15e | |||
| 22a95ad8ea | |||
| df4bd6a60c | |||
| 813e7b05e4 | |||
| ab8b486b4a | |||
| 590f666ec9 | |||
| 9adaee915b | |||
| bce0f06fe9 | |||
| 856ecb84a0 | |||
| 90ddc06c98 | |||
| 405abc4e95 | |||
| 549c59ecf5 | |||
| 0a485eafcb | |||
| e0c11956a6 | |||
| da6a9bf3eb | |||
| dacd11e1cc | |||
| fc854b4c77 | |||
| 4dcc1f0374 | |||
| fc57390242 | |||
| bd15ef0a0c | |||
| 967ecafc33 | |||
| 29576da985 | |||
| 200a2556ef | |||
| ae0ab5025e | |||
| aa74276b25 | |||
| b03112a5dd | |||
| a3f49df62d | |||
| aa2af3f6dd | |||
| 20dcbc593c | |||
| 472ba8c1fd | |||
| d8345a44a4 | |||
| a187cb6c9c | |||
| b89c0b35d1 | |||
| 7ffcc0a5e7 | |||
| bde43fbdfb | |||
| 3728b2208f | |||
| dc52a756ee | |||
| 98dc886841 | |||
| d0cf104e43 | |||
| d7ed2412f6 | |||
| 7d38f0e234 | |||
| 3e8d072d24 | |||
| 84ac771893 | |||
| 3a9e0b5be6 | |||
| 9694ff433f | |||
| 2e82e78b98 | |||
| aaef4bee27 | |||
| 4ca8569488 | |||
| 8377ada3e0 | |||
| 8a034d59ed | |||
| 8e492d8798 | |||
| 7974ef80d7 | |||
| 3664d86430 | |||
| 9adef80d6b | |||
| be57adaee7 | |||
| d117e442a4 | |||
| 8820bc0796 | |||
| 57a64de023 | |||
| 5ed689ceb0 | |||
| 25f1765f36 | |||
| 063bd58802 | |||
| 901c6b34fa | |||
| 5b2d6488a2 | |||
| f6f35415d1 | |||
| 6c6069e963 | |||
| 6219d82560 | |||
| 1dcd7a16ab | |||
| b60caeb9dd | |||
| 4c4768aaf3 | |||
| 2f4ac0a663 | |||
| 23a446f852 | |||
| ec48334a1a | |||
| f4c061d412 | |||
| 31a076d7b3 | |||
| 6bd43d986c | |||
| dd32a2f15a | |||
| c88c20820f | |||
| 86de510731 | |||
| 0b31fbf827 | |||
| 34ad1450eb | |||
| e6ba71390d | |||
| f0c8dbe0ec | |||
| bf046a8ccb | |||
| b05ba7683e | |||
| aedf8dad15 | |||
| 74ebb7c722 | |||
| 1307f66494 | |||
| 448a24cb36 | |||
| 7266f23450 | |||
| c0ad31acfc | |||
| 25d3a0de27 | |||
| 1e38bbfbc1 | |||
| 1c62e95812 | |||
| d453cc27a3 | |||
| 2c3e841d8a | |||
| 50668c462f | |||
| 8d1192e832 | |||
| 4a8e2e9ed4 | |||
| 12fc45220a | |||
| 6bce68fbe7 | |||
| d54f947c98 | |||
| 6c8bb3a22e | |||
| ed29ce5183 | |||
| a51d269b7c | |||
| 8283e4e6d6 | |||
| 23ce91eb55 | |||
| 545ac7fcfa | |||
| 3926ccccad | |||
| f431307ef2 | |||
| ca368e0f9b | |||
| 8afeb56c11 | |||
| 2a6f90c5f3 | |||
| 271031128e | |||
| b991f954d0 | |||
| f12bb3f80d | |||
| 6dc978e8d8 | |||
| 9f05a873bc | |||
| 703d498772 | |||
| ed3b9543bb | |||
| fc7efba7d8 | |||
| b3178fe8f4 | |||
| e36798a993 | |||
| a143605465 | |||
| d3ad35b21e | |||
| 68134941bf | |||
| 54d0fef559 | |||
| 7f9c47176a | |||
| 9060ac7897 | |||
| d9073e4a17 | |||
| de1c1d7cc2 | |||
| 6ff1bd5917 | |||
| a6b04f426e | |||
| fa49dbe2cb | |||
| 682eb04a52 | |||
| 77064fb09e | |||
| be8d93563a | |||
| d4a6a5216d | |||
| 1cb1427050 | |||
| e4f4eace1c | |||
| 30a98b7e8c | |||
| d36c8d95ad | |||
| 506bd0abcf |
@@ -0,0 +1,27 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
|
||||
#
|
||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
ColumnLimit: 100
|
||||
IndentWidth: 4
|
||||
---
|
||||
# settings for C and C++
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignConsecutiveMacros: AcrossComments
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
AttributeMacros:
|
||||
- DELETED_FUNCTION
|
||||
- XSPAN_DELETED_FUNCTION
|
||||
- may_throw
|
||||
EmptyLineBeforeAccessModifier: Leave
|
||||
# IndentPPDirectives: AfterHash # TODO later
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: true
|
||||
Standard: Cpp03
|
||||
StatementMacros:
|
||||
- CLANG_FORMAT_DUMMY_STATEMENT
|
||||
...
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||
---
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-casting-through-void,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-empty-catch,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-inc-dec-in-conditions,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-sizeof-expression,
|
||||
-bugprone-suspicious-include,
|
||||
-bugprone-suspicious-memory-comparison,
|
||||
-bugprone-suspicious-string-compare,
|
||||
-bugprone-switch-missing-default-case,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-optin.performance.Padding,
|
||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
-clang-analyzer-security.insecureAPI.strcpy,
|
||||
clang-diagnostic-*,
|
||||
performance-*,
|
||||
-performance-avoid-endl,
|
||||
-performance-enum-size,
|
||||
-performance-no-int-to-ptr,
|
||||
-performance-unnecessary-value-param,
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '.*'
|
||||
InheritParentConfig: false
|
||||
...
|
||||
@@ -0,0 +1,44 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clangd from https://clangd.llvm.org/
|
||||
---
|
||||
# treat *.h files as C++ source code
|
||||
If:
|
||||
PathMatch: src/.*\.h
|
||||
PathExclude: vendor/.*
|
||||
CompileFlags:
|
||||
Add:
|
||||
- -xc++
|
||||
---
|
||||
# C++ flags
|
||||
If:
|
||||
PathMatch: [ src/.*\.h, src/.*\.cpp ]
|
||||
PathExclude: vendor/.*
|
||||
CompileFlags:
|
||||
Add:
|
||||
- -std=gnu++17
|
||||
# -std=gnu++20 # requires clangd >= 11.0
|
||||
# -std=gnu++23 # requires clangd >= 18.0
|
||||
---
|
||||
# common flags for all C/C++ files
|
||||
If:
|
||||
PathMatch: [ src/.*\.h, src/.*\.c, src/.*\.cpp ]
|
||||
PathExclude: vendor/.*
|
||||
CompileFlags:
|
||||
Add:
|
||||
# see https://github.com/clangd/clangd/issues/1038 : Support deterministic relative include path
|
||||
- -Ivendor
|
||||
- -I../vendor
|
||||
- -I../../vendor
|
||||
- -DDEBUG
|
||||
- -fno-strict-aliasing
|
||||
- -fno-strict-overflow
|
||||
- -funsigned-char
|
||||
Diagnostics:
|
||||
Includes:
|
||||
# IgnoreHeader: A list of regexes. Include Cleaner will not produce diagnostics
|
||||
# for headers whose path is a suffix match for any of these.
|
||||
IgnoreHeader:
|
||||
- src/.*\.h
|
||||
UnusedIncludes: None
|
||||
...
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# see https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{GNUmakefile*,MMakefile*,Makefile*,Makevars*,*.mk}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[{*.asm,*.S}]
|
||||
indent_size = 8
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
indent_size = 2
|
||||
@@ -0,0 +1,36 @@
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# see https://github.com/github-linguist/linguist
|
||||
#
|
||||
# HINT: check settings with
|
||||
# git ls-files | git check-attr --stdin --all
|
||||
# git ls-files --eol
|
||||
|
||||
# disable all line ending conversions
|
||||
* -text
|
||||
|
||||
#
|
||||
# tell diff tools that these files are generated automatically
|
||||
#
|
||||
|
||||
/doc/upx.1 linguist-generated
|
||||
/doc/upx-doc.* linguist-generated
|
||||
|
||||
/src/stub/*.h linguist-generated
|
||||
/src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated
|
||||
/src/stub/tmp/** linguist-generated
|
||||
|
||||
/misc/podman/*/packages*.txt linguist-generated
|
||||
/misc/testsuite/*expected_sha256sums* linguist-generated
|
||||
|
||||
#
|
||||
# make GitHub language detection more accurate
|
||||
#
|
||||
|
||||
/src/*.h linguist-language=C++
|
||||
/src/*/*.h linguist-language=C++
|
||||
|
||||
/src/stub/**/*.ash linguist-language=Assembly
|
||||
/src/stub/**/*.asm linguist-language=Assembly
|
||||
/src/stub/**/*.S linguist-language=Assembly
|
||||
|
||||
/src/stub/tmp/** linguist-vendored
|
||||
@@ -0,0 +1,10 @@
|
||||
* @markus-oberhumer @jreiser
|
||||
|
||||
/src/p_lx_* @jreiser
|
||||
/src/p_mach* @jreiser
|
||||
/src/p_unix* @jreiser
|
||||
/src/p_vmlin* @jreiser
|
||||
|
||||
/src/stub/src/*bsd.* @jreiser
|
||||
/src/stub/src/*darwin.* @jreiser
|
||||
/src/stub/src/*linux.* @jreiser
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
This issue tracker is **ONLY** used for reporting bugs.
|
||||
Please use [stackoverflow](https://stackoverflow.com) for supporting issues.
|
||||
|
||||
<!---
|
||||
|
||||
IF YOU REMOVE THIS TEMPLATE WE WILL CLOSE YOUR ISSUE WITHOUT RESPONSE.
|
||||
Just read it and fill in the details we're asking, it saves so much of our time. Thanks!
|
||||
|
||||
-->
|
||||
|
||||
## What's the problem (or question)?
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## What should have happened?
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
## Do you have an idea for a solution?
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
## How can we reproduce the issue?
|
||||
<!--- Provide unambiguous set of steps to reproduce this bug. Include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Please tell us details about your environment.
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* UPX version used (`upx --version`):
|
||||
* Host Operating System and version:
|
||||
* Host CPU architecture:
|
||||
* Target Operating System and version:
|
||||
* Target CPU architecture:
|
||||
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
This issue tracker is **ONLY** used for requesting sensible features.
|
||||
Please use [stackoverflow](https://stackoverflow.com) for supporting issues.
|
||||
|
||||
<!---
|
||||
|
||||
IF YOU REMOVE THIS TEMPLATE WE WILL CLOSE YOUR ISSUE WITHOUT RESPONSE.
|
||||
Just read it and fill in the details we're asking, it saves so much of our time. Thanks!
|
||||
|
||||
-->
|
||||
|
||||
## What's the problem (or question)?
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## What should have happened?
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
## Do you have an idea for a solution?
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
## How can we reproduce the issue?
|
||||
<!--- Provide unambiguous set of steps to reproduce this bug. Include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Please tell us details about your environment.
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* UPX version used (`upx --version`):
|
||||
* Host Operating System and version:
|
||||
* Host CPU architecture:
|
||||
* Target Operating System and version:
|
||||
* Target CPU architecture:
|
||||
@@ -0,0 +1,14 @@
|
||||
UPX PULL REQUEST NOTES
|
||||
======================
|
||||
|
||||
Handling pull requests is actually quite time consuming, so please
|
||||
|
||||
- if you want to contribute **a real C++ code bug-fix** then open an issue
|
||||
on the main UPX issue tracker first
|
||||
|
||||
- if you want to contribute **a new feature** then by all means open an issue
|
||||
on the main UPX issue tracker first before starting any coding!
|
||||
|
||||
- please refuse the temptation to "improve" the docs, scripts, CI, makefiles,
|
||||
cmake build system, spelling errors, etc - we will NOT merge this; only open
|
||||
an issue if you're sure there is a **real bug**
|
||||
@@ -0,0 +1,15 @@
|
||||
# Security Context
|
||||
|
||||
IMPORTANT NOTE: UPX inherits the security context of any files it handles.
|
||||
|
||||
This means that packing, unpacking, or even testing or listing a file requires
|
||||
the same security considerations as actually executing the file.
|
||||
|
||||
Use UPX on trusted files only!
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| git HEAD | :white_check_mark: |
|
||||
| any other | :x: |
|
||||
@@ -0,0 +1,778 @@
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
# note: GitHub Actions runner images are frequently updated, and
|
||||
# unfortunately this sometimes breaks builds in mysterious ways...
|
||||
# see https://github.com/actions/runner-images.git
|
||||
|
||||
name: CI
|
||||
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
env:
|
||||
CMAKE_REQUIRED_QUIET: 'OFF'
|
||||
CMAKE_VERBOSE_MAKEFILE: 'ON'
|
||||
CTEST_OUTPUT_ON_FAILURE: 'ON'
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
NO_COLOR: 1
|
||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||
UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
|
||||
UPX_CONFIG_HAVE_WORKING_BUILD_RPATH: 'ON'
|
||||
UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1
|
||||
UPX_DEBUG_TEST_LIBC_QSORT: 1
|
||||
ZSTD_CLEVEL: 17
|
||||
# 2025-05-21
|
||||
ZIG_DIST_VERSION: 0.14.1
|
||||
|
||||
jobs:
|
||||
job-rebuild-and-verify-stubs:
|
||||
name: Rebuild stubs
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:24.04 # provides glibc-2.39
|
||||
#container: debian:12-slim # also works; provides glibc-2.36
|
||||
#container: debian:testing-slim # also works; currently provides glibc-2.38
|
||||
steps:
|
||||
- run: uname -a; pwd; id; umask
|
||||
- name: Install packages
|
||||
run: |
|
||||
dpkg --add-architecture i386
|
||||
apt-get update && apt-get upgrade -y
|
||||
# install system packages
|
||||
apt-get install -y --no-install-recommends bash ca-certificates curl git libmpc3 make perl-base tar time xz-utils libc6:i386 zlib1g:i386
|
||||
# install python2-minimal packages from Debian-11
|
||||
mkdir ../deps; cd ../deps; mkdir packages
|
||||
curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb
|
||||
curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb
|
||||
dpkg -i ./*python2*.deb && rm ./*python2*.deb && ldconfig
|
||||
ln -s -v python2.7 /usr/bin/python2
|
||||
# manually unpack and install compat libs from Ubuntu-16.04
|
||||
curl -sS -L -O https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb
|
||||
for f in ./*.deb; do dpkg -x $f ./packages; done
|
||||
mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
||||
rm -rf ./*.deb ./packages && ldconfig
|
||||
# install upx-stubtools
|
||||
curl -sS -L https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
|
||||
- name: Check out code
|
||||
run: |
|
||||
git config --global --add safe.directory '*' # needed when running in a container
|
||||
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
|
||||
git submodule update --init -- vendor/lzma-sdk
|
||||
git fsck --strict --no-progress
|
||||
- name: Rebuild and verify stubs
|
||||
run: |
|
||||
export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
|
||||
make -C src/stub maintainer-clean extra-clean
|
||||
git status || true # make sure the stub files got deleted
|
||||
make -C src/stub extra-all all
|
||||
if ! git diff --quiet; then git diff; exit 1; fi
|
||||
- run: bash ./misc/scripts/check_whitespace_git.sh
|
||||
- name: Check source code formatting
|
||||
run: |
|
||||
export UPX_CLANG_FORMAT="$(readlink -en ../deps/bin-upx-20221212/clang-format-15.0.6)"
|
||||
make -C src clang-format
|
||||
if ! git diff --quiet; then git diff; exit 1; fi
|
||||
- name: Rebuild docs
|
||||
run: |
|
||||
make -C doc clean all
|
||||
if ! git diff --quiet; then git diff || true; fi # ignore diff error
|
||||
- name: Clean up
|
||||
shell: bash
|
||||
run: |
|
||||
git ls-files -z --others --ignored --exclude-standard ./src/stub | xargs -0r rm -v --
|
||||
find ./src/stub/src -type d -name tmp -print0 | xargs -0r rmdir -v --
|
||||
- run: git status --ignored || true
|
||||
|
||||
job-linux-cmake-0: # uses cmake + make
|
||||
if: true
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: ubuntu-22.04 }
|
||||
- { os: ubuntu-24.04 }
|
||||
- { os: ubuntu-22.04-arm }
|
||||
- { os: ubuntu-24.04-arm }
|
||||
name: ${{ format('{0}', matrix.os) }}-0
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: uname -a; pwd; id; umask
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install -y gdb parallel
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- run: make build/extra/gcc/all
|
||||
- run: make build/extra/clang/all
|
||||
# run: make build/extra/gcc-pie/all
|
||||
# run: make build/extra/clang-pie/all
|
||||
- run: ls -l build/*/*/*/upx* || true
|
||||
- run: file build/*/*/*/upx* || true
|
||||
- name: Make artifact
|
||||
shell: bash
|
||||
run: |
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}-0" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N"
|
||||
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||
if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi
|
||||
(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Mimic ctest tests SIGSEGV
|
||||
shell: bash
|
||||
run: |
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
#jobs="$jobs gcc-pie/debug gcc-pie/release clang-pie/debug clang-pie/release"
|
||||
for ((i = 0; i < 5; i++)); do
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest_sigsegv.sh' ::: $jobs
|
||||
done
|
||||
- name: Run ctest tests
|
||||
run: |
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
#jobs="$jobs gcc-pie/debug gcc-pie/release clang-pie/debug clang-pie/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
|
||||
|
||||
job-linux-cmake: # uses cmake + make
|
||||
if: true
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: ubuntu-22.04, use_extra: true, use_wine: true }
|
||||
- { os: ubuntu-24.04, use_extra: true, use_wine: true }
|
||||
name: ${{ format('{0}', matrix.os) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: uname -a; pwd; id; umask
|
||||
- name: Install extra 32-bit and MinGW packages
|
||||
if: ${{ matrix.use_extra }}
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update && sudo apt-get upgrade -y
|
||||
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
|
||||
# make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads
|
||||
for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do
|
||||
if test -f /usr/bin/$f-posix; then sudo update-alternatives --set $f /usr/bin/$f-posix; fi
|
||||
ls -l /usr/bin/${f}*
|
||||
done
|
||||
ls -l /etc/alternatives/*mingw* || true
|
||||
sudo apt-get install -y libc6-dbg:i386 valgrind
|
||||
- name: Install Wine
|
||||
if: ${{ matrix.use_extra && matrix.use_wine }}
|
||||
run: |
|
||||
sudo apt-get install -y wine wine32:i386 wine64
|
||||
ls -l /usr/bin/wine*
|
||||
mkdir -p -v ~/.wine && wineboot --init
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- name: Check out test suite
|
||||
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||
- run: set -x; clang --version; clang++ --version
|
||||
- run: set -x; gcc --version; g++ --version
|
||||
- run: clang -E -x c -dM /dev/null # list predefined macros for C
|
||||
- run: clang++ -E -x c++ -dM /dev/null # list predefined macros for C++
|
||||
- run: gcc -E -x c -dM /dev/null # list predefined macros for C
|
||||
- run: g++ -E -x c++ -dM /dev/null # list predefined macros for C++
|
||||
- run: make build/extra/gcc/all
|
||||
- run: make build/extra/clang/all
|
||||
- run: make build/extra/gcc-m32/all
|
||||
if: ${{ matrix.use_extra }}
|
||||
- run: make build/extra/gcc-mx32/all
|
||||
if: ${{ matrix.use_extra }}
|
||||
- run: make build/extra/cross-windows-mingw32/all
|
||||
if: ${{ matrix.use_extra }}
|
||||
- run: make build/extra/cross-windows-mingw64/all
|
||||
if: ${{ matrix.use_extra }}
|
||||
- run: ls -l build/*/*/*/upx* || true
|
||||
- run: file build/*/*/*/upx* || true
|
||||
- name: Make artifact
|
||||
run: |
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N"
|
||||
dirs="gcc/debug gcc/release clang/debug clang/release"
|
||||
if test "${{ matrix.use_extra }}" = "true"; then
|
||||
dirs="$dirs gcc-m32/debug gcc-m32/release gcc-mx32/debug gcc-mx32/release"
|
||||
dirs="$dirs cross-windows-mingw32/debug cross-windows-mingw32/release"
|
||||
dirs="$dirs cross-windows-mingw64/debug cross-windows-mingw64/release"
|
||||
fi
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/extra/$d; done
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/extra/$d --strip; done
|
||||
for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done
|
||||
for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done
|
||||
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||
if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi
|
||||
(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Run install tests
|
||||
run: |
|
||||
(cd build/extra/gcc/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||
(cd build/extra/gcc/release && DESTDIR="$PWD/Install with make" make install)
|
||||
- name: Mimic ctest tests SIGSEGV
|
||||
run: |
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest_sigsegv.sh' ::: $jobs
|
||||
- name: Run ctest tests
|
||||
run: |
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
command -v wine >/dev/null && jobs="$jobs cross-windows-mingw32/debug cross-windows-mingw32/release"
|
||||
command -v wine >/dev/null && jobs="$jobs cross-windows-mingw64/debug cross-windows-mingw64/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
|
||||
- name: Mimic ctest tests with Valgrind
|
||||
if: true # note: valgrind is SLOW
|
||||
run: |
|
||||
if command -v valgrind >/dev/null; then
|
||||
export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
|
||||
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
|
||||
jobs="gcc/debug gcc/release clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||
fi
|
||||
- name: Run file system tests
|
||||
run: |
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||
- name: Run file system tests with Valgrind
|
||||
if: false # note: valgrind is SLOW
|
||||
run: |
|
||||
if command -v valgrind >/dev/null; then
|
||||
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
|
||||
jobs="gcc/debug gcc/release clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||
fi
|
||||
- name: Run test suite
|
||||
run: |
|
||||
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
|
||||
|
||||
job-macos-cmake: # uses cmake + make
|
||||
if: true
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# NOTE: Xcode updates regularly tend to break Homebrew clang/gcc; often some ld64 issue; use "xcode_version" as needed; or try "-Wl,-ld_classic"
|
||||
# NOTE: macos does not have "env -C"; only with brew coreutils
|
||||
- { os: macos-13, gcc: gcc-12, gxx: g++-12, testsuite: true }
|
||||
- { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true }
|
||||
# { os: macos-15, gcc: gcc-14, gxx: g++-14, testsuite: true }
|
||||
- { os: macos-15, testsuite: true }
|
||||
name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: uname -a; pwd; id; umask
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
if: ${{ matrix.xcode_version }}
|
||||
with: { xcode-version: '${{ matrix.xcode_version }}' }
|
||||
- name: Install brew packages
|
||||
if: ${{ matrix.testsuite }}
|
||||
run: |
|
||||
test -z "$HOMEBREW_PREFIX" && HOMEBREW_PREFIX="$(brew --prefix)"
|
||||
echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >> $GITHUB_ENV
|
||||
# testsuite needs working "readlink -en" and "sha256sum -b"
|
||||
packages="parallel util-linux"
|
||||
test -e "$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin/readlink" || packages="$packages coreutils"
|
||||
if test -n "$packages"; then
|
||||
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list --versions
|
||||
# only run "brew update" if needed
|
||||
if ! brew install $packages; then echo "===== brew update" && brew update && brew install $packages; fi
|
||||
fi
|
||||
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
|
||||
echo "UPX_DEBUG_FORCE_PACK_MACOS=1" >> $GITHUB_ENV
|
||||
case "${{ matrix.os }}" in
|
||||
# TODO FIXME: UPX on macos-13+ is broken => disable run-packed for now
|
||||
macos-1[345]) echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV ;;
|
||||
esac
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- name: Check out test suite
|
||||
if: ${{ matrix.testsuite }}
|
||||
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||
- run: set -x; xcode-select -p || true; xcodebuild -version || true
|
||||
- run: set -x; clang --version; clang++ --version
|
||||
- run: clang -E -x c -dM /dev/null # list predefined macros for C
|
||||
- run: clang++ -E -x c++ -dM /dev/null # list predefined macros for C++
|
||||
- run: set -x; ${{ matrix.gcc }} --version; ${{ matrix.gxx }} --version
|
||||
if: ${{ matrix.gcc }}
|
||||
- run: ${{ matrix.gcc }} -E -x c -dM /dev/null # list predefined macros for C
|
||||
if: ${{ matrix.gcc }}
|
||||
- run: ${{ matrix.gxx }} -E -x c++ -dM /dev/null # list predefined macros for C++
|
||||
if: ${{ matrix.gcc }}
|
||||
- run: make build/extra/clang/all
|
||||
- name: Build extra/gcc/all
|
||||
if: ${{ matrix.gcc }}
|
||||
run: make build/extra/gcc/all CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"
|
||||
- name: Build xtarget/cross-darwin-arm64/all
|
||||
run: |
|
||||
make UPX_XTARGET=xtarget/cross-darwin-arm64 xtarget/all \
|
||||
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin"
|
||||
- run: ls -l build/*/*/*/upx* || true
|
||||
- run: file build/*/*/*/upx* || true
|
||||
- name: Make artifact
|
||||
shell: bash
|
||||
run: |
|
||||
X="${{ matrix.xcode_version }}"; test -n "$X" && X="-xcode-$X"
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N"
|
||||
dirs="clang/debug clang/release"
|
||||
test -n "${{ matrix.gcc }}" && dirs="$dirs gcc/debug gcc/release"
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/extra/$d; done
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/extra/$d --strip; done
|
||||
for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done
|
||||
for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done
|
||||
(cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/")
|
||||
hardlink="$HOMEBREW_PREFIX/opt/util-linux/bin/hardlink"
|
||||
if test -f "$hardlink"; then (cd "tmp/artifact/$N" && "$hardlink" .) fi
|
||||
(cd tmp/artifact && gtar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Run install tests
|
||||
run: |
|
||||
(cd build/extra/clang/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||
(cd build/extra/clang/release && DESTDIR="$PWD/Install with make" make install)
|
||||
- name: Run ctest tests
|
||||
run: |
|
||||
for f in ./build/extra/*/*/upx; do file $f; done
|
||||
jobs="clang/debug clang/release"
|
||||
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
|
||||
- name: Mimic ctest tests
|
||||
run: |
|
||||
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||
jobs="clang/debug clang/release"
|
||||
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||
- name: Run file system tests
|
||||
if: ${{ matrix.testsuite }} # for coreutils readlink
|
||||
run: |
|
||||
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||
export upx_test_file="$PWD"/build/extra/clang/release/upx
|
||||
jobs="clang/debug clang/release"
|
||||
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||
- name: Run test suite
|
||||
if: ${{ matrix.testsuite }}
|
||||
run: |
|
||||
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||
jobs="clang/debug clang/release"
|
||||
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
|
||||
|
||||
job-windows-cmake: # uses cmake + msbuild
|
||||
if: true
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, vsarch: amd64 }
|
||||
- { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, vsarch: amd64 }
|
||||
- { name: windows-2022-arm64, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64 }
|
||||
# { name: windows-2022-arm64ec, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, use_amd64ec: true }
|
||||
- { name: windows-2022-i386, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
|
||||
- { name: windows-2025-amd64, os: windows-2025, vsversion: 2022, vsarch: amd64 }
|
||||
- { name: windows-2025-arm64, os: windows-2025, vsversion: 2022, vsarch: amd64_arm64 }
|
||||
- { name: windows-2025-arm64ec, os: windows-2025, vsversion: 2022, vsarch: amd64_arm64, use_amd64ec: true }
|
||||
- { name: windows-2025-i386, os: windows-2025, vsversion: 2022, vsarch: amd64_x86 }
|
||||
name: ${{ format('{0}', matrix.name) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- name: Check out test suite
|
||||
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
|
||||
- name: Set platform
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ matrix.vsarch }}" == amd64 ]]; then true;
|
||||
echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A x64" >> $GITHUB_ENV
|
||||
elif [[ "${{ matrix.use_amd64ec }}" == "true" ]]; then true;
|
||||
echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A ARM64EC" >> $GITHUB_ENV
|
||||
echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV
|
||||
elif [[ "${{ matrix.vsarch }}" == amd64_arm64 ]]; then true;
|
||||
echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A ARM64" >> $GITHUB_ENV
|
||||
echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV
|
||||
elif [[ "${{ matrix.vsarch }}" == amd64_x86 ]]; then true;
|
||||
echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A Win32" >> $GITHUB_ENV
|
||||
fi
|
||||
- run: make build/debug
|
||||
- run: make build/release
|
||||
- name: Make artifact
|
||||
shell: bash
|
||||
run: |
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N"
|
||||
DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/debug" cmake --install build/debug --config Debug
|
||||
DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/release" cmake --install build/release --config Release
|
||||
DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/debug" cmake --install build/debug --config Debug --strip
|
||||
DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/release" cmake --install build/release --config Release --strip
|
||||
cmake --install build/debug --config Debug --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/debug"
|
||||
cmake --install build/release --config Release --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/release"
|
||||
cmake --install build/debug --config Debug --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/debug" --strip
|
||||
cmake --install build/release --config Release --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/release" --strip
|
||||
(cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N")
|
||||
(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Run ctest tests
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
run: |
|
||||
ctest --test-dir build/debug --parallel 8 -C Debug
|
||||
ctest --test-dir build/release --parallel 8 -C Release
|
||||
- name: Mimic ctest tests
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
env -C build/debug/Debug upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh
|
||||
env -C build/release/Release upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh
|
||||
- name: Run test suite build/release
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||
env -C build/release/Release upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
||||
|
||||
job-windows-toolchains: # build "by hand" using cmd.exe
|
||||
if: github.repository_owner == 'upx'
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# { name: amd64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64 }
|
||||
- { name: amd64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64 }
|
||||
# { name: arm64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_arm64 }
|
||||
- { name: arm64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64 }
|
||||
- { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' }
|
||||
# { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' }
|
||||
# { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_x86 }
|
||||
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
|
||||
name: ${{ format('windows {0}', matrix.name) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
C: ${{ matrix.name }}
|
||||
B: release
|
||||
steps:
|
||||
- run: git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- name: Prepare sources and Check out test suite
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||
mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd}
|
||||
repository_name="${GITHUB_REPOSITORY##*/}" # basename
|
||||
echo "H=d:\\a\\$repository_name\\$repository_name" >> $GITHUB_ENV
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
|
||||
- name: Build by hand
|
||||
shell: cmd
|
||||
run: |
|
||||
@REM ===== set vars =====
|
||||
where cl & where link
|
||||
set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT
|
||||
set RUN_LIB=link -lib ${{ matrix.link_machine_flags }}
|
||||
@rem UPX only uses the very basic Windows API
|
||||
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0501
|
||||
set BDIR=%H%\build\%C%\%B%
|
||||
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||
@REM ===== build bzip2 =====
|
||||
cd %BDIR%\bzip2
|
||||
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c
|
||||
@rem %RUN_LIB% -out:bzip2.lib *.obj
|
||||
@REM ===== build UCL =====
|
||||
cd %BDIR%\ucl
|
||||
set s=%H%\vendor\ucl
|
||||
%RUN_CL% -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||
%RUN_LIB% -out:ucl.lib *.obj
|
||||
@REM ===== build zlib =====
|
||||
cd %BDIR%\zlib
|
||||
set s=%H%\vendor\zlib
|
||||
%RUN_CL% -J -O2 -W3 -WX %DEFS% -I%s% -DHAVE_VSNPRINTF -c %H%\vendor\zlib\*.c
|
||||
%RUN_LIB% -out:zlib.lib *.obj
|
||||
@REM ===== build zstd =====
|
||||
cd %BDIR%\zstd
|
||||
set s=%H%\vendor\zstd\lib
|
||||
@rem %RUN_CL% -J -O2 -W4 -WX %DEFS% -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
|
||||
@rem %RUN_LIB% -out:zstd.lib *.obj
|
||||
@REM ===== build UPX =====
|
||||
cd %BDIR%\upx
|
||||
set s=%H%\src
|
||||
cat .GITREV.txt
|
||||
set /p GITREV=<.GITREV.txt
|
||||
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
|
||||
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
|
||||
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
|
||||
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
||||
%RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% %UPX_DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj
|
||||
- name: Make artifact
|
||||
shell: bash
|
||||
run: |
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N/$B"
|
||||
cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
|
||||
(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Run basic tests
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
run: |
|
||||
$ErrorActionPreference = 'stop'
|
||||
$ErrorView = 'NormalView'
|
||||
cd $Env:H\build\$Env:C\$Env:B\upx
|
||||
$Env:UPX = "--no-color --no-progress"
|
||||
.\upx.exe --version
|
||||
.\upx.exe --sysinfo -v
|
||||
.\upx.exe upx.exe -o upx_packed.exe
|
||||
dir *.exe
|
||||
.\upx.exe -l upx_packed.exe
|
||||
.\upx.exe -t upx_packed.exe
|
||||
.\upx_packed.exe --version
|
||||
- name: Mimic ctest tests
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh
|
||||
- name: Run test suite
|
||||
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
||||
|
||||
job-linux-zigcc: # uses cmake + make
|
||||
if: github.repository_owner == 'upx'
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# only build a few selected targets => more targets are tested in the Weekly CI
|
||||
- { zig_target: aarch64-linux-musl, qemu: qemu-aarch64 }
|
||||
- { zig_target: aarch64-linux-musl, qemu: qemu-aarch64, zig_pic: -fPIE }
|
||||
- { zig_target: aarch64-macos.11.0-none }
|
||||
- { zig_target: aarch64-windows-gnu }
|
||||
- { zig_target: arm-linux-musleabihf, qemu: qemu-arm }
|
||||
- { zig_target: armeb-linux-musleabihf, qemu: qemu-armeb }
|
||||
- { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 }
|
||||
- { zig_target: i386-linux-gnu.2.17, zig_flags: -march=i586 }
|
||||
- { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 }
|
||||
- { zig_target: i386-windows-gnu }
|
||||
- { zig_target: mips-linux-musleabi, zig_flags: -msoft-float, qemu: qemu-mips }
|
||||
- { zig_target: mips-linux-musleabihf, qemu: qemu-mips }
|
||||
- { zig_target: mipsel-linux-musleabi, zig_flags: -msoft-float, qemu: qemu-mipsel }
|
||||
- { zig_target: mipsel-linux-musleabihf, qemu: qemu-mipsel }
|
||||
# { zig_target: mips-linux-musleabi-mips32r2, zig_flags: -march=mips32r2, qemu: qemu-mips }
|
||||
# { zig_target: mips-linux-musleabi-mips32r3, zig_flags: -march=mips32r3, qemu: qemu-mips }
|
||||
# { zig_target: mips-linux-musleabi-mips32r5, zig_flags: -march=mips32r5, qemu: qemu-mips }
|
||||
# { zig_target: mips-linux-musleabi-mips32r6, zig_flags: -march=mips32r6, qemu: qemu-mips }
|
||||
- { zig_target: powerpc-linux-musleabihf, qemu: qemu-ppc }
|
||||
- { zig_target: powerpc64-linux-musl, qemu: qemu-ppc64 }
|
||||
- { zig_target: powerpc64-linux-musl, qemu: qemu-ppc64, zig_pic: -fPIE }
|
||||
- { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le }
|
||||
- { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le, zig_pic: -fPIE }
|
||||
- { zig_target: x86_64-linux-gnu.2.3.4, qemu: qemu-x86_64 } # can use QEMU because of gcompat
|
||||
- { zig_target: x86_64-linux-gnu.2.17, qemu: qemu-x86_64 } # can use QEMU because of gcompat
|
||||
- { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 }
|
||||
- { zig_target: x86_64-macos.11.0-none }
|
||||
- { zig_target: x86_64-windows-gnu }
|
||||
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
|
||||
runs-on: ubuntu-latest
|
||||
#container: 'alpine:3.22'
|
||||
#container: ${{ contains(matrix.qemu, 'qemu-ppc64') && 'alpine:3.19' || 'alpine:3.22' }}
|
||||
#container: ${{ (matrix.qemu == 'qemu-ppc64') && 'alpine:edge' || 'alpine:3.22' }}
|
||||
container: ${{ (matrix.qemu == 'qemu-aarch64' && matrix.zig_pic == '-fPIE') && 'alpine:3.18' || 'alpine:3.22' }}
|
||||
env:
|
||||
UPX_CONFIG_HAVE_WORKING_BUILD_RPATH: ''
|
||||
# for zig-cc wrapper scripts (see below):
|
||||
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
|
||||
ZIG_FLAGS: ${{ matrix.zig_flags }}
|
||||
ZIG_PIC: ${{ matrix.zig_pic }}
|
||||
ZIG_TARGET: ${{ matrix.zig_target }}
|
||||
steps:
|
||||
- run: uname -a; pwd; id; umask
|
||||
- name: Install Alpine Linux container packages
|
||||
if: ${{ job.container }}
|
||||
shell: sh
|
||||
run: |
|
||||
apk update && apk upgrade && apk add bash cmake curl file gdb git make parallel patch strace tar util-linux xz zstd
|
||||
# set PATH like in Ubuntu
|
||||
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
|
||||
git config --global --add safe.directory '*' # needed when running in a container
|
||||
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
|
||||
- uses: actions/checkout@v4
|
||||
with: { submodules: true }
|
||||
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
|
||||
shell: bash
|
||||
run: |
|
||||
rev=$(git rev-parse --short=7 HEAD)
|
||||
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
|
||||
if [[ "${{ matrix.zig_target }}" == i386-linux-gnu.2.3.* ]]; then true;
|
||||
echo "UPX_CONFIG_DISABLE_SHARED_LIBS=ON" >> $GITHUB_ENV # zig problem when linking in Debug mode
|
||||
fi
|
||||
if [[ "${{ matrix.zig_target }}" == x86_64-linux-gnu.2* ]]; then true;
|
||||
echo "NEED_GCOMPAT=1" >> $GITHUB_ENV
|
||||
# TODO FIXME: problem with self-packed upx and musl+gcompat: "Not a valid dynamic program"
|
||||
echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV
|
||||
fi
|
||||
# install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu
|
||||
mkdir -p -v ~/.local/bin
|
||||
cd ~/.local/bin
|
||||
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
|
||||
ZIG_DIST_NAME=zig-x86_64-linux-${ZIG_DIST_VERSION}
|
||||
#curl -sS -L -O https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz
|
||||
curl -sS -L -O https://ziglang.org/download/0.14.1/${ZIG_DIST_NAME}.tar.xz
|
||||
ls -l ${ZIG_DIST_NAME}.tar.xz
|
||||
file ${ZIG_DIST_NAME}.tar.xz || true
|
||||
tar -xoJf ${ZIG_DIST_NAME}.tar.xz
|
||||
rm ${ZIG_DIST_NAME}.tar.xz
|
||||
ln -s -v ${ZIG_DIST_NAME}/zig zig
|
||||
#echo "PATH=$PATH" && which zig
|
||||
echo -n 'zig version: '; zig version
|
||||
# patch zig
|
||||
ls -la "$HOME" "$GITHUB_WORKSPACE" || true
|
||||
#(cd ${ZIG_DIST_NAME} && patch --verbose -p1 -i "$GITHUB_WORKSPACE"/misc/patches/zig/0001-x.patch)
|
||||
# create wrapper scripts (needed for CMake)
|
||||
log=
|
||||
log='set -x\n'
|
||||
echo -e '#!/bin/sh\n'$log'exec zig ar "$@"' > zig-ar
|
||||
echo -e '#!/bin/sh\n'$log'exec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
|
||||
echo -e '#!/bin/sh\n'$log'exec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
|
||||
echo -e '#!/bin/sh\n'$log'exec zig ranlib "$@"' > zig-ranlib
|
||||
chmod +x zig-ar zig-cc zig-cxx zig-ranlib
|
||||
ls -la; head zig-ar zig-cc zig-cxx zig-ranlib
|
||||
# update ZIG_TARGET
|
||||
[[ $ZIG_TARGET == mips-linux-musleabi-* ]] && ZIG_TARGET=mips-linux-musleabi
|
||||
[[ $ZIG_TARGET == mips-linux-musleabihf-* ]] && ZIG_TARGET=mips-linux-musleabihf
|
||||
[[ $ZIG_TARGET == mipsel-linux-musleabi-* ]] && ZIG_TARGET=mipsel-linux-musleabi
|
||||
[[ $ZIG_TARGET == mipsel-linux-musleabihf-* ]] && ZIG_TARGET=mipsel-linux-musleabihf
|
||||
ZIG_TARGET=${ZIG_TARGET/i386-/x86-} # i386 => x86
|
||||
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
|
||||
# update ZIG_FLAGS
|
||||
# -fPIE is for compilation only => also use the correct linker flag "-pie"
|
||||
# INFO: it seems the zig driver does handle this automatically(??), so not really needed
|
||||
if test "X$ZIG_PIC" = "X-fPIE"; then true;
|
||||
ZIG_FLAGS="$ZIG_FLAGS --start-no-unused-arguments -pie --end-no-unused-arguments"
|
||||
echo "UPX_CONFIG_DISABLE_SHARED_LIBS=ON" >> $GITHUB_ENV # conflicts with ZIG_PIC/ZIG_FLAGS
|
||||
fi
|
||||
if [[ $ZIG_TARGET == *-linux-gnu.2.3.* ]]; then true;
|
||||
# glibc-2.3.3: undefined symbols in Debug build: __snprintf_chk __vsnprintf_chk
|
||||
# glibc-2.3.4: ld.lld: error: undefined symbol: openat64
|
||||
ZIG_FLAGS="$ZIG_FLAGS -fno-sanitize=all"
|
||||
echo "UPX_CONFIG_DISABLE_SANITIZE=ON" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "ZIG_FLAGS=$ZIG_FLAGS" >> $GITHUB_ENV
|
||||
- run: set -x; zig version; zig-cc --version || true; zig-cxx --version || true
|
||||
- run: zig-cc -E -x c -dM /dev/null # list predefined macros for C
|
||||
- run: zig-cxx -E -x c++ -dM /dev/null # list predefined macros for C++
|
||||
- name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||
run: |
|
||||
make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/release \
|
||||
CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
|
||||
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||
run: |
|
||||
make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/debug \
|
||||
CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
|
||||
- run: ls -l build/*/*/*/upx* || true
|
||||
- run: file build/*/*/*/upx* || true
|
||||
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
|
||||
shell: bash
|
||||
run: |
|
||||
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||
mkdir -p "tmp/artifact/$N"
|
||||
if [[ "${{ matrix.zig_target }}" == *-linux* ]]; then
|
||||
dirs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/zig/$d; done
|
||||
for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/zig/$d --strip; done
|
||||
for d in $dirs; do cmake --install build/zig/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done
|
||||
for d in $dirs; do cmake --install build/zig/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done
|
||||
fi
|
||||
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||
if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi
|
||||
(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst")
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||
- name: Run install tests
|
||||
if: ${{ contains(matrix.zig_target, '-linux') }}
|
||||
run: |
|
||||
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with make" make install)
|
||||
- name: Run ctest tests
|
||||
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }}
|
||||
run: |
|
||||
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'make build/zig/{}+test' ::: $jobs
|
||||
- name: Mimic ctest tests
|
||||
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }}
|
||||
run: |
|
||||
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||
- name: ${{ format('Mimic ctest tests with QEMU {0}', matrix.qemu) }}
|
||||
if: ${{ matrix.qemu }}
|
||||
run: |
|
||||
qemu="${{ matrix.qemu }}"
|
||||
apk add coreutils "${qemu%% *}"
|
||||
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||
export upx_exe_runner="$qemu"
|
||||
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||
- name: Mimic ctest tests with Valgrind
|
||||
if: ${{ matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }}
|
||||
run: |
|
||||
export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
|
||||
apk add coreutils valgrind
|
||||
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||
upx_exe_runner="$upx_exe_runner --suppressions=$PWD/misc/valgrind/musl.supp"
|
||||
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||
- name: Run file system tests
|
||||
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }}
|
||||
run: |
|
||||
apk add coreutils sudo
|
||||
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||
echo "===== parallel jobs: $jobs"
|
||||
parallel -kv --lb 'cd build/zig/{} && chmod a+w . && sudo -u nobody bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
|
||||
# see https://github.com/actions/stale
|
||||
|
||||
# Automatically closing issues is far from perfect, but then we only
|
||||
# have limited resources and this approach favors issues that people
|
||||
# actually care about.
|
||||
#
|
||||
# also see:
|
||||
# "Should I Stale or Should I Close? An Analysis of a Bot that Closes
|
||||
# Abandoned Issues and Pull Request".
|
||||
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
||||
|
||||
name: GitHub - Close stale issues
|
||||
on:
|
||||
schedule: [cron: "50 0 * * 1"] # run weekly Monday 00:50 UTC
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
job-close-stale-issues:
|
||||
if: github.repository_owner == 'upx' && github.repository == 'upx/upx'
|
||||
name: Close stale issues
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
operations-per-run: 300
|
||||
exempt-all-milestones: true
|
||||
exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression'
|
||||
days-before-stale: 90
|
||||
days-before-close: 30
|
||||
stale-issue-message: 'This issue is stale because it has been open for 90 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open for 90 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/.cache*
|
||||
/.idea/
|
||||
/.hg*
|
||||
/.vscode*
|
||||
/.zed/
|
||||
/CMakeCache*
|
||||
/CMakeFiles*
|
||||
/CTest*
|
||||
/Makevars[.-]global*
|
||||
/Testing*
|
||||
/build*
|
||||
/maint*
|
||||
/vendor*
|
||||
|
||||
GNUmakefile*
|
||||
MMakefile*
|
||||
Makevars[.-]local*
|
||||
compile_commands*.json
|
||||
compile_flags*.txt
|
||||
Tmp*
|
||||
tmp*
|
||||
|
||||
*.a
|
||||
*.bz2
|
||||
*.d
|
||||
*.diff
|
||||
*.dll
|
||||
*.dylib
|
||||
*.exe
|
||||
*.gz
|
||||
*.lib
|
||||
*.map
|
||||
*.o
|
||||
*.obj
|
||||
*.out
|
||||
*.patch
|
||||
*.py[cdo]
|
||||
*.rar
|
||||
*.so
|
||||
*.swp
|
||||
*.tmp
|
||||
*.ttp
|
||||
*.xz
|
||||
*.zip
|
||||
*.zst
|
||||
|
||||
/doc/*.man
|
||||
/doc/*.ps
|
||||
/doc/*.tex
|
||||
|
||||
/src/stub/**/.*-stamp
|
||||
/src/stub/src/**/tmp*/*
|
||||
/src/stub/tmp*/*.bin
|
||||
/src/stub/tmp*/*.bin.bindump
|
||||
/src/stub/tmp*/*.bin.disasm
|
||||
/src/stub/tmp*/*.o.disasm
|
||||
/src/stub/tmp*/mips.r3000-*.[is]
|
||||
/src/stub/tmp*/mipsel.r3000-*.[is]
|
||||
|
||||
/src/stub/tools/sstrip/amd64-linux-sstrip
|
||||
/src/stub/tools/sstrip/i386-linux-sstrip
|
||||
/src/stub/tools/sstrip/sstrip
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
[submodule "vendor/doctest"]
|
||||
path = vendor/doctest
|
||||
url = https://github.com/upx/upx-vendor-doctest.git
|
||||
branch = upx-vendor
|
||||
shallow = true
|
||||
[submodule "vendor/lzma-sdk"]
|
||||
path = vendor/lzma-sdk
|
||||
url = https://github.com/upx/upx-vendor-lzma-sdk.git
|
||||
branch = upx-vendor
|
||||
shallow = true
|
||||
[submodule "vendor/ucl"]
|
||||
path = vendor/ucl
|
||||
url = https://github.com/upx/upx-vendor-ucl.git
|
||||
branch = upx-vendor
|
||||
shallow = true
|
||||
[submodule "vendor/valgrind"]
|
||||
path = vendor/valgrind
|
||||
url = https://github.com/upx/upx-vendor-valgrind.git
|
||||
branch = upx-vendor
|
||||
shallow = true
|
||||
[submodule "vendor/zlib"]
|
||||
path = vendor/zlib
|
||||
url = https://github.com/upx/upx-vendor-zlib.git
|
||||
branch = upx-vendor
|
||||
shallow = true
|
||||
@@ -1,52 +0,0 @@
|
||||
syntax: regexp
|
||||
|
||||
^\.bzr
|
||||
^ChangeLog
|
||||
^Makevars.global
|
||||
^build
|
||||
^maint
|
||||
|
||||
syntax: glob
|
||||
|
||||
.depend
|
||||
Makevars.local
|
||||
|
||||
*.a
|
||||
*.dll
|
||||
*.lib
|
||||
*.py[cdo]
|
||||
*.so
|
||||
*.swp
|
||||
|
||||
doc/*.1
|
||||
doc/*.doc
|
||||
doc/*.html
|
||||
doc/*.man
|
||||
doc/*.ps
|
||||
doc/*.tex
|
||||
|
||||
src/GNUmakefile
|
||||
src/MMakefile
|
||||
src/compress_nrv*
|
||||
src/*.mft
|
||||
src/*.rc
|
||||
|
||||
src/*.d
|
||||
src/*.exe
|
||||
src/*.map
|
||||
src/*.o
|
||||
src/*.obj
|
||||
src/*.out
|
||||
src/*.res
|
||||
src/*.ttp
|
||||
|
||||
stub/**MMakefile
|
||||
stub/**.*-stamp
|
||||
stub/tmp*/*
|
||||
stub/**/tmp*/*
|
||||
|
||||
stub/tools/armpe/armpe_tester
|
||||
|
||||
stub/tools/sstrip/amd64-linux-sstrip
|
||||
stub/tools/sstrip/i386-linux-sstrip
|
||||
stub/tools/sstrip/sstrip
|
||||
@@ -1,18 +0,0 @@
|
||||
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
||||
1931f4f28074970ec53b4cd21c7fc181b4da8e5e RELEASE_301
|
||||
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
|
||||
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||
b82ef51896199484afe5b0553af7d1e59b7ce428 BRANCHPOINT_FOR_upx2.hg
|
||||
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
||||
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||
ef9c7f2c9658d73a9b5ab2ed291483d2bbcd8bc7 RELEASE_300
|
||||
efa52753e366300c0e0ebe20631adcb24ed3c15b RELEASE_293
|
||||
+538
@@ -0,0 +1,538 @@
|
||||
#
|
||||
# UPX "CMake" build file; see https://cmake.org/
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
# Build requirements:
|
||||
# A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11
|
||||
# (older or other compilers may work but are unsupported, use at your own risk)
|
||||
|
||||
# Sections of this CMakeLists.txt:
|
||||
# - options
|
||||
# - init
|
||||
# - common compilation flags
|
||||
# - targets
|
||||
# - target compilation flags
|
||||
# - test
|
||||
# - install
|
||||
# - print summary
|
||||
|
||||
# CMake version check; using a somewhat current CMake version is highly recommended
|
||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt")
|
||||
if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
|
||||
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
|
||||
elseif(NOT ${CMAKE_VERSION} VERSION_LESS "3.10")
|
||||
cmake_minimum_required(VERSION "3.10" FATAL_ERROR)
|
||||
else()
|
||||
cmake_minimum_required(VERSION "3.8" FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17
|
||||
endif()
|
||||
|
||||
# support functions and some utility
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/functions.cmake")
|
||||
upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
|
||||
upx_print_var(CMAKE_GENERATOR_TOOLSET CMAKE_GENERATOR_PLATFORM)
|
||||
|
||||
#***********************************************************************
|
||||
# options
|
||||
#***********************************************************************
|
||||
|
||||
upx_cmake_include_hook(1_options)
|
||||
|
||||
# compilation config options
|
||||
if(NOT USE_STRICT_DEFAULTS)
|
||||
# permissive config defaults when building from source code tarball
|
||||
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with Git version info." ON)
|
||||
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with sanitize options." ON)
|
||||
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." ON)
|
||||
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." ON)
|
||||
else()
|
||||
# strict config defaults for Git developer builds
|
||||
message(STATUS "===== UPX NOTE: strict developer config defaults enabled =====")
|
||||
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with Git version info." OFF)
|
||||
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with sanitize options." OFF)
|
||||
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." OFF)
|
||||
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." OFF)
|
||||
endif()
|
||||
|
||||
# test config options (see below)
|
||||
# IMPORTANT NOTE: self-pack test can only work if the host executable format is supported by UPX!
|
||||
option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" OFF)
|
||||
option(UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS "Do not run exhaustive tests" OFF)
|
||||
|
||||
#***********************************************************************
|
||||
# init
|
||||
#***********************************************************************
|
||||
|
||||
set(UPX_VERSION_STRING "5.0.2") # this should match src/version.h
|
||||
|
||||
upx_cmake_include_hook(2_init)
|
||||
|
||||
# Disallow in-source build. Note that you will still have to manually
|
||||
# clean up a few files if you accidentally try an in-source build.
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
upx_disallow_in_source_build()
|
||||
endif()
|
||||
|
||||
# global settings
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.14.99" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
endif()
|
||||
# global CMake settings that default to ON
|
||||
upx_cache_bool_vars(ON
|
||||
CMAKE_C_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS CMAKE_REQUIRED_QUIET
|
||||
)
|
||||
# internal UPX settings that default to OFF; useful for CI jobs
|
||||
upx_cache_bool_vars(OFF
|
||||
UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||
UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
|
||||
UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD
|
||||
UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST UPX_CONFIG_DISABLE_RUN_PACKED_TEST
|
||||
UPX_CONFIG_DISABLE_SAVE_TEMPS UPX_CONFIG_DISABLE_SHARED_LIBS UPX_CONFIG_REQUIRE_THREADS
|
||||
)
|
||||
upx_cache_bool_vars(ON UPX_CONFIG_EXPECT_THREADS)
|
||||
upx_print_env_var(CC CXX)
|
||||
|
||||
# determine Git revision
|
||||
set(GITREV_SHORT "")
|
||||
set(GITREV_PLUS "")
|
||||
set(GIT_DESCRIBE "")
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||
find_package(Git)
|
||||
if(Git_FOUND)
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
||||
RESULT_VARIABLE result ERROR_QUIET
|
||||
OUTPUT_VARIABLE GITREV_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(LENGTH "${GITREV_SHORT}" l)
|
||||
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
||||
execute_process(RESULT_VARIABLE result COMMAND "${GIT_EXECUTABLE}" diff --quiet)
|
||||
if(NOT ${result} EQUAL 0)
|
||||
set(GITREV_PLUS "+")
|
||||
endif()
|
||||
else()
|
||||
set(GITREV_SHORT "")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --match "v*.*.*" --tags --dirty
|
||||
RESULT_VARIABLE result ERROR_QUIET
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+)-g(.+)$")
|
||||
set(GIT_DESCRIBE "${CMAKE_MATCH_1}-devel.${CMAKE_MATCH_2}+git-${CMAKE_MATCH_3}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(GITREV_SHORT)
|
||||
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
|
||||
if(GIT_DESCRIBE)
|
||||
message(STATUS "UPX_VERSION_GIT_DESCRIBE = \"${GIT_DESCRIBE}\"")
|
||||
endif()
|
||||
elseif(UPX_CONFIG_DISABLE_GITREV)
|
||||
message(STATUS "UPX_VERSION_GITREV: disabled")
|
||||
else()
|
||||
message(STATUS "UPX_VERSION_GITREV: not set")
|
||||
endif()
|
||||
|
||||
# CMake init
|
||||
upx_set_default_build_type(Release) # default is CMAKE_BUILD_TYPE=Release
|
||||
project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX)
|
||||
upx_apply_build_type()
|
||||
upx_set_global_vars()
|
||||
upx_check_working_build_rpath(UPX_CONFIG_HAVE_WORKING_BUILD_RPATH)
|
||||
|
||||
if(DEFINED UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX "${UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX}")
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL AND CMAKE_INSTALL_PREFIX)
|
||||
include(GNUInstallDirs)
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# common compilation flags
|
||||
#***********************************************************************
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
upx_cmake_include_hook(3_common_compilation_flags)
|
||||
|
||||
# assert sane type sizes
|
||||
check_type_size("size_t" C_SIZEOF_SIZE_T LANGUAGE C)
|
||||
check_type_size("size_t" CXX_SIZEOF_SIZE_T LANGUAGE CXX)
|
||||
if(NOT "${C_SIZEOF_SIZE_T}" MATCHES "^(4|8|16)$")
|
||||
message(FATAL_ERROR "ERROR: unexpected C_SIZEOF_SIZE_T '${C_SIZEOF_SIZE_T}'")
|
||||
endif()
|
||||
if(NOT ",${C_SIZEOF_SIZE_T}," STREQUAL ",${CXX_SIZEOF_SIZE_T},")
|
||||
message(FATAL_ERROR "FATAL ERROR: '${C_SIZEOF_SIZE_T}' '${CXX_SIZEOF_SIZE_T}' mismatch")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED HAVE_UNISTD_H)
|
||||
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||
endif()
|
||||
if(NOT DEFINED HAVE_UTIMENSAT)
|
||||
# proper checking for utimensat() is somewhat messy
|
||||
check_function_exists(utimensat HAVE_UTIMENSAT_FUNCTION__)
|
||||
if(HAVE_UTIMENSAT_FUNCTION__)
|
||||
check_symbol_exists(utimensat "sys/types.h;fcntl.h;sys/stat.h" HAVE_UTIMENSAT_SYMBOL__)
|
||||
if(HAVE_UTIMENSAT_SYMBOL__)
|
||||
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtim.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) # POSIX.1-2008
|
||||
if(NOT HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtimespec.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) # macOS
|
||||
endif()
|
||||
if(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC OR HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||
set(HAVE_UTIMENSAT 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UPX_CONFIG_DISABLE_WSTRICT)
|
||||
# enable all basic warnings
|
||||
set(warn_Wall -Wall)
|
||||
set(warn_WN -W3)
|
||||
else()
|
||||
# enable all basic warnings, and enable lots of strict warnings
|
||||
set(warn_Wall -Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings)
|
||||
set(warn_WN -W4)
|
||||
endif()
|
||||
if(UPX_CONFIG_DISABLE_WERROR)
|
||||
# warnings are just warnings
|
||||
set(warn_Werror "")
|
||||
set(warn_WX "")
|
||||
else()
|
||||
# warnings are fatal errors; annoy developers to keep the source code warning-free
|
||||
set(warn_Werror -Werror)
|
||||
set(warn_WX -WX)
|
||||
endif()
|
||||
if(MSVC_FRONTEND)
|
||||
# disable warning C5105 which may get triggered by some older versions of <windows.h>
|
||||
set(warn_WX -wd5105 ${warn_WX})
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||
# use -O2 instead of -O3 to reduce code size
|
||||
string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" a "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" b "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
|
||||
endif()
|
||||
if(MSVC_FRONTEND OR WIN32 OR MINGW OR CYGWIN)
|
||||
# disable silly warnings about using "deprecated" POSIX functions like fopen()
|
||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(-D_SCL_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
add_definitions(-D__USE_MINGW_ANSI_STDIO)
|
||||
endif()
|
||||
if(MSVC_FRONTEND)
|
||||
# use -funsigned-char; set __cplusplus according to selected C++ standard
|
||||
add_definitions(-J -Zc:__cplusplus)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||
upx_add_definitions(-Zc:preprocessor) # use new preprocessor
|
||||
endif()
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||
# protect against security threats caused by misguided compiler "optimizations"
|
||||
upx_add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
|
||||
upx_add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
||||
# disable overambitious auto-vectorization until this actually gains something
|
||||
upx_add_definitions(-fno-tree-vectorize)
|
||||
# disable annoying clang warnings which get added by the macOS Xcode cmake generator
|
||||
if(CMAKE_GENERATOR MATCHES "Xcode")
|
||||
upx_add_definitions(-Wno-shorten-64-to-32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# examine compiler configuration
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||
upx_print_common_symbols()
|
||||
upx_print_mingw_symbols()
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# targets
|
||||
#***********************************************************************
|
||||
|
||||
# internal settings; these may change in a future versions
|
||||
set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe in UPX version 6
|
||||
set(UPX_CONFIG_DISABLE_BZIP2 ON) # bzip2 is currently not used; we might need it to decompress linux kernels
|
||||
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 6
|
||||
|
||||
upx_cmake_include_hook(4_targets)
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_THREADS)
|
||||
find_package(Threads)
|
||||
endif()
|
||||
# make sure that threads are indeed fully supported in C++
|
||||
if(Threads_FOUND)
|
||||
foreach(f std_lock_guard.cpp types_abi.cpp)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
|
||||
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
|
||||
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
|
||||
OUTPUT_VARIABLE output CXX_STANDARD 17)
|
||||
else()
|
||||
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
|
||||
OUTPUT_VARIABLE output)
|
||||
endif()
|
||||
if(NOT result)
|
||||
# failed; under MinGW be sure to use the posix-threads and NOT the win32-threads version
|
||||
if(UPX_CONFIG_REQUIRE_THREADS OR (UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS))
|
||||
message(WARNING "Threads FAILED ${f}: ${output}") # output from try_compile
|
||||
endif()
|
||||
set(Threads_FOUND OFF)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||
upx_add_glob_files(bzip2_SOURCES "vendor/bzip2/*.c")
|
||||
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
|
||||
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
|
||||
endif()
|
||||
endif() # UPX_CONFIG_DISABLE_BZIP2
|
||||
|
||||
upx_add_glob_files(ucl_SOURCES "vendor/ucl/src/*.c")
|
||||
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
||||
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
|
||||
endif()
|
||||
|
||||
upx_add_glob_files(zlib_SOURCES "vendor/zlib/*.c")
|
||||
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
||||
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
||||
endif()
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
upx_add_glob_files(zstd_SOURCES "vendor/zstd/lib/*/*.c")
|
||||
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
|
||||
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
|
||||
endif()
|
||||
endif() # UPX_CONFIG_DISABLE_ZSTD
|
||||
|
||||
upx_add_glob_files(upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
|
||||
add_executable(upx ${upx_SOURCES})
|
||||
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
|
||||
set_property(TARGET upx PROPERTY CXX_STANDARD 17)
|
||||
endif()
|
||||
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
||||
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||
target_link_libraries(upx upx_vendor_bzip2)
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
target_link_libraries(upx upx_vendor_zstd)
|
||||
endif()
|
||||
if(Threads_FOUND)
|
||||
target_link_libraries(upx Threads::Threads)
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# target compilation flags
|
||||
#***********************************************************************
|
||||
|
||||
upx_cmake_include_hook(5_target_compilation_flags)
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||
set(t upx_vendor_bzip2)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
target_compile_definitions(${t} PRIVATE BZ_NO_STDIO=1)
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
|
||||
elseif(GNU_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
|
||||
endif() # UPX_CONFIG_DISABLE_BZIP2
|
||||
|
||||
set(t upx_vendor_ucl)
|
||||
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||
elseif(GNU_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
|
||||
|
||||
set(t upx_vendor_zlib)
|
||||
target_include_directories(${t} PRIVATE vendor/zlib)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
target_compile_definitions(${t} PRIVATE HAVE_VSNPRINTF=1)
|
||||
if(HAVE_UNISTD_H)
|
||||
target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
|
||||
endif()
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE -W3 ${warn_WX})
|
||||
elseif(GNU_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror})
|
||||
endif()
|
||||
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
set(t upx_vendor_zstd)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1)
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||
elseif(GNU_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
|
||||
endif() # UPX_CONFIG_DISABLE_ZSTD
|
||||
|
||||
set(t upx)
|
||||
target_include_directories(${t} PRIVATE vendor)
|
||||
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
|
||||
if(GITREV_SHORT)
|
||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
|
||||
if(GIT_DESCRIBE)
|
||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}")
|
||||
endif()
|
||||
endif()
|
||||
if(Threads_FOUND)
|
||||
target_compile_definitions(${t} PRIVATE WITH_THREADS=1)
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_WSTRICT)
|
||||
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WSTRICT=0)
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_WERROR)
|
||||
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||
target_compile_definitions(${t} PRIVATE WITH_BZIP2=1)
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||
endif()
|
||||
if(HAVE_UTIMENSAT)
|
||||
target_compile_definitions(${t} PRIVATE USE_UTIMENSAT=1)
|
||||
if(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||
target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1)
|
||||
endif()
|
||||
endif()
|
||||
# improve speed of the Debug versions
|
||||
upx_compile_source_debug_with_O2(src/compress/compress_lzma.cpp)
|
||||
upx_compile_source_debug_with_O2(src/filter/filter_impl.cpp)
|
||||
#upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX})
|
||||
elseif(GNU_FRONTEND)
|
||||
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||
endif()
|
||||
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
|
||||
|
||||
#***********************************************************************
|
||||
# test
|
||||
# ctest
|
||||
# make test
|
||||
# ninja test
|
||||
#***********************************************************************
|
||||
|
||||
upx_cmake_include_hook(6_test)
|
||||
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
|
||||
|
||||
add_custom_command(TARGET upx POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/XTesting/$<CONFIG>")
|
||||
|
||||
include(CTest)
|
||||
if(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
|
||||
upx_add_test(upx-version upx --version)
|
||||
upx_add_test(upx-version-short upx --version-short)
|
||||
upx_add_test(upx-license upx --license)
|
||||
upx_add_test(upx-help-1 upx --help)
|
||||
upx_add_test(upx-help-2 upx --help-short)
|
||||
upx_add_test(upx-help-3 upx --help-verbose)
|
||||
upx_add_test(upx-sysinfo-1 upx --sysinfo)
|
||||
upx_add_test(upx-sysinfo-2 upx --sysinfo -v)
|
||||
upx_add_test(upx-sysinfo-3 upx --sysinfo -vv)
|
||||
if(NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||
# IMPORTANT NOTE: these tests can only work if the host executable format
|
||||
# is supported by UPX!
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/self_pack_test.cmake")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
|
||||
|
||||
#***********************************************************************
|
||||
# install
|
||||
# cmake --install .
|
||||
# make install
|
||||
# ninja install
|
||||
#***********************************************************************
|
||||
|
||||
upx_cmake_include_hook(7_install)
|
||||
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
|
||||
|
||||
# installation prefix and directories
|
||||
if(NOT CMAKE_INSTALL_PREFIX)
|
||||
#message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined")
|
||||
message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined")
|
||||
endif()
|
||||
# install files
|
||||
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_BINDIR)
|
||||
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(FILES
|
||||
COPYING LICENSE NEWS README doc/THANKS.txt doc/upx-doc.html doc/upx-doc.txt
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
|
||||
)
|
||||
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
|
||||
endif()
|
||||
|
||||
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||
|
||||
#***********************************************************************
|
||||
# summary
|
||||
# print some info about the build configuration
|
||||
#***********************************************************************
|
||||
|
||||
upx_cmake_include_hook(8_summary)
|
||||
|
||||
upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||
# print detailed info
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/print_info.cmake")
|
||||
upx_print_info()
|
||||
endif()
|
||||
upx_print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_TRY_COMPILE_CONFIGURATION CMAKE_BUILD_TYPE)
|
||||
if(Threads_FOUND)
|
||||
message(STATUS "WITH_THREADS = 1")
|
||||
elseif(UPX_CONFIG_REQUIRE_THREADS)
|
||||
message(FATAL_ERROR "ERROR: WITH_THREADS required")
|
||||
elseif(UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS)
|
||||
message(FATAL_ERROR "ERROR: WITH_THREADS expected; set UPX_CONFIG_EXPECT_THREADS=OFF")
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$")
|
||||
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
||||
endif()
|
||||
|
||||
# extra sanity checks to detect incompatible C vs CXX settings
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
|
||||
upx_platform_check_c_cxx_mismatch()
|
||||
endif()
|
||||
|
||||
upx_cmake_include_hook(9_finish)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt" "")
|
||||
|
||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||
@@ -1,48 +1,89 @@
|
||||
#
|
||||
# UPX toplevel Makefile - needs GNU make 3.81 or better
|
||||
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
# INFO: this Makefile is just a convenience wrapper for calling CMake
|
||||
|
||||
# HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this:
|
||||
# mkdir -p build/release
|
||||
# cd build/release
|
||||
# cmake ../.. # run config
|
||||
# make -j4 # and run build
|
||||
|
||||
CMAKE = cmake
|
||||
UPX_CMAKE_BUILD_FLAGS += --parallel
|
||||
ifneq ($(VERBOSE),)
|
||||
#UPX_CMAKE_BUILD_FLAGS += --verbose # requires CMake >= 3.14
|
||||
UPX_CMAKE_CONFIG_FLAGS += -DCMAKE_VERBOSE_MAKEFILE=ON
|
||||
endif
|
||||
# enable this if you prefer Ninja for the actual builds:
|
||||
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja
|
||||
|
||||
#***********************************************************************
|
||||
# default
|
||||
#***********************************************************************
|
||||
|
||||
.DEFAULT_GOAL = build/release
|
||||
|
||||
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
||||
run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
||||
# avoid re-running run_cmake_config if .upx_cmake_config_done.txt already exists
|
||||
run_config = $(if $(wildcard $1/CMakeFiles/.*_cmake_config_done.txt),,$(call run_cmake_config,$1,$2))
|
||||
run_build = $(call run_cmake_build,$1,$2)
|
||||
|
||||
build/debug: PHONY
|
||||
$(call run_config,$@,Debug)
|
||||
$(call run_build,$@,Debug)
|
||||
|
||||
build/release: PHONY
|
||||
$(call run_config,$@,Release)
|
||||
$(call run_build,$@,Release)
|
||||
|
||||
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||
.PHONY: PHONY
|
||||
.SECONDEXPANSION:
|
||||
.SUFFIXES:
|
||||
export SHELL = /bin/sh
|
||||
|
||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||
$(error GNU make 3.81 or better is required)
|
||||
endif
|
||||
# shortcuts (all => debug + release)
|
||||
debug: build/debug PHONY
|
||||
release: build/release PHONY
|
||||
all build/all: build/debug build/release PHONY
|
||||
build/%/all: $$(dir $$@)debug $$(dir $$@)release PHONY ;
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = .
|
||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||
#***********************************************************************
|
||||
# test
|
||||
#***********************************************************************
|
||||
|
||||
CTEST = ctest
|
||||
CTEST_JOBS ?= 8
|
||||
CTEST_FLAGS = --output-on-failure --parallel $(CTEST_JOBS)
|
||||
|
||||
# info: src/stub needs special build tools
|
||||
BUILD_STUB = 0
|
||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||
BUILD_STUB = 1
|
||||
endif
|
||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||
BUILD_STUB = 1
|
||||
endif
|
||||
build/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||
build/%/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||
build/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
|
||||
build/%/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
|
||||
build/%/all+test: $$(dir $$@)debug+test $$(dir $$@)release+test PHONY ;
|
||||
|
||||
# shortcuts
|
||||
debug+test: build/debug+test PHONY
|
||||
release+test: build/release+test PHONY
|
||||
all+test build/all+test: build/debug+test build/release+test PHONY
|
||||
|
||||
default:
|
||||
@echo "UPX info: please choose a target for 'make'"
|
||||
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||
|
||||
all mostlyclean clean distclean maintainer-clean:
|
||||
ifeq ($(BUILD_STUB),1)
|
||||
$(MAKE) -C src/stub $@
|
||||
endif
|
||||
#
|
||||
# END of Makefile
|
||||
#
|
||||
|
||||
# extra pre-defined build configurations and some utility; optional
|
||||
-include ./Makevars-local.mk
|
||||
-include ./misc/make/Makefile-extra.mk
|
||||
|
||||
# developer convenience
|
||||
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
|
||||
ifneq ($(and $(wildcard ./misc/scripts/.),$(wildcard ./doc/upx.pod)),)
|
||||
check-whitespace clang-format run-testsuite run-testsuite-all run-testsuite-debug run-testsuite-release: src/Makefile PHONY
|
||||
$(MAKE) -C src $@
|
||||
$(MAKE) -C doc $@
|
||||
|
||||
|
||||
ifneq ($(wildcard .hg/.),)
|
||||
# automatically generate ChangeLog from local Mercurial repo
|
||||
ChangeLog:
|
||||
hg log --style=changelog > $@
|
||||
.PHONY: ChangeLog
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
endif
|
||||
|
||||
@@ -2,6 +2,161 @@
|
||||
User visible changes for UPX
|
||||
==================================================================
|
||||
|
||||
Changes in 5.0.2 (20 Jul 2025):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/20
|
||||
|
||||
Changes in 5.0.1 (06 May 2025):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/19
|
||||
|
||||
Changes in 5.0.0 (20 Feb 2025):
|
||||
* ELF: use of memfd_create supports Enforcing mode of SELinux
|
||||
* ELF: two-step de-compression enables future per-PT_LOAD work
|
||||
* ELF: --unmap-all-pages completely avoids /proc/self/exe
|
||||
* ELF: PT_MIPS_ABIFLAGS is now forwarded into the compressed output;
|
||||
qemu-mips can choose the right floating-point emulation
|
||||
* ELF: many minor internal changes fix nits revealed by fuzzing
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/18
|
||||
|
||||
Changes in 4.2.4 (09 May 2024):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/17
|
||||
|
||||
Changes in 4.2.3 (27 Mar 2024):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/16
|
||||
|
||||
Changes in 4.2.2 (03 Jan 2024):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/15
|
||||
|
||||
Changes in 4.2.1 (01 Nov 2023):
|
||||
* linux: /proc/self/exe now is optional
|
||||
* windows: use SetFileTime to preserve sub-second file timestamps
|
||||
* official Windows builds: revert activeCodePage change introduced in 4.2.0
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/14
|
||||
|
||||
Changes in 4.2.0 (26 Oct 2023):
|
||||
* win32/pe and win64/pe: stricter relocation checks; please report regressions
|
||||
* unix: use utimensat to preserve sub-second file timestamps
|
||||
* new option '--link' to preserve hard-links (Unix only; use with care)
|
||||
* add support for NO_COLOR env var; see https://no-color.org/
|
||||
* disable macOS support until we fix compatibility with macOS 13+
|
||||
* official Windows builds: set activeCodePage to UTF-8
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/13
|
||||
|
||||
Changes in 4.1.0 (08 Aug 2023):
|
||||
* ELF: handle shared libraries with more than 2 PT_LOAD segments
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/11
|
||||
|
||||
Changes in 4.0.2 (30 Jan 2023):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/9
|
||||
|
||||
Changes in 4.0.1 (16 Nov 2022):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/8
|
||||
|
||||
Changes in 4.0.0 (28 Oct 2022):
|
||||
* Switch to semantic versioning
|
||||
* SECURITY NOTES: emphasize the security context in the docs
|
||||
* Support easy building from source code with CMake
|
||||
* Support easy rebuilding the stubs from source with Podman/Docker
|
||||
* Add integrated doctest C++ testing framework
|
||||
* Add support for EFI files (PE x86; Kornel Pal)
|
||||
* win32/pe and win64/pe: set correct SizeOfHeaders in the PE header
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/6
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/7
|
||||
|
||||
Changes in 3.96 (23 Jan 2020):
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/5
|
||||
|
||||
Changes in 3.95 (26 Aug 2018):
|
||||
* Flag --android-shlib to work around bad design in Android
|
||||
* Flag --force-pie when ET_DYN main program is not marked as DF_1_PIE
|
||||
* Better compatibility with varying layout of address space on Linux
|
||||
* Support for 4 PT_LOAD layout in ELF generated by binutils-2.31
|
||||
* bug fixes, particularly better diagnosis of malformed input
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/4
|
||||
|
||||
Changes in 3.94 (12 May 2017):
|
||||
* Add support for arm64-linux (aka "aarch64").
|
||||
* Add support for --lzma compression on 64-bit PowerPC (Thierry Fauck).
|
||||
* For Mach, "upx -d" will unpack a prefix of the file (and warn).
|
||||
* Various improvements to the ELF formats.
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/3
|
||||
|
||||
Changes in 3.93 (29 Jan 2017):
|
||||
* Fixed some win32/pe and win64/pe regressions introduced in 3.92
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/2
|
||||
|
||||
Changes in 3.92 (11 Dec 2016):
|
||||
* INFO: UPX has moved to GitHub - the new home page is https://upx.github.io
|
||||
* IMPORTANT: all PE formats: internal changes: reunited the diverged source
|
||||
files - please report all regressions into the bug tracker and try UPX 3.91
|
||||
in case of problems.
|
||||
* Support Apple MacOS 10.12 "Sierra", including more-robust de-compression.
|
||||
* Explicitly diagnose Go-language bad PT_LOAD; recommend hemfix.c.
|
||||
https://sourceforge.net/p/upx/bugs/195/ https://github.com/pwaller/goupx
|
||||
* Fix CERT-FI Case 829767 UPX command line tools segfaults.
|
||||
Received by UPX Team on 2015-May-08; originally reported
|
||||
by Codenomicon to NCSC-FI on 2015-01-08.
|
||||
The vulnerabilities were discovered by Joonas Kuorilehto and
|
||||
Antti Häyrynen from Codenomicon.
|
||||
* bug fixes - see https://github.com/upx/upx/milestone/1
|
||||
|
||||
Changes in 3.91 (30 Sep 2013):
|
||||
* Added experimental support for Windows 64-bit PE files, based on
|
||||
work by Stefan Widmann. Please use for testing only!
|
||||
* bug fixes
|
||||
|
||||
==================================================================
|
||||
|
||||
Changes in 3.09 (18 Feb 2013):
|
||||
* New option --preserve-build-id for GNU ELF.
|
||||
* Allow for code signing and LC_UUID on Mac OS X executables.
|
||||
* Allow non-contiguous LC_SEGMENTs and 0==.vmsize for Mach-O.
|
||||
* Allow zero-filled final page in PackUnix::canUnpack().
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.08 (12 Dec 2011):
|
||||
* Fix allocation in runtime stub for darwin.macho-entry (i386 and amd64).
|
||||
* Compress shared library on ELF i386 only [ld.so threatens even this case].
|
||||
* Attempt to support ELF on QNX 6.3.0 for armel (experimental).
|
||||
* Better diagnostic when ELF -fPIC is needed.
|
||||
* PT_NOTE improvements for BSD.
|
||||
* Preserve more ELF .e_flags on ARM.
|
||||
* Minor code improvements for ELF stubs.
|
||||
* Defend against another flavor of corrupt PE header.
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.07 (08 Sep 2010):
|
||||
* win32/pe: fixed relocation handling for files with *no* TLS callbacks
|
||||
[severe bug introduced in 3.06]
|
||||
|
||||
Changes in 3.06 (04 Sep 2010):
|
||||
* win32/pe: TLS callback support contributed by Stefan Widmann. Thanks!
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.05 (27 Apr 2010):
|
||||
* i386-linux and amd64-linux support shared libraries (DT_INIT must
|
||||
exist, all info needed by runtime loader must be first in .text, etc.)
|
||||
* Linux /proc/self/exe now is preserved by default, by leaving behind
|
||||
one page. New compress-time option --unmap-all-pages is available.
|
||||
* Withdraw support for shared libraries on Darwin (Apple Mac OS X)
|
||||
because upx does not understand enough about .dylib.
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.04 (27 Sep 2009):
|
||||
* new format Mach/AMD64 supports 64-bit programs on Apple Macintosh.
|
||||
* new formats Dylib/i386 and Dylib/ppc32 support shared libraries
|
||||
[such as browser plugins] on Darwin (Apple Macintosh). An existing
|
||||
-init function (LC_ROUTINES command) is required.
|
||||
* new format vmlinuz/armel for Debian NSLU2 (etc.) linux kernel
|
||||
* bvmlinuz boot protocol 2.08 for 386 Linux kernel
|
||||
* Extended ABI version 4 for armel-eabi ARM Linux ELF
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.03 (27 Apr 2008):
|
||||
* implement cache flushing for PowerPC (esp. model 440)
|
||||
* fix cache flushing on MIPS (>3 MiB compressed, or with holes)
|
||||
* fix MIPS big-endian
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.02 (16 Dec 2007):
|
||||
* fix unmapping on arm-linux.elf
|
||||
* fix error checking in mmap for i386-linux.elf [triggered by -fPIE]
|
||||
@@ -26,7 +181,7 @@ Changes in 2.93 beta (08 Mar 2007):
|
||||
you have to explicitly use '--lzma' even for '--ultra-brute' here
|
||||
because runtime decompression is about 30 times slower than NRV -
|
||||
which is really noticeable on old machines.
|
||||
* dos/exe: fixed a rarely occuring bug in relocation handling
|
||||
* dos/exe: fixed a rarely occurring bug in relocation handling
|
||||
* win32/pe & arm/pe: better icon compression handling
|
||||
|
||||
Changes in 2.92 beta (23 Jan 2007):
|
||||
@@ -37,7 +192,7 @@ Changes in 2.92 beta (23 Jan 2007):
|
||||
|
||||
Changes in 2.91 beta (29 Nov 2006):
|
||||
* assorted bug fixes
|
||||
* arm/pe: fix "missing" icon & version info resource problem for wince 5
|
||||
* wince/arm: fix "missing" icon & version info resource problem for WinCE 5
|
||||
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
||||
|
||||
Changes in 2.90 beta (08 Oct 2006):
|
||||
@@ -91,7 +246,7 @@ Changes in 1.95 beta (09 Apr 2006):
|
||||
* win32/pe: really worked around R6002 runtime errors
|
||||
|
||||
Changes in 1.94 beta (11 Mar 2006):
|
||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
||||
* new format: added support for wince/arm (ARM executables running on WinCE)
|
||||
* new format: added support for linux elf/amd64
|
||||
* new format: added support for linux elf/ppc32
|
||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
||||
@@ -143,7 +298,7 @@ Changes in 1.11 beta (20 Dec 2000):
|
||||
==================================================================
|
||||
|
||||
Changes in 1.25 (29 Jun 2004)
|
||||
* INFO: http://upx.sourceforge.net is the permanent UPX home page
|
||||
* INFO: http://upx.sourceforge.net is the new UPX home page
|
||||
* watcom/le: don't crash on files without relocations
|
||||
* win32/pe: stricter checks of some PE values
|
||||
* source code: much improved portability using ACC, the
|
||||
@@ -259,6 +414,8 @@ Changes in 0.99 (25 Feb 2000)
|
||||
* dos/com and dos/sys: fixed a bad decompressor problem
|
||||
* linux/386: the counter for the progress indicator was off by one
|
||||
|
||||
==================================================================
|
||||
|
||||
Changes in 0.94 (06 Dec 1999)
|
||||
* win32/pe: the stub now calls ExitProcess in case of import errors
|
||||
* under DOS and Windows, the environment variable UPX now accepts
|
||||
@@ -406,12 +563,12 @@ Changes in 0.40 (05 Oct 1998)
|
||||
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
||||
* fixed a rare bug in dos/exe
|
||||
* worked around a bug in djgpp's strip 2.8
|
||||
* djgpp/coff: Allegro packfile support should work now
|
||||
* djgpp2/coff: Allegro packfile support should work now
|
||||
* added dos/exeh compression method (works on 386+)
|
||||
|
||||
Changes in 0.30 (27 Jul 1998)
|
||||
* fixed a serious bug in the 32-bit compressors - please don't use
|
||||
djgpp/coff and watcom/le compressed files from previous versions,
|
||||
djgpp2/coff and watcom/le compressed files from previous versions,
|
||||
some of them are possibly damaged !
|
||||
* the 16-bit uncompressors are a little bit shorter & faster
|
||||
* fixed progress indicator for VESA and SVGA text modes
|
||||
@@ -422,6 +579,5 @@ Changes in 0.20 (05 Jul 1998)
|
||||
|
||||
Changes in 0.05 (26 May 1998)
|
||||
* first public beta release
|
||||
|
||||
|
||||
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||
* based on experience gained from our previous packers DJP (djgpp2/coff, 1996),
|
||||
lzop (1996) and mfxpak (atari/tos, 1990)
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
Here are some possible projects from which you can choose if you'd like to
|
||||
contribute to UPX. Be sure to get in touch with us first to avoid
|
||||
duplicate efforts.
|
||||
|
||||
|
||||
User interface:
|
||||
---------------
|
||||
|
||||
- Write a nifty Win32 GUI (in C++), but try to keep the size of the
|
||||
final executable small. Compression should be in a separate
|
||||
thread that calls do_one_file() [see src/work.cpp].
|
||||
|
||||
- Draw a nice UPX icon.
|
||||
|
||||
|
||||
More formats:
|
||||
-------------
|
||||
|
||||
- Amiga
|
||||
|
||||
- BeOS
|
||||
|
||||
- C64
|
||||
|
||||
- elks/8086 (this is a 16-bit linux-8086 kernel)
|
||||
See http://www.elks.ecs.soton.ac.uk/
|
||||
|
||||
- freebsd/386 (generic), freebsd/elf386 (specialized).
|
||||
Probably could share most of the linux code.
|
||||
|
||||
- add support for self-extracting HTML pages using a Javascript stub
|
||||
(like the AlgART HTML Packer "AHP")
|
||||
|
||||
|
||||
Existing formats:
|
||||
-----------------
|
||||
|
||||
- djgpp2/coff: add support for DLX dynamic loading
|
||||
(see SEAL http://www.home.sk/public/seal/ )
|
||||
|
||||
- dos/com: add support for very long files - convert to exe if necessary
|
||||
|
||||
- dos/exe: implement filter support
|
||||
|
||||
- linux/i386:
|
||||
- use the new assembly preprocessor stuff (ie. process the file
|
||||
headers internally)
|
||||
- UPX uncompressor daemon
|
||||
- rewrite the stub in assembly (not sure if this is a good idea...)
|
||||
|
||||
- watcom/le: add support for per section compression, LX support, VXD
|
||||
|
||||
- win32/pe: display a nice dialog box in the stub in case
|
||||
of problems (like importing a DLL or function fails)
|
||||
- win32/pe: per section compression
|
||||
|
||||
|
||||
Compression ratio:
|
||||
------------------
|
||||
|
||||
- invent more effective filters
|
||||
|
||||
- I (Markus) will continue to work on better compression algorithms,
|
||||
so be sure to do better than me if you plan working on this ;-)
|
||||
|
||||
|
||||
Other:
|
||||
------
|
||||
|
||||
- anything else you think that could improve UPX...
|
||||
|
||||
|
||||
Thanks for your contribution.
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io
|
||||
|
||||
|
||||
|
||||
@@ -18,10 +18,8 @@ WELCOME
|
||||
|
||||
Welcome to UPX !
|
||||
|
||||
Please don't forget to read the file LICENSE - UPX is distributed
|
||||
under the GNU General Public License (GPL) with special exceptions
|
||||
allowing the distribution of all compressed executables, including
|
||||
commercial programs.
|
||||
UPX is a free, secure, portable, extendable, high-performance
|
||||
executable packer for several executable formats.
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
@@ -37,106 +35,86 @@ and run exactly as before, with no runtime or memory penalty for most
|
||||
of the supported formats.
|
||||
|
||||
UPX supports a number of different executable formats, including
|
||||
Windows 95/98/ME/NT/2000/XP/CE programs and DLLs, DOS programs,
|
||||
and Linux executables and kernels.
|
||||
Windows programs and DLLs, and Linux executables.
|
||||
|
||||
UPX is free software distributed under the term of the GNU General
|
||||
Public License. Full source code is available.
|
||||
|
||||
UPX may be distributed and used freely, even with commercial applications.
|
||||
See the UPX License Agreement for details.
|
||||
See the UPX License Agreements for details.
|
||||
|
||||
UPX is rated number one in the well known Archive Comparison Test. Visit
|
||||
http://compression.ca/ .
|
||||
|
||||
UPX aims to be Commercial Quality Freeware.
|
||||
SECURITY CONTEXT
|
||||
================
|
||||
|
||||
IMPORTANT NOTE: UPX inherits the security context of any files it handles.
|
||||
|
||||
This means that packing, unpacking, or even testing or listing a file requires
|
||||
the same security considerations as actually executing the file.
|
||||
|
||||
Use UPX on trusted files only!
|
||||
|
||||
|
||||
SHORT DOCUMENTATION
|
||||
===================
|
||||
|
||||
'upx program.exe' will compress a program or DLL. For best compression
|
||||
results try 'upx --brute program.exe'.
|
||||
results try 'upx --best program.exe' or 'upx --brute program.exe'.
|
||||
|
||||
Please see the file UPX.DOC for the full documentation. The files
|
||||
NEWS and BUGS also contain various tidbits of information.
|
||||
|
||||
|
||||
DISCLAIMER
|
||||
==========
|
||||
|
||||
UPX comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
||||
|
||||
Having said that, we think that UPX is quite stable now. Indeed we
|
||||
have compressed lots of files without any problems. Also, the
|
||||
current version has undergone several months of beta testing -
|
||||
actually it's almost 8 years since our first public beta.
|
||||
|
||||
This is the first production quality release, and we plan that future
|
||||
releases will be backward compatible with this version.
|
||||
|
||||
Please report all problems or suggestions to the authors. Thanks.
|
||||
|
||||
|
||||
THE FUTURE
|
||||
==========
|
||||
|
||||
- We'd really love to support handheld systems like the PalmPilot because
|
||||
compression makes a lot of sense here. And - because of the atari/tos
|
||||
format - we already have a working decompressor in 68000 assembly.
|
||||
Unfortunately we know next to nothing about the operating system
|
||||
architecture of such handhelds, so we need some information from
|
||||
an expert. Please contact us if you think you can help.
|
||||
- Stay up-to-date with ongoing OS and executable format changes
|
||||
|
||||
- The Linux approach could probably get ported to a lot of other Unix
|
||||
variants, at least for other i386 architectures it shouldn't be too
|
||||
much work. If someone sends me a fresh hard disk and an official
|
||||
FreeBSD/OpenBSD/NetBSD/Solaris/BeOS... CD I might take a look at it ;-)
|
||||
- RISC-V 64 for Linux
|
||||
|
||||
- ARM64 for Windows (help wanted)
|
||||
|
||||
- We will *NOT* add any sort of protection and/or encryption.
|
||||
This only gives people a false feeling of security because
|
||||
by definition all protectors/compressors can be broken.
|
||||
And don't trust any advertisement of authors of other executable
|
||||
compressors about this topic - just do a websearch on "unpackers"...
|
||||
all "protectors" can be broken by definition.
|
||||
|
||||
- Fix all remaining bugs - keep your reports coming ;-)
|
||||
|
||||
- See the file PROJECTS in the source code distribution if you want
|
||||
to contribute.
|
||||
- Fix all remaining bugs - please report any issues
|
||||
https://github.com/upx/upx/issues
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
Copyright (C) 2000-2025 John F. Reiser
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
UPX is distributed with full source code under the terms of the
|
||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||
the file COPYING), or (at your option) under the GPLv+2 with special
|
||||
exceptions and restrictions granting the free usage for all binaries
|
||||
including commercial programs (see the file LICENSE).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
UPX License Agreement for more details.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
You should have received a copy of the UPX License Agreement along
|
||||
with this program; see the file LICENSE. If not, visit the UPX home page.
|
||||
You should have received a copy of the UPX License Agreements along
|
||||
with this program; see the files COPYING and LICENSE. If not,
|
||||
visit the UPX home page.
|
||||
|
||||
|
||||
Share and enjoy,
|
||||
Markus & Laszlo
|
||||
Markus & Laszlo & John
|
||||
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@BitWagon.com>
|
||||
|
||||
|
||||
[ The term UPX is a shorthand for the Ultimate Packer for eXecutables
|
||||
and holds no connection with potential owners of registered trademarks
|
||||
or other rights. ]
|
||||
|
||||
[ Feel free to contact us if you have commercial compression requirements
|
||||
or interesting job offers. ]
|
||||
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
MAJOR NEWS IN UPX 3
|
||||
===================
|
||||
|
||||
The main news since UPX 2 are:
|
||||
|
||||
* new format: added support for linux elf/arm
|
||||
|
||||
* better compression using the LZMA algorithm (option '--lzma')
|
||||
|
||||
+48
-60
@@ -27,21 +27,6 @@ Foreword
|
||||
Markus & Laszlo
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Welcome to the UPX source code release!
|
||||
|
||||
UPX is not a toy for kids. Apart from basic knowledge about executables
|
||||
and data compression you will need to be firm in C++, assembler,
|
||||
Perl and Makefiles. Probably some other things as well.
|
||||
|
||||
If you can't manage to compile it then the sources are
|
||||
probably not for you. Don't email us for help.
|
||||
|
||||
The authors use Linux for development. You might want to as well.
|
||||
|
||||
|
||||
Short overview
|
||||
--------------
|
||||
|
||||
@@ -56,52 +41,68 @@ Short overview
|
||||
are #included by the individual executable format handlers.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
- first of all you need to build the UCL compression library
|
||||
http://www.oberhumer.com/opensource/ucl/
|
||||
|
||||
|
||||
Tools needed to build/modify the UPX sources
|
||||
--------------------------------------------
|
||||
|
||||
- A C++ compiler supporting inner classes, templates, exceptions
|
||||
and RTTI.
|
||||
- A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11
|
||||
(older or other compilers may work but are unsupported, use at your own risk)
|
||||
|
||||
- GNU make 3.80 or better (GNU make 3.81 recommened).
|
||||
- GNU make
|
||||
|
||||
- CMake 3.13 or better; see https://cmake.org/
|
||||
|
||||
|
||||
To compile the packer sources
|
||||
-----------------------------
|
||||
|
||||
Set the environment variable UPX_UCLDIR to point to your
|
||||
UCL build directory, e.g.
|
||||
|
||||
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||
|
||||
Set the environment variable UPX_LZMADIR to point to your
|
||||
to your unpacked lzma443.tar.bz2 source directory, e.g.
|
||||
|
||||
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
|
||||
|
||||
Finally type
|
||||
|
||||
make
|
||||
- just run "make" in the top-level source directory
|
||||
|
||||
|
||||
If you want to modify the stub sources you'll also need
|
||||
-------------------------------------------------------
|
||||
|
||||
- GNU make 3.81 or better
|
||||
http://savannah.gnu.org/projects/make/
|
||||
- Podman/Docker: see misc/podman/rebuild-stubs - this
|
||||
is the preferred way of rebuilding the stubs
|
||||
|
||||
- Perl & Python
|
||||
- otherwise you will need:
|
||||
- a Linux host system with Perl, Python2 and some older compat-libs
|
||||
- upx-stubtools - a number of cross-assemblers and cross-compilers.
|
||||
Precompiled binaries for amd64-linux hosts are available from
|
||||
https://github.com/upx/upx-stubtools/releases
|
||||
|
||||
|
||||
Developer quick start
|
||||
---------------------
|
||||
1) $ mkdir my-upx; cd my-upx # new directory for safety and convenience
|
||||
2) $ git clone https://github.com/upx/upx.git
|
||||
3) $ git clone https://github.com/upx/upx-testsuite.git
|
||||
4) # Optional for re-building stubs:
|
||||
4a) $ pushd upx/src/stub # my-upx/upx/src/stub
|
||||
4b) $ wget https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz
|
||||
# Extract to $HOME/bin/bin-upx or $HOME/local/bin/bin-upx.
|
||||
# See directions in: https://github.com/upx/upx-stubtools
|
||||
4c) $ make clean; make # verify that you can re-build stubs
|
||||
4d) $ popd # my-upx
|
||||
5) $ cd upx # my-upx/upx
|
||||
6) $ git submodule update --init # compression algorithms, etc.
|
||||
# DO NOT TOUCH vendor/...
|
||||
# After a git merge/pull/etc, then use "git status"
|
||||
# to check whether the vendor directory is clean;
|
||||
# if not, then update via "git submodule update".
|
||||
# If stuck, then reset via "rm -rf vendor; git submodule update --init".
|
||||
7) $ mkdir -p build/debug build/release
|
||||
8) $ pushd build/debug # my-upx/upx/build/debug
|
||||
9) $ cmake ../.. # configure cmake
|
||||
10) $ cmake --build . --verbose # optional "--verbose"
|
||||
# This relies on stub/*.h, which YOU must re-build if necessary.
|
||||
# When in doubt, then use "cd src/stub; make clean; make".
|
||||
11) $ popd # my-upx/upx
|
||||
12) $ cd src # my-upx/upx/src
|
||||
12a) On MacOS: install homebrew (https:://brew.sh), then "brew install coreutils"
|
||||
and put <some_prefix>/opt/coreutils/libexec/gnubin into PATH so that
|
||||
"readlink -en" and "sha256sum -b" work.
|
||||
13) $ make run-testsuite 2>&1 | tee testsuite.log
|
||||
|
||||
- A number of cross-assemblers and cross-compilers - precompiled
|
||||
binaries for i386-linux hosts are available from
|
||||
http://sourceforge.net/project/showfiles.php?group_id=2331
|
||||
|
||||
|
||||
Misc. notes
|
||||
@@ -117,9 +118,9 @@ Misc. notes
|
||||
- Use gcc extensions and other compiler specific stuff only through
|
||||
macros.
|
||||
|
||||
***
|
||||
|
||||
Some conventions:
|
||||
-----------------
|
||||
|
||||
- follow our coding style
|
||||
- indent level = 4
|
||||
@@ -128,17 +129,4 @@ Some conventions:
|
||||
- Use throwSomeException() functions instead of throw SomeException():
|
||||
this makes the code shorter if used often.
|
||||
|
||||
***
|
||||
|
||||
Patches/Contributions
|
||||
|
||||
- Please send us bug fixes/contributions only using
|
||||
|
||||
diff -u oldfile newfile
|
||||
|
||||
or
|
||||
|
||||
diff -uNr olddirectory newdirectory
|
||||
|
||||
|
||||
# vi:ts=4:et
|
||||
# vim:set ts=4 sw=4 et:
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
UPX TODO list. Last updated 2006-12-08.
|
||||
|
||||
|
||||
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
||||
|
||||
- [None]
|
||||
|
||||
|
||||
OTHER:
|
||||
|
||||
- docs: convert docs from upx.pod to use AsciiDoc
|
||||
|
||||
- check all <const_cast> to make sure they are not invalid
|
||||
|
||||
- throwNotCompressible() is not a real error, so make the output nicer
|
||||
(info: bla bla). Also ui.cpp (total_*).
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
IMPROVED COMPRESSION RATIO
|
||||
==========================
|
||||
|
||||
- experiment with new filters
|
||||
|
||||
- implement filters for dos/exe
|
||||
|
||||
- filters: could we exploit a f->firstcall info field ?
|
||||
|
||||
- for small programs (e.g. < 64k), try an additional algorithm
|
||||
to see if it gives better compression
|
||||
|
||||
|
||||
ALL FORMATS
|
||||
===========
|
||||
|
||||
- more thoroughly test the exe-header in canPack()
|
||||
and throw exceptions when encountering bad values.
|
||||
|
||||
- implement `--cpu=486' option to use bswap on the 32-bit formats
|
||||
(if cpu >= 486)
|
||||
|
||||
|
||||
FORMAT DJGPP2/COFF
|
||||
==================
|
||||
|
||||
- handle overlays
|
||||
|
||||
- fix default file extension handling when the --coff option is set
|
||||
|
||||
|
||||
FORMAT DOS/EXE
|
||||
==============
|
||||
|
||||
- implement filters
|
||||
|
||||
- add a check so that we don't pack djgpp1 binaries
|
||||
|
||||
|
||||
FORMAT LINUX/386
|
||||
================
|
||||
|
||||
- don't mmap() the temporary output file - this seems to improve
|
||||
file io speed
|
||||
|
||||
|
||||
FORMAT TMT/ADAM
|
||||
===============
|
||||
|
||||
- the decompressors are already aligned, no need for an
|
||||
extra alignment
|
||||
|
||||
|
||||
FORMAT WATCOM/LE
|
||||
================
|
||||
|
||||
- handle files without relocations
|
||||
|
||||
- the decompressors are already aligned, no need for an
|
||||
extra alignment
|
||||
|
||||
- fix default file extension handling when the --le option is set
|
||||
|
||||
- handle holes in the file
|
||||
|
||||
|
||||
FORMAT WIN16/NE
|
||||
===============
|
||||
|
||||
- implement readFileHeader() to correctly identify a win16/ne
|
||||
executable, so that the call for contribution will get thrown
|
||||
|
||||
|
||||
FORMAT WIN32/PE
|
||||
===============
|
||||
|
||||
- fix the section alignment with the Intel compiler
|
||||
|
||||
- decrease runtime memory overhead
|
||||
|
||||
3 - difficult) don't compress the BSS section and other holes.
|
||||
|
||||
4 - medium - ml) fix when objectalign < 0x1000
|
||||
|
||||
4 - easy - ml) put the original offset of moved resources somewhere into
|
||||
the res.dir. (if it's safe to do)
|
||||
|
||||
4 - ??? - ml) fix FIXMEs
|
||||
|
||||
5 - medium - ml) try to put the preprocessed imports & relocs back to their
|
||||
original section if possible. this could save some virtual memory
|
||||
address space.
|
||||
|
||||
+11
-12
@@ -1,15 +1,15 @@
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io
|
||||
|
||||
|
||||
Limitations and other things which are not (yet) supported:
|
||||
@@ -28,7 +28,7 @@ dos/exe
|
||||
watcom/le
|
||||
---------
|
||||
* 16-bit selector alias fixups
|
||||
* 16-bit offset relocation for objects larger than 4 kB
|
||||
* 16-bit offset relocation for objects larger than 4 KiB
|
||||
* 16:16 fixups
|
||||
|
||||
If you need any of the above (they're very rare), send us an URL of a
|
||||
@@ -44,8 +44,7 @@ test file.
|
||||
|
||||
win32/pe
|
||||
--------
|
||||
* writeable shared sections (`--force' *may* work)
|
||||
* writable shared sections (`--force' *may* work)
|
||||
* certificates in the image
|
||||
* compressing files which contain a big BSS requires lots of memory
|
||||
during compression
|
||||
|
||||
+38
-47
@@ -1,29 +1,9 @@
|
||||
#
|
||||
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||
# UPX doc Makefile - needs GNU make, sed, pod2html, pod2man and pod2text
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
SHELL = /bin/sh
|
||||
|
||||
# internal make variables
|
||||
comma := ,
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
tab := $(empty) $(empty)
|
||||
|
||||
# update $PATH for our special stub build tools
|
||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
||||
endif
|
||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||
export PATH := $(HOME)/bin/bin-upx:$(PATH)
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
BUILT_SOURCES := upx.1 upx-doc.html upx-doc.txt
|
||||
|
||||
top_srcdir ?= ..
|
||||
|
||||
@@ -31,55 +11,66 @@ PACKAGE = upx
|
||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
|
||||
# internal make variables
|
||||
comma := ,
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
tab := $(empty) $(empty)
|
||||
|
||||
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||
|
||||
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
||||
BUILT_SOURCES = upx.1 upx.doc upx.html
|
||||
#***********************************************************************
|
||||
# targets
|
||||
#***********************************************************************
|
||||
|
||||
.DEFAULT_GOAL = all
|
||||
|
||||
###
|
||||
### targets
|
||||
###
|
||||
.PHONY: PHONY
|
||||
.SECONDEXPANSION:
|
||||
.SUFFIXES:
|
||||
|
||||
all: $(BUILT_SOURCES)
|
||||
all: $(BUILT_SOURCES) PHONY
|
||||
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f $(BUILT_SOURCES) pod2htm*
|
||||
mostlyclean clean distclean maintainer-clean: PHONY
|
||||
rm -f $(BUILT_SOURCES) ./pod2htm*
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
#***********************************************************************
|
||||
# rules
|
||||
#***********************************************************************
|
||||
|
||||
|
||||
###
|
||||
### rules
|
||||
###
|
||||
|
||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
||||
|
||||
%.1 : %.pod
|
||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||
test -s $@
|
||||
# # strip version number from "Pod::Man" comment
|
||||
sed -i -e 's/^\(\.\\" Automatically generated by Pod::Man\).*/\1/' $@
|
||||
|
||||
%.doc : %.pod
|
||||
pod2text < $< | $(RTRIM) > $@
|
||||
|
||||
%.html : %.pod
|
||||
%-doc.html : %.pod
|
||||
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||
@rm -f pod2htm*
|
||||
@rm -f ./pod2htm*
|
||||
test -s $@
|
||||
|
||||
%.man : %.1
|
||||
nroff -man $< | $(RTRIM) > $@
|
||||
test -s $@
|
||||
|
||||
%.ps : %.1
|
||||
groff -man $< | $(RTRIM) > $@
|
||||
test -s $@
|
||||
|
||||
%.tex : %.pod
|
||||
pod2latex $<
|
||||
test -s $@
|
||||
|
||||
%-doc.txt : %.pod
|
||||
pod2text < $< | $(RTRIM) > $@
|
||||
test -s $@
|
||||
|
||||
###
|
||||
### dependencies
|
||||
###
|
||||
#***********************************************************************
|
||||
# dependencies
|
||||
#***********************************************************************
|
||||
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||
|
||||
|
||||
+17
-12
@@ -1,15 +1,15 @@
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
ooooo ooo ooooooooo. ooooooo ooooo
|
||||
`888' `8' `888 `Y88. `8888 d8'
|
||||
888 8 888 .d88' Y888..8P
|
||||
888 8 888ooo88P' `8888'
|
||||
888 8 888 .8PY888.
|
||||
`88. .8' 888 d8' `888b
|
||||
`YbodP' o888o o888o o88888o
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io
|
||||
|
||||
|
||||
.___.. .
|
||||
@@ -37,23 +37,28 @@ Charles W. Sandmann <sandmann@clio.rice.edu>
|
||||
for the idea with the stubless decompressor in djgpp2/coff
|
||||
Ice
|
||||
for debugging the PE headersize problem down
|
||||
Jens Medoch <jssg@users.sourceforge.net>
|
||||
for the ps1/exe format
|
||||
Joergen Ibsen <jibz@hotmail.com> and d'b
|
||||
for the relocation & address optimization ideas
|
||||
John S. Fine <johnfine@erols.com>
|
||||
for the new version of the dos/exe decompressor
|
||||
Kornel Pal
|
||||
for the EFI support
|
||||
Lukundoo <Lukundoo@softhome.net>
|
||||
for beta testing
|
||||
Michael Devore
|
||||
for initial dos/exe device driver support
|
||||
Oleg V. Volkov <rover@lglobus.ru>
|
||||
for various FreeBSD specific informations
|
||||
for various FreeBSD specific information
|
||||
The Owl & G-RoM
|
||||
for the --compress-icons fix
|
||||
Ralph Roth <RalphRoth@gmx.net>
|
||||
for reporting several bugs
|
||||
Salvador Eduardo Tropea
|
||||
for beta testing
|
||||
The WINE project (http://www.winehq.com/)
|
||||
Stefan Widmann
|
||||
for the win32/pe TLS callback support
|
||||
The WINE project (https://www.winehq.com/)
|
||||
for lots of useful information found in their PE loader sources
|
||||
Natascha
|
||||
|
||||
+66
-38
@@ -1,5 +1,5 @@
|
||||
Decompressing ELF Directly to Memory on Linux/x86
|
||||
Copyright (C) 2000-2007 John F. Reiser jreiser@BitWagon.com
|
||||
Copyright (C) 2000-2025 John F. Reiser jreiser@BitWagon.com
|
||||
|
||||
References:
|
||||
<elf.h> definitions for the ELF file format
|
||||
@@ -15,7 +15,7 @@ the value that is manipulated by system call 45 (__NR_brk in
|
||||
there will be no execve() except for the execve() of the decompressor
|
||||
program itself. So, the decompressor program (which contains the
|
||||
compressed version of the original executable) must have the same
|
||||
brk() as the original executable. So, the second PT_LOAD
|
||||
brk() as the original executable. So, the first PT_LOAD
|
||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||
All of the decompressor's code, and all of the compressed image
|
||||
@@ -25,35 +25,27 @@ decompressor program.
|
||||
The decompressor program stub is just under 2K bytes when linked.
|
||||
After linking, the decompressor code is converted to an initialized
|
||||
array, and #included into the compilation of the compressor;
|
||||
see src/stub/l_le_n2b.h. To make self-contained compressed
|
||||
see stub/i386-linux.elf-entry.h. To make self-contained compressed
|
||||
executables even smaller, the compressor also compresses all but the
|
||||
startup and decompression subroutine of the decompressor itself,
|
||||
saving a few hundred bytes. The startup code first decompresses the
|
||||
rest of the decompressor, then jumps to it. A nonstandard linker
|
||||
script src/stub/l_lx_elf86.lds places both the .text and .data
|
||||
of the decompressor into the same PT_LOAD at 0x00401000. The
|
||||
compressor includes the compressed bytes of the original executable
|
||||
at the end of this first PT_LOAD.
|
||||
script src/stub/src/i386-linux.elf-entry.lds arranges the SECTIONS
|
||||
so that PackLinuxElf32x86::buildLoader() and buildLinuxLoader()
|
||||
generate the desired stub code, which goes into PT_LOAD[1].
|
||||
|
||||
At runtime, the decompressed stub lives at 0x00400000. In order for the
|
||||
decompressed stub to work properly at an address that is different
|
||||
from its link-time address, the compiled code must contain no absolute
|
||||
addresses. So, the data items in l_lx_elf.c must be only parameters
|
||||
and automatic (on-stack) local variables; no global data, no static data,
|
||||
and no string constants. Use "size l_le_n2b.o l_6e_n2b.o" to check
|
||||
that both data and bss have length zero. Also, the '&' operator
|
||||
may not be used to take the address of a function.
|
||||
|
||||
The address 0x00400000 was chosen to be out of the way of the usual
|
||||
load address 0x08048000, and to minimize fragmentation in kernel
|
||||
page tables; one page of page tables covers 4MB. The address
|
||||
0x00401000 was chosen as 1 page up from a 64KB boundary, to
|
||||
make the startup code and its constants smaller.
|
||||
At runtime, the decompressed stub lives close beyond the brk().
|
||||
In order for the decompressed stub to work properly at an address
|
||||
that is different from its link-time address, the compiled code must
|
||||
contain no absolute addresses. So, the data items in stub code
|
||||
must be only parameters and automatic (on-stack) local variables;
|
||||
no global data, no static data, and no string constants. Also,
|
||||
the '&' operator may not be used to take the address of a function.
|
||||
|
||||
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
||||
and Elf32_Phdr, and then uses the Ehdr and Phdrs to control decompression
|
||||
of the PT_LOAD segments.
|
||||
Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
||||
and Elf32_Phdr, and then uses those Ehdr and Phdrs to control decompression
|
||||
of the PT_LOAD segments. Subroutine do_xmap() of src/stub/src/
|
||||
i386-linux.elf-main.c performs the
|
||||
"virtual execve()" using the compressed data as source, and stores
|
||||
the decompressed bytes directly into the appropriate virtual addresses.
|
||||
|
||||
@@ -64,18 +56,54 @@ assuming that its automatic stack variables are initialized to zero),
|
||||
and remove (all but 4 bytes of) the decompression program (and
|
||||
compressed executable) from the address space.
|
||||
|
||||
Because the UPX runtime stub removes all traces of the compressed file
|
||||
from the address space, then the Linux kernel erases the symlink
|
||||
/proc/self/exe. Linux stores the pathname argument that was specified
|
||||
to execve() immediately after the '\0' which terminates the character
|
||||
string of the last environment variable [as of execve()]. This is true
|
||||
for at least all Linux 2.6, 2.4, and 2.2 kernels. The pathname is not
|
||||
"bound" to the file as strongly as /proc/self/exe (the file may be changed
|
||||
without affecting the pathname), but the pathname does provide some
|
||||
information. The pathname may be relative to the working directory,
|
||||
so look before any chdir().
|
||||
As of upx-3.05, by default on Linux, upon decompression then one page
|
||||
of the compressed executable remains mapped into the address space
|
||||
of the process. If all of the pages of the compressed executable are
|
||||
unmapped, then the Linux kernel erases the symlink /proc/self/exe,
|
||||
and this can cause trouble for the runtime shared library loader
|
||||
expanding $ORIGIN in -rpath, or for application code that relies on
|
||||
/proc/self/exe. Use the compress-time command-line option
|
||||
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
||||
and previous versions did this by default with no option. However,
|
||||
too much other software erroneously assumes that /proc/self/exe
|
||||
always exists. upx-4.3.0 made /proc/self/exe optional so that
|
||||
chroot() and related environments can work.
|
||||
For Elf formats, UPX adds an environment variable named " " [three
|
||||
spaces] which saves the results of readlink("/proc/self/exe",,)
|
||||
If /proc/self/exe is ENOENT, then the variable has the same value
|
||||
as its name "/proc/self/exe".
|
||||
|
||||
The Elf formats for Linux add an environment variable named " " [three
|
||||
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
||||
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
||||
for linux/elf386 and linux/ElfAMD.
|
||||
All of the above documentation refers to ET_EXEC main programs,
|
||||
which always use the same virtual addresses. An ET_DYN executable
|
||||
(main program or shared library) follows much the same scheme,
|
||||
re-using the address space that the kernel chose originally.
|
||||
|
||||
Linux stores the pathname argument that was specified to execve()
|
||||
immediately after the '\0' which terminates the character string of the
|
||||
last environment variable [as of execve()]. This is true for at least
|
||||
all Linux 2.6, 2.4, and 2.2 kernels. Linux kernel 2.6.29 and later
|
||||
records a pointer to that character string in Elf32_auxv[AT_EXECFN].
|
||||
The pathname is not "bound" to the file as strongly as /proc/self/exe
|
||||
(the file may be changed without affecting the pathname), but the
|
||||
pathname does provide some information. The pathname may be relative
|
||||
to the working directory, so look before performing any chdir().
|
||||
|
||||
On any page, then SELinux in strictest enforcing mode prohibits
|
||||
simultaneous PROT_EXEC and PROT_WRITE, and also prohibits adding
|
||||
PROT_EXEC if the kernel VMA struct (Virtual Memory Area struct)
|
||||
that manages that page ever has had PROT_WRITE. This implies that
|
||||
the only way to get PROT_EXEC is to map the page directly from a file.
|
||||
Therefore, in late 2023 the various decompression stubs are being
|
||||
rewritten to "bounce" the decompressed data through pages in a
|
||||
memory-resident file created by the memfd_create() system call,
|
||||
and subsequently mapped PROT_EXEC. Actual copying of the pages
|
||||
can be avoided by careful sequence mmap() modes, but the overhead
|
||||
of an additional system call is required.
|
||||
|
||||
The not-as-strict "targeted enforcing" mode of
|
||||
SELinux seems not to demand this extra work, except for executables
|
||||
that run with elevated privileges, such as various system daemons.
|
||||
So "ordinary" user-mode apps can run in current "targeted enforcing"
|
||||
mode. But because the actual runtime mode of SELinux is unknown
|
||||
at compression time, then the memfd_create method should be used
|
||||
all the time.
|
||||
|
||||
+2
-2
@@ -108,14 +108,14 @@ then skip another one - the unfiltering process needs some information
|
||||
to be able to reverse the filtering.
|
||||
|
||||
UPX uses the following idea, which works nicely. First we assume that
|
||||
the size of the area that should be filtered is less than 16MB. Then
|
||||
the size of the area that should be filtered is less than 16 MiB. Then
|
||||
UPX scans over this area and keeps a record of the bytes that are
|
||||
following the 0xE8 bytes. If we are lucky, there will be bytes that
|
||||
were not found following 0xE8. These bytes are our candidates to be
|
||||
used as markers.
|
||||
|
||||
Do you still remember that we assumed that the size of scanned area is
|
||||
less than 16MB? Well, this means that when we process a real call, the
|
||||
less than 16 MiB? Well, this means that when we process a real call, the
|
||||
resulting offset will be less than 0x00FFFFFF too. So the MSB is always
|
||||
0x00. Which is a nice place to store our marker. Of course we should
|
||||
reverse the byte order in the resulting offset - so this marker will
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ code 127, and a record will be added to the history file
|
||||
|
||||
In "targeted enforcing" mode, SELinux pays close attention mostly to
|
||||
designated processes that run with elevated privileges: web server,
|
||||
print server, login server, etc. Ordinary user excutables receive
|
||||
print server, login server, etc. Ordinary user executables receive
|
||||
much less scrutiny. However, one of the eventual goals of SELinux is to
|
||||
eradicate runtime generation of instructions because of the possibility
|
||||
for exploitation by malware (virus, trojan, key logger, privilege
|
||||
|
||||
Generated
+803
@@ -0,0 +1,803 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>upx - compress or expand executable files</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rev="made" href="mailto:root@localhost" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<h1 id="NAME">NAME</h1>
|
||||
|
||||
<p>upx - compress or expand executable files</p>
|
||||
|
||||
<h1 id="SYNOPSIS">SYNOPSIS</h1>
|
||||
|
||||
<p><b>upx</b> <span style="white-space: nowrap;">[ <i>command</i> ]</span> <span style="white-space: nowrap;">[ <i>options</i> ]</span> <i>filename</i>...</p>
|
||||
|
||||
<h1 id="ABSTRACT">ABSTRACT</h1>
|
||||
|
||||
<pre><code> The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io</code></pre>
|
||||
|
||||
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
|
||||
|
||||
<h1 id="DISCLAIMER">DISCLAIMER</h1>
|
||||
|
||||
<p><b>UPX</b> comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.</p>
|
||||
|
||||
<p>Please report all problems or suggestions to the authors. Thanks.</p>
|
||||
|
||||
<h1 id="SECURITY-CONTEXT">SECURITY CONTEXT</h1>
|
||||
|
||||
<p>IMPORTANT NOTE: <b>UPX</b> inherits the security context of any files it handles.</p>
|
||||
|
||||
<p>This means that packing, unpacking, or even testing or listing a file requires the same security considerations as actually executing the file.</p>
|
||||
|
||||
<p>Use <b>UPX</b> on trusted files only!</p>
|
||||
|
||||
<h1 id="DESCRIPTION">DESCRIPTION</h1>
|
||||
|
||||
<p><b>UPX</b> is a versatile executable packer with the following features:</p>
|
||||
|
||||
<pre><code>- secure: as UPX is documented Open Source since many years any relevant
|
||||
Security/Antivirus software is able to peek inside UPX compressed
|
||||
apps to verify them
|
||||
|
||||
- excellent compression ratio: typically compresses better than Zip,
|
||||
use UPX to decrease the size of your distribution !
|
||||
|
||||
- very fast decompression: more than 500 MB/sec on any reasonably modern
|
||||
machine
|
||||
|
||||
- no memory overhead for your compressed executables for most of the
|
||||
supported formats because of in-place decompression
|
||||
|
||||
- safe: you can list, test and unpack your executables.
|
||||
Also, a checksum of both the compressed and uncompressed file is
|
||||
maintained internally.
|
||||
|
||||
- universal: UPX can pack a number of executable formats, including
|
||||
Windows programs and DLLs, macOS apps and Linux executables
|
||||
|
||||
- portable: UPX is written in portable endian-neutral C++
|
||||
|
||||
- extendable: because of the class layout it's very easy to support
|
||||
new executable formats or add new compression algorithms
|
||||
|
||||
- free: UPX is distributed with full source code under the GNU General
|
||||
Public License v2+, with special exceptions granting the free usage
|
||||
for commercial programs</code></pre>
|
||||
|
||||
<p>You probably understand now why we call <b>UPX</b> the "<i>ultimate</i>" executable packer.</p>
|
||||
|
||||
<h1 id="COMMANDS">COMMANDS</h1>
|
||||
|
||||
<h2 id="Compress">Compress</h2>
|
||||
|
||||
<p>This is the default operation, eg. <b>upx yourfile.exe</b> will compress the file specified on the command line.</p>
|
||||
|
||||
<h2 id="Decompress">Decompress</h2>
|
||||
|
||||
<p>All <b>UPX</b> supported file formats can be unpacked using the <b>-d</b> switch, eg. <b>upx -d yourfile.exe</b> will uncompress the file you've just compressed.</p>
|
||||
|
||||
<h2 id="Test">Test</h2>
|
||||
|
||||
<p>The <b>-t</b> command tests the integrity of the compressed and uncompressed data, eg. <b>upx -t yourfile.exe</b> check whether your file can be safely decompressed. Note, that this command doesn't check the whole file, only the part that will be uncompressed during program execution. This means that you should not use this command instead of a virus checker.</p>
|
||||
|
||||
<h2 id="List">List</h2>
|
||||
|
||||
<p>The <b>-l</b> command prints out some information about the compressed files specified on the command line as parameters, eg <b>upx -l yourfile.exe</b> shows the compressed / uncompressed size and the compression ratio of <i>yourfile.exe</i>.</p>
|
||||
|
||||
<h1 id="OPTIONS">OPTIONS</h1>
|
||||
|
||||
<p><b>-q</b>: be quiet, suppress warnings</p>
|
||||
|
||||
<p><b>-q -q</b> (or <b>-qq</b>): be very quiet, suppress errors</p>
|
||||
|
||||
<p><b>-q -q -q</b> (or <b>-qqq</b>): produce no output at all</p>
|
||||
|
||||
<p><b>--help</b>: prints the help</p>
|
||||
|
||||
<p><b>--version</b>: print the version of <b>UPX</b></p>
|
||||
|
||||
<p><b>--exact</b>: when compressing, require to be able to get a byte-identical file after decompression with option <b>-d</b>. [NOTE: this is work in progress and is not supported for all formats yet. If you do care, as a workaround you can compress and then decompress your program a first time - any further compress-decompress steps should then yield byte-identical results as compared to the first decompressed version.]</p>
|
||||
|
||||
<p><b>-k</b>: keep backup files</p>
|
||||
|
||||
<p><b>-o file</b>: write output to file</p>
|
||||
|
||||
<p>[ ...more docs need to be written... - type `<b>upx --help</b>' for now ]</p>
|
||||
|
||||
<h1 id="COMPRESSION-LEVELS-TUNING">COMPRESSION LEVELS & TUNING</h1>
|
||||
|
||||
<p><b>UPX</b> offers ten different compression levels from <b>-1</b> to <b>-9</b>, and <b>--best</b>. The default compression level is <b>-8</b> for files smaller than 512 KiB, and <b>-7</b> otherwise.</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><p>Compression levels 1, 2 and 3 are pretty fast.</p>
|
||||
|
||||
</li>
|
||||
<li><p>Compression levels 4, 5 and 6 achieve a good time/ratio performance.</p>
|
||||
|
||||
</li>
|
||||
<li><p>Compression levels 7, 8 and 9 favor compression ratio over speed.</p>
|
||||
|
||||
</li>
|
||||
<li><p>Compression level <b>--best</b> may take a long time.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Note that compression level <b>--best</b> can be somewhat slow for large files, but you definitely should use it when releasing a final version of your program.</p>
|
||||
|
||||
<p>Quick info for achieving the best compression ratio:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><p>Try <b>upx --brute --no-lzma myfile.exe</b> or even <b>upx --ultra-brute --no-lzma myfile.exe</b>.</p>
|
||||
|
||||
</li>
|
||||
<li><p>The option <b>--lzma</b> enables LZMA compression, which compresses better but is *significantly slower* at decompression. You probably do not want to use it for large files.</p>
|
||||
|
||||
<p>(Note that <b>--lzma</b> is automatically enabled by <b>--all-methods</b> and <b>--brute</b>, use <b>--no-lzma</b> to override.)</p>
|
||||
|
||||
</li>
|
||||
<li><p>Try if <b>--overlay=strip</b> works.</p>
|
||||
|
||||
</li>
|
||||
<li><p>For win32/pe programs there's <b>--strip-relocs=0</b>. See notes below.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="OVERLAY-HANDLING-OPTIONS">OVERLAY HANDLING OPTIONS</h1>
|
||||
|
||||
<p>Info: An "overlay" means auxiliary data attached after the logical end of an executable, and it often contains application specific data (this is a common practice to avoid an extra data file, though it would be better to use resource sections).</p>
|
||||
|
||||
<p><b>UPX</b> handles overlays like many other executable packers do: it simply copies the overlay after the compressed image. This works with some files, but doesn't work with others, depending on how an application actually accesses this overlaid data.</p>
|
||||
|
||||
<pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||
|
||||
--overlay=strip Strip any overlay from the program instead of
|
||||
copying it. Be warned, this may make the compressed
|
||||
program crash or otherwise unusable.
|
||||
|
||||
--overlay=skip Refuse to compress any program which has an overlay.</code></pre>
|
||||
|
||||
<h1 id="ENVIRONMENT-VARIABLE">ENVIRONMENT VARIABLE</h1>
|
||||
|
||||
<p>The environment variable <b>UPX</b> can hold a set of default options for <b>UPX</b>. These options are interpreted first and can be overwritten by explicit command line parameters. For example:</p>
|
||||
|
||||
<pre><code>for DOS/Windows: set UPX=-9 --compress-icons#0
|
||||
for sh/ksh/zsh: UPX="-9 --compress-icons=0"; export UPX
|
||||
for csh/tcsh: setenv UPX "-9 --compress-icons=0"</code></pre>
|
||||
|
||||
<p>Under DOS/Windows you must use '#' instead of '=' when setting the environment variable because of a COMMAND.COM limitation.</p>
|
||||
|
||||
<p>Not all of the options are valid in the environment variable - <b>UPX</b> will tell you.</p>
|
||||
|
||||
<p>You can explicitly use the <b>--no-env</b> option to ignore the environment variable.</p>
|
||||
|
||||
<h1 id="NOTES-FOR-THE-SUPPORTED-EXECUTABLE-FORMATS">NOTES FOR THE SUPPORTED EXECUTABLE FORMATS</h1>
|
||||
|
||||
<h2 id="NOTES-FOR-ATARI-TOS">NOTES FOR ATARI/TOS</h2>
|
||||
|
||||
<p>This is the executable format used by the Atari ST/TT, a Motorola 68000 based personal computer which was popular in the late '80s. Support of this format is only because of nostalgic feelings of one of the authors and serves no practical purpose :-). See https://freemint.github.io for more info.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression. All debug information will be stripped, though.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-BVMLINUZ-I386">NOTES FOR BVMLINUZ/I386</h2>
|
||||
|
||||
<p>Same as vmlinuz/i386.</p>
|
||||
|
||||
<h2 id="NOTES-FOR-DOS-COM">NOTES FOR DOS/COM</h2>
|
||||
|
||||
<p>Obviously <b>UPX</b> won't work with executables that want to read data from themselves (like some commandline utilities that ship with Win95/98/ME).</p>
|
||||
|
||||
<p>Compressed programs only work on a 286+.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression.</p>
|
||||
|
||||
<p>Maximum uncompressed size: ~65100 bytes.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-DOS-EXE">NOTES FOR DOS/EXE</h2>
|
||||
|
||||
<p>dos/exe stands for all "normal" 16-bit DOS executables.</p>
|
||||
|
||||
<p>Obviously <b>UPX</b> won't work with executables that want to read data from themselves (like some command line utilities that ship with Win95/98/ME).</p>
|
||||
|
||||
<p>Compressed programs only work on a 286+.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--no-reloc Use no relocation records in the exe header.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-DOS-SYS">NOTES FOR DOS/SYS</h2>
|
||||
|
||||
<p>Compressed programs only work on a 286+.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression.</p>
|
||||
|
||||
<p>Maximum uncompressed size: ~65350 bytes.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-DJGPP2-COFF">NOTES FOR DJGPP2/COFF</h2>
|
||||
|
||||
<p>First of all, it is recommended to use <b>UPX</b> *instead* of <b>strip</b>. strip has the very bad habit of replacing your stub with its own (outdated) version. Additionally <b>UPX</b> corrects a bug/feature in strip v2.8.x: it will fix the 4 KiB alignment of the stub.</p>
|
||||
|
||||
<p><b>UPX</b> includes the full functionality of stubify. This means it will automatically stubify your COFF files. Use the option <b>--coff</b> to disable this functionality (see below).</p>
|
||||
|
||||
<p><b>UPX</b> automatically handles Allegro packfiles.</p>
|
||||
|
||||
<p>The DLM format (a rather exotic shared library extension) is not supported.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression. All debug information and trailing garbage will be stripped, though.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--coff Produce COFF output instead of EXE. By default
|
||||
UPX keeps your current stub.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-LINUX-general">NOTES FOR LINUX [general]</h2>
|
||||
|
||||
<p>Introduction</p>
|
||||
|
||||
<pre><code>Linux/386 support in UPX consists of 3 different executable formats,
|
||||
one optimized for ELF executables ("linux/elf386"), one optimized
|
||||
for shell scripts ("linux/sh386"), and one generic format
|
||||
("linux/386").
|
||||
|
||||
We will start with a general discussion first, but please
|
||||
also read the relevant docs for each of the individual formats.
|
||||
|
||||
Also, there is special support for bootable kernels - see the
|
||||
description of the vmlinuz/386 format.</code></pre>
|
||||
|
||||
<p>General user's overview</p>
|
||||
|
||||
<pre><code>Running a compressed executable program trades less space on a
|
||||
``permanent'' storage medium (such as a hard disk, floppy disk,
|
||||
CD-ROM, flash memory, EPROM, etc.) for more space in one or more
|
||||
``temporary'' storage media (such as RAM, swap space, /tmp, etc.).
|
||||
Running a compressed executable also requires some additional CPU
|
||||
cycles to generate the compressed executable in the first place,
|
||||
and to decompress it at each invocation.
|
||||
|
||||
How much space is traded? It depends on the executable, but many
|
||||
programs save 30% to 50% of permanent disk space. How much CPU
|
||||
overhead is there? Again, it depends on the executable, but
|
||||
decompression speed generally is at least many megabytes per second,
|
||||
and frequently is limited by the speed of the underlying disk
|
||||
or network I/O.
|
||||
|
||||
Depending on the statistics of usage and access, and the relative
|
||||
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
|
||||
invoking and running a compressed executable can be faster than
|
||||
directly running the corresponding uncompressed program.
|
||||
The operating system might perform fewer expensive I/O operations
|
||||
to invoke the compressed program. Paging to or from swap space
|
||||
or /tmp might be faster than paging from the general file system.
|
||||
``Medium-sized'' programs which access about 1/3 to 1/2 of their
|
||||
stored program bytes can do particularly well with compression.
|
||||
Small programs tend not to benefit as much because the absolute
|
||||
savings is less. Big programs tend not to benefit proportionally
|
||||
because each invocation may use only a small fraction of the program,
|
||||
yet UPX decompresses the entire program before invoking it.
|
||||
But in environments where disk or flash memory storage is limited,
|
||||
then compression may win anyway.
|
||||
|
||||
Currently, executables compressed by UPX do not share RAM at runtime
|
||||
in the way that executables mapped from a file system do. As a
|
||||
result, if the same program is run simultaneously by more than one
|
||||
process, then using the compressed version will require more RAM and/or
|
||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||
might not be good candidates for compression.
|
||||
|
||||
UPX recognizes three executable formats for Linux: Linux/elf386,
|
||||
Linux/sh386, and Linux/386. Linux/386 is the most generic format;
|
||||
it accommodates any file that can be executed. At runtime, the UPX
|
||||
decompression stub re-creates in /tmp a copy of the original file,
|
||||
and then the copy is (re-)executed with the same arguments.
|
||||
ELF binary executables prefer the Linux/elf386 format by default,
|
||||
because UPX decompresses them directly into RAM, uses only one
|
||||
exec, does not use space in /tmp, and does not use /proc.
|
||||
Shell scripts where the underlying shell accepts a ``-c'' argument
|
||||
can use the Linux/sh386 format. UPX decompresses the shell script
|
||||
into low memory, then maps the shell and passes the entire text of the
|
||||
script as an argument with a leading ``-c''.</code></pre>
|
||||
|
||||
<p>General benefits:</p>
|
||||
|
||||
<pre><code>- UPX can compress all executables, be it AOUT, ELF, libc4, libc5,
|
||||
libc6, Shell/Perl/Python/... scripts, standalone Java .class
|
||||
binaries, or whatever...
|
||||
All scripts and programs will work just as before.
|
||||
|
||||
- Compressed programs are completely self-contained. No need for
|
||||
any external program.
|
||||
|
||||
- UPX keeps your original program untouched. This means that
|
||||
after decompression you will have a byte-identical version,
|
||||
and you can use UPX as a file compressor just like gzip.
|
||||
[ Note that UPX maintains a checksum of the file internally,
|
||||
so it is indeed a reliable alternative. ]
|
||||
|
||||
- As the stub only uses syscalls and isn't linked against libc it
|
||||
should run under any Linux configuration that can run ELF
|
||||
binaries.
|
||||
|
||||
- For the same reason compressed executables should run under
|
||||
FreeBSD and other systems which can run Linux binaries.
|
||||
[ Please send feedback on this topic ]</code></pre>
|
||||
|
||||
<p>General drawbacks:</p>
|
||||
|
||||
<pre><code>- It is not advisable to compress programs which usually have many
|
||||
instances running (like `sh' or `make') because the common segments of
|
||||
compressed programs won't be shared any longer between different
|
||||
processes.
|
||||
|
||||
- `ldd' and `size' won't show anything useful because all they
|
||||
see is the statically linked stub. Since version 0.82 the section
|
||||
headers are stripped from the UPX stub and `size' doesn't even
|
||||
recognize the file format. The file patches/patch-elfcode.h has a
|
||||
patch to fix this bug in `size' and other programs which use GNU BFD.</code></pre>
|
||||
|
||||
<p>General notes:</p>
|
||||
|
||||
<pre><code>- As UPX leaves your original program untouched it is advantageous
|
||||
to strip it before compression.
|
||||
|
||||
- If you compress a script you will lose platform independence -
|
||||
this could be a problem if you are using NFS mounted disks.
|
||||
|
||||
- Compression of suid, guid and sticky-bit programs is rejected
|
||||
because of possible security implications.
|
||||
|
||||
- For the same reason there is no sense in making any compressed
|
||||
program suid.
|
||||
|
||||
- Obviously UPX won't work with executables that want to read data
|
||||
from themselves. E.g., this might be a problem for Perl scripts
|
||||
which access their __DATA__ lines.
|
||||
|
||||
- In case of internal errors the stub will abort with exitcode 127.
|
||||
Typical reasons for this to happen are that the program has somehow
|
||||
been modified after compression.
|
||||
Running `strace -o strace.log compressed_file' will tell you more.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-LINUX-ELF386">NOTES FOR LINUX/ELF386</h2>
|
||||
|
||||
<p>Please read the general Linux description first.</p>
|
||||
|
||||
<p>The linux/elf386 format decompresses directly into RAM, uses only one exec, does not use space in /tmp, and does not use /proc.</p>
|
||||
|
||||
<p>Linux/elf386 is automatically selected for Linux ELF executables.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression.</p>
|
||||
|
||||
<p>How it works:</p>
|
||||
|
||||
<pre><code>For ELF executables, UPX decompresses directly to memory, simulating
|
||||
the mapping that the operating system kernel uses during exec(),
|
||||
including the PT_INTERP program interpreter (if any).
|
||||
The brk() is set by a special PT_LOAD segment in the compressed
|
||||
executable itself. UPX then wipes the stack clean except for
|
||||
arguments, environment variables, and Elf_auxv entries (this is
|
||||
required by bugs in the startup code of /lib/ld-linux.so as of
|
||||
May 2000), and transfers control to the program interpreter or
|
||||
the e_entry address of the original executable.
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
|
||||
|
||||
<p>Specific drawbacks:</p>
|
||||
|
||||
<pre><code>- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
RAM and swap space to hold all of the decompressed program during
|
||||
the lifetime of the process. If you already use most of your swap
|
||||
space, then you may run out. A system that is "out of memory"
|
||||
can become fragile. Many programs do not react gracefully when
|
||||
malloc() returns 0. With newer Linux kernels, the kernel
|
||||
may decide to kill some processes to regain memory, and you
|
||||
may not like the kernel's choice of which to kill. Running
|
||||
/usr/bin/top is one way to check on the usage of swap space.</code></pre>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>(none)</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-LINUX-SH386">NOTES FOR LINUX/SH386</h2>
|
||||
|
||||
<p>Please read the general Linux description first.</p>
|
||||
|
||||
<p>Shell scripts where the underling shell accepts a ``-c'' argument can use the Linux/sh386 format. <b>UPX</b> decompresses the shell script into low memory, then maps the shell and passes the entire text of the script as an argument with a leading ``-c''. It does not use space in /tmp, and does not use /proc.</p>
|
||||
|
||||
<p>Linux/sh386 is automatically selected for shell scripts that use a known shell.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression.</p>
|
||||
|
||||
<p>How it works:</p>
|
||||
|
||||
<pre><code>For shell script executables (files beginning with "#!/" or "#! /")
|
||||
where the shell is known to accept "-c <command>", UPX decompresses
|
||||
the file into low memory, then maps the shell (and its PT_INTERP),
|
||||
and passes control to the shell with the entire decompressed file
|
||||
as the argument after "-c". Known shells are sh, ash, bash, bsh, csh,
|
||||
ksh, tcsh, pdksh. Restriction: UPX cannot use this method
|
||||
for shell scripts which use the one optional string argument after
|
||||
the shell name in the script (example: "#! /bin/sh option3\n".)
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
|
||||
|
||||
<p>Specific drawbacks:</p>
|
||||
|
||||
<pre><code>- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
RAM and swap space to hold all of the decompressed program during
|
||||
the lifetime of the process. If you already use most of your swap
|
||||
space, then you may run out. A system that is "out of memory"
|
||||
can become fragile. Many programs do not react gracefully when
|
||||
malloc() returns 0. With newer Linux kernels, the kernel
|
||||
may decide to kill some processes to regain memory, and you
|
||||
may not like the kernel's choice of which to kill. Running
|
||||
/usr/bin/top is one way to check on the usage of swap space.</code></pre>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>(none)</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-LINUX-386">NOTES FOR LINUX/386</h2>
|
||||
|
||||
<p>Please read the general Linux description first.</p>
|
||||
|
||||
<p>The generic linux/386 format decompresses to /tmp and needs /proc file system support. It starts the decompressed program via the execve() syscall.</p>
|
||||
|
||||
<p>Linux/386 is only selected if the specialized linux/elf386 and linux/sh386 won't recognize a file.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression.</p>
|
||||
|
||||
<p>How it works:</p>
|
||||
|
||||
<pre><code>For files which are not ELF and not a script for a known "-c" shell,
|
||||
UPX uses kernel execve(), which first requires decompressing to a
|
||||
temporary file in the file system. Interestingly -
|
||||
because of the good memory management of the Linux kernel - this
|
||||
often does not introduce a noticeable delay, and in fact there
|
||||
will be no disk access at all if you have enough free memory as
|
||||
the entire process takes places within the file system buffers.
|
||||
|
||||
A compressed executable consists of the UPX stub and an overlay
|
||||
which contains the original program in a compressed form.
|
||||
|
||||
The UPX stub is a statically linked ELF executable and does
|
||||
the following at program startup:
|
||||
|
||||
1) decompress the overlay to a temporary location in /tmp
|
||||
2) open the temporary file for reading
|
||||
3) try to delete the temporary file and start (execve)
|
||||
the uncompressed program in /tmp using /proc/<pid>/fd/X as
|
||||
attained by step 2)
|
||||
4) if that fails, fork off a subprocess to clean up and
|
||||
start the program in /tmp in the meantime
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.</code></pre>
|
||||
|
||||
<p>Specific drawbacks:</p>
|
||||
|
||||
<pre><code>- You need additional free disk space for the uncompressed program
|
||||
in your /tmp directory. This program is deleted immediately after
|
||||
decompression, but you still need it for the full execution time
|
||||
of the program.
|
||||
|
||||
- You must have /proc file system support as the stub wants to open
|
||||
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||
cannot compress programs that are used during the boot sequence
|
||||
before /proc is mounted.
|
||||
|
||||
- Utilities like `top' will display numerical values in the process
|
||||
name field. This is because Linux computes the process name from
|
||||
the first argument of the last execve syscall (which is typically
|
||||
something like /proc/<pid>/fd/3).
|
||||
|
||||
- Because of temporary decompression to disk the decompression speed
|
||||
is not as fast as with the other executable formats. Still, I can see
|
||||
no noticeable delay when starting programs like my ~3 MiB emacs (which
|
||||
is less than 1 MiB when compressed :-).</code></pre>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--force-execve Force the use of the generic linux/386 "execve"
|
||||
format, i.e. do not try the linux/elf386 and
|
||||
linux/sh386 formats.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-PS1-EXE">NOTES FOR PS1/EXE</h2>
|
||||
|
||||
<p>This is the executable format used by the Sony PlayStation (PSone), a MIPS R3000 based gaming console which is popular since the late '90s. Support of this format is very similar to the Atari one, because of nostalgic feelings of one of the authors.</p>
|
||||
|
||||
<p>Packed programs will be byte-identical to the original after uncompression, until further notice.</p>
|
||||
|
||||
<p>Maximum uncompressed size: ~1.89 / ~7.60 MiB.</p>
|
||||
|
||||
<p>Notes:</p>
|
||||
|
||||
<pre><code>- UPX creates as default a suitable executable for CD-Mastering
|
||||
and console transfer. For a CD-Master main executable you could also try
|
||||
the special option "--boot-only" as described below.
|
||||
It has been reported that upx packed executables are fully compatible with
|
||||
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
|
||||
Sony PlayStation (PSone) emulation mode.
|
||||
|
||||
- Normally the packed files use the same memory areas like the uncompressed
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||
error. With the "--force" option UPX will relocate the loading address
|
||||
for the packed file, but this isn't a real problem if it is a single or
|
||||
the main executable.</code></pre>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
|
||||
|
||||
--boot-only This format is for main exes and CD-Mastering only !
|
||||
It may slightly improve the compression ratio,
|
||||
decompression routines are faster than default ones.
|
||||
But it cannot be used for console transfer !
|
||||
|
||||
--no-align This option disables CD mode 2 data sector format
|
||||
alignment. May slightly improves the compression ratio,
|
||||
but the compressed executable will not boot from a CD.
|
||||
Use it for console transfer only !</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-RTM32-PE-and-ARM-PE">NOTES FOR RTM32/PE and ARM/PE</h2>
|
||||
|
||||
<p>Same as win32/pe.</p>
|
||||
|
||||
<h2 id="NOTES-FOR-TMT-ADAM">NOTES FOR TMT/ADAM</h2>
|
||||
|
||||
<p>This format is used by the TMT Pascal compiler - see http://www.tmt.com/ .</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-VMLINUZ-386">NOTES FOR VMLINUZ/386</h2>
|
||||
|
||||
<p>The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed bootable Linux kernel image ("vmlinuz", "zImage", "bzImage"), gzip-decompress it and re-compress it with the <b>UPX</b> compression method.</p>
|
||||
|
||||
<p>vmlinuz/386 is completely unrelated to the other Linux executable formats, and it does not share any of their drawbacks.</p>
|
||||
|
||||
<p>Notes:</p>
|
||||
|
||||
<pre><code>- Be sure that "vmlinuz/386" or "bvmlinuz/386" is displayed
|
||||
during compression - otherwise a wrong executable format
|
||||
may have been used, and the kernel won't boot.</code></pre>
|
||||
|
||||
<p>Benefits:</p>
|
||||
|
||||
<pre><code>- Better compression (but note that the kernel was already compressed,
|
||||
so the improvement is not as large as with other formats).
|
||||
Still, the bytes saved may be essential for special needs like
|
||||
boot disks.
|
||||
|
||||
For example, this is what I get for my 2.2.16 kernel:
|
||||
1589708 vmlinux
|
||||
641073 bzImage [original]
|
||||
560755 bzImage.upx [compressed by "upx -9"]
|
||||
|
||||
- Much faster decompression at kernel boot time (but kernel
|
||||
decompression speed is not really an issue these days).</code></pre>
|
||||
|
||||
<p>Drawbacks:</p>
|
||||
|
||||
<pre><code>(none)</code></pre>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-WATCOM-LE">NOTES FOR WATCOM/LE</h2>
|
||||
|
||||
<p><b>UPX</b> has been successfully tested with the following extenders: DOS4G, DOS4GW, PMODE/W, DOS32a, CauseWay. The WDOS/X extender is partly supported (for details see the file bugs BUGS).</p>
|
||||
|
||||
<p>DLLs and the LX format are not supported.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--le Produce an unbound LE output instead of
|
||||
keeping the current stub.</code></pre>
|
||||
|
||||
<h2 id="NOTES-FOR-WIN32-PE">NOTES FOR WIN32/PE</h2>
|
||||
|
||||
<p>The PE support in <b>UPX</b> is quite stable now, but probably there are still some incompatibilities with some files.</p>
|
||||
|
||||
<p>Because of the way <b>UPX</b> (and other packers for this format) works, you can see increased memory usage of your compressed files because the whole program is loaded into memory at startup. If you start several instances of huge compressed programs you're wasting memory because the common segments of the program won't get shared across the instances. On the other hand if you're compressing only smaller programs, or running only one instance of larger programs, then this penalty is smaller, but it's still there.</p>
|
||||
|
||||
<p>If you're running executables from network, then compressed programs will load faster, and require less bandwidth during execution.</p>
|
||||
|
||||
<p>DLLs are supported. But UPX compressed DLLs can not share common data and code when they got used by multiple applications. So compressing msvcrt.dll is a waste of memory, but compressing the dll plugins of a particular application may be a better idea.</p>
|
||||
|
||||
<p>Screensavers are supported, with the restriction that the filename must end with ".scr" (as screensavers are handled slightly different than normal exe files).</p>
|
||||
|
||||
<p>UPX compressed PE files have some minor memory overhead (usually in the 10 - 30 KiB range) which can be seen by specifying the "-i" command line switch during compression.</p>
|
||||
|
||||
<p>Extra options available for this executable format:</p>
|
||||
|
||||
<pre><code>--compress-exports=0 Don't compress the export section.
|
||||
Use this if you plan to run the compressed
|
||||
program under Wine.
|
||||
--compress-exports=1 Compress the export section. [DEFAULT]
|
||||
Compression of the export section can improve the
|
||||
compression ratio quite a bit but may not work
|
||||
with all programs (like winword.exe).
|
||||
UPX never compresses the export section of a DLL
|
||||
regardless of this option.
|
||||
|
||||
--compress-icons=0 Don't compress any icons.
|
||||
--compress-icons=1 Compress all but the first icon.
|
||||
--compress-icons=2 Compress all icons which are not in the
|
||||
first icon directory. [DEFAULT]
|
||||
--compress-icons=3 Compress all icons.
|
||||
|
||||
--compress-resources=0 Don't compress any resources at all.
|
||||
|
||||
--keep-resource=list Don't compress resources specified by the list.
|
||||
The members of the list are separated by commas.
|
||||
A list member has the following format: I<type[/name]>.
|
||||
I<Type> is the type of the resource. Standard types
|
||||
must be specified as decimal numbers, user types can be
|
||||
specified by decimal IDs or strings. I<Name> is the
|
||||
identifier of the resource. It can be a decimal number
|
||||
or a string. For example:
|
||||
|
||||
--keep-resource=2/MYBITMAP,5,6/12345
|
||||
|
||||
UPX won't compress the named bitmap resource "MYBITMAP",
|
||||
it leaves every dialog (5) resource uncompressed, and
|
||||
it won't touch the string table resource with identifier
|
||||
12345.
|
||||
|
||||
--force Force compression even when there is an
|
||||
unexpected value in a header field.
|
||||
Use with care.
|
||||
|
||||
--strip-relocs=0 Don't strip relocation records.
|
||||
--strip-relocs=1 Strip relocation records. [DEFAULT]
|
||||
This option only works on executables with base
|
||||
address greater or equal to 0x400000. Usually the
|
||||
compressed files becomes smaller, but some files
|
||||
may become larger. Note that the resulting file will
|
||||
not work under Windows 3.x (Win32s).
|
||||
UPX never strips relocations from a DLL
|
||||
regardless of this option.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.</code></pre>
|
||||
|
||||
<h1 id="DIAGNOSTICS">DIAGNOSTICS</h1>
|
||||
|
||||
<p>Exit status is normally 0; if an error occurs, exit status is 1. If a warning occurs, exit status is 2.</p>
|
||||
|
||||
<p><b>UPX</b>'s diagnostics are intended to be self-explanatory.</p>
|
||||
|
||||
<h1 id="BUGS">BUGS</h1>
|
||||
|
||||
<p>Please report all bugs immediately to the authors.</p>
|
||||
|
||||
<h1 id="AUTHORS">AUTHORS</h1>
|
||||
|
||||
<pre><code>Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
http://www.oberhumer.com
|
||||
|
||||
Laszlo Molnar <ezerotven+github@gmail.com>
|
||||
|
||||
John F. Reiser <jreiser@BitWagon.com></code></pre>
|
||||
|
||||
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
||||
|
||||
<p>Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer</p>
|
||||
|
||||
<p>Copyright (C) 1996-2025 Laszlo Molnar</p>
|
||||
|
||||
<p>Copyright (C) 2000-2025 John F. Reiser</p>
|
||||
|
||||
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
|
||||
|
||||
<p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
|
||||
|
||||
<p>You should have received a copy of the UPX License Agreements along with this program; see the files COPYING and LICENSE. If not, visit the UPX home page.</p>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
Generated
+838
@@ -0,0 +1,838 @@
|
||||
NAME
|
||||
upx - compress or expand executable files
|
||||
|
||||
SYNOPSIS
|
||||
upx [ *command* ] [ *options* ] *filename*...
|
||||
|
||||
ABSTRACT
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io
|
||||
|
||||
UPX is a portable, extendable, high-performance executable packer for
|
||||
several different executable formats. It achieves an excellent
|
||||
compression ratio and offers **very** fast decompression. Your
|
||||
executables suffer no memory overhead or other drawbacks for most of the
|
||||
formats supported, because of in-place decompression.
|
||||
|
||||
DISCLAIMER
|
||||
UPX comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
|
||||
|
||||
Please report all problems or suggestions to the authors. Thanks.
|
||||
|
||||
SECURITY CONTEXT
|
||||
IMPORTANT NOTE: UPX inherits the security context of any files it
|
||||
handles.
|
||||
|
||||
This means that packing, unpacking, or even testing or listing a file
|
||||
requires the same security considerations as actually executing the
|
||||
file.
|
||||
|
||||
Use UPX on trusted files only!
|
||||
|
||||
DESCRIPTION
|
||||
UPX is a versatile executable packer with the following features:
|
||||
|
||||
- secure: as UPX is documented Open Source since many years any relevant
|
||||
Security/Antivirus software is able to peek inside UPX compressed
|
||||
apps to verify them
|
||||
|
||||
- excellent compression ratio: typically compresses better than Zip,
|
||||
use UPX to decrease the size of your distribution !
|
||||
|
||||
- very fast decompression: more than 500 MB/sec on any reasonably modern
|
||||
machine
|
||||
|
||||
- no memory overhead for your compressed executables for most of the
|
||||
supported formats because of in-place decompression
|
||||
|
||||
- safe: you can list, test and unpack your executables.
|
||||
Also, a checksum of both the compressed and uncompressed file is
|
||||
maintained internally.
|
||||
|
||||
- universal: UPX can pack a number of executable formats, including
|
||||
Windows programs and DLLs, macOS apps and Linux executables
|
||||
|
||||
- portable: UPX is written in portable endian-neutral C++
|
||||
|
||||
- extendable: because of the class layout it's very easy to support
|
||||
new executable formats or add new compression algorithms
|
||||
|
||||
- free: UPX is distributed with full source code under the GNU General
|
||||
Public License v2+, with special exceptions granting the free usage
|
||||
for commercial programs
|
||||
|
||||
You probably understand now why we call UPX the "*ultimate*" executable
|
||||
packer.
|
||||
|
||||
COMMANDS
|
||||
Compress
|
||||
This is the default operation, eg. upx yourfile.exe will compress the
|
||||
file specified on the command line.
|
||||
|
||||
Decompress
|
||||
All UPX supported file formats can be unpacked using the -d switch, eg.
|
||||
upx -d yourfile.exe will uncompress the file you've just compressed.
|
||||
|
||||
Test
|
||||
The -t command tests the integrity of the compressed and uncompressed
|
||||
data, eg. upx -t yourfile.exe check whether your file can be safely
|
||||
decompressed. Note, that this command doesn't check the whole file, only
|
||||
the part that will be uncompressed during program execution. This means
|
||||
that you should not use this command instead of a virus checker.
|
||||
|
||||
List
|
||||
The -l command prints out some information about the compressed files
|
||||
specified on the command line as parameters, eg upx -l yourfile.exe
|
||||
shows the compressed / uncompressed size and the compression ratio of
|
||||
*yourfile.exe*.
|
||||
|
||||
OPTIONS
|
||||
-q: be quiet, suppress warnings
|
||||
|
||||
-q -q (or -qq): be very quiet, suppress errors
|
||||
|
||||
-q -q -q (or -qqq): produce no output at all
|
||||
|
||||
--help: prints the help
|
||||
|
||||
--version: print the version of UPX
|
||||
|
||||
--exact: when compressing, require to be able to get a byte-identical
|
||||
file after decompression with option -d. [NOTE: this is work in progress
|
||||
and is not supported for all formats yet. If you do care, as a
|
||||
workaround you can compress and then decompress your program a first
|
||||
time - any further compress-decompress steps should then yield
|
||||
byte-identical results as compared to the first decompressed version.]
|
||||
|
||||
-k: keep backup files
|
||||
|
||||
-o file: write output to file
|
||||
|
||||
[ ...more docs need to be written... - type `upx --help' for now ]
|
||||
|
||||
COMPRESSION LEVELS & TUNING
|
||||
UPX offers ten different compression levels from -1 to -9, and --best.
|
||||
The default compression level is -8 for files smaller than 512 KiB, and
|
||||
-7 otherwise.
|
||||
|
||||
* Compression levels 1, 2 and 3 are pretty fast.
|
||||
|
||||
* Compression levels 4, 5 and 6 achieve a good time/ratio performance.
|
||||
|
||||
* Compression levels 7, 8 and 9 favor compression ratio over speed.
|
||||
|
||||
* Compression level --best may take a long time.
|
||||
|
||||
Note that compression level --best can be somewhat slow for large files,
|
||||
but you definitely should use it when releasing a final version of your
|
||||
program.
|
||||
|
||||
Quick info for achieving the best compression ratio:
|
||||
|
||||
* Try upx --brute --no-lzma myfile.exe or even upx --ultra-brute
|
||||
--no-lzma myfile.exe.
|
||||
|
||||
* The option --lzma enables LZMA compression, which compresses better
|
||||
but is *significantly slower* at decompression. You probably do not
|
||||
want to use it for large files.
|
||||
|
||||
(Note that --lzma is automatically enabled by --all-methods and
|
||||
--brute, use --no-lzma to override.)
|
||||
|
||||
* Try if --overlay=strip works.
|
||||
|
||||
* For win32/pe programs there's --strip-relocs=0. See notes below.
|
||||
|
||||
OVERLAY HANDLING OPTIONS
|
||||
Info: An "overlay" means auxiliary data attached after the logical end
|
||||
of an executable, and it often contains application specific data (this
|
||||
is a common practice to avoid an extra data file, though it would be
|
||||
better to use resource sections).
|
||||
|
||||
UPX handles overlays like many other executable packers do: it simply
|
||||
copies the overlay after the compressed image. This works with some
|
||||
files, but doesn't work with others, depending on how an application
|
||||
actually accesses this overlaid data.
|
||||
|
||||
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||
|
||||
--overlay=strip Strip any overlay from the program instead of
|
||||
copying it. Be warned, this may make the compressed
|
||||
program crash or otherwise unusable.
|
||||
|
||||
--overlay=skip Refuse to compress any program which has an overlay.
|
||||
|
||||
ENVIRONMENT VARIABLE
|
||||
The environment variable UPX can hold a set of default options for UPX.
|
||||
These options are interpreted first and can be overwritten by explicit
|
||||
command line parameters. For example:
|
||||
|
||||
for DOS/Windows: set UPX=-9 --compress-icons#0
|
||||
for sh/ksh/zsh: UPX="-9 --compress-icons=0"; export UPX
|
||||
for csh/tcsh: setenv UPX "-9 --compress-icons=0"
|
||||
|
||||
Under DOS/Windows you must use '#' instead of '=' when setting the
|
||||
environment variable because of a COMMAND.COM limitation.
|
||||
|
||||
Not all of the options are valid in the environment variable - UPX will
|
||||
tell you.
|
||||
|
||||
You can explicitly use the --no-env option to ignore the environment
|
||||
variable.
|
||||
|
||||
NOTES FOR THE SUPPORTED EXECUTABLE FORMATS
|
||||
NOTES FOR ATARI/TOS
|
||||
This is the executable format used by the Atari ST/TT, a Motorola 68000
|
||||
based personal computer which was popular in the late '80s. Support of
|
||||
this format is only because of nostalgic feelings of one of the authors
|
||||
and serves no practical purpose :-). See https://freemint.github.io for
|
||||
more info.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression. All debug information will be stripped, though.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
NOTES FOR BVMLINUZ/I386
|
||||
Same as vmlinuz/i386.
|
||||
|
||||
NOTES FOR DOS/COM
|
||||
Obviously UPX won't work with executables that want to read data from
|
||||
themselves (like some commandline utilities that ship with Win95/98/ME).
|
||||
|
||||
Compressed programs only work on a 286+.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression.
|
||||
|
||||
Maximum uncompressed size: ~65100 bytes.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
NOTES FOR DOS/EXE
|
||||
dos/exe stands for all "normal" 16-bit DOS executables.
|
||||
|
||||
Obviously UPX won't work with executables that want to read data from
|
||||
themselves (like some command line utilities that ship with
|
||||
Win95/98/ME).
|
||||
|
||||
Compressed programs only work on a 286+.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--no-reloc Use no relocation records in the exe header.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
NOTES FOR DOS/SYS
|
||||
Compressed programs only work on a 286+.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression.
|
||||
|
||||
Maximum uncompressed size: ~65350 bytes.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--8086 Create an executable that works on any 8086 CPU.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
NOTES FOR DJGPP2/COFF
|
||||
First of all, it is recommended to use UPX *instead* of strip. strip has
|
||||
the very bad habit of replacing your stub with its own (outdated)
|
||||
version. Additionally UPX corrects a bug/feature in strip v2.8.x: it
|
||||
will fix the 4 KiB alignment of the stub.
|
||||
|
||||
UPX includes the full functionality of stubify. This means it will
|
||||
automatically stubify your COFF files. Use the option --coff to disable
|
||||
this functionality (see below).
|
||||
|
||||
UPX automatically handles Allegro packfiles.
|
||||
|
||||
The DLM format (a rather exotic shared library extension) is not
|
||||
supported.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression. All debug information and trailing garbage will be
|
||||
stripped, though.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--coff Produce COFF output instead of EXE. By default
|
||||
UPX keeps your current stub.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
NOTES FOR LINUX [general]
|
||||
Introduction
|
||||
|
||||
Linux/386 support in UPX consists of 3 different executable formats,
|
||||
one optimized for ELF executables ("linux/elf386"), one optimized
|
||||
for shell scripts ("linux/sh386"), and one generic format
|
||||
("linux/386").
|
||||
|
||||
We will start with a general discussion first, but please
|
||||
also read the relevant docs for each of the individual formats.
|
||||
|
||||
Also, there is special support for bootable kernels - see the
|
||||
description of the vmlinuz/386 format.
|
||||
|
||||
General user's overview
|
||||
|
||||
Running a compressed executable program trades less space on a
|
||||
``permanent'' storage medium (such as a hard disk, floppy disk,
|
||||
CD-ROM, flash memory, EPROM, etc.) for more space in one or more
|
||||
``temporary'' storage media (such as RAM, swap space, /tmp, etc.).
|
||||
Running a compressed executable also requires some additional CPU
|
||||
cycles to generate the compressed executable in the first place,
|
||||
and to decompress it at each invocation.
|
||||
|
||||
How much space is traded? It depends on the executable, but many
|
||||
programs save 30% to 50% of permanent disk space. How much CPU
|
||||
overhead is there? Again, it depends on the executable, but
|
||||
decompression speed generally is at least many megabytes per second,
|
||||
and frequently is limited by the speed of the underlying disk
|
||||
or network I/O.
|
||||
|
||||
Depending on the statistics of usage and access, and the relative
|
||||
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
|
||||
invoking and running a compressed executable can be faster than
|
||||
directly running the corresponding uncompressed program.
|
||||
The operating system might perform fewer expensive I/O operations
|
||||
to invoke the compressed program. Paging to or from swap space
|
||||
or /tmp might be faster than paging from the general file system.
|
||||
``Medium-sized'' programs which access about 1/3 to 1/2 of their
|
||||
stored program bytes can do particularly well with compression.
|
||||
Small programs tend not to benefit as much because the absolute
|
||||
savings is less. Big programs tend not to benefit proportionally
|
||||
because each invocation may use only a small fraction of the program,
|
||||
yet UPX decompresses the entire program before invoking it.
|
||||
But in environments where disk or flash memory storage is limited,
|
||||
then compression may win anyway.
|
||||
|
||||
Currently, executables compressed by UPX do not share RAM at runtime
|
||||
in the way that executables mapped from a file system do. As a
|
||||
result, if the same program is run simultaneously by more than one
|
||||
process, then using the compressed version will require more RAM and/or
|
||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||
might not be good candidates for compression.
|
||||
|
||||
UPX recognizes three executable formats for Linux: Linux/elf386,
|
||||
Linux/sh386, and Linux/386. Linux/386 is the most generic format;
|
||||
it accommodates any file that can be executed. At runtime, the UPX
|
||||
decompression stub re-creates in /tmp a copy of the original file,
|
||||
and then the copy is (re-)executed with the same arguments.
|
||||
ELF binary executables prefer the Linux/elf386 format by default,
|
||||
because UPX decompresses them directly into RAM, uses only one
|
||||
exec, does not use space in /tmp, and does not use /proc.
|
||||
Shell scripts where the underlying shell accepts a ``-c'' argument
|
||||
can use the Linux/sh386 format. UPX decompresses the shell script
|
||||
into low memory, then maps the shell and passes the entire text of the
|
||||
script as an argument with a leading ``-c''.
|
||||
|
||||
General benefits:
|
||||
|
||||
- UPX can compress all executables, be it AOUT, ELF, libc4, libc5,
|
||||
libc6, Shell/Perl/Python/... scripts, standalone Java .class
|
||||
binaries, or whatever...
|
||||
All scripts and programs will work just as before.
|
||||
|
||||
- Compressed programs are completely self-contained. No need for
|
||||
any external program.
|
||||
|
||||
- UPX keeps your original program untouched. This means that
|
||||
after decompression you will have a byte-identical version,
|
||||
and you can use UPX as a file compressor just like gzip.
|
||||
[ Note that UPX maintains a checksum of the file internally,
|
||||
so it is indeed a reliable alternative. ]
|
||||
|
||||
- As the stub only uses syscalls and isn't linked against libc it
|
||||
should run under any Linux configuration that can run ELF
|
||||
binaries.
|
||||
|
||||
- For the same reason compressed executables should run under
|
||||
FreeBSD and other systems which can run Linux binaries.
|
||||
[ Please send feedback on this topic ]
|
||||
|
||||
General drawbacks:
|
||||
|
||||
- It is not advisable to compress programs which usually have many
|
||||
instances running (like `sh' or `make') because the common segments of
|
||||
compressed programs won't be shared any longer between different
|
||||
processes.
|
||||
|
||||
- `ldd' and `size' won't show anything useful because all they
|
||||
see is the statically linked stub. Since version 0.82 the section
|
||||
headers are stripped from the UPX stub and `size' doesn't even
|
||||
recognize the file format. The file patches/patch-elfcode.h has a
|
||||
patch to fix this bug in `size' and other programs which use GNU BFD.
|
||||
|
||||
General notes:
|
||||
|
||||
- As UPX leaves your original program untouched it is advantageous
|
||||
to strip it before compression.
|
||||
|
||||
- If you compress a script you will lose platform independence -
|
||||
this could be a problem if you are using NFS mounted disks.
|
||||
|
||||
- Compression of suid, guid and sticky-bit programs is rejected
|
||||
because of possible security implications.
|
||||
|
||||
- For the same reason there is no sense in making any compressed
|
||||
program suid.
|
||||
|
||||
- Obviously UPX won't work with executables that want to read data
|
||||
from themselves. E.g., this might be a problem for Perl scripts
|
||||
which access their __DATA__ lines.
|
||||
|
||||
- In case of internal errors the stub will abort with exitcode 127.
|
||||
Typical reasons for this to happen are that the program has somehow
|
||||
been modified after compression.
|
||||
Running `strace -o strace.log compressed_file' will tell you more.
|
||||
|
||||
NOTES FOR LINUX/ELF386
|
||||
Please read the general Linux description first.
|
||||
|
||||
The linux/elf386 format decompresses directly into RAM, uses only one
|
||||
exec, does not use space in /tmp, and does not use /proc.
|
||||
|
||||
Linux/elf386 is automatically selected for Linux ELF executables.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression.
|
||||
|
||||
How it works:
|
||||
|
||||
For ELF executables, UPX decompresses directly to memory, simulating
|
||||
the mapping that the operating system kernel uses during exec(),
|
||||
including the PT_INTERP program interpreter (if any).
|
||||
The brk() is set by a special PT_LOAD segment in the compressed
|
||||
executable itself. UPX then wipes the stack clean except for
|
||||
arguments, environment variables, and Elf_auxv entries (this is
|
||||
required by bugs in the startup code of /lib/ld-linux.so as of
|
||||
May 2000), and transfers control to the program interpreter or
|
||||
the e_entry address of the original executable.
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.
|
||||
|
||||
Specific drawbacks:
|
||||
|
||||
- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
RAM and swap space to hold all of the decompressed program during
|
||||
the lifetime of the process. If you already use most of your swap
|
||||
space, then you may run out. A system that is "out of memory"
|
||||
can become fragile. Many programs do not react gracefully when
|
||||
malloc() returns 0. With newer Linux kernels, the kernel
|
||||
may decide to kill some processes to regain memory, and you
|
||||
may not like the kernel's choice of which to kill. Running
|
||||
/usr/bin/top is one way to check on the usage of swap space.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
(none)
|
||||
|
||||
NOTES FOR LINUX/SH386
|
||||
Please read the general Linux description first.
|
||||
|
||||
Shell scripts where the underling shell accepts a ``-c'' argument can
|
||||
use the Linux/sh386 format. UPX decompresses the shell script into low
|
||||
memory, then maps the shell and passes the entire text of the script as
|
||||
an argument with a leading ``-c''. It does not use space in /tmp, and
|
||||
does not use /proc.
|
||||
|
||||
Linux/sh386 is automatically selected for shell scripts that use a known
|
||||
shell.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression.
|
||||
|
||||
How it works:
|
||||
|
||||
For shell script executables (files beginning with "#!/" or "#! /")
|
||||
where the shell is known to accept "-c <command>", UPX decompresses
|
||||
the file into low memory, then maps the shell (and its PT_INTERP),
|
||||
and passes control to the shell with the entire decompressed file
|
||||
as the argument after "-c". Known shells are sh, ash, bash, bsh, csh,
|
||||
ksh, tcsh, pdksh. Restriction: UPX cannot use this method
|
||||
for shell scripts which use the one optional string argument after
|
||||
the shell name in the script (example: "#! /bin/sh option3\n".)
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.
|
||||
|
||||
Specific drawbacks:
|
||||
|
||||
- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
RAM and swap space to hold all of the decompressed program during
|
||||
the lifetime of the process. If you already use most of your swap
|
||||
space, then you may run out. A system that is "out of memory"
|
||||
can become fragile. Many programs do not react gracefully when
|
||||
malloc() returns 0. With newer Linux kernels, the kernel
|
||||
may decide to kill some processes to regain memory, and you
|
||||
may not like the kernel's choice of which to kill. Running
|
||||
/usr/bin/top is one way to check on the usage of swap space.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
(none)
|
||||
|
||||
NOTES FOR LINUX/386
|
||||
Please read the general Linux description first.
|
||||
|
||||
The generic linux/386 format decompresses to /tmp and needs /proc file
|
||||
system support. It starts the decompressed program via the execve()
|
||||
syscall.
|
||||
|
||||
Linux/386 is only selected if the specialized linux/elf386 and
|
||||
linux/sh386 won't recognize a file.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression.
|
||||
|
||||
How it works:
|
||||
|
||||
For files which are not ELF and not a script for a known "-c" shell,
|
||||
UPX uses kernel execve(), which first requires decompressing to a
|
||||
temporary file in the file system. Interestingly -
|
||||
because of the good memory management of the Linux kernel - this
|
||||
often does not introduce a noticeable delay, and in fact there
|
||||
will be no disk access at all if you have enough free memory as
|
||||
the entire process takes places within the file system buffers.
|
||||
|
||||
A compressed executable consists of the UPX stub and an overlay
|
||||
which contains the original program in a compressed form.
|
||||
|
||||
The UPX stub is a statically linked ELF executable and does
|
||||
the following at program startup:
|
||||
|
||||
1) decompress the overlay to a temporary location in /tmp
|
||||
2) open the temporary file for reading
|
||||
3) try to delete the temporary file and start (execve)
|
||||
the uncompressed program in /tmp using /proc/<pid>/fd/X as
|
||||
attained by step 2)
|
||||
4) if that fails, fork off a subprocess to clean up and
|
||||
start the program in /tmp in the meantime
|
||||
|
||||
The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
and only uses kernel syscalls. It is not linked against any libc.
|
||||
|
||||
Specific drawbacks:
|
||||
|
||||
- You need additional free disk space for the uncompressed program
|
||||
in your /tmp directory. This program is deleted immediately after
|
||||
decompression, but you still need it for the full execution time
|
||||
of the program.
|
||||
|
||||
- You must have /proc file system support as the stub wants to open
|
||||
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||
cannot compress programs that are used during the boot sequence
|
||||
before /proc is mounted.
|
||||
|
||||
- Utilities like `top' will display numerical values in the process
|
||||
name field. This is because Linux computes the process name from
|
||||
the first argument of the last execve syscall (which is typically
|
||||
something like /proc/<pid>/fd/3).
|
||||
|
||||
- Because of temporary decompression to disk the decompression speed
|
||||
is not as fast as with the other executable formats. Still, I can see
|
||||
no noticeable delay when starting programs like my ~3 MiB emacs (which
|
||||
is less than 1 MiB when compressed :-).
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--force-execve Force the use of the generic linux/386 "execve"
|
||||
format, i.e. do not try the linux/elf386 and
|
||||
linux/sh386 formats.
|
||||
|
||||
NOTES FOR PS1/EXE
|
||||
This is the executable format used by the Sony PlayStation (PSone), a
|
||||
MIPS R3000 based gaming console which is popular since the late '90s.
|
||||
Support of this format is very similar to the Atari one, because of
|
||||
nostalgic feelings of one of the authors.
|
||||
|
||||
Packed programs will be byte-identical to the original after
|
||||
uncompression, until further notice.
|
||||
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 MiB.
|
||||
|
||||
Notes:
|
||||
|
||||
- UPX creates as default a suitable executable for CD-Mastering
|
||||
and console transfer. For a CD-Master main executable you could also try
|
||||
the special option "--boot-only" as described below.
|
||||
It has been reported that upx packed executables are fully compatible with
|
||||
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
|
||||
Sony PlayStation (PSone) emulation mode.
|
||||
|
||||
- Normally the packed files use the same memory areas like the uncompressed
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||
error. With the "--force" option UPX will relocate the loading address
|
||||
for the packed file, but this isn't a real problem if it is a single or
|
||||
the main executable.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
|
||||
|
||||
--boot-only This format is for main exes and CD-Mastering only !
|
||||
It may slightly improve the compression ratio,
|
||||
decompression routines are faster than default ones.
|
||||
But it cannot be used for console transfer !
|
||||
|
||||
--no-align This option disables CD mode 2 data sector format
|
||||
alignment. May slightly improves the compression ratio,
|
||||
but the compressed executable will not boot from a CD.
|
||||
Use it for console transfer only !
|
||||
|
||||
NOTES FOR RTM32/PE and ARM/PE
|
||||
Same as win32/pe.
|
||||
|
||||
NOTES FOR TMT/ADAM
|
||||
This format is used by the TMT Pascal compiler - see http://www.tmt.com/
|
||||
.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
NOTES FOR VMLINUZ/386
|
||||
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed bootable
|
||||
Linux kernel image ("vmlinuz", "zImage", "bzImage"), gzip-decompress it
|
||||
and re-compress it with the UPX compression method.
|
||||
|
||||
vmlinuz/386 is completely unrelated to the other Linux executable
|
||||
formats, and it does not share any of their drawbacks.
|
||||
|
||||
Notes:
|
||||
|
||||
- Be sure that "vmlinuz/386" or "bvmlinuz/386" is displayed
|
||||
during compression - otherwise a wrong executable format
|
||||
may have been used, and the kernel won't boot.
|
||||
|
||||
Benefits:
|
||||
|
||||
- Better compression (but note that the kernel was already compressed,
|
||||
so the improvement is not as large as with other formats).
|
||||
Still, the bytes saved may be essential for special needs like
|
||||
boot disks.
|
||||
|
||||
For example, this is what I get for my 2.2.16 kernel:
|
||||
1589708 vmlinux
|
||||
641073 bzImage [original]
|
||||
560755 bzImage.upx [compressed by "upx -9"]
|
||||
|
||||
- Much faster decompression at kernel boot time (but kernel
|
||||
decompression speed is not really an issue these days).
|
||||
|
||||
Drawbacks:
|
||||
|
||||
(none)
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
NOTES FOR WATCOM/LE
|
||||
UPX has been successfully tested with the following extenders: DOS4G,
|
||||
DOS4GW, PMODE/W, DOS32a, CauseWay. The WDOS/X extender is partly
|
||||
supported (for details see the file bugs BUGS).
|
||||
|
||||
DLLs and the LX format are not supported.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--le Produce an unbound LE output instead of
|
||||
keeping the current stub.
|
||||
|
||||
NOTES FOR WIN32/PE
|
||||
The PE support in UPX is quite stable now, but probably there are still
|
||||
some incompatibilities with some files.
|
||||
|
||||
Because of the way UPX (and other packers for this format) works, you
|
||||
can see increased memory usage of your compressed files because the
|
||||
whole program is loaded into memory at startup. If you start several
|
||||
instances of huge compressed programs you're wasting memory because the
|
||||
common segments of the program won't get shared across the instances. On
|
||||
the other hand if you're compressing only smaller programs, or running
|
||||
only one instance of larger programs, then this penalty is smaller, but
|
||||
it's still there.
|
||||
|
||||
If you're running executables from network, then compressed programs
|
||||
will load faster, and require less bandwidth during execution.
|
||||
|
||||
DLLs are supported. But UPX compressed DLLs can not share common data
|
||||
and code when they got used by multiple applications. So compressing
|
||||
msvcrt.dll is a waste of memory, but compressing the dll plugins of a
|
||||
particular application may be a better idea.
|
||||
|
||||
Screensavers are supported, with the restriction that the filename must
|
||||
end with ".scr" (as screensavers are handled slightly different than
|
||||
normal exe files).
|
||||
|
||||
UPX compressed PE files have some minor memory overhead (usually in the
|
||||
10 - 30 KiB range) which can be seen by specifying the "-i" command line
|
||||
switch during compression.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--compress-exports=0 Don't compress the export section.
|
||||
Use this if you plan to run the compressed
|
||||
program under Wine.
|
||||
--compress-exports=1 Compress the export section. [DEFAULT]
|
||||
Compression of the export section can improve the
|
||||
compression ratio quite a bit but may not work
|
||||
with all programs (like winword.exe).
|
||||
UPX never compresses the export section of a DLL
|
||||
regardless of this option.
|
||||
|
||||
--compress-icons=0 Don't compress any icons.
|
||||
--compress-icons=1 Compress all but the first icon.
|
||||
--compress-icons=2 Compress all icons which are not in the
|
||||
first icon directory. [DEFAULT]
|
||||
--compress-icons=3 Compress all icons.
|
||||
|
||||
--compress-resources=0 Don't compress any resources at all.
|
||||
|
||||
--keep-resource=list Don't compress resources specified by the list.
|
||||
The members of the list are separated by commas.
|
||||
A list member has the following format: I<type[/name]>.
|
||||
I<Type> is the type of the resource. Standard types
|
||||
must be specified as decimal numbers, user types can be
|
||||
specified by decimal IDs or strings. I<Name> is the
|
||||
identifier of the resource. It can be a decimal number
|
||||
or a string. For example:
|
||||
|
||||
--keep-resource=2/MYBITMAP,5,6/12345
|
||||
|
||||
UPX won't compress the named bitmap resource "MYBITMAP",
|
||||
it leaves every dialog (5) resource uncompressed, and
|
||||
it won't touch the string table resource with identifier
|
||||
12345.
|
||||
|
||||
--force Force compression even when there is an
|
||||
unexpected value in a header field.
|
||||
Use with care.
|
||||
|
||||
--strip-relocs=0 Don't strip relocation records.
|
||||
--strip-relocs=1 Strip relocation records. [DEFAULT]
|
||||
This option only works on executables with base
|
||||
address greater or equal to 0x400000. Usually the
|
||||
compressed files becomes smaller, but some files
|
||||
may become larger. Note that the resulting file will
|
||||
not work under Windows 3.x (Win32s).
|
||||
UPX never strips relocations from a DLL
|
||||
regardless of this option.
|
||||
|
||||
--all-methods Compress the program several times, using all
|
||||
available compression methods. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--all-filters Compress the program several times, using all
|
||||
available preprocessing filters. This may improve
|
||||
the compression ratio in some cases, but usually
|
||||
the default filter gives the best results anyway.
|
||||
|
||||
DIAGNOSTICS
|
||||
Exit status is normally 0; if an error occurs, exit status is 1. If a
|
||||
warning occurs, exit status is 2.
|
||||
|
||||
UPX's diagnostics are intended to be self-explanatory.
|
||||
|
||||
BUGS
|
||||
Please report all bugs immediately to the authors.
|
||||
|
||||
AUTHORS
|
||||
Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
http://www.oberhumer.com
|
||||
|
||||
Laszlo Molnar <ezerotven+github@gmail.com>
|
||||
|
||||
John F. Reiser <jreiser@BitWagon.com>
|
||||
|
||||
COPYRIGHT
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
|
||||
Copyright (C) 2000-2025 John F. Reiser
|
||||
|
||||
UPX is distributed with full source code under the terms of the GNU
|
||||
General Public License v2+; either under the pure GPLv2+ (see the file
|
||||
COPYING), or (at your option) under the GPLv+2 with special exceptions
|
||||
and restrictions granting the free usage for all binaries including
|
||||
commercial programs (see the file LICENSE).
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
You should have received a copy of the UPX License Agreements along with
|
||||
this program; see the files COPYING and LICENSE. If not, visit the UPX
|
||||
home page.
|
||||
|
||||
@@ -0,0 +1,960 @@
|
||||
.\" -*- mode: troff; coding: utf-8 -*-
|
||||
.\" Automatically generated by Pod::Man
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
|
||||
.ie n \{\
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is >0, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{\
|
||||
. if \nF \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{\
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "UPX 1"
|
||||
.TH UPX 1 2025-07-20 "upx 5.0.2" " "
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
upx \- compress or expand executable files
|
||||
.SH SYNOPSIS
|
||||
.IX Header "SYNOPSIS"
|
||||
\&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR...
|
||||
.SH ABSTRACT
|
||||
.IX Header "ABSTRACT"
|
||||
.Vb 3
|
||||
\& The Ultimate Packer for eXecutables
|
||||
\& Copyright (c) 1996\-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
\& https://upx.github.io
|
||||
.Ve
|
||||
.PP
|
||||
\&\fBUPX\fR is a portable, extendable, high-performance executable packer for
|
||||
several different executable formats. It achieves an excellent compression
|
||||
ratio and offers \fI*very*\fR fast decompression. Your executables suffer
|
||||
no memory overhead or other drawbacks for most of the formats supported,
|
||||
because of in-place decompression.
|
||||
.SH DISCLAIMER
|
||||
.IX Header "DISCLAIMER"
|
||||
\&\fBUPX\fR comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
|
||||
.PP
|
||||
Please report all problems or suggestions to the authors. Thanks.
|
||||
.SH "SECURITY CONTEXT"
|
||||
.IX Header "SECURITY CONTEXT"
|
||||
IMPORTANT NOTE: \fBUPX\fR inherits the security context of any files it handles.
|
||||
.PP
|
||||
This means that packing, unpacking, or even testing or listing a file requires
|
||||
the same security considerations as actually executing the file.
|
||||
.PP
|
||||
Use \fBUPX\fR on trusted files only!
|
||||
.SH DESCRIPTION
|
||||
.IX Header "DESCRIPTION"
|
||||
\&\fBUPX\fR is a versatile executable packer with the following features:
|
||||
.PP
|
||||
.Vb 3
|
||||
\& \- secure: as UPX is documented Open Source since many years any relevant
|
||||
\& Security/Antivirus software is able to peek inside UPX compressed
|
||||
\& apps to verify them
|
||||
\&
|
||||
\& \- excellent compression ratio: typically compresses better than Zip,
|
||||
\& use UPX to decrease the size of your distribution !
|
||||
\&
|
||||
\& \- very fast decompression: more than 500 MB/sec on any reasonably modern
|
||||
\& machine
|
||||
\&
|
||||
\& \- no memory overhead for your compressed executables for most of the
|
||||
\& supported formats because of in\-place decompression
|
||||
\&
|
||||
\& \- safe: you can list, test and unpack your executables.
|
||||
\& Also, a checksum of both the compressed and uncompressed file is
|
||||
\& maintained internally.
|
||||
\&
|
||||
\& \- universal: UPX can pack a number of executable formats, including
|
||||
\& Windows programs and DLLs, macOS apps and Linux executables
|
||||
\&
|
||||
\& \- portable: UPX is written in portable endian\-neutral C++
|
||||
\&
|
||||
\& \- extendable: because of the class layout it\*(Aqs very easy to support
|
||||
\& new executable formats or add new compression algorithms
|
||||
\&
|
||||
\& \- free: UPX is distributed with full source code under the GNU General
|
||||
\& Public License v2+, with special exceptions granting the free usage
|
||||
\& for commercial programs
|
||||
.Ve
|
||||
.PP
|
||||
You probably understand now why we call \fBUPX\fR the "\fIultimate\fR"
|
||||
executable packer.
|
||||
.SH COMMANDS
|
||||
.IX Header "COMMANDS"
|
||||
.SS Compress
|
||||
.IX Subsection "Compress"
|
||||
This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file
|
||||
specified on the command line.
|
||||
.SS Decompress
|
||||
.IX Subsection "Decompress"
|
||||
All \fBUPX\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg.
|
||||
\&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed.
|
||||
.SS Test
|
||||
.IX Subsection "Test"
|
||||
The \fB\-t\fR command tests the integrity of the compressed and uncompressed
|
||||
data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely
|
||||
decompressed. Note, that this command doesn't check the whole file, only
|
||||
the part that will be uncompressed during program execution. This means
|
||||
that you should not use this command instead of a virus checker.
|
||||
.SS List
|
||||
.IX Subsection "List"
|
||||
The \fB\-l\fR command prints out some information about the compressed files
|
||||
specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR
|
||||
shows the compressed / uncompressed size and the compression ratio of
|
||||
\&\fIyourfile.exe\fR.
|
||||
.SH OPTIONS
|
||||
.IX Header "OPTIONS"
|
||||
\&\fB\-q\fR: be quiet, suppress warnings
|
||||
.PP
|
||||
\&\fB\-q \-q\fR (or \fB\-qq\fR): be very quiet, suppress errors
|
||||
.PP
|
||||
\&\fB\-q \-q \-q\fR (or \fB\-qqq\fR): produce no output at all
|
||||
.PP
|
||||
\&\fB\-\-help\fR: prints the help
|
||||
.PP
|
||||
\&\fB\-\-version\fR: print the version of \fBUPX\fR
|
||||
.PP
|
||||
\&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file
|
||||
after decompression with option \fB\-d\fR. [NOTE: this is work in progress and is
|
||||
not supported for all formats yet. If you do care, as a workaround you can
|
||||
compress and then decompress your program a first time \- any further
|
||||
compress-decompress steps should then yield byte-identical results
|
||||
as compared to the first decompressed version.]
|
||||
.PP
|
||||
\&\fB\-k\fR: keep backup files
|
||||
.PP
|
||||
\&\fB\-o file\fR: write output to file
|
||||
.PP
|
||||
[ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ]
|
||||
.SH "COMPRESSION LEVELS & TUNING"
|
||||
.IX Header "COMPRESSION LEVELS & TUNING"
|
||||
\&\fBUPX\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR,
|
||||
and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files
|
||||
smaller than 512 KiB, and \fB\-7\fR otherwise.
|
||||
.IP \(bu 4
|
||||
Compression levels 1, 2 and 3 are pretty fast.
|
||||
.IP \(bu 4
|
||||
Compression levels 4, 5 and 6 achieve a good time/ratio performance.
|
||||
.IP \(bu 4
|
||||
Compression levels 7, 8 and 9 favor compression ratio over speed.
|
||||
.IP \(bu 4
|
||||
Compression level \fB\-\-best\fR may take a long time.
|
||||
.PP
|
||||
Note that compression level \fB\-\-best\fR can be somewhat slow for large
|
||||
files, but you definitely should use it when releasing a final version
|
||||
of your program.
|
||||
.PP
|
||||
Quick info for achieving the best compression ratio:
|
||||
.IP \(bu 4
|
||||
Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even
|
||||
\&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR.
|
||||
.IP \(bu 4
|
||||
The option \fB\-\-lzma\fR enables LZMA compression, which compresses better but
|
||||
is *significantly slower* at decompression. You probably do not want
|
||||
to use it for large files.
|
||||
.Sp
|
||||
(Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and
|
||||
\&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.)
|
||||
.IP \(bu 4
|
||||
Try if \fB\-\-overlay=strip\fR works.
|
||||
.IP \(bu 4
|
||||
For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below.
|
||||
.SH "OVERLAY HANDLING OPTIONS"
|
||||
.IX Header "OVERLAY HANDLING OPTIONS"
|
||||
Info: An "overlay" means auxiliary data attached after the logical end of
|
||||
an executable, and it often contains application specific data
|
||||
(this is a common practice to avoid an extra data file, though
|
||||
it would be better to use resource sections).
|
||||
.PP
|
||||
\&\fBUPX\fR handles overlays like many other executable packers do: it simply
|
||||
copies the overlay after the compressed image. This works with some
|
||||
files, but doesn't work with others, depending on how an application
|
||||
actually accesses this overlaid data.
|
||||
.PP
|
||||
.Vb 1
|
||||
\& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||
\&
|
||||
\& \-\-overlay=strip Strip any overlay from the program instead of
|
||||
\& copying it. Be warned, this may make the compressed
|
||||
\& program crash or otherwise unusable.
|
||||
\&
|
||||
\& \-\-overlay=skip Refuse to compress any program which has an overlay.
|
||||
.Ve
|
||||
.SH "ENVIRONMENT VARIABLE"
|
||||
.IX Header "ENVIRONMENT VARIABLE"
|
||||
The environment variable \fBUPX\fR can hold a set of default
|
||||
options for \fBUPX\fR. These options are interpreted first and
|
||||
can be overwritten by explicit command line parameters.
|
||||
For example:
|
||||
.PP
|
||||
.Vb 3
|
||||
\& for DOS/Windows: set UPX=\-9 \-\-compress\-icons#0
|
||||
\& for sh/ksh/zsh: UPX="\-9 \-\-compress\-icons=0"; export UPX
|
||||
\& for csh/tcsh: setenv UPX "\-9 \-\-compress\-icons=0"
|
||||
.Ve
|
||||
.PP
|
||||
Under DOS/Windows you must use '#' instead of '=' when setting the
|
||||
environment variable because of a COMMAND.COM limitation.
|
||||
.PP
|
||||
Not all of the options are valid in the environment variable \-
|
||||
\&\fBUPX\fR will tell you.
|
||||
.PP
|
||||
You can explicitly use the \fB\-\-no\-env\fR option to ignore the
|
||||
environment variable.
|
||||
.SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
||||
.IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
||||
.SS "NOTES FOR ATARI/TOS"
|
||||
.IX Subsection "NOTES FOR ATARI/TOS"
|
||||
This is the executable format used by the Atari ST/TT, a Motorola 68000
|
||||
based personal computer which was popular in the late '80s. Support
|
||||
of this format is only because of nostalgic feelings of one of
|
||||
the authors and serves no practical purpose :\-).
|
||||
See https://freemint.github.io for more info.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
All debug information will be stripped, though.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR BVMLINUZ/I386"
|
||||
.IX Subsection "NOTES FOR BVMLINUZ/I386"
|
||||
Same as vmlinuz/i386.
|
||||
.SS "NOTES FOR DOS/COM"
|
||||
.IX Subsection "NOTES FOR DOS/COM"
|
||||
Obviously \fBUPX\fR won't work with executables that want to read data from
|
||||
themselves (like some commandline utilities that ship with Win95/98/ME).
|
||||
.PP
|
||||
Compressed programs only work on a 286+.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
.PP
|
||||
Maximum uncompressed size: ~65100 bytes.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& \-\-8086 Create an executable that works on any 8086 CPU.
|
||||
\&
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR DOS/EXE"
|
||||
.IX Subsection "NOTES FOR DOS/EXE"
|
||||
dos/exe stands for all "normal" 16\-bit DOS executables.
|
||||
.PP
|
||||
Obviously \fBUPX\fR won't work with executables that want to read data from
|
||||
themselves (like some command line utilities that ship with Win95/98/ME).
|
||||
.PP
|
||||
Compressed programs only work on a 286+.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& \-\-8086 Create an executable that works on any 8086 CPU.
|
||||
\&
|
||||
\& \-\-no\-reloc Use no relocation records in the exe header.
|
||||
\&
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR DOS/SYS"
|
||||
.IX Subsection "NOTES FOR DOS/SYS"
|
||||
Compressed programs only work on a 286+.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
.PP
|
||||
Maximum uncompressed size: ~65350 bytes.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& \-\-8086 Create an executable that works on any 8086 CPU.
|
||||
\&
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR DJGPP2/COFF"
|
||||
.IX Subsection "NOTES FOR DJGPP2/COFF"
|
||||
First of all, it is recommended to use \fBUPX\fR *instead* of \fBstrip\fR. strip has
|
||||
the very bad habit of replacing your stub with its own (outdated) version.
|
||||
Additionally \fBUPX\fR corrects a bug/feature in strip v2.8.x: it
|
||||
will fix the 4 KiB alignment of the stub.
|
||||
.PP
|
||||
\&\fBUPX\fR includes the full functionality of stubify. This means it will
|
||||
automatically stubify your COFF files. Use the option \fB\-\-coff\fR to
|
||||
disable this functionality (see below).
|
||||
.PP
|
||||
\&\fBUPX\fR automatically handles Allegro packfiles.
|
||||
.PP
|
||||
The DLM format (a rather exotic shared library extension) is not supported.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
All debug information and trailing garbage will be stripped, though.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& \-\-coff Produce COFF output instead of EXE. By default
|
||||
\& UPX keeps your current stub.
|
||||
\&
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR LINUX [general]"
|
||||
.IX Subsection "NOTES FOR LINUX [general]"
|
||||
Introduction
|
||||
.PP
|
||||
.Vb 4
|
||||
\& Linux/386 support in UPX consists of 3 different executable formats,
|
||||
\& one optimized for ELF executables ("linux/elf386"), one optimized
|
||||
\& for shell scripts ("linux/sh386"), and one generic format
|
||||
\& ("linux/386").
|
||||
\&
|
||||
\& We will start with a general discussion first, but please
|
||||
\& also read the relevant docs for each of the individual formats.
|
||||
\&
|
||||
\& Also, there is special support for bootable kernels \- see the
|
||||
\& description of the vmlinuz/386 format.
|
||||
.Ve
|
||||
.PP
|
||||
General user's overview
|
||||
.PP
|
||||
.Vb 7
|
||||
\& Running a compressed executable program trades less space on a
|
||||
\& \`\`permanent\*(Aq\*(Aq storage medium (such as a hard disk, floppy disk,
|
||||
\& CD\-ROM, flash memory, EPROM, etc.) for more space in one or more
|
||||
\& \`\`temporary\*(Aq\*(Aq storage media (such as RAM, swap space, /tmp, etc.).
|
||||
\& Running a compressed executable also requires some additional CPU
|
||||
\& cycles to generate the compressed executable in the first place,
|
||||
\& and to decompress it at each invocation.
|
||||
\&
|
||||
\& How much space is traded? It depends on the executable, but many
|
||||
\& programs save 30% to 50% of permanent disk space. How much CPU
|
||||
\& overhead is there? Again, it depends on the executable, but
|
||||
\& decompression speed generally is at least many megabytes per second,
|
||||
\& and frequently is limited by the speed of the underlying disk
|
||||
\& or network I/O.
|
||||
\&
|
||||
\& Depending on the statistics of usage and access, and the relative
|
||||
\& speeds of CPU, RAM, swap space, /tmp, and file system storage, then
|
||||
\& invoking and running a compressed executable can be faster than
|
||||
\& directly running the corresponding uncompressed program.
|
||||
\& The operating system might perform fewer expensive I/O operations
|
||||
\& to invoke the compressed program. Paging to or from swap space
|
||||
\& or /tmp might be faster than paging from the general file system.
|
||||
\& \`\`Medium\-sized\*(Aq\*(Aq programs which access about 1/3 to 1/2 of their
|
||||
\& stored program bytes can do particularly well with compression.
|
||||
\& Small programs tend not to benefit as much because the absolute
|
||||
\& savings is less. Big programs tend not to benefit proportionally
|
||||
\& because each invocation may use only a small fraction of the program,
|
||||
\& yet UPX decompresses the entire program before invoking it.
|
||||
\& But in environments where disk or flash memory storage is limited,
|
||||
\& then compression may win anyway.
|
||||
\&
|
||||
\& Currently, executables compressed by UPX do not share RAM at runtime
|
||||
\& in the way that executables mapped from a file system do. As a
|
||||
\& result, if the same program is run simultaneously by more than one
|
||||
\& process, then using the compressed version will require more RAM and/or
|
||||
\& swap space. So, shell programs (bash, csh, etc.) and \`\`make\*(Aq\*(Aq
|
||||
\& might not be good candidates for compression.
|
||||
\&
|
||||
\& UPX recognizes three executable formats for Linux: Linux/elf386,
|
||||
\& Linux/sh386, and Linux/386. Linux/386 is the most generic format;
|
||||
\& it accommodates any file that can be executed. At runtime, the UPX
|
||||
\& decompression stub re\-creates in /tmp a copy of the original file,
|
||||
\& and then the copy is (re\-)executed with the same arguments.
|
||||
\& ELF binary executables prefer the Linux/elf386 format by default,
|
||||
\& because UPX decompresses them directly into RAM, uses only one
|
||||
\& exec, does not use space in /tmp, and does not use /proc.
|
||||
\& Shell scripts where the underlying shell accepts a \`\`\-c\*(Aq\*(Aq argument
|
||||
\& can use the Linux/sh386 format. UPX decompresses the shell script
|
||||
\& into low memory, then maps the shell and passes the entire text of the
|
||||
\& script as an argument with a leading \`\`\-c\*(Aq\*(Aq.
|
||||
.Ve
|
||||
.PP
|
||||
General benefits:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \- UPX can compress all executables, be it AOUT, ELF, libc4, libc5,
|
||||
\& libc6, Shell/Perl/Python/... scripts, standalone Java .class
|
||||
\& binaries, or whatever...
|
||||
\& All scripts and programs will work just as before.
|
||||
\&
|
||||
\& \- Compressed programs are completely self\-contained. No need for
|
||||
\& any external program.
|
||||
\&
|
||||
\& \- UPX keeps your original program untouched. This means that
|
||||
\& after decompression you will have a byte\-identical version,
|
||||
\& and you can use UPX as a file compressor just like gzip.
|
||||
\& [ Note that UPX maintains a checksum of the file internally,
|
||||
\& so it is indeed a reliable alternative. ]
|
||||
\&
|
||||
\& \- As the stub only uses syscalls and isn\*(Aqt linked against libc it
|
||||
\& should run under any Linux configuration that can run ELF
|
||||
\& binaries.
|
||||
\&
|
||||
\& \- For the same reason compressed executables should run under
|
||||
\& FreeBSD and other systems which can run Linux binaries.
|
||||
\& [ Please send feedback on this topic ]
|
||||
.Ve
|
||||
.PP
|
||||
General drawbacks:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \- It is not advisable to compress programs which usually have many
|
||||
\& instances running (like \`sh\*(Aq or \`make\*(Aq) because the common segments of
|
||||
\& compressed programs won\*(Aqt be shared any longer between different
|
||||
\& processes.
|
||||
\&
|
||||
\& \- \`ldd\*(Aq and \`size\*(Aq won\*(Aqt show anything useful because all they
|
||||
\& see is the statically linked stub. Since version 0.82 the section
|
||||
\& headers are stripped from the UPX stub and \`size\*(Aq doesn\*(Aqt even
|
||||
\& recognize the file format. The file patches/patch\-elfcode.h has a
|
||||
\& patch to fix this bug in \`size\*(Aq and other programs which use GNU BFD.
|
||||
.Ve
|
||||
.PP
|
||||
General notes:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& \- As UPX leaves your original program untouched it is advantageous
|
||||
\& to strip it before compression.
|
||||
\&
|
||||
\& \- If you compress a script you will lose platform independence \-
|
||||
\& this could be a problem if you are using NFS mounted disks.
|
||||
\&
|
||||
\& \- Compression of suid, guid and sticky\-bit programs is rejected
|
||||
\& because of possible security implications.
|
||||
\&
|
||||
\& \- For the same reason there is no sense in making any compressed
|
||||
\& program suid.
|
||||
\&
|
||||
\& \- Obviously UPX won\*(Aqt work with executables that want to read data
|
||||
\& from themselves. E.g., this might be a problem for Perl scripts
|
||||
\& which access their _\|_DATA_\|_ lines.
|
||||
\&
|
||||
\& \- In case of internal errors the stub will abort with exitcode 127.
|
||||
\& Typical reasons for this to happen are that the program has somehow
|
||||
\& been modified after compression.
|
||||
\& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more.
|
||||
.Ve
|
||||
.SS "NOTES FOR LINUX/ELF386"
|
||||
.IX Subsection "NOTES FOR LINUX/ELF386"
|
||||
Please read the general Linux description first.
|
||||
.PP
|
||||
The linux/elf386 format decompresses directly into RAM,
|
||||
uses only one exec, does not use space in /tmp,
|
||||
and does not use /proc.
|
||||
.PP
|
||||
Linux/elf386 is automatically selected for Linux ELF executables.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
.PP
|
||||
How it works:
|
||||
.PP
|
||||
.Vb 9
|
||||
\& For ELF executables, UPX decompresses directly to memory, simulating
|
||||
\& the mapping that the operating system kernel uses during exec(),
|
||||
\& including the PT_INTERP program interpreter (if any).
|
||||
\& The brk() is set by a special PT_LOAD segment in the compressed
|
||||
\& executable itself. UPX then wipes the stack clean except for
|
||||
\& arguments, environment variables, and Elf_auxv entries (this is
|
||||
\& required by bugs in the startup code of /lib/ld\-linux.so as of
|
||||
\& May 2000), and transfers control to the program interpreter or
|
||||
\& the e_entry address of the original executable.
|
||||
\&
|
||||
\& The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
\& and only uses kernel syscalls. It is not linked against any libc.
|
||||
.Ve
|
||||
.PP
|
||||
Specific drawbacks:
|
||||
.PP
|
||||
.Vb 9
|
||||
\& \- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
\& RAM and swap space to hold all of the decompressed program during
|
||||
\& the lifetime of the process. If you already use most of your swap
|
||||
\& space, then you may run out. A system that is "out of memory"
|
||||
\& can become fragile. Many programs do not react gracefully when
|
||||
\& malloc() returns 0. With newer Linux kernels, the kernel
|
||||
\& may decide to kill some processes to regain memory, and you
|
||||
\& may not like the kernel\*(Aqs choice of which to kill. Running
|
||||
\& /usr/bin/top is one way to check on the usage of swap space.
|
||||
.Ve
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& (none)
|
||||
.Ve
|
||||
.SS "NOTES FOR LINUX/SH386"
|
||||
.IX Subsection "NOTES FOR LINUX/SH386"
|
||||
Please read the general Linux description first.
|
||||
.PP
|
||||
Shell scripts where the underling shell accepts a ``\-c'' argument
|
||||
can use the Linux/sh386 format. \fBUPX\fR decompresses the shell script
|
||||
into low memory, then maps the shell and passes the entire text of the
|
||||
script as an argument with a leading ``\-c''.
|
||||
It does not use space in /tmp, and does not use /proc.
|
||||
.PP
|
||||
Linux/sh386 is automatically selected for shell scripts that
|
||||
use a known shell.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
.PP
|
||||
How it works:
|
||||
.PP
|
||||
.Vb 8
|
||||
\& For shell script executables (files beginning with "#!/" or "#! /")
|
||||
\& where the shell is known to accept "\-c <command>", UPX decompresses
|
||||
\& the file into low memory, then maps the shell (and its PT_INTERP),
|
||||
\& and passes control to the shell with the entire decompressed file
|
||||
\& as the argument after "\-c". Known shells are sh, ash, bash, bsh, csh,
|
||||
\& ksh, tcsh, pdksh. Restriction: UPX cannot use this method
|
||||
\& for shell scripts which use the one optional string argument after
|
||||
\& the shell name in the script (example: "#! /bin/sh option3\en".)
|
||||
\&
|
||||
\& The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
\& and only uses kernel syscalls. It is not linked against any libc.
|
||||
.Ve
|
||||
.PP
|
||||
Specific drawbacks:
|
||||
.PP
|
||||
.Vb 9
|
||||
\& \- For linux/elf386 and linux/sh386 formats, you will be relying on
|
||||
\& RAM and swap space to hold all of the decompressed program during
|
||||
\& the lifetime of the process. If you already use most of your swap
|
||||
\& space, then you may run out. A system that is "out of memory"
|
||||
\& can become fragile. Many programs do not react gracefully when
|
||||
\& malloc() returns 0. With newer Linux kernels, the kernel
|
||||
\& may decide to kill some processes to regain memory, and you
|
||||
\& may not like the kernel\*(Aqs choice of which to kill. Running
|
||||
\& /usr/bin/top is one way to check on the usage of swap space.
|
||||
.Ve
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& (none)
|
||||
.Ve
|
||||
.SS "NOTES FOR LINUX/386"
|
||||
.IX Subsection "NOTES FOR LINUX/386"
|
||||
Please read the general Linux description first.
|
||||
.PP
|
||||
The generic linux/386 format decompresses to /tmp and needs
|
||||
/proc file system support. It starts the decompressed program
|
||||
via the \fBexecve()\fR syscall.
|
||||
.PP
|
||||
Linux/386 is only selected if the specialized linux/elf386
|
||||
and linux/sh386 won't recognize a file.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
.PP
|
||||
How it works:
|
||||
.PP
|
||||
.Vb 7
|
||||
\& For files which are not ELF and not a script for a known "\-c" shell,
|
||||
\& UPX uses kernel execve(), which first requires decompressing to a
|
||||
\& temporary file in the file system. Interestingly \-
|
||||
\& because of the good memory management of the Linux kernel \- this
|
||||
\& often does not introduce a noticeable delay, and in fact there
|
||||
\& will be no disk access at all if you have enough free memory as
|
||||
\& the entire process takes places within the file system buffers.
|
||||
\&
|
||||
\& A compressed executable consists of the UPX stub and an overlay
|
||||
\& which contains the original program in a compressed form.
|
||||
\&
|
||||
\& The UPX stub is a statically linked ELF executable and does
|
||||
\& the following at program startup:
|
||||
\&
|
||||
\& 1) decompress the overlay to a temporary location in /tmp
|
||||
\& 2) open the temporary file for reading
|
||||
\& 3) try to delete the temporary file and start (execve)
|
||||
\& the uncompressed program in /tmp using /proc/<pid>/fd/X as
|
||||
\& attained by step 2)
|
||||
\& 4) if that fails, fork off a subprocess to clean up and
|
||||
\& start the program in /tmp in the meantime
|
||||
\&
|
||||
\& The UPX stub is about 1700 bytes long, partly written in assembler
|
||||
\& and only uses kernel syscalls. It is not linked against any libc.
|
||||
.Ve
|
||||
.PP
|
||||
Specific drawbacks:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \- You need additional free disk space for the uncompressed program
|
||||
\& in your /tmp directory. This program is deleted immediately after
|
||||
\& decompression, but you still need it for the full execution time
|
||||
\& of the program.
|
||||
\&
|
||||
\& \- You must have /proc file system support as the stub wants to open
|
||||
\& /proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||
\& cannot compress programs that are used during the boot sequence
|
||||
\& before /proc is mounted.
|
||||
\&
|
||||
\& \- Utilities like \`top\*(Aq will display numerical values in the process
|
||||
\& name field. This is because Linux computes the process name from
|
||||
\& the first argument of the last execve syscall (which is typically
|
||||
\& something like /proc/<pid>/fd/3).
|
||||
\&
|
||||
\& \- Because of temporary decompression to disk the decompression speed
|
||||
\& is not as fast as with the other executable formats. Still, I can see
|
||||
\& no noticeable delay when starting programs like my ~3 MiB emacs (which
|
||||
\& is less than 1 MiB when compressed :\-).
|
||||
.Ve
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 3
|
||||
\& \-\-force\-execve Force the use of the generic linux/386 "execve"
|
||||
\& format, i.e. do not try the linux/elf386 and
|
||||
\& linux/sh386 formats.
|
||||
.Ve
|
||||
.SS "NOTES FOR PS1/EXE"
|
||||
.IX Subsection "NOTES FOR PS1/EXE"
|
||||
This is the executable format used by the Sony PlayStation (PSone),
|
||||
a MIPS R3000 based gaming console which is popular since the late '90s.
|
||||
Support of this format is very similar to the Atari one, because of
|
||||
nostalgic feelings of one of the authors.
|
||||
.PP
|
||||
Packed programs will be byte-identical to the original after uncompression,
|
||||
until further notice.
|
||||
.PP
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 MiB.
|
||||
.PP
|
||||
Notes:
|
||||
.PP
|
||||
.Vb 6
|
||||
\& \- UPX creates as default a suitable executable for CD\-Mastering
|
||||
\& and console transfer. For a CD\-Master main executable you could also try
|
||||
\& the special option "\-\-boot\-only" as described below.
|
||||
\& It has been reported that upx packed executables are fully compatible with
|
||||
\& the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
|
||||
\& Sony PlayStation (PSone) emulation mode.
|
||||
\&
|
||||
\& \- Normally the packed files use the same memory areas like the uncompressed
|
||||
\& versions, so they will not override other memory areas while unpacking.
|
||||
\& If this isn\*(Aqt possible UPX will abort showing a \*(Aqpacked data overlap\*(Aq
|
||||
\& error. With the "\-\-force" option UPX will relocate the loading address
|
||||
\& for the packed file, but this isn\*(Aqt a real problem if it is a single or
|
||||
\& the main executable.
|
||||
.Ve
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-8\-bit Uses 8 bit size compression [default: 32 bit]
|
||||
\&
|
||||
\& \-\-8mib\-ram PSone has 8 MiB ram available [default: 2 MiB]
|
||||
\&
|
||||
\& \-\-boot\-only This format is for main exes and CD\-Mastering only !
|
||||
\& It may slightly improve the compression ratio,
|
||||
\& decompression routines are faster than default ones.
|
||||
\& But it cannot be used for console transfer !
|
||||
\&
|
||||
\& \-\-no\-align This option disables CD mode 2 data sector format
|
||||
\& alignment. May slightly improves the compression ratio,
|
||||
\& but the compressed executable will not boot from a CD.
|
||||
\& Use it for console transfer only !
|
||||
.Ve
|
||||
.SS "NOTES FOR RTM32/PE and ARM/PE"
|
||||
.IX Subsection "NOTES FOR RTM32/PE and ARM/PE"
|
||||
Same as win32/pe.
|
||||
.SS "NOTES FOR TMT/ADAM"
|
||||
.IX Subsection "NOTES FOR TMT/ADAM"
|
||||
This format is used by the TMT Pascal compiler \- see http://www.tmt.com/ .
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR VMLINUZ/386"
|
||||
.IX Subsection "NOTES FOR VMLINUZ/386"
|
||||
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed
|
||||
bootable Linux kernel image ("vmlinuz", "zImage", "bzImage"),
|
||||
gzip-decompress it and re-compress it with the \fBUPX\fR compression method.
|
||||
.PP
|
||||
vmlinuz/386 is completely unrelated to the other Linux executable
|
||||
formats, and it does not share any of their drawbacks.
|
||||
.PP
|
||||
Notes:
|
||||
.PP
|
||||
.Vb 3
|
||||
\& \- Be sure that "vmlinuz/386" or "bvmlinuz/386" is displayed
|
||||
\& during compression \- otherwise a wrong executable format
|
||||
\& may have been used, and the kernel won\*(Aqt boot.
|
||||
.Ve
|
||||
.PP
|
||||
Benefits:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \- Better compression (but note that the kernel was already compressed,
|
||||
\& so the improvement is not as large as with other formats).
|
||||
\& Still, the bytes saved may be essential for special needs like
|
||||
\& boot disks.
|
||||
\&
|
||||
\& For example, this is what I get for my 2.2.16 kernel:
|
||||
\& 1589708 vmlinux
|
||||
\& 641073 bzImage [original]
|
||||
\& 560755 bzImage.upx [compressed by "upx \-9"]
|
||||
\&
|
||||
\& \- Much faster decompression at kernel boot time (but kernel
|
||||
\& decompression speed is not really an issue these days).
|
||||
.Ve
|
||||
.PP
|
||||
Drawbacks:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& (none)
|
||||
.Ve
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 4
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SS "NOTES FOR WATCOM/LE"
|
||||
.IX Subsection "NOTES FOR WATCOM/LE"
|
||||
\&\fBUPX\fR has been successfully tested with the following extenders:
|
||||
DOS4G, DOS4GW, PMODE/W, DOS32a, CauseWay.
|
||||
The WDOS/X extender is partly supported (for details
|
||||
see the file bugs BUGS).
|
||||
.PP
|
||||
DLLs and the LX format are not supported.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& \-\-le Produce an unbound LE output instead of
|
||||
\& keeping the current stub.
|
||||
.Ve
|
||||
.SS "NOTES FOR WIN32/PE"
|
||||
.IX Subsection "NOTES FOR WIN32/PE"
|
||||
The PE support in \fBUPX\fR is quite stable now, but probably there are
|
||||
still some incompatibilities with some files.
|
||||
.PP
|
||||
Because of the way \fBUPX\fR (and other packers for this format) works, you
|
||||
can see increased memory usage of your compressed files because the whole
|
||||
program is loaded into memory at startup.
|
||||
If you start several instances of huge compressed programs you're
|
||||
wasting memory because the common segments of the program won't
|
||||
get shared across the instances.
|
||||
On the other hand if you're compressing only smaller programs, or
|
||||
running only one instance of larger programs, then this penalty is
|
||||
smaller, but it's still there.
|
||||
.PP
|
||||
If you're running executables from network, then compressed programs
|
||||
will load faster, and require less bandwidth during execution.
|
||||
.PP
|
||||
DLLs are supported. But UPX compressed DLLs can not share common data and
|
||||
code when they got used by multiple applications. So compressing msvcrt.dll
|
||||
is a waste of memory, but compressing the dll plugins of a particular
|
||||
application may be a better idea.
|
||||
.PP
|
||||
Screensavers are supported, with the restriction that the filename
|
||||
must end with ".scr" (as screensavers are handled slightly different
|
||||
than normal exe files).
|
||||
.PP
|
||||
UPX compressed PE files have some minor memory overhead (usually in the
|
||||
10 \- 30 KiB range) which can be seen by specifying the "\-i" command
|
||||
line switch during compression.
|
||||
.PP
|
||||
Extra options available for this executable format:
|
||||
.PP
|
||||
.Vb 9
|
||||
\& \-\-compress\-exports=0 Don\*(Aqt compress the export section.
|
||||
\& Use this if you plan to run the compressed
|
||||
\& program under Wine.
|
||||
\& \-\-compress\-exports=1 Compress the export section. [DEFAULT]
|
||||
\& Compression of the export section can improve the
|
||||
\& compression ratio quite a bit but may not work
|
||||
\& with all programs (like winword.exe).
|
||||
\& UPX never compresses the export section of a DLL
|
||||
\& regardless of this option.
|
||||
\&
|
||||
\& \-\-compress\-icons=0 Don\*(Aqt compress any icons.
|
||||
\& \-\-compress\-icons=1 Compress all but the first icon.
|
||||
\& \-\-compress\-icons=2 Compress all icons which are not in the
|
||||
\& first icon directory. [DEFAULT]
|
||||
\& \-\-compress\-icons=3 Compress all icons.
|
||||
\&
|
||||
\& \-\-compress\-resources=0 Don\*(Aqt compress any resources at all.
|
||||
\&
|
||||
\& \-\-keep\-resource=list Don\*(Aqt compress resources specified by the list.
|
||||
\& The members of the list are separated by commas.
|
||||
\& A list member has the following format: I<type[/name]>.
|
||||
\& I<Type> is the type of the resource. Standard types
|
||||
\& must be specified as decimal numbers, user types can be
|
||||
\& specified by decimal IDs or strings. I<Name> is the
|
||||
\& identifier of the resource. It can be a decimal number
|
||||
\& or a string. For example:
|
||||
\&
|
||||
\& \-\-keep\-resource=2/MYBITMAP,5,6/12345
|
||||
\&
|
||||
\& UPX won\*(Aqt compress the named bitmap resource "MYBITMAP",
|
||||
\& it leaves every dialog (5) resource uncompressed, and
|
||||
\& it won\*(Aqt touch the string table resource with identifier
|
||||
\& 12345.
|
||||
\&
|
||||
\& \-\-force Force compression even when there is an
|
||||
\& unexpected value in a header field.
|
||||
\& Use with care.
|
||||
\&
|
||||
\& \-\-strip\-relocs=0 Don\*(Aqt strip relocation records.
|
||||
\& \-\-strip\-relocs=1 Strip relocation records. [DEFAULT]
|
||||
\& This option only works on executables with base
|
||||
\& address greater or equal to 0x400000. Usually the
|
||||
\& compressed files becomes smaller, but some files
|
||||
\& may become larger. Note that the resulting file will
|
||||
\& not work under Windows 3.x (Win32s).
|
||||
\& UPX never strips relocations from a DLL
|
||||
\& regardless of this option.
|
||||
\&
|
||||
\& \-\-all\-methods Compress the program several times, using all
|
||||
\& available compression methods. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default method gives the best results anyway.
|
||||
\&
|
||||
\& \-\-all\-filters Compress the program several times, using all
|
||||
\& available preprocessing filters. This may improve
|
||||
\& the compression ratio in some cases, but usually
|
||||
\& the default filter gives the best results anyway.
|
||||
.Ve
|
||||
.SH DIAGNOSTICS
|
||||
.IX Header "DIAGNOSTICS"
|
||||
Exit status is normally 0; if an error occurs, exit status
|
||||
is 1. If a warning occurs, exit status is 2.
|
||||
.PP
|
||||
\&\fBUPX\fR's diagnostics are intended to be self-explanatory.
|
||||
.SH BUGS
|
||||
.IX Header "BUGS"
|
||||
Please report all bugs immediately to the authors.
|
||||
.SH AUTHORS
|
||||
.IX Header "AUTHORS"
|
||||
.Vb 2
|
||||
\& Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
\& http://www.oberhumer.com
|
||||
\&
|
||||
\& Laszlo Molnar <ezerotven+github@gmail.com>
|
||||
\&
|
||||
\& John F. Reiser <jreiser@BitWagon.com>
|
||||
.Ve
|
||||
.SH COPYRIGHT
|
||||
.IX Header "COPYRIGHT"
|
||||
Copyright (C) 1996\-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
.PP
|
||||
Copyright (C) 1996\-2025 Laszlo Molnar
|
||||
.PP
|
||||
Copyright (C) 2000\-2025 John F. Reiser
|
||||
.PP
|
||||
\&\fBUPX\fR is distributed with full source code under the terms of the
|
||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||
the file COPYING), or (at your option) under the GPLv+2 with special
|
||||
exceptions and restrictions granting the free usage for all binaries
|
||||
including commercial programs (see the file LICENSE).
|
||||
.PP
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.PP
|
||||
You should have received a copy of the UPX License Agreements along
|
||||
with this program; see the files COPYING and LICENSE. If not,
|
||||
visit the UPX home page.
|
||||
+68
-71
@@ -13,8 +13,8 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
||||
=head1 ABSTRACT
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2025 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
https://upx.github.io
|
||||
|
||||
|
||||
B<UPX> is a portable, extendable, high-performance executable packer for
|
||||
@@ -23,74 +23,59 @@ ratio and offers I<*very*> fast decompression. Your executables suffer
|
||||
no memory overhead or other drawbacks for most of the formats supported,
|
||||
because of in-place decompression.
|
||||
|
||||
While you may use B<UPX> freely for both non-commercial and commercial
|
||||
executables (for details see the file LICENSE), we would highly
|
||||
appreciate if you credit B<UPX> and ourselves in the documentation,
|
||||
possibly including a reference to the B<UPX> home page. Thanks.
|
||||
|
||||
[ Using B<UPX> in non-OpenSource applications without proper credits
|
||||
is considered not politically correct ;-) ]
|
||||
|
||||
|
||||
|
||||
=head1 DISCLAIMER
|
||||
|
||||
B<UPX> comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
||||
|
||||
This is the first production quality release, and we plan that future 1.xx
|
||||
releases will be backward compatible with this version.
|
||||
B<UPX> comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
|
||||
|
||||
Please report all problems or suggestions to the authors. Thanks.
|
||||
|
||||
|
||||
|
||||
=head1 SECURITY CONTEXT
|
||||
|
||||
IMPORTANT NOTE: B<UPX> inherits the security context of any files it handles.
|
||||
|
||||
This means that packing, unpacking, or even testing or listing a file requires
|
||||
the same security considerations as actually executing the file.
|
||||
|
||||
Use B<UPX> on trusted files only!
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<UPX> is a versatile executable packer with the following features:
|
||||
|
||||
- excellent compression ratio: compresses better than zip/gzip,
|
||||
- secure: as UPX is documented Open Source since many years any relevant
|
||||
Security/Antivirus software is able to peek inside UPX compressed
|
||||
apps to verify them
|
||||
|
||||
- excellent compression ratio: typically compresses better than Zip,
|
||||
use UPX to decrease the size of your distribution !
|
||||
|
||||
- very fast decompression: about 10 MB/sec on an ancient Pentium 133,
|
||||
about 200 MB/sec on an Athlon XP 2000+.
|
||||
- very fast decompression: more than 500 MB/sec on any reasonably modern
|
||||
machine
|
||||
|
||||
- no memory overhead for your compressed executables for most of the
|
||||
supported formats
|
||||
supported formats because of in-place decompression
|
||||
|
||||
- safe: you can list, test and unpack your executables
|
||||
- safe: you can list, test and unpack your executables.
|
||||
Also, a checksum of both the compressed and uncompressed file is
|
||||
maintained internally.
|
||||
|
||||
- universal: UPX can pack a number of executable formats:
|
||||
* atari/tos
|
||||
* bvmlinuz/386 [bootable Linux kernel]
|
||||
* djgpp2/coff
|
||||
* dos/com
|
||||
* dos/exe
|
||||
* dos/sys
|
||||
* linux/386
|
||||
* linux/elf386
|
||||
* linux/sh386
|
||||
* ps1/exe
|
||||
* rtm32/pe
|
||||
* tmt/adam
|
||||
* vmlinuz/386 [bootable Linux kernel]
|
||||
* vmlinux/386
|
||||
* watcom/le (supporting DOS4G, PMODE/W, DOS32a and CauseWay)
|
||||
* win32/pe (exe and dll)
|
||||
* arm/pe (exe and dll)
|
||||
* linux/elfamd64
|
||||
* linux/elfppc32
|
||||
* mach/elfppc32
|
||||
- universal: UPX can pack a number of executable formats, including
|
||||
Windows programs and DLLs, macOS apps and Linux executables
|
||||
|
||||
- portable: UPX is written in portable endian-neutral C++
|
||||
|
||||
- extendable: because of the class layout it's very easy to support
|
||||
new executable formats or add new compression algorithms
|
||||
|
||||
- free: UPX can be distributed and used freely. And from version 0.99
|
||||
the full source code of UPX is released under the GNU General Public
|
||||
License (GPL) !
|
||||
- free: UPX is distributed with full source code under the GNU General
|
||||
Public License v2+, with special exceptions granting the free usage
|
||||
for commercial programs
|
||||
|
||||
You probably understand now why we call B<UPX> the "I<ultimate>"
|
||||
executable packer.
|
||||
@@ -145,7 +130,11 @@ compress and then decompress your program a first time - any further
|
||||
compress-decompress steps should then yield byte-identical results
|
||||
as compared to the first decompressed version.]
|
||||
|
||||
[ ...to be written... - type `B<upx --help>' for now ]
|
||||
B<-k>: keep backup files
|
||||
|
||||
B<-o file>: write output to file
|
||||
|
||||
[ ...more docs need to be written... - type `B<upx --help>' for now ]
|
||||
|
||||
|
||||
|
||||
@@ -153,7 +142,7 @@ as compared to the first decompressed version.]
|
||||
|
||||
B<UPX> offers ten different compression levels from B<-1> to B<-9>,
|
||||
and B<--best>. The default compression level is B<-8> for files
|
||||
smaller than 512 kB, and B<-7> otherwise.
|
||||
smaller than 512 KiB, and B<-7> otherwise.
|
||||
|
||||
=over 4
|
||||
|
||||
@@ -185,7 +174,17 @@ Quick info for achieving the best compression ratio:
|
||||
|
||||
=item *
|
||||
|
||||
Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
|
||||
Try B<upx --brute --no-lzma myfile.exe> or even
|
||||
B<upx --ultra-brute --no-lzma myfile.exe>.
|
||||
|
||||
=item *
|
||||
|
||||
The option B<--lzma> enables LZMA compression, which compresses better but
|
||||
is *significantly slower* at decompression. You probably do not want
|
||||
to use it for large files.
|
||||
|
||||
(Note that B<--lzma> is automatically enabled by B<--all-methods> and
|
||||
B<--brute>, use B<--no-lzma> to override.)
|
||||
|
||||
=item *
|
||||
|
||||
@@ -209,7 +208,7 @@ it would be better to use resource sections).
|
||||
B<UPX> handles overlays like many other executable packers do: it simply
|
||||
copies the overlay after the compressed image. This works with some
|
||||
files, but doesn't work with others, depending on how an application
|
||||
actually accesses this overlayed data.
|
||||
actually accesses this overlaid data.
|
||||
|
||||
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||
|
||||
@@ -221,7 +220,7 @@ actually accesses this overlayed data.
|
||||
|
||||
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
=head1 ENVIRONMENT VARIABLE
|
||||
|
||||
The environment variable B<UPX> can hold a set of default
|
||||
options for B<UPX>. These options are interpreted first and
|
||||
@@ -251,7 +250,7 @@ This is the executable format used by the Atari ST/TT, a Motorola 68000
|
||||
based personal computer which was popular in the late '80s. Support
|
||||
of this format is only because of nostalgic feelings of one of
|
||||
the authors and serves no practical purpose :-).
|
||||
See http://www.freemint.de for more info.
|
||||
See https://freemint.github.io for more info.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
All debug information will be stripped, though.
|
||||
@@ -349,7 +348,7 @@ Extra options available for this executable format:
|
||||
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
|
||||
the very bad habit of replacing your stub with its own (outdated) version.
|
||||
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
|
||||
will fix the 4 KByte alignment of the stub.
|
||||
will fix the 4 KiB alignment of the stub.
|
||||
|
||||
B<UPX> includes the full functionality of stubify. This means it will
|
||||
automatically stubify your COFF files. Use the option B<--coff> to
|
||||
@@ -660,8 +659,8 @@ Specific drawbacks:
|
||||
|
||||
- Because of temporary decompression to disk the decompression speed
|
||||
is not as fast as with the other executable formats. Still, I can see
|
||||
no noticeable delay when starting programs like my ~3 MB emacs (which
|
||||
is less than 1 MB when compressed :-).
|
||||
no noticeable delay when starting programs like my ~3 MiB emacs (which
|
||||
is less than 1 MiB when compressed :-).
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
@@ -674,14 +673,14 @@ Extra options available for this executable format:
|
||||
=head2 NOTES FOR PS1/EXE
|
||||
|
||||
This is the executable format used by the Sony PlayStation (PSone),
|
||||
a Mips R3000 based gaming console which is popular since the late '90s.
|
||||
a MIPS R3000 based gaming console which is popular since the late '90s.
|
||||
Support of this format is very similar to the Atari one, because of
|
||||
nostalgic feelings of one of the authors.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression,
|
||||
until further notice.
|
||||
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 MiB.
|
||||
|
||||
Notes:
|
||||
|
||||
@@ -708,7 +707,7 @@ Extra options available for this executable format:
|
||||
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
|
||||
|
||||
--boot-only This format is for main exes and CD-Mastering only !
|
||||
It may slightly improve the compression ratio,
|
||||
@@ -838,7 +837,7 @@ must end with ".scr" (as screensavers are handled slightly different
|
||||
than normal exe files).
|
||||
|
||||
UPX compressed PE files have some minor memory overhead (usually in the
|
||||
10 - 30 kbytes range) which can be seen by specifying the "-i" command
|
||||
10 - 30 KiB range) which can be seen by specifying the "-i" command
|
||||
line switch during compression.
|
||||
|
||||
Extra options available for this executable format:
|
||||
@@ -923,32 +922,30 @@ Please report all bugs immediately to the authors.
|
||||
Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
http://www.oberhumer.com
|
||||
|
||||
Laszlo Molnar <ml1050@users.sourceforge.net>
|
||||
Laszlo Molnar <ezerotven+github@gmail.com>
|
||||
|
||||
John F. Reiser <jreiser@BitWagon.com>
|
||||
|
||||
Jens Medoch <jssg@users.sourceforge.net>
|
||||
|
||||
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
Copyright (C) 2000-2025 John F. Reiser
|
||||
|
||||
Copyright (C) 2002-2007 Jens Medoch
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
B<UPX> is distributed with full source code under the terms of the
|
||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||
the file COPYING), or (at your option) under the GPLv+2 with special
|
||||
exceptions and restrictions granting the free usage for all binaries
|
||||
including commercial programs (see the file LICENSE).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
B<UPX License Agreement> for more details.
|
||||
|
||||
You should have received a copy of the UPX License Agreement along
|
||||
with this program; see the file LICENSE. If not, visit the UPX home page.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
You should have received a copy of the UPX License Agreements along
|
||||
with this program; see the files COPYING and LICENSE. If not,
|
||||
visit the UPX home page.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||
---
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-switch-missing-default-case,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-core.UndefinedBinaryOperatorResult,
|
||||
-clang-analyzer-core.uninitialized.Assign,
|
||||
-clang-analyzer-security.insecureAPI.strcpy,
|
||||
clang-diagnostic-*,
|
||||
performance-*,
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '.*'
|
||||
InheritParentConfig: false
|
||||
...
|
||||
@@ -0,0 +1,24 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||
---
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-bugprone-casting-through-void,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-inc-dec-in-conditions,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-sizeof-expression,
|
||||
-bugprone-suspicious-include,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
clang-diagnostic-*,
|
||||
performance-*,
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '.*'
|
||||
InheritParentConfig: false
|
||||
...
|
||||
@@ -0,0 +1,24 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||
---
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-inc-dec-in-conditions,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-switch-missing-default-case,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-optin.performance.Padding,
|
||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
clang-diagnostic-*,
|
||||
performance-*,
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '.*'
|
||||
InheritParentConfig: false
|
||||
...
|
||||
@@ -0,0 +1,28 @@
|
||||
# vim:set ft=yaml ts=2 sw=2 et:
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||
---
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-casting-through-void,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-misplaced-widening-cast,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-switch-missing-default-case,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-core.UndefinedBinaryOperatorResult,
|
||||
-clang-analyzer-deadcode.DeadStores,
|
||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
clang-diagnostic-*,
|
||||
performance-*,
|
||||
-performance-no-int-to-ptr,
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '.*'
|
||||
InheritParentConfig: false
|
||||
...
|
||||
Executable
+549
@@ -0,0 +1,549 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# ===- run-clang-tidy.py - Parallel clang-tidy runner --------*- python -*--===#
|
||||
#
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
# ===-----------------------------------------------------------------------===#
|
||||
# FIXME: Integrate with clang-tidy-diff.py
|
||||
|
||||
|
||||
"""
|
||||
Parallel clang-tidy runner
|
||||
==========================
|
||||
|
||||
Runs clang-tidy over all files in a compilation database. Requires clang-tidy
|
||||
and clang-apply-replacements in $PATH.
|
||||
|
||||
Example invocations.
|
||||
- Run clang-tidy on all files in the current working directory with a default
|
||||
set of checks and show warnings in the cpp files and all project headers.
|
||||
run-clang-tidy.py $PWD
|
||||
|
||||
- Fix all header guards.
|
||||
run-clang-tidy.py -fix -checks=-*,llvm-header-guard
|
||||
|
||||
- Fix all header guards included from clang-tidy and header guards
|
||||
for clang-tidy headers.
|
||||
run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \
|
||||
-header-filter=extra/clang-tidy
|
||||
|
||||
Compilation database setup:
|
||||
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import queue
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
yaml = None
|
||||
|
||||
|
||||
def strtobool(val):
|
||||
"""Convert a string representation of truth to a bool following LLVM's CLI argument parsing."""
|
||||
|
||||
val = val.lower()
|
||||
if val in ["", "true", "1"]:
|
||||
return True
|
||||
elif val in ["false", "0"]:
|
||||
return False
|
||||
|
||||
# Return ArgumentTypeError so that argparse does not substitute its own error message
|
||||
raise argparse.ArgumentTypeError(
|
||||
"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
|
||||
)
|
||||
|
||||
|
||||
def find_compilation_database(path):
|
||||
"""Adjusts the directory until a compilation database is found."""
|
||||
result = os.path.realpath("./")
|
||||
while not os.path.isfile(os.path.join(result, path)):
|
||||
parent = os.path.dirname(result)
|
||||
if result == parent:
|
||||
print("Error: could not find compilation database.")
|
||||
sys.exit(1)
|
||||
result = parent
|
||||
return result
|
||||
|
||||
|
||||
def make_absolute(f, directory):
|
||||
if os.path.isabs(f):
|
||||
return f
|
||||
return os.path.normpath(os.path.join(directory, f))
|
||||
|
||||
|
||||
def get_tidy_invocation(
|
||||
f,
|
||||
clang_tidy_binary,
|
||||
checks,
|
||||
tmpdir,
|
||||
build_path,
|
||||
header_filter,
|
||||
allow_enabling_alpha_checkers,
|
||||
extra_arg,
|
||||
extra_arg_before,
|
||||
quiet,
|
||||
config_file_path,
|
||||
config,
|
||||
line_filter,
|
||||
use_color,
|
||||
plugins,
|
||||
warnings_as_errors,
|
||||
):
|
||||
"""Gets a command line for clang-tidy."""
|
||||
start = [clang_tidy_binary]
|
||||
if allow_enabling_alpha_checkers:
|
||||
start.append("-allow-enabling-analyzer-alpha-checkers")
|
||||
if header_filter is not None:
|
||||
start.append("-header-filter=" + header_filter)
|
||||
if line_filter is not None:
|
||||
start.append("-line-filter=" + line_filter)
|
||||
if use_color is not None:
|
||||
if use_color:
|
||||
start.append("--use-color")
|
||||
else:
|
||||
start.append("--use-color=false")
|
||||
if checks:
|
||||
start.append("-checks=" + checks)
|
||||
if tmpdir is not None:
|
||||
start.append("-export-fixes")
|
||||
# Get a temporary file. We immediately close the handle so clang-tidy can
|
||||
# overwrite it.
|
||||
(handle, name) = tempfile.mkstemp(suffix=".yaml", dir=tmpdir)
|
||||
os.close(handle)
|
||||
start.append(name)
|
||||
for arg in extra_arg:
|
||||
start.append("-extra-arg=%s" % arg)
|
||||
for arg in extra_arg_before:
|
||||
start.append("-extra-arg-before=%s" % arg)
|
||||
start.append("-p=" + build_path)
|
||||
if quiet:
|
||||
start.append("-quiet")
|
||||
if config_file_path:
|
||||
start.append("--config-file=" + config_file_path)
|
||||
elif config:
|
||||
start.append("-config=" + config)
|
||||
for plugin in plugins:
|
||||
start.append("-load=" + plugin)
|
||||
if warnings_as_errors:
|
||||
start.append("--warnings-as-errors=" + warnings_as_errors)
|
||||
start.append(f)
|
||||
return start
|
||||
|
||||
|
||||
def merge_replacement_files(tmpdir, mergefile):
|
||||
"""Merge all replacement files in a directory into a single file"""
|
||||
# The fixes suggested by clang-tidy >= 4.0.0 are given under
|
||||
# the top level key 'Diagnostics' in the output yaml files
|
||||
mergekey = "Diagnostics"
|
||||
merged = []
|
||||
for replacefile in glob.iglob(os.path.join(tmpdir, "*.yaml")):
|
||||
content = yaml.safe_load(open(replacefile, "r"))
|
||||
if not content:
|
||||
continue # Skip empty files.
|
||||
merged.extend(content.get(mergekey, []))
|
||||
|
||||
if merged:
|
||||
# MainSourceFile: The key is required by the definition inside
|
||||
# include/clang/Tooling/ReplacementsYaml.h, but the value
|
||||
# is actually never used inside clang-apply-replacements,
|
||||
# so we set it to '' here.
|
||||
output = {"MainSourceFile": "", mergekey: merged}
|
||||
with open(mergefile, "w") as out:
|
||||
yaml.safe_dump(output, out)
|
||||
else:
|
||||
# Empty the file:
|
||||
open(mergefile, "w").close()
|
||||
|
||||
|
||||
def find_binary(arg, name, build_path):
|
||||
"""Get the path for a binary or exit"""
|
||||
if arg:
|
||||
if shutil.which(arg):
|
||||
return arg
|
||||
else:
|
||||
raise SystemExit(
|
||||
"error: passed binary '{}' was not found or is not executable".format(
|
||||
arg
|
||||
)
|
||||
)
|
||||
|
||||
built_path = os.path.join(build_path, "bin", name)
|
||||
binary = shutil.which(name) or shutil.which(built_path)
|
||||
if binary:
|
||||
return binary
|
||||
else:
|
||||
raise SystemExit(
|
||||
"error: failed to find {} in $PATH or at {}".format(name, built_path)
|
||||
)
|
||||
|
||||
|
||||
def apply_fixes(args, clang_apply_replacements_binary, tmpdir):
|
||||
"""Calls clang-apply-fixes on a given directory."""
|
||||
invocation = [clang_apply_replacements_binary]
|
||||
invocation.append("-ignore-insert-conflict")
|
||||
if args.format:
|
||||
invocation.append("-format")
|
||||
if args.style:
|
||||
invocation.append("-style=" + args.style)
|
||||
invocation.append(tmpdir)
|
||||
subprocess.call(invocation)
|
||||
|
||||
|
||||
def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files):
|
||||
"""Takes filenames out of queue and runs clang-tidy on them."""
|
||||
while True:
|
||||
name = queue.get()
|
||||
invocation = get_tidy_invocation(
|
||||
name,
|
||||
clang_tidy_binary,
|
||||
args.checks,
|
||||
tmpdir,
|
||||
build_path,
|
||||
args.header_filter,
|
||||
args.allow_enabling_alpha_checkers,
|
||||
args.extra_arg,
|
||||
args.extra_arg_before,
|
||||
args.quiet,
|
||||
args.config_file,
|
||||
args.config,
|
||||
args.line_filter,
|
||||
args.use_color,
|
||||
args.plugins,
|
||||
args.warnings_as_errors,
|
||||
)
|
||||
|
||||
proc = subprocess.Popen(
|
||||
invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
output, err = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
if proc.returncode < 0:
|
||||
msg = "%s: terminated by signal %d\n" % (name, -proc.returncode)
|
||||
err += msg.encode("utf-8")
|
||||
failed_files.append(name)
|
||||
with lock:
|
||||
sys.stdout.write(" ".join(invocation) + "\n" + output.decode("utf-8"))
|
||||
if len(err) > 0:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.write(err.decode("utf-8"))
|
||||
queue.task_done()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Runs clang-tidy over all files "
|
||||
"in a compilation database. Requires "
|
||||
"clang-tidy and clang-apply-replacements in "
|
||||
"$PATH or in your build directory."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-allow-enabling-alpha-checkers",
|
||||
action="store_true",
|
||||
help="allow alpha checkers from clang-analyzer.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-clang-apply-replacements-binary",
|
||||
metavar="PATH",
|
||||
help="path to clang-apply-replacements binary",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-checks",
|
||||
default=None,
|
||||
help="checks filter, when not specified, use clang-tidy default",
|
||||
)
|
||||
config_group = parser.add_mutually_exclusive_group()
|
||||
config_group.add_argument(
|
||||
"-config",
|
||||
default=None,
|
||||
help="Specifies a configuration in YAML/JSON format: "
|
||||
" -config=\"{Checks: '*', "
|
||||
' CheckOptions: {x: y}}" '
|
||||
"When the value is empty, clang-tidy will "
|
||||
"attempt to find a file named .clang-tidy for "
|
||||
"each source file in its parent directories.",
|
||||
)
|
||||
config_group.add_argument(
|
||||
"-config-file",
|
||||
default=None,
|
||||
help="Specify the path of .clang-tidy or custom config "
|
||||
"file: e.g. -config-file=/some/path/myTidyConfigFile. "
|
||||
"This option internally works exactly the same way as "
|
||||
"-config option after reading specified config file. "
|
||||
"Use either -config-file or -config, not both.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-header-filter",
|
||||
default=None,
|
||||
help="regular expression matching the names of the "
|
||||
"headers to output diagnostics from. Diagnostics from "
|
||||
"the main file of each translation unit are always "
|
||||
"displayed.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-line-filter",
|
||||
default=None,
|
||||
help="List of files with line ranges to filter the warnings.",
|
||||
)
|
||||
if yaml:
|
||||
parser.add_argument(
|
||||
"-export-fixes",
|
||||
metavar="file_or_directory",
|
||||
dest="export_fixes",
|
||||
help="A directory or a yaml file to store suggested fixes in, "
|
||||
"which can be applied with clang-apply-replacements. If the "
|
||||
"parameter is a directory, the fixes of each compilation unit are "
|
||||
"stored in individual yaml files in the directory.",
|
||||
)
|
||||
else:
|
||||
parser.add_argument(
|
||||
"-export-fixes",
|
||||
metavar="directory",
|
||||
dest="export_fixes",
|
||||
help="A directory to store suggested fixes in, which can be applied "
|
||||
"with clang-apply-replacements. The fixes of each compilation unit are "
|
||||
"stored in individual yaml files in the directory.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-j",
|
||||
type=int,
|
||||
default=0,
|
||||
help="number of tidy instances to be run in parallel.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"files", nargs="*", default=[".*"], help="files to be processed (regex on path)"
|
||||
)
|
||||
parser.add_argument("-fix", action="store_true", help="apply fix-its")
|
||||
parser.add_argument(
|
||||
"-format", action="store_true", help="Reformat code after applying fixes"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-style",
|
||||
default="file",
|
||||
help="The style of reformat code after applying fixes",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-use-color",
|
||||
type=strtobool,
|
||||
nargs="?",
|
||||
const=True,
|
||||
help="Use colors in diagnostics, overriding clang-tidy's"
|
||||
" default behavior. This option overrides the 'UseColor"
|
||||
"' option in .clang-tidy file, if any.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", dest="build_path", help="Path used to read a compile command database."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-extra-arg",
|
||||
dest="extra_arg",
|
||||
action="append",
|
||||
default=[],
|
||||
help="Additional argument to append to the compiler command line.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-extra-arg-before",
|
||||
dest="extra_arg_before",
|
||||
action="append",
|
||||
default=[],
|
||||
help="Additional argument to prepend to the compiler command line.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-quiet", action="store_true", help="Run clang-tidy in quiet mode"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-load",
|
||||
dest="plugins",
|
||||
action="append",
|
||||
default=[],
|
||||
help="Load the specified plugin in clang-tidy.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-warnings-as-errors",
|
||||
default=None,
|
||||
help="Upgrades warnings to errors. Same format as '-checks'",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
db_path = "compile_commands.json"
|
||||
|
||||
if args.build_path is not None:
|
||||
build_path = args.build_path
|
||||
else:
|
||||
# Find our database
|
||||
build_path = find_compilation_database(db_path)
|
||||
|
||||
clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path)
|
||||
|
||||
if args.fix:
|
||||
clang_apply_replacements_binary = find_binary(
|
||||
args.clang_apply_replacements_binary, "clang-apply-replacements", build_path
|
||||
)
|
||||
|
||||
combine_fixes = False
|
||||
export_fixes_dir = None
|
||||
delete_fixes_dir = False
|
||||
if args.export_fixes is not None:
|
||||
# if a directory is given, create it if it does not exist
|
||||
if args.export_fixes.endswith(os.path.sep) and not os.path.isdir(
|
||||
args.export_fixes
|
||||
):
|
||||
os.makedirs(args.export_fixes)
|
||||
|
||||
if not os.path.isdir(args.export_fixes):
|
||||
if not yaml:
|
||||
raise RuntimeError(
|
||||
"Cannot combine fixes in one yaml file. Either install PyYAML or specify an output directory."
|
||||
)
|
||||
|
||||
combine_fixes = True
|
||||
|
||||
if os.path.isdir(args.export_fixes):
|
||||
export_fixes_dir = args.export_fixes
|
||||
|
||||
if export_fixes_dir is None and (args.fix or combine_fixes):
|
||||
export_fixes_dir = tempfile.mkdtemp()
|
||||
delete_fixes_dir = True
|
||||
|
||||
# Load the database and extract all files.
|
||||
database = json.load(open(os.path.join(build_path, db_path)))
|
||||
files = set(
|
||||
[make_absolute(entry["file"], entry["directory"]) for entry in database]
|
||||
)
|
||||
|
||||
# Build up a big regexy filter from all command line arguments.
|
||||
file_name_re = re.compile("|".join(args.files))
|
||||
|
||||
# filter files with mo.group(0), and sort files
|
||||
matched_files = []
|
||||
for name in files:
|
||||
mo = file_name_re.search(name)
|
||||
if mo and mo.group(0):
|
||||
matched_files.append(name)
|
||||
files = sorted(matched_files)
|
||||
if not files:
|
||||
if delete_fixes_dir:
|
||||
shutil.rmtree(export_fixes_dir)
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
invocation = get_tidy_invocation(
|
||||
"",
|
||||
clang_tidy_binary,
|
||||
args.checks,
|
||||
None,
|
||||
build_path,
|
||||
args.header_filter,
|
||||
args.allow_enabling_alpha_checkers,
|
||||
args.extra_arg,
|
||||
args.extra_arg_before,
|
||||
args.quiet,
|
||||
args.config_file,
|
||||
args.config,
|
||||
args.line_filter,
|
||||
args.use_color,
|
||||
args.plugins,
|
||||
args.warnings_as_errors,
|
||||
)
|
||||
invocation.append("-list-checks")
|
||||
invocation.append("-")
|
||||
if args.quiet:
|
||||
# Even with -quiet we still want to check if we can call clang-tidy.
|
||||
with open(os.devnull, "w") as dev_null:
|
||||
subprocess.check_call(invocation, stdout=dev_null)
|
||||
else:
|
||||
subprocess.check_call(invocation)
|
||||
except:
|
||||
print("Unable to run clang-tidy.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
max_task = args.j
|
||||
if max_task == 0:
|
||||
max_task = multiprocessing.cpu_count()
|
||||
|
||||
return_code = 0
|
||||
try:
|
||||
# Spin up a bunch of tidy-launching threads.
|
||||
task_queue = queue.Queue(max_task)
|
||||
# List of files with a non-zero return code.
|
||||
failed_files = []
|
||||
lock = threading.Lock()
|
||||
for _ in range(max_task):
|
||||
t = threading.Thread(
|
||||
target=run_tidy,
|
||||
args=(
|
||||
args,
|
||||
clang_tidy_binary,
|
||||
export_fixes_dir,
|
||||
build_path,
|
||||
task_queue,
|
||||
lock,
|
||||
failed_files,
|
||||
),
|
||||
)
|
||||
t.daemon = True
|
||||
t.start()
|
||||
|
||||
# Fill the queue with files.
|
||||
for name in files:
|
||||
if file_name_re.search(name):
|
||||
task_queue.put(name)
|
||||
|
||||
# Wait for all threads to be done.
|
||||
task_queue.join()
|
||||
if len(failed_files):
|
||||
return_code = 1
|
||||
|
||||
except KeyboardInterrupt:
|
||||
# This is a sad hack. Unfortunately subprocess goes
|
||||
# bonkers with ctrl-c and we start forking merrily.
|
||||
print("\nCtrl-C detected, goodbye.")
|
||||
if delete_fixes_dir:
|
||||
shutil.rmtree(export_fixes_dir)
|
||||
os.kill(0, 9)
|
||||
|
||||
if combine_fixes:
|
||||
print("Writing fixes to " + args.export_fixes + " ...")
|
||||
try:
|
||||
merge_replacement_files(export_fixes_dir, args.export_fixes)
|
||||
except:
|
||||
print("Error exporting fixes.\n", file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
return_code = 1
|
||||
|
||||
if args.fix:
|
||||
print("Applying fixes ...")
|
||||
try:
|
||||
apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir)
|
||||
except:
|
||||
print("Error applying fixes.\n", file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
return_code = 1
|
||||
|
||||
if delete_fixes_dir:
|
||||
shutil.rmtree(export_fixes_dir)
|
||||
sys.exit(return_code)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,455 @@
|
||||
#
|
||||
# UPX "CMake" build file; see https://cmake.org/
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
# set USE_STRICT_DEFAULTS
|
||||
if(NOT DEFINED USE_STRICT_DEFAULTS AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/use_strict_defaults.cmake" OPTIONAL)
|
||||
endif()
|
||||
if(NOT DEFINED USE_STRICT_DEFAULTS)
|
||||
# use permissive config defaults when building from source code tarball
|
||||
set(USE_STRICT_DEFAULTS FALSE CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# macros
|
||||
#***********************************************************************
|
||||
|
||||
# support config hooks; developer convenience
|
||||
macro(upx_cmake_include_hook section)
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/hooks/CMakeLists.${section}.txt" OPTIONAL)
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.${section}.txt" OPTIONAL)
|
||||
endmacro()
|
||||
|
||||
# Disallow in-source build. Note that you will still have to manually
|
||||
# clean up a few files if you accidentally try an in-source build.
|
||||
macro(upx_disallow_in_source_build)
|
||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
|
||||
# try to clean up (does not work)
|
||||
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt")
|
||||
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache")
|
||||
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ternary conditional operator
|
||||
macro(upx_ternary result_var_name condition true_value false_value)
|
||||
if(${condition})
|
||||
set(${result_var_name} "${true_value}")
|
||||
else()
|
||||
set(${result_var_name} "${false_value}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# set the default build type; must be called BEFORE project() cmake init
|
||||
macro(upx_set_default_build_type type)
|
||||
set(upx_global_default_build_type "${type}")
|
||||
get_property(upx_global_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT upx_global_is_multi_config AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "${upx_global_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
# also enable some global settings by default
|
||||
if(NOT DEFINED CMAKE_C_STANDARD_REQUIRED)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# set the default multi-config build type; must be called AFTER project() cmake init
|
||||
macro(upx_apply_build_type)
|
||||
if(upx_global_is_multi_config)
|
||||
set(c "${CMAKE_CONFIGURATION_TYPES}")
|
||||
list(INSERT c 0 "${upx_global_default_build_type}")
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES c)
|
||||
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
|
||||
endif()
|
||||
# now also set the build type for use in try_compile()
|
||||
if(NOT CMAKE_TRY_COMPILE_CONFIGURATION)
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
|
||||
else()
|
||||
set(CMAKE_TRY_COMPILE_CONFIGURATION "${upx_global_default_build_type}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# set MINGW, MSVC_FRONTEND, GNU_FRONTEND and MSVC_SIMULATE
|
||||
macro(upx_set_global_vars)
|
||||
if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW")
|
||||
set(MINGW 1)
|
||||
endif()
|
||||
if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC"))
|
||||
set(MSVC_FRONTEND 1)
|
||||
elseif(NOT DEFINED GNU_FRONTEND AND (CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^GNU" OR CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU|LLVM)"))
|
||||
set(GNU_FRONTEND 1)
|
||||
endif()
|
||||
if(NOT DEFINED MSVC_SIMULATE AND (CMAKE_C_SIMULATE_ID MATCHES "^MSVC"))
|
||||
set(MSVC_SIMULATE 1)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# useful for CI jobs: check for working BUILD_RPATH
|
||||
macro(upx_check_working_build_rpath var_name)
|
||||
if(WIN32 OR MINGW OR CYGWIN)
|
||||
# always works; DLLs reside next to the executables
|
||||
set(${var_name} ON)
|
||||
upx_cache_bool_vars(ON ${var_name})
|
||||
elseif(CMAKE_BUILD_WITH_INSTALL_RPATH OR CMAKE_SKIP_RPATH OR CMAKE_SKIP_BUILD_RPATH)
|
||||
# cannot work; BUILD_RPATH is disabled by global CMake settings
|
||||
set(${var_name} OFF)
|
||||
upx_cache_bool_vars(OFF ${var_name})
|
||||
else()
|
||||
# we do not know if/how the BUILD_RPATH is set; be cautious by default
|
||||
upx_cache_bool_vars(OFF ${var_name})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#***********************************************************************
|
||||
# util
|
||||
#***********************************************************************
|
||||
|
||||
# convert to CMake bool
|
||||
function(upx_make_bool_var result_var_name var_name default_value)
|
||||
set(result "${default_value}")
|
||||
# only query $var_name if it is defined and not empty
|
||||
if(NOT ",${var_name}," STREQUAL ",,")
|
||||
if(DEFINED ${var_name})
|
||||
if(NOT ",${${var_name}}," STREQUAL ",,")
|
||||
set(result "${${var_name}}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(${result})
|
||||
set(result ON)
|
||||
else()
|
||||
set(result OFF)
|
||||
endif()
|
||||
set(${result_var_name} "${result}" PARENT_SCOPE) # return value
|
||||
endfunction()
|
||||
|
||||
function(upx_maybe_unused_var) # ARGV
|
||||
foreach(var_name ${ARGV})
|
||||
if(DEFINED ${var_name})
|
||||
set(dummy "${${var_name}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(upx_print_var) # ARGV
|
||||
foreach(var_name ${ARGV})
|
||||
if(DEFINED ${var_name})
|
||||
if(NOT ",${${var_name}}," STREQUAL ",,")
|
||||
if(${var_name})
|
||||
message(STATUS "${var_name} = ${${var_name}}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(upx_print_env_var) # ARGV
|
||||
foreach(var_name ${ARGV})
|
||||
if(DEFINED ENV{${var_name}})
|
||||
if(NOT ",$ENV{${var_name}}," STREQUAL ",,")
|
||||
message(STATUS "ENV{${var_name}} = '$ENV{${var_name}}'")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(upx_print_have_symbol) # ARGV; needs include(CheckSymbolExists)
|
||||
set(rq "${CMAKE_REQUIRED_QUIET}")
|
||||
set(CMAKE_REQUIRED_QUIET ON)
|
||||
foreach(symbol ${ARGV})
|
||||
set(cache_var_name "HAVE_symbol_${symbol}")
|
||||
check_symbol_exists("${symbol}" "limits.h;stddef.h;stdint.h" "${cache_var_name}")
|
||||
if(${cache_var_name})
|
||||
message(STATUS "HAVE_symbol ${symbol}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(CMAKE_REQUIRED_QUIET "${rq}")
|
||||
endfunction()
|
||||
|
||||
# examine compiler configuration
|
||||
function(upx_print_common_symbols)
|
||||
upx_print_have_symbol(__FAST_MATH__)
|
||||
upx_print_have_symbol(__PIC__ __pic__ __PIE__ __pie__)
|
||||
endfunction()
|
||||
|
||||
# examine MinGW/Cygwin compiler configuration
|
||||
function(upx_print_mingw_symbols)
|
||||
if(WIN32 OR MINGW OR CYGWIN)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)")
|
||||
# runtime library: msvcrt vs ucrt vs cygwin
|
||||
upx_print_have_symbol(__CRTDLL__ __CYGWIN__ __CYGWIN32__ __CYGWIN64__ __MINGW32__ __MINGW64__ __MINGW64_VERSION_MAJOR __MSVCRT__ __MSVCRT_VERSION__ _UCRT _WIN32 _WIN32_WINNT _WIN64)
|
||||
# exception handing: SJLJ (setjmp/longjmp) vs DWARF vs SEH
|
||||
upx_print_have_symbol(__GCC_HAVE_DWARF2_CFI_ASM __SEH__ __USING_SJLJ_EXCEPTIONS__)
|
||||
# threads: win32 vs posix/pthread/winpthreads vs mcfgthread
|
||||
upx_print_have_symbol(_REENTRANT __USING_MCFGTHREAD__)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# add wildcard expansions to a variable
|
||||
function(upx_add_glob_files) # ARGV
|
||||
set(var_name ${ARGV0})
|
||||
list(REMOVE_AT ARGV 0)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.3")
|
||||
file(GLOB files ${ARGV})
|
||||
else()
|
||||
file(GLOB files LIST_DIRECTORIES false ${ARGV})
|
||||
endif()
|
||||
set(result "")
|
||||
if(DEFINED ${var_name})
|
||||
set(result "${${var_name}}")
|
||||
endif()
|
||||
list(APPEND result "${files}")
|
||||
list(SORT result)
|
||||
list(REMOVE_DUPLICATES result)
|
||||
#message(STATUS "upx_add_glob_files: ${var_name} = ${result}")
|
||||
set(${var_name} "${result}" PARENT_SCOPE) # return value
|
||||
endfunction()
|
||||
|
||||
# remove wildcard expansions from a variable
|
||||
function(upx_remove_glob_files) # ARGV
|
||||
set(var_name ${ARGV0})
|
||||
list(REMOVE_AT ARGV 0)
|
||||
file(GLOB files ${ARGV})
|
||||
set(result "")
|
||||
if(DEFINED ${var_name})
|
||||
set(result "${${var_name}}")
|
||||
foreach(file ${files})
|
||||
list(REMOVE_ITEM result "${file}")
|
||||
endforeach()
|
||||
list(SORT result)
|
||||
list(REMOVE_DUPLICATES result)
|
||||
endif()
|
||||
#message(STATUS "upx_remove_glob_files: ${var_name} = ${result}")
|
||||
set(${var_name} "${result}" PARENT_SCOPE) # return value
|
||||
endfunction()
|
||||
|
||||
# useful for CI jobs: allow settings via environment and cache result
|
||||
function(upx_cache_bool_vars) # ARGV
|
||||
set(default_value "${ARGV0}")
|
||||
list(REMOVE_AT ARGV 0)
|
||||
foreach(var_name ${ARGV})
|
||||
set(value ${default_value})
|
||||
if(DEFINED UPX_CACHE_VALUE_${var_name}) # check cache
|
||||
set(value "${UPX_CACHE_VALUE_${var_name}}")
|
||||
elseif(DEFINED ${var_name}) # defined via "cmake -DXXX=YYY"
|
||||
set(value "${${var_name}}")
|
||||
elseif(DEFINED ENV{${var_name}}) # check environment
|
||||
if("$ENV{${var_name}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE|off|on|false|true)$")
|
||||
set(value "$ENV{${var_name}}")
|
||||
set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for status message below
|
||||
endif()
|
||||
endif()
|
||||
# convert to bool
|
||||
if(value)
|
||||
set(value ON)
|
||||
else()
|
||||
set(value OFF)
|
||||
endif()
|
||||
# store result
|
||||
if(UPX_CACHE_ORIGIN_FROM_ENV_${var_name})
|
||||
message(STATUS "setting from environment: ${var_name} = ${value}")
|
||||
endif()
|
||||
set(${var_name} "${value}" PARENT_SCOPE) # store result
|
||||
set(UPX_CACHE_VALUE_${var_name} "${value}" CACHE INTERNAL "" FORCE) # and store in cache
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(upx_platform_check_mismatch var_name_1 var_name_2)
|
||||
if(DEFINED ${var_name_1} OR DEFINED ${var_name_2})
|
||||
if(NOT ",${${var_name_1}}," STREQUAL ",${${var_name_2}},")
|
||||
if(UPX_CONFIG_DISABLE_WERROR)
|
||||
message(WARNING "WARNING: '${var_name_1}' '${var_name_2}' mismatch")
|
||||
else()
|
||||
message(FATAL_ERROR "FATAL ERROR: '${var_name_1}' '${var_name_2}' mismatch")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# check for incompatible C vs CXX settings
|
||||
function(upx_platform_check_c_cxx_mismatch)
|
||||
upx_platform_check_mismatch(CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID)
|
||||
upx_platform_check_mismatch(CMAKE_C_SIMULATE_ID CMAKE_CXX_SIMULATE_ID)
|
||||
upx_platform_check_mismatch(CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI)
|
||||
upx_platform_check_mismatch(CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
|
||||
endfunction()
|
||||
|
||||
#***********************************************************************
|
||||
# compilation flags
|
||||
#***********************************************************************
|
||||
|
||||
function(upx_internal_add_definitions_with_prefix) # ARGV; needs include(CheckCCompilerFlag)
|
||||
set(flag_prefix "${ARGV0}")
|
||||
if("${flag_prefix}" MATCHES "^empty$") # need "empty" to work around bug in old CMake versions
|
||||
set(flag_prefix "")
|
||||
endif()
|
||||
list(REMOVE_AT ARGV 0)
|
||||
set(failed "")
|
||||
foreach(f ${ARGV})
|
||||
set(flag "${flag_prefix}${f}")
|
||||
string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" cache_var_name "HAVE_CFLAG_${flag}")
|
||||
check_c_compiler_flag("${flag}" ${cache_var_name})
|
||||
if(${cache_var_name})
|
||||
#message(STATUS "add_definitions: ${flag}")
|
||||
add_definitions("${flag}")
|
||||
else()
|
||||
list(APPEND failed "${f}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(failed_flags "${failed}" PARENT_SCOPE) # return value
|
||||
endfunction()
|
||||
|
||||
function(upx_add_definitions) # ARGV; needs include(CheckCCompilerFlag)
|
||||
set(failed_flags "")
|
||||
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# for clang-cl try "-clang:" flag prefix first
|
||||
upx_internal_add_definitions_with_prefix("-clang:" ${ARGV})
|
||||
upx_internal_add_definitions_with_prefix("empty" ${failed_flags})
|
||||
else()
|
||||
upx_internal_add_definitions_with_prefix("empty" ${ARGV})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# useful for CI jobs: allow target extra compile options
|
||||
function(upx_add_target_extra_compile_options) # ARGV
|
||||
set(t "${ARGV0}")
|
||||
list(REMOVE_AT ARGV 0)
|
||||
foreach(var_name ${ARGV})
|
||||
if(NOT DEFINED ${var_name})
|
||||
elseif(",${${var_name}}," STREQUAL ",,")
|
||||
else()
|
||||
set(flags "${${var_name}}")
|
||||
if(NOT flags MATCHES ";") # NOTE: split into list from string only if not already a list
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.8.99")
|
||||
separate_arguments(flags NATIVE_COMMAND "${flags}")
|
||||
else()
|
||||
separate_arguments(flags)
|
||||
endif()
|
||||
endif()
|
||||
target_compile_options(${t} PRIVATE "${flags}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# compile a target with -O2 optimization even in Debug build
|
||||
function(upx_compile_target_debug_with_O2) # ARGV
|
||||
foreach(t ${ARGV})
|
||||
if(MSVC_FRONTEND)
|
||||
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# compile a source file with -O2 optimization even in Debug build; messy because of CMake limitations
|
||||
function(upx_compile_source_debug_with_O2) # ARGV
|
||||
set(flags "$<$<CONFIG:Debug>:-O2>")
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.8")
|
||||
# 3.8: The COMPILE_FLAGS source file property learned to support generator expressions
|
||||
if(upx_global_is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$")
|
||||
return()
|
||||
endif()
|
||||
set(flags "-O2")
|
||||
endif()
|
||||
if(CMAKE_GENERATOR MATCHES "Xcode") # multi-config
|
||||
# NOTE: Xcode does not support per-config per-source COMPILE_FLAGS (as of CMake 3.27.7)
|
||||
return()
|
||||
endif()
|
||||
foreach(source ${ARGV})
|
||||
if(MSVC_FRONTEND)
|
||||
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
|
||||
else()
|
||||
get_source_file_property(prop "${source}" COMPILE_FLAGS)
|
||||
if("${prop}" MATCHES "^(NOTFOUND)?$")
|
||||
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
|
||||
else()
|
||||
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${prop} ${flags}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# sanitize a target; note that this may require special run-time support libs from your toolchain
|
||||
function(upx_sanitize_target) # ARGV
|
||||
if(NOT DEFINED UPX_CONFIG_SANITIZE_FLAGS_DEBUG)
|
||||
# default sanitizer for Debug builds
|
||||
set(UPX_CONFIG_SANITIZE_FLAGS_DEBUG -fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all)
|
||||
endif()
|
||||
if(NOT DEFINED UPX_CONFIG_SANITIZE_FLAGS_RELEASE)
|
||||
# default sanitizer for Release builds
|
||||
set(UPX_CONFIG_SANITIZE_FLAGS_RELEASE -fstack-protector)
|
||||
endif()
|
||||
foreach(t ${ARGV})
|
||||
if(UPX_CONFIG_DISABLE_SANITIZE)
|
||||
# no-op
|
||||
elseif(MSVC_FRONTEND)
|
||||
# MSVC uses -GS (similar to -fstack-protector) by default
|
||||
elseif(NOT GNU_FRONTEND)
|
||||
# unknown compiler
|
||||
elseif(MINGW OR CYGWIN)
|
||||
# avoid link errors with current MinGW-w64 versions
|
||||
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "9.0")
|
||||
# unreliable/broken sanitize implementation before clang-9 (Sep 2019)
|
||||
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "^GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0")
|
||||
# unsupported compiler; unreliable/broken sanitize implementation before gcc-8 (May 2018)
|
||||
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:${UPX_CONFIG_SANITIZE_FLAGS_DEBUG}>)
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
get_target_property(target_type ${t} TYPE)
|
||||
if(NOT ",${target_type}," STREQUAL ",STATIC_LIBRARY,")
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.12.99")
|
||||
target_link_options(${t} PRIVATE $<$<CONFIG:Debug>:${UPX_CONFIG_SANITIZE_FLAGS_DEBUG}>)
|
||||
target_link_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
target_link_options(${t} PRIVATE $<$<CONFIG:Release>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
target_link_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:${UPX_CONFIG_SANITIZE_FLAGS_RELEASE}>)
|
||||
endif() # CMAKE_VERSION
|
||||
endif() # target_type
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
#***********************************************************************
|
||||
# test
|
||||
#***********************************************************************
|
||||
|
||||
function(upx_add_test) # ARGV
|
||||
set(name "${ARGV0}")
|
||||
list(REMOVE_AT ARGV 0)
|
||||
set(wd "${CMAKE_CURRENT_BINARY_DIR}/XTesting/$<CONFIG>")
|
||||
add_test(NAME "${name}" WORKING_DIRECTORY "${wd}" COMMAND ${ARGV})
|
||||
endfunction()
|
||||
|
||||
function(upx_test_depends) # ARGV
|
||||
set(name "${ARGV0}")
|
||||
list(REMOVE_AT ARGV 0)
|
||||
get_property(prop TEST "${name}" PROPERTY DEPENDS)
|
||||
if("${prop}" MATCHES "^(NOTFOUND)?$")
|
||||
set_tests_properties("${name}" PROPERTIES DEPENDS "${ARGV}")
|
||||
else()
|
||||
set_tests_properties("${name}" PROPERTIES DEPENDS "${prop};${ARGV}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# UPX "CMake" build file; see https://cmake.org/
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
#***********************************************************************
|
||||
# summary section
|
||||
# print some info about the build configuration
|
||||
#***********************************************************************
|
||||
|
||||
function(upx_print_info)
|
||||
get_property(PROPERTY_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
get_property(PROPERTY_TARGET_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
|
||||
|
||||
# generator
|
||||
upx_print_var(CMAKE_GENERATOR_TOOLSET CMAKE_GENERATOR_PLATFORM)
|
||||
upx_print_var(PROPERTY_GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
# directories
|
||||
if(NOT ",${CMAKE_BINARY_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR}," OR NOT ",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_SOURCE_DIR},")
|
||||
upx_print_var(CMAKE_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
# system
|
||||
upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION CMAKE_HOST_SYSTEM_PROCESSOR)
|
||||
upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_SYSTEM_PROCESSOR)
|
||||
upx_print_var(CMAKE_ANDROID_NDK CMAKE_ANDROID_NDK_VERSION CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
|
||||
upx_print_var(CMAKE_APPLE_SILICON_PROCESSOR CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT)
|
||||
upx_print_var(CMAKE_VS_PLATFORM_TOOLSET CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE CMAKE_VS_PLATFORM_TOOLSET_VERSION)
|
||||
upx_print_var(CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR)
|
||||
upx_print_var(CMAKE_SIZEOF_VOID_P)
|
||||
|
||||
# binutils
|
||||
upx_print_var(CMAKE_EXECUTABLE_FORMAT CMAKE_EXECUTABLE_SUFFIX UPX_CONFIG_CMAKE_EXECUTABLE_SUFFIX)
|
||||
upx_print_var(CMAKE_AR CMAKE_RANLIB)
|
||||
|
||||
# compilers
|
||||
foreach(lang IN ITEMS ASM C CXX)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_LAUNCHER)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_ARG1)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_ID)
|
||||
upx_print_var(CMAKE_${lang}_SIMULATE_ID)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_VERSION)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT )
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID)
|
||||
upx_print_var(CMAKE_${lang}_PLATFORM_ID)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_ABI)
|
||||
upx_print_var(CMAKE_${lang}_COMPILER_TARGET)
|
||||
endforeach()
|
||||
|
||||
# misc
|
||||
upx_print_var(CMAKE_BUILD_WITH_INSTALL_RPATH CMAKE_SKIP_RPATH CMAKE_SKIP_BUILD_RPATH CMAKE_SKIP_INSTALL_RPATH)
|
||||
upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE)
|
||||
upx_print_var(PROPERTY_TARGET_SUPPORTS_SHARED_LIBS)
|
||||
upx_print_var(UPX_CONFIG_SANITIZE_FLAGS_DEBUG UPX_CONFIG_SANITIZE_FLAGS_RELEASE)
|
||||
|
||||
# shortcuts
|
||||
upx_print_var(AIX APPLE CLANG CYGWIN GNU_FRONTEND GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE MSVC_SIMULATE MSVC_TOOLSET_VERSION MSVC_VERSION MSYS UNIX WIN32 WIN64)
|
||||
endfunction()
|
||||
|
||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||
@@ -0,0 +1,155 @@
|
||||
#
|
||||
# UPX "CMake" build file; see https://cmake.org/
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
#***********************************************************************
|
||||
# test section: self-pack tests
|
||||
#
|
||||
# IMPORTANT NOTE: these tests can only work if the host executable format
|
||||
# is supported by UPX!
|
||||
#***********************************************************************
|
||||
|
||||
set(emu "")
|
||||
if(DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
|
||||
set(emu "${CMAKE_CROSSCOMPILING_EMULATOR}")
|
||||
endif()
|
||||
set(exe "${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
set(upx_self_exe "$<TARGET_FILE:upx>")
|
||||
set(fo "--force-overwrite")
|
||||
|
||||
#
|
||||
# basic tests
|
||||
#
|
||||
|
||||
upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe})
|
||||
upx_add_test(upx-self-pack-fa upx -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe})
|
||||
upx_add_test(upx-self-pack-fn upx -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe})
|
||||
upx_add_test(upx-self-pack-fr upx -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe})
|
||||
upx_add_test(upx-self-pack-nrv2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe})
|
||||
upx_add_test(upx-self-pack-nrv2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe})
|
||||
upx_add_test(upx-self-pack-nrv2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${exe})
|
||||
upx_add_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe})
|
||||
|
||||
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||
|
||||
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
|
||||
upx_add_test(upx-unpack-fa upx -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe})
|
||||
upx_add_test(upx-unpack-fn upx -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe})
|
||||
upx_add_test(upx-unpack-fr upx -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe})
|
||||
upx_add_test(upx-unpack-nrv2b upx -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe})
|
||||
upx_add_test(upx-unpack-nrv2d upx -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe})
|
||||
upx_add_test(upx-unpack-nrv2e upx -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe})
|
||||
upx_add_test(upx-unpack-lzma upx -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe})
|
||||
|
||||
# all unpacked files must be identical
|
||||
upx_add_test(upx-compare-fa "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fa${exe})
|
||||
upx_add_test(upx-compare-fn "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fn${exe})
|
||||
upx_add_test(upx-compare-fr "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fr${exe})
|
||||
upx_add_test(upx-compare-nrv2b "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2b${exe})
|
||||
upx_add_test(upx-compare-nrv2d "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2d${exe})
|
||||
upx_add_test(upx-compare-nrv2e "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2e${exe})
|
||||
upx_add_test(upx-compare-lzma "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-lzma${exe})
|
||||
|
||||
# test dependencies
|
||||
upx_test_depends(upx-list "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||
upx_test_depends(upx-fileinfo "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||
upx_test_depends(upx-test "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||
upx_test_depends(upx-unpack upx-self-pack)
|
||||
upx_test_depends(upx-unpack-fa upx-self-pack-fa)
|
||||
upx_test_depends(upx-unpack-fn upx-self-pack-fn)
|
||||
upx_test_depends(upx-unpack-fr upx-self-pack-fr)
|
||||
upx_test_depends(upx-unpack-nrv2b upx-self-pack-nrv2b)
|
||||
upx_test_depends(upx-unpack-nrv2d upx-self-pack-nrv2d)
|
||||
upx_test_depends(upx-unpack-nrv2e upx-self-pack-nrv2e)
|
||||
upx_test_depends(upx-unpack-lzma upx-self-pack-lzma)
|
||||
upx_test_depends(upx-compare-fa "upx-unpack;upx-unpack-fa")
|
||||
upx_test_depends(upx-compare-fn "upx-unpack;upx-unpack-fn")
|
||||
upx_test_depends(upx-compare-fr "upx-unpack;upx-unpack-fr")
|
||||
upx_test_depends(upx-compare-nrv2b "upx-unpack;upx-unpack-nrv2b")
|
||||
upx_test_depends(upx-compare-nrv2d "upx-unpack;upx-unpack-nrv2d")
|
||||
upx_test_depends(upx-compare-nrv2e "upx-unpack;upx-unpack-nrv2e")
|
||||
upx_test_depends(upx-compare-lzma "upx-unpack;upx-unpack-lzma")
|
||||
# tests with higher COST values will run first
|
||||
set_tests_properties(upx-self-pack PROPERTIES COST 90)
|
||||
set_tests_properties(upx-self-pack-fa PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-fn PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-fr PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-nrv2b PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-nrv2d PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-nrv2e PROPERTIES COST 20)
|
||||
set_tests_properties(upx-self-pack-lzma PROPERTIES COST 30)
|
||||
set_tests_properties(upx-unpack PROPERTIES COST 10)
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST)
|
||||
upx_add_test(upx-run-unpacked ${emu} ./upx-unpacked${exe} --version-short)
|
||||
upx_test_depends(upx-run-unpacked upx-unpack)
|
||||
endif()
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
|
||||
upx_add_test(upx-run-packed ${emu} ./upx-packed${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-fa ${emu} ./upx-packed-fa${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-fn ${emu} ./upx-packed-fn${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-fr ${emu} ./upx-packed-fr${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-nrv2b ${emu} ./upx-packed-nrv2b${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-nrv2d ${emu} ./upx-packed-nrv2d${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-nrv2e ${emu} ./upx-packed-nrv2e${exe} --version-short)
|
||||
upx_add_test(upx-run-packed-lzma ${emu} ./upx-packed-lzma${exe} --version-short)
|
||||
upx_test_depends(upx-run-packed upx-self-pack)
|
||||
upx_test_depends(upx-run-packed-fa upx-self-pack-fa)
|
||||
upx_test_depends(upx-run-packed-fn upx-self-pack-fn)
|
||||
upx_test_depends(upx-run-packed-fr upx-self-pack-fr)
|
||||
upx_test_depends(upx-run-packed-nrv2b upx-self-pack-nrv2b)
|
||||
upx_test_depends(upx-run-packed-nrv2d upx-self-pack-nrv2d)
|
||||
upx_test_depends(upx-run-packed-nrv2e upx-self-pack-nrv2e)
|
||||
upx_test_depends(upx-run-packed-lzma upx-self-pack-lzma)
|
||||
endif()
|
||||
|
||||
#
|
||||
# exhaustive tests
|
||||
#
|
||||
|
||||
if(NOT UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
|
||||
foreach(method IN ITEMS nrv2b nrv2d nrv2e lzma)
|
||||
foreach(level IN ITEMS 1 2 3 4 5 6 7)
|
||||
foreach(small IN ITEMS normal small)
|
||||
set(s "${method}-${level}")
|
||||
set(ss "")
|
||||
if(small MATCHES "small")
|
||||
set(s "${method}-${level}-${small}")
|
||||
set(ss "--small")
|
||||
endif()
|
||||
upx_add_test(upx-self-pack-${s} upx --${method} -${level} ${ss} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe})
|
||||
upx_add_test(upx-list-${s} upx -l upx-packed-${s}${exe})
|
||||
upx_add_test(upx-fileinfo-${s} upx --fileinfo upx-packed-${s}${exe})
|
||||
upx_add_test(upx-test-${s} upx -t upx-packed-${s}${exe})
|
||||
upx_add_test(upx-unpack-${s} upx -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe})
|
||||
upx_add_test(upx-compare-${s} "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-${s}${exe})
|
||||
upx_test_depends(upx-list-${s} upx-self-pack-${s})
|
||||
upx_test_depends(upx-fileinfo-${s} upx-self-pack-${s})
|
||||
upx_test_depends(upx-test-${s} upx-self-pack-${s})
|
||||
upx_test_depends(upx-unpack-${s} upx-self-pack-${s})
|
||||
upx_test_depends(upx-compare-${s} "upx-unpack;upx-unpack-${s}")
|
||||
if(method MATCHES "lzma")
|
||||
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "3${level}")
|
||||
else()
|
||||
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "2${level}")
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
|
||||
upx_add_test(upx-run-packed-${s} ${emu} ./upx-packed-${s}${exe} --version-short)
|
||||
upx_test_depends(upx-run-packed-${s} upx-self-pack-${s})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif() # UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||
|
||||
# clean up
|
||||
set(emu "")
|
||||
set(exe "")
|
||||
set(upx_self_exe "")
|
||||
set(fo "")
|
||||
|
||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
#include <mutex>
|
||||
|
||||
static std::mutex lock_mutex;
|
||||
|
||||
int main() {
|
||||
std::lock_guard<std::mutex> lock(lock_mutex);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// check ABI - require proper alignment of fundamental types for use in atomics
|
||||
static_assert(alignof(char) == sizeof(char), "");
|
||||
static_assert(alignof(signed char) == sizeof(signed char), "");
|
||||
static_assert(alignof(unsigned char) == sizeof(unsigned char), "");
|
||||
static_assert(alignof(short) == sizeof(short), "");
|
||||
static_assert(alignof(unsigned short) == sizeof(unsigned short), "");
|
||||
static_assert(alignof(int) == sizeof(int), "");
|
||||
static_assert(alignof(unsigned int) == sizeof(unsigned int), "");
|
||||
static_assert(alignof(long) == sizeof(long), "");
|
||||
static_assert(alignof(unsigned long) == sizeof(unsigned long), "");
|
||||
static_assert(alignof(ptrdiff_t) == sizeof(ptrdiff_t), "");
|
||||
static_assert(alignof(size_t) == sizeof(size_t), "");
|
||||
static_assert(alignof(intptr_t) == sizeof(intptr_t), "");
|
||||
static_assert(alignof(uintptr_t) == sizeof(uintptr_t), "");
|
||||
static_assert(alignof(void *) == sizeof(void *), "");
|
||||
|
||||
int main() { return 0; }
|
||||
@@ -0,0 +1,381 @@
|
||||
#
|
||||
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
ifeq ($(UPX_MAKEFILE_EXTRA_MK_INCLUDED),)
|
||||
override UPX_MAKEFILE_EXTRA_MK_INCLUDED := 1
|
||||
|
||||
#***********************************************************************
|
||||
# support functions
|
||||
#***********************************************************************
|
||||
|
||||
override check_defined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),$(error ERROR: variable '$1' is not defined),))
|
||||
override check_undefined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),,$(error ERROR: variable '$1' is already defined)))
|
||||
|
||||
# return "1" or empty-string
|
||||
override eq = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),,1)
|
||||
override ne = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),1,)
|
||||
|
||||
override tolower = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
|
||||
override toupper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
|
||||
|
||||
# canonicalize the case of CMAKE_BUILD_TYPE to "Debug" and "Release"
|
||||
override cm_build_type = $(if $(call eq,$1,),$(error EMPTY-build-type),$(if $(call eq,$(call tolower,$1),debug),Debug,$(if $(call eq,$(call tolower,$1),release),Release,$(if $(call eq,$(call tolower,$1),none),None,$1))))
|
||||
|
||||
#***********************************************************************
|
||||
# extra builds: some pre-defined build configurations
|
||||
#***********************************************************************
|
||||
|
||||
$(call check_defined,run_config run_build)
|
||||
$(call check_undefined,run_config_and_build)
|
||||
|
||||
define run_config_and_build
|
||||
$(call run_config,$1,$2)
|
||||
$(call run_build,$1,$2)
|
||||
endef
|
||||
|
||||
# force building with clang/clang++
|
||||
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang/%: export CC = clang
|
||||
build/extra/clang/%: export CXX = clang++
|
||||
|
||||
# force building with clang/clang++ -m32
|
||||
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-m32/%: export CC = clang -m32
|
||||
build/extra/clang-m32/%: export CXX = clang++ -m32
|
||||
|
||||
# force building with clang/clang++ -mx32
|
||||
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-mx32/%: export CC = clang -mx32
|
||||
build/extra/clang-mx32/%: export CXX = clang++ -mx32
|
||||
|
||||
# force building with clang/clang++ -m64
|
||||
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-m64/%: export CC = clang -m64
|
||||
build/extra/clang-m64/%: export CXX = clang++ -m64
|
||||
|
||||
# force building with clang/clang++ -flto=auto
|
||||
build/extra/clang-lto-auto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-lto-auto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-lto-auto/%: export CC = clang -flto=auto
|
||||
build/extra/clang-lto-auto/%: export CXX = clang++ -flto=auto
|
||||
|
||||
# force building with clang/clang++ -pie
|
||||
build/extra/clang-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-pie/%: export CC = clang -pie -fPIE -Wno-unused-command-line-argument
|
||||
build/extra/clang-pie/%: export CXX = clang++ -pie -fPIE -Wno-unused-command-line-argument
|
||||
build/extra/clang-pie/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with clang/clang++ -static
|
||||
build/extra/clang-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-static/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-static/%: export CC = clang -static
|
||||
build/extra/clang-static/%: export CXX = clang++ -static
|
||||
build/extra/clang-static/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with clang/clang++ -static-pie
|
||||
build/extra/clang-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-static-pie/%: export CC = clang -static-pie -fPIE -Wno-unused-command-line-argument
|
||||
build/extra/clang-static-pie/%: export CXX = clang++ -static-pie -fPIE -Wno-unused-command-line-argument
|
||||
build/extra/clang-static-pie/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with clang/clang++ -static -flto
|
||||
build/extra/clang-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-static-lto/%: export CC = clang -static -flto
|
||||
build/extra/clang-static-lto/%: export CXX = clang++ -static -flto
|
||||
build/extra/clang-static-lto/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with clang/clang++ C++20 (and C17)
|
||||
build/extra/clang-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-std-cxx20/%: export CC = clang -std=gnu17
|
||||
build/extra/clang-std-cxx20/%: export CXX = clang++ -std=gnu++20
|
||||
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# force building with clang/clang++ C++23 (and C23)
|
||||
build/extra/clang-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-std-cxx23/%: export CC = clang -std=gnu2x -Wno-constant-logical-operand
|
||||
build/extra/clang-std-cxx23/%: export CXX = clang++ -std=gnu++2b
|
||||
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# force building with clang/clang++ C++26 (and C23)
|
||||
build/extra/clang-std-cxx26/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-std-cxx26/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-std-cxx26/%: export CC = clang -std=gnu2x -Wno-constant-logical-operand
|
||||
build/extra/clang-std-cxx26/%: export CXX = clang++ -std=gnu++2c
|
||||
build/extra/clang-std-cxx26/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/clang-std-cxx26/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# force building with gcc/g++
|
||||
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc/%: export CC = gcc
|
||||
build/extra/gcc/%: export CXX = g++
|
||||
|
||||
# force building with gcc/g++ -m32
|
||||
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-m32/%: export CC = gcc -m32
|
||||
build/extra/gcc-m32/%: export CXX = g++ -m32
|
||||
|
||||
# force building with gcc/g++ -mx32
|
||||
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-mx32/%: export CC = gcc -mx32
|
||||
build/extra/gcc-mx32/%: export CXX = g++ -mx32
|
||||
|
||||
# force building with gcc/g++ -m64
|
||||
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-m64/%: export CC = gcc -m64
|
||||
build/extra/gcc-m64/%: export CXX = g++ -m64
|
||||
|
||||
# force building with gcc/g++ -flto=auto
|
||||
build/extra/gcc-lto-auto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-lto-auto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-lto-auto/%: export CC = gcc -flto=auto
|
||||
build/extra/gcc-lto-auto/%: export CXX = g++ -flto=auto
|
||||
|
||||
# force building with gcc/g++ -pie
|
||||
build/extra/gcc-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-pie/%: export CC = gcc -pie -fPIE
|
||||
build/extra/gcc-pie/%: export CXX = g++ -pie -fPIE
|
||||
build/extra/gcc-pie/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with gcc/g++ -static
|
||||
build/extra/gcc-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-static/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-static/%: export CC = gcc -static
|
||||
build/extra/gcc-static/%: export CXX = g++ -static
|
||||
build/extra/gcc-static/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with gcc/g++ -static-pie
|
||||
build/extra/gcc-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-static-pie/%: export CC = gcc -static-pie -fPIE
|
||||
build/extra/gcc-static-pie/%: export CXX = g++ -static-pie -fPIE
|
||||
build/extra/gcc-static-pie/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with gcc/g++ -static -flto
|
||||
build/extra/gcc-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-static-lto/%: export CC = gcc -static -flto
|
||||
build/extra/gcc-static-lto/%: export CXX = g++ -static -flto
|
||||
build/extra/gcc-static-lto/%: export UPX_CONFIG_DISABLE_SHARED_LIBS = ON
|
||||
|
||||
# force building with gcc/g++ C++20 (and C17)
|
||||
build/extra/gcc-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-std-cxx20/%: export CC = gcc -std=gnu17
|
||||
build/extra/gcc-std-cxx20/%: export CXX = g++ -std=gnu++20
|
||||
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# force building with gcc/g++ C++23 (and C23)
|
||||
build/extra/gcc-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-std-cxx23/%: export CC = gcc -std=gnu2x
|
||||
build/extra/gcc-std-cxx23/%: export CXX = g++ -std=gnu++2b
|
||||
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# force building with gcc/g++ C++26 (and C23)
|
||||
build/extra/gcc-std-cxx26/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/gcc-std-cxx26/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/gcc-std-cxx26/%: export CC = gcc -std=gnu23
|
||||
build/extra/gcc-std-cxx26/%: export CXX = g++ -std=gnu++26
|
||||
build/extra/gcc-std-cxx26/%: export UPX_CONFIG_DISABLE_C_STANDARD = ON
|
||||
build/extra/gcc-std-cxx26/%: export UPX_CONFIG_DISABLE_CXX_STANDARD = ON
|
||||
|
||||
# cross compiler: Linux glibc aarch64-linux-gnu (arm64)
|
||||
build/extra/cross-linux-gnu-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-linux-gnu-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-linux-gnu-aarch64/%: export CC = aarch64-linux-gnu-gcc
|
||||
build/extra/cross-linux-gnu-aarch64/%: export CXX = aarch64-linux-gnu-g++
|
||||
build/extra/cross-linux-gnu-aarch64/%: CMAKE_SYSTEM_NAME ?= Linux
|
||||
build/extra/cross-linux-gnu-aarch64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-aarch64
|
||||
|
||||
# cross compiler: Linux glibc arm-linux-gnueabihf
|
||||
build/extra/cross-linux-gnu-arm-eabihf/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-linux-gnu-arm-eabihf/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-linux-gnu-arm-eabihf/%: export CC = arm-linux-gnueabihf-gcc
|
||||
build/extra/cross-linux-gnu-arm-eabihf/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
|
||||
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_SYSTEM_NAME ?= Linux
|
||||
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-arm
|
||||
|
||||
# cross compiler: Windows x86 win32 MinGW (i386)
|
||||
build/extra/cross-windows-mingw32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-windows-mingw32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
|
||||
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
|
||||
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_NAME ?= Windows
|
||||
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_PROCESSOR ?= X86
|
||||
build/extra/cross-windows-mingw32/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
|
||||
|
||||
# cross compiler: Windows x64 win64 MinGW (amd64)
|
||||
build/extra/cross-windows-mingw64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-windows-mingw64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
|
||||
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
|
||||
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_NAME ?= Windows
|
||||
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_PROCESSOR ?= AMD64
|
||||
build/extra/cross-windows-mingw64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
|
||||
|
||||
# cross compiler: macOS arm64 (aarch64)
|
||||
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
|
||||
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
|
||||
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_NAME ?= Darwin
|
||||
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_PROCESSOR ?= arm64
|
||||
|
||||
# cross compiler: macOS x86_64 (amd64)
|
||||
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
|
||||
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
|
||||
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_NAME ?= Darwin
|
||||
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_PROCESSOR ?= x86_64
|
||||
|
||||
#***********************************************************************
|
||||
# C/C++ static analyzers
|
||||
#***********************************************************************
|
||||
|
||||
# force building with clang Static Analyzer (scan-build)
|
||||
SCAN_BUILD = scan-build
|
||||
build/analyze/clang-analyzer/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/analyze/clang-analyzer/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/analyze/clang-analyzer/%: override CMAKE := $(SCAN_BUILD) $(CMAKE)
|
||||
build/analyze/clang-analyzer/%: export CCC_CC ?= clang
|
||||
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
|
||||
|
||||
# run clang-tidy: uses file compile_commands.json from an existing clang build;
|
||||
# does not create any actual files, so purely PHONY
|
||||
CLANG_TIDY_BUILD_BASE = build/extra/clang
|
||||
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
|
||||
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*'
|
||||
build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp'
|
||||
build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/
|
||||
build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/
|
||||
build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/
|
||||
build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-upx/$$(notdir $$@)
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-bzip2/$$(notdir $$@)
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-ucl/$$(notdir $$@)
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zlib/$$(notdir $$@)
|
||||
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
|
||||
|
||||
# OLD names [deprecated]
|
||||
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug PHONY
|
||||
build/extra/scan-build/release: build/analyze/clang-analyzer/release PHONY
|
||||
|
||||
#***********************************************************************
|
||||
# advanced: generic eXtra target
|
||||
#***********************************************************************
|
||||
|
||||
# usage:
|
||||
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
|
||||
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
|
||||
|
||||
ifneq ($(UPX_XTARGET),)
|
||||
ifneq ($(CC),)
|
||||
ifneq ($(CXX),)
|
||||
|
||||
UPX_XTARGET := $(UPX_XTARGET)
|
||||
build/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/$(UPX_XTARGET)/%: export CC := $(CC)
|
||||
build/$(UPX_XTARGET)/%: export CXX := $(CXX)
|
||||
# shortcuts
|
||||
xtarget/debug: build/$(UPX_XTARGET)/debug PHONY
|
||||
xtarget/release: build/$(UPX_XTARGET)/release PHONY
|
||||
xtarget/all: xtarget/debug xtarget/release PHONY
|
||||
xtarget/debug+test: build/$(UPX_XTARGET)/debug+test PHONY
|
||||
xtarget/release+test: build/$(UPX_XTARGET)/release+test PHONY
|
||||
xtarget/all+test: xtarget/debug+test xtarget/release+test PHONY
|
||||
# set new default
|
||||
.DEFAULT_GOAL := build/$(UPX_XTARGET)/release
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
#***********************************************************************
|
||||
# assemble cmake config flags; useful for CI jobs
|
||||
#
|
||||
# info: by default CMake only honors the CC and CXX environment variables; make
|
||||
# it easy to set other variables like CMAKE_AR or CMAKE_RANLIB
|
||||
#***********************************************************************
|
||||
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(UPX_CMAKE_CONFIG_FLAGS_GENERATOR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(UPX_CMAKE_CONFIG_FLAGS_TOOLSET)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(UPX_CMAKE_CONFIG_FLAGS_PLATFORM)
|
||||
|
||||
$(call check_undefined,__add_cmake_config)
|
||||
# promote an environment or Make variable to a CMake cache entry:
|
||||
__add_cmake_config = $(and $($1),-D$1="$($1)")
|
||||
|
||||
# pass common CMake settings
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_VERBOSE_MAKEFILE)
|
||||
# pass common CMake toolchain settings
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_ADDR2LINE)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_AR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_DLLTOOL)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_LINKER)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_NM)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJCOPY)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJDUMP)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_RANLIB)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_READELF)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_STRIP)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_TAPI)
|
||||
# pass common CMake LTO toolchain settings
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_AR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_RANLIB)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_AR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_RANLIB)
|
||||
# pass common CMake cross compilation settings
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_NAME)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_PROCESSOR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CROSSCOMPILING_EMULATOR)
|
||||
# pass UPX config options; see CMakeLists.txt
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_GITREV)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SANITIZE)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WERROR)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WSTRICT)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
|
||||
# pass UPX extra compile options; see CMakeLists.txt
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
|
||||
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
|
||||
|
||||
#***********************************************************************
|
||||
# check git submodules
|
||||
#***********************************************************************
|
||||
|
||||
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
|
||||
|
||||
$(foreach 1,$(SUBMODULES),$(if $(wildcard vendor/$1/[CL]*),,\
|
||||
$(error ERROR: missing git submodule '$1'; run 'git submodule update --init')))
|
||||
|
||||
endif # UPX_MAKEFILE_EXTRA_MK_INCLUDED
|
||||
@@ -0,0 +1,29 @@
|
||||
From 741b9d2f24b5796fc499a411f632820ab4f889e5 Mon Sep 17 00:00:00 2001
|
||||
From: "Markus F.X.J. Oberhumer" <markus@oberhumer.com>
|
||||
Date: Wed, 9 Apr 2025 20:00:24 +0200
|
||||
Subject: [PATCH] x
|
||||
|
||||
---
|
||||
lib/libcxx/include/__config | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config
|
||||
index fec323f..a16d145 100644
|
||||
--- a/lib/libcxx/include/__config
|
||||
+++ b/lib/libcxx/include/__config
|
||||
@@ -637,9 +637,11 @@ typedef __char32_t char32_t;
|
||||
# define _DECLARE_C99_LDBL_MATH 1
|
||||
# endif
|
||||
|
||||
+# if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
|
||||
+# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
|
||||
// If we are getting operator new from the MSVC CRT, then allocation overloads
|
||||
// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
|
||||
-# if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
|
||||
+# elif defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
|
||||
# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
|
||||
# elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
|
||||
// We're deferring to Microsoft's STL to provide aligned new et al. We don't
|
||||
--
|
||||
2.49.0
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||
|
||||
# create the image from Dockerfile
|
||||
# using a rootless Podman container
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
image=upx-stubtools-20240405-v1
|
||||
[[ $1 == --print-image ]] && echo "$image" && exit 0
|
||||
|
||||
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||
|
||||
podman image list "$image"
|
||||
echo
|
||||
podman image tree "$image"
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||
|
||||
# list all system packages that are installed in the image
|
||||
# using a rootless Podman container
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||
|
||||
podman image list "$image"
|
||||
echo
|
||||
podman image tree "$image"
|
||||
|
||||
echo 'Packages:'
|
||||
flags=( --read-only --rm --pull=never )
|
||||
flags+=( --cap-drop=all ) # drop all capabilities
|
||||
flags+=( --network=none ) # no network needed
|
||||
podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort'
|
||||
|
||||
echo
|
||||
echo 'Packages sorted by Installed-Size:'
|
||||
podman run "${flags[@]}" "$image" bash -c $'awk \'
|
||||
BEGIN {
|
||||
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
|
||||
}
|
||||
{
|
||||
if ($1 == "Architecture:") arch = $2;
|
||||
if ($1 == "Installed-Size:") size = $2;
|
||||
if ($1 == "Package:") package = $2;
|
||||
if ($1 == "") {
|
||||
printf("%9d %-40s %s\\n", size, package, arch);
|
||||
count += 1; total += size;
|
||||
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
|
||||
}
|
||||
}
|
||||
END {
|
||||
printf("%9d ===== TOTAL (%d packages)\\n", total, count);
|
||||
}
|
||||
\' /var/lib/dpkg/status | LC_ALL=C sort -rn'
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||
|
||||
# run an interactive shell in the image
|
||||
# using a rootless Podman container
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||
|
||||
flags=( --read-only --rm --pull=never )
|
||||
flags+=( --cap-drop=all ) # drop all capabilities
|
||||
flags+=( --network=none ) # no network needed
|
||||
flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM
|
||||
if [[ 1 == 1 ]]; then
|
||||
# run as user upx 2000:2000
|
||||
flags+=( --user 2000 )
|
||||
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
|
||||
flags+=( -w /home/upx/src/upx ) # set working directory
|
||||
flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs
|
||||
flags+=( --tmpfs /home/upx/.config:rw,exec ) # mount a writeable tmpfs
|
||||
flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs
|
||||
else
|
||||
# run as user root 0:0
|
||||
# ONLY FOR DEBUGGING THE IMAGE
|
||||
# map container user/group 0 to current host user/group
|
||||
flags+=( --user 0 )
|
||||
fi
|
||||
|
||||
if [[ $# == 0 ]]; then
|
||||
podman run "${flags[@]}" "$image" bash -l
|
||||
else
|
||||
podman run "${flags[@]}" "$image" "$@"
|
||||
fi
|
||||
|
||||
# now we can rebuild the UPX stubs:
|
||||
# cd /home/upx/src/upx/src/stub
|
||||
# # make sure that git is clean:
|
||||
# git status .
|
||||
# # remove stub files and make sure that they got deleted:
|
||||
# make maintainer-clean extra-clean
|
||||
# git status .
|
||||
# # rebuild
|
||||
# make extra-all all
|
||||
# # make sure that the stub files did rebuild correctly:
|
||||
# git status .
|
||||
# git diff .
|
||||
|
||||
# we can also build UPX in the container:
|
||||
# cd /home/upx/src/upx
|
||||
# rm -rf ./build/extra/gcc/release
|
||||
# make build/extra/gcc/release
|
||||
# # run tests
|
||||
# ./build/extra/gcc/release/upx --version
|
||||
# make -C build/extra/gcc/release test
|
||||
|
||||
# and we can also build UPX with -m32:
|
||||
# cd /home/upx/src/upx
|
||||
# rm -rf ./build/extra/gcc-m32/release
|
||||
# make build/extra/gcc-m32/release
|
||||
# # run tests
|
||||
# ./build/extra/gcc-m32/release/upx --version
|
||||
# make -C build/extra/gcc-m32/release test
|
||||
|
||||
# and we can also build UPX with -mx32: (NOTE: needs CONFIG_X86_X32_ABI on host kernel!)
|
||||
# cd /home/upx/src/upx
|
||||
# rm -rf ./build/extra/gcc-mx32/release
|
||||
# make build/extra/gcc-mx32/release
|
||||
# # run tests (needs CONFIG_X86_X32_ABI on host kernel)
|
||||
# ./build/extra/gcc-mx32/release/upx --version
|
||||
# make -C build/extra/gcc-mx32/release test
|
||||
|
||||
# and we can also rebuild the UPX docs the container:
|
||||
# cd /home/upx/src/upx/doc
|
||||
# make clean all
|
||||
# git status .
|
||||
# git diff .
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||
|
||||
# rebuild stubs from source code
|
||||
# (also see 20-image-run-shell.sh for more container usage examples)
|
||||
# using a rootless Podman container
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||
|
||||
flags=( --read-only --rm --pull=never )
|
||||
flags+=( --cap-drop=all ) # drop all capabilities
|
||||
flags+=( --network=none ) # no network needed
|
||||
if [[ 1 == 1 ]]; then
|
||||
# run as user upx 2000:2000
|
||||
flags+=( --user 2000 )
|
||||
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
|
||||
fi
|
||||
|
||||
podman run "${flags[@]}" "$image" bash -c $'
|
||||
set -ex; set -o pipefail
|
||||
cd /home/upx/src/upx
|
||||
# check whitespace
|
||||
[[ -d .git ]] && bash ./misc/scripts/check_whitespace_git.sh
|
||||
# rebuild docs
|
||||
make -C doc clean all
|
||||
# rebuild stubs
|
||||
cd /home/upx/src/upx/src/stub
|
||||
make maintainer-clean extra-clean
|
||||
git status . || true # make sure the stub files got deleted
|
||||
make extra-all all
|
||||
echo "===== Rebuilt stubs. All done. ====="
|
||||
exit 0
|
||||
'
|
||||
@@ -0,0 +1,102 @@
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
FROM docker.io/library/ubuntu:24.04
|
||||
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20240405-v1
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
# install system packages
|
||||
RUN dpkg --add-architecture i386 \
|
||||
&& apt-get update && apt-get upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
aria2 bash bash-completion ca-certificates curl git less libmpc3 \
|
||||
make ncurses-term perl-base tar time wget xz-utils \
|
||||
libc6:i386 zlib1g:i386 \
|
||||
# the following packages are not required for rebuilding the stubs, but
|
||||
# they do make the image *much* more convenient and also allow building
|
||||
# the full UPX binary inside the container via CMake:
|
||||
7zip bat bfs btop bubblewrap busybox bzip2 bzip3 cabextract ccache chrpath cmake cpio \
|
||||
dash diffstat direnv elfutils execstack eza fd-find file fish fzf \
|
||||
g++ gawk gdb gh gojq ht htop hyperfine jq ksh \
|
||||
lftp libzstd-dev lsb-release lsd lz4 lzip lzop minify mksh moreutils musl neovim ninja-build \
|
||||
p7zip parallel patch patchelf patchutils pax-utils proot \
|
||||
python3 python3-pyasn1 python3-pycryptodome python3-pycurl python3-tomli python3-tomli-w \
|
||||
python3-yaml python3-zstd \
|
||||
re2c ripgrep rsync screen socat strace universal-ctags unzip valgrind yash yq \
|
||||
zip zlib1g-dev zoxide zsh zstd \
|
||||
# extra packages for compiling with "gcc -m32" and "gcc -mx32":
|
||||
g++-multilib gcc-multilib \
|
||||
&& true
|
||||
|
||||
# install python2-minimal packages from Debian-11; REQUIRED
|
||||
RUN cd /root \
|
||||
&& aria2c --checksum=sha-256=85833c92314011b89bbead6f9a5a7a360b5ee4f9b95e001225afead4ebf9f7d3 \
|
||||
'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
|
||||
&& aria2c --checksum=sha-256=44f0cdc1a343303d31c55fcb3a6402cfe326adf749ec30e375e6e0c0c5f7c1f7 \
|
||||
'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
|
||||
&& dpkg -i ./*.deb \
|
||||
&& rm ./*.deb \
|
||||
&& if ! test -f /usr/bin/python2; then ln -s -v python2.7 /usr/bin/python2; fi \
|
||||
&& ldconfig \
|
||||
&& true
|
||||
|
||||
# manually unpack and install compat libs from Ubuntu-16.04; REQUIRED
|
||||
RUN cd /root \
|
||||
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
|
||||
'https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \
|
||||
&& mkdir packages \
|
||||
&& for f in ./*.deb; do dpkg -x $f ./packages; done \
|
||||
&& mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \
|
||||
&& rm -rf ./*.deb ./packages \
|
||||
&& ldconfig \
|
||||
&& true
|
||||
|
||||
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
|
||||
RUN cd /root \
|
||||
&& aria2c --checksum=sha-256=509e06639118a79d8e79489a400e134c6d3ca36bad2c6ec29648d7c1e5b81afa \
|
||||
'https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz' \
|
||||
&& cd /usr/local/bin \
|
||||
&& tar -xoaf /root/bin-upx-20221212.tar.xz \
|
||||
&& rm /root/bin-upx-20221212.tar.xz \
|
||||
&& true
|
||||
|
||||
# install official UPX release binaries into /usr/local/bin; not required but convenient for testing
|
||||
RUN cd /root \
|
||||
&& curl -sS -L -O https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
|
||||
&& xzversions="3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 5.0.0 5.0.1" \
|
||||
&& for v in $xzversions; do curl -sS -L -O https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \
|
||||
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
||||
&& for v in 3.91 $xzversions; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \
|
||||
&& rm -r ./upx-*.tar.* ./upx-*linux \
|
||||
&& true
|
||||
|
||||
# create default container user upx:upx 2000:2000
|
||||
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
||||
&& cd /home/upx && chmod 00700 . \
|
||||
# prepare ~/.cache, ~/.config and ~/.local for possible tmpfs mounts
|
||||
&& mkdir -p .cache/tmp .local/bin src/upx \
|
||||
&& for d in ccache fontconfig go-build mesa_shader_cache parallel tmp wine zig; do mkdir -p .cache/$d; done \
|
||||
&& for d in fish git helix kak nvim; do mkdir -p .config/$d; done \
|
||||
&& for d in bin include lib share state; do mkdir -p .local/$d; done \
|
||||
&& ln -s .cache/wine .wine && ln -s .cache/tmp tmp \
|
||||
# symlink upx-stubtools
|
||||
&& ln -s /usr/local/bin/bin-upx-20221212 .local/bin/bin-upx \
|
||||
# some convenience settings according to upx developer preferences
|
||||
&& echo "alias path='echo PATH=\"\$PATH\"'" >> .bashrc \
|
||||
&& echo "alias md=mkdir" >> .bashrc \
|
||||
&& echo "alias rd=rmdir" >> .bashrc \
|
||||
&& echo 'mdd() { mkdir "$1" && cd "$1"; }' >> .bashrc \
|
||||
&& echo 'm() { make "$@"; }' >> .bashrc \
|
||||
&& echo 'mm() { make -j8 "$@"; }' >> .bashrc \
|
||||
&& echo 'tn() { time nice "$@"; }' >> .bashrc \
|
||||
&& echo 'tnm() { time nice make "$@"; }' >> .bashrc \
|
||||
&& echo 'tnmm() { time nice make -j8 "$@"; }' >> .bashrc \
|
||||
&& echo 'source /usr/share/bash-completion/completions/make' >> .bashrc \
|
||||
&& echo 'complete -F _make m mm tnm tnmm' >> .bashrc \
|
||||
&& echo 'eval "$(zoxide init bash)"' >> .bashrc \
|
||||
&& echo "alias zz=zi\nalias y=z\nalias yy=zi" >> .bashrc \
|
||||
&& echo "alias cd..='cd ..'" >> .bashrc \
|
||||
&& echo "alias ..='cd ..'" >> .bashrc \
|
||||
&& echo "alias .='cd ..'" >> .bashrc \
|
||||
&& chown -R upx:upx . \
|
||||
&& true
|
||||
USER upx
|
||||
Generated
+747
@@ -0,0 +1,747 @@
|
||||
Packages:
|
||||
+++-=============================-=================================-============-================================================================================
|
||||
Desired=Unknown/Install/Remove/Purge/Hold
|
||||
ii 7zip 23.01+dfsg-11 amd64 7-Zip file archiver with a high compression ratio
|
||||
ii apt 2.8.3 amd64 commandline package manager
|
||||
ii aria2 1.37.0+debian-1build3 amd64 High speed download utility
|
||||
ii base-files 13ubuntu10.2 amd64 Debian base system miscellaneous files
|
||||
ii base-passwd 3.6.3build1 amd64 Debian base system master password and group files
|
||||
ii bash 5.2.21-2ubuntu4 amd64 GNU Bourne Again SHell
|
||||
ii bash-completion 1:2.11-8 all programmable completion for the bash shell
|
||||
ii bat 0.24.0-1build1 amd64 cat(1) clone with syntax highlighting and git integration
|
||||
ii bfs 3.1.2-1build1 amd64 Breadth-first version of find(1)
|
||||
ii binutils 2.42-4ubuntu2.5 amd64 GNU assembler, linker and binary utilities
|
||||
ii binutils-common:amd64 2.42-4ubuntu2.5 amd64 Common files for the GNU assembler, linker and binary utilities
|
||||
ii binutils-x86-64-linux-gnu 2.42-4ubuntu2.5 amd64 GNU binary utilities, for x86-64-linux-gnu target
|
||||
ii bsdextrautils 2.39.3-9ubuntu6.2 amd64 extra utilities from 4.4BSD-Lite
|
||||
ii bsdutils 1:2.39.3-9ubuntu6.2 amd64 basic utilities from 4.4BSD-Lite
|
||||
ii btop 1.3.0-1 amd64 Modern and colorful command line resource monitor that shows usage and stats
|
||||
ii bubblewrap 0.9.0-1ubuntu0.1 amd64 utility for unprivileged chroot and namespace manipulation
|
||||
ii busybox 1:1.36.1-6ubuntu3.1 amd64 Tiny utilities for small and embedded systems
|
||||
ii bzip2 1.0.8-5.1build0.1 amd64 high-quality block-sorting file compressor - utilities
|
||||
ii bzip3 1.4.0-1 amd64 better, faster and stronger spiritual successor to bzip2 - utilities
|
||||
ii ca-certificates 20240203 all Common CA certificates
|
||||
ii cabextract 1.11-2 amd64 Microsoft Cabinet file unpacker
|
||||
ii ccache 4.9.1-1 amd64 Compiler cache for fast recompilation of C/C++ code
|
||||
ii chrpath 0.16-2build1 amd64 Tool to edit the rpath in ELF binaries
|
||||
ii cmake 3.28.3-1build7 amd64 cross-platform, open-source make system
|
||||
ii cmake-data 3.28.3-1build7 all CMake data files (modules, templates and documentation)
|
||||
ii coreutils 9.4-3ubuntu6 amd64 GNU core utilities
|
||||
ii cpio 2.15+dfsg-1ubuntu2 amd64 GNU cpio -- a program to manage archives of files
|
||||
ii cpp 4:13.2.0-7ubuntu1 amd64 GNU C preprocessor (cpp)
|
||||
ii cpp-13 13.3.0-6ubuntu2~24.04 amd64 GNU C preprocessor
|
||||
ii cpp-13-x86-64-linux-gnu 13.3.0-6ubuntu2~24.04 amd64 GNU C preprocessor for x86_64-linux-gnu
|
||||
ii cpp-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C preprocessor (cpp) for the amd64 architecture
|
||||
ii curl 8.5.0-2ubuntu10.6 amd64 command line tool for transferring data with URL syntax
|
||||
ii dash 0.5.12-6ubuntu5 amd64 POSIX-compliant shell
|
||||
ii debconf 1.5.86ubuntu1 all Debian configuration management system
|
||||
ii debianutils 5.17build1 amd64 Miscellaneous utilities specific to Debian
|
||||
ii diffstat 1.66-1build1 amd64 produces graph of changes introduced by a diff file
|
||||
ii diffutils 1:3.10-1build1 amd64 File comparison utilities
|
||||
ii direnv 2.32.1-2ubuntu0.24.04.2 amd64 Utility to set directory specific environment variables
|
||||
ii dpkg 1.22.6ubuntu6.1 amd64 Debian package management system
|
||||
ii e2fsprogs 1.47.0-2.4~exp1ubuntu4.1 amd64 ext2/ext3/ext4 file system utilities
|
||||
ii elfutils 0.190-1.1ubuntu0.1 amd64 collection of utilities to handle ELF objects
|
||||
ii execstack 0.0.20131005-1.1ubuntu1 amd64 ELF GNU_STACK program header editing utility
|
||||
ii eza 0.18.2-1 amd64 Modern replacement for ls
|
||||
ii fd-find 9.0.0-1 amd64 Simple, fast and user-friendly alternative to find
|
||||
ii file 1:5.45-3build1 amd64 Recognize the type of data in a file using "magic" numbers
|
||||
ii findutils 4.9.0-5build1 amd64 utilities for finding files--find, xargs
|
||||
ii fish 3.7.0-1 amd64 friendly interactive shell
|
||||
ii fish-common 3.7.0-1 all friendly interactive shell (architecture-independent files)
|
||||
ii fzf 0.44.1-1ubuntu0.2 amd64 general-purpose command-line fuzzy finder
|
||||
ii g++ 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler
|
||||
ii g++-13 13.3.0-6ubuntu2~24.04 amd64 GNU C++ compiler
|
||||
ii g++-13-multilib 13.3.0-6ubuntu2~24.04 amd64 GNU C++ compiler (multilib support)
|
||||
ii g++-13-x86-64-linux-gnu 13.3.0-6ubuntu2~24.04 amd64 GNU C++ compiler for x86_64-linux-gnu architecture
|
||||
ii g++-multilib 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler (multilib files)
|
||||
ii g++-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler for the amd64 architecture
|
||||
ii gawk 1:5.2.1-2build3 amd64 GNU awk, a pattern scanning and processing language
|
||||
ii gcc 4:13.2.0-7ubuntu1 amd64 GNU C compiler
|
||||
ii gcc-13 13.3.0-6ubuntu2~24.04 amd64 GNU C compiler
|
||||
ii gcc-13-base:amd64 13.3.0-6ubuntu2~24.04 amd64 GCC, the GNU Compiler Collection (base package)
|
||||
ii gcc-13-multilib 13.3.0-6ubuntu2~24.04 amd64 GNU C compiler (multilib support)
|
||||
ii gcc-13-x86-64-linux-gnu 13.3.0-6ubuntu2~24.04 amd64 GNU C compiler for the x86_64-linux-gnu architecture
|
||||
ii gcc-14-base:amd64 14.2.0-4ubuntu2~24.04 amd64 GCC, the GNU Compiler Collection (base package)
|
||||
ii gcc-14-base:i386 14.2.0-4ubuntu2~24.04 i386 GCC, the GNU Compiler Collection (base package)
|
||||
ii gcc-multilib 4:13.2.0-7ubuntu1 amd64 GNU C compiler (multilib files)
|
||||
ii gcc-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C compiler for the amd64 architecture
|
||||
ii gdb 15.0.50.20240403-0ubuntu1 amd64 GNU Debugger
|
||||
ii gh 2.45.0-1ubuntu0.2 amd64 GitHub CLI, GitHub’s official command line tool
|
||||
ii git 1:2.43.0-1ubuntu7.2 amd64 fast, scalable, distributed revision control system
|
||||
ii git-man 1:2.43.0-1ubuntu7.2 all fast, scalable, distributed revision control system (manual pages)
|
||||
ii gojq 0.12.13-1ubuntu0.24.04.2 amd64 pure Go implementation of jq (program)
|
||||
ii gpgv 2.4.4-2ubuntu17.2 amd64 GNU privacy guard - signature verification tool
|
||||
ii grep 3.11-4build1 amd64 GNU grep, egrep and fgrep
|
||||
ii groff-base 1.23.0-3build2 amd64 GNU troff text-formatting system (base system components)
|
||||
ii gzip 1.12-1ubuntu3 amd64 GNU compression utilities
|
||||
ii hostname 3.23+nmu2ubuntu2 amd64 utility to set/show the host name or domain name
|
||||
ii ht 2.1.0+repack1-5 amd64 Viewer/editor/analyser (mostly) for executables
|
||||
ii htop 3.3.0-4build1 amd64 interactive processes viewer
|
||||
ii hyperfine 1.18.0-2build1 amd64 Command-line benchmarking tool
|
||||
ii init-system-helpers 1.66ubuntu1 all helper tools for all init systems
|
||||
ii jq 1.7.1-3build1 amd64 lightweight and flexible command-line JSON processor
|
||||
ii ksh 20240113 all transitional package
|
||||
ii ksh93u+m 1.0.8-1 amd64 AT&T KornShell
|
||||
ii less 590-2ubuntu2.1 amd64 pager program similar to more
|
||||
ii lftp 4.9.2-2ubuntu1 amd64 Sophisticated command-line FTP/HTTP/BitTorrent client programs
|
||||
ii lib32asan8 14.2.0-4ubuntu2~24.04 amd64 AddressSanitizer -- a fast memory error detector (32bit)
|
||||
ii lib32atomic1 14.2.0-4ubuntu2~24.04 amd64 support library providing __atomic built-in functions (32bit)
|
||||
ii lib32gcc-13-dev 13.3.0-6ubuntu2~24.04 amd64 GCC support library (32 bit development files)
|
||||
ii lib32gcc-s1 14.2.0-4ubuntu2~24.04 amd64 GCC support library (32 bit Version)
|
||||
ii lib32gomp1 14.2.0-4ubuntu2~24.04 amd64 GCC OpenMP (GOMP) support library (32bit)
|
||||
ii lib32itm1 14.2.0-4ubuntu2~24.04 amd64 GNU Transactional Memory Library (32bit)
|
||||
ii lib32quadmath0 14.2.0-4ubuntu2~24.04 amd64 GCC Quad-Precision Math Library (32bit)
|
||||
ii lib32stdc++-13-dev 13.3.0-6ubuntu2~24.04 amd64 GNU Standard C++ Library v3 (development files)
|
||||
ii lib32stdc++6 14.2.0-4ubuntu2~24.04 amd64 GNU Standard C++ Library v3 (32 bit Version)
|
||||
ii lib32ubsan1 14.2.0-4ubuntu2~24.04 amd64 UBSan -- undefined behaviour sanitizer (32bit)
|
||||
ii libacl1:amd64 2.3.2-1build1.1 amd64 access control list - shared library
|
||||
ii libapt-pkg6.0t64:amd64 2.8.3 amd64 package management runtime library
|
||||
ii libarchive13t64:amd64 3.7.2-2ubuntu0.4 amd64 Multi-format archive and compression library (shared library)
|
||||
ii libaria2-0:amd64 1.37.0+debian-1build3 amd64 C++ library interface to aria2
|
||||
ii libasan8:amd64 14.2.0-4ubuntu2~24.04 amd64 AddressSanitizer -- a fast memory error detector
|
||||
ii libasm1t64:amd64 0.190-1.1ubuntu0.1 amd64 library with a programmable assembler interface
|
||||
ii libassuan0:amd64 2.5.6-1build1 amd64 IPC library for the GnuPG components
|
||||
ii libatomic1:amd64 14.2.0-4ubuntu2~24.04 amd64 support library providing __atomic built-in functions
|
||||
ii libattr1:amd64 1:2.5.2-1build1.1 amd64 extended attribute handling - shared library
|
||||
ii libaudit-common 1:3.1.2-2.1build1.1 all Dynamic library for security auditing - common files
|
||||
ii libaudit1:amd64 1:3.1.2-2.1build1.1 amd64 Dynamic library for security auditing
|
||||
ii libbabeltrace1:amd64 1.5.11-3build3 amd64 Babeltrace conversion libraries
|
||||
ii libbinutils:amd64 2.42-4ubuntu2.5 amd64 GNU binary utilities (private shared library)
|
||||
ii libblkid1:amd64 2.39.3-9ubuntu6.2 amd64 block device ID library
|
||||
ii libbrotli1:amd64 1.1.0-2build2 amd64 library implementing brotli encoder and decoder (shared libraries)
|
||||
ii libbsd0:amd64 0.12.1-1build1.1 amd64 utility functions from BSD systems - shared library
|
||||
ii libbz2-1.0:amd64 1.0.8-5.1build0.1 amd64 high-quality block-sorting file compressor library - runtime
|
||||
ii libbzip3-0:amd64 1.4.0-1 amd64 better, faster and stronger spiritual successor to bzip2 - runtime
|
||||
ii libc-bin 2.39-0ubuntu8.4 amd64 GNU C Library: Binaries
|
||||
ii libc-dev-bin 2.39-0ubuntu8.4 amd64 GNU C Library: Development binaries
|
||||
ii libc6-dbg:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: detached debugging symbols
|
||||
ii libc6-dev-i386 2.39-0ubuntu8.4 amd64 GNU C Library: 32-bit development libraries for AMD64
|
||||
ii libc6-dev-x32 2.39-0ubuntu8.4 amd64 GNU C Library: X32 ABI Development Libraries for AMD64
|
||||
ii libc6-dev:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: Development Libraries and Header Files
|
||||
ii libc6-i386 2.39-0ubuntu8.4 amd64 GNU C Library: 32-bit shared libraries for AMD64
|
||||
ii libc6-x32 2.39-0ubuntu8.4 amd64 GNU C Library: X32 ABI Shared libraries for AMD64
|
||||
ii libc6:amd64 2.39-0ubuntu8.4 amd64 GNU C Library: Shared libraries
|
||||
ii libc6:i386 2.39-0ubuntu8.4 i386 GNU C Library: Shared libraries
|
||||
ii libcap-ng0:amd64 0.8.4-2build2 amd64 alternate POSIX capabilities library
|
||||
ii libcap2:amd64 1:2.66-5ubuntu2.2 amd64 POSIX 1003.1e capabilities (library)
|
||||
ii libcares2:amd64 1.27.0-1.0ubuntu1 amd64 asynchronous name resolver
|
||||
ii libcc1-0:amd64 14.2.0-4ubuntu2~24.04 amd64 GCC cc1 plugin for GDB
|
||||
ii libcom-err2:amd64 1.47.0-2.4~exp1ubuntu4.1 amd64 common error description library
|
||||
ii libcrypt-dev:amd64 1:4.4.36-4build1 amd64 libcrypt development files
|
||||
ii libcrypt1:amd64 1:4.4.36-4build1 amd64 libcrypt shared library
|
||||
ii libctf-nobfd0:amd64 2.42-4ubuntu2.5 amd64 Compact C Type Format library (runtime, no BFD dependency)
|
||||
ii libctf0:amd64 2.42-4ubuntu2.5 amd64 Compact C Type Format library (runtime, BFD dependency)
|
||||
ii libcurl3t64-gnutls:amd64 8.5.0-2ubuntu10.6 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour)
|
||||
ii libcurl4t64:amd64 8.5.0-2ubuntu10.6 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour)
|
||||
ii libdb5.3t64:amd64 5.3.28+dfsg2-7 amd64 Berkeley v5.3 Database Libraries [runtime]
|
||||
ii libdebconfclient0:amd64 0.271ubuntu3 amd64 Debian Configuration Management System (C-implementation library)
|
||||
ii libdebuginfod-common 0.190-1.1ubuntu0.1 all configuration to enable the Debian debug info server
|
||||
ii libdebuginfod1t64:amd64 0.190-1.1ubuntu0.1 amd64 library to interact with debuginfod (development files)
|
||||
ii libdw1t64:amd64 0.190-1.1ubuntu0.1 amd64 library that provides access to the DWARF debug information
|
||||
ii libelf1t64:amd64 0.190-1.1ubuntu0.1 amd64 library to read and write ELF files
|
||||
ii liberror-perl 0.17029-2 all Perl module for error/exception handling in an OO-ish way
|
||||
ii libexpat1:amd64 2.6.1-2ubuntu0.3 amd64 XML parsing C library - runtime library
|
||||
ii libext2fs2t64:amd64 1.47.0-2.4~exp1ubuntu4.1 amd64 ext2/ext3/ext4 file system libraries
|
||||
ii libffi8:amd64 3.4.6-1build1 amd64 Foreign Function Interface library runtime
|
||||
ii libgcc-13-dev:amd64 13.3.0-6ubuntu2~24.04 amd64 GCC support library (development files)
|
||||
ii libgcc-s1:amd64 14.2.0-4ubuntu2~24.04 amd64 GCC support library
|
||||
ii libgcc-s1:i386 14.2.0-4ubuntu2~24.04 i386 GCC support library
|
||||
ii libgcrypt20:amd64 1.10.3-2build1 amd64 LGPL Crypto library - runtime library
|
||||
ii libgdbm-compat4t64:amd64 1.23-5.1build1 amd64 GNU dbm database routines (legacy support runtime version)
|
||||
ii libgdbm6t64:amd64 1.23-5.1build1 amd64 GNU dbm database routines (runtime version)
|
||||
ii libgit2-1.7:amd64 1.7.2+ds-1ubuntu3 amd64 low-level Git library
|
||||
ii libglib2.0-0t64:amd64 2.80.0-6ubuntu3.4 amd64 GLib library of C routines
|
||||
ii libgmp10:amd64 2:6.3.0+dfsg-2ubuntu6.1 amd64 Multiprecision arithmetic library
|
||||
ii libgnutls30t64:amd64 3.8.3-1.1ubuntu3.3 amd64 GNU TLS library - main runtime library
|
||||
ii libgomp1:amd64 14.2.0-4ubuntu2~24.04 amd64 GCC OpenMP (GOMP) support library
|
||||
ii libgpg-error0:amd64 1.47-3build2.1 amd64 GnuPG development runtime library
|
||||
ii libgprofng0:amd64 2.42-4ubuntu2.5 amd64 GNU Next Generation profiler (runtime library)
|
||||
ii libgssapi-krb5-2:amd64 1.20.1-6ubuntu2.6 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
|
||||
ii libhiredis1.1.0:amd64 1.2.0-6ubuntu3 amd64 minimalistic C client library for Redis
|
||||
ii libhogweed6t64:amd64 3.9.1-2.2build1.1 amd64 low level cryptographic library (public-key cryptos)
|
||||
ii libhttp-parser2.9:amd64 2.9.4-6build1 amd64 parser for HTTP messages written in C
|
||||
ii libhwasan0:amd64 14.2.0-4ubuntu2~24.04 amd64 AddressSanitizer -- a fast memory error detector
|
||||
ii libicu74:amd64 74.2-1ubuntu3.1 amd64 International Components for Unicode
|
||||
ii libidn2-0:amd64 2.3.7-2build1.1 amd64 Internationalized domain names (IDNA2008/TR46) library
|
||||
ii libio-pty-perl 1:1.20-1build2 amd64 Perl module for pseudo tty IO
|
||||
ii libipc-run-perl 20231003.0-1 all Perl module for running processes
|
||||
ii libipt2 2.0.6-1build1 amd64 Intel Processor Trace Decoder Library
|
||||
ii libisl23:amd64 0.26-3build1.1 amd64 manipulating sets and relations of integer points bounded by linear constraints
|
||||
ii libitm1:amd64 14.2.0-4ubuntu2~24.04 amd64 GNU Transactional Memory Library
|
||||
ii libjansson4:amd64 2.14-2build2 amd64 C library for encoding, decoding and manipulating JSON data
|
||||
ii libjq1:amd64 1.7.1-3build1 amd64 lightweight and flexible command-line JSON processor - shared library
|
||||
ii libjsoncpp25:amd64 1.9.5-6build1 amd64 library for reading and writing JSON for C++
|
||||
ii libk5crypto3:amd64 1.20.1-6ubuntu2.6 amd64 MIT Kerberos runtime libraries - Crypto Library
|
||||
ii libkeyutils1:amd64 1.6.3-3build1 amd64 Linux Key Management Utilities (library)
|
||||
ii libkrb5-3:amd64 1.20.1-6ubuntu2.6 amd64 MIT Kerberos runtime libraries
|
||||
ii libkrb5support0:amd64 1.20.1-6ubuntu2.6 amd64 MIT Kerberos runtime libraries - Support library
|
||||
ii libldap2:amd64 2.6.7+dfsg-1~exp1ubuntu8.2 amd64 OpenLDAP libraries
|
||||
ii liblsan0:amd64 14.2.0-4ubuntu2~24.04 amd64 LeakSanitizer -- a memory leak detector (runtime)
|
||||
ii libluajit-5.1-2:amd64 2.1.0+git20231223.c525bcb+dfsg-1 amd64 Just in time compiler for Lua - library version
|
||||
ii libluajit-5.1-common 2.1.0+git20231223.c525bcb+dfsg-1 all Just in time compiler for Lua - common files
|
||||
ii liblz4-1:amd64 1.9.4-1build1.1 amd64 Fast LZ compression algorithm library - runtime
|
||||
ii liblzma5:amd64 5.6.1+really5.4.5-1ubuntu0.2 amd64 XZ-format compression library
|
||||
ii liblzo2-2:amd64 2.10-2build4 amd64 data compression library
|
||||
ii libmagic-mgc 1:5.45-3build1 amd64 File type determination library using "magic" numbers (compiled magic file)
|
||||
ii libmagic1t64:amd64 1:5.45-3build1 amd64 Recognize the type of data in a file using "magic" numbers - library
|
||||
ii libmd0:amd64 1.1.0-2build1.1 amd64 message digest functions from BSD systems - shared library
|
||||
ii libmount1:amd64 2.39.3-9ubuntu6.2 amd64 device mounting library
|
||||
ii libmpc3:amd64 1.3.1-1build1.1 amd64 multiple precision complex floating-point library
|
||||
ii libmpfr6:amd64 4.2.1-1build1.1 amd64 multiple precision floating-point computation
|
||||
ii libmsgpackc2:amd64 4.0.0-3build1 amd64 binary-based efficient object serialization library
|
||||
ii libmspack0t64:amd64 0.11-1.1build1 amd64 library for Microsoft compression formats (shared library)
|
||||
ii libncurses6:amd64 6.4+20240113-1ubuntu2 amd64 shared libraries for terminal handling
|
||||
ii libncursesw6:amd64 6.4+20240113-1ubuntu2 amd64 shared libraries for terminal handling (wide character support)
|
||||
ii libnettle8t64:amd64 3.9.1-2.2build1.1 amd64 low level cryptographic library (symmetric and one-way cryptos)
|
||||
ii libnghttp2-14:amd64 1.59.0-1ubuntu0.2 amd64 library implementing HTTP/2 protocol (shared library)
|
||||
ii libnl-3-200:amd64 3.7.0-0.3build1.1 amd64 library for dealing with netlink sockets
|
||||
ii libnl-genl-3-200:amd64 3.7.0-0.3build1.1 amd64 library for dealing with netlink sockets - generic netlink
|
||||
ii libnpth0t64:amd64 1.6-3.1build1 amd64 replacement for GNU Pth using system threads
|
||||
ii libonig5:amd64 6.9.9-1build1 amd64 regular expressions library
|
||||
ii libp11-kit0:amd64 0.25.3-4ubuntu2.1 amd64 library for loading and coordinating access to PKCS#11 modules - runtime
|
||||
ii libpam-modules-bin 1.5.3-5ubuntu5.1 amd64 Pluggable Authentication Modules for PAM - helper binaries
|
||||
ii libpam-modules:amd64 1.5.3-5ubuntu5.1 amd64 Pluggable Authentication Modules for PAM
|
||||
ii libpam-runtime 1.5.3-5ubuntu5.1 all Runtime support for the PAM library
|
||||
ii libpam0g:amd64 1.5.3-5ubuntu5.1 amd64 Pluggable Authentication Modules library
|
||||
ii libpcre2-32-0:amd64 10.42-4ubuntu2.1 amd64 New Perl Compatible Regular Expression Library - 32 bit runtime files
|
||||
ii libpcre2-8-0:amd64 10.42-4ubuntu2.1 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files
|
||||
ii libperl5.38t64:amd64 5.38.2-3.2ubuntu0.1 amd64 shared Perl library
|
||||
ii libpipeline1:amd64 1.5.7-2 amd64 Unix process pipeline manipulation library
|
||||
ii libpopt0:amd64 1.19+dfsg-1build1 amd64 lib for parsing cmdline parameters
|
||||
ii libproc2-0:amd64 2:4.0.4-4ubuntu3.2 amd64 library for accessing process information from /proc
|
||||
ii libpsl5t64:amd64 0.21.2-1.1build1 amd64 Library for Public Suffix List (shared libraries)
|
||||
ii libpython2.7-minimal:amd64 2.7.18-8+deb11u1 amd64 Minimal subset of the Python language (version 2.7)
|
||||
ii libpython3-stdlib:amd64 3.12.3-0ubuntu2 amd64 interactive high-level object-oriented language (default python3 version)
|
||||
ii libpython3.12-minimal:amd64 3.12.3-1ubuntu0.5 amd64 Minimal subset of the Python language (version 3.12)
|
||||
ii libpython3.12-stdlib:amd64 3.12.3-1ubuntu0.5 amd64 Interactive high-level object-oriented language (standard library, version 3.12)
|
||||
ii libpython3.12t64:amd64 3.12.3-1ubuntu0.5 amd64 Shared Python runtime library (version 3.12)
|
||||
ii libquadmath0:amd64 14.2.0-4ubuntu2~24.04 amd64 GCC Quad-Precision Math Library
|
||||
ii libreadline8t64:amd64 8.2-4build1 amd64 GNU readline and history libraries, run-time libraries
|
||||
ii librhash0:amd64 1.4.3-3build1 amd64 shared library for hash functions computing
|
||||
ii librtmp1:amd64 2.4+20151223.gitfa8646d.1-2build7 amd64 toolkit for RTMP streams (shared library)
|
||||
ii libsasl2-2:amd64 2.1.28+dfsg1-5ubuntu3.1 amd64 Cyrus SASL - authentication abstraction library
|
||||
ii libsasl2-modules-db:amd64 2.1.28+dfsg1-5ubuntu3.1 amd64 Cyrus SASL - pluggable authentication modules (DB)
|
||||
ii libseccomp2:amd64 2.5.5-1ubuntu3.1 amd64 high level interface to Linux seccomp filter
|
||||
ii libselinux1:amd64 3.5-2ubuntu2.1 amd64 SELinux runtime shared libraries
|
||||
ii libsemanage-common 3.5-1build5 all Common files for SELinux policy management libraries
|
||||
ii libsemanage2:amd64 3.5-1build5 amd64 SELinux policy management library
|
||||
ii libsensors-config 1:3.6.0-9build1 all lm-sensors configuration files
|
||||
ii libsensors5:amd64 1:3.6.0-9build1 amd64 library to read temperature/voltage/fan sensors
|
||||
ii libsepol2:amd64 3.5-2build1 amd64 SELinux library for manipulating binary security policies
|
||||
ii libsframe1:amd64 2.42-4ubuntu2.5 amd64 Library to handle the SFrame format (runtime library)
|
||||
ii libsigsegv2:amd64 2.14-1ubuntu2 amd64 Library for handling page faults in a portable way
|
||||
ii libsmartcols1:amd64 2.39.3-9ubuntu6.2 amd64 smart column output alignment library
|
||||
ii libsource-highlight-common 3.1.9-4.3build1 all architecture-independent files for source highlighting library
|
||||
ii libsource-highlight4t64:amd64 3.1.9-4.3build1 amd64 source highlighting library
|
||||
ii libsqlite3-0:amd64 3.45.1-1ubuntu2.3 amd64 SQLite 3 shared library
|
||||
ii libss2:amd64 1.47.0-2.4~exp1ubuntu4.1 amd64 command-line interface parsing library
|
||||
ii libssh-4:amd64 0.10.6-2build2 amd64 tiny C SSH library (OpenSSL flavor)
|
||||
ii libssh2-1t64:amd64 1.11.0-4.1build2 amd64 SSH2 client-side library
|
||||
ii libssl3t64:amd64 3.0.13-0ubuntu3.5 amd64 Secure Sockets Layer toolkit - shared libraries
|
||||
ii libstdc++-13-dev:amd64 13.3.0-6ubuntu2~24.04 amd64 GNU Standard C++ Library v3 (development files)
|
||||
ii libstdc++6:amd64 14.2.0-4ubuntu2~24.04 amd64 GNU Standard C++ Library v3
|
||||
ii libsystemd0:amd64 255.4-1ubuntu8.6 amd64 systemd utility library
|
||||
ii libtalloc2:amd64 2.4.2-1build2 amd64 hierarchical pool based memory allocator
|
||||
ii libtasn1-6:amd64 4.19.0-3ubuntu0.24.04.1 amd64 Manage ASN.1 structures (runtime)
|
||||
ii libtermkey1:amd64 0.22-1 amd64 library for processing keyboard input
|
||||
ii libtime-duration-perl 1.21-2 all module for rounded or exact English expression of durations
|
||||
ii libtimedate-perl 2.3300-2 all collection of modules to manipulate date/time information
|
||||
ii libtinfo6:amd64 6.4+20240113-1ubuntu2 amd64 shared low-level terminfo library for terminal handling
|
||||
ii libtree-sitter0:amd64 0.20.8-2 amd64 incremental parsing system for programming tools
|
||||
ii libtsan2:amd64 14.2.0-4ubuntu2~24.04 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime)
|
||||
ii libubsan1:amd64 14.2.0-4ubuntu2~24.04 amd64 UBSan -- undefined behaviour sanitizer (runtime)
|
||||
ii libuchardet0:amd64 0.0.8-1build1 amd64 universal charset detection library - shared library
|
||||
ii libudev1:amd64 255.4-1ubuntu8.6 amd64 libudev shared library
|
||||
ii libunibilium4:amd64 2.1.0-3 amd64 simple, self-contained terminfo library
|
||||
ii libunistring5:amd64 1.1-2build1.1 amd64 Unicode string library for C
|
||||
ii libunwind8:amd64 1.6.2-3build1.1 amd64 library to determine the call-chain of a program - runtime
|
||||
ii liburing2:amd64 2.5-1build1 amd64 Linux kernel io_uring access library - shared library
|
||||
ii libutempter0:amd64 1.2.1-3build1 amd64 privileged helper for utmp/wtmp updates (runtime)
|
||||
ii libuuid1:amd64 2.39.3-9ubuntu6.2 amd64 Universally Unique ID library
|
||||
ii libuv1t64:amd64 1.48.0-1.1build1 amd64 asynchronous event notification library - runtime library
|
||||
ii libvterm0:amd64 0.3.3-2build1 amd64 abstract terminal library
|
||||
ii libwrap0:amd64 7.6.q-33 amd64 Wietse Venema's TCP wrappers library
|
||||
ii libx11-6:amd64 2:1.8.7-1build1 amd64 X11 client-side library
|
||||
ii libx11-data 2:1.8.7-1build1 all X11 client-side library
|
||||
ii libx32asan8 14.2.0-4ubuntu2~24.04 amd64 AddressSanitizer -- a fast memory error detector (x32)
|
||||
ii libx32atomic1 14.2.0-4ubuntu2~24.04 amd64 support library providing __atomic built-in functions (x32)
|
||||
ii libx32gcc-13-dev 13.3.0-6ubuntu2~24.04 amd64 GCC support library (x32 development files)
|
||||
ii libx32gcc-s1 14.2.0-4ubuntu2~24.04 amd64 GCC support library (x32)
|
||||
ii libx32gomp1 14.2.0-4ubuntu2~24.04 amd64 GCC OpenMP (GOMP) support library (x32)
|
||||
ii libx32itm1 14.2.0-4ubuntu2~24.04 amd64 GNU Transactional Memory Library (x32)
|
||||
ii libx32quadmath0 14.2.0-4ubuntu2~24.04 amd64 GCC Quad-Precision Math Library (x32)
|
||||
ii libx32stdc++-13-dev 13.3.0-6ubuntu2~24.04 amd64 GNU Standard C++ Library v3 (development files)
|
||||
ii libx32stdc++6 14.2.0-4ubuntu2~24.04 amd64 GNU Standard C++ Library v3 (x32)
|
||||
ii libx32ubsan1 14.2.0-4ubuntu2~24.04 amd64 UBSan -- undefined behaviour sanitizer (x32)
|
||||
ii libxau6:amd64 1:1.0.9-1build6 amd64 X11 authorisation library
|
||||
ii libxcb1:amd64 1.15-1ubuntu2 amd64 X C Binding
|
||||
ii libxdmcp6:amd64 1:1.1.3-0ubuntu6 amd64 X11 Display Manager Control Protocol library
|
||||
ii libxml2:amd64 2.9.14+dfsg-1.3ubuntu3.3 amd64 GNOME XML library
|
||||
ii libxxhash0:amd64 0.8.2-2build1 amd64 shared library for xxhash
|
||||
ii libyaml-0-2:amd64 0.2.5-1build1 amd64 Fast YAML 1.1 parser and emitter library
|
||||
ii libzstd-dev:amd64 1.5.5+dfsg2-2build1.1 amd64 fast lossless compression algorithm -- development files
|
||||
ii libzstd1:amd64 1.5.5+dfsg2-2build1.1 amd64 fast lossless compression algorithm
|
||||
ii linux-libc-dev:amd64 6.8.0-60.63 amd64 Linux Kernel Headers for development
|
||||
ii login 1:4.13+dfsg1-4ubuntu3.2 amd64 system login tools
|
||||
ii logsave 1.47.0-2.4~exp1ubuntu4.1 amd64 save the output of a command in a log file
|
||||
ii lsb-release 12.0-2 all Linux Standard Base version reporting utility (minimal implementation)
|
||||
ii lsd 1.0.0-2 amd64 ls command with a lot of pretty colors and some other stuff
|
||||
ii lua-luv:amd64 1.48.0-2-2build1 amd64 libuv bindings for Lua
|
||||
ii lz4 1.9.4-1build1.1 amd64 Fast LZ compression algorithm library - tool
|
||||
ii lzip 1.24.1-1build1 amd64 lossless data compressor based on the LZMA algorithm
|
||||
ii lzop 1.04-2build3 amd64 fast compression program
|
||||
ii make 4.3-4.1build2 amd64 utility for directing compilation
|
||||
ii man-db 2.12.0-4build2 amd64 tools for reading manual pages
|
||||
ii mawk 1.3.4.20240123-1build1 amd64 Pattern scanning and text processing language
|
||||
ii media-types 10.1.0 all List of standard media types and their usual file extension
|
||||
ii minify 2.20.17-1 amd64 CLI implementation of the Go minify library package
|
||||
ii mksh 59c-37 amd64 MirBSD Korn Shell
|
||||
ii moreutils 0.69-1 amd64 additional Unix utilities
|
||||
ii mount 2.39.3-9ubuntu6.2 amd64 tools for mounting and manipulating filesystems
|
||||
ii musl:amd64 1.2.4-2 amd64 standard C library
|
||||
ii ncurses-base 6.4+20240113-1ubuntu2 all basic terminal type definitions
|
||||
ii ncurses-bin 6.4+20240113-1ubuntu2 amd64 terminal-related programs and man pages
|
||||
ii ncurses-term 6.4+20240113-1ubuntu2 all additional terminal type definitions
|
||||
ii neovim 0.9.5-6ubuntu2 amd64 heavily refactored vim fork
|
||||
ii neovim-runtime 0.9.5-6ubuntu2 all heavily refactored vim fork (runtime files)
|
||||
ii netbase 6.4 all Basic TCP/IP networking system
|
||||
ii ninja-build 1.11.1-2 amd64 small build system closest in spirit to Make
|
||||
ii openssl 3.0.13-0ubuntu3.5 amd64 Secure Sockets Layer toolkit - cryptographic utility
|
||||
ii p7zip 16.02+transitional.1 all transitional package
|
||||
ii parallel 20231122+ds-1 all build and execute command lines from standard input in parallel
|
||||
ii passwd 1:4.13+dfsg1-4ubuntu3.2 amd64 change and administer password and group data
|
||||
ii patch 2.7.6-7build3 amd64 Apply a diff file to an original
|
||||
ii patchelf 0.18.0-1.1build1 amd64 modify properties of ELF executables
|
||||
ii patchutils 0.4.2-1build3 amd64 Utilities to work with patches
|
||||
ii pax-utils 1.3.7-1 amd64 Security-focused ELF files checking tool
|
||||
ii perl 5.38.2-3.2ubuntu0.1 amd64 Larry Wall's Practical Extraction and Report Language
|
||||
ii perl-base 5.38.2-3.2ubuntu0.1 amd64 minimal Perl system
|
||||
ii perl-modules-5.38 5.38.2-3.2ubuntu0.1 all Core Perl modules
|
||||
ii procps 2:4.0.4-4ubuntu3.2 amd64 /proc file system utilities
|
||||
ii proot 5.1.0-1.3 amd64 emulate chroot, bind mount and binfmt_misc for non-root users
|
||||
ii python2.7-minimal 2.7.18-8+deb11u1 amd64 Minimal subset of the Python language (version 2.7)
|
||||
ii python3 3.12.3-0ubuntu2 amd64 interactive high-level object-oriented language (default python3 version)
|
||||
ii python3-argcomplete 3.1.4-1ubuntu0.1 all bash tab completion for argparse (for Python 3)
|
||||
ii python3-minimal 3.12.3-0ubuntu2 amd64 minimal subset of the Python language (default python3 version)
|
||||
ii python3-pyasn1 0.4.8-4 all ASN.1 library for Python (Python 3 module)
|
||||
ii python3-pycryptodome 3.20.0+dfsg-1 amd64 cryptographic Python library (Python 3)
|
||||
ii python3-pycurl 7.45.3-1build2 amd64 Python bindings to libcurl (Python 3)
|
||||
ii python3-pyelftools 0.30-1 all pure-python3 library for parsing ELF and DWARF
|
||||
ii python3-toml 0.10.2-1 all library for Tom's Obvious, Minimal Language - Python 3.x
|
||||
ii python3-tomli 2.0.1-2 all lil' TOML parser for Python
|
||||
ii python3-tomli-w 1.0.0-2 all lil' TOML writer for Python
|
||||
ii python3-xmltodict 0.13.0-1 all Makes working with XML feel like you are working with JSON (Python 3)
|
||||
ii python3-yaml 6.0.1-2build2 amd64 YAML parser and emitter for Python3
|
||||
ii python3-zstd 1.5.5.1-1build1 amd64 python bindings to Yann Collet ZSTD compression library
|
||||
ii python3.12 3.12.3-1ubuntu0.5 amd64 Interactive high-level object-oriented language (version 3.12)
|
||||
ii python3.12-minimal 3.12.3-1ubuntu0.5 amd64 Minimal subset of the Python language (version 3.12)
|
||||
ii re2c 3.1-1build1 amd64 lexer generator for C, C++, Go and Rust
|
||||
ii readline-common 8.2-4build1 all GNU readline and history libraries, common files
|
||||
ii ripgrep 14.1.0-1 amd64 Recursively searches directories for a regex pattern
|
||||
ii rpcsvc-proto 1.4.2-0ubuntu7 amd64 RPC protocol compiler and definitions
|
||||
ii rsync 3.2.7-1ubuntu1.2 amd64 fast, versatile, remote (and local) file-copying tool
|
||||
ii screen 4.9.1-1build1 amd64 terminal multiplexer with VT100/ANSI terminal emulation
|
||||
ii sed 4.9-2build1 amd64 GNU stream editor for filtering/transforming text
|
||||
ii sensible-utils 0.0.22 all Utilities for sensible alternative selection
|
||||
ii socat 1.8.0.0-4build3 amd64 multipurpose relay for bidirectional data transfer
|
||||
ii strace 6.8-0ubuntu2 amd64 System call tracer
|
||||
ii sysstat 12.6.1-2 amd64 system performance tools for Linux
|
||||
ii sysvinit-utils 3.08-6ubuntu3 amd64 System-V-like utilities
|
||||
ii tar 1.35+dfsg-3build1 amd64 GNU version of the tar archiving utility
|
||||
ii time 1.9-0.2build1 amd64 GNU time program for measuring CPU resource usage
|
||||
ii tzdata 2025b-0ubuntu0.24.04.1 all time zone and daylight-saving time data
|
||||
ii ubuntu-keyring 2023.11.28.1 all GnuPG keys of the Ubuntu archive
|
||||
ii ucf 3.0043+nmu1 all Update Configuration File(s): preserve user changes to config files
|
||||
ii universal-ctags 5.9.20210829.0-1 amd64 build tag file indexes of source code definitions
|
||||
ii unminimize 0.2.1 amd64 Un-minimize your minimial images or setup
|
||||
ii unzip 6.0-28ubuntu4.1 amd64 De-archiver for .zip files
|
||||
ii util-linux 2.39.3-9ubuntu6.2 amd64 miscellaneous system utilities
|
||||
ii valgrind 1:3.22.0-0ubuntu3 amd64 instrumentation framework for building dynamic analysis tools
|
||||
ii wget 1.21.4-1ubuntu4.1 amd64 retrieves files from the web
|
||||
ii xz-utils 5.6.1+really5.4.5-1ubuntu0.2 amd64 XZ-format compression utilities
|
||||
ii yash 2.55-2 amd64 yet another shell
|
||||
ii yq 3.1.0-3 all Command-line YAML processor - jq wrapper for YAML documents
|
||||
ii zip 3.0-13ubuntu0.2 amd64 Archiver for .zip files
|
||||
ii zlib1g-dev:amd64 1:1.3.dfsg-3.1ubuntu2.1 amd64 compression library - development
|
||||
ii zlib1g:amd64 1:1.3.dfsg-3.1ubuntu2.1 amd64 compression library - runtime
|
||||
ii zlib1g:i386 1:1.3.dfsg-3.1ubuntu2.1 i386 compression library - runtime
|
||||
ii zoxide 0.9.3-1 amd64 Smarter cd command for your terminal
|
||||
ii zsh 5.9-6ubuntu2 amd64 shell with lots of features
|
||||
ii zsh-common 5.9-6ubuntu2 all architecture independent files for Zsh
|
||||
ii zstd 1.5.5+dfsg2-2build1.1 amd64 fast lossless compression algorithm -- CLI tool
|
||||
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|
||||
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
|
||||
||/ Name Version Architecture Description
|
||||
|
||||
Packages sorted by Installed-Size:
|
||||
1015747 ===== TOTAL (369 packages)
|
||||
76943 valgrind amd64
|
||||
61333 gcc-13-x86-64-linux-gnu amd64
|
||||
44381 gh amd64
|
||||
36493 cmake amd64
|
||||
35919 libicu74 amd64
|
||||
33545 g++-13-x86-64-linux-gnu amd64
|
||||
30811 cpp-13-x86-64-linux-gnu amd64
|
||||
29327 libperl5.38t64 amd64
|
||||
21815 neovim-runtime all
|
||||
21692 git amd64
|
||||
21662 libstdc++-13-dev amd64
|
||||
19159 perl-modules-5.38 all
|
||||
16248 zsh-common all
|
||||
16082 libgcc-13-dev amd64
|
||||
13431 libc6 amd64
|
||||
13112 libc6-dev amd64
|
||||
12519 gdb amd64
|
||||
12321 fish-common all
|
||||
12297 libc6 i386
|
||||
12004 libc6-x32 amd64
|
||||
11989 libc6-i386 amd64
|
||||
11549 binutils-x86-64-linux-gnu amd64
|
||||
11182 libc6-dbg amd64
|
||||
10984 cmake-data all
|
||||
10791 libasan8 amd64
|
||||
9704 libx32asan8 amd64
|
||||
9539 lib32asan8 amd64
|
||||
9017 libpython3.12-stdlib amd64
|
||||
8917 libpython3.12t64 amd64
|
||||
8902 libtsan2 amd64
|
||||
8335 libmagic-mgc amd64
|
||||
8296 lib32gcc-13-dev amd64
|
||||
8119 libc6-dev-x32 amd64
|
||||
7924 python3.12-minimal amd64
|
||||
7913 perl-base amd64
|
||||
7531 libx32gcc-13-dev amd64
|
||||
7437 linux-libc-dev amd64
|
||||
7226 lib32stdc++-13-dev amd64
|
||||
7059 libx32stdc++-13-dev amd64
|
||||
7024 direnv amd64
|
||||
6947 libc6-dev-i386 amd64
|
||||
6944 coreutils amd64
|
||||
6775 neovim amd64
|
||||
6608 libssl3t64 amd64
|
||||
6237 dpkg amd64
|
||||
6158 7zip amd64
|
||||
5219 bat amd64
|
||||
5210 ripgrep amd64
|
||||
5179 libpython3.12-minimal amd64
|
||||
4897 libhwasan0 amd64
|
||||
4341 ncurses-term all
|
||||
4244 minify amd64
|
||||
4193 libglib2.0-0t64 amd64
|
||||
4108 apt amd64
|
||||
4074 gojq amd64
|
||||
3956 python3-pycryptodome amd64
|
||||
3833 libgprofng0 amd64
|
||||
3828 liblsan0 amd64
|
||||
3738 fzf amd64
|
||||
3721 groff-base amd64
|
||||
3605 python2.7-minimal amd64
|
||||
3443 fish amd64
|
||||
3441 re2c amd64
|
||||
3438 util-linux amd64
|
||||
3408 lsd amd64
|
||||
3403 libaria2-0 amd64
|
||||
3382 fd-find amd64
|
||||
3364 libubsan1 amd64
|
||||
3249 libapt-pkg6.0t64 amd64
|
||||
3181 libx32ubsan1 amd64
|
||||
3111 ksh93u+m amd64
|
||||
3110 libstdc++6 amd64
|
||||
3104 lib32ubsan1 amd64
|
||||
2995 parallel all
|
||||
2958 elfutils amd64
|
||||
2928 man-db amd64
|
||||
2894 lib32stdc++6 amd64
|
||||
2810 libx32stdc++6 amd64
|
||||
2785 libpython2.7-minimal amd64
|
||||
2431 zsh amd64
|
||||
2419 passwd amd64
|
||||
2352 libgnutls30t64 amd64
|
||||
2350 libbinutils amd64
|
||||
2191 ht amd64
|
||||
2183 libc-bin amd64
|
||||
2163 git-man all
|
||||
2103 strace amd64
|
||||
2079 libxml2 amd64
|
||||
2032 libisl23 amd64
|
||||
2009 universal-ctags amd64
|
||||
1980 aria2 amd64
|
||||
1900 bash amd64
|
||||
1885 openssl amd64
|
||||
1848 lftp amd64
|
||||
1802 zstd amd64
|
||||
1800 procps amd64
|
||||
1761 libdb5.3t64 amd64
|
||||
1757 libunistring5 amd64
|
||||
1736 gawk amd64
|
||||
1731 libsqlite3-0 amd64
|
||||
1712 libp11-kit0 amd64
|
||||
1634 mksh amd64
|
||||
1610 socat amd64
|
||||
1582 btop amd64
|
||||
1579 ccache amd64
|
||||
1504 e2fsprogs amd64
|
||||
1454 bash-completion all
|
||||
1452 sysstat amd64
|
||||
1448 yash amd64
|
||||
1396 libgcrypt20 amd64
|
||||
1387 tzdata all
|
||||
1362 libx11-6 amd64
|
||||
1342 libx11-data all
|
||||
1322 zlib1g-dev amd64
|
||||
1314 hyperfine amd64
|
||||
1237 libzstd-dev amd64
|
||||
1237 libgit2-1.7 amd64
|
||||
1186 libmpfr6 amd64
|
||||
1145 libpam-modules amd64
|
||||
1142 eza amd64
|
||||
1136 zoxide amd64
|
||||
1025 libsystemd0 amd64
|
||||
1015 libkrb5-3 amd64
|
||||
996 screen amd64
|
||||
925 libcurl4t64 amd64
|
||||
916 wget amd64
|
||||
906 libcurl3t64-gnutls amd64
|
||||
904 libarchive13t64 amd64
|
||||
884 login amd64
|
||||
852 busybox amd64
|
||||
843 libbrotli1 amd64
|
||||
812 lua-luv amd64
|
||||
785 musl amd64
|
||||
781 rsync amd64
|
||||
766 libdw1t64 amd64
|
||||
761 libzstd1 amd64
|
||||
751 libsepol2 amd64
|
||||
745 libsource-highlight4t64 amd64
|
||||
736 python3.12 amd64
|
||||
732 xz-utils amd64
|
||||
708 tar amd64
|
||||
672 perl amd64
|
||||
647 ncurses-bin amd64
|
||||
635 libpcre2-8-0 amd64
|
||||
629 libonig5 amd64
|
||||
624 python3-pyelftools all
|
||||
614 lib32quadmath0 amd64
|
||||
602 libluajit-5.1-2 amd64
|
||||
564 binutils-common amd64
|
||||
556 libtinfo6 amd64
|
||||
554 libpcre2-32-0 amd64
|
||||
553 gcc-13 amd64
|
||||
552 findutils amd64
|
||||
543 libgmp10 amd64
|
||||
540 libldap2 amd64
|
||||
538 libext2fs2t64 amd64
|
||||
536 zip amd64
|
||||
521 curl amd64
|
||||
512 python3-yaml amd64
|
||||
508 libbabeltrace1 amd64
|
||||
496 libssh-4 amd64
|
||||
493 debconf all
|
||||
467 libreadline8t64 amd64
|
||||
452 diffutils amd64
|
||||
426 libgssapi-krb5-2 amd64
|
||||
426 base-files amd64
|
||||
424 libnettle8t64 amd64
|
||||
424 htop amd64
|
||||
422 libncursesw6 amd64
|
||||
415 libssh2-1t64 amd64
|
||||
404 make amd64
|
||||
389 python3-pyasn1 all
|
||||
388 libexpat1 amd64
|
||||
386 ca-certificates all
|
||||
384 ncurses-base all
|
||||
379 liblzma5 amd64
|
||||
375 unzip amd64
|
||||
373 libgomp1 amd64
|
||||
367 libmount1 amd64
|
||||
358 libjq1 amd64
|
||||
357 bfs amd64
|
||||
355 ninja-build amd64
|
||||
351 libx32gomp1 amd64
|
||||
348 mount amd64
|
||||
346 lib32gomp1 amd64
|
||||
344 libcrypt-dev amd64
|
||||
344 grep amd64
|
||||
340 sed amd64
|
||||
337 libhogweed6t64 amd64
|
||||
337 gpgv amd64
|
||||
336 libncurses6 amd64
|
||||
328 cpio amd64
|
||||
314 libudev1 amd64
|
||||
311 libx32quadmath0 amd64
|
||||
309 less amd64
|
||||
307 libctf-nobfd0 amd64
|
||||
305 libsource-highlight-common all
|
||||
300 libquadmath0 amd64
|
||||
289 libblkid1 amd64
|
||||
288 libsemanage2 amd64
|
||||
288 bsdutils amd64
|
||||
287 bsdextrautils amd64
|
||||
276 libpam-runtime all
|
||||
273 patchelf amd64
|
||||
273 mawk amd64
|
||||
270 pax-utils amd64
|
||||
270 libpam-modules-bin amd64
|
||||
264 libuv1t64 amd64
|
||||
258 libk5crypto3 amd64
|
||||
255 libipc-run-perl all
|
||||
254 base-passwd amd64
|
||||
245 rpcsvc-proto amd64
|
||||
244 gzip amd64
|
||||
237 libjsoncpp25 amd64
|
||||
235 libproc2-0 amd64
|
||||
235 libgcc-s1 i386
|
||||
232 lz4 amd64
|
||||
232 libctf0 amd64
|
||||
231 moreutils amd64
|
||||
230 librhash0 amd64
|
||||
226 libcrypt1 amd64
|
||||
224 libidn2-0 amd64
|
||||
224 debianutils amd64
|
||||
223 lib32gcc-s1 amd64
|
||||
218 patch amd64
|
||||
218 libluajit-5.1-common all
|
||||
215 patchutils amd64
|
||||
214 ucf all
|
||||
211 libmagic1t64 amd64
|
||||
209 libpam0g amd64
|
||||
207 libuchardet0 amd64
|
||||
206 proot amd64
|
||||
204 libelf1t64 amd64
|
||||
202 python3-pycurl amd64
|
||||
200 libselinux1 amd64
|
||||
200 libnghttp2-14 amd64
|
||||
199 execstack amd64
|
||||
198 libtree-sitter0 amd64
|
||||
197 libgcc-s1 amd64
|
||||
196 libxcb1 amd64
|
||||
188 libx32gcc-s1 amd64
|
||||
187 libunwind8 amd64
|
||||
187 dash amd64
|
||||
185 libgpg-error0 amd64
|
||||
176 libcares2 amd64
|
||||
172 libnl-3-200 amd64
|
||||
171 libsmartcols1 amd64
|
||||
163 zlib1g amd64
|
||||
163 lzip amd64
|
||||
160 binutils amd64
|
||||
158 zlib1g i386
|
||||
157 lzop amd64
|
||||
157 liblzo2-2 amd64
|
||||
155 liblz4-1 amd64
|
||||
151 libaudit1 amd64
|
||||
150 python3-argcomplete all
|
||||
149 libmpc3 amd64
|
||||
148 libsasl2-2 amd64
|
||||
148 libcc1-0 amd64
|
||||
143 libyaml-0-2 amd64
|
||||
143 libseccomp2 amd64
|
||||
137 librtmp1 amd64
|
||||
136 libhiredis1.1.0 amd64
|
||||
133 libkrb5support0 amd64
|
||||
131 libipt2 amd64
|
||||
130 init-system-helpers all
|
||||
130 bubblewrap amd64
|
||||
127 libsframe1 amd64
|
||||
127 libbsd0 amd64
|
||||
126 time amd64
|
||||
123 libtimedate-perl all
|
||||
122 libtasn1-6 amd64
|
||||
120 libpopt0 amd64
|
||||
115 libitm1 amd64
|
||||
113 gcc-13-base amd64
|
||||
112 jq amd64
|
||||
112 gcc-14-base i386
|
||||
112 gcc-14-base amd64
|
||||
111 python3-minimal amd64
|
||||
109 libx32itm1 amd64
|
||||
109 bzip2 amd64
|
||||
107 sysvinit-utils amd64
|
||||
107 libwrap0 amd64
|
||||
106 libc-dev-bin amd64
|
||||
105 lib32itm1 amd64
|
||||
103 libio-pty-perl amd64
|
||||
100 libassuan0 amd64
|
||||
99 libpsl5t64 amd64
|
||||
98 libmspack0t64 amd64
|
||||
98 libcap2 amd64
|
||||
96 liburing2 amd64
|
||||
95 libunibilium4 amd64
|
||||
95 libjansson4 amd64
|
||||
95 libbz2-1.0 amd64
|
||||
93 media-types all
|
||||
93 libvterm0 amd64
|
||||
93 libgdbm6t64 amd64
|
||||
90 libxxhash0 amd64
|
||||
84 libuuid1 amd64
|
||||
83 libtalloc2 amd64
|
||||
82 cabextract amd64
|
||||
81 python3 amd64
|
||||
81 libbzip3-0 amd64
|
||||
79 libsensors5 amd64
|
||||
79 libmd0 amd64
|
||||
77 readline-common all
|
||||
77 python3-toml all
|
||||
75 libsasl2-modules-db amd64
|
||||
75 libasm1t64 amd64
|
||||
74 libacl1 amd64
|
||||
72 libffi8 amd64
|
||||
72 diffstat amd64
|
||||
70 libdebuginfod1t64 amd64
|
||||
69 yq all
|
||||
69 libss2 amd64
|
||||
69 liberror-perl all
|
||||
67 libpipeline1 amd64
|
||||
66 libhttp-parser2.9 amd64
|
||||
66 bzip3 amd64
|
||||
63 sensible-utils all
|
||||
63 libtermkey1 amd64
|
||||
63 file amd64
|
||||
61 ksh all
|
||||
60 python3-tomli all
|
||||
60 libcap-ng0 amd64
|
||||
60 libattr1 amd64
|
||||
57 libcom-err2 amd64
|
||||
53 libnl-genl-3-200 amd64
|
||||
51 logsave amd64
|
||||
51 libutempter0 amd64
|
||||
51 libdebuginfod-common all
|
||||
49 libatomic1 amd64
|
||||
48 libmsgpackc2 amd64
|
||||
47 python3-xmltodict all
|
||||
47 libx32atomic1 amd64
|
||||
47 libsigsegv2 amd64
|
||||
46 hostname amd64
|
||||
44 python3-zstd amd64
|
||||
42 libnpth0t64 amd64
|
||||
41 libxdmcp6 amd64
|
||||
41 libkeyutils1 amd64
|
||||
39 lib32atomic1 amd64
|
||||
38 libdebconfclient0 amd64
|
||||
37 gcc amd64
|
||||
37 cpp amd64
|
||||
36 netbase all
|
||||
36 chrpath amd64
|
||||
34 libtime-duration-perl all
|
||||
34 libgdbm-compat4t64 amd64
|
||||
33 libxau6 amd64
|
||||
31 python3-tomli-w all
|
||||
29 ubuntu-keyring all
|
||||
29 g++-13 amd64
|
||||
27 libpython3-stdlib amd64
|
||||
26 libsemanage-common all
|
||||
25 libsensors-config all
|
||||
25 gcc-x86-64-linux-gnu amd64
|
||||
20 cpp-x86-64-linux-gnu amd64
|
||||
17 lsb-release all
|
||||
17 libaudit-common all
|
||||
16 unminimize amd64
|
||||
13 g++ amd64
|
||||
11 g++-x86-64-linux-gnu amd64
|
||||
11 cpp-13 amd64
|
||||
8 p7zip all
|
||||
8 gcc-multilib amd64
|
||||
6 gcc-13-multilib amd64
|
||||
6 g++-multilib amd64
|
||||
6 g++-13-multilib amd64
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
[[ -z $1 ]] || cd "$1" || exit 1
|
||||
|
||||
find . \
|
||||
-type d -name '.git' -prune -o \
|
||||
-type d -name '.hg' -prune -o \
|
||||
-type d -name 'build*' -prune -o \
|
||||
-type d -name 'tmp*' -prune -o \
|
||||
-type d -name 'vendor' -prune -o \
|
||||
-type f -iname '*.bat' -prune -o \
|
||||
-type f -iname '*.exe' -prune -o \
|
||||
-type f -iname '*.o' -prune -o \
|
||||
-type f -iname '*.obj' -prune -o \
|
||||
-type f -iname '*.out' -prune -o \
|
||||
-type f -iname '*.pdf' -prune -o \
|
||||
-type f -iname '*.swp' -prune -o \
|
||||
-type f -print0 | \
|
||||
LC_ALL=C sort -z | xargs -0r perl -n -e '
|
||||
#print("$ARGV\n");
|
||||
if (m,[\x00\x01\x02\x7f\xfe\xff],) { print "ERROR: binary file detected $ARGV: $_"; exit(1); }
|
||||
if (m,[\r\x1a],) { print "ERROR: DOS EOL detected $ARGV: $_"; exit(1); }
|
||||
if (m,([ \t]+)$,) {
|
||||
if ($ARGV =~ m,\.patch$,) { }
|
||||
else { print "ERROR: trailing whitespace detected $ARGV: $_"; exit(1); }
|
||||
}
|
||||
if (m,\t,) {
|
||||
if ($ARGV =~ m,\.patch$,) { }
|
||||
elsif ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||
elsif ($ARGV =~ m,\.mk$,) { }
|
||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
||||
}
|
||||
' || exit 1
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
[[ -z $1 ]] || cd "$1" || exit 1
|
||||
[[ -d .git ]] || exit 1
|
||||
|
||||
git ls-files --full-name -z | perl -0 -n -e '
|
||||
s,^,./,;
|
||||
if (m,^\./src/lzma-sdk(\0|$),) { }
|
||||
elsif (m,^\./vendor/,) { }
|
||||
elsif (m,\.bat(\0|$),) { }
|
||||
elsif (m,\.exe(\0|$),) { }
|
||||
else { print; }
|
||||
' | LC_ALL=C sort -z | xargs -0r perl -n -e '
|
||||
#print("$ARGV\n");
|
||||
if (m,[\x00\x01\x02\x7f\xfe\xff],) { print "ERROR: binary file detected $ARGV: $_"; exit(1); }
|
||||
if (m,[\r\x1a],) { print "ERROR: DOS EOL detected $ARGV: $_"; exit(1); }
|
||||
if (m,([ \t]+)$,) {
|
||||
if ($ARGV =~ m,\.patch$,) { }
|
||||
else { print "ERROR: trailing whitespace detected $ARGV: $_"; exit(1); }
|
||||
}
|
||||
if (m,\t,) {
|
||||
if ($ARGV =~ m,\.patch$,) { }
|
||||
elsif ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||
elsif ($ARGV =~ m,\.mk$,) { }
|
||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
||||
}
|
||||
' || exit 1
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#! /usr/bin/env python3
|
||||
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||
|
||||
# simulate "readlink -en FILE"
|
||||
# - result may differ from actual readlink(1) for edge cases
|
||||
# - works with Python2 and Python3
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
import os, sys
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit(1)
|
||||
real_path = os.path.realpath(sys.argv[1])
|
||||
if not os.path.exists(real_path):
|
||||
sys.exit(1)
|
||||
sys.stdout.write(real_path)
|
||||
sys.stdout.flush()
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#! /usr/bin/env python3
|
||||
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||
|
||||
# simulate "readlink -fn FILE" for systems that lack it (e.g. macOS-11)
|
||||
# - result may differ from actual readlink(1) for edge cases
|
||||
# - works with Python2 and Python3
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
import os, sys
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit(1)
|
||||
real_path = os.path.realpath(sys.argv[1])
|
||||
sys.stdout.write(real_path)
|
||||
sys.stdout.flush()
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
# assemble cmake config flags; useful for CI jobs
|
||||
# also see misc/make/Makefile-extra.mk
|
||||
|
||||
cmake_config_flags=()
|
||||
|
||||
# promote an environment variable to a CMake cache entry:
|
||||
__add_cmake_config() {
|
||||
[[ -z "${!1}" ]] || cmake_config_flags+=( -D$1="${!1}" )
|
||||
}
|
||||
|
||||
# pass common CMake settings
|
||||
for v in CMAKE_VERBOSE_MAKEFILE; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
# pass common CMake toolchain settings
|
||||
for v in CMAKE_ADDR2LINE CMAKE_AR CMAKE_DLLTOOL CMAKE_LINKER CMAKE_NM CMAKE_OBJCOPY CMAKE_OBJDUMP CMAKE_RANLIB CMAKE_READELF CMAKE_STRIP CMAKE_TAPI; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
# pass common CMake LTO toolchain settings
|
||||
for v in CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
# pass common CMake cross compilation settings
|
||||
for v in CMAKE_SYSTEM_NAME CMAKE_SYSTEM_PROCESSOR CMAKE_CROSSCOMPILING_EMULATOR; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
# pass UPX config options; see CMakeLists.txt
|
||||
for v in UPX_CONFIG_DISABLE_GITREV UPX_CONFIG_DISABLE_SANITIZE UPX_CONFIG_DISABLE_WERROR UPX_CONFIG_DISABLE_WSTRICT UPX_CONFIG_DISABLE_SELF_PACK_TEST UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
# pass UPX extra compile options; see CMakeLists.txt
|
||||
for v in UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2 UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD; do
|
||||
__add_cmake_config $v
|
||||
done
|
||||
|
||||
exec "${CMAKE:-cmake}" $UPX_CMAKE_CONFIG_FLAGS "${cmake_config_flags[@]}" "$@"
|
||||
exit 99
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||
#
|
||||
# NOTE: we are using clang-format-15.0.6 from upx-stubtools
|
||||
# see https://github.com/upx/upx-stubtools/releases
|
||||
#
|
||||
# NOTE: we use .clang-format config from upx.git/.clang-format
|
||||
|
||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
|
||||
fi
|
||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6"
|
||||
fi
|
||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6"
|
||||
fi
|
||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||
echo "ERROR: $0: cannot find clang-format-15.0.6"
|
||||
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# limit memory usage to 1 GiB (in case of clang-format problems with invalid files)
|
||||
ulimit -v 1048576 || true
|
||||
|
||||
#echo $UPX_CLANG_FORMAT
|
||||
exec "$UPX_CLANG_FORMAT" -style=file "$@"
|
||||
exit 99
|
||||
Executable
+180
@@ -0,0 +1,180 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
# mimic running "ctest", i.e. the "test" section of CMakeLists.txt
|
||||
# - does not redirect stdout
|
||||
# - allows freely setting $upx_exe_runner, while CMake is restricted to configure-time settings
|
||||
#
|
||||
# requires:
|
||||
# $upx_exe (required, but with convenience fallback "./upx")
|
||||
# optional settings:
|
||||
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||
#
|
||||
|
||||
# Debugging aid for locating failing commands. Depends on 'bash' shell.
|
||||
# (BASH_LINENO is relative to current FUNCTION only; non-function ==> 0)
|
||||
# Notice single-quoting of entire first argument.
|
||||
trap 'echo ERROR: pwd=\"$PWD\" file=\"$BASH_SOURCE\" line=${BASH_LINENO[0]} cmd=\"$BASH_COMMAND\"' ERR
|
||||
# Example: "false a b c" ==> ERROR: pwd="path/misc/testsuite" file="./mimic_ctest.sh" line=0 cmd="false a b c"
|
||||
|
||||
#***********************************************************************
|
||||
# init & checks
|
||||
#***********************************************************************
|
||||
|
||||
# upx_exe
|
||||
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
# usage examples:
|
||||
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||
# export upx_exe_runner="wine"
|
||||
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||
fi
|
||||
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
|
||||
# run_upx sanity check
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
|
||||
#***********************************************************************
|
||||
# see CMakeLists.txt
|
||||
#
|
||||
# IDEA: create a Makefile and use "make -j8" so that these tests can
|
||||
# run in parallel much like "ctest --parallel 8"
|
||||
#***********************************************************************
|
||||
|
||||
# similar to cmake function upx_cache_bool_vars()
|
||||
set_cmake_bool_vars() {
|
||||
local default_value="$1"; shift
|
||||
local var_name
|
||||
for var_name do
|
||||
case "${!var_name}" in
|
||||
0 | FALSE | OFF | false | off) eval "export $var_name=OFF" ;;
|
||||
1 | TRUE | ON | true | on) eval "export $var_name=ON" ;;
|
||||
*) eval "export $var_name=$default_value" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
set -x
|
||||
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_SELF_PACK_TEST
|
||||
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST
|
||||
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_PACKED_TEST
|
||||
if [[ "${emu[0]}" == *valgrind* ]]; then # valgrind is SLOW
|
||||
set_cmake_bool_vars ON UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||
else
|
||||
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||
fi
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||
|
||||
"${run_upx[@]}" --version
|
||||
"${run_upx[@]}" --version-short
|
||||
"${run_upx[@]}" --license
|
||||
"${run_upx[@]}" --help
|
||||
"${run_upx[@]}" --help-short
|
||||
"${run_upx[@]}" --help-verbose
|
||||
"${run_upx[@]}" --sysinfo
|
||||
"${run_upx[@]}" --sysinfo -v
|
||||
"${run_upx[@]}" --sysinfo -vv
|
||||
|
||||
if [[ $UPX_CONFIG_DISABLE_SELF_PACK_TEST == ON ]]; then
|
||||
echo "Self-pack test disabled. All done."; exit 0
|
||||
fi
|
||||
|
||||
exe=".out"
|
||||
upx_self_exe=$upx_exe
|
||||
fo="--force-overwrite"
|
||||
|
||||
"${run_upx[@]}" -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}
|
||||
"${run_upx[@]}" -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe}
|
||||
"${run_upx[@]}" -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe}
|
||||
"${run_upx[@]}" -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe}
|
||||
"${run_upx[@]}" -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe}
|
||||
"${run_upx[@]}" -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe}
|
||||
"${run_upx[@]}" -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${exe}
|
||||
"${run_upx[@]}" -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}
|
||||
|
||||
"${run_upx[@]}" -l upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||
"${run_upx[@]}" --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||
"${run_upx[@]}" -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||
|
||||
"${run_upx[@]}" -d upx-packed${exe} ${fo} -o upx-unpacked${exe}
|
||||
"${run_upx[@]}" -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe}
|
||||
"${run_upx[@]}" -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe}
|
||||
"${run_upx[@]}" -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe}
|
||||
"${run_upx[@]}" -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe}
|
||||
"${run_upx[@]}" -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe}
|
||||
"${run_upx[@]}" -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe}
|
||||
"${run_upx[@]}" -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe}
|
||||
|
||||
# all unpacked files must be identical
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-fa${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-fn${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-fr${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-nrv2b${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-nrv2d${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-nrv2e${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-lzma${exe}
|
||||
|
||||
if [[ $UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST != ON ]]; then
|
||||
"${emu[@]}" ./upx-unpacked${exe} --version-short
|
||||
fi
|
||||
|
||||
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
|
||||
"${emu[@]}" ./upx-packed${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-fa${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-fn${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-fr${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-nrv2b${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-nrv2d${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-nrv2e${exe} --version-short
|
||||
"${emu[@]}" ./upx-packed-lzma${exe} --version-short
|
||||
fi
|
||||
|
||||
if [[ $UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS != ON ]]; then
|
||||
set +x
|
||||
for method in nrv2b nrv2d nrv2e lzma; do
|
||||
for level in 1 2 3 4 5 6 7; do
|
||||
for small in normal small; do
|
||||
s="${method}-${level}"
|
||||
ss=
|
||||
if [[ $small == "small" ]]; then
|
||||
s="${method}-${level}-${small}"
|
||||
ss="--small"
|
||||
fi
|
||||
echo "========== $s =========="
|
||||
"${run_upx[@]}" -qq --${method} -${level} ${ss} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe}
|
||||
"${run_upx[@]}" -qq -l upx-packed-${s}${exe}
|
||||
"${run_upx[@]}" -qq --fileinfo upx-packed-${s}${exe}
|
||||
"${run_upx[@]}" -qq -t upx-packed-${s}${exe}
|
||||
"${run_upx[@]}" -qq -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe}
|
||||
cmp -s upx-unpacked${exe} upx-unpacked-${s}${exe}
|
||||
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
|
||||
"${emu[@]}" ./upx-packed-${s}${exe} --version-short
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
echo "All done."
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
# mimic running "ctest", i.e. the "test" section of CMakeLists.txt
|
||||
# - does not redirect stdout
|
||||
# - allows freely setting $upx_exe_runner, while CMake is restricted to configure-time settings
|
||||
#
|
||||
# requires:
|
||||
# $upx_exe (required, but with convenience fallback "./upx")
|
||||
# optional settings:
|
||||
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||
#
|
||||
|
||||
cat >catch-sigsegv.gdb <<'EOF'
|
||||
catch signal SIGSEGV
|
||||
commands
|
||||
x/i $pc
|
||||
info reg
|
||||
x/32i $pc-0x20
|
||||
quit 77
|
||||
end
|
||||
EOF
|
||||
|
||||
catcher=$(readlink -fn catch-sigsegv.gdb)
|
||||
|
||||
function emu_gdb() {
|
||||
gdb -q -x "$catcher" <<EOF --args "$@"
|
||||
run
|
||||
EOF
|
||||
}
|
||||
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
true
|
||||
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||
true
|
||||
else
|
||||
upx_exe_runner=emu_gdb
|
||||
true
|
||||
fi
|
||||
|
||||
source "$argv0dir/mimic_ctest.sh"
|
||||
Executable
+425
@@ -0,0 +1,425 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
# test file system behaviour with symlinks; requires:
|
||||
# $upx_exe (required, but with convenience fallback "./upx")
|
||||
# optional settings:
|
||||
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||
# $upx_test_file
|
||||
#
|
||||
|
||||
# IMPORTANT NOTE: this script only works on Unix
|
||||
# IMPORTANT NOTE: do NOT run as user root!
|
||||
umask 0022
|
||||
|
||||
# disable on macOS for now, see https://github.com/upx/upx/issues/612
|
||||
if [[ "$(uname)" == Darwin ]]; then
|
||||
case "$UPX_DEBUG_FORCE_PACK_MACOS" in
|
||||
"" | "0") echo "$0: SKIPPED"; exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
id || true
|
||||
echo "PWD='$PWD'"
|
||||
if [[ $UID == 0 || $EUID == 0 ]]; then
|
||||
echo "ERROR: do not run as root: UID=$UID EUID=$EUID"
|
||||
exit 91
|
||||
fi
|
||||
|
||||
#***********************************************************************
|
||||
# init & checks
|
||||
#***********************************************************************
|
||||
|
||||
# upx_exe
|
||||
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
# usage examples:
|
||||
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||
# export upx_exe_runner="wine"
|
||||
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||
fi
|
||||
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
|
||||
# run_upx sanity check
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
|
||||
#***********************************************************************
|
||||
# util functions
|
||||
#***********************************************************************
|
||||
|
||||
exit_code=0
|
||||
num_errors=0
|
||||
all_errors=
|
||||
|
||||
failed() {
|
||||
####exit $1
|
||||
# log error and keep going
|
||||
exit_code=1
|
||||
local a="$(basename "$(dirname "$PWD")")"
|
||||
local b="$(basename "$PWD")"
|
||||
let num_errors+=1 || true
|
||||
all_errors="${all_errors} $a/$b/$1"
|
||||
echo " FAILED $b/$1"
|
||||
}
|
||||
|
||||
assert_file() {
|
||||
local f
|
||||
for f in "$@"; do
|
||||
[[ ! -L "$f" && -f "$f" ]] && continue
|
||||
echo "failed '$f': not a regular file"
|
||||
failed 21
|
||||
done
|
||||
}
|
||||
|
||||
assert_symlink_to_file() {
|
||||
local f
|
||||
for f in "$@"; do
|
||||
[[ -L "$f" && -f "$f" ]] && continue
|
||||
echo "failed '$f': not a symlink to file"
|
||||
failed 22
|
||||
done
|
||||
}
|
||||
|
||||
assert_symlink_to_dir() {
|
||||
local f
|
||||
for f in "$@"; do
|
||||
[[ -L "$f" && -d "$f" ]] && continue
|
||||
echo "failed '$f': not a symlink to dir"
|
||||
failed 23
|
||||
done
|
||||
}
|
||||
|
||||
assert_symlink_dangling() {
|
||||
local f
|
||||
for f in "$@"; do
|
||||
[[ -L "$f" && ! -e "$f" ]] && continue
|
||||
echo "failed '$f': not a dangling symlink"
|
||||
failed 24
|
||||
done
|
||||
}
|
||||
|
||||
copy_directory() {
|
||||
if command -v rsync >/dev/null; then
|
||||
rsync -aH "$1/" "$2"
|
||||
else
|
||||
cp -ai "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
create_files() {
|
||||
# clean
|
||||
local d
|
||||
for d in z_dir_1 z_dir_2 z_dir_3 z_dir_4; do
|
||||
if [[ -d $d ]]; then
|
||||
chmod -R +rwx "./$d"
|
||||
rm -rf "./$d"
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir z_dir_1
|
||||
cd z_dir_1
|
||||
: > z_file
|
||||
ln -s z_file z_symlink_file
|
||||
: > z_file_link_1
|
||||
ln z_file_link_1 z_file_link_2
|
||||
ln -s z_file_link_1 z_symlink_file_link
|
||||
mkdir z_dir
|
||||
ln -s z_dir z_symlink_dir
|
||||
ln -s z_file_missing z_symlink_dangling
|
||||
assert_file z_file*
|
||||
assert_symlink_to_file z_symlink_file
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
cd ..
|
||||
|
||||
# write-protect z_dir_2/z_file*
|
||||
copy_directory z_dir_1 z_dir_2
|
||||
chmod a-w z_dir_2/z_file*
|
||||
|
||||
# write-protect z_dir_3 itself
|
||||
copy_directory z_dir_1 z_dir_3
|
||||
chmod a-w z_dir_3
|
||||
|
||||
# write-protect everything in z_dir_4
|
||||
copy_directory z_dir_1 z_dir_4
|
||||
chmod -R a-w z_dir_4
|
||||
}
|
||||
|
||||
print_header() {
|
||||
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||
echo -e "\n${x}\n${1}\n${x}\n"
|
||||
}
|
||||
|
||||
enter_dir() {
|
||||
cd "$1" || exit 1
|
||||
echo "===== $(basename "$PWD")"
|
||||
}
|
||||
leave_dir() {
|
||||
echo "===== $(basename "$PWD") files"
|
||||
ls -lA
|
||||
cd ..
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# setup
|
||||
#***********************************************************************
|
||||
|
||||
#set -x # debug
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||
|
||||
# get $test_file
|
||||
if [[ -f $upx_test_file ]]; then
|
||||
test_file="$(readlink -fn "$upx_test_file")"
|
||||
else
|
||||
for test_file in /usr/bin/gmake /usr/bin/make /usr/bin/env /bin/ls; do
|
||||
if [[ -f $test_file ]]; then
|
||||
test_file="$(readlink -fn "$test_file")"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
ls -l "$test_file"
|
||||
file "$test_file" || true
|
||||
|
||||
# create and enter a tmpdir in the current directory
|
||||
tmpdir="$(mktemp -d tmp-upx-test-XXXXXX)"
|
||||
cd "./$tmpdir" || exit 1
|
||||
|
||||
#***********************************************************************
|
||||
# default
|
||||
#***********************************************************************
|
||||
|
||||
print_header "default"
|
||||
flags="-qq -2 --no-filter"
|
||||
mkdir default
|
||||
cd default
|
||||
create_files
|
||||
enter_dir z_dir_1
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_2
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_3
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_4
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
cd ..
|
||||
|
||||
#***********************************************************************
|
||||
# force-overwrite
|
||||
#***********************************************************************
|
||||
|
||||
print_header "force-overwrite"
|
||||
flags="-qq -2 --no-filter --force-overwrite"
|
||||
mkdir force-overwrite
|
||||
cd force-overwrite
|
||||
create_files
|
||||
enter_dir z_dir_1
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||
assert_file z_symlink_file z_symlink_file_link
|
||||
assert_file z_symlink_dir
|
||||
assert_file z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_2
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||
assert_file z_symlink_file z_symlink_file_link
|
||||
assert_file z_symlink_dir
|
||||
assert_file z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_3
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_4
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
cd ..
|
||||
|
||||
#***********************************************************************
|
||||
# link
|
||||
#***********************************************************************
|
||||
|
||||
print_header "link"
|
||||
flags="-qq -2 --no-filter --link"
|
||||
mkdir link
|
||||
cd link
|
||||
create_files
|
||||
enter_dir z_dir_1
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||
assert_file z_symlink_file z_symlink_file_link
|
||||
assert_file z_symlink_dir
|
||||
assert_file z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_2
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||
assert_file z_symlink_file z_symlink_file_link
|
||||
assert_file z_symlink_dir
|
||||
assert_file z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_3
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
enter_dir z_dir_4
|
||||
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||
assert_symlink_to_dir z_symlink_dir
|
||||
assert_symlink_dangling z_symlink_dangling
|
||||
leave_dir
|
||||
cd ..
|
||||
|
||||
#***********************************************************************
|
||||
# done
|
||||
#***********************************************************************
|
||||
|
||||
# clean up
|
||||
cd ..
|
||||
chmod -R +rwx "./$tmpdir"
|
||||
rm -rf "./$tmpdir"
|
||||
|
||||
if [[ $exit_code == 0 ]]; then
|
||||
echo "UPX testsuite passed. All done."
|
||||
else
|
||||
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
|
||||
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
|
||||
fi
|
||||
exit $exit_code
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
########## begin .sha256sums.recreate
|
||||
expected_sha256sums__t010_decompressed="\
|
||||
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
||||
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
|
||||
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
|
||||
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
|
||||
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
|
||||
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
|
||||
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
||||
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
|
||||
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
||||
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
|
||||
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
|
||||
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
|
||||
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
||||
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
|
||||
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
||||
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
|
||||
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
||||
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
|
||||
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t020_canonicalized="\
|
||||
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
||||
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
|
||||
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
|
||||
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
|
||||
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
|
||||
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
|
||||
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
||||
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
|
||||
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
||||
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
|
||||
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
|
||||
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
|
||||
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
||||
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
|
||||
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
||||
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
|
||||
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
||||
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
|
||||
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
||||
919f31ec6a70a81159f4fc1d3cd4e9d66800a242df2fac9e339a36e1bf648091 *amd64-linux.elf/upx-3.91
|
||||
548e950c9f082eb0eb42b18411bbc257365cfc9c937ab20f501ebf0db5850d25 *amd64-linux.elf/upx-3.95
|
||||
822718cc0f6ac5e57bb23eeb65be6f3f7e73df8b062853abddcc924ec8207596 *amd64-win64.pe/upx-3.95.exe
|
||||
4d8b2a8f29b38e097287e550d11810d7ecd4c5f07744545b3a315de908987bf6 *arm-linux.elf/upx-3.95
|
||||
1440d6b44968954baf56fbc2a0739a51873455876114d4445ae4b67cb5e7893b *arm-wince.pe/upx-3.91.exe
|
||||
04c08626d4b03a4e969018eed7093c24de191b5d27db2a25221b134827806929 *arm64-linux.elf/upx-3.95
|
||||
6c8b276a0b611402d336b43cf8514b9a8d98be4f55a8301e784b7b88031b2b85 *armeb-linux.elf/upx-3.91
|
||||
dcd0c0060d44886966ae4e97b79a2c172f02d56228ea76dbc5c880ad59ef4ee5 *armeb-linux.elf/upx-3.95
|
||||
a7ee051c5f9dcf233e2ee248274121b99fb8f098eff95469bc0638a7423723f0 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
85cf31be166cb59587a99419cdd0fc5a79825d7508ab2c9a4bc0d700d603354d *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
fc7656d9a877967be7e339bfc98a0c63ea7b5abc30b96fa9e5931c75ecbe9827 *i386-linux.elf/upx-3.91
|
||||
d454a7639e96b986ad422b02045ecfefa3b9405901eaa32d92a2c489292b9600 *i386-linux.elf/upx-3.95
|
||||
934dd17076c0298d35a738533ea668e1fcbf8fc85c6671fcdd3a12e7722502ce *i386-win32.pe/upx-3.91.exe
|
||||
519a9f6b3de56f5f080151074b9d5d81e31c1961cd6e395f73d2d522b7f7f8e0 *i386-win32.pe/upx-3.95.exe
|
||||
a7bd9f616231d883f6700b09e3c9a0af2880c6b5e5b0ce1cd8f06de43c48856c *m68k-atari.tos/upx-3.91.ttp
|
||||
7a0479691e51ea4a8a0246a1f0ffa9694ee2f0e0cf3aa43dc0f1324c4d427ba3 *mips-linux.elf/upx-3.95
|
||||
f60bab42fe3914109ab1b9f5d00a5be753cd0a2c1a79a3998d58800efedbfff7 *mipsel-linux.elf/upx-3.91
|
||||
b6d8cc9e2023a3fc415166afc378ccf2eb505487df84c8d959ec74b3fb4f8256 *mipsel-linux.elf/upx-3.95
|
||||
acd3dc5ed3e4c4eeaa42e7cca71a79d687dd844ce5f384666ed6e78327b5a8e3 *powerpc-linux.elf/upx-3.91
|
||||
03600584c97fa466ef58239452baf9ec6ff2f06b79d97d45c8490953080de6e3 *powerpc-linux.elf/upx-3.95
|
||||
e615fc0e61d2bdd09f34275ec6c3de46fe5ce54da61cf5f5c94c40c6072bc1d6 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||
c5bafac11df5a38c1b72fd070373a0e1d5a066527129937c5bc9a280e21ad656 *amd64-linux.elf/upx-3.91
|
||||
6cc1e01ac0b6140464a06f5aefb51c0388fdfe28f264a38061b50b3508203c07 *amd64-linux.elf/upx-3.95
|
||||
5ab022e2c3ecb09931e2181fb5f7699f35e2b453b54c823e42653c84b0df5f2c *amd64-win64.pe/upx-3.95.exe
|
||||
e21b2305df2c1896eeae61010c3b65d8a50d476ea4a9bab6ec2fa4f9a0bed5a6 *arm-linux.elf/upx-3.95
|
||||
53121baf42c85991900aa3947f3d817fe6e894bc6f325ab1d576de6fba5fbcbf *arm-wince.pe/upx-3.91.exe
|
||||
7431abc46f0960311364ecd690965dd1fc74b2de4baca8e0af8f966735b6372e *arm64-linux.elf/upx-3.95
|
||||
8b67fc95dc555c2de4e3d0c85e4ab977f4c3fba24d68a2f9c402c51e08ad5f3b *armeb-linux.elf/upx-3.91
|
||||
c3b3e5b0a379022b26bae96432c3f5f946990f45b0b26afe056afe1170bf33c7 *armeb-linux.elf/upx-3.95
|
||||
51e4faea51e12c7442b27bb50150f532ac51d8102f77a669cbce82f2675a2ef2 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
1196f578ab0b862bae8ac6b5166b770f072cf0ac521a2a23a6347c19ea82a0da *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
3015651261f28fb43ed43a8c1fa257bcfcdc788e6fd3f436f3de23733736c724 *i386-linux.elf/upx-3.91
|
||||
8cca96ea354af889f5e9d3074b2c7005f982463a3f22e1cca2bc01aed9232de1 *i386-linux.elf/upx-3.95
|
||||
3edf364443a3cd56efd04e95cc7d7c1846bf76addedd7263cfe8330771f19509 *i386-win32.pe/upx-3.91.exe
|
||||
48141fd66443f85ea867d7fa0bb3a50debb10f15bdb26c71888026e17c88d3a8 *i386-win32.pe/upx-3.95.exe
|
||||
07e1c09a953a9c87afa33d1236f46244280161bf3802273a523d380318886177 *m68k-atari.tos/upx-3.91.ttp
|
||||
39b3a5c780d9354714d5e2ed69068511422f8faf9ab660706adc8ad5ecdf3598 *mips-linux.elf/upx-3.95
|
||||
123ce137e4cd555470fcf9fe67df75179b6f337fee66d075ddc06f9848817a37 *mipsel-linux.elf/upx-3.91
|
||||
b78d8cd3a3402fed266c737cc34a32cc21b2b67b573e9e9071d4faf9fca89b89 *mipsel-linux.elf/upx-3.95
|
||||
ea9cae1d1701db3a0c53e9a651766db5bdc30032f48913a4a9e99f193a800acc *powerpc-linux.elf/upx-3.91
|
||||
aea86bf87870a1e48a454ac1ea9a80d90d8abe5113d418a71d8a9c4a74bb2d0a *powerpc-linux.elf/upx-3.95
|
||||
5fbc114a7fec5ed8e098d8e918cdf7b446a8c9dc5496336fe077fe084dbea8ce *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||
509bc9676a0f5f5ce6df118da8e792151db816fcce5490eadc87fc525aad5a35 *amd64-linux.elf/upx-3.91
|
||||
e8d6bf8204c6bf5d170ca8d4c9cb48b3b7a48b04d665dd6e111980081fcba3b3 *amd64-linux.elf/upx-3.95
|
||||
7bd7cd37093200fa94d21dd7fdfef4d7fb9c3049fbf5f408f1f242cb8d9c6a55 *amd64-win64.pe/upx-3.95.exe
|
||||
4424d813ae55bec589779461c4d4b25361a58ea91659f4a12a7a2d08158cea64 *arm-linux.elf/upx-3.95
|
||||
ad0a7a18e87657d28260b7c527d284863becd3c5f92259c570125465f88d4042 *arm-wince.pe/upx-3.91.exe
|
||||
0bbeb73af475bc852313074a14360ae863364175d7fbd4c2f3450790bc3a58ee *arm64-linux.elf/upx-3.95
|
||||
7da4a04118f50824821c00f4f9abf6056128ac33de6ac45a145fb5d4810850d9 *armeb-linux.elf/upx-3.91
|
||||
b4191959889ecb2b9bd2dd046318b414ab5a8268517572017466fbc9c986925e *armeb-linux.elf/upx-3.95
|
||||
6fcdc8e34ce8b3501db2260c8a921c6e963954fdeffedfefca353a27bcc02d56 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
6f4f901c1838252f9b3104060475a6f13a2ebec830096ff28d870148580e4287 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
8127f8380300508e8062e9391e321abd0429a6a31fec41e769cc7fe80af27e27 *i386-linux.elf/upx-3.91
|
||||
b0a7e6b822f038b7940a54ea160b045d2241e3dfa15a5081a23fbc4d42fb6773 *i386-linux.elf/upx-3.95
|
||||
c78db15a8113b806e56812fd842fb467d2a9c9557fcdc0467dae3f4c33316630 *i386-win32.pe/upx-3.91.exe
|
||||
89314e8621c4a00e1a65e045686245d3c1e2ba0a858f1dcc8f3cc2d0eedccfb5 *i386-win32.pe/upx-3.95.exe
|
||||
710ad88b63cc7e0fa0b413ebdbcebf41140678f551b5dd883ed6220507be3601 *m68k-atari.tos/upx-3.91.ttp
|
||||
c7e3478872650b7f4f8ccb4a0649944e62f44f5a9249cb9425210333e1f2fdf4 *mips-linux.elf/upx-3.95
|
||||
cd9b3d3780a79cb416b261d622e8e86f2369fa8bb9bc49b529c50cac2980d528 *mipsel-linux.elf/upx-3.91
|
||||
5baf7db9e4335c0227106262efc9d18ad23b88c6d6bb636656aea67bb063b6ec *mipsel-linux.elf/upx-3.95
|
||||
aba8bd826ee52d533f9e1c4270d4f4194fe8d8747ea10a1d3ce59b6443f1a9f2 *powerpc-linux.elf/upx-3.91
|
||||
6f737ccbf8c830476bed9c4dd33dd7757ea25bf2f8fb03b44d03e9b77ada0f1b *powerpc-linux.elf/upx-3.95
|
||||
62eeb7b59d1eafa59cbb5ffa6572fd47560a8a8bf85274e711f29d2fe390c773 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||
ed2849169a873bb4070e9d878126f7bc19fb326d1dc6e169901ff3a3026661c3 *amd64-linux.elf/upx-3.91
|
||||
2b7f9baf27490274fe9301e8a962ac2bae03da0afec67c17df8f8f0e27157891 *amd64-linux.elf/upx-3.95
|
||||
a55ec5a7f2911f6da8b9336daf4f1051e753cfb7a4458c7f7baa6b63340c6daf *amd64-win64.pe/upx-3.95.exe
|
||||
8765db7ae04a03af743ad8afc586b943b84b65aca9f1ec240232daa2161ba703 *arm-linux.elf/upx-3.95
|
||||
7a6c603eecf214e5d6742f1fce922223c97c8bd2527678a968640dd6c1bc0d71 *arm-wince.pe/upx-3.91.exe
|
||||
810aa1e8f15d9617a0fac4bc4e5c5c5219fc44125d41ced661c744d6c5bb9857 *arm64-linux.elf/upx-3.95
|
||||
1dbb05c09fb972c3a5f87ace0c802af48f8b20f7f977f5a14b91dad59800d6a6 *armeb-linux.elf/upx-3.91
|
||||
a1fba814639540616175e0c058267e96f839d85a187b01af764af14ae1b6019c *armeb-linux.elf/upx-3.95
|
||||
7a8eaa5139b95cc56591200fce62d3c9af163671467952cab6fcf487318107bb *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
9b5fc0f54a5f811bda190c36fb2fa5c5b03c6c3de0c62693e4191230b5a419b8 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
68b4ce63cb0bd7dd5b287e1f9fa5d9bc234ac36359ce3ebff863984c503a698e *i386-linux.elf/upx-3.91
|
||||
aa75cf22f0b59cc796de678198432a3dc2d40ab871e4989dd97ff1a6c148f294 *i386-linux.elf/upx-3.95
|
||||
0e0780f5fccc52f6c78414f7279263b26e31de7c6ca1ec65a240e37cf0a4f5c9 *i386-win32.pe/upx-3.91.exe
|
||||
3ddd6265d69e374f5f0f8c9f602e0e59c895da2f3fef611ef89f0ee4ae2c592b *i386-win32.pe/upx-3.95.exe
|
||||
e268c98fdacfd04268d76644f2bb4746ae04b57801407aaa1867798840eeeea0 *m68k-atari.tos/upx-3.91.ttp
|
||||
499e1d1486810cfa5b6662e30189183979e25f45d35654d8cd60fd793d0c07d8 *mips-linux.elf/upx-3.95
|
||||
4a30189ad7312eafb2d47e1b526ec22eaf614a895f8dce96f3e1c7385438f44c *mipsel-linux.elf/upx-3.91
|
||||
339d38602413d97d9bba113f39884815af10ebcdccf37e3f5e8d0879f262a048 *mipsel-linux.elf/upx-3.95
|
||||
6d4f9d4383ebc9d8411d06a7c219dcf3e8513ea8c989f2d31ab382602f873ba5 *powerpc-linux.elf/upx-3.91
|
||||
5dd727d8d5a35cc0ab86d629285d8ff450f52b538118679edaa886ce9c1fed7d *powerpc-linux.elf/upx-3.95
|
||||
7b9aeffda399143db878f24a9faecdc21fb8ec906fed80bc6636d82771090f2f *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||
fc30606d37c697f5c79742bf6e7d2afa8503e69fc87e52274d00b5210d03157a *amd64-linux.elf/upx-3.91
|
||||
c6d66f6d4f92812801c021a854fbd94745a7b63e0477678b8eb1dc26c5b0a9a4 *amd64-linux.elf/upx-3.95
|
||||
cbb5c90bd9195bd9e3acd931312a70deeccfab5540f398ceda8826f8d6b332bf *amd64-win64.pe/upx-3.95.exe
|
||||
bb88759de778b1099b51a012f915e646ebfddcbd2fb26b3a1e760fc81a41d2b9 *arm-linux.elf/upx-3.95
|
||||
76a5f0518fc797bd3f132ce6eb61ca187b5d463f191417883a73d4584716c23a *arm-wince.pe/upx-3.91.exe
|
||||
7b9290c2ab01632d8baa28b24498fbcd734caf8e3846864bb62a8282de3ffd9a *arm64-linux.elf/upx-3.95
|
||||
0bafd7837327b590b3be06676ee73c52405e5e4a36a6d06f8b6773e93c499420 *armeb-linux.elf/upx-3.91
|
||||
aea39071ff8ce0b2a59f30e50603ef2ec39789693a3dd9baa4e6be1e49b4e068 *armeb-linux.elf/upx-3.95
|
||||
aa05c3a2953f0f2d70842cba45786b707a79ffef22fd084f51e304762cc67765 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
c677241e9a8753ba1332ac3875ab6398fb2d792d2627edd9e58f2535b3131abe *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
7bcd42f58dcc8ddb6cb1a4e33d56b584fe6d49b002b01a0859571d1324dd593a *i386-linux.elf/upx-3.91
|
||||
b6fe6220c0b3f4df131da3aaae566810f2aa1f13b63d23de3ead9174d08d82e1 *i386-linux.elf/upx-3.95
|
||||
8ec02f816f4727b519e8775edc1afb1df32991319a6c6f050ece416011925379 *i386-win32.pe/upx-3.91.exe
|
||||
d5aeeedada49c0c2870ea450ed66b2cea31369bccfccf9407378ae0fb0736deb *i386-win32.pe/upx-3.95.exe
|
||||
e414ad0aba43790d0498b26c23055fb051129b6cbe3e070a1406c91ac5b8032b *m68k-atari.tos/upx-3.91.ttp
|
||||
c5107a84d32de820c81401259a7dd23435ea625588d56c6c75ad6fa14b0dbf8b *mips-linux.elf/upx-3.95
|
||||
78473f7d7ddf56812b8dee087ca62517ecdbd10fa14972ba6670338fc19061d1 *mipsel-linux.elf/upx-3.91
|
||||
fd9ea397a29b41a2143f9e02217e181d0075d7ad7d87bdbadc7fc94bfb1b0d76 *mipsel-linux.elf/upx-3.95
|
||||
c47d1299f6ecf86e62528fc54979117b2b2ddbb6c80f553689402399fc7eab28 *powerpc-linux.elf/upx-3.91
|
||||
77c3b4ba6909a4e20180bc13775e280086d67240519c323c2005f3fcee6e0b78 *powerpc-linux.elf/upx-3.95
|
||||
030a1ac080381a5ec7ad1e167f8809709620e555db792f43146c8c34e2cb37ec *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||
115046275f6bccbaa34b7aefbedeba8741aba4e4876340a3d7363bae86ee4209 *amd64-linux.elf/upx-3.91
|
||||
a8394890b5d731258316b520da2a5e4b43902742d237536fb7fbc578c6197fbb *amd64-linux.elf/upx-3.95
|
||||
5a0ecb45658904bcd0b823b77dba039c9814e2eff4ed429784c36b7074b9858c *amd64-win64.pe/upx-3.95.exe
|
||||
0976be6c56de1ac2314d8a4962ae3d9d7be962847600db5e2bab529ab32cebd6 *arm-linux.elf/upx-3.95
|
||||
fdbe0395ac401285edb9c2f9bfbb0fbd3c0eaad5052a88d8369b1a66b35a8a3e *arm-wince.pe/upx-3.91.exe
|
||||
1c8d536870d0244bb12cb8fdd6cd35ad7e9a53bbc4aa8e2e12af72447caaf467 *arm64-linux.elf/upx-3.95
|
||||
912b6ca141a028974bc46aeb571314db371647201974283992752933f39200b1 *armeb-linux.elf/upx-3.91
|
||||
0b5757e474bcf3136edf10e403f95e706b214a5cf7d8577fbf7778175b1bef61 *armeb-linux.elf/upx-3.95
|
||||
0a0099246096d20ff6035a4df6566954b9d8aff9ed8fdbd35aa5ee4995b02bfe *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
5df7aa9f0896df87eb8798119ad16a9b89c87a7568a67339e33b5baa99ec361f *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
53e5aae9bc70f58e3dc2aef5a94f66df2517d547670e72ee2b3189b7da809f41 *i386-linux.elf/upx-3.91
|
||||
adaa1e2f46f7a235ab838b15aa7e820057e5ed7011d9d07c67dc770a88e3dd62 *i386-linux.elf/upx-3.95
|
||||
f3d33c5c9809943a902133490bcf0cfbe39a5ef1635a0c29b3bdc4f35dfffa50 *i386-win32.pe/upx-3.91.exe
|
||||
474e68a2390cf0376f59402eaef4c902daa49428b628e025b1c8506428a37937 *i386-win32.pe/upx-3.95.exe
|
||||
1561dd69f67e8705804dba41ebd876bce6a4ce8ed8b0bc0d0e7628697e7fee68 *m68k-atari.tos/upx-3.91.ttp
|
||||
74f7f69b4a8b2b7c428fa55e3970ee767c1947f19ed1b0644870ecb6b3cb713d *mips-linux.elf/upx-3.95
|
||||
12a42365234c001a52586b74a9597dc7d65184ddf1ee1d40734823a3443cd92a *mipsel-linux.elf/upx-3.91
|
||||
68f674d081d87e86e54f0051eee9e2bc85b566051992774ab28ff3173cbcb75a *mipsel-linux.elf/upx-3.95
|
||||
f569d8f49d7110bb8b262a48055b39d889e9977c40c5f1b21e74f8cbf93b27ae *powerpc-linux.elf/upx-3.91
|
||||
d8227a8a88c083760889acaf259e7da59eab75a23e341289bc8e3c60563ae344 *powerpc-linux.elf/upx-3.95
|
||||
8260862f104a23c2a3fa574e10d882204ed40a17702040edbbbc8d25f961163f *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||
09cee61e2a4e94455d75a76711078719c3ca7fab77f047c4c85c9424e651956d *amd64-linux.elf/upx-3.91
|
||||
0196cbaa36e5224b26729f1bb13990327878ffb0d2cd5784f8fbe715f12dcc1c *amd64-linux.elf/upx-3.95
|
||||
e07e9babdeb12fddeebbfa1b0293163cc5e63017d6f0933d02587c8da1e90a82 *amd64-win64.pe/upx-3.95.exe
|
||||
4b93e4dd9baea301479fa989d935b7b6b43b2b54464c5def0db1a00b6a15d719 *arm-linux.elf/upx-3.95
|
||||
8d1706ab02013b536c3a4cec20d40a96591ffa45fdcb464ccd3f038567006d79 *arm-wince.pe/upx-3.91.exe
|
||||
be753ff9bc789d80f32cec35cc0f9c67b102d297f607b328779ba8d80da13593 *arm64-linux.elf/upx-3.95
|
||||
4c6d40107b5bce15a40aef514b57ac6dd644162998915aee412feca21582118a *armeb-linux.elf/upx-3.91
|
||||
9d70d663c00378aa1c1c43d55327a895be33ea081bac13ce8a7ea6895b539679 *armeb-linux.elf/upx-3.95
|
||||
dda2c348c43741a1bd65049a8e7b51be1ebf873d215370ec002185c85390c168 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
560392427ded22f2f3fea59ef10e55d65cf841001e67b1e4558ef13514baa602 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
f3f8feceebe8536633554b204df68c2e94e1d1a313fe7a576b7f5d404c916083 *i386-linux.elf/upx-3.91
|
||||
e7f98419e346670f72d66ac25f3d6ad53201e768819980eecae24d801366be27 *i386-linux.elf/upx-3.95
|
||||
3510bc5627237752bedd275e73c42bc02cd46145ff916e7bccbdec663f763ee4 *i386-win32.pe/upx-3.91.exe
|
||||
ad47c7522167f6f7e47d495e1fa119431386ca5ea9bc16b6a4b9cb38cf9cd29f *i386-win32.pe/upx-3.95.exe
|
||||
1c999e5c6cded8c99a7f6b4595879893ae63d2af1388dc61dd8b4e3106676480 *m68k-atari.tos/upx-3.91.ttp
|
||||
55a098c2cdce1917b76ce0845f434fc23b0bd30b34e884b19401c51c8c7f4756 *mips-linux.elf/upx-3.95
|
||||
4b6487d412f43acb8e41951a2135e56025139a9ad3e57102749df4d4bef934fa *mipsel-linux.elf/upx-3.91
|
||||
1dcd626fc4566c608e987fd6999b695793c5cae7f78872e3d1a9a23942fea188 *mipsel-linux.elf/upx-3.95
|
||||
2047a4a880322bf41e8afbb4787f6103364de4a299b543808251a4144c4d990b *powerpc-linux.elf/upx-3.91
|
||||
63679bd238f30bfb14853246eb257536471fea10f942b2adfdd43cbef21dea30 *powerpc-linux.elf/upx-3.95
|
||||
bee0b9b5fa783550d3e7e5ba6e48d92776578dd82d6ac644e14191e0879d185b *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
########## end .sha256sums.recreate
|
||||
Executable
+336
@@ -0,0 +1,336 @@
|
||||
#! /usr/bin/env bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||
|
||||
#
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
# very first version of the upx-testsuite; requires:
|
||||
# $upx_exe (required, but with convenience fallback "./upx")
|
||||
# $upx_testsuite_SRCDIR (required, but with convenience fallback)
|
||||
# $upx_testsuite_BUILDDIR (optional)
|
||||
#
|
||||
# optional settings:
|
||||
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||
# $UPX_TESTSUITE_VERBOSE
|
||||
# $UPX_TESTSUITE_LEVEL
|
||||
#
|
||||
# see https://github.com/upx/upx-testsuite.git
|
||||
#
|
||||
|
||||
#***********************************************************************
|
||||
# init & checks
|
||||
#***********************************************************************
|
||||
|
||||
# upx_exe
|
||||
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
# usage examples:
|
||||
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||
# export upx_exe_runner="wine"
|
||||
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||
fi
|
||||
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
|
||||
# run_upx sanity check
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
|
||||
# upx_testsuite_SRCDIR
|
||||
if [[ -z $upx_testsuite_SRCDIR ]]; then
|
||||
# convenience fallback: search standard locations below upx top-level directory
|
||||
if [[ -d "$argv0dir/../../../upx--upx-testsuite.git/files/packed" ]]; then
|
||||
upx_testsuite_SRCDIR="$argv0dir/../../../upx--upx-testsuite.git"
|
||||
elif [[ -d "$argv0dir/../../../upx-testsuite.git/files/packed" ]]; then
|
||||
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite.git"
|
||||
elif [[ -d "$argv0dir/../../../upx-testsuite/files/packed" ]]; then
|
||||
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite"
|
||||
fi
|
||||
fi
|
||||
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
||||
echo "invalid or missing \$upx_testsuite_SRCDIR:"
|
||||
echo " please git clone https://github.com/upx/upx-testsuite.git"
|
||||
echo " and set (export) the envvar upx_testsuite_SRCDIR to the local file path"
|
||||
exit 1
|
||||
fi
|
||||
upx_testsuite_SRCDIR=$(readlink -fn "$upx_testsuite_SRCDIR") # make absolute
|
||||
[[ -d $upx_testsuite_SRCDIR ]] || exit 1
|
||||
|
||||
# upx_testsuite_BUILDDIR
|
||||
if [[ -z $upx_testsuite_BUILDDIR ]]; then
|
||||
upx_testsuite_BUILDDIR="./tmp-upx-testsuite"
|
||||
fi
|
||||
mkdir -p "$upx_testsuite_BUILDDIR" || exit 1
|
||||
upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
|
||||
[[ -d $upx_testsuite_BUILDDIR ]] || exit 1
|
||||
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
||||
: > ./.mfxnobackup
|
||||
|
||||
# run_upx sanity check after "cd"
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then
|
||||
echo "UPX-ERROR: FATAL: upx --version-short FAILED"
|
||||
echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
|
||||
echo "INFO: run_upx='${run_upx[*]}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#***********************************************************************
|
||||
# setup
|
||||
#***********************************************************************
|
||||
|
||||
#set -x # debug
|
||||
|
||||
exit_code=0
|
||||
num_errors=0
|
||||
all_errors=
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||
|
||||
case $UPX_TESTSUITE_LEVEL in
|
||||
[0-8]) ;;
|
||||
*) UPX_TESTSUITE_LEVEL=999 ;;
|
||||
esac
|
||||
if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
|
||||
echo "UPX testsuite SKIPPED."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
rm -rf ./testsuite_1
|
||||
mkdir testsuite_1 || exit 1
|
||||
cd testsuite_1 || exit 1
|
||||
|
||||
#***********************************************************************
|
||||
# support functions
|
||||
#***********************************************************************
|
||||
|
||||
run_upx() {
|
||||
local flags="--disable-random-id --fake-stub-version=5.01 --fake-stub-year=2025"
|
||||
local ec=0
|
||||
if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then
|
||||
echo "LOG: '${run_upx[*]}' $*"
|
||||
fi
|
||||
"${run_upx[@]}" $flags "$@" || ec=$?
|
||||
if [[ $ec != 0 ]]; then
|
||||
echo "FATAL: '${run_upx[*]}' $*"
|
||||
echo " (exit code was $ec)"
|
||||
exit 42
|
||||
fi
|
||||
}
|
||||
|
||||
testsuite_header() {
|
||||
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||
echo -e "\n${x}\n${1}\n${x}\n"
|
||||
}
|
||||
|
||||
testsuite_split_f() {
|
||||
fd=$(dirname "$1")
|
||||
fb=$(basename "$1")
|
||||
fsubdir=$(basename "$fd")
|
||||
# sanity checks
|
||||
if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then
|
||||
fd=''; fb=''; fsubdir=''
|
||||
fi
|
||||
}
|
||||
|
||||
testsuite_check_sha() {
|
||||
(cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
||||
echo
|
||||
cat $1/.sha256sums.current
|
||||
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
||||
echo "UPX-ERROR: $1 FAILED: checksum mismatch"
|
||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||
exit_code=99
|
||||
let num_errors+=1 || true
|
||||
all_errors="${all_errors} $1"
|
||||
#exit 99
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
testsuite_check_sha_decompressed() {
|
||||
(cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
||||
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
||||
cat $1/.sha256sums.current
|
||||
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
|
||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||
exit 98
|
||||
fi
|
||||
}
|
||||
|
||||
testsuite_use_canonicalized=1
|
||||
testsuite_run_compress() {
|
||||
testsuite_header $testdir
|
||||
local files f
|
||||
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
||||
files='t020_canonicalized/*/*'
|
||||
else
|
||||
files='t010_decompressed/*/*'
|
||||
fi
|
||||
for f in $files; do
|
||||
testsuite_split_f "$f"
|
||||
[[ -z $fb ]] && continue
|
||||
echo "# $f"
|
||||
mkdir -p "$testdir/$fsubdir" "$testdir/.decompressed/$fsubdir"
|
||||
run_upx -qq --prefer-ucl "$@" "$f" -o "$testdir/$fsubdir/$fb"
|
||||
run_upx -qq -d "$testdir/$fsubdir/$fb" -o "$testdir/.decompressed/$fsubdir/$fb"
|
||||
done
|
||||
testsuite_check_sha $testdir
|
||||
run_upx -qq -l "$testdir"/*/*
|
||||
run_upx -qq --file-info "$testdir"/*/*
|
||||
run_upx -q -t "$testdir"/*/*
|
||||
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
||||
# check that after decompression the file matches the canonicalized version
|
||||
cp t020_canonicalized/.sha256sums.expected $testdir/.decompressed/
|
||||
testsuite_check_sha_decompressed $testdir/.decompressed
|
||||
rm -rf "./$testdir/.decompressed"
|
||||
fi
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# expected checksums
|
||||
#
|
||||
# To ease maintenance of this script in case of updates this section
|
||||
# can be automatically re-created from the current checksums -
|
||||
# see call of function recreate_expected_sha256sums below.
|
||||
#***********************************************************************
|
||||
|
||||
recreate_expected_sha256sums() {
|
||||
local o="$1"
|
||||
local files f d
|
||||
echo "########## begin .sha256sums.recreate" > "$o"
|
||||
files='*/.sha256sums.current'
|
||||
for f in $files; do
|
||||
d=$(dirname "$f")
|
||||
echo "expected_sha256sums__${d}="'"\' >> "$o"
|
||||
cat "$f" >> "$o"
|
||||
echo '"' >> "$o"
|
||||
done
|
||||
echo "########## end .sha256sums.recreate" >> "$o"
|
||||
}
|
||||
|
||||
source "$argv0dir/upx_testsuite_1-expected_sha256sums.sh" || exit 1
|
||||
|
||||
#***********************************************************************
|
||||
# decompression tests
|
||||
#***********************************************************************
|
||||
|
||||
testdir=t010_decompressed
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
|
||||
testsuite_header $testdir
|
||||
for f in "$upx_testsuite_SRCDIR"/files/packed/*/upx-3.9[15]*; do
|
||||
testsuite_split_f "$f"
|
||||
[[ -z $fb ]] && continue
|
||||
echo "# $f"
|
||||
mkdir -p "$testdir/$fsubdir"
|
||||
run_upx -qq -d "$f" -o "$testdir/$fsubdir/$fb"
|
||||
done
|
||||
testsuite_check_sha $testdir
|
||||
|
||||
# run one pack+unpack step to canonicalize the files
|
||||
testdir=t020_canonicalized
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
|
||||
testsuite_header $testdir
|
||||
for f in t010_decompressed/*/*; do
|
||||
testsuite_split_f "$f"
|
||||
[[ -z $fb ]] && continue
|
||||
echo "# $f"
|
||||
mkdir -p "$testdir/$fsubdir/.packed"
|
||||
run_upx -qq --prefer-ucl -1 "$f" -o "$testdir/$fsubdir/.packed/$fb"
|
||||
run_upx -qq -d "$testdir/$fsubdir/.packed/$fb" -o "$testdir/$fsubdir/$fb"
|
||||
done
|
||||
testsuite_check_sha $testdir
|
||||
|
||||
#***********************************************************************
|
||||
# compression tests
|
||||
# info: we use fast compression levels because we want to
|
||||
# test UPX and not the compression libraries
|
||||
#***********************************************************************
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 2 ]]; then
|
||||
testdir=t110_compress_ucl_nrv2b_3_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --nrv2b -3 --no-filter
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 3 ]]; then
|
||||
testdir=t120_compress_ucl_nrv2d_3_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --nrv2d -3 --no-filter
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 4 ]]; then
|
||||
testdir=t130_compress_ucl_nrv2e_3_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --nrv2e -3 --no-filter
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 5 ]]; then
|
||||
testdir=t140_compress_lzma_2_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --lzma -2 --no-filter
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 6 ]]; then
|
||||
testdir=t150_compress_ucl_2_all_filters
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress -2 --all-filters
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 7 ]]; then
|
||||
testdir=t160_compress_all_methods_1_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --all-methods -1 --no-filter
|
||||
fi
|
||||
|
||||
if [[ $UPX_TESTSUITE_LEVEL -ge 8 ]]; then
|
||||
testdir=t170_compress_all_methods_no_lzma_5_no_filter
|
||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
|
||||
fi
|
||||
|
||||
#***********************************************************************
|
||||
# summary
|
||||
#***********************************************************************
|
||||
|
||||
# recreate checksums from current version for an easy update in case of changes
|
||||
recreate_expected_sha256sums .sha256sums.recreate
|
||||
|
||||
testsuite_header "UPX testsuite summary: level $UPX_TESTSUITE_LEVEL"
|
||||
run_upx --version-short
|
||||
echo
|
||||
echo "upx_exe='$upx_exe'"
|
||||
ls -l "$upx_exe"
|
||||
if command -v file >/dev/null; then
|
||||
file "$upx_exe" || true
|
||||
fi
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'"
|
||||
echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'"
|
||||
echo ".sha256sums.{expected,current} counts:"
|
||||
cat ./*/.sha256sums.expected | LC_ALL=C sort | wc
|
||||
cat ./*/.sha256sums.current | LC_ALL=C sort | wc
|
||||
echo
|
||||
if [[ $exit_code == 0 ]]; then
|
||||
echo "UPX testsuite passed. All done."
|
||||
else
|
||||
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
|
||||
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
|
||||
fi
|
||||
exit $exit_code
|
||||
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# valgrind suppressions for musl libc
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
# musl malloc
|
||||
{
|
||||
musl-malloc-enframe
|
||||
Memcheck:Cond
|
||||
fun:enframe
|
||||
}
|
||||
|
||||
# these are only needed for older musl versions
|
||||
|
||||
{
|
||||
musl-malloc-mal0_clear
|
||||
Memcheck:Cond
|
||||
fun:mal0_clear
|
||||
fun:calloc
|
||||
}
|
||||
|
||||
{
|
||||
musl-string-memchr
|
||||
Memcheck:Cond
|
||||
fun:memchr
|
||||
}
|
||||
{
|
||||
musl-string-stpcpy
|
||||
Memcheck:Cond
|
||||
fun:stpcpy
|
||||
}
|
||||
{
|
||||
musl-string-strchrnul
|
||||
Memcheck:Cond
|
||||
fun:strchrnul
|
||||
}
|
||||
{
|
||||
musl-string-strlen
|
||||
Memcheck:Cond
|
||||
fun:strlen
|
||||
}
|
||||
+85
-88
@@ -1,111 +1,108 @@
|
||||
#
|
||||
# UPX Makefile - needs GNU make 3.81 or better
|
||||
# UPX src Makefile - needs GNU make and CMake >= 3.13
|
||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
export SHELL = /bin/sh
|
||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||
|
||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||
$(error GNU make 3.81 or better is required)
|
||||
endif
|
||||
# NOTE: this Makefile is intended for developers - please use
|
||||
# the top-level Makefile instead
|
||||
|
||||
ifndef srcdir
|
||||
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
||||
srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||
endif
|
||||
ifndef top_srcdir
|
||||
top_srcdir := $(srcdir)/..
|
||||
endif
|
||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||
ifneq ($(srcdir),.)
|
||||
##$(info Info: using VPATH . $(srcdir))
|
||||
VPATH := . $(srcdir)
|
||||
top_srcdir := $(srcdir)/..
|
||||
endif
|
||||
|
||||
ifeq ($(CXX),)
|
||||
CXX = g++
|
||||
endif
|
||||
ifneq ($(findstring $(firstword $(CXX)),g++),)
|
||||
USE_GNUC ?= 1
|
||||
endif
|
||||
ifeq ($(USE_GNUC),1)
|
||||
ifeq ($(DEBUG),1)
|
||||
CXXFLAGS += -O0 -g
|
||||
else
|
||||
CXXFLAGS += -O2
|
||||
endif
|
||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
||||
##CXXFLAGS += -Wshadow
|
||||
endif
|
||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||
CXXLD ?= $(CXX)
|
||||
#***********************************************************************
|
||||
# redirect to top-level Makefile
|
||||
#***********************************************************************
|
||||
|
||||
exeext ?= .out
|
||||
libext ?= .a
|
||||
objext ?= .o
|
||||
# NOTE that the top-level Makefile .DEFAULT_GOAL is build/release
|
||||
.DEFAULT_GOAL = build/all
|
||||
|
||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||
.PHONY: PHONY
|
||||
.SECONDEXPANSION:
|
||||
.SUFFIXES:
|
||||
|
||||
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
||||
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
||||
INCLUDES += -I$(UPX_UCLDIR)/include
|
||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
||||
build/debug build/release build/all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||
build/debug+test build/release+test build/all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||
# shortcuts
|
||||
debug release all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||
debug+test release+test all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||
|
||||
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||
|
||||
#***********************************************************************
|
||||
# make run-testsuite
|
||||
# git clone https://github.com/upx/upx-testsuite.git
|
||||
#***********************************************************************
|
||||
|
||||
# search for the UPX testsuite; you can override by setting "upx_testsuite_SRCDIR"
|
||||
ifndef upx_testsuite_SRCDIR
|
||||
# search standard locations below $(top_srcdir)
|
||||
ifneq ($(wildcard $(top_srcdir)/../upx--upx-testsuite.git/files/packed/.),)
|
||||
upx_testsuite_SRCDIR := $(top_srcdir)/../upx--upx-testsuite.git
|
||||
else ifneq ($(wildcard $(top_srcdir)/../upx-testsuite.git/files/packed/.),)
|
||||
upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite.git
|
||||
else ifneq ($(wildcard $(top_srcdir)/../upx-testsuite/files/packed/.),)
|
||||
upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite
|
||||
endif
|
||||
LIBS += -lucl -lz
|
||||
# you should set envvar UPX_LZMADIR to point to your unpacked LZMA SDK
|
||||
include $(top_srcdir)/src/stub/src/c/Makevars.lzma
|
||||
ifneq ($(UPX_LZMA_VERSION),)
|
||||
DEFS += -DWITH_LZMA=$(UPX_LZMA_VERSION)
|
||||
INCLUDES += -I$(UPX_LZMADIR)
|
||||
endif
|
||||
|
||||
|
||||
all: upx$(exeext) | .depend
|
||||
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .depend
|
||||
|
||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||
$($(notdir $@).PRE_LINK_STEP)
|
||||
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
||||
$($(notdir $@).POST_LINK_STEP)
|
||||
|
||||
%.o : %.cpp | .depend
|
||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||
|
||||
.depend: $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h) $(MAKEFILE_LIST)
|
||||
@rm -f $@
|
||||
ifeq ($(USE_GNUC),1)
|
||||
@echo "Updating $@"
|
||||
@$(strip $(CXX) $(call e,CPPFLAGS) -MM) $(filter %.cpp,$^) > $@
|
||||
else
|
||||
touch $@
|
||||
# run the UPX testsuite
|
||||
# The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
|
||||
# The actual (new) checksums are in ./tmp-upx-testsuite-*/testsuite_1/.sha256sums.recreate
|
||||
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
|
||||
ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
|
||||
run-testsuite: run-testsuite-release PHONY
|
||||
run-testsuite-all: run-testsuite-debug run-testsuite-release PHONY
|
||||
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||
run-testsuite-debug: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-debug
|
||||
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
|
||||
run-testsuite-debug: build/debug PHONY
|
||||
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
|
||||
run-testsuite-release: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-release
|
||||
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
|
||||
run-testsuite-release: build/release PHONY
|
||||
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
|
||||
endif
|
||||
endif
|
||||
|
||||
#***********************************************************************
|
||||
# make check-whitespace
|
||||
#***********************************************************************
|
||||
|
||||
ifeq ($(USE_GNUC),1)
|
||||
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-cast-qual
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
||||
ifeq ($(UPX_LZMA_VERSION),0x443)
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-non-virtual-dtor
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||
endif
|
||||
# needed for gcc-4.3:
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
|
||||
|
||||
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
|
||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
||||
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
||||
endif
|
||||
check-whitespace: PHONY; $(CHECK_WHITESPACE)
|
||||
|
||||
endif # /usr/bin/env
|
||||
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f *.d *.map *.o *.obj *.res .depend upx.exe upx.out upx.ttp upx$(exeext)
|
||||
#***********************************************************************
|
||||
# make clang-format
|
||||
#***********************************************************************
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
# automatically format most C++ source code files
|
||||
ifneq ($(wildcard /usr/bin/env),)
|
||||
ifeq ($(shell uname),Linux)
|
||||
|
||||
ifeq ($(MAKECMDGOALS),mostlyclean)
|
||||
else ifeq ($(MAKECMDGOALS),clean)
|
||||
else ifeq ($(MAKECMDGOALS),distclean)
|
||||
else ifeq ($(MAKECMDGOALS),maintainer-clean)
|
||||
else
|
||||
-include .depend
|
||||
endif
|
||||
# Markus loves clang-format, but John hates it; find a compromise
|
||||
CLANG_FORMAT_EXCLUDE_FILES += stub/%.h util/miniacc.h
|
||||
CLANG_FORMAT_EXCLUDE_FILES += p_lx_% p_mach% p_unix% p_vmlin%
|
||||
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
|
||||
CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
|
||||
CLANG_FORMAT_FILES += $(sort $(wildcard ../misc/cmake/try_compile/*.[ch]*))
|
||||
CLANG_FORMAT_FILES := $(sort $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)))
|
||||
clang-format: $(CLANG_FORMAT_FILES) PHONY
|
||||
@echo "running upx-clang-format"
|
||||
@bash $(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
|
||||
|
||||
endif # Linux
|
||||
endif # /usr/bin/env
|
||||
|
||||
# vim:set ts=8 sw=8 noet:
|
||||
|
||||
+1015
-505
File diff suppressed because it is too large
Load Diff
+94
-148
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,56 +22,52 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_BELE_H
|
||||
# error "this is an internal include file"
|
||||
#endif
|
||||
|
||||
// this is an internal include file private to bele.h
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(BELE_CTP)
|
||||
// CTP - Compile-Time Polymorphism (templates)
|
||||
# define V static inline
|
||||
# define S static int __acc_cdecl_qsort
|
||||
# define C
|
||||
// CTP - Compile-Time Polymorphism (templates)
|
||||
#define V static inline bele_constexpr
|
||||
#define VV static forceinline_constexpr
|
||||
#define S static int __acc_cdecl_qsort
|
||||
#define C noexcept
|
||||
#elif defined(BELE_RTP)
|
||||
// RTP - Run-Time Polymorphism (virtual functions)
|
||||
# define V virtual
|
||||
# define S virtual int
|
||||
# define C const
|
||||
// RTP - Run-Time Polymorphism (virtual functions)
|
||||
#define V virtual
|
||||
#define VV virtual
|
||||
#define S virtual int
|
||||
#define C const noexcept
|
||||
#else
|
||||
# error
|
||||
#error
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BELE_RTP)
|
||||
struct AbstractPolicy
|
||||
{
|
||||
inline AbstractPolicy() { }
|
||||
virtual inline ~AbstractPolicy() { }
|
||||
struct AbstractPolicy {
|
||||
explicit inline AbstractPolicy() noexcept = default;
|
||||
virtual inline ~AbstractPolicy() noexcept {}
|
||||
V bool isBE() C = 0;
|
||||
V bool isLE() C = 0;
|
||||
|
||||
V unsigned get16(const void *p) C = 0;
|
||||
V unsigned get24(const void *p) C = 0;
|
||||
V unsigned get32(const void *p) C = 0;
|
||||
V acc_uint64l_t get64(const void *p) C = 0;
|
||||
V upx_uint64_t get64(const void *p) C = 0;
|
||||
|
||||
V void set16(void *p, unsigned v) C = 0;
|
||||
V void set24(void *p, unsigned v) C = 0;
|
||||
V void set32(void *p, unsigned v) C = 0;
|
||||
V void set64(void *p, acc_uint64l_t v) C = 0;
|
||||
V void set64(void *p, upx_uint64_t v) C = 0;
|
||||
|
||||
V unsigned get16_signed(const void *p) C = 0;
|
||||
V unsigned get24_signed(const void *p) C = 0;
|
||||
V unsigned get32_signed(const void *p) C = 0;
|
||||
V acc_uint64l_t get64_signed(const void *p) C = 0;
|
||||
V int get16_signed(const void *p) C = 0;
|
||||
V int get24_signed(const void *p) C = 0;
|
||||
V int get32_signed(const void *p) C = 0;
|
||||
V upx_int64_t get64_signed(const void *p) C = 0;
|
||||
|
||||
S u16_compare(const void *a, const void *b) C = 0;
|
||||
S u24_compare(const void *a, const void *b) C = 0;
|
||||
@@ -83,74 +79,61 @@ struct AbstractPolicy
|
||||
S u32_compare_signed(const void *a, const void *b) C = 0;
|
||||
S u64_compare_signed(const void *a, const void *b) C = 0;
|
||||
|
||||
private:
|
||||
// disable copy and move
|
||||
UPX_CXX_DISABLE_COPY_MOVE(AbstractPolicy)
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
UPX_CXX_DISABLE_NEW_DELETE(AbstractPolicy)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(BELE_RTP)
|
||||
#undef C
|
||||
#define C const noexcept override
|
||||
#endif
|
||||
|
||||
struct BEPolicy
|
||||
struct BEPolicy final
|
||||
#if defined(BELE_RTP)
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
inline BEPolicy() { }
|
||||
explicit inline BEPolicy() noexcept = default;
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||
#endif
|
||||
V bool isBE() C { return true; }
|
||||
V bool isLE() C { return false; }
|
||||
VV bool isBE() C { return true; }
|
||||
VV bool isLE() C { return false; }
|
||||
|
||||
typedef BE16 U16;
|
||||
typedef BE32 U32;
|
||||
typedef BE64 U64;
|
||||
|
||||
V unsigned get16(const void *p) C
|
||||
{ return get_be16(p); }
|
||||
V unsigned get24(const void *p) C
|
||||
{ return get_be24(p); }
|
||||
V unsigned get32(const void *p) C
|
||||
{ return get_be32(p); }
|
||||
V acc_uint64l_t get64(const void *p) C
|
||||
{ return get_be64(p); }
|
||||
V unsigned get16(const void *p) C { return get_be16(p); }
|
||||
V unsigned get24(const void *p) C { return get_be24(p); }
|
||||
V unsigned get32(const void *p) C { return get_be32(p); }
|
||||
V upx_uint64_t get64(const void *p) C { return get_be64(p); }
|
||||
|
||||
V void set16(void *p, unsigned v) C
|
||||
{ set_be16(p, v); }
|
||||
V void set24(void *p, unsigned v) C
|
||||
{ set_be24(p, v); }
|
||||
V void set32(void *p, unsigned v) C
|
||||
{ set_be32(p, v); }
|
||||
V void set64(void *p, acc_uint64l_t v) C
|
||||
{ set_be64(p, v); }
|
||||
V void set16(void *p, unsigned v) C { set_be16(p, v); }
|
||||
V void set24(void *p, unsigned v) C { set_be24(p, v); }
|
||||
V void set32(void *p, unsigned v) C { set_be32(p, v); }
|
||||
V void set64(void *p, upx_uint64_t v) C { set_be64(p, v); }
|
||||
|
||||
V unsigned get16_signed(const void *p) C
|
||||
{ return get_be16_signed(p); }
|
||||
V unsigned get24_signed(const void *p) C
|
||||
{ return get_be24_signed(p); }
|
||||
V unsigned get32_signed(const void *p) C
|
||||
{ return get_be32_signed(p); }
|
||||
V acc_uint64l_t get64_signed(const void *p) C
|
||||
{ return get_be64_signed(p); }
|
||||
V int get16_signed(const void *p) C { return get_be16_signed(p); }
|
||||
V int get24_signed(const void *p) C { return get_be24_signed(p); }
|
||||
V int get32_signed(const void *p) C { return get_be32_signed(p); }
|
||||
V upx_int64_t get64_signed(const void *p) C { return get_be64_signed(p); }
|
||||
|
||||
S u16_compare(const void *a, const void *b) C
|
||||
{ return be16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C
|
||||
{ return be24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C
|
||||
{ return be32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C
|
||||
{ return be64_compare(a, b); }
|
||||
S u16_compare(const void *a, const void *b) C { return be16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C { return be24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C { return be32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C { return be64_compare(a, b); }
|
||||
|
||||
S u16_compare_signed(const void *a, const void *b) C
|
||||
{ return be16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C
|
||||
{ return be24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C
|
||||
{ return be32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C
|
||||
{ return be64_compare_signed(a, b); }
|
||||
S u16_compare_signed(const void *a, const void *b) C { return be16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C { return be24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C { return be32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C { return be64_compare_signed(a, b); }
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
@@ -161,73 +144,55 @@ struct BEPolicy
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
private:
|
||||
// disable copy and move
|
||||
UPX_CXX_DISABLE_COPY_MOVE(BEPolicy)
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
|
||||
};
|
||||
|
||||
|
||||
struct LEPolicy
|
||||
struct LEPolicy final
|
||||
#if defined(BELE_RTP)
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
inline LEPolicy() { }
|
||||
explicit inline LEPolicy() noexcept = default;
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||
#endif
|
||||
V bool isBE() C { return false; }
|
||||
V bool isLE() C { return true; }
|
||||
VV bool isBE() C { return false; }
|
||||
VV bool isLE() C { return true; }
|
||||
|
||||
typedef LE16 U16;
|
||||
typedef LE32 U32;
|
||||
typedef LE64 U64;
|
||||
|
||||
V unsigned get16(const void *p) C
|
||||
{ return get_le16(p); }
|
||||
V unsigned get24(const void *p) C
|
||||
{ return get_le24(p); }
|
||||
V unsigned get32(const void *p) C
|
||||
{ return get_le32(p); }
|
||||
V acc_uint64l_t get64(const void *p) C
|
||||
{ return get_le64(p); }
|
||||
V unsigned get16(const void *p) C { return get_le16(p); }
|
||||
V unsigned get24(const void *p) C { return get_le24(p); }
|
||||
V unsigned get32(const void *p) C { return get_le32(p); }
|
||||
V upx_uint64_t get64(const void *p) C { return get_le64(p); }
|
||||
|
||||
V void set16(void *p, unsigned v) C
|
||||
{ set_le16(p, v); }
|
||||
V void set24(void *p, unsigned v) C
|
||||
{ set_le24(p, v); }
|
||||
V void set32(void *p, unsigned v) C
|
||||
{ set_le32(p, v); }
|
||||
V void set64(void *p, acc_uint64l_t v) C
|
||||
{ set_le64(p, v); }
|
||||
V void set16(void *p, unsigned v) C { set_le16(p, v); }
|
||||
V void set24(void *p, unsigned v) C { set_le24(p, v); }
|
||||
V void set32(void *p, unsigned v) C { set_le32(p, v); }
|
||||
V void set64(void *p, upx_uint64_t v) C { set_le64(p, v); }
|
||||
|
||||
V unsigned get16_signed(const void *p) C
|
||||
{ return get_le16_signed(p); }
|
||||
V unsigned get24_signed(const void *p) C
|
||||
{ return get_le24_signed(p); }
|
||||
V unsigned get32_signed(const void *p) C
|
||||
{ return get_le32_signed(p); }
|
||||
V acc_uint64l_t get64_signed(const void *p) C
|
||||
{ return get_le64_signed(p); }
|
||||
V int get16_signed(const void *p) C { return get_le16_signed(p); }
|
||||
V int get24_signed(const void *p) C { return get_le24_signed(p); }
|
||||
V int get32_signed(const void *p) C { return get_le32_signed(p); }
|
||||
V upx_int64_t get64_signed(const void *p) C { return get_le64_signed(p); }
|
||||
|
||||
S u16_compare(const void *a, const void *b) C
|
||||
{ return le16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C
|
||||
{ return le24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C
|
||||
{ return le32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C
|
||||
{ return le64_compare(a, b); }
|
||||
S u16_compare(const void *a, const void *b) C { return le16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C { return le24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C { return le32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C { return le64_compare(a, b); }
|
||||
|
||||
S u16_compare_signed(const void *a, const void *b) C
|
||||
{ return le16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C
|
||||
{ return le24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C
|
||||
{ return le32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C
|
||||
{ return le64_compare_signed(a, b); }
|
||||
S u16_compare_signed(const void *a, const void *b) C { return le16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C { return le24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C { return le32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C { return le64_compare_signed(a, b); }
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
@@ -238,46 +203,27 @@ struct LEPolicy
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
private:
|
||||
// disable copy and move
|
||||
UPX_CXX_DISABLE_COPY_MOVE(LEPolicy)
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
UPX_CXX_DISABLE_NEW_DELETE(LEPolicy)
|
||||
};
|
||||
|
||||
|
||||
// Native Endianness policy (aka host policy)
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
typedef BEPolicy NEPolicy;
|
||||
typedef BEPolicy HostPolicy;
|
||||
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||
typedef LEPolicy NEPolicy;
|
||||
typedef LEPolicy HostPolicy;
|
||||
#else
|
||||
# error "ACC_ABI_ENDIAN"
|
||||
#error "ACC_ABI_ENDIAN"
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
struct HostAlignedPolicy
|
||||
{
|
||||
#if defined(BELE_CTP)
|
||||
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
||||
#endif
|
||||
|
||||
typedef acc_uint16e_t U16;
|
||||
typedef acc_uint32e_t U32;
|
||||
typedef acc_uint64l_t U64;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#undef V
|
||||
#undef VV
|
||||
#undef S
|
||||
#undef C
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/* bptr.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_BPTR_H
|
||||
#define __UPX_BPTR_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// BoundedPtr
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
class BoundedPtr
|
||||
{
|
||||
// typedef BoundedPtr<T> Self;
|
||||
public:
|
||||
typedef T* StoredType;
|
||||
typedef T* PointerType;
|
||||
typedef T& ReferenceType;
|
||||
|
||||
~BoundedPtr() { }
|
||||
|
||||
explicit BoundedPtr(void* base, unsigned size, T* ptr=0)
|
||||
: ptr_(ptr), base_(base), size_(size) { check(); }
|
||||
BoundedPtr& operator= (const BoundedPtr& other) {
|
||||
assert(base_ == other.base_); assert(size_ == other.size_);
|
||||
ptr_ = other.ptr_; check(); return *this;
|
||||
}
|
||||
BoundedPtr& operator= (T* other) {
|
||||
ptr_ = other; check(); return *this;
|
||||
}
|
||||
|
||||
operator T* () { check(); return ptr_; }
|
||||
operator const T* () const { check(); return ptr_; }
|
||||
|
||||
BoundedPtr& operator += (size_t n) {
|
||||
checkStrict(); ptr_ += n; checkStrict(); return *this;
|
||||
}
|
||||
BoundedPtr& operator -= (size_t n) {
|
||||
checkStrict(); ptr_ -= n; checkStrict(); return *this;
|
||||
}
|
||||
BoundedPtr& operator ++ (void) {
|
||||
checkStrict(); ptr_ += 1; checkStrict(); return *this;
|
||||
}
|
||||
// T* operator ++ (int) {
|
||||
// T* p = ptr_; checkStrict(); ptr_ += 1; checkStrict(); return p;
|
||||
// }
|
||||
// BoundedPtr& operator -- (void) {
|
||||
// checkStrict(); ptr_ -= 1; checkStrict(); return *this;
|
||||
// }
|
||||
|
||||
|
||||
private:
|
||||
void checkNULL() const {
|
||||
if (!ptr_)
|
||||
throwCantUnpack("unexpected NULL pointer; take care!");
|
||||
}
|
||||
void checkRange(size_t extra=0) const {
|
||||
size_t off = (const char *) ptr_ - (const char *) base_;
|
||||
if (off > size_ || off + extra > size_)
|
||||
throwCantUnpack("pointer out of range; take care!");
|
||||
}
|
||||
void checkStrict(size_t extra=0) const {
|
||||
checkNULL();
|
||||
checkRange(extra);
|
||||
}
|
||||
void check(size_t extra=0) const {
|
||||
if (ptr_) checkRange(extra);
|
||||
}
|
||||
|
||||
T* ptr_;
|
||||
void* base_;
|
||||
size_t size_;
|
||||
|
||||
// disable copy
|
||||
BoundedPtr(const BoundedPtr&); // {}
|
||||
// BoundedPtr& operator= (const BoundedPtr&); // { return *this; }
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
/* dt_impl.cpp -- doctest support code implementation
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../util/system_defs.h"
|
||||
#include "../util/system_features.h"
|
||||
|
||||
/*************************************************************************
|
||||
// doctest support code implementation
|
||||
**************************************************************************/
|
||||
|
||||
#define DOCTEST_CONFIG_IMPLEMENT
|
||||
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||
|
||||
#if defined(__wasi__)
|
||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||
#elif defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
|
||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||
#define DOCTEST_CONFIG_COLORS_NONE
|
||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
|
||||
#if !(WITH_THREADS) && !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
||||
#ifndef DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__FAST_MATH__) && defined(__clang__) && (__clang_major__ + 0 > 0)
|
||||
#if __clang_major__ >= 6
|
||||
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
|
||||
#endif
|
||||
#if defined(__has_warning)
|
||||
#if __has_warning("-Wnan-infinity-disabled")
|
||||
// warning: use of NaN is undefined behavior due to the currently enabled floating-point options
|
||||
#pragma clang diagnostic ignored "-Wnan-infinity-disabled"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <doctest/doctest/parts/doctest.cpp>
|
||||
|
||||
#endif // DOCTEST_CONFIG_DISABLE
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,227 +0,0 @@
|
||||
/* compress.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "mem.h"
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
#if 0
|
||||
return adler32(adler, (const Bytef *) buf, len); // zlib
|
||||
#elif defined(WITH_UCL)
|
||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
#if 0
|
||||
return crc32(crc, (const Bytef *) buf, len); // zlib
|
||||
#elif defined(WITH_UCL)
|
||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
upx_compress_result_t cresult_buffer;
|
||||
|
||||
assert(method > 0); assert(level > 0);
|
||||
|
||||
#if 1
|
||||
// set available bytes in dst
|
||||
if (*dst_len == 0)
|
||||
*dst_len = MemBuffer::getSizeForCompression(src_len);
|
||||
#else
|
||||
// force users to provide *dst_len
|
||||
assert(*dst_len != 0);
|
||||
#endif
|
||||
// for UPX, we always require a reasonably sized outbut buffer
|
||||
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||
|
||||
if (!cresult)
|
||||
cresult = &cresult_buffer;
|
||||
memset(cresult, 0, sizeof(*cresult));
|
||||
#if 1
|
||||
// debug
|
||||
cresult->method = method;
|
||||
cresult->level = level;
|
||||
cresult->u_len = src_len;
|
||||
cresult->c_len = 0;
|
||||
#endif
|
||||
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
}
|
||||
|
||||
#if 1
|
||||
// debug
|
||||
cresult->c_len = *dst_len;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_ZLIB)
|
||||
else if (M_IS_DEFLATE(method))
|
||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
assert((int)overlap_overhead > 0);
|
||||
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/* compress.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != nullptr);
|
||||
#if 1
|
||||
return upx_ucl_adler32(buf, len, adler);
|
||||
#else
|
||||
return upx_zlib_adler32(buf, len, adler);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != nullptr);
|
||||
#if 1
|
||||
return upx_ucl_crc32(buf, len, crc);
|
||||
#else
|
||||
return upx_zlib_crc32(buf, len, crc);
|
||||
#endif
|
||||
}
|
||||
#endif // UNUSED
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult) {
|
||||
int r = UPX_E_ERROR;
|
||||
upx_compress_result_t cresult_buffer;
|
||||
|
||||
assert(method > 0);
|
||||
assert(level > 0);
|
||||
|
||||
#if 1
|
||||
// set available bytes in dst
|
||||
if (*dst_len == 0)
|
||||
*dst_len = MemBuffer::getSizeForCompression(src_len);
|
||||
#else
|
||||
// force users to provide *dst_len
|
||||
assert(*dst_len != 0);
|
||||
#endif
|
||||
// for UPX, we always require a reasonably sized output buffer
|
||||
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||
|
||||
if (!cresult)
|
||||
cresult = &cresult_buffer;
|
||||
cresult->reset();
|
||||
#if 1
|
||||
// debugging aid
|
||||
cresult->debug.method = method;
|
||||
cresult->debug.level = level;
|
||||
cresult->debug.u_len = src_len;
|
||||
cresult->debug.c_len = 0;
|
||||
#endif
|
||||
|
||||
const unsigned orig_dst_len = *dst_len;
|
||||
if (__acc_cte(false)) {
|
||||
}
|
||||
#if (WITH_BZIP2)
|
||||
else if (M_IS_BZIP2(method))
|
||||
r = upx_bzip2_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_NRV)
|
||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
||||
r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_ZSTD)
|
||||
else if (M_IS_ZSTD(method))
|
||||
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown compression method %d", method);
|
||||
}
|
||||
|
||||
#if 1
|
||||
// debugging aid
|
||||
cresult->debug.c_len = *dst_len;
|
||||
#endif
|
||||
assert_noexcept(*dst_len <= orig_dst_len);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
|
||||
if (cresult && cresult->debug.method == 0)
|
||||
cresult = nullptr;
|
||||
|
||||
const unsigned orig_dst_len = *dst_len;
|
||||
if (__acc_cte(false)) {
|
||||
}
|
||||
#if (WITH_BZIP2)
|
||||
else if (M_IS_BZIP2(method))
|
||||
r = upx_bzip2_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_NRV)
|
||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
||||
r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_ZLIB)
|
||||
else if (M_IS_DEFLATE(method))
|
||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_ZSTD)
|
||||
else if (M_IS_ZSTD(method))
|
||||
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown compression method %d", method);
|
||||
}
|
||||
|
||||
assert_noexcept(*dst_len <= orig_dst_len);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len,
|
||||
unsigned *dst_len, int method, const upx_compress_result_t *cresult) {
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
if (cresult && cresult->debug.method == 0)
|
||||
cresult = nullptr;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
assert((int) overlap_overhead > 0);
|
||||
|
||||
const unsigned orig_dst_len = *dst_len;
|
||||
if (__acc_cte(false)) {
|
||||
}
|
||||
#if (WITH_BZIP2)
|
||||
else if (M_IS_BZIP2(method))
|
||||
r = upx_bzip2_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_NRV)
|
||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
||||
r = upx_nrv_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if (WITH_ZSTD)
|
||||
else if (M_IS_ZSTD(method))
|
||||
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown compression method %d", method);
|
||||
}
|
||||
|
||||
assert_noexcept(*dst_len <= orig_dst_len);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,106 +20,146 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPX_COMPRESS_H
|
||||
#define __UPX_COMPRESS_H
|
||||
|
||||
// clang-format off
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(WITH_LZMA)
|
||||
#if (WITH_BZIP2)
|
||||
int upx_bzip2_init(void);
|
||||
const char *upx_bzip2_version_string(void);
|
||||
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_bzip2_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
#if (WITH_LZMA)
|
||||
int upx_lzma_init(void);
|
||||
const char *upx_lzma_version_string(void);
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
#if (WITH_NRV)
|
||||
int upx_nrv_init(void);
|
||||
const char *upx_nrv_version_string(void);
|
||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_nrv_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WITH_UCL)
|
||||
#if (WITH_UCL)
|
||||
int upx_ucl_init(void);
|
||||
const char *upx_ucl_version_string(void);
|
||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
|
||||
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ZLIB)
|
||||
#if (WITH_ZLIB)
|
||||
int upx_zlib_init(void);
|
||||
const char *upx_zlib_version_string(void);
|
||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
|
||||
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||
#endif
|
||||
|
||||
#if (WITH_ZSTD)
|
||||
int upx_zstd_init(void);
|
||||
const char *upx_zstd_version_string(void);
|
||||
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_zstd_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned *dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -0,0 +1,211 @@
|
||||
/* compress_bzip2.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../util/system_headers.h"
|
||||
#if WITH_BZIP2
|
||||
#include <bzip2/bzlib.h>
|
||||
#endif
|
||||
#include "../conf.h"
|
||||
|
||||
void bzip2_compress_config_t::reset() noexcept { mem_clear(this); }
|
||||
|
||||
#if WITH_BZIP2
|
||||
#include "compress.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
#if defined(BZ_NO_STDIO) || 1
|
||||
// we need to supply bz_internal_error() when building with BZ_NO_STDIO
|
||||
extern "C" {
|
||||
extern void bz_internal_error(int);
|
||||
void bz_internal_error(int errcode) { throwInternalError("bz_internal_error %d", errcode); }
|
||||
}
|
||||
#endif // BZ_NO_STDIO
|
||||
|
||||
static int convert_errno_from_bzip2(int r) {
|
||||
switch (r) {
|
||||
case BZ_OK:
|
||||
return UPX_E_OK;
|
||||
case BZ_MEM_ERROR:
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
// TODO later: convert to UPX_E_INPUT_OVERRUN, UPX_E_OUTPUT_OVERRUN
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_bzip2_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb_parm, int method, int level,
|
||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||
assert(method == M_BZIP2);
|
||||
assert(level > 0);
|
||||
assert(cresult != nullptr);
|
||||
UNUSED(cb_parm);
|
||||
int r = UPX_E_ERROR;
|
||||
const bzip2_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_bzip2 : nullptr;
|
||||
bzip2_compress_result_t *const res = &cresult->result_bzip2;
|
||||
res->reset();
|
||||
|
||||
int blockSize100k = (src_len + 100000 - 1) / 100000;
|
||||
if (blockSize100k < 1)
|
||||
blockSize100k = 1;
|
||||
if (blockSize100k > 9)
|
||||
blockSize100k = 9;
|
||||
// idea for later: could enhance lcconf to allow setting blockSize100k
|
||||
UNUSED(lcconf);
|
||||
if (level <= 3 && blockSize100k > level)
|
||||
blockSize100k = level;
|
||||
|
||||
char *dest = (char *) dst;
|
||||
char *source = (char *) const_cast<byte *>(src);
|
||||
r = BZ2_bzBuffToBuffCompress(dest, dst_len, source, src_len, blockSize100k, 0, 0);
|
||||
return convert_errno_from_bzip2(r);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_bzip2_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
assert(method == M_BZIP2);
|
||||
UNUSED(method);
|
||||
UNUSED(cresult);
|
||||
char *dest = (char *) dst;
|
||||
char *source = (char *) const_cast<byte *>(src);
|
||||
int small = 0;
|
||||
int r = BZ2_bzBuffToBuffDecompress(dest, dst_len, source, src_len, small, 0);
|
||||
return convert_errno_from_bzip2(r);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_bzip2_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||
unsigned src_len, unsigned *dst_len, int method,
|
||||
const upx_compress_result_t *cresult) {
|
||||
assert(method == M_BZIP2);
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_bzip2_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping, so we use an extra memcmp().
|
||||
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
int upx_bzip2_init(void) { return 0; }
|
||||
|
||||
const char *upx_bzip2_version_string(void) { return BZ2_bzlibVersion(); }
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
static bool check_bzip2(const int method, const int level, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
const unsigned c_extra = 4096;
|
||||
MemBuffer u_buf, c_buf, d_buf;
|
||||
unsigned c_len, d_len;
|
||||
upx_compress_result_t cresult;
|
||||
int r;
|
||||
|
||||
u_buf.alloc(u_len);
|
||||
memset(u_buf, 0, u_len);
|
||||
c_buf.allocForCompression(u_len, c_extra);
|
||||
d_buf.allocForDecompression(u_len);
|
||||
|
||||
c_len = c_buf.getSize() - c_extra;
|
||||
r = upx_bzip2_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||
if (r != 0 || c_len != expected_c_len)
|
||||
return false;
|
||||
|
||||
d_len = d_buf.getSize();
|
||||
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||
return false;
|
||||
|
||||
d_len = u_len - 1;
|
||||
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r == 0)
|
||||
return false;
|
||||
|
||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||
// unsigned x_len = d_len;
|
||||
// r = upx_bzip2_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("compress_bzip2") { CHECK(check_bzip2(M_BZIP2, 9, 46)); }
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
TEST_CASE("upx_bzip2_decompress") {
|
||||
#if 0 // TODO later, see above
|
||||
const byte *c_data;
|
||||
byte d_buf[32];
|
||||
unsigned d_len;
|
||||
int r;
|
||||
|
||||
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||
d_len = 32;
|
||||
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||
CHECK((r == 0 && d_len == 32));
|
||||
r = upx_bzip2_decompress(c_data, 15, d_buf, &d_len, M_BZIP2, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 31;
|
||||
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
#endif // TODO
|
||||
}
|
||||
|
||||
#endif // WITH_BZIP2
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -0,0 +1,526 @@
|
||||
/* compress_lzma.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
#if (ACC_CC_CLANG)
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#elif (ACC_CC_GNUC >= 0x040200)
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#elif (ACC_CC_MSC)
|
||||
#pragma warning(disable : 4456) // -Wno-shadow
|
||||
#endif
|
||||
|
||||
void lzma_compress_config_t::reset() noexcept {
|
||||
pos_bits.reset();
|
||||
lit_pos_bits.reset();
|
||||
lit_context_bits.reset();
|
||||
dict_size.reset();
|
||||
fast_mode = 2;
|
||||
num_fast_bytes.reset();
|
||||
match_finder_cycles = 0;
|
||||
|
||||
max_num_probs = 0;
|
||||
}
|
||||
|
||||
// INFO: LZMA SDK is placed in the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute the original LZMA SDK code, either in source code form
|
||||
// or as a compiled binary, for any purpose, commercial or non-commercial,
|
||||
// and by any means.
|
||||
//
|
||||
// https://www.7-zip.org/sdk.html
|
||||
// https://sourceforge.net/p/sevenzip/discussion/45797/thread/685169cf/
|
||||
|
||||
/*************************************************************************
|
||||
// compress defaults
|
||||
**************************************************************************/
|
||||
|
||||
static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int method, int level,
|
||||
const lzma_compress_config_t *lcconf) {
|
||||
// setup defaults
|
||||
res->pos_bits = 2; // 0 .. 4
|
||||
res->lit_pos_bits = 0; // 0 .. 4
|
||||
res->lit_context_bits = 3; // 0 .. 8
|
||||
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
||||
res->fast_mode = 2; // 0 .. 2
|
||||
res->num_fast_bytes = 64; // 5 .. 273
|
||||
res->match_finder_cycles = 0;
|
||||
// UPX overrides
|
||||
res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value;
|
||||
res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value;
|
||||
res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value;
|
||||
res->dict_size = lzma_compress_config_t::dict_size_t::default_value;
|
||||
res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value;
|
||||
// method overrides
|
||||
if (method >= 0x100) {
|
||||
res->pos_bits = (method >> 16) & 15;
|
||||
res->lit_pos_bits = (method >> 12) & 15;
|
||||
res->lit_context_bits = (method >> 8) & 15;
|
||||
}
|
||||
#if 0
|
||||
// DEBUG - set sizes so that we use a maximum amount of stack.
|
||||
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||
// need about 6 MiB of stack during runtime decompression.
|
||||
res->lit_pos_bits = 4;
|
||||
res->lit_context_bits = 8;
|
||||
#endif
|
||||
|
||||
// TODO: tune these settings according to level
|
||||
switch (level) {
|
||||
case 1:
|
||||
res->dict_size = 256 * 1024;
|
||||
res->fast_mode = 0;
|
||||
res->num_fast_bytes = 8;
|
||||
break;
|
||||
case 2:
|
||||
res->dict_size = 256 * 1024;
|
||||
res->fast_mode = 0;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 9:
|
||||
res->dict_size = 8 * 1024 * 1024;
|
||||
break;
|
||||
case 10:
|
||||
res->dict_size = src_len;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
// cconf overrides
|
||||
if (lcconf) {
|
||||
upx::oassign(res->pos_bits, lcconf->pos_bits);
|
||||
upx::oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||
upx::oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||
upx::oassign(res->dict_size, lcconf->dict_size);
|
||||
upx::oassign(res->num_fast_bytes, lcconf->num_fast_bytes);
|
||||
}
|
||||
|
||||
// limit dictionary size
|
||||
if (res->dict_size > src_len)
|
||||
res->dict_size = src_len;
|
||||
|
||||
// limit num_probs
|
||||
if (lcconf && lcconf->max_num_probs) {
|
||||
for (;;) {
|
||||
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||
if (n <= lcconf->max_num_probs)
|
||||
break;
|
||||
if (res->lit_pos_bits > res->lit_context_bits) {
|
||||
if (res->lit_pos_bits == 0)
|
||||
goto error;
|
||||
res->lit_pos_bits -= 1;
|
||||
} else {
|
||||
if (res->lit_context_bits == 0)
|
||||
goto error;
|
||||
res->lit_context_bits -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lzma_compress_config_t::pos_bits_t::assertValue(res->pos_bits);
|
||||
lzma_compress_config_t::lit_pos_bits_t::assertValue(res->lit_pos_bits);
|
||||
lzma_compress_config_t::lit_context_bits_t::assertValue(res->lit_context_bits);
|
||||
lzma_compress_config_t::dict_size_t::assertValue(res->dict_size);
|
||||
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
||||
|
||||
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||
NO_printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||
res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// compress - cruft because of pseudo-COM layer
|
||||
**************************************************************************/
|
||||
|
||||
#if (ACC_CC_CLANG >= 0x080000)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#elif (ACC_CC_GNUC >= 0x040700)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
|
||||
#undef MSDOS
|
||||
#undef OS2
|
||||
#undef _WIN32
|
||||
#undef _WIN32_WCE
|
||||
#undef COMPRESS_MF_MT
|
||||
#undef _NO_EXCEPTIONS
|
||||
#include <lzma-sdk/C/Common/MyInitGuid.h>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.h>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.h>
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct InStream final : public ISequentialInStream, public CMyUnknownImp {
|
||||
virtual ~InStream() {}
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *b_buf = nullptr;
|
||||
size_t b_size;
|
||||
size_t b_pos;
|
||||
void Init(const Byte *data, size_t size) {
|
||||
b_buf = data;
|
||||
b_size = size;
|
||||
b_pos = 0;
|
||||
}
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
||||
};
|
||||
|
||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) {
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain)
|
||||
size = (UInt32) remain;
|
||||
memmove(data, b_buf + b_pos, size);
|
||||
b_pos += size;
|
||||
if (processedSize != nullptr)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct OutStream final : public ISequentialOutStream, public CMyUnknownImp {
|
||||
virtual ~OutStream() {}
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *b_buf = nullptr;
|
||||
size_t b_size;
|
||||
size_t b_pos;
|
||||
bool overflow;
|
||||
void Init(Byte *data, size_t size) {
|
||||
b_buf = data;
|
||||
b_size = size;
|
||||
b_pos = 0;
|
||||
overflow = false;
|
||||
}
|
||||
HRESULT WriteByte(Byte c) {
|
||||
if (b_pos >= b_size) {
|
||||
overflow = true;
|
||||
return E_FAIL;
|
||||
}
|
||||
b_buf[b_pos++] = c;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
||||
};
|
||||
|
||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) {
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain)
|
||||
size = (UInt32) remain, overflow = true;
|
||||
memmove(b_buf + b_pos, data, size);
|
||||
b_pos += size;
|
||||
if (processedSize != nullptr)
|
||||
*processedSize = size;
|
||||
return overflow ? E_FAIL : S_OK;
|
||||
}
|
||||
|
||||
struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
|
||||
virtual ~ProgressInfo() {}
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
||||
upx_callback_t *cb = nullptr;
|
||||
};
|
||||
|
||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace MyLzma
|
||||
|
||||
#include <lzma-sdk/C/Common/Alloc.cpp>
|
||||
#include <lzma-sdk/C/Common/CRC.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Common/InBuffer.cpp>
|
||||
#include <lzma-sdk/C/7zip/Common/OutBuffer.cpp>
|
||||
#include <lzma-sdk/C/7zip/Common/StreamUtils.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZ/LZInWindow.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZ/LZOutWindow.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
#if (ACC_CC_CLANG >= 0x080000)
|
||||
#pragma clang diagnostic pop
|
||||
#elif (ACC_CC_GNUC >= 0x040700)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb, int method, int level,
|
||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||
assert(M_IS_LZMA(method));
|
||||
assert(level > 0);
|
||||
assert(cresult != nullptr);
|
||||
|
||||
int r = UPX_E_ERROR;
|
||||
HRESULT rh;
|
||||
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
||||
lzma_compress_result_t *const res = &cresult->result_lzma;
|
||||
res->reset();
|
||||
|
||||
MyLzma::InStream is;
|
||||
is.AddRef();
|
||||
is.Init(src, src_len);
|
||||
MyLzma::OutStream os;
|
||||
os.AddRef();
|
||||
os.Init(dst, *dst_len);
|
||||
MyLzma::ProgressInfo progress;
|
||||
progress.AddRef();
|
||||
progress.cb = cb; // progress.Init()
|
||||
|
||||
NCompress::NLZMA::CEncoder enc;
|
||||
constexpr unsigned NPROPS = 8;
|
||||
static const PROPID propIDs[NPROPS] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3 ds
|
||||
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5 fb
|
||||
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
||||
NCoderPropID::kMatchFinder // 7 mf
|
||||
};
|
||||
PROPVARIANT pr[NPROPS];
|
||||
if (!prepare_result(res, src_len, method, level, lcconf))
|
||||
goto error;
|
||||
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||
pr[7].vt = VT_BSTR;
|
||||
pr[0].uintVal = res->pos_bits;
|
||||
pr[1].uintVal = res->lit_pos_bits;
|
||||
pr[2].uintVal = res->lit_context_bits;
|
||||
pr[3].uintVal = res->dict_size;
|
||||
pr[4].uintVal = res->fast_mode;
|
||||
pr[5].uintVal = res->num_fast_bytes;
|
||||
pr[6].uintVal = res->match_finder_cycles;
|
||||
static const wchar_t matchfinder[] = L"BT4";
|
||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||
pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
||||
|
||||
try {
|
||||
if (enc.SetCoderProperties(propIDs, pr, NPROPS) != S_OK)
|
||||
goto error;
|
||||
// encode properties in LZMA-style (5 bytes)
|
||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||
goto error;
|
||||
if (os.overflow) {
|
||||
// r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
goto error;
|
||||
}
|
||||
assert(os.b_pos == 5);
|
||||
|
||||
// reset and encode properties in UPX-style (2 bytes)
|
||||
os.b_pos = 0;
|
||||
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
||||
os.WriteByte(Byte((res->lit_pos_bits << 4) | res->lit_context_bits));
|
||||
|
||||
// compress
|
||||
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
||||
|
||||
} catch (...) {
|
||||
rh = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
assert(is.b_pos <= src_len);
|
||||
assert(os.b_pos <= *dst_len);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
else if (os.overflow) {
|
||||
assert(os.b_pos == *dst_len);
|
||||
// r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
} else if (rh == S_OK) {
|
||||
assert(is.b_pos == src_len);
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = (unsigned) os.b_pos;
|
||||
NO_printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
|
||||
res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len,
|
||||
*dst_len);
|
||||
NO_printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// decompress
|
||||
**************************************************************************/
|
||||
|
||||
#undef _LZMA_IN_CB
|
||||
#undef _LZMA_OUT_READ
|
||||
#undef _LZMA_PROB32
|
||||
#undef _LZMA_LOC_OPT
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
||||
|
||||
int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
assert(M_IS_LZMA(method));
|
||||
// see res->num_probs above
|
||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||
|
||||
CLzmaDecoderState s;
|
||||
mem_clear(&s);
|
||||
SizeT src_out = 0, dst_out = 0;
|
||||
int r = UPX_E_ERROR;
|
||||
int rh;
|
||||
|
||||
// decode UPX-style properties (2 bytes)
|
||||
if (src_len < 3) {
|
||||
r = UPX_E_INPUT_OVERRUN;
|
||||
goto error;
|
||||
}
|
||||
s.Properties.pb = src[0] & 7;
|
||||
s.Properties.lp = (src[1] >> 4);
|
||||
s.Properties.lc = src[1] & 15;
|
||||
if (s.Properties.pb >= 5)
|
||||
goto error;
|
||||
if (s.Properties.lp >= 5)
|
||||
goto error;
|
||||
if (s.Properties.lc >= 9)
|
||||
goto error;
|
||||
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp)
|
||||
goto error;
|
||||
src += 2;
|
||||
src_len -= 2;
|
||||
|
||||
if (cresult) {
|
||||
assert(cresult->debug.method == method);
|
||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
NO_printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||
res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
UNUSED(res);
|
||||
}
|
||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||
if (!s.Probs) {
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||
assert(src_out <= src_len);
|
||||
assert(dst_out <= *dst_len);
|
||||
if (rh == 0) {
|
||||
r = UPX_E_OK;
|
||||
if (src_out != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
} else if (rh == LZMA_RESULT_INPUT_OVERRUN)
|
||||
r = UPX_E_INPUT_OVERRUN;
|
||||
else if (rh == LZMA_RESULT_OUTPUT_OVERRUN)
|
||||
r = UPX_E_OUTPUT_OVERRUN;
|
||||
|
||||
error:
|
||||
*dst_len = dst_out;
|
||||
free(s.Probs);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||
unsigned src_len, unsigned *dst_len, int method,
|
||||
const upx_compress_result_t *cresult) {
|
||||
assert(M_IS_LZMA(method));
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_lzma_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping, so we use an extra memcmp().
|
||||
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_init(void) { return 0; }
|
||||
|
||||
const char *upx_lzma_version_string(void) { return "4.43"; }
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
TEST_CASE("upx_lzma_decompress") {
|
||||
const byte *c_data;
|
||||
byte d_buf[16];
|
||||
unsigned d_len;
|
||||
int r;
|
||||
|
||||
c_data = (const byte *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
|
||||
d_len = 16;
|
||||
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||
CHECK((r == 0 && d_len == 16));
|
||||
r = upx_lzma_decompress(c_data, 8, d_buf, &d_len, M_LZMA, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 15;
|
||||
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -0,0 +1,373 @@
|
||||
/* compress_ucl.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int convert_errno_from_ucl(int r) {
|
||||
switch (r) {
|
||||
case UCL_E_OK:
|
||||
return UPX_E_OK;
|
||||
case UCL_E_ERROR:
|
||||
return UPX_E_ERROR;
|
||||
case UCL_E_OUT_OF_MEMORY:
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
case UCL_E_NOT_COMPRESSIBLE:
|
||||
return UPX_E_NOT_COMPRESSIBLE;
|
||||
case UCL_E_INPUT_OVERRUN:
|
||||
return UPX_E_INPUT_OVERRUN;
|
||||
case UCL_E_OUTPUT_OVERRUN:
|
||||
return UPX_E_OUTPUT_OVERRUN;
|
||||
case UCL_E_LOOKBEHIND_OVERRUN:
|
||||
return UPX_E_LOOKBEHIND_OVERRUN;
|
||||
case UCL_E_EOF_NOT_FOUND:
|
||||
return UPX_E_EOF_NOT_FOUND;
|
||||
case UCL_E_INPUT_NOT_CONSUMED:
|
||||
return UPX_E_INPUT_NOT_CONSUMED;
|
||||
case UCL_E_INVALID_ARGUMENT:
|
||||
return UPX_E_INVALID_ARGUMENT;
|
||||
// UCL extra:
|
||||
case UCL_E_OVERLAP_OVERRUN:
|
||||
return UPX_E_ERROR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
||||
if (state != -1 && state != 3)
|
||||
return;
|
||||
upx_callback_t *cb = (upx_callback_t *) user;
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb_parm, int method, int level,
|
||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||
int r;
|
||||
assert(level > 0);
|
||||
assert(cresult != nullptr);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||
|
||||
ucl_progress_callback_t cb;
|
||||
cb.callback = nullptr;
|
||||
cb.user = nullptr;
|
||||
if (cb_parm && cb_parm->nprogress) {
|
||||
cb.callback = wrap_nprogress_ucl;
|
||||
cb.user = cb_parm;
|
||||
}
|
||||
|
||||
ucl_compress_config_t cconf;
|
||||
cconf.reset();
|
||||
if (cconf_parm) {
|
||||
// cconf = cconf_parm->conf_ucl; // struct copy
|
||||
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf));
|
||||
}
|
||||
|
||||
ucl_uint *const res = cresult->result_ucl.result;
|
||||
// assume no info available - fill in worst case results
|
||||
// res[0] = 1; // min_offset_found - NOT USED
|
||||
res[1] = src_len - 1; // max_offset_found
|
||||
// res[2] = 2; // min_match_found - NOT USED
|
||||
res[3] = src_len - 1; // max_match_found
|
||||
// res[4] = 1; // min_run_found - NOT USED
|
||||
res[5] = src_len; // max_run_found
|
||||
res[6] = 1; // first_offset_found
|
||||
// res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
cconf.bb_endian = 0;
|
||||
cconf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
|
||||
static const upx_uint8_t sizes[3] = {32, 8, 16};
|
||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||
} else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// optimize compression params
|
||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 8 * 1024 - 1;
|
||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 32 * 1024 - 1;
|
||||
|
||||
if M_IS_NRV2B (method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||
else if M_IS_NRV2D (method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||
else if M_IS_NRV2E (method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// make sure first_offset_found is set
|
||||
if (res[6] == 0)
|
||||
res[6] = 1;
|
||||
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
int r;
|
||||
|
||||
switch (method) {
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||
unsigned src_len, unsigned *dst_len, int method,
|
||||
const upx_compress_result_t *cresult) {
|
||||
int r;
|
||||
UNUSED(tbuf); // not needed for UCL
|
||||
|
||||
switch (method) {
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
extern "C" {
|
||||
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return upx_calloc(n, 1); }
|
||||
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
||||
} // extern "C"
|
||||
|
||||
int upx_ucl_init(void) {
|
||||
#if (ACC_CC_MSC && ACC_ARCH_I386) && (_MSC_VER >= 1940)
|
||||
(void) ucl_init(); // TODO later
|
||||
#else
|
||||
if (ucl_init() != UCL_E_OK)
|
||||
return -1;
|
||||
#endif
|
||||
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
||||
return -2;
|
||||
ucl_set_malloc_hooks(my_malloc, my_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *upx_ucl_version_string(void) { return ucl_version_string(); }
|
||||
|
||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||
}
|
||||
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
const unsigned c_extra = 4096;
|
||||
MemBuffer u_buf, c_buf, d_buf;
|
||||
unsigned c_len, d_len;
|
||||
upx_compress_result_t cresult;
|
||||
int r;
|
||||
const int level = 3; // don't waste time
|
||||
|
||||
u_buf.alloc(u_len);
|
||||
memset(u_buf, 0, u_len);
|
||||
c_buf.allocForCompression(u_len, c_extra);
|
||||
d_buf.allocForDecompression(u_len);
|
||||
|
||||
c_len = c_buf.getSize() - c_extra;
|
||||
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||
if (r != 0 || c_len != expected_c_len)
|
||||
return false;
|
||||
|
||||
d_len = d_buf.getSize();
|
||||
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||
return false;
|
||||
|
||||
d_len = u_len - 1;
|
||||
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r == 0)
|
||||
return false;
|
||||
|
||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||
// unsigned x_len = d_len;
|
||||
// r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("compress_ucl") {
|
||||
CHECK(check_ucl(M_NRV2B_8, 34));
|
||||
CHECK(check_ucl(M_NRV2B_LE16, 34));
|
||||
CHECK(check_ucl(M_NRV2B_LE32, 34));
|
||||
CHECK(check_ucl(M_NRV2D_8, 32));
|
||||
CHECK(check_ucl(M_NRV2D_LE16, 32));
|
||||
CHECK(check_ucl(M_NRV2D_LE32, 34));
|
||||
CHECK(check_ucl(M_NRV2E_8, 32));
|
||||
CHECK(check_ucl(M_NRV2E_LE16, 32));
|
||||
CHECK(check_ucl(M_NRV2E_LE32, 34));
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
TEST_CASE("upx_ucl_decompress") {
|
||||
const byte *c_data;
|
||||
byte d_buf[16];
|
||||
unsigned d_len;
|
||||
int r;
|
||||
|
||||
c_data = (const byte *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
|
||||
d_len = 16;
|
||||
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||
CHECK((r == 0 && d_len == 16));
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 15;
|
||||
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
|
||||
c_data = (const byte *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
|
||||
d_len = 16;
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||
CHECK((r == 0 && d_len == 16));
|
||||
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 15;
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
|
||||
c_data = (const byte *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
|
||||
d_len = 16;
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||
CHECK((r == 0 && d_len == 16));
|
||||
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 15;
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -0,0 +1,314 @@
|
||||
/* compress_zlib.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
void zlib_compress_config_t::reset() noexcept {
|
||||
mem_clear(this);
|
||||
mem_level.reset();
|
||||
window_bits.reset();
|
||||
strategy.reset();
|
||||
}
|
||||
|
||||
#if WITH_ZLIB
|
||||
#include "compress.h"
|
||||
#include "../util/membuffer.h"
|
||||
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
|
||||
#define ZLIB_CONST 1
|
||||
#include <zlib/zlib.h>
|
||||
#include <zlib/deflate.h>
|
||||
// NOLINTEND(clang-analyzer-optin.performance.Padding)
|
||||
|
||||
static int convert_errno_from_zlib(int zr) {
|
||||
switch (zr) {
|
||||
case Z_OK:
|
||||
return UPX_E_OK;
|
||||
// positive values
|
||||
case Z_STREAM_END:
|
||||
return UPX_E_ERROR;
|
||||
case Z_NEED_DICT:
|
||||
return UPX_E_ERROR;
|
||||
// negative values
|
||||
case Z_ERRNO:
|
||||
return UPX_E_ERROR;
|
||||
case Z_STREAM_ERROR:
|
||||
return UPX_E_ERROR;
|
||||
case Z_DATA_ERROR:
|
||||
return UPX_E_ERROR;
|
||||
case Z_MEM_ERROR:
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
case Z_BUF_ERROR:
|
||||
return UPX_E_OUTPUT_OVERRUN;
|
||||
case Z_VERSION_ERROR:
|
||||
return UPX_E_ERROR;
|
||||
case -7: // UPX extra
|
||||
return UPX_E_INPUT_OVERRUN;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb_parm, int method, int level,
|
||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||
assert(method == M_DEFLATE);
|
||||
assert(level > 0);
|
||||
assert(cresult != nullptr);
|
||||
UNUSED(cb_parm);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
||||
zlib_compress_result_t *const res = &cresult->result_zlib;
|
||||
res->reset();
|
||||
|
||||
if (level == 10)
|
||||
level = 9;
|
||||
|
||||
zlib_compress_config_t::mem_level_t mem_level;
|
||||
zlib_compress_config_t::window_bits_t window_bits;
|
||||
zlib_compress_config_t::strategy_t strategy;
|
||||
// cconf overrides
|
||||
if (lcconf) {
|
||||
upx::oassign(mem_level, lcconf->mem_level);
|
||||
upx::oassign(window_bits, lcconf->window_bits);
|
||||
upx::oassign(strategy, lcconf->strategy);
|
||||
}
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) nullptr;
|
||||
s.zfree = (free_func) nullptr;
|
||||
s.next_in = src;
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = (int) deflateInit2(&s, level, Z_DEFLATED, 0 - (int) window_bits, mem_level, strategy);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
assert(s.state->level == level);
|
||||
zr = deflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END)
|
||||
goto error;
|
||||
zr = deflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) deflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK) {
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_ERROR;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
assert(method == M_DEFLATE);
|
||||
UNUSED(method);
|
||||
UNUSED(cresult);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) nullptr;
|
||||
s.zfree = (free_func) nullptr;
|
||||
s.next_in = src;
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = inflateInit2(&s, -15);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
zr = inflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END) {
|
||||
if (zr == Z_BUF_ERROR && s.avail_in == 0)
|
||||
zr = -7; // UPX extra
|
||||
goto error;
|
||||
}
|
||||
zr = inflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) inflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK) {
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||
unsigned src_len, unsigned *dst_len, int method,
|
||||
const upx_compress_result_t *cresult) {
|
||||
assert(method == M_DEFLATE);
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_zlib_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping, so we use an extra memcmp().
|
||||
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_init(void) {
|
||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
||||
return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *upx_zlib_version_string(void) { return zlibVersion(); }
|
||||
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||
return adler32(adler, (const Bytef *) buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
return crc32(crc, (const Bytef *) buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
const unsigned c_extra = 4096;
|
||||
MemBuffer u_buf, c_buf, d_buf;
|
||||
unsigned c_len, d_len;
|
||||
upx_compress_result_t cresult;
|
||||
int r;
|
||||
|
||||
u_buf.alloc(u_len);
|
||||
memset(u_buf, 0, u_len);
|
||||
c_buf.allocForCompression(u_len, c_extra);
|
||||
d_buf.allocForDecompression(u_len);
|
||||
|
||||
c_len = c_buf.getSize() - c_extra;
|
||||
r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||
if (r != 0 || c_len != expected_c_len)
|
||||
return false;
|
||||
|
||||
d_len = d_buf.getSize();
|
||||
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||
return false;
|
||||
|
||||
d_len = u_len - 1;
|
||||
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r == 0)
|
||||
return false;
|
||||
|
||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||
// unsigned x_len = d_len;
|
||||
// r = upx_zlib_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("compress_zlib") {
|
||||
CHECK(check_zlib(M_DEFLATE, 1, 89));
|
||||
CHECK(check_zlib(M_DEFLATE, 3, 89));
|
||||
CHECK(check_zlib(M_DEFLATE, 5, 33));
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
TEST_CASE("upx_zlib_decompress") {
|
||||
const byte *c_data;
|
||||
byte d_buf[16];
|
||||
unsigned d_len;
|
||||
int r;
|
||||
|
||||
c_data = (const byte *) "\xfb\xff\x1f\x15\x00\x00";
|
||||
d_len = 16;
|
||||
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||
CHECK((r == 0 && d_len == 16));
|
||||
r = upx_zlib_decompress(c_data, 5, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 15;
|
||||
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
#endif // WITH_ZLIB
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -0,0 +1,231 @@
|
||||
/* compress_zstd.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../util/system_headers.h"
|
||||
#if WITH_ZSTD
|
||||
#include <zstd/lib/zstd.h>
|
||||
#include <zstd/lib/zstd_errors.h>
|
||||
#include <zstd/lib/compress/hist.h>
|
||||
#endif
|
||||
#include "../conf.h"
|
||||
|
||||
void zstd_compress_config_t::reset() noexcept { mem_clear(this); }
|
||||
|
||||
#if WITH_ZSTD
|
||||
#include "compress.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
static int convert_errno_from_zstd(size_t zr) {
|
||||
const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr);
|
||||
switch (ze) {
|
||||
case ZSTD_error_memory_allocation:
|
||||
return UPX_E_OUT_OF_MEMORY;
|
||||
case ZSTD_error_srcSize_wrong:
|
||||
return UPX_E_INPUT_OVERRUN;
|
||||
case ZSTD_error_dstSize_tooSmall:
|
||||
return UPX_E_OUTPUT_OVERRUN;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// TODO later: use advanced compression API for compression finetuning
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
upx_callback_t *cb_parm, int method, int level,
|
||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||
assert(method == M_ZSTD);
|
||||
assert(level > 0);
|
||||
assert(cresult != nullptr);
|
||||
UNUSED(cb_parm);
|
||||
int r = UPX_E_ERROR;
|
||||
size_t zr;
|
||||
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
|
||||
zstd_compress_result_t *const res = &cresult->result_zstd;
|
||||
res->reset();
|
||||
|
||||
// TODO later: map level 1..10 to zstd-level 1..22
|
||||
if (level == 10)
|
||||
level = 22;
|
||||
|
||||
// cconf overrides
|
||||
if (lcconf) {
|
||||
UNUSED(lcconf);
|
||||
}
|
||||
|
||||
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
|
||||
if (ZSTD_isError(zr)) {
|
||||
*dst_len = 0; // TODO ???
|
||||
r = convert_errno_from_zstd(zr);
|
||||
assert(r != UPX_E_OK);
|
||||
} else {
|
||||
assert(zr <= *dst_len);
|
||||
*dst_len = (unsigned) zr;
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zstd_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
assert(method == M_ZSTD);
|
||||
UNUSED(method);
|
||||
UNUSED(cresult);
|
||||
int r = UPX_E_ERROR;
|
||||
size_t zr;
|
||||
|
||||
zr = ZSTD_decompress(dst, *dst_len, src, src_len);
|
||||
if (ZSTD_isError(zr)) {
|
||||
*dst_len = 0; // TODO ???
|
||||
r = convert_errno_from_zstd(zr);
|
||||
assert(r != UPX_E_OK);
|
||||
} else {
|
||||
assert(zr <= *dst_len);
|
||||
*dst_len = (unsigned) zr;
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zstd_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||
unsigned src_len, unsigned *dst_len, int method,
|
||||
const upx_compress_result_t *cresult) {
|
||||
assert(method == M_ZSTD);
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_zstd_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping, so we use an extra memcmp().
|
||||
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zstd_init(void) {
|
||||
if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString()) != 0)
|
||||
return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *upx_zstd_version_string(void) { return ZSTD_VERSION_STRING; }
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
static bool check_zstd(const int method, const int level, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
const unsigned c_extra = 4096;
|
||||
MemBuffer u_buf, c_buf, d_buf;
|
||||
unsigned c_len, d_len;
|
||||
upx_compress_result_t cresult;
|
||||
int r;
|
||||
|
||||
u_buf.alloc(u_len);
|
||||
memset(u_buf, 0, u_len);
|
||||
c_buf.allocForCompression(u_len, c_extra);
|
||||
d_buf.allocForDecompression(u_len);
|
||||
|
||||
c_len = c_buf.getSize() - c_extra;
|
||||
r = upx_zstd_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||
if (r != 0 || c_len != expected_c_len)
|
||||
return false;
|
||||
|
||||
d_len = d_buf.getSize();
|
||||
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||
return false;
|
||||
|
||||
d_len = u_len - 1;
|
||||
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||
&d_len, method, nullptr);
|
||||
if (r == 0)
|
||||
return false;
|
||||
|
||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||
// unsigned x_len = d_len;
|
||||
// r = upx_zstd_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("compress_zstd") {
|
||||
CHECK(check_zstd(M_ZSTD, 1, 19));
|
||||
CHECK(check_zstd(M_ZSTD, 3, 19));
|
||||
CHECK(check_zstd(M_ZSTD, 5, 19));
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
TEST_CASE("upx_zstd_decompress") {
|
||||
const byte *c_data;
|
||||
byte d_buf[32];
|
||||
unsigned d_len;
|
||||
int r;
|
||||
|
||||
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||
d_len = 32;
|
||||
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||
CHECK((r == 0 && d_len == 32));
|
||||
r = upx_zstd_decompress(c_data, 15, d_buf, &d_len, M_ZSTD, nullptr);
|
||||
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||
d_len = 31;
|
||||
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
#endif // WITH_ZSTD
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -1,563 +0,0 @@
|
||||
/* compress_lzma.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
void lzma_compress_config_t::reset()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
pos_bits.reset();
|
||||
lit_pos_bits.reset();
|
||||
lit_context_bits.reset();
|
||||
dict_size.reset();
|
||||
fast_mode = 2;
|
||||
num_fast_bytes.reset();
|
||||
match_finder_cycles = 0;
|
||||
|
||||
max_num_probs = 0;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_LZMA)
|
||||
extern int compress_lzma_dummy;
|
||||
int compress_lzma_dummy = 0;
|
||||
#else
|
||||
|
||||
|
||||
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||
// See SPECIAL EXCEPTION below.
|
||||
//
|
||||
// Quoting from lzma-4.43/lzma.txt:
|
||||
//
|
||||
// LICENSE
|
||||
// -------
|
||||
//
|
||||
// LZMA SDK is available under any of the following licenses:
|
||||
//
|
||||
// 1) GNU Lesser General Public License (GNU LGPL)
|
||||
// 2) Common Public License (CPL)
|
||||
// 3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
|
||||
// 4) Proprietary license
|
||||
//
|
||||
// It means that you can select one of these four options and follow rules
|
||||
// of that license.
|
||||
//
|
||||
// 1,2) GNU LGPL and CPL licenses are pretty similar and both these
|
||||
// licenses are classified as
|
||||
// - "Free software licenses" at http://www.gnu.org/
|
||||
// - "OSI-approved" at http://www.opensource.org/
|
||||
//
|
||||
// 3) SPECIAL EXCEPTION
|
||||
//
|
||||
// Igor Pavlov, as the author of this code, expressly permits you
|
||||
// to statically or dynamically link your code (or bind by name)
|
||||
// to the files from LZMA SDK without subjecting your linked
|
||||
// code to the terms of the CPL or GNU LGPL.
|
||||
// Any modifications or additions to files from LZMA SDK, however,
|
||||
// are subject to the GNU LGPL or CPL terms.
|
||||
//
|
||||
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||
// while you keep LZMA SDK code unmodified.
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cruft because of pseudo-COM layer
|
||||
**************************************************************************/
|
||||
|
||||
#undef USE_LZMA_PROPERTIES
|
||||
|
||||
#undef MSDOS
|
||||
#undef OS2
|
||||
#undef _WIN32
|
||||
#undef _WIN32_WCE
|
||||
#undef COMPRESS_MF_MT
|
||||
#undef _NO_EXCEPTIONS
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# define INITGUID 1
|
||||
//# include "CPP/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
# include "CPP/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
#else
|
||||
# include "C/Common/MyInitGuid.h"
|
||||
//# include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
# include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
#endif
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
||||
void Init(const Byte *data, size_t size) {
|
||||
b_buf = data; b_size = size; b_pos = 0;
|
||||
}
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain;
|
||||
memcpy(data, b_buf + b_pos, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
||||
void Init(Byte *data, size_t size) {
|
||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
||||
}
|
||||
HRESULT WriteByte(Byte c) {
|
||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
||||
b_buf[b_pos++] = c;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
||||
memcpy(b_buf + b_pos, data, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return overflow ? E_FAIL : S_OK;
|
||||
}
|
||||
|
||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
upx_callback_p cb;
|
||||
};
|
||||
|
||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#if (ACC_CC_INTELC) && defined(__linux__)
|
||||
# pragma warning(disable: 424) // #424: extra ";" ignored
|
||||
#endif
|
||||
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# include "C/Alloc.c"
|
||||
# include "C/7zCrc.c"
|
||||
# include "C/Compress/Lz/MatchFinder.c"
|
||||
//# include "CPP/7zip/Common/InBuffer.cpp"
|
||||
# include "CPP/7zip/Common/OutBuffer.cpp"
|
||||
# include "CPP/7zip/Common/StreamUtils.cpp"
|
||||
//# include "CPP/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//# include "CPP/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
# include "CPP/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
# include "CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#else
|
||||
# include "C/Common/Alloc.cpp"
|
||||
# include "C/Common/CRC.cpp"
|
||||
//# include "C/7zip/Common/InBuffer.cpp"
|
||||
# include "C/7zip/Common/OutBuffer.cpp"
|
||||
# include "C/7zip/Common/StreamUtils.cpp"
|
||||
# include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||
//# include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//# include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
# include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
# include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#endif
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(M_IS_LZMA(method));
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
int r = UPX_E_ERROR;
|
||||
HRESULT rh;
|
||||
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
|
||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
|
||||
MyLzma::InStream is; is.AddRef();
|
||||
MyLzma::OutStream os; os.AddRef();
|
||||
is.Init(src, src_len);
|
||||
os.Init(dst, *dst_len);
|
||||
|
||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||
progress.cb = cb;
|
||||
|
||||
NCompress::NLZMA::CEncoder enc;
|
||||
const PROPID propIDs[8] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3 ds
|
||||
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5 fb
|
||||
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
||||
NCoderPropID::kMatchFinder // 7 mf
|
||||
};
|
||||
PROPVARIANT pr[8];
|
||||
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
|
||||
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||
unsigned nprops = 7;
|
||||
|
||||
// setup defaults
|
||||
pr[0].uintVal = 2; // 0 .. 4
|
||||
pr[1].uintVal = 0; // 0 .. 4
|
||||
pr[2].uintVal = 3; // 0 .. 8
|
||||
pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30
|
||||
pr[4].uintVal = 2;
|
||||
pr[5].uintVal = 64; // 5 .. 273
|
||||
pr[6].uintVal = 0;
|
||||
#ifdef COMPRESS_MF_BT4
|
||||
static wchar_t matchfinder[] = L"BT4";
|
||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||
pr[nprops].vt = VT_BSTR;
|
||||
pr[nprops].bstrVal = matchfinder;
|
||||
nprops++;
|
||||
#endif
|
||||
#if 1
|
||||
pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c;
|
||||
pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
|
||||
pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c;
|
||||
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
|
||||
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
|
||||
#endif
|
||||
// method overrides
|
||||
if (method >= 0x100) {
|
||||
pr[0].uintVal = (method >> 16) & 15;
|
||||
pr[1].uintVal = (method >> 12) & 15;
|
||||
pr[2].uintVal = (method >> 8) & 15;
|
||||
}
|
||||
#if 0
|
||||
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
||||
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||
// need about 6 MB of stack during runtime decompression.
|
||||
pr[1].uintVal = 4;
|
||||
pr[2].uintVal = 8;
|
||||
#endif
|
||||
|
||||
// FIXME: tune these settings according to level
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
pr[3].uintVal = 256 * 1024;
|
||||
pr[4].uintVal = 0;
|
||||
pr[5].uintVal = 8;
|
||||
break;
|
||||
case 2:
|
||||
pr[3].uintVal = 256 * 1024;
|
||||
pr[4].uintVal = 0;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 9:
|
||||
pr[3].uintVal = 8 * 1024 * 1024;
|
||||
break;
|
||||
case 10:
|
||||
pr[3].uintVal = src_len;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
// cconf overrides
|
||||
if (lcconf)
|
||||
{
|
||||
oassign(pr[0].uintVal, lcconf->pos_bits);
|
||||
oassign(pr[1].uintVal, lcconf->lit_pos_bits);
|
||||
oassign(pr[2].uintVal, lcconf->lit_context_bits);
|
||||
oassign(pr[3].uintVal, lcconf->dict_size);
|
||||
oassign(pr[5].uintVal, lcconf->num_fast_bytes);
|
||||
}
|
||||
|
||||
// limit dictionary size
|
||||
if (pr[3].uintVal > src_len)
|
||||
pr[3].uintVal = src_len;
|
||||
|
||||
// limit num_probs
|
||||
if (lcconf && lcconf->max_num_probs)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||
if (n <= lcconf->max_num_probs)
|
||||
break;
|
||||
if (pr[1].uintVal > pr[2].uintVal)
|
||||
{
|
||||
if (pr[1].uintVal == 0)
|
||||
goto error;
|
||||
pr[1].uintVal -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pr[2].uintVal == 0)
|
||||
goto error;
|
||||
pr[2].uintVal -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res->pos_bits = pr[0].uintVal;
|
||||
res->lit_pos_bits = pr[1].uintVal;
|
||||
res->lit_context_bits = pr[2].uintVal;
|
||||
res->dict_size = pr[3].uintVal;
|
||||
res->fast_mode = pr[4].uintVal;
|
||||
res->num_fast_bytes = pr[5].uintVal;
|
||||
res->match_finder_cycles = pr[6].uintVal;
|
||||
//res->num_probs = LzmaGetNumProbs(&s.Properties));
|
||||
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try {
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
||||
goto error;
|
||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||
goto error;
|
||||
if (os.overflow) {
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
goto error;
|
||||
}
|
||||
assert(os.b_pos == 5);
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
os.b_pos = 1;
|
||||
#else
|
||||
os.b_pos = 0;
|
||||
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||
os.WriteByte((t << 3) | res->pos_bits);
|
||||
os.WriteByte((res->lit_pos_bits << 4) | (res->lit_context_bits));
|
||||
#endif
|
||||
|
||||
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
} catch (...) { rh = E_OUTOFMEMORY; }
|
||||
#endif
|
||||
|
||||
assert(is.b_pos <= src_len);
|
||||
assert(os.b_pos <= *dst_len);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
else if (os.overflow)
|
||||
{
|
||||
assert(os.b_pos == *dst_len);
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
else if (rh == S_OK)
|
||||
{
|
||||
assert(is.b_pos == src_len);
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = os.b_pos;
|
||||
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
||||
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// decompress
|
||||
**************************************************************************/
|
||||
|
||||
#undef _LZMA_IN_CB
|
||||
#undef _LZMA_OUT_READ
|
||||
#undef _LZMA_PROB32
|
||||
#undef _LZMA_LOC_OPT
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# include "C/Compress/Lzma/LzmaDecode.h"
|
||||
# include "C/Compress/Lzma/LzmaDecode.c"
|
||||
#else
|
||||
# include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||
# include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||
#endif
|
||||
|
||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(M_IS_LZMA(method));
|
||||
// see res->num_probs above
|
||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||
|
||||
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
||||
SizeT src_out = 0, dst_out = 0;
|
||||
int r = UPX_E_ERROR;
|
||||
int rh;
|
||||
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
if (src_len < 2)
|
||||
goto error;
|
||||
rh = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||
if (rh != 0)
|
||||
goto error;
|
||||
src += 1; src_len -= 1;
|
||||
#else
|
||||
if (src_len < 3)
|
||||
goto error;
|
||||
s.Properties.pb = src[0] & 7;
|
||||
s.Properties.lp = (src[1] >> 4);
|
||||
s.Properties.lc = src[1] & 15;
|
||||
if (s.Properties.pb >= 5) goto error;
|
||||
if (s.Properties.lp >= 5) goto error;
|
||||
if (s.Properties.lc >= 9) goto error;
|
||||
// extra
|
||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
||||
src += 2; src_len -= 2;
|
||||
#endif
|
||||
|
||||
if (cresult)
|
||||
{
|
||||
assert(cresult->method == method);
|
||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
UNUSED(res);
|
||||
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||
}
|
||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||
if (!s.Probs)
|
||||
{
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||
assert(src_out <= src_len);
|
||||
assert(dst_out <= *dst_len);
|
||||
if (rh == 0)
|
||||
{
|
||||
r = UPX_E_OK;
|
||||
if (src_out != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = dst_out;
|
||||
free(s.Probs);
|
||||
|
||||
UNUSED(cresult);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(M_IS_LZMA(method));
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping.
|
||||
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_lzma_version_string(void)
|
||||
{
|
||||
#if (WITH_LZMA == 0x449)
|
||||
return "4.49";
|
||||
#elif (WITH_LZMA == 0x443)
|
||||
return "4.43";
|
||||
#else
|
||||
# error "unknown version"
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_LZMA */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
/* compress_ucl.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#if !defined(WITH_UCL)
|
||||
extern int compress_ucl_dummy;
|
||||
int compress_ucl_dummy = 0;
|
||||
#else
|
||||
|
||||
#if 1 && !defined(UCL_USE_ASM) && (ACC_ARCH_I386)
|
||||
# if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
||||
# define UCL_USE_ASM
|
||||
# endif
|
||||
#endif
|
||||
#if defined(UCL_NO_ASM)
|
||||
# undef UCL_USE_ASM
|
||||
#endif
|
||||
#if defined(ACC_CFG_NO_UNALIGNED)
|
||||
# undef UCL_USE_ASM
|
||||
#endif
|
||||
#if 1 && defined(UCL_USE_ASM)
|
||||
# include <ucl/ucl_asm.h>
|
||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||
# define ucl_nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
||||
# define ucl_nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_asm_safe_le32
|
||||
# define ucl_nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8
|
||||
# define ucl_nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16
|
||||
# define ucl_nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32
|
||||
# define ucl_nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8
|
||||
# define ucl_nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16
|
||||
# define ucl_nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int convert_errno_from_ucl(int r)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case UCL_E_OK: return UPX_E_OK;
|
||||
case UCL_E_ERROR: return UPX_E_ERROR;
|
||||
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
||||
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
||||
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
||||
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
||||
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
||||
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
||||
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
||||
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
||||
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
||||
// UCL extra:
|
||||
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||
{
|
||||
if (state != -1 && state != 3) return;
|
||||
upx_callback_p cb = (upx_callback_p) user;
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, a, b);
|
||||
}}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb_parm,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||
|
||||
ucl_progress_callback_t cb;
|
||||
cb.callback = 0;
|
||||
cb.user = NULL;
|
||||
if (cb_parm && cb_parm->nprogress) {
|
||||
cb.callback = wrap_nprogress_ucl;
|
||||
cb.user = cb_parm;
|
||||
}
|
||||
|
||||
ucl_compress_config_t cconf; cconf.reset();
|
||||
if (cconf_parm)
|
||||
cconf = cconf_parm->conf_ucl; // struct copy
|
||||
|
||||
ucl_uint *res = cresult->result_ucl.result;
|
||||
// assume no info available - fill in worst case results
|
||||
//res[0] = 1; // min_offset_found - NOT USED
|
||||
res[1] = src_len - 1; // max_offset_found
|
||||
//res[2] = 2; // min_match_found - NOT USED
|
||||
res[3] = src_len - 1; // max_match_found
|
||||
//res[4] = 1; // min_run_found - NOT USED
|
||||
res[5] = src_len; // max_run_found
|
||||
res[6] = 1; // first_offset_found
|
||||
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
cconf.bb_endian = 0;
|
||||
cconf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
static const unsigned char sizes[3] = {32, 8, 16};
|
||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||
}
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// make sure first_offset_found is set
|
||||
if (res[6] == 0)
|
||||
res[6] = 1;
|
||||
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
UNUSED(tbuf); // not needed for UCL
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_ucl_version_string(void)
|
||||
{
|
||||
return ucl_version_string();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_UCL */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
/* compress_zlib.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
void zlib_compress_config_t::reset()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
mem_level.reset();
|
||||
window_bits.reset();
|
||||
strategy.reset();
|
||||
}
|
||||
|
||||
|
||||
#if !defined(WITH_ZLIB)
|
||||
extern int compress_zlib_dummy;
|
||||
int compress_zlib_dummy = 0;
|
||||
#else
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
static int convert_errno_from_zlib(int zr)
|
||||
{
|
||||
switch (zr)
|
||||
{
|
||||
case Z_OK: return UPX_E_OK;
|
||||
case Z_DATA_ERROR: return UPX_E_ERROR;
|
||||
case Z_NEED_DICT: return UPX_E_ERROR;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb_parm,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
UNUSED(cb_parm);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : NULL;
|
||||
zlib_compress_result_t *res = &cresult->result_zlib;
|
||||
|
||||
if (level == 10)
|
||||
level = 9;
|
||||
|
||||
zlib_compress_config_t::mem_level_t mem_level;
|
||||
zlib_compress_config_t::window_bits_t window_bits;
|
||||
zlib_compress_config_t::strategy_t strategy;
|
||||
// cconf overrides
|
||||
if (lcconf)
|
||||
{
|
||||
oassign(mem_level, lcconf->mem_level);
|
||||
oassign(window_bits, lcconf->window_bits);
|
||||
oassign(strategy, lcconf->strategy);
|
||||
}
|
||||
|
||||
res->dummy = 0;
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) 0;
|
||||
s.zfree = (free_func) 0;
|
||||
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
||||
mem_level, strategy);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
zr = deflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END)
|
||||
goto error;
|
||||
zr = deflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) deflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK)
|
||||
{
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_ERROR;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
UNUSED(method);
|
||||
UNUSED(cresult);
|
||||
int r = UPX_E_ERROR;
|
||||
int zr;
|
||||
|
||||
z_stream s;
|
||||
s.zalloc = (alloc_func) 0;
|
||||
s.zfree = (free_func) 0;
|
||||
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||
s.avail_in = src_len;
|
||||
s.next_out = dst;
|
||||
s.avail_out = *dst_len;
|
||||
s.total_in = s.total_out = 0;
|
||||
|
||||
zr = inflateInit2(&s, -15);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
zr = inflate(&s, Z_FINISH);
|
||||
if (zr != Z_STREAM_END)
|
||||
goto error;
|
||||
zr = inflateEnd(&s);
|
||||
if (zr != Z_OK)
|
||||
goto error;
|
||||
r = UPX_E_OK;
|
||||
goto done;
|
||||
error:
|
||||
(void) inflateEnd(&s);
|
||||
r = convert_errno_from_zlib(zr);
|
||||
if (r == UPX_E_OK)
|
||||
r = UPX_E_ERROR;
|
||||
done:
|
||||
if (r == UPX_E_OK)
|
||||
{
|
||||
if (s.avail_in != 0 || s.total_in != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
}
|
||||
assert(s.total_in <= src_len);
|
||||
assert(s.total_out <= *dst_len);
|
||||
*dst_len = s.total_out;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping.
|
||||
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_zlib_version_string(void)
|
||||
{
|
||||
return zlibVersion();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_ZLIB */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+671
-602
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,75 +22,53 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_CONSOLE)
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
UNUSED(f);
|
||||
UNUSED(o);
|
||||
UNUSED(now);
|
||||
return CON_FILE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
#if 1
|
||||
fputs(s,f);
|
||||
fputs(s, f);
|
||||
#else
|
||||
/* filter out all ANSI sequences */
|
||||
int c;
|
||||
while ((c = *s++) != 0)
|
||||
{
|
||||
if (c == '\033' && *s == ']')
|
||||
{
|
||||
while ((c = *s++) != 0) {
|
||||
if (c == '\033' && *s == ']') {
|
||||
while (*s && *s != 'm')
|
||||
s++;
|
||||
}
|
||||
else
|
||||
fputc(c,f);
|
||||
} else
|
||||
fputc(c, f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_file =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_file = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,33 +22,30 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
FILE *con_term = nullptr;
|
||||
|
||||
FILE *con_term = NULL;
|
||||
|
||||
#if defined(USE_CONSOLE)
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static console_t * const me = &console_init;
|
||||
console_t * con = &console_init;
|
||||
static console_t *const me = &console_init;
|
||||
console_t *con = &console_init;
|
||||
|
||||
int con_mode = CON_INIT;
|
||||
|
||||
|
||||
static void try_init(console_t *c, FILE *f)
|
||||
{
|
||||
static void try_init(console_t *c, FILE *f) {
|
||||
int k;
|
||||
|
||||
assert(c);
|
||||
assert(c->init);
|
||||
k = c->init(f,opt->console,con_mode);
|
||||
k = c->init(f, opt->console, con_mode);
|
||||
if (k == CON_INIT)
|
||||
return;
|
||||
#if 0
|
||||
@@ -56,11 +53,10 @@ static void try_init(console_t *c, FILE *f)
|
||||
if (k != opt->console)
|
||||
return;
|
||||
#endif
|
||||
if (k > con_mode)
|
||||
{
|
||||
if (k > con_mode) {
|
||||
con_mode = k;
|
||||
con = c;
|
||||
con->init = 0;
|
||||
con->init = nullptr;
|
||||
if (!con->set_fg)
|
||||
con->set_fg = console_none.set_fg;
|
||||
if (!con->print0)
|
||||
@@ -70,41 +66,37 @@ static void try_init(console_t *c, FILE *f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int do_init(FILE *f)
|
||||
{
|
||||
static int do_init(FILE *f) {
|
||||
assert(con_mode == CON_INIT);
|
||||
|
||||
try_init(&console_none,f);
|
||||
try_init(&console_none, f);
|
||||
assert(con != me);
|
||||
assert(con == &console_none);
|
||||
if (opt->console == CON_NONE || opt->to_stdout)
|
||||
return con_mode;
|
||||
try_init(&console_file,f);
|
||||
try_init(&console_file, f);
|
||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||
return con_mode;
|
||||
|
||||
#if defined(USE_ANSI)
|
||||
try_init(&console_ansi_mono,f);
|
||||
try_init(&console_ansi_color,f);
|
||||
#if (USE_ANSI)
|
||||
try_init(&console_ansi_mono, f);
|
||||
try_init(&console_ansi_color, f);
|
||||
#endif
|
||||
#if defined(USE_SCREEN)
|
||||
try_init(&console_screen,f);
|
||||
#if (USE_SCREEN)
|
||||
try_init(&console_screen, f);
|
||||
#endif
|
||||
#if defined(USE_AALIB)
|
||||
try_init(&console_aalib,f);
|
||||
#if (USE_AALIB)
|
||||
try_init(&console_aalib, f);
|
||||
#endif
|
||||
|
||||
return con_mode;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
if (con != me)
|
||||
return con_mode;
|
||||
assert(o == -1);
|
||||
@@ -114,53 +106,36 @@ static int init(FILE *f, int o, int now)
|
||||
return do_init(f);
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
return con->set_fg(f,fg);
|
||||
return con->set_fg(f, fg);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
return con->intro(f);
|
||||
}
|
||||
|
||||
console_t console_init = {init, set_fg, nullptr, intro};
|
||||
|
||||
console_t console_init =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
0,
|
||||
intro
|
||||
};
|
||||
|
||||
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
||||
{
|
||||
void con_fprintf(FILE *f, const char *format, ...) {
|
||||
va_list args;
|
||||
char buf[80*25];
|
||||
char buf[80 * 25];
|
||||
|
||||
va_start(args, format);
|
||||
upx_vsnprintf(buf, sizeof(buf), format,args);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
con->print0(f,buf);
|
||||
con->print0(f, buf);
|
||||
}
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,61 +22,42 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_CONSOLE)
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
UNUSED(f);
|
||||
UNUSED(o);
|
||||
UNUSED(now);
|
||||
return CON_NONE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
UNUSED(f);
|
||||
UNUSED(s);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_none =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_none = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,29 +22,26 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_SCREEN)
|
||||
#if (USE_SCREEN)
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int do_init(screen_t *s, int fd)
|
||||
{
|
||||
static int do_init(screen_t *s, int fd) {
|
||||
int fg, bg;
|
||||
|
||||
if (s->init(s,fd) != 0)
|
||||
if (s->init(s, fd) != 0)
|
||||
return -1;
|
||||
|
||||
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
||||
@@ -59,88 +56,78 @@ static int do_init(screen_t *s, int fd)
|
||||
if (fg == (bg >> 4))
|
||||
return -1;
|
||||
if (bg != BG_BLACK)
|
||||
if (!s->isMono(s))
|
||||
{
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
if (!s->isMono(s)) {
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static screen_t *do_construct(screen_t *s, int fd)
|
||||
{
|
||||
static screen_t *do_construct(screen_t *s, int fd) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (do_init(s,fd) != 0)
|
||||
{
|
||||
return nullptr;
|
||||
if (do_init(s, fd) != 0) {
|
||||
s->destroy(s);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static screen_t *screen = NULL;
|
||||
static screen_t *screen = nullptr;
|
||||
|
||||
static void __acc_cdecl_atexit do_destroy(void)
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
static void __acc_cdecl_atexit do_destroy(void) {
|
||||
if (screen) {
|
||||
if (screen->atExit)
|
||||
screen->atExit();
|
||||
screen->destroy(screen);
|
||||
screen = NULL;
|
||||
screen = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mode = -1;
|
||||
static int init_fg = -1;
|
||||
static int init_bg = -1;
|
||||
static int cur_fg = -1;
|
||||
static int cur_bg = -1;
|
||||
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
int fd = fileno(f);
|
||||
int n;
|
||||
|
||||
UNUSED(now);
|
||||
assert(screen == NULL);
|
||||
assert(screen == nullptr);
|
||||
|
||||
if (o == CON_SCREEN)
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
n = CON_ANSI_COLOR;
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
n = CON_ANSI_MONO;
|
||||
else
|
||||
return CON_INIT;
|
||||
|
||||
#if defined(__DJGPP__)
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||
screen = do_construct(screen_djgpp2_construct(), fd);
|
||||
#endif
|
||||
#if defined(USE_SCREEN_WIN32)
|
||||
#if (USE_SCREEN_WIN32)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_win32_construct(),fd);
|
||||
screen = do_construct(screen_win32_construct(), fd);
|
||||
#endif
|
||||
#if defined(USE_SCREEN_VCSA)
|
||||
#if (USE_SCREEN_VCSA)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_vcsa_construct(),fd);
|
||||
screen = do_construct(screen_vcsa_construct(), fd);
|
||||
#endif
|
||||
#if defined(USE_SCREEN_CURSES)
|
||||
#if (USE_SCREEN_CURSES)
|
||||
if (!screen && o == CON_SCREEN)
|
||||
screen = do_construct(screen_curses_construct(),fd);
|
||||
screen = do_construct(screen_curses_construct(), fd);
|
||||
#endif
|
||||
if (!screen)
|
||||
return CON_INIT;
|
||||
@@ -155,19 +142,16 @@ static int init(FILE *f, int o, int now)
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
const int last_fg = cur_fg;
|
||||
int f1 = fg & mask_fg;
|
||||
int f2 = init_fg & mask_fg;
|
||||
|
||||
UNUSED(f);
|
||||
cur_fg = fg;
|
||||
if (screen->isMono(screen))
|
||||
{
|
||||
if (screen->isMono(screen)) {
|
||||
const int b = (init_bg & mask_bg) >> 4;
|
||||
if (fg == -1) /* restore startup fg */
|
||||
if (fg == -1) /* restore startup fg */
|
||||
f1 = f2;
|
||||
else if (b == 0)
|
||||
f1 = (f2 <= 8) ? 15 : 8;
|
||||
@@ -175,19 +159,15 @@ static int set_fg(FILE *f, int fg)
|
||||
f1 = (f2 == 0) ? 15 : 0;
|
||||
else
|
||||
f1 = (f2 == 0) ? 8 : 0;
|
||||
}
|
||||
else if (con_mode == CON_ANSI_MONO && f1 != f2)
|
||||
{
|
||||
} else if (con_mode == CON_ANSI_MONO && f1 != f2) {
|
||||
f1 = f2 ^ 0x08;
|
||||
}
|
||||
|
||||
screen->setFg(screen,f1 & mask_fg);
|
||||
screen->setFg(screen, f1 & mask_fg);
|
||||
return last_fg;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *ss)
|
||||
{
|
||||
static void print0(FILE *f, const char *ss) {
|
||||
int cx, cy;
|
||||
int old_cx = 0, old_cy = 0;
|
||||
const int sx = screen->getCols(screen);
|
||||
@@ -199,57 +179,47 @@ static void print0(FILE *f, const char *ss)
|
||||
// scrollUp() under Win32 is *extremely* slow.
|
||||
UNUSED(f);
|
||||
|
||||
screen->getCursor(screen,&old_cx,&old_cy);
|
||||
cx = old_cx; cy = old_cy;
|
||||
screen->getCursor(screen, &old_cx, &old_cy);
|
||||
cx = old_cx;
|
||||
cy = old_cy;
|
||||
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
const char *s = ss;
|
||||
// char buffer for pass 2
|
||||
char p[256+1];
|
||||
char p[256 + 1];
|
||||
int pi = 0, px = 0, py = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
// walk over whitespace
|
||||
for (;;)
|
||||
{
|
||||
if (*s == '\n')
|
||||
{
|
||||
for (;;) {
|
||||
if (*s == '\n') {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
else if (*s == '\r')
|
||||
{
|
||||
} else if (*s == '\r') {
|
||||
cx = 0;
|
||||
if (pass > 0 && cy < sy)
|
||||
screen->clearLine(screen,cy);
|
||||
}
|
||||
else
|
||||
screen->clearLine(screen, cy);
|
||||
} else
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
// adjust cursor
|
||||
if (cx >= sx)
|
||||
{
|
||||
if (cx >= sx) {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// check if we should print something
|
||||
if (pi > 0 && (*s == 0 || py != cy))
|
||||
{
|
||||
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||
p[pi] = 0;
|
||||
screen->putString(screen,p,px,py);
|
||||
screen->putString(screen, p, px, py);
|
||||
pi = 0;
|
||||
}
|
||||
// check if we should scroll even more (this can happen
|
||||
// if the string is longer than sy lines)
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy -= scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
||||
// done ?
|
||||
if (*s == 0)
|
||||
break;
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// store current char
|
||||
if (pi == 0)
|
||||
{
|
||||
if (pi == 0) {
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
@@ -273,52 +241,35 @@ static void print0(FILE *f, const char *ss)
|
||||
s++;
|
||||
}
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (pass == 0) {
|
||||
// end of pass 1 - scroll up, restore cursor
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy = old_cy - scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
cy = old_cy;
|
||||
cx = old_cx;
|
||||
}
|
||||
}
|
||||
|
||||
screen->setCursor(screen,cx,cy);
|
||||
screen->setCursor(screen, cx, cy);
|
||||
screen->refresh(screen);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
#if defined(USE_FRAMES)
|
||||
#if (USE_FRAMES)
|
||||
if (screen->intro)
|
||||
return screen->intro(screen,screen_show_frames);
|
||||
return screen->intro(screen, screen_show_frames);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_screen =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
|
||||
console_t console_screen = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_SCREEN */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,10 +22,10 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -39,96 +39,77 @@
|
||||
#undef USE_SCREEN_WIN32
|
||||
#undef USE_FRAMES
|
||||
|
||||
#if defined(WITH_GUI) && !defined(NO_CONSOLE)
|
||||
# define NO_CONSOLE
|
||||
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
||||
#define NO_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#if 1 && defined(__linux__)
|
||||
# define USE_SCREEN
|
||||
# define USE_SCREEN_VCSA
|
||||
# if !defined(HAVE_LINUX_KD_H)
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# endif
|
||||
# if !defined(HAVE_LINUX_KDEV_T_H) || !defined(HAVE_LINUX_MAJOR_H)
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# endif
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_VCSA 1
|
||||
#if !(HAVE_LINUX_KD_H)
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#endif
|
||||
#if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1 && defined(__DJGPP__)
|
||||
# define USE_SCREEN
|
||||
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
#define USE_SCREEN 1
|
||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
# define USE_SCREEN
|
||||
# define USE_SCREEN_WIN32
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_WIN32 1
|
||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||
# define USE_SCREEN
|
||||
# define USE_SCREEN_WIN32
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_WIN32 1
|
||||
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
|
||||
#define NO_CONSOLE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 || defined(NO_ANSI)
|
||||
# undef USE_ANSI
|
||||
#if 0 || (NO_ANSI)
|
||||
#undef USE_ANSI
|
||||
#endif
|
||||
#if 0 || defined(NO_SCREEN)
|
||||
# undef USE_SCREEN
|
||||
#if 0 || (NO_SCREEN)
|
||||
#undef USE_SCREEN
|
||||
#endif
|
||||
#if 0 || defined(NO_FRAMES) || !defined(USE_SCREEN)
|
||||
# undef USE_FRAMES
|
||||
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
#if 1
|
||||
# undef USE_FRAMES
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 || defined(USE_ANSI) || defined(USE_SCREEN)
|
||||
# define USE_CONSOLE
|
||||
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||
#define USE_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#if 0 || defined(NO_CONSOLE) || !defined(USE_CONSOLE)
|
||||
# undef USE_CONSOLE
|
||||
# undef USE_ANSI
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# undef USE_SCREEN_CURSES
|
||||
# undef USE_FRAMES
|
||||
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
||||
#undef USE_CONSOLE
|
||||
#undef USE_ANSI
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#undef USE_SCREEN_CURSES
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
enum {
|
||||
CON_INIT,
|
||||
CON_NONE,
|
||||
CON_FILE,
|
||||
CON_ANSI_MONO,
|
||||
CON_ANSI_COLOR,
|
||||
CON_SCREEN,
|
||||
CON_UNUSED
|
||||
};
|
||||
enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
|
||||
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
#if defined(USE_CONSOLE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int (*init)(FILE *f, int, int);
|
||||
int (*set_fg)(FILE *f, int fg);
|
||||
void (*print0)(FILE *f, const char *s);
|
||||
bool (*intro)(FILE *f);
|
||||
}
|
||||
console_t;
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
||||
__attribute__((__format__(printf,2,3)));
|
||||
#else
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
||||
#endif
|
||||
} console_t;
|
||||
|
||||
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
||||
|
||||
#define FG_BLACK 0x00
|
||||
#define FG_BLUE 0x01
|
||||
@@ -147,25 +128,24 @@ void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
||||
#define FG_YELLOW 0x0e
|
||||
#define FG_WHITE 0x0f
|
||||
|
||||
#define BG_BLACK 0x00
|
||||
#define BG_BLUE 0x10
|
||||
#define BG_GREEN 0x20
|
||||
#define BG_CYAN 0x30
|
||||
#define BG_RED 0x40
|
||||
#define BG_VIOLET 0x50
|
||||
#define BG_ORANGE 0x60
|
||||
#define BG_WHITE 0x70
|
||||
#define BG_BLACK 0x00
|
||||
#define BG_BLUE 0x10
|
||||
#define BG_GREEN 0x20
|
||||
#define BG_CYAN 0x30
|
||||
#define BG_RED 0x40
|
||||
#define BG_VIOLET 0x50
|
||||
#define BG_ORANGE 0x60
|
||||
#define BG_WHITE 0x70
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
extern FILE *con_term;
|
||||
|
||||
#if defined(USE_CONSOLE)
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
extern int con_mode;
|
||||
extern console_t *con;
|
||||
@@ -177,18 +157,13 @@ extern console_t console_ansi_mono;
|
||||
extern console_t console_ansi_color;
|
||||
extern console_t console_screen;
|
||||
|
||||
|
||||
#define con_fg(f,x) con->set_fg(f,x)
|
||||
#define con_fg(f, x) con->set_fg(f, x)
|
||||
|
||||
#else
|
||||
|
||||
#define con_fg(f,x) 0
|
||||
#define con_fprintf fprintf
|
||||
#define con_fg(f, x) 0
|
||||
#define con_fprintf fprintf
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,23 +22,24 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_SCREEN) && defined(__DJGPP__)
|
||||
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
#if (ACC_CC_GNUC >= 0x040300ul)
|
||||
#pragma GCC diagnostic ignored "-Wvla"
|
||||
#endif
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#define this local_this
|
||||
#define this self
|
||||
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
/* #define USE_SCROLLBACK */
|
||||
|
||||
/* #define USE_SCROLLBACK 1 */
|
||||
|
||||
/*************************************************************************
|
||||
// direct screen access
|
||||
@@ -53,13 +54,13 @@
|
||||
#include <sys/exceptn.h>
|
||||
#include <sys/farptr.h>
|
||||
#include <sys/movedata.h>
|
||||
#define dossel _go32_info_block.selector_for_linear_memory
|
||||
#define co80 _go32_info_block.linear_address_of_primary_screen
|
||||
#define dossel _go32_info_block.selector_for_linear_memory
|
||||
#define co80 _go32_info_block.linear_address_of_primary_screen
|
||||
#undef kbhit
|
||||
|
||||
#define Cell upx_uint16_t
|
||||
|
||||
struct screen_data_t
|
||||
{
|
||||
struct screen_data_t {
|
||||
int mode;
|
||||
int cols;
|
||||
int rows;
|
||||
@@ -69,92 +70,63 @@ struct screen_data_t
|
||||
unsigned char attr;
|
||||
unsigned char init_attr;
|
||||
unsigned char empty_attr;
|
||||
unsigned short empty_cell;
|
||||
#ifdef USE_SCROLLBACK
|
||||
Cell empty_cell;
|
||||
#if USE_SCROLLBACK
|
||||
/* scrollback buffer */
|
||||
unsigned short sb_buf[32][256];
|
||||
Cell sb_buf[32][256];
|
||||
int sb_size;
|
||||
int sb_base;
|
||||
int sb_sp;
|
||||
#endif /* USE_SCROLLBACK */
|
||||
};
|
||||
|
||||
|
||||
/* atExit information */
|
||||
static struct
|
||||
{
|
||||
static struct {
|
||||
int cursor_shape;
|
||||
} ae = {
|
||||
-1
|
||||
};
|
||||
} ae = {-1};
|
||||
|
||||
|
||||
#ifdef USE_SCROLLBACK
|
||||
static __inline__ void sb_add(screen_t *this, int *val, int inc)
|
||||
{
|
||||
#if USE_SCROLLBACK
|
||||
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
||||
*val = (*val + inc) & (this->data->sb_size - 1);
|
||||
}
|
||||
|
||||
static void sb_push(screen_t *this, const unsigned short *line, int len)
|
||||
{
|
||||
memcpy(this->data->sb_buf[this->data->sb_sp],line,len);
|
||||
sb_add(this,&this->data->sb_sp,1);
|
||||
static void sb_push(screen_t *this, const Cell *line, int len) {
|
||||
memcpy(this->data->sb_buf[this->data->sb_sp], line, len);
|
||||
sb_add(this, &this->data->sb_sp, 1);
|
||||
if (this->data->sb_sp == this->data->sb_base)
|
||||
sb_add(this,&this->data->sb_base,1);
|
||||
sb_add(this, &this->data->sb_base, 1);
|
||||
}
|
||||
|
||||
static const unsigned short *sb_pop(screen_t *this)
|
||||
{
|
||||
static const Cell *sb_pop(screen_t *this) {
|
||||
if (this->data->sb_sp == this->data->sb_base)
|
||||
return NULL;
|
||||
sb_add(this,&this->data->sb_sp,-1);
|
||||
return nullptr;
|
||||
sb_add(this, &this->data->sb_sp, -1);
|
||||
return this->data->sb_buf[this->data->sb_sp];
|
||||
}
|
||||
#endif /* USE_SCROLLBACK */
|
||||
|
||||
static void refresh(screen_t *this) { UNUSED(this); }
|
||||
|
||||
static void refresh(screen_t *this)
|
||||
{
|
||||
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
||||
UNUSED(this);
|
||||
return (Cell) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||
}
|
||||
|
||||
|
||||
static __inline__
|
||||
unsigned short make_cell(screen_t *this, int ch, int attr)
|
||||
{
|
||||
UNUSED(this);
|
||||
return (unsigned short) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||
}
|
||||
|
||||
|
||||
static int getMode(const screen_t *this)
|
||||
{
|
||||
static int getMode(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return ScreenMode();
|
||||
}
|
||||
|
||||
|
||||
static int getPage(const screen_t *this)
|
||||
{
|
||||
static int getPage(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return _farpeekb(dossel, 0x462);
|
||||
}
|
||||
|
||||
static int getRows(const screen_t *this) { return this->data->rows; }
|
||||
|
||||
static int getRows(const screen_t *this)
|
||||
{
|
||||
return this->data->rows;
|
||||
}
|
||||
static int getCols(const screen_t *this) { return this->data->cols; }
|
||||
|
||||
|
||||
static int getCols(const screen_t *this)
|
||||
{
|
||||
return this->data->cols;
|
||||
}
|
||||
|
||||
|
||||
static int isMono(const screen_t *this)
|
||||
{
|
||||
static int isMono(const screen_t *this) {
|
||||
if (this->data->mode == 7)
|
||||
return 1;
|
||||
if ((_farpeekb(dossel, 0x465) & (4 | 16)) != 0)
|
||||
@@ -162,42 +134,26 @@ static int isMono(const screen_t *this)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getFg(const screen_t *this) { return this->data->attr & mask_fg; }
|
||||
|
||||
static int getFg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_fg;
|
||||
}
|
||||
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
||||
|
||||
|
||||
static int getBg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_bg;
|
||||
}
|
||||
|
||||
|
||||
static void setFg(screen_t *this, int fg)
|
||||
{
|
||||
static void setFg(screen_t *this, int fg) {
|
||||
this->data->attr = (this->data->attr & mask_bg) | (fg & mask_fg);
|
||||
}
|
||||
|
||||
|
||||
static void setBg(screen_t *this, int bg)
|
||||
{
|
||||
static void setBg(screen_t *this, int bg) {
|
||||
this->data->attr = (this->data->attr & mask_fg) | (bg & mask_bg);
|
||||
}
|
||||
|
||||
|
||||
static void setCursor(screen_t *this, int x, int y)
|
||||
{
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows)
|
||||
{
|
||||
ScreenSetCursor(y,x);
|
||||
static void setCursor(screen_t *this, int x, int y) {
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows) {
|
||||
ScreenSetCursor(y, x);
|
||||
this->data->cursor_x = x;
|
||||
this->data->cursor_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// I added ScreenGetCursor, because when upx prints something longer than
|
||||
// 1 line (an error message for example), the this->data->cursor_y can
|
||||
@@ -209,88 +165,71 @@ static void setCursor(screen_t *this, int x, int y)
|
||||
// the 2 passes implementation.
|
||||
*/
|
||||
|
||||
static void getCursor(const screen_t *this, int *x, int *y)
|
||||
{
|
||||
static void getCursor(const screen_t *this, int *x, int *y) {
|
||||
int cx = this->data->cursor_x;
|
||||
int cy = this->data->cursor_y;
|
||||
#if 1
|
||||
ScreenGetCursor(&cy,&cx);
|
||||
ScreenGetCursor(&cy, &cx);
|
||||
#endif
|
||||
if (x) *x = cx;
|
||||
if (y) *y = cy;
|
||||
if (x)
|
||||
*x = cx;
|
||||
if (y)
|
||||
*y = cy;
|
||||
}
|
||||
|
||||
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y)
|
||||
{
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y) {
|
||||
UNUSED(this);
|
||||
ScreenPutChar(ch,attr,x,y);
|
||||
ScreenPutChar(ch, attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void putChar(screen_t *this, int ch, int x, int y)
|
||||
{
|
||||
ScreenPutChar(ch,this->data->attr,x,y);
|
||||
static void putChar(screen_t *this, int ch, int x, int y) {
|
||||
ScreenPutChar(ch, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
{
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) {
|
||||
UNUSED(this);
|
||||
assert((int)strlen(s) <= 256);
|
||||
assert(x + (int)strlen(s) <= this->data->cols);
|
||||
ScreenPutString(s,attr,x,y);
|
||||
assert((int) strlen(s) <= 256);
|
||||
assert(x + (int) strlen(s) <= this->data->cols);
|
||||
ScreenPutString(s, attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void putString(screen_t *this, const char *s, int x, int y)
|
||||
{
|
||||
assert((int)strlen(s) <= 256);
|
||||
assert(x + (int)strlen(s) <= this->data->cols);
|
||||
ScreenPutString(s,this->data->attr,x,y);
|
||||
static void putString(screen_t *this, const char *s, int x, int y) {
|
||||
assert((int) strlen(s) <= 256);
|
||||
assert(x + (int) strlen(s) <= this->data->cols);
|
||||
ScreenPutString(s, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static void getChar(screen_t *this, int *ch, int *attr, int x, int y)
|
||||
{
|
||||
static void getChar(screen_t *this, int *ch, int *attr, int x, int y) {
|
||||
UNUSED(this);
|
||||
ScreenGetChar(ch,attr,x,y);
|
||||
ScreenGetChar(ch, attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static int getCursorShape(const screen_t *this)
|
||||
{
|
||||
static int getCursorShape(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return _farpeekw(dossel, 0x460);
|
||||
}
|
||||
|
||||
|
||||
static void setCursorShape(screen_t *this, int shape)
|
||||
{
|
||||
static void setCursorShape(screen_t *this, int shape) {
|
||||
__dpmi_regs r;
|
||||
|
||||
memset(&r,0,sizeof(r)); /* just in case... */
|
||||
memset(&r, 0, sizeof(r)); /* just in case... */
|
||||
r.x.ax = 0x0103;
|
||||
#if 1
|
||||
if (this)
|
||||
r.h.al = getMode(this); /* required for buggy BIOSes */
|
||||
r.h.al = getMode(this); /* required for buggy BIOSes */
|
||||
#endif
|
||||
r.x.cx = shape & 0x7f1f;
|
||||
__dpmi_int(0x10, &r);
|
||||
}
|
||||
|
||||
|
||||
static int hideCursor(screen_t *this)
|
||||
{
|
||||
static int hideCursor(screen_t *this) {
|
||||
int shape = getCursorShape(this);
|
||||
setCursorShape(this,0x2000);
|
||||
setCursorShape(this, 0x2000);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
static int init(screen_t *this, int fd)
|
||||
{
|
||||
static int init(screen_t *this, int fd) {
|
||||
int mode;
|
||||
int cols, rows;
|
||||
int attr;
|
||||
@@ -304,7 +243,7 @@ static int init(screen_t *this, int fd)
|
||||
return -1;
|
||||
|
||||
this->data->mode = -1;
|
||||
#ifdef USE_SCROLLBACK
|
||||
#if USE_SCROLLBACK
|
||||
this->data->sb_size = 32;
|
||||
this->data->sb_base = 0;
|
||||
this->data->sb_sp = 0;
|
||||
@@ -314,7 +253,7 @@ static int init(screen_t *this, int fd)
|
||||
if (getPage(this) != 0)
|
||||
return -1;
|
||||
|
||||
#if 1 && defined(__DJGPP__)
|
||||
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
/* check for Windows NT/2000/XP */
|
||||
if (_get_dos_version(1) == 0x0532)
|
||||
return -1;
|
||||
@@ -323,27 +262,23 @@ static int init(screen_t *this, int fd)
|
||||
cols = ScreenCols();
|
||||
rows = ScreenRows();
|
||||
mode = getMode(this);
|
||||
if (mode > 0x13)
|
||||
{
|
||||
if (mode > 0x13) {
|
||||
/* assume this is some SVGA/VESA text mode */
|
||||
__dpmi_regs r;
|
||||
|
||||
memset(&r,0,sizeof(r)); /* just in case... */
|
||||
r.x.ax = 0x4f03; /* VESA - get current video mode */
|
||||
memset(&r, 0, sizeof(r)); /* just in case... */
|
||||
r.x.ax = 0x4f03; /* VESA - get current video mode */
|
||||
__dpmi_int(0x10, &r);
|
||||
if (r.h.ah == 0)
|
||||
mode = r.x.bx;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (mode != 2 && mode != 3 && mode != 7)
|
||||
return -1;
|
||||
}
|
||||
ScreenGetCursor(&this->data->cursor_y,&this->data->cursor_x);
|
||||
getChar(this,NULL,&attr,this->data->cursor_x,this->data->cursor_y);
|
||||
ScreenGetCursor(&this->data->cursor_y, &this->data->cursor_x);
|
||||
getChar(this, nullptr, &attr, this->data->cursor_x, this->data->cursor_y);
|
||||
this->data->init_attr = attr;
|
||||
if (mode != 7)
|
||||
{
|
||||
if (mode != 7) {
|
||||
/* Does it normally blink when bg has its 3rd bit set? */
|
||||
int b_mask = (_farpeekb(dossel, 0x465) & 0x20) ? 0x70 : 0xf0;
|
||||
attr = attr & (mask_fg | b_mask);
|
||||
@@ -353,27 +288,22 @@ static int init(screen_t *this, int fd)
|
||||
this->data->rows = rows;
|
||||
this->data->attr = attr;
|
||||
this->data->empty_attr = attr;
|
||||
this->data->empty_cell = make_cell(this,' ',attr);
|
||||
this->data->empty_cell = make_cell(this, ' ', attr);
|
||||
|
||||
ae.cursor_shape = getCursorShape(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
{
|
||||
if (y >= 0 && y < this->data->rows && len > 0 && len <= 2*this->data->cols)
|
||||
movedata(_my_ds(),(unsigned)line,dossel,co80+y*this->data->cols*2,len);
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len) {
|
||||
if (y >= 0 && y < this->data->rows && len > 0 && len <= 2 * this->data->cols)
|
||||
movedata(_my_ds(), (unsigned) line, dossel, co80 + y * this->data->cols * 2, len);
|
||||
}
|
||||
|
||||
|
||||
static void clearLine(screen_t *this, int y)
|
||||
{
|
||||
if (y >= 0 && y < this->data->rows)
|
||||
{
|
||||
static void clearLine(screen_t *this, int y) {
|
||||
if (y >= 0 && y < this->data->rows) {
|
||||
unsigned sp = co80 + y * this->data->cols * 2;
|
||||
unsigned short a = this->data->empty_cell;
|
||||
Cell a = this->data->empty_cell;
|
||||
int i = this->data->cols;
|
||||
|
||||
_farsetsel(dossel);
|
||||
@@ -384,51 +314,43 @@ static void clearLine(screen_t *this, int y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void clear(screen_t *this)
|
||||
{
|
||||
static void clear(screen_t *this) {
|
||||
unsigned char attr = ScreenAttrib;
|
||||
ScreenAttrib = this->data->empty_attr;
|
||||
ScreenClear();
|
||||
ScreenAttrib = attr;
|
||||
}
|
||||
|
||||
|
||||
static int scrollUp(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollUp(screen_t *this, int lines) {
|
||||
int sr = this->data->rows;
|
||||
int sc = this->data->cols;
|
||||
int y;
|
||||
|
||||
|
||||
if (lines <= 0 || lines > sr)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_SCROLLBACK
|
||||
#if USE_SCROLLBACK
|
||||
/* copy to scrollback buffer */
|
||||
for (y = 0; y < lines; y++)
|
||||
{
|
||||
unsigned short buf[ sc ];
|
||||
movedata(dossel,co80+y*this->data->cols*2,_my_ds(),(unsigned)buf,sizeof(buf));
|
||||
sb_push(this,buf,sizeof(buf));
|
||||
for (y = 0; y < lines; y++) {
|
||||
Cell buf[sc];
|
||||
movedata(dossel, co80 + y * this->data->cols * 2, _my_ds(), (unsigned) buf, sizeof(buf));
|
||||
sb_push(this, buf, sizeof(buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* move screen up */
|
||||
if (lines < sr)
|
||||
movedata(dossel,co80+lines*sc*2,dossel,co80,(sr-lines)*sc*2);
|
||||
movedata(dossel, co80 + lines * sc * 2, dossel, co80, (sr - lines) * sc * 2);
|
||||
|
||||
/* fill in blank lines at bottom */
|
||||
for (y = sr - lines; y < sr; y++)
|
||||
clearLine(this,y);
|
||||
clearLine(this, y);
|
||||
|
||||
this->data->scroll_counter += lines;
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
static int scrollDown(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollDown(screen_t *this, int lines) {
|
||||
int sr = this->data->rows;
|
||||
int sc = this->data->cols;
|
||||
int y;
|
||||
@@ -437,26 +359,24 @@ static int scrollDown(screen_t *this, int lines)
|
||||
return 0;
|
||||
|
||||
/* move screen down */
|
||||
if (lines < sr)
|
||||
{
|
||||
if (lines < sr) {
|
||||
/* !@#% movedata can't handle overlapping regions... */
|
||||
/* movedata(dossel,co80,dossel,co80+lines*sc*2,(sr-lines)*sc*2); */
|
||||
unsigned short buf[ (sr-lines)*sc ];
|
||||
movedata(dossel,co80,_my_ds(),(unsigned)buf,sizeof(buf));
|
||||
movedata(_my_ds(),(unsigned)buf,dossel,co80+lines*sc*2,sizeof(buf));
|
||||
Cell buf[(sr - lines) * sc];
|
||||
movedata(dossel, co80, _my_ds(), (unsigned) buf, sizeof(buf));
|
||||
movedata(_my_ds(), (unsigned) buf, dossel, co80 + lines * sc * 2, sizeof(buf));
|
||||
}
|
||||
|
||||
/* copy top lines from scrollback buffer */
|
||||
for (y = lines; --y >= 0; )
|
||||
{
|
||||
#ifdef USE_SCROLLBACK
|
||||
const unsigned short *buf = sb_pop(this);
|
||||
if (buf == NULL)
|
||||
clearLine(this,y);
|
||||
for (y = lines; --y >= 0;) {
|
||||
#if USE_SCROLLBACK
|
||||
const Cell *buf = sb_pop(this);
|
||||
if (buf == nullptr)
|
||||
clearLine(this, y);
|
||||
else
|
||||
updateLineN(this,buf,y,sc*2);
|
||||
updateLineN(this, buf, y, sc * 2);
|
||||
#else
|
||||
clearLine(this,y);
|
||||
clearLine(this, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -464,24 +384,16 @@ static int scrollDown(screen_t *this, int lines)
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int getScrollCounter(const screen_t *this) { return this->data->scroll_counter; }
|
||||
|
||||
static int getScrollCounter(const screen_t *this)
|
||||
{
|
||||
return this->data->scroll_counter;
|
||||
}
|
||||
|
||||
|
||||
static int s_kbhit(screen_t *this)
|
||||
{
|
||||
static int s_kbhit(screen_t *this) {
|
||||
UNUSED(this);
|
||||
return kbhit();
|
||||
}
|
||||
|
||||
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
{
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *)) {
|
||||
int shape;
|
||||
unsigned short old_flags = __djgpp_hwint_flags;
|
||||
upx_uint16_t old_flags = __djgpp_hwint_flags;
|
||||
|
||||
if ((this->data->init_attr & mask_bg) != BG_BLACK)
|
||||
return 0;
|
||||
@@ -492,7 +404,7 @@ static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
|
||||
shape = hideCursor(this);
|
||||
show_frames(this);
|
||||
setCursorShape(this,shape);
|
||||
setCursorShape(this, shape);
|
||||
|
||||
while (kbhit())
|
||||
(void) getkey();
|
||||
@@ -501,65 +413,30 @@ static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void atExit(void)
|
||||
{
|
||||
static void atExit(void) {
|
||||
static int done = 0;
|
||||
if (done) return;
|
||||
if (done)
|
||||
return;
|
||||
done = 1;
|
||||
if (ae.cursor_shape >= 0)
|
||||
setCursorShape(NULL,ae.cursor_shape);
|
||||
setCursorShape(nullptr, ae.cursor_shape);
|
||||
}
|
||||
|
||||
|
||||
static const screen_t driver =
|
||||
{
|
||||
sobject_destroy,
|
||||
0, /* finalize, */
|
||||
atExit,
|
||||
init,
|
||||
refresh,
|
||||
getMode,
|
||||
getPage,
|
||||
getRows,
|
||||
getCols,
|
||||
isMono,
|
||||
getFg,
|
||||
getBg,
|
||||
getCursor,
|
||||
getCursorShape,
|
||||
setFg,
|
||||
setBg,
|
||||
setCursor,
|
||||
setCursorShape,
|
||||
hideCursor,
|
||||
putChar,
|
||||
putCharAttr,
|
||||
putString,
|
||||
putStringAttr,
|
||||
clear,
|
||||
clearLine,
|
||||
updateLineN,
|
||||
scrollUp,
|
||||
scrollDown,
|
||||
getScrollCounter,
|
||||
s_kbhit,
|
||||
intro,
|
||||
(struct screen_data_t *) 0
|
||||
};
|
||||
|
||||
static const screen_t driver = {sobject_destroy, nullptr, /* finalize */
|
||||
atExit, init, refresh,
|
||||
getMode, getPage, getRows,
|
||||
getCols, isMono, getFg,
|
||||
getBg, getCursor, getCursorShape,
|
||||
setFg, setBg, setCursor,
|
||||
setCursorShape, hideCursor, putChar,
|
||||
putCharAttr, putString, putStringAttr,
|
||||
clear, clearLine, updateLineN,
|
||||
scrollUp, scrollDown, getScrollCounter,
|
||||
s_kbhit, intro, (struct screen_data_t *) nullptr};
|
||||
|
||||
/* public constructor */
|
||||
screen_t *screen_djgpp2_construct(void)
|
||||
{
|
||||
return sobject_construct(&driver,sizeof(*driver.data));
|
||||
}
|
||||
screen_t *screen_djgpp2_construct(void) { return sobject_construct(&driver, sizeof(*driver.data)); }
|
||||
|
||||
#endif /* (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__) */
|
||||
|
||||
#endif /* defined(USE_SCREEN) && defined(__DJGPP__) */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,80 +22,64 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
#if (USE_SCREEN)
|
||||
|
||||
#if defined(USE_SCREEN)
|
||||
|
||||
#define this local_this
|
||||
#define this self
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
// ugly hacks
|
||||
static screen_t *last_screen = NULL;
|
||||
static screen_t *last_screen = nullptr;
|
||||
|
||||
screen_t *sobject_get_screen(void)
|
||||
{
|
||||
return last_screen;
|
||||
}
|
||||
screen_t *sobject_get_screen(void) { return last_screen; }
|
||||
|
||||
|
||||
void sobject_destroy(screen_t *this)
|
||||
{
|
||||
last_screen = NULL;
|
||||
void sobject_destroy(screen_t *this) {
|
||||
last_screen = nullptr;
|
||||
if (!this)
|
||||
return;
|
||||
if (this->data)
|
||||
{
|
||||
if (this->data) {
|
||||
if (this->finalize)
|
||||
this->finalize(this);
|
||||
free(this->data);
|
||||
this->data = NULL;
|
||||
this->data = nullptr;
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
||||
screen_t *sobject_construct(const screen_t *c, size_t data_size)
|
||||
{
|
||||
screen_t *sobject_construct(const screen_t *c, size_t data_size) {
|
||||
screen_t *this;
|
||||
|
||||
last_screen = NULL;
|
||||
last_screen = nullptr;
|
||||
|
||||
/* allocate object */
|
||||
this = (screen_t *) malloc(sizeof(*this));
|
||||
if (!this)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
/* copy function table */
|
||||
*this = *c;
|
||||
|
||||
/* initialize instance variables */
|
||||
this->data = (struct screen_data_t *) malloc(data_size);
|
||||
if (!this->data)
|
||||
{
|
||||
if (!this->data) {
|
||||
free(this);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
memset(this->data,0,data_size);
|
||||
memset(this->data, 0, data_size);
|
||||
|
||||
last_screen = this;
|
||||
return this;
|
||||
}
|
||||
|
||||
#endif /* (USE_SCREEN) */
|
||||
|
||||
#endif /* defined(USE_SCREEN) */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,23 +22,21 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_SCREEN) && defined(USE_SCREEN_VCSA)
|
||||
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#define this local_this
|
||||
#define this self
|
||||
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
/* #define USE_SCROLLBACK */
|
||||
|
||||
/* #define USE_SCROLLBACK 1 */
|
||||
|
||||
/*************************************************************************
|
||||
// direct screen access ( /dev/vcsaNN )
|
||||
@@ -48,14 +46,14 @@
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#if defined(__linux__)
|
||||
# include <linux/kd.h>
|
||||
# include <linux/kdev_t.h>
|
||||
# include <linux/major.h>
|
||||
#include <linux/kd.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/major.h>
|
||||
#endif
|
||||
|
||||
#define Cell upx_uint16_t
|
||||
|
||||
struct screen_data_t
|
||||
{
|
||||
struct screen_data_t {
|
||||
int fd;
|
||||
int mode;
|
||||
int page;
|
||||
@@ -67,129 +65,81 @@ struct screen_data_t
|
||||
unsigned char attr;
|
||||
unsigned char init_attr;
|
||||
unsigned char map[256];
|
||||
unsigned short empty_line[256];
|
||||
#ifdef USE_SCROLLBACK
|
||||
Cell empty_line[256];
|
||||
#if USE_SCROLLBACK
|
||||
/* scrollback buffer */
|
||||
unsigned short sb_buf[32][256];
|
||||
Cell sb_buf[32][256];
|
||||
int sb_size;
|
||||
int sb_base;
|
||||
int sb_sp;
|
||||
#endif /* USE_SCROLLBACK */
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_SCROLLBACK
|
||||
static __inline__ void sb_add(screen_t *this, int *val, int inc)
|
||||
{
|
||||
#if USE_SCROLLBACK
|
||||
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
||||
*val = (*val + inc) & (this->data->sb_size - 1);
|
||||
}
|
||||
|
||||
static void sb_push(screen_t *this, const unsigned short *line, int len)
|
||||
{
|
||||
memcpy(this->data->sb_buf[this->data->sb_sp],line,len);
|
||||
sb_add(this,&this->data->sb_sp,1);
|
||||
static void sb_push(screen_t *this, const Cell *line, int len) {
|
||||
memcpy(this->data->sb_buf[this->data->sb_sp], line, len);
|
||||
sb_add(this, &this->data->sb_sp, 1);
|
||||
if (this->data->sb_sp == this->data->sb_base)
|
||||
sb_add(this,&this->data->sb_base,1);
|
||||
sb_add(this, &this->data->sb_base, 1);
|
||||
}
|
||||
|
||||
static const unsigned short *sb_pop(screen_t *this)
|
||||
{
|
||||
static const Cell *sb_pop(screen_t *this) {
|
||||
if (this->data->sb_sp == this->data->sb_base)
|
||||
return NULL;
|
||||
sb_add(this,&this->data->sb_sp,-1);
|
||||
return nullptr;
|
||||
sb_add(this, &this->data->sb_sp, -1);
|
||||
return this->data->sb_buf[this->data->sb_sp];
|
||||
}
|
||||
#endif /* USE_SCROLLBACK */
|
||||
|
||||
static void refresh(screen_t *this) { UNUSED(this); }
|
||||
|
||||
static void refresh(screen_t *this)
|
||||
{
|
||||
UNUSED(this);
|
||||
}
|
||||
|
||||
|
||||
static __inline__
|
||||
unsigned short make_cell(screen_t *this, int ch, int attr)
|
||||
{
|
||||
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
||||
return ((attr & 0xff) << 8) | (this->data->map[ch & 0xff] & 0xff);
|
||||
}
|
||||
|
||||
static int getMode(const screen_t *this) { return this->data->mode; }
|
||||
|
||||
static int getMode(const screen_t *this)
|
||||
{
|
||||
return this->data->mode;
|
||||
}
|
||||
static int getPage(const screen_t *this) { return this->data->page; }
|
||||
|
||||
static int getRows(const screen_t *this) { return this->data->rows; }
|
||||
|
||||
static int getPage(const screen_t *this)
|
||||
{
|
||||
return this->data->page;
|
||||
}
|
||||
static int getCols(const screen_t *this) { return this->data->cols; }
|
||||
|
||||
|
||||
static int getRows(const screen_t *this)
|
||||
{
|
||||
return this->data->rows;
|
||||
}
|
||||
|
||||
|
||||
static int getCols(const screen_t *this)
|
||||
{
|
||||
return this->data->cols;
|
||||
}
|
||||
|
||||
|
||||
static int isMono(const screen_t *this)
|
||||
{
|
||||
static int isMono(const screen_t *this) {
|
||||
/* FIXME */
|
||||
UNUSED(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getFg(const screen_t *this) { return this->data->attr & mask_fg; }
|
||||
|
||||
static int getFg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_fg;
|
||||
}
|
||||
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
||||
|
||||
|
||||
static int getBg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_bg;
|
||||
}
|
||||
|
||||
|
||||
static void setFg(screen_t *this, int fg)
|
||||
{
|
||||
static void setFg(screen_t *this, int fg) {
|
||||
this->data->attr = (this->data->attr & mask_bg) | (fg & mask_fg);
|
||||
}
|
||||
|
||||
|
||||
static void setBg(screen_t *this, int bg)
|
||||
{
|
||||
static void setBg(screen_t *this, int bg) {
|
||||
this->data->attr = (this->data->attr & mask_fg) | (bg & mask_bg);
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static int gotoxy(screen_t *this, int x, int y)
|
||||
{
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows)
|
||||
{
|
||||
if (lseek(this->data->fd, 4 + (x + y * this->data->cols) * 2, SEEK_SET) != -1)
|
||||
{
|
||||
static int gotoxy(screen_t *this, int x, int y) {
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows) {
|
||||
if (lseek(this->data->fd, 4 + (x + y * this->data->cols) * 2, SEEK_SET) != -1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void setCursor(screen_t *this, int x, int y)
|
||||
{
|
||||
if (gotoxy(this,x,y) == 0)
|
||||
{
|
||||
unsigned char b[2] = { x, y };
|
||||
static void setCursor(screen_t *this, int x, int y) {
|
||||
if (gotoxy(this, x, y) == 0) {
|
||||
unsigned char b[2] = {x, y};
|
||||
if (lseek(this->data->fd, 2, SEEK_SET) != -1)
|
||||
write(this->data->fd, b, 2);
|
||||
this->data->cursor_x = x;
|
||||
@@ -197,67 +147,53 @@ static void setCursor(screen_t *this, int x, int y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void getCursor(const screen_t *this, int *x, int *y)
|
||||
{
|
||||
static void getCursor(const screen_t *this, int *x, int *y) {
|
||||
int cx = this->data->cursor_x;
|
||||
int cy = this->data->cursor_y;
|
||||
#if 1
|
||||
if (lseek(this->data->fd, 2, SEEK_SET) != -1)
|
||||
{
|
||||
if (lseek(this->data->fd, 2, SEEK_SET) != -1) {
|
||||
unsigned char b[2];
|
||||
if (read(this->data->fd, b, 2) == 2)
|
||||
{
|
||||
if (b[0] < this->data->cols && b[1] < this->data->rows)
|
||||
{
|
||||
if (read(this->data->fd, b, 2) == 2) {
|
||||
if (b[0] < this->data->cols && b[1] < this->data->rows) {
|
||||
cx = b[0];
|
||||
cy = b[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (x) *x = cx;
|
||||
if (y) *y = cy;
|
||||
if (x)
|
||||
*x = cx;
|
||||
if (y)
|
||||
*y = cy;
|
||||
}
|
||||
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y) {
|
||||
Cell a = make_cell(this, ch, attr);
|
||||
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y)
|
||||
{
|
||||
unsigned short a = make_cell(this,ch,attr);
|
||||
|
||||
if (gotoxy(this,x,y) == 0)
|
||||
if (gotoxy(this, x, y) == 0)
|
||||
write(this->data->fd, &a, 2);
|
||||
}
|
||||
|
||||
|
||||
static void putChar(screen_t *this, int ch, int x, int y)
|
||||
{
|
||||
putCharAttr(this,ch,this->data->attr,x,y);
|
||||
static void putChar(screen_t *this, int ch, int x, int y) {
|
||||
putCharAttr(this, ch, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
{
|
||||
assert((int)strlen(s) <= 256);
|
||||
assert(x + (int)strlen(s) <= this->data->cols);
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) {
|
||||
assert((int) strlen(s) <= 256);
|
||||
assert(x + (int) strlen(s) <= this->data->cols);
|
||||
while (*s)
|
||||
putCharAttr(this,*s++,attr,x++,y);
|
||||
putCharAttr(this, *s++, attr, x++, y);
|
||||
}
|
||||
|
||||
|
||||
static void putString(screen_t *this, const char *s, int x, int y)
|
||||
{
|
||||
putStringAttr(this,s,this->data->attr,x,y);
|
||||
static void putString(screen_t *this, const char *s, int x, int y) {
|
||||
putStringAttr(this, s, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static void getChar(screen_t *this, int *ch, int *attr, int x, int y)
|
||||
{
|
||||
unsigned short a;
|
||||
static void getChar(screen_t *this, int *ch, int *attr, int x, int y) {
|
||||
upx_uint16_t a;
|
||||
|
||||
if (gotoxy(this,x,y) == 0 && read(this->data->fd, &a, 2) == 2)
|
||||
{
|
||||
if (gotoxy(this, x, y) == 0 && read(this->data->fd, &a, 2) == 2) {
|
||||
if (ch)
|
||||
*ch = a & 0xff;
|
||||
if (attr)
|
||||
@@ -265,19 +201,15 @@ static void getChar(screen_t *this, int *ch, int *attr, int x, int y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static int init_scrnmap(screen_t *this, int fd)
|
||||
{
|
||||
static int init_scrnmap(screen_t *this, int fd) {
|
||||
int scrnmap_done = 0;
|
||||
int i;
|
||||
|
||||
#if 1 && defined(GIO_UNISCRNMAP) && defined(E_TABSZ)
|
||||
if (!scrnmap_done)
|
||||
{
|
||||
unsigned short scrnmap[E_TABSZ];
|
||||
if (ioctl(fd, GIO_UNISCRNMAP, scrnmap) == 0)
|
||||
{
|
||||
if (!scrnmap_done) {
|
||||
upx_uint16_t scrnmap[E_TABSZ];
|
||||
if (ioctl(fd, GIO_UNISCRNMAP, scrnmap) == 0) {
|
||||
for (i = 0; i < E_TABSZ; i++)
|
||||
this->data->map[scrnmap[i] & 0xff] = i;
|
||||
scrnmap_done = 1;
|
||||
@@ -285,11 +217,9 @@ static int init_scrnmap(screen_t *this, int fd)
|
||||
}
|
||||
#endif
|
||||
#if 1 && defined(GIO_SCRNMAP) && defined(E_TABSZ)
|
||||
if (!scrnmap_done)
|
||||
{
|
||||
if (!scrnmap_done) {
|
||||
unsigned char scrnmap[E_TABSZ];
|
||||
if (ioctl(fd, GIO_SCRNMAP, scrnmap) == 0)
|
||||
{
|
||||
if (ioctl(fd, GIO_SCRNMAP, scrnmap) == 0) {
|
||||
for (i = 0; i < E_TABSZ; i++)
|
||||
this->data->map[scrnmap[i] & 0xff] = i;
|
||||
scrnmap_done = 1;
|
||||
@@ -300,9 +230,7 @@ static int init_scrnmap(screen_t *this, int fd)
|
||||
return scrnmap_done;
|
||||
}
|
||||
|
||||
|
||||
static int init(screen_t *this, int fd)
|
||||
{
|
||||
static int init(screen_t *this, int fd) {
|
||||
struct stat st;
|
||||
|
||||
if (!this || !this->data)
|
||||
@@ -311,37 +239,33 @@ static int init(screen_t *this, int fd)
|
||||
this->data->fd = -1;
|
||||
this->data->mode = -1;
|
||||
this->data->page = 0;
|
||||
#ifdef USE_SCROLLBACK
|
||||
#if USE_SCROLLBACK
|
||||
this->data->sb_size = 32;
|
||||
this->data->sb_base = 0;
|
||||
this->data->sb_sp = 0;
|
||||
#endif
|
||||
if (fd < 0 || !acc_isatty(fd))
|
||||
return -1;
|
||||
if (fstat(fd,&st) != 0)
|
||||
if (fstat(fd, &st) != 0)
|
||||
return -1;
|
||||
|
||||
/* check if we are running in a virtual console */
|
||||
/* check if we are running in a virtual console */
|
||||
#if defined(MINOR) && defined(MAJOR) && defined(TTY_MAJOR)
|
||||
if (MAJOR(st.st_rdev) == TTY_MAJOR)
|
||||
{
|
||||
if (MAJOR(st.st_rdev) == TTY_MAJOR) {
|
||||
char vc_name[64];
|
||||
unsigned char vc_data[4];
|
||||
int i;
|
||||
int attr;
|
||||
unsigned short a;
|
||||
Cell a;
|
||||
|
||||
upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev));
|
||||
upx_safe_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev));
|
||||
this->data->fd = open(vc_name, O_RDWR);
|
||||
if (this->data->fd == -1)
|
||||
{
|
||||
upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev));
|
||||
if (this->data->fd == -1) {
|
||||
upx_safe_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev));
|
||||
this->data->fd = open(vc_name, O_RDWR);
|
||||
}
|
||||
if (this->data->fd != -1)
|
||||
{
|
||||
if (read(this->data->fd, vc_data, 4) == 4)
|
||||
{
|
||||
if (this->data->fd != -1) {
|
||||
if (read(this->data->fd, vc_data, 4) == 4) {
|
||||
this->data->mode = 3;
|
||||
this->data->rows = vc_data[0];
|
||||
this->data->cols = vc_data[1];
|
||||
@@ -350,18 +274,15 @@ static int init(screen_t *this, int fd)
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
this->data->map[i] = i;
|
||||
i = init_scrnmap(this,this->data->fd) ||
|
||||
init_scrnmap(this,STDIN_FILENO);
|
||||
i = init_scrnmap(this, this->data->fd) || init_scrnmap(this, STDIN_FILENO);
|
||||
|
||||
getChar(this,NULL,&attr,this->data->cursor_x,this->data->cursor_y);
|
||||
getChar(this, nullptr, &attr, this->data->cursor_x, this->data->cursor_y);
|
||||
this->data->init_attr = attr;
|
||||
this->data->attr = attr;
|
||||
a = make_cell(this,' ',attr);
|
||||
a = make_cell(this, ' ', attr);
|
||||
for (i = 0; i < 256; i++)
|
||||
this->data->empty_line[i] = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
close(this->data->fd);
|
||||
this->data->fd = -1;
|
||||
}
|
||||
@@ -375,25 +296,19 @@ static int init(screen_t *this, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void finalize(screen_t *this)
|
||||
{
|
||||
static void finalize(screen_t *this) {
|
||||
if (this->data->fd != -1)
|
||||
(void) close(this->data->fd);
|
||||
}
|
||||
|
||||
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
{
|
||||
if (len > 0 && len <= 2*this->data->cols && gotoxy(this,0,y) == 0)
|
||||
{
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len) {
|
||||
if (len > 0 && len <= 2 * this->data->cols && gotoxy(this, 0, y) == 0) {
|
||||
int i;
|
||||
unsigned char new_line[len];
|
||||
unsigned char *l1 = new_line;
|
||||
const unsigned char *l2 = (const unsigned char *) line;
|
||||
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
for (i = 0; i < len; i += 2) {
|
||||
*l1++ = *l2++;
|
||||
*l1++ = this->data->map[*l2++];
|
||||
}
|
||||
@@ -401,25 +316,19 @@ static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void clearLine(screen_t *this, int y)
|
||||
{
|
||||
if (gotoxy(this,0,y) == 0)
|
||||
write(this->data->fd, this->data->empty_line, 2*this->data->cols);
|
||||
static void clearLine(screen_t *this, int y) {
|
||||
if (gotoxy(this, 0, y) == 0)
|
||||
write(this->data->fd, this->data->empty_line, 2 * this->data->cols);
|
||||
}
|
||||
|
||||
|
||||
static void clear(screen_t *this)
|
||||
{
|
||||
static void clear(screen_t *this) {
|
||||
int y;
|
||||
|
||||
for (y = 0; y < this->data->rows; y++)
|
||||
clearLine(this,y);
|
||||
clearLine(this, y);
|
||||
}
|
||||
|
||||
|
||||
static int scrollUp(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollUp(screen_t *this, int lines) {
|
||||
int sr = this->data->rows;
|
||||
int sc = this->data->cols;
|
||||
int y;
|
||||
@@ -427,38 +336,34 @@ static int scrollUp(screen_t *this, int lines)
|
||||
if (lines <= 0 || lines > sr)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_SCROLLBACK
|
||||
#if USE_SCROLLBACK
|
||||
/* copy to scrollback buffer */
|
||||
for (y = 0; y < lines; y++)
|
||||
{
|
||||
unsigned short buf[ sc ];
|
||||
gotoxy(this,0,y);
|
||||
for (y = 0; y < lines; y++) {
|
||||
Cell buf[sc];
|
||||
gotoxy(this, 0, y);
|
||||
read(this->data->fd, buf, sizeof(buf));
|
||||
sb_push(this,buf,sizeof(buf));
|
||||
sb_push(this, buf, sizeof(buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* move screen up */
|
||||
if (lines < sr)
|
||||
{
|
||||
unsigned short buf[ (sr-lines)*sc ];
|
||||
gotoxy(this,0,lines);
|
||||
if (lines < sr) {
|
||||
Cell buf[(sr - lines) * sc];
|
||||
gotoxy(this, 0, lines);
|
||||
read(this->data->fd, buf, sizeof(buf));
|
||||
gotoxy(this,0,0);
|
||||
gotoxy(this, 0, 0);
|
||||
write(this->data->fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* fill in blank lines at bottom */
|
||||
for (y = sr - lines; y < sr; y++)
|
||||
clearLine(this,y);
|
||||
clearLine(this, y);
|
||||
|
||||
this->data->scroll_counter += lines;
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
static int scrollDown(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollDown(screen_t *this, int lines) {
|
||||
int sr = this->data->rows;
|
||||
int sc = this->data->cols;
|
||||
int y;
|
||||
@@ -467,26 +372,24 @@ static int scrollDown(screen_t *this, int lines)
|
||||
return 0;
|
||||
|
||||
/* move screen down */
|
||||
if (lines < sr)
|
||||
{
|
||||
unsigned short buf[ (sr-lines)*sc ];
|
||||
gotoxy(this,0,0);
|
||||
if (lines < sr) {
|
||||
Cell buf[(sr - lines) * sc];
|
||||
gotoxy(this, 0, 0);
|
||||
read(this->data->fd, buf, sizeof(buf));
|
||||
gotoxy(this,0,lines);
|
||||
gotoxy(this, 0, lines);
|
||||
write(this->data->fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* copy top lines from scrollback buffer */
|
||||
for (y = lines; --y >= 0; )
|
||||
{
|
||||
#ifdef USE_SCROLLBACK
|
||||
const unsigned short *buf = sb_pop(this);
|
||||
if (buf == NULL)
|
||||
clearLine(this,y);
|
||||
for (y = lines; --y >= 0;) {
|
||||
#if USE_SCROLLBACK
|
||||
const Cell *buf = sb_pop(this);
|
||||
if (buf == nullptr)
|
||||
clearLine(this, y);
|
||||
else
|
||||
updateLineN(this,buf,y,sc*2);
|
||||
updateLineN(this, buf, y, sc * 2);
|
||||
#else
|
||||
clearLine(this,y);
|
||||
clearLine(this, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -494,45 +397,33 @@ static int scrollDown(screen_t *this, int lines)
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int getScrollCounter(const screen_t *this) { return this->data->scroll_counter; }
|
||||
|
||||
static int getScrollCounter(const screen_t *this)
|
||||
{
|
||||
return this->data->scroll_counter;
|
||||
}
|
||||
|
||||
|
||||
static int getCursorShape(const screen_t *this)
|
||||
{
|
||||
static int getCursorShape(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void setCursorShape(screen_t *this, int shape)
|
||||
{
|
||||
static void setCursorShape(screen_t *this, int shape) {
|
||||
UNUSED(this);
|
||||
UNUSED(shape);
|
||||
}
|
||||
|
||||
|
||||
static int kbhit(screen_t *this)
|
||||
{
|
||||
static int kbhit(screen_t *this) {
|
||||
const int fd = STDIN_FILENO;
|
||||
const unsigned long usec = 0;
|
||||
const unsigned usec = 0;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
|
||||
UNUSED(this);
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_usec = usec % 1000000;
|
||||
return (select(fd + 1, &fds, NULL, NULL, &tv) > 0);
|
||||
return (select(fd + 1, &fds, nullptr, nullptr, &tv) > 0);
|
||||
}
|
||||
|
||||
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
{
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *)) {
|
||||
int shape;
|
||||
struct termios term_old, term_new;
|
||||
int term_r;
|
||||
@@ -541,19 +432,18 @@ static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
return 0;
|
||||
|
||||
term_r = tcgetattr(STDIN_FILENO, &term_old);
|
||||
if (term_r == 0)
|
||||
{
|
||||
if (term_r == 0) {
|
||||
term_new = term_old;
|
||||
term_new.c_lflag &= ~(ISIG | ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &term_new);
|
||||
}
|
||||
|
||||
shape = getCursorShape(this);
|
||||
setCursorShape(this,0x2000);
|
||||
setCursorShape(this, 0x2000);
|
||||
show_frames(this);
|
||||
if (this->data->rows > 24)
|
||||
setCursor(this,this->data->cursor_x,this->data->cursor_y+1);
|
||||
setCursorShape(this,shape);
|
||||
setCursor(this, this->data->cursor_x, this->data->cursor_y + 1);
|
||||
setCursorShape(this, shape);
|
||||
|
||||
while (kbhit(this))
|
||||
(void) fgetc(stdin);
|
||||
@@ -563,55 +453,42 @@ static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const screen_t driver =
|
||||
{
|
||||
sobject_destroy,
|
||||
finalize,
|
||||
0, /* atExit */
|
||||
init,
|
||||
refresh,
|
||||
getMode,
|
||||
getPage,
|
||||
getRows,
|
||||
getCols,
|
||||
isMono,
|
||||
getFg,
|
||||
getBg,
|
||||
getCursor,
|
||||
getCursorShape,
|
||||
setFg,
|
||||
setBg,
|
||||
setCursor,
|
||||
setCursorShape,
|
||||
0, /* hideCursor */
|
||||
putChar,
|
||||
putCharAttr,
|
||||
putString,
|
||||
putStringAttr,
|
||||
clear,
|
||||
clearLine,
|
||||
updateLineN,
|
||||
scrollUp,
|
||||
scrollDown,
|
||||
getScrollCounter,
|
||||
kbhit,
|
||||
intro,
|
||||
(struct screen_data_t *) 0
|
||||
};
|
||||
|
||||
static const screen_t driver = {sobject_destroy,
|
||||
finalize,
|
||||
nullptr, /* atExit */
|
||||
init,
|
||||
refresh,
|
||||
getMode,
|
||||
getPage,
|
||||
getRows,
|
||||
getCols,
|
||||
isMono,
|
||||
getFg,
|
||||
getBg,
|
||||
getCursor,
|
||||
getCursorShape,
|
||||
setFg,
|
||||
setBg,
|
||||
setCursor,
|
||||
setCursorShape,
|
||||
nullptr, /* hideCursor */
|
||||
putChar,
|
||||
putCharAttr,
|
||||
putString,
|
||||
putStringAttr,
|
||||
clear,
|
||||
clearLine,
|
||||
updateLineN,
|
||||
scrollUp,
|
||||
scrollDown,
|
||||
getScrollCounter,
|
||||
kbhit,
|
||||
intro,
|
||||
(struct screen_data_t *) nullptr};
|
||||
|
||||
/* public constructor */
|
||||
screen_t *screen_vcsa_construct(void)
|
||||
{
|
||||
return sobject_construct(&driver,sizeof(*driver.data));
|
||||
}
|
||||
screen_t *screen_vcsa_construct(void) { return sobject_construct(&driver, sizeof(*driver.data)); }
|
||||
|
||||
#endif /* (USE_SCREEN) && (USE_SCREEN_VCSA) */
|
||||
|
||||
#endif /* defined(USE_SCREEN) && defined(USE_SCREEN_VCSA) */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,43 +22,30 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#define WANT_WINDOWS_LEAN_H 1
|
||||
#include "../util/system_headers.h"
|
||||
#if (HAVE_CONIO_H)
|
||||
#include <conio.h>
|
||||
#endif
|
||||
#include "../conf.h"
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_SCREEN_WIN32)
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#define this local_this
|
||||
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
#if (USE_SCREEN_WIN32)
|
||||
|
||||
/*************************************************************************
|
||||
// direct screen access
|
||||
**************************************************************************/
|
||||
|
||||
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1200))
|
||||
/* avoid -W4 warnings in <conio.h> */
|
||||
# pragma warning(disable: 4032)
|
||||
/* avoid -W4 warnings in <windows.h> */
|
||||
# pragma warning(disable: 4201 4214 4514)
|
||||
#endif
|
||||
#if defined(__RSXNT__)
|
||||
# define timeval win32_timeval /* struct timeval already in <sys/time.h> */
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#if defined(HAVE_CONIO_H)
|
||||
# include <conio.h>
|
||||
#endif
|
||||
#include "screen.h"
|
||||
|
||||
#define this self
|
||||
|
||||
struct screen_data_t
|
||||
{
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
struct screen_data_t {
|
||||
HANDLE hi;
|
||||
HANDLE ho;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
@@ -80,106 +67,65 @@ struct screen_data_t
|
||||
CHAR_INFO empty_line[256];
|
||||
};
|
||||
|
||||
#define P(x) ((SHORT) (x))
|
||||
|
||||
#define P(x) ((SHORT) (x))
|
||||
|
||||
static const COORD pos00 = { 0, 0 };
|
||||
static const COORD size11 = { 1, 1 };
|
||||
|
||||
static const COORD pos00 = {0, 0};
|
||||
static const COORD size11 = {1, 1};
|
||||
|
||||
/* atExit information */
|
||||
static struct
|
||||
{
|
||||
static struct {
|
||||
int is_valid;
|
||||
HANDLE ho;
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
} ae;
|
||||
|
||||
static void refresh(screen_t *this) { UNUSED(this); }
|
||||
|
||||
static void refresh(screen_t *this)
|
||||
{
|
||||
UNUSED(this);
|
||||
}
|
||||
static int getMode(const screen_t *this) { return this->data->mode; }
|
||||
|
||||
|
||||
static int getMode(const screen_t *this)
|
||||
{
|
||||
return this->data->mode;
|
||||
}
|
||||
|
||||
|
||||
static int getPage(const screen_t *this)
|
||||
{
|
||||
static int getPage(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getRows(const screen_t *this) { return this->data->rows; }
|
||||
|
||||
static int getRows(const screen_t *this)
|
||||
{
|
||||
return this->data->rows;
|
||||
}
|
||||
static int getCols(const screen_t *this) { return this->data->cols; }
|
||||
|
||||
|
||||
static int getCols(const screen_t *this)
|
||||
{
|
||||
return this->data->cols;
|
||||
}
|
||||
|
||||
|
||||
static int isMono(const screen_t *this)
|
||||
{
|
||||
static int isMono(const screen_t *this) {
|
||||
UNUSED(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getFg(const screen_t *this) { return this->data->attr & mask_fg; }
|
||||
|
||||
static int getFg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_fg;
|
||||
}
|
||||
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
||||
|
||||
|
||||
static int getBg(const screen_t *this)
|
||||
{
|
||||
return this->data->attr & mask_bg;
|
||||
}
|
||||
|
||||
|
||||
static void setFg(screen_t *this, int fg)
|
||||
{
|
||||
static void setFg(screen_t *this, int fg) {
|
||||
this->data->attr = (WORD) ((this->data->attr & mask_bg) | (fg & mask_fg));
|
||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||
}
|
||||
|
||||
|
||||
static void setBg(screen_t *this, int bg)
|
||||
{
|
||||
static void setBg(screen_t *this, int bg) {
|
||||
this->data->attr = (WORD) ((this->data->attr & mask_fg) | (bg & mask_bg));
|
||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||
}
|
||||
|
||||
|
||||
static void setCursor(screen_t *this, int x, int y)
|
||||
{
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows)
|
||||
{
|
||||
COORD coord = { P(x), P(y) };
|
||||
static void setCursor(screen_t *this, int x, int y) {
|
||||
if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows) {
|
||||
COORD coord = {P(x), P(y)};
|
||||
SetConsoleCursorPosition(this->data->ho, coord);
|
||||
this->data->cursor_x = x;
|
||||
this->data->cursor_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void getCursor(const screen_t *this, int *x, int *y)
|
||||
{
|
||||
static void getCursor(const screen_t *this, int *x, int *y) {
|
||||
int cx = this->data->cursor_x;
|
||||
int cy = this->data->cursor_y;
|
||||
#if 1
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (GetConsoleScreenBufferInfo(this->data->ho, &csbi))
|
||||
{
|
||||
if (GetConsoleScreenBufferInfo(this->data->ho, &csbi)) {
|
||||
cx = csbi.dwCursorPosition.X;
|
||||
cy = csbi.dwCursorPosition.Y;
|
||||
#if 0
|
||||
@@ -188,30 +134,26 @@ static void getCursor(const screen_t *this, int *x, int *y)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (x) *x = cx;
|
||||
if (y) *y = cy;
|
||||
if (x)
|
||||
*x = cx;
|
||||
if (y)
|
||||
*y = cy;
|
||||
}
|
||||
|
||||
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y)
|
||||
{
|
||||
static void putCharAttr(screen_t *this, int ch, int attr, int x, int y) {
|
||||
CHAR_INFO ci;
|
||||
SMALL_RECT region = { P(x), P(y), P(x), P(y) };
|
||||
SMALL_RECT region = {P(x), P(y), P(x), P(y)};
|
||||
ci.Char.UnicodeChar = 0;
|
||||
ci.Char.AsciiChar = (CHAR) ch;
|
||||
ci.Attributes = (WORD) attr;
|
||||
WriteConsoleOutputA(this->data->ho, &ci, size11, pos00, ®ion);
|
||||
}
|
||||
|
||||
|
||||
static void putChar(screen_t *this, int ch, int x, int y)
|
||||
{
|
||||
static void putChar(screen_t *this, int ch, int x, int y) {
|
||||
this->putCharAttr(this, ch, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
{
|
||||
static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) {
|
||||
int i;
|
||||
int l = (int) strlen(s);
|
||||
if (l <= 0)
|
||||
@@ -219,10 +161,9 @@ static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
assert(l <= 256);
|
||||
assert(x + l <= this->data->cols);
|
||||
CHAR_INFO ci[256];
|
||||
COORD size = { P(l), 1 };
|
||||
SMALL_RECT region = { P(x), P(y), P(x + l - 1), P(y) };
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
COORD size = {P(l), 1};
|
||||
SMALL_RECT region = {P(x), P(y), P(x + l - 1), P(y)};
|
||||
for (i = 0; i < l; i++) {
|
||||
ci[i].Char.UnicodeChar = 0;
|
||||
ci[i].Char.AsciiChar = *s++;
|
||||
ci[i].Attributes = (WORD) attr;
|
||||
@@ -230,58 +171,45 @@ static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y)
|
||||
WriteConsoleOutputA(this->data->ho, &ci[0], size, pos00, ®ion);
|
||||
}
|
||||
|
||||
|
||||
static void putString(screen_t *this, const char *s, int x, int y)
|
||||
{
|
||||
static void putString(screen_t *this, const char *s, int x, int y) {
|
||||
this->putStringAttr(this, s, this->data->attr, x, y);
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static int cci2shape(const CONSOLE_CURSOR_INFO *cci)
|
||||
{
|
||||
static int cci2shape(const CONSOLE_CURSOR_INFO *cci) {
|
||||
int shape = cci->dwSize & 255;
|
||||
if (!cci->bVisible)
|
||||
shape |= 0x2000;
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
static int getCursorShape(const screen_t *this)
|
||||
{
|
||||
static int getCursorShape(const screen_t *this) {
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
GetConsoleCursorInfo(this->data->ho, &cci);
|
||||
return cci2shape(&cci);
|
||||
}
|
||||
|
||||
|
||||
static void setCursorShape(screen_t *this, int shape)
|
||||
{
|
||||
static void setCursorShape(screen_t *this, int shape) {
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
cci.dwSize = shape & 255;
|
||||
cci.bVisible = (shape & 0x2000) ? 0 : 1;
|
||||
SetConsoleCursorInfo(this->data->ho, &cci);
|
||||
}
|
||||
|
||||
|
||||
static int hideCursor(screen_t *this)
|
||||
{
|
||||
static int hideCursor(screen_t *this) {
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
int shape;
|
||||
|
||||
GetConsoleCursorInfo(this->data->ho, &cci);
|
||||
shape = cci2shape(&cci);
|
||||
if (cci.bVisible)
|
||||
{
|
||||
if (cci.bVisible) {
|
||||
cci.bVisible = 0;
|
||||
SetConsoleCursorInfo(this->data->ho, &cci);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
static int init(screen_t *this, int fd)
|
||||
{
|
||||
static int init(screen_t *this, int fd) {
|
||||
HANDLE hi, ho;
|
||||
CONSOLE_SCREEN_BUFFER_INFO *csbi;
|
||||
DWORD mode;
|
||||
@@ -329,6 +257,22 @@ static int init(screen_t *this, int fd)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// check if we are running under Wine
|
||||
// (this rather direct Win32 screen driver maps poorly to Unix terminals)
|
||||
// ntdll.dll wine_get_version() was added in wine-0.9.59 (Apr 2008)
|
||||
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
|
||||
if (ntdll != nullptr) {
|
||||
typedef const char *(CDECL * wine_get_version_func_t)(void);
|
||||
wine_get_version_func_t wine_get_version;
|
||||
wine_get_version =
|
||||
(wine_get_version_func_t) (void *) GetProcAddress(ntdll, "wine_get_version");
|
||||
if (wine_get_version != nullptr) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
this->data->cursor_x = csbi->dwCursorPosition.X;
|
||||
this->data->cursor_y = csbi->dwCursorPosition.Y;
|
||||
|
||||
@@ -338,7 +282,7 @@ static int init(screen_t *this, int fd)
|
||||
attr = csbi->wAttributes;
|
||||
this->data->hi = hi;
|
||||
this->data->ho = ho;
|
||||
this->data->mode = 3; // ???
|
||||
this->data->mode = 3; // ???
|
||||
this->data->attr = attr;
|
||||
this->data->init_attr = attr;
|
||||
this->data->empty_cell.Char.UnicodeChar = 0;
|
||||
@@ -350,11 +294,8 @@ static int init(screen_t *this, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
{
|
||||
if (y >= 0 && y < this->data->rows && len > 0 && len <= 2*this->data->cols)
|
||||
{
|
||||
static void updateLineN(screen_t *this, const void *line, int y, int len) {
|
||||
if (y >= 0 && y < this->data->rows && len > 0 && len <= 2 * this->data->cols) {
|
||||
#if 0
|
||||
const char *s = (const char *) line;
|
||||
int l = len / 2;
|
||||
@@ -376,160 +317,106 @@ static void updateLineN(screen_t *this, const void *line, int y, int len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void clearLine(screen_t *this, int y)
|
||||
{
|
||||
if (y >= 0 && y < this->data->rows)
|
||||
{
|
||||
COORD size = { P(this->data->cols), 1 };
|
||||
SMALL_RECT region = { 0, P(y), P(this->data->cols-1), P(y) };
|
||||
static void clearLine(screen_t *this, int y) {
|
||||
if (y >= 0 && y < this->data->rows) {
|
||||
COORD size = {P(this->data->cols), 1};
|
||||
SMALL_RECT region = {0, P(y), P(this->data->cols - 1), P(y)};
|
||||
WriteConsoleOutputA(this->data->ho, this->data->empty_line, size, pos00, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void clear(screen_t *this)
|
||||
{
|
||||
static void clear(screen_t *this) {
|
||||
int y;
|
||||
for (y = 0; y < this->data->rows; y++)
|
||||
this->clearLine(this, y);
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
static int do_scroll(screen_t *this, int lines, int way)
|
||||
{
|
||||
static int do_scroll(screen_t *this, int lines, int way) {
|
||||
if (lines <= 0 || lines > this->data->rows)
|
||||
return 0;
|
||||
if (lines == this->data->rows)
|
||||
{
|
||||
if (lines == this->data->rows) {
|
||||
this->clear(this);
|
||||
return lines;
|
||||
}
|
||||
|
||||
SMALL_RECT rect = { 0, 0, P(this->data->cols-1), P(this->data->rows-1) };
|
||||
//SMALL_RECT clip = rect;
|
||||
COORD dest = { 0, 0 };
|
||||
switch (way)
|
||||
{
|
||||
case 0:
|
||||
rect.Top = P(rect.Top + lines);
|
||||
break;
|
||||
case 1:
|
||||
rect.Bottom = P(rect.Bottom - lines);
|
||||
dest.Y = P(dest.Y + lines);
|
||||
break;
|
||||
SMALL_RECT rect = {0, 0, P(this->data->cols - 1), P(this->data->rows - 1)};
|
||||
// SMALL_RECT clip = rect;
|
||||
COORD dest = {0, 0};
|
||||
switch (way) {
|
||||
case 0:
|
||||
rect.Top = P(rect.Top + lines);
|
||||
break;
|
||||
case 1:
|
||||
rect.Bottom = P(rect.Bottom - lines);
|
||||
dest.Y = P(dest.Y + lines);
|
||||
break;
|
||||
}
|
||||
//ScrollConsoleScreenBuffer(this->data->ho, &rect, &clip, dest, &this->data->empty_cell);
|
||||
ScrollConsoleScreenBuffer(this->data->ho, &rect, NULL, dest, &this->data->empty_cell);
|
||||
// ScrollConsoleScreenBuffer(this->data->ho, &rect, &clip, dest, &this->data->empty_cell);
|
||||
ScrollConsoleScreenBuffer(this->data->ho, &rect, nullptr, dest, &this->data->empty_cell);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int scrollUp(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollUp(screen_t *this, int lines) {
|
||||
lines = do_scroll(this, lines, 0);
|
||||
this->data->scroll_counter += lines;
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int scrollDown(screen_t *this, int lines)
|
||||
{
|
||||
static int scrollDown(screen_t *this, int lines) {
|
||||
lines = do_scroll(this, lines, 1);
|
||||
this->data->scroll_counter -= lines;
|
||||
return lines;
|
||||
}
|
||||
|
||||
static int getScrollCounter(const screen_t *this)
|
||||
{
|
||||
return this->data->scroll_counter;
|
||||
}
|
||||
static int getScrollCounter(const screen_t *this) { return this->data->scroll_counter; }
|
||||
|
||||
|
||||
static int s_kbhit(screen_t *this)
|
||||
{
|
||||
static int s_kbhit(screen_t *this) {
|
||||
UNUSED(this);
|
||||
#if defined(HAVE_CONIO_H)
|
||||
# if defined(__RSXNT__)
|
||||
#if (HAVE_CONIO_H)
|
||||
#if defined(__RSXNT__)
|
||||
return 0;
|
||||
# elif defined(__BORLANDC__) || defined(__WATCOMC__)
|
||||
#elif defined(__BORLANDC__) || defined(__WATCOMC__)
|
||||
return kbhit();
|
||||
# else
|
||||
#else
|
||||
return _kbhit();
|
||||
# endif
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *) )
|
||||
{
|
||||
static int intro(screen_t *this, void (*show_frames)(screen_t *)) {
|
||||
UNUSED(this);
|
||||
UNUSED(show_frames);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void atExit(void)
|
||||
{
|
||||
static void atExit(void) {
|
||||
static int done = 0;
|
||||
if (done) return;
|
||||
if (done)
|
||||
return;
|
||||
done = 1;
|
||||
if (ae.is_valid)
|
||||
{
|
||||
if (ae.is_valid) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const screen_t driver =
|
||||
{
|
||||
sobject_destroy,
|
||||
0, /* finalize, */
|
||||
atExit,
|
||||
init,
|
||||
refresh,
|
||||
getMode,
|
||||
getPage,
|
||||
getRows,
|
||||
getCols,
|
||||
isMono,
|
||||
getFg,
|
||||
getBg,
|
||||
getCursor,
|
||||
getCursorShape,
|
||||
setFg,
|
||||
setBg,
|
||||
setCursor,
|
||||
setCursorShape,
|
||||
hideCursor,
|
||||
putChar,
|
||||
putCharAttr,
|
||||
putString,
|
||||
putStringAttr,
|
||||
clear,
|
||||
clearLine,
|
||||
updateLineN,
|
||||
scrollUp,
|
||||
scrollDown,
|
||||
getScrollCounter,
|
||||
s_kbhit,
|
||||
intro,
|
||||
(struct screen_data_t *) 0
|
||||
};
|
||||
|
||||
static const screen_t driver = {sobject_destroy, nullptr, /* finalize */
|
||||
atExit, init, refresh,
|
||||
getMode, getPage, getRows,
|
||||
getCols, isMono, getFg,
|
||||
getBg, getCursor, getCursorShape,
|
||||
setFg, setBg, setCursor,
|
||||
setCursorShape, hideCursor, putChar,
|
||||
putCharAttr, putString, putStringAttr,
|
||||
clear, clearLine, updateLineN,
|
||||
scrollUp, scrollDown, getScrollCounter,
|
||||
s_kbhit, intro, (struct screen_data_t *) nullptr};
|
||||
|
||||
/* public constructor */
|
||||
screen_t *screen_win32_construct(void)
|
||||
{
|
||||
return sobject_construct(&driver,sizeof(*driver.data));
|
||||
}
|
||||
screen_t *screen_win32_construct(void) { return sobject_construct(&driver, sizeof(*driver.data)); }
|
||||
|
||||
#endif /* (USE_SCREEN_WIN32) */
|
||||
|
||||
#endif /* defined(USE_SCREEN) && (ACC_OS_WIN32 || ACC_OS_WIN64) */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,15 +22,12 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPX_SCREEN_H
|
||||
#define __UPX_SCREEN_H
|
||||
|
||||
#if defined(USE_SCREEN)
|
||||
|
||||
#if (USE_SCREEN)
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -40,12 +37,11 @@ struct screen_data_t;
|
||||
struct screen_t;
|
||||
typedef struct screen_t screen_t;
|
||||
|
||||
struct screen_t
|
||||
{
|
||||
/* public: */
|
||||
struct screen_t {
|
||||
/* public: */
|
||||
void (*destroy)(screen_t *s);
|
||||
void (*finalize)(screen_t *s);
|
||||
void (*atExit)(void); /* atexit/signal handler */
|
||||
void (*atExit)(void); /* atexit/signal handler */
|
||||
|
||||
int (*init)(screen_t *s, int fd);
|
||||
|
||||
@@ -83,13 +79,12 @@ struct screen_t
|
||||
|
||||
int (*kbhit)(screen_t *s);
|
||||
|
||||
int (*intro)(screen_t *s, void (*)(screen_t*) );
|
||||
int (*intro)(screen_t *s, void (*)(screen_t *));
|
||||
|
||||
/* private: */
|
||||
/* private: */
|
||||
struct screen_data_t *data;
|
||||
};
|
||||
|
||||
|
||||
screen_t *sobject_construct(const screen_t *c, size_t data_size);
|
||||
void sobject_destroy(screen_t *);
|
||||
screen_t *sobject_get_screen(void);
|
||||
@@ -101,52 +96,6 @@ screen_t *screen_win32_construct(void);
|
||||
|
||||
void screen_show_frames(screen_t *);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// debugging support
|
||||
**************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
#undef LOG
|
||||
#undef LOGI
|
||||
#undef LOGU
|
||||
#undef LOGS
|
||||
|
||||
#if defined(SCREEN_DEBUG)
|
||||
static void LOG(const char *format, ...)
|
||||
{
|
||||
static FILE *logfile = NULL;
|
||||
va_list args;
|
||||
|
||||
if (!logfile)
|
||||
logfile = fopen("screen.log", "wt");
|
||||
if (!logfile)
|
||||
return;
|
||||
|
||||
va_start(args,format);
|
||||
vfprintf(logfile,format,args);
|
||||
fflush(logfile);
|
||||
va_end(args);
|
||||
}
|
||||
# define LOGI(x) LOG(#x " %ld\n", (long)(x))
|
||||
# define LOGU(x) LOG(#x " %lu\n", (long)(x))
|
||||
# define LOGS(x) LOG(#x " %s\n", x)
|
||||
#else
|
||||
# define LOGI(x)
|
||||
# define LOGU(x)
|
||||
# define LOGS(x)
|
||||
#endif
|
||||
|
||||
#endif /* if #0 */
|
||||
|
||||
|
||||
#endif /* USE_SCREEN */
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
+109
-107
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,62 +22,61 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
long Throwable::counter = 0;
|
||||
/*static*/ Throwable::Stats Throwable::stats;
|
||||
|
||||
Throwable::Throwable(const char *m, int e, bool w) NOTHROW
|
||||
: super(), msg(NULL), err(e), is_warning(w)
|
||||
{
|
||||
if (m)
|
||||
Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
|
||||
msg(nullptr),
|
||||
err(e),
|
||||
is_warning(w) {
|
||||
if (m != nullptr) {
|
||||
msg = strdup(m);
|
||||
#if 0
|
||||
fprintf(stderr, "construct exception: %s %ld\n", msg, counter);
|
||||
counter++;
|
||||
#endif
|
||||
assert_noexcept(msg != nullptr);
|
||||
}
|
||||
NO_fprintf(stderr, "construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||
size_t(stats.counter_total), (const char *) msg);
|
||||
stats.counter_current += 1;
|
||||
stats.counter_total += 1;
|
||||
}
|
||||
|
||||
|
||||
Throwable::Throwable(const Throwable &other) NOTHROW
|
||||
: super(other), msg(NULL), err(other.err), is_warning(other.is_warning)
|
||||
{
|
||||
if (other.msg)
|
||||
Throwable::Throwable(const Throwable &other) noexcept : super(other),
|
||||
msg(nullptr),
|
||||
err(other.err),
|
||||
is_warning(other.is_warning) {
|
||||
if (other.msg != nullptr) {
|
||||
msg = strdup(other.msg);
|
||||
#if 0
|
||||
fprintf(stderr, "copy exception: %s %ld\n", msg, counter);
|
||||
counter++;
|
||||
#endif
|
||||
assert_noexcept(msg != nullptr);
|
||||
}
|
||||
NO_fprintf(stderr, "copy construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||
size_t(stats.counter_total), (const char *) msg);
|
||||
stats.counter_current += 1;
|
||||
stats.counter_total += 1;
|
||||
}
|
||||
|
||||
|
||||
Throwable::~Throwable() NOTHROW
|
||||
{
|
||||
#if 0
|
||||
counter--;
|
||||
fprintf(stderr, "destruct exception: %s %ld\n", msg, counter);
|
||||
#endif
|
||||
if (msg)
|
||||
free(msg);
|
||||
Throwable::~Throwable() noexcept {
|
||||
stats.counter_current -= 1;
|
||||
NO_fprintf(stderr, "destruct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||
size_t(stats.counter_total), (const char *) msg);
|
||||
upx::owner_free(msg);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// compression
|
||||
**************************************************************************/
|
||||
|
||||
void throwCantPack(const char *msg)
|
||||
{
|
||||
void throwCantPack(const char *msg) {
|
||||
// UGLY, but makes things easier
|
||||
if (opt->cmd == CMD_COMPRESS)
|
||||
if (opt->cmd == CMD_NONE)
|
||||
throw CantPackException(msg);
|
||||
else if (opt->cmd == CMD_COMPRESS)
|
||||
throw CantPackException(msg);
|
||||
else if (opt->cmd == CMD_FILEINFO)
|
||||
throw CantPackException(msg);
|
||||
@@ -85,119 +84,126 @@ void throwCantPack(const char *msg)
|
||||
throw CantUnpackException(msg);
|
||||
}
|
||||
|
||||
void throwCantPackExact()
|
||||
{
|
||||
throwCantPack("option '--exact' does not work with this file");
|
||||
}
|
||||
void throwCantPackExact() { throwCantPack("option '--exact' does not work with this file"); }
|
||||
|
||||
void throwFilterException()
|
||||
{
|
||||
throwCantPack("filter problem");
|
||||
}
|
||||
void throwFilterException() { throwCantPack("filter problem"); }
|
||||
|
||||
void throwUnknownExecutableFormat(const char *msg, bool warn)
|
||||
{
|
||||
void throwUnknownExecutableFormat(const char *msg, bool warn) {
|
||||
throw UnknownExecutableFormatException(msg, warn);
|
||||
}
|
||||
|
||||
void throwNotCompressible(const char *msg)
|
||||
{
|
||||
throw NotCompressibleException(msg);
|
||||
}
|
||||
void throwNotCompressible(const char *msg) { throw NotCompressibleException(msg); }
|
||||
|
||||
void throwAlreadyPacked(const char *msg)
|
||||
{
|
||||
throw AlreadyPackedException(msg);
|
||||
}
|
||||
void throwAlreadyPacked(const char *msg) { throw AlreadyPackedException(msg); }
|
||||
|
||||
void throwAlreadyPackedByUPX(const char *msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
void throwAlreadyPackedByUPX(const char *msg) {
|
||||
if (msg == nullptr)
|
||||
msg = "already packed by UPX";
|
||||
throwAlreadyPacked(msg);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// decompression
|
||||
**************************************************************************/
|
||||
|
||||
void throwCantUnpack(const char *msg)
|
||||
{
|
||||
void throwCantUnpack(const char *msg) {
|
||||
// UGLY, but makes things easier
|
||||
throwCantPack(msg);
|
||||
}
|
||||
|
||||
void throwNotPacked(const char *msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
void throwNotPacked(const char *msg) {
|
||||
if (msg == nullptr)
|
||||
msg = "not packed by UPX";
|
||||
throw NotPackedException(msg);
|
||||
}
|
||||
|
||||
void throwChecksumError()
|
||||
{
|
||||
throw Exception("checksum error");
|
||||
}
|
||||
|
||||
void throwCompressedDataViolation()
|
||||
{
|
||||
throw Exception("compressed data violation");
|
||||
}
|
||||
void throwChecksumError() { throw Exception("checksum error"); }
|
||||
|
||||
void throwCompressedDataViolation() { throw Exception("compressed data violation"); }
|
||||
|
||||
/*************************************************************************
|
||||
// other
|
||||
**************************************************************************/
|
||||
|
||||
void throwInternalError(const char *msg)
|
||||
{
|
||||
throw InternalError(msg);
|
||||
}
|
||||
void throwInternalError(const char *msg) { throw InternalError(msg); }
|
||||
|
||||
void throwBadLoader()
|
||||
{
|
||||
throwInternalError("bad loader");
|
||||
}
|
||||
void throwBadLoader() { throwInternalError("bad loader"); }
|
||||
|
||||
|
||||
void throwOutOfMemoryException(const char *msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
void throwOutOfMemoryException(const char *msg) {
|
||||
if (msg == nullptr)
|
||||
msg = "out of memory";
|
||||
throw OutOfMemoryException(msg);
|
||||
}
|
||||
|
||||
void throwIOException(const char *msg, int e) { throw IOException(msg, e); }
|
||||
|
||||
void throwIOException(const char *msg, int e)
|
||||
{
|
||||
throw IOException(msg, e);
|
||||
}
|
||||
|
||||
|
||||
void throwEOFException(const char *msg, int e)
|
||||
{
|
||||
if (msg == NULL && e == 0)
|
||||
void throwEOFException(const char *msg, int e) {
|
||||
if (msg == nullptr && e == 0)
|
||||
msg = "premature end of file";
|
||||
throw EOFException(msg, e);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// varargs overloads
|
||||
**************************************************************************/
|
||||
|
||||
const char *prettyName(const char *n) NOTHROW
|
||||
{
|
||||
if (n == NULL)
|
||||
template <>
|
||||
void throwCantPack(const char *format, ...) {
|
||||
char msg[1024];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||
va_end(ap);
|
||||
throwCantPack(msg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void throwCantUnpack(const char *format, ...) {
|
||||
char msg[1024];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||
va_end(ap);
|
||||
throwCantUnpack(msg);
|
||||
}
|
||||
|
||||
template <>
|
||||
void throwInternalError(const char *format, ...) {
|
||||
char msg[1024];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||
va_end(ap);
|
||||
throwInternalError(msg);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept {
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
void throwAssertFailed(const char *expr, const char *file, int line, const char *func) {
|
||||
if (opt->debug.debug_level >= 1) {
|
||||
throwCantPack("corrupted file; details: %s (%s: %s: %d)", expr, file, func, line);
|
||||
} else {
|
||||
throwCantPack("corrupted file; try '--debug' for more details");
|
||||
}
|
||||
}
|
||||
|
||||
const char *prettyExceptionName(const char *n) noexcept {
|
||||
if (n == nullptr)
|
||||
return "(null)";
|
||||
while (*n)
|
||||
{
|
||||
if (*n >= '0' && *n <= '9') // Linux ABI
|
||||
while (*n) {
|
||||
if (*n >= '0' && *n <= '9') // Linux ABI
|
||||
n++;
|
||||
else if (*n == ' ')
|
||||
n++;
|
||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++
|
||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC)
|
||||
n += 6;
|
||||
else
|
||||
break;
|
||||
@@ -205,8 +211,4 @@ const char *prettyName(const char *n) NOTHROW
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+95
-119
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,217 +22,193 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_EXCEPT_H
|
||||
#define __UPX_EXCEPT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
const char *prettyName(const char *n) NOTHROW;
|
||||
|
||||
#pragma once
|
||||
|
||||
/*************************************************************************
|
||||
// exceptions
|
||||
**************************************************************************/
|
||||
|
||||
class Throwable : public std::exception
|
||||
{
|
||||
class Throwable : public std::exception {
|
||||
typedef std::exception super;
|
||||
|
||||
protected:
|
||||
Throwable(const char *m = 0, int e = 0, bool w = false) NOTHROW;
|
||||
Throwable(const char *m = nullptr, int e = 0, bool w = false) noexcept;
|
||||
|
||||
public:
|
||||
Throwable(const Throwable &) NOTHROW;
|
||||
virtual ~Throwable() NOTHROW;
|
||||
const char *getMsg() const NOTHROW { return msg; }
|
||||
int getErrno() const NOTHROW { return err; }
|
||||
bool isWarning() const NOTHROW { return is_warning; }
|
||||
Throwable(const Throwable &) noexcept; // copy constructor
|
||||
virtual ~Throwable() noexcept;
|
||||
const char *getMsg() const noexcept { return msg; }
|
||||
int getErrno() const noexcept { return err; }
|
||||
bool isWarning() const noexcept { return is_warning; }
|
||||
|
||||
private:
|
||||
char *msg;
|
||||
int err;
|
||||
OwningPointer(char) msg = nullptr;
|
||||
int err = 0;
|
||||
protected:
|
||||
bool is_warning; // can be set by subclasses
|
||||
bool is_warning = false; // can be set by subclasses
|
||||
|
||||
private:
|
||||
// disable assignment
|
||||
Throwable& operator= (const Throwable &);
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
// disable copy assignment and move
|
||||
Throwable &operator=(const Throwable &) noexcept DELETED_FUNCTION; // copy assignment
|
||||
UPX_CXX_DISABLE_MOVE(Throwable)
|
||||
// disable dynamic allocation => force throwing by value
|
||||
UPX_CXX_DISABLE_NEW_DELETE(Throwable)
|
||||
// disable taking the address => force passing by reference
|
||||
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||
UPX_CXX_DISABLE_ADDRESS(Throwable)
|
||||
|
||||
private:
|
||||
static long counter; // for debugging
|
||||
// static debug stats
|
||||
struct Stats {
|
||||
upx_std_atomic(size_t) counter_total;
|
||||
upx_std_atomic(size_t) counter_current;
|
||||
};
|
||||
static Stats stats;
|
||||
};
|
||||
|
||||
|
||||
// Exceptions can/should be caught
|
||||
class Exception : public Throwable
|
||||
{
|
||||
class Exception : public Throwable {
|
||||
typedef Throwable super;
|
||||
public:
|
||||
Exception(const char *m = 0, int e = 0, bool w = false) NOTHROW : super(m,e,w) { }
|
||||
Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {}
|
||||
};
|
||||
|
||||
|
||||
// Errors should not be caught (or re-thrown)
|
||||
class Error : public Throwable
|
||||
{
|
||||
class Error : public Throwable {
|
||||
typedef Throwable super;
|
||||
public:
|
||||
Error(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// system exception
|
||||
// system exceptions
|
||||
**************************************************************************/
|
||||
|
||||
class OutOfMemoryException : public Exception
|
||||
{
|
||||
class OutOfMemoryException final : public Exception {
|
||||
typedef Exception super;
|
||||
public:
|
||||
OutOfMemoryException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
class IOException : public Exception
|
||||
{
|
||||
class IOException /*not_final*/ : public Exception {
|
||||
typedef Exception super;
|
||||
public:
|
||||
IOException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
class EOFException : public IOException
|
||||
{
|
||||
class EOFException final : public IOException {
|
||||
typedef IOException super;
|
||||
public:
|
||||
EOFException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
class FileNotFoundException : public IOException
|
||||
{
|
||||
class FileNotFoundException final : public IOException {
|
||||
typedef IOException super;
|
||||
public:
|
||||
FileNotFoundException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
class FileAlreadyExistsException : public IOException
|
||||
{
|
||||
class FileAlreadyExistsException final : public IOException {
|
||||
typedef IOException super;
|
||||
public:
|
||||
FileAlreadyExistsException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// application execptions
|
||||
// application exceptions
|
||||
**************************************************************************/
|
||||
|
||||
class OverlayException : public Exception
|
||||
{
|
||||
class OverlayException final : public Exception {
|
||||
typedef Exception super;
|
||||
public:
|
||||
OverlayException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
||||
};
|
||||
|
||||
class CantPackException : public Exception
|
||||
{
|
||||
class CantPackException /*not_final*/ : public Exception {
|
||||
typedef Exception super;
|
||||
public:
|
||||
CantPackException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
CantPackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
||||
};
|
||||
|
||||
class UnknownExecutableFormatException : public CantPackException
|
||||
{
|
||||
class UnknownExecutableFormatException final : public CantPackException {
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
UnknownExecutableFormatException(const char *m = 0, bool w = false) NOTHROW : super(m,w) { }
|
||||
UnknownExecutableFormatException(const char *m = nullptr, bool w = false) noexcept
|
||||
: super(m, w) {}
|
||||
};
|
||||
|
||||
class AlreadyPackedException : public CantPackException
|
||||
{
|
||||
class AlreadyPackedException final : public CantPackException {
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
AlreadyPackedException(const char *m = 0) NOTHROW : super(m) { is_warning = true; }
|
||||
AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; }
|
||||
};
|
||||
|
||||
class NotCompressibleException : public CantPackException
|
||||
{
|
||||
class NotCompressibleException final : public CantPackException {
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
NotCompressibleException(const char *m = 0) NOTHROW : super(m) { }
|
||||
NotCompressibleException(const char *m = nullptr) noexcept : super(m) {}
|
||||
};
|
||||
|
||||
|
||||
class CantUnpackException : public Exception
|
||||
{
|
||||
class CantUnpackException /*not_final*/ : public Exception {
|
||||
typedef Exception super;
|
||||
public:
|
||||
CantUnpackException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
||||
};
|
||||
|
||||
class NotPackedException : public CantUnpackException
|
||||
{
|
||||
class NotPackedException final : public CantUnpackException {
|
||||
typedef CantUnpackException super;
|
||||
public:
|
||||
NotPackedException(const char *m = 0) NOTHROW : super(m,true) { }
|
||||
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// errors
|
||||
**************************************************************************/
|
||||
|
||||
class InternalError : public Error
|
||||
{
|
||||
class InternalError final : public Error {
|
||||
typedef Error super;
|
||||
public:
|
||||
InternalError(const char *m = 0) NOTHROW : super(m,0) { }
|
||||
InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
#undef NORET
|
||||
#if 0 && defined(__GNUC__)
|
||||
// (noreturn) is probably not the correct semantics for throwing exceptions
|
||||
#define NORET __attribute__((__noreturn__))
|
||||
#else
|
||||
#define NORET
|
||||
#endif
|
||||
const char *prettyExceptionName(const char *n) noexcept;
|
||||
|
||||
void throwCantPack(const char *msg) NORET;
|
||||
void throwCantPackExact() NORET;
|
||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
||||
void throwAlreadyPackedByUPX(const char *msg = NULL) NORET;
|
||||
void throwCantUnpack(const char *msg) NORET;
|
||||
void throwNotPacked(const char *msg = NULL) NORET;
|
||||
void throwFilterException() NORET;
|
||||
void throwBadLoader() NORET;
|
||||
void throwChecksumError() NORET;
|
||||
void throwCompressedDataViolation() NORET;
|
||||
void throwInternalError(const char *msg) NORET;
|
||||
void throwOutOfMemoryException(const char *msg = NULL) NORET;
|
||||
void throwIOException(const char *msg = NULL, int e = 0) NORET;
|
||||
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
||||
noreturn void throwCantPack(const char *msg) may_throw;
|
||||
noreturn void throwCantPackExact() may_throw;
|
||||
noreturn void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw;
|
||||
noreturn void throwNotCompressible(const char *msg = nullptr) may_throw;
|
||||
noreturn void throwAlreadyPacked(const char *msg = nullptr) may_throw;
|
||||
noreturn void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw;
|
||||
noreturn void throwCantUnpack(const char *msg) may_throw;
|
||||
noreturn void throwNotPacked(const char *msg = nullptr) may_throw;
|
||||
noreturn void throwFilterException() may_throw;
|
||||
noreturn void throwBadLoader() may_throw;
|
||||
noreturn void throwChecksumError() may_throw;
|
||||
noreturn void throwCompressedDataViolation() may_throw;
|
||||
noreturn void throwInternalError(const char *msg) may_throw;
|
||||
noreturn void throwOutOfMemoryException(const char *msg = nullptr) may_throw;
|
||||
noreturn void throwIOException(const char *msg = nullptr, int e = 0) may_throw;
|
||||
noreturn void throwEOFException(const char *msg = nullptr, int e = 0) may_throw;
|
||||
|
||||
#undef NORET
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
// some C++ template wizardry is needed to overload throwCantPack() for varargs
|
||||
template <class T>
|
||||
void throwCantPack(const T *, ...) DELETED_FUNCTION;
|
||||
template <>
|
||||
noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||
template <class T>
|
||||
void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
|
||||
template <>
|
||||
noreturn void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||
template <class T>
|
||||
void throwInternalError(const T *, ...) DELETED_FUNCTION;
|
||||
template <>
|
||||
noreturn void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2);
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+190
-263
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,82 +22,75 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// static file-related util functions; will throw on error
|
||||
**************************************************************************/
|
||||
|
||||
void File::chmod(const char *name, int mode)
|
||||
{
|
||||
#if defined(HAVE_CHMOD)
|
||||
if (::chmod(name,mode) != 0)
|
||||
throwIOException(name,errno);
|
||||
/*static*/ void FileBase::chmod(const char *name, int mode) {
|
||||
assert(name != nullptr && name[0] != 0);
|
||||
#if HAVE_CHMOD
|
||||
if (::chmod(name, mode) != 0)
|
||||
throwIOException(name, errno);
|
||||
#else
|
||||
UNUSED(name); UNUSED(mode);
|
||||
UNUSED(name);
|
||||
UNUSED(mode);
|
||||
// no error
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::rename(const char *old_, const char *new_)
|
||||
{
|
||||
#if defined(__DJGPP__)
|
||||
if (::_rename(old_,new_) != 0)
|
||||
/*static*/ void FileBase::rename(const char *old_, const char *new_) {
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
if (::_rename(old_, new_) != 0)
|
||||
#else
|
||||
if (::rename(old_,new_) != 0)
|
||||
if (::rename(old_, new_) != 0)
|
||||
#endif
|
||||
throwIOException("rename error",errno);
|
||||
throwIOException("rename error", errno);
|
||||
}
|
||||
|
||||
|
||||
void File::unlink(const char *name)
|
||||
{
|
||||
if (::unlink(name) != 0)
|
||||
throwIOException(name,errno);
|
||||
/*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
|
||||
assert_noexcept(name != nullptr && name[0] != 0);
|
||||
bool success = ::unlink(name) == 0;
|
||||
#if HAVE_CHMOD
|
||||
if (!success)
|
||||
success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0);
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
/*static*/ void FileBase::unlink(const char *name) {
|
||||
if (!unlink_noexcept(name))
|
||||
throwIOException(name, errno);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// FileBase
|
||||
**************************************************************************/
|
||||
|
||||
FileBase::FileBase() :
|
||||
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
|
||||
{
|
||||
memset(&st,0,sizeof(st));
|
||||
}
|
||||
|
||||
|
||||
FileBase::~FileBase()
|
||||
{
|
||||
#if 0 && defined(__GNUC__) // debug
|
||||
FileBase::~FileBase() may_throw {
|
||||
#if 0 && defined(__GNUC__) // debug
|
||||
if (isOpen())
|
||||
fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__);
|
||||
fprintf(stderr, "%s: %s\n", _name, __PRETTY_FUNCTION__);
|
||||
#endif
|
||||
|
||||
// FIXME: we should use close() during exception unwinding but
|
||||
// closex() otherwise
|
||||
closex();
|
||||
if (std::uncaught_exceptions() == 0)
|
||||
closex(); // may_throw
|
||||
else
|
||||
close_noexcept(); // currently in exception unwinding, use noexcept variant
|
||||
}
|
||||
|
||||
|
||||
bool FileBase::do_sopen()
|
||||
{
|
||||
bool FileBase::do_sopen() {
|
||||
if (_shflags < 0)
|
||||
_fd = ::open(_name, _flags, _mode);
|
||||
else
|
||||
{
|
||||
#if defined(__DJGPP__)
|
||||
_fd = ::open(_name,_flags | _shflags, _mode);
|
||||
#elif defined(__MINT__)
|
||||
_fd = ::open(_name,_flags | (_shflags & O_SHMODE), _mode);
|
||||
else {
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
_fd = ::open(_name, _flags | _shflags, _mode);
|
||||
#elif (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
_fd = ::open(_name, _flags | (_shflags & O_SHMODE), _mode);
|
||||
#elif defined(SH_DENYRW)
|
||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||
#else
|
||||
@@ -106,15 +99,14 @@ bool FileBase::do_sopen()
|
||||
}
|
||||
if (_fd < 0)
|
||||
return false;
|
||||
st.st_size = 0;
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileBase::close()
|
||||
{
|
||||
bool FileBase::close_noexcept() noexcept {
|
||||
bool ok = true;
|
||||
if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)
|
||||
if (::close(_fd) == -1)
|
||||
@@ -122,120 +114,70 @@ bool FileBase::close()
|
||||
_fd = -1;
|
||||
_flags = 0;
|
||||
_mode = 0;
|
||||
_name = NULL;
|
||||
_name = nullptr;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void FileBase::closex()
|
||||
{
|
||||
if (!close())
|
||||
throwIOException("close failed",errno);
|
||||
void FileBase::closex() may_throw {
|
||||
if (!close_noexcept())
|
||||
throwIOException("close failed", errno);
|
||||
}
|
||||
|
||||
|
||||
int FileBase::read(void *buf, int len)
|
||||
{
|
||||
if (!isOpen() || len < 0)
|
||||
throwIOException("bad read");
|
||||
errno = 0;
|
||||
long l = acc_safe_hread(_fd, buf, len);
|
||||
if (errno)
|
||||
throwIOException("read error",errno);
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
|
||||
int FileBase::readx(void *buf, int len)
|
||||
{
|
||||
int l = this->read(buf, len);
|
||||
if (l != len)
|
||||
throwEOFException();
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
void FileBase::write(const void *buf, int len)
|
||||
{
|
||||
if (!isOpen() || len < 0)
|
||||
throwIOException("bad write");
|
||||
errno = 0;
|
||||
long l = acc_safe_hwrite(_fd, buf, len);
|
||||
if (l != len)
|
||||
throwIOException("write error",errno);
|
||||
}
|
||||
|
||||
|
||||
void FileBase::seek(off_t off, int whence)
|
||||
{
|
||||
// Return value of ::seek is the resulting file offset (same as ::tell())
|
||||
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
||||
if (!isOpen())
|
||||
throwIOException("bad seek 1");
|
||||
if (!mem_size_valid_bytes(off >= 0 ? off : -off)) // sanity check
|
||||
throwIOException("bad seek");
|
||||
if (whence == SEEK_SET) {
|
||||
if (off < 0)
|
||||
throwIOException("bad seek 2");
|
||||
off += _offset;
|
||||
}
|
||||
if (whence == SEEK_END) {
|
||||
} else if (whence == SEEK_END) {
|
||||
if (off > 0)
|
||||
throwIOException("bad seek 3");
|
||||
off += _offset + _length;
|
||||
whence = SEEK_SET;
|
||||
}
|
||||
if (::lseek(_fd,off,whence) < 0)
|
||||
throwIOException("seek error",errno);
|
||||
}
|
||||
|
||||
|
||||
off_t FileBase::tell() const
|
||||
{
|
||||
if (!isOpen())
|
||||
throwIOException("bad tell");
|
||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||
} else if (whence == SEEK_CUR) {
|
||||
} else
|
||||
throwInternalError("bad seek: whence");
|
||||
upx_off_t l = ::lseek(_fd, off, whence);
|
||||
if (l < 0)
|
||||
throwIOException("tell error",errno);
|
||||
throwIOException("seek error", errno);
|
||||
return l - _offset;
|
||||
}
|
||||
|
||||
upx_off_t FileBase::tell() const {
|
||||
if (!isOpen())
|
||||
throwIOException("bad tell");
|
||||
upx_off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||
if (l < 0)
|
||||
throwIOException("tell error", errno);
|
||||
return l - _offset;
|
||||
}
|
||||
|
||||
void FileBase::set_extent(off_t offset, off_t length)
|
||||
{
|
||||
void FileBase::set_extent(upx_off_t offset, upx_off_t length) {
|
||||
_offset = offset;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
off_t FileBase::st_size() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
upx_off_t FileBase::st_size() const { return _length; }
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// InputFile
|
||||
**************************************************************************/
|
||||
|
||||
InputFile::InputFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
InputFile::~InputFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void InputFile::sopen(const char *name, int flags, int shflags)
|
||||
{
|
||||
close();
|
||||
void InputFile::sopen(const char *name, int flags, int shflags) {
|
||||
closex();
|
||||
_name = name;
|
||||
_flags = flags;
|
||||
_shflags = shflags;
|
||||
_mode = 0;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
if (!super::do_sopen()) {
|
||||
if (errno == ENOENT)
|
||||
throw FileNotFoundException(_name, errno);
|
||||
else if (errno == EEXIST)
|
||||
@@ -243,84 +185,63 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
||||
else
|
||||
throwIOException(_name, errno);
|
||||
}
|
||||
_length_orig = _length;
|
||||
}
|
||||
|
||||
|
||||
int InputFile::read(void *buf, int len)
|
||||
{
|
||||
return super::read(buf, len);
|
||||
int InputFile::read(SPAN_P(void) buf, upx_int64_t blen) {
|
||||
if (!isOpen() || blen < 0)
|
||||
throwIOException("bad read");
|
||||
int len = (int) mem_size(1, blen); // sanity check
|
||||
errno = 0;
|
||||
long l = acc_safe_hread(_fd, raw_bytes(buf, len), len);
|
||||
if (errno)
|
||||
throwIOException("read error", errno);
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
int InputFile::readx(void *buf, int len)
|
||||
{
|
||||
return super::readx(buf, len);
|
||||
int InputFile::readx(SPAN_P(void) buf, upx_int64_t blen) {
|
||||
int l = this->read(buf, blen);
|
||||
if (l != blen)
|
||||
throwEOFException();
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
int InputFile::read(MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
return read(buf->getVoidPtr(), len);
|
||||
upx_off_t InputFile::seek(upx_off_t off, int whence) {
|
||||
upx_off_t pos = super::seek(off, whence);
|
||||
if (_length < pos)
|
||||
throwIOException("bad seek 4");
|
||||
return pos;
|
||||
}
|
||||
|
||||
int InputFile::readx(MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
return read(buf->getVoidPtr(), len);
|
||||
upx_off_t InputFile::st_size_orig() const { return _length_orig; }
|
||||
|
||||
int InputFile::dupFd() may_throw {
|
||||
if (!isOpen())
|
||||
throwIOException("bad dup");
|
||||
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
|
||||
errno = ENOSYS;
|
||||
int r = -1;
|
||||
#else
|
||||
int r = ::dup(getFd());
|
||||
#endif
|
||||
if (r < 0)
|
||||
throwIOException("dup", errno);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int InputFile::read(MemBuffer &buf, int len)
|
||||
{
|
||||
return read(&buf, len);
|
||||
}
|
||||
|
||||
int InputFile::readx(MemBuffer &buf, int len)
|
||||
{
|
||||
return readx(&buf, len);
|
||||
}
|
||||
|
||||
|
||||
void InputFile::seek(off_t off, int whence)
|
||||
{
|
||||
super::seek(off,whence);
|
||||
}
|
||||
|
||||
|
||||
off_t InputFile::tell() const
|
||||
{
|
||||
return super::tell();
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// OutputFile
|
||||
**************************************************************************/
|
||||
|
||||
OutputFile::OutputFile() :
|
||||
bytes_written(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OutputFile::~OutputFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||
{
|
||||
close();
|
||||
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
|
||||
closex();
|
||||
_name = name;
|
||||
_flags = flags;
|
||||
_shflags = shflags;
|
||||
_mode = mode;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
if (!super::do_sopen()) {
|
||||
#if 0
|
||||
// don't throw FileNotFound here -- this is confusing
|
||||
if (errno == ENOENT)
|
||||
@@ -328,16 +249,14 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||
else
|
||||
#endif
|
||||
if (errno == EEXIST)
|
||||
throw FileAlreadyExistsException(_name,errno);
|
||||
throw FileAlreadyExistsException(_name, errno);
|
||||
else
|
||||
throwIOException(_name,errno);
|
||||
throwIOException(_name, errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool OutputFile::openStdout(int flags, bool force)
|
||||
{
|
||||
close();
|
||||
bool OutputFile::openStdout(int flags, bool force) {
|
||||
closex();
|
||||
int fd = STDOUT_FILENO;
|
||||
if (!force && acc_isatty(fd))
|
||||
return false;
|
||||
@@ -353,65 +272,92 @@ bool OutputFile::openStdout(int flags, bool force)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::write(const void *buf, int len)
|
||||
{
|
||||
super::write(buf, len);
|
||||
void OutputFile::write(SPAN_0(const void) buf, upx_int64_t blen) {
|
||||
if (!isOpen() || blen < 0)
|
||||
throwIOException("bad write");
|
||||
// allow nullptr if blen == 0
|
||||
if (blen == 0)
|
||||
return;
|
||||
int len = (int) mem_size(1, blen); // sanity check
|
||||
errno = 0;
|
||||
#if WITH_XSPAN >= 2
|
||||
NO_fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(),
|
||||
buf.raw_base(), len);
|
||||
#endif
|
||||
long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len);
|
||||
if (l != len)
|
||||
throwIOException("write error", errno);
|
||||
bytes_written += len;
|
||||
#if TESTING && 0
|
||||
static upx_std_atomic(bool) dumping;
|
||||
if (!dumping) {
|
||||
dumping = true;
|
||||
char fn[64];
|
||||
static int part = 0;
|
||||
snprintf(fn, sizeof(fn), "upx-dump-%04d.data", part++);
|
||||
OutputFile::dump(fn, buf, len);
|
||||
dumping = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
off_t OutputFile::st_size() const
|
||||
{
|
||||
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||
upx_off_t OutputFile::st_size() const {
|
||||
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||
}
|
||||
struct stat my_st;
|
||||
my_st.st_size = 0;
|
||||
if (::fstat(_fd, &my_st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
return my_st.st_size;
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::write(const MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
write(buf->getVoidPtr(), len);
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::write(const MemBuffer &buf, int len)
|
||||
{
|
||||
write(&buf, len);
|
||||
}
|
||||
|
||||
void OutputFile::rewrite(const void *buf, int len)
|
||||
{
|
||||
void OutputFile::rewrite(SPAN_P(const void) buf, int len) {
|
||||
assert(!opt->to_stdout);
|
||||
write(buf, len);
|
||||
bytes_written -= len; // restore
|
||||
bytes_written -= len; // restore
|
||||
}
|
||||
|
||||
void OutputFile::seek(off_t off, int whence)
|
||||
{
|
||||
upx_off_t OutputFile::seek(upx_off_t off, int whence) {
|
||||
if (!mem_size_valid_bytes(off >= 0 ? off : -off)) // sanity check
|
||||
throwIOException("bad seek");
|
||||
assert(!opt->to_stdout);
|
||||
super::seek(off,whence);
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
if (bytes_written < off)
|
||||
bytes_written = off;
|
||||
_length = bytes_written; // cheap, lazy update; needed?
|
||||
break;
|
||||
case SEEK_END:
|
||||
_length = bytes_written; // necessary
|
||||
break;
|
||||
}
|
||||
return super::seek(off, whence);
|
||||
}
|
||||
|
||||
void OutputFile::set_extent(off_t offset, off_t length)
|
||||
{
|
||||
// WARNING: fsync() does not exist in some Windows environments.
|
||||
// This trick works only on UNIX-like systems.
|
||||
// int OutputFile::read(void *buf, int len) {
|
||||
// fsync(_fd);
|
||||
// InputFile infile;
|
||||
// infile.open(this->getName(), O_RDONLY | O_BINARY);
|
||||
// infile.seek(this->tell(), SEEK_SET);
|
||||
// return infile.read(buf, len);
|
||||
//}
|
||||
|
||||
void OutputFile::set_extent(upx_off_t offset, upx_off_t length) {
|
||||
super::set_extent(offset, length);
|
||||
bytes_written = 0;
|
||||
if (0==offset && (off_t)~0u==length) {
|
||||
if (0 == offset && 0xffffffffLL == length) { // TODO: check all callers of this method
|
||||
st.st_size = 0;
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size - offset;
|
||||
}
|
||||
}
|
||||
|
||||
off_t OutputFile::unset_extent()
|
||||
{
|
||||
off_t l = ::lseek(_fd, 0, SEEK_END);
|
||||
upx_off_t OutputFile::unset_extent() {
|
||||
upx_off_t l = ::lseek(_fd, 0, SEEK_END);
|
||||
if (l < 0)
|
||||
throwIOException("lseek error", errno);
|
||||
_offset = 0;
|
||||
@@ -420,48 +366,29 @@ off_t OutputFile::unset_extent()
|
||||
return _length;
|
||||
}
|
||||
|
||||
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
||||
{
|
||||
/*static*/ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) {
|
||||
if (flags < 0)
|
||||
flags = O_CREAT | O_BINARY | O_TRUNC;
|
||||
flags |= O_WRONLY;
|
||||
flags = O_CREAT | O_TRUNC;
|
||||
flags |= O_WRONLY | O_BINARY;
|
||||
OutputFile f;
|
||||
f.open(name, flags, 0600);
|
||||
f.write(buf, len);
|
||||
f.write(raw_bytes(buf, len), len);
|
||||
f.closex();
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
MemoryOutputFile::MemoryOutputFile() :
|
||||
b(NULL), b_size(0), b_pos(0), bytes_written(0)
|
||||
{
|
||||
TEST_CASE("file") {
|
||||
InputFile fi;
|
||||
CHECK(!fi.isOpen());
|
||||
CHECK(fi.getFd() == -1);
|
||||
CHECK(fi.st_size() == 0);
|
||||
OutputFile fo;
|
||||
CHECK(!fo.isOpen());
|
||||
CHECK(fo.getFd() == -1);
|
||||
CHECK(fo.getBytesWritten() == 0);
|
||||
}
|
||||
|
||||
|
||||
void MemoryOutputFile::write(const void *buf, int len)
|
||||
{
|
||||
if (!isOpen() || len < 0)
|
||||
throwIOException("bad write");
|
||||
if (len == 0)
|
||||
return;
|
||||
if (b_pos + len > b_size)
|
||||
throwIOException("write error",ENOSPC);
|
||||
memcpy(b + b_pos, buf, len);
|
||||
b_pos += len;
|
||||
bytes_written += len;
|
||||
}
|
||||
|
||||
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+65
-123
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2025 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,168 +22,110 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_FILE_H
|
||||
#define __UPX_FILE_H
|
||||
|
||||
class MemBuffer;
|
||||
|
||||
#pragma once
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class File
|
||||
{
|
||||
class FileBase {
|
||||
protected:
|
||||
File() { }
|
||||
virtual ~File() { }
|
||||
public:
|
||||
static void chmod(const char *name, int mode);
|
||||
static void rename(const char *old_, const char *new_);
|
||||
static void unlink(const char *name);
|
||||
};
|
||||
explicit FileBase() noexcept = default;
|
||||
virtual ~FileBase() may_throw;
|
||||
|
||||
|
||||
class FileBase : public File
|
||||
{
|
||||
protected:
|
||||
FileBase();
|
||||
virtual ~FileBase();
|
||||
public:
|
||||
virtual bool close();
|
||||
virtual void closex();
|
||||
virtual bool isOpen() const { return _fd >= 0; }
|
||||
int getFd() const { return _fd; }
|
||||
const char *getName() const { return _name; }
|
||||
virtual off_t st_size() const; // { return _length; }
|
||||
virtual void set_extent(off_t offset, off_t length);
|
||||
bool close_noexcept() noexcept;
|
||||
void closex() may_throw;
|
||||
bool isOpen() const noexcept { return _fd >= 0; }
|
||||
int getFd() const noexcept { return _fd; }
|
||||
const char *getName() const noexcept { return _name; }
|
||||
|
||||
virtual upx_off_t seek(upx_off_t off, int whence);
|
||||
upx_off_t tell() const;
|
||||
virtual upx_off_t st_size() const; // { return _length; }
|
||||
virtual void set_extent(upx_off_t offset, upx_off_t length);
|
||||
|
||||
public:
|
||||
// static file-related util functions; will throw on error
|
||||
static void chmod(const char *name, int mode) may_throw;
|
||||
static void rename(const char *old_, const char *new_) may_throw;
|
||||
static void unlink(const char *name) may_throw;
|
||||
static bool unlink_noexcept(const char *name) noexcept;
|
||||
|
||||
protected:
|
||||
bool do_sopen();
|
||||
virtual int read(void *buf, int len);
|
||||
virtual int readx(void *buf, int len);
|
||||
virtual void write(const void *buf, int len);
|
||||
virtual void seek(off_t off, int whence);
|
||||
virtual off_t tell() const;
|
||||
int _fd = -1;
|
||||
int _flags = 0;
|
||||
int _shflags = 0;
|
||||
int _mode = 0;
|
||||
const char *_name = nullptr;
|
||||
upx_off_t _offset = 0;
|
||||
upx_off_t _length = 0;
|
||||
|
||||
int _fd;
|
||||
int _flags;
|
||||
int _shflags;
|
||||
int _mode;
|
||||
const char *_name;
|
||||
off_t _offset;
|
||||
off_t _length;
|
||||
public:
|
||||
struct stat st;
|
||||
struct stat st = {};
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class InputFile : public FileBase
|
||||
{
|
||||
class InputFile final : public FileBase {
|
||||
typedef FileBase super;
|
||||
|
||||
public:
|
||||
InputFile();
|
||||
virtual ~InputFile();
|
||||
explicit InputFile() noexcept = default;
|
||||
|
||||
virtual void sopen(const char *name, int flags, int shflags);
|
||||
virtual void open(const char *name, int flags)
|
||||
{
|
||||
sopen(name, flags, -1);
|
||||
}
|
||||
void sopen(const char *name, int flags, int shflags);
|
||||
void open(const char *name, int flags) { sopen(name, flags, -1); }
|
||||
|
||||
virtual int read(void *buf, int len);
|
||||
virtual int readx(void *buf, int len);
|
||||
virtual int read(MemBuffer *buf, int len);
|
||||
virtual int readx(MemBuffer *buf, int len);
|
||||
virtual int read(MemBuffer &buf, int len);
|
||||
virtual int readx(MemBuffer &buf, int len);
|
||||
int read(SPAN_P(void) buf, upx_int64_t blen);
|
||||
int readx(SPAN_P(void) buf, upx_int64_t blen);
|
||||
|
||||
virtual void seek(off_t off, int whence);
|
||||
virtual off_t tell() const;
|
||||
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||
upx_off_t st_size_orig() const;
|
||||
|
||||
noinline int dupFd() may_throw;
|
||||
|
||||
protected:
|
||||
upx_off_t _length_orig = 0;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class OutputFile : public FileBase
|
||||
{
|
||||
class OutputFile final : public FileBase {
|
||||
typedef FileBase super;
|
||||
|
||||
public:
|
||||
OutputFile();
|
||||
virtual ~OutputFile();
|
||||
explicit OutputFile() noexcept = default;
|
||||
|
||||
virtual void sopen(const char *name, int flags, int shflags, int mode);
|
||||
virtual void open(const char *name, int flags, int mode)
|
||||
{
|
||||
sopen(name, flags, -1, mode);
|
||||
}
|
||||
virtual bool openStdout(int flags=0, bool force=false);
|
||||
void sopen(const char *name, int flags, int shflags, int mode);
|
||||
void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); }
|
||||
bool openStdout(int flags = 0, bool force = false);
|
||||
|
||||
virtual void write(const void *buf, int len);
|
||||
virtual void write(const MemBuffer *buf, int len);
|
||||
virtual void write(const MemBuffer &buf, int len);
|
||||
virtual void set_extent(off_t offset, off_t length);
|
||||
virtual off_t unset_extent(); // returns actual length
|
||||
// info: allow nullptr if blen == 0
|
||||
void write(SPAN_0(const void) buf, upx_int64_t blen);
|
||||
|
||||
off_t getBytesWritten() const { return bytes_written; }
|
||||
virtual off_t st_size() const; // { return _length; }
|
||||
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||
virtual upx_off_t st_size() const override; // { return _length; }
|
||||
virtual void set_extent(upx_off_t offset, upx_off_t length) override;
|
||||
upx_off_t unset_extent(); // returns actual length
|
||||
|
||||
// FIXME - these won't work when using the '--stdout' option
|
||||
virtual void seek(off_t off, int whence);
|
||||
virtual void rewrite(const void *buf, int len);
|
||||
upx_off_t getBytesWritten() const { return bytes_written; }
|
||||
|
||||
// FIXME - this won't work when using the '--stdout' option
|
||||
void rewrite(SPAN_P(const void) buf, int len);
|
||||
|
||||
// util
|
||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||
static void dump(const char *name, SPAN_P(const void) buf, int len, int flags = -1);
|
||||
|
||||
protected:
|
||||
off_t bytes_written;
|
||||
upx_off_t bytes_written = 0;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if 0 /* NOT USED */
|
||||
class MemoryOutputFile : public FileBase
|
||||
{
|
||||
typedef FileBase super;
|
||||
public:
|
||||
MemoryOutputFile();
|
||||
virtual ~MemoryOutputFile() { b = NULL; }
|
||||
|
||||
virtual bool close() { b = NULL; return true; }
|
||||
virtual bool isOpen() const { return b != NULL; }
|
||||
virtual void open(void *buf, unsigned size)
|
||||
{ b = (upx_bytep) buf; b_size = size; }
|
||||
|
||||
virtual void write(const void *buf, int len);
|
||||
|
||||
off_t getBytesWritten() const { return bytes_written; }
|
||||
|
||||
protected:
|
||||
upx_bytep b;
|
||||
unsigned b_size;
|
||||
unsigned b_pos;
|
||||
off_t bytes_written;
|
||||
};
|
||||
#endif /* if 0 */
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user