Compare commits
1451 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
-105
@@ -1,105 +0,0 @@
|
|||||||
# Support for AppVeyor CI -- https://www.appveyor.com/
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
os: Visual Studio 2015
|
|
||||||
|
|
||||||
environment:
|
|
||||||
global: { TRAVIS_OS_NAME: windows, CROSS: "", C: "", B: release, T: "", X: "" }
|
|
||||||
matrix:
|
|
||||||
- { C: msvc-10.0-x86, CL_VERSION: 16.00, VS_VERSION: 2010 }
|
|
||||||
### - { C: msvc-10.0-x64, CL_VERSION: 16.00, VS_VERSION: 2010 } # AppVeyor: x64 compiler is not installed
|
|
||||||
- { C: msvc-11.0-x86, CL_VERSION: 17.00, VS_VERSION: 2012 }
|
|
||||||
### - { C: msvc-11.0-x64, CL_VERSION: 17.00, VS_VERSION: 2012 } # AppVeyor: x64 compiler is not installed
|
|
||||||
- { C: msvc-12.0-x86, CL_VERSION: 18.00, VS_VERSION: 2013 }
|
|
||||||
- { C: msvc-12.0-x64, CL_VERSION: 18.00, VS_VERSION: 2013 }
|
|
||||||
- { C: msvc-14.0-x86, CL_VERSION: 19.00, VS_VERSION: 2015 }
|
|
||||||
- { C: msvc-14.0-x64, CL_VERSION: 19.00, VS_VERSION: 2015 }
|
|
||||||
# - { C: gcc-4.9-m32, T: SKIP }
|
|
||||||
# - { C: gcc-4.9-m64, T: SKIP }
|
|
||||||
UPX_AUTOMATIC_BUILDS_SSL_KEY:
|
|
||||||
secure: PZMpVeqnEYe39kK+Zu2/fnmZ6/HG6Lvls0hh9GMVU9vCWsr8xaU7kIbHBS01puUkb4bEWPILKYvSEDuhOhguDjd/P4QdXWipvV/F2GaVax0=
|
|
||||||
UPX_AUTOMATIC_BUILDS_SSL_IV:
|
|
||||||
secure: ZshjJ/78dbY60mVJjZJv9Si7rHY9VQb1tfQvFd4lqvY=
|
|
||||||
|
|
||||||
init:
|
|
||||||
- git config --global core.autocrlf input
|
|
||||||
- where bash & where cat & where chmod & where cp & where curl & where date & where file & where git & where gzip & where mkdir & where mv & where openssl & where readlink & where rm & where rmdir & where sed & where sha256sum & where sort & where ssh & where ssh-add & where ssh-agent & where ssh-keyscan & where tar
|
|
||||||
# - bash --version & git --version & sed --version & tar --version
|
|
||||||
- git --version & bash --version
|
|
||||||
# - dir "c:\Program Files\Git\usr\bin"
|
|
||||||
# - dir "c:\cygwin\bin"
|
|
||||||
# - dir "c:\mingw\bin"
|
|
||||||
# - dir "c:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin"
|
|
||||||
|
|
||||||
install:
|
|
||||||
- cd c:\projects
|
|
||||||
- md build build\%C% deps
|
|
||||||
- cd c:\projects\upx
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
- cd c:\projects\deps
|
|
||||||
- curl -q -L --retry 5 -o ucl-1.03.tar.gz "https://github.com/upx/upx/releases/download/v3.00/ucl-1.03.tar.gz"
|
|
||||||
- curl -q -L --retry 5 -o zlib-1.2.8.tar.gz "https://github.com/upx/upx/releases/download/v3.00/zlib-1.2.8.tar.gz"
|
|
||||||
- git clone https://github.com/upx/upx-testsuite
|
|
||||||
- tar -xzf ucl-1.03.tar.gz
|
|
||||||
- tar -xzf zlib-1.2.8.tar.gz
|
|
||||||
# patch UCL for msvc-14.0 (vsnprintf issue)
|
|
||||||
- sed -i '/# *define.*snprintf *_v*snprintf$/d' ucl-1.03/acc/acc_auto.h
|
|
||||||
##- curl -q -L --retry 5 -o config.guess "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD"
|
|
||||||
##- curl -q -L --retry 5 -o config.sub "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD"
|
|
||||||
##- cp config.guess config.sub ucl-1.03/acconfig/
|
|
||||||
# setup compiler
|
|
||||||
- if "%C%"=="msvc-10.0-x86" ( call "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 )
|
|
||||||
- if "%C%"=="msvc-10.0-x64" ( call "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64 )
|
|
||||||
- if "%C%"=="msvc-11.0-x86" ( call "c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" x86 )
|
|
||||||
- if "%C%"=="msvc-11.0-x64" ( call "c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64 )
|
|
||||||
- if "%C%"=="msvc-12.0-x86" ( call "c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86 )
|
|
||||||
- if "%C%"=="msvc-12.0-x64" ( call "c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 )
|
|
||||||
- if "%C%"=="msvc-14.0-x86" ( call "c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 )
|
|
||||||
- if "%C%"=="msvc-14.0-x64" ( call "c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 )
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- cd c:\projects\upx
|
|
||||||
- if "%C%"=="gcc-4.9-m32" set PATH=c:\cygwin\bin;%PATH%
|
|
||||||
- if "%C%"=="gcc-4.9-m32" bash -x ./.github/travis_build.sh
|
|
||||||
- if "%C%"=="gcc-4.9-m32" exit
|
|
||||||
- if "%C%"=="gcc-4.9-m64" set PATH=c:\cygwin\bin;%PATH%
|
|
||||||
- if "%C%"=="gcc-4.9-m64" bash -x ./.github/travis_build.sh
|
|
||||||
- if "%C%"=="gcc-4.9-m64" exit
|
|
||||||
# setup directories following the VPATH build in travis_build.sh
|
|
||||||
- where cl & where link
|
|
||||||
- set BDIR=c:\projects\build\%C%\%B%
|
|
||||||
- md %BDIR% %BDIR%\ucl-1.03 %BDIR%\upx %BDIR%\upx-testsuite %BDIR%\zlib-1.2.8
|
|
||||||
- set DEFS=-D_CRT_SECURE_NO_WARNINGS
|
|
||||||
- git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
|
||||||
# build UCL
|
|
||||||
- cd %BDIR%\ucl-1.03
|
|
||||||
- set s=c:\projects\deps\ucl-1.03
|
|
||||||
- cl -MT -O2 -W4 %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
|
||||||
- link -lib -out:ucl.lib *.obj
|
|
||||||
# build zlib
|
|
||||||
- cd %BDIR%\zlib-1.2.8
|
|
||||||
- cl -MT -O2 -W2 %DEFS% -c c:\projects\deps\zlib-1.2.8\*.c
|
|
||||||
- link -lib -out:zlib.lib *.obj
|
|
||||||
# build UPX
|
|
||||||
- cd %BDIR%\upx
|
|
||||||
- set s=c:\projects\upx\src
|
|
||||||
- cat .GITREV.txt
|
|
||||||
- set /p GITREV=<.GITREV.txt
|
|
||||||
- cl -MT -EHsc -J -O2 -W4 -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% -DWITH_LZMA=0x443 -DUCL_NO_ASM -I%s%\lzma-sdk -Ic:\projects\deps\ucl-1.03\include -Ic:\projects\deps\zlib-1.2.8 -Feupx.exe %s%\*.cpp %BDIR%\ucl-1.03\ucl.lib %BDIR%\zlib-1.2.8\zlib.lib
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- set UPX=--no-color --no-progress
|
|
||||||
- cd %BDIR%\upx
|
|
||||||
# basic tests
|
|
||||||
- .\upx.exe --version
|
|
||||||
- .\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
|
|
||||||
# now run the UPX testsuite using bash
|
|
||||||
- cd c:\projects\upx
|
|
||||||
- bash ./.github/travis_testsuite_1.sh
|
|
||||||
- bash ./.github/travis_deploy.sh
|
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
# Support for Circle CI -- https://circleci.com/gh/upx/upx
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
machine:
|
|
||||||
environment:
|
|
||||||
TRAVIS_OS_NAME: linux
|
|
||||||
CROSS:
|
|
||||||
C: gcc-4.8-m64
|
|
||||||
B: release
|
|
||||||
T:
|
|
||||||
X:
|
|
||||||
|
|
||||||
checkout:
|
|
||||||
post:
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
pre:
|
|
||||||
- mkdir -p ../deps
|
|
||||||
- cd ../deps && wget -q -O - https://github.com/upx/upx/releases/download/v3.00/ucl-1.03.tar.xz | tar -xJ
|
|
||||||
- cd ../deps && wget -q -O - https://github.com/upx/upx/releases/download/v3.00/zlib-1.2.8.tar.xz | tar -xJ
|
|
||||||
- cd ../deps && git clone https://github.com/upx/upx-testsuite
|
|
||||||
override:
|
|
||||||
- mkdir -p ../build/travis
|
|
||||||
- bash ./.github/travis_build.sh
|
|
||||||
|
|
||||||
test:
|
|
||||||
override:
|
|
||||||
- bash ./.github/travis_testsuite_1.sh
|
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
|
||||||
@@ -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
|
||||||
|
...
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
# 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.rand,
|
||||||
|
-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
|
||||||
|
...
|
||||||
+6
-5
@@ -1,6 +1,7 @@
|
|||||||
#
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
# see http://editorconfig.org/
|
# see https://editorconfig.org/
|
||||||
#
|
|
||||||
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
@@ -14,8 +15,8 @@ trim_trailing_whitespace = true
|
|||||||
indent_size = 8
|
indent_size = 8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[*.S]
|
[{*.asm,*.S}]
|
||||||
indent_size = 8
|
indent_size = 8
|
||||||
|
|
||||||
[*.yml]
|
[{*.yaml,*.yml}]
|
||||||
indent_size = 2
|
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
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
---
|
||||||
|
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.
|
IF YOU REMOVE THIS TEMPLATE WE WILL CLOSE YOUR ISSUE WITHOUT RESPONSE.
|
||||||
@@ -27,5 +39,7 @@ Just read it and fill in the details we're asking, it saves so much of our time.
|
|||||||
## Please tell us details about your environment.
|
## Please tell us details about your environment.
|
||||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||||
* UPX version used (`upx --version`):
|
* UPX version used (`upx --version`):
|
||||||
* Operating System and version:
|
* Host Operating System and version:
|
||||||
* CPU architecture:
|
* 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: |
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Support for Travis CI -- https://travis-ci.org/upx/upx/builds
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
# create dirs
|
|
||||||
cd / || exit 1
|
|
||||||
mkbuilddirs $upx_BUILDDIR $ucl_BUILDDIR $upx_testsuite_BUILDDIR $zlib_BUILDDIR
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
|
|
||||||
echo
|
|
||||||
print_settings
|
|
||||||
echo
|
|
||||||
echo "$CC --version"; $CC --version
|
|
||||||
echo "$CXX --version"; $CXX --version
|
|
||||||
echo
|
|
||||||
|
|
||||||
# check whitespace
|
|
||||||
if [[ $TRAVIS_OS_NAME == linux ]]; then
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
echo "Checking source code for whitespace violations..."
|
|
||||||
bash ./src/stub/scripts/check_whitespace.sh || exit 1
|
|
||||||
echo " Passed."
|
|
||||||
fi # linux
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
#
|
|
||||||
# rebuild UPX stubs (needs upx-stubtools)
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $BM_X =~ (^|\+)rebuild-stubs($|\+) ]]; then
|
|
||||||
bin_upx=$(readlink -en -- "$upx_SRCDIR/../deps/bin-upx-20160918")
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
make -C src/stub maintainer-clean
|
|
||||||
failed=0
|
|
||||||
PATH="$bin_upx:$PATH" make -C src/stub all || failed=1
|
|
||||||
if [[ $failed != 0 ]]; then
|
|
||||||
echo "UPX-ERROR: FATAL: rebuild-stubs failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if ! git diff --quiet; then
|
|
||||||
git status || true
|
|
||||||
git diff || true
|
|
||||||
echo "UPX-ERROR: FATAL: rebuild-stubs git status mismatch. See log file."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
|
||||||
echo "X=rebuild-stubs done. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
unset bin_upx failed
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# build UCL
|
|
||||||
#
|
|
||||||
|
|
||||||
cd / && cd $ucl_BUILDDIR || exit 1
|
|
||||||
if [[ -n $BM_CROSS || $TRAVIS_OS_NAME == windows ]]; then
|
|
||||||
# ucl-1.03/configure is too old - build manually
|
|
||||||
rm -f ./*.o libucl.a
|
|
||||||
$CC -O2 -I$ucl_SRCDIR/include -I$ucl_SRCDIR -c $ucl_SRCDIR/src/*.c
|
|
||||||
$AR rcs libucl.a *.o
|
|
||||||
mkdir -p src/.libs
|
|
||||||
cp libucl.a src/.libs
|
|
||||||
else
|
|
||||||
if [[ ! -f config.status ]]; then
|
|
||||||
$ucl_SRCDIR/configure --enable-static --disable-shared --disable-asm
|
|
||||||
fi
|
|
||||||
make
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# build zlib
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $BUILD_LOCAL_ZLIB == 1 ]]; then
|
|
||||||
cd / && cd $zlib_BUILDDIR || exit 1
|
|
||||||
# build manually
|
|
||||||
rm -f ./*.o libz.a
|
|
||||||
$CC -O2 -c $zlib_SRCDIR/*.c
|
|
||||||
$AR rcs libz.a *.o
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# build UPX
|
|
||||||
#
|
|
||||||
|
|
||||||
export UPX_UCLDIR="$ucl_SRCDIR"
|
|
||||||
cd / && cd $upx_BUILDDIR || exit 1
|
|
||||||
make="make -f $upx_SRCDIR/src/Makefile"
|
|
||||||
EXTRA_CPPFLAGS="$EXTRA_CPPFLAGS -DUCL_NO_ASM"
|
|
||||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$ucl_BUILDDIR/src/.libs"
|
|
||||||
if [[ $BUILD_LOCAL_ZLIB == 1 ]]; then
|
|
||||||
EXTRA_CPPFLAGS="$EXTRA_CPPFLAGS -I$zlib_SRCDIR"
|
|
||||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$zlib_BUILDDIR"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -fprofile-arcs -ftest-coverage"
|
|
||||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fprofile-arcs -ftest-coverage"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)debug($|\+) ]]; then
|
|
||||||
make="$make BUILD_TYPE_DEBUG=1"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)sanitize($|\+) ]]; then
|
|
||||||
case $TRAVIS_OS_NAME-$CC in linux-gcc*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fuse-ld=gold" ;; esac
|
|
||||||
make="$make BUILD_TYPE_SANITIZE=1"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)scan-build($|\+) ]]; then
|
|
||||||
make="$SCAN_BUILD $make"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)valgrind($|\+) ]]; then
|
|
||||||
EXTRA_CPPFLAGS="$EXTRA_CPPFLAGS -DWITH_VALGRIND"
|
|
||||||
fi
|
|
||||||
if [[ $BM_B =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
|
||||||
echo "ALLOW_FAIL"
|
|
||||||
set +e
|
|
||||||
fi
|
|
||||||
export EXTRA_CPPFLAGS EXTRA_CXXFLAGS EXTRA_LDFLAGS
|
|
||||||
|
|
||||||
[[ -z $upx_exeext ]] && upx_exeext=.out
|
|
||||||
$make exeext=$upx_exeext
|
|
||||||
|
|
||||||
pwd
|
|
||||||
ls -l upx${upx_exeext}
|
|
||||||
$SIZE upx${upx_exeext} || true
|
|
||||||
file upx${upx_exeext}
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Support for Travis CI -- https://travis-ci.org/upx/upx/builds
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
set -x # debug
|
|
||||||
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then exit 0; fi
|
|
||||||
# save space
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then exit 0; fi
|
|
||||||
if [[ $BM_B =~ (^|\+)debug($|\+) ]]; then exit 0; fi
|
|
||||||
if [[ $BM_B =~ (^|\+)sanitize($|\+) ]]; then exit 0; fi
|
|
||||||
if [[ $BM_B =~ (^|\+)scan-build($|\+) ]]; then exit 0; fi
|
|
||||||
if [[ $BM_B =~ (^|\+)valgrind($|\+) ]]; then exit 0; fi
|
|
||||||
|
|
||||||
# prepare $subdir and $branch
|
|
||||||
subdir=
|
|
||||||
branch=
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
branch=$APPVEYOR_REPO_BRANCH
|
|
||||||
if [[ -n $APPVEYOR_PULL_REQUEST_NUMBER ]]; then exit 0; fi
|
|
||||||
elif [[ -n $GITLAB_CI ]]; then
|
|
||||||
subdir=$CI_BUILD_NAME
|
|
||||||
branch=$CI_BUILD_REF_NAME
|
|
||||||
else
|
|
||||||
branch=$TRAVIS_BRANCH
|
|
||||||
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then exit 0; fi
|
|
||||||
fi
|
|
||||||
subdir=${subdir%%:*}; subdir=${subdir%%/*}; subdir=${subdir%%-*}
|
|
||||||
case $branch in
|
|
||||||
devel*) ;;
|
|
||||||
master*) ;;
|
|
||||||
travis*) ;;
|
|
||||||
*) exit 0;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# get $rev, $branch and $git_user
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
rev=$(git rev-parse --verify HEAD)
|
|
||||||
timestamp=$(git log -n1 --format='%at' HEAD)
|
|
||||||
date=$(TZ=UTC0 date -d "@$timestamp" '+%Y%m%d-%H%M%S')
|
|
||||||
#branch="$branch-$date-${rev:0:6}"
|
|
||||||
# make the branch name a little bit shorter so that it looks nice on GitHub
|
|
||||||
branch="$branch-${date:0:8}-${rev:0:7}"
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
branch="$branch-appveyor"
|
|
||||||
git_user="AppVeyor CI"
|
|
||||||
elif [[ -n $GITLAB_CI ]]; then
|
|
||||||
branch="$branch-gitlab"
|
|
||||||
git_user="GitLab CI"
|
|
||||||
else
|
|
||||||
branch="$branch-travis"
|
|
||||||
git_user="Travis CI"
|
|
||||||
fi
|
|
||||||
unset timestamp date
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // prepare directory $d
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
cd / && cd $upx_BUILDDIR || exit 1
|
|
||||||
|
|
||||||
mkdir deploy || exit 1
|
|
||||||
chmod 700 deploy
|
|
||||||
cd deploy || exit 1
|
|
||||||
|
|
||||||
if [[ -n $BM_CROSS ]]; then
|
|
||||||
d=$BM_CROSS
|
|
||||||
else
|
|
||||||
cpu=unknown
|
|
||||||
case $BM_C in
|
|
||||||
clang*-m32 | gcc*-m32) cpu=i386;;
|
|
||||||
clang*-m64 | gcc*-m64) cpu=amd64;;
|
|
||||||
clang*-mx32 | gcc*-mx32) cpu=amd64;;
|
|
||||||
msvc*-x86) cpu=i386;;
|
|
||||||
msvc*-x64) cpu=amd64;;
|
|
||||||
esac
|
|
||||||
os=$TRAVIS_OS_NAME
|
|
||||||
if [[ $os == osx ]]; then
|
|
||||||
os=darwin
|
|
||||||
elif [[ $os == windows ]]; then
|
|
||||||
[[ $cpu == i386 ]] && os=win32
|
|
||||||
[[ $cpu == amd64 ]] && os=win64
|
|
||||||
fi
|
|
||||||
d=$cpu-$os
|
|
||||||
fi
|
|
||||||
d=$d-$BM_C-$BM_B
|
|
||||||
|
|
||||||
mkdir $d || exit 1
|
|
||||||
for exeext in .exe .out; do
|
|
||||||
f=$upx_BUILDDIR/upx$exeext
|
|
||||||
if [[ -f $f ]]; then
|
|
||||||
cp -p -i $f $d/upx-git-${rev:0:12}$exeext
|
|
||||||
sha256sum -b $d/upx-git-${rev:0:12}$exeext
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // clone, add files & push
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
new_branch=0
|
|
||||||
if ! git clone -b $branch --single-branch https://github.com/upx/upx-automatic-builds.git; then
|
|
||||||
git clone -b master --single-branch https://github.com/upx/upx-automatic-builds.git
|
|
||||||
new_branch=1
|
|
||||||
fi
|
|
||||||
cd upx-automatic-builds || exit 1
|
|
||||||
chmod 700 .git
|
|
||||||
git config user.name "$git_user"
|
|
||||||
git config user.email "none@none"
|
|
||||||
if [[ $new_branch == 1 ]]; then
|
|
||||||
git checkout --orphan $branch
|
|
||||||
git reset --hard
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n $subdir ]]; then
|
|
||||||
[[ -d $subdir ]] || mkdir $subdir
|
|
||||||
mv ../$d $subdir/
|
|
||||||
git add $subdir/$d
|
|
||||||
else
|
|
||||||
mv ../$d .
|
|
||||||
git add $d
|
|
||||||
fi
|
|
||||||
|
|
||||||
if git diff --cached --exit-code --quiet >/dev/null; then
|
|
||||||
# nothing to do ???
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
now=$(date '+%s')
|
|
||||||
##date=$(TZ=UTC0 date -d "@$now" '+%Y-%m-%d %H:%M:%S')
|
|
||||||
git commit --date="$now" -m "Automatic build $d"
|
|
||||||
git ls-files
|
|
||||||
#git log --pretty=fuller
|
|
||||||
|
|
||||||
umask 077
|
|
||||||
[[ -d ~/.ssh ]] || mkdir ~/.ssh
|
|
||||||
repo=$(git config remote.origin.url)
|
|
||||||
ssh_repo=${repo/https:\/\/github.com\//git@github.com:}
|
|
||||||
eval $(ssh-agent -s)
|
|
||||||
set +x # IMPORTANT
|
|
||||||
openssl aes-256-cbc -d -a -K "$UPX_AUTOMATIC_BUILDS_SSL_KEY" -iv "$UPX_AUTOMATIC_BUILDS_SSL_IV" -in "$upx_SRCDIR/.github/upx-automatic-builds@github.com.enc" -out .git/deploy.key
|
|
||||||
set -x
|
|
||||||
chmod 600 .git/deploy.key
|
|
||||||
ssh-add .git/deploy.key
|
|
||||||
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
|
||||||
|
|
||||||
let i=0 || true
|
|
||||||
while true; do
|
|
||||||
if [[ $i -ge 10 ]]; then
|
|
||||||
echo "ERROR: git push failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ $new_branch == 1 ]]; then
|
|
||||||
if git push -u $ssh_repo $branch; then break; fi
|
|
||||||
else
|
|
||||||
if git push $ssh_repo $branch; then break; fi
|
|
||||||
fi
|
|
||||||
git fetch -v origin $branch
|
|
||||||
git rebase origin/$branch
|
|
||||||
sleep $((RANDOM % 5 + 1))
|
|
||||||
let i+=1
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
|
|
||||||
# Support for Travis CI -- https://travis-ci.org/upx/upx/builds
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
#set -x # debug
|
|
||||||
umask 022
|
|
||||||
export GIT_PAGER=
|
|
||||||
|
|
||||||
# rename short variables to more readable Build-Matrix BM_ names
|
|
||||||
# C is COMPILER
|
|
||||||
# B is BUILD_OPTIONS
|
|
||||||
# T is TESTSUITE_OPTIONS
|
|
||||||
# X is EXTRA_OPTIONS
|
|
||||||
BM_CROSS=$CROSS; BM_C=$C; BM_B=$B; BM_T=$T; BM_X=$X
|
|
||||||
unset CROSS C B T X
|
|
||||||
[[ -z $BM_C ]] && BM_C=gcc
|
|
||||||
[[ -z $BM_B ]] && BM_B=release
|
|
||||||
|
|
||||||
# just in case, unset variable for passing extra UPX options
|
|
||||||
export UPX=
|
|
||||||
# un-export some vars
|
|
||||||
declare +x UPX_AUTOMATIC_BUILDS_SSL_KEY UPX_AUTOMATIC_BUILDS_SSL_IV
|
|
||||||
|
|
||||||
# compatibility wrappers
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
# use GNU coreutils ("brew install coreutils")
|
|
||||||
date() {
|
|
||||||
gdate "$@"
|
|
||||||
}
|
|
||||||
readlink() {
|
|
||||||
greadlink "$@"
|
|
||||||
}
|
|
||||||
sha256sum() {
|
|
||||||
gsha256sum "$@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
openssl() {
|
|
||||||
/usr/bin/openssl "$@"
|
|
||||||
}
|
|
||||||
sort() {
|
|
||||||
/usr/bin/sort "$@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set CC and CXX from BM_C and BM_CROSS
|
|
||||||
if [[ -z $CC_OVERRIDE ]]; then
|
|
||||||
CC=false CXX=false SCAN_BUILD=false
|
|
||||||
AR=ar SIZE=size
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
BUILD_LOCAL_ZLIB=1
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
|
|
||||||
fi
|
|
||||||
upx_exeext=.exe
|
|
||||||
# dir c:\cygwin
|
|
||||||
case $BM_C in
|
|
||||||
gcc-m32 | gcc-4.9-m32)
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
gcc-m64 | gcc-4.9-m64)
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
msvc | msvc-*)
|
|
||||||
AR="link -lib"; CC="cl"; CXX="cl" ;; # standard system compiler
|
|
||||||
esac
|
|
||||||
fi # APPVEYOR_JOB_ID
|
|
||||||
if [[ -n $BM_CROSS ]]; then
|
|
||||||
BUILD_LOCAL_ZLIB=1
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
|
|
||||||
fi
|
|
||||||
cat /etc/os-release || true
|
|
||||||
if egrep -q '^PRETTY_NAME="?Ubuntu .*12\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
arm-linux-gnueabi-gcc | arm-linux-gnueabi-gcc-4.6)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
|
|
||||||
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
|
|
||||||
arm-linux-gnueabihf-gcc | arm-linux-gnueabihf-gcc-4.6)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
|
|
||||||
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
|
|
||||||
i[36]86-w64-mingw32-gcc | i[36]86-w64-mingw32-gcc-4.6)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
x86_64-w64-mingw32-gcc | x86_64-w64-mingw32-gcc-4.6)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
esac
|
|
||||||
elif egrep -q '^PRETTY_NAME="?Ubuntu 16\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
aarch64-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-aarch64 -L /usr/aarch64-linux-gnu"
|
|
||||||
x=aarch64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
arm-linux-gnueabi-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
|
|
||||||
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
arm-linux-gnueabihf-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
|
|
||||||
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
i[36]86-w64-mingw32-gcc-5)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
mips-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-mips -L /usr/mips-linux-gnu"
|
|
||||||
x=mips-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
mipsel-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-mipsel -L /usr/mipsel-linux-gnu"
|
|
||||||
x=mipsel-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc -L /usr/powerpc-linux-gnu"
|
|
||||||
x=powerpc-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc64-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64 -L /usr/powerpc64-linux-gnu"
|
|
||||||
x=powerpc64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc64le-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64le -L /usr/powerpc64le-linux-gnu"
|
|
||||||
x=powerpc64le-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
s390x-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-s390x -L /usr/s390x-linux-gnu"
|
|
||||||
x=s390x-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
x86_64-w64-mingw32-gcc-5)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
fi # BM_CROSS
|
|
||||||
if [[ "$CC" == "false" ]]; then # generic
|
|
||||||
if [[ -z $BM_CROSS ]]; then
|
|
||||||
case $BM_C in
|
|
||||||
clang | clang-m?? | clang-3.4-m?? | clang-[678][0-9][0-9]-m??)
|
|
||||||
CC="clang"; CXX="clang++" ;; # standard system compiler
|
|
||||||
clang-[3].[0-9]-m??)
|
|
||||||
v=${BM_C:6:3}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
gcc | gcc-m?? | gcc-mx32)
|
|
||||||
CC="gcc"; CXX="g++" ;; # standard system compiler
|
|
||||||
gcc-[34].[0-9]-m?? | gcc-[34].[0-9]-mx32)
|
|
||||||
v=${BM_C:4:3}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
gcc-[56]-m?? | gcc-[56]-mx32)
|
|
||||||
v=${BM_C:4:1}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
fi # generic
|
|
||||||
case $BM_C in
|
|
||||||
clang*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
|
|
||||||
clang*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
|
|
||||||
gcc*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
|
|
||||||
gcc*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
|
|
||||||
gcc*-mx32) CC="$CC -mx32"; CXX="$CXX -mx32" ;;
|
|
||||||
esac
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
CC="$CC -std=gnu89"
|
|
||||||
fi
|
|
||||||
unset v x
|
|
||||||
export AR CC CXX
|
|
||||||
fi # CC_OVERRIDE
|
|
||||||
|
|
||||||
# source dirs
|
|
||||||
[[ -z $upx_SRCDIR ]] && upx_SRCDIR=$(readlink -mn -- $argv0dir/..)
|
|
||||||
[[ -z $ucl_SRCDIR ]] && ucl_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/ucl-1.03)
|
|
||||||
[[ -z $upx_testsuite_SRCDIR ]] && upx_testsuite_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/upx-testsuite)
|
|
||||||
[[ -z $zlib_SRCDIR ]] && zlib_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/zlib-1.2.8)
|
|
||||||
|
|
||||||
# build dirs
|
|
||||||
mkbuilddirs() {
|
|
||||||
local d
|
|
||||||
for d in "$@"; do
|
|
||||||
mkdir -p -v "$d" || exit 1
|
|
||||||
[[ -f "$d/.mfxnobackup" ]] || touch "$d/.mfxnobackup"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
# search for an existing $toptop_builddir
|
|
||||||
if [[ -z $toptop_builddir ]]; then
|
|
||||||
for d in . ..; do
|
|
||||||
for subdir in "local" appveyor circle gitlab travis .; do
|
|
||||||
dd=$d/build/$subdir
|
|
||||||
if [[ -d $dd ]]; then
|
|
||||||
toptop_builddir=$(readlink -en -- "$dd")
|
|
||||||
break 2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
unset d subdir dd
|
|
||||||
fi
|
|
||||||
[[ -z $toptop_builddir ]] && toptop_builddir=$(readlink -mn -- ./build)
|
|
||||||
[[ -z $toptop_bdir ]] && toptop_bdir=$(readlink -mn -- "$toptop_builddir/${BM_CROSS:+$BM_CROSS-}$BM_C/$BM_B")
|
|
||||||
[[ -z $upx_BUILDDIR ]] && upx_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx")
|
|
||||||
[[ -z $ucl_BUILDDIR ]] && ucl_BUILDDIR=$(readlink -mn -- "$toptop_bdir/ucl-1.03")
|
|
||||||
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx-testsuite")
|
|
||||||
[[ -z $zlib_BUILDDIR ]] && zlib_BUILDDIR=$(readlink -mn -- "$toptop_bdir/zlib-1.2.8")
|
|
||||||
[[ -z $lcov_OUTPUTDIR ]] && lcov_OUTPUTDIR=$(readlink -mn -- "$toptop_bdir/.lcov-results")
|
|
||||||
unset toptop_builddir toptop_bdir
|
|
||||||
|
|
||||||
# ensure absolute directories
|
|
||||||
make_absolute() {
|
|
||||||
local d
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
if [[ -n ${!1} ]]; then
|
|
||||||
d=$(readlink -mn -- "${!1}")
|
|
||||||
eval $1="$d"
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
}
|
|
||||||
for var_prefix in ucl upx upx_testsuite zlib; do
|
|
||||||
for var_suffix in _BUILDDIR _SRCDIR; do
|
|
||||||
make_absolute ${var_prefix}${var_suffix}
|
|
||||||
done
|
|
||||||
done
|
|
||||||
make_absolute lcov_OUTPUTDIR
|
|
||||||
unset var_prefix var_suffix
|
|
||||||
|
|
||||||
print_settings() {
|
|
||||||
local v var_prefix var_suffix
|
|
||||||
# Build Matrix
|
|
||||||
for v in TRAVIS_OS_NAME BM_CROSS BM_C BM_B BM_T; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
# BM_C related
|
|
||||||
for v in AR CC CXX CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LIBS SCAN_BUILD; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
v=EXTRA_${v}
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
# directories and other info
|
|
||||||
for v in TRAVIS_XCODE_SDK UPX_UCLDIR lcov_OUTPUTDIR; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
for var_prefix in ucl upx upx_testsuite zlib; do
|
|
||||||
for var_suffix in _BUILDDIR _SRCDIR; do
|
|
||||||
v=${var_prefix}${var_suffix}
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
##env | LC_ALL=C sort
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
@@ -1,381 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Support for Travis CI -- https://travis-ci.org/upx/upx/builds
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
#
|
|
||||||
# very first version of the upx-testsuite
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then
|
|
||||||
echo "UPX testsuite SKIPPED."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
|
||||||
|
|
||||||
# create dirs
|
|
||||||
cd / || exit 1
|
|
||||||
mkbuilddirs $upx_testsuite_BUILDDIR
|
|
||||||
cd / && cd $upx_testsuite_BUILDDIR || exit 1
|
|
||||||
if [[ ! -d $upx_testsuite_SRCDIR/files/packed ]]; then exit 1; fi
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // support functions
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
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 $f || -z $fsubdir || -z $fb ]]; then
|
|
||||||
fd= fb= fsubdir=
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_check_sha() {
|
|
||||||
(cd "$1" && sha256sum -b */* | 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=1
|
|
||||||
let num_errors+=1 || true
|
|
||||||
all_errors="${all_errors} $1"
|
|
||||||
#exit 1
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_check_sha_decompressed() {
|
|
||||||
(cd "$1" && sha256sum -b */* | 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 1
|
|
||||||
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
|
|
||||||
$upx_run -qq --prefer-ucl "$@" $f -o $testdir/$fsubdir/$fb
|
|
||||||
$upx_run -qq -d $testdir/$fsubdir/$fb -o $testdir/.decompressed/$fsubdir/$fb
|
|
||||||
done
|
|
||||||
testsuite_check_sha $testdir
|
|
||||||
$upx_run -qq -l $testdir/*/*
|
|
||||||
$upx_run -qq --file-info $testdir/*/*
|
|
||||||
$upx_run -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"
|
|
||||||
}
|
|
||||||
|
|
||||||
########## begin .sha256sums.recreate
|
|
||||||
expected_sha256sums__t010_decompressed="\
|
|
||||||
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
|
||||||
28d7ca8f0dfca8159e637eaf2057230b6e6719e07751aca1d19a45b5efed817c *arm-wince.pe/upx-3.91.exe
|
|
||||||
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
|
||||||
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
|
||||||
0dbc3c267ca8cd35ee3ea138b59c8b1ae35872c918be6d17df1a892b75710f9b *i386-win32.pe/upx-3.91.exe
|
|
||||||
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
|
||||||
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t020_canonicalized="\
|
|
||||||
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
|
||||||
28d7ca8f0dfca8159e637eaf2057230b6e6719e07751aca1d19a45b5efed817c *arm-wince.pe/upx-3.91.exe
|
|
||||||
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
|
||||||
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
|
||||||
0dbc3c267ca8cd35ee3ea138b59c8b1ae35872c918be6d17df1a892b75710f9b *i386-win32.pe/upx-3.91.exe
|
|
||||||
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
|
||||||
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
|
||||||
52d0189f9ed16162332fbe359d723753ca1b7d7374a249d6b16144e363073384 *amd64-linux.elf/upx-3.91
|
|
||||||
0af0b3df9ca5b34ebc8ed06b3bf46807e585032961f053abfeefcb60bd63907e *arm-wince.pe/upx-3.91.exe
|
|
||||||
851ea686cc1d6ef7c63978829f0bfe40c761d00e9f07c3d4f9ce59201da4409c *armeb-linux.elf/upx-3.91
|
|
||||||
3345fda466927211ed3291ea1255fa09937fcfad974ffb1120deeefe6f655a9e *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
8631629945812b6766da0187390b4d26e830f39a79d80aacda196e678a4be10c *i386-linux.elf/upx-3.91
|
|
||||||
06794bdb9a8085ca5ef577648bf39402868a507f2a0bd02285c807929499aba4 *i386-win32.pe/upx-3.91.exe
|
|
||||||
6c9e164baa12c45ca8d55788b34e8fabdddb52374200444d42ff48c1d84103eb *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
1f3ae2bde7c72e60d3c12fccf572c5aa5dbee566d1d28029e62a8b921c6d77bd *mipsel-linux.elf/upx-3.91
|
|
||||||
181345ff1dd1c35944ec79d1197ee223913617cdd148a576cd3b9b776b8e86c2 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
|
||||||
d90f1e94fb8a1d5c123e1c13b30db148870c36ff6f00fc5677bd9f05bae1fc02 *amd64-linux.elf/upx-3.91
|
|
||||||
e09a089e642f33502a35ab9a416142d3db4dbb67930366054e25c390678c3f7c *arm-wince.pe/upx-3.91.exe
|
|
||||||
b794cc520ab507887324fe04e1c36e1ed0b63ecdb29241213a3a3cf980e16cc2 *armeb-linux.elf/upx-3.91
|
|
||||||
ea5df377a14457fc4a4791e67859f77f8fe8b94ed81fd13666618fc690d70987 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
5f0876049576446707270baa651eaa724891cccbee268e18450812d5be5e9990 *i386-linux.elf/upx-3.91
|
|
||||||
4a65a19b430d50b9f15786342e3de86feb3627af07743b50a9ebfedb10c59a08 *i386-win32.pe/upx-3.91.exe
|
|
||||||
d7514121a811a36112cb2f3e42c3284e03a7807e972778229c62c075656d796f *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
0effcd336be6dcb092e37bafc9611c99c1d19c1c53a8ca6a26834d9f5f9eb56c *mipsel-linux.elf/upx-3.91
|
|
||||||
dfe218814633aa9ed47477bf021ac0bae0b491ebf9d4ff44194f3d7195e5a200 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
|
||||||
00b67a1cc766b13a6167e0f672cf46b62f0879b6318ed9f548f670b011b3f185 *amd64-linux.elf/upx-3.91
|
|
||||||
a377c263a3d981af1ec278a418fcdd09298d76cece0e7c7c9af63f20ccba769d *arm-wince.pe/upx-3.91.exe
|
|
||||||
dbf2fa9b4fa5319c52b25d34aa6f57577b2a63e7241b6d4600915de0f3400190 *armeb-linux.elf/upx-3.91
|
|
||||||
4d925cff00b8959324c0838284f4619831b8080136cef05131906149fdec5bbc *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
b114b257ff5de11b75eb4489d2cb2bd3be6cf9cf141e36f02b0ab781d0f9a3ff *i386-linux.elf/upx-3.91
|
|
||||||
ce874eafe18c0f09928992a3aa1f5fe9f0be9d89b87b39ecbcf1c460e4b8e0f7 *i386-win32.pe/upx-3.91.exe
|
|
||||||
c60b3faccc59ff37c2e1e3c908d4fe01a2532e7ac1abd4c4ec4ecee974a0e8bd *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
2b74a6a831c7f9f4df22c65f8a5748a2b6cf6fd68232b0d250737938de27efc6 *mipsel-linux.elf/upx-3.91
|
|
||||||
47ddad5acc39e21d66e471c8af8d9b52e8dd8d7ad89631f771c2ea4d218f441e *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
|
||||||
f67ce2b6d4d36367a249faeb802df51dbc56019754c0f4606b5a6f97b72a54d1 *amd64-linux.elf/upx-3.91
|
|
||||||
57be6aa4f1e5ee6ef6f5eb8694b22eb07c3ea5cc9b9ebfde75db4c9a04a71a5a *arm-wince.pe/upx-3.91.exe
|
|
||||||
ef18c1ae56a037d15f0494f4b835c1336a43745edba87c783f62745488008783 *armeb-linux.elf/upx-3.91
|
|
||||||
54a6158bc6bd8cc28d3abc53cc5cf9b63c3c63ae884e96fb6d6ea974c7426206 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
801d1761289f94d7f51effb88e100832d14ae96398844084b9d10852886c4731 *i386-linux.elf/upx-3.91
|
|
||||||
f828953a66d7b3394dd2514b5972680a0cc651bd198b7607f6d3f6f6cc390a0e *i386-win32.pe/upx-3.91.exe
|
|
||||||
587b5f1f529da60f5820b8f811743aaad59e3fa9407930de1ab433863f7262a4 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
84c811f5d27bac393610bfad4180258494c43d691c13eb57394ab95d4736e621 *mipsel-linux.elf/upx-3.91
|
|
||||||
ed83830ab5e1753a742cf4981401fd8d5bdaabcfdeb385a2e8087aeb46f93512 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
|
||||||
2849771c8799d7a446b54ad9914d679e315a9f0d9440f9728c6d5ab6541ed494 *amd64-linux.elf/upx-3.91
|
|
||||||
7ccbe7d7822cd9fed9b3c902c2bcb80f85df4f5bbb4e9e850257435ffa375a38 *arm-wince.pe/upx-3.91.exe
|
|
||||||
c6849deffc7bb1976c18a4815bca0b8fd0b6d19e4136965108daa6382efae2d5 *armeb-linux.elf/upx-3.91
|
|
||||||
c04818c54d68c99f345ee7995634dffbe7f1c2f2db8f2b510bba461d9125f5a9 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
a3758350a0454fb78060b6d6e48d8f000e17a628b6041e8c82e3990e0b3aabe9 *i386-linux.elf/upx-3.91
|
|
||||||
b4f27ba234a5c9b4f68e2067602a180c02f95fb044830f54a45267fe1c50bb83 *i386-win32.pe/upx-3.91.exe
|
|
||||||
dd9fb59d57a7157af1a44559f6ebd8a293b0988c66b4d0951c949f88f814bf8f *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
c0bc81487114b9d158ffe1dbd4081b9e3636695c63f11b3e204033b56fc69706 *mipsel-linux.elf/upx-3.91
|
|
||||||
0a700713f0c7ff19a534963f5ab95a63d2f185f82d0c42ce8c1a485aba4c1147 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
|
||||||
831b0dd82d2c8fb058e8300bda5dd51657a709e76c45e0c372d9cf83c2e06f31 *amd64-linux.elf/upx-3.91
|
|
||||||
057b08389af5a31a0bf4baf03d09eb07f4698f8ddec615ae35795cec62132966 *arm-wince.pe/upx-3.91.exe
|
|
||||||
49b6b8d4f04d9078686372a315e7768fc882ad66bebb67225fa0b2255b5dd1c9 *armeb-linux.elf/upx-3.91
|
|
||||||
aef085cb86ef29d7aa380a3daea403f53659af1615ceeaa76e609dc793f50cfd *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
52087d4a2c17445b0e8d5238ec3abd2ca5cd909513cff76bf42232f33d93903f *i386-linux.elf/upx-3.91
|
|
||||||
e669d7c4fec901130dd387dc8f95e3b3f5e739d6ef0bfac10080dbd257084ae6 *i386-win32.pe/upx-3.91.exe
|
|
||||||
40cd5a94039a1703986a68dd404290aa7c27fd8c184fa4c651467b8c2d621a5d *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
b1db1d04e350972aa06216ec43d12a451abf5c928c885b0c442f9436c804e84e *mipsel-linux.elf/upx-3.91
|
|
||||||
65602c3e1e3e152d44d9f803281d4021bfd91aab825b72d8901faf4d7d9b593e *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
|
||||||
bce397f12372437802d887d203bb2f8e4755dbe1a0e3c6bb9fa9cccd3306eef7 *amd64-linux.elf/upx-3.91
|
|
||||||
84b1fe14dbff7d4e2f1bcfee9b6e3c73f68eb5b95b37cbf2c655340bd959bfa3 *arm-wince.pe/upx-3.91.exe
|
|
||||||
1b6ac9c0893b3093d47e403a14a5d346ae3a0f135ecdbe3bb04fc0542abd469b *armeb-linux.elf/upx-3.91
|
|
||||||
d27237cd4b55c80d2b6c7da8d70ffc4f390290fcc550eec06c795e92d934b72a *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
2032623990d22b2cf8df5f2c0b581de5fd53869869b65818ea023a6857c4eff0 *i386-linux.elf/upx-3.91
|
|
||||||
51e91ff8226517ad8cd06d240e2c6c2f3d3e4033af1e593a5b294356d1bb5d33 *i386-win32.pe/upx-3.91.exe
|
|
||||||
b371684bbb2693797dd1164159de3bff9618bf6b99536542f57da07093dbb649 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
7c1fa54b86f3e5f3410216aa627bd32680d7bd8210776a14762566cb2ea37d52 *mipsel-linux.elf/upx-3.91
|
|
||||||
5c60d0817feeb4dde55be90e552ccddc81591fbaecb899c3a21afc91c0ceb3b9 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
########## end .sha256sums.recreate
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // init
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
#set -x # debug
|
|
||||||
exit_code=0
|
|
||||||
num_errors=0
|
|
||||||
all_errors=
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
|
||||||
echo "ALLOW_FAIL"
|
|
||||||
set +e
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.out ]] && upx_exe=$upx_BUILDDIR/upx.out
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.exe ]] && upx_exe=$upx_BUILDDIR/upx.exe
|
|
||||||
if [[ -z $upx_exe ]]; then exit 1; fi
|
|
||||||
upx_run=$upx_exe
|
|
||||||
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
|
||||||
upx_run="$upx_qemu $upx_qemu_flags -- $upx_exe"
|
|
||||||
fi
|
|
||||||
if [[ $BM_T =~ (^|\+)wine($|\+) && -n $upx_wine ]]; then
|
|
||||||
upx_run="$upx_wine $upx_wine_flags $upx_exe"
|
|
||||||
fi
|
|
||||||
if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
|
|
||||||
if [[ -z $upx_valgrind ]]; then
|
|
||||||
upx_valgrind="valgrind"
|
|
||||||
fi
|
|
||||||
if [[ -z $upx_valgrind_flags ]]; then
|
|
||||||
#upx_valgrind_flags="--leak-check=full --show-reachable=yes"
|
|
||||||
#upx_valgrind_flags="-q --leak-check=no --error-exitcode=1"
|
|
||||||
upx_valgrind_flags="--leak-check=no --error-exitcode=1"
|
|
||||||
fi
|
|
||||||
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
(cd / && cd $upx_BUILDDIR && lcov -d . --zerocounters)
|
|
||||||
fi
|
|
||||||
|
|
||||||
export UPX="--prefer-ucl --no-color --no-progress"
|
|
||||||
|
|
||||||
# let's go
|
|
||||||
if ! $upx_run --version; then echo "UPX-ERROR: FATAL: upx --version FAILED"; exit 1; fi
|
|
||||||
if ! $upx_run -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
|
||||||
if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
|
||||||
rm -rf ./testsuite_1
|
|
||||||
mkbuilddirs testsuite_1
|
|
||||||
cd testsuite_1 || 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.91*; do
|
|
||||||
testsuite_split_f $f
|
|
||||||
[[ -z $fb ]] && continue
|
|
||||||
echo "# $f"
|
|
||||||
mkdir -p $testdir/$fsubdir
|
|
||||||
$upx_run -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
|
|
||||||
$upx_run -qq --prefer-ucl -1 $f -o $testdir/$fsubdir/.packed/$fb
|
|
||||||
$upx_run -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
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // summary
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
# recreate checkums from current version for an easy update in case of changes
|
|
||||||
recreate_expected_sha256sums .sha256sums.recreate
|
|
||||||
|
|
||||||
testsuite_header "UPX testsuite summary"
|
|
||||||
if ! $upx_run --version; then
|
|
||||||
echo "UPX-ERROR: upx --version FAILED"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "upx_exe='$upx_exe'"
|
|
||||||
if [[ "$upx_run" != "$upx_exe" ]]; then
|
|
||||||
echo "upx_run='$upx_run'"
|
|
||||||
fi
|
|
||||||
if [[ -f "$upx_exe" ]]; then
|
|
||||||
ls -l "$upx_exe"
|
|
||||||
file "$upx_exe" || true
|
|
||||||
fi
|
|
||||||
echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'"
|
|
||||||
echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'"
|
|
||||||
echo ".sha256sums.{expected,current}:"
|
|
||||||
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
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
uqz4mAtKkF5Ex7Zt2tRP9mhQsAYn5+Xbupfuhee/s+2yVdBBdlXXRN2Q2AhMxF01
|
|
||||||
myhEuAtRNoQ4m7eyNgNU01pKb+dlyw2xiS+izm9+5fxuuEZfiuv76tQToQLltSdq
|
|
||||||
jP3Gt08MloJGcWraFiAXXji0S45MasJO3VOdygz09PbzIvGVp/NskGCMCU9lJlRt
|
|
||||||
2CsItWR+iHs6HNurWEKtEZz4qR8+HZ6RU5IquOnnHnI357lVUiC1w2qRcxmNVWuI
|
|
||||||
qS7GPvgisv0m4XMxe+l4L3b6a7laZr/hqHjFQqu/aO9Kmy5WmYRe3Bx4hTv5vqRi
|
|
||||||
OBDOUzwUcrdlUu2wqcvZhVxPaxxqA5u8G63Z3O30VCtWPZVU4yx9TRzcy/0lwxol
|
|
||||||
dw1b5t7Bl8uIzNyLsFMVS1MpnBspUrxBko6TqLAhv/DvUQmWGJRkP4Ar9naB4myS
|
|
||||||
vX6sim+Jn57Fr8aZMlvJbqlNindjxnX6+13u51C80GaYJBjHLkAIPaTTNLviOWpj
|
|
||||||
rbACDifaFloAsgJqz0KK/T7eohJBH2jVe2d9YxU6wZq6THDKJaeQ+nG5MWYvlkWa
|
|
||||||
K3N+jN8KI1GWqNpUtD8rbLPY1UZo05wQFZBCfdvEZoYdzJFVIS3t6kr0/gOIZu0D
|
|
||||||
AAIfIcopnpWpUk52MOEekzRRjJuF8fUMkiPX1oVs9HMKW+TU+yx/sFia+ke76w3i
|
|
||||||
1oiHKJJJNaoCjQXlAcT40rGLmSTLgL0ACCWIMGjK1QJYkpER8GCBCh9/whrJ3k1Q
|
|
||||||
0hm5hYiGty2ysRJFLIFPkYjangz7hIVzgOUSTYhVjJmIA62W2LmNKcixGX+sssCJ
|
|
||||||
/DK/Zs0uPiEX4gjkiomDksn7Dy8vAtHe7PzWpZA83mgPK+6zxoM6dgpM7FSe5q1/
|
|
||||||
tyf394l4nB7eayRUnx3NfK2/PTwrJcms5yAD9Hm2h72cp26TXh+RDVYWOgVX5/N0
|
|
||||||
dIsDRYo+/077pRTKwiCPrMxTxys53HHV7r5APd+FPmxikXvuszZvYTZ9K2MZB/1L
|
|
||||||
S2MCJ/u4GTTCwcbvfEjKVs3Fbqu7c2D/tVzakVEmMXloEAGPN/NrzOJsMMEDhWiw
|
|
||||||
g1wneAg5qF5nG+7R5WqstAeaRCYdXl46xay7iePZQ7viwHA8Zjuke18eHmh7J5jz
|
|
||||||
uzdh81rxCL3beoXb+BEr1/yKWfrJVTl33+m6c+zxdrV0B7O/ijlYxjke7Wo+ESac
|
|
||||||
WM2a4xU/WgXMi2+83XqcSZcRPdusZKA6bcTvAcYc/r8t7O1wjfPsTVj0WaM2DwL0
|
|
||||||
P1QTU4INmVn94zIV0+fGfyN0qI3YiS5iuOoPwLOVB13YECIyXnZz2/VJF7ZASOpS
|
|
||||||
701or4uF7GVEZxw19ow0AQttk6J/bEzbr7rZ5Um1yCMeQQ1TMHepJfuUbxle4W4S
|
|
||||||
8w8yC/Ytcy/e4rbiLG2/cY5b35LxtH1TCuaEtuiqa7vkmzr36qqD6fRWnXWC9QdR
|
|
||||||
0nWyJNj0xIIyMyilnBY2clAjDdT9qd2tMfpoz9hyBkTZPltzDw6Xd/IhhyL1URav
|
|
||||||
h0NCABGqXbpg8q7KCrIzIE6dJIh+7glfQuWkynmInntN4+fqk9Ked0haHkq5oGH5
|
|
||||||
vN5ZQNWPyQ67LaXQ4kW8iksgkgl7JEQsuie8oMuQZe13D4S3PWGFKchrBFGwN2xY
|
|
||||||
ut2+PCs5Al2BHU0qaCKdV7nCqv2tPC8G4uXNw081R2KwyoRlbKhowgFBYBTQIobJ
|
|
||||||
pc1GLU7HKm9tC61xIZ4u9oij/Bz1+gxx9vLxfx++EC/8UI23oMGygaYdda4gdEtm
|
|
||||||
v1wt8ldpzO4owI+9peFSolGLwKztwSPxln+5bvOsdsaZ6z5uW37N5ch/EwSwdmfo
|
|
||||||
Sm1i7fv/zQuZjmZkJXRJGvTd+sKdu7+IZUrTpu5W+jUfMAgmPc+AuYmSOn00K9dv
|
|
||||||
IJKY973ggNDaJKEw1uKzckl9uk/HRrgk+wgZPaWVRhOulj1npyFf+WmrZ2r3nTq0
|
|
||||||
koEI8UEselRuKJmojl4O0bz8fXZNgPtpLB/A0cdrj0Ist5TR+qRW9h3eSsybDYRS
|
|
||||||
GWP4UzFLAIwHflwNX0Q+9/u0uOxaXX6dKXzoddWksInBzh1pmQfrtUM3y7bHQYG5
|
|
||||||
zqnAMNMwm4WmtmF/mpjg0fKpiwFUU1geygkOwUsaK5Qcp5F0FPocdPRWVxUG0t3Y
|
|
||||||
QsmSpU5STb99YCs4TvhfUnQmdB2r+d0pZhlMte3v5lcpekSb2FxbUwdX3t9S2uGy
|
|
||||||
ho9CYmUj1+8ivUizjTLirOu/B8ohQT6kwvNqRSiQwU+YPa5DpxA1DYamIg6ehuX5
|
|
||||||
6u/dF4Eht+Cn6hasyzFviIUnV1y4ixLfSb0EGw+YoLbHgr8X4Uv4guaNQduKJyEu
|
|
||||||
g6p1v40fDhZ8AuQly+BOLL0yBlQoDrkY9+3HcIZAC5NmJFU5hle4Hz4gLzS6DwXo
|
|
||||||
2u8tqIELdtP9Zo4SKM7/yNy+rjl2RNRUEUNjidZsWuIC4bEeL3sUImP0Wt+zpdV0
|
|
||||||
y0RK1/wPW4dES5xFTCUp9xdP08dsSMtIrYJeBXbHrTZswnuOvk4MYGpmn/qy+qwc
|
|
||||||
GnkJtzJVm+uNspYuD0cW+JbJz5T+w1eNbejjZ+QVhqmE7ctSHndQUSueIyOcm79E
|
|
||||||
23jLzIoHMSHsiBJ8KeHN5bTfe66Gl8y3LIOpfchYd5XzkqxS7M01PxkWGZDWGYdl
|
|
||||||
6Gx64mg7ojPrSNaOzAu3da8oLvGi/YIf3wdJenZqiTzBnSzRsBnTpohQddHbB1Hj
|
|
||||||
uogDJSoad0ZSY0lLcvxncPB29hKpljFZ4IHO2UKOyO9+LFKsfK8/RbdSx/sHcUaH
|
|
||||||
hblVkVTSRReHmShxSw6abYZHivGNV0tXNXkY6uEzOMe+Vck9j9dTBSK0bFS/2Xdd
|
|
||||||
ZII/KFQH10+WEYyw+FurMUeVwU/FER4qpy+13r1PjxMSHfnJviEb8EjgvrcwAUDX
|
|
||||||
G9JNVtL4Vui6NMFV1u2qkbEMZK763YAIKYZC9UZYjbbhhgYTTMEfRcNvwVCix8nH
|
|
||||||
2TlWGhivuw5abE9QFduT1fHXJL+1uCn2GMhS8v3fxUrnGDQFit0YLlGEMm5/wVaM
|
|
||||||
PIZH5JDHlINUC0vbUrMXCz8Ztg3qhpOLiExlBHTD4vqYt9kniHLXOQfexegSC85C
|
|
||||||
AKiugEOdoHHYJGjNyXj6c0jTuMAe0CBwAKddUqPQztoKclNb02G2a9l5ColE29Uz
|
|
||||||
jXAb8PFANNqn4Nnm6oPPF1KxB45vLdT6+F1SRzXZunJ6p9N4E9KBtEOR+ixlcphL
|
|
||||||
InLJSg5iKTfWhXlSK6eldvVsP2GeoyjliERsKLgq1YGMiCW076dmoxR2Z5iPlD2V
|
|
||||||
G7Hz5nWjPBIoFhABEnONDxbrYB6ryeunILYcHpAaXSYq4OueRo6QGO8NRqFcNutG
|
|
||||||
WpwBfIlnu6rl9MDO053SJ1ah6D97n/D5aQa2JMMha0faZz84+MH3cnudAgpPjsG9
|
|
||||||
9G/2fEP08lQNAFiyY91wW3Mtj2No9+OJVYmwFORJm7IOu5nfuQZbzz9OFPcZLU5Y
|
|
||||||
DVo86icZgXayytW2XZtCKzVBDse+yi0xblGSNtwHlQIN8gKDVpa0I34DxUkIn1Cl
|
|
||||||
bk9S6+m6APF9ynN/kVCwMu9Nq3lwzmY6JCb/KX0d66uyVwYG3BN1UEWqJhDJjGep
|
|
||||||
a2JmHnG1aVhYaE/2EsOc+YP89Oub+KeuCj2dHJj2dH3QDCjr2xZUbLO7mw1tsATH
|
|
||||||
dPjNEBvxet9UU/RXqhhkfkv1XGr/umWrkjKbFqDNl5Tav/00+I59rboW7C/cWRxN
|
|
||||||
CVbadLPJlPNRR8+54G+VkDZgqaQprPwYih5a7d2MEzrMtZbU0uCJc839dqMgsf++
|
|
||||||
k4maampkcDLhxt8bBg43WoDgWxiQ+KVWyEBGmTOT2q4WYeLI9PZLseA9eNJbpt9J
|
|
||||||
oxtNNdqkU48YZWsq/3L1L0eXdGvv5TIMto4bH3SWuvQ2sepwMRxxwTg8qFrutk9K
|
|
||||||
OLOUbO1Z2ivh1g6+DAgs3RFmy9hPzzqPmJk8cL6F5tcd/VwGcow3UBJ1+Xn3SE5Y
|
|
||||||
UCHNrSfSrvDaA3N8jyvS/uPq0qRgp7LQRqrhh5cVPi67goDx/ku/fVbMbcrarO/e
|
|
||||||
Czv6CX7Id2QliOSMGGVId+ECXBvuIGAb2d4til+zTnfhBE2+uS5WQ7MjzH9PKZ7n
|
|
||||||
TDuV36mA1FDCX+WShPau7R0SGXSqKyeHJ8XSuFHbGwr1Zxwoq4GBYIcAxWjp9HA4
|
|
||||||
dhBE2x5WSTbnqh1sClxfOeE8MHxi+EUonCcvfvm30NOcC4zw1dCDc6SKLoMJYrFz
|
|
||||||
EdR3Kt1SJ9M0Jl3dD/gCTKG5kObJzqmo9BladIpQt6c=
|
|
||||||
@@ -0,0 +1,590 @@
|
|||||||
|
# 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
|
||||||
|
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
|
||||||
|
UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1
|
||||||
|
UPX_DEBUG_TEST_LIBC_QSORT: 1
|
||||||
|
# 2024-04-20
|
||||||
|
ZIG_DIST_VERSION: 0.12.0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job-rebuild-and-verify-stubs:
|
||||||
|
name: Rebuild stubs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: ubuntu:24.04 # glibc-2.39
|
||||||
|
#container: debian:12-slim # also works; glibc-2.36
|
||||||
|
#container: debian:testing-slim # also works
|
||||||
|
steps:
|
||||||
|
- name: Install packages
|
||||||
|
run: |
|
||||||
|
uname -a; pwd; id; umask
|
||||||
|
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 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
|
||||||
|
- 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 -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="$PWD/../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
|
||||||
|
|
||||||
|
job-linux-cmake: # uses cmake + make
|
||||||
|
if: true
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('{0}', matrix.os) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { os: ubuntu-22.04, use_extra: true, use_wine: true }
|
||||||
|
- { os: ubuntu-20.04, use_extra: true }
|
||||||
|
steps:
|
||||||
|
- 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: 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 }}
|
||||||
|
- 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"
|
||||||
|
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||||
|
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
|
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: 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
|
||||||
|
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.sh' ::: $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 test suite
|
||||||
|
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 test suite 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 ]
|
||||||
|
name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# NOTE: macos does not have "env -C"; only with brew coreutils
|
||||||
|
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils
|
||||||
|
- { os: macos-11, gcc: gcc-10, gxx: g++-10, testsuite: true }
|
||||||
|
- { os: macos-12, gcc: gcc-11, gxx: g++-11, testsuite: true }
|
||||||
|
- { os: macos-13, testsuite: true } # use default Xcode-15; NOTE: gcc-12 on macos-13 does not work with Xcode-15
|
||||||
|
- { os: macos-13, gcc: gcc-12, gxx: g++-12, testsuite: true, xcode_version: 14.3.1 }
|
||||||
|
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true } # gcc-13: INTERNAL ERROR in ld64
|
||||||
|
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true, xcode_version: 14.3.1 } # gcc-13: MISSING HEADER FILES
|
||||||
|
- { os: macos-14, gcc: gcc-12, gxx: g++-12, testsuite: true } # => use gcc-12 for now
|
||||||
|
steps:
|
||||||
|
- 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="ninja parallel"
|
||||||
|
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 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-13 | macos-14) 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: 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"
|
||||||
|
- name: Make artifact
|
||||||
|
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"
|
||||||
|
(cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/")
|
||||||
|
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
|
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 test suite
|
||||||
|
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 ]
|
||||||
|
name: ${{ format('{0}', matrix.name) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
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 }
|
||||||
|
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 }}' }
|
||||||
|
- 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.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
|
mkdir -p "tmp/artifact/$N"
|
||||||
|
(cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N")
|
||||||
|
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: 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 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 ]
|
||||||
|
name: ${{ format('windows {0}', matrix.name) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
C: ${{ matrix.name }}
|
||||||
|
B: release
|
||||||
|
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 }
|
||||||
|
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
|
||||||
|
%RUN_CL% -J -O2 -W3 -WX %DEFS% -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"
|
||||||
|
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: 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 ]
|
||||||
|
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: alpine:3.19
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# only build a few 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-none }
|
||||||
|
- { zig_target: aarch64-macos.11.0-none }
|
||||||
|
# { zig_target: aarch64-macos.12.0-none }
|
||||||
|
# { zig_target: aarch64-macos.13.0-none }
|
||||||
|
- { zig_target: aarch64-windows-gnu }
|
||||||
|
- { zig_target: arm-linux-musleabihf, qemu: qemu-arm }
|
||||||
|
# { zig_target: arm-linux-musleabihf, qemu: qemu-arm, zig_pic: -fPIE }
|
||||||
|
- { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 }
|
||||||
|
- { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 }
|
||||||
|
# { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386, zig_pic: -fPIE }
|
||||||
|
- { zig_target: i386-windows-gnu }
|
||||||
|
# mips and mipsel: bad hard-float code generation(??); or QEMU bug; or UPX bug; see https://github.com/upx/upx/issues/788
|
||||||
|
- { zig_target: mips-linux-musl, zig_flags: -msoft-float, qemu: qemu-mips }
|
||||||
|
- { zig_target: mipsel-linux-musl, zig_flags: -msoft-float, qemu: qemu-mipsel }
|
||||||
|
- { zig_target: powerpc-linux-musl, qemu: qemu-ppc }
|
||||||
|
# powerpc64: obscure problem with C++ exceptions in UPX doctest checks; use -fPIC to work-around
|
||||||
|
- { zig_target: powerpc64-linux-musl, zig_flags: -fPIC, qemu: qemu-ppc64 }
|
||||||
|
- { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le }
|
||||||
|
- { zig_target: x86_64-linux-gnu.2.3.4, qemu: qemu-x86_64 } # can use QEMU because of gcompat
|
||||||
|
- { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 }
|
||||||
|
# { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE }
|
||||||
|
# { zig_target: x86_64-macos-none }
|
||||||
|
- { zig_target: x86_64-macos.11.0-none }
|
||||||
|
# { zig_target: x86_64-macos.12.0-none }
|
||||||
|
# { zig_target: x86_64-macos.13.0-none }
|
||||||
|
- { zig_target: x86_64-windows-gnu }
|
||||||
|
env:
|
||||||
|
# zig is currently missing winpthreads; see https://github.com/ziglang/zig/issues/10989
|
||||||
|
UPX_CONFIG_EXPECT_THREADS: ${{ contains(matrix.zig_target, '-windows-') && 'OFF' || 'ON' }}
|
||||||
|
# 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:
|
||||||
|
- name: Install Alpine Linux container packages
|
||||||
|
if: ${{ job.container }}
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
apk update && apk upgrade && apk add bash cmake curl file git make parallel tar xz
|
||||||
|
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
|
||||||
|
# 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
|
||||||
|
- 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 }}" == x86_64-linux-gnu.2.3.4 ]]; then
|
||||||
|
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
|
||||||
|
# update ZIG_TARGET (i386 => x86)
|
||||||
|
ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
|
||||||
|
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
|
||||||
|
# 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}
|
||||||
|
curl -sS -L -O https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz
|
||||||
|
ls -l ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
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
|
||||||
|
# create wrapper scripts (needed for CMake)
|
||||||
|
echo -e '#!/bin/sh\nexec zig ar "$@"' > zig-ar
|
||||||
|
echo -e '#!/bin/sh\nexec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
|
||||||
|
echo -e '#!/bin/sh\nexec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
|
||||||
|
echo -e '#!/bin/sh\nexec 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
|
||||||
|
- 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"
|
||||||
|
file build/zig/${ZIG_TARGET}${ZIG_PIC}/release/upx*
|
||||||
|
- 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"
|
||||||
|
file build/zig/${ZIG_TARGET}${ZIG_PIC}/debug/upx*
|
||||||
|
- 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"
|
||||||
|
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||||
|
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
|
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' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
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' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
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' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
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 test suite
|
||||||
|
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
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 }}
|
||||||
+27
-30
@@ -1,58 +1,55 @@
|
|||||||
/.bzr*
|
|
||||||
/.hg*
|
/.hg*
|
||||||
/Makevars.global*
|
/.vscode*
|
||||||
|
/Makevars[.-]global*
|
||||||
|
/Testing*
|
||||||
/build*
|
/build*
|
||||||
/maint*
|
/maint*
|
||||||
|
/vendor*
|
||||||
|
|
||||||
.depend
|
GNUmakefile*
|
||||||
GNUmakefile
|
MMakefile*
|
||||||
MMakefile
|
Makevars[.-]local*
|
||||||
Makevars.local*
|
compile_flags*.txt
|
||||||
tmp-testsuite*
|
Tmp*
|
||||||
|
tmp*
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
|
*.bz2
|
||||||
|
*.d
|
||||||
|
*.diff
|
||||||
*.dll
|
*.dll
|
||||||
|
*.dylib
|
||||||
|
*.exe
|
||||||
|
*.gz
|
||||||
*.lib
|
*.lib
|
||||||
|
*.map
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.out
|
||||||
|
*.patch
|
||||||
*.py[cdo]
|
*.py[cdo]
|
||||||
|
*.rar
|
||||||
*.so
|
*.so
|
||||||
*.swp
|
*.swp
|
||||||
|
*.tmp
|
||||||
|
*.ttp
|
||||||
|
*.xz
|
||||||
|
*.zip
|
||||||
|
*.zst
|
||||||
|
|
||||||
doc/*.1
|
|
||||||
doc/*.doc
|
|
||||||
doc/*.html
|
|
||||||
doc/*.man
|
doc/*.man
|
||||||
doc/*.ps
|
doc/*.ps
|
||||||
doc/*.tex
|
doc/*.tex
|
||||||
|
|
||||||
src/compress_nrv*
|
|
||||||
src/*.mft
|
|
||||||
src/*.rc
|
|
||||||
|
|
||||||
src/*.d
|
|
||||||
src/*.exe
|
|
||||||
src/*.map
|
|
||||||
src/*.o
|
|
||||||
src/*.obj
|
|
||||||
src/*.out
|
|
||||||
src/*.res
|
|
||||||
src/*.ttp
|
|
||||||
|
|
||||||
src/stub/**/.*-stamp
|
src/stub/**/.*-stamp
|
||||||
src/stub/**/MMakefile
|
|
||||||
src/stub/tmp*/*.bin
|
src/stub/tmp*/*.bin
|
||||||
src/stub/tmp*/*.bin.bindump
|
src/stub/tmp*/*.bin.bindump
|
||||||
src/stub/tmp*/*.bin.disasm
|
src/stub/tmp*/*.bin.disasm
|
||||||
src/stub/tmp*/*.d
|
|
||||||
src/stub/tmp*/*.map
|
|
||||||
src/stub/tmp*/*.o
|
|
||||||
src/stub/tmp*/*.o.disasm
|
src/stub/tmp*/*.o.disasm
|
||||||
src/stub/tmp*/mips.r3000-*.[is]
|
src/stub/tmp*/mips.r3000-*.[is]
|
||||||
src/stub/tmp*/mipsel.r3000-*.[is]
|
src/stub/tmp*/mipsel.r3000-*.[is]
|
||||||
src/stub/src/**/tmp*/*
|
src/stub/src/**/tmp*/*
|
||||||
|
|
||||||
src/stub/tools/armpe/armpe_tester.exe
|
|
||||||
src/stub/tools/armpe/armpe_tester.out
|
|
||||||
|
|
||||||
src/stub/tools/sstrip/amd64-linux-sstrip
|
src/stub/tools/sstrip/amd64-linux-sstrip
|
||||||
src/stub/tools/sstrip/i386-linux-sstrip
|
src/stub/tools/sstrip/i386-linux-sstrip
|
||||||
src/stub/tools/sstrip/sstrip
|
src/stub/tools/sstrip/sstrip
|
||||||
|
|||||||
-295
@@ -1,295 +0,0 @@
|
|||||||
# Support for GibLab CI -- https://gitlab.com/
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- export TRAVIS_OS_NAME=linux
|
|
||||||
- unset CROSS C B T X
|
|
||||||
- uname -a; pwd; id; umask
|
|
||||||
- cat /etc/os-release || true
|
|
||||||
- |
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^(CentOS|Fedora|OpenSUSE) ]]; then
|
|
||||||
time rpm -qa | LC_ALL=C sort
|
|
||||||
fi
|
|
||||||
- |
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^(Debian|Ubuntu) ]]; then
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
time dpkg -l
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^Ubuntu1604- ]]; then
|
|
||||||
dpkg --add-architecture i386
|
|
||||||
fi;
|
|
||||||
time apt-get -yq update
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^CentOS5- ]]; then
|
|
||||||
time rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm;
|
|
||||||
time yum install -y
|
|
||||||
coreutils curl diffutils grep gzip sed
|
|
||||||
bzip2 file findutils git openssh-clients openssl perl tar wget which xz
|
|
||||||
gcc gcc-c++ make valgrind
|
|
||||||
glibc-devel libstdc++-devel zlib-devel
|
|
||||||
glibc-devel.i386 libstdc++-devel.i386 zlib-devel.i386;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^CentOS6- ]]; then
|
|
||||||
time yum install -y
|
|
||||||
coreutils curl diffutils grep gzip sed
|
|
||||||
bzip2 file findutils git openssh-clients openssl perl tar wget which xz
|
|
||||||
gcc gcc-c++ make valgrind
|
|
||||||
glibc-devel libstdc++-devel zlib-devel
|
|
||||||
glibc-devel.i686 libstdc++-devel.i686 zlib-devel.i686;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^CentOS7- ]]; then
|
|
||||||
time yum install -y
|
|
||||||
coreutils curl diffutils grep gzip sed
|
|
||||||
bzip2 file findutils git openssh-clients openssl perl tar wget which xz
|
|
||||||
clang gcc gcc-c++ make valgrind
|
|
||||||
glibc-devel libasan libstdc++-devel zlib-devel
|
|
||||||
glibc-devel.i686 libasan.i686 libstdc++-devel.i686 zlib-devel.i686;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^Fedora ]]; then
|
|
||||||
time dnf install -y --best --allowerasing
|
|
||||||
coreutils curl diffutils grep gzip sed
|
|
||||||
bzip2 file findutils git openssh-clients openssl perl tar wget which xz
|
|
||||||
clang gcc gcc-c++ lcov make valgrind
|
|
||||||
glibc-devel libasan libstdc++-devel libubsan zlib-devel
|
|
||||||
glibc-devel.i686 libasan.i686 libstdc++-devel.i686 libubsan.i686 zlib-devel.i686;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^OpenSUSE42.2- ]]; then
|
|
||||||
time zypper update -y;
|
|
||||||
time zypper install -y
|
|
||||||
coreutils curl diffutils grep gzip sed
|
|
||||||
bzip2 file findutils git openssh openssl perl tar wget which xz
|
|
||||||
llvm-clang gcc gcc-32bit gcc-c++ gcc-c++-32bit lcov make valgrind
|
|
||||||
glibc-devel libstdc++-devel libz1 zlib-devel
|
|
||||||
glibc-devel-32bit libstdc++-devel-32bit libz1-32bit zlib-devel-32bit;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^(Debian|Ubuntu) ]]; then
|
|
||||||
time apt-get -yq --no-install-suggests --no-install-recommends --force-yes upgrade;
|
|
||||||
time apt-get -yq --no-install-suggests --no-install-recommends --force-yes install
|
|
||||||
build-essential ca-certificates curl file git openssh-client openssl wget xz-utils zlib1g-dev;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^Ubuntu1604- ]]; then
|
|
||||||
time apt-get -yq --no-install-suggests --no-install-recommends --force-yes install
|
|
||||||
g++-multilib
|
|
||||||
libstdc++-5-dev:i386 zlib1g-dev:i386
|
|
||||||
libx32stdc++-5-dev libx32z1-dev;
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^Ubuntu1604-cross ]]; then
|
|
||||||
time apt-get -yq --no-install-suggests --no-install-recommends --force-yes install
|
|
||||||
crossbuild-essential-arm64 crossbuild-essential-armel crossbuild-essential-armhf
|
|
||||||
crossbuild-essential-powerpc crossbuild-essential-ppc64el crossbuild-essential-s390x
|
|
||||||
binutils-mingw-w64-i686 g++-mingw-w64-i686
|
|
||||||
binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64
|
|
||||||
binutils-mips-linux-gnu g++-mips-linux-gnu
|
|
||||||
binutils-mipsel-linux-gnu g++-mipsel-linux-gnu
|
|
||||||
binutils-powerpc-linux-gnu g++-powerpc-linux-gnu
|
|
||||||
binutils-powerpc64-linux-gnu g++-powerpc64-linux-gnu
|
|
||||||
qemu-user qemu-utils wine;
|
|
||||||
fi
|
|
||||||
- git --version && bash --version
|
|
||||||
- umask 022; mkdir -p ../deps ../build/gitlab
|
|
||||||
- time git submodule update --init --recursive
|
|
||||||
- cd ../deps && time wget -q -O - https://github.com/upx/upx/releases/download/v3.00/ucl-1.03.tar.xz | tar -x --use-compress-program=xz
|
|
||||||
- cd ../deps && time wget -q -O - https://github.com/upx/upx/releases/download/v3.00/zlib-1.2.8.tar.xz | tar -x --use-compress-program=xz
|
|
||||||
- cd ../deps && time git clone https://github.com/upx/upx-testsuite
|
|
||||||
- |
|
|
||||||
if [[ $CI_BUILD_NAME =~ ^Fedora ]]; then
|
|
||||||
time dnf install -y --best --allowerasing python
|
|
||||||
cd ../deps && time wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20160918/bin-upx-20160918.tar.xz | tar -x --use-compress-program=xz
|
|
||||||
fi
|
|
||||||
- cd $CI_PROJECT_DIR; pwd
|
|
||||||
|
|
||||||
CentOS5-gcc-m32+m64: # gcc-4.1
|
|
||||||
image: centos:5
|
|
||||||
script:
|
|
||||||
# patch src/Makefile for gcc-4.1
|
|
||||||
- perl -i -p -e 's/ -Wmissing-declarations / /; s/ -Wvla / /;' src/Makefile
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
CentOS6-gcc-m32+m64: # gcc-4.4
|
|
||||||
image: centos:6
|
|
||||||
script:
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
CentOS7-clang+gcc-m32+m64: # clang-3.4, gcc-4.8
|
|
||||||
image: centos:7
|
|
||||||
script:
|
|
||||||
- time C=clang-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Debian7-gcc-m64: # gcc-4.7
|
|
||||||
image: debian:7
|
|
||||||
script:
|
|
||||||
- time C=gcc-4.7-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.7-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Debian8-gcc-m64: # gcc-4.9
|
|
||||||
image: debian:8
|
|
||||||
script:
|
|
||||||
- time C=gcc-4.9-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.9-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-4.9-m64 bash ./.github/travis_deploy.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Fedora23-clang+gcc-m32+m64: # clang-3.7, gcc-5
|
|
||||||
image: fedora:23
|
|
||||||
script:
|
|
||||||
- time X=rebuild-stubs bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 T=valgrind bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Fedora24-clang+gcc-m32+m64: # clang-3.8, gcc-6
|
|
||||||
image: fedora:24
|
|
||||||
script:
|
|
||||||
- time X=rebuild-stubs bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 T=valgrind bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Fedora25-clang+gcc-m32+m64: # clang-3.8, gcc-6
|
|
||||||
image: fedora:25
|
|
||||||
script:
|
|
||||||
- time X=rebuild-stubs bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 B=sanitize bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-m64 T=valgrind bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
OpenSUSE42.2-clang+gcc-m32+m64: # clang-3.8, gcc-4.8
|
|
||||||
image: opensuse:42.2
|
|
||||||
script:
|
|
||||||
- time C=clang-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.8-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.8-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=clang-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-4.8-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-4.8-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Ubuntu1204-gcc-m64: # gcc-4.6
|
|
||||||
image: ubuntu:12.04
|
|
||||||
script:
|
|
||||||
- time C=gcc-4.6-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.6-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Ubuntu1404-gcc-m64: # gcc-4.8
|
|
||||||
image: ubuntu:14.04
|
|
||||||
script:
|
|
||||||
- time C=gcc-4.8-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-4.8-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-4.8-m64 bash ./.github/travis_deploy.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Ubuntu1604-gcc-m32+m64: # gcc-5
|
|
||||||
image: ubuntu:16.04
|
|
||||||
script:
|
|
||||||
- time C=gcc-5-m32 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-5-m64 bash ./.github/travis_build.sh
|
|
||||||
- time C=gcc-5-m32 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-5-m64 bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time C=gcc-5-m32 bash ./.github/travis_deploy.sh
|
|
||||||
- time C=gcc-5-m64 bash ./.github/travis_deploy.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
Ubuntu1604-cross: # gcc-5
|
|
||||||
image: ubuntu:16.04
|
|
||||||
script:
|
|
||||||
- time CROSS=aarch64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=arm-linux-gnueabi C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=arm-linux-gnueabihf C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=i686-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=mips-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=mipsel-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=powerpc-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=powerpc64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=powerpc64le-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=s390x-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=x86_64-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_build.sh
|
|
||||||
- time CROSS=aarch64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time CROSS=arm-linux-gnueabi C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time CROSS=arm-linux-gnueabihf C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=i686-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=mips-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time CROSS=mipsel-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=powerpc-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=powerpc64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=powerpc64le-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=s390x-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_testsuite_1.sh
|
|
||||||
# - time CROSS=x86_64-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_testsuite_1.sh
|
|
||||||
- time CROSS=aarch64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=arm-linux-gnueabi C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=arm-linux-gnueabihf C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=i686-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=mips-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=mipsel-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=powerpc-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=powerpc64-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=powerpc64le-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=s390x-linux-gnu C=gcc-5 T=qemu bash ./.github/travis_deploy.sh
|
|
||||||
- time CROSS=x86_64-w64-mingw32 C=gcc-5 T=wine bash ./.github/travis_deploy.sh
|
|
||||||
tags: [ shared ]
|
|
||||||
except: [ tags ]
|
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
|
||||||
+25
-4
@@ -1,4 +1,25 @@
|
|||||||
[submodule "src/lzma-sdk"]
|
[submodule "vendor/doctest"]
|
||||||
path = src/lzma-sdk
|
path = vendor/doctest
|
||||||
url = https://github.com/upx/upx-lzma-sdk.git
|
url = https://github.com/upx/upx-vendor-doctest.git
|
||||||
branch = master
|
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
|
||||||
|
|||||||
-258
@@ -1,258 +0,0 @@
|
|||||||
# Support for Travis CI -- https://travis-ci.org/upx/upx/builds
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
language: cpp
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
on_failure: change
|
|
||||||
|
|
||||||
.ubuntu_toolchain_sources: &S
|
|
||||||
- ubuntu-toolchain-r-test
|
|
||||||
- llvm-toolchain-precise-3.5
|
|
||||||
- llvm-toolchain-precise-3.6
|
|
||||||
- llvm-toolchain-precise-3.7
|
|
||||||
- llvm-toolchain-precise-3.8
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- CROSS= C= B= T= X=
|
|
||||||
- secure: "YXHLXK+CM5d8yELIUSSs+P0/CoefClO7/AUX1oBj5W75g+YzR5uS2doVsB8UH8S8/GdNxk4P9Jgn4EiEVnjfGgn2eAD9MVpDPIxyJs5vI+5G77asq3QNdSl6QFv3O9I/6yBoVCewgPFPqsMd7Yvs/Ea3LcQkqalVhrC8ybYtmfs6VL2w33gn2J3b3TCn/s21L0ijklM0xvP1GNMDtuUpTSish5wvGOHE/91rwtdUDbJR8u31QY7fTASDiNnL/7ihgEIZ5XxpDYXviX1GC+nemhX1fWpmVmuT8m30Ruodi0yJVGASw9i2SaKv/VX/fJ/w2vlCfspL5LMZKkVLlfpIo3mQGqmMHFxv7mNy+hRu50ptoWNSkWArcqifwveh2liHUpl4jTvWaVll5Tw5VUGJhAUdzCTnqLIbWFnKIgCedL3iRFi4+EbyWNxel8lFESMOTDZFfJG5yEiDJbgbLsUaT2GmrsOphwAG7zDcZzvYTdjg/lF4Wh0MUnQJ+0MhDpii8Ahjp49lAPdw8uRQyyY7d7ksYKXVIkbgl6dRCC5vZSPucJiFjq2BClqIoEmzZPvHveDbovzFkNhJX9tFLrHLcXbPPcegww1FGoQ3wBM6JwJ+TvSD6N4OdCmou05aDuuQeznHi3GxOScjGwxdMIU28fdJDCTDg2rOihm22kHVajo="
|
|
||||||
- secure: "JpSv3+QRmHcfN/bmT3mVkqET44NCPhM/qpcUssCVXnd2GW0qWURoyPHzVMn/gbeAkUjR6djtN3OzJ+M181QmlmTmE26pZC9Q6r1buNDWdkIH1FcpMCa67BBAjmq+yDwulDtvCMv0lbz60v57lzHBOLczF3yMxBVTjXxt1RsrzDLHzzVaDR5lEe+sQUNeRL7Vaq8crimPNTr4ZhMe59eweTO/3AWovuSPf250k1flfv7I8audZgrVZdbVKvj5C3Sziy1AGXcu8mDfET9/Ya2XBCQHWODjiKlnhSxqthhP3gQuacaLjpS2FjvQlamd+I9x6BBoLSeNbiXD9vgCydDUKvmUrU+zQs64U1hHk9WZWVC19kG7lTtTdanGDIUlIUtFZgqE4AQpJaIUWkUmHGyHi61JMvduzX21eL5c5j9DoJteX42FPb1n3xK/JSnUkLMpbFdQuy5inhzefhDfeNzaYxt8nPwHnJqrF73SW4PLDKeRyzvg/P+zqcou8nXrHfA1z9/FlnYzf7Qc9meai9Q/JARX3Q1ZKu5uyG+RuBLe2POq0192w6pflTr1ZlLJsKNSc1147PviKfmpla1lg3/6uVzMp5tgwbve/hx9SDXiRueGttKw/ymsY662+8G24NRKo4fxNklWFHaB4owM84edDzXDckPXbPgue8/HQT8BFio="
|
|
||||||
matrix:
|
|
||||||
- TRAVIS_EMPTY_JOB_WORKAROUND=true
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
exclude:
|
|
||||||
- env: TRAVIS_EMPTY_JOB_WORKAROUND=true
|
|
||||||
include:
|
|
||||||
- os: linux
|
|
||||||
sudo: required
|
|
||||||
dist: trusty
|
|
||||||
compiler: gcc
|
|
||||||
env: X=rebuild-stubs
|
|
||||||
addons: { apt: { packages: [ "g++-multilib", "lib32z1" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.4-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.4-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.4-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.4" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.5-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.5-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.5-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.5" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.6-m32
|
|
||||||
addons: { apt: { packages: [ "g++-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.6-m64
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.7-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.7-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.7-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.7" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.8-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.8-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.8-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.8" ] } }
|
|
||||||
# - os: linux
|
|
||||||
# sudo: required
|
|
||||||
# dist: trusty
|
|
||||||
# compiler: gcc
|
|
||||||
# env: C=gcc-4.8-mx32
|
|
||||||
# addons: { apt: { packages: [ "g++-multilib", "libx32stdc++-4.8-dev", "libx32z1-dev" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.9-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.9-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-4.9-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-4.9" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-5-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-5-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-5-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-5" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m32 B=debug
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m64 B=debug
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m64 B=debug+sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m64 B=sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: C=gcc-6-m64 B=valgrind T=valgrind
|
|
||||||
addons: { apt: { sources: *S, packages: [ "g++-6", valgrind ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.4-m32
|
|
||||||
addons: { apt: { packages: [ "g++-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.4-m64
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.5-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.5", "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.5-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.5" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.6-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.6", "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.6-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.6" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.7-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.7", "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.7-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.7" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8", "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m64 B=debug+sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m64 B=sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m64 B=debug+scan-build
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.8-m64 B=scan-build
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.8" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: CROSS=arm-linux-gnueabi C=gcc-4.6 T=SKIP
|
|
||||||
addons: { apt: { packages: [ "g++-arm-linux-gnueabi", "qemu-user" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: CROSS=arm-linux-gnueabihf C=gcc-4.6 T=SKIP
|
|
||||||
addons: { apt: { packages: [ "g++-arm-linux-gnueabihf", "qemu-user" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: CROSS=i386-w64-mingw32 C=gcc-4.6 T=wine
|
|
||||||
addons: { apt: { packages: [ "binutils-mingw-w64-i686", "g++-mingw-w64-i686", "wine" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: CROSS=x86_64-w64-mingw32 C=gcc-4.6 T=wine
|
|
||||||
addons: { apt: { packages: [ "binutils-mingw-w64-x86-64", "g++-mingw-w64-x86-64", "wine" ] } }
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode6.4
|
|
||||||
compiler: clang
|
|
||||||
# must use debug build or else we get "ld: internal error: atom not found" when linking
|
|
||||||
env: C=clang-602-m32 B=debug
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode6.4
|
|
||||||
compiler: clang
|
|
||||||
# must use debug build or else we get "ld: internal error: atom not found" when linking
|
|
||||||
env: C=clang-602-m64 B=debug
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode7.3
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-703-m32
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode7.3
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-703-m64
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode8.2
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-800-m32
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode8.2
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-800-m64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- uname -a; pwd; id; umask
|
|
||||||
- cat /etc/os-release || true
|
|
||||||
- |
|
|
||||||
cd /
|
|
||||||
if [[ $TRAVIS_OS_NAME == linux ]]; then
|
|
||||||
if [[ $B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
travis_retry pip install --user cpp-coveralls
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
if ! gsha256sum </bin/sh >/dev/null 2>/dev/null; then travis_retry brew install coreutils; fi
|
|
||||||
if [[ $B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
travis_retry brew install lcov
|
|
||||||
travis_retry pip install --user cpp-coveralls
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
- git --version && bash --version
|
|
||||||
- umask 022; cd $TRAVIS_BUILD_DIR && mkdir -p ../deps ../build/travis
|
|
||||||
- cd ../deps && travis_retry wget -q -O - https://github.com/upx/upx/releases/download/v3.00/ucl-1.03.tar.xz | tar -xJ
|
|
||||||
- cd ../deps && travis_retry wget -q -O - https://github.com/upx/upx/releases/download/v3.00/zlib-1.2.8.tar.xz | tar -xJ
|
|
||||||
- cd ../deps && travis_retry git clone https://github.com/upx/upx-testsuite
|
|
||||||
- |
|
|
||||||
if [[ $X =~ (^|\+)rebuild-stubs($|\+) ]]; then
|
|
||||||
cd ../deps && travis_retry wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20160918/bin-upx-20160918.tar.xz | tar -xJ
|
|
||||||
fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cd $TRAVIS_BUILD_DIR && bash ./.github/travis_build.sh
|
|
||||||
- cd $TRAVIS_BUILD_DIR && bash ./.github/travis_testsuite_1.sh
|
|
||||||
after_success:
|
|
||||||
- cd $TRAVIS_BUILD_DIR && bash ./.github/travis_deploy.sh
|
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
|
||||||
+520
@@ -0,0 +1,520 @@
|
|||||||
|
#
|
||||||
|
# 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)
|
||||||
|
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")
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# 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 info: strict 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 "4.2.4") # 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
|
||||||
|
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_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()
|
||||||
|
|
||||||
|
# set MSVC_FRONTEND, GNU_FRONTEND and MINGW
|
||||||
|
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)"))
|
||||||
|
set(GNU_FRONTEND 1)
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW")
|
||||||
|
set(MINGW 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# common compilation flags
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
include(CheckStructHasMember)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
|
upx_cmake_include_hook(3_common_compilation_flags)
|
||||||
|
|
||||||
|
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(-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 5
|
||||||
|
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 5
|
||||||
|
|
||||||
|
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
|
||||||
|
#message(STATUS "Threads FAILED ${f}: ${output}") # debug output from try_compile
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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()
|
||||||
|
if(CMAKE_INSTALL_PREFIX)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
endif()
|
||||||
|
# install files
|
||||||
|
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||||
|
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||||
|
install(FILES
|
||||||
|
COPYING LICENSE NEWS README doc/THANKS.txt doc/upx-doc.html doc/upx-doc.txt
|
||||||
|
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
|
||||||
|
)
|
||||||
|
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_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)
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/print_info.cmake")
|
||||||
|
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_mismatch(CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_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)
|
||||||
|
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,36 +1,88 @@
|
|||||||
#
|
#
|
||||||
# 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
|
||||||
# Copyright (C) 1996-2017 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 -j # 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/.upx_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:
|
.SUFFIXES:
|
||||||
export SHELL = /bin/sh
|
|
||||||
|
|
||||||
srcdir = .
|
# shortcuts (all => debug + release)
|
||||||
top_srcdir = .
|
debug: build/debug PHONY
|
||||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
release: build/release PHONY
|
||||||
|
all build/all: build/debug build/release PHONY
|
||||||
|
build/%/all: $$(dir $$@)debug $$(dir $$@)release PHONY ;
|
||||||
|
|
||||||
# info: src/stub needs special build tools from https://github.com/upx/upx-stubtools
|
#***********************************************************************
|
||||||
BUILD_STUB = 0
|
# test
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/upx-stubtools-check-version),)
|
#***********************************************************************
|
||||||
BUILD_STUB = 1
|
|
||||||
endif
|
|
||||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/upx-stubtools-check-version),)
|
|
||||||
BUILD_STUB = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
default:
|
CTEST = ctest
|
||||||
@echo "UPX info: please choose a target for 'make'"
|
CTEST_JOBS ?= 8
|
||||||
|
CTEST_FLAGS = --output-on-failure --parallel $(CTEST_JOBS)
|
||||||
|
|
||||||
all mostlyclean clean distclean maintainer-clean:
|
build/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||||
ifeq ($(BUILD_STUB),1)
|
build/%/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||||
$(MAKE) -C src/stub $@
|
build/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
|
||||||
endif
|
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
|
||||||
|
|
||||||
|
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||||
|
|
||||||
|
#
|
||||||
|
# END of Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
# extra pre-defined build configurations and some utility; optional
|
||||||
|
include ./misc/make/Makefile-extra.mk
|
||||||
|
|
||||||
|
# developer convenience
|
||||||
|
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
|
||||||
|
ifneq ($(wildcard ./misc/scripts/.),)
|
||||||
|
check-whitespace clang-format run-testsuite run-testsuite-all run-testsuite-debug run-testsuite-release: src/Makefile PHONY
|
||||||
$(MAKE) -C src $@
|
$(MAKE) -C src $@
|
||||||
$(MAKE) -C doc $@
|
endif
|
||||||
|
endif
|
||||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
|
||||||
|
|
||||||
# vim:set ts=8 sw=8 noet:
|
|
||||||
|
|||||||
@@ -2,12 +2,75 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
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):
|
Changes in 3.93 (29 Jan 2017):
|
||||||
* UPX has moved to GitHub - the new home page is https://upx.github.io
|
* Fixed some win32/pe and win64/pe regressions introduced in 3.92
|
||||||
* 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):
|
Changes in 3.92 (11 Dec 2016):
|
||||||
* UPX has moved to GitHub - the new home page is https://upx.github.io
|
* 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
|
* IMPORTANT: all PE formats: internal changes: reunited the diverged source
|
||||||
files - please report all regressions into the bug tracker and try UPX 3.91
|
files - please report all regressions into the bug tracker and try UPX 3.91
|
||||||
in case of problems.
|
in case of problems.
|
||||||
@@ -19,7 +82,7 @@ Changes in 3.92 (11 Dec 2016):
|
|||||||
by Codenomicon to NCSC-FI on 2015-01-08.
|
by Codenomicon to NCSC-FI on 2015-01-08.
|
||||||
The vulnerabilities were discovered by Joonas Kuorilehto and
|
The vulnerabilities were discovered by Joonas Kuorilehto and
|
||||||
Antti Häyrynen from Codenomicon.
|
Antti Häyrynen from Codenomicon.
|
||||||
* bug fixes
|
* bug fixes - see https://github.com/upx/upx/milestone/1
|
||||||
|
|
||||||
Changes in 3.91 (30 Sep 2013):
|
Changes in 3.91 (30 Sep 2013):
|
||||||
* Added experimental support for Windows 64-bit PE files, based on
|
* Added experimental support for Windows 64-bit PE files, based on
|
||||||
@@ -40,7 +103,7 @@ Changes in 3.08 (12 Dec 2011):
|
|||||||
* Compress shared library on ELF i386 only [ld.so threatens even this case].
|
* 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).
|
* Attempt to support ELF on QNX 6.3.0 for armel (experimental).
|
||||||
* Better diagnostic when ELF -fPIC is needed.
|
* Better diagnostic when ELF -fPIC is needed.
|
||||||
* PT_NOTE improvements for *BSD.
|
* PT_NOTE improvements for BSD.
|
||||||
* Preserve more ELF .e_flags on ARM.
|
* Preserve more ELF .e_flags on ARM.
|
||||||
* Minor code improvements for ELF stubs.
|
* Minor code improvements for ELF stubs.
|
||||||
* Defend against another flavor of corrupt PE header.
|
* Defend against another flavor of corrupt PE header.
|
||||||
@@ -103,7 +166,7 @@ Changes in 2.93 beta (08 Mar 2007):
|
|||||||
you have to explicitly use '--lzma' even for '--ultra-brute' here
|
you have to explicitly use '--lzma' even for '--ultra-brute' here
|
||||||
because runtime decompression is about 30 times slower than NRV -
|
because runtime decompression is about 30 times slower than NRV -
|
||||||
which is really noticeable on old machines.
|
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
|
* win32/pe & arm/pe: better icon compression handling
|
||||||
|
|
||||||
Changes in 2.92 beta (23 Jan 2007):
|
Changes in 2.92 beta (23 Jan 2007):
|
||||||
@@ -114,7 +177,7 @@ Changes in 2.92 beta (23 Jan 2007):
|
|||||||
|
|
||||||
Changes in 2.91 beta (29 Nov 2006):
|
Changes in 2.91 beta (29 Nov 2006):
|
||||||
* assorted bug fixes
|
* 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
|
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
||||||
|
|
||||||
Changes in 2.90 beta (08 Oct 2006):
|
Changes in 2.90 beta (08 Oct 2006):
|
||||||
@@ -168,7 +231,7 @@ Changes in 1.95 beta (09 Apr 2006):
|
|||||||
* win32/pe: really worked around R6002 runtime errors
|
* win32/pe: really worked around R6002 runtime errors
|
||||||
|
|
||||||
Changes in 1.94 beta (11 Mar 2006):
|
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/amd64
|
||||||
* new format: added support for linux elf/ppc32
|
* new format: added support for linux elf/ppc32
|
||||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
||||||
@@ -220,7 +283,7 @@ Changes in 1.11 beta (20 Dec 2000):
|
|||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
Changes in 1.25 (29 Jun 2004)
|
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
|
* watcom/le: don't crash on files without relocations
|
||||||
* win32/pe: stricter checks of some PE values
|
* win32/pe: stricter checks of some PE values
|
||||||
* source code: much improved portability using ACC, the
|
* source code: much improved portability using ACC, the
|
||||||
@@ -336,6 +399,8 @@ Changes in 0.99 (25 Feb 2000)
|
|||||||
* dos/com and dos/sys: fixed a bad decompressor problem
|
* dos/com and dos/sys: fixed a bad decompressor problem
|
||||||
* linux/386: the counter for the progress indicator was off by one
|
* linux/386: the counter for the progress indicator was off by one
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
|
||||||
Changes in 0.94 (06 Dec 1999)
|
Changes in 0.94 (06 Dec 1999)
|
||||||
* win32/pe: the stub now calls ExitProcess in case of import errors
|
* win32/pe: the stub now calls ExitProcess in case of import errors
|
||||||
* under DOS and Windows, the environment variable UPX now accepts
|
* under DOS and Windows, the environment variable UPX now accepts
|
||||||
@@ -483,12 +548,12 @@ Changes in 0.40 (05 Oct 1998)
|
|||||||
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
||||||
* fixed a rare bug in dos/exe
|
* fixed a rare bug in dos/exe
|
||||||
* worked around a bug in djgpp's strip 2.8
|
* 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+)
|
* added dos/exeh compression method (works on 386+)
|
||||||
|
|
||||||
Changes in 0.30 (27 Jul 1998)
|
Changes in 0.30 (27 Jul 1998)
|
||||||
* fixed a serious bug in the 32-bit compressors - please don't use
|
* 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 !
|
some of them are possibly damaged !
|
||||||
* the 16-bit uncompressors are a little bit shorter & faster
|
* the 16-bit uncompressors are a little bit shorter & faster
|
||||||
* fixed progress indicator for VESA and SVGA text modes
|
* fixed progress indicator for VESA and SVGA text modes
|
||||||
@@ -499,6 +564,5 @@ Changes in 0.20 (05 Jul 1998)
|
|||||||
|
|
||||||
Changes in 0.05 (26 May 1998)
|
Changes in 0.05 (26 May 1998)
|
||||||
* first public beta release
|
* first public beta release
|
||||||
|
* based on experience gained from our previous packers DJP (djgpp2/coff, 1996),
|
||||||
|
lzop (1996) and mfxpak (atari/tos, 1990)
|
||||||
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
|
||||||
|
|||||||
@@ -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-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
|
||||||
https://upx.github.io
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -18,10 +18,8 @@ WELCOME
|
|||||||
|
|
||||||
Welcome to UPX !
|
Welcome to UPX !
|
||||||
|
|
||||||
Please don't forget to read the file LICENSE - UPX is distributed
|
UPX is a free, secure, portable, extendable, high-performance
|
||||||
under the GNU General Public License (GPL) with special exceptions
|
executable packer for several executable formats.
|
||||||
allowing the distribution of all compressed executables, including
|
|
||||||
commercial programs.
|
|
||||||
|
|
||||||
|
|
||||||
INTRODUCTION
|
INTRODUCTION
|
||||||
@@ -37,86 +35,73 @@ and run exactly as before, with no runtime or memory penalty for most
|
|||||||
of the supported formats.
|
of the supported formats.
|
||||||
|
|
||||||
UPX supports a number of different executable formats, including
|
UPX supports a number of different executable formats, including
|
||||||
Windows 95/98/ME/NT/2000/XP/CE programs and DLLs, DOS programs,
|
Windows programs and DLLs, and Linux executables.
|
||||||
and Linux executables and kernels.
|
|
||||||
|
|
||||||
UPX is free software distributed under the term of the GNU General
|
UPX is free software distributed under the term of the GNU General
|
||||||
Public License. Full source code is available.
|
Public License. Full source code is available.
|
||||||
|
|
||||||
UPX may be distributed and used freely, even with commercial applications.
|
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
|
SHORT DOCUMENTATION
|
||||||
===================
|
===================
|
||||||
|
|
||||||
'upx program.exe' will compress a program or DLL. For best compression
|
'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
|
Please see the file UPX.DOC for the full documentation. The files
|
||||||
NEWS and BUGS also contain various tidbits of information.
|
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
|
THE FUTURE
|
||||||
==========
|
==========
|
||||||
|
|
||||||
- AArch64 (64-bit ARM) for Linux and iOS.
|
- Stay up-to-date with ongoing OS and executable format changes
|
||||||
|
|
||||||
- The Linux approach could probably get ported to a lot of other Unix
|
- RISC-V 64 for Linux
|
||||||
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
|
- ARM64 for Windows (help wanted)
|
||||||
FreeBSD/OpenBSD/NetBSD/Solaris/BeOS... CD I might take a look at it ;-)
|
|
||||||
|
|
||||||
- We will *NOT* add any sort of protection and/or encryption.
|
- We will *NOT* add any sort of protection and/or encryption.
|
||||||
This only gives people a false feeling of security because
|
This only gives people a false feeling of security because
|
||||||
by definition all protectors/compressors can be broken.
|
all "protectors" can be broken by definition.
|
||||||
And don't trust any advertisement of authors of other executable
|
|
||||||
compressors about this topic - just do a websearch on "unpackers"...
|
|
||||||
|
|
||||||
- Fix all remaining bugs - keep your reports coming ;-)
|
- Fix all remaining bugs - please report any issues
|
||||||
|
https://github.com/upx/upx/issues
|
||||||
- See the file PROJECTS in the source code distribution if you want
|
|
||||||
to contribute.
|
|
||||||
|
|
||||||
|
|
||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2024 John F. Reiser
|
||||||
|
|
||||||
This program may be used freely, and you are welcome to
|
UPX is distributed with full source code under the terms of the
|
||||||
redistribute it under certain conditions.
|
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,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
UPX License Agreement for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the UPX License Agreement along
|
You should have received a copy of the UPX License Agreements along
|
||||||
with this program; see the file LICENSE. If not, visit the UPX home page.
|
with this program; see the files COPYING and LICENSE. If not,
|
||||||
|
visit the UPX home page.
|
||||||
|
|
||||||
|
|
||||||
Share and enjoy,
|
Share and enjoy,
|
||||||
@@ -133,7 +118,3 @@ Markus & Laszlo & John
|
|||||||
[ The term UPX is a shorthand for the Ultimate Packer for eXecutables
|
[ The term UPX is a shorthand for the Ultimate Packer for eXecutables
|
||||||
and holds no connection with potential owners of registered trademarks
|
and holds no connection with potential owners of registered trademarks
|
||||||
or other rights. ]
|
or other rights. ]
|
||||||
|
|
||||||
[ Feel free to contact us if you have commercial compression requirements
|
|
||||||
or interesting job offers. ]
|
|
||||||
|
|
||||||
|
|||||||
-24
@@ -1,24 +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-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
|
||||||
https://upx.github.io
|
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|
||||||
* better support for MacOS
|
|
||||||
+45
-54
@@ -27,21 +27,6 @@ Foreword
|
|||||||
Markus & Laszlo
|
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
|
Short overview
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -56,51 +41,70 @@ Short overview
|
|||||||
are #included by the individual executable format handlers.
|
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
|
Tools needed to build/modify the UPX sources
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
- A C++ compiler: gcc >= 3.3 or clang.
|
- 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.81 or better
|
- GNU make
|
||||||
|
|
||||||
- zlib and zlib-devel [or zlib-dev] software packages for your
|
- CMake 3.13 or better; see https://cmake.org/
|
||||||
host environment
|
|
||||||
|
|
||||||
- LZMA SDK from https://github.com/upx/upx-lzma-sdk
|
|
||||||
When using git run 'git submodule update --init --recursive'.
|
|
||||||
|
|
||||||
|
|
||||||
To compile the packer sources
|
To compile the packer sources
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Set the environment variable UPX_UCLDIR to point to your
|
- just run "make" in the top-level source directory
|
||||||
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)
|
|
||||||
|
|
||||||
Finally type
|
|
||||||
|
|
||||||
make
|
|
||||||
|
|
||||||
|
|
||||||
If you want to modify the stub sources you'll also need
|
If you want to modify the stub sources you'll also need
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
- Perl & Python
|
- Podman/Docker: see misc/podman/rebuild-stubs - this
|
||||||
|
is the preferred way of rebuilding the stubs
|
||||||
|
|
||||||
|
- 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.
|
- upx-stubtools - a number of cross-assemblers and cross-compilers.
|
||||||
Precompiled binaries for i386-linux hosts are available from
|
Precompiled binaries for amd64-linux hosts are available from
|
||||||
https://github.com/upx/upx-stubtools/releases
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Misc. notes
|
Misc. notes
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
@@ -114,9 +118,9 @@ Misc. notes
|
|||||||
- Use gcc extensions and other compiler specific stuff only through
|
- Use gcc extensions and other compiler specific stuff only through
|
||||||
macros.
|
macros.
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
Some conventions:
|
Some conventions:
|
||||||
|
-----------------
|
||||||
|
|
||||||
- follow our coding style
|
- follow our coding style
|
||||||
- indent level = 4
|
- indent level = 4
|
||||||
@@ -125,17 +129,4 @@ Some conventions:
|
|||||||
- Use throwSomeException() functions instead of throw SomeException():
|
- Use throwSomeException() functions instead of throw SomeException():
|
||||||
this makes the code shorter if used often.
|
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
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set ts=4 sw=4 et:
|
# vim:set ts=4 sw=4 et:
|
||||||
|
|||||||
+1
-2
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -48,4 +48,3 @@ win32/pe
|
|||||||
* certificates in the image
|
* certificates in the image
|
||||||
* compressing files which contain a big BSS requires lots of memory
|
* compressing files which contain a big BSS requires lots of memory
|
||||||
during compression
|
during compression
|
||||||
|
|
||||||
+38
-39
@@ -1,21 +1,9 @@
|
|||||||
#
|
#
|
||||||
# UPX doc Makefile - needs GNU make 3.81 or better
|
# UPX doc Makefile - needs GNU make, sed, pod2html, pod2man and pod2text
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
BUILT_SOURCES := upx.1 upx-doc.html upx-doc.txt
|
||||||
.SUFFIXES:
|
|
||||||
SHELL = /bin/sh
|
|
||||||
|
|
||||||
# internal make variables
|
|
||||||
comma := ,
|
|
||||||
empty :=
|
|
||||||
space := $(empty) $(empty)
|
|
||||||
tab := $(empty) $(empty)
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# //
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
top_srcdir ?= ..
|
top_srcdir ?= ..
|
||||||
|
|
||||||
@@ -23,55 +11,66 @@ PACKAGE = upx
|
|||||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
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)
|
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)]*$$//'
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
DETAB2 := sed -e 's/$(tab)/ /g'
|
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
|
||||||
|
|
||||||
###
|
.PHONY: PHONY
|
||||||
### targets
|
.SECONDEXPANSION:
|
||||||
###
|
.SUFFIXES:
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
all: $(BUILT_SOURCES) PHONY
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
mostlyclean clean distclean maintainer-clean: PHONY
|
||||||
rm -f $(BUILT_SOURCES) pod2htm*
|
rm -f $(BUILT_SOURCES) ./pod2htm*
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
#***********************************************************************
|
||||||
|
# rules
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
||||||
###
|
|
||||||
### rules
|
|
||||||
###
|
|
||||||
|
|
||||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
|
||||||
|
|
||||||
%.1 : %.pod
|
%.1 : %.pod
|
||||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
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
|
%-doc.html : %.pod
|
||||||
pod2text < $< | $(RTRIM) > $@
|
|
||||||
|
|
||||||
%.html : %.pod
|
|
||||||
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
@rm -f pod2htm*
|
@rm -f ./pod2htm*
|
||||||
|
test -s $@
|
||||||
|
|
||||||
%.man : %.1
|
%.man : %.1
|
||||||
nroff -man $< | $(RTRIM) > $@
|
nroff -man $< | $(RTRIM) > $@
|
||||||
|
test -s $@
|
||||||
|
|
||||||
%.ps : %.1
|
%.ps : %.1
|
||||||
groff -man $< | $(RTRIM) > $@
|
groff -man $< | $(RTRIM) > $@
|
||||||
|
test -s $@
|
||||||
|
|
||||||
%.tex : %.pod
|
%.tex : %.pod
|
||||||
pod2latex $<
|
pod2latex $<
|
||||||
|
test -s $@
|
||||||
|
|
||||||
|
%-doc.txt : %.pod
|
||||||
|
pod2text < $< | $(RTRIM) > $@
|
||||||
|
test -s $@
|
||||||
|
|
||||||
###
|
#***********************************************************************
|
||||||
### dependencies
|
# dependencies
|
||||||
###
|
#***********************************************************************
|
||||||
|
|
||||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -37,16 +37,20 @@ Charles W. Sandmann <sandmann@clio.rice.edu>
|
|||||||
for the idea with the stubless decompressor in djgpp2/coff
|
for the idea with the stubless decompressor in djgpp2/coff
|
||||||
Ice
|
Ice
|
||||||
for debugging the PE headersize problem down
|
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
|
Joergen Ibsen <jibz@hotmail.com> and d'b
|
||||||
for the relocation & address optimization ideas
|
for the relocation & address optimization ideas
|
||||||
John S. Fine <johnfine@erols.com>
|
John S. Fine <johnfine@erols.com>
|
||||||
for the new version of the dos/exe decompressor
|
for the new version of the dos/exe decompressor
|
||||||
|
Kornel Pal
|
||||||
|
for the EFI support
|
||||||
Lukundoo <Lukundoo@softhome.net>
|
Lukundoo <Lukundoo@softhome.net>
|
||||||
for beta testing
|
for beta testing
|
||||||
Michael Devore
|
Michael Devore
|
||||||
for initial dos/exe device driver support
|
for initial dos/exe device driver support
|
||||||
Oleg V. Volkov <rover@lglobus.ru>
|
Oleg V. Volkov <rover@lglobus.ru>
|
||||||
for various FreeBSD specific informations
|
for various FreeBSD specific information
|
||||||
The Owl & G-RoM
|
The Owl & G-RoM
|
||||||
for the --compress-icons fix
|
for the --compress-icons fix
|
||||||
Ralph Roth <RalphRoth@gmx.net>
|
Ralph Roth <RalphRoth@gmx.net>
|
||||||
@@ -55,7 +59,6 @@ Salvador Eduardo Tropea
|
|||||||
for beta testing
|
for beta testing
|
||||||
Stefan Widmann
|
Stefan Widmann
|
||||||
for the win32/pe TLS callback support
|
for the win32/pe TLS callback support
|
||||||
The WINE project (http://www.winehq.com/)
|
The WINE project (https://www.winehq.com/)
|
||||||
for lots of useful information found in their PE loader sources
|
for lots of useful information found in their PE loader sources
|
||||||
Natascha
|
Natascha
|
||||||
|
|
||||||
+46
-44
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright (C) 2000-2017 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2024 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<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
|
there will be no execve() except for the execve() of the decompressor
|
||||||
program itself. So, the decompressor program (which contains the
|
program itself. So, the decompressor program (which contains the
|
||||||
compressed version of the original executable) must have the same
|
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).
|
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||||
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||||
All of the decompressor's code, and all of the compressed image
|
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.
|
The decompressor program stub is just under 2K bytes when linked.
|
||||||
After linking, the decompressor code is converted to an initialized
|
After linking, the decompressor code is converted to an initialized
|
||||||
array, and #included into the compilation of the compressor;
|
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
|
executables even smaller, the compressor also compresses all but the
|
||||||
startup and decompression subroutine of the decompressor itself,
|
startup and decompression subroutine of the decompressor itself,
|
||||||
saving a few hundred bytes. The startup code first decompresses the
|
saving a few hundred bytes. The startup code first decompresses the
|
||||||
rest of the decompressor, then jumps to it. A nonstandard linker
|
rest of the decompressor, then jumps to it. A nonstandard linker
|
||||||
script src/stub/l_lx_elf86.lds places both the .text and .data
|
script src/stub/src/i386-linux.elf-entry.lds arranges the SECTIONS
|
||||||
of the decompressor into the same PT_LOAD at 0x00401000. The
|
so that PackLinuxElf32x86::buildLoader() and buildLinuxLoader()
|
||||||
compressor includes the compressed bytes of the original executable
|
generate the desired stub code, which goes into PT_LOAD[1].
|
||||||
at the end of this first PT_LOAD.
|
|
||||||
|
|
||||||
At runtime, the decompressed stub lives at 0x00400000. In order for the
|
At runtime, the decompressed stub lives close beyond the brk().
|
||||||
decompressed stub to work properly at an address that is different
|
In order for the decompressed stub to work properly at an address
|
||||||
from its link-time address, the compiled code must contain no absolute
|
that is different from its link-time address, the compiled code must
|
||||||
addresses. So, the data items in l_lx_elf.c must be only parameters
|
contain no absolute addresses. So, the data items in stub code
|
||||||
and automatic (on-stack) local variables; no global data, no static data,
|
must be only parameters and automatic (on-stack) local variables;
|
||||||
and no string constants. Use "size l_le_n2b.o l_6e_n2b.o" to check
|
no global data, no static data, and no string constants. Also,
|
||||||
that both data and bss have length zero. Also, the '&' operator
|
the '&' operator may not be used to take the address of a function.
|
||||||
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 4 MiB. The address
|
|
||||||
0x00401000 was chosen as 1 page up from a 64 KiB boundary, to
|
|
||||||
make the startup code and its constants smaller.
|
|
||||||
|
|
||||||
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
||||||
and Elf32_Phdr, and then uses the Ehdr and Phdrs to control decompression
|
and Elf32_Phdr, and then uses those Ehdr and Phdrs to control decompression
|
||||||
of the PT_LOAD segments.
|
of the PT_LOAD segments. Subroutine do_xmap() of src/stub/src/
|
||||||
Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
i386-linux.elf-main.c performs the
|
||||||
"virtual execve()" using the compressed data as source, and stores
|
"virtual execve()" using the compressed data as source, and stores
|
||||||
the decompressed bytes directly into the appropriate virtual addresses.
|
the decompressed bytes directly into the appropriate virtual addresses.
|
||||||
|
|
||||||
@@ -74,22 +66,17 @@ expanding $ORIGIN in -rpath, or for application code that relies on
|
|||||||
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
||||||
and previous versions did this by default with no option. However,
|
and previous versions did this by default with no option. However,
|
||||||
too much other software erroneously assumes that /proc/self/exe
|
too much other software erroneously assumes that /proc/self/exe
|
||||||
always exists.
|
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".
|
||||||
|
|
||||||
On arm*-linux-elf there is no good address at which to retain one
|
All of the above documentation refers to ET_EXEC main programs,
|
||||||
page of the compressed executable. Pages below the usual .p_vaddr
|
which always use the same virtual addresses. An ET_DYN executable
|
||||||
0x8000 (32KiB) are rejected by the kernel. Using a page above the
|
(main program or shared library) follows much the same scheme,
|
||||||
original uncompressed brk(0) would require placing the entire initial
|
re-using the address space that the kernel chose originally.
|
||||||
compressed program above uncompressed brk(0), which would significantly
|
|
||||||
increase the running brk(0); but too many programs break if brk(0)
|
|
||||||
moves. Thus on arm*-linux-elf the compressed executable begins
|
|
||||||
with 0x8000==.p_vaddr, all pages mapped by execve() that are also
|
|
||||||
occupied by decompressed bytes are removed before overwriting, and
|
|
||||||
/proc/self/exe becomes a "(deleted)" symlink. It might be possible
|
|
||||||
to preserve /proc/self/exe if the original uncompressed executable
|
|
||||||
were created with 0x9000==.p_vaddr (one page higher than the usual
|
|
||||||
0x8000) so that the compressed page mapped at 0x8000 would linger.
|
|
||||||
[This has not been tested.]
|
|
||||||
|
|
||||||
Linux stores the pathname argument that was specified to execve()
|
Linux stores the pathname argument that was specified to execve()
|
||||||
immediately after the '\0' which terminates the character string of the
|
immediately after the '\0' which terminates the character string of the
|
||||||
@@ -99,9 +86,24 @@ 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 pathname is not "bound" to the file as strongly as /proc/self/exe
|
||||||
(the file may be changed without affecting the pathname), but the
|
(the file may be changed without affecting the pathname), but the
|
||||||
pathname does provide some information. The pathname may be relative
|
pathname does provide some information. The pathname may be relative
|
||||||
to the working directory, so look before any chdir().
|
to the working directory, so look before performing any chdir().
|
||||||
|
|
||||||
The Elf formats for Linux add an environment variable named " " [three
|
On any page, then SELinux in strictest enforcing mode prohibits
|
||||||
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
simultaneous PROT_EXEC and PROT_WRITE, and also prohibits adding
|
||||||
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
PROT_EXEC if the kernel VMA struct (Virtual Memory Area struct)
|
||||||
for linux/elf386 and linux/ElfAMD.
|
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.
|
||||||
|
|||||||
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-2024 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-2024 Markus Franz Xaver Johannes Oberhumer</p>
|
||||||
|
|
||||||
|
<p>Copyright (C) 1996-2024 Laszlo Molnar</p>
|
||||||
|
|
||||||
|
<p>Copyright (C) 2000-2024 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-2024 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-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
|
|
||||||
|
Copyright (C) 2000-2024 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 2024-05-09 "upx 4.2.4" " "
|
||||||
|
.\" 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\-2024 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\-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
.PP
|
||||||
|
Copyright (C) 1996\-2024 Laszlo Molnar
|
||||||
|
.PP
|
||||||
|
Copyright (C) 2000\-2024 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.
|
||||||
+60
-64
@@ -13,8 +13,8 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
|||||||
=head1 ABSTRACT
|
=head1 ABSTRACT
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2017 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
B<UPX> is a portable, extendable, high-performance executable packer for
|
B<UPX> is a portable, extendable, high-performance executable packer for
|
||||||
@@ -23,75 +23,59 @@ ratio and offers I<*very*> fast decompression. Your executables suffer
|
|||||||
no memory overhead or other drawbacks for most of the formats supported,
|
no memory overhead or other drawbacks for most of the formats supported,
|
||||||
because of in-place decompression.
|
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
|
=head1 DISCLAIMER
|
||||||
|
|
||||||
B<UPX> comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
B<UPX> comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
|
||||||
|
|
||||||
This is the first production quality release, and we plan that future 1.xx
|
|
||||||
releases will be backward compatible with this version.
|
|
||||||
|
|
||||||
Please report all problems or suggestions to the authors. Thanks.
|
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
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
B<UPX> is a versatile executable packer with the following features:
|
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 !
|
use UPX to decrease the size of your distribution !
|
||||||
|
|
||||||
- very fast decompression: about 10 MiB/sec on an ancient Pentium 133,
|
- very fast decompression: more than 500 MB/sec on any reasonably modern
|
||||||
about 200 MiB/sec on an Athlon XP 2000+.
|
machine
|
||||||
|
|
||||||
- no memory overhead for your compressed executables for most of the
|
- 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
|
Also, a checksum of both the compressed and uncompressed file is
|
||||||
maintained internally.
|
maintained internally.
|
||||||
|
|
||||||
- universal: UPX can pack a number of executable formats:
|
- universal: UPX can pack a number of executable formats, including
|
||||||
* atari/tos
|
Windows programs and DLLs, macOS apps and Linux executables
|
||||||
* 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)
|
|
||||||
* win64/pe (exe and dll)
|
|
||||||
* arm/pe (exe and dll)
|
|
||||||
* linux/elfamd64
|
|
||||||
* linux/elfppc32
|
|
||||||
* mach/elfppc32
|
|
||||||
|
|
||||||
- portable: UPX is written in portable endian-neutral C++
|
- portable: UPX is written in portable endian-neutral C++
|
||||||
|
|
||||||
- extendable: because of the class layout it's very easy to support
|
- extendable: because of the class layout it's very easy to support
|
||||||
new executable formats or add new compression algorithms
|
new executable formats or add new compression algorithms
|
||||||
|
|
||||||
- free: UPX can be distributed and used freely. And from version 0.99
|
- free: UPX is distributed with full source code under the GNU General
|
||||||
the full source code of UPX is released under the GNU General Public
|
Public License v2+, with special exceptions granting the free usage
|
||||||
License (GPL) !
|
for commercial programs
|
||||||
|
|
||||||
You probably understand now why we call B<UPX> the "I<ultimate>"
|
You probably understand now why we call B<UPX> the "I<ultimate>"
|
||||||
executable packer.
|
executable packer.
|
||||||
@@ -146,7 +130,11 @@ compress and then decompress your program a first time - any further
|
|||||||
compress-decompress steps should then yield byte-identical results
|
compress-decompress steps should then yield byte-identical results
|
||||||
as compared to the first decompressed version.]
|
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 ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +174,17 @@ Quick info for achieving the best compression ratio:
|
|||||||
|
|
||||||
=item *
|
=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 *
|
=item *
|
||||||
|
|
||||||
@@ -210,7 +208,7 @@ it would be better to use resource sections).
|
|||||||
B<UPX> handles overlays like many other executable packers do: it simply
|
B<UPX> handles overlays like many other executable packers do: it simply
|
||||||
copies the overlay after the compressed image. This works with some
|
copies the overlay after the compressed image. This works with some
|
||||||
files, but doesn't work with others, depending on how an application
|
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]
|
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||||
|
|
||||||
@@ -222,7 +220,7 @@ actually accesses this overlayed data.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 ENVIRONMENT
|
=head1 ENVIRONMENT VARIABLE
|
||||||
|
|
||||||
The environment variable B<UPX> can hold a set of default
|
The environment variable B<UPX> can hold a set of default
|
||||||
options for B<UPX>. These options are interpreted first and
|
options for B<UPX>. These options are interpreted first and
|
||||||
@@ -252,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
|
based personal computer which was popular in the late '80s. Support
|
||||||
of this format is only because of nostalgic feelings of one of
|
of this format is only because of nostalgic feelings of one of
|
||||||
the authors and serves no practical purpose :-).
|
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.
|
Packed programs will be byte-identical to the original after uncompression.
|
||||||
All debug information will be stripped, though.
|
All debug information will be stripped, though.
|
||||||
@@ -675,7 +673,7 @@ Extra options available for this executable format:
|
|||||||
=head2 NOTES FOR PS1/EXE
|
=head2 NOTES FOR PS1/EXE
|
||||||
|
|
||||||
This is the executable format used by the Sony PlayStation (PSone),
|
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
|
Support of this format is very similar to the Atari one, because of
|
||||||
nostalgic feelings of one of the authors.
|
nostalgic feelings of one of the authors.
|
||||||
|
|
||||||
@@ -928,28 +926,26 @@ Please report all bugs immediately to the authors.
|
|||||||
|
|
||||||
John F. Reiser <jreiser@BitWagon.com>
|
John F. Reiser <jreiser@BitWagon.com>
|
||||||
|
|
||||||
Jens Medoch <jssg@users.sourceforge.net>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2024 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2017 Jens Medoch
|
B<UPX> is distributed with full source code under the terms of the
|
||||||
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
This program may be used freely, and you are welcome to
|
the file COPYING), or (at your option) under the GPLv+2 with special
|
||||||
redistribute it under certain conditions.
|
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,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
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.
|
|
||||||
|
|
||||||
|
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,382 @@
|
|||||||
|
#
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
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()
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# 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_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()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# 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
|
||||||
|
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()
|
||||||
|
# default sanitizer for Debug builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
|
||||||
|
# default sanitizer for Release builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# test
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
function(upx_add_test) # ARGV
|
||||||
|
set(name "${ARGV0}")
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
add_test(NAME "${name}" 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,48 @@
|
|||||||
|
#
|
||||||
|
# UPX "CMake" build file; see https://cmake.org/
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# summary section
|
||||||
|
# print some info about the build configuration
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# generator
|
||||||
|
upx_print_var(CMAKE_GENERATOR_TOOLSET CMAKE_GENERATOR_PLATFORM)
|
||||||
|
|
||||||
|
# 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_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR)
|
||||||
|
|
||||||
|
# binutils
|
||||||
|
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_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_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE)
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
upx_print_var(APPLE CLANG CYGWIN GNU_FRONTEND GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE MSVC_TOOLSET_VERSION MSVC_VERSION MSYS UNIX WIN32 WIN64)
|
||||||
|
|
||||||
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#
|
||||||
|
# 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)
|
||||||
|
set(s "${method}-${level}")
|
||||||
|
upx_add_test(upx-self-pack-${s} upx --${method} -${level} --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()
|
||||||
|
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,329 @@
|
|||||||
|
#
|
||||||
|
# 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 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++ -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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# force building with clang/clang++ C17/C++20
|
||||||
|
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++ C23/C++23
|
||||||
|
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
|
||||||
|
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 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++ -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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# force building with gcc/g++ C17/C++20
|
||||||
|
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++ C23/C++23
|
||||||
|
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
|
||||||
|
|
||||||
|
# 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/all: xtarget/debug xtarget/release PHONY
|
||||||
|
xtarget/debug: build/$(UPX_XTARGET)/debug PHONY
|
||||||
|
xtarget/release: build/$(UPX_XTARGET)/release PHONY
|
||||||
|
xtarget/all+test: xtarget/debug+test xtarget/release+test PHONY
|
||||||
|
xtarget/debug+test: build/$(UPX_XTARGET)/debug+test PHONY
|
||||||
|
xtarget/release+test: build/$(UPX_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
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
$(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
|
||||||
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,98 @@
|
|||||||
|
# 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 bfs bubblewrap busybox bzip2 bzip3 cabextract ccache chrpath cmake cpio dash diffstat \
|
||||||
|
elfutils execstack fd-find file fish fzf g++ gawk gdb gojq ht htop hyperfine jq ksh \
|
||||||
|
libzstd-dev lsb-release 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-toml python3-yaml python3-zstd \
|
||||||
|
re2c ripgrep rsync screen 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 \
|
||||||
|
&& wget -q 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" \
|
||||||
|
&& for v in $xzversions; do wget -q 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 md=mkdir" >> .bashrc \
|
||||||
|
&& echo "alias rd=rmdir" >> .bashrc \
|
||||||
|
&& echo 'mdd() { mkdir "$1" && cd "$1"; }' >> .bashrc \
|
||||||
|
&& echo 'm() { make "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tn() { time nice "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tnm() { time nice make "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tnmm() { time nice make -j "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'source /usr/share/bash-completion/completions/make' >> .bashrc \
|
||||||
|
&& echo 'complete -F _make m 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
+719
@@ -0,0 +1,719 @@
|
|||||||
|
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.7.14build2 amd64 commandline package manager
|
||||||
|
ii aria2 1.37.0+debian-1build3 amd64 High speed download utility
|
||||||
|
ii base-files 13ubuntu10 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 bfs 3.1.2-1build1 amd64 Breadth-first version of find(1)
|
||||||
|
ii binutils 2.42-4ubuntu2 amd64 GNU assembler, linker and binary utilities
|
||||||
|
ii binutils-common:amd64 2.42-4ubuntu2 amd64 Common files for the GNU assembler, linker and binary utilities
|
||||||
|
ii binutils-x86-64-linux-gnu 2.42-4ubuntu2 amd64 GNU binary utilities, for x86-64-linux-gnu target
|
||||||
|
ii bsdextrautils 2.39.3-9ubuntu6 amd64 extra utilities from 4.4BSD-Lite
|
||||||
|
ii bsdutils 1:2.39.3-9ubuntu6 amd64 basic utilities from 4.4BSD-Lite
|
||||||
|
ii bubblewrap 0.9.0-1build1 amd64 utility for unprivileged chroot and namespace manipulation
|
||||||
|
ii busybox 1:1.36.1-6ubuntu3 amd64 Tiny utilities for small and embedded systems
|
||||||
|
ii bzip2 1.0.8-5.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.2.0-23ubuntu4 amd64 GNU C preprocessor
|
||||||
|
ii cpp-13-x86-64-linux-gnu 13.2.0-23ubuntu4 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.1 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 dpkg 1.22.6ubuntu6 amd64 Debian package management system
|
||||||
|
ii e2fsprogs 1.47.0-2.4~exp1ubuntu4 amd64 ext2/ext3/ext4 file system utilities
|
||||||
|
ii elfutils 0.190-1.1build4 amd64 collection of utilities to handle ELF objects
|
||||||
|
ii execstack 0.0.20131005-1.1ubuntu1 amd64 ELF GNU_STACK program header editing utility
|
||||||
|
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-1 amd64 general-purpose command-line fuzzy finder
|
||||||
|
ii g++ 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler
|
||||||
|
ii g++-13 13.2.0-23ubuntu4 amd64 GNU C++ compiler
|
||||||
|
ii g++-13-multilib 13.2.0-23ubuntu4 amd64 GNU C++ compiler (multilib support)
|
||||||
|
ii g++-13-x86-64-linux-gnu 13.2.0-23ubuntu4 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.2.0-23ubuntu4 amd64 GNU C compiler
|
||||||
|
ii gcc-13-base:amd64 13.2.0-23ubuntu4 amd64 GCC, the GNU Compiler Collection (base package)
|
||||||
|
ii gcc-13-multilib 13.2.0-23ubuntu4 amd64 GNU C compiler (multilib support)
|
||||||
|
ii gcc-13-x86-64-linux-gnu 13.2.0-23ubuntu4 amd64 GNU C compiler for the x86_64-linux-gnu architecture
|
||||||
|
ii gcc-14-base:amd64 14-20240412-0ubuntu1 amd64 GCC, the GNU Compiler Collection (base package)
|
||||||
|
ii gcc-14-base:i386 14-20240412-0ubuntu1 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 git 1:2.43.0-1ubuntu7 amd64 fast, scalable, distributed revision control system
|
||||||
|
ii git-man 1:2.43.0-1ubuntu7 all fast, scalable, distributed revision control system (manual pages)
|
||||||
|
ii gojq 0.12.13-1 amd64 pure Go implementation of jq (program)
|
||||||
|
ii gpgv 2.4.4-2ubuntu17 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 lib32asan8 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector (32bit)
|
||||||
|
ii lib32atomic1 14-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions (32bit)
|
||||||
|
ii lib32gcc-13-dev 13.2.0-23ubuntu4 amd64 GCC support library (32 bit development files)
|
||||||
|
ii lib32gcc-s1 14-20240412-0ubuntu1 amd64 GCC support library (32 bit Version)
|
||||||
|
ii lib32gomp1 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library (32bit)
|
||||||
|
ii lib32itm1 14-20240412-0ubuntu1 amd64 GNU Transactional Memory Library (32bit)
|
||||||
|
ii lib32quadmath0 14-20240412-0ubuntu1 amd64 GCC Quad-Precision Math Library (32bit)
|
||||||
|
ii lib32stdc++-13-dev 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii lib32stdc++6 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3 (32 bit Version)
|
||||||
|
ii lib32ubsan1 14-20240412-0ubuntu1 amd64 UBSan -- undefined behaviour sanitizer (32bit)
|
||||||
|
ii libacl1:amd64 2.3.2-1build1 amd64 access control list - shared library
|
||||||
|
ii libapt-pkg6.0t64:amd64 2.7.14build2 amd64 package management runtime library
|
||||||
|
ii libarchive13t64:amd64 3.7.2-2 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-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector
|
||||||
|
ii libasm1t64:amd64 0.190-1.1build4 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-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions
|
||||||
|
ii libattr1:amd64 1:2.5.2-1build1 amd64 extended attribute handling - shared library
|
||||||
|
ii libaudit-common 1:3.1.2-2.1build1 all Dynamic library for security auditing - common files
|
||||||
|
ii libaudit1:amd64 1:3.1.2-2.1build1 amd64 Dynamic library for security auditing
|
||||||
|
ii libbabeltrace1:amd64 1.5.11-3build3 amd64 Babeltrace conversion libraries
|
||||||
|
ii libbinutils:amd64 2.42-4ubuntu2 amd64 GNU binary utilities (private shared library)
|
||||||
|
ii libblkid1:amd64 2.39.3-9ubuntu6 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 amd64 utility functions from BSD systems - shared library
|
||||||
|
ii libbz2-1.0:amd64 1.0.8-5.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.1 amd64 GNU C Library: Binaries
|
||||||
|
ii libc-dev-bin 2.39-0ubuntu8.1 amd64 GNU C Library: Development binaries
|
||||||
|
ii libc6-dbg:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: detached debugging symbols
|
||||||
|
ii libc6-dev-i386 2.39-0ubuntu8.1 amd64 GNU C Library: 32-bit development libraries for AMD64
|
||||||
|
ii libc6-dev-x32 2.39-0ubuntu8.1 amd64 GNU C Library: X32 ABI Development Libraries for AMD64
|
||||||
|
ii libc6-dev:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: Development Libraries and Header Files
|
||||||
|
ii libc6-i386 2.39-0ubuntu8.1 amd64 GNU C Library: 32-bit shared libraries for AMD64
|
||||||
|
ii libc6-x32 2.39-0ubuntu8.1 amd64 GNU C Library: X32 ABI Shared libraries for AMD64
|
||||||
|
ii libc6:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: Shared libraries
|
||||||
|
ii libc6:i386 2.39-0ubuntu8.1 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 amd64 POSIX 1003.1e capabilities (library)
|
||||||
|
ii libcares2:amd64 1.27.0-1.0ubuntu1 amd64 asynchronous name resolver
|
||||||
|
ii libcc1-0:amd64 14-20240412-0ubuntu1 amd64 GCC cc1 plugin for GDB
|
||||||
|
ii libcom-err2:amd64 1.47.0-2.4~exp1ubuntu4 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 amd64 Compact C Type Format library (runtime, no BFD dependency)
|
||||||
|
ii libctf0:amd64 2.42-4ubuntu2 amd64 Compact C Type Format library (runtime, BFD dependency)
|
||||||
|
ii libcurl3t64-gnutls:amd64 8.5.0-2ubuntu10.1 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour)
|
||||||
|
ii libcurl4t64:amd64 8.5.0-2ubuntu10.1 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.1build4 all configuration to enable the Debian debug info server
|
||||||
|
ii libdebuginfod1t64:amd64 0.190-1.1build4 amd64 library to interact with debuginfod (development files)
|
||||||
|
ii libdw1t64:amd64 0.190-1.1build4 amd64 library that provides access to the DWARF debug information
|
||||||
|
ii libelf1t64:amd64 0.190-1.1build4 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-2build1 amd64 XML parsing C library - runtime library
|
||||||
|
ii libext2fs2t64:amd64 1.47.0-2.4~exp1ubuntu4 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.2.0-23ubuntu4 amd64 GCC support library (development files)
|
||||||
|
ii libgcc-s1:amd64 14-20240412-0ubuntu1 amd64 GCC support library
|
||||||
|
ii libgcc-s1:i386 14-20240412-0ubuntu1 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 libglib2.0-0t64:amd64 2.80.0-6ubuntu1 amd64 GLib library of C routines
|
||||||
|
ii libgmp10:amd64 2:6.3.0+dfsg-2ubuntu6 amd64 Multiprecision arithmetic library
|
||||||
|
ii libgnutls30t64:amd64 3.8.3-1.1ubuntu3.1 amd64 GNU TLS library - main runtime library
|
||||||
|
ii libgomp1:amd64 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library
|
||||||
|
ii libgpg-error0:amd64 1.47-3build2 amd64 GnuPG development runtime library
|
||||||
|
ii libgprofng0:amd64 2.42-4ubuntu2 amd64 GNU Next Generation profiler (runtime library)
|
||||||
|
ii libgssapi-krb5-2:amd64 1.20.1-6ubuntu2 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 amd64 low level cryptographic library (public-key cryptos)
|
||||||
|
ii libhwasan0:amd64 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector
|
||||||
|
ii libicu74:amd64 74.2-1ubuntu3 amd64 International Components for Unicode
|
||||||
|
ii libidn2-0:amd64 2.3.7-2build1 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 amd64 manipulating sets and relations of integer points bounded by linear constraints
|
||||||
|
ii libitm1:amd64 14-20240412-0ubuntu1 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 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 amd64 MIT Kerberos runtime libraries
|
||||||
|
ii libkrb5support0:amd64 1.20.1-6ubuntu2 amd64 MIT Kerberos runtime libraries - Support library
|
||||||
|
ii libldap2:amd64 2.6.7+dfsg-1~exp1ubuntu8 amd64 OpenLDAP libraries
|
||||||
|
ii liblsan0:amd64 14-20240412-0ubuntu1 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 amd64 Fast LZ compression algorithm library - runtime
|
||||||
|
ii liblzma5:amd64 5.6.1+really5.4.5-1 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 amd64 message digest functions from BSD systems - shared library
|
||||||
|
ii libmount1:amd64 2.39.3-9ubuntu6 amd64 device mounting library
|
||||||
|
ii libmpc3:amd64 1.3.1-1build1 amd64 multiple precision complex floating-point library
|
||||||
|
ii libmpfr6:amd64 4.2.1-1build1 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 amd64 low level cryptographic library (symmetric and one-way cryptos)
|
||||||
|
ii libnghttp2-14:amd64 1.59.0-1build4 amd64 library implementing HTTP/2 protocol (shared library)
|
||||||
|
ii libnl-3-200:amd64 3.7.0-0.3build1 amd64 library for dealing with netlink sockets
|
||||||
|
ii libnl-genl-3-200:amd64 3.7.0-0.3build1 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 amd64 library for loading and coordinating access to PKCS#11 modules - runtime
|
||||||
|
ii libpam-modules-bin 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules for PAM - helper binaries
|
||||||
|
ii libpam-modules:amd64 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules for PAM
|
||||||
|
ii libpam-runtime 1.5.3-5ubuntu5 all Runtime support for the PAM library
|
||||||
|
ii libpam0g:amd64 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules library
|
||||||
|
ii libpcre2-32-0:amd64 10.42-4ubuntu2 amd64 New Perl Compatible Regular Expression Library - 32 bit runtime files
|
||||||
|
ii libpcre2-8-0:amd64 10.42-4ubuntu2 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files
|
||||||
|
ii libperl5.38t64:amd64 5.38.2-3.2build2 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 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-0ubuntu1 amd64 interactive high-level object-oriented language (default python3 version)
|
||||||
|
ii libpython3.12-minimal:amd64 3.12.3-1 amd64 Minimal subset of the Python language (version 3.12)
|
||||||
|
ii libpython3.12-stdlib:amd64 3.12.3-1 amd64 Interactive high-level object-oriented language (standard library, version 3.12)
|
||||||
|
ii libpython3.12t64:amd64 3.12.3-1 amd64 Shared Python runtime library (version 3.12)
|
||||||
|
ii libquadmath0:amd64 14-20240412-0ubuntu1 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 amd64 Cyrus SASL - authentication abstraction library
|
||||||
|
ii libsasl2-modules-db:amd64 2.1.28+dfsg1-5ubuntu3 amd64 Cyrus SASL - pluggable authentication modules (DB)
|
||||||
|
ii libseccomp2:amd64 2.5.5-1ubuntu3 amd64 high level interface to Linux seccomp filter
|
||||||
|
ii libselinux1:amd64 3.5-2ubuntu2 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 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 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 amd64 SQLite 3 shared library
|
||||||
|
ii libss2:amd64 1.47.0-2.4~exp1ubuntu4 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 amd64 Secure Sockets Layer toolkit - shared libraries
|
||||||
|
ii libstdc++-13-dev:amd64 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii libstdc++6:amd64 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3
|
||||||
|
ii libsystemd0:amd64 255.4-1ubuntu8 amd64 systemd utility library
|
||||||
|
ii libtalloc2:amd64 2.4.2-1build2 amd64 hierarchical pool based memory allocator
|
||||||
|
ii libtasn1-6:amd64 4.19.0-3build1 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-20240412-0ubuntu1 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime)
|
||||||
|
ii libubsan1:amd64 14-20240412-0ubuntu1 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 amd64 libudev shared library
|
||||||
|
ii libunibilium4:amd64 2.1.0-3 amd64 simple, self-contained terminfo library
|
||||||
|
ii libunistring5:amd64 1.1-2build1 amd64 Unicode string library for C
|
||||||
|
ii libunwind8:amd64 1.6.2-3build1 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 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 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-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector (x32)
|
||||||
|
ii libx32atomic1 14-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions (x32)
|
||||||
|
ii libx32gcc-13-dev 13.2.0-23ubuntu4 amd64 GCC support library (x32 development files)
|
||||||
|
ii libx32gcc-s1 14-20240412-0ubuntu1 amd64 GCC support library (x32)
|
||||||
|
ii libx32gomp1 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library (x32)
|
||||||
|
ii libx32itm1 14-20240412-0ubuntu1 amd64 GNU Transactional Memory Library (x32)
|
||||||
|
ii libx32quadmath0 14-20240412-0ubuntu1 amd64 GCC Quad-Precision Math Library (x32)
|
||||||
|
ii libx32stdc++-13-dev 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii libx32stdc++6 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3 (x32)
|
||||||
|
ii libx32ubsan1 14-20240412-0ubuntu1 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 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 amd64 fast lossless compression algorithm -- development files
|
||||||
|
ii libzstd1:amd64 1.5.5+dfsg2-2build1 amd64 fast lossless compression algorithm
|
||||||
|
ii linux-libc-dev:amd64 6.8.0-31.31 amd64 Linux Kernel Headers for development
|
||||||
|
ii login 1:4.13+dfsg1-4ubuntu3 amd64 system login tools
|
||||||
|
ii logsave 1.47.0-2.4~exp1ubuntu4 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 lua-luv:amd64 1.48.0-2-2build1 amd64 libuv bindings for Lua
|
||||||
|
ii lz4 1.9.4-1build1 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 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 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 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.2build2 amd64 Larry Wall's Practical Extraction and Report Language
|
||||||
|
ii perl-base 5.38.2-3.2build2 amd64 minimal Perl system
|
||||||
|
ii perl-modules-5.38 5.38.2-3.2build2 all Core Perl modules
|
||||||
|
ii procps 2:4.0.4-4ubuntu3 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-0ubuntu1 amd64 interactive high-level object-oriented language (default python3 version)
|
||||||
|
ii python3-argcomplete 3.1.4-1 all bash tab completion for argparse (for Python 3)
|
||||||
|
ii python3-minimal 3.12.3-0ubuntu1 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-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-1 amd64 Interactive high-level object-oriented language (version 3.12)
|
||||||
|
ii python3.12-minimal 3.12.3-1 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 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 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 2024a-2ubuntu1 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 unzip 6.0-28ubuntu4 amd64 De-archiver for .zip files
|
||||||
|
ii util-linux 2.39.3-9ubuntu6 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 amd64 retrieves files from the web
|
||||||
|
ii xz-utils 5.6.1+really5.4.5-1 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-13build1 amd64 Archiver for .zip files
|
||||||
|
ii zlib1g-dev:amd64 1:1.3.dfsg-3.1ubuntu2 amd64 compression library - development
|
||||||
|
ii zlib1g:amd64 1:1.3.dfsg-3.1ubuntu2 amd64 compression library - runtime
|
||||||
|
ii zlib1g:i386 1:1.3.dfsg-3.1ubuntu2 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 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:
|
||||||
|
964659 ===== TOTAL (355 packages)
|
||||||
|
76943 valgrind amd64
|
||||||
|
72249 gcc-13-x86-64-linux-gnu amd64
|
||||||
|
37841 g++-13-x86-64-linux-gnu amd64
|
||||||
|
36493 cmake amd64
|
||||||
|
35919 libicu74 amd64
|
||||||
|
35027 cpp-13-x86-64-linux-gnu amd64
|
||||||
|
29327 libperl5.38t64 amd64
|
||||||
|
21815 neovim-runtime all
|
||||||
|
21684 git amd64
|
||||||
|
20518 libstdc++-13-dev amd64
|
||||||
|
19159 perl-modules-5.38 all
|
||||||
|
16248 zsh-common all
|
||||||
|
16092 libgcc-13-dev amd64
|
||||||
|
13430 libc6 amd64
|
||||||
|
13111 libc6-dev amd64
|
||||||
|
12519 gdb amd64
|
||||||
|
12321 fish-common all
|
||||||
|
12296 libc6 i386
|
||||||
|
12003 libc6-x32 amd64
|
||||||
|
11992 libc6-i386 amd64
|
||||||
|
11569 binutils-x86-64-linux-gnu amd64
|
||||||
|
11174 libc6-dbg amd64
|
||||||
|
10984 cmake-data all
|
||||||
|
10764 libasan8 amd64
|
||||||
|
9665 libx32asan8 amd64
|
||||||
|
9556 lib32asan8 amd64
|
||||||
|
9012 libpython3.12-stdlib amd64
|
||||||
|
8905 libpython3.12t64 amd64
|
||||||
|
8893 libtsan2 amd64
|
||||||
|
8636 lib32gcc-13-dev amd64
|
||||||
|
8335 libmagic-mgc amd64
|
||||||
|
8118 libc6-dev-x32 amd64
|
||||||
|
7923 python3.12-minimal amd64
|
||||||
|
7913 perl-base amd64
|
||||||
|
7492 libx32gcc-13-dev amd64
|
||||||
|
7166 linux-libc-dev amd64
|
||||||
|
6946 libc6-dev-i386 amd64
|
||||||
|
6944 coreutils amd64
|
||||||
|
6775 neovim amd64
|
||||||
|
6743 lib32stdc++-13-dev amd64
|
||||||
|
6607 libssl3t64 amd64
|
||||||
|
6433 libx32stdc++-13-dev amd64
|
||||||
|
6237 dpkg amd64
|
||||||
|
6158 7zip amd64
|
||||||
|
5210 ripgrep amd64
|
||||||
|
5169 libpython3.12-minimal amd64
|
||||||
|
4879 libhwasan0 amd64
|
||||||
|
4341 ncurses-term all
|
||||||
|
4244 minify amd64
|
||||||
|
4103 apt amd64
|
||||||
|
3983 gojq amd64
|
||||||
|
3956 python3-pycryptodome amd64
|
||||||
|
3949 libglib2.0-0t64 amd64
|
||||||
|
3849 libgprofng0 amd64
|
||||||
|
3806 liblsan0 amd64
|
||||||
|
3721 groff-base amd64
|
||||||
|
3627 fzf amd64
|
||||||
|
3605 python2.7-minimal amd64
|
||||||
|
3443 fish amd64
|
||||||
|
3441 re2c amd64
|
||||||
|
3438 util-linux amd64
|
||||||
|
3403 libaria2-0 amd64
|
||||||
|
3382 fd-find amd64
|
||||||
|
3349 libubsan1 amd64
|
||||||
|
3244 libapt-pkg6.0t64 amd64
|
||||||
|
3157 libx32ubsan1 amd64
|
||||||
|
3111 ksh93u+m amd64
|
||||||
|
3110 libstdc++6 amd64
|
||||||
|
3109 lib32ubsan1 amd64
|
||||||
|
2995 parallel all
|
||||||
|
2966 lib32stdc++6 amd64
|
||||||
|
2957 elfutils amd64
|
||||||
|
2928 man-db amd64
|
||||||
|
2785 libpython2.7-minimal amd64
|
||||||
|
2770 libx32stdc++6 amd64
|
||||||
|
2431 zsh amd64
|
||||||
|
2419 passwd amd64
|
||||||
|
2352 libgnutls30t64 amd64
|
||||||
|
2346 libbinutils amd64
|
||||||
|
2191 ht amd64
|
||||||
|
2182 libc-bin amd64
|
||||||
|
2161 git-man all
|
||||||
|
2103 strace amd64
|
||||||
|
2078 libxml2 amd64
|
||||||
|
2032 libisl23 amd64
|
||||||
|
2009 universal-ctags amd64
|
||||||
|
1980 aria2 amd64
|
||||||
|
1900 bash amd64
|
||||||
|
1884 openssl amd64
|
||||||
|
1798 zstd amd64
|
||||||
|
1796 procps amd64
|
||||||
|
1761 libdb5.3t64 amd64
|
||||||
|
1757 libunistring5 amd64
|
||||||
|
1736 gawk amd64
|
||||||
|
1730 libsqlite3-0 amd64
|
||||||
|
1712 libp11-kit0 amd64
|
||||||
|
1634 mksh amd64
|
||||||
|
1579 ccache amd64
|
||||||
|
1504 e2fsprogs amd64
|
||||||
|
1454 bash-completion all
|
||||||
|
1452 sysstat amd64
|
||||||
|
1448 yash amd64
|
||||||
|
1396 libgcrypt20 amd64
|
||||||
|
1381 tzdata all
|
||||||
|
1362 libx11-6 amd64
|
||||||
|
1342 libx11-data all
|
||||||
|
1321 zlib1g-dev amd64
|
||||||
|
1314 hyperfine amd64
|
||||||
|
1237 libzstd-dev amd64
|
||||||
|
1186 libmpfr6 amd64
|
||||||
|
1136 zoxide amd64
|
||||||
|
1123 libpam-modules amd64
|
||||||
|
1025 libsystemd0 amd64
|
||||||
|
1014 libkrb5-3 amd64
|
||||||
|
996 screen amd64
|
||||||
|
924 libcurl4t64 amd64
|
||||||
|
916 wget amd64
|
||||||
|
905 libcurl3t64-gnutls amd64
|
||||||
|
904 libarchive13t64 amd64
|
||||||
|
884 login amd64
|
||||||
|
852 busybox amd64
|
||||||
|
843 libbrotli1 amd64
|
||||||
|
812 lua-luv amd64
|
||||||
|
785 musl amd64
|
||||||
|
780 rsync amd64
|
||||||
|
765 libdw1t64 amd64
|
||||||
|
761 libzstd1 amd64
|
||||||
|
751 libsepol2 amd64
|
||||||
|
745 libsource-highlight4t64 amd64
|
||||||
|
735 python3.12 amd64
|
||||||
|
732 xz-utils amd64
|
||||||
|
708 tar amd64
|
||||||
|
698 lib32quadmath0 amd64
|
||||||
|
672 perl amd64
|
||||||
|
647 ncurses-bin amd64
|
||||||
|
635 libpcre2-8-0 amd64
|
||||||
|
629 libonig5 amd64
|
||||||
|
624 python3-pyelftools all
|
||||||
|
602 libluajit-5.1-2 amd64
|
||||||
|
560 binutils-common amd64
|
||||||
|
556 libtinfo6 amd64
|
||||||
|
554 libpcre2-32-0 amd64
|
||||||
|
552 findutils amd64
|
||||||
|
543 libgmp10 amd64
|
||||||
|
542 gcc-13 amd64
|
||||||
|
538 libext2fs2t64 amd64
|
||||||
|
536 zip amd64
|
||||||
|
536 libldap2 amd64
|
||||||
|
520 curl amd64
|
||||||
|
512 python3-yaml amd64
|
||||||
|
508 libbabeltrace1 amd64
|
||||||
|
496 libssh-4 amd64
|
||||||
|
493 debconf all
|
||||||
|
467 libreadline8t64 amd64
|
||||||
|
452 diffutils amd64
|
||||||
|
426 base-files amd64
|
||||||
|
425 libgssapi-krb5-2 amd64
|
||||||
|
424 libnettle8t64 amd64
|
||||||
|
424 htop amd64
|
||||||
|
422 libncursesw6 amd64
|
||||||
|
415 libssh2-1t64 amd64
|
||||||
|
404 make amd64
|
||||||
|
389 python3-pyasn1 all
|
||||||
|
386 ca-certificates all
|
||||||
|
384 ncurses-base all
|
||||||
|
384 libexpat1 amd64
|
||||||
|
378 liblzma5 amd64
|
||||||
|
375 unzip amd64
|
||||||
|
374 lib32gomp1 amd64
|
||||||
|
372 libgomp1 amd64
|
||||||
|
367 libmount1 amd64
|
||||||
|
358 libjq1 amd64
|
||||||
|
357 bfs amd64
|
||||||
|
355 ninja-build amd64
|
||||||
|
351 libx32gomp1 amd64
|
||||||
|
348 mount 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
|
||||||
|
310 libctf-nobfd0 amd64
|
||||||
|
309 less amd64
|
||||||
|
305 libsource-highlight-common all
|
||||||
|
300 libquadmath0 amd64
|
||||||
|
299 libx32quadmath0 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
|
||||||
|
269 libpam-modules-bin amd64
|
||||||
|
264 libuv1t64 amd64
|
||||||
|
257 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
|
||||||
|
231 lib32gcc-s1 amd64
|
||||||
|
230 librhash0 amd64
|
||||||
|
226 libcrypt1 amd64
|
||||||
|
224 libidn2-0 amd64
|
||||||
|
224 debianutils amd64
|
||||||
|
218 patch amd64
|
||||||
|
218 libluajit-5.1-common all
|
||||||
|
215 patchutils amd64
|
||||||
|
214 ucf all
|
||||||
|
211 libmagic1t64 amd64
|
||||||
|
208 libpam0g amd64
|
||||||
|
207 libuchardet0 amd64
|
||||||
|
206 proot 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
|
||||||
|
196 libelf1t64 amd64
|
||||||
|
187 libunwind8 amd64
|
||||||
|
187 dash amd64
|
||||||
|
185 libgpg-error0 amd64
|
||||||
|
184 libx32gcc-s1 amd64
|
||||||
|
176 libcares2 amd64
|
||||||
|
172 libnl-3-200 amd64
|
||||||
|
171 libsmartcols1 amd64
|
||||||
|
163 lzip amd64
|
||||||
|
162 zlib1g amd64
|
||||||
|
159 binutils amd64
|
||||||
|
157 zlib1g i386
|
||||||
|
157 lzop amd64
|
||||||
|
157 liblzo2-2 amd64
|
||||||
|
155 liblz4-1 amd64
|
||||||
|
154 python3-argcomplete all
|
||||||
|
151 libaudit1 amd64
|
||||||
|
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
|
||||||
|
132 libkrb5support0 amd64
|
||||||
|
131 libipt2 amd64
|
||||||
|
130 init-system-helpers all
|
||||||
|
129 bubblewrap amd64
|
||||||
|
127 libbsd0 amd64
|
||||||
|
126 time amd64
|
||||||
|
126 libsframe1 amd64
|
||||||
|
123 libtimedate-perl all
|
||||||
|
121 libtasn1-6 amd64
|
||||||
|
120 libpopt0 amd64
|
||||||
|
115 libitm1 amd64
|
||||||
|
113 lib32itm1 amd64
|
||||||
|
112 jq amd64
|
||||||
|
111 python3-minimal amd64
|
||||||
|
110 gcc-14-base i386
|
||||||
|
110 gcc-14-base amd64
|
||||||
|
110 gcc-13-base amd64
|
||||||
|
109 bzip2 amd64
|
||||||
|
107 sysvinit-utils amd64
|
||||||
|
105 libx32itm1 amd64
|
||||||
|
105 libc-dev-bin amd64
|
||||||
|
103 libio-pty-perl amd64
|
||||||
|
100 libassuan0 amd64
|
||||||
|
99 libpsl5t64 amd64
|
||||||
|
98 libmspack0t64 amd64
|
||||||
|
97 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 python3 amd64
|
||||||
|
82 cabextract amd64
|
||||||
|
81 libbzip3-0 amd64
|
||||||
|
79 libsensors5 amd64
|
||||||
|
79 libmd0 amd64
|
||||||
|
77 readline-common all
|
||||||
|
77 python3-toml all
|
||||||
|
75 libsasl2-modules-db amd64
|
||||||
|
74 libasm1t64 amd64
|
||||||
|
74 libacl1 amd64
|
||||||
|
72 libffi8 amd64
|
||||||
|
72 diffstat amd64
|
||||||
|
69 yq all
|
||||||
|
69 libss2 amd64
|
||||||
|
69 liberror-perl all
|
||||||
|
69 libdebuginfod1t64 amd64
|
||||||
|
67 libpipeline1 amd64
|
||||||
|
66 bzip3 amd64
|
||||||
|
63 sensible-utils all
|
||||||
|
63 libtermkey1 amd64
|
||||||
|
63 file amd64
|
||||||
|
61 ksh all
|
||||||
|
60 libcap-ng0 amd64
|
||||||
|
60 libattr1 amd64
|
||||||
|
57 libcom-err2 amd64
|
||||||
|
53 libnl-genl-3-200 amd64
|
||||||
|
51 logsave amd64
|
||||||
|
51 libutempter0 amd64
|
||||||
|
50 libdebuginfod-common all
|
||||||
|
48 libmsgpackc2 amd64
|
||||||
|
47 python3-xmltodict all
|
||||||
|
47 libsigsegv2 amd64
|
||||||
|
46 hostname amd64
|
||||||
|
45 libatomic1 amd64
|
||||||
|
44 python3-zstd amd64
|
||||||
|
43 libx32atomic1 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
|
||||||
|
29 ubuntu-keyring all
|
||||||
|
28 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
|
||||||
|
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
|
||||||
@@ -11,14 +11,18 @@ find . \
|
|||||||
-type d -name '.hg' -prune -o \
|
-type d -name '.hg' -prune -o \
|
||||||
-type d -name 'build*' -prune -o \
|
-type d -name 'build*' -prune -o \
|
||||||
-type d -name 'tmp*' -prune -o \
|
-type d -name 'tmp*' -prune -o \
|
||||||
|
-type d -name 'vendor' -prune -o \
|
||||||
-type f -iname '*.bat' -prune -o \
|
-type f -iname '*.bat' -prune -o \
|
||||||
-type f -iname '*.exe' -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 '*.pdf' -prune -o \
|
||||||
-type f -iname '*.swp' -prune -o \
|
-type f -iname '*.swp' -prune -o \
|
||||||
-type f -print0 | \
|
-type f -print0 | \
|
||||||
LC_ALL=C sort -z | xargs -0r perl -n -e '
|
LC_ALL=C sort -z | xargs -0r perl -n -e '
|
||||||
#print("$ARGV\n");
|
#print("$ARGV\n");
|
||||||
if (m,[\x00\x01\x02\xfe\xff],) { print "ERROR: binary file detected $ARGV: $_"; exit(1); }
|
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,[\r\x1a],) { print "ERROR: DOS EOL detected $ARGV: $_"; exit(1); }
|
||||||
if (m,([ \t]+)$,) {
|
if (m,([ \t]+)$,) {
|
||||||
# allow exactly two trailing spaces for GitHub flavoured Markdown in .md files
|
# allow exactly two trailing spaces for GitHub flavoured Markdown in .md files
|
||||||
@@ -28,6 +32,7 @@ LC_ALL=C sort -z | xargs -0r perl -n -e '
|
|||||||
}
|
}
|
||||||
if (m,\t,) {
|
if (m,\t,) {
|
||||||
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||||
|
elsif ($ARGV =~ m,\.mk$,) { }
|
||||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
||||||
@@ -10,12 +10,13 @@ set -e; set -o pipefail
|
|||||||
git ls-files --full-name -z | perl -0 -n -e '
|
git ls-files --full-name -z | perl -0 -n -e '
|
||||||
s,^,./,;
|
s,^,./,;
|
||||||
if (m,^\./src/lzma-sdk(\0|$),) { }
|
if (m,^\./src/lzma-sdk(\0|$),) { }
|
||||||
|
elsif (m,^\./vendor/,) { }
|
||||||
elsif (m,\.bat(\0|$),) { }
|
elsif (m,\.bat(\0|$),) { }
|
||||||
elsif (m,\.exe(\0|$),) { }
|
elsif (m,\.exe(\0|$),) { }
|
||||||
else { print; }
|
else { print; }
|
||||||
' | LC_ALL=C sort -z | xargs -0r perl -n -e '
|
' | LC_ALL=C sort -z | xargs -0r perl -n -e '
|
||||||
#print("$ARGV\n");
|
#print("$ARGV\n");
|
||||||
if (m,[\x00\x01\x02\xfe\xff],) { print "ERROR: binary file detected $ARGV: $_"; exit(1); }
|
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,[\r\x1a],) { print "ERROR: DOS EOL detected $ARGV: $_"; exit(1); }
|
||||||
if (m,([ \t]+)$,) {
|
if (m,([ \t]+)$,) {
|
||||||
# allow exactly two trailing spaces for GitHub flavoured Markdown in .md files
|
# allow exactly two trailing spaces for GitHub flavoured Markdown in .md files
|
||||||
@@ -25,6 +26,7 @@ git ls-files --full-name -z | perl -0 -n -e '
|
|||||||
}
|
}
|
||||||
if (m,\t,) {
|
if (m,\t,) {
|
||||||
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||||
|
elsif ($ARGV =~ m,\.mk$,) { }
|
||||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
else { print "ERROR: hard TAB detected $ARGV: $_"; 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
+166
@@ -0,0 +1,166 @@
|
|||||||
|
#! /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")
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# 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 -j" 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
|
||||||
|
s="${method}-${level}"
|
||||||
|
echo "========== $s =========="
|
||||||
|
"${run_upx[@]}" -qq --${method} -${level} --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
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
echo "All done."
|
||||||
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="\
|
||||||
|
ef49d1c9617dbb3dc1bb36ab70df8a263cd816cc5e91ad28cc62f91ccc77afa7 *amd64-linux.elf/upx-3.91
|
||||||
|
253b1542cdcd5d554eb442e263eb44e400f00e63cfd4d0d727eacec5fcdbbd00 *amd64-linux.elf/upx-3.95
|
||||||
|
d96c42d14684e7248de5712310364eafa28b337695bc0d8c37f91d593b869250 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
c1d3b9ec3157f068097f5deffddce4fc4d3d95602daa539992e0accff6af0de8 *arm-linux.elf/upx-3.95
|
||||||
|
9ca862c0c92d7e4068145024486bb85a6031bf06f9a37c6af543234e08e8ab36 *arm-wince.pe/upx-3.91.exe
|
||||||
|
9173b4e4b1ac0b92e63dc51168dbd41d38208520b0f4c17b91d22e584ad55ae4 *arm64-linux.elf/upx-3.95
|
||||||
|
8c6c5f1678fb74d2f65a1e6c28e3089a4b99b49939fabac3ca1f71183bc73ffa *armeb-linux.elf/upx-3.91
|
||||||
|
13caa682f323a0438a651f53768af9b7fb1208980d46d94c6fb984ecf4422599 *armeb-linux.elf/upx-3.95
|
||||||
|
55f30818e45da393628aa80c3518f3cf099666ae3af5014bded2196ea28ddaea *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
6b80b2be79ec38af3071fcaf8f0d0ec524e4523e7e52e2f10111862ab93ec793 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
9bb71da401ae398ca42cde73afffe0c0db29fff24f22196c4116636ab6385170 *i386-linux.elf/upx-3.91
|
||||||
|
c2375a808f989c0f8290fcd9760db0033413323d8597deb796f182f8ac38afa2 *i386-linux.elf/upx-3.95
|
||||||
|
892695e1abdc0fbbd110ee30c317fde56947f4a8b3dfe413507ee7665f109986 *i386-win32.pe/upx-3.91.exe
|
||||||
|
f76ec227836388da3174007e2c5e27fb6cb397a83297872e78befb298a65796d *i386-win32.pe/upx-3.95.exe
|
||||||
|
8f7c5b3d67c78c117c02bec8b30ec5fca7baa79a35d250a4d981cb7137f8635d *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
745ac3afd263f3a653165bd229e35c817a58c9b894a8d6fbd4e5aaf6c38c1264 *mips-linux.elf/upx-3.95
|
||||||
|
a11da76425bc3bb308de3c19e6df22f56bf12c95afcf96ee8c2d4aaeda07ac8a *mipsel-linux.elf/upx-3.91
|
||||||
|
76c458e8e9b94eceb60d8c51f602a5dec44b2617886ea0b5b7b8802c61d962e9 *mipsel-linux.elf/upx-3.95
|
||||||
|
cec277d9e6e0cbf551f697c1d52e5d29b48533efbe4269df0aafbc12731a93ed *powerpc-linux.elf/upx-3.91
|
||||||
|
92c6cec7bf40d1aa5a62a55fce95bb99d94c5b477edbea127ee0468471ddbdb3 *powerpc-linux.elf/upx-3.95
|
||||||
|
df2f12597c901196e8f10782e72fb4c294955f03a66cc4e8bf3c24414929f717 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||||
|
f7e51450a373cb49f88e3e17c268f4198429f7ad06bed57dda28161b5383196a *amd64-linux.elf/upx-3.91
|
||||||
|
15c57828824d18604519fd43349f0340ccebfddf246ab355f8f30253123132ea *amd64-linux.elf/upx-3.95
|
||||||
|
728b2feceda3cfdd849aef4402d5d4e61aa6fa6d56266e7730b148dc66f4a7b0 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
188a3581ed2bac5fdfd50e08267e2e9cf4cf3ddbfc9f5ae15643298bda4bf11c *arm-linux.elf/upx-3.95
|
||||||
|
0711f0b8531de9659f099f43f2a883d628bee8de67f927e7137c19c6d23a30bd *arm-wince.pe/upx-3.91.exe
|
||||||
|
ae6fa69b1242bdfe808d64b7bbefddfe9c1c96302627ee8c65fa2851102fc502 *arm64-linux.elf/upx-3.95
|
||||||
|
7586b4029355eff2edf25141835ee2405ab9f936956e56420315c3d3fecc8bda *armeb-linux.elf/upx-3.91
|
||||||
|
e37875b1a91ef3c88bdba113649a061b72239dbfe77b77077c51254037a982b6 *armeb-linux.elf/upx-3.95
|
||||||
|
536e5a6bb18378f3eea81be12f218f4da60ea81eddf480434aaf418610e4e52d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
386f3037b26b8b2ce49a527028d738956e7ef649b29a0ef15e32acef4a3b291a *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
5761d8e12b01163c2bf378bef813df9a621da08c4508773db992a1cce067c70c *i386-linux.elf/upx-3.91
|
||||||
|
8afc2b549e2f78987641045697afaac0378b48e84c3e946334c9e4f1a7e693fa *i386-linux.elf/upx-3.95
|
||||||
|
1cc6663f3d9e847f9fec39a52c8efe38b39a66074c0ad77a880a84dde7c68d3f *i386-win32.pe/upx-3.91.exe
|
||||||
|
edf158ec6064e9b11b677a73239a70e414fa8c4f3b8950f74e81514ccb28ef4f *i386-win32.pe/upx-3.95.exe
|
||||||
|
faa36b6601743dcc5eaedb57187a893006652b6c68acecff179ce2cd123e6209 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
6c76928b5914b5c2e072bf2f90a2c95049cc41aec6b98b1f0b3c4f84df069f02 *mips-linux.elf/upx-3.95
|
||||||
|
029c2a47f1f613c538d2f39674167489a9d1bbbb6649a06d51d2b5ea983b4924 *mipsel-linux.elf/upx-3.91
|
||||||
|
4d837edcaf344505ad1a3721ec8e5db35ddaa273a747201e460b946c0a89d6ea *mipsel-linux.elf/upx-3.95
|
||||||
|
0e24a9e58939f7aacd3482db24e04bdac406a658dbb8d5e65d71d76d455e5aa5 *powerpc-linux.elf/upx-3.91
|
||||||
|
04bd4885f37c77a34b39e76cca2fd363f794ed1611093d7fffe1ee19920ce1dd *powerpc-linux.elf/upx-3.95
|
||||||
|
3b6be5bff0e435a8dbd8529562912c58dafdcb9694d75564238f3d086048abd2 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||||
|
715de64e0911c959d0ea208db13bf23a5e635e97e73feb9e04ac9d32117e6a3f *amd64-linux.elf/upx-3.91
|
||||||
|
da805c93ffea03da2f0c0dbb1b313cf0d88ef2c0cb0ad77b0be792210106cd6c *amd64-linux.elf/upx-3.95
|
||||||
|
213e6d3c80b4d741e8c78da915d32c1a2b74072d31e86ec46a10ac2535cf8f6f *amd64-win64.pe/upx-3.95.exe
|
||||||
|
3a66e868147347208935c042517b9f0e2e30d2dbb5c004ec8df6a9ab1e42ecd5 *arm-linux.elf/upx-3.95
|
||||||
|
8d295980b1e6a8240bf75b86a9b8e4561424cbabeab01246f51e553d84b40839 *arm-wince.pe/upx-3.91.exe
|
||||||
|
194947a439c1348570e45343e404c409be3f10feb70fdd87d9bca0addc772c44 *arm64-linux.elf/upx-3.95
|
||||||
|
a01384f43803428e0bfc5f8152304eb8618ef862e4e996a4a4fa4dd9c4576833 *armeb-linux.elf/upx-3.91
|
||||||
|
f2fdba359d52bb82fbab093176a3fbf37b9cb13e8d297523ed57051c3bd401e3 *armeb-linux.elf/upx-3.95
|
||||||
|
582030394a570f92be2d31b3862ab7fb0a6f08982c793a4d41c1471d2cabb939 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
f60dc2f332f58b7fa08f551f8c33d645d71d9ee79e2a719130d10ea4091373ef *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
13887e5466a7d0fc2652aedcef44e33e6ee9b8d6f0ac21dbc4ec90fcc0613bfa *i386-linux.elf/upx-3.91
|
||||||
|
636759f884399ff05e8493a759f60ea52cd4640eb5e9760f12fc25fbf730b1ed *i386-linux.elf/upx-3.95
|
||||||
|
c4a5d27ce7d8f0f326e49489223eda188a9be61971a88758a559efb9f854611a *i386-win32.pe/upx-3.91.exe
|
||||||
|
4ca9a3dd0e0ec38cc1aa3720d9c666f86df4fbe9dcb87ef0dad56d0a47dc327a *i386-win32.pe/upx-3.95.exe
|
||||||
|
f34a020e6325d213052d9f09c775c4d292c34c51380b1ab1b22c6663645167f0 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
3006af1262a29173c46340f1ee4526fba41145f7476841d5bf6b499aa6dea0fd *mips-linux.elf/upx-3.95
|
||||||
|
6af81d3c7cb6f1388925fe2d78ea96313d91d5e17249268739de4d56857f27bd *mipsel-linux.elf/upx-3.91
|
||||||
|
9d3849cd0037ef550703c574e0ccb3032b0d27217ec02c90a0ad8592d2a229f1 *mipsel-linux.elf/upx-3.95
|
||||||
|
704b6eb2033cf3eab30cbc53c35fc85bf0cb17f904528792de33967a1406091d *powerpc-linux.elf/upx-3.91
|
||||||
|
b89b2f3b250ddd156cb857717c86a0c0325a26dd084717c64f3022277ad02be4 *powerpc-linux.elf/upx-3.95
|
||||||
|
d52f201ab041fa64a4ee4234bd0e443e883e402bb93ced9e22554bd3ef3cc9ab *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||||
|
af8536d70ecb8c0680c1c9dc45ef60dcb13fab99f0e4644d9f86216a9cf003e2 *amd64-linux.elf/upx-3.91
|
||||||
|
004a705f4981a19f35767b33bdb70b942717a701ad8635bd56ba33e347c6ed69 *amd64-linux.elf/upx-3.95
|
||||||
|
cf07c202497ab38417ec3ccb65cbb0eb9b87f6c6df40d7dc4b44616282c8e0f8 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
da153c1747e0e242cc8b90c04362f67caa0aa638562bc12fcc7fe08ebb1b4fcb *arm-linux.elf/upx-3.95
|
||||||
|
9755110ebc951c9767e376155d9c6fee9789b009ce82ae47276664f5c832557e *arm-wince.pe/upx-3.91.exe
|
||||||
|
bb9e92b577ace19da295032c294063d724655cf5b97d014053c3fb05ce478884 *arm64-linux.elf/upx-3.95
|
||||||
|
a3c639403fd7b2f035315773c1aa3f68cc0532cf5cd075defd34fa44c4bbbb7a *armeb-linux.elf/upx-3.91
|
||||||
|
3f9604a69a945d86b93f2182ee82f754881331c7ef566d0cd4dc36d7acfa1aa0 *armeb-linux.elf/upx-3.95
|
||||||
|
e6518528d60861e37cb8429376628a7f3d1d5fc90f0933facd70b4e9e0b50709 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
53280a22c34ee1733007ccf858e1f5416c0f7043a4361799087e19a4b2a7eaf4 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
a51ce8993b3577fc2ee45b52174aaadc66c2f90ff53a0148ed096a65d99d24a2 *i386-linux.elf/upx-3.91
|
||||||
|
d018260f04d1efc2b46c8b7ff5b132358e58cb062c158b08a7179fbb561b0e48 *i386-linux.elf/upx-3.95
|
||||||
|
121e4acc3fbad4954cb2d2b957d229b042beaf4b68749c4f85ebfc60fcc80d43 *i386-win32.pe/upx-3.91.exe
|
||||||
|
d604523130da29af35705d9008098ae8b4bb9e7d4743357674470252dd68b8d3 *i386-win32.pe/upx-3.95.exe
|
||||||
|
4d26f0be2b6b6c4802515a7f0dfd97998c6d23e696ae6c0393c9ac0893885a9b *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
4d3b0c7b4dabb5a7a193a0a2899f086f5dfc555106188131389678ecc137378a *mips-linux.elf/upx-3.95
|
||||||
|
be2e9fb66c087f37b58f203b406b618526296dd8c9c53e73bb622740f1e377ba *mipsel-linux.elf/upx-3.91
|
||||||
|
9da821fac44f787875727cf001ca33ed87e02c5fe477f0ebb965c5e0eb62c26c *mipsel-linux.elf/upx-3.95
|
||||||
|
98d7c0214663ae47f59244a90aabbb72a798a4ad0c74ce79d448013f5cad6893 *powerpc-linux.elf/upx-3.91
|
||||||
|
c58266817c4e38982c66e4b75e0002c6e7a51710864f930987b8670ee121ee0b *powerpc-linux.elf/upx-3.95
|
||||||
|
7fecab59271c9d4596bd79978e112a5fea72e33bd7c53c1985d187009d807724 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||||
|
977380191b474f5a7fa78e8015a279bfaa77626bc56d83185fec8761531b3029 *amd64-linux.elf/upx-3.91
|
||||||
|
4f94c9bee7a2f7deed245dc767c215654a41373be978123c3f1ef9074454c59d *amd64-linux.elf/upx-3.95
|
||||||
|
00aa338efc865f720a901afb1c19064cf137abb71d361be9b19192b0ff8a9479 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
c1908a58fcc23a9a964f2cd5f76f805a7cc9ca39480d129c6bdb8db30033840b *arm-linux.elf/upx-3.95
|
||||||
|
78ffa99aa69e2f66f864dce88e787e3b1c0c056009e0f863986d65aabd186107 *arm-wince.pe/upx-3.91.exe
|
||||||
|
245c6bb22ae2b39671503244329f1e4498277b06d600447ad81c7d41ebc872d6 *arm64-linux.elf/upx-3.95
|
||||||
|
9e359728cdb9bf6ea21a864b2c9da56809eda27d6b88828b85ab815311bf77b6 *armeb-linux.elf/upx-3.91
|
||||||
|
86edb5959b5cabad270d7c77e750bc710424b92cfb2ebaeedf3ba403382f4e93 *armeb-linux.elf/upx-3.95
|
||||||
|
b65db2766ffdd45657a07edd57426c55acce2a73a1e3559ab43903ae77574131 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
e827d64700b14e8c19de2882e66d0df0fca4cda0255ae41a66810e4c86583a93 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
c95a7ad9a5015abb1b8a163afe46b4f1529c70ca4ef9353cfb6e5c7eef60245c *i386-linux.elf/upx-3.91
|
||||||
|
21ef65f5c756f216c0f9db9475a7514e10b8e003c30bc22416ec8156cba65252 *i386-linux.elf/upx-3.95
|
||||||
|
6db34f6cdc626c4857fc7b188910562909e571eed3be2116448e244ca82eaa64 *i386-win32.pe/upx-3.91.exe
|
||||||
|
68a08dd3995681af594c66df4b94559e5900f0a09fcf822e3fc2522c3133ad69 *i386-win32.pe/upx-3.95.exe
|
||||||
|
1546ce426b3cfe38bdea18fafadee409253d5d2b452aae5476e073b29e17bb58 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
6ecc64d1fb9fb2a675980ce939b0b8142e802e7218b8ea45f2bb82205ed9242e *mips-linux.elf/upx-3.95
|
||||||
|
eb3c90f8f775e70cb2cc187b7e55d66a3bb28fa760e14a17353acd1130fd122a *mipsel-linux.elf/upx-3.91
|
||||||
|
b47964dbe65e9975d6bddfbfdd321a5e6c96b6eba79b30d0f94ec4323b796991 *mipsel-linux.elf/upx-3.95
|
||||||
|
c32a2deaa707eafaed36a4ab8fb26bb8d8c63a9743b19ad207e305553d14c7fe *powerpc-linux.elf/upx-3.91
|
||||||
|
c4dbfbd0f5021d50f1addc68273f20b49204bf26ae8c8896a0aacc7d2c5a2d47 *powerpc-linux.elf/upx-3.95
|
||||||
|
bb96ea8a29500893b729dad4afe90b09186641c32c42a70a3d2380a771f896d9 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||||
|
de00c3bcb56d78c3fd1d1e633b3f64b884b3611abc305b9e79f4f14385178418 *amd64-linux.elf/upx-3.91
|
||||||
|
eb5aea4d780711dd59e3f86d34a49f16d3669acc6569292bf9ea445d406c5c80 *amd64-linux.elf/upx-3.95
|
||||||
|
2fae12ccc55eeac6c05ff2c6b27539c66816080647283ac2e1b22576242b6bb5 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
14120b8348172a08cd7651184941820ed1c69b7a8d859e375390eee529f5c94e *arm-linux.elf/upx-3.95
|
||||||
|
a6690508c1acdaa07ce97feec0f330182c24206d8e9133949d2a42fccc1cbf27 *arm-wince.pe/upx-3.91.exe
|
||||||
|
4f30adcd3d047fad15344bf6cf3cf4f91cfbacbb121af889df8634fa4c888247 *arm64-linux.elf/upx-3.95
|
||||||
|
f85f0a70b024a050999d476420b9db88206e340b2ffff3781c491b538ae03e37 *armeb-linux.elf/upx-3.91
|
||||||
|
e1b2dc75427212dc268c6921aa2059adf5709b21f230432a4725b16e1c64b238 *armeb-linux.elf/upx-3.95
|
||||||
|
fcf64cfce9e9762e03740d2bf9e2e86d873ade1b6f4a68eb07625f516426810d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
9188a6f911b79fb8629880836b2f5787eb4d938872ba4f1a64c93e70cde9f428 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
8369ff8112aeb55a1684ce0ec16e13e6bc524b734557b49b292f9aae60edccb6 *i386-linux.elf/upx-3.91
|
||||||
|
c4e16cc1a64db618d9038ea9ba6032b7fe5aac05c0d7731b91373094a6a0f6e4 *i386-linux.elf/upx-3.95
|
||||||
|
b21cf7756542b3bab5f4a59d4036cd3176e297dceb744dec96ac365be6568dcd *i386-win32.pe/upx-3.91.exe
|
||||||
|
b1bc0d360918d51ca7b7f32f5083845e4566c7fa7a425d0451f4b10f227d1eac *i386-win32.pe/upx-3.95.exe
|
||||||
|
c40af5d1ba0531abb92587cbcbe604d4f562b685d6e7bbb40ec4d879fddf1267 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
0865d2f1d65e2693d801b3c28d64910a009707be65598772df655c640469a4e5 *mips-linux.elf/upx-3.95
|
||||||
|
4cf108686c2419c6d82eecb2473a6d0ca0a0b47096cc01ea2b55113f84762cc7 *mipsel-linux.elf/upx-3.91
|
||||||
|
0a90a99e0ebb1e9c86e0bdf6a3eec6ca116e65b235ba1ee9029694b84cadc438 *mipsel-linux.elf/upx-3.95
|
||||||
|
4d8f85d254b1fd87bebe2fd732afd6214c98b869cda17ff0c4c566358446038a *powerpc-linux.elf/upx-3.91
|
||||||
|
bbc6179756637db10b636d7383226cb1d685866e8e9191069107725365b42f38 *powerpc-linux.elf/upx-3.95
|
||||||
|
52d7db1d6d6611d4a064c036b57044fd93d4c5762452be07188ee2ff6b1e42bc *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||||
|
ee887f19ee6a5d5f0a0ce7116a41570e106c10bc0bb25acf7eb3ee254c1ed560 *amd64-linux.elf/upx-3.91
|
||||||
|
9bd019e6442b219825f19082a20e4e73c49b24a4dee39e9e2cf0fc907ecdb46f *amd64-linux.elf/upx-3.95
|
||||||
|
382fe4b3e4f575322b746d7d45e4553ba3cf47cb4351b9900508fb52a00118ad *amd64-win64.pe/upx-3.95.exe
|
||||||
|
ae71103c2e105099ab345a648abf109b9aec3039137c90af30710dd4a4b51736 *arm-linux.elf/upx-3.95
|
||||||
|
9150f49be3fcb03a5f23b209e5db443c9b96fa4d8e20d3730195f9eafff5d8e8 *arm-wince.pe/upx-3.91.exe
|
||||||
|
100d9cee849b7996cbde2dc82df766e5104ae030055ae9b286c53b60e9e51405 *arm64-linux.elf/upx-3.95
|
||||||
|
43ded21db5b7b8355bc371e39cd3b1be05e91635e3cb6d64f9a8aea16127e157 *armeb-linux.elf/upx-3.91
|
||||||
|
b0ac3a36871630af80bb9b6ba94604b3ebc1fe05fdb6d095a7c461916fb3d231 *armeb-linux.elf/upx-3.95
|
||||||
|
36b6a947567386e325f1d3ff84a55ecbd37687e3264cfb0a57aa5e3be5ff85f9 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
ad02fcac751563d49cb0711d818231c1030bad9ef2b12fd54e60e2bc6510e9d6 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
d1b4e2c81a0baf4ad273dd96722783e9219e69049a78d536757f39761a7cfe8b *i386-linux.elf/upx-3.91
|
||||||
|
6e509d556ccd2af102d43924bd4eb1e9bed9d557e44387769032df4ede525f0d *i386-linux.elf/upx-3.95
|
||||||
|
2138186fb26cc7983ec4a4ead290573f2e8226fea4a0b9b6d668d86fb21d1573 *i386-win32.pe/upx-3.91.exe
|
||||||
|
5f286eaf28bab252a0f4f069b7b88910b9ce62327c4d15837b91ce65e4f9030e *i386-win32.pe/upx-3.95.exe
|
||||||
|
0ab25c2cd8cf53a31323464080991344479998f45fd9b215caba003f96e9e11c *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
ba14b6b4e846d29bd4211fbcdb2a641f55f8a5700806af64c52182736b757f46 *mips-linux.elf/upx-3.95
|
||||||
|
40c23e16bfe68ec0a59f9651ac747db1e81f07deabc4c22a732e40e03e2b1100 *mipsel-linux.elf/upx-3.91
|
||||||
|
7d353d8381c3401c3c9765fa6091c634791ae9b7338ca5b769f63c38f8f418e7 *mipsel-linux.elf/upx-3.95
|
||||||
|
b43bd16efb19081fe0945948231486cdd1b1157d193ab7cbbd470594f46c57ca *powerpc-linux.elf/upx-3.91
|
||||||
|
7a8a24fa57d17f99b11133a0822a5e499681d09695525b80f8c61d90d06c4ac8 *powerpc-linux.elf/upx-3.95
|
||||||
|
0339ffc1d99f5b5ad12e8492b6a9dc707f705a120494a6bc453fb8617808d10a *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
########## end .sha256sums.recreate
|
||||||
Executable
+335
@@ -0,0 +1,335 @@
|
|||||||
|
#! /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 ec=0
|
||||||
|
if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then
|
||||||
|
echo "LOG: '${run_upx[*]}' $*"
|
||||||
|
fi
|
||||||
|
"${run_upx[@]}" "$@" || 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
|
||||||
|
}
|
||||||
+77
-143
@@ -1,174 +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
|
||||||
# Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
#
|
#
|
||||||
|
|
||||||
# build configuration options for this Makefile
|
# NOTE: this Makefile is intended for developers - please use
|
||||||
BUILD_TYPE_DEBUG ?= 0
|
# the top-level Makefile instead
|
||||||
BUILD_TYPE_SANITIZE ?= 0
|
|
||||||
BUILD_USE_DEPEND ?= 1
|
|
||||||
|
|
||||||
MAKEFLAGS += -r
|
|
||||||
.SUFFIXES:
|
|
||||||
export SHELL = /bin/sh
|
|
||||||
override ee = $($1) $(EXTRA_$1) $(upx_$1) $(upx_EXTRA_$1) $($(basename $(notdir $@)).$1)
|
|
||||||
|
|
||||||
ifndef srcdir
|
ifndef srcdir
|
||||||
srcdir := $(dir $(lastword $(MAKEFILE_LIST)))
|
srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR')
|
|
||||||
endif
|
endif
|
||||||
ifndef top_srcdir
|
ifndef top_srcdir
|
||||||
top_srcdir := $(srcdir)/..
|
top_srcdir := $(srcdir)/..
|
||||||
endif
|
|
||||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
|
||||||
ifneq ($(srcdir),.)
|
|
||||||
vpath %.cpp .:$(srcdir)
|
|
||||||
vpath %.h .:$(srcdir)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# toolchain
|
#***********************************************************************
|
||||||
CXX ?= g++
|
# redirect to top-level Makefile
|
||||||
CXXLD = $(CXX)
|
#***********************************************************************
|
||||||
exeext ?= .out
|
|
||||||
libext ?= .a
|
|
||||||
objext ?= .o
|
|
||||||
|
|
||||||
upx_SOURCES := $(sort $(wildcard $(srcdir)/*.cpp))
|
# NOTE that the top-level Makefile .DEFAULT_GOAL is build/release
|
||||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
.DEFAULT_GOAL = build/all
|
||||||
|
|
||||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||||
UPX_VERSION_GITREV := $(strip $(shell cd '$(top_srcdir)' && git rev-parse --short=12 HEAD || echo 'ERROR'))
|
.PHONY: PHONY
|
||||||
ifneq ($(UPX_VERSION_GITREV),)
|
.SECONDEXPANSION:
|
||||||
GITREV_PLUS := $(strip $(shell cd '$(top_srcdir)' && git diff --exit-code HEAD >/dev/null && echo '' || echo '+'))
|
.SUFFIXES:
|
||||||
DEFS += '-DUPX_VERSION_GITREV="$(UPX_VERSION_GITREV)$(GITREV_PLUS)"'
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
build/debug build/release build/all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
build/debug+test build/release+test build/all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
INCLUDES += -I$(UPX_UCLDIR)/include
|
# shortcuts
|
||||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
debug release all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
endif
|
debug+test release+test all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
LIBS += -lucl -lz
|
|
||||||
# LZMA from https://github.com/upx/upx-lzma-sdk
|
|
||||||
include $(top_srcdir)/src/stub/src/c/Makevars.lzma
|
|
||||||
|
|
||||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||||
ifeq ($(BUILD_TYPE_DEBUG),1)
|
|
||||||
CXXFLAGS_OPTIMIZE ?= -O0 -g
|
|
||||||
else
|
|
||||||
CXXFLAGS_OPTIMIZE ?= -O2
|
|
||||||
endif
|
|
||||||
CXXFLAGS += $(CXXFLAGS_OPTIMIZE)
|
|
||||||
# protect against security threats caused by misguided C++ compiler "optimizations"
|
|
||||||
ifeq ($(findstring clang,$(CXX)),)
|
|
||||||
CXXFLAGS += -fno-delete-null-pointer-checks
|
|
||||||
endif
|
|
||||||
CXXFLAGS += -fno-strict-aliasing -fwrapv
|
|
||||||
CXXFLAGS += -funsigned-char
|
|
||||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings
|
|
||||||
CXXFLAGS_WERROR ?= -Werror
|
|
||||||
CXXFLAGS += $(CXXFLAGS_WERROR)
|
|
||||||
|
|
||||||
ifeq ($(BUILD_TYPE_SANITIZE),1)
|
#***********************************************************************
|
||||||
CXXFLAGS_SANITIZE ?= -fsanitize=address,undefined -fno-omit-frame-pointer -DACC_CFG_NO_UNALIGNED
|
# make run-testsuite
|
||||||
CXXFLAGS += $(CXXFLAGS_SANITIZE)
|
# git clone https://github.com/upx/upx-testsuite.git
|
||||||
# these are the only 2 objects that are actually speed-sensitive
|
#***********************************************************************
|
||||||
compress_lzma$(objext) filteri$(objext) : override CXXFLAGS_SANITIZE =
|
|
||||||
endif
|
|
||||||
|
|
||||||
# rules
|
# search for the UPX testsuite; you can override by setting "upx_testsuite_SRCDIR"
|
||||||
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 ee,CXXFLAGS) $(call ee,LDFLAGS) -o $@ $(upx_OBJECTS) $(call ee,LDADD) $(call ee,LIBS))
|
|
||||||
$($(notdir $@).POST_LINK_STEP)
|
|
||||||
$(CHECK_WHITESPACE)
|
|
||||||
|
|
||||||
%.o : %.cpp | ./.depend
|
|
||||||
$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -c $<)
|
|
||||||
%.cpp.ii : %.cpp
|
|
||||||
$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -E $<)
|
|
||||||
|
|
||||||
ifeq ($(BUILD_USE_DEPEND),1)
|
|
||||||
./.depend: $(sort $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h)) $(MAKEFILE_LIST)
|
|
||||||
@rm -f $@
|
|
||||||
@echo "Updating $@"
|
|
||||||
@$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -MM) $(filter %.cpp,$^) > $@
|
|
||||||
else
|
|
||||||
./.depend:
|
|
||||||
.PHONY: ./.depend
|
|
||||||
endif
|
|
||||||
|
|
||||||
CHECK_WHITESPACE =
|
|
||||||
ifeq ($(shell uname),Linux)
|
|
||||||
CHECK_WHITESPACE = $(top_srcdir)/src/stub/scripts/check_whitespace.sh $(top_srcdir)
|
|
||||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
|
||||||
CHECK_WHITESPACE = $(top_srcdir)/src/stub/scripts/check_whitespace_git.sh $(top_srcdir)
|
|
||||||
endif
|
|
||||||
check-whitespace : ; $(CHECK_WHITESPACE)
|
|
||||||
endif
|
|
||||||
.PHONY: check-whitespace
|
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
|
||||||
rm -f *.d *.ii *.map *.o *.obj *.res ./.depend upx.exe upx.out upx.ttp upx$(exeext)
|
|
||||||
|
|
||||||
./.depend compress_lzma$(objext) : INCLUDES += -I$(UPX_LZMADIR)
|
|
||||||
|
|
||||||
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
|
||||||
p_mach$(objext) : CXXFLAGS += -Wno-cast-align
|
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),mostlyclean)
|
|
||||||
else ifeq ($(MAKECMDGOALS),clean)
|
|
||||||
else ifeq ($(MAKECMDGOALS),distclean)
|
|
||||||
else ifeq ($(MAKECMDGOALS),maintainer-clean)
|
|
||||||
else ifeq ($(MAKECMDGOALS),clang-format)
|
|
||||||
else ifeq ($(MAKECMDGOALS),check-whitespace)
|
|
||||||
else
|
|
||||||
ifeq ($(BUILD_USE_DEPEND),1)
|
|
||||||
-include ./.depend
|
|
||||||
endif
|
|
||||||
help$(objext): $(MAKEFILE_LIST)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# "make run-testsuite"
|
|
||||||
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
|
|
||||||
# you also can override upx_testsuite_SRCDIR
|
|
||||||
ifndef upx_testsuite_SRCDIR
|
ifndef upx_testsuite_SRCDIR
|
||||||
# search standard locations below $(top_srcdir)
|
# search standard locations below $(top_srcdir)
|
||||||
ifneq ($(wildcard $(top_srcdir)/../upx-testsuite.git/files/packed/.),)
|
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
|
upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite.git
|
||||||
else ifneq ($(wildcard $(top_srcdir)/../upx-testsuite/files/packed/.),)
|
else ifneq ($(wildcard $(top_srcdir)/../upx-testsuite/files/packed/.),)
|
||||||
upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite
|
upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# run the UPX testsuite
|
# 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 $(upx_testsuite_SRCDIR)/files/packed/.),)
|
||||||
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
|
ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
|
||||||
run-testsuite: export upx_exe := ./upx$(exeext)
|
run-testsuite: run-testsuite-release PHONY
|
||||||
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
run-testsuite-all: run-testsuite-debug run-testsuite-release PHONY
|
||||||
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||||
run-testsuite: ./upx$(exeext)
|
run-testsuite-debug: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-debug
|
||||||
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
|
||||||
.PHONY: run-testsuite
|
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
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# make check-whitespace
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# make clang-format
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
|
ifneq ($(wildcard /usr/bin/env),)
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp
|
|
||||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
# Markus loves clang-format, but John hates it; find a compromise
|
||||||
CLANG_FORMAT_FILES += snprintf.cpp
|
CLANG_FORMAT_EXCLUDE_FILES += stub/%.h util/miniacc.h
|
||||||
CLANG_FORMAT_FILES += stdcxx.cpp stdcxx.h
|
CLANG_FORMAT_EXCLUDE_FILES += p_lx_% p_mach% p_unix% p_vmlin%
|
||||||
CLANG_FORMAT_FILES += ui.cpp ui.h util.h
|
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
|
||||||
clang-format:
|
CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
|
||||||
$(top_srcdir)/src/stub/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(CLANG_FORMAT_FILES))
|
CLANG_FORMAT_FILES += $(sort $(wildcard ../misc/cmake/try_compile/*.[ch]*))
|
||||||
.PHONY: clang-format
|
CLANG_FORMAT_FILES := $(sort $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)))
|
||||||
endif
|
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:
|
# vim:set ts=8 sw=8 noet:
|
||||||
|
|||||||
+704
-376
File diff suppressed because it is too large
Load Diff
+90
-140
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,36 +25,32 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// this is an internal include file private to bele.h
|
||||||
#ifndef __UPX_BELE_H
|
|
||||||
# error "this is an internal include file"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
// CTP - Compile-Time Polymorphism (templates)
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
# define V static inline
|
#define V static inline
|
||||||
# define S static int __acc_cdecl_qsort
|
#define VV static forceinline_constexpr
|
||||||
# define C /*empty*/
|
#define S static int __acc_cdecl_qsort
|
||||||
|
#define C noexcept
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
// RTP - Run-Time Polymorphism (virtual functions)
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
# define V virtual
|
#define V virtual
|
||||||
# define S virtual int
|
#define VV virtual
|
||||||
# define C const
|
#define S virtual int
|
||||||
|
#define C const noexcept
|
||||||
#else
|
#else
|
||||||
# error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
struct AbstractPolicy
|
struct AbstractPolicy {
|
||||||
{
|
explicit inline AbstractPolicy() noexcept {}
|
||||||
inline AbstractPolicy() { }
|
virtual inline ~AbstractPolicy() noexcept {}
|
||||||
virtual inline ~AbstractPolicy() { }
|
|
||||||
V bool isBE() C = 0;
|
V bool isBE() C = 0;
|
||||||
V bool isLE() C = 0;
|
V bool isLE() C = 0;
|
||||||
|
|
||||||
@@ -68,10 +64,10 @@ struct AbstractPolicy
|
|||||||
V void set32(void *p, unsigned v) C = 0;
|
V void set32(void *p, unsigned v) C = 0;
|
||||||
V void set64(void *p, upx_uint64_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 int get16_signed(const void *p) C = 0;
|
||||||
V unsigned get24_signed(const void *p) C = 0;
|
V int get24_signed(const void *p) C = 0;
|
||||||
V unsigned get32_signed(const void *p) C = 0;
|
V int get32_signed(const void *p) C = 0;
|
||||||
V upx_uint64_t get64_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 u16_compare(const void *a, const void *b) C = 0;
|
||||||
S u24_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 u32_compare_signed(const void *a, const void *b) C = 0;
|
||||||
S u64_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 dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(AbstractPolicy)
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
#undef C
|
||||||
|
#define C const noexcept override
|
||||||
|
#endif
|
||||||
|
|
||||||
struct BEPolicy
|
struct BEPolicy final
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
: public AbstractPolicy
|
: public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline BEPolicy() { }
|
explicit inline BEPolicy() noexcept {}
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||||
#endif
|
#endif
|
||||||
V bool isBE() C { return true; }
|
VV bool isBE() C { return true; }
|
||||||
V bool isLE() C { return false; }
|
VV bool isLE() C { return false; }
|
||||||
|
|
||||||
typedef BE16 U16;
|
typedef BE16 U16;
|
||||||
typedef BE32 U32;
|
typedef BE32 U32;
|
||||||
typedef BE64 U64;
|
typedef BE64 U64;
|
||||||
|
|
||||||
V unsigned get16(const void *p) C
|
V unsigned get16(const void *p) C { return get_be16(p); }
|
||||||
{ return get_be16(p); }
|
V unsigned get24(const void *p) C { return get_be24(p); }
|
||||||
V unsigned get24(const void *p) C
|
V unsigned get32(const void *p) C { return get_be32(p); }
|
||||||
{ return get_be24(p); }
|
V upx_uint64_t get64(const void *p) C { return get_be64(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
|
V void set16(void *p, unsigned v) C { set_be16(p, v); }
|
||||||
{ set_be16(p, v); }
|
V void set24(void *p, unsigned v) C { set_be24(p, v); }
|
||||||
V void set24(void *p, unsigned v) C
|
V void set32(void *p, unsigned v) C { set_be32(p, v); }
|
||||||
{ set_be24(p, v); }
|
V void set64(void *p, upx_uint64_t v) C { set_be64(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
|
V int get16_signed(const void *p) C { return get_be16_signed(p); }
|
||||||
{ return get_be16_signed(p); }
|
V int get24_signed(const void *p) C { return get_be24_signed(p); }
|
||||||
V unsigned get24_signed(const void *p) C
|
V int get32_signed(const void *p) C { return get_be32_signed(p); }
|
||||||
{ return get_be24_signed(p); }
|
V upx_int64_t get64_signed(const void *p) C { return get_be64_signed(p); }
|
||||||
V unsigned get32_signed(const void *p) C
|
|
||||||
{ return get_be32_signed(p); }
|
|
||||||
V upx_uint64_t get64_signed(const void *p) C
|
|
||||||
{ return get_be64_signed(p); }
|
|
||||||
|
|
||||||
S u16_compare(const void *a, const void *b) C
|
S u16_compare(const void *a, const void *b) C { return be16_compare(a, b); }
|
||||||
{ return be16_compare(a, b); }
|
S u24_compare(const void *a, const void *b) C { return be24_compare(a, b); }
|
||||||
S u24_compare(const void *a, const void *b) C
|
S u32_compare(const void *a, const void *b) C { return be32_compare(a, b); }
|
||||||
{ return be24_compare(a, b); }
|
S u64_compare(const void *a, const void *b) C { return be64_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
|
S u16_compare_signed(const void *a, const void *b) C { return be16_compare_signed(a, b); }
|
||||||
{ return be16_compare_signed(a, b); }
|
S u24_compare_signed(const void *a, const void *b) C { return be24_compare_signed(a, b); }
|
||||||
S u24_compare_signed(const void *a, const void *b) C
|
S u32_compare_signed(const void *a, const void *b) C { return be32_compare_signed(a, b); }
|
||||||
{ return be24_compare_signed(a, b); }
|
S u64_compare_signed(const void *a, const void *b) C { return be64_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() {
|
static void compileTimeAssertions() {
|
||||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
@@ -161,73 +144,55 @@ struct BEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy and move
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(BEPolicy)
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LEPolicy final
|
||||||
struct LEPolicy
|
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
: public AbstractPolicy
|
: public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline LEPolicy() { }
|
explicit inline LEPolicy() noexcept {}
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||||
#endif
|
#endif
|
||||||
V bool isBE() C { return false; }
|
VV bool isBE() C { return false; }
|
||||||
V bool isLE() C { return true; }
|
VV bool isLE() C { return true; }
|
||||||
|
|
||||||
typedef LE16 U16;
|
typedef LE16 U16;
|
||||||
typedef LE32 U32;
|
typedef LE32 U32;
|
||||||
typedef LE64 U64;
|
typedef LE64 U64;
|
||||||
|
|
||||||
V unsigned get16(const void *p) C
|
V unsigned get16(const void *p) C { return get_le16(p); }
|
||||||
{ return get_le16(p); }
|
V unsigned get24(const void *p) C { return get_le24(p); }
|
||||||
V unsigned get24(const void *p) C
|
V unsigned get32(const void *p) C { return get_le32(p); }
|
||||||
{ return get_le24(p); }
|
V upx_uint64_t get64(const void *p) C { return get_le64(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
|
V void set16(void *p, unsigned v) C { set_le16(p, v); }
|
||||||
{ set_le16(p, v); }
|
V void set24(void *p, unsigned v) C { set_le24(p, v); }
|
||||||
V void set24(void *p, unsigned v) C
|
V void set32(void *p, unsigned v) C { set_le32(p, v); }
|
||||||
{ set_le24(p, v); }
|
V void set64(void *p, upx_uint64_t v) C { set_le64(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
|
V int get16_signed(const void *p) C { return get_le16_signed(p); }
|
||||||
{ return get_le16_signed(p); }
|
V int get24_signed(const void *p) C { return get_le24_signed(p); }
|
||||||
V unsigned get24_signed(const void *p) C
|
V int get32_signed(const void *p) C { return get_le32_signed(p); }
|
||||||
{ return get_le24_signed(p); }
|
V upx_int64_t get64_signed(const void *p) C { return get_le64_signed(p); }
|
||||||
V unsigned get32_signed(const void *p) C
|
|
||||||
{ return get_le32_signed(p); }
|
|
||||||
V upx_uint64_t get64_signed(const void *p) C
|
|
||||||
{ return get_le64_signed(p); }
|
|
||||||
|
|
||||||
S u16_compare(const void *a, const void *b) C
|
S u16_compare(const void *a, const void *b) C { return le16_compare(a, b); }
|
||||||
{ return le16_compare(a, b); }
|
S u24_compare(const void *a, const void *b) C { return le24_compare(a, b); }
|
||||||
S u24_compare(const void *a, const void *b) C
|
S u32_compare(const void *a, const void *b) C { return le32_compare(a, b); }
|
||||||
{ return le24_compare(a, b); }
|
S u64_compare(const void *a, const void *b) C { return le64_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
|
S u16_compare_signed(const void *a, const void *b) C { return le16_compare_signed(a, b); }
|
||||||
{ return le16_compare_signed(a, b); }
|
S u24_compare_signed(const void *a, const void *b) C { return le24_compare_signed(a, b); }
|
||||||
S u24_compare_signed(const void *a, const void *b) C
|
S u32_compare_signed(const void *a, const void *b) C { return le32_compare_signed(a, b); }
|
||||||
{ return le24_compare_signed(a, b); }
|
S u64_compare_signed(const void *a, const void *b) C { return le64_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() {
|
static void compileTimeAssertions() {
|
||||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
@@ -238,41 +203,26 @@ struct LEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy and move
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(LEPolicy)
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(LEPolicy)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Native Endianness policy (aka host policy)
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
|
typedef BEPolicy NEPolicy;
|
||||||
typedef BEPolicy HostPolicy;
|
typedef BEPolicy HostPolicy;
|
||||||
#elif (ACC_ABI_LITTLE_ENDIAN)
|
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||||
|
typedef LEPolicy NEPolicy;
|
||||||
typedef LEPolicy HostPolicy;
|
typedef LEPolicy HostPolicy;
|
||||||
#else
|
#else
|
||||||
# error "ACC_ABI_ENDIAN"
|
#error "ACC_ABI_ENDIAN"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
|
||||||
struct HostAlignedPolicy
|
|
||||||
{
|
|
||||||
#if defined(BELE_CTP)
|
|
||||||
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef upx_uint16_t U16;
|
|
||||||
typedef upx_uint32_t U32;
|
|
||||||
typedef upx_uint64_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 V
|
||||||
|
#undef VV
|
||||||
#undef S
|
#undef S
|
||||||
#undef C
|
#undef C
|
||||||
|
|
||||||
|
|||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
/* bptr.h --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2017 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
|
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_BPTR_H
|
|
||||||
#define __UPX_BPTR_H 1
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// BoundedPtr
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class BoundedPtr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//typedef T* StoredType;
|
|
||||||
//typedef T* PointerType;
|
|
||||||
//typedef T& ReferenceType;
|
|
||||||
|
|
||||||
~BoundedPtr() { }
|
|
||||||
|
|
||||||
explicit BoundedPtr(void* base, size_t size_in_bytes, T* ptr=0)
|
|
||||||
: ptr_(ptr), base_(base), size_in_bytes_(0)
|
|
||||||
{
|
|
||||||
assert(base_ != NULL);
|
|
||||||
size_in_bytes_ = mem_size(1, size_in_bytes);
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
// assignment
|
|
||||||
BoundedPtr& operator= (const BoundedPtr& other) {
|
|
||||||
assert(base_ == other.base_);
|
|
||||||
assert(size_in_bytes_ == other.size_in_bytes_);
|
|
||||||
ptr_ = other.ptr_; check(); return *this;
|
|
||||||
}
|
|
||||||
BoundedPtr& operator= (T* other) {
|
|
||||||
ptr_ = other; check(); return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T* () { return ptr_; }
|
|
||||||
operator const T* () const { return ptr_; }
|
|
||||||
|
|
||||||
BoundedPtr& operator += (size_t n) {
|
|
||||||
checkNULL(); ptr_ += n; checkRange(); return *this;
|
|
||||||
}
|
|
||||||
BoundedPtr& operator -= (size_t n) {
|
|
||||||
checkNULL(); ptr_ -= n; checkRange(); return *this;
|
|
||||||
}
|
|
||||||
BoundedPtr& operator ++ (void) {
|
|
||||||
checkNULL(); ptr_ += 1; checkRange(); return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkNULL() const {
|
|
||||||
if __acc_very_unlikely(!ptr_)
|
|
||||||
throwCantUnpack("unexpected NULL pointer; take care!");
|
|
||||||
}
|
|
||||||
void checkRange() const {
|
|
||||||
size_t off = (const char *) ptr_ - (const char *) base_;
|
|
||||||
if __acc_very_unlikely(off > size_in_bytes_)
|
|
||||||
throwCantUnpack("pointer out of range; take care!");
|
|
||||||
}
|
|
||||||
void check() const { // check ptr_ invariant: either NULL or valid checkRange()
|
|
||||||
if (ptr_ != NULL)
|
|
||||||
checkRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
T* ptr_;
|
|
||||||
void* base_;
|
|
||||||
size_t size_in_bytes_;
|
|
||||||
|
|
||||||
// disable copy
|
|
||||||
BoundedPtr(const BoundedPtr&); // {}
|
|
||||||
// disable dynamic allocation
|
|
||||||
DISABLE_NEW_DELETE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
@@ -0,0 +1,857 @@
|
|||||||
|
/* dt_check.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// doctest checks, and various tests to catch toolchain/qemu/sanitizer/valgrind/wine/etc
|
||||||
|
// problems; grown historically
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#include <cmath> // std::isinf std::isnan
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_doctest_check()
|
||||||
|
//
|
||||||
|
// honors environment variables:
|
||||||
|
// UPX_DEBUG_DOCTEST_DISABLE
|
||||||
|
// UPX_DEBUG_DOCTEST_VERBOSE
|
||||||
|
//
|
||||||
|
// HINT: set "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_doctest_check(int argc, char **argv) {
|
||||||
|
#if defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
UNUSED(argc);
|
||||||
|
UNUSED(argv);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST"))
|
||||||
|
return 0;
|
||||||
|
bool minimal = true; // don't show summary
|
||||||
|
bool duration = false; // don't show timings
|
||||||
|
bool success = false; // don't show all succeeding tests
|
||||||
|
#if DEBUG
|
||||||
|
// default for debug builds: do show the [doctest] summary
|
||||||
|
minimal = false;
|
||||||
|
#endif
|
||||||
|
const char *e = upx_getenv("UPX_DEBUG_DOCTEST_VERBOSE");
|
||||||
|
if (e && e[0]) {
|
||||||
|
if (strcmp(e, "0") == 0) {
|
||||||
|
minimal = true;
|
||||||
|
} else if (strcmp(e, "1") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
} else if (strcmp(e, "2") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
duration = true;
|
||||||
|
} else if (strcmp(e, "3") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
duration = true;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doctest::Context context;
|
||||||
|
if (minimal)
|
||||||
|
context.setOption("dt-minimal", true);
|
||||||
|
if (duration)
|
||||||
|
context.setOption("dt-duration", true);
|
||||||
|
if (success)
|
||||||
|
context.setOption("dt-success", true);
|
||||||
|
// this requires that main_get_options() understands/ignores doctest "--dt-XXX" options
|
||||||
|
if (argc > 0 && argv != nullptr)
|
||||||
|
context.applyCommandLine(argc, argv);
|
||||||
|
int r = context.run();
|
||||||
|
if (r != 0)
|
||||||
|
return 1;
|
||||||
|
if (context.shouldExit())
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
#endif // DOCTEST_CONFIG_DISABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compile-time checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// need extra parenthesis because the C preprocessor does not understand C++ templates
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull)
|
||||||
|
#if !(ACC_CC_MSC) // unfortunately *not* constexpr with current MSVC
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(bswap16(0xf4f3f2f1)) == no_bswap16(0xf4f3f2f1))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(bswap32(0xf4f3f2f1)) == no_bswap32(0xf4f3f2f1))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(bswap64(0xf8f7f6f5f4f3f2f1ull)) ==
|
||||||
|
no_bswap64(0xf8f7f6f5f4f3f2f1ull))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 0, 8) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 1, 8) == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 127, 8) == 127)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 128, 8) == -128)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u - 1, 8) == -1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 256, 8) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 257, 8) == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 0, 1) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 1, 1) == -1)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
|
||||||
|
#if 0 // does not work with MSVC
|
||||||
|
#if '\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 127)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255)
|
||||||
|
#endif
|
||||||
|
#if L'\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 < 0)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 > 0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_compiler_sanity_check()
|
||||||
|
// assert a sane architecture and compiler
|
||||||
|
// (modern compilers will optimize away most of this code)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct CheckIntegral {
|
||||||
|
struct TestT {
|
||||||
|
T a;
|
||||||
|
T x[2];
|
||||||
|
};
|
||||||
|
template <class U>
|
||||||
|
struct TestU {
|
||||||
|
U a = {};
|
||||||
|
const U b = {};
|
||||||
|
static constexpr U c = {};
|
||||||
|
U x[2] = {};
|
||||||
|
const U y[2] = {};
|
||||||
|
static constexpr U z[2] = {};
|
||||||
|
};
|
||||||
|
template <class U>
|
||||||
|
static void checkU(void) noexcept {
|
||||||
|
{
|
||||||
|
U a = {};
|
||||||
|
const U b = {};
|
||||||
|
constexpr U c = {};
|
||||||
|
U x[2] = {};
|
||||||
|
const U y[2] = {};
|
||||||
|
constexpr U z[2] = {};
|
||||||
|
assert_noexcept(a == 0);
|
||||||
|
assert_noexcept(b == 0);
|
||||||
|
assert_noexcept(c == 0);
|
||||||
|
assert_noexcept(x[0] == 0 && x[1] == 0);
|
||||||
|
assert_noexcept(y[0] == 0 && y[1] == 0);
|
||||||
|
assert_noexcept(z[0] == 0 && z[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
TestU<U> t;
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.b == 0);
|
||||||
|
assert_noexcept(t.c == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
assert_noexcept(t.y[0] == 0 && t.y[1] == 0);
|
||||||
|
assert_noexcept(t.z[0] == 0 && t.z[1] == 0);
|
||||||
|
}
|
||||||
|
#if __cplusplus <= 201703L
|
||||||
|
COMPILE_TIME_ASSERT(std::is_pod<U>::value) // std::is_pod is deprecated in C++20
|
||||||
|
#endif
|
||||||
|
COMPILE_TIME_ASSERT(std::is_standard_layout<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivial<U>::value)
|
||||||
|
// more checks, these are probably implied by std::is_trivial
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_destructible<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_copyable<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<U>::value)
|
||||||
|
// UPX extras
|
||||||
|
COMPILE_TIME_ASSERT(upx_is_integral<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(upx_is_integral_v<U>)
|
||||||
|
}
|
||||||
|
static void check(void) noexcept {
|
||||||
|
{
|
||||||
|
TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
TestT t;
|
||||||
|
mem_clear(&t);
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
checkU<T>();
|
||||||
|
checkU<typename std::add_const<T>::type>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct CheckAlignment {
|
||||||
|
static void check(void) noexcept {
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
|
struct alignas(1) Test1 {
|
||||||
|
char a;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
struct alignas(1) Test2 {
|
||||||
|
char a;
|
||||||
|
T b[3];
|
||||||
|
};
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Test1)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Test2)
|
||||||
|
Test1 t1[7];
|
||||||
|
Test2 t2[7];
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Test1) == 1 + sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Test2) == 1 + 3 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||||
|
UNUSED(t1);
|
||||||
|
UNUSED(t2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct TestBELE {
|
||||||
|
static noinline bool test(void) noexcept {
|
||||||
|
CheckIntegral<T>::check();
|
||||||
|
CheckAlignment<T>::check();
|
||||||
|
// arithmetic checks
|
||||||
|
T allbits = {};
|
||||||
|
assert_noexcept(allbits == 0);
|
||||||
|
allbits += 1;
|
||||||
|
allbits -= 2;
|
||||||
|
T v1;
|
||||||
|
v1 = 1;
|
||||||
|
v1 *= 4;
|
||||||
|
v1 /= 2;
|
||||||
|
v1 -= 1;
|
||||||
|
T v2;
|
||||||
|
v2 = 1;
|
||||||
|
assert_noexcept((v1 == v2));
|
||||||
|
assert_noexcept(!(v1 != v2));
|
||||||
|
assert_noexcept((v1 <= v2));
|
||||||
|
assert_noexcept((v1 >= v2));
|
||||||
|
assert_noexcept(!(v1 < v2));
|
||||||
|
assert_noexcept(!(v1 > v2));
|
||||||
|
v2 ^= allbits;
|
||||||
|
assert_noexcept(!(v1 == v2));
|
||||||
|
assert_noexcept((v1 != v2));
|
||||||
|
assert_noexcept((v1 <= v2));
|
||||||
|
assert_noexcept(!(v1 >= v2));
|
||||||
|
assert_noexcept((v1 < v2));
|
||||||
|
assert_noexcept(!(v1 > v2));
|
||||||
|
v2 += 2;
|
||||||
|
assert_noexcept(v1 == 1);
|
||||||
|
assert_noexcept(v2 == 0);
|
||||||
|
v1 <<= 1;
|
||||||
|
v1 |= v2;
|
||||||
|
v1 >>= 1;
|
||||||
|
v2 &= v1;
|
||||||
|
v2 /= v1;
|
||||||
|
v2 *= v1;
|
||||||
|
v1 += v2;
|
||||||
|
v1 -= v2;
|
||||||
|
assert_noexcept(v1 == 1);
|
||||||
|
assert_noexcept(v2 == 0);
|
||||||
|
if ((v1 ^ v2) != 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
struct TestNoAliasingStruct {
|
||||||
|
static noinline bool test(A *a, B *b) noexcept {
|
||||||
|
*a = 0;
|
||||||
|
*b = 0;
|
||||||
|
*b -= 3;
|
||||||
|
return *a != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class A, class B>
|
||||||
|
static forceinline bool testNoAliasing(A *a, B *b) noexcept {
|
||||||
|
return TestNoAliasingStruct<A, B>::test(a, b);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
struct TestIntegerWrap {
|
||||||
|
static inline bool inc_gt(const T x) noexcept { return x + 1 > x; }
|
||||||
|
static inline bool dec_lt(const T x) noexcept { return x - 1 < x; }
|
||||||
|
static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic exception handling checks to early catch toolchain/qemu/wine/etc problems
|
||||||
|
//
|
||||||
|
|
||||||
|
struct TestDestructor {
|
||||||
|
explicit TestDestructor(int *pp, int vv) noexcept : p(pp), v(vv) {}
|
||||||
|
virtual noinline ~TestDestructor() noexcept { *p = (*p << 2) + v; }
|
||||||
|
int *p;
|
||||||
|
int v;
|
||||||
|
};
|
||||||
|
|
||||||
|
static noinline void throwSomeValue(int x) may_throw {
|
||||||
|
if (x < 0)
|
||||||
|
throw int(x);
|
||||||
|
else
|
||||||
|
throw size_t(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline void check_exceptions_2(void (*func)(int), int *x) may_throw {
|
||||||
|
TestDestructor d(x, *x);
|
||||||
|
func(*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexcept {
|
||||||
|
bool cxx_exception_handling_works = false;
|
||||||
|
int x = 1;
|
||||||
|
try {
|
||||||
|
TestDestructor d(&x, 3);
|
||||||
|
check_exceptions_2(func, &x);
|
||||||
|
} catch (const size_t &e) {
|
||||||
|
if (e == 1 && x == 23)
|
||||||
|
cxx_exception_handling_works = true;
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
assert_noexcept(cxx_exception_handling_works);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic floating point checks to early catch toolchain/qemu/wine/etc problems
|
||||||
|
//
|
||||||
|
|
||||||
|
static noinline float i64_f32_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0f; }
|
||||||
|
static noinline float u64_f32_add_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a + b) / 1000000.0f;
|
||||||
|
}
|
||||||
|
static noinline float i64_f32_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0f; }
|
||||||
|
static noinline float u64_f32_sub_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a - b) / 1000000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline double i64_f64_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0; }
|
||||||
|
static noinline double u64_f64_add_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a + b) / 1000000.0;
|
||||||
|
}
|
||||||
|
static noinline double i64_f64_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0; }
|
||||||
|
static noinline double u64_f64_sub_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a - b) / 1000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Int, class Float>
|
||||||
|
struct TestFloat {
|
||||||
|
static constexpr Int X = 1000000;
|
||||||
|
static noinline Float div(Int a, Float f) { return a / f; }
|
||||||
|
static noinline Float add_div(Int a, Int b, Float f) { return Float(a + b) / f; }
|
||||||
|
static noinline Float sub_div(Int a, Int b, Float f) { return Float(a - b) / f; }
|
||||||
|
static noinline Float add_div_x(Int a, Int b) { return Float(a + b) / Float(X); }
|
||||||
|
static noinline Float sub_div_x(Int a, Int b) { return Float(a - b) / Float(X); }
|
||||||
|
static noinline void check() noexcept {
|
||||||
|
assert_noexcept(div(2 * X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(add_div(X, X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(add_div_x(X, X) == Float(2));
|
||||||
|
assert_noexcept(sub_div(3 * X, X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(sub_div_x(3 * X, X) == Float(2));
|
||||||
|
// extra debugging; floating point edge cases cause portability problems in practice
|
||||||
|
static const char envvar[] = "UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO";
|
||||||
|
if (is_envvar_true(envvar)) {
|
||||||
|
#if defined(__FAST_MATH__)
|
||||||
|
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||||
|
fprintf(stderr, "upx: WARNING: ignoring %s: __FAST_MATH__\n", envvar);
|
||||||
|
#else
|
||||||
|
assert_noexcept(std::isnan(div(0, Float(0))));
|
||||||
|
assert_noexcept(std::isinf(div(1, Float(0))));
|
||||||
|
assert_noexcept(std::isinf(div(Int(-1), Float(0))));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static noinline void check_basic_floating_point(void) noexcept {
|
||||||
|
assert_noexcept(i64_f32_add_div(1000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(u64_f32_add_div(1000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(i64_f32_sub_div(3000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(u64_f32_sub_div(3000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(i64_f64_add_div(1000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(u64_f64_add_div(1000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(i64_f64_sub_div(3000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(u64_f64_sub_div(3000000, 1000000) == 2.0);
|
||||||
|
TestFloat<upx_int32_t, float>::check();
|
||||||
|
TestFloat<upx_uint32_t, float>::check();
|
||||||
|
TestFloat<upx_int64_t, float>::check();
|
||||||
|
TestFloat<upx_uint64_t, float>::check();
|
||||||
|
TestFloat<upx_int32_t, double>::check();
|
||||||
|
TestFloat<upx_uint32_t, double>::check();
|
||||||
|
TestFloat<upx_int64_t, double>::check();
|
||||||
|
TestFloat<upx_uint64_t, double>::check();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#include "../util/miniacc.h"
|
||||||
|
|
||||||
|
void upx_compiler_sanity_check(void) noexcept {
|
||||||
|
check_basic_floating_point();
|
||||||
|
|
||||||
|
if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST")) {
|
||||||
|
// If UPX_DEBUG_DOCTEST_DISABLE is set then we don't want to throw any
|
||||||
|
// exceptions in order to improve debugging experience.
|
||||||
|
} else {
|
||||||
|
// check working C++ exception handling to early catch toolchain/qemu/wine/etc problems
|
||||||
|
check_basic_cxx_exception_handling(throwSomeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check_basic_decltype()
|
||||||
|
{
|
||||||
|
auto a = +0;
|
||||||
|
constexpr auto b = -0;
|
||||||
|
const auto &c = -1;
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<int, decltype(a)>::value))
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<const int, decltype(b)>::value))
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<const int &, decltype(c)>::value))
|
||||||
|
UNUSED(a);
|
||||||
|
UNUSED(b);
|
||||||
|
UNUSED(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
|
||||||
|
#include "../util/miniacc.h"
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(char) == 1)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(short) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(int) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(long) >= 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(void *) >= 4)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
|
||||||
|
|
||||||
|
CheckIntegral<char>::check();
|
||||||
|
CheckIntegral<signed char>::check();
|
||||||
|
CheckIntegral<unsigned char>::check();
|
||||||
|
CheckIntegral<short>::check();
|
||||||
|
CheckIntegral<int>::check();
|
||||||
|
CheckIntegral<long>::check();
|
||||||
|
CheckIntegral<long long>::check();
|
||||||
|
CheckIntegral<ptrdiff_t>::check();
|
||||||
|
CheckIntegral<size_t>::check();
|
||||||
|
CheckIntegral<upx_off_t>::check();
|
||||||
|
CheckIntegral<upx_uintptr_t>::check();
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(upx_charptr_unit_type) == 1)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
|
||||||
|
|
||||||
|
// check UPX_VERSION_xxx
|
||||||
|
{
|
||||||
|
using upx::compile_time::mem_eq;
|
||||||
|
using upx::compile_time::string_len;
|
||||||
|
static_assert(string_len(UPX_VERSION_STRING4) == 4);
|
||||||
|
static_assert(string_len(UPX_VERSION_YEAR) == 4);
|
||||||
|
static_assert(string_len(UPX_VERSION_DATE_ISO) == 10);
|
||||||
|
static_assert(string_len(UPX_VERSION_DATE) == 12 || string_len(UPX_VERSION_DATE) == 13);
|
||||||
|
static_assert(mem_eq(UPX_VERSION_STRING4, UPX_VERSION_STRING, 3));
|
||||||
|
static_assert(mem_eq(UPX_VERSION_YEAR, UPX_VERSION_DATE_ISO, 4));
|
||||||
|
static_assert(mem_eq(UPX_VERSION_YEAR, &UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 5], 4));
|
||||||
|
char buf[16];
|
||||||
|
constexpr long long v = UPX_VERSION_HEX;
|
||||||
|
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld.%lld", (v >> 16), (v >> 8) & 255, v & 255);
|
||||||
|
assert_noexcept(strcmp(buf, UPX_VERSION_STRING) == 0);
|
||||||
|
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld%lld", (v >> 16), (v >> 8) & 255, v & 255);
|
||||||
|
assert_noexcept(strcmp(buf, UPX_VERSION_STRING4) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gitrev[0]) {
|
||||||
|
size_t revlen = strlen(gitrev);
|
||||||
|
if (strncmp(gitrev, "ERROR", 5) == 0) {
|
||||||
|
assert_noexcept(revlen == 5 || revlen == 6);
|
||||||
|
} else {
|
||||||
|
assert_noexcept(revlen == 12 || revlen == 13);
|
||||||
|
}
|
||||||
|
if (revlen == 6 || revlen == 13) {
|
||||||
|
assert_noexcept(gitrev[revlen - 1] == '+');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_noexcept(UPX_RSIZE_MAX_MEM == 805306368);
|
||||||
|
|
||||||
|
#if DEBUG || 1
|
||||||
|
assert_noexcept(TestBELE<LE16>::test());
|
||||||
|
assert_noexcept(TestBELE<LE32>::test());
|
||||||
|
assert_noexcept(TestBELE<LE64>::test());
|
||||||
|
assert_noexcept(TestBELE<BE16>::test());
|
||||||
|
assert_noexcept(TestBELE<BE32>::test());
|
||||||
|
assert_noexcept(TestBELE<BE64>::test());
|
||||||
|
{
|
||||||
|
alignas(16) static const byte dd[32] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0,
|
||||||
|
0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0};
|
||||||
|
const byte *d;
|
||||||
|
const N_BELE_RTP::AbstractPolicy *bele;
|
||||||
|
d = dd + 7;
|
||||||
|
assert_noexcept(upx_adler32(d, 4) == 0x09f003f7);
|
||||||
|
assert_noexcept(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||||
|
assert_noexcept(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
|
assert_noexcept(get_be16(d) == 0xfffe);
|
||||||
|
assert_noexcept(bele->get16(d) == 0xfffe);
|
||||||
|
assert_noexcept(get_be16_signed(d) == -2);
|
||||||
|
assert_noexcept(get_be24(d) == 0xfffefd);
|
||||||
|
assert_noexcept(bele->get24(d) == 0xfffefd);
|
||||||
|
assert_noexcept(get_be24_signed(d) == -259);
|
||||||
|
assert_noexcept(get_be32(d) == 0xfffefdfc);
|
||||||
|
assert_noexcept(bele->get32(d) == 0xfffefdfc);
|
||||||
|
assert_noexcept(get_be32_signed(d) == -66052);
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
assert_noexcept(get_le16(d) == 0xfeff);
|
||||||
|
assert_noexcept(bele->get16(d) == 0xfeff);
|
||||||
|
assert_noexcept(get_le16_signed(d) == -257);
|
||||||
|
assert_noexcept(get_le24(d) == 0xfdfeff);
|
||||||
|
assert_noexcept(bele->get24(d) == 0xfdfeff);
|
||||||
|
assert_noexcept(get_le24_signed(d) == -131329);
|
||||||
|
assert_noexcept(get_le32(d) == 0xfcfdfeff);
|
||||||
|
assert_noexcept(bele->get32(d) == 0xfcfdfeff);
|
||||||
|
assert_noexcept(get_le32_signed(d) == -50462977);
|
||||||
|
assert_noexcept(get_le64_signed(d) == -506097522914230529LL);
|
||||||
|
assert_noexcept(find_be16(d, 2, 0xfffe) == 0);
|
||||||
|
assert_noexcept(find_le16(d, 2, 0xfeff) == 0);
|
||||||
|
assert_noexcept(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||||
|
assert_noexcept(find_le32(d, 4, 0xfcfdfeff) == 0);
|
||||||
|
d += 12;
|
||||||
|
assert_noexcept(get_be16_signed(d) == 32638);
|
||||||
|
assert_noexcept(get_be24_signed(d) == 8355453);
|
||||||
|
assert_noexcept(get_be32_signed(d) == 2138996092);
|
||||||
|
assert_noexcept(get_be64_signed(d) == 9186918263483431288LL);
|
||||||
|
}
|
||||||
|
#if DEBUG >= 1
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
{
|
||||||
|
const unsigned u = i;
|
||||||
|
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
|
||||||
|
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
|
||||||
|
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
|
||||||
|
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
|
||||||
|
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
|
||||||
|
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
|
||||||
|
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
|
||||||
|
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
|
||||||
|
assert_noexcept(sign_extend(u, 32) == i);
|
||||||
|
assert_noexcept(sign_extend(0u - u, 32) == -i);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const upx_uint64_t u = i;
|
||||||
|
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
|
||||||
|
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
|
||||||
|
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
|
||||||
|
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
|
||||||
|
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
|
||||||
|
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
|
||||||
|
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
|
||||||
|
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
|
||||||
|
assert_noexcept(sign_extend(u, 64) == i);
|
||||||
|
assert_noexcept(sign_extend(0ull - u, 64) == -i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned dd;
|
||||||
|
void *const d = ⅆ
|
||||||
|
dd = ne32_to_le32(0xf7f6f5f4);
|
||||||
|
assert_noexcept(get_le26(d) == 0x03f6f5f4);
|
||||||
|
set_le26(d, 0);
|
||||||
|
assert_noexcept(get_le26(d) == 0);
|
||||||
|
assert_noexcept(dd == ne32_to_le32(0xf4000000));
|
||||||
|
set_le26(d, 0xff020304);
|
||||||
|
assert_noexcept(get_le26(d) == 0x03020304);
|
||||||
|
assert_noexcept(dd == ne32_to_le32(0xf7020304));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
upx_uint16_t a = 0;
|
||||||
|
upx_uint32_t b = 0;
|
||||||
|
upx_uint64_t c = 0;
|
||||||
|
set_ne16(&a, 0x04030201); // ignore upper bits
|
||||||
|
set_ne32(&b, 0x04030201);
|
||||||
|
set_ne64(&c, 0x0807060504030201ull);
|
||||||
|
assert_noexcept(a == 0x0201);
|
||||||
|
assert_noexcept(b == 0x04030201);
|
||||||
|
assert_noexcept(c == 0x0807060504030201ull);
|
||||||
|
assert_noexcept(get_ne16(&a) == 0x0201);
|
||||||
|
assert_noexcept(get_ne32(&b) == 0x04030201);
|
||||||
|
assert_noexcept(get_ne64(&c) == 0x0807060504030201ull);
|
||||||
|
}
|
||||||
|
#endif // DEBUG
|
||||||
|
union {
|
||||||
|
short v_short;
|
||||||
|
int v_int;
|
||||||
|
long v_long;
|
||||||
|
long long v_llong;
|
||||||
|
BE16 b16;
|
||||||
|
BE32 b32;
|
||||||
|
BE64 b64;
|
||||||
|
LE16 l16;
|
||||||
|
LE32 l32;
|
||||||
|
LE64 l64;
|
||||||
|
} u;
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.b32));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.l32));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.b64));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.l64));
|
||||||
|
// check working -fno-strict-aliasing
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.v_int));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.v_long));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.v_llong));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_long, &u.v_llong));
|
||||||
|
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::inc_gt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::inc_gt(UINT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::dec_lt(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::dec_lt(0));
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::neg_eq(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(UINT_MAX));
|
||||||
|
// check working -fno-strict-overflow
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::inc_gt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::inc_gt(INT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::dec_lt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::dec_lt(INT_MIN));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::neg_eq(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::neg_eq(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::neg_eq(INT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::neg_eq(INT_MIN)); // special case
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// some doctest test cases
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("assert_noexcept") {
|
||||||
|
// just to make sure that our own assert() macros do not trigger any compiler warnings
|
||||||
|
byte dummy = 0;
|
||||||
|
byte *ptr1 = &dummy;
|
||||||
|
const byte *const ptr2 = &dummy;
|
||||||
|
void *ptr3 = nullptr;
|
||||||
|
assert(true);
|
||||||
|
assert(1);
|
||||||
|
assert(ptr1);
|
||||||
|
assert(ptr2);
|
||||||
|
assert(!ptr3);
|
||||||
|
assert_noexcept(true);
|
||||||
|
assert_noexcept(1);
|
||||||
|
assert_noexcept(ptr1);
|
||||||
|
assert_noexcept(ptr2);
|
||||||
|
assert_noexcept(!ptr3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("acc_vget") {
|
||||||
|
CHECK_EQ(acc_vget_int(0, 0), 0);
|
||||||
|
CHECK_EQ(acc_vget_long(1, -1), 1);
|
||||||
|
CHECK_EQ(acc_vget_acc_int64l_t(2, 1), 2);
|
||||||
|
CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr);
|
||||||
|
if (acc_vget_int(1, 0) > 0)
|
||||||
|
return;
|
||||||
|
assert_noexcept(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ptr_invalidate_and_poison") {
|
||||||
|
int *ip = nullptr; // initialized
|
||||||
|
ptr_invalidate_and_poison(ip);
|
||||||
|
assert(ip != nullptr);
|
||||||
|
(void) ip;
|
||||||
|
double *dp; // not initialized
|
||||||
|
ptr_invalidate_and_poison(dp);
|
||||||
|
assert(dp != nullptr);
|
||||||
|
(void) dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx_getenv") {
|
||||||
|
CHECK_EQ(upx_getenv(nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx_getenv(""), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-aliasing") {
|
||||||
|
bool ok;
|
||||||
|
long v = 0;
|
||||||
|
short *ps = ACC_STATIC_CAST(short *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
int *pi = ACC_STATIC_CAST(int *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
long *pl = ACC_STATIC_CAST(long *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
*ps = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *ps == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pi = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *pi == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*ps = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*pi = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
UNUSED(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-overflow") {
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MAX, 0) + 1, INT_MIN);
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MIN, 0) - 1, INT_MAX);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MAX, 0) + 1, LONG_MIN);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MIN, 0) - 1, LONG_MAX);
|
||||||
|
bool ok;
|
||||||
|
int i;
|
||||||
|
i = INT_MAX;
|
||||||
|
i += 1;
|
||||||
|
ok = i == INT_MIN;
|
||||||
|
CHECK(ok);
|
||||||
|
i = INT_MIN;
|
||||||
|
i -= 1;
|
||||||
|
ok = i == INT_MAX;
|
||||||
|
CHECK(ok);
|
||||||
|
UNUSED(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc snprintf") {
|
||||||
|
// runtime check that Windows/MinGW <stdio.h> works as expected
|
||||||
|
char buf[64];
|
||||||
|
long long ll = acc_vget_int(-1, 0);
|
||||||
|
unsigned long long llu = (unsigned long long) ll;
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu);
|
||||||
|
CHECK_EQ(strcmp(buf, "-3.-2.-1.3.2.18446744073709551615"), 0);
|
||||||
|
intmax_t im = ll;
|
||||||
|
uintmax_t um = llu;
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%jd", -4, 0, 0, 0, 0, 0, 0, 0, 4, im);
|
||||||
|
CHECK_EQ(strcmp(buf, "-4.0.0.0.0.0.0.0.4.-1"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%ju", -5, 0, 0, 0, 0, 0, 0, 0, 5, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-5.0.0.0.0.0.0.0.5.18446744073709551615"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%jx", -6, 0, 0, 0, 0, 0, 0, 0, 6, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-6.0.0.0.0.0.0.0.6.ffffffffffffffff"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%#jx", -7, 0, 0, 0, 0, 0, 0, 0, 7, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-7.0.0.0.0.0.0.0.7.0xffffffffffffffff"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#X %#lx %#llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#06x %#06lX %#06llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0x001a 0X001B 0x001c"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#6x %#6lx %#6llX", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, " 0x1a 0x1b 0X1C"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#-6X %#-6lx %#-6llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c "), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc qsort") {
|
||||||
|
// runtime check that libc qsort() never compares identical objects
|
||||||
|
// UPDATE: while only poor implementations of qsort() would actually do this
|
||||||
|
// it is probably allowed by the standard, so skip this test by default
|
||||||
|
if (!is_envvar_true("UPX_DEBUG_TEST_LIBC_QSORT"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct Elem {
|
||||||
|
upx_uint16_t id;
|
||||||
|
upx_uint16_t value;
|
||||||
|
static int __acc_cdecl_qsort compare(const void *aa, const void *bb) noexcept {
|
||||||
|
const Elem *a = (const Elem *) aa;
|
||||||
|
const Elem *b = (const Elem *) bb;
|
||||||
|
assert_noexcept(a->id != b->id); // check not IDENTICAL
|
||||||
|
return a->value < b->value ? -1 : (a->value == b->value ? 0 : 1);
|
||||||
|
}
|
||||||
|
static noinline bool check_sort(upx_sort_func_t sort, Elem *e, size_t n, bool is_stable) {
|
||||||
|
upx_uint32_t x = 5381 + (upx_rand() & 255);
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
e[i].id = (upx_uint16_t) i;
|
||||||
|
x = x * 33 + 1 + (i & 255);
|
||||||
|
e[i].value = (upx_uint16_t) ((x >> 4) & 15);
|
||||||
|
}
|
||||||
|
sort(e, n, sizeof(Elem), Elem::compare);
|
||||||
|
// verify
|
||||||
|
for (size_t i = 1; i < n; i++) {
|
||||||
|
if very_unlikely (e[i - 1].value > e[i].value)
|
||||||
|
return false;
|
||||||
|
if (is_stable)
|
||||||
|
if very_unlikely (e[i - 1].value == e[i].value && e[i - 1].id >= e[i].id)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constexpr size_t N = 4096;
|
||||||
|
Elem e[N];
|
||||||
|
for (size_t n = 0; n <= N; n = 2 * n + 1) {
|
||||||
|
// system sort functions
|
||||||
|
CHECK(Elem::check_sort(::qsort, e, n, false)); // libc qsort()
|
||||||
|
#if UPX_CONFIG_USE_STABLE_SORT
|
||||||
|
upx_sort_func_t wrap_stable_sort = [](void *aa, size_t nn, size_t, upx_compare_func_t cc) {
|
||||||
|
upx_std_stable_sort<sizeof(Elem)>(aa, nn, cc);
|
||||||
|
};
|
||||||
|
CHECK(Elem::check_sort(wrap_stable_sort, e, n, true)); // std::stable_sort()
|
||||||
|
#endif
|
||||||
|
// simple UPX sort functions
|
||||||
|
CHECK(Elem::check_sort(upx_gnomesort, e, n, true));
|
||||||
|
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n, false));
|
||||||
|
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,554 @@
|
|||||||
|
/* dt_cxxlib.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// lots of tests (and probably quite a number of redundant tests)
|
||||||
|
// modern compilers will optimize away much of this code
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#include <vector> // std::vector
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compile-time checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// need extra parenthesis because the C preprocessor does not understand C++ templates
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, int, char>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, char, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
|
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
|
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("ab") == 3)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L'a') == sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"") == 1 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"a") == 2 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"ab") == 3 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0LL) == sizeof(long long))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(sizeof(0)) == sizeof(size_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned))
|
||||||
|
#if 0
|
||||||
|
// works, but may trigger clang/gcc warnings "-Wunused-value"
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1LL, 1)) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1, 1LL)) == sizeof(long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace compile_time = upx::compile_time;
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("ab") == 2)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("abc") == 3)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("abc", "ab"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "ab"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "aba"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_ne("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const char *) nullptr, nullptr, 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const byte *) nullptr, nullptr, 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("", "", 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("abc", "abc", 3))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::mem_eq("abc", "abz", 3))
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("std::vector") {
|
||||||
|
constexpr size_t N = 16;
|
||||||
|
std::vector<int> v(N);
|
||||||
|
CHECK(v.end() - v.begin() == N);
|
||||||
|
CHECK(&v[0] == &(*(v.begin())));
|
||||||
|
// CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal??
|
||||||
|
// TODO later: make sure that this throws
|
||||||
|
#if defined(_LIBCPP_HARDENING_MODE_DEBUG) && \
|
||||||
|
(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG)
|
||||||
|
CHECK_THROWS((void) &v[N]);
|
||||||
|
#endif
|
||||||
|
UNUSED(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// UPX_CXX_DISABLE_xxx
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyType1 {
|
||||||
|
MyType1() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(MyType1)
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyType1)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(MyType1)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyType2 {
|
||||||
|
MyType2() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyType2)
|
||||||
|
typedef MyType2<TA, TB, TC> Self;
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(Self)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(Self)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyVType1 {
|
||||||
|
MyVType1() noexcept {}
|
||||||
|
virtual ~MyVType1() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(MyVType1)
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyVType1)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(MyVType1)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyVType2 {
|
||||||
|
MyVType2() noexcept {}
|
||||||
|
virtual ~MyVType2() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyVType2)
|
||||||
|
typedef MyVType2<TA, TB, TC> Self;
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(Self)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Self)
|
||||||
|
};
|
||||||
|
TEST_CASE("UPX_CXX_DISABLE_xxx") {
|
||||||
|
MyType1<char, int, 1> dummy1;
|
||||||
|
MyType2<char, int, 2> dummy2;
|
||||||
|
MyVType1<char, int, 1> vdummy1;
|
||||||
|
MyVType2<char, int, 2> vdummy2;
|
||||||
|
(void) dummy1;
|
||||||
|
(void) dummy2;
|
||||||
|
(void) vdummy1;
|
||||||
|
(void) vdummy2;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace test_disable_new_delete {
|
||||||
|
|
||||||
|
struct A1 {
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
struct A2 {
|
||||||
|
int a;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(A2)
|
||||||
|
};
|
||||||
|
struct B1_A1 : public A1 {
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
struct B1_A2 : public A2 {
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
struct B2_A1 : public A1 {
|
||||||
|
int b;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A1)
|
||||||
|
};
|
||||||
|
struct B2_A2 : public A2 {
|
||||||
|
int b;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A2)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct X1 {
|
||||||
|
virtual ~X1() noexcept {}
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
struct X2 {
|
||||||
|
virtual ~X2() noexcept {}
|
||||||
|
int x;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(X2)
|
||||||
|
};
|
||||||
|
struct Y1_X1 : public X1 {
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
struct Y1_X2 : public X2 {
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
struct Y2_X1 : public X1 {
|
||||||
|
int y;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Y2_X1)
|
||||||
|
};
|
||||||
|
struct Y2_X2 : public X2 {
|
||||||
|
int y;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Y2_X2)
|
||||||
|
};
|
||||||
|
struct Z1_X1 : public X1 {
|
||||||
|
virtual ~Z1_X1() noexcept {}
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
struct Z1_X2 : public X2 {
|
||||||
|
virtual ~Z1_X2() noexcept {}
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
struct Z2_X1 : public X1 {
|
||||||
|
virtual ~Z2_X1() noexcept {}
|
||||||
|
int z;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Z2_X1)
|
||||||
|
};
|
||||||
|
struct Z2_X2 : public X2 {
|
||||||
|
virtual ~Z2_X2() noexcept {}
|
||||||
|
int z;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Z2_X2)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace test_disable_new_delete
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// util
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if WITH_THREADS
|
||||||
|
TEST_CASE("upx::ptr_std_atomic_cast") {
|
||||||
|
// pointer-size
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((void **) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((uintptr_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_uintptr_t *) nullptr), nullptr);
|
||||||
|
#if 1
|
||||||
|
// more fundamental types
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((char *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((short *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((int *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((long *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((size_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int8_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int16_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int32_t *) nullptr), nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("upx::atomic_exchange") {
|
||||||
|
{
|
||||||
|
upx_uintptr_t x = (upx_uintptr_t) 0 - 1;
|
||||||
|
upx_uintptr_t y = upx::atomic_exchange(&x, (upx_uintptr_t) 2);
|
||||||
|
CHECK_EQ(x, 2);
|
||||||
|
CHECK_EQ(y, (upx_uintptr_t) 0 - 1);
|
||||||
|
UNUSED(y);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const int buf[2] = {101, 202};
|
||||||
|
const int *ptr_array[2] = {&buf[0], &buf[1]};
|
||||||
|
assert_noexcept(*ptr_array[0] == 101 && *ptr_array[1] == 202);
|
||||||
|
const int *p = upx::atomic_exchange(&ptr_array[0], ptr_array[1]);
|
||||||
|
CHECK_EQ(p, buf + 0);
|
||||||
|
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 202);
|
||||||
|
p = upx::atomic_exchange(&ptr_array[1], p);
|
||||||
|
CHECK_EQ(p, buf + 1);
|
||||||
|
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 101);
|
||||||
|
UNUSED(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ObjectDeleter 1") {
|
||||||
|
LE16 *o = nullptr; // object
|
||||||
|
LE32 *a = nullptr; // array
|
||||||
|
LE64 *m = nullptr; // malloc
|
||||||
|
{
|
||||||
|
auto o_deleter = upx::ObjectDeleter(&o, 1);
|
||||||
|
o = new LE16;
|
||||||
|
assert(o != nullptr);
|
||||||
|
auto a_deleter = upx::ArrayDeleter(&a, 1);
|
||||||
|
a = New(LE32, 1);
|
||||||
|
assert(a != nullptr);
|
||||||
|
auto m_deleter = upx::MallocDeleter(&m, 1);
|
||||||
|
m = (LE64 *) ::malloc(sizeof(LE64));
|
||||||
|
assert(m != nullptr);
|
||||||
|
}
|
||||||
|
assert(o == nullptr);
|
||||||
|
assert(a == nullptr);
|
||||||
|
assert(m == nullptr);
|
||||||
|
// test "const" versions
|
||||||
|
{
|
||||||
|
const auto o_deleter = upx::ObjectDeleter(&o, 1);
|
||||||
|
o = new LE16;
|
||||||
|
assert(o != nullptr);
|
||||||
|
const auto a_deleter = upx::ArrayDeleter(&a, 1);
|
||||||
|
a = New(LE32, 1);
|
||||||
|
assert(a != nullptr);
|
||||||
|
const auto m_deleter = upx::MallocDeleter(&m, 1);
|
||||||
|
m = (LE64 *) ::malloc(sizeof(LE64));
|
||||||
|
assert(m != nullptr);
|
||||||
|
}
|
||||||
|
assert(o == nullptr);
|
||||||
|
assert(a == nullptr);
|
||||||
|
assert(m == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ObjectDeleter 2") {
|
||||||
|
constexpr size_t N = 2;
|
||||||
|
BE16 *o[N]; // multiple objects
|
||||||
|
BE32 *a[N]; // multiple arrays
|
||||||
|
BE64 *m[N]; // multiple mallocs
|
||||||
|
{
|
||||||
|
auto o_deleter = upx::ObjectDeleter(o, 0);
|
||||||
|
auto a_deleter = upx::ArrayDeleter(a, 0);
|
||||||
|
auto m_deleter = upx::MallocDeleter(m, 0);
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
o[i] = new BE16;
|
||||||
|
assert(o[i] != nullptr);
|
||||||
|
o_deleter.count += 1;
|
||||||
|
a[i] = New(BE32, 1 + i);
|
||||||
|
assert(a[i] != nullptr);
|
||||||
|
a_deleter.count += 1;
|
||||||
|
m[i] = (BE64 *) ::malloc(sizeof(BE64));
|
||||||
|
assert(m[i] != nullptr);
|
||||||
|
m_deleter.count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
assert(o[i] == nullptr);
|
||||||
|
assert(a[i] == nullptr);
|
||||||
|
assert(m[i] == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ptr_static_cast") {
|
||||||
|
// check that we do not trigger any -Wcast-align warnings
|
||||||
|
using upx::ptr_static_cast;
|
||||||
|
void *vp = nullptr;
|
||||||
|
byte *bp = nullptr;
|
||||||
|
int *ip = nullptr;
|
||||||
|
double *dp = nullptr;
|
||||||
|
|
||||||
|
assert((vp == ptr_static_cast<void *>(vp)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(bp)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(ip)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(dp)));
|
||||||
|
|
||||||
|
assert((bp == ptr_static_cast<byte *>(vp)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(bp)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(ip)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(dp)));
|
||||||
|
|
||||||
|
assert((ip == ptr_static_cast<int *>(vp)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(bp)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(ip)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(dp)));
|
||||||
|
|
||||||
|
assert((dp == ptr_static_cast<double *>(vp)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(bp)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(ip)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(dp)));
|
||||||
|
|
||||||
|
const byte *bc = nullptr;
|
||||||
|
const int *ic = nullptr;
|
||||||
|
assert((bc == ptr_static_cast<byte *>(bp)));
|
||||||
|
assert((bc == ptr_static_cast<const byte *>(bc)));
|
||||||
|
assert((bc == ptr_static_cast<byte *>(ip)));
|
||||||
|
assert((bc == ptr_static_cast<const byte *>(ic)));
|
||||||
|
assert((ic == ptr_static_cast<int *>(bp)));
|
||||||
|
assert((ic == ptr_static_cast<const int *>(bc)));
|
||||||
|
assert((ic == ptr_static_cast<int *>(ip)));
|
||||||
|
assert((ic == ptr_static_cast<const int *>(ic)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::noncopyable") {
|
||||||
|
struct Test : private upx::noncopyable {
|
||||||
|
int v = 1;
|
||||||
|
};
|
||||||
|
Test t = {};
|
||||||
|
CHECK(t.v == 1);
|
||||||
|
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
|
||||||
|
// @COMPILER_BUG @MSVC_BUG
|
||||||
|
t.v = 0;
|
||||||
|
#else
|
||||||
|
mem_clear(&t);
|
||||||
|
#endif
|
||||||
|
CHECK(t.v == 0);
|
||||||
|
constexpr Test x = {};
|
||||||
|
static_assert(x.v == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// TriBool checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class T>
|
||||||
|
struct TestTriBool {
|
||||||
|
static noinline void test(bool expect_true) {
|
||||||
|
static_assert(std::is_class<T>::value);
|
||||||
|
static_assert(std::is_nothrow_default_constructible<T>::value);
|
||||||
|
static_assert(std::is_nothrow_destructible<T>::value);
|
||||||
|
static_assert(std::is_standard_layout<T>::value);
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value);
|
||||||
|
static_assert(sizeof(typename T::value_type) == sizeof(typename T::underlying_type));
|
||||||
|
static_assert(alignof(typename T::value_type) == alignof(typename T::underlying_type));
|
||||||
|
#if defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||||
|
// broken compiler or broken ABI
|
||||||
|
#elif defined(__i386__) && defined(__GNUC__) && (__GNUC__ == 7) && !defined(__clang__)
|
||||||
|
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
|
||||||
|
// i386: "long long" enum align bug/ABI problem on older compilers
|
||||||
|
static_assert(alignof(T) <= alignof(typename T::underlying_type));
|
||||||
|
#else
|
||||||
|
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
|
||||||
|
static_assert(alignof(T) == alignof(typename T::underlying_type));
|
||||||
|
#endif
|
||||||
|
static_assert(!bool(T(false)));
|
||||||
|
static_assert(bool(T(true)));
|
||||||
|
static_assert(bool(T(T::Third)) == T::is_third_true);
|
||||||
|
static_assert(T(false) == T::False);
|
||||||
|
static_assert(T(true) == T::True);
|
||||||
|
static_assert(T(T::False) == T::False);
|
||||||
|
static_assert(T(T::True) == T::True);
|
||||||
|
static_assert(T(T::Third) == T::Third);
|
||||||
|
static_assert(T(T::Third) == T(9));
|
||||||
|
static_assert(T(8) == T(9));
|
||||||
|
static_assert(!(T(0) == T(9)));
|
||||||
|
static_assert(!(T(1) == T(9)));
|
||||||
|
static_assert(T(T::Third) == 9);
|
||||||
|
static_assert(T(8) == 9);
|
||||||
|
static_assert(!(T(0) == 9));
|
||||||
|
static_assert(!(T(1) == 9));
|
||||||
|
constexpr T array[] = {false, true, T::Third};
|
||||||
|
static_assert(array[0].isStrictFalse());
|
||||||
|
static_assert(array[1].isStrictTrue());
|
||||||
|
static_assert(array[2].isThird());
|
||||||
|
static_assert(sizeof(array) == 3 * sizeof(T));
|
||||||
|
T a;
|
||||||
|
assert(a.getValue() == T::False);
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = false;
|
||||||
|
assert(a.getValue() == T::False);
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = true;
|
||||||
|
assert(a.getValue() == T::True);
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = T::Third;
|
||||||
|
assert(a.getValue() == T::Third);
|
||||||
|
assert(T::is_third_true == expect_true);
|
||||||
|
if (expect_true) {
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
} else {
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
}
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(!a.isStrictBool());
|
||||||
|
assert(a.isThird());
|
||||||
|
a = 99;
|
||||||
|
assert(a.getValue() == T::Third);
|
||||||
|
if (expect_true) {
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
assert((!a ? false : true));
|
||||||
|
} else {
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((a ? false : true));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
}
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(!a.isStrictBool());
|
||||||
|
assert(a.isThird());
|
||||||
|
mem_clear(&a);
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("upx::TriBool") {
|
||||||
|
using upx::TriBool, upx::tribool;
|
||||||
|
static_assert(!tribool(false));
|
||||||
|
static_assert(tribool(true));
|
||||||
|
static_assert(!tribool(tribool::Third));
|
||||||
|
TestTriBool<tribool>::test(false);
|
||||||
|
#if DEBUG || 1
|
||||||
|
TestTriBool<TriBool<upx_int8_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint8_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int16_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint16_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int32_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint32_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int64_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint64_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int8_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint8_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int16_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint16_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int32_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint32_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int64_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint64_t, true> >::test(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* dt_impl.cpp -- doctest support code implementation
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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 >= 6)
|
||||||
|
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||||
|
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
|
||||||
|
#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
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,25 +20,22 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "mem.h"
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return adler;
|
return adler;
|
||||||
assert(buf != NULL);
|
assert(buf != nullptr);
|
||||||
#if 1
|
#if 1
|
||||||
return upx_ucl_adler32(buf, len, adler);
|
return upx_ucl_adler32(buf, len, adler);
|
||||||
#else
|
#else
|
||||||
@@ -47,37 +43,32 @@ unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
#if 0 /* UNUSED */
|
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return crc;
|
return crc;
|
||||||
assert(buf != NULL);
|
assert(buf != nullptr);
|
||||||
#if 1
|
#if 1
|
||||||
return upx_ucl_crc32(buf, len, crc);
|
return upx_ucl_crc32(buf, len, crc);
|
||||||
#else
|
#else
|
||||||
return upx_zlib_crc32(buf, len, crc);
|
return upx_zlib_crc32(buf, len, crc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* UNUSED */
|
#endif // UNUSED
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
|
||||||
upx_callback_p cb,
|
upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
upx_compress_result_t cresult_buffer;
|
upx_compress_result_t cresult_buffer;
|
||||||
|
|
||||||
assert(method > 0); assert(level > 0);
|
assert(method > 0);
|
||||||
|
assert(level > 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// set available bytes in dst
|
// set available bytes in dst
|
||||||
@@ -87,68 +78,76 @@ int upx_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
// force users to provide *dst_len
|
// force users to provide *dst_len
|
||||||
assert(*dst_len != 0);
|
assert(*dst_len != 0);
|
||||||
#endif
|
#endif
|
||||||
// for UPX, we always require a reasonably sized outbut buffer
|
// for UPX, we always require a reasonably sized output buffer
|
||||||
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||||
|
|
||||||
if (!cresult)
|
if (!cresult)
|
||||||
cresult = &cresult_buffer;
|
cresult = &cresult_buffer;
|
||||||
memset(cresult, 0, sizeof(*cresult));
|
cresult->reset();
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->method = method;
|
cresult->debug.method = method;
|
||||||
cresult->level = level;
|
cresult->debug.level = level;
|
||||||
cresult->u_len = src_len;
|
cresult->debug.u_len = src_len;
|
||||||
cresult->c_len = 0;
|
cresult->debug.c_len = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if __acc_cte(0) {
|
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)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
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,
|
r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
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
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->c_len = *dst_len;
|
cresult->debug.c_len = *dst_len;
|
||||||
#endif
|
#endif
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_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 method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
assert(src_len < *dst_len); // must be compressed
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = NULL;
|
cresult = nullptr;
|
||||||
|
|
||||||
if __acc_cte(0) {
|
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)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
@@ -164,38 +163,42 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
else if (M_IS_DEFLATE(method))
|
else if (M_IS_DEFLATE(method))
|
||||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
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
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_test_overlap ( const upx_bytep buf,
|
int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len,
|
||||||
const upx_bytep tbuf,
|
unsigned *dst_len, int method, const upx_compress_result_t *cresult) {
|
||||||
unsigned src_off, unsigned src_len,
|
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = NULL;
|
cresult = nullptr;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
assert(src_len < *dst_len); // must be compressed
|
assert(src_len < *dst_len); // must be compressed
|
||||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
assert((int)overlap_overhead > 0);
|
assert((int) overlap_overhead > 0);
|
||||||
|
|
||||||
if __acc_cte(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)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
@@ -207,11 +210,16 @@ int upx_test_overlap ( const upx_bytep buf,
|
|||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
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);
|
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
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,111 +20,146 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef __UPX_COMPRESS_H
|
// clang-format off
|
||||||
#define __UPX_COMPRESS_H 1
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#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)
|
#if (WITH_LZMA)
|
||||||
int upx_lzma_init(void);
|
int upx_lzma_init(void);
|
||||||
const char *upx_lzma_version_string(void);
|
const char *upx_lzma_version_string(void);
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
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,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
int upx_nrv_init(void);
|
int upx_nrv_init(void);
|
||||||
const char *upx_nrv_version_string(void);
|
const char *upx_nrv_version_string(void);
|
||||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
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,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_nrv_test_overlap ( const upx_bytep buf,
|
int upx_nrv_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
int upx_ucl_init(void);
|
int upx_ucl_init(void);
|
||||||
const char *upx_ucl_version_string(void);
|
const char *upx_ucl_version_string(void);
|
||||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
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,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
|
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
|
||||||
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
|
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
int upx_zlib_init(void);
|
int upx_zlib_init(void);
|
||||||
const char *upx_zlib_version_string(void);
|
const char *upx_zlib_version_string(void);
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
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,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
|
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
|
||||||
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (WITH_ZSTD)
|
||||||
#endif /* already included */
|
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
|
||||||
|
|
||||||
/* vim:set ts=4 sw=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-2024 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,554 @@
|
|||||||
|
/* compress_lzma.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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"
|
||||||
|
#endif
|
||||||
|
#if (ACC_CC_GNUC >= 0x040200)
|
||||||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
|
#endif
|
||||||
|
#if (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: 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.
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// 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) {
|
||||||
|
oassign(res->pos_bits, lcconf->pos_bits);
|
||||||
|
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||||
|
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||||
|
oassign(res->dict_size, lcconf->dict_size);
|
||||||
|
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,369 @@
|
|||||||
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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 (ucl_init() != UCL_E_OK)
|
||||||
|
return -1;
|
||||||
|
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,310 @@
|
|||||||
|
/* compress_zlib.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 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"
|
||||||
|
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
|
||||||
|
#define ZLIB_CONST 1
|
||||||
|
#include <zlib/zlib.h>
|
||||||
|
#include <zlib/deflate.h>
|
||||||
|
// NOLINTEND(clang-analyzer-optin.performance.Padding)
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset() noexcept {
|
||||||
|
mem_clear(this);
|
||||||
|
mem_level.reset();
|
||||||
|
window_bits.reset();
|
||||||
|
strategy.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
oassign(mem_level, lcconf->mem_level);
|
||||||
|
oassign(window_bits, lcconf->window_bits);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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-2024 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,528 +0,0 @@
|
|||||||
/* compress_lzma.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2017 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
|
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
#if (ACC_CC_MSC)
|
|
||||||
# pragma warning(disable: 4456) // -Wno-shadow
|
|
||||||
#endif
|
|
||||||
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
|
||||||
# pragma warning(disable: 4127) // warning C4127: conditional expression is constant
|
|
||||||
#endif
|
|
||||||
#if (ACC_CC_INTELC_GNUC)
|
|
||||||
# pragma warning(error: 424) // #424: extra ";" ignored
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// compress defaults
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
static int prepare(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;
|
|
||||||
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_c;
|
|
||||||
res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
|
|
||||||
res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value_c;
|
|
||||||
res->dict_size = lzma_compress_config_t::dict_size_t::default_value_c;
|
|
||||||
res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
|
|
||||||
// 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 maxmimum 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)
|
|
||||||
{
|
|
||||||
oassign(res->pos_bits, lcconf->pos_bits);
|
|
||||||
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
|
||||||
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
|
||||||
oassign(res->dict_size, lcconf->dict_size);
|
|
||||||
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 + (768 << (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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// compress - cruft because of pseudo-COM layer
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#undef MSDOS
|
|
||||||
#undef OS2
|
|
||||||
#undef _WIN32
|
|
||||||
#undef _WIN32_WCE
|
|
||||||
#undef COMPRESS_MF_MT
|
|
||||||
#undef _NO_EXCEPTIONS
|
|
||||||
#include "C/Common/MyInitGuid.h"
|
|
||||||
//#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
|
||||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
|
||||||
|
|
||||||
namespace MyLzma {
|
|
||||||
|
|
||||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
|
||||||
{
|
|
||||||
virtual ~InStream() { }
|
|
||||||
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;
|
|
||||||
memmove(data, b_buf + b_pos, size);
|
|
||||||
b_pos += size;
|
|
||||||
if (processedSize != NULL) *processedSize = size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
|
||||||
{
|
|
||||||
virtual ~OutStream() { }
|
|
||||||
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;
|
|
||||||
memmove(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
|
|
||||||
{
|
|
||||||
virtual ~ProgressInfo() { }
|
|
||||||
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
|
|
||||||
|
|
||||||
#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"
|
|
||||||
#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];
|
|
||||||
const unsigned nprops = 8;
|
|
||||||
static const wchar_t matchfinder[] = L"BT4";
|
|
||||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
|
||||||
pr[7].vt = VT_BSTR; pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
|
||||||
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;
|
|
||||||
if (prepare(res, src_len, method, level, lcconf) != 0)
|
|
||||||
goto error;
|
|
||||||
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;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
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);
|
|
||||||
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(Byte((t << 3) | res->pos_bits));
|
|
||||||
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
|
|
||||||
|
|
||||||
rh = enc.Code(&is, &os, NULL, NULL, &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;
|
|
||||||
//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
|
|
||||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
|
||||||
#include "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; memset(&s, 0, sizeof(s));
|
|
||||||
SizeT src_out = 0, dst_out = 0;
|
|
||||||
int r = UPX_E_ERROR;
|
|
||||||
int rh;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
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, so we use an extra memcmp().
|
|
||||||
if (tbuf != NULL && 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)
|
|
||||||
{
|
|
||||||
#if (WITH_LZMA == 0x443)
|
|
||||||
return "4.43";
|
|
||||||
#else
|
|
||||||
# error "unknown WITH_LZMA version"
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
@@ -1,320 +0,0 @@
|
|||||||
/* compress_ucl.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2017 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
|
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
|
||||||
#if !(WITH_UCL)
|
|
||||||
extern int compress_ucl_dummy;
|
|
||||||
int compress_ucl_dummy = 0;
|
|
||||||
#else
|
|
||||||
|
|
||||||
#if 1 && !(UCL_USE_ASM) && (ACC_ARCH_I386)
|
|
||||||
# if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
|
||||||
# define UCL_USE_ASM 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if (UCL_NO_ASM)
|
|
||||||
# undef UCL_USE_ASM
|
|
||||||
#endif
|
|
||||||
#if (ACC_CFG_NO_UNALIGNED)
|
|
||||||
# undef UCL_USE_ASM
|
|
||||||
#endif
|
|
||||||
#if 1 && (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 __UCL_CDECL 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)
|
|
||||||
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // 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
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
|
|
||||||
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
|
||||||
}
|
|
||||||
|
|
||||||
int upx_ucl_init(void)
|
|
||||||
{
|
|
||||||
if (ucl_init() != UCL_E_OK)
|
|
||||||
return -1;
|
|
||||||
#if defined(UPX_OFFICIAL_BUILD)
|
|
||||||
if (UCL_VERSION != ucl_version())
|
|
||||||
return -2;
|
|
||||||
#endif
|
|
||||||
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
|
|
||||||
|
|
||||||
#endif /* WITH_UCL */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
/* compress_zlib.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2017 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
|
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#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 !(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 = ACC_UNCONST_CAST(upx_bytep, src);
|
|
||||||
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 = ACC_UNCONST_CAST(upx_bytep, 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)
|
|
||||||
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, so we use an extra memcmp().
|
|
||||||
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
return UPX_E_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// misc
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
int upx_zlib_init(void)
|
|
||||||
{
|
|
||||||
#if defined(UPX_OFFICIAL_BUILD)
|
|
||||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
|
||||||
return -2;
|
|
||||||
#endif
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* WITH_ZLIB */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
+545
-408
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,58 +33,41 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_FILE;
|
return CON_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
#if 1
|
#if 1
|
||||||
fputs(s,f);
|
fputs(s, f);
|
||||||
#else
|
#else
|
||||||
/* filter out all ANSI sequences */
|
/* filter out all ANSI sequences */
|
||||||
int c;
|
int c;
|
||||||
while ((c = *s++) != 0)
|
while ((c = *s++) != 0) {
|
||||||
{
|
if (c == '\033' && *s == ']') {
|
||||||
if (c == '\033' && *s == ']')
|
|
||||||
{
|
|
||||||
while (*s && *s != 'm')
|
while (*s && *s != 'm')
|
||||||
s++;
|
s++;
|
||||||
}
|
} else
|
||||||
else
|
fputc(c, f);
|
||||||
fputc(c,f);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_file = {init, set_fg, print0, intro};
|
||||||
console_t console_file =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,10 +25,9 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
#include "conf.h"
|
FILE *con_term = nullptr;
|
||||||
|
|
||||||
FILE *con_term = NULL;
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -36,19 +35,17 @@ FILE *con_term = NULL;
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static console_t * const me = &console_init;
|
static console_t *const me = &console_init;
|
||||||
console_t * con = &console_init;
|
console_t *con = &console_init;
|
||||||
|
|
||||||
int con_mode = CON_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;
|
int k;
|
||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
assert(c->init);
|
assert(c->init);
|
||||||
k = c->init(f,opt->console,con_mode);
|
k = c->init(f, opt->console, con_mode);
|
||||||
if (k == CON_INIT)
|
if (k == CON_INIT)
|
||||||
return;
|
return;
|
||||||
#if 0
|
#if 0
|
||||||
@@ -56,11 +53,10 @@ static void try_init(console_t *c, FILE *f)
|
|||||||
if (k != opt->console)
|
if (k != opt->console)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
if (k > con_mode)
|
if (k > con_mode) {
|
||||||
{
|
|
||||||
con_mode = k;
|
con_mode = k;
|
||||||
con = c;
|
con = c;
|
||||||
con->init = 0;
|
con->init = nullptr;
|
||||||
if (!con->set_fg)
|
if (!con->set_fg)
|
||||||
con->set_fg = console_none.set_fg;
|
con->set_fg = console_none.set_fg;
|
||||||
if (!con->print0)
|
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);
|
assert(con_mode == CON_INIT);
|
||||||
|
|
||||||
try_init(&console_none,f);
|
try_init(&console_none, f);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
assert(con == &console_none);
|
assert(con == &console_none);
|
||||||
if (opt->console == CON_NONE || opt->to_stdout)
|
if (opt->console == CON_NONE || opt->to_stdout)
|
||||||
return con_mode;
|
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))
|
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||||
return con_mode;
|
return con_mode;
|
||||||
|
|
||||||
#if (USE_ANSI)
|
#if (USE_ANSI)
|
||||||
try_init(&console_ansi_mono,f);
|
try_init(&console_ansi_mono, f);
|
||||||
try_init(&console_ansi_color,f);
|
try_init(&console_ansi_color, f);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
try_init(&console_screen,f);
|
try_init(&console_screen, f);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_AALIB)
|
#if (USE_AALIB)
|
||||||
try_init(&console_aalib,f);
|
try_init(&console_aalib, f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return con_mode;
|
return con_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
if (con != me)
|
if (con != me)
|
||||||
return con_mode;
|
return con_mode;
|
||||||
assert(o == -1);
|
assert(o == -1);
|
||||||
@@ -114,47 +106,34 @@ static int init(FILE *f, int o, int now)
|
|||||||
return do_init(f);
|
return do_init(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
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)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
return con->intro(f);
|
return con->intro(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_init = {init, set_fg, nullptr, intro};
|
||||||
|
|
||||||
console_t console_init =
|
void con_fprintf(FILE *f, const char *format, ...) {
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
va_list args;
|
||||||
char buf[80*25];
|
char buf[80 * 25];
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
upx_vsnprintf(buf, sizeof(buf), format,args);
|
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
con->print0(f,buf);
|
con->print0(f, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,44 +33,30 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_NONE;
|
return CON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(s);
|
UNUSED(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_none = {init, set_fg, print0, intro};
|
||||||
console_t console_none =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -35,16 +34,14 @@
|
|||||||
#define mask_fg 0x0f
|
#define mask_fg 0x0f
|
||||||
#define mask_bg 0xf0
|
#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;
|
int fg, bg;
|
||||||
|
|
||||||
if (s->init(s,fd) != 0)
|
if (s->init(s, fd) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
||||||
@@ -59,8 +56,7 @@ static int do_init(screen_t *s, int fd)
|
|||||||
if (fg == (bg >> 4))
|
if (fg == (bg >> 4))
|
||||||
return -1;
|
return -1;
|
||||||
if (bg != BG_BLACK)
|
if (bg != BG_BLACK)
|
||||||
if (!s->isMono(s))
|
if (!s->isMono(s)) {
|
||||||
{
|
|
||||||
/* return 0; */ /* we could emulate ANSI mono */
|
/* return 0; */ /* we could emulate ANSI mono */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -68,52 +64,43 @@ static int do_init(screen_t *s, int fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static screen_t *do_construct(screen_t *s, int fd) {
|
||||||
static screen_t *do_construct(screen_t *s, int fd)
|
|
||||||
{
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return nullptr;
|
||||||
if (do_init(s,fd) != 0)
|
if (do_init(s, fd) != 0) {
|
||||||
{
|
|
||||||
s->destroy(s);
|
s->destroy(s);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static screen_t *screen = NULL;
|
static screen_t *screen = nullptr;
|
||||||
|
|
||||||
static void __acc_cdecl_atexit do_destroy(void)
|
static void __acc_cdecl_atexit do_destroy(void) {
|
||||||
{
|
if (screen) {
|
||||||
if (screen)
|
|
||||||
{
|
|
||||||
if (screen->atExit)
|
if (screen->atExit)
|
||||||
screen->atExit();
|
screen->atExit();
|
||||||
screen->destroy(screen);
|
screen->destroy(screen);
|
||||||
screen = NULL;
|
screen = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mode = -1;
|
static int mode = -1;
|
||||||
static int init_fg = -1;
|
static int init_fg = -1;
|
||||||
static int init_bg = -1;
|
static int init_bg = -1;
|
||||||
static int cur_fg = -1;
|
static int cur_fg = -1;
|
||||||
static int cur_bg = -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 fd = fileno(f);
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
assert(screen == NULL);
|
assert(screen == nullptr);
|
||||||
|
|
||||||
if (o == CON_SCREEN)
|
if (o == CON_SCREEN)
|
||||||
n = CON_SCREEN;
|
n = CON_SCREEN;
|
||||||
@@ -126,21 +113,21 @@ static int init(FILE *f, int o, int now)
|
|||||||
else
|
else
|
||||||
return CON_INIT;
|
return CON_INIT;
|
||||||
|
|
||||||
#if defined(__DJGPP__)
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
screen = do_construct(screen_djgpp2_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_win32_construct(),fd);
|
screen = do_construct(screen_win32_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_VCSA)
|
#if (USE_SCREEN_VCSA)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_vcsa_construct(),fd);
|
screen = do_construct(screen_vcsa_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_CURSES)
|
#if (USE_SCREEN_CURSES)
|
||||||
if (!screen && o == CON_SCREEN)
|
if (!screen && o == CON_SCREEN)
|
||||||
screen = do_construct(screen_curses_construct(),fd);
|
screen = do_construct(screen_curses_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
if (!screen)
|
if (!screen)
|
||||||
return CON_INIT;
|
return CON_INIT;
|
||||||
@@ -155,17 +142,14 @@ static int init(FILE *f, int o, int now)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
const int last_fg = cur_fg;
|
const int last_fg = cur_fg;
|
||||||
int f1 = fg & mask_fg;
|
int f1 = fg & mask_fg;
|
||||||
int f2 = init_fg & mask_fg;
|
int f2 = init_fg & mask_fg;
|
||||||
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
cur_fg = fg;
|
cur_fg = fg;
|
||||||
if (screen->isMono(screen))
|
if (screen->isMono(screen)) {
|
||||||
{
|
|
||||||
const int b = (init_bg & mask_bg) >> 4;
|
const int b = (init_bg & mask_bg) >> 4;
|
||||||
if (fg == -1) /* restore startup fg */
|
if (fg == -1) /* restore startup fg */
|
||||||
f1 = f2;
|
f1 = f2;
|
||||||
@@ -175,19 +159,15 @@ static int set_fg(FILE *f, int fg)
|
|||||||
f1 = (f2 == 0) ? 15 : 0;
|
f1 = (f2 == 0) ? 15 : 0;
|
||||||
else
|
else
|
||||||
f1 = (f2 == 0) ? 8 : 0;
|
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;
|
f1 = f2 ^ 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->setFg(screen,f1 & mask_fg);
|
screen->setFg(screen, f1 & mask_fg);
|
||||||
return last_fg;
|
return last_fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *ss) {
|
||||||
static void print0(FILE *f, const char *ss)
|
|
||||||
{
|
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
int old_cx = 0, old_cy = 0;
|
int old_cx = 0, old_cy = 0;
|
||||||
const int sx = screen->getCols(screen);
|
const int sx = screen->getCols(screen);
|
||||||
@@ -199,57 +179,47 @@ static void print0(FILE *f, const char *ss)
|
|||||||
// scrollUp() under Win32 is *extremely* slow.
|
// scrollUp() under Win32 is *extremely* slow.
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
|
|
||||||
screen->getCursor(screen,&old_cx,&old_cy);
|
screen->getCursor(screen, &old_cx, &old_cy);
|
||||||
cx = old_cx; cy = old_cy;
|
cx = old_cx;
|
||||||
|
cy = old_cy;
|
||||||
|
|
||||||
for (pass = 0; pass < 2; pass++)
|
for (pass = 0; pass < 2; pass++) {
|
||||||
{
|
|
||||||
const char *s = ss;
|
const char *s = ss;
|
||||||
// char buffer for pass 2
|
// char buffer for pass 2
|
||||||
char p[256+1];
|
char p[256 + 1];
|
||||||
int pi = 0, px = 0, py = 0;
|
int pi = 0, px = 0, py = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
// walk over whitespace
|
// walk over whitespace
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
if (*s == '\n') {
|
||||||
if (*s == '\n')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
} else if (*s == '\r') {
|
||||||
else if (*s == '\r')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
if (pass > 0 && cy < sy)
|
if (pass > 0 && cy < sy)
|
||||||
screen->clearLine(screen,cy);
|
screen->clearLine(screen, cy);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
// adjust cursor
|
// adjust cursor
|
||||||
if (cx >= sx)
|
if (cx >= sx) {
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
}
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// check if we should print something
|
// check if we should print something
|
||||||
if (pi > 0 && (*s == 0 || py != cy))
|
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||||
{
|
|
||||||
p[pi] = 0;
|
p[pi] = 0;
|
||||||
screen->putString(screen,p,px,py);
|
screen->putString(screen, p, px, py);
|
||||||
pi = 0;
|
pi = 0;
|
||||||
}
|
}
|
||||||
// check if we should scroll even more (this can happen
|
// check if we should scroll even more (this can happen
|
||||||
// if the string is longer than sy lines)
|
// if the string is longer than sy lines)
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen,scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy -= scroll_y;
|
cy -= scroll_y;
|
||||||
if (cy < 0)
|
if (cy < 0)
|
||||||
cy = 0;
|
cy = 0;
|
||||||
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
|||||||
// done ?
|
// done ?
|
||||||
if (*s == 0)
|
if (*s == 0)
|
||||||
break;
|
break;
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// store current char
|
// store current char
|
||||||
if (pi == 0)
|
if (pi == 0) {
|
||||||
{
|
|
||||||
px = cx;
|
px = cx;
|
||||||
py = cy;
|
py = cy;
|
||||||
}
|
}
|
||||||
@@ -273,47 +241,34 @@ static void print0(FILE *f, const char *ss)
|
|||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass == 0)
|
if (pass == 0) {
|
||||||
{
|
|
||||||
// end of pass 1 - scroll up, restore cursor
|
// end of pass 1 - scroll up, restore cursor
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen,scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy = old_cy - scroll_y;
|
cy = old_cy - scroll_y;
|
||||||
if (cy < 0)
|
if (cy < 0)
|
||||||
cy = 0;
|
cy = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
cy = old_cy;
|
cy = old_cy;
|
||||||
cx = old_cx;
|
cx = old_cx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->setCursor(screen,cx,cy);
|
screen->setCursor(screen, cx, cy);
|
||||||
screen->refresh(screen);
|
screen->refresh(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if (USE_FRAMES)
|
#if (USE_FRAMES)
|
||||||
if (screen->intro)
|
if (screen->intro)
|
||||||
return screen->intro(screen,screen_show_frames);
|
return screen->intro(screen, screen_show_frames);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_screen = {init, set_fg, print0, intro};
|
||||||
console_t console_screen =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* USE_SCREEN */
|
#endif /* USE_SCREEN */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -40,95 +40,76 @@
|
|||||||
#undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
|
|
||||||
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
||||||
# define NO_CONSOLE 1
|
#define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && defined(__linux__)
|
#if 1 && defined(__linux__)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_VCSA 1
|
#define USE_SCREEN_VCSA 1
|
||||||
# if !(HAVE_LINUX_KD_H)
|
#if !(HAVE_LINUX_KD_H)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# endif
|
#endif
|
||||||
# if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
#if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32 1
|
#define USE_SCREEN_WIN32 1
|
||||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32 1
|
#define USE_SCREEN_WIN32 1
|
||||||
|
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
|
||||||
|
#define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (NO_ANSI)
|
#if 0 || (NO_ANSI)
|
||||||
# undef USE_ANSI
|
#undef USE_ANSI
|
||||||
#endif
|
#endif
|
||||||
#if 0 || (NO_SCREEN)
|
#if 0 || (NO_SCREEN)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
#endif
|
#endif
|
||||||
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||||
# define USE_CONSOLE 1
|
#define USE_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
||||||
# undef USE_CONSOLE
|
#undef USE_CONSOLE
|
||||||
# undef USE_ANSI
|
#undef USE_ANSI
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# undef USE_SCREEN_CURSES
|
#undef USE_SCREEN_CURSES
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
enum {
|
enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
|
||||||
CON_INIT,
|
|
||||||
CON_NONE,
|
|
||||||
CON_FILE,
|
|
||||||
CON_ANSI_MONO,
|
|
||||||
CON_ANSI_COLOR,
|
|
||||||
CON_SCREEN,
|
|
||||||
CON_UNUSED
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int (*init)(FILE *f, int, int);
|
int (*init)(FILE *f, int, int);
|
||||||
int (*set_fg)(FILE *f, int fg);
|
int (*set_fg)(FILE *f, int fg);
|
||||||
void (*print0)(FILE *f, const char *s);
|
void (*print0)(FILE *f, const char *s);
|
||||||
bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
} console_t;
|
||||||
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
|
|
||||||
|
|
||||||
|
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
||||||
|
|
||||||
#define FG_BLACK 0x00
|
#define FG_BLACK 0x00
|
||||||
#define FG_BLUE 0x01
|
#define FG_BLUE 0x01
|
||||||
@@ -158,7 +139,6 @@ void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
|||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -177,12 +157,11 @@ extern console_t console_ansi_mono;
|
|||||||
extern console_t console_ansi_color;
|
extern console_t console_ansi_color;
|
||||||
extern console_t console_screen;
|
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
|
#else
|
||||||
|
|
||||||
#define con_fg(f,x) 0
|
#define con_fg(f, x) 0
|
||||||
#define con_fprintf fprintf
|
#define con_fprintf fprintf
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,9 +25,12 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (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"
|
#include "screen.h"
|
||||||
|
|
||||||
@@ -78,7 +81,9 @@ struct screen_data_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* atExit information */
|
/* atExit information */
|
||||||
static struct { int cursor_shape; } ae = {-1};
|
static struct {
|
||||||
|
int cursor_shape;
|
||||||
|
} ae = {-1};
|
||||||
|
|
||||||
#if USE_SCROLLBACK
|
#if USE_SCROLLBACK
|
||||||
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
||||||
@@ -94,7 +99,7 @@ static void sb_push(screen_t *this, const Cell *line, int len) {
|
|||||||
|
|
||||||
static const Cell *sb_pop(screen_t *this) {
|
static const Cell *sb_pop(screen_t *this) {
|
||||||
if (this->data->sb_sp == this->data->sb_base)
|
if (this->data->sb_sp == this->data->sb_base)
|
||||||
return NULL;
|
return nullptr;
|
||||||
sb_add(this, &this->data->sb_sp, -1);
|
sb_add(this, &this->data->sb_sp, -1);
|
||||||
return this->data->sb_buf[this->data->sb_sp];
|
return this->data->sb_buf[this->data->sb_sp];
|
||||||
}
|
}
|
||||||
@@ -104,7 +109,7 @@ static void refresh(screen_t *this) { UNUSED(this); }
|
|||||||
|
|
||||||
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
||||||
UNUSED(this);
|
UNUSED(this);
|
||||||
return (Cell)(((attr & 0xff) << 8) | (ch & 0xff));
|
return (Cell) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMode(const screen_t *this) {
|
static int getMode(const screen_t *this) {
|
||||||
@@ -248,7 +253,7 @@ static int init(screen_t *this, int fd) {
|
|||||||
if (getPage(this) != 0)
|
if (getPage(this) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
/* check for Windows NT/2000/XP */
|
/* check for Windows NT/2000/XP */
|
||||||
if (_get_dos_version(1) == 0x0532)
|
if (_get_dos_version(1) == 0x0532)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -271,7 +276,7 @@ static int init(screen_t *this, int fd) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ScreenGetCursor(&this->data->cursor_y, &this->data->cursor_x);
|
ScreenGetCursor(&this->data->cursor_y, &this->data->cursor_x);
|
||||||
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->init_attr = attr;
|
||||||
if (mode != 7) {
|
if (mode != 7) {
|
||||||
/* Does it normally blink when bg has its 3rd bit set? */
|
/* Does it normally blink when bg has its 3rd bit set? */
|
||||||
@@ -366,7 +371,7 @@ static int scrollDown(screen_t *this, int lines) {
|
|||||||
for (y = lines; --y >= 0;) {
|
for (y = lines; --y >= 0;) {
|
||||||
#if USE_SCROLLBACK
|
#if USE_SCROLLBACK
|
||||||
const Cell *buf = sb_pop(this);
|
const Cell *buf = sb_pop(this);
|
||||||
if (buf == NULL)
|
if (buf == nullptr)
|
||||||
clearLine(this, y);
|
clearLine(this, y);
|
||||||
else
|
else
|
||||||
updateLineN(this, buf, y, sc * 2);
|
updateLineN(this, buf, y, sc * 2);
|
||||||
@@ -414,10 +419,10 @@ static void atExit(void) {
|
|||||||
return;
|
return;
|
||||||
done = 1;
|
done = 1;
|
||||||
if (ae.cursor_shape >= 0)
|
if (ae.cursor_shape >= 0)
|
||||||
setCursorShape(NULL, ae.cursor_shape);
|
setCursorShape(nullptr, ae.cursor_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const screen_t driver = {sobject_destroy, 0, /* finalize, */
|
static const screen_t driver = {sobject_destroy, nullptr, /* finalize */
|
||||||
atExit, init, refresh,
|
atExit, init, refresh,
|
||||||
getMode, getPage, getRows,
|
getMode, getPage, getRows,
|
||||||
getCols, isMono, getFg,
|
getCols, isMono, getFg,
|
||||||
@@ -427,11 +432,11 @@ static const screen_t driver = {sobject_destroy, 0, /* finalize, */
|
|||||||
putCharAttr, putString, putStringAttr,
|
putCharAttr, putString, putStringAttr,
|
||||||
clear, clearLine, updateLineN,
|
clear, clearLine, updateLineN,
|
||||||
scrollUp, scrollDown, getScrollCounter,
|
scrollUp, scrollDown, getScrollCounter,
|
||||||
s_kbhit, intro, (struct screen_data_t *) 0};
|
s_kbhit, intro, (struct screen_data_t *) nullptr};
|
||||||
|
|
||||||
/* public constructor */
|
/* 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) && defined(__DJGPP__) */
|
#endif /* (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__) */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -38,19 +38,19 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// ugly hacks
|
// 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) {
|
void sobject_destroy(screen_t *this) {
|
||||||
last_screen = NULL;
|
last_screen = nullptr;
|
||||||
if (!this)
|
if (!this)
|
||||||
return;
|
return;
|
||||||
if (this->data) {
|
if (this->data) {
|
||||||
if (this->finalize)
|
if (this->finalize)
|
||||||
this->finalize(this);
|
this->finalize(this);
|
||||||
free(this->data);
|
free(this->data);
|
||||||
this->data = NULL;
|
this->data = nullptr;
|
||||||
}
|
}
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -58,12 +58,12 @@ void sobject_destroy(screen_t *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;
|
screen_t *this;
|
||||||
|
|
||||||
last_screen = NULL;
|
last_screen = nullptr;
|
||||||
|
|
||||||
/* allocate object */
|
/* allocate object */
|
||||||
this = (screen_t *) malloc(sizeof(*this));
|
this = (screen_t *) malloc(sizeof(*this));
|
||||||
if (!this)
|
if (!this)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
/* copy function table */
|
/* copy function table */
|
||||||
*this = *c;
|
*this = *c;
|
||||||
@@ -72,7 +72,7 @@ screen_t *sobject_construct(const screen_t *c, size_t data_size) {
|
|||||||
this->data = (struct screen_data_t *) malloc(data_size);
|
this->data = (struct screen_data_t *) malloc(data_size);
|
||||||
if (!this->data) {
|
if (!this->data) {
|
||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
memset(this->data, 0, data_size);
|
memset(this->data, 0, data_size);
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ static void sb_push(screen_t *this, const Cell *line, int len) {
|
|||||||
|
|
||||||
static const Cell *sb_pop(screen_t *this) {
|
static const Cell *sb_pop(screen_t *this) {
|
||||||
if (this->data->sb_sp == this->data->sb_base)
|
if (this->data->sb_sp == this->data->sb_base)
|
||||||
return NULL;
|
return nullptr;
|
||||||
sb_add(this, &this->data->sb_sp, -1);
|
sb_add(this, &this->data->sb_sp, -1);
|
||||||
return this->data->sb_buf[this->data->sb_sp];
|
return this->data->sb_buf[this->data->sb_sp];
|
||||||
}
|
}
|
||||||
@@ -258,10 +258,10 @@ static int init(screen_t *this, int fd) {
|
|||||||
int attr;
|
int attr;
|
||||||
Cell 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);
|
this->data->fd = open(vc_name, O_RDWR);
|
||||||
if (this->data->fd == -1) {
|
if (this->data->fd == -1) {
|
||||||
upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev));
|
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);
|
this->data->fd = open(vc_name, O_RDWR);
|
||||||
}
|
}
|
||||||
if (this->data->fd != -1) {
|
if (this->data->fd != -1) {
|
||||||
@@ -276,7 +276,7 @@ static int init(screen_t *this, int fd) {
|
|||||||
this->data->map[i] = 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->init_attr = attr;
|
||||||
this->data->attr = attr;
|
this->data->attr = attr;
|
||||||
a = make_cell(this, ' ', attr);
|
a = make_cell(this, ' ', attr);
|
||||||
@@ -384,7 +384,7 @@ static int scrollDown(screen_t *this, int lines) {
|
|||||||
for (y = lines; --y >= 0;) {
|
for (y = lines; --y >= 0;) {
|
||||||
#if USE_SCROLLBACK
|
#if USE_SCROLLBACK
|
||||||
const Cell *buf = sb_pop(this);
|
const Cell *buf = sb_pop(this);
|
||||||
if (buf == NULL)
|
if (buf == nullptr)
|
||||||
clearLine(this, y);
|
clearLine(this, y);
|
||||||
else
|
else
|
||||||
updateLineN(this, buf, y, sc * 2);
|
updateLineN(this, buf, y, sc * 2);
|
||||||
@@ -420,7 +420,7 @@ static int kbhit(screen_t *this) {
|
|||||||
FD_SET(fd, &fds);
|
FD_SET(fd, &fds);
|
||||||
tv.tv_sec = usec / 1000000;
|
tv.tv_sec = usec / 1000000;
|
||||||
tv.tv_usec = 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 *)) {
|
||||||
@@ -455,7 +455,7 @@ static int intro(screen_t *this, void (*show_frames)(screen_t *)) {
|
|||||||
|
|
||||||
static const screen_t driver = {sobject_destroy,
|
static const screen_t driver = {sobject_destroy,
|
||||||
finalize,
|
finalize,
|
||||||
0, /* atExit */
|
nullptr, /* atExit */
|
||||||
init,
|
init,
|
||||||
refresh,
|
refresh,
|
||||||
getMode,
|
getMode,
|
||||||
@@ -471,7 +471,7 @@ static const screen_t driver = {sobject_destroy,
|
|||||||
setBg,
|
setBg,
|
||||||
setCursor,
|
setCursor,
|
||||||
setCursorShape,
|
setCursorShape,
|
||||||
0, /* hideCursor */
|
nullptr, /* hideCursor */
|
||||||
putChar,
|
putChar,
|
||||||
putCharAttr,
|
putCharAttr,
|
||||||
putString,
|
putString,
|
||||||
@@ -484,7 +484,7 @@ static const screen_t driver = {sobject_destroy,
|
|||||||
getScrollCounter,
|
getScrollCounter,
|
||||||
kbhit,
|
kbhit,
|
||||||
intro,
|
intro,
|
||||||
(struct screen_data_t *) 0};
|
(struct screen_data_t *) nullptr};
|
||||||
|
|
||||||
/* public constructor */
|
/* 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)); }
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,10 +25,19 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#define WANT_WINDOWS_LEAN_H 1
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#if (HAVE_CONIO_H)
|
||||||
|
#include <conio.h>
|
||||||
|
#endif
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// direct screen access
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
#define this self
|
#define this self
|
||||||
@@ -36,24 +45,6 @@
|
|||||||
#define mask_fg 0x0f
|
#define mask_fg 0x0f
|
||||||
#define mask_bg 0xf0
|
#define mask_bg 0xf0
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// 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 (HAVE_CONIO_H)
|
|
||||||
#include <conio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct screen_data_t {
|
struct screen_data_t {
|
||||||
HANDLE hi;
|
HANDLE hi;
|
||||||
HANDLE ho;
|
HANDLE ho;
|
||||||
@@ -76,7 +67,7 @@ struct screen_data_t {
|
|||||||
CHAR_INFO empty_line[256];
|
CHAR_INFO empty_line[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define P(x) ((SHORT)(x))
|
#define P(x) ((SHORT) (x))
|
||||||
|
|
||||||
static const COORD pos00 = {0, 0};
|
static const COORD pos00 = {0, 0};
|
||||||
static const COORD size11 = {1, 1};
|
static const COORD size11 = {1, 1};
|
||||||
@@ -111,12 +102,12 @@ 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));
|
this->data->attr = (WORD) ((this->data->attr & mask_bg) | (fg & mask_fg));
|
||||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
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));
|
this->data->attr = (WORD) ((this->data->attr & mask_fg) | (bg & mask_bg));
|
||||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +257,22 @@ static int init(screen_t *this, int fd) {
|
|||||||
#endif
|
#endif
|
||||||
#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_x = csbi->dwCursorPosition.X;
|
||||||
this->data->cursor_y = csbi->dwCursorPosition.Y;
|
this->data->cursor_y = csbi->dwCursorPosition.Y;
|
||||||
|
|
||||||
@@ -346,7 +353,7 @@ static int do_scroll(screen_t *this, int lines, int way) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ScrollConsoleScreenBuffer(this->data->ho, &rect, &clip, dest, &this->data->empty_cell);
|
// 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, nullptr, dest, &this->data->empty_cell);
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
@@ -395,7 +402,7 @@ static void atExit(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const screen_t driver = {sobject_destroy, 0, /* finalize, */
|
static const screen_t driver = {sobject_destroy, nullptr, /* finalize */
|
||||||
atExit, init, refresh,
|
atExit, init, refresh,
|
||||||
getMode, getPage, getRows,
|
getMode, getPage, getRows,
|
||||||
getCols, isMono, getFg,
|
getCols, isMono, getFg,
|
||||||
@@ -405,7 +412,7 @@ static const screen_t driver = {sobject_destroy, 0, /* finalize, */
|
|||||||
putCharAttr, putString, putStringAttr,
|
putCharAttr, putString, putStringAttr,
|
||||||
clear, clearLine, updateLineN,
|
clear, clearLine, updateLineN,
|
||||||
scrollUp, scrollDown, getScrollCounter,
|
scrollUp, scrollDown, getScrollCounter,
|
||||||
s_kbhit, intro, (struct screen_data_t *) 0};
|
s_kbhit, intro, (struct screen_data_t *) nullptr};
|
||||||
|
|
||||||
/* public constructor */
|
/* 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)); }
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UPX_SCREEN_H
|
#pragma once
|
||||||
#define __UPX_SCREEN_H 1
|
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -99,6 +98,4 @@ void screen_show_frames(screen_t *);
|
|||||||
|
|
||||||
#endif /* USE_SCREEN */
|
#endif /* USE_SCREEN */
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
+106
-100
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,59 +25,58 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
unsigned long Throwable::counter = 0;
|
/*static*/ Throwable::Stats Throwable::stats;
|
||||||
|
|
||||||
Throwable::Throwable(const char *m, int e, bool w) NOTHROW
|
Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
|
||||||
: super(), msg(NULL), err(e), is_warning(w)
|
msg(nullptr),
|
||||||
{
|
err(e),
|
||||||
if (m)
|
is_warning(w) {
|
||||||
|
if (m != nullptr) {
|
||||||
msg = strdup(m);
|
msg = strdup(m);
|
||||||
#if 0
|
assert_noexcept(msg != nullptr);
|
||||||
fprintf(stderr, "construct exception: %s %lu\n", msg, counter);
|
}
|
||||||
counter++;
|
NO_fprintf(stderr, "construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
#endif
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
|
stats.counter_current += 1;
|
||||||
|
stats.counter_total += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Throwable::Throwable(const Throwable &other) noexcept : super(other),
|
||||||
Throwable::Throwable(const Throwable &other) NOTHROW
|
msg(nullptr),
|
||||||
: super(other), msg(NULL), err(other.err), is_warning(other.is_warning)
|
err(other.err),
|
||||||
{
|
is_warning(other.is_warning) {
|
||||||
if (other.msg)
|
if (other.msg != nullptr) {
|
||||||
msg = strdup(other.msg);
|
msg = strdup(other.msg);
|
||||||
#if 0
|
assert_noexcept(msg != nullptr);
|
||||||
fprintf(stderr, "copy exception: %s %lu\n", msg, counter);
|
}
|
||||||
counter++;
|
NO_fprintf(stderr, "copy construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
#endif
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
|
stats.counter_current += 1;
|
||||||
|
stats.counter_total += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Throwable::~Throwable() noexcept {
|
||||||
Throwable::~Throwable() NOTHROW
|
stats.counter_current -= 1;
|
||||||
{
|
NO_fprintf(stderr, "destruct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
#if 0
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
counter--;
|
upx::owner_free(msg);
|
||||||
fprintf(stderr, "destruct exception: %s %lu\n", msg, counter);
|
|
||||||
#endif
|
|
||||||
if (msg)
|
|
||||||
free(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compression
|
// compression
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void throwCantPack(const char *msg)
|
void throwCantPack(const char *msg) {
|
||||||
{
|
|
||||||
// UGLY, but makes things easier
|
// 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);
|
throw CantPackException(msg);
|
||||||
else if (opt->cmd == CMD_FILEINFO)
|
else if (opt->cmd == CMD_FILEINFO)
|
||||||
throw CantPackException(msg);
|
throw CantPackException(msg);
|
||||||
@@ -85,119 +84,126 @@ void throwCantPack(const char *msg)
|
|||||||
throw CantUnpackException(msg);
|
throw CantUnpackException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwCantPackExact()
|
void throwCantPackExact() { throwCantPack("option '--exact' does not work with this file"); }
|
||||||
{
|
|
||||||
throwCantPack("option '--exact' does not work with this file");
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwFilterException()
|
void throwFilterException() { throwCantPack("filter problem"); }
|
||||||
{
|
|
||||||
throwCantPack("filter problem");
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwUnknownExecutableFormat(const char *msg, bool warn)
|
void throwUnknownExecutableFormat(const char *msg, bool warn) {
|
||||||
{
|
|
||||||
throw UnknownExecutableFormatException(msg, warn);
|
throw UnknownExecutableFormatException(msg, warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwNotCompressible(const char *msg)
|
void throwNotCompressible(const char *msg) { throw NotCompressibleException(msg); }
|
||||||
{
|
|
||||||
throw NotCompressibleException(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwAlreadyPacked(const char *msg)
|
void throwAlreadyPacked(const char *msg) { throw AlreadyPackedException(msg); }
|
||||||
{
|
|
||||||
throw AlreadyPackedException(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwAlreadyPackedByUPX(const char *msg)
|
void throwAlreadyPackedByUPX(const char *msg) {
|
||||||
{
|
if (msg == nullptr)
|
||||||
if (msg == NULL)
|
|
||||||
msg = "already packed by UPX";
|
msg = "already packed by UPX";
|
||||||
throwAlreadyPacked(msg);
|
throwAlreadyPacked(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// decompression
|
// decompression
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void throwCantUnpack(const char *msg)
|
void throwCantUnpack(const char *msg) {
|
||||||
{
|
|
||||||
// UGLY, but makes things easier
|
// UGLY, but makes things easier
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwNotPacked(const char *msg)
|
void throwNotPacked(const char *msg) {
|
||||||
{
|
if (msg == nullptr)
|
||||||
if (msg == NULL)
|
|
||||||
msg = "not packed by UPX";
|
msg = "not packed by UPX";
|
||||||
throw NotPackedException(msg);
|
throw NotPackedException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwChecksumError()
|
void throwChecksumError() { throw Exception("checksum error"); }
|
||||||
{
|
|
||||||
throw Exception("checksum error");
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwCompressedDataViolation()
|
|
||||||
{
|
|
||||||
throw Exception("compressed data violation");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void throwCompressedDataViolation() { throw Exception("compressed data violation"); }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// other
|
// other
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void throwInternalError(const char *msg)
|
void throwInternalError(const char *msg) { throw InternalError(msg); }
|
||||||
{
|
|
||||||
throw InternalError(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void throwBadLoader()
|
void throwBadLoader() { throwInternalError("bad loader"); }
|
||||||
{
|
|
||||||
throwInternalError("bad loader");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void throwOutOfMemoryException(const char *msg) {
|
||||||
void throwOutOfMemoryException(const char *msg)
|
if (msg == nullptr)
|
||||||
{
|
|
||||||
if (msg == NULL)
|
|
||||||
msg = "out of memory";
|
msg = "out of memory";
|
||||||
throw OutOfMemoryException(msg);
|
throw OutOfMemoryException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void throwIOException(const char *msg, int e) { throw IOException(msg, e); }
|
||||||
|
|
||||||
void throwIOException(const char *msg, int e)
|
void throwEOFException(const char *msg, int e) {
|
||||||
{
|
if (msg == nullptr && e == 0)
|
||||||
throw IOException(msg, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void throwEOFException(const char *msg, int e)
|
|
||||||
{
|
|
||||||
if (msg == NULL && e == 0)
|
|
||||||
msg = "premature end of file";
|
msg = "premature end of file";
|
||||||
throw EOFException(msg, e);
|
throw EOFException(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// varargs overloads
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const char *prettyName(const char *n) NOTHROW
|
template <>
|
||||||
{
|
void throwCantPack(const char *format, ...) {
|
||||||
if (n == NULL)
|
char msg[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
(void) 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);
|
||||||
|
(void) 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);
|
||||||
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
throwCantUnpack(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)";
|
return "(null)";
|
||||||
while (*n)
|
while (*n) {
|
||||||
{
|
|
||||||
if (*n >= '0' && *n <= '9') // Linux ABI
|
if (*n >= '0' && *n <= '9') // Linux ABI
|
||||||
n++;
|
n++;
|
||||||
else if (*n == ' ')
|
else if (*n == ' ')
|
||||||
n++;
|
n++;
|
||||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++
|
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC)
|
||||||
n += 6;
|
n += 6;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|||||||
+93
-112
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,209 +25,190 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_EXCEPT_H
|
|
||||||
#define __UPX_EXCEPT_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
const char *prettyName(const char *n) NOTHROW;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// exceptions
|
// exceptions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class Throwable : public std::exception
|
class Throwable : public std::exception {
|
||||||
{
|
|
||||||
typedef std::exception super;
|
typedef std::exception super;
|
||||||
|
|
||||||
protected:
|
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:
|
public:
|
||||||
Throwable(const Throwable &) NOTHROW;
|
Throwable(const Throwable &) noexcept; // copy constructor
|
||||||
virtual ~Throwable() NOTHROW;
|
virtual ~Throwable() noexcept;
|
||||||
const char *getMsg() const NOTHROW { return msg; }
|
const char *getMsg() const noexcept { return msg; }
|
||||||
int getErrno() const NOTHROW { return err; }
|
int getErrno() const noexcept { return err; }
|
||||||
bool isWarning() const NOTHROW { return is_warning; }
|
bool isWarning() const noexcept { return is_warning; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *msg;
|
OwningPointer(char) msg = nullptr;
|
||||||
int err;
|
int err = 0;
|
||||||
protected:
|
protected:
|
||||||
bool is_warning; // can be set by subclasses
|
bool is_warning = false; // can be set by subclasses
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disable assignment
|
// disable copy assignment and move
|
||||||
Throwable& operator= (const Throwable &);
|
Throwable &operator=(const Throwable &) noexcept DELETED_FUNCTION; // copy assignment
|
||||||
// disable dynamic allocation
|
UPX_CXX_DISABLE_MOVE(Throwable)
|
||||||
DISABLE_NEW_DELETE
|
// 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:
|
private:
|
||||||
static unsigned 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
|
// Exceptions can/should be caught
|
||||||
class Exception : public Throwable
|
class Exception : public Throwable {
|
||||||
{
|
|
||||||
typedef Throwable super;
|
typedef Throwable super;
|
||||||
public:
|
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)
|
// Errors should not be caught (or re-thrown)
|
||||||
class Error : public Throwable
|
class Error : public Throwable {
|
||||||
{
|
|
||||||
typedef Throwable super;
|
typedef Throwable super;
|
||||||
public:
|
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;
|
typedef Exception super;
|
||||||
public:
|
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 /*not_final*/ : public Exception {
|
||||||
class IOException : public Exception
|
|
||||||
{
|
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
public:
|
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 final : public IOException {
|
||||||
class EOFException : public IOException
|
|
||||||
{
|
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
public:
|
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 final : public IOException {
|
||||||
class FileNotFoundException : public IOException
|
|
||||||
{
|
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
public:
|
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 final : public IOException {
|
||||||
class FileAlreadyExistsException : public IOException
|
|
||||||
{
|
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
public:
|
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;
|
typedef Exception super;
|
||||||
public:
|
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;
|
typedef Exception super;
|
||||||
public:
|
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 : public CantPackException {
|
||||||
{
|
|
||||||
typedef CantPackException super;
|
typedef CantPackException super;
|
||||||
public:
|
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;
|
typedef CantPackException super;
|
||||||
public:
|
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;
|
typedef CantPackException super;
|
||||||
public:
|
public:
|
||||||
NotCompressibleException(const char *m = 0) NOTHROW : super(m) { }
|
NotCompressibleException(const char *m = nullptr) noexcept : super(m) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CantUnpackException /*not_final*/ : public Exception {
|
||||||
class CantUnpackException : public Exception
|
|
||||||
{
|
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
public:
|
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;
|
typedef CantUnpackException super;
|
||||||
public:
|
public:
|
||||||
NotPackedException(const char *m = 0) NOTHROW : super(m,true) { }
|
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// errors
|
// errors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class InternalError : public Error
|
class InternalError final : public Error {
|
||||||
{
|
|
||||||
typedef Error super;
|
typedef Error super;
|
||||||
public:
|
public:
|
||||||
InternalError(const char *m = 0) NOTHROW : super(m,0) { }
|
InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#undef NORET
|
const char *prettyExceptionName(const char *n) noexcept;
|
||||||
#if 1 && defined(__GNUC__)
|
|
||||||
#define NORET __attribute__((__noreturn__))
|
|
||||||
#else
|
|
||||||
#define NORET /*empty*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void throwCantPack(const char *msg) NORET;
|
noreturn void throwCantPack(const char *msg) may_throw;
|
||||||
void throwCantPackExact() NORET;
|
noreturn void throwCantPackExact() may_throw;
|
||||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
noreturn void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw;
|
||||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
noreturn void throwNotCompressible(const char *msg = nullptr) may_throw;
|
||||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
noreturn void throwAlreadyPacked(const char *msg = nullptr) may_throw;
|
||||||
void throwAlreadyPackedByUPX(const char *msg = NULL) NORET;
|
noreturn void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw;
|
||||||
void throwCantUnpack(const char *msg) NORET;
|
noreturn void throwCantUnpack(const char *msg) may_throw;
|
||||||
void throwNotPacked(const char *msg = NULL) NORET;
|
noreturn void throwNotPacked(const char *msg = nullptr) may_throw;
|
||||||
void throwFilterException() NORET;
|
noreturn void throwFilterException() may_throw;
|
||||||
void throwBadLoader() NORET;
|
noreturn void throwBadLoader() may_throw;
|
||||||
void throwChecksumError() NORET;
|
noreturn void throwChecksumError() may_throw;
|
||||||
void throwCompressedDataViolation() NORET;
|
noreturn void throwCompressedDataViolation() may_throw;
|
||||||
void throwInternalError(const char *msg) NORET;
|
noreturn void throwInternalError(const char *msg) may_throw;
|
||||||
void throwOutOfMemoryException(const char *msg = NULL) NORET;
|
noreturn void throwOutOfMemoryException(const char *msg = nullptr) may_throw;
|
||||||
void throwIOException(const char *msg = NULL, int e = 0) NORET;
|
noreturn void throwIOException(const char *msg = nullptr, int e = 0) may_throw;
|
||||||
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
noreturn void throwEOFException(const char *msg = nullptr, int e = 0) may_throw;
|
||||||
|
|
||||||
#undef NORET
|
// some C++ template wizardry is needed to overload throwCantPack() for varargs
|
||||||
|
template <class T>
|
||||||
|
void throwCantPack(const T *, ...) DELETED_FUNCTION;
|
||||||
#endif /* __cplusplus */
|
template <>
|
||||||
|
noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
#endif /* already included */
|
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: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+155
-260
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,79 +25,72 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// static file-related util functions; will throw on error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void File::chmod(const char *name, int mode)
|
/*static*/ void FileBase::chmod(const char *name, int mode) {
|
||||||
{
|
assert(name != nullptr && name[0] != 0);
|
||||||
#if (HAVE_CHMOD)
|
#if HAVE_CHMOD
|
||||||
if (::chmod(name,mode) != 0)
|
if (::chmod(name, mode) != 0)
|
||||||
throwIOException(name,errno);
|
throwIOException(name, errno);
|
||||||
#else
|
#else
|
||||||
UNUSED(name); UNUSED(mode);
|
UNUSED(name);
|
||||||
|
UNUSED(mode);
|
||||||
|
// no error
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ void FileBase::rename(const char *old_, const char *new_) {
|
||||||
void File::rename(const char *old_, const char *new_)
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
{
|
if (::_rename(old_, new_) != 0)
|
||||||
#if defined(__DJGPP__)
|
|
||||||
if (::_rename(old_,new_) != 0)
|
|
||||||
#else
|
#else
|
||||||
if (::rename(old_,new_) != 0)
|
if (::rename(old_, new_) != 0)
|
||||||
#endif
|
#endif
|
||||||
throwIOException("rename error",errno);
|
throwIOException("rename error", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
|
||||||
void File::unlink(const char *name)
|
assert_noexcept(name != nullptr && name[0] != 0);
|
||||||
{
|
bool success = ::unlink(name) == 0;
|
||||||
if (::unlink(name) != 0)
|
#if HAVE_CHMOD
|
||||||
throwIOException(name,errno);
|
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() :
|
FileBase::~FileBase() may_throw {
|
||||||
_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
|
#if 0 && defined(__GNUC__) // debug
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__);
|
fprintf(stderr, "%s: %s\n", _name, __PRETTY_FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
|
if (std::uncaught_exceptions() == 0)
|
||||||
// FIXME: we should use close() during exception unwinding but
|
closex(); // may_throw
|
||||||
// closex() otherwise
|
else
|
||||||
closex();
|
close_noexcept(); // currently in exception unwinding, use noexcept variant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileBase::do_sopen() {
|
||||||
bool FileBase::do_sopen()
|
|
||||||
{
|
|
||||||
if (_shflags < 0)
|
if (_shflags < 0)
|
||||||
_fd = ::open(_name, _flags, _mode);
|
_fd = ::open(_name, _flags, _mode);
|
||||||
else
|
else {
|
||||||
{
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
#if defined(__DJGPP__)
|
_fd = ::open(_name, _flags | _shflags, _mode);
|
||||||
_fd = ::open(_name,_flags | _shflags, _mode);
|
#elif (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
#elif defined(__MINT__)
|
_fd = ::open(_name, _flags | (_shflags & O_SHMODE), _mode);
|
||||||
_fd = ::open(_name,_flags | (_shflags & O_SHMODE), _mode);
|
|
||||||
#elif defined(SH_DENYRW)
|
#elif defined(SH_DENYRW)
|
||||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||||
#else
|
#else
|
||||||
@@ -106,15 +99,14 @@ bool FileBase::do_sopen()
|
|||||||
}
|
}
|
||||||
if (_fd < 0)
|
if (_fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
st.st_size = 0;
|
||||||
if (::fstat(_fd, &st) != 0)
|
if (::fstat(_fd, &st) != 0)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size;
|
_length = st.st_size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileBase::close_noexcept() noexcept {
|
||||||
bool FileBase::close()
|
|
||||||
{
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)
|
if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)
|
||||||
if (::close(_fd) == -1)
|
if (::close(_fd) == -1)
|
||||||
@@ -122,123 +114,69 @@ bool FileBase::close()
|
|||||||
_fd = -1;
|
_fd = -1;
|
||||||
_flags = 0;
|
_flags = 0;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
_name = NULL;
|
_name = nullptr;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileBase::closex() may_throw {
|
||||||
void FileBase::closex()
|
if (!close_noexcept())
|
||||||
{
|
throwIOException("close failed", errno);
|
||||||
if (!close())
|
|
||||||
throwIOException("close failed",errno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return value of ::seek is the resulting file offset (same as ::tell())
|
||||||
int FileBase::read(void *buf, int len)
|
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
off_t FileBase::seek(upx_int64_t off64, int whence)
|
|
||||||
{
|
|
||||||
mem_size_assert(1, off64 >= 0 ? off64 : -off64); // sanity check
|
|
||||||
off_t off = ACC_ICONV(off_t, off64);
|
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
|
mem_size_assert(1, off >= 0 ? off : -off); // sanity check
|
||||||
if (whence == SEEK_SET) {
|
if (whence == SEEK_SET) {
|
||||||
if (off < 0)
|
if (off < 0)
|
||||||
throwIOException("bad seek 2");
|
throwIOException("bad seek 2");
|
||||||
off += _offset;
|
off += _offset;
|
||||||
}
|
} else if (whence == SEEK_END) {
|
||||||
if (whence == SEEK_END) {
|
|
||||||
if (off > 0)
|
if (off > 0)
|
||||||
throwIOException("bad seek 3");
|
throwIOException("bad seek 3");
|
||||||
off += _offset + _length;
|
off += _offset + _length;
|
||||||
whence = SEEK_SET;
|
whence = SEEK_SET;
|
||||||
}
|
} else if (whence == SEEK_CUR) {
|
||||||
if (::lseek(_fd,off,whence) < 0)
|
} else
|
||||||
throwIOException("seek error",errno);
|
throwInternalError("bad seek: whence");
|
||||||
return off - _offset;
|
upx_off_t l = ::lseek(_fd, off, whence);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
off_t FileBase::tell() const
|
|
||||||
{
|
|
||||||
if (!isOpen())
|
|
||||||
throwIOException("bad tell");
|
|
||||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("tell error",errno);
|
throwIOException("seek error", errno);
|
||||||
return l - _offset;
|
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;
|
_offset = offset;
|
||||||
_length = length;
|
_length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t FileBase::st_size() const
|
upx_off_t FileBase::st_size() const { return _length; }
|
||||||
{
|
|
||||||
return _length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// InputFile
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
InputFile::InputFile()
|
void InputFile::sopen(const char *name, int flags, int shflags) {
|
||||||
{
|
closex();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
InputFile::~InputFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InputFile::sopen(const char *name, int flags, int shflags)
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
if (!FileBase::do_sopen())
|
if (!super::do_sopen()) {
|
||||||
{
|
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
throw FileNotFoundException(_name, errno);
|
throw FileNotFoundException(_name, errno);
|
||||||
else if (errno == EEXIST)
|
else if (errno == EEXIST)
|
||||||
@@ -249,89 +187,60 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
|||||||
_length_orig = _length;
|
_length_orig = _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InputFile::read(SPAN_P(void) buf, upx_int64_t blen) {
|
||||||
int InputFile::read(void *buf, int len)
|
if (!isOpen() || blen < 0)
|
||||||
{
|
throwIOException("bad read");
|
||||||
return super::read(buf, len);
|
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)
|
int InputFile::readx(SPAN_P(void) buf, upx_int64_t blen) {
|
||||||
{
|
int l = this->read(buf, blen);
|
||||||
return super::readx(buf, len);
|
if (l != blen)
|
||||||
|
throwEOFException();
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upx_off_t InputFile::seek(upx_off_t off, int whence) {
|
||||||
int InputFile::read(MemBuffer *buf, int len)
|
upx_off_t pos = super::seek(off, whence);
|
||||||
{
|
|
||||||
buf->checkState();
|
|
||||||
assert((unsigned)len <= buf->getSize());
|
|
||||||
return read(buf->getVoidPtr(), len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int InputFile::readx(MemBuffer *buf, int len)
|
|
||||||
{
|
|
||||||
buf->checkState();
|
|
||||||
assert((unsigned)len <= buf->getSize());
|
|
||||||
return read(buf->getVoidPtr(), len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int InputFile::read(MemBuffer &buf, int len)
|
|
||||||
{
|
|
||||||
return read(&buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int InputFile::readx(MemBuffer &buf, int len)
|
|
||||||
{
|
|
||||||
return readx(&buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
off_t InputFile::seek(upx_int64_t off64, int whence)
|
|
||||||
{
|
|
||||||
off_t pos = super::seek(off64, whence);
|
|
||||||
if (_length < pos)
|
if (_length < pos)
|
||||||
throwIOException("bad seek 4");
|
throwIOException("bad seek 4");
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upx_off_t InputFile::st_size_orig() const { return _length_orig; }
|
||||||
|
|
||||||
off_t InputFile::tell() const
|
int InputFile::dupFd() may_throw {
|
||||||
{
|
if (!isOpen())
|
||||||
return super::tell();
|
throwIOException("bad dup");
|
||||||
}
|
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
|
||||||
|
errno = ENOSYS;
|
||||||
off_t InputFile::st_size_orig() const
|
int r = -1;
|
||||||
{
|
#else
|
||||||
return _length_orig;
|
int r = ::dup(getFd());
|
||||||
|
#endif
|
||||||
|
if (r < 0)
|
||||||
|
throwIOException("dup", errno);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// OutputFile
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
OutputFile::OutputFile() :
|
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
|
||||||
bytes_written(0)
|
closex();
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OutputFile::~OutputFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
if (!FileBase::do_sopen())
|
if (!super::do_sopen()) {
|
||||||
{
|
|
||||||
#if 0
|
#if 0
|
||||||
// don't throw FileNotFound here -- this is confusing
|
// don't throw FileNotFound here -- this is confusing
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
@@ -339,16 +248,14 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (errno == EEXIST)
|
if (errno == EEXIST)
|
||||||
throw FileAlreadyExistsException(_name,errno);
|
throw FileAlreadyExistsException(_name, errno);
|
||||||
else
|
else
|
||||||
throwIOException(_name,errno);
|
throwIOException(_name, errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutputFile::openStdout(int flags, bool force) {
|
||||||
bool OutputFile::openStdout(int flags, bool force)
|
closex();
|
||||||
{
|
|
||||||
close();
|
|
||||||
int fd = STDOUT_FILENO;
|
int fd = STDOUT_FILENO;
|
||||||
if (!force && acc_isatty(fd))
|
if (!force && acc_isatty(fd))
|
||||||
return false;
|
return false;
|
||||||
@@ -364,15 +271,36 @@ bool OutputFile::openStdout(int flags, bool force)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputFile::write(SPAN_0(const void) buf, upx_int64_t blen) {
|
||||||
void OutputFile::write(const void *buf, int len)
|
if (!isOpen() || blen < 0)
|
||||||
{
|
throwIOException("bad write");
|
||||||
super::write(buf, len);
|
// 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;
|
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
|
upx_off_t OutputFile::st_size() const {
|
||||||
{
|
|
||||||
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||||
}
|
}
|
||||||
@@ -383,31 +311,14 @@ off_t OutputFile::st_size() const
|
|||||||
return my_st.st_size;
|
return my_st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputFile::rewrite(SPAN_P(const void) buf, int len) {
|
||||||
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)
|
|
||||||
{
|
|
||||||
assert(!opt->to_stdout);
|
assert(!opt->to_stdout);
|
||||||
write(buf, len);
|
write(buf, len);
|
||||||
bytes_written -= len; // restore
|
bytes_written -= len; // restore
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t OutputFile::seek(upx_int64_t off64, int whence)
|
upx_off_t OutputFile::seek(upx_off_t off, int whence) {
|
||||||
{
|
mem_size_assert(1, off >= 0 ? off : -off); // sanity check
|
||||||
mem_size_assert(1, off64 >= 0 ? off64 : -off64); // sanity check
|
|
||||||
off_t off = ACC_ICONV(off_t, off64);
|
|
||||||
assert(!opt->to_stdout);
|
assert(!opt->to_stdout);
|
||||||
switch (whence) {
|
switch (whence) {
|
||||||
case SEEK_SET: {
|
case SEEK_SET: {
|
||||||
@@ -420,12 +331,12 @@ off_t OutputFile::seek(upx_int64_t off64, int whence)
|
|||||||
_length = bytes_written; // necessary
|
_length = bytes_written; // necessary
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return super::seek(off,whence);
|
return super::seek(off, whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: fsync() does not exist in some Windows environments.
|
// WARNING: fsync() does not exist in some Windows environments.
|
||||||
// This trick works only on UNIX-like systems.
|
// This trick works only on UNIX-like systems.
|
||||||
//int OutputFile::read(void *buf, int len)
|
// int OutputFile::read(void *buf, int len)
|
||||||
//{
|
//{
|
||||||
// fsync(_fd);
|
// fsync(_fd);
|
||||||
// InputFile infile;
|
// InputFile infile;
|
||||||
@@ -434,20 +345,19 @@ off_t OutputFile::seek(upx_int64_t off64, int whence)
|
|||||||
// return infile.read(buf, len);
|
// return infile.read(buf, len);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void OutputFile::set_extent(off_t offset, off_t length)
|
void OutputFile::set_extent(upx_off_t offset, upx_off_t length) {
|
||||||
{
|
|
||||||
super::set_extent(offset, length);
|
super::set_extent(offset, length);
|
||||||
bytes_written = 0;
|
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)
|
if (::fstat(_fd, &st) != 0)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size - offset;
|
_length = st.st_size - offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t OutputFile::unset_extent()
|
upx_off_t OutputFile::unset_extent() {
|
||||||
{
|
upx_off_t l = ::lseek(_fd, 0, SEEK_END);
|
||||||
off_t l = ::lseek(_fd, 0, SEEK_END);
|
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("lseek error", errno);
|
throwIOException("lseek error", errno);
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
@@ -456,44 +366,29 @@ off_t OutputFile::unset_extent()
|
|||||||
return _length;
|
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)
|
if (flags < 0)
|
||||||
flags = O_CREAT | O_TRUNC;
|
flags = O_CREAT | O_TRUNC;
|
||||||
flags |= O_WRONLY | O_BINARY;
|
flags |= O_WRONLY | O_BINARY;
|
||||||
OutputFile f;
|
OutputFile f;
|
||||||
f.open(name, flags, 0600);
|
f.open(name, flags, 0600);
|
||||||
f.write(buf, len);
|
f.write(raw_bytes(buf, len), len);
|
||||||
f.closex();
|
f.closex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if 0
|
TEST_CASE("file") {
|
||||||
|
InputFile fi;
|
||||||
MemoryOutputFile::MemoryOutputFile() :
|
CHECK(!fi.isOpen());
|
||||||
b(NULL), b_size(0), b_pos(0), bytes_written(0)
|
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 */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=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