Compare commits
875 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 8eabb9b02f | |||
| 8a195a0b35 | |||
| 955206aaf0 | |||
| 082dd7d5ee | |||
| 90714cf624 | |||
| 6e2a41cb26 | |||
| fe4a8f33b1 | |||
| 391f511094 | |||
| 9df4b6ea24 | |||
| c4a921283a | |||
| 4e05f087f9 | |||
| 40b506d2e0 | |||
| 263f384810 | |||
| d80c145a18 | |||
| 7a681bd20d | |||
| ed31fb184b | |||
| 360b94dd6c | |||
| 8524e73f59 | |||
| a4e47625ac | |||
| 7c16872a6e | |||
| 8bca8629be | |||
| 85fdd579d6 | |||
| e88d2ff88c | |||
| bdf08baebd | |||
| 3dcdd25177 | |||
| 491e8640b2 | |||
| b23b7ef85e | |||
| b167374f13 |
-109
@@ -1,109 +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: msvc-15.0-x86, CL_VERSION: 19.10, VS_VERSION: 2017, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 }
|
|
||||||
- { C: msvc-15.0-x64, CL_VERSION: 19.10, VS_VERSION: 2017, APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 }
|
|
||||||
# - { 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 cmp & 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 )
|
|
||||||
- if "%C%"=="msvc-15.0-x86" ( call "c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x86 )
|
|
||||||
- if "%C%"=="msvc-15.0-x64" ( call "c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\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 -WX -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:
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||||
|
#
|
||||||
|
# for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
|
||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
ColumnLimit: 100
|
||||||
|
IndentWidth: 4
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
AttributeMacros:
|
||||||
|
- __acc_cdecl
|
||||||
|
- __acc_cdecl_atexit
|
||||||
|
- __acc_cdecl_qsort
|
||||||
|
- __acc_cdecl_sighandler
|
||||||
|
- __acc_forceinline
|
||||||
|
- __acc_noinline
|
||||||
|
- __acc_static_noinline
|
||||||
|
- __acc_static_forceinline
|
||||||
|
- forceinline
|
||||||
|
- noinline
|
||||||
|
EmptyLineBeforeAccessModifier: Leave
|
||||||
|
SortIncludes: false
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
Standard: Cpp03
|
||||||
|
StatementMacros:
|
||||||
|
- ACCCHK_ASSERT
|
||||||
|
- ACCCHK_ASSERT_IS_SIGNED_T
|
||||||
|
- ACCCHK_ASSERT_IS_UNSIGNED_T
|
||||||
|
- ACCCHK_ASSERT_SIGN_T
|
||||||
|
- ACC_BLOCK_BEGIN
|
||||||
|
- ACC_COMPILE_TIME_ASSERT
|
||||||
|
- ACC_COMPILE_TIME_ASSERT_HEADER
|
||||||
|
- ACC_CXX_DISABLE_NEW_DELETE
|
||||||
|
- ACC_CXX_TRIGGER_FUNCTION
|
||||||
|
- ACC_CXX_TRIGGER_FUNCTION_IMPL
|
||||||
|
- CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
|
- COMPILE_TIME_ASSERT
|
||||||
|
- COMPILE_TIME_ASSERT_ALIGNED1
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- ACC_PP_MACRO_EXPAND
|
||||||
|
- ACC_PP_STRINGIZE
|
||||||
|
...
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
#
|
# see https://editorconfig.org/
|
||||||
# see http://editorconfig.org/
|
|
||||||
#
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# make GitHub language detection more accurate, see https://github.com/github/linguist
|
||||||
|
|
||||||
|
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
|
||||||
@@ -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.
|
||||||
@@ -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,8 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: 'github-actions'
|
||||||
|
directory: '/'
|
||||||
|
schedule:
|
||||||
|
# Check for updates to GitHub Actions every weekday
|
||||||
|
interval: 'daily'
|
||||||
@@ -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,169 +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
|
|
||||||
if [[ -f "$HOME/local/bin/bin-upx/upx-stubtools-check-version" ]]; then
|
|
||||||
bin_upx=$(readlink -en -- "$HOME/local/bin/bin-upx")
|
|
||||||
elif [[ -f "$HOME/.local/bin/bin-upx/upx-stubtools-check-version" ]]; then
|
|
||||||
bin_upx=$(readlink -en -- "$HOME/.local/bin/bin-upx")
|
|
||||||
else
|
|
||||||
bin_upx=$(readlink -en -- "$upx_SRCDIR/../deps/bin-upx-20160918")
|
|
||||||
fi
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
extra_subdirs=()
|
|
||||||
extra_subdirs+=( src/stub/src/arch/amd64 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm/v4a )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm/v4t )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm64/v8 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/i386 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/m68k/m68000 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/m68k/m68020 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/mips/r3000 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/powerpc/32 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/powerpc/64le )
|
|
||||||
make -C src/stub maintainer-clean
|
|
||||||
for d in ${extra_subdirs[@]}; do
|
|
||||||
make -C $d -f Makefile.extra maintainer-clean
|
|
||||||
git status $d || true
|
|
||||||
done
|
|
||||||
git status src/stub/src || true
|
|
||||||
git status || true
|
|
||||||
failed=0
|
|
||||||
for d in ${extra_subdirs[@]}; do
|
|
||||||
PATH="$bin_upx:$PATH" make -C $d -f Makefile.extra || failed=1
|
|
||||||
done
|
|
||||||
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
|
|
||||||
git status
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
|
||||||
echo "X=rebuild-stubs done. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
unset bin_upx extra_subdirs d failed
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# build UCL
|
|
||||||
#
|
|
||||||
|
|
||||||
cd / && cd $ucl_BUILDDIR || exit 1
|
|
||||||
# patch UCL
|
|
||||||
sed 's/^#elif (ACC_ARCH_AMD64 || ACC_ARCH_IA64)$/& \&\& !defined(__ILP32__)/' $ucl_SRCDIR/acc/acc_chk.ch > a.tmp
|
|
||||||
if cmp -s a.tmp $ucl_SRCDIR/acc/acc_chk.ch; then rm a.tmp; else mv a.tmp $ucl_SRCDIR/acc/acc_chk.ch; fi
|
|
||||||
if [[ $BUILD_LOCAL_UCL == 1 ]]; 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,194 +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*) ;;
|
|
||||||
gitlab*) ;;
|
|
||||||
master*) ;;
|
|
||||||
travis*) ;;
|
|
||||||
*) exit 0;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# get $rev, $branch and $git_user
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
rev=$(git rev-parse --verify HEAD)
|
|
||||||
if [[ "$branch" == gitlab* ]]; then
|
|
||||||
if git fetch -v origin devel; then
|
|
||||||
git branch -a -v
|
|
||||||
rev=$(git merge-base origin/devel $rev || echo $rev)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
timestamp=$(git log -n1 --format='%at' $rev)
|
|
||||||
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
|
|
||||||
|
|
||||||
if [[ -n $subdir ]]; then
|
|
||||||
print_header "DEPLOY $subdir/$d"
|
|
||||||
else
|
|
||||||
print_header "DEPLOY $d"
|
|
||||||
fi
|
|
||||||
|
|
||||||
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 || true
|
|
||||||
fi
|
|
||||||
git ls-files -v
|
|
||||||
|
|
||||||
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 -v
|
|
||||||
#git log --pretty=fuller
|
|
||||||
|
|
||||||
umask 077
|
|
||||||
[[ -d ~/.ssh ]] || mkdir ~/.ssh
|
|
||||||
fix_home_ssh_perms
|
|
||||||
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
|
|
||||||
fix_home_ssh_perms
|
|
||||||
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
|
||||||
fix_home_ssh_perms
|
|
||||||
|
|
||||||
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 branch -a -v
|
|
||||||
git fetch -v origin "$branch"
|
|
||||||
git branch -a -v
|
|
||||||
git rebase FETCH_HEAD
|
|
||||||
git branch -a -v
|
|
||||||
sleep $((RANDOM % 5 + 1))
|
|
||||||
let i+=1
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,256 +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_UCL=1
|
|
||||||
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_UCL=1
|
|
||||||
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"; BUILD_LOCAL_UCL=1; BUILD_LOCAL_ZLIB=1 ;;
|
|
||||||
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_header() {
|
|
||||||
local x="==========="; x="$x$x$x$x$x$x$x"
|
|
||||||
echo -e "\n${x}\n${1}\n${x}\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
fix_home_ssh_perms() {
|
|
||||||
if [[ -d ~/.ssh ]]; then
|
|
||||||
if [[ -x /usr/sbin/restorecon ]]; then
|
|
||||||
/usr/sbin/restorecon -v -R ~/.ssh || true
|
|
||||||
fi
|
|
||||||
chmod -c -R go-rwx ~/.ssh || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
@@ -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="\
|
||||||
|
693102863358cc906bce946afec10dd0e15d0effc6ceb462d9beaaba25967304 *amd64-linux.elf/upx-3.91
|
||||||
|
4aa9e1868d7797b50768cf1ae0ab0e93cc2eff81f3abaf36f2fdb5faf673f7b7 *amd64-linux.elf/upx-3.95
|
||||||
|
996dc60b7b6aa8c4c55b4fbec9b1ad3e2f82f9986fd1cdcd2cb41ab01877d5a9 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
bb6cd600a28de3abc86c618125d72231d3d4b40de0260d2da7393970859723dd *arm-linux.elf/upx-3.95
|
||||||
|
bc945bc3f64a318a00ecbfde2e4a4bac2d298f753e5a8dbdc6a972bcabfce6eb *arm-wince.pe/upx-3.91.exe
|
||||||
|
19bdd27706f3476dfd46e5cdde782908af5bf9d068bf337ad8a26024d51ede8f *arm64-linux.elf/upx-3.95
|
||||||
|
3b6e5e9eeb660859e35d9d3e005fb51a8163bfe548d8be6525660a30d1ea5c37 *armeb-linux.elf/upx-3.91
|
||||||
|
2f2d916ee977e06b07429e563aeab0d052b7ba359dd61a7d767e2a7ef7fa049d *armeb-linux.elf/upx-3.95
|
||||||
|
1e8cded938d4ee16bcc66fb5462650733a8862a1c9fab264a77a22e7958b36a7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
6f439d62cdb735570c6c5e941924b6d2819024cad6c3453db020edc1e9e0d66b *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
f6a8a76b9af29272722be6785242a9822ce6b2ca3483cd953c2c34e4d85e1cf4 *i386-linux.elf/upx-3.91
|
||||||
|
7eead732dddffdb1db5e5002babe112f8589eeb8251cb23e0b6f29dacfad3817 *i386-linux.elf/upx-3.95
|
||||||
|
2c41d77ae9ac810cde23a222046d05b57a272c90aa75b127e0697a586be1ce1f *i386-win32.pe/upx-3.91.exe
|
||||||
|
0218c00a3686363148a2bbe7d89634d54a2d7840beeab7f5fef2f269e56d517e *i386-win32.pe/upx-3.95.exe
|
||||||
|
44034fc9a3609538d8edfbe3996aa3946b1745e537d1ea2ca14181c177b98034 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
55c6151325fdf1638584f0fa5ee228547445e239bb0c8f4c6f31c30945e114b1 *mips-linux.elf/upx-3.95
|
||||||
|
b6905f55277b3abc8ad10eb1ca95135ce9f2a5d87c992f7de78ca8e69d8e819e *mipsel-linux.elf/upx-3.91
|
||||||
|
3a5eb4b01cb334e4a30a0ebb1c7d9f85f2035e6e5989acc296beb3ff34c98152 *mipsel-linux.elf/upx-3.95
|
||||||
|
df4157e8e613f62fb26b1965b1c22dc44bf18f4aec4611283afadb9889d267d4 *powerpc-linux.elf/upx-3.91
|
||||||
|
054a126aa7e17c6c5b8a00f608c4bf98f252ec4ab9ca2c03aebf9c92e30bda4f *powerpc-linux.elf/upx-3.95
|
||||||
|
4667d37cb2474a30b184cd4d7ca8ba071650c396ebe9f1f9a39172c924676090 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||||
|
f3cfc0be5885525965fbd3e56f5a4083a727414978bb4c018b4b0355c5b06921 *amd64-linux.elf/upx-3.91
|
||||||
|
06f933cf1c5e42f2f00ffb6a5312fa687846b6a566d372459208f8cad34e34bb *amd64-linux.elf/upx-3.95
|
||||||
|
db33236e886947a74c766e632ded0249166e2e5f74a3d03cda37cc07901cd1b1 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
3564858c026c2b0637e3c8e41a972fabc609ccc69c7ddd0ae457dd4ba7a62008 *arm-linux.elf/upx-3.95
|
||||||
|
dceda960aa7b15b13a06bf88d1512d52e7e460d85a81207b6b5407bdbb51ffe8 *arm-wince.pe/upx-3.91.exe
|
||||||
|
52b93b549591081ef72d19fe09d4588d7f2bc736f2ad50a32be03fb7fcd70e95 *arm64-linux.elf/upx-3.95
|
||||||
|
1877be1f5f5333f1ee7c77bfb020f35f5c125e7f6b661a92a6918b468c02484f *armeb-linux.elf/upx-3.91
|
||||||
|
a4d1f01a3dc748e92dd33e1377885ef2955c2c35fd379474c6622ce67267fac2 *armeb-linux.elf/upx-3.95
|
||||||
|
d5d3cf6ecf1a89f5871bcfef9c59794f249b9f7ca12afdf15b79d343a18ddefc *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
eca16dec497e1a9f334fd4d806f035cafcd3438749d25b494e95f4935760ae4f *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
1ab8d00e13d149f6e74187eadaacd1d8cfa4777ce7489cef88fba4cbde9bcdee *i386-linux.elf/upx-3.91
|
||||||
|
dd3169256039f7df2db15a86114818b275c03bd96c3ee828d724131b98fcc6f2 *i386-linux.elf/upx-3.95
|
||||||
|
17a97d24ebbdaa3bd8f7ec9633e38bca1754c8af2d79250aaa5472499a98e0ec *i386-win32.pe/upx-3.91.exe
|
||||||
|
1bb873ed8a8cbb11238f98c3f616ec6a34f4765a6021e10d9686158f382458f0 *i386-win32.pe/upx-3.95.exe
|
||||||
|
13b0b57643342d0e08fe084cbf799f518b3d44ac9f39edda7db3e6b6c36386cc *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
91145a85e926495a536661d4e842a7b5b259707ef6accf5f08d13adcec173f13 *mips-linux.elf/upx-3.95
|
||||||
|
8090533000872748b70c761d5581d78fde421d66884ab238527ca41d1446c2ae *mipsel-linux.elf/upx-3.91
|
||||||
|
f82e7b166647f157c981af92eaeec63bf080609591a5d13f76f84cd49c8e7495 *mipsel-linux.elf/upx-3.95
|
||||||
|
ae312cc5d34fd889ed9582a928ab03c589c0caddb111aceade7e072f928c6361 *powerpc-linux.elf/upx-3.91
|
||||||
|
fd28cb894be895afb8aec675739b276810e7a35c5212016c3f7acde853d8c763 *powerpc-linux.elf/upx-3.95
|
||||||
|
e299bb500c34d2f90b2b35a7186a0b24fb5ac80e56d4a2d80f9c8bd32cf2be62 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||||
|
eea59d6755beed52bff26941d31362f28097d029d4f61a2f9065dcc63cd628fb *amd64-linux.elf/upx-3.91
|
||||||
|
b89f4ca39165071a7a5eb107ed9b7c6c77b7c7ad90acdb2b073314571aacc23a *amd64-linux.elf/upx-3.95
|
||||||
|
6af6bc4f2d4bdb1e7694f44ce695c54d181011b734f159018d5e2c515d14a47c *amd64-win64.pe/upx-3.95.exe
|
||||||
|
9ae22ad9af331ec8c08ab22b0a8e0e0ff849512a6d11257c55fe7c423c0b7937 *arm-linux.elf/upx-3.95
|
||||||
|
8605ddb612a1a3e096e272cb876e7777585804fa000f338f2164437a6da3de9a *arm-wince.pe/upx-3.91.exe
|
||||||
|
2ab36b41db84e6e3002420ec397d79abed451869a7a8b703ab3b81f79c487753 *arm64-linux.elf/upx-3.95
|
||||||
|
38879c80525760492a95de9bfcbce49997c5bff30bb43a6bb173b1978d21f248 *armeb-linux.elf/upx-3.91
|
||||||
|
72e3bf259bf1304235a7ebe600f5b37be21297b8552f2fbdf47e28e3aa19e807 *armeb-linux.elf/upx-3.95
|
||||||
|
3af56cb84be62f4078ae39be3370ef68061b094c62b3cbcd5d38e99e0e91df7f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
224b882b4dcebc1112ced3df1b468ea8dc58083dac4893fa0061dc50ce6abf7c *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
59e3a1d456036bed175056978d12484a64405f356b1a1fa480866e7e31c9543b *i386-linux.elf/upx-3.91
|
||||||
|
9662deb5f74b23c5b63d09457442895091f4b6cfd619f7bd6ffc27ec75f08682 *i386-linux.elf/upx-3.95
|
||||||
|
3c585a745cd105073bb7324f2183731be84cfc4669f2bab1ef20c9bff909d2fc *i386-win32.pe/upx-3.91.exe
|
||||||
|
fc796dad77cb6cb99bcb5700c3ff0a7b185c1fe8b129a293dd0e45d0903b13e6 *i386-win32.pe/upx-3.95.exe
|
||||||
|
da41cb691775b8b0ef969954ea272262ed77e83b57257b2ba0ba19427a2ab991 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
ea6ff916a226e39a5e67b2118fc3ceb0dbc69d8d473051a5df19af14e03ae25e *mips-linux.elf/upx-3.95
|
||||||
|
0cbc8eaecb2aa7dcc2e9d7b11ba0c0e26193f1328a35107cf1069a8c5f9e63be *mipsel-linux.elf/upx-3.91
|
||||||
|
7b112c59fccf3e5f3d4ec253fdb25761e47705a1c5d3a0103249b1747bbbe7d9 *mipsel-linux.elf/upx-3.95
|
||||||
|
de8354fbeaf0623f3d08c3945dcdb5a8f0c078fe3e8082a13767979e841e6677 *powerpc-linux.elf/upx-3.91
|
||||||
|
403c26bc1dda0cbf23032bc5ec5ac42ed8537a640a077c4332446227c8a3eb7b *powerpc-linux.elf/upx-3.95
|
||||||
|
093a7fdbb555c8aea8728b4d6240ed3b723ee9007c5f6ea40a8daf2d1eb63f54 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||||
|
6dd472386ff2a9683d75fe4cc8d0d40be223681f4d7305a51a7aacf25501e60f *amd64-linux.elf/upx-3.91
|
||||||
|
4bbb96b109ae2b8b43b957bc66c3cdc2cfcf3a692377153ef912d09a495c876c *amd64-linux.elf/upx-3.95
|
||||||
|
510fc860ac393abcfdbb547e999c12a6c6e928ead026607a6879fa7ca1e2d568 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
a54c0e5b61257154c56f076460f64efbb4216c913c846073d0a695ac3c0ddffd *arm-linux.elf/upx-3.95
|
||||||
|
9182294f2e31db89b138294cbbc6f6d03ea39a00565adf0e052ed3d21491e1b5 *arm-wince.pe/upx-3.91.exe
|
||||||
|
fde8face710b6a479a96d7d2d40a29ac8894d5483403e33acbf4a5d6f9cdb29d *arm64-linux.elf/upx-3.95
|
||||||
|
0a92af3f6034487034ea062bc44c93bba74219fa5fdcbb34d1643a95f7daa9ed *armeb-linux.elf/upx-3.91
|
||||||
|
2c11ec89ad145e9f82c3cbbd63ed1e1eca2b0d3c3081fce3e0500ed33c05a623 *armeb-linux.elf/upx-3.95
|
||||||
|
13cbcb06079492a21b7440b981250f84ff2be48a69daa168d95cee798f8fbf77 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
adfdcd033340a7b14945c9a60da036e25d44c8b1ee0811ac0a4ef1cbca423cc5 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
e5fff5b965da26349311c0513d09086600c3b466f1d53e42d6e35d6b4656168e *i386-linux.elf/upx-3.91
|
||||||
|
cf8df3858bbb1c92a06e57ce1b971e11bbf280954f2fc1dc7e5b5a4641d72819 *i386-linux.elf/upx-3.95
|
||||||
|
ddc4952ef008b7f31e69bf53310d6f03b36a959ebb1cd3c3985d560efcbd4296 *i386-win32.pe/upx-3.91.exe
|
||||||
|
99b0b637b562798a440ba605d44e34cf7d4ff995b04dc2e54ebee288ed5180b4 *i386-win32.pe/upx-3.95.exe
|
||||||
|
89a5de403a012256afefff0f88e1cff4696dee611946e326ad15416dbdba7d13 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
eac695bc19163050c5bee9271393156a195bfef9c3c76f5aaf3aaef00f5602eb *mips-linux.elf/upx-3.95
|
||||||
|
b1331b88421cdf8ef73f8ef1a2c86045fc56a495c08d06d83018c88f5f3934de *mipsel-linux.elf/upx-3.91
|
||||||
|
9644118e26647d489e811ebe3bfd320e2976dbe26621e994fe979b0f9d175818 *mipsel-linux.elf/upx-3.95
|
||||||
|
64a4a31815e4bf43e2ea866faa494c69a4209ed53055f16562d0d2d6ba7fd927 *powerpc-linux.elf/upx-3.91
|
||||||
|
dec559bf9cbd4d1745e8f3bf2cedf016a72f443d037f75eab0d2baab191f0ae1 *powerpc-linux.elf/upx-3.95
|
||||||
|
f10b8afa319b1056a82f24dd52d13003c5cf005fc3cc3481dad1e58ef33e973f *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||||
|
2e89a5b8192957b066d5a5ee39e47663518f49c1e7811f6806e21d938201d5b6 *amd64-linux.elf/upx-3.91
|
||||||
|
d1cfdda4b93d697211c052f3d85cd745e533261f05cc06c2869a8561c07b4f57 *amd64-linux.elf/upx-3.95
|
||||||
|
c7381363e31af6789111f58ca590b0d751956c322684efa1914f1d918ecc23ce *amd64-win64.pe/upx-3.95.exe
|
||||||
|
4dc8ba75edd4b1c3d890c9deeb033d9abf08fb65054eddb4f34138d34503c21d *arm-linux.elf/upx-3.95
|
||||||
|
36f744d6dca6ecb8c60ee456859ac6a1ac241d12ababa20a5e2d0d79551d53aa *arm-wince.pe/upx-3.91.exe
|
||||||
|
72d3de2abdc3985c790d833a9535054683e2b3feaa6b96778e55ea8f448846a3 *arm64-linux.elf/upx-3.95
|
||||||
|
233d4f130995bb7155064ce6f651b9f6ac61268c8698ccc90a8ea3b2e297cb39 *armeb-linux.elf/upx-3.91
|
||||||
|
a107428a7675181974a8efc359d39da74510098d8307347865f7bcdd707e28ad *armeb-linux.elf/upx-3.95
|
||||||
|
bd57c1e3844310c2a864384f2b83a5781933a5beb05a5eb748a6094e37621166 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
1a13debece417ada4e18d5ec02efa7ef1c354ddfa4674b5717e0aa6bc90c16e3 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
f7b56af17d3d8402310387d1e82f90fa670dfa058feb3fe413ac81c01a1efbb1 *i386-linux.elf/upx-3.91
|
||||||
|
fe9162fbfe8f4eb1c9f286df68107c08f25592d2edaaf5707540c81f709e29ac *i386-linux.elf/upx-3.95
|
||||||
|
aaa267d824bd0520c016edcc1a6642d4898030760879e1da883b8211cf071350 *i386-win32.pe/upx-3.91.exe
|
||||||
|
d178699c0ed805829e457987ea5da21f4e37cf1eb74529235d9b1275bf3122f6 *i386-win32.pe/upx-3.95.exe
|
||||||
|
8376ba3954c4fd9cd5e5e8e38923759db005a4048c3d86dc76476e9f3d92a07d *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
65a0227127b7952a42216c79a8431d1bbe7f04c9efdc81f72095d095a969cb80 *mips-linux.elf/upx-3.95
|
||||||
|
c2bd45b55980bfbc5e568a640643772e3e82bc02cd2c7559cb1c57fc0809d01e *mipsel-linux.elf/upx-3.91
|
||||||
|
74e25daba42baeaaffadab00bacca56b1de5f151a00160592077288a678f41f2 *mipsel-linux.elf/upx-3.95
|
||||||
|
904310944bec344897fc6b7a61dfe8ee639d136c555a950c736059cbc6cac8be *powerpc-linux.elf/upx-3.91
|
||||||
|
5304a95cdcdbdcb76cfac2b93e254f601fb73f68be0a44ed282096aec8d55ae8 *powerpc-linux.elf/upx-3.95
|
||||||
|
7ebd0be91bc9f60e22304103b3543b16a0fd128aa22f11474e31aecc97703e43 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||||
|
4d8069614af5721c7878daf10ee1d30a6bffc5446532963e2ff0e6cb6f1feecd *amd64-linux.elf/upx-3.91
|
||||||
|
f1971902f7d8f840fdc70ad9edbf5587db556ba046947f5ee7b4130e9ba7de5a *amd64-linux.elf/upx-3.95
|
||||||
|
0198a6cfd468f7ec7cd32294333400a4c97bf1cac32602594681db8f08c87700 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
d46340dcd209cce0f1d65d6a50754ea3246cdbba730199765b2c2ac40957bd55 *arm-linux.elf/upx-3.95
|
||||||
|
aa03361a7dae633d5b6c8b4164726c99bfc28fcf4f1ac8ebea6fc44e90c03244 *arm-wince.pe/upx-3.91.exe
|
||||||
|
aa0a3dda3e2f073eb36d6614c02f4af79590876a23437623ea6c231be8e070fa *arm64-linux.elf/upx-3.95
|
||||||
|
578547a4d527655c7fd661148dfcf0f7dc9585dfb08063c13b116364a881bf15 *armeb-linux.elf/upx-3.91
|
||||||
|
0034809b31b0105631b0e4c0a4378cfd26a80dfca2016228e8084f410025f091 *armeb-linux.elf/upx-3.95
|
||||||
|
55b9b578a97a7b8637a9041a222269f2563a4e1f75c329c533f83432c8f9652c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
98a9f601d095f910c68bbf35ff50f19e3e851ef5dae78fc0e9ef4462dd8a314d *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
45f714365212b31419986016b5b730ca77523036469e28242543bfde4dc44678 *i386-linux.elf/upx-3.91
|
||||||
|
e45f6ae7ad7b9e719e5080bfbd04e7c961242473bb8f1574cb625bc8a1abd201 *i386-linux.elf/upx-3.95
|
||||||
|
0b5d940059fc6f2a3d5664eadd0781399210c306be99411beeb8f6f02ea85762 *i386-win32.pe/upx-3.91.exe
|
||||||
|
0f5b50dfe0db34ae07f113871a39c64624f964ed16dc8d49922e6a891c17a3bd *i386-win32.pe/upx-3.95.exe
|
||||||
|
56fd999694feb66cdc2272daf86bb91b3c66b857867f3e0c071f3e70624760f4 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
2d8d2e02bedad8ba1e7d69a89888b173b9be48ee154e2461c205ba4eae6ececa *mips-linux.elf/upx-3.95
|
||||||
|
c478c21ecabe91910cf861ebc6b6d38deeb31545e5ae44eaf826dafb477bbfba *mipsel-linux.elf/upx-3.91
|
||||||
|
4d66e1b32ca6b1d399616de5643ee5d1c54a7bf1eca761055570450f56efe4f9 *mipsel-linux.elf/upx-3.95
|
||||||
|
72c85b48afb30cc191483af41f797a397225cfaaa44e2eaf7a9d59d9033335e1 *powerpc-linux.elf/upx-3.91
|
||||||
|
c0ed0c72fd6a6e0bfb4444b8c358018246f80cbc732388a22bd2492fd9fdc59c *powerpc-linux.elf/upx-3.95
|
||||||
|
070f4c2ca60717abedda0ab4030d546cca8a75b9872038a414e2946b8d8f93e7 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||||
|
223bcdc5f11daa4d0258090e967d4e0b5986d764d6b21fcfadba7212676396f2 *amd64-linux.elf/upx-3.91
|
||||||
|
a3e5f1a20bd9db4ae920c5c7e7f1707a63fa3f557f9db50b5e1004b706e3a52c *amd64-linux.elf/upx-3.95
|
||||||
|
355011427a4d433ccef5060e4cbebc59b0ecc38a430566cdb684330388ea0812 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
1e0a8363b539953181dc95283a1e3100bacce961f49e875c8f430b18d0e6672d *arm-linux.elf/upx-3.95
|
||||||
|
e281362e2172468d20ea2c7171c847f47e01a63d912cafacf977236655708521 *arm-wince.pe/upx-3.91.exe
|
||||||
|
7f3497c67e816b3f2af6642f09ba809166f8a0a65f52936cfb2e3d9756d7bd44 *arm64-linux.elf/upx-3.95
|
||||||
|
7d9d52959a64c5dd19ea343c8c2bdd4d70fd0644d13c62924760407515fd74ba *armeb-linux.elf/upx-3.91
|
||||||
|
e05ad251ec24e2f788de71c4c8cf7c8880a8eb7d8a516ca8d6ab94c715c2f77d *armeb-linux.elf/upx-3.95
|
||||||
|
00a030d8967c5145b955eba17d84edd44b21c93b570f80a44e894a10a3ebf99f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
b4b0e3c774dbf3940af777d28e1ba7c62bfedaa710e3376e81259218779eae56 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
f903265140b193e672c4dd2bc28e68b9f822d73517f0b339fc715ad781a49fab *i386-linux.elf/upx-3.91
|
||||||
|
6253062e41c4619bb3aeb807665a2925b1f01095d000c614c443b81d44112a1d *i386-linux.elf/upx-3.95
|
||||||
|
7664ed4ce00b962a21ca5654993c4c4cb2ec1afcf9dc921cd90862f8412572cc *i386-win32.pe/upx-3.91.exe
|
||||||
|
6ef354d0b2dffc71c32fc33f3f89b0b8ae7035e43e8a684a12d6ce2c53caf706 *i386-win32.pe/upx-3.95.exe
|
||||||
|
5890050fe690bb93bf70693f1bef0e6ea708029836c7d8aa57de02b6aefe4239 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
2bce2082ae39dedcc21a1a6c83e954073b368e9172ee0c7f2a3f13b3447a7898 *mips-linux.elf/upx-3.95
|
||||||
|
d5b88d291a8a2141d9d9f07a6a21e11522e510c6520ba0c36ebf94d089962607 *mipsel-linux.elf/upx-3.91
|
||||||
|
ff42d564999e02346c86d4156266f423edd55b3887aadf76d81a8c355e3b175d *mipsel-linux.elf/upx-3.95
|
||||||
|
f33205ad8252524d8c48d18cdb03bba507e29c9cc931f94327a5a46480f70843 *powerpc-linux.elf/upx-3.91
|
||||||
|
011683a891e30ea346efe9ba5c1488fb50f143e4090bd2be07537c696d6167db *powerpc-linux.elf/upx-3.95
|
||||||
|
9d919460b0ceec4b880cdf14850fea8096d6796c2457467b3cc9b2ce954cc6de *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
########## end .sha256sums.recreate
|
||||||
+57
-147
@@ -1,42 +1,38 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
## vim:set ts=4 sw=4 et:
|
## vim:set ts=4 sw=4 et:
|
||||||
set -e; set -o pipefail
|
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")
|
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then
|
# very first version of the upx-testsuite; requires:
|
||||||
echo "UPX testsuite SKIPPED."
|
# $upx_exe
|
||||||
exit 0
|
# $upx_testsuite_SRCDIR
|
||||||
fi
|
# $upx_testsuite_BUILDDIR (optional)
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
# $BM_T (optional)
|
||||||
exit 0
|
|
||||||
fi
|
# convenience
|
||||||
|
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=./tmp-upx-testsuite
|
||||||
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
||||||
|
|
||||||
# create dirs
|
# make dirs absolute
|
||||||
cd / || exit 1
|
upx_testsuite_SRCDIR=$(readlink -en -- "$upx_testsuite_SRCDIR")
|
||||||
mkbuilddirs $upx_testsuite_BUILDDIR
|
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
||||||
cd / && cd $upx_testsuite_BUILDDIR || exit 1
|
echo 'invalid or missing $upx_testsuite_SRCDIR:'
|
||||||
if [[ ! -d $upx_testsuite_SRCDIR/files/packed ]]; then exit 1; fi
|
echo ' please git clone https://github.com/upx/upx-testsuite'
|
||||||
|
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$upx_testsuite_BUILDDIR"
|
||||||
|
upx_testsuite_BUILDDIR=$(readlink -en -- "$upx_testsuite_BUILDDIR")
|
||||||
|
|
||||||
|
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // support functions
|
# // support functions
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
testsuite_header() {
|
testsuite_header() {
|
||||||
print_header "$1"
|
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||||
|
echo -e "\n${x}\n${1}\n${x}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
testsuite_split_f() {
|
testsuite_split_f() {
|
||||||
@@ -44,7 +40,7 @@ testsuite_split_f() {
|
|||||||
fb=$(basename "$1")
|
fb=$(basename "$1")
|
||||||
fsubdir=$(basename "$fd")
|
fsubdir=$(basename "$fd")
|
||||||
# sanity checks
|
# sanity checks
|
||||||
if [[ ! -f "$1" || -z "$fsubdir" || -z "$fb" ]]; then
|
if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then
|
||||||
fd= fb= fsubdir=
|
fd= fb= fsubdir=
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -56,10 +52,10 @@ testsuite_check_sha() {
|
|||||||
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
||||||
echo "UPX-ERROR: $1 FAILED: checksum mismatch"
|
echo "UPX-ERROR: $1 FAILED: checksum mismatch"
|
||||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||||
exit_code=1
|
exit_code=99
|
||||||
let num_errors+=1 || true
|
let num_errors+=1 || true
|
||||||
all_errors="${all_errors} $1"
|
all_errors="${all_errors} $1"
|
||||||
#exit 1
|
#exit 99
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
@@ -70,7 +66,7 @@ testsuite_check_sha_decompressed() {
|
|||||||
cat $1/.sha256sums.current
|
cat $1/.sha256sums.current
|
||||||
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
|
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
|
||||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||||
exit 1
|
exit 98
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +108,7 @@ testsuite_run_compress() {
|
|||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
recreate_expected_sha256sums() {
|
recreate_expected_sha256sums() {
|
||||||
local o="$1"
|
local o=$1
|
||||||
local files f d
|
local files f d
|
||||||
echo "########## begin .sha256sums.recreate" > "$o"
|
echo "########## begin .sha256sums.recreate" > "$o"
|
||||||
files=*/.sha256sums.current
|
files=*/.sha256sums.current
|
||||||
@@ -125,107 +121,7 @@ recreate_expected_sha256sums() {
|
|||||||
echo "########## end .sha256sums.recreate" >> "$o"
|
echo "########## end .sha256sums.recreate" >> "$o"
|
||||||
}
|
}
|
||||||
|
|
||||||
########## begin .sha256sums.recreate
|
source "$argv0dir/travis_testsuite_1-expected_sha256sums.sh" || exit 1
|
||||||
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="\
|
|
||||||
c82d400d99a78f21b594ad9900208ee89b3df5b67723c06dbb374dc3f42ca934 *amd64-linux.elf/upx-3.91
|
|
||||||
5b9ec916beae0eadc665235158a9ae5bce1309823a344503268a88e32e77824a *arm-wince.pe/upx-3.91.exe
|
|
||||||
a099aedddbaa960247209e08ed922b43f4bbd6559ad646a6ff801384e2f661eb *armeb-linux.elf/upx-3.91
|
|
||||||
960dc15876221832510142816605b9ef568c0de3050ca0a79f3553643c5d5e0f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
43ec77282bbe73eb5d6f5471e9593127928bcfc2ebaedd93dd86969b12c9c61d *i386-linux.elf/upx-3.91
|
|
||||||
ca6925a15c1ab8931f0a8fe9ef87f5893403d6e46098f4cd1a5f6f6f0fbdeb44 *i386-win32.pe/upx-3.91.exe
|
|
||||||
14ff2a4e215a25ed7442b004bca3d82094f7c01784fc4876eb50d365441f35c3 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
4163afbb2475b669e131265c0f7ea179c35f19ccce66732feee08fe20c33775e *mipsel-linux.elf/upx-3.91
|
|
||||||
00c9d16157a734e1b386e5fe01dbae76c7f8ab7d6035dfa6975d656b43ef4e67 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
|
||||||
27b530885ccb425cf14963feea677c4177cce5324821c277823b3262a7a6ced4 *amd64-linux.elf/upx-3.91
|
|
||||||
22216286b1bf3066d9022b921f37beff6712b5f3fc8c092f2dc1477638d9f8cc *arm-wince.pe/upx-3.91.exe
|
|
||||||
90e2960d01214b3e2f62f76effa2360fed655e72392acfa8096d1d9a729ade21 *armeb-linux.elf/upx-3.91
|
|
||||||
b6e98d36bd916fa63ec799e47dd7cac3674154370a9680492d84f1853bf14c3e *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
483e4a7eba0b88302658fcaacb7ee1de32fb514dac5dccb010a55a5202918c0c *i386-linux.elf/upx-3.91
|
|
||||||
d2692b3e4a278559456e299164714c4bb8ebbcf230ab12521619e2e94580597d *i386-win32.pe/upx-3.91.exe
|
|
||||||
cd1ae0f2781787bf7c61f3600cc889313e6027615d78e562d624d717671e55c3 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
26b30c10ba8980fa6fc564b79eb2931e07bb7b2f89f07a0656c28be71185a3ea *mipsel-linux.elf/upx-3.91
|
|
||||||
bbce9449d105e4ac7e9a04d56b286cbba3b34c1bf8ee928e9e97a4943ae3c5ac *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
|
||||||
81a528ed6f678bdbb1c18a9ee69b7d04169466e756a71baa98c7651ad1c40bec *amd64-linux.elf/upx-3.91
|
|
||||||
08c55815175ce0d34fca3b368336dd346a2354dbe4f046210c82f6961350a50f *arm-wince.pe/upx-3.91.exe
|
|
||||||
6dae3b18770e6af45e074b092c1f2f3632bef1996ce71af0f6e252caf34555a1 *armeb-linux.elf/upx-3.91
|
|
||||||
45f50d69e685f7ea752f76c05554d4c2ce023c0218465a4f8919138a76ae6c71 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
f1db16f6be23b0bd96226e7e57f8b41ddfb93ede5ca0750ae680bbd615523083 *i386-linux.elf/upx-3.91
|
|
||||||
eb7c2f74979c11b35193a0a9d428596bda46420d9363666fe1b967f5cd1610c6 *i386-win32.pe/upx-3.91.exe
|
|
||||||
cefb13395220fb2e931d0fb32e27663c4a27035f9e79131bbabc44fa54e6336e *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
602be188fca1dd63593a2ace68ea221d720fd2ddf9df85c1ab019feda69f1cad *mipsel-linux.elf/upx-3.91
|
|
||||||
2f299fdbc37bf6675559c5b1245aecf56de268bc074bd558bd7d9f84f7be5eae *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
|
||||||
12d2ec20370655396711fc794db41745c21f51c998b766e6aa96283feb00eb48 *amd64-linux.elf/upx-3.91
|
|
||||||
9759deb5aa8fb004c4b23bbe174042e45869aedeea1a1dd1b729be0e736814da *arm-wince.pe/upx-3.91.exe
|
|
||||||
9b25bcc69fcdbdf4b4adc54e5c6508749c918179644ff9fa34b437bc7e42eca5 *armeb-linux.elf/upx-3.91
|
|
||||||
a2a800d2ba5cfc1b6bb2b48c91adccb5d3c3b6c0b5c548affccac9244197a312 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
1865bc9b76579e33df4038f3d0abf848993b0c865b687f4b4bd482099416ef80 *i386-linux.elf/upx-3.91
|
|
||||||
80aba41aad8268085e853ec872f885981838a625c14095d21ba70cb7abe045a5 *i386-win32.pe/upx-3.91.exe
|
|
||||||
bbed61e42fa7b330b5cde66e4614329f41e21facff1f3667edc03495219c29f9 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
57b47244a3a0d01725cbdc9af8572cbe20e2d173857015ad4d32245b52577dc2 *mipsel-linux.elf/upx-3.91
|
|
||||||
6b02b01fa48910a104b523b265503131e4259ef83765464d002614e1a4eba38f *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
|
||||||
3e0df832830a4a0cca77da16868a2655f85b2b36f783123b6f067f5586460704 *amd64-linux.elf/upx-3.91
|
|
||||||
c7b0f611e9941be58b700219e7a5d34cdbdbf972b6184b13dec5e98fe84de808 *arm-wince.pe/upx-3.91.exe
|
|
||||||
ef7c6febc18d5ecf7d846f38d75f398a92b5b21eb5d35b1eac4935d0e6de92ac *armeb-linux.elf/upx-3.91
|
|
||||||
425c9128285f49b41f9b736f48794f5bebba6981250f669e5a342016b89f2170 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
d6cb6d50dfda98ff8efbab2d2c8751adfb67df58652313c630d45db1b89e921e *i386-linux.elf/upx-3.91
|
|
||||||
5565f8196d971feec261dc663ca7ec329fd82b1b18ad49593b865edbaa15765d *i386-win32.pe/upx-3.91.exe
|
|
||||||
78f24d77855034d467568f05c22cb5e3abd167c90a4d89f4e2059c3e6faa3e2b *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
23d6856df8f31b9176e0f4709135ce81656ed94539bf909e873b787ce89821cd *mipsel-linux.elf/upx-3.91
|
|
||||||
8dbf63b21d3ced1cceec71e507d3086de2612b8ce8ba35ee2d75acd06435baf1 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
|
||||||
27a248133cd386332daa14ec25367b4f1ff5595df213a2d72c341bbb7f264033 *amd64-linux.elf/upx-3.91
|
|
||||||
6b2333719a4fe6c8d2067f682d57cf6fc5fd928bffad4e61aaffcc31287772a7 *arm-wince.pe/upx-3.91.exe
|
|
||||||
d094f3a0e80e579aa6afeac239aacb3d8210580acdb095c9fc5511d77da7aeaa *armeb-linux.elf/upx-3.91
|
|
||||||
d09af3652aa601650f9cd0f125d54e50dfe57b45b9871567140e62a04d032407 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
110bb3344a27b2677085e130956371df43ca6c231c01070480bb3a9e519fed30 *i386-linux.elf/upx-3.91
|
|
||||||
c3c8b428f7e57a528db89f1365b4f3fda60f0dc03eadb30775ecdbadaa19f0aa *i386-win32.pe/upx-3.91.exe
|
|
||||||
53c77efbccf41072c4c206343ba3c838be04c47eab415d18c08f086d481612db *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
616cefa819c0e516c554faac20e6aaf9350a2aacf0041a2641d5809c0da220df *mipsel-linux.elf/upx-3.91
|
|
||||||
04ad8f4a60de80bbba7953489d3ef4b74b89a3961ae764acee00bd6df814ed9a *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
|
||||||
c8f0808d9cd81ece5f04c33388e6c5a056e2ceeb03308a1aa390ea6afc22d6ba *amd64-linux.elf/upx-3.91
|
|
||||||
685b7e419b8b0fe3cabdf338a5cad17da55edc608c1bb91c13580b5988d38908 *arm-wince.pe/upx-3.91.exe
|
|
||||||
7344cf818e8a668c7364f47779742bf41b451ebb7db85abc917c463a5f9c9d9a *armeb-linux.elf/upx-3.91
|
|
||||||
fd0652470c19ebb4a2d1a49e02e71acf9fadab78e513bb4f75d1dc26a0caa7a3 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
3b9dd7de613541f567b2573063399473deeaa015a1c3679fe0fb339d80724e0d *i386-linux.elf/upx-3.91
|
|
||||||
5b334db8debd2d59470cad25c7b45e38f6195cdafe92dc8281e4edc9c51385ef *i386-win32.pe/upx-3.91.exe
|
|
||||||
db1c6a70d990cb9a8e02db9b28054267658ce371b8a50e909efdd04cd3670279 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
19b801ace68ca0ff034dd557d3ef0a8340d8f17d7b97f120727f67ce098a7d7a *mipsel-linux.elf/upx-3.91
|
|
||||||
a0b3ba40848df9b3a8aac31bc20671992be179ec2d702337bd1addd15513c2e4 *powerpc-linux.elf/upx-3.91
|
|
||||||
"
|
|
||||||
########## end .sha256sums.recreate
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // init
|
# // init
|
||||||
@@ -241,8 +137,6 @@ if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
|||||||
set +e
|
set +e
|
||||||
fi
|
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
|
if [[ -z $upx_exe ]]; then exit 1; fi
|
||||||
upx_run=$upx_exe
|
upx_run=$upx_exe
|
||||||
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
||||||
@@ -263,18 +157,16 @@ if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
|
|||||||
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
(cd / && cd $upx_BUILDDIR && lcov -d . --zerocounters)
|
|
||||||
fi
|
|
||||||
|
|
||||||
export UPX="--prefer-ucl --no-color --no-progress"
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
|
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
||||||
|
|
||||||
# let's go
|
# let's go
|
||||||
if ! $upx_run --version; then echo "UPX-ERROR: FATAL: upx --version FAILED"; exit 1; fi
|
if ! $upx_run --version-short; then echo "UPX-ERROR: FATAL: upx --version-short 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 -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
|
if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
rm -rf ./testsuite_1
|
rm -rf ./testsuite_1
|
||||||
mkbuilddirs testsuite_1
|
mkdir testsuite_1
|
||||||
cd testsuite_1 || exit 1
|
cd testsuite_1 || exit 1
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
@@ -285,7 +177,7 @@ testdir=t010_decompressed
|
|||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
|
||||||
testsuite_header $testdir
|
testsuite_header $testdir
|
||||||
for f in $upx_testsuite_SRCDIR/files/packed/*/upx-3.91*; do
|
for f in $upx_testsuite_SRCDIR/files/packed/*/upx-3.9[15]*; do
|
||||||
testsuite_split_f $f
|
testsuite_split_f $f
|
||||||
[[ -z $fb ]] && continue
|
[[ -z $fb ]] && continue
|
||||||
echo "# $f"
|
echo "# $f"
|
||||||
@@ -294,7 +186,6 @@ for f in $upx_testsuite_SRCDIR/files/packed/*/upx-3.91*; do
|
|||||||
done
|
done
|
||||||
testsuite_check_sha $testdir
|
testsuite_check_sha $testdir
|
||||||
|
|
||||||
|
|
||||||
# run one pack+unpack step to canonicalize the files
|
# run one pack+unpack step to canonicalize the files
|
||||||
testdir=t020_canonicalized
|
testdir=t020_canonicalized
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
@@ -316,52 +207,71 @@ testsuite_check_sha $testdir
|
|||||||
# // test UPX and not the compression libraries
|
# // test UPX and not the compression libraries
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
|
case $UPX_TESTSUITE_FAST in
|
||||||
|
[0-7]) ;;
|
||||||
|
*) UPX_TESTSUITE_FAST=999 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 1 ]]; then
|
||||||
testdir=t110_compress_ucl_nrv2b_3_no_filter
|
testdir=t110_compress_ucl_nrv2b_3_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --nrv2b -3 --no-filter
|
time testsuite_run_compress --nrv2b -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 2 ]]; then
|
||||||
testdir=t120_compress_ucl_nrv2d_3_no_filter
|
testdir=t120_compress_ucl_nrv2d_3_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --nrv2d -3 --no-filter
|
time testsuite_run_compress --nrv2d -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 3 ]]; then
|
||||||
testdir=t130_compress_ucl_nrv2e_3_no_filter
|
testdir=t130_compress_ucl_nrv2e_3_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --nrv2e -3 --no-filter
|
time testsuite_run_compress --nrv2e -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 4 ]]; then
|
||||||
testdir=t140_compress_lzma_2_no_filter
|
testdir=t140_compress_lzma_2_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --lzma -2 --no-filter
|
time testsuite_run_compress --lzma -2 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 5 ]]; then
|
||||||
testdir=t150_compress_ucl_2_all_filters
|
testdir=t150_compress_ucl_2_all_filters
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress -2 --all-filters
|
time testsuite_run_compress -2 --all-filters
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 6 ]]; then
|
||||||
testdir=t160_compress_all_methods_1_no_filter
|
testdir=t160_compress_all_methods_1_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --all-methods -1 --no-filter
|
time testsuite_run_compress --all-methods -1 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_FAST -ge 7 ]]; then
|
||||||
testdir=t170_compress_all_methods_no_lzma_5_no_filter
|
testdir=t170_compress_all_methods_no_lzma_5_no_filter
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
|
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // summary
|
# // summary
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
# recreate checkums from current version for an easy update in case of changes
|
# recreate checksums from current version for an easy update in case of changes
|
||||||
recreate_expected_sha256sums .sha256sums.recreate
|
recreate_expected_sha256sums .sha256sums.recreate
|
||||||
|
|
||||||
testsuite_header "UPX testsuite summary"
|
testsuite_header "UPX testsuite summary"
|
||||||
if ! $upx_run --version; then
|
if ! $upx_run --version-short; then
|
||||||
echo "UPX-ERROR: upx --version FAILED"
|
echo "UPX-ERROR: upx --version-short FAILED"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
echo "upx_exe='$upx_exe'"
|
echo "upx_exe='$upx_exe'"
|
||||||
if [[ "$upx_run" != "$upx_exe" ]]; then
|
if [[ $upx_run != "$upx_exe" ]]; then
|
||||||
echo "upx_run='$upx_run'"
|
echo "upx_run='$upx_run'"
|
||||||
fi
|
fi
|
||||||
if [[ -f "$upx_exe" ]]; then
|
if [[ -f $upx_exe ]]; then
|
||||||
ls -l "$upx_exe"
|
ls -l "$upx_exe"
|
||||||
file "$upx_exe" || true
|
file "$upx_exe" || true
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -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,437 @@
|
|||||||
|
# Support for GitHub Actions -- https://github.com/features/actions
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job-rebuild-and-verify-stubs:
|
||||||
|
name: 'Rebuild stubs'
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- name: 'Install extra packages'
|
||||||
|
run: |
|
||||||
|
uname -a; pwd; id; umask
|
||||||
|
mkdir ../deps; cd ../deps; mkdir packages
|
||||||
|
# for ubuntu-22.04: install python2-minimal
|
||||||
|
##sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
|
||||||
|
# manually install compat libs from Ubuntu 16.04
|
||||||
|
wget -q 'http://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
|
||||||
|
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
||||||
|
rm -rf ./*.deb ./packages
|
||||||
|
sudo ldconfig
|
||||||
|
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- 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
|
||||||
|
- name: 'Check source code formatting'
|
||||||
|
run: |
|
||||||
|
bash ./misc/scripts/check_whitespace_git.sh
|
||||||
|
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
|
||||||
|
|
||||||
|
job-linux-cmake:
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('{0} cmake', matrix.os) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { os: ubuntu-22.04, use_m32: true }
|
||||||
|
- { os: ubuntu-20.04, use_m32: false }
|
||||||
|
steps:
|
||||||
|
- name: 'Install extra 32-bit and Windows packages'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: |
|
||||||
|
sudo dpkg --add-architecture i386
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: 'Check out test suite'
|
||||||
|
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||||
|
- name: 'Build cmake extra/gcc/debug'
|
||||||
|
run: 'make build/extra/gcc/debug'
|
||||||
|
- name: 'Build cmake extra/gcc/release'
|
||||||
|
run: 'make build/extra/gcc/release'
|
||||||
|
- name: 'Build cmake extra/clang/debug'
|
||||||
|
run: 'make build/extra/clang/debug'
|
||||||
|
- name: 'Build cmake extra/clang/release'
|
||||||
|
run: 'make build/extra/clang/release'
|
||||||
|
- name: 'Build cmake extra/gcc-m32/debug'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/gcc-m32/debug'
|
||||||
|
- name: 'Build cmake extra/gcc-m32/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/gcc-m32/release'
|
||||||
|
- name: 'Build cmake extra/cross-windows-mingw32/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/cross-windows-mingw32/release'
|
||||||
|
- name: 'Build cmake extra/cross-windows-mingw64/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/cross-windows-mingw64/release'
|
||||||
|
- name: 'Make artifact'
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||||
|
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")
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
- name: 'Run basic tests'
|
||||||
|
run: |
|
||||||
|
make -C build/extra/gcc/debug test
|
||||||
|
make -C build/extra/gcc/release test
|
||||||
|
make -C build/extra/clang/debug test
|
||||||
|
make -C build/extra/clang/release test
|
||||||
|
- name: 'Run basic tests 32-bit'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: |
|
||||||
|
make -C build/extra/gcc-m32/debug test
|
||||||
|
make -C build/extra/gcc-m32/release test
|
||||||
|
- name: 'Run test suite build/extra/gcc/release'
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
|
job-macos-cmake:
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('{0} cmake', matrix.os) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
|
||||||
|
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
|
||||||
|
steps:
|
||||||
|
- name: 'Install brew packages'
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: |
|
||||||
|
brew update
|
||||||
|
brew install coreutils
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
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'
|
||||||
|
- name: 'Build cmake extra/clang/debug'
|
||||||
|
run: 'make build/extra/clang/debug'
|
||||||
|
- name: 'Build cmake extra/clang/release'
|
||||||
|
run: 'make build/extra/clang/release'
|
||||||
|
- name: 'Build cmake extra/gcc/debug'
|
||||||
|
if: ${{ matrix.gcc != '' }}
|
||||||
|
run: 'make build/extra/gcc/debug CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||||
|
- name: 'Build cmake extra/gcc/release'
|
||||||
|
if: ${{ matrix.gcc != '' }}
|
||||||
|
run: 'make build/extra/gcc/release CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||||
|
- name: 'Build cmake xtarget/cross-darwin-arm64/debug'
|
||||||
|
run: |
|
||||||
|
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
|
||||||
|
make UPX_XTARGET=cross-darwin-arm64 xtarget/debug
|
||||||
|
- name: 'Build cmake xtarget/cross-darwin-arm64/release'
|
||||||
|
run: |
|
||||||
|
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
|
||||||
|
make UPX_XTARGET=cross-darwin-arm64 xtarget/release
|
||||||
|
- name: 'Make artifact'
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||||
|
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")
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
- name: 'Run basic tests'
|
||||||
|
run: |
|
||||||
|
make -C build/extra/clang/debug test
|
||||||
|
make -C build/extra/clang/release test
|
||||||
|
- name: 'Run test suite build/extra/clang/release'
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
|
job-windows-cmake:
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('{0} cmake', matrix.os) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# windows-2019 used to work but got broken with the 20220821.1 runner-image
|
||||||
|
# update; we cannot download that image for inspection, and debugging the
|
||||||
|
# remote image is painful, so disable for now
|
||||||
|
# see https://github.com/actions/runner-images.git
|
||||||
|
####- { os: windows-2019 }
|
||||||
|
- { os: windows-2022 }
|
||||||
|
steps:
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: 'Check out test suite'
|
||||||
|
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||||
|
- name: 'Inspect runner-image settings'
|
||||||
|
# debug remote image; also see https://github.com/actions/runner-images.git
|
||||||
|
if: ${{ false }}
|
||||||
|
run: |
|
||||||
|
Get-Command bash; Get-Command cmake; Get-Command make
|
||||||
|
bash --version; cmake --version; make --version
|
||||||
|
Get-Command cl -ErrorAction SilentlyContinue
|
||||||
|
- name: 'Build cmake debug'
|
||||||
|
run: 'make build/debug'
|
||||||
|
- name: 'Build cmake release'
|
||||||
|
run: 'make build/release'
|
||||||
|
- name: 'Make artifact'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||||
|
mkdir -p "tmp/artifact/$N"
|
||||||
|
(cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N")
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
- name: 'Run basic tests'
|
||||||
|
run: |
|
||||||
|
cmake --build build/debug --config Debug --target RUN_TESTS
|
||||||
|
cmake --build build/release --config Release --target RUN_TESTS
|
||||||
|
- name: 'Run test suite build/release'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
|
job-windows-toolchains:
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('windows {0}', matrix.name) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
C: ${{ matrix.C }}
|
||||||
|
B: release
|
||||||
|
H: 'd:\a\upx\upx'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { name: amd64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64 }
|
||||||
|
- { name: amd64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64 }
|
||||||
|
- { name: arm64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64_arm64 }
|
||||||
|
- { name: arm64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64_arm64 }
|
||||||
|
- { name: i386-win32-vs2019, os: windows-2019, C: msvc-14.2-x86, arch: amd64_x86 }
|
||||||
|
- { name: i386-win32-vs2022, os: windows-2022, C: msvc-14.3-x86, arch: amd64_x86 }
|
||||||
|
steps:
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: 'Prepare sources and Check out test suite'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git config --global core.autocrlf input
|
||||||
|
git --version && bash --version
|
||||||
|
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
|
mkdir -p -v build/$C/$B/{ucl,upx,zlib,zstd}
|
||||||
|
- name: 'Set up Developer Command Prompt'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
- name: 'Build'
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
@REM setup directories
|
||||||
|
where cl & where link
|
||||||
|
set BDIR=%H%\build\%C%\%B%
|
||||||
|
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
|
||||||
|
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||||
|
@REM ===== build UCL =====
|
||||||
|
cd %BDIR%\ucl
|
||||||
|
set s=%H%\vendor\ucl
|
||||||
|
cl -MT -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||||
|
link -lib -out:ucl.lib *.obj
|
||||||
|
@REM ===== build zlib =====
|
||||||
|
cd %BDIR%\zlib
|
||||||
|
cl -MT -J -O2 -W3 -WX %DEFS% -c %H%\vendor\zlib\*.c
|
||||||
|
link -lib -out:zlib.lib *.obj
|
||||||
|
@REM ===== build zstd =====
|
||||||
|
@rem cd %BDIR%\zstd
|
||||||
|
@rem set s=%H%\vendor\zstd\lib
|
||||||
|
@rem cl -MT -J -O2 -W4 -WX -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM %DEFS% -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
|
||||||
|
@rem link -lib -out:zstd.lib *.obj
|
||||||
|
@REM ===== build UPX =====
|
||||||
|
cd %BDIR%\upx
|
||||||
|
set s=%H%\src
|
||||||
|
cat .GITREV.txt
|
||||||
|
set /p GITREV=<.GITREV.txt
|
||||||
|
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
||||||
|
cl -MT -std:c++17 -Zc:__cplusplus -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" -DWITH_ZSTD=0 %DEFS% -I%H%\vendor -I%H%\vendor\boost-pfr\include -Feupx.exe %sources% %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj
|
||||||
|
- name: 'Make artifact'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}
|
||||||
|
mkdir -p "tmp/artifact/$N/$B"
|
||||||
|
cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
- name: 'Run basic tests'
|
||||||
|
if: ${{ matrix.arch != '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 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.arch != 'amd64_arm64' }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
|
||||||
|
|
||||||
|
job-linux-zigcc:
|
||||||
|
if: ${{ true }}
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
##container: alpine:3.17 # older versions such as alpine:3.12 also work; no-container also works
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { zig_target: aarch64-linux-musl }
|
||||||
|
- { zig_target: aarch64-macos.11-none }
|
||||||
|
- { zig_target: aarch64-macos.12-none }
|
||||||
|
- { zig_target: aarch64-macos.13-none }
|
||||||
|
- { zig_target: aarch64-windows-gnu }
|
||||||
|
- { zig_target: i386-linux-musl }
|
||||||
|
- { zig_target: i386-windows-gnu }
|
||||||
|
- { zig_target: x86_64-linux-musl }
|
||||||
|
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
|
||||||
|
- { zig_target: x86_64-macos.11-none }
|
||||||
|
- { zig_target: x86_64-macos.12-none }
|
||||||
|
- { zig_target: x86_64-macos.13-none }
|
||||||
|
- { zig_target: x86_64-windows-gnu }
|
||||||
|
env:
|
||||||
|
# 2023-01-30
|
||||||
|
ZIG_DIST_VERSION: 0.11.0-dev.1491+2b27bc2c6
|
||||||
|
# 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 file git make tar xz
|
||||||
|
# set PATH like in Ubuntu
|
||||||
|
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
|
||||||
|
# this seems to be needed when running in a container (beause of UID mismatch??)
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# GitHub Actions magic: set "UPX_GITREV_SHORT" environment value for use in steps below
|
||||||
|
rev=$(git rev-parse --short=7 HEAD)
|
||||||
|
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
|
||||||
|
# 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}
|
||||||
|
wget -q '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: |
|
||||||
|
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/release
|
||||||
|
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release
|
||||||
|
cmake ../../../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_RELEASE
|
||||||
|
cmake --build . --config Release --parallel --verbose
|
||||||
|
file ./upx*
|
||||||
|
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||||
|
run: |
|
||||||
|
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
|
||||||
|
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
|
||||||
|
cmake ../../../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_DEBUG
|
||||||
|
cmake --build . --config Debug --parallel --verbose
|
||||||
|
file ./upx*
|
||||||
|
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}
|
||||||
|
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")
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
|
||||||
|
# vim:set ts=2 sw=2 et:
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# 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 inactive issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '30 6 * * 4'
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
close-issues:
|
||||||
|
name: 'Close inactive issues'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v7
|
||||||
|
with:
|
||||||
|
operations-per-run: 300
|
||||||
|
exempt-all-milestones: true
|
||||||
|
exempt-issue-labels: 'blocker,enhancement,regression'
|
||||||
|
days-before-stale: 60
|
||||||
|
days-before-close: 30
|
||||||
|
stale-issue-message: 'This issue is stale because it has been open 60 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 60 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 }}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
name: 'Static Analyzer - CodeQL'
|
||||||
|
|
||||||
|
on:
|
||||||
|
# push:
|
||||||
|
# branches: [ 'devel', 'devel4', 'devel5', 'master' ]
|
||||||
|
# pull_request:
|
||||||
|
# # The branches below must be a subset of the branches above
|
||||||
|
# branches: [ 'devel', 'devel4', 'devel5' ]
|
||||||
|
schedule:
|
||||||
|
- cron: '20 1 * * 3'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'cpp' ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# minimal GitHub CI building UPX with clang and gcc in an Alpine Linux container
|
||||||
|
|
||||||
|
name: 'CI - Minimal CI with Alpine Linux'
|
||||||
|
|
||||||
|
on: { workflow_dispatch: }
|
||||||
|
jobs:
|
||||||
|
job-alpine-cmake:
|
||||||
|
strategy: {matrix: {container: ['alpine:3.12','alpine:3.17','alpine:edge']}}
|
||||||
|
name: ${{ format('container {0}', matrix.container) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: ${{ matrix.container }}
|
||||||
|
steps:
|
||||||
|
- name: ${{ format('Install packages {0}', matrix.container) }}
|
||||||
|
run: 'apk update && apk upgrade && apk add bash clang cmake g++ git make'
|
||||||
|
- name: ${{ format('Check out code upx-{0}', github.ref_name) }}
|
||||||
|
run: |
|
||||||
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
|
||||||
|
git -C upx submodule update --init
|
||||||
|
echo "artifact_name=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-minimal-ci-${{ matrix.container }}" | sed 's/[:,; ]/-/g' >> $GITHUB_ENV
|
||||||
|
- { name: 'Build clang', run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' }
|
||||||
|
- { name: 'Build gcc', run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' }
|
||||||
|
- { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' }
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: 'upx*/build/*/*/*/upx'
|
||||||
|
- { name: 'Run basic tests clang', run: 'make -C upx/build/xtarget/clang-static/release test' }
|
||||||
|
- { name: 'Run basic tests gcc', run: 'make -C upx/build/xtarget/gcc-static/release test' }
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
name: 'GitHub - Close pull requests'
|
||||||
|
on:
|
||||||
|
#pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
close-pull-requests:
|
||||||
|
name: 'Close pull requests'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: 'Close pull requests'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh pr list --repo='${{ github.repository }}' --state=open --json=number | jq '.[].number' | xargs -r -n1 -- gh pr close --repo='${{ github.repository }}'
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: 'Static Analyzer - scan-build'
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '40 1 * * 3'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: 'alpine:edge'
|
||||||
|
steps:
|
||||||
|
- name: 'Install packages'
|
||||||
|
run: 'apk update && apk upgrade && apk add bash clang clang-analyzer cmake g++ git make'
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: 'Perform scan-build Analysis Debug'
|
||||||
|
run: 'make build/extra/scan-build/debug'
|
||||||
|
- name: 'Perform scan-build Analysis Release'
|
||||||
|
run: 'make build/extra/scan-build/release'
|
||||||
+9
-25
@@ -1,58 +1,42 @@
|
|||||||
/.bzr*
|
|
||||||
/.hg*
|
/.hg*
|
||||||
/.vscode*
|
/.vscode*
|
||||||
/Makevars.global*
|
/Makevars.global*
|
||||||
/build*
|
/build*
|
||||||
/maint*
|
/maint*
|
||||||
|
/vendor*
|
||||||
|
|
||||||
.depend
|
|
||||||
GNUmakefile
|
GNUmakefile
|
||||||
MMakefile
|
MMakefile
|
||||||
Makevars.local*
|
Makevars.local*
|
||||||
tmp-testsuite*
|
tmp*
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
|
*.d
|
||||||
*.dll
|
*.dll
|
||||||
|
*.exe
|
||||||
*.lib
|
*.lib
|
||||||
|
*.map
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.out
|
||||||
*.py[cdo]
|
*.py[cdo]
|
||||||
*.so
|
*.so
|
||||||
*.swp
|
*.swp
|
||||||
|
*.ttp
|
||||||
|
|
||||||
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*/*.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
|
||||||
|
|||||||
+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
|
||||||
|
|||||||
-262
@@ -1,262 +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
|
|
||||||
- llvm-toolchain-precise-3.9
|
|
||||||
|
|
||||||
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:
|
|
||||||
fast_finish: 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" ] } }
|
|
||||||
- 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.9-m32
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9", "g++-6-multilib", "zlib1g-dev:i386" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.9-m64
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.9-m64 B=debug+sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.9-m64 B=sanitize
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.9-m64 B=debug+scan-build
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9" ] } }
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-3.9-m64 B=scan-build
|
|
||||||
addons: { apt: { sources: *S, packages: [ "clang-3.9" ] } }
|
|
||||||
- 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.3
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-802-m32
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode8.3
|
|
||||||
compiler: clang
|
|
||||||
env: C=clang-802-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:
|
|
||||||
- success=1
|
|
||||||
- cd $TRAVIS_BUILD_DIR || success=0
|
|
||||||
- test $success = 0 || bash ./.github/travis_build.sh || success=0
|
|
||||||
- test $success = 0 || bash ./.github/travis_testsuite_1.sh || success=0
|
|
||||||
- test $success = 0 || bash ./.github/travis_deploy.sh || success=0
|
|
||||||
- test $success = 1
|
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
|
||||||
+349
@@ -0,0 +1,349 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
|
||||||
|
|
||||||
|
# compilation config options
|
||||||
|
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||||
|
# permissive config defaults when building from source code tarball
|
||||||
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." ON)
|
||||||
|
else()
|
||||||
|
# strict config defaults for devel builds
|
||||||
|
message(STATUS "===== UPX info: strict config defaults enabled")
|
||||||
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# test config options (see below)
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# init
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# Disallow in-source builds. Note that you will still have to manually
|
||||||
|
# clean up a few files if you accidentally try an in-source build.
|
||||||
|
if(NOT MSVC_IDE)
|
||||||
|
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||||
|
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||||
|
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
|
||||||
|
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# determine git revision
|
||||||
|
set(GITREV_SHORT "")
|
||||||
|
set(GITREV_PLUS "")
|
||||||
|
set(GIT_DESCRIBE "")
|
||||||
|
find_package(Git)
|
||||||
|
if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||||
|
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()
|
||||||
|
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
|
||||||
|
set(GITREV_SHORT "")
|
||||||
|
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
|
||||||
|
project(upx VERSION 4.0.2 LANGUAGES C CXX)
|
||||||
|
|
||||||
|
# set default build type to "Release"
|
||||||
|
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(is_multi_config)
|
||||||
|
set(c "${CMAKE_CONFIGURATION_TYPES}")
|
||||||
|
list(INSERT c 0 "Release")
|
||||||
|
list(INSERT c 1 "Debug")
|
||||||
|
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)
|
||||||
|
elseif(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# targets and compilation flags
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
#find_package(Threads) # multithreading is currently not used; maybe in UPX version 5
|
||||||
|
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
|
||||||
|
|
||||||
|
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
|
||||||
|
list(SORT ucl_SOURCES)
|
||||||
|
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
||||||
|
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
|
||||||
|
|
||||||
|
file(GLOB zlib_SOURCES "vendor/zlib/*.c")
|
||||||
|
list(SORT zlib_SOURCES)
|
||||||
|
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
||||||
|
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c")
|
||||||
|
list(SORT zstd_SOURCES)
|
||||||
|
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
|
||||||
|
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
|
||||||
|
list(SORT upx_SOURCES)
|
||||||
|
add_executable(upx ${upx_SOURCES})
|
||||||
|
set_property(TARGET upx PROPERTY CXX_STANDARD 17)
|
||||||
|
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
||||||
|
|
||||||
|
if(NOT MSVC)
|
||||||
|
# rather strict default compilation warnings
|
||||||
|
set(warn_strict
|
||||||
|
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations
|
||||||
|
-Wpointer-arith -Wshadow -Wvla -Wwrite-strings
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(UPX_CONFIG_DISABLE_WERROR)
|
||||||
|
set(warn_Werror "")
|
||||||
|
set(warn_WX "")
|
||||||
|
else()
|
||||||
|
set(warn_Werror -Werror)
|
||||||
|
set(warn_WX -WX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT 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)
|
||||||
|
# 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)
|
||||||
|
# set __cplusplus according to selected C++ standard; use new preprocessor
|
||||||
|
add_definitions(-Zc:__cplusplus -Zc:preprocessor)
|
||||||
|
else()
|
||||||
|
# protect against security threats caused by misguided compiler "optimizations"
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
|
||||||
|
endif()
|
||||||
|
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
||||||
|
# disable overambitious auto-vectorization until this actually gains something
|
||||||
|
add_definitions(-fno-tree-vectorize)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# compile a target with -O2 in Debug build
|
||||||
|
function(upx_compile_target_debug_with_O2 t)
|
||||||
|
if(MSVC)
|
||||||
|
# msvc uses some Debug compile options like -RTC1 that are incompatible with -O2
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_sanitize_target t)
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
|
||||||
|
if(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
|
||||||
|
# avoid link errors with current MinGW-w64 versions
|
||||||
|
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
|
||||||
|
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:Release>:-fstack-protector>)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
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)
|
||||||
|
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(t upx_vendor_zlib)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_UNISTD_H -DHAVE_VSNPRINTF)
|
||||||
|
# clang-15: -Wno-strict-prototypes is needed to silence the new -Wdeprecated-non-prototype warning
|
||||||
|
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
set(t upx_vendor_zstd)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
target_compile_options(${t} PRIVATE -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM)
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(t upx)
|
||||||
|
target_include_directories(${t} PRIVATE vendor vendor/boost-pfr/include)
|
||||||
|
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()
|
||||||
|
#upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||||
|
target_link_libraries(upx upx_vendor_zstd)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# "ctest"
|
||||||
|
# "make test"
|
||||||
|
# "ninja test"
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
|
add_test(NAME upx-version COMMAND upx --version)
|
||||||
|
add_test(NAME upx-help COMMAND upx --help)
|
||||||
|
endif()
|
||||||
|
if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||||
|
# NOTE: these tests can only work if the host executable format is supported by UPX!
|
||||||
|
function(upx_add_test)
|
||||||
|
set(name ${ARGV0})
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
add_test(NAME ${name} COMMAND ${ARGV})
|
||||||
|
set_tests_properties(${name} PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially
|
||||||
|
endfunction()
|
||||||
|
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(upx_self_exe "$<TARGET_FILE:upx>")
|
||||||
|
set(fo "--force-overwrite")
|
||||||
|
upx_add_test(upx-self-pack upx -3 ${upx_self_exe} ${fo} -o upx-packed${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2b upx -3 --nrv2b ${upx_self_exe} ${fo} -o upx-packed-n2b${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2d upx -3 --nrv2d ${upx_self_exe} ${fo} -o upx-packed-n2d${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2e upx -3 --nrv2e ${upx_self_exe} ${fo} -o upx-packed-n2e${exe})
|
||||||
|
upx_add_test(upx-self-pack-lzma upx -3 --lzma ${upx_self_exe} ${fo} -o upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
|
||||||
|
upx_add_test(upx-run-unpacked ./upx-unpacked${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# "cmake --install ."
|
||||||
|
# "make install"
|
||||||
|
# "ninja 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()
|
||||||
|
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||||
|
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||||
|
install(FILES
|
||||||
|
COPYING LICENSE NEWS README THANKS 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
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# finally print some info about the build configuration
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(print_var)
|
||||||
|
foreach(v ${ARGV})
|
||||||
|
if(${v})
|
||||||
|
message(STATUS "${v} = ${${v}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||||
|
print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
|
||||||
|
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING)
|
||||||
|
print_var(CMAKE_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_ARCHITECTURE_ID CMAKE_C_PLATFORM_ID CMAKE_C_COMPILER_ABI)
|
||||||
|
print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
|
||||||
|
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
|
||||||
|
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$")
|
||||||
|
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
|
||||||
|
# extra sanity checks to detect incompatible C vs CXX settings
|
||||||
|
if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},")
|
||||||
|
message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch")
|
||||||
|
endif()
|
||||||
|
if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},")
|
||||||
|
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch")
|
||||||
|
endif()
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
|
||||||
|
|
||||||
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
@@ -1,36 +1,186 @@
|
|||||||
#
|
#
|
||||||
# UPX toplevel Makefile - needs GNU make 3.81 or better
|
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||||
#
|
|
||||||
# Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
# INFO: this Makefile is just a convenience wrapper for calling CMake
|
||||||
|
|
||||||
|
# NOTE: 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 ../..
|
||||||
|
# make -j (or use "cmake --build . --parallel")
|
||||||
|
|
||||||
|
CMAKE = cmake
|
||||||
|
UPX_CMAKE_BUILD_FLAGS += --parallel
|
||||||
|
ifneq ($(VERBOSE),)
|
||||||
|
UPX_CMAKE_BUILD_FLAGS += --verbose
|
||||||
|
endif
|
||||||
|
# enable this if you prefer Ninja for the actual builds:
|
||||||
|
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# default
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
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 CMakeCache.txt already exists
|
||||||
|
run_config = $(if $(wildcard $1/CMakeCache.txt),,$(call run_cmake_config,$1,$2))
|
||||||
|
run_build = $(call run_cmake_build,$1,$2)
|
||||||
|
|
||||||
|
.DEFAULT_GOAL = build/release
|
||||||
|
|
||||||
|
build/debug: PHONY
|
||||||
|
$(call run_config,$@,Debug)
|
||||||
|
$(call run_build,$@,Debug)
|
||||||
|
|
||||||
|
build/release: PHONY
|
||||||
|
$(call run_config,$@,Release)
|
||||||
|
$(call run_build,$@,Release)
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
all: build/debug build/release
|
||||||
|
debug: build/debug
|
||||||
|
release: build/release
|
||||||
|
|
||||||
|
.PHONY: PHONY
|
||||||
|
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
export SHELL = /bin/sh
|
|
||||||
|
|
||||||
srcdir = .
|
# END of Makefile; extra stuff follows
|
||||||
top_srcdir = .
|
|
||||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
#***********************************************************************
|
||||||
|
# extra builds: some pre-defined build configurations
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
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 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 clang Static Analyzer (scan-build)
|
||||||
|
build/extra/scan-build/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/scan-build/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/scan-build/%: CMAKE := scan-build $(CMAKE)
|
||||||
|
build/extra/scan-build/%: export CCC_CC ?= clang
|
||||||
|
build/extra/scan-build/%: export CCC_CXX ?= clang++
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc aarch64-linux-gnu
|
||||||
|
build/extra/cross-linux-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-aarch64/%: export CC = aarch64-linux-gnu-gcc
|
||||||
|
build/extra/cross-linux-aarch64/%: export CXX = aarch64-linux-gnu-g++
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc arm-linux-gnueabihf
|
||||||
|
build/extra/cross-linux-arm/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-arm/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-arm/%: export CC = arm-linux-gnueabihf-gcc
|
||||||
|
build/extra/cross-linux-arm/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
|
||||||
|
|
||||||
|
# cross compiler: Windows x86 win32 MinGW
|
||||||
|
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
|
||||||
|
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++
|
||||||
|
|
||||||
|
# cross compiler: Windows x64 win64 MinGW
|
||||||
|
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
|
||||||
|
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++
|
||||||
|
|
||||||
|
# cross compiler: macOS arm64
|
||||||
|
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
|
||||||
|
|
||||||
|
# cross compiler: macOS x86_64
|
||||||
|
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
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# 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/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/xtarget/$(UPX_XTARGET)/%: export CC
|
||||||
|
build/xtarget/$(UPX_XTARGET)/%: export CXX
|
||||||
|
# shortcuts
|
||||||
|
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug
|
||||||
|
xtarget/release: build/xtarget/$(UPX_XTARGET)/release
|
||||||
|
# set new default
|
||||||
|
.DEFAULT_GOAL = xtarget/release
|
||||||
|
|
||||||
# info: src/stub needs special build tools from https://github.com/upx/upx-stubtools
|
|
||||||
BUILD_STUB = 0
|
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/upx-stubtools-check-version),)
|
|
||||||
BUILD_STUB = 1
|
|
||||||
endif
|
endif
|
||||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/upx-stubtools-check-version),)
|
endif
|
||||||
BUILD_STUB = 1
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
default:
|
#***********************************************************************
|
||||||
@echo "UPX info: please choose a target for 'make'"
|
# check git submodules
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
all mostlyclean clean distclean maintainer-clean:
|
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
|
||||||
ifeq ($(BUILD_STUB),1)
|
|
||||||
$(MAKE) -C src/stub $@
|
|
||||||
endif
|
|
||||||
$(MAKE) -C src $@
|
|
||||||
$(MAKE) -C doc $@
|
|
||||||
|
|
||||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
|
||||||
|
$(error ERROR: missing git submodule $m; run 'git submodule update --init')))
|
||||||
# vim:set ts=8 sw=8 noet:
|
|
||||||
|
|||||||
@@ -2,6 +2,34 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
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):
|
Changes in 3.94 (12 May 2017):
|
||||||
* Add support for arm64-linux (aka "aarch64").
|
* Add support for arm64-linux (aka "aarch64").
|
||||||
* Add support for --lzma compression on 64-bit PowerPC (Thierry Fauck).
|
* Add support for --lzma compression on 64-bit PowerPC (Thierry Fauck).
|
||||||
@@ -10,12 +38,11 @@ Changes in 3.94 (12 May 2017):
|
|||||||
* bug fixes - see https://github.com/upx/upx/milestone/3
|
* 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/1
|
* 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.
|
||||||
@@ -111,7 +138,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):
|
||||||
@@ -344,6 +371,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
|
||||||
|
|||||||
@@ -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-2023 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, macOS apps 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2023 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
|
|
||||||
+11
-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,48 +41,33 @@ 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 supports 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/rebuild-stubs-with-podman - 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
|
||||||
|
|
||||||
|
|
||||||
@@ -114,9 +84,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 +95,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:
|
||||||
|
|||||||
@@ -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-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +55,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
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-std=gnu++17
|
||||||
|
-Ivendor
|
||||||
|
-fno-strict-aliasing
|
||||||
|
-fno-strict-overflow
|
||||||
|
-funsigned-char
|
||||||
+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-2023 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
|
||||||
|
|
||||||
+34
-40
@@ -1,21 +1,8 @@
|
|||||||
#
|
#
|
||||||
# UPX doc Makefile - needs GNU make 3.81 or better
|
# UPX doc Makefile - needs GNU make, pod2html, pod2man and pod2text
|
||||||
#
|
#
|
||||||
|
|
||||||
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 +10,62 @@ 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
|
||||||
|
|
||||||
###
|
all: $(BUILT_SOURCES) PHONY
|
||||||
### targets
|
|
||||||
###
|
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
mostlyclean clean distclean maintainer-clean: PHONY
|
||||||
|
rm -f $(BUILT_SOURCES) ./pod2htm*
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
#***********************************************************************
|
||||||
rm -f $(BUILT_SOURCES) pod2htm*
|
# rules
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.SUFFIXES:
|
||||||
|
.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 $@
|
||||||
|
|
||||||
%.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)
|
||||||
|
.PHONY: PHONY
|
||||||
|
|||||||
+1
-1
@@ -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-2023 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
|
|||||||
@@ -0,0 +1,807 @@
|
|||||||
|
<?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-2023 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 overlayed 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>
|
||||||
|
|
||||||
|
Jens Medoch <jssg@users.sourceforge.net></code></pre>
|
||||||
|
|
||||||
|
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
||||||
|
|
||||||
|
<p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p>
|
||||||
|
|
||||||
|
<p>Copyright (C) 1996-2023 Laszlo Molnar</p>
|
||||||
|
|
||||||
|
<p>Copyright (C) 2000-2023 John F. Reiser</p>
|
||||||
|
|
||||||
|
<p>Copyright (C) 2002-2023 Jens Medoch</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>
|
||||||
|
|
||||||
|
|
||||||
+842
@@ -0,0 +1,842 @@
|
|||||||
|
NAME
|
||||||
|
upx - compress or expand executable files
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
upx [ *command* ] [ *options* ] *filename*...
|
||||||
|
|
||||||
|
ABSTRACT
|
||||||
|
The Ultimate Packer for eXecutables
|
||||||
|
Copyright (c) 1996-2023 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 overlayed 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>
|
||||||
|
|
||||||
|
Jens Medoch <jssg@users.sourceforge.net>
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
|
|
||||||
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
|
|
||||||
|
Copyright (C) 2002-2023 Jens Medoch
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
+60
-60
@@ -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-2023 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 *
|
||||||
|
|
||||||
@@ -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.
|
||||||
|
|
||||||
@@ -934,22 +932,24 @@ Please report all bugs immediately to the authors.
|
|||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2017 Jens Medoch
|
Copyright (C) 2002-2023 Jens Medoch
|
||||||
|
|
||||||
This program may be used freely, and you are welcome to
|
B<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.
|
||||||
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.
|
||||||
|
|||||||
+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
|
||||||
|
|
||||||
|
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
|
||||||
|
# so you have to create that image first
|
||||||
|
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
|
||||||
|
image=upx-cross-compile-20230115-v2
|
||||||
|
|
||||||
|
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||||
|
|
||||||
|
podman image list "$image"
|
||||||
|
podman image tree "$image"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#! /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
|
||||||
|
|
||||||
|
image=upx-cross-compile-20230115-v2
|
||||||
|
|
||||||
|
flags=( -ti --read-only --rm )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
flags+=( -e TERM="$TERM" ) # 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
|
||||||
|
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
|
||||||
|
|
||||||
|
podman run "${flags[@]}" "$image" bash -l
|
||||||
|
|
||||||
|
# now we can cross-compile UPX for Windows:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/cross-windows-mingw64/release
|
||||||
|
# make build/extra/cross-windows-mingw64/release
|
||||||
|
|
||||||
|
# and we can run the clang Static Analyzer (scan-build)
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/scan-build/release
|
||||||
|
# make build/extra/scan-build/release
|
||||||
|
|
||||||
|
# and lots of other cross-compilers are installed; see "ls /usr/bin/*g++*"
|
||||||
|
|
||||||
|
# and finally see misc/cross-compile-upx-with-podman/build-all-inside-container.sh
|
||||||
|
# after running that script we can do cool things like:
|
||||||
|
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/alpha-linux-gnu/debug
|
||||||
|
# qemu-alpha -L /usr/alpha-linux-gnu upx --version
|
||||||
|
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/hppa-linux-gnu/debug
|
||||||
|
# qemu-hppa -L /usr/hppa-linux-gnu upx --version
|
||||||
|
# (similar for many other architectures/builds)
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
|
||||||
|
# so you have to create that image first
|
||||||
|
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
|
||||||
|
FROM localhost/upx-stubtools-20221212-v4
|
||||||
|
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-20230115-v2
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Ubuntu 22.04
|
||||||
|
RUN apt-get update && apt-get upgrade -y \
|
||||||
|
&& apt-get install -y \
|
||||||
|
# Linux glibc cross compilers
|
||||||
|
g++-aarch64-linux-gnu \
|
||||||
|
g++-alpha-linux-gnu \
|
||||||
|
g++-arm-linux-gnueabi \
|
||||||
|
g++-arm-linux-gnueabihf \
|
||||||
|
g++-hppa-linux-gnu \
|
||||||
|
g++-i686-linux-gnu \
|
||||||
|
g++-m68k-linux-gnu \
|
||||||
|
g++-mips-linux-gnu \
|
||||||
|
g++-mipsel-linux-gnu \
|
||||||
|
g++-mips64-linux-gnuabi64 \
|
||||||
|
g++-mips64el-linux-gnuabi64 \
|
||||||
|
g++-powerpc-linux-gnu \
|
||||||
|
g++-powerpc64-linux-gnu \
|
||||||
|
g++-powerpc64le-linux-gnu \
|
||||||
|
g++-riscv64-linux-gnu \
|
||||||
|
g++-s390x-linux-gnu \
|
||||||
|
g++-sh4-linux-gnu \
|
||||||
|
g++-sparc64-linux-gnu \
|
||||||
|
# Linux glibc cross compilers - ILP32 on 64-bit CPUs
|
||||||
|
g++-x86-64-linux-gnux32 \
|
||||||
|
# Windows cross compilers
|
||||||
|
g++-mingw-w64-i686 \
|
||||||
|
g++-mingw-w64-x86-64 \
|
||||||
|
&& true
|
||||||
|
RUN apt-get install -y \
|
||||||
|
# clang-14 and tools
|
||||||
|
clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \
|
||||||
|
# QEMU and Wine
|
||||||
|
qemu-system qemu-user wine wine32 \
|
||||||
|
# misc
|
||||||
|
gdb lsb-release valgrind \
|
||||||
|
&& true
|
||||||
|
RUN cd /usr/bin \
|
||||||
|
# create unversioned clang symlinks in /usr/local/bin
|
||||||
|
&& for f in clang*-14 llvm-*-14 scan-*-14; do ln -s -v ../../bin/$f /usr/local/bin/${f%-14}; done \
|
||||||
|
&& ln -s -v ../../bin/obj2yaml-14 /usr/local/bin/llvm-obj2yaml \
|
||||||
|
&& ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# switch back to default user upx 2000:2000
|
||||||
|
USER upx
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#! /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")"
|
||||||
|
|
||||||
|
# build UPX for 21 targets; must be run inside the container!
|
||||||
|
# using a rootless Podman container
|
||||||
|
|
||||||
|
# simple sanity check that we are indeed running inside the container
|
||||||
|
if [[ $UPX_CONTAINER_IMAGE_NAME != upx-cross-compile-* ]]; then
|
||||||
|
echo "$argv0: NOTE: please run this script *inside* the container"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# go to upx top-level directory
|
||||||
|
cd "$argv0dir/../.." || exit 1
|
||||||
|
pwd
|
||||||
|
[[ -f src/version.h ]] || exit 1 # sanity check
|
||||||
|
|
||||||
|
function run_config_and_build {
|
||||||
|
# requires: AR CC CXX RANLIB
|
||||||
|
local toolchain=$1
|
||||||
|
local cmake_config_flags build_type bdir
|
||||||
|
# cmake flags
|
||||||
|
cmake_config_flags=
|
||||||
|
case $toolchain in
|
||||||
|
# these old architectures do not support sanitize
|
||||||
|
alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
hppa-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
# avoid link errors with current MinGW-w64 versions
|
||||||
|
i686-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
x86_64-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
# avoid warnings about arm libstdc++ ABI change in gcc-7
|
||||||
|
arm-linux-*) CXX="$CXX -Wno-psabi" ;;
|
||||||
|
esac
|
||||||
|
if [[ 1 == 1 ]]; then
|
||||||
|
# prefer building with Ninja (ninja-build)
|
||||||
|
cmake_config_flags="$cmake_config_flags -G Ninja -DUPX_CONFIG_CMAKE_DISABLE_INSTALL=ON"
|
||||||
|
fi
|
||||||
|
# for all build types
|
||||||
|
for build_type in Debug Release; do
|
||||||
|
bdir=build/cross-compile-upx-with-podman/$toolchain/${build_type,,}
|
||||||
|
mkdir -p $bdir
|
||||||
|
# run_config
|
||||||
|
if [[ ! -f $bdir/CMakeCache.txt ]]; then
|
||||||
|
cmake -S . -B $bdir -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags
|
||||||
|
fi
|
||||||
|
# run_build
|
||||||
|
cmake --build $bdir --config $build_type --parallel
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# see Dockerfile for packages
|
||||||
|
for package in \
|
||||||
|
g++-aarch64-linux-gnu \
|
||||||
|
g++-alpha-linux-gnu \
|
||||||
|
g++-arm-linux-gnueabi \
|
||||||
|
g++-arm-linux-gnueabihf \
|
||||||
|
g++-hppa-linux-gnu \
|
||||||
|
g++-i686-linux-gnu \
|
||||||
|
g++-m68k-linux-gnu \
|
||||||
|
g++-mips-linux-gnu \
|
||||||
|
g++-mipsel-linux-gnu \
|
||||||
|
g++-mips64-linux-gnuabi64 \
|
||||||
|
g++-mips64el-linux-gnuabi64 \
|
||||||
|
g++-powerpc-linux-gnu \
|
||||||
|
g++-powerpc64-linux-gnu \
|
||||||
|
g++-powerpc64le-linux-gnu \
|
||||||
|
g++-riscv64-linux-gnu \
|
||||||
|
g++-s390x-linux-gnu \
|
||||||
|
g++-sh4-linux-gnu \
|
||||||
|
g++-sparc64-linux-gnu \
|
||||||
|
g++-x86-64-linux-gnux32 \
|
||||||
|
g++-mingw-w64-i686 \
|
||||||
|
g++-mingw-w64-x86-64
|
||||||
|
do
|
||||||
|
# setup toolchain and environment variables
|
||||||
|
toolchain=$package
|
||||||
|
toolchain=${toolchain/-x86-64/-x86_64}
|
||||||
|
toolchain=${toolchain/g++-/}
|
||||||
|
case $toolchain in
|
||||||
|
mingw-w64-i686) toolchain=i686-w64-mingw32 ;;
|
||||||
|
mingw-w64-x86_64) toolchain=x86_64-w64-mingw32 ;;
|
||||||
|
esac
|
||||||
|
echo "========== $toolchain"
|
||||||
|
export AR=/usr/bin/${toolchain}-ar
|
||||||
|
export CC=/usr/bin/${toolchain}-gcc
|
||||||
|
export CXX=/usr/bin/${toolchain}-g++
|
||||||
|
export RANLIB=/usr/bin/${toolchain}-ranlib
|
||||||
|
ls -l $AR $CC $CXX $RANLIB
|
||||||
|
run_config_and_build $toolchain
|
||||||
|
unset AR CC CXX RANLIB
|
||||||
|
done
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#! /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
|
||||||
|
|
||||||
|
image=upx-stubtools-20221212-v4
|
||||||
|
|
||||||
|
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||||
|
|
||||||
|
podman image list "$image"
|
||||||
|
podman image tree "$image"
|
||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
#! /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
|
||||||
|
|
||||||
|
image=upx-stubtools-20221212-v4
|
||||||
|
|
||||||
|
flags=( -ti --read-only --rm )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
flags+=( -e TERM="$TERM" ) # 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
|
||||||
|
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
|
||||||
|
|
||||||
|
podman run "${flags[@]}" "$image" bash -l
|
||||||
|
|
||||||
|
# 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 .
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
FROM docker.io/library/ubuntu:22.04
|
||||||
|
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v4
|
||||||
|
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 ca-certificates git less libmpc3 libncurses5 make \
|
||||||
|
ncurses-term perl-base python2-minimal 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 bzip2 cmake curl elfutils fd-find file fzf g++ gdb gojq htop hyperfine \
|
||||||
|
jq libzstd-dev lsb-release lzip lzop ninja-build p7zip patch patchelf pax-utils \
|
||||||
|
ripgrep rsync screen universal-ctags unzip vim zip zlib1g-dev zsh zstd \
|
||||||
|
# extra packages for compiling with "gcc -m32" and and "gcc -mx32":
|
||||||
|
gcc-multilib g++-multilib \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# manually install compat libs from Ubuntu 16.04; REQUIRED
|
||||||
|
RUN cd /root \
|
||||||
|
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
|
||||||
|
'http://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 \
|
||||||
|
&& for v in 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; 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 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; 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 user upx 2000:2000
|
||||||
|
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
||||||
|
&& mkdir -p /home/upx/.cache/zig /home/upx/.local/bin /home/upx/src/upx \
|
||||||
|
&& ln -s /usr/local/bin/bin-upx-20221212 /home/upx/.local/bin/bin-upx \
|
||||||
|
&& chown -R upx:upx /home/upx \
|
||||||
|
&& true
|
||||||
|
USER upx
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
|
||||||
|
# "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 1
|
||||||
+63
-133
@@ -1,18 +1,13 @@
|
|||||||
#
|
#
|
||||||
# UPX Makefile - needs GNU make 3.81 or better
|
# UPX Makefile - needs GNU make
|
||||||
#
|
|
||||||
# Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
#
|
#
|
||||||
|
|
||||||
# build configuration options for this Makefile
|
# IMPORTANT NOTE: this Makefile is deprecated - please
|
||||||
BUILD_TYPE_DEBUG ?= 0
|
# directly use the CMake build instead!
|
||||||
BUILD_TYPE_SANITIZE ?= 0
|
|
||||||
BUILD_USE_DEPEND ?= 1
|
|
||||||
|
|
||||||
MAKEFLAGS += -r
|
MAKEFLAGS += -r
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
export SHELL = /bin/sh
|
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 := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
@@ -21,156 +16,91 @@ endif
|
|||||||
ifndef top_srcdir
|
ifndef top_srcdir
|
||||||
top_srcdir := $(srcdir)/..
|
top_srcdir := $(srcdir)/..
|
||||||
endif
|
endif
|
||||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
|
||||||
ifneq ($(srcdir),.)
|
|
||||||
vpath %.cpp .:$(srcdir)
|
|
||||||
vpath %.h .:$(srcdir)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# toolchain
|
#
|
||||||
CXX ?= g++
|
# redirect to top-level CMake build
|
||||||
CXXLD = $(CXX)
|
#
|
||||||
exeext ?= .out
|
|
||||||
libext ?= .a
|
|
||||||
objext ?= .o
|
|
||||||
|
|
||||||
upx_SOURCES := $(sort $(wildcard $(srcdir)/*.cpp))
|
.DEFAULT_GOAL = build/debug
|
||||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
|
||||||
|
|
||||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
build/debug: $(top_srcdir)/build/debug/upx
|
||||||
UPX_VERSION_GITREV := $(strip $(shell cd '$(top_srcdir)' && git rev-parse --short=12 HEAD || echo 'ERROR'))
|
build/release: $(top_srcdir)/build/release/upx
|
||||||
ifneq ($(UPX_VERSION_GITREV),)
|
# shortcuts
|
||||||
GITREV_PLUS := $(strip $(shell cd '$(top_srcdir)' && git diff --exit-code HEAD >/dev/null && echo '' || echo '+'))
|
all: build/debug build/release
|
||||||
DEFS += '-DUPX_VERSION_GITREV="$(UPX_VERSION_GITREV)$(GITREV_PLUS)"'
|
debug: build/debug
|
||||||
endif
|
release: build/release
|
||||||
endif
|
|
||||||
|
|
||||||
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
$(top_srcdir)/build/debug/upx: PHONY
|
||||||
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
$(MAKE) -C $(top_srcdir) build/debug
|
||||||
INCLUDES += -I$(UPX_UCLDIR)/include
|
$(top_srcdir)/build/release/upx: PHONY
|
||||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
$(MAKE) -C $(top_srcdir) build/release
|
||||||
endif
|
|
||||||
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)
|
.PHONY: PHONY
|
||||||
ifeq ($(BUILD_TYPE_DEBUG),1)
|
.NOTPARALLEL:
|
||||||
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
|
|
||||||
CXXFLAGS += $(CXXFLAGS_SANITIZE)
|
|
||||||
# these are the only 2 objects that are actually speed-sensitive
|
|
||||||
compress_lzma$(objext) filteri$(objext) : override CXXFLAGS_SANITIZE =
|
|
||||||
endif
|
|
||||||
|
|
||||||
# rules
|
|
||||||
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"
|
# "make run-testsuite"
|
||||||
|
#
|
||||||
|
|
||||||
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
|
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
|
||||||
# you also can override upx_testsuite_SRCDIR
|
# 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)/.github/travis_testsuite_1.sh
|
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
|
||||||
# The actual (new) checksums are in tmp-testsuite/testsuite_1/.sha256sums.recreate
|
# The actual (new) checksums are in ./tmp-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)/.github/travis_testsuite_1.sh),)
|
||||||
run-testsuite: export upx_exe := ./upx$(exeext)
|
run-testsuite: run-testsuite-release
|
||||||
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||||
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
||||||
run-testsuite: ./upx$(exeext)
|
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
|
||||||
|
run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx
|
||||||
|
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
||||||
|
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
|
||||||
|
run-testsuite-release: PHONY $(top_srcdir)/build/release/upx
|
||||||
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
||||||
.PHONY: run-testsuite
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# "make clang-format"
|
||||||
|
#
|
||||||
|
|
||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp
|
# Markus loves clang-format, but John hates it; find a compromise
|
||||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
|
||||||
CLANG_FORMAT_FILES += snprintf.cpp
|
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
|
||||||
CLANG_FORMAT_FILES += stdcxx.cpp stdcxx.h
|
CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
|
||||||
CLANG_FORMAT_FILES += ui.cpp ui.h util.h
|
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
|
||||||
clang-format:
|
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
||||||
$(top_srcdir)/src/stub/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(CLANG_FORMAT_FILES))
|
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
||||||
.PHONY: clang-format
|
clang-format: PHONY $(CLANG_FORMAT_FILES)
|
||||||
|
@echo "running upx-clang-format"
|
||||||
|
@$(top_srcdir)/misc/scripts/upx-clang-format -i $(CLANG_FORMAT_FILES)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# "make check-whitespace"
|
||||||
|
#
|
||||||
|
|
||||||
|
CHECK_WHITESPACE =
|
||||||
|
ifeq ($(shell uname),Linux)
|
||||||
|
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
|
||||||
|
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
||||||
|
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
||||||
|
endif
|
||||||
|
check-whitespace : PHONY ; $(CHECK_WHITESPACE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# vim:set ts=8 sw=8 noet:
|
# vim:set ts=8 sw=8 noet:
|
||||||
|
|||||||
+491
-363
File diff suppressed because it is too large
Load Diff
+74
-103
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,12 +25,10 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef UPX_BELE_H__
|
||||||
#ifndef __UPX_BELE_H
|
|
||||||
#error "this is an internal include file"
|
#error "this is an internal include file"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -49,10 +47,8 @@
|
|||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
struct AbstractPolicy
|
struct AbstractPolicy {
|
||||||
{
|
|
||||||
inline AbstractPolicy() {}
|
inline AbstractPolicy() {}
|
||||||
virtual inline ~AbstractPolicy() {}
|
virtual inline ~AbstractPolicy() {}
|
||||||
V bool isBE() C = 0;
|
V bool isBE() 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,15 +79,24 @@ 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, assignment and move assignment
|
||||||
|
AbstractPolicy(const AbstractPolicy &) = delete;
|
||||||
|
AbstractPolicy &operator=(const AbstractPolicy &) = delete;
|
||||||
|
AbstractPolicy &operator=(AbstractPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
#undef C
|
||||||
|
#define C const override
|
||||||
|
#endif
|
||||||
|
|
||||||
struct BEPolicy
|
struct BEPolicy
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
: public AbstractPolicy
|
final : public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline BEPolicy() {}
|
inline BEPolicy() {}
|
||||||
@@ -107,50 +112,30 @@ struct BEPolicy
|
|||||||
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,14 +146,18 @@ struct BEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy, assignment and move assignment
|
||||||
|
BEPolicy(const BEPolicy &) = delete;
|
||||||
|
BEPolicy &operator=(const BEPolicy &) = delete;
|
||||||
|
BEPolicy &operator=(BEPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LEPolicy
|
struct LEPolicy
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
: public AbstractPolicy
|
final : public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline LEPolicy() {}
|
inline LEPolicy() {}
|
||||||
@@ -184,50 +173,30 @@ struct LEPolicy
|
|||||||
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,11 +207,16 @@ struct LEPolicy
|
|||||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disable copy, assignment and move assignment
|
||||||
|
LEPolicy(const LEPolicy &) = delete;
|
||||||
|
LEPolicy &operator=(const LEPolicy &) = delete;
|
||||||
|
LEPolicy &operator=(LEPolicy &&) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// native policy (aka host policy)
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
typedef BEPolicy HostPolicy;
|
typedef BEPolicy HostPolicy;
|
||||||
#elif (ACC_ABI_LITTLE_ENDIAN)
|
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||||
@@ -251,10 +225,8 @@ typedef LEPolicy HostPolicy;
|
|||||||
#error "ACC_ABI_ENDIAN"
|
#error "ACC_ABI_ENDIAN"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 /* UNUSED */
|
||||||
struct HostAlignedPolicy
|
struct HostAlignedPolicy {
|
||||||
{
|
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
||||||
#endif
|
#endif
|
||||||
@@ -271,7 +243,6 @@ struct HostAlignedPolicy
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef V
|
#undef V
|
||||||
#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,475 @@
|
|||||||
|
/* dt_check.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_doctest_check()
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_doctest_check(int argc, char **argv) {
|
||||||
|
#if defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
UNUSED(argc);
|
||||||
|
UNUSED(argv);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
|
||||||
|
if (e && e[0] && strcmp(e, "0") != 0)
|
||||||
|
return 0;
|
||||||
|
bool minimal = true; // only show failing tests
|
||||||
|
bool duration = false; // show timings
|
||||||
|
bool success = false; // show all tests
|
||||||
|
#if DEBUG
|
||||||
|
minimal = false;
|
||||||
|
#endif
|
||||||
|
e = getenv("UPX_DEBUG_DOCTEST_VERBOSE");
|
||||||
|
if (e && e[0]) {
|
||||||
|
minimal = false;
|
||||||
|
if (strcmp(e, "0") == 0) {
|
||||||
|
minimal = true;
|
||||||
|
} else if (strcmp(e, "2") == 0) {
|
||||||
|
duration = true;
|
||||||
|
} else if (strcmp(e, "3") == 0) {
|
||||||
|
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 "--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
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
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)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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_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(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
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct TestBELE {
|
||||||
|
__acc_static_noinline bool test(void) {
|
||||||
|
// POD checks
|
||||||
|
{
|
||||||
|
COMPILE_TIME_ASSERT(std::is_standard_layout<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivial<T>::value)
|
||||||
|
// extra checks, these are probably implied by std::is_trivial:
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_copyable<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<T>::value)
|
||||||
|
}
|
||||||
|
// alignment checks
|
||||||
|
{
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
|
struct alignas(1) test1_t {
|
||||||
|
char a;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
struct alignas(1) test2_t {
|
||||||
|
char a;
|
||||||
|
T b[3];
|
||||||
|
};
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
||||||
|
test1_t t1[7];
|
||||||
|
test2_t t2[7];
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||||
|
UNUSED(t1);
|
||||||
|
UNUSED(t2);
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
// arithmetic checks
|
||||||
|
{
|
||||||
|
T allbits;
|
||||||
|
allbits = 0;
|
||||||
|
allbits += 1;
|
||||||
|
allbits -= 2;
|
||||||
|
T v1;
|
||||||
|
v1 = 1;
|
||||||
|
v1 *= 2;
|
||||||
|
v1 -= 1;
|
||||||
|
T v2;
|
||||||
|
v2 = 1;
|
||||||
|
assert((v1 == v2));
|
||||||
|
assert(!(v1 != v2));
|
||||||
|
assert((v1 <= v2));
|
||||||
|
assert((v1 >= v2));
|
||||||
|
assert(!(v1 < v2));
|
||||||
|
assert(!(v1 > v2));
|
||||||
|
v2 ^= allbits;
|
||||||
|
assert(!(v1 == v2));
|
||||||
|
assert((v1 != v2));
|
||||||
|
assert((v1 <= v2));
|
||||||
|
assert(!(v1 >= v2));
|
||||||
|
assert((v1 < v2));
|
||||||
|
assert(!(v1 > v2));
|
||||||
|
v2 += 2;
|
||||||
|
assert(v1 == 1);
|
||||||
|
assert(v2 == 0);
|
||||||
|
v1 <<= 1;
|
||||||
|
v1 |= v2;
|
||||||
|
v1 >>= 1;
|
||||||
|
v2 &= v1;
|
||||||
|
v2 /= v1;
|
||||||
|
v2 *= v1;
|
||||||
|
assert(v1 == 1);
|
||||||
|
assert(v2 == 0);
|
||||||
|
if ((v1 ^ v2) != 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
struct TestNoAliasingStruct {
|
||||||
|
__acc_static_noinline bool test(A *a, B *b) {
|
||||||
|
*a = 0;
|
||||||
|
*b = 0;
|
||||||
|
*b -= 3;
|
||||||
|
return *a != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class A, class B>
|
||||||
|
__acc_static_forceinline bool testNoAliasing(A *a, B *b) {
|
||||||
|
return TestNoAliasingStruct<A, B>::test(a, b);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
struct TestIntegerWrap {
|
||||||
|
static inline bool inc(T x) { return x + 1 > x; }
|
||||||
|
static inline bool dec(T x) { return x - 1 < x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#include "../miniacc.h"
|
||||||
|
|
||||||
|
void upx_compiler_sanity_check(void) {
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
|
||||||
|
#include "../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)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
|
||||||
|
assert(strlen(UPX_VERSION_STRING4) == 4);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1)
|
||||||
|
assert(strlen(UPX_VERSION_YEAR) == 4);
|
||||||
|
assert(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0);
|
||||||
|
assert(memcmp(&UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 1 - 4], UPX_VERSION_YEAR, 4) == 0);
|
||||||
|
if (gitrev[0]) {
|
||||||
|
size_t revlen = strlen(gitrev);
|
||||||
|
if (strncmp(gitrev, "ERROR", 5) == 0) {
|
||||||
|
assert(revlen == 5 || revlen == 6);
|
||||||
|
} else {
|
||||||
|
assert(revlen == 12 || revlen == 13);
|
||||||
|
}
|
||||||
|
if (revlen == 6 || revlen == 13) {
|
||||||
|
assert(gitrev[revlen - 1] == '+');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(UPX_RSIZE_MAX_MEM == 805306368);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
assert(TestBELE<LE16>::test());
|
||||||
|
assert(TestBELE<LE32>::test());
|
||||||
|
assert(TestBELE<LE64>::test());
|
||||||
|
assert(TestBELE<BE16>::test());
|
||||||
|
assert(TestBELE<BE32>::test());
|
||||||
|
assert(TestBELE<BE64>::test());
|
||||||
|
{
|
||||||
|
alignas(16) static const unsigned char 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 unsigned char *d;
|
||||||
|
const N_BELE_RTP::AbstractPolicy *bele;
|
||||||
|
d = dd + 7;
|
||||||
|
assert(upx_adler32(d, 4) == 0x09f003f7);
|
||||||
|
assert(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||||
|
assert(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
|
assert(get_be16(d) == 0xfffe);
|
||||||
|
assert(bele->get16(d) == 0xfffe);
|
||||||
|
assert(get_be16_signed(d) == -2);
|
||||||
|
assert(get_be24(d) == 0xfffefd);
|
||||||
|
assert(bele->get24(d) == 0xfffefd);
|
||||||
|
assert(get_be24_signed(d) == -259);
|
||||||
|
assert(get_be32(d) == 0xfffefdfc);
|
||||||
|
assert(bele->get32(d) == 0xfffefdfc);
|
||||||
|
assert(get_be32_signed(d) == -66052);
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
assert(get_le16(d) == 0xfeff);
|
||||||
|
assert(bele->get16(d) == 0xfeff);
|
||||||
|
assert(get_le16_signed(d) == -257);
|
||||||
|
assert(get_le24(d) == 0xfdfeff);
|
||||||
|
assert(bele->get24(d) == 0xfdfeff);
|
||||||
|
assert(get_le24_signed(d) == -131329);
|
||||||
|
assert(get_le32(d) == 0xfcfdfeff);
|
||||||
|
assert(bele->get32(d) == 0xfcfdfeff);
|
||||||
|
assert(get_le32_signed(d) == -50462977);
|
||||||
|
assert(get_le64_signed(d) == -506097522914230529LL);
|
||||||
|
assert(find_be16(d, 2, 0xfffe) == 0);
|
||||||
|
assert(find_le16(d, 2, 0xfeff) == 0);
|
||||||
|
assert(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||||
|
assert(find_le32(d, 4, 0xfcfdfeff) == 0);
|
||||||
|
d += 12;
|
||||||
|
assert(get_be16_signed(d) == 32638);
|
||||||
|
assert(get_be24_signed(d) == 8355453);
|
||||||
|
assert(get_be32_signed(d) == 2138996092);
|
||||||
|
assert(get_be64_signed(d) == 9186918263483431288LL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
unsigned dd;
|
||||||
|
void *const d = ⅆ
|
||||||
|
dd = ne32_to_le32(0xf7f6f5f4);
|
||||||
|
assert(get_le26(d) == 0x03f6f5f4);
|
||||||
|
set_le26(d, 0);
|
||||||
|
assert(get_le26(d) == 0);
|
||||||
|
assert(dd == ne32_to_le32(0xf4000000));
|
||||||
|
set_le26(d, 0xff020304);
|
||||||
|
assert(get_le26(d) == 0x03020304);
|
||||||
|
assert(dd == ne32_to_le32(0xf7020304));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
upx_uint16_t a;
|
||||||
|
upx_uint32_t b;
|
||||||
|
upx_uint64_t c;
|
||||||
|
set_ne16(&a, 0x04030201); // ignore upper bits
|
||||||
|
set_ne32(&b, 0x04030201);
|
||||||
|
set_ne64(&c, 0x0807060504030201ull);
|
||||||
|
assert(a == 0x0201);
|
||||||
|
assert(b == 0x04030201);
|
||||||
|
assert(c == 0x0807060504030201ull);
|
||||||
|
assert(get_ne16(&a) == 0x0201);
|
||||||
|
assert(get_ne32(&b) == 0x04030201);
|
||||||
|
assert(get_ne64(&c) == 0x0807060504030201ull);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
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(testNoAliasing(&u.v_short, &u.b32));
|
||||||
|
assert(testNoAliasing(&u.v_short, &u.l32));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.b64));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.l64));
|
||||||
|
// check working -fno-strict-aliasing
|
||||||
|
assert(testNoAliasing(&u.v_short, &u.v_int));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.v_long));
|
||||||
|
assert(testNoAliasing(&u.v_int, &u.v_llong));
|
||||||
|
assert(testNoAliasing(&u.v_long, &u.v_llong));
|
||||||
|
|
||||||
|
assert(TestIntegerWrap<unsigned>::inc(0));
|
||||||
|
assert(!TestIntegerWrap<unsigned>::inc(UINT_MAX));
|
||||||
|
assert(TestIntegerWrap<unsigned>::dec(1));
|
||||||
|
assert(!TestIntegerWrap<unsigned>::dec(0));
|
||||||
|
// check working -fno-strict-overflow
|
||||||
|
assert(TestIntegerWrap<int>::inc(0));
|
||||||
|
assert(!TestIntegerWrap<int>::inc(INT_MAX));
|
||||||
|
assert(TestIntegerWrap<int>::dec(0));
|
||||||
|
assert(!TestIntegerWrap<int>::dec(INT_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// some doctest test cases
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc snprintf") {
|
||||||
|
// runtime check that Win32/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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/* dt_impl.cpp -- doctest support code implementation
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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 support code implementation
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define DOCTEST_CONFIG_IMPLEMENT
|
||||||
|
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#endif
|
||||||
|
#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||||
|
#define DOCTEST_CONFIG_COLORS_NONE
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
|
#endif
|
||||||
|
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||||
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER)
|
||||||
|
// 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
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,791 @@
|
|||||||
|
/* xspan -- a minimally invasive checked memory smart pointer
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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)
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// raw_bytes
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("raw_bytes ptr") {
|
||||||
|
upx_uint16_t *ptr = nullptr;
|
||||||
|
CHECK_NOTHROW(raw_bytes(ptr, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(ptr, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 0, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 1, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 0, 1));
|
||||||
|
upx_uint16_t buf[4];
|
||||||
|
ptr = buf;
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u);
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("raw_bytes bounded array") {
|
||||||
|
upx_uint16_t buf[4];
|
||||||
|
CHECK_NOTHROW(raw_bytes(buf, 8));
|
||||||
|
CHECK_THROWS(raw_bytes(buf, 9));
|
||||||
|
CHECK_NOTHROW(raw_index_bytes(buf, 4, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(buf, 4, 1));
|
||||||
|
CHECK_NOTHROW(raw_index_bytes(buf, 3, 2));
|
||||||
|
CHECK_THROWS(raw_index_bytes(buf, 3, 3));
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u);
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// basic xspan
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("basic xspan usage") {
|
||||||
|
char buf[4] = {0, 1, 2, 3};
|
||||||
|
|
||||||
|
SUBCASE("XSPAN_x") {
|
||||||
|
XSPAN_0(char) a0 = nullptr;
|
||||||
|
|
||||||
|
XSPAN_0(char) b0 = buf;
|
||||||
|
XSPAN_P(char) bp = buf;
|
||||||
|
|
||||||
|
XSPAN_0(char) c0 = XSPAN_0_MAKE(char, buf);
|
||||||
|
XSPAN_P(char) cp = XSPAN_P_MAKE(char, buf);
|
||||||
|
XSPAN_S(char) cs = XSPAN_S_MAKE(char, buf, sizeof(buf));
|
||||||
|
|
||||||
|
XSPAN_0(const char) const x0 = XSPAN_0_MAKE(const char, buf);
|
||||||
|
XSPAN_P(const char) const xp = XSPAN_P_MAKE(const char, buf);
|
||||||
|
XSPAN_S(const char) const xs = XSPAN_S_MAKE(const char, buf, sizeof(buf));
|
||||||
|
XSPAN_P(const char) const yp = xs;
|
||||||
|
XSPAN_0(const char) const z0p = yp;
|
||||||
|
XSPAN_0(const char) const z0s = xs;
|
||||||
|
|
||||||
|
CHECK((a0 == nullptr));
|
||||||
|
CHECK(c0 == b0);
|
||||||
|
CHECK(cp == bp);
|
||||||
|
CHECK(cs == bp);
|
||||||
|
CHECK(x0 == z0p);
|
||||||
|
CHECK(xp == z0s);
|
||||||
|
|
||||||
|
CHECK_NOTHROW(raw_bytes(a0, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(a0, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
|
||||||
|
CHECK(raw_bytes(c0, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cp, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cs, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
CHECK_THROWS(raw_bytes(cs, 5));
|
||||||
|
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("XSPAN_x_VAR") {
|
||||||
|
XSPAN_0_VAR(char, a0, nullptr);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, b0, buf);
|
||||||
|
XSPAN_P_VAR(char, bp, buf);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, c0, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(char, cp, buf, sizeof(buf));
|
||||||
|
XSPAN_S_VAR(char, cs, buf, sizeof(buf));
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, d0, buf + 1, sizeof(buf), buf);
|
||||||
|
XSPAN_P_VAR(char, dp, buf + 1, sizeof(buf), buf);
|
||||||
|
XSPAN_S_VAR(char, ds, buf + 1, sizeof(buf), buf);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(const char, const x0, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(const char, const xp, buf, sizeof(buf));
|
||||||
|
XSPAN_S_VAR(const char, const xs, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(const char, const yp, xs);
|
||||||
|
XSPAN_0_VAR(const char, const z0p, yp);
|
||||||
|
XSPAN_0_VAR(const char, const z0s, xs);
|
||||||
|
|
||||||
|
CHECK((a0 == nullptr));
|
||||||
|
CHECK(c0 == b0);
|
||||||
|
CHECK(cp == bp);
|
||||||
|
CHECK(cs == bp);
|
||||||
|
CHECK(d0 == dp);
|
||||||
|
CHECK(d0 == ds);
|
||||||
|
CHECK(x0 == z0p);
|
||||||
|
CHECK(xp == z0s);
|
||||||
|
|
||||||
|
CHECK_NOTHROW(raw_bytes(a0, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(a0, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
|
||||||
|
CHECK(raw_bytes(c0, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cp, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cs, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
CHECK_THROWS(raw_bytes(cs, 5));
|
||||||
|
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("xspan in class") {
|
||||||
|
struct MyType {
|
||||||
|
XSPAN_0(char) s0;
|
||||||
|
XSPAN_P(char) sp;
|
||||||
|
XSPAN_S(char) ss;
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
XSPAN_0(char) x0 = nullptr;
|
||||||
|
#endif
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
// much nicer syntax when using fully checked xspan:
|
||||||
|
MyType(char *b, size_t n, bool) : s0(b, n), sp(b, n), ss(b, n) {}
|
||||||
|
#endif
|
||||||
|
MyType(char *b, size_t n)
|
||||||
|
: s0(XSPAN_0_MAKE(char, b, n)), sp(XSPAN_P_MAKE(char, b, n)),
|
||||||
|
ss(XSPAN_S_MAKE(char, b, n)) {
|
||||||
|
UNUSED(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MyType x(buf, sizeof(buf));
|
||||||
|
MyType y = MyType(buf, sizeof(buf));
|
||||||
|
CHECK(x.s0 == y.sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_XSPAN >= 2) && DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpanOrNull") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(Span0(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(Span0(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
Span0 a1(nullptr);
|
||||||
|
assert(a1 == nullptr);
|
||||||
|
assert(a1.raw_ptr() == nullptr);
|
||||||
|
assert(a1.raw_base() == nullptr);
|
||||||
|
assert(a1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1[0]);
|
||||||
|
|
||||||
|
Span0 a2 = nullptr;
|
||||||
|
assert(a2 == nullptr);
|
||||||
|
assert(a2.raw_ptr() == nullptr);
|
||||||
|
assert(a2.raw_base() == nullptr);
|
||||||
|
assert(a2.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*a2);
|
||||||
|
CHECK_THROWS(a2[0]);
|
||||||
|
|
||||||
|
Span0 base0(nullptr, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == nullptr);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
CHECK_THROWS(*base0); // nullptr
|
||||||
|
CHECK_THROWS(base0[0]); // nullptr
|
||||||
|
CHECK_THROWS(base0 + 1); // nullptr
|
||||||
|
|
||||||
|
Span0 base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == nullptr);
|
||||||
|
assert(a1.raw_ptr() == nullptr);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
Span0 new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
a2 = new_base4;
|
||||||
|
CHECK_THROWS(a2 = base4); // not same base
|
||||||
|
|
||||||
|
Span0 s0_no_base(nullptr);
|
||||||
|
Span0 s0_with_base(nullptr, 4, base_buf);
|
||||||
|
s0_no_base = nullptr;
|
||||||
|
s0_with_base = nullptr;
|
||||||
|
s0_with_base = s0_no_base;
|
||||||
|
assert(s0_no_base.raw_base() == nullptr);
|
||||||
|
assert(s0_with_base.raw_base() == base_buf);
|
||||||
|
s0_no_base = s0_with_base;
|
||||||
|
assert(s0_no_base.raw_base() == base_buf);
|
||||||
|
assert(s0_no_base.raw_ptr() == nullptr);
|
||||||
|
assert(s0_with_base.raw_ptr() == nullptr);
|
||||||
|
s0_no_base = my_null;
|
||||||
|
s0_with_base = my_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef PtrOrSpan<char> SpanP;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(SpanP(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(SpanP(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
SpanP x1(base_buf, 0);
|
||||||
|
assert(x1 != nullptr);
|
||||||
|
assert(x1.raw_ptr() == base_buf);
|
||||||
|
assert(x1.raw_base() == base_buf);
|
||||||
|
assert(x1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*x1);
|
||||||
|
CHECK_THROWS(x1[0]);
|
||||||
|
|
||||||
|
SpanP a2 = base_buf;
|
||||||
|
assert(a2 != nullptr);
|
||||||
|
assert(a2.raw_ptr() == base_buf);
|
||||||
|
assert(a2.raw_base() == nullptr);
|
||||||
|
assert(a2.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK(*a2 == 0);
|
||||||
|
CHECK(a2[1] == 1);
|
||||||
|
|
||||||
|
SpanP base0(base_buf, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == base_buf);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanP base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanP a1(base_buf, 4);
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == base0);
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
assert(a1.raw_ptr() == base0.raw_ptr());
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
SpanP new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
a2 = new_base4;
|
||||||
|
CHECK_THROWS(a2 = base4); // not same base
|
||||||
|
|
||||||
|
SpanP sp_no_base(base_buf);
|
||||||
|
SpanP sp_with_base(base_buf, 4, base_buf);
|
||||||
|
assert(sp_no_base.raw_base() == nullptr);
|
||||||
|
assert(sp_with_base.raw_base() == base_buf);
|
||||||
|
CHECK_THROWS(sp_no_base = my_null); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = my_null); // nullptr assignment
|
||||||
|
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
Span0 s0_no_base(nullptr);
|
||||||
|
Span0 s0_with_base(nullptr, 4, base_buf);
|
||||||
|
CHECK_THROWS(sp_no_base = s0_no_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_no_base = s0_with_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("Span") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef Span<char> SpanS;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(SpanS(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(SpanS(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
SpanS x1(base_buf, 0);
|
||||||
|
assert(x1 != nullptr);
|
||||||
|
assert(x1.raw_ptr() == base_buf);
|
||||||
|
assert(x1.raw_base() == base_buf);
|
||||||
|
assert(x1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*x1);
|
||||||
|
CHECK_THROWS(x1[0]);
|
||||||
|
|
||||||
|
SpanS a2(base_buf, 4);
|
||||||
|
assert(a2 != nullptr);
|
||||||
|
assert(a2.raw_ptr() == base_buf);
|
||||||
|
assert(a2.raw_base() == base_buf);
|
||||||
|
assert(a2.raw_size_in_bytes() == 4u);
|
||||||
|
CHECK(*a2 == 0);
|
||||||
|
CHECK(a2[1] == 1);
|
||||||
|
|
||||||
|
SpanS base0(base_buf, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == base_buf);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanS base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanS a1(base_buf, 4);
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == base0);
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
assert(a1.raw_ptr() == base0.raw_ptr());
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
SpanS new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
CHECK_THROWS(a2 = new_base4); // not same base
|
||||||
|
|
||||||
|
SpanS ss_with_base(base_buf, 4, base_buf);
|
||||||
|
assert(ss_with_base.raw_base() == base_buf);
|
||||||
|
CHECK_THROWS(ss_with_base = my_null); // nullptr assignment
|
||||||
|
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||||
|
{
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
|
const Span0 v0_v0(nullptr);
|
||||||
|
const Span0 v0_b0(nullptr, 4, base_buf);
|
||||||
|
const Span0 v0_b1(nullptr, 3, base_buf + 1);
|
||||||
|
const Span0 b0_v0(base_buf);
|
||||||
|
const Span0 b0_b0(base_buf, 4, base_buf);
|
||||||
|
CHECK_THROWS(XSPAN_0_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
|
const Span0 b1_v0(base_buf + 1);
|
||||||
|
const Span0 b1_b0(base_buf + 1, 4, base_buf);
|
||||||
|
const Span0 b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
|
CHECK_THROWS(ss_with_base = v0_v0); // nullptr assignment
|
||||||
|
CHECK_THROWS(ss_with_base = v0_b0); // nullptr assignment
|
||||||
|
CHECK_THROWS(ss_with_base = v0_b1); // nullptr assignment
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_v0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b1));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef PtrOrSpan<char> SpanP;
|
||||||
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
|
const SpanP b0_v0(base_buf);
|
||||||
|
const SpanP b0_b0(base_buf, 4, base_buf);
|
||||||
|
CHECK_THROWS(XSPAN_P_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
|
const SpanP b1_v0(base_buf + 1);
|
||||||
|
const SpanP b1_b0(base_buf + 1, 4, base_buf);
|
||||||
|
const SpanP b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("Span void ptr") {
|
||||||
|
static char a[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_0(void) a0(a, 4);
|
||||||
|
XSPAN_P(void) ap(a, 4);
|
||||||
|
XSPAN_S(void) as(a, 4);
|
||||||
|
XSPAN_0(const void) c0(a, 4);
|
||||||
|
XSPAN_P(const void) cp(a, 4);
|
||||||
|
XSPAN_S(const void) cs(a, 4);
|
||||||
|
static const char b[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_0(const void) b0(b, 4);
|
||||||
|
XSPAN_P(const void) bp(b, 4);
|
||||||
|
XSPAN_S(const void) bs(b, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span deref/array/arrow") {
|
||||||
|
static char real_a[2 + 4 + 2] = {126, 127, 0, 1, 2, 3, 124, 125};
|
||||||
|
static char *a = real_a + 2;
|
||||||
|
XSPAN_0(char) a0(a, 4);
|
||||||
|
XSPAN_P(char) ap(a, 4);
|
||||||
|
XSPAN_S(char) as(a, 4);
|
||||||
|
CHECK_THROWS(a0[4]);
|
||||||
|
CHECK_THROWS(a0[-1]);
|
||||||
|
CHECK_THROWS(a0[-2]);
|
||||||
|
a0 += 2;
|
||||||
|
CHECK(*a0 == 2);
|
||||||
|
CHECK(a0[-1] == 1);
|
||||||
|
CHECK(a0[0] == 2);
|
||||||
|
CHECK(a0[1] == 3);
|
||||||
|
ap += 2;
|
||||||
|
CHECK(*ap == 2);
|
||||||
|
CHECK(ap[-1] == 1);
|
||||||
|
CHECK(ap[0] == 2);
|
||||||
|
CHECK(ap[1] == 3);
|
||||||
|
as += 2;
|
||||||
|
CHECK(*as == 2);
|
||||||
|
CHECK(as[-1] == 1);
|
||||||
|
CHECK(as[0] == 2);
|
||||||
|
CHECK(as[1] == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span subspan") {
|
||||||
|
static char buf[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_S(char) as(buf, 4);
|
||||||
|
CHECK(as.subspan(1, 1)[0] == 1);
|
||||||
|
CHECK((as + 1).subspan(1, 1)[0] == 2);
|
||||||
|
CHECK((as + 2).subspan(0, -2)[0] == 0);
|
||||||
|
CHECK_THROWS(as.subspan(1, 0)[0]);
|
||||||
|
CHECK_THROWS(as.subspan(1, 1)[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span constness") {
|
||||||
|
static char buf[4] = {0, 1, 2, 3};
|
||||||
|
|
||||||
|
XSPAN_0(char) b0(buf, 4);
|
||||||
|
XSPAN_P(char) bp(buf, 4);
|
||||||
|
XSPAN_S(char) bs(buf, 4);
|
||||||
|
|
||||||
|
XSPAN_0(char) s0(b0);
|
||||||
|
XSPAN_P(char) sp(bp);
|
||||||
|
XSPAN_S(char) ss(bs);
|
||||||
|
|
||||||
|
XSPAN_0(const char) b0c(buf, 4);
|
||||||
|
XSPAN_P(const char) bpc(buf, 4);
|
||||||
|
XSPAN_S(const char) bsc(buf, 4);
|
||||||
|
|
||||||
|
XSPAN_0(const char) s0c(b0c);
|
||||||
|
XSPAN_P(const char) spc(bpc);
|
||||||
|
XSPAN_S(const char) ssc(bsc);
|
||||||
|
|
||||||
|
XSPAN_0(const char) x0c(b0);
|
||||||
|
XSPAN_P(const char) xpc(bp);
|
||||||
|
XSPAN_S(const char) xsc(bs);
|
||||||
|
|
||||||
|
CHECK(ptr_diff_bytes(b0, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bp, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bs, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(sp, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bs, buf) == 0);
|
||||||
|
//
|
||||||
|
CHECK(ptr_diff_bytes(s0, bp) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, sp) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, ss) == 0);
|
||||||
|
//
|
||||||
|
CHECK(ptr_diff_bytes(s0c, b0c) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(spc, bpc) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(ssc, bsc) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
namespace {
|
||||||
|
int my_memcmp_v1(XSPAN_P(const void) a, XSPAN_0(const void) b, size_t n) {
|
||||||
|
if (b == nullptr)
|
||||||
|
return -2;
|
||||||
|
XSPAN_0(const void) x(a);
|
||||||
|
return memcmp(x, b, n);
|
||||||
|
}
|
||||||
|
int my_memcmp_v2(XSPAN_P(const char) a, XSPAN_0(const char) b, size_t n) {
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
if (b == nullptr)
|
||||||
|
return -2;
|
||||||
|
a += 1;
|
||||||
|
b -= 1;
|
||||||
|
XSPAN_0(const char) x(a);
|
||||||
|
XSPAN_0(const char) y = b;
|
||||||
|
return memcmp(x, y, n);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan") {
|
||||||
|
static const char buf[4] = {0, 1, 2, 3};
|
||||||
|
CHECK(my_memcmp_v1(buf, nullptr, 4) == -2);
|
||||||
|
CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0);
|
||||||
|
CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan char") {
|
||||||
|
char real_buf[2 + 8 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 6, 7, 124, 125};
|
||||||
|
char *buf = real_buf + 2;
|
||||||
|
XSPAN_P(char) a(buf, XSpanSizeInBytes(8));
|
||||||
|
XSPAN_P(char) b = a.subspan(0, 7);
|
||||||
|
XSPAN_P(char) c = (b + 1).subspan(0, 6);
|
||||||
|
a += 1;
|
||||||
|
CHECK(*a == 1);
|
||||||
|
*a++ += 1;
|
||||||
|
*b++ = 1;
|
||||||
|
CHECK(a == buf + 2);
|
||||||
|
CHECK(b == buf + 1);
|
||||||
|
CHECK(c == buf + 1);
|
||||||
|
CHECK(*b == 2);
|
||||||
|
CHECK(*c == 2);
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
CHECK(b.raw_size_in_bytes() == 7u);
|
||||||
|
CHECK(c.raw_size_in_bytes() == 6u);
|
||||||
|
CHECK(a.raw_base() == buf);
|
||||||
|
CHECK(b.raw_base() == buf);
|
||||||
|
CHECK(c.raw_base() == buf + 1);
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(a) != 0);
|
||||||
|
#endif
|
||||||
|
++c;
|
||||||
|
c++;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(c) != 0);
|
||||||
|
#endif
|
||||||
|
++c;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK_THROWS(get_le32(c));
|
||||||
|
#endif
|
||||||
|
++b;
|
||||||
|
b++;
|
||||||
|
b += 4;
|
||||||
|
CHECK(b.raw_ptr() == buf + 7);
|
||||||
|
CHECK_THROWS(*b);
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
a = b;
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
CHECK(a.raw_ptr() == buf + 7);
|
||||||
|
a++;
|
||||||
|
CHECK_THROWS(*a);
|
||||||
|
CHECK_THROWS(raw_bytes(a, 1));
|
||||||
|
a = b;
|
||||||
|
CHECK_THROWS(a = c);
|
||||||
|
*a = 0;
|
||||||
|
a = buf;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(upx_safe_strlen(a) == 7u);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan int") {
|
||||||
|
int buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
|
XSPAN_P(int) a(buf, XSpanCount(8));
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8 * sizeof(int));
|
||||||
|
XSPAN_P(int) b = a.subspan(0, 7);
|
||||||
|
CHECK(b.raw_size_in_bytes() == 7 * sizeof(int));
|
||||||
|
XSPAN_P(int) c = (b + 1).subspan(0, 6);
|
||||||
|
CHECK(c.raw_size_in_bytes() == 6 * sizeof(int));
|
||||||
|
a += 1;
|
||||||
|
CHECK(*a == 1);
|
||||||
|
CHECK(*a++ == 1);
|
||||||
|
CHECK(*++a == 3);
|
||||||
|
CHECK(--*a == 2);
|
||||||
|
CHECK(*a-- == 2);
|
||||||
|
CHECK(*b == 0);
|
||||||
|
CHECK(*c == 1);
|
||||||
|
a = buf + 7;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(a) == ne32_to_le32(7));
|
||||||
|
#endif
|
||||||
|
a++;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK_THROWS(get_le32(a));
|
||||||
|
#endif
|
||||||
|
CHECK_THROWS(raw_bytes(a, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// codegen
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class T>
|
||||||
|
__acc_static_noinline int foo(T p) {
|
||||||
|
unsigned r = 0;
|
||||||
|
r += *p++;
|
||||||
|
r += *++p;
|
||||||
|
p += 3;
|
||||||
|
r += *p;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
XSPAN_0(T)
|
||||||
|
make_span_0(T *ptr, size_t count) {
|
||||||
|
return PtrOrSpanOrNull<T>(ptr, count);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
XSPAN_P(T)
|
||||||
|
make_span_p(T *ptr, size_t count) {
|
||||||
|
return PtrOrSpan<T>(ptr, count);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
XSPAN_S(T)
|
||||||
|
make_span_s(T *ptr, size_t count) {
|
||||||
|
return Span<T>(ptr, count);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("Span codegen") {
|
||||||
|
char buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
|
CHECK(foo(buf) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_XSPAN >= 2
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -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-2023 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_p 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
|
||||||
@@ -94,60 +85,57 @@ int upx_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
cresult = &cresult_buffer;
|
cresult = &cresult_buffer;
|
||||||
memset(cresult, 0, sizeof(*cresult));
|
memset(cresult, 0, sizeof(*cresult));
|
||||||
#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) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#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");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->c_len = *dst_len;
|
cresult->debug.c_len = *dst_len;
|
||||||
#endif
|
#endif
|
||||||
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) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
@@ -164,6 +152,10 @@ 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 decompression method");
|
||||||
@@ -172,29 +164,23 @@ int upx_decompress ( const upx_bytep src, unsigned src_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) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
@@ -207,6 +193,10 @@ 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 decompression method");
|
||||||
@@ -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-2023 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,19 +20,40 @@
|
|||||||
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
|
#ifndef UPX_COMPRESS_H__
|
||||||
#define __UPX_COMPRESS_H 1
|
#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_p 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);
|
||||||
@@ -126,6 +146,28 @@ unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
int upx_zstd_init(void);
|
||||||
|
const char *upx_zstd_version_string(void);
|
||||||
|
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,544 @@
|
|||||||
|
/* compress_lzma.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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
|
||||||
|
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
||||||
|
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void lzma_compress_config_t::reset() {
|
||||||
|
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 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 + (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));
|
||||||
|
// 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
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef MSDOS
|
||||||
|
#undef OS2
|
||||||
|
#undef _WIN32
|
||||||
|
#undef _WIN32_WCE
|
||||||
|
#undef COMPRESS_MF_MT
|
||||||
|
#undef _NO_EXCEPTIONS
|
||||||
|
#undef NULL
|
||||||
|
#define NULL nullptr
|
||||||
|
#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_p 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
|
||||||
|
|
||||||
|
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 != 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
// 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 <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;
|
||||||
|
memset(&s, 0, sizeof(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;
|
||||||
|
// 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") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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;
|
||||||
|
}
|
||||||
|
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 != 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 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, 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 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 (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") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\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 = (C *) "\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 = (C *) "\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
/* compress_zlib.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 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"
|
||||||
|
#include <zlib/zlib.h>
|
||||||
|
#include <zlib/deflate.h>
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset() {
|
||||||
|
mem_clear(this, sizeof(*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;
|
||||||
|
}
|
||||||
|
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 != 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;
|
||||||
|
|
||||||
|
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) nullptr;
|
||||||
|
s.zfree = (free_func) nullptr;
|
||||||
|
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 = (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 = 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) {
|
||||||
|
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") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/* compress_zstd.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
void zstd_compress_config_t::reset() { mem_clear(this, sizeof(*this)); }
|
||||||
|
|
||||||
|
#if WITH_ZSTD
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
#include <zstd/lib/zstd.h>
|
||||||
|
#include <zstd/lib/zstd_errors.h>
|
||||||
|
#include <zstd/lib/compress/hist.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_p 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;
|
||||||
|
|
||||||
|
// TODO later: map level 1..10 to zstd-level 1..22
|
||||||
|
if (level == 10)
|
||||||
|
level = 22;
|
||||||
|
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf) {
|
||||||
|
UNUSED(lcconf);
|
||||||
|
}
|
||||||
|
|
||||||
|
res->dummy = 0;
|
||||||
|
|
||||||
|
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") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[32];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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: */
|
|
||||||
+359
-188
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,20 +25,28 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef UPX_CONF_H__
|
||||||
|
#define UPX_CONF_H__ 1
|
||||||
|
|
||||||
#ifndef __UPX_CONF_H
|
#if !(__cplusplus+0 >= 201703L)
|
||||||
#define __UPX_CONF_H 1
|
# error "C++ 17 is required"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#if !defined(_FILE_OFFSET_BITS)
|
#if !defined(_FILE_OFFSET_BITS)
|
||||||
# define _FILE_OFFSET_BITS 64
|
# define _FILE_OFFSET_BITS 64
|
||||||
#endif
|
#endif
|
||||||
#undef NDEBUG
|
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__)
|
||||||
|
# if !defined(_USE_MINGW_ANSI_STDIO)
|
||||||
|
# define _USE_MINGW_ANSI_STDIO 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// ACC
|
// ACC and system includes
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
|
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
|
||||||
@@ -49,17 +57,41 @@
|
|||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
#if !(ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_MSC)
|
#if !(ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_MSC)
|
||||||
// other compilers may work, but we're NOT interested into supporting them
|
// other compilers may work, but we're NOT interested into supporting them
|
||||||
# error "only clang and gcc are officially supported"
|
# error "only clang, gcc and msvc are officially supported"
|
||||||
#endif
|
#endif
|
||||||
// UPX sanity checks for a sane compiler
|
// UPX sanity checks for a sane compiler
|
||||||
#if !defined(UINT_MAX) || (UINT_MAX != 0xffffffffL)
|
#if !defined(UINT_MAX) || (UINT_MAX != 0xffffffffL)
|
||||||
# error "UINT_MAX"
|
# error "UINT_MAX"
|
||||||
#endif
|
#endif
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long long) == 8)
|
||||||
|
// check sane compiler mandatory flags
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(-1 == ~0) // two's complement - see http://wg21.link/P0907R4
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(0u-1 == ~0u) // two's complement - see http://wg21.link/P0907R4
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0)
|
ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(((int)(1u << 31)) >> 31 == -1) // arithmetic right shift
|
ACC_COMPILE_TIME_ASSERT_HEADER(((int)(1u << 31)) >> 31 == -1) // arithmetic right shift
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((-1) >> 31 == -1) // arithmetic right shift
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) > 0) // -funsigned-char
|
ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
||||||
|
|
||||||
|
// enable/disable some warnings
|
||||||
|
#if (ACC_CC_CLANG >= 0x0b0000)
|
||||||
|
# pragma clang diagnostic error "-Wsuggest-override"
|
||||||
|
#elif (ACC_CC_GNUC >= 0x0a0000)
|
||||||
|
// don't enable before gcc-10 because of gcc bug #78010
|
||||||
|
# pragma GCC diagnostic error "-Wsuggest-override"
|
||||||
|
#endif
|
||||||
|
// Some non-GLIBC toolchains do not use 'nullptr' everywhere when C++:
|
||||||
|
// openwrt-sdk-x86-64_gcc-11.2.0_musl.Linux-x86_64/staging_dir/
|
||||||
|
// toolchain-x86_64_gcc-11.2.0_musl/include/fortify/stdlib.h:
|
||||||
|
// 51:32: error: zero as null pointer constant
|
||||||
|
#if (ACC_CC_CLANG >= 0x050000)
|
||||||
|
# pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
|
||||||
|
#elif (ACC_CC_GNUC >= 0x040700) && defined(__GLIBC__)
|
||||||
|
# pragma GCC diagnostic error "-Wzero-as-null-pointer-constant"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (ACC_CC_MSC)
|
#if (ACC_CC_MSC)
|
||||||
# pragma warning(error: 4127)
|
# pragma warning(error: 4127)
|
||||||
@@ -71,21 +103,67 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) > 0) // -funsigned-char
|
|||||||
# pragma warning(disable: 4820) // padding added after data member
|
# pragma warning(disable: 4820) // padding added after data member
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages)
|
#undef snprintf
|
||||||
#if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(__CEGCC__) && !defined(_WIN32)
|
#undef vsnprintf
|
||||||
# undef HAVE_CHMOD
|
#define HAVE_STDINT_H 1
|
||||||
# undef HAVE_CHOWN
|
|
||||||
# undef HAVE_LSTAT
|
|
||||||
# undef HAVE_UTIME
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ACC_WANT_ACC_INCD_H 1
|
#define ACC_WANT_ACC_INCD_H 1
|
||||||
#define ACC_WANT_ACC_INCE_H 1
|
#define ACC_WANT_ACC_INCE_H 1
|
||||||
#define ACC_WANT_ACC_LIB_H 1
|
#define ACC_WANT_ACC_LIB_H 1
|
||||||
#define ACC_WANT_ACC_CXX_H 1
|
#define ACC_WANT_ACC_CXX_H 1
|
||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
|
#if (ACC_CC_MSC)
|
||||||
|
# include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* intergral types */
|
// C++ system headers
|
||||||
|
#include <exception>
|
||||||
|
#include <new>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
|
#if __STDC_NO_ATOMICS__ || 1
|
||||||
|
// UPX currently does not use multithreading
|
||||||
|
#define upx_std_atomic(Type) Type
|
||||||
|
//#define upx_std_atomic(Type) typename std::add_volatile<Type>::type
|
||||||
|
#else
|
||||||
|
#include <atomic>
|
||||||
|
#define upx_std_atomic(Type) std::atomic<Type>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// C++ submodule headers
|
||||||
|
#include <doctest/doctest/parts/doctest_fwd.h>
|
||||||
|
#if WITH_BOOST_PFR
|
||||||
|
# include <sstream>
|
||||||
|
# include <boost/pfr/io.hpp>
|
||||||
|
#endif
|
||||||
|
#if WITH_RANGELESS_FN
|
||||||
|
# include <rangeless/include/fn.hpp>
|
||||||
|
#endif
|
||||||
|
#ifndef WITH_VALGRIND
|
||||||
|
# define WITH_VALGRIND 1
|
||||||
|
#endif
|
||||||
|
#if defined(__SANITIZE_ADDRESS__) || defined(_WIN32) || !defined(__GNUC__)
|
||||||
|
# undef WITH_VALGRIND
|
||||||
|
#endif
|
||||||
|
#if (WITH_VALGRIND)
|
||||||
|
# include <valgrind/include/valgrind/memcheck.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// IMPORTANT: unconditionally enable assertions
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
// <type_traits> C++20 std::is_bounded_array
|
||||||
|
template <class T>
|
||||||
|
struct std_is_bounded_array : public std::false_type {};
|
||||||
|
template <class T, size_t N>
|
||||||
|
struct std_is_bounded_array<T[N]> : public std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// core
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// intergral types
|
||||||
typedef acc_int8_t upx_int8_t;
|
typedef acc_int8_t upx_int8_t;
|
||||||
typedef acc_uint8_t upx_uint8_t;
|
typedef acc_uint8_t upx_uint8_t;
|
||||||
typedef acc_int16_t upx_int16_t;
|
typedef acc_int16_t upx_int16_t;
|
||||||
@@ -95,25 +173,50 @@ typedef acc_uint32_t upx_uint32_t;
|
|||||||
typedef acc_int64_t upx_int64_t;
|
typedef acc_int64_t upx_int64_t;
|
||||||
typedef acc_uint64_t upx_uint64_t;
|
typedef acc_uint64_t upx_uint64_t;
|
||||||
typedef acc_uintptr_t upx_uintptr_t;
|
typedef acc_uintptr_t upx_uintptr_t;
|
||||||
#define UPX_INT16_C ACC_INT16_C
|
|
||||||
#define UPX_UINT16_C ACC_UINT16_C
|
|
||||||
#define UPX_INT32_C ACC_INT32_C
|
|
||||||
#define UPX_UINT32_C ACC_UINT32_C
|
|
||||||
#define UPX_INT64_C ACC_INT64_C
|
|
||||||
#define UPX_UINT64_C ACC_UINT64_C
|
|
||||||
|
|
||||||
typedef unsigned char upx_byte;
|
typedef unsigned char upx_byte;
|
||||||
#define upx_bytep upx_byte *
|
#define upx_bytep upx_byte *
|
||||||
|
|
||||||
|
// protect against integer overflows and malicious header fields
|
||||||
|
// see C 11 standard, Annex K
|
||||||
|
typedef size_t upx_rsize_t;
|
||||||
|
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
|
||||||
|
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
|
||||||
|
#define UPX_RSIZE_MAX_STR (1024 * 1024)
|
||||||
|
|
||||||
|
// using the system off_t was a bad idea even back in 199x...
|
||||||
|
typedef upx_int64_t upx_off_t;
|
||||||
|
#undef off_t
|
||||||
|
#if 0
|
||||||
|
// at some future point we can do this...
|
||||||
|
#define off_t DO_NOT_USE_off_t
|
||||||
|
#else
|
||||||
|
#define off_t upx_off_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// shortcuts
|
||||||
|
#define forceinline __acc_forceinline
|
||||||
|
#if _MSC_VER
|
||||||
|
#define noinline __declspec(noinline)
|
||||||
|
#undef __acc_noinline
|
||||||
|
#define __acc_noinline noinline
|
||||||
|
#else
|
||||||
|
#define noinline __acc_noinline
|
||||||
|
#endif
|
||||||
|
#define likely __acc_likely
|
||||||
|
#define unlikely __acc_unlikely
|
||||||
|
#define very_likely __acc_very_likely
|
||||||
|
#define very_unlikely __acc_very_unlikely
|
||||||
|
|
||||||
|
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||||
|
#define DELETED_FUNCTION = delete
|
||||||
|
#define UNUSED(var) ACC_UNUSED(var)
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// portab
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(__linux__) && !defined(__unix__)
|
|
||||||
# define __unix__ 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// just in case
|
// just in case
|
||||||
#undef _
|
#undef _
|
||||||
#undef __
|
#undef __
|
||||||
@@ -123,56 +226,15 @@ typedef unsigned char upx_byte;
|
|||||||
#undef small
|
#undef small
|
||||||
#undef tos
|
#undef tos
|
||||||
#undef unix
|
#undef unix
|
||||||
|
#if defined(__linux__) && !defined(__unix__)
|
||||||
|
# define __unix__ 1
|
||||||
|
#endif
|
||||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
# undef sopen
|
# undef sopen
|
||||||
# undef __unix__
|
# undef __unix__
|
||||||
# undef __unix
|
# undef __unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WITH_LZMA 0x443
|
|
||||||
#define WITH_UCL 1
|
|
||||||
#define WITH_ZLIB 1
|
|
||||||
#if (WITH_UCL)
|
|
||||||
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
|
||||||
# include <ucl/uclconf.h>
|
|
||||||
# include <ucl/ucl.h>
|
|
||||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
|
||||||
# error "please upgrade your UCL installation"
|
|
||||||
# endif
|
|
||||||
# undef ucl_compress_config_t
|
|
||||||
# undef ucl_compress_config_p
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// malloc debuggers
|
|
||||||
#if (WITH_VALGRIND)
|
|
||||||
# include <valgrind/memcheck.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
|
|
||||||
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
|
|
||||||
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
|
|
||||||
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// IMPORTANT: unconditionally enable assertions
|
|
||||||
#undef NDEBUG
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// protect against integer overflows and malicious header fields
|
|
||||||
// see C 11 standard, Annex K
|
|
||||||
typedef size_t upx_rsize_t;
|
|
||||||
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
|
|
||||||
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE
|
|
||||||
#define UPX_RSIZE_MAX_STR (1024 * 1024)
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// portab
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef STDIN_FILENO
|
#ifndef STDIN_FILENO
|
||||||
# define STDIN_FILENO (fileno(stdin))
|
# define STDIN_FILENO (fileno(stdin))
|
||||||
#endif
|
#endif
|
||||||
@@ -183,10 +245,10 @@ typedef size_t upx_rsize_t;
|
|||||||
# define STDERR_FILENO (fileno(stderr))
|
# define STDERR_FILENO (fileno(stderr))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !(HAVE_STRCASECMP) && (HAVE_STRICMP)
|
#if !(HAVE_STRCASECMP) && (HAVE_STRICMP) && !defined(strcasecmp)
|
||||||
# define strcasecmp stricmp
|
# define strcasecmp stricmp
|
||||||
#endif
|
#endif
|
||||||
#if !(HAVE_STRNCASECMP) && (HAVE_STRNICMP)
|
#if !(HAVE_STRNCASECMP) && (HAVE_STRNICMP) && !defined(strncasecmp)
|
||||||
# define strncasecmp strnicmp
|
# define strncasecmp strnicmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -230,10 +292,14 @@ typedef size_t upx_rsize_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// avoid warnings about shadowing global functions
|
// avoid warnings about shadowing global functions
|
||||||
|
#undef _base
|
||||||
|
#undef basename
|
||||||
#undef index
|
#undef index
|
||||||
#define basename upx_basename
|
#undef outp
|
||||||
#define index upx_index
|
#define _base upx_renamed__base
|
||||||
#define outp upx_outp
|
#define basename upx_renamed_basename
|
||||||
|
#define index upx_renamed_index
|
||||||
|
#define outp upx_renamed_outp
|
||||||
|
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
#undef PAGE_SIZE
|
#undef PAGE_SIZE
|
||||||
@@ -247,41 +313,90 @@ typedef size_t upx_rsize_t;
|
|||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPTIONS_VAR
|
|
||||||
# define OPTIONS_VAR "UPX"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if (ACC_CC_MSC)
|
#define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/
|
||||||
#define __packed_struct(s) struct s {
|
|
||||||
|
// malloc debuggers
|
||||||
|
#if !defined(VALGRIND_CHECK_MEM_IS_ADDRESSABLE)
|
||||||
|
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
|
||||||
|
# define VALGRIND_CHECK_MEM_IS_DEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
|
||||||
|
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
|
||||||
|
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
|
||||||
|
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
|
||||||
|
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b)))
|
||||||
|
#elif (ACC_CC_CLANG || ACC_CC_GNUC)
|
||||||
|
# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b)))
|
||||||
|
#else
|
||||||
|
# define attribute_format(a,b) /*empty*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void NO_printf(const char *, ...) attribute_format(1, 2);
|
||||||
|
inline void NO_fprintf(FILE *, const char *, ...) attribute_format(2, 3);
|
||||||
|
inline void NO_printf(const char *, ...) {}
|
||||||
|
inline void NO_fprintf(FILE *, const char *, ...) {}
|
||||||
|
|
||||||
|
#if !defined(__has_builtin)
|
||||||
|
# define __has_builtin(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_memcpy_inline)
|
||||||
|
# define upx_memcpy_inline __builtin_memcpy_inline
|
||||||
|
#elif __has_builtin(__builtin_memcpy)
|
||||||
|
# define upx_memcpy_inline __builtin_memcpy
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define upx_memcpy_inline __builtin_memcpy
|
||||||
|
#else
|
||||||
|
# define upx_memcpy_inline memcpy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_return_address)
|
||||||
|
# define upx_return_address() __builtin_return_address(0)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define upx_return_address() __builtin_return_address(0)
|
||||||
|
#elif (ACC_CC_MSC)
|
||||||
|
# define upx_return_address() _ReturnAddress()
|
||||||
|
#else
|
||||||
|
# define upx_return_address() nullptr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO cleanup: we now require C++14, so remove all __packed_struct usage
|
||||||
|
#define __packed_struct(s) struct alignas(1) s {
|
||||||
#define __packed_struct_end() };
|
#define __packed_struct_end() };
|
||||||
#else
|
|
||||||
#define __packed_struct(s) __acc_struct_packed(s)
|
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
#define __packed_struct_end() __acc_struct_packed_end()
|
// horrible hack for broken compiler
|
||||||
|
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
|
||||||
|
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||||
|
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
|
||||||
|
#define alignas(x) upx_fake_alignas__(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNUSED(var) ACC_UNUSED(var)
|
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
|
||||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
|
||||||
|
|
||||||
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
|
||||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||||
__packed_struct(acc_tmp_t) acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; __packed_struct_end() \
|
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
|
||||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
|
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
|
||||||
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)0)->x)+sizeof(((acc_tmp_t*)0)->y)+sizeof(((acc_tmp_t*)0)->z) == 2*sizeof(b)+sizeof(a)) \
|
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)nullptr)->x)+sizeof(((acc_tmp_t*)nullptr)->y)+sizeof(((acc_tmp_t*)nullptr)->z) == 2*sizeof(b)+sizeof(a)) \
|
||||||
}
|
}
|
||||||
#if defined(__acc_alignof)
|
#define COMPILE_TIME_ASSERT_ALIGNOF__(a,b) \
|
||||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) \
|
||||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
|
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b)) \
|
||||||
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
|
COMPILE_TIME_ASSERT(alignof(a) == sizeof(b))
|
||||||
#else
|
#define COMPILE_TIME_ASSERT_ALIGNED1(a) COMPILE_TIME_ASSERT_ALIGNOF__(a,char)
|
||||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
|
||||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
|
||||||
#endif
|
|
||||||
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
|
|
||||||
|
|
||||||
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
||||||
|
|
||||||
@@ -298,8 +413,17 @@ inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a;
|
|||||||
template <class T>
|
template <class T>
|
||||||
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
||||||
|
|
||||||
|
template <size_t TypeSize>
|
||||||
|
struct USizeOfTypeImpl {
|
||||||
|
static forceinline constexpr unsigned value() {
|
||||||
|
COMPILE_TIME_ASSERT(TypeSize >= 1 && TypeSize <= 64 * 1024); // arbitrary limit
|
||||||
|
return ACC_ICONV(unsigned, TypeSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#define usizeof(type) (USizeOfTypeImpl<sizeof(type)>::value())
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
|
||||||
|
|
||||||
// An Array allocates memory on the heap, but automatically
|
// An Array allocates memory on the heap, and automatically
|
||||||
// gets destructed when leaving scope or on exceptions.
|
// gets destructed when leaving scope or on exceptions.
|
||||||
#define Array(type, var, size) \
|
#define Array(type, var, size) \
|
||||||
MemBuffer var ## _membuf(mem_size(sizeof(type), size)); \
|
MemBuffer var ## _membuf(mem_size(sizeof(type), size)); \
|
||||||
@@ -307,17 +431,44 @@ inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b;
|
|||||||
|
|
||||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||||
|
|
||||||
|
|
||||||
class noncopyable
|
class noncopyable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
inline noncopyable() {}
|
inline noncopyable() {}
|
||||||
inline ~noncopyable() {}
|
inline ~noncopyable() {}
|
||||||
private:
|
private:
|
||||||
noncopyable(const noncopyable &); // undefined
|
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor
|
||||||
const noncopyable& operator=(const noncopyable &); // undefined
|
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment
|
||||||
|
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor
|
||||||
|
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace compile_time {
|
||||||
|
constexpr size_t string_len(const char *a) {
|
||||||
|
return *a == '\0' ? 0 : 1 + string_len(a + 1);
|
||||||
|
}
|
||||||
|
constexpr bool string_eq(const char *a, const char *b) {
|
||||||
|
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
|
||||||
|
}
|
||||||
|
constexpr bool string_lt(const char *a, const char *b) {
|
||||||
|
return (unsigned char)*a < (unsigned char)*b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1));
|
||||||
|
}
|
||||||
|
constexpr bool string_ne(const char *a, const char *b) {
|
||||||
|
return !string_eq(a, b);
|
||||||
|
}
|
||||||
|
constexpr bool string_gt(const char *a, const char *b) {
|
||||||
|
return string_lt(b, a);
|
||||||
|
}
|
||||||
|
constexpr bool string_le(const char *a, const char *b) {
|
||||||
|
return !string_lt(b, a);
|
||||||
|
}
|
||||||
|
constexpr bool string_ge(const char *a, const char *b) {
|
||||||
|
return !string_lt(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// constants
|
// constants
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -361,14 +512,14 @@ private:
|
|||||||
#define UPX_F_DOS_EXE 3
|
#define UPX_F_DOS_EXE 3
|
||||||
#define UPX_F_DJGPP2_COFF 4
|
#define UPX_F_DJGPP2_COFF 4
|
||||||
#define UPX_F_WATCOM_LE 5
|
#define UPX_F_WATCOM_LE 5
|
||||||
#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
|
//#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
|
||||||
#define UPX_F_DOS_EXEH 7 // OBSOLETE
|
#define UPX_F_DOS_EXEH 7 // OBSOLETE
|
||||||
#define UPX_F_TMT_ADAM 8
|
#define UPX_F_TMT_ADAM 8
|
||||||
#define UPX_F_WIN32_PE 9
|
#define UPX_F_WIN32_PE 9
|
||||||
#define UPX_F_LINUX_i386 10
|
#define UPX_F_LINUX_i386 10
|
||||||
#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
|
//#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
|
||||||
#define UPX_F_LINUX_ELF_i386 12
|
#define UPX_F_LINUX_ELF_i386 12
|
||||||
#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
|
//#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
|
||||||
#define UPX_F_LINUX_SH_i386 14
|
#define UPX_F_LINUX_SH_i386 14
|
||||||
#define UPX_F_VMLINUZ_i386 15
|
#define UPX_F_VMLINUZ_i386 15
|
||||||
#define UPX_F_BVMLINUZ_i386 16
|
#define UPX_F_BVMLINUZ_i386 16
|
||||||
@@ -398,15 +549,15 @@ private:
|
|||||||
|
|
||||||
#define UPX_F_MACH_ARM64EL 37
|
#define UPX_F_MACH_ARM64EL 37
|
||||||
|
|
||||||
#define UPX_F_MACH_PPC64LE 38
|
//#define UPX_F_MACH_PPC64LE 38 // DOES NOT EXIST
|
||||||
#define UPX_F_LINUX_ELFPPC64LE 39
|
#define UPX_F_LINUX_ELFPPC64LE 39
|
||||||
#define UPX_F_VMLINUX_PPC64LE 40
|
#define UPX_F_VMLINUX_PPC64LE 40
|
||||||
#define UPX_F_DYLIB_PPC64LE 41
|
//#define UPX_F_DYLIB_PPC64LE 41 // DOES NOT EXIST
|
||||||
|
|
||||||
#define UPX_F_LINUX_ELF64_ARM 42
|
#define UPX_F_LINUX_ELF64_ARM 42
|
||||||
|
|
||||||
#define UPX_F_ATARI_TOS 129
|
#define UPX_F_ATARI_TOS 129
|
||||||
#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
|
//#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
#define UPX_F_LINUX_ELF32_ARMEB 133
|
#define UPX_F_LINUX_ELF32_ARMEB 133
|
||||||
@@ -416,13 +567,11 @@ private:
|
|||||||
#define UPX_F_LINUX_ELF32_MIPSEB 137
|
#define UPX_F_LINUX_ELF32_MIPSEB 137
|
||||||
#define UPX_F_DYLIB_PPC32 138
|
#define UPX_F_DYLIB_PPC32 138
|
||||||
|
|
||||||
|
#define UPX_F_MACH_PPC64 139
|
||||||
|
#define UPX_F_LINUX_ELFPPC64 140
|
||||||
|
#define UPX_F_VMLINUX_PPC64 141
|
||||||
|
#define UPX_F_DYLIB_PPC64 142
|
||||||
|
|
||||||
// compression methods
|
|
||||||
#define M_ALL (-1)
|
|
||||||
#define M_END (-2)
|
|
||||||
#define M_NONE (-3)
|
|
||||||
#define M_SKIP (-4)
|
|
||||||
#define M_ULTRA_BRUTE (-5)
|
|
||||||
// compression methods - DO NOT CHANGE
|
// compression methods - DO NOT CHANGE
|
||||||
#define M_NRV2B_LE32 2
|
#define M_NRV2B_LE32 2
|
||||||
#define M_NRV2B_8 3
|
#define M_NRV2B_8 3
|
||||||
@@ -437,7 +586,14 @@ private:
|
|||||||
//#define M_CL1B_8 12
|
//#define M_CL1B_8 12
|
||||||
//#define M_CL1B_LE16 13
|
//#define M_CL1B_LE16 13
|
||||||
#define M_LZMA 14
|
#define M_LZMA 14
|
||||||
#define M_DEFLATE 15 /* zlib */
|
#define M_DEFLATE 15 // zlib
|
||||||
|
#define M_ZSTD 16
|
||||||
|
// compression methods internal usage
|
||||||
|
#define M_ALL (-1)
|
||||||
|
#define M_END (-2)
|
||||||
|
#define M_NONE (-3)
|
||||||
|
#define M_SKIP (-4)
|
||||||
|
#define M_ULTRA_BRUTE (-5)
|
||||||
|
|
||||||
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||||
@@ -445,6 +601,7 @@ private:
|
|||||||
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||||
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
||||||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||||
|
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
|
||||||
|
|
||||||
|
|
||||||
// filters
|
// filters
|
||||||
@@ -455,9 +612,20 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compression - callback_t
|
// compression - setup and callback_t
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define WITH_LZMA 1
|
||||||
|
#define WITH_UCL 1
|
||||||
|
#define WITH_ZLIB 1
|
||||||
|
#if (WITH_UCL)
|
||||||
|
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||||
|
# include <ucl/include/ucl/uclconf.h>
|
||||||
|
# include <ucl/include/ucl/ucl.h>
|
||||||
|
# undef ucl_compress_config_t
|
||||||
|
# undef ucl_compress_config_p
|
||||||
|
#endif
|
||||||
|
|
||||||
struct upx_callback_t;
|
struct upx_callback_t;
|
||||||
typedef upx_callback_t *upx_callback_p;
|
typedef upx_callback_t *upx_callback_p;
|
||||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||||
@@ -476,43 +644,47 @@ struct upx_callback_t
|
|||||||
// compression - config_t
|
// compression - config_t
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
template <class T, T default_value, T min_value, T max_value>
|
template <class T, T default_value_, T min_value_, T max_value_>
|
||||||
struct OptVar
|
struct OptVar
|
||||||
{
|
{
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
static const T default_value_c = default_value;
|
static const T default_value = default_value_;
|
||||||
static const T min_value_c = min_value;
|
static const T min_value = min_value_;
|
||||||
static const T max_value_c = max_value;
|
static const T max_value = max_value_;
|
||||||
|
|
||||||
void assertValue() const {
|
static void assertValue(const T &v) {
|
||||||
// info: this generates annoying warnings "unsigned >= 0 is always true"
|
// info: this generates annoying warnings "unsigned >= 0 is always true"
|
||||||
//assert(v >= min_value_c);
|
//assert(v >= min_value);
|
||||||
assert(v == min_value_c || v >= min_value_c + 1);
|
assert(v == min_value || v >= min_value + 1);
|
||||||
assert(v <= max_value_c);
|
assert(v <= max_value);
|
||||||
|
}
|
||||||
|
void assertValue() const {
|
||||||
|
assertValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
OptVar() : v(default_value), is_set(0) { }
|
OptVar() : v(default_value), is_set(false) { }
|
||||||
OptVar& operator= (const T other) {
|
OptVar& operator= (const T &other) {
|
||||||
v = other; is_set += 1;
|
assertValue(other);
|
||||||
assertValue();
|
v = other;
|
||||||
|
is_set = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() { v = default_value; is_set = 0; }
|
void reset() { v = default_value; is_set = false; }
|
||||||
operator T () const { return v; }
|
operator T () const { return v; }
|
||||||
|
|
||||||
T v;
|
T v;
|
||||||
unsigned is_set;
|
bool is_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// optional assignments
|
// optional assignments
|
||||||
template <class T, T a, T b, T c>
|
template <class T, T a, T b, T c>
|
||||||
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) {
|
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) {
|
||||||
if (other.is_set) { self.v = other.v; self.is_set += 1; }
|
if (other.is_set) { self.v = other.v; self.is_set = true; }
|
||||||
}
|
}
|
||||||
template <class T, T a, T b, T c>
|
template <class T, T a, T b, T c>
|
||||||
inline void oassign(unsigned &v, const OptVar<T,a,b,c> &other) {
|
inline void oassign(T &v, const OptVar<T,a,b,c> &other) {
|
||||||
if (other.is_set) { v = other.v; }
|
if (other.is_set) { v = other.v; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,13 +710,11 @@ struct lzma_compress_config_t
|
|||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||||
{
|
{
|
||||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct zlib_compress_config_t
|
struct zlib_compress_config_t
|
||||||
{
|
{
|
||||||
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||||
@@ -558,16 +728,23 @@ struct zlib_compress_config_t
|
|||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zstd_compress_config_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
struct upx_compress_config_t
|
struct upx_compress_config_t
|
||||||
{
|
{
|
||||||
lzma_compress_config_t conf_lzma;
|
lzma_compress_config_t conf_lzma;
|
||||||
ucl_compress_config_t conf_ucl;
|
ucl_compress_config_t conf_ucl;
|
||||||
zlib_compress_config_t conf_zlib;
|
zlib_compress_config_t conf_zlib;
|
||||||
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
|
zstd_compress_config_t conf_zstd;
|
||||||
|
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NULL_cconf ((upx_compress_config_t *) NULL)
|
#define NULL_cconf ((upx_compress_config_t *) nullptr)
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -588,7 +765,6 @@ struct lzma_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ucl_compress_result_t
|
struct ucl_compress_result_t
|
||||||
{
|
{
|
||||||
ucl_uint result[16];
|
ucl_uint result[16];
|
||||||
@@ -596,7 +772,6 @@ struct ucl_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct zlib_compress_result_t
|
struct zlib_compress_result_t
|
||||||
{
|
{
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
@@ -604,20 +779,29 @@ struct zlib_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zstd_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
struct upx_compress_result_t
|
struct upx_compress_result_t
|
||||||
{
|
{
|
||||||
// debug
|
// debugging aid
|
||||||
|
struct {
|
||||||
int method, level;
|
int method, level;
|
||||||
unsigned u_len, c_len;
|
unsigned u_len, c_len;
|
||||||
|
} debug;
|
||||||
|
|
||||||
lzma_compress_result_t result_lzma;
|
lzma_compress_result_t result_lzma;
|
||||||
ucl_compress_result_t result_ucl;
|
ucl_compress_result_t result_ucl;
|
||||||
zlib_compress_result_t result_zlib;
|
zlib_compress_result_t result_zlib;
|
||||||
|
zstd_compress_result_t result_zstd;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
memset(this, 0, sizeof(*this));
|
memset(&this->debug, 0, sizeof(this->debug));
|
||||||
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -626,76 +810,64 @@ struct upx_compress_result_t
|
|||||||
// globals
|
// globals
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "snprintf.h" // must get included first!
|
#include "util/snprintf.h" // must get included first!
|
||||||
#include "stdcxx.h"
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "bele.h"
|
#include "bele.h"
|
||||||
#include "util.h"
|
#include "console/console.h"
|
||||||
#include "console.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
|
|
||||||
// classes
|
// classes
|
||||||
class ElfLinker;
|
class ElfLinker;
|
||||||
typedef ElfLinker Linker;
|
typedef ElfLinker Linker;
|
||||||
|
|
||||||
|
// util/membuffer.h
|
||||||
|
class MemBuffer;
|
||||||
|
void *membuffer_get_void_ptr(MemBuffer &mb);
|
||||||
|
unsigned membuffer_get_size(MemBuffer &mb);
|
||||||
|
|
||||||
|
// xspan
|
||||||
|
#include "util/xspan.h"
|
||||||
|
|
||||||
|
// util/dt_check.cpp
|
||||||
|
void upx_compiler_sanity_check();
|
||||||
|
int upx_doctest_check();
|
||||||
|
int upx_doctest_check(int argc, char **argv);
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
bool set_exit_code(int ec);
|
bool main_set_exit_code(int ec);
|
||||||
#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
int main_get_options(int argc, char **argv);
|
||||||
void e_exit(int ec) __attribute__((__noreturn__));
|
void main_get_envoptions();
|
||||||
#else
|
int upx_main(int argc, char *argv[]);
|
||||||
void e_exit(int ec);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// msg.cpp
|
// msg.cpp
|
||||||
void printSetNl(int need_nl);
|
void printSetNl(int need_nl);
|
||||||
void printClearLine(FILE *f = NULL);
|
void printClearLine(FILE *f = nullptr);
|
||||||
void printErr(const char *iname, const Throwable *e);
|
void printErr(const char *iname, const Throwable *e);
|
||||||
void printUnhandledException(const char *iname, const std::exception *e);
|
void printUnhandledException(const char *iname, const std::exception *e);
|
||||||
#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
void printErr(const char *iname, const char *format, ...) attribute_format(2, 3);
|
||||||
void __acc_cdecl_va printErr(const char *iname, const char *format, ...)
|
void printWarn(const char *iname, const char *format, ...) attribute_format(2, 3);
|
||||||
__attribute__((__format__(__printf__,2,3)));
|
|
||||||
void __acc_cdecl_va printWarn(const char *iname, const char *format, ...)
|
|
||||||
__attribute__((__format__(__printf__,2,3)));
|
|
||||||
#else
|
|
||||||
void __acc_cdecl_va printErr(const char *iname, const char *format, ...);
|
|
||||||
void __acc_cdecl_va printWarn(const char *iname, const char *format, ...);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
void infoWarning(const char *format, ...) attribute_format(1, 2);
|
||||||
void __acc_cdecl_va infoWarning(const char *format, ...)
|
void infoHeader(const char *format, ...) attribute_format(1, 2);
|
||||||
__attribute__((__format__(__printf__,1,2)));
|
void info(const char *format, ...) attribute_format(1, 2);
|
||||||
void __acc_cdecl_va infoHeader(const char *format, ...)
|
|
||||||
__attribute__((__format__(__printf__,1,2)));
|
|
||||||
void __acc_cdecl_va info(const char *format, ...)
|
|
||||||
__attribute__((__format__(__printf__,1,2)));
|
|
||||||
#else
|
|
||||||
void __acc_cdecl_va infoWarning(const char *format, ...);
|
|
||||||
void __acc_cdecl_va infoHeader(const char *format, ...);
|
|
||||||
void __acc_cdecl_va info(const char *format, ...);
|
|
||||||
#endif
|
|
||||||
void infoHeader();
|
void infoHeader();
|
||||||
void infoWriting(const char *what, long size);
|
void infoWriting(const char *what, long size);
|
||||||
|
|
||||||
|
|
||||||
// work.cpp
|
// work.cpp
|
||||||
void do_one_file(const char *iname, char *oname);
|
void do_one_file(const char *iname, char *oname);
|
||||||
void do_files(int i, int argc, char *argv[]);
|
int do_files(int i, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
// help.cpp
|
// help.cpp
|
||||||
extern const char gitrev[];
|
extern const char gitrev[];
|
||||||
void show_head(void);
|
void show_head();
|
||||||
void show_help(int verbose=0);
|
void show_help(int verbose=0);
|
||||||
void show_license(void);
|
void show_license();
|
||||||
void show_usage(void);
|
void show_usage();
|
||||||
void show_version(int);
|
void show_version(bool one_line=false);
|
||||||
|
|
||||||
|
// compress/compress.cpp
|
||||||
// compress.cpp
|
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||||
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
||||||
|
|
||||||
@@ -723,7 +895,6 @@ int upx_test_overlap ( const upx_bytep buf,
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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)
|
||||||
|
|
||||||
@@ -41,9 +40,7 @@ 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);
|
||||||
@@ -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,9 +66,7 @@ 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);
|
||||||
@@ -98,13 +92,11 @@ static int do_init(FILE *f)
|
|||||||
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,41 +106,28 @@ 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)
|
||||||
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,13 +34,11 @@
|
|||||||
#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)
|
||||||
@@ -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;
|
||||||
@@ -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,9 +159,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,9 +167,7 @@ static int set_fg(FILE *f, int 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);
|
||||||
@@ -200,54 +180,44 @@ static void print0(FILE *f, const char *ss)
|
|||||||
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;
|
||||||
@@ -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,18 +241,15 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -294,9 +259,7 @@ static void print0(FILE *f, const char *ss)
|
|||||||
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)
|
||||||
@@ -305,15 +268,7 @@ static bool intro(FILE *f)
|
|||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -64,9 +64,10 @@
|
|||||||
#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
|
||||||
@@ -80,7 +81,6 @@
|
|||||||
#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
|
||||||
@@ -94,41 +94,22 @@
|
|||||||
#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,7 +157,6 @@ 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
|
||||||
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
#if (ACC_CC_GNUC >= 0x040300ul)
|
#if (ACC_CC_GNUC >= 0x040300ul)
|
||||||
@@ -81,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) {
|
||||||
@@ -97,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];
|
||||||
}
|
}
|
||||||
@@ -274,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? */
|
||||||
@@ -369,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);
|
||||||
@@ -417,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,
|
||||||
@@ -430,7 +432,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_djgpp2_construct(void) { return sobject_construct(&driver, sizeof(*driver.data)); }
|
screen_t *screen_djgpp2_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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
|
|
||||||
@@ -346,7 +346,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 +395,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 +405,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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,9 @@
|
|||||||
<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
|
#ifndef UPX_SCREEN_H__
|
||||||
|
#define UPX_SCREEN_H__ 1
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
+34
-80
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,19 +25,18 @@
|
|||||||
<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;
|
unsigned long Throwable::counter = 0;
|
||||||
|
|
||||||
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),
|
||||||
|
is_warning(w) {
|
||||||
if (m)
|
if (m)
|
||||||
msg = strdup(m);
|
msg = strdup(m);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -46,10 +45,10 @@ Throwable::Throwable(const char *m, int e, bool w) NOTHROW
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
msg = strdup(other.msg);
|
msg = strdup(other.msg);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -58,9 +57,7 @@ Throwable::Throwable(const Throwable &other) NOTHROW
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Throwable::~Throwable() noexcept {
|
||||||
Throwable::~Throwable() NOTHROW
|
|
||||||
{
|
|
||||||
#if 0
|
#if 0
|
||||||
counter--;
|
counter--;
|
||||||
fprintf(stderr, "destruct exception: %s %lu\n", msg, counter);
|
fprintf(stderr, "destruct exception: %s %lu\n", msg, counter);
|
||||||
@@ -69,13 +66,11 @@ Throwable::~Throwable() NOTHROW
|
|||||||
free(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_COMPRESS)
|
||||||
throw CantPackException(msg);
|
throw CantPackException(msg);
|
||||||
@@ -85,114 +80,73 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const char *prettyName(const char *n) NOTHROW
|
const char *prettyName(const char *n) noexcept {
|
||||||
{
|
if (n == nullptr)
|
||||||
if (n == NULL)
|
|
||||||
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 == ' ')
|
||||||
|
|||||||
+93
-102
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,175 +25,167 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_EXCEPT_H
|
#ifndef UPX_EXCEPT_H__
|
||||||
#define __UPX_EXCEPT_H 1
|
#define UPX_EXCEPT_H__ 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
const char *prettyName(const char *n) NOTHROW;
|
const char *prettyName(const char *n) noexcept;
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 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;
|
||||||
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;
|
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 assignment
|
||||||
Throwable& operator= (const Throwable &);
|
Throwable &operator=(const Throwable &) = delete;
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation => force throwing by value
|
||||||
DISABLE_NEW_DELETE
|
ACC_CXX_DISABLE_NEW_DELETE
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned long counter; // for debugging
|
static unsigned long counter; // for debugging
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 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:
|
|
||||||
Exception(const char *m = 0, int e = 0, bool w = false) NOTHROW : super(m,e,w) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
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:
|
|
||||||
Error(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// system exception
|
// system exception
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class OutOfMemoryException : public Exception
|
class OutOfMemoryException : 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 : 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 : 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 : 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 : public IOException {
|
||||||
class FileAlreadyExistsException : public IOException
|
|
||||||
{
|
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
public:
|
|
||||||
FileAlreadyExistsException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// application execptions
|
// application exceptions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class OverlayException : public Exception
|
class OverlayException : 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 : 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 : 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 : 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 : 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 : public CantUnpackException {
|
||||||
{
|
|
||||||
typedef CantUnpackException super;
|
typedef CantUnpackException super;
|
||||||
public:
|
|
||||||
NotPackedException(const char *m = 0) NOTHROW : super(m,true) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
|
||||||
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// errors
|
// errors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class InternalError : public Error
|
class InternalError : public Error {
|
||||||
{
|
|
||||||
typedef Error super;
|
typedef Error super;
|
||||||
public:
|
|
||||||
InternalError(const char *m = 0) NOTHROW : super(m,0) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
|
||||||
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
@@ -201,31 +193,30 @@ public:
|
|||||||
|
|
||||||
#undef NORET
|
#undef NORET
|
||||||
#if 1 && defined(__GNUC__)
|
#if 1 && defined(__GNUC__)
|
||||||
#define NORET __attribute__((__noreturn__))
|
#define NORET __acc_noinline __attribute__((__noreturn__))
|
||||||
#else
|
#else
|
||||||
#define NORET /*empty*/
|
#define NORET __acc_noinline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void throwCantPack(const char *msg) NORET;
|
NORET void throwCantPack(const char *msg);
|
||||||
void throwCantPackExact() NORET;
|
NORET void throwCantPackExact();
|
||||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
NORET void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false);
|
||||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
NORET void throwNotCompressible(const char *msg = nullptr);
|
||||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
NORET void throwAlreadyPacked(const char *msg = nullptr);
|
||||||
void throwAlreadyPackedByUPX(const char *msg = NULL) NORET;
|
NORET void throwAlreadyPackedByUPX(const char *msg = nullptr);
|
||||||
void throwCantUnpack(const char *msg) NORET;
|
NORET void throwCantUnpack(const char *msg);
|
||||||
void throwNotPacked(const char *msg = NULL) NORET;
|
NORET void throwNotPacked(const char *msg = nullptr);
|
||||||
void throwFilterException() NORET;
|
NORET void throwFilterException();
|
||||||
void throwBadLoader() NORET;
|
NORET void throwBadLoader();
|
||||||
void throwChecksumError() NORET;
|
NORET void throwChecksumError();
|
||||||
void throwCompressedDataViolation() NORET;
|
NORET void throwCompressedDataViolation();
|
||||||
void throwInternalError(const char *msg) NORET;
|
NORET void throwInternalError(const char *msg);
|
||||||
void throwOutOfMemoryException(const char *msg = NULL) NORET;
|
NORET void throwOutOfMemoryException(const char *msg = nullptr);
|
||||||
void throwIOException(const char *msg = NULL, int e = 0) NORET;
|
NORET void throwIOException(const char *msg = nullptr, int e = 0);
|
||||||
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
NORET void throwEOFException(const char *msg = nullptr, int e = 0);
|
||||||
|
|
||||||
#undef NORET
|
#undef NORET
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|||||||
+76
-226
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,29 +25,24 @@
|
|||||||
<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 functions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void File::chmod(const char *name, int mode)
|
void FileBase::chmod(const char *name, int mode) {
|
||||||
{
|
|
||||||
#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);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
if (::_rename(old_, new_) != 0)
|
if (::_rename(old_, new_) != 0)
|
||||||
#else
|
#else
|
||||||
@@ -56,27 +51,21 @@ void File::rename(const char *old_, const char *new_)
|
|||||||
throwIOException("rename error", errno);
|
throwIOException("rename error", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileBase::unlink(const char *name) {
|
||||||
void File::unlink(const char *name)
|
|
||||||
{
|
|
||||||
if (::unlink(name) != 0)
|
if (::unlink(name) != 0)
|
||||||
throwIOException(name, errno);
|
throwIOException(name, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
FileBase::FileBase() :
|
FileBase::FileBase()
|
||||||
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
|
: _fd(-1), _flags(0), _shflags(0), _mode(0), _name(nullptr), _offset(0), _length(0) {
|
||||||
{
|
|
||||||
memset(&st, 0, sizeof(st));
|
memset(&st, 0, sizeof(st));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileBase::~FileBase() {
|
||||||
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__);
|
||||||
@@ -87,13 +76,10 @@ FileBase::~FileBase()
|
|||||||
closex();
|
closex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
_fd = ::open(_name, _flags | _shflags, _mode);
|
_fd = ::open(_name, _flags | _shflags, _mode);
|
||||||
#elif defined(__MINT__)
|
#elif defined(__MINT__)
|
||||||
@@ -112,9 +98,7 @@ bool FileBase::do_sopen()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileBase::close() {
|
||||||
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,58 +106,22 @@ 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() {
|
||||||
void FileBase::closex()
|
|
||||||
{
|
|
||||||
if (!close())
|
if (!close())
|
||||||
throwIOException("close failed", errno);
|
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");
|
||||||
@@ -185,51 +133,36 @@ off_t FileBase::seek(upx_int64_t off64, int whence)
|
|||||||
off += _offset + _length;
|
off += _offset + _length;
|
||||||
whence = SEEK_SET;
|
whence = SEEK_SET;
|
||||||
}
|
}
|
||||||
if (::lseek(_fd,off,whence) < 0)
|
// SEEK_CUR falls through to here
|
||||||
|
upx_off_t rv = ::lseek(_fd, off, whence);
|
||||||
|
if (rv < 0)
|
||||||
throwIOException("seek error", errno);
|
throwIOException("seek error", errno);
|
||||||
return off - _offset;
|
return rv - _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upx_off_t FileBase::tell() const {
|
||||||
off_t FileBase::tell() const
|
|
||||||
{
|
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad tell");
|
throwIOException("bad tell");
|
||||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
upx_off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("tell error", errno);
|
throwIOException("tell error", errno);
|
||||||
return l - _offset;
|
return l - _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileBase::set_extent(upx_off_t offset, upx_off_t length) {
|
||||||
void FileBase::set_extent(off_t offset, 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::InputFile() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void InputFile::sopen(const char *name, int flags, int shflags) {
|
||||||
InputFile::~InputFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InputFile::sopen(const char *name, int flags, int shflags)
|
|
||||||
{
|
|
||||||
close();
|
close();
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
@@ -237,8 +170,7 @@ void InputFile::sopen(const char *name, int flags, int 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,80 +181,40 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
|||||||
_length_orig = _length;
|
_length_orig = _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InputFile::read(SPAN_P(void) buf, int len) {
|
||||||
int InputFile::read(void *buf, int len)
|
if (!isOpen() || len < 0)
|
||||||
{
|
throwIOException("bad read");
|
||||||
return super::read(buf, len);
|
mem_size_assert(1, len); // 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, int len) {
|
||||||
{
|
int l = this->read(buf, len);
|
||||||
return super::readx(buf, len);
|
if (l != len)
|
||||||
|
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
|
|
||||||
{
|
|
||||||
return super::tell();
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t InputFile::st_size_orig() const
|
|
||||||
{
|
|
||||||
return _length_orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
OutputFile::OutputFile() :
|
OutputFile::OutputFile() : bytes_written(0) {}
|
||||||
bytes_written(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
|
||||||
OutputFile::~OutputFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|
||||||
{
|
|
||||||
close();
|
close();
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
@@ -330,8 +222,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||||||
_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)
|
||||||
@@ -345,9 +236,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutputFile::openStdout(int flags, bool force) {
|
||||||
bool OutputFile::openStdout(int flags, bool force)
|
|
||||||
{
|
|
||||||
close();
|
close();
|
||||||
int fd = STDOUT_FILENO;
|
int fd = STDOUT_FILENO;
|
||||||
if (!force && acc_isatty(fd))
|
if (!force && acc_isatty(fd))
|
||||||
@@ -364,15 +253,25 @@ bool OutputFile::openStdout(int flags, bool force)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputFile::write(SPAN_0(const void) buf, int len) {
|
||||||
void OutputFile::write(const void *buf, int len)
|
if (!isOpen() || len < 0)
|
||||||
{
|
throwIOException("bad write");
|
||||||
super::write(buf, len);
|
// allow nullptr if len == 0
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
mem_size_assert(1, len); // sanity check
|
||||||
|
errno = 0;
|
||||||
|
#if 0
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +282,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: {
|
||||||
@@ -434,20 +316,18 @@ 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 && (upx_off_t) ~0u == length) {
|
||||||
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 +336,14 @@ off_t OutputFile::unset_extent()
|
|||||||
return _length;
|
return _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
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
|
|
||||||
|
|
||||||
MemoryOutputFile::MemoryOutputFile() :
|
|
||||||
b(NULL), b_size(0), b_pos(0), bytes_written(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: */
|
||||||
|
|||||||
+58
-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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,164 +25,110 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_FILE_H
|
#ifndef UPX_FILE_H__
|
||||||
#define __UPX_FILE_H 1
|
#define UPX_FILE_H__ 1
|
||||||
|
|
||||||
class MemBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class File
|
class FileBase {
|
||||||
{
|
|
||||||
protected:
|
|
||||||
File() { }
|
|
||||||
virtual ~File() { }
|
|
||||||
public:
|
|
||||||
static void chmod(const char *name, int mode);
|
|
||||||
static void rename(const char *old_, const char *new_);
|
|
||||||
static void unlink(const char *name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FileBase : public File
|
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
FileBase();
|
FileBase();
|
||||||
virtual ~FileBase();
|
virtual ~FileBase();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool close();
|
bool close();
|
||||||
virtual void closex();
|
void closex();
|
||||||
virtual bool isOpen() const { return _fd >= 0; }
|
bool isOpen() const { return _fd >= 0; }
|
||||||
int getFd() const { return _fd; }
|
int getFd() const { return _fd; }
|
||||||
const char *getName() const { return _name; }
|
const char *getName() const { return _name; }
|
||||||
virtual off_t st_size() const; // { return _length; }
|
|
||||||
virtual void set_extent(off_t offset, off_t length);
|
virtual upx_off_t seek(upx_off_t off, int whence);
|
||||||
|
upx_off_t tell() const;
|
||||||
|
virtual upx_off_t st_size() const; // { return _length; }
|
||||||
|
virtual void set_extent(upx_off_t offset, upx_off_t length);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// static file-related util functions
|
||||||
|
static void chmod(const char *name, int mode);
|
||||||
|
static void rename(const char *old_, const char *new_);
|
||||||
|
static void unlink(const char *name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool do_sopen();
|
bool do_sopen();
|
||||||
virtual int read(void *buf, int len);
|
int _fd = -1;
|
||||||
virtual int readx(void *buf, int len);
|
int _flags = 0;
|
||||||
virtual void write(const void *buf, int len);
|
int _shflags = 0;
|
||||||
virtual off_t seek(upx_int64_t off, int whence);
|
int _mode = 0;
|
||||||
virtual off_t tell() const;
|
const char *_name = nullptr;
|
||||||
|
upx_off_t _offset = 0;
|
||||||
|
upx_off_t _length = 0;
|
||||||
|
|
||||||
int _fd;
|
|
||||||
int _flags;
|
|
||||||
int _shflags;
|
|
||||||
int _mode;
|
|
||||||
const char *_name;
|
|
||||||
off_t _offset;
|
|
||||||
off_t _length;
|
|
||||||
public:
|
public:
|
||||||
struct stat st;
|
struct stat st = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class InputFile : public FileBase
|
class InputFile final : public FileBase {
|
||||||
{
|
|
||||||
typedef FileBase super;
|
typedef FileBase super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputFile();
|
InputFile();
|
||||||
virtual ~InputFile();
|
virtual ~InputFile() {}
|
||||||
|
|
||||||
virtual void sopen(const char *name, int flags, int shflags);
|
void sopen(const char *name, int flags, int shflags);
|
||||||
virtual void open(const char *name, int flags)
|
void open(const char *name, int flags) { sopen(name, flags, -1); }
|
||||||
{
|
|
||||||
sopen(name, flags, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int read(void *buf, int len);
|
int read(SPAN_P(void) buf, int len);
|
||||||
virtual int readx(void *buf, int len);
|
int readx(SPAN_P(void) buf, int len);
|
||||||
virtual int read(MemBuffer *buf, int len);
|
|
||||||
virtual int readx(MemBuffer *buf, int len);
|
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||||
virtual int read(MemBuffer &buf, int len);
|
upx_off_t st_size_orig() const;
|
||||||
virtual int readx(MemBuffer &buf, int len);
|
|
||||||
|
|
||||||
virtual off_t seek(upx_int64_t off, int whence);
|
|
||||||
virtual off_t tell() const;
|
|
||||||
virtual off_t st_size_orig() const;
|
|
||||||
protected:
|
protected:
|
||||||
off_t _length_orig;
|
upx_off_t _length_orig = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class OutputFile : public FileBase
|
class OutputFile final : public FileBase {
|
||||||
{
|
|
||||||
typedef FileBase super;
|
typedef FileBase super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OutputFile();
|
OutputFile();
|
||||||
virtual ~OutputFile();
|
virtual ~OutputFile() {}
|
||||||
|
|
||||||
virtual void sopen(const char *name, int flags, int shflags, int mode);
|
void sopen(const char *name, int flags, int shflags, int mode);
|
||||||
virtual void open(const char *name, int flags, int mode)
|
void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); }
|
||||||
{
|
bool openStdout(int flags = 0, bool force = false);
|
||||||
sopen(name, flags, -1, mode);
|
|
||||||
}
|
|
||||||
virtual bool openStdout(int flags=0, bool force=false);
|
|
||||||
|
|
||||||
virtual void write(const void *buf, int len);
|
// info: allow nullptr if len == 0
|
||||||
virtual void write(const MemBuffer *buf, int len);
|
void write(SPAN_0(const void) buf, int len);
|
||||||
virtual void write(const MemBuffer &buf, int len);
|
|
||||||
virtual void set_extent(off_t offset, off_t length);
|
|
||||||
virtual off_t unset_extent(); // returns actual length
|
|
||||||
|
|
||||||
off_t getBytesWritten() const { return bytes_written; }
|
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||||
virtual off_t st_size() const; // { return _length; }
|
virtual upx_off_t st_size() const override; // { return _length; }
|
||||||
|
virtual void set_extent(upx_off_t offset, upx_off_t length) override;
|
||||||
|
upx_off_t unset_extent(); // returns actual length
|
||||||
|
|
||||||
|
upx_off_t getBytesWritten() const { return bytes_written; }
|
||||||
|
|
||||||
// FIXME - these won't work when using the '--stdout' option
|
// FIXME - these won't work when using the '--stdout' option
|
||||||
virtual off_t seek(upx_int64_t off, int whence);
|
void rewrite(SPAN_P(const void) buf, int len);
|
||||||
virtual void rewrite(const void *buf, int len);
|
|
||||||
|
|
||||||
// util
|
// util
|
||||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
static void dump(const char *name, SPAN_P(const void) buf, int len, int flags = -1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
off_t bytes_written;
|
upx_off_t bytes_written = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#if 0 /* NOT USED */
|
|
||||||
class MemoryOutputFile : public FileBase
|
|
||||||
{
|
|
||||||
typedef FileBase super;
|
|
||||||
public:
|
|
||||||
MemoryOutputFile();
|
|
||||||
virtual ~MemoryOutputFile() { b = NULL; }
|
|
||||||
|
|
||||||
virtual bool close() { b = NULL; return true; }
|
|
||||||
virtual bool isOpen() const { return b != NULL; }
|
|
||||||
virtual void open(void *buf, unsigned size)
|
|
||||||
{ b = (upx_bytep) buf; b_size = size; }
|
|
||||||
|
|
||||||
virtual void write(const void *buf, int len);
|
|
||||||
|
|
||||||
off_t getBytesWritten() const { return bytes_written; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
upx_bytep b;
|
|
||||||
unsigned b_size;
|
|
||||||
unsigned b_pos;
|
|
||||||
off_t bytes_written;
|
|
||||||
};
|
|
||||||
#endif /* if 0 */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+34
-56
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,42 +25,34 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static //inline
|
static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) {
|
||||||
void initFilter(Filter *f, upx_byte *buf, unsigned buf_len)
|
|
||||||
{
|
|
||||||
f->buf = buf;
|
f->buf = buf;
|
||||||
f->buf_len = buf_len;
|
f->buf_len = buf_len;
|
||||||
// clear output parameters
|
// clear output parameters
|
||||||
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
|
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// get a FilterEntry
|
// get a FilterEntry
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
|
||||||
{
|
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
static unsigned char filter_map[256];
|
static unsigned char filter_map[256];
|
||||||
|
|
||||||
if (!done)
|
if (!done) {
|
||||||
{
|
|
||||||
// init the filter_map[]
|
// init the filter_map[]
|
||||||
assert(n_filters <= 254); // as 0xff means "empty slot"
|
assert(n_filters <= 254); // as 0xff means "empty slot"
|
||||||
memset(filter_map, 0xff, sizeof(filter_map));
|
memset(filter_map, 0xff, sizeof(filter_map));
|
||||||
for (int i = 0; i < n_filters; i++)
|
for (int i = 0; i < n_filters; i++) {
|
||||||
{
|
|
||||||
int filter_id = filters[i].id;
|
int filter_id = filters[i].id;
|
||||||
assert(filter_id >= 0 && filter_id <= 255);
|
assert(filter_id >= 0 && filter_id <= 255);
|
||||||
assert(filter_map[filter_id] == 0xff);
|
assert(filter_map[filter_id] == 0xff);
|
||||||
@@ -70,28 +62,25 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (id < 0 || id > 255)
|
if (id < 0 || id > 255)
|
||||||
return NULL;
|
return nullptr;
|
||||||
unsigned index = filter_map[id];
|
unsigned index = filter_map[id];
|
||||||
if (index == 0xff) // empty slot
|
if (index == 0xff) // empty slot
|
||||||
return NULL;
|
return nullptr;
|
||||||
assert(filters[index].id == id);
|
assert(filters[index].id == id);
|
||||||
return &filters[index];
|
return &filters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::isValidFilter(int filter_id) {
|
||||||
bool Filter::isValidFilter(int filter_id)
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
|
||||||
{
|
return fe != nullptr;
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);
|
|
||||||
return fe != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
bool Filter::isValidFilter(int filter_id, const int *allowed_filters) {
|
||||||
{
|
|
||||||
if (!isValidFilter(filter_id))
|
if (!isValidFilter(filter_id))
|
||||||
return false;
|
return false;
|
||||||
if (filter_id == 0)
|
if (filter_id == 0)
|
||||||
return true;
|
return true;
|
||||||
if (allowed_filters == NULL)
|
if (allowed_filters == nullptr)
|
||||||
return false;
|
return false;
|
||||||
while (*allowed_filters != FT_END)
|
while (*allowed_filters != FT_END)
|
||||||
if (*allowed_filters++ == filter_id)
|
if (*allowed_filters++ == filter_id)
|
||||||
@@ -99,30 +88,26 @@ bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// high level API
|
// high level API
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void Filter::init(int id_, unsigned addvalue_)
|
void Filter::init(int id_, unsigned addvalue_) {
|
||||||
{
|
|
||||||
this->id = id_;
|
this->id = id_;
|
||||||
initFilter(this, NULL, 0);
|
initFilter(this, nullptr, 0);
|
||||||
// clear input parameters
|
// clear input parameters
|
||||||
this->addvalue = addvalue_;
|
this->addvalue = addvalue_;
|
||||||
this->preferred_ctos = NULL;
|
this->preferred_ctos = nullptr;
|
||||||
// clear input/output parameters
|
// clear input/output parameters
|
||||||
this->cto = 0;
|
this->cto = 0;
|
||||||
this->n_mru = 0;
|
this->n_mru = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::filter(upx_byte *buf_, unsigned buf_len_) {
|
||||||
bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|
||||||
{
|
|
||||||
initFilter(this, buf_, buf_len_);
|
initFilter(this, buf_, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == NULL)
|
if (fe == nullptr)
|
||||||
throwInternalError("filter-1");
|
throwInternalError("filter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
return true;
|
return true;
|
||||||
@@ -138,10 +123,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|||||||
if (clevel != 1)
|
if (clevel != 1)
|
||||||
this->adler = upx_adler32(this->buf, this->buf_len);
|
this->adler = upx_adler32(this->buf, this->buf_len);
|
||||||
|
|
||||||
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
// OutputFile::dump("filter.dat", buf, buf_len);
|
// OutputFile::dump("filter.dat", buf, buf_len);
|
||||||
int r = (*fe->do_filter)(this);
|
int r = (*fe->do_filter)(this);
|
||||||
//printf("filter: %02x %d\n", fe->id, r);
|
NO_printf("filter: %02x %d\n", fe->id, r);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
throwFilterException();
|
throwFilterException();
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@@ -149,13 +134,11 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum) {
|
||||||
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
|
||||||
{
|
|
||||||
initFilter(this, buf_, buf_len_);
|
initFilter(this, buf_, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == NULL)
|
if (fe == nullptr)
|
||||||
throwInternalError("unfilter-1");
|
throwInternalError("unfilter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
return;
|
return;
|
||||||
@@ -166,24 +149,21 @@ void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
|||||||
if (!fe->do_unfilter)
|
if (!fe->do_unfilter)
|
||||||
throwInternalError("unfilter-2");
|
throwInternalError("unfilter-2");
|
||||||
|
|
||||||
//printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
int r = (*fe->do_unfilter)(this);
|
int r = (*fe->do_unfilter)(this);
|
||||||
//printf("unfilter: %02x %d\n", fe->id, r);
|
NO_printf("unfilter: %02x %d\n", fe->id, r);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
throwInternalError("unfilter-3");
|
throwInternalError("unfilter-3");
|
||||||
// OutputFile::dump("unfilter.dat", buf, buf_len);
|
// OutputFile::dump("unfilter.dat", buf, buf_len);
|
||||||
|
|
||||||
// verify checksum
|
// verify checksum
|
||||||
if (verify_checksum && clevel != 1)
|
if (verify_checksum && clevel != 1) {
|
||||||
{
|
|
||||||
if (this->adler != upx_adler32(this->buf, this->buf_len))
|
if (this->adler != upx_adler32(this->buf, this->buf_len))
|
||||||
throwInternalError("unfilter-4");
|
throwInternalError("unfilter-4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::verifyUnfilter() {
|
||||||
void Filter::verifyUnfilter()
|
|
||||||
{
|
|
||||||
// Note:
|
// Note:
|
||||||
// This verify is just because of complete paranoia that there
|
// This verify is just because of complete paranoia that there
|
||||||
// could be a hidden bug in the filter implementation, and
|
// could be a hidden bug in the filter implementation, and
|
||||||
@@ -193,21 +173,19 @@ void Filter::verifyUnfilter()
|
|||||||
// See also:
|
// See also:
|
||||||
// Packer::verifyOverlappingDecompression()
|
// Packer::verifyOverlappingDecompression()
|
||||||
|
|
||||||
//printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
if (clevel != 1)
|
if (clevel != 1)
|
||||||
unfilter(this->buf, this->buf_len, true);
|
unfilter(this->buf, this->buf_len, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_) {
|
||||||
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
|
||||||
{
|
|
||||||
// Note: must use const_cast here. This is fine as the scan
|
// Note: must use const_cast here. This is fine as the scan
|
||||||
// implementations (fe->do_scan) actually don't change the buffer.
|
// implementations (fe->do_scan) actually don't change the buffer.
|
||||||
upx_byte *b = const_cast<upx_byte *>(buf_);
|
upx_byte *b = const_cast<upx_byte *>(buf_);
|
||||||
initFilter(this, b, buf_len_);
|
initFilter(this, b, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == NULL)
|
if (fe == nullptr)
|
||||||
throwInternalError("scan-1");
|
throwInternalError("scan-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
return true;
|
return true;
|
||||||
@@ -218,9 +196,9 @@ bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
|||||||
if (!fe->do_scan)
|
if (!fe->do_scan)
|
||||||
throwInternalError("scan-2");
|
throwInternalError("scan-2");
|
||||||
|
|
||||||
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
int r = (*fe->do_scan)(this);
|
int r = (*fe->do_scan)(this);
|
||||||
//printf("filter: %02x %d\n", fe->id, r);
|
NO_printf("filter: %02x %d\n", fe->id, r);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
throwFilterException();
|
throwFilterException();
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
|||||||
+15
-21
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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,13 +25,9 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_FILTER_H
|
#ifndef UPX_FILTER_H__
|
||||||
#define __UPX_FILTER_H 1
|
#define UPX_FILTER_H__ 1
|
||||||
|
|
||||||
class Filter;
|
|
||||||
class FilterImp;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// A filter is a reversible operation that modifies a given
|
// A filter is a reversible operation that modifies a given
|
||||||
@@ -50,10 +46,12 @@ class FilterImp;
|
|||||||
// to absolute addresses so that the buffer compresses better.
|
// to absolute addresses so that the buffer compresses better.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class Filter
|
class Filter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Filter(int level) { clevel = level; init(); }
|
Filter(int level) {
|
||||||
|
clevel = level;
|
||||||
|
init();
|
||||||
|
}
|
||||||
void init(int id = 0, unsigned addvalue = 0);
|
void init(int id = 0, unsigned addvalue = 0);
|
||||||
|
|
||||||
bool filter(upx_byte *buf, unsigned buf_len);
|
bool filter(upx_byte *buf, unsigned buf_len);
|
||||||
@@ -67,8 +65,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
// Will be set by each call to filter()/unfilter().
|
// Will be set by each call to filter()/unfilter().
|
||||||
// Read-only afterwards.
|
// Read-only afterwards.
|
||||||
upx_byte *buf;
|
upx_byte *buf = nullptr;
|
||||||
unsigned buf_len;
|
unsigned buf_len = 0;
|
||||||
|
|
||||||
// Checksum of the buffer before applying the filter
|
// Checksum of the buffer before applying the filter
|
||||||
// or after un-applying the filter.
|
// or after un-applying the filter.
|
||||||
@@ -76,7 +74,7 @@ public:
|
|||||||
|
|
||||||
// Input parameters used by various filters.
|
// Input parameters used by various filters.
|
||||||
unsigned addvalue;
|
unsigned addvalue;
|
||||||
const int *preferred_ctos;
|
const int *preferred_ctos = nullptr;
|
||||||
|
|
||||||
// Input/output parameters used by various filters
|
// Input/output parameters used by various filters
|
||||||
unsigned char cto; // call trick offset
|
unsigned char cto; // call trick offset
|
||||||
@@ -96,7 +94,6 @@ private:
|
|||||||
int clevel; // compression level
|
int clevel; // compression level
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// We don't want a full OO interface here because of
|
// We don't want a full OO interface here because of
|
||||||
// certain implementation speed reasons.
|
// certain implementation speed reasons.
|
||||||
@@ -104,13 +101,11 @@ private:
|
|||||||
// This class is private to Filter - don't look.
|
// This class is private to Filter - don't look.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class FilterImp
|
class FilterImpl {
|
||||||
{
|
|
||||||
friend class Filter;
|
friend class Filter;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FilterEntry
|
struct FilterEntry {
|
||||||
{
|
|
||||||
int id; // 0 .. 255
|
int id; // 0 .. 255
|
||||||
unsigned min_buf_len;
|
unsigned min_buf_len;
|
||||||
unsigned max_buf_len;
|
unsigned max_buf_len;
|
||||||
@@ -128,7 +123,6 @@ private:
|
|||||||
static const int n_filters; // number of filters[]
|
static const int n_filters; // number of filters[]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+3
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
@@ -129,6 +129,7 @@ static int F(Filter *f)
|
|||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
|
UNUSED(noncalls2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
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
|
||||||
@@ -128,6 +128,7 @@ static int F(Filter *f)
|
|||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
|
UNUSED(noncalls2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
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
|
||||||
@@ -254,6 +254,7 @@ static int F(Filter *f)
|
|||||||
calls,noncalls,noncalls2,size,cto8);
|
calls,noncalls,noncalls2,size,cto8);
|
||||||
printf("CALL/JMP/JCC %d %d %d\n",wtally[0],wtally[1],wtally[2]);
|
printf("CALL/JMP/JCC %d %d %d\n",wtally[0],wtally[1],wtally[2]);
|
||||||
#endif
|
#endif
|
||||||
|
UNUSED(noncalls2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2017 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
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
|
||||||
@@ -129,6 +129,7 @@ static int F(Filter *f)
|
|||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
|
UNUSED(noncalls2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* filteri.cpp -- filter implementation (low-level)
|
/* filter_impl.cpp -- filter implementation (low-level)
|
||||||
|
|
||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
#include "filter.h"
|
#include "../filter.h"
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
umin(unsigned const a, unsigned const b)
|
umin(unsigned const a, unsigned const b)
|
||||||
@@ -45,20 +45,20 @@ umin(unsigned const a, unsigned const b)
|
|||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "filter/getcto.h"
|
#include "getcto.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// simple filters: calltrick / swaptrick / delta / ...
|
// simple filters: calltrick / swaptrick / delta / ...
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "filter/ct.h"
|
#include "ct.h"
|
||||||
#include "filter/sw.h"
|
#include "sw.h"
|
||||||
#include "filter/ctsw.h"
|
#include "ctsw.h"
|
||||||
|
|
||||||
#include "filter/sub8.h"
|
#include "sub8.h"
|
||||||
#include "filter/sub16.h"
|
#include "sub16.h"
|
||||||
#include "filter/sub32.h"
|
#include "sub32.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -68,25 +68,25 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x) (b[x] == 0xe8)
|
#define COND(b,x) (b[x] == 0xe8)
|
||||||
#define F f_cto32_e8_bswap_le
|
#define F f_cto32_e8_bswap_le
|
||||||
#define U u_cto32_e8_bswap_le
|
#define U u_cto32_e8_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e8_bswap_le
|
#define F s_cto32_e8_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
#define COND(b,x) (b[x] == 0xe9)
|
#define COND(b,x) (b[x] == 0xe9)
|
||||||
#define F f_cto32_e9_bswap_le
|
#define F f_cto32_e9_bswap_le
|
||||||
#define U u_cto32_e9_bswap_le
|
#define U u_cto32_e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e9_bswap_le
|
#define F s_cto32_e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||||
#define F f_cto32_e8e9_bswap_le
|
#define F f_cto32_e8e9_bswap_le
|
||||||
#define U u_cto32_e8e9_bswap_le
|
#define U u_cto32_e8e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e8e9_bswap_le
|
#define F s_cto32_e8e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -97,9 +97,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||||
#define F f_ctoj32_e8e9_bswap_le
|
#define F f_ctoj32_e8e9_bswap_le
|
||||||
#define U u_ctoj32_e8e9_bswap_le
|
#define U u_ctoj32_e8e9_bswap_le
|
||||||
#include "filter/ctoj.h"
|
#include "ctoj.h"
|
||||||
#define F s_ctoj32_e8e9_bswap_le
|
#define F s_ctoj32_e8e9_bswap_le
|
||||||
#include "filter/ctoj.h"
|
#include "ctoj.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -112,9 +112,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||||
#define F f_ctok32_e8e9_bswap_le
|
#define F f_ctok32_e8e9_bswap_le
|
||||||
#define U u_ctok32_e8e9_bswap_le
|
#define U u_ctok32_e8e9_bswap_le
|
||||||
#include "filter/ctok.h"
|
#include "ctok.h"
|
||||||
#define F s_ctok32_e8e9_bswap_le
|
#define F s_ctok32_e8e9_bswap_le
|
||||||
#include "filter/ctok.h"
|
#include "ctok.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
#undef COND2
|
#undef COND2
|
||||||
#undef COND1
|
#undef COND1
|
||||||
@@ -138,9 +138,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
|
|
||||||
#define F f_ctojr32_e8e9_bswap_le
|
#define F f_ctojr32_e8e9_bswap_le
|
||||||
#define U u_ctojr32_e8e9_bswap_le
|
#define U u_ctojr32_e8e9_bswap_le
|
||||||
#include "filter/ctojr.h"
|
#include "ctojr.h"
|
||||||
#define F s_ctojr32_e8e9_bswap_le
|
#define F s_ctojr32_e8e9_bswap_le
|
||||||
#include "filter/ctojr.h"
|
#include "ctojr.h"
|
||||||
|
|
||||||
#undef CONDU
|
#undef CONDU
|
||||||
#undef CONDF
|
#undef CONDF
|
||||||
@@ -158,9 +158,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||||
#define F f_ppcbxx
|
#define F f_ppcbxx
|
||||||
#define U u_ppcbxx
|
#define U u_ppcbxx
|
||||||
#include "filter/ppcbxx.h"
|
#include "ppcbxx.h"
|
||||||
#define F s_ppcbxx
|
#define F s_ppcbxx
|
||||||
#include "filter/ppcbxx.h"
|
#include "ppcbxx.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -168,9 +168,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
// database for use in class Filter
|
// database for use in class Filter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const FilterImp::FilterEntry FilterImp::filters[] = {
|
const FilterImpl::FilterEntry FilterImpl::filters[] = {
|
||||||
// no filter
|
// no filter
|
||||||
{ 0x00, 0, 0, NULL, NULL, NULL },
|
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
||||||
|
|
||||||
// 16-bit calltrick
|
// 16-bit calltrick
|
||||||
{ 0x01, 4, 0, f_ct16_e8, u_ct16_e8, s_ct16_e8 },
|
{ 0x01, 4, 0, f_ct16_e8, u_ct16_e8, s_ct16_e8 },
|
||||||
@@ -261,6 +261,6 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||||
};
|
};
|
||||||
|
|
||||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
const int FilterImpl::n_filters = TABLESIZE(filters);
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2004-2017 John F. Reiser
|
Copyright (C) 2004-2023 John F. Reiser
|
||||||
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
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+2
-2
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
|
|||||||
+50
-45
@@ -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-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2017 Laszlo Molnar
|
Copyright (C) 1996-2023 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
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
|
||||||
#include "packmast.h"
|
#include "packmast.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
#include "compress/compress.h" // upx_ucl_version_string()
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
static bool head_done = 0;
|
static bool head_done = 0;
|
||||||
|
|
||||||
|
// also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
|
||||||
#if defined(UPX_VERSION_GITREV)
|
#if defined(UPX_VERSION_GITREV)
|
||||||
const char gitrev[] = UPX_VERSION_GITREV;
|
const char gitrev[] = UPX_VERSION_GITREV;
|
||||||
#else
|
#else
|
||||||
@@ -53,7 +54,6 @@ void show_head(void)
|
|||||||
return;
|
return;
|
||||||
head_done = 1;
|
head_done = 1;
|
||||||
|
|
||||||
#define V(x) (strcmp(UPX_VERSION_STRING, UPX_VERSION_STRING4) ? UPX_VERSION_STRING : UPX_VERSION_STRING x)
|
|
||||||
fg = con_fg(f,FG_GREEN);
|
fg = con_fg(f,FG_GREEN);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" Ultimate Packer for eXecutables\n"
|
" Ultimate Packer for eXecutables\n"
|
||||||
@@ -67,10 +67,6 @@ void show_head(void)
|
|||||||
#if defined(UPX_VERSION_GITREV)
|
#if defined(UPX_VERSION_GITREV)
|
||||||
gitrev,
|
gitrev,
|
||||||
(sizeof(gitrev)-1 > 6 && gitrev[sizeof(gitrev)-2] == '+') ? '+' : ' ',
|
(sizeof(gitrev)-1 > 6 && gitrev[sizeof(gitrev)-2] == '+') ? '+' : ' ',
|
||||||
#elif (ACC_OS_DOS16 || ACC_OS_DOS32)
|
|
||||||
V("d"),
|
|
||||||
#elif (ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
|
||||||
V("w"),
|
|
||||||
#else
|
#else
|
||||||
UPX_VERSION_STRING,
|
UPX_VERSION_STRING,
|
||||||
#endif
|
#endif
|
||||||
@@ -112,7 +108,7 @@ struct PackerNames
|
|||||||
Entry names[64];
|
Entry names[64];
|
||||||
size_t names_count;
|
size_t names_count;
|
||||||
const options_t *o;
|
const options_t *o;
|
||||||
PackerNames() : names_count(0), o(NULL) { }
|
PackerNames() : names_count(0), o(nullptr) { }
|
||||||
void add(const Packer *p)
|
void add(const Packer *p)
|
||||||
{
|
{
|
||||||
p->assertPacker();
|
p->assertPacker();
|
||||||
@@ -125,8 +121,8 @@ struct PackerNames
|
|||||||
{
|
{
|
||||||
PackerNames *self = (PackerNames *) user;
|
PackerNames *self = (PackerNames *) user;
|
||||||
self->add(p);
|
self->add(p);
|
||||||
delete p; p = NULL;
|
delete p; p = nullptr;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
|
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
|
||||||
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
|
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
|
||||||
@@ -140,7 +136,7 @@ static void show_all_packers(FILE *f, int verbose)
|
|||||||
{
|
{
|
||||||
options_t o; o.reset();
|
options_t o; o.reset();
|
||||||
PackerNames pn; pn.o = &o;
|
PackerNames pn; pn.o = &o;
|
||||||
PackMaster::visitAllPackers(PackerNames::visit, NULL, &o, &pn);
|
PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn);
|
||||||
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname);
|
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname);
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
for (size_t i = 0; i < pn.names_count; ++i)
|
for (size_t i = 0; i < pn.names_count; ++i)
|
||||||
@@ -219,6 +215,7 @@ void show_help(int verbose)
|
|||||||
con_fprintf(f,"\nCompression tuning options:\n");
|
con_fprintf(f,"\nCompression tuning options:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
|
" --lzma try LZMA [slower but tighter than NRV]\n"
|
||||||
" --brute try all available compression methods & filters [slow]\n"
|
" --brute try all available compression methods & filters [slow]\n"
|
||||||
" --ultra-brute try even more compression variants [very slow]\n"
|
" --ultra-brute try even more compression variants [very slow]\n"
|
||||||
"\n");
|
"\n");
|
||||||
@@ -262,15 +259,6 @@ void show_help(int verbose)
|
|||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --8086 make compressed sys work on any 8086\n"
|
" --8086 make compressed sys work on any 8086\n"
|
||||||
"\n");
|
"\n");
|
||||||
#if 0
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
|
||||||
con_fprintf(f,"Options for linux/386\n");
|
|
||||||
fg = con_fg(f,fg);
|
|
||||||
con_fprintf(f,
|
|
||||||
" --script use /usr/local/lib/upx/upx[bd] as decompressor\n"
|
|
||||||
" --script=/path/upxX use path/upxX as decompressor\n"
|
|
||||||
"\n");
|
|
||||||
#endif
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options for ps1/exe:\n");
|
con_fprintf(f,"Options for ps1/exe:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
@@ -327,13 +315,13 @@ void show_help(int verbose)
|
|||||||
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
|
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
|
||||||
"");
|
"");
|
||||||
|
|
||||||
#if (DEBUG) || (TESTING)
|
#if DEBUG || TESTING
|
||||||
fg = con_fg(f,FG_RED);
|
fg = con_fg(f,FG_RED);
|
||||||
con_fprintf(f,"\nWARNING: this version is compiled with"
|
con_fprintf(f,"\nWARNING: this version is compiled with"
|
||||||
#if (DEBUG)
|
#if DEBUG
|
||||||
" -DDEBUG"
|
" -DDEBUG"
|
||||||
#endif
|
#endif
|
||||||
#if (TESTING)
|
#if TESTING
|
||||||
" -DTESTING"
|
" -DTESTING"
|
||||||
#endif
|
#endif
|
||||||
"\n");
|
"\n");
|
||||||
@@ -361,17 +349,17 @@ void show_license(void)
|
|||||||
" This program is distributed in the hope that it will be useful,\n"
|
" This program is distributed in the hope that it will be useful,\n"
|
||||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||||
" UPX License Agreement for more details.\n"
|
" UPX License Agreements for more details.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" You should have received a copy of the UPX License Agreement\n"
|
" You should have received a copy of the UPX License Agreements\n"
|
||||||
" along with this program; see the file LICENSE.\n"
|
" along with this program; see the files COPYING and LICENSE.\n"
|
||||||
" If not, visit one of the following pages:\n"
|
" If not, visit one of the following pages:\n"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
int fg = con_fg(f,FG_CYAN);
|
int fg = con_fg(f,FG_CYAN);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" http://upx.sourceforge.net\n"
|
" https://upx.github.io\n"
|
||||||
" http://www.oberhumer.com/opensource/upx/\n"
|
" https://www.oberhumer.com/opensource/upx/\n"
|
||||||
);
|
);
|
||||||
(void)con_fg(f,FG_ORANGE);
|
(void)con_fg(f,FG_ORANGE);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
@@ -389,47 +377,64 @@ void show_license(void)
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void show_version(int x)
|
void show_version(bool one_line)
|
||||||
{
|
{
|
||||||
FILE *fp = stdout;
|
FILE *fp = stdout;
|
||||||
const char *v;
|
const char *v;
|
||||||
UNUSED(x);
|
|
||||||
UNUSED(v);
|
|
||||||
|
|
||||||
fprintf(fp, "upx %s\n", UPX_VERSION_STRING
|
#if defined(UPX_VERSION_GIT_DESCRIBE)
|
||||||
#if defined(UPX_VERSION_GITREV)
|
fprintf(fp, "upx %s\n", UPX_VERSION_GIT_DESCRIBE);
|
||||||
"-git-" UPX_VERSION_GITREV
|
#elif defined(UPX_VERSION_GITREV)
|
||||||
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING "-git-" UPX_VERSION_GITREV);
|
||||||
|
#else
|
||||||
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||||
#endif
|
#endif
|
||||||
);
|
if (one_line)
|
||||||
|
return;
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
v = upx_nrv_version_string();
|
v = upx_nrv_version_string();
|
||||||
if (v != NULL && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "NRV data compression library %s\n", v);
|
fprintf(fp, "NRV data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
v = upx_ucl_version_string();
|
v = upx_ucl_version_string();
|
||||||
if (v != NULL && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "UCL data compression library %s\n", v);
|
fprintf(fp, "UCL data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
v = upx_zlib_version_string();
|
v = upx_zlib_version_string();
|
||||||
if (v != NULL && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "zlib data compression library %s\n", v);
|
fprintf(fp, "zlib data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
v = upx_lzma_version_string();
|
v = upx_lzma_version_string();
|
||||||
if (v != NULL && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "LZMA SDK version %s\n", v);
|
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
fprintf(fp, "Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\n");
|
#if (WITH_ZSTD)
|
||||||
fprintf(fp, "Copyright (C) 1996-2017 Laszlo Molnar\n");
|
v = upx_zstd_version_string();
|
||||||
fprintf(fp, "Copyright (C) 2000-2017 John F. Reiser\n");
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "Copyright (C) 2002-2017 Jens Medoch\n");
|
fprintf(fp, "zstd data compression library %s\n", v);
|
||||||
|
#endif
|
||||||
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
||||||
|
#endif
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n");
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2023 Laszlo Molnar\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2000-2023 John F. Reiser\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2002-2023 Jens Medoch\n");
|
||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
|
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n");
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
||||||
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
// see vendor/zstd/LICENSE; main author is Yann Collet
|
||||||
|
fprintf(fp, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
|
||||||
|
#endif
|
||||||
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname);
|
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user