Compare commits
577 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3757579ffc | |||
| 2962dc351b | |||
| c04c685469 | |||
| 72c9769953 | |||
| 42759b94bd | |||
| aa9e69f03e | |||
| 0f3939df15 | |||
| 62265a1bc9 | |||
| 76b2cec8ee | |||
| 3d82f0cfe1 | |||
| e5546bc8b0 | |||
| 6fc0a00ac8 | |||
| 3e5ba5c064 | |||
| 4c32a8e3d4 | |||
| 2ea316d754 | |||
| 548227a55b | |||
| a831a20910 | |||
| 811f66de84 | |||
| 84d806328b | |||
| 285d4c4c65 | |||
| 8506f5b17c | |||
| a87fd56b3e | |||
| f0cb30e2b9 | |||
| 038743c694 | |||
| 0e6cef99a0 | |||
| 92c925fe95 | |||
| 4562d5459d | |||
| 8393ded1b3 | |||
| b0dc483165 | |||
| 3c0ca81311 | |||
| 157a63a023 | |||
| 80e22a7e38 | |||
| ddf2da3d76 | |||
| 0e6478a60f | |||
| aed2c085b8 | |||
| a7592b2ca2 | |||
| 265c100845 | |||
| 84e8288f61 | |||
| c69b4561fb | |||
| 6db0af8d04 | |||
| 842d2cbb0d | |||
| 9fb64ded10 | |||
| 9d26713b1a | |||
| eb3c55b5cb | |||
| 896596f672 | |||
| e4de14612f | |||
| 1d2b276425 | |||
| 35c6a200ad | |||
| 90a7faa15e | |||
| 91f5fe1c0e | |||
| d48a7d303d | |||
| bb816f0c74 | |||
| 93abe97ea5 | |||
| 97cf29ffbb | |||
| ed35613d64 | |||
| f5ec8363b4 | |||
| 87956de092 | |||
| 0f9315383c | |||
| 3538d796a7 | |||
| 24f3824524 | |||
| 70b20d7d89 | |||
| 7b21a0620b | |||
| 3949af6d3c | |||
| d1f62e3ab4 | |||
| 6e644fa480 | |||
| 5bef968068 | |||
| 543cfe0a73 | |||
| 3ba91b8072 | |||
| a27a9e6000 | |||
| 7e839e6962 | |||
| 809a1b3dae | |||
| 9b80628f84 | |||
| a21a006fe9 | |||
| 54d16a458a | |||
| cfc5f42ef2 | |||
| e3d24238e4 | |||
| 56e7b36959 | |||
| f29791470f | |||
| 52d9b53b74 | |||
| 839a78f2e0 | |||
| 680ce0a7af | |||
| 06b0de9c77 | |||
| 76b0b7b1ae | |||
| fabda4df3a | |||
| fdcdaf596a | |||
| be44cefbe7 | |||
| c1050e624b | |||
| ae6d3b9bff | |||
| 25aa0e2e46 | |||
| 8f7578eef1 | |||
| 29ce4807fb | |||
| 41f6945be1 | |||
| 718ec468ff | |||
| d429801498 | |||
| 024091e6b5 | |||
| d849e9de98 | |||
| c0e40da2ab | |||
| dff3766501 | |||
| 2767ec54e1 | |||
| ac72c02793 | |||
| 69c51eee4d | |||
| ff5a4eeb96 | |||
| b48f870701 | |||
| 10807ebdc2 | |||
| 5d649f83ec | |||
| 65b25adceb | |||
| d615985b8a | |||
| b019440980 | |||
| 38ed4b2017 | |||
| 2ad0d51226 | |||
| e4a611bcae | |||
| f3728d99b9 | |||
| b87f60a917 | |||
| 28f26da6ab | |||
| d3e780d617 | |||
| d549c2b5c9 | |||
| f310ce376e | |||
| 553fc9b1fb | |||
| 6dde9f7dc0 | |||
| 3dca1175e5 | |||
| 09c5e38322 | |||
| fe6f1f0bb6 | |||
| 250c656b9e | |||
| 9a0b5b65b8 | |||
| 57b2fb4c62 | |||
| 099c3d829e | |||
| a1a6d02b6f | |||
| f2ad7fb9c4 | |||
| 1bcf709fcf | |||
| 47fc230893 | |||
| be05d85570 | |||
| f598fa13a9 | |||
| 568859d16f | |||
| b5ed0a637b | |||
| 17eff0aed4 | |||
| 0a3f048eed | |||
| 3cde897557 | |||
| 0500e7d016 | |||
| 778663ae69 | |||
| 636cefb9f3 | |||
| 1236776aa2 | |||
| 51a6a5cca5 | |||
| 3326c86e91 | |||
| b0dbc3fe39 | |||
| decc1efb74 | |||
| 2cf1c32d18 | |||
| fc6e3840b7 | |||
| 5e85c1a11b | |||
| 468bfce599 | |||
| 1e6e4043ed | |||
| 67564513d2 | |||
| ed2633bf95 | |||
| 3e70021406 | |||
| bf8dd31914 | |||
| d4e94f5086 | |||
| ae77fd60bb | |||
| e79c790264 | |||
| 46029bb8a0 | |||
| f74c225338 | |||
| c479fe32b3 | |||
| dc23ee0ad2 | |||
| a5c32db01b | |||
| d7142312c9 | |||
| 283ab0e7ea | |||
| b6dd61cea8 | |||
| 11970d276d | |||
| d618716ec1 | |||
| 4f0f977f04 | |||
| 2c4b1d8a8c | |||
| b2810c6deb | |||
| ceb2b56b71 | |||
| d14fa5f8a4 | |||
| 79263a52ac | |||
| ecb3f83e83 | |||
| f6aedb35ce | |||
| 3b7d25ac49 | |||
| e964d4acf3 | |||
| e306085b81 | |||
| b094ad4f2b | |||
| 19c6b969ab | |||
| acfda848cd | |||
| 52400e2561 | |||
| f62576a2be | |||
| 19bf9f59e9 | |||
| fadf7cfc7b | |||
| ec0c9399fa | |||
| 37b923245d | |||
| 38a676f6f7 | |||
| cd1df6f6b1 | |||
| 4a24fe8c53 | |||
| 6dac3dd248 | |||
| 37d393cbc8 | |||
| 27f155374a | |||
| 8102137ad7 | |||
| 9c46f4653f | |||
| 29b4752d0e | |||
| 2724039c09 | |||
| 6ae4e88475 | |||
| facabd68d7 | |||
| 18f043015e | |||
| ab259a1af9 | |||
| 1dd96a7628 | |||
| 1ee7ecb1f0 | |||
| 67548a4d9a | |||
| 9fbe95ad48 | |||
| 91c15b2475 | |||
| c9550b48d8 | |||
| a1d090a6fd | |||
| 4870765e1b | |||
| d8be2ed276 | |||
| 2b371e99bd | |||
| 005e39871b | |||
| 96dd9eeb44 | |||
| 65b06f6046 | |||
| 0515be4334 | |||
| e32de83758 | |||
| e767461f65 | |||
| 632c7c4826 | |||
| 7f9d381c7b | |||
| 4d5d6661d5 | |||
| b0b87eda02 | |||
| f63a673a8b | |||
| 290dd0c5d2 | |||
| 194bf2b852 | |||
| d6d5e7ae3d | |||
| 39a6cc4b5f | |||
| a24de15060 | |||
| eb021accd1 | |||
| 98a77dde00 | |||
| 854988bc5f | |||
| bfeed2ab9a | |||
| d11fc71e79 | |||
| f1703fa322 | |||
| 06675acc67 | |||
| 57ad6bc37d | |||
| 0192b0b7e4 | |||
| 3b098b845a | |||
| ac398f1ffe | |||
| 92dfb9c83c | |||
| 38d6cb090c | |||
| e93172bd33 | |||
| 30fcca4b64 | |||
| 4f6320d3aa | |||
| 62dbf8485f | |||
| 9331ed39d4 | |||
| 35dd9cfd22 | |||
| 0ac6c36af2 | |||
| 3c4b959f78 | |||
| a00687b092 | |||
| bb6b087862 | |||
| bfb438dc89 | |||
| cd3f69c290 | |||
| d54315392e | |||
| cfa8107ab9 | |||
| f4e5b29708 | |||
| d65fea1147 | |||
| 25a3c109c1 | |||
| b526eed346 | |||
| 59c6a71b72 | |||
| c7a2a0faa1 | |||
| bfb5ea50a9 | |||
| 149d84edca | |||
| 7636abc158 | |||
| 6eace187e7 | |||
| dd1838a7eb | |||
| dd928cf956 | |||
| 38be230467 | |||
| 1f747a28a9 | |||
| 1a7732b285 | |||
| f8ea416a4d | |||
| b9bf81d548 | |||
| 8975e2a6b5 | |||
| 394cd77bec | |||
| a9ac4b5e23 | |||
| 10e759f1f1 | |||
| 777d4f5279 | |||
| c65c882ecc | |||
| a66ee9fafd | |||
| 757401dd0c | |||
| 11e3770864 | |||
| fbb317e9c8 | |||
| 9d7698a359 | |||
| 44fd11f4dd | |||
| 8779113131 | |||
| 26cfd0a616 | |||
| 75e153dd99 | |||
| fa364d6ea3 | |||
| 13e5c13695 | |||
| 43b3b54197 | |||
| 3a16d4a12e | |||
| 50fc9235de | |||
| 70287d3c49 | |||
| 41e9f7985f | |||
| c3327977da | |||
| 905bfacf44 | |||
| 053e95033f | |||
| 5a1203be0d | |||
| 745fef7425 | |||
| c9d625a237 | |||
| 334731f56b | |||
| d5e7672a45 | |||
| e702aa0252 | |||
| 2684e815e0 | |||
| efbc93229a | |||
| 05539ad5b6 | |||
| 670aae2e11 | |||
| e6ff68dc2c | |||
| 641b116f04 | |||
| f81f7194ed | |||
| 161d20e614 | |||
| fc4dcd46db | |||
| 891dc87064 | |||
| b866631448 | |||
| 672d69c68a | |||
| 507c31ec14 | |||
| 65cc40bdda | |||
| 067895fa5f | |||
| 3f7f26c74b | |||
| 9a6b5940cf | |||
| 828f4a63bf | |||
| 707fb55625 | |||
| 8d41ae09c8 | |||
| 7ec0faca1e | |||
| 300fa29446 | |||
| 6981f7b3ae | |||
| 682a1e97e4 | |||
| 1d71dd3851 | |||
| 5edfda46e5 | |||
| d7754a97c7 | |||
| c79aa6ad8a | |||
| 525e091472 | |||
| 16f6de677d | |||
| 12c36bab6c | |||
| c429859cbf | |||
| dc76b2af97 | |||
| b75e7687f4 | |||
| ece5af2895 | |||
| 1aaa33552e | |||
| f622871eb0 | |||
| 060b01260d | |||
| 871f8a4793 | |||
| c54e03d0f2 | |||
| aaf3f75990 | |||
| 512a26cee4 | |||
| b4a793ed26 | |||
| 5d2c74008e | |||
| 7fafc68940 | |||
| d1af2af499 | |||
| a5206eb696 | |||
| 1ff0d137ab | |||
| 07aa65b55e | |||
| 0fadddec65 | |||
| 1bebe53cef | |||
| 43019c744c | |||
| c585774162 | |||
| 75e87a58da | |||
| 19e84fea62 | |||
| db39f9c4dc | |||
| dae45ae0d4 | |||
| efeffc6e01 | |||
| ebf0f2f68a | |||
| 09bd1d8c40 | |||
| 40653e40a4 | |||
| b3e4efbabe | |||
| 279101d464 | |||
| f571feee72 | |||
| 900afd1c8c | |||
| 08a72d5251 | |||
| 736a6cd955 | |||
| 75ce5e5df3 | |||
| eaf2143162 | |||
| f0bdb8dea1 | |||
| 60093cfff6 | |||
| 56bb7b53cb | |||
| 0cffeca102 | |||
| 937d4462ca | |||
| db5a39572c | |||
| ecc9c67e1f | |||
| 0901ce1b68 | |||
| be6e77379a | |||
| 726f5de778 | |||
| 98b835e0a7 | |||
| 04ffb641a6 | |||
| 1b7233b673 | |||
| eaa0f33473 | |||
| c03b382d61 | |||
| e633694255 | |||
| 278b25bad2 | |||
| f89f0838dc | |||
| b1729e3bcf | |||
| d1ab85a1a6 | |||
| 7f5b64c91a | |||
| 78b68283c4 | |||
| 9e3b1c9f8a | |||
| 5dc54c7adc | |||
| 320e5b850f | |||
| d8395d8c42 | |||
| a20c5a1e7f | |||
| 3bdfcaa541 | |||
| 7b2faf2016 | |||
| 42902dabac | |||
| 14521eb6dd | |||
| b9533f409c | |||
| 4df68aafd2 | |||
| c72ceaa979 | |||
| 8ac79ca0ad | |||
| e0bfaf1028 | |||
| b361b91ec7 | |||
| b5d1eba4c1 | |||
| ba447344d6 | |||
| 7b68aa7bdc | |||
| 5d15e57294 | |||
| 0bf8ff151e | |||
| 06fae05910 | |||
| f68ac8155b | |||
| 15484aa296 | |||
| 5b113a5041 | |||
| 1320e3efdb | |||
| d32f447bda | |||
| b74c4e4ac1 | |||
| 35333403ef | |||
| a627648249 | |||
| 127fd095e7 | |||
| f8934c09ff | |||
| 7a09c88e30 | |||
| 17526d1132 | |||
| ff7939c1c0 | |||
| 96c196b1be | |||
| adb0ca8250 | |||
| fa56a1d9cd | |||
| 3d691645a4 | |||
| e1edc5f50a | |||
| 4a8efd2e2f | |||
| 8d364c82e2 | |||
| c5059231dc | |||
| f584c91386 | |||
| b8d9c2b755 | |||
| 163377d1a0 | |||
| 8944e90175 | |||
| 33cdcb0e82 | |||
| ec870a5aeb | |||
| 0653bb5a72 | |||
| 43b6ff29e3 | |||
| a444a8a704 | |||
| 3fa18c1799 | |||
| 19147963b9 | |||
| 5056215a1f | |||
| 340b7614e2 | |||
| 8a1bd67a20 | |||
| a094df7b55 | |||
| cc893dfc11 | |||
| 8ef17da082 | |||
| 7993e619cd | |||
| 1ab8d5fb3f | |||
| 213ac3ac73 | |||
| 0a8876443a | |||
| f37a3bb9bb | |||
| 2632342f44 | |||
| 8efcf6f099 | |||
| 58343fc78d | |||
| 6c41a4c9c8 | |||
| 334be287fc | |||
| aa050e0001 | |||
| cc994326a0 | |||
| 58de07629e | |||
| 9f830e0c41 | |||
| c52d302f07 | |||
| 44049ecf30 | |||
| e1b5904196 | |||
| 88e692791a | |||
| f00667ad7d | |||
| 696d0eec64 | |||
| 513b00a30e | |||
| 0cb0dbf6d8 | |||
| 9f00515da4 | |||
| 72f31787f6 | |||
| cd686cb1d9 | |||
| d9657e9831 | |||
| 72f3e9b25a | |||
| 811b15a5b3 | |||
| ab00825f37 | |||
| e86d9179aa | |||
| 26d8e9c4c5 | |||
| 5f3ebc8a7f | |||
| 425b1b44bc | |||
| 39442e6282 | |||
| 99575e1010 | |||
| 64aa7540e2 | |||
| 3ff5dbd179 | |||
| e25d04fb12 | |||
| dd1d5a92d2 | |||
| c6e0aad40b | |||
| 99b795ceaa | |||
| 33dc60df26 | |||
| 619aeb54ff | |||
| 77ba43328b | |||
| 01a30752c7 | |||
| e56b748435 | |||
| bb4cbdff44 | |||
| 0b47e474a7 | |||
| 8e85680eb4 | |||
| fefce0d5c4 | |||
| 0ac3cb2329 | |||
| 708ab1dcd7 | |||
| 9b87ddb621 | |||
| 5dc4eb4b03 | |||
| a203c72281 | |||
| 6cf85cee6e | |||
| 1eb6a40fdd | |||
| 1bed77e4d3 | |||
| f2a68023fa | |||
| 8ccffc40e3 | |||
| dd8c1d0441 | |||
| f9f28ff176 | |||
| 3649041195 | |||
| c23c7a9379 | |||
| 9934e33b99 | |||
| 9e75fdda66 | |||
| d873a26f41 | |||
| 91aa5b55ab | |||
| 3f460a76ce | |||
| 7256ea3b32 | |||
| 4cdf77e16f | |||
| d89813e911 | |||
| 7c57b10cae | |||
| 8d1a98e03b | |||
| 65a2da4b40 | |||
| 02f6786b2a | |||
| 9da4f7a6dc | |||
| 510505a85c | |||
| 741cb3a136 | |||
| 9f5d67e27c | |||
| 93c6496ba8 | |||
| 779b648c5f | |||
| 9d5e06232d | |||
| b221c44466 | |||
| 665296f7cf | |||
| 39778d5f47 | |||
| 0af9bbb623 | |||
| fdec47a83d | |||
| 7ff913bbd2 | |||
| 94775bef9f | |||
| 3cf102334f | |||
| 627e733a30 | |||
| d31b80da5b | |||
| eb231b65f3 | |||
| 59e3b1f98d | |||
| 8b174bb272 | |||
| 4199a44bef | |||
| 777392c0fe | |||
| ede1fec5e7 | |||
| 16de3e78a5 | |||
| d7508d8c09 | |||
| 2a136c1c1d | |||
| 2578102be9 | |||
| dadee7acfb | |||
| 28f0bb4e11 | |||
| 824c8a8efb | |||
| 37f27a1262 | |||
| 2b8a7a492a | |||
| db56bbb11b | |||
| 82d26f04a4 | |||
| 5045f7eb42 | |||
| 82a6ccac4d | |||
| 2d74298001 | |||
| ce21254ed2 | |||
| 874250fe49 | |||
| c8a3acbba8 | |||
| 81e11987a2 | |||
| 668cefec2f | |||
| 212bc04257 | |||
| db401fd05e | |||
| bebe72481c | |||
| 2b9e83256d | |||
| 5763518cce | |||
| 3e4c5bab72 | |||
| bce109ab54 |
+18
-19
@@ -1,28 +1,27 @@
|
|||||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
|
||||||
#
|
#
|
||||||
# for clang-format-10.0.1 from https://github.com/upx/upx-stubtools/releases
|
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||||
---
|
---
|
||||||
BasedOnStyle: LLVM
|
BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -4
|
|
||||||
#AlignConsecutiveAssignments: true
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
ColumnLimit: 100
|
ColumnLimit: 100
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
|
---
|
||||||
|
# settings for C and C++
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignConsecutiveMacros: AcrossComments
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
AttributeMacros:
|
||||||
|
- DELETED_FUNCTION
|
||||||
|
- XSPAN_DELETED_FUNCTION
|
||||||
|
- may_throw
|
||||||
|
EmptyLineBeforeAccessModifier: Leave
|
||||||
|
# IndentPPDirectives: AfterHash # TODO later
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
SpaceAfterCStyleCast: true
|
SpaceAfterCStyleCast: true
|
||||||
Standard: Cpp03
|
Standard: Cpp03
|
||||||
StatementMacros: [
|
StatementMacros:
|
||||||
ACCCHK_ASSERT,
|
- CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
ACCCHK_ASSERT_IS_SIGNED_T,
|
|
||||||
ACCCHK_ASSERT_IS_UNSIGNED_T,
|
|
||||||
ACCCHK_ASSERT_SIGN_T,
|
|
||||||
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,
|
|
||||||
]
|
|
||||||
...
|
...
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-assignment-in-if-condition,
|
||||||
|
-bugprone-branch-clone,
|
||||||
|
-bugprone-casting-through-void,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-empty-catch,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-inc-dec-in-conditions,
|
||||||
|
-bugprone-macro-parentheses,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-sizeof-expression,
|
||||||
|
-bugprone-suspicious-include,
|
||||||
|
-bugprone-suspicious-memory-comparison,
|
||||||
|
-bugprone-suspicious-string-compare,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-optin.performance.Padding,
|
||||||
|
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||||
|
-clang-analyzer-security.insecureAPI.rand,
|
||||||
|
-clang-analyzer-security.insecureAPI.strcpy,
|
||||||
|
clang-diagnostic-*,
|
||||||
|
performance-*,
|
||||||
|
-performance-avoid-endl,
|
||||||
|
-performance-enum-size,
|
||||||
|
-performance-no-int-to-ptr,
|
||||||
|
-performance-unnecessary-value-param,
|
||||||
|
FormatStyle: file
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
InheritParentConfig: false
|
||||||
|
...
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clangd from https://clangd.llvm.org/
|
||||||
|
---
|
||||||
|
# treat *.h files as C++ source code
|
||||||
|
If:
|
||||||
|
PathMatch: src/.*\.h
|
||||||
|
PathExclude: vendor/.*
|
||||||
|
CompileFlags:
|
||||||
|
Add:
|
||||||
|
- -xc++
|
||||||
|
---
|
||||||
|
# C++ flags
|
||||||
|
If:
|
||||||
|
PathMatch: [ src/.*\.h, src/.*\.cpp ]
|
||||||
|
PathExclude: vendor/.*
|
||||||
|
CompileFlags:
|
||||||
|
Add:
|
||||||
|
- -std=gnu++17
|
||||||
|
# -std=gnu++20 # requires clangd >= 11.0
|
||||||
|
# -std=gnu++23 # requires clangd >= 18.0
|
||||||
|
---
|
||||||
|
# common flags for all C/C++ files
|
||||||
|
If:
|
||||||
|
PathMatch: [ src/.*\.h, src/.*\.c, src/.*\.cpp ]
|
||||||
|
PathExclude: vendor/.*
|
||||||
|
CompileFlags:
|
||||||
|
Add:
|
||||||
|
# see https://github.com/clangd/clangd/issues/1038 : Support deterministic relative include path
|
||||||
|
- -Ivendor
|
||||||
|
- -I../vendor
|
||||||
|
- -I../../vendor
|
||||||
|
- -DDEBUG
|
||||||
|
- -fno-strict-aliasing
|
||||||
|
- -fno-strict-overflow
|
||||||
|
- -funsigned-char
|
||||||
|
Diagnostics:
|
||||||
|
Includes:
|
||||||
|
# IgnoreHeader: A list of regexes. Include Cleaner will not produce diagnostics
|
||||||
|
# for headers whose path is a suffix match for any of these.
|
||||||
|
IgnoreHeader:
|
||||||
|
- src/.*\.h
|
||||||
|
UnusedIncludes: None
|
||||||
|
...
|
||||||
+3
-2
@@ -1,3 +1,4 @@
|
|||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
# see https://editorconfig.org/
|
# see https://editorconfig.org/
|
||||||
|
|
||||||
root = true
|
root = true
|
||||||
@@ -14,8 +15,8 @@ trim_trailing_whitespace = true
|
|||||||
indent_size = 8
|
indent_size = 8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[*.S]
|
[{*.asm,*.S}]
|
||||||
indent_size = 8
|
indent_size = 8
|
||||||
|
|
||||||
[*.yml]
|
[{*.yaml,*.yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
+33
-7
@@ -1,10 +1,36 @@
|
|||||||
# make GitHub language detection more accurate, see https://github.com/github/linguist
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# see https://github.com/github-linguist/linguist
|
||||||
|
#
|
||||||
|
# HINT: check settings with
|
||||||
|
# git ls-files | git check-attr --stdin --all
|
||||||
|
# git ls-files --eol
|
||||||
|
|
||||||
src/*.h linguist-language=C++
|
# disable all line ending conversions
|
||||||
src/*/*.h linguist-language=C++
|
* -text
|
||||||
|
|
||||||
src/stub/**/*.ash linguist-language=Assembly
|
#
|
||||||
src/stub/**/*.asm linguist-language=Assembly
|
# tell diff tools that these files are generated automatically
|
||||||
src/stub/**/*.S linguist-language=Assembly
|
#
|
||||||
|
|
||||||
src/stub/tmp/** linguist-vendored
|
/doc/upx.1 linguist-generated
|
||||||
|
/doc/upx-doc.* linguist-generated
|
||||||
|
|
||||||
|
/src/stub/*.h linguist-generated
|
||||||
|
/src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated
|
||||||
|
/src/stub/tmp/** linguist-generated
|
||||||
|
|
||||||
|
/misc/podman/*/packages*.txt linguist-generated
|
||||||
|
/misc/testsuite/*expected_sha256sums* linguist-generated
|
||||||
|
|
||||||
|
#
|
||||||
|
# make GitHub language detection more accurate
|
||||||
|
#
|
||||||
|
|
||||||
|
/src/*.h linguist-language=C++
|
||||||
|
/src/*/*.h linguist-language=C++
|
||||||
|
|
||||||
|
/src/stub/**/*.ash linguist-language=Assembly
|
||||||
|
/src/stub/**/*.asm linguist-language=Assembly
|
||||||
|
/src/stub/**/*.S linguist-language=Assembly
|
||||||
|
|
||||||
|
/src/stub/tmp/** linguist-vendored
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
* @markus-oberhumer @jreiser
|
||||||
|
|
||||||
|
/src/p_lx_* @jreiser
|
||||||
|
/src/p_mach* @jreiser
|
||||||
|
/src/p_unix* @jreiser
|
||||||
|
/src/p_vmlin* @jreiser
|
||||||
|
|
||||||
|
/src/stub/src/*bsd.* @jreiser
|
||||||
|
/src/stub/src/*darwin.* @jreiser
|
||||||
|
/src/stub/src/*linux.* @jreiser
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
version: 2
|
|
||||||
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: 'github-actions'
|
|
||||||
directory: '/'
|
|
||||||
schedule:
|
|
||||||
# Check for updates to GitHub Actions every weekday
|
|
||||||
interval: 'daily'
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
|
|
||||||
|
|
||||||
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 ./misc/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-20210104")
|
|
||||||
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/64 )
|
|
||||||
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
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
|
|
||||||
|
|
||||||
#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")
|
|
||||||
chmod() {
|
|
||||||
gchmod "$@"
|
|
||||||
}
|
|
||||||
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 grep -E -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 grep -E -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
|
|
||||||
elif grep -E -q '^PRETTY_NAME="?Ubuntu 20\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
x86_64-w64-mingw32-gcc-9)
|
|
||||||
export upx_EXTRA_CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1"
|
|
||||||
export upx_EXTRA_LDFLAGS="-static"
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine64"
|
|
||||||
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
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
case $BM_C in
|
|
||||||
clang | clang-m?? | clang-[6789][0-9][0-9]-m?? | clang-1[0-1][0-9][0-9]-m??)
|
|
||||||
CC="clang"; CXX="clang++" ;; # standard system compiler
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
case $BM_C in
|
|
||||||
clang | clang-m?? | clang-3.4-m??)
|
|
||||||
CC="clang"; CXX="clang++" ;; # standard system compiler
|
|
||||||
clang-[3456].[0-9]-m??)
|
|
||||||
v=${BM_C:6:3}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
clang-[789]-m??)
|
|
||||||
v=${BM_C:6:1}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
clang-1[0-9]-m??)
|
|
||||||
v=${BM_C:6:2}; 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-[56789]-m?? | gcc-[56789]-mx32)
|
|
||||||
v=${BM_C:4:1}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
gcc-1[0-9]-m?? | gcc-1[0-9]-mx32)
|
|
||||||
v=${BM_C:4:2}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
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.11)
|
|
||||||
|
|
||||||
# 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 github 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.11")
|
|
||||||
[[ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
########## 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="\
|
|
||||||
e697578691a81e9d4bae7d32ea1f2e83c48956d6910d0306761e484dc3c07e18 *amd64-linux.elf/upx-3.91
|
|
||||||
6b54df3465da21601619d973b618cf45f695e8511f8d9c88d65f8efc1e347512 *amd64-linux.elf/upx-3.95
|
|
||||||
939e9058b5abec32f27588474ad334d8d05a9a8515e75dc417d397c6de74d02a *amd64-win64.pe/upx-3.95.exe
|
|
||||||
290cf727b3944db22fb1618d0e36d06659126d759a06fd0a5ffb397927d34f31 *arm-linux.elf/upx-3.95
|
|
||||||
4c488f100a589aace7e52a1f49982b618662ed2227e66a1e8c9699c9969ccedc *arm-wince.pe/upx-3.91.exe
|
|
||||||
b5da1b05cfe70c4d8dc169d8e27bfd8d95f92cc2c7307f907a7bc561e3523dab *arm64-linux.elf/upx-3.95
|
|
||||||
56abe47901f0e4fb207c3c19d21334664229081391d6df7e5e5c81b97c57419e *armeb-linux.elf/upx-3.91
|
|
||||||
d0712d61d08a6e7161a9ff2dc933888199705fcf194c9a96350d75774c5a6a62 *armeb-linux.elf/upx-3.95
|
|
||||||
bb56e464921ad806bc72308f85d42ea1b4f6715983ecdb9415b1d525f5e3ec9c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
7adf07236d7a36099122edeba72534944f7f0cab36f110169f3b5755f48bad76 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
590b4b75ad6fc076440bf7afc9261ff1e5e3efeec84c5cd81243aec2b0b5274d *i386-linux.elf/upx-3.91
|
|
||||||
0dfda4fbe5bd260f1592649eb564bb28ee768413e1c7fe3a678d8d7b025edcea *i386-linux.elf/upx-3.95
|
|
||||||
e3f98f4c2d0473b11fedd966e2fa184c0cf7e49a46fcbd5705387f9f2b191106 *i386-win32.pe/upx-3.91.exe
|
|
||||||
38c37ec2351783a48d4cce3f240bbf6a31331f9d9bd86f77cee468ff179cf58c *i386-win32.pe/upx-3.95.exe
|
|
||||||
ac331450fd0609f0f47a5012156a13d06dcabdc8ba58d5a7810dee6f17fda123 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
7483078331cbfc32f6150929c244f4cc0a34282f60332da37bcfdbe41c1014cb *mips-linux.elf/upx-3.95
|
|
||||||
23fe3c6320f3cebce8027ec5597c228b9f160407e1e0e8a810e2ae6be8dc0d43 *mipsel-linux.elf/upx-3.91
|
|
||||||
3279bdf38a14623c7a939df871f0efa5aafa4d4ed6a28c779a5d5213e6dfb7a1 *mipsel-linux.elf/upx-3.95
|
|
||||||
5fe46128190a2553c6219f6f998b31ff007a5692f44585bcec27566eb6bf6640 *powerpc-linux.elf/upx-3.91
|
|
||||||
c5ce8e7076d542a92205f98c8017fc9b6f97541a1e082ca2239c1138104001ef *powerpc-linux.elf/upx-3.95
|
|
||||||
21268d593853c2e724037ca0e0c832b89414c3c41e2a0cc9c5038ab162be710b *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
|
||||||
b8e4d487f79a5c097244793f0535b2cfc4587449f9cbc9a7e19f5171a7a05f8c *amd64-linux.elf/upx-3.91
|
|
||||||
ab4972d2fd8369c43337aa636060b881c65ca18942d46d7ea24392a771b07b30 *amd64-linux.elf/upx-3.95
|
|
||||||
f5380d57da37b4d5e1258f0d36e329a936c3976ac7f684baa20899c9cfc5f167 *amd64-win64.pe/upx-3.95.exe
|
|
||||||
024b27a1edf93da0efc93190c4b6d2003d76e43a80065b24a1aa5bf0143feb06 *arm-linux.elf/upx-3.95
|
|
||||||
0c588526f42f3f0931731fb01e1e257780c9a87a1701b2c3f4a7605b6911f618 *arm-wince.pe/upx-3.91.exe
|
|
||||||
2c12d439d9a24c532b6c41decd9b01d2774d03e34692129ee17b8448e3436e3e *arm64-linux.elf/upx-3.95
|
|
||||||
eb7436b949fd646500bf42f14abe2ea6d466cbda5cbfff36a4e71693611d6c9f *armeb-linux.elf/upx-3.91
|
|
||||||
3e0db5fc130ac5b08d9b4df0cdf0fb9a40fa299cd5e28b2550277845500fa729 *armeb-linux.elf/upx-3.95
|
|
||||||
fb7d8645e851534e4050efac23aff3fc0557f217d4fe2bb3715f8771845f5759 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
12d2e9029826966caa38cf719757a055298c86d46e6bea7eef7a20a77a6902a9 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
b10d190bb8c2aee25ed264051b1527649c5f6fa3f8dde46c7ddd9fb3caae8e94 *i386-linux.elf/upx-3.91
|
|
||||||
b6c3402266a0d798ffbdf5ed3c6bbd80cc25999cddf178ce65c8e5917cb60cd9 *i386-linux.elf/upx-3.95
|
|
||||||
1a353bff5e90a73664fb1366fcab3ddde11f9309a59cf0e58a9f6deb40170bff *i386-win32.pe/upx-3.91.exe
|
|
||||||
9fd5633d06eae78f683857fc90ebda7cad60395cc46751101190086f069e55c1 *i386-win32.pe/upx-3.95.exe
|
|
||||||
2df5dd59cabcd7c09293982cc4638a608c424e515f8040aa70473d30fd7373db *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
771ee01c165aa0dac865f946dd4207680a723ef822f2ceda27c6c442978cb898 *mips-linux.elf/upx-3.95
|
|
||||||
f99b2e97c49e86cbe8141160de3b5196e78fe85776a159b745a78144c7fd29a9 *mipsel-linux.elf/upx-3.91
|
|
||||||
bad98328d8666b5f92b7210fa22920947fbfb38a86e788f1bcbb8ce1c8e64bcc *mipsel-linux.elf/upx-3.95
|
|
||||||
fc671351debd86f347f874e5a1cace099bbf388fd19f8ec2ac226ab22c84e46e *powerpc-linux.elf/upx-3.91
|
|
||||||
cb248465ee6fbf2aff427c9c015de65c547bab7ac3b84b5243980d707c3514ea *powerpc-linux.elf/upx-3.95
|
|
||||||
49e84bc28d7d80d828cf9298101468730dc1badc6e2f710884e2afc34d669391 *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
|
||||||
037e9867bc52669e8f4869d64a41a8faaca3e57f6b226b79a894aa8854f0d73b *amd64-linux.elf/upx-3.91
|
|
||||||
54b9d627cbb8bf19a8b7e299af33fcfbf45287ee41de1fc3b7806f45cc9f0c4f *amd64-linux.elf/upx-3.95
|
|
||||||
c76b656a4e5c9d3f691d186b488e89401246395e05a4c571d8384826ec1afd7a *amd64-win64.pe/upx-3.95.exe
|
|
||||||
1099f092f803371ae60fe45d1210ed000fa011026a6e3a339119d30e7b533a3d *arm-linux.elf/upx-3.95
|
|
||||||
0fd539a9cf015e60f55cfe9a2cb735c39abcec4097a1d9dad14133817322f149 *arm-wince.pe/upx-3.91.exe
|
|
||||||
f74bcbafa912d4b60431744347562551efb3a4c738b33b54788702c9a04a2755 *arm64-linux.elf/upx-3.95
|
|
||||||
2159088afb2481c20bd3e46b22f135ea9a71fccf84cf8e3cd5288012bf499efb *armeb-linux.elf/upx-3.91
|
|
||||||
a4e1fb939ffd0dd4fba8d96332406475220439ee368c4445b715d723c14257f7 *armeb-linux.elf/upx-3.95
|
|
||||||
7832f40d5a2f4208c5a765a90758a75b8208ac5b4c01a78c276be2ff74d6be13 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
e6bde12bead66eff48502e7944fe44a557db3f236b6d0155be5b9bf891c6beff *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
8306fa054b3281547f545b2ec1c5a059f0f29414fdeb4a5572f07c25bc8deff2 *i386-linux.elf/upx-3.91
|
|
||||||
75f6be5e52b89ac19f822ba9ed598c050078d9ec5530dd73144b5f0748dfe6e7 *i386-linux.elf/upx-3.95
|
|
||||||
61ea92bd711bcbf8c74e33054f320ab214dc1b2570e814a5d1f65001f7e1e507 *i386-win32.pe/upx-3.91.exe
|
|
||||||
ed5db8134d10a59b0dc1b973339823d20104ac3c1be0332fb55b1f2e220110c5 *i386-win32.pe/upx-3.95.exe
|
|
||||||
d381ff2c7115e3100daa567e49dbf36bd42ea7544039d8e7fb66ecc5009f88c0 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
6aa24a6661d322f60805406b87a5be605a5aee52d33e798328b7d118dfba4862 *mips-linux.elf/upx-3.95
|
|
||||||
04a1492fad74bc942216721a9e538638c9dc14f64272c5d90b54dc5a38c98b4d *mipsel-linux.elf/upx-3.91
|
|
||||||
31f6814a6964c9d5e44f1cc842742036747e95df2bdc4f4dddc8f05d4d9eac1a *mipsel-linux.elf/upx-3.95
|
|
||||||
5b1121a963ecec3e221e0b475f6cde7aad14d5cdd8cba43a4516dbdb92eb5a66 *powerpc-linux.elf/upx-3.91
|
|
||||||
c4f35cda7fdf64d9195115a82c806f084e2dbce0f80a31b34a882138d6d159c1 *powerpc-linux.elf/upx-3.95
|
|
||||||
ce70def8c58def3d548aa04f502c8279392eadcdb2c3d3cac8466cfcd3a6b7ab *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
|
||||||
38b58e0702763bd421f8940479a8545f39a2a8f27d90d2c276dc677d8a99846c *amd64-linux.elf/upx-3.91
|
|
||||||
5b34c95e9d636903b85b79b299d28f2aa6bd8d3a3d1696acf308d8cf8bfe99d4 *amd64-linux.elf/upx-3.95
|
|
||||||
dd10984767f9fe67900b64d63699ccaf858b9072272eef5ca373a7701d5057bb *amd64-win64.pe/upx-3.95.exe
|
|
||||||
4aff8b057429fcdac4f4b3691278c87280e247879ef07ea0291a1c56f999750d *arm-linux.elf/upx-3.95
|
|
||||||
9e5ad415bb42155a3c527fd259ac7ca1534a14bec888cb1ee8a7cc8e2ca0019c *arm-wince.pe/upx-3.91.exe
|
|
||||||
65facbcdbf7f79d88fce4af18629f8489510134005b3e490eb42fa112603e18e *arm64-linux.elf/upx-3.95
|
|
||||||
78d94d8209a443ae3c05f360c1086fe8bcad109e3a7d5267c571ad53ad38702e *armeb-linux.elf/upx-3.91
|
|
||||||
37242e5eb6ef64ed6dc862a791643d62cfc9c3b98a6f88556216a002101ef73f *armeb-linux.elf/upx-3.95
|
|
||||||
99209d2c5e6e7bf9edad472b181318f135a619f10d19ecde37158a80e186658b *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
f713b061cc6171d6fd467f6041618bf5c61179c406ccf6b79acb378e7fa1f3dd *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
48b554af082672ed3c5dab9ef5d78f561215f23ab98eb49904766e2801b70799 *i386-linux.elf/upx-3.91
|
|
||||||
9c1f8e34110030920684ee1276033bcaaa3cd2917d4cc001dad6efd865e8f2e8 *i386-linux.elf/upx-3.95
|
|
||||||
6d08ec9ab29b1d85bfcaebac1adeec1a5155c8b37a5c979e40f4e0fcae12cb45 *i386-win32.pe/upx-3.91.exe
|
|
||||||
1754e33c11034d09076c6a534532d5d9a13e967e4206221cc8a0c6d904bb6edc *i386-win32.pe/upx-3.95.exe
|
|
||||||
d044c35793adedbba31dee6adb4dbd1fcde183f2299d11b17e15aca83500217e *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
f555a0e2444ec2d859609236c66f45b9984cbfcd9668d16dea5de0feb86a94ea *mips-linux.elf/upx-3.95
|
|
||||||
8a96d7674eb6754235d0e7cc2e72bae241a166e2d232e70ee97bd0382c5dba9f *mipsel-linux.elf/upx-3.91
|
|
||||||
40ddb03c43e5740b634aa05a915fbe5ec2fb1f7076b7a3553d236498f4830964 *mipsel-linux.elf/upx-3.95
|
|
||||||
262cf98e2533c38008b2a2273f5ee3ccdfb753b854c8afb836be5f1b1af56710 *powerpc-linux.elf/upx-3.91
|
|
||||||
20513f3e3f675b167ce74707f9b31c4e4885f5d7c3d8b050a4a7ea7221b1b6f2 *powerpc-linux.elf/upx-3.95
|
|
||||||
b8aca35fce8a1ceea2c7ba4f11cfcbb3549ac0e93b955a0c390f6a7063e865e3 *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
|
||||||
5033deb9509be51229a7fb9fff629547797bfff7046e413a3450892ab459c58e *amd64-linux.elf/upx-3.91
|
|
||||||
d92a21d5b25c4b367142859eb3f29d9754d54b151058475a81e5bda6e5093dcd *amd64-linux.elf/upx-3.95
|
|
||||||
870083b25a88a2ff5cb49dfa109e55fc082b11af39c352740bab65c551b40282 *amd64-win64.pe/upx-3.95.exe
|
|
||||||
152fbbeabd01c771d526a887ae6a8d92bc5a9dd92ad0779d9a40a036f4760309 *arm-linux.elf/upx-3.95
|
|
||||||
f88d160e5a3e7e323623dc5f1f6edabd6ed0ac477beb168bf754047c04531097 *arm-wince.pe/upx-3.91.exe
|
|
||||||
379a8eec659fd1a1bced32342b45e146333b3a257942d66f7a1062f9cba88f9c *arm64-linux.elf/upx-3.95
|
|
||||||
86f5d6d3f7b738e4e30157fb011720fbae61f52a6296e3dfeb445afeceb91e32 *armeb-linux.elf/upx-3.91
|
|
||||||
7cb7f1a18d00631decbbd73d56d4cb54a5402cb3784607406c258ce5af3f51ca *armeb-linux.elf/upx-3.95
|
|
||||||
4b34e1f0553937c3fb6b98b4cad7beff510d5f0c9bbfd2fd2cc6986bc569d579 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
41332641b361c584763bfc149d3762bb4c337fe979af85f4b6cc03c3318ac9a9 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
e3c7e93cddce54b2c044b23b2ce239e2373134212cd930ad700ab93178785941 *i386-linux.elf/upx-3.91
|
|
||||||
14827578a5bbcebcf02ab9754145a290cb06d0c2dc3d9c34da182c3a22071cb6 *i386-linux.elf/upx-3.95
|
|
||||||
f10fb96a4db81cde3f76f3499710c16accfb7c7b30bc3e5532ea3b0b5aa57d54 *i386-win32.pe/upx-3.91.exe
|
|
||||||
a83278c357fa81f565ee1f95edbfc0156318b9638a5934421ee9f2f1bae5479a *i386-win32.pe/upx-3.95.exe
|
|
||||||
f29d9bb67de28a5eddbd3153c616f8b840d019bed48dfc6cf99ffc0bc6146390 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
356630562c9b017d18e09373ca71e19e870ae10b25ffa7a0d6e3e5c1fb948d73 *mips-linux.elf/upx-3.95
|
|
||||||
336a1795b3675a8ee76fff35f6c9ea9c7fc8f48dd53224a990f1191b1cbbab65 *mipsel-linux.elf/upx-3.91
|
|
||||||
dbebbc932fc3caec6be1fe92d21eed379ed3bf7e55293c10c54dfba9c37229a9 *mipsel-linux.elf/upx-3.95
|
|
||||||
adb8d16a5a635cdb3ca12346c5317ce16431cc8ecb9a54a856ee9c2586f7911a *powerpc-linux.elf/upx-3.91
|
|
||||||
286c92ba6bb88c13c01fc932d1a742a2cc0d01b4c59731d72c7a91d0c7c6c9ef *powerpc-linux.elf/upx-3.95
|
|
||||||
9102d4d31572fc5b5244a6f7643e1d001cc3044836a25c6211f3117d4c2b1dac *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
|
||||||
407f350965205d7ef3d860cd89ff1dbee74082a7a6777363deb64ac5676ef495 *amd64-linux.elf/upx-3.91
|
|
||||||
8d391e5a14922113c7b72a16728f497553fc834b02971c0ffe65a1efe461f240 *amd64-linux.elf/upx-3.95
|
|
||||||
867627ab2c87ffe1d82d5f131c0b05f73fc73d1e0a0011e369adb543be3b0deb *amd64-win64.pe/upx-3.95.exe
|
|
||||||
f9f39f443c419ffaf2a5d95f00144d56de4ca66f21d919272345cf360c947694 *arm-linux.elf/upx-3.95
|
|
||||||
9394653a9f6ca77c82916f06d402af45639815edc1eb06ba01e67510927f9d34 *arm-wince.pe/upx-3.91.exe
|
|
||||||
e22d64d16fe071c70e62e3c97701632a88a1568d8146e197df89f1bcc003041a *arm64-linux.elf/upx-3.95
|
|
||||||
61a18df8b91461fb6ffd9fbfff3d24549abe5a64ca512a063a9c09f2d8dbbf64 *armeb-linux.elf/upx-3.91
|
|
||||||
6866f745d8bfd1f60d3f7fb68e39238f80371e4dec6f42ee08193db13eb2c04e *armeb-linux.elf/upx-3.95
|
|
||||||
d8a099f8e4fd380b70f0cf8ef56cbebf232ea0c127529593c15fc34af7df32e7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
5b8d383bbd3594016b09f923f3e3d472649e3854abf9a4d695d67524d57debde *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
7116ee5cce8865154ab815eaf717f39b82265c5f88320799d01bea2d92799a3c *i386-linux.elf/upx-3.91
|
|
||||||
4f29bc1c53e9cd7047929b8ceb92cc9022cede80fd80afa1c23f48152789d4c7 *i386-linux.elf/upx-3.95
|
|
||||||
65e85f6944b98df0ac16d50af98f501f3f87b35c0432edc17244e768f0850a3a *i386-win32.pe/upx-3.91.exe
|
|
||||||
6414e7ed0bb0aedc4b027030f42d5d2e49f10cd9d98b9250015be88d708fa4eb *i386-win32.pe/upx-3.95.exe
|
|
||||||
1dc02f7ab54cd23da1ba3efaa3e3ca275cc23bcdcb2f5131bc9c643c87076d0d *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
6b9269ee5709fd2a2bda88fa4d9198e4f163ee067cbd1faca12d17f906c5a2e0 *mips-linux.elf/upx-3.95
|
|
||||||
4424522044277c9ecfd3869c3746d4ac760b272a58157a8a7b49c1bc8bed6bbd *mipsel-linux.elf/upx-3.91
|
|
||||||
673f459fd6024a433d6a86245b569557d523f4f33a2bd1a31ff5ca590a19c663 *mipsel-linux.elf/upx-3.95
|
|
||||||
1e6d47f288f6e9ccdfee98bd3700771dd9cad47115909ec9192f10d7a87440a9 *powerpc-linux.elf/upx-3.91
|
|
||||||
203a33bb365a745a317a9292562cd80e0f82c7dbafb810fddb8a752d06159dcb *powerpc-linux.elf/upx-3.95
|
|
||||||
6bea6492b66df759ed13748b53b3d5058a1d3b9debf0b209c8b450e76e5fd29e *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
|
||||||
257a9f44da07e6eb423e651a8323a2b79d38c5d599a4ec1de8f62a7c103eedf4 *amd64-linux.elf/upx-3.91
|
|
||||||
4adc3488e71c834f28a0d9955b3959d7db19ff375720c02c433aae63ec847b67 *amd64-linux.elf/upx-3.95
|
|
||||||
47165d0a33de56cdcf5788773f3630b698bbdc68b8f2a383b348d4264406536b *amd64-win64.pe/upx-3.95.exe
|
|
||||||
4038aad4341b884dbe34aac6055391a78af540f368370b5b61bb45c40905160a *arm-linux.elf/upx-3.95
|
|
||||||
4f3f1dbdd225a72d37555d5f60a2eb8308b87ad1e641285f3f693e91cb430985 *arm-wince.pe/upx-3.91.exe
|
|
||||||
3c7b8a6813a446b05d6ea1d5b81155ac216fd847a3b456d01a5cdbe30a6b686d *arm64-linux.elf/upx-3.95
|
|
||||||
13c966e3377bac700e3e84d725dd8ff9ca949fb74d1ca7774a00af71112dfb7d *armeb-linux.elf/upx-3.91
|
|
||||||
2d542d14c90a530cf812c713740a0f1b2d73a81b91ef7efbc037c8d3507a714c *armeb-linux.elf/upx-3.95
|
|
||||||
9ea810301eda67e45eee400500d1c88969cd63bda1224446c86eef8a75657748 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
|
||||||
688efbc1826e6bd0ccceb0462325d5e384f38b7d05dfa3b7901fa18536b6ea68 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
|
||||||
294d5099c4794a2de49d264c0bd4bdf80c866041b7caac7f8420ed003ee18180 *i386-linux.elf/upx-3.91
|
|
||||||
8c40b35f36c8850aa481de5ab13a5cb0fbc8fc9593977dd438c08d55dadfa9fc *i386-linux.elf/upx-3.95
|
|
||||||
b5d3bbd9c5f3d376be43c75a32374b022adfb6566feeef14d30420c819566082 *i386-win32.pe/upx-3.91.exe
|
|
||||||
aa9d18c47e60a814d383a6778cf26654a2bea6a097520e7177d3c546a1421159 *i386-win32.pe/upx-3.95.exe
|
|
||||||
4ea046a2c8be33ed14531e30ccbd3440b9569e68abd76932a8837abf4abba553 *m68k-atari.tos/upx-3.91.ttp
|
|
||||||
eeb7ae0de5b423611989f948585a4fdb18926161927c8f99e137cb4ad5f464b0 *mips-linux.elf/upx-3.95
|
|
||||||
5f4433586e45651bacd01bca156090f06fa48e95a78077cc93d1b6bc9965e8d5 *mipsel-linux.elf/upx-3.91
|
|
||||||
d17b7488d441269f0427cf567fc6f5c43fbe32398860f0099d361b9d4672a2dc *mipsel-linux.elf/upx-3.95
|
|
||||||
eca17f5f26c878c3f5ffee569ce5eb3af19127685ceb0bf7a419d13537e774a2 *powerpc-linux.elf/upx-3.91
|
|
||||||
2ea98117f051c4f05292e2c5b71e9a1252ab32fe2dbb03e4f1106c765913cc4f *powerpc-linux.elf/upx-3.95
|
|
||||||
fecfda8d1c58bfe2fe7a0d9d3806258129e449b25e5bf65418c364758c693e94 *powerpc64le-linux.elf/upx-3.95
|
|
||||||
"
|
|
||||||
########## end .sha256sums.recreate
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
#
|
|
||||||
# very first version of the upx-testsuite
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then
|
|
||||||
echo "UPX testsuite SKIPPED."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# convenience
|
|
||||||
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
|
||||||
|
|
||||||
# create dirs
|
|
||||||
cd / || exit 1
|
|
||||||
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
|
||||||
echo 'invalid or missing $upx_testsuite_SRCDIR:'
|
|
||||||
echo ' please git clone https://github.com/upx/upx-testsuite'
|
|
||||||
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
mkbuilddirs "$upx_testsuite_BUILDDIR"
|
|
||||||
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // support functions
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
testsuite_header() {
|
|
||||||
local x='==========='; x="$x$x$x$x$x$x$x"
|
|
||||||
echo -e "\n${x}\n${1}\n${x}\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_split_f() {
|
|
||||||
fd=$(dirname "$1")
|
|
||||||
fb=$(basename "$1")
|
|
||||||
fsubdir=$(basename "$fd")
|
|
||||||
# sanity checks
|
|
||||||
if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then
|
|
||||||
fd= fb= fsubdir=
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_check_sha() {
|
|
||||||
(cd "$1" && sha256sum -b */* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
|
||||||
echo
|
|
||||||
cat $1/.sha256sums.current
|
|
||||||
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
|
||||||
echo "UPX-ERROR: $1 FAILED: checksum mismatch"
|
|
||||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
|
||||||
exit_code=99
|
|
||||||
let num_errors+=1 || true
|
|
||||||
all_errors="${all_errors} $1"
|
|
||||||
#exit 99
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_check_sha_decompressed() {
|
|
||||||
(cd "$1" && sha256sum -b */* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
|
||||||
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
|
||||||
cat $1/.sha256sums.current
|
|
||||||
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
|
|
||||||
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
|
||||||
exit 98
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
testsuite_use_canonicalized=1
|
|
||||||
testsuite_run_compress() {
|
|
||||||
testsuite_header $testdir
|
|
||||||
local files f
|
|
||||||
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
|
||||||
files=t020_canonicalized/*/*
|
|
||||||
else
|
|
||||||
files=t010_decompressed/*/*
|
|
||||||
fi
|
|
||||||
for f in $files; do
|
|
||||||
testsuite_split_f $f
|
|
||||||
[[ -z $fb ]] && continue
|
|
||||||
echo "# $f"
|
|
||||||
mkdir -p $testdir/$fsubdir $testdir/.decompressed/$fsubdir
|
|
||||||
$upx_run -qq --prefer-ucl "$@" $f -o $testdir/$fsubdir/$fb
|
|
||||||
$upx_run -qq -d $testdir/$fsubdir/$fb -o $testdir/.decompressed/$fsubdir/$fb
|
|
||||||
done
|
|
||||||
testsuite_check_sha $testdir
|
|
||||||
$upx_run -qq -l $testdir/*/*
|
|
||||||
$upx_run -qq --file-info $testdir/*/*
|
|
||||||
$upx_run -q -t $testdir/*/*
|
|
||||||
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
|
||||||
# check that after decompression the file matches the canonicalized version
|
|
||||||
cp t020_canonicalized/.sha256sums.expected $testdir/.decompressed/
|
|
||||||
testsuite_check_sha_decompressed $testdir/.decompressed
|
|
||||||
rm -rf "./$testdir/.decompressed"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // expected checksums
|
|
||||||
# //
|
|
||||||
# // To ease maintenance of this script in case of updates this section
|
|
||||||
# // can be automatically re-created from the current checksums -
|
|
||||||
# // see call of function recreate_expected_sha256sums below.
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
recreate_expected_sha256sums() {
|
|
||||||
local o=$1
|
|
||||||
local files f d
|
|
||||||
echo "########## begin .sha256sums.recreate" > "$o"
|
|
||||||
files=*/.sha256sums.current
|
|
||||||
for f in $files; do
|
|
||||||
d=$(dirname "$f")
|
|
||||||
echo "expected_sha256sums__${d}="'"\' >> "$o"
|
|
||||||
cat "$f" >> "$o"
|
|
||||||
echo '"' >> "$o"
|
|
||||||
done
|
|
||||||
echo "########## end .sha256sums.recreate" >> "$o"
|
|
||||||
}
|
|
||||||
|
|
||||||
source "$argv0dir/travis_testsuite_1-expected_sha256sums.sh" || exit 1
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // init
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
#set -x # debug
|
|
||||||
exit_code=0
|
|
||||||
num_errors=0
|
|
||||||
all_errors=
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
|
||||||
echo "ALLOW_FAIL"
|
|
||||||
set +e
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.out ]] && upx_exe=$upx_BUILDDIR/upx.out
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.exe ]] && upx_exe=$upx_BUILDDIR/upx.exe
|
|
||||||
if [[ -z $upx_exe ]]; then exit 1; fi
|
|
||||||
upx_run=$upx_exe
|
|
||||||
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
|
||||||
upx_run="$upx_qemu $upx_qemu_flags -- $upx_exe"
|
|
||||||
fi
|
|
||||||
if [[ $BM_T =~ (^|\+)wine($|\+) && -n $upx_wine ]]; then
|
|
||||||
upx_run="$upx_wine $upx_wine_flags $upx_exe"
|
|
||||||
fi
|
|
||||||
if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
|
|
||||||
if [[ -z $upx_valgrind ]]; then
|
|
||||||
upx_valgrind="valgrind"
|
|
||||||
fi
|
|
||||||
if [[ -z $upx_valgrind_flags ]]; then
|
|
||||||
#upx_valgrind_flags="--leak-check=full --show-reachable=yes"
|
|
||||||
#upx_valgrind_flags="-q --leak-check=no --error-exitcode=1"
|
|
||||||
upx_valgrind_flags="--leak-check=no --error-exitcode=1"
|
|
||||||
fi
|
|
||||||
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
(cd / && cd "$upx_BUILDDIR" && lcov -d . --zerocounters)
|
|
||||||
fi
|
|
||||||
|
|
||||||
export UPX="--prefer-ucl --no-color --no-progress"
|
|
||||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
|
||||||
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
|
||||||
|
|
||||||
# let's go
|
|
||||||
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 --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
|
||||||
rm -rf ./testsuite_1
|
|
||||||
mkbuilddirs testsuite_1
|
|
||||||
cd testsuite_1 || exit 1
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // decompression tests
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
testdir=t010_decompressed
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
|
|
||||||
testsuite_header $testdir
|
|
||||||
for f in $upx_testsuite_SRCDIR/files/packed/*/upx-3.9[15]*; do
|
|
||||||
testsuite_split_f $f
|
|
||||||
[[ -z $fb ]] && continue
|
|
||||||
echo "# $f"
|
|
||||||
mkdir -p $testdir/$fsubdir
|
|
||||||
$upx_run -qq -d $f -o $testdir/$fsubdir/$fb
|
|
||||||
done
|
|
||||||
testsuite_check_sha $testdir
|
|
||||||
|
|
||||||
# run one pack+unpack step to canonicalize the files
|
|
||||||
testdir=t020_canonicalized
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
|
|
||||||
testsuite_header $testdir
|
|
||||||
for f in t010_decompressed/*/*; do
|
|
||||||
testsuite_split_f $f
|
|
||||||
[[ -z $fb ]] && continue
|
|
||||||
echo "# $f"
|
|
||||||
mkdir -p $testdir/$fsubdir/.packed
|
|
||||||
$upx_run -qq --prefer-ucl -1 $f -o $testdir/$fsubdir/.packed/$fb
|
|
||||||
$upx_run -qq -d $testdir/$fsubdir/.packed/$fb -o $testdir/$fsubdir/$fb
|
|
||||||
done
|
|
||||||
testsuite_check_sha $testdir
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // compression tests
|
|
||||||
# // info: we use fast compression levels because we want to
|
|
||||||
# // test UPX and not the compression libraries
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
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
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --nrv2b -3 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 2 ]]; then
|
|
||||||
testdir=t120_compress_ucl_nrv2d_3_no_filter
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --nrv2d -3 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 3 ]]; then
|
|
||||||
testdir=t130_compress_ucl_nrv2e_3_no_filter
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --nrv2e -3 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 4 ]]; then
|
|
||||||
testdir=t140_compress_lzma_2_no_filter
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --lzma -2 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 5 ]]; then
|
|
||||||
testdir=t150_compress_ucl_2_all_filters
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress -2 --all-filters
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 6 ]]; then
|
|
||||||
testdir=t160_compress_all_methods_1_no_filter
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --all-methods -1 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $UPX_TESTSUITE_FAST -ge 7 ]]; then
|
|
||||||
testdir=t170_compress_all_methods_no_lzma_5_no_filter
|
|
||||||
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
|
||||||
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
|
|
||||||
fi
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# // summary
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
# recreate checksums from current version for an easy update in case of changes
|
|
||||||
recreate_expected_sha256sums .sha256sums.recreate
|
|
||||||
|
|
||||||
testsuite_header "UPX testsuite summary"
|
|
||||||
if ! $upx_run --version-short; then
|
|
||||||
echo "UPX-ERROR: upx --version-short FAILED"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "upx_exe='$upx_exe'"
|
|
||||||
if [[ $upx_run != "$upx_exe" ]]; then
|
|
||||||
echo "upx_run='$upx_run'"
|
|
||||||
fi
|
|
||||||
if [[ -f $upx_exe ]]; then
|
|
||||||
ls -l "$upx_exe"
|
|
||||||
file "$upx_exe" || true
|
|
||||||
fi
|
|
||||||
echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'"
|
|
||||||
echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'"
|
|
||||||
echo ".sha256sums.{expected,current}:"
|
|
||||||
cat */.sha256sums.expected | LC_ALL=C sort | wc
|
|
||||||
cat */.sha256sums.current | LC_ALL=C sort | wc
|
|
||||||
echo
|
|
||||||
if [[ $exit_code == 0 ]]; then
|
|
||||||
echo "UPX testsuite passed. All done."
|
|
||||||
else
|
|
||||||
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
|
|
||||||
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
|
|
||||||
fi
|
|
||||||
exit $exit_code
|
|
||||||
+498
-179
@@ -1,271 +1,590 @@
|
|||||||
# Support for GitHub Actions -- https://github.com/features/actions
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
# note: GitHub Actions runner images are frequently updated, and
|
# note: GitHub Actions runner images are frequently updated, and
|
||||||
# unfortunately this sometimes breaks builds in mysterious ways...
|
# unfortunately this sometimes breaks builds in mysterious ways...
|
||||||
# see https://github.com/actions/runner-images.git
|
# see https://github.com/actions/runner-images.git
|
||||||
|
|
||||||
name: 'CI'
|
name: CI
|
||||||
|
|
||||||
on:
|
on: [push, workflow_dispatch]
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
- '!appveyor*'
|
|
||||||
- '!gitlab*'
|
|
||||||
- '!travis*'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
CMAKE_REQUIRED_QUIET: 'OFF'
|
||||||
|
CMAKE_VERBOSE_MAKEFILE: 'ON'
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 'ON'
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
|
||||||
|
UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1
|
||||||
|
UPX_DEBUG_TEST_LIBC_QSORT: 1
|
||||||
|
# 2024-04-20
|
||||||
|
ZIG_DIST_VERSION: 0.12.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
job-rebuild-and-verify-stubs:
|
job-rebuild-and-verify-stubs:
|
||||||
name: 'Rebuild stubs'
|
name: Rebuild stubs
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-latest
|
||||||
|
container: ubuntu:24.04 # glibc-2.39
|
||||||
|
#container: debian:12-slim # also works; glibc-2.36
|
||||||
|
#container: debian:testing-slim # also works
|
||||||
steps:
|
steps:
|
||||||
- name: 'Install extra packages'
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
uname -a; pwd; id; umask
|
uname -a; pwd; id; umask
|
||||||
cd ..; mkdir -p deps; cd deps; mkdir packages
|
dpkg --add-architecture i386
|
||||||
# for ubuntu-22.04: install python2
|
apt-get update && apt-get upgrade -y
|
||||||
##export DEBIAN_FRONTEND=noninteractive
|
# install system packages
|
||||||
##sudo apt-get install -y --no-install-recommends python2-minimal
|
apt-get install -y --no-install-recommends bash ca-certificates curl git libmpc3 make perl-base xz-utils libc6:i386 zlib1g:i386
|
||||||
# manually install compat libs from Ubuntu 16.04
|
# install python2-minimal packages from Debian-11
|
||||||
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb'
|
mkdir ../deps; cd ../deps; mkdir packages
|
||||||
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb'
|
curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb
|
||||||
for f in *.deb; do dpkg -x $f ./packages; done
|
curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb
|
||||||
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
dpkg -i ./*python2*.deb && rm ./*python2*.deb && ldconfig
|
||||||
sudo ldconfig
|
ln -s -v python2.7 /usr/bin/python2
|
||||||
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz | tar -xJ
|
# manually unpack and install compat libs from Ubuntu-16.04
|
||||||
- name: 'Check out code'
|
curl -sS -L -O https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb
|
||||||
uses: actions/checkout@v3
|
for f in ./*.deb; do dpkg -x $f ./packages; done
|
||||||
with: { submodules: true }
|
mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
||||||
- name: 'Rebuild and verify stubs'
|
rm -rf ./*.deb ./packages && ldconfig
|
||||||
|
# install upx-stubtools
|
||||||
|
curl -sS -L https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
|
||||||
|
- name: Check out code
|
||||||
run: |
|
run: |
|
||||||
env C=gcc X=rebuild-stubs TRAVIS_OS_NAME=linux bash ./.github/travis_build.sh
|
git config --global --add safe.directory '*' # needed when running in a container
|
||||||
- name: 'Check source code formatting'
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
|
||||||
|
git submodule update --init -- vendor/lzma-sdk
|
||||||
|
- name: Rebuild and verify stubs
|
||||||
run: |
|
run: |
|
||||||
bash ./misc/scripts/check_whitespace_git.sh
|
export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
|
||||||
env UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20210104/clang-format-10.0.1" make -C src clang-format
|
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
|
if ! git diff --quiet; then git diff; exit 1; fi
|
||||||
|
- run: bash ./misc/scripts/check_whitespace_git.sh
|
||||||
|
- name: Check source code formatting
|
||||||
|
run: |
|
||||||
|
export UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6"
|
||||||
|
make -C src clang-format
|
||||||
|
if ! git diff --quiet; then git diff; exit 1; fi
|
||||||
|
- name: Rebuild docs
|
||||||
|
run: |
|
||||||
|
make -C doc clean all
|
||||||
|
if ! git diff --quiet; then git diff || true; fi # ignore diff error
|
||||||
|
|
||||||
job-linux-cmake:
|
job-linux-cmake: # uses cmake + make
|
||||||
|
if: true
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
name: ${{ format('{0} cmake', matrix.os) }}
|
name: ${{ format('{0}', matrix.os) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { os: ubuntu-20.04 }
|
- { os: ubuntu-22.04, use_extra: true, use_wine: true }
|
||||||
- { os: ubuntu-22.04 }
|
- { os: ubuntu-20.04, use_extra: true }
|
||||||
steps:
|
steps:
|
||||||
- name: 'Check out code'
|
- name: Install extra 32-bit and MinGW packages
|
||||||
uses: actions/checkout@v3
|
if: ${{ matrix.use_extra }}
|
||||||
with: { submodules: true }
|
|
||||||
- name: 'Build cmake debug-gcc'
|
|
||||||
run: 'make build/debug-gcc'
|
|
||||||
- name: 'Build cmake release-gcc'
|
|
||||||
run: 'make build/release-gcc'
|
|
||||||
- name: 'Build cmake debug-clang'
|
|
||||||
run: 'make build/debug-clang'
|
|
||||||
- name: 'Build cmake release-clang'
|
|
||||||
run: 'make build/release-clang'
|
|
||||||
- name: 'Make artifact'
|
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
sudo dpkg --add-architecture i386
|
||||||
|
sudo apt-get update && sudo apt-get upgrade -y
|
||||||
|
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
|
||||||
|
# make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads
|
||||||
|
for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do
|
||||||
|
if test -f /usr/bin/$f-posix; then sudo update-alternatives --set $f /usr/bin/$f-posix; fi
|
||||||
|
ls -l /usr/bin/${f}*
|
||||||
|
done
|
||||||
|
ls -l /etc/alternatives/*mingw* || true
|
||||||
|
sudo apt-get install -y libc6-dbg:i386 valgrind
|
||||||
|
- name: Install Wine
|
||||||
|
if: ${{ matrix.use_extra && matrix.use_wine }}
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y wine wine32:i386 wine64
|
||||||
|
ls -l /usr/bin/wine*
|
||||||
|
mkdir -p -v ~/.wine && wineboot --init
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: Check out test suite
|
||||||
|
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
|
- run: make build/extra/gcc/all
|
||||||
|
- run: make build/extra/clang/all
|
||||||
|
- run: make build/extra/gcc-m32/all
|
||||||
|
if: ${{ matrix.use_extra }}
|
||||||
|
- run: make build/extra/gcc-mx32/all
|
||||||
|
if: ${{ matrix.use_extra }}
|
||||||
|
- run: make build/extra/cross-windows-mingw32/all
|
||||||
|
if: ${{ matrix.use_extra }}
|
||||||
|
- run: make build/extra/cross-windows-mingw64/all
|
||||||
|
if: ${{ matrix.use_extra }}
|
||||||
|
- name: Make artifact
|
||||||
|
run: |
|
||||||
|
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
mkdir -p "tmp/artifact/$N"
|
mkdir -p "tmp/artifact/$N"
|
||||||
(cd build && cp -ai --parents */upx "../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")
|
(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
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||||
name: ${{ env.artifact_name }}
|
- name: Run install tests
|
||||||
path: tmp/artifact
|
|
||||||
- name: 'Run basic tests'
|
|
||||||
run: |
|
run: |
|
||||||
make -C build/debug-gcc test
|
(cd build/extra/gcc/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||||
make -C build/release-gcc test
|
(cd build/extra/gcc/release && DESTDIR="$PWD/Install with make" make install)
|
||||||
make -C build/debug-clang test
|
- name: Run ctest tests
|
||||||
make -C build/release-clang test
|
run: |
|
||||||
|
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
command -v wine >/dev/null && jobs="$jobs cross-windows-mingw32/debug cross-windows-mingw32/release"
|
||||||
|
command -v wine >/dev/null && jobs="$jobs cross-windows-mingw64/debug cross-windows-mingw64/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
|
||||||
|
- name: Mimic ctest tests
|
||||||
|
run: |
|
||||||
|
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
- name: Mimic ctest tests with Valgrind
|
||||||
|
if: true # note: valgrind is SLOW
|
||||||
|
run: |
|
||||||
|
if command -v valgrind >/dev/null; then
|
||||||
|
export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
|
||||||
|
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||||
|
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
|
||||||
|
jobs="gcc/debug gcc/release clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
fi
|
||||||
|
- name: Run file system test suite
|
||||||
|
run: |
|
||||||
|
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||||
|
- name: Run file system test suite with Valgrind
|
||||||
|
if: false # note: valgrind is SLOW
|
||||||
|
run: |
|
||||||
|
if command -v valgrind >/dev/null; then
|
||||||
|
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||||
|
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
|
||||||
|
jobs="gcc/debug gcc/release clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||||
|
fi
|
||||||
|
- name: Run test suite
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
jobs="gcc/debug gcc/release clang/debug clang/release"
|
||||||
|
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
|
||||||
|
|
||||||
job-macos-cmake:
|
job-macos-cmake: # uses cmake + make
|
||||||
|
if: true
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
name: ${{ format('{0} cmake', matrix.os) }}
|
name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10' }
|
# NOTE: macos does not have "env -C"; only with brew coreutils
|
||||||
# { os: macos-12, gcc: gcc-11, gxx: 'g++-11' } # disable gcc - XCode 14.0 ld bug
|
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils
|
||||||
- { os: macos-12 }
|
- { os: macos-11, gcc: gcc-10, gxx: g++-10, testsuite: true }
|
||||||
|
- { os: macos-12, gcc: gcc-11, gxx: g++-11, testsuite: true }
|
||||||
|
- { os: macos-13, testsuite: true } # use default Xcode-15; NOTE: gcc-12 on macos-13 does not work with Xcode-15
|
||||||
|
- { os: macos-13, gcc: gcc-12, gxx: g++-12, testsuite: true, xcode_version: 14.3.1 }
|
||||||
|
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true } # gcc-13: INTERNAL ERROR in ld64
|
||||||
|
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true, xcode_version: 14.3.1 } # gcc-13: MISSING HEADER FILES
|
||||||
|
- { os: macos-14, gcc: gcc-12, gxx: g++-12, testsuite: true } # => use gcc-12 for now
|
||||||
steps:
|
steps:
|
||||||
- name: 'Check out code'
|
- uses: maxim-lobanov/setup-xcode@v1
|
||||||
uses: actions/checkout@v3
|
if: ${{ matrix.xcode_version }}
|
||||||
with: { submodules: true }
|
with: { xcode-version: '${{ matrix.xcode_version }}' }
|
||||||
- name: 'Build cmake debug-gcc'
|
- name: Install brew packages
|
||||||
if: ${{ matrix.gcc != '' }}
|
if: ${{ matrix.testsuite }}
|
||||||
run: 'make build/debug-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
|
||||||
- name: 'Build cmake release-gcc'
|
|
||||||
if: ${{ matrix.gcc != '' }}
|
|
||||||
run: 'make build/release-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
|
||||||
- name: 'Build cmake debug-clang'
|
|
||||||
run: 'make build/debug-clang'
|
|
||||||
- name: 'Build cmake release-clang'
|
|
||||||
run: 'make build/release-clang'
|
|
||||||
- name: 'Make artifact'
|
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
test -z "$HOMEBREW_PREFIX" && HOMEBREW_PREFIX="$(brew --prefix)"
|
||||||
|
echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >> $GITHUB_ENV
|
||||||
|
# testsuite needs working "readlink -en" and "sha256sum -b"
|
||||||
|
packages="ninja parallel"
|
||||||
|
test -e "$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin/readlink" || packages="$packages coreutils"
|
||||||
|
if test -n "$packages"; then
|
||||||
|
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list --versions
|
||||||
|
# only run "brew update" if needed
|
||||||
|
if ! brew install $packages; then brew update && brew install $packages; fi
|
||||||
|
fi
|
||||||
|
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
|
||||||
|
echo "UPX_DEBUG_FORCE_PACK_MACOS=1" >> $GITHUB_ENV
|
||||||
|
case "${{ matrix.os }}" in
|
||||||
|
# TODO FIXME: UPX on macos-13+ is broken => disable run-packed for now
|
||||||
|
macos-13 | macos-14) echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV ;;
|
||||||
|
esac
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: Check out test suite
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
|
- run: make build/extra/clang/all
|
||||||
|
- name: Build extra/gcc/all
|
||||||
|
if: ${{ matrix.gcc }}
|
||||||
|
run: make build/extra/gcc/all CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"
|
||||||
|
- name: Build xtarget/cross-darwin-arm64/all
|
||||||
|
run: |
|
||||||
|
make UPX_XTARGET=xtarget/cross-darwin-arm64 xtarget/all \
|
||||||
|
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin"
|
||||||
|
- name: Make artifact
|
||||||
|
run: |
|
||||||
|
X="${{ matrix.xcode_version }}"; test -n "$X" && X="-xcode-$X"
|
||||||
|
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
mkdir -p "tmp/artifact/$N"
|
mkdir -p "tmp/artifact/$N"
|
||||||
(cd build && rsync -R -a */upx "../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")
|
(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
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||||
name: ${{ env.artifact_name }}
|
- name: Run install tests
|
||||||
path: tmp/artifact
|
|
||||||
- name: 'Run basic tests'
|
|
||||||
run: |
|
run: |
|
||||||
make -C build/debug-clang test
|
(cd build/extra/clang/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||||
make -C build/release-clang test
|
(cd build/extra/clang/release && DESTDIR="$PWD/Install with make" make install)
|
||||||
|
- name: Run ctest tests
|
||||||
|
run: |
|
||||||
|
for f in ./build/extra/*/*/upx; do file $f; done
|
||||||
|
jobs="clang/debug clang/release"
|
||||||
|
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
|
||||||
|
- name: Mimic ctest tests
|
||||||
|
run: |
|
||||||
|
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||||
|
jobs="clang/debug clang/release"
|
||||||
|
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
- name: Run file system test suite
|
||||||
|
if: ${{ matrix.testsuite }} # for coreutils readlink
|
||||||
|
run: |
|
||||||
|
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||||
|
export upx_test_file="$PWD"/build/extra/clang/release/upx
|
||||||
|
jobs="clang/debug clang/release"
|
||||||
|
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||||
|
- name: Run test suite
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: |
|
||||||
|
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
jobs="clang/debug clang/release"
|
||||||
|
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
|
||||||
|
|
||||||
job-windows-cmake:
|
job-windows-cmake: # uses cmake + msbuild
|
||||||
|
if: true
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
name: ${{ format('{0} cmake', matrix.os) }}
|
name: ${{ format('{0}', matrix.name) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# windows-2019 used to work but got broken with the 20220821.1
|
- { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, vsarch: amd64 }
|
||||||
# runner-image update; disable for now
|
- { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, vsarch: amd64 }
|
||||||
# see https://github.com/actions/runner-images.git
|
|
||||||
####- { os: windows-2019 }
|
|
||||||
- { os: windows-2022 }
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Check out code'
|
- run: git config --global core.autocrlf false
|
||||||
uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Inspect runner-image settings'
|
- name: Check out test suite
|
||||||
# see https://github.com/actions/runner-images.git
|
run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
if: ${{ false }}
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
run: |
|
with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
|
||||||
Get-Command bash; Get-Command cmake; Get-Command make
|
- run: make build/debug
|
||||||
bash --version; cmake --version; make --version
|
- run: make build/release
|
||||||
Get-Command cl -ErrorAction SilentlyContinue
|
- name: Make artifact
|
||||||
- name: 'Build cmake debug'
|
|
||||||
run: 'make build/debug'
|
|
||||||
- name: 'Build cmake release'
|
|
||||||
run: 'make build/release'
|
|
||||||
- name: 'Make artifact'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
mkdir -p "tmp/artifact/$N"
|
mkdir -p "tmp/artifact/$N"
|
||||||
(cd build && cp -ai --parents */*/upx.exe "../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
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||||
name: ${{ env.artifact_name }}
|
- name: Run ctest tests
|
||||||
path: tmp/artifact
|
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||||
- name: 'Run basic tests'
|
|
||||||
run: |
|
run: |
|
||||||
cmake --build build/debug --config Debug --target RUN_TESTS
|
ctest --test-dir build/debug --parallel 8 -C Debug
|
||||||
cmake --build build/release --config Release --target RUN_TESTS
|
ctest --test-dir build/release --parallel 8 -C Release
|
||||||
|
- name: Run test suite build/release
|
||||||
|
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
env -C build/release/Release bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
||||||
|
|
||||||
job-windows-toolchains:
|
job-windows-toolchains: # build "by hand" using cmd.exe
|
||||||
|
if: github.repository_owner == 'upx'
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
name: ${{ matrix.name }}
|
name: ${{ format('windows {0}', matrix.name) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
C: ${{ matrix.C }}
|
C: ${{ matrix.name }}
|
||||||
B: release
|
B: release
|
||||||
H: 'd:\a\upx'
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { name: amd64-win64-msvc-14.2, os: windows-2019, C: msvc-14.2-x64, A: x64 }
|
- { name: amd64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64 }
|
||||||
- { name: amd64-win64-msvc-14.3, os: windows-2022, C: msvc-14.3-x64, A: x64 }
|
- { name: amd64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64 }
|
||||||
- { name: i386-win32-msvc-14.2, os: windows-2019, C: msvc-14.2-x86, A: x86 }
|
- { name: arm64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_arm64 }
|
||||||
- { name: i386-win32-msvc-14.3, os: windows-2022, C: msvc-14.3-x86, A: x86 }
|
- { name: arm64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64 }
|
||||||
|
- { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' }
|
||||||
|
# { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' }
|
||||||
|
- { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_x86 }
|
||||||
|
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
|
||||||
steps:
|
steps:
|
||||||
- name: 'Check out code'
|
- run: git config --global core.autocrlf false
|
||||||
uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Prepare sources'
|
- name: Prepare sources and Check out test suite
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
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 & where touch
|
|
||||||
git config --global core.autocrlf input
|
|
||||||
git --version & bash --version
|
|
||||||
cd %H%
|
|
||||||
md build build\%C% deps
|
|
||||||
cd deps
|
|
||||||
git clone --depth=1 https://github.com/upx/upx-testsuite
|
|
||||||
- name: 'Set up Developer Command Prompt'
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
with:
|
|
||||||
arch: ${{ matrix.A }}
|
|
||||||
- name: 'Build'
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
@REM setup directories following the VPATH build in travis_build.sh
|
|
||||||
where cl & where link
|
|
||||||
set BDIR=%H%\build\%C%\%B%
|
|
||||||
md %BDIR% %BDIR%\ucl %BDIR%\upx %BDIR%\upx-testsuite %BDIR%\zlib
|
|
||||||
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%\upx\vendor\ucl
|
|
||||||
cl -MT -J -O2 -W4 %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 %DEFS% -c %H%\upx\vendor\zlib\*.c
|
|
||||||
link -lib -out:zlib.lib *.obj
|
|
||||||
@REM ===== build UPX =====
|
|
||||||
cd %BDIR%\upx
|
|
||||||
set s=%H%\upx\src
|
|
||||||
cat .GITREV.txt
|
|
||||||
set /p GITREV=<.GITREV.txt
|
|
||||||
cl -MT -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% -I%H%\upx\vendor -Feupx.exe %s%\*.cpp %s%\util\*.cpp %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj
|
|
||||||
- name: 'Make artifact'
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.name }}
|
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
|
mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd}
|
||||||
|
repository_name="${GITHUB_REPOSITORY##*/}" # basename
|
||||||
|
echo "H=d:\\a\\$repository_name\\$repository_name" >> $GITHUB_ENV
|
||||||
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
|
||||||
|
- name: Build by hand
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
@REM ===== set vars =====
|
||||||
|
where cl & where link
|
||||||
|
set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT
|
||||||
|
set RUN_LIB=link -lib ${{ matrix.link_machine_flags }}
|
||||||
|
@rem UPX only uses the very basic Windows API
|
||||||
|
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0501
|
||||||
|
set BDIR=%H%\build\%C%\%B%
|
||||||
|
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||||
|
@REM ===== build bzip2 =====
|
||||||
|
cd %BDIR%\bzip2
|
||||||
|
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c
|
||||||
|
@rem %RUN_LIB% -out:bzip2.lib *.obj
|
||||||
|
@REM ===== build UCL =====
|
||||||
|
cd %BDIR%\ucl
|
||||||
|
set s=%H%\vendor\ucl
|
||||||
|
%RUN_CL% -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||||
|
%RUN_LIB% -out:ucl.lib *.obj
|
||||||
|
@REM ===== build zlib =====
|
||||||
|
cd %BDIR%\zlib
|
||||||
|
%RUN_CL% -J -O2 -W3 -WX %DEFS% -DHAVE_VSNPRINTF -c %H%\vendor\zlib\*.c
|
||||||
|
%RUN_LIB% -out:zlib.lib *.obj
|
||||||
|
@REM ===== build zstd =====
|
||||||
|
cd %BDIR%\zstd
|
||||||
|
set s=%H%\vendor\zstd\lib
|
||||||
|
@rem %RUN_CL% -J -O2 -W4 -WX %DEFS% -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
|
||||||
|
@rem %RUN_LIB% -out:zstd.lib *.obj
|
||||||
|
@REM ===== build UPX =====
|
||||||
|
cd %BDIR%\upx
|
||||||
|
set s=%H%\src
|
||||||
|
cat .GITREV.txt
|
||||||
|
set /p GITREV=<.GITREV.txt
|
||||||
|
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
|
||||||
|
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
|
||||||
|
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
|
||||||
|
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
||||||
|
%RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% %UPX_DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj
|
||||||
|
- name: Make artifact
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
mkdir -p "tmp/artifact/$N/$B"
|
mkdir -p "tmp/artifact/$N/$B"
|
||||||
cp -ai ../build/$C/$B/upx/upx*.exe "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
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||||
name: ${{ env.artifact_name }}
|
- name: Run basic tests
|
||||||
path: tmp/artifact
|
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||||
- name: 'Run basic tests'
|
|
||||||
run: |
|
run: |
|
||||||
$ErrorActionPreference = 'stop'
|
$ErrorActionPreference = 'stop'
|
||||||
$ErrorView = 'NormalView'
|
$ErrorView = 'NormalView'
|
||||||
cd $Env:H\build\$Env:C\$Env:B\upx
|
cd $Env:H\build\$Env:C\$Env:B\upx
|
||||||
$Env:UPX = "--no-color --no-progress"
|
$Env:UPX = "--no-color --no-progress"
|
||||||
.\upx.exe --version
|
.\upx.exe --version
|
||||||
|
.\upx.exe --sysinfo -v
|
||||||
.\upx.exe upx.exe -o upx_packed.exe
|
.\upx.exe upx.exe -o upx_packed.exe
|
||||||
dir *.exe
|
dir *.exe
|
||||||
.\upx.exe -l upx_packed.exe
|
.\upx.exe -l upx_packed.exe
|
||||||
.\upx.exe -t upx_packed.exe
|
.\upx.exe -t upx_packed.exe
|
||||||
.\upx_packed.exe --version
|
.\upx_packed.exe --version
|
||||||
- name: 'Run test suite'
|
- name: Run test suite
|
||||||
|
if: ${{ matrix.vsarch != 'amd64_arm64' }}
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
bash ./.github/travis_testsuite_1.sh
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
job-linux-zigcc: # uses cmake + make
|
||||||
|
if: github.repository_owner == 'upx'
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: alpine:3.19
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# only build a few targets => more targets are tested in the Weekly CI
|
||||||
|
- { zig_target: aarch64-linux-musl, qemu: qemu-aarch64 }
|
||||||
|
# { zig_target: aarch64-linux-musl, qemu: qemu-aarch64, zig_pic: -fPIE }
|
||||||
|
# { zig_target: aarch64-macos-none }
|
||||||
|
- { zig_target: aarch64-macos.11.0-none }
|
||||||
|
# { zig_target: aarch64-macos.12.0-none }
|
||||||
|
# { zig_target: aarch64-macos.13.0-none }
|
||||||
|
- { zig_target: aarch64-windows-gnu }
|
||||||
|
- { zig_target: arm-linux-musleabihf, qemu: qemu-arm }
|
||||||
|
# { zig_target: arm-linux-musleabihf, qemu: qemu-arm, zig_pic: -fPIE }
|
||||||
|
- { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 }
|
||||||
|
- { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 }
|
||||||
|
# { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386, zig_pic: -fPIE }
|
||||||
|
- { zig_target: i386-windows-gnu }
|
||||||
|
# mips and mipsel: bad hard-float code generation(??); or QEMU bug; or UPX bug; see https://github.com/upx/upx/issues/788
|
||||||
|
- { zig_target: mips-linux-musl, zig_flags: -msoft-float, qemu: qemu-mips }
|
||||||
|
- { zig_target: mipsel-linux-musl, zig_flags: -msoft-float, qemu: qemu-mipsel }
|
||||||
|
- { zig_target: powerpc-linux-musl, qemu: qemu-ppc }
|
||||||
|
# powerpc64: obscure problem with C++ exceptions in UPX doctest checks; use -fPIC to work-around
|
||||||
|
- { zig_target: powerpc64-linux-musl, zig_flags: -fPIC, qemu: qemu-ppc64 }
|
||||||
|
- { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le }
|
||||||
|
- { zig_target: x86_64-linux-gnu.2.3.4, qemu: qemu-x86_64 } # can use QEMU because of gcompat
|
||||||
|
- { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 }
|
||||||
|
# { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE }
|
||||||
|
# { zig_target: x86_64-macos-none }
|
||||||
|
- { zig_target: x86_64-macos.11.0-none }
|
||||||
|
# { zig_target: x86_64-macos.12.0-none }
|
||||||
|
# { zig_target: x86_64-macos.13.0-none }
|
||||||
|
- { zig_target: x86_64-windows-gnu }
|
||||||
|
env:
|
||||||
|
# zig is currently missing winpthreads; see https://github.com/ziglang/zig/issues/10989
|
||||||
|
UPX_CONFIG_EXPECT_THREADS: ${{ contains(matrix.zig_target, '-windows-') && 'OFF' || 'ON' }}
|
||||||
|
# for zig-cc wrapper scripts (see below):
|
||||||
|
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
|
||||||
|
ZIG_FLAGS: ${{ matrix.zig_flags }}
|
||||||
|
ZIG_PIC: ${{ matrix.zig_pic }}
|
||||||
|
ZIG_TARGET: ${{ matrix.zig_target }}
|
||||||
|
steps:
|
||||||
|
- name: Install Alpine Linux container packages
|
||||||
|
if: ${{ job.container }}
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
apk update && apk upgrade && apk add bash cmake curl file git make parallel tar xz
|
||||||
|
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
|
||||||
|
# set PATH like in Ubuntu
|
||||||
|
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
|
||||||
|
git config --global --add safe.directory '*' # needed when running in a container
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
rev=$(git rev-parse --short=7 HEAD)
|
||||||
|
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
|
||||||
|
if [[ "${{ matrix.zig_target }}" == x86_64-linux-gnu.2.3.4 ]]; then
|
||||||
|
echo "NEED_GCOMPAT=1" >> $GITHUB_ENV
|
||||||
|
# TODO FIXME: problem with self-packed upx and musl+gcompat: "Not a valid dynamic program"
|
||||||
|
echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
# update ZIG_TARGET (i386 => x86)
|
||||||
|
ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
|
||||||
|
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
|
||||||
|
# install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu
|
||||||
|
mkdir -p -v ~/.local/bin
|
||||||
|
cd ~/.local/bin
|
||||||
|
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
|
||||||
|
curl -sS -L -O https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz
|
||||||
|
ls -l ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
tar -xoJf ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
rm ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
ln -s -v ${ZIG_DIST_NAME}/zig zig
|
||||||
|
#echo "PATH=$PATH" && which zig
|
||||||
|
echo -n 'zig version: '; zig version
|
||||||
|
# create wrapper scripts (needed for CMake)
|
||||||
|
echo -e '#!/bin/sh\nexec zig ar "$@"' > zig-ar
|
||||||
|
echo -e '#!/bin/sh\nexec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
|
||||||
|
echo -e '#!/bin/sh\nexec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
|
||||||
|
echo -e '#!/bin/sh\nexec zig ranlib "$@"' > zig-ranlib
|
||||||
|
chmod +x zig-ar zig-cc zig-cxx zig-ranlib
|
||||||
|
ls -la; head zig-ar zig-cc zig-cxx zig-ranlib
|
||||||
|
- name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||||
|
run: |
|
||||||
|
make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/release \
|
||||||
|
CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
|
||||||
|
file build/zig/${ZIG_TARGET}${ZIG_PIC}/release/upx*
|
||||||
|
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||||
|
run: |
|
||||||
|
make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/debug \
|
||||||
|
CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
|
||||||
|
file build/zig/${ZIG_TARGET}${ZIG_PIC}/debug/upx*
|
||||||
|
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
|
||||||
|
mkdir -p "tmp/artifact/$N"
|
||||||
|
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||||
|
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
|
||||||
|
- name: Run install tests
|
||||||
|
if: ${{ contains(matrix.zig_target, '-linux') }}
|
||||||
|
run: |
|
||||||
|
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
|
||||||
|
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with make" make install)
|
||||||
|
- name: Run ctest tests
|
||||||
|
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
run: |
|
||||||
|
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||||
|
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'make build/zig/{}+test' ::: $jobs
|
||||||
|
- name: Mimic ctest tests
|
||||||
|
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
run: |
|
||||||
|
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||||
|
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
- name: ${{ format('Mimic ctest tests with QEMU {0}', matrix.qemu) }}
|
||||||
|
if: ${{ matrix.qemu }}
|
||||||
|
run: |
|
||||||
|
qemu="${{ matrix.qemu }}"
|
||||||
|
apk add coreutils "${qemu%% *}"
|
||||||
|
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||||
|
export upx_exe_runner="$qemu"
|
||||||
|
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
- name: Mimic ctest tests with Valgrind
|
||||||
|
if: ${{ matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
run: |
|
||||||
|
export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
|
||||||
|
apk add coreutils valgrind
|
||||||
|
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||||
|
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
|
||||||
|
upx_exe_runner="$upx_exe_runner --suppressions=$PWD/misc/valgrind/musl.supp"
|
||||||
|
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
|
||||||
|
- name: Run file system test suite
|
||||||
|
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
|
||||||
|
run: |
|
||||||
|
apk add coreutils sudo
|
||||||
|
test -n "$NEED_GCOMPAT" && apk add gcompat
|
||||||
|
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
|
||||||
|
echo "===== parallel jobs: $jobs"
|
||||||
|
parallel -kv --lb 'cd build/zig/{} && chmod a+w . && sudo -u nobody bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
name: "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
|
|
||||||
+16
-12
@@ -1,8 +1,10 @@
|
|||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
|
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
|
||||||
# see https://github.com/actions/stale
|
# see https://github.com/actions/stale
|
||||||
|
|
||||||
# Automatically closing issues is far from perfect, but then we only have
|
# Automatically closing issues is far from perfect, but then we only
|
||||||
# limited resources and this approach favors issues that people
|
# have limited resources and this approach favors issues that people
|
||||||
# actually care about.
|
# actually care about.
|
||||||
#
|
#
|
||||||
# also see:
|
# also see:
|
||||||
@@ -10,26 +12,28 @@
|
|||||||
# Abandoned Issues and Pull Request".
|
# Abandoned Issues and Pull Request".
|
||||||
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
||||||
|
|
||||||
name: 'Close inactive issues'
|
name: GitHub - Close stale issues
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule: [cron: "50 0 * * 1"] # run weekly Monday 00:50 UTC
|
||||||
- cron: "30 6 * * 4"
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
close-issues:
|
job-close-stale-issues:
|
||||||
name: 'Close inactive issues'
|
if: github.repository_owner == 'upx' && github.repository == 'upx/upx'
|
||||||
|
name: Close stale issues
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v6
|
- uses: actions/stale@v9
|
||||||
with:
|
with:
|
||||||
# operations-per-run: 300
|
operations-per-run: 300
|
||||||
days-before-stale: 60
|
exempt-all-milestones: true
|
||||||
|
exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression'
|
||||||
|
days-before-stale: 90
|
||||||
days-before-close: 30
|
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-issue-message: 'This issue is stale because it has been open for 90 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
|
||||||
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.'
|
stale-pr-message: 'This PR is stale because it has been open for 90 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.'
|
||||||
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
|
close-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.'
|
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 }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: '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 }}'
|
|
||||||
+18
-12
@@ -1,49 +1,55 @@
|
|||||||
/.hg*
|
/.hg*
|
||||||
/.vscode*
|
/.vscode*
|
||||||
/Makevars.global*
|
/Makevars[.-]global*
|
||||||
|
/Testing*
|
||||||
/build*
|
/build*
|
||||||
/maint*
|
/maint*
|
||||||
/vendor*
|
/vendor*
|
||||||
|
|
||||||
.depend
|
GNUmakefile*
|
||||||
GNUmakefile
|
MMakefile*
|
||||||
MMakefile
|
Makevars[.-]local*
|
||||||
Makevars.local*
|
compile_flags*.txt
|
||||||
tmp-testsuite*
|
Tmp*
|
||||||
|
tmp*
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
|
*.bz2
|
||||||
*.d
|
*.d
|
||||||
|
*.diff
|
||||||
*.dll
|
*.dll
|
||||||
|
*.dylib
|
||||||
*.exe
|
*.exe
|
||||||
|
*.gz
|
||||||
*.lib
|
*.lib
|
||||||
*.map
|
*.map
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
*.out
|
*.out
|
||||||
|
*.patch
|
||||||
*.py[cdo]
|
*.py[cdo]
|
||||||
|
*.rar
|
||||||
*.so
|
*.so
|
||||||
*.swp
|
*.swp
|
||||||
|
*.tmp
|
||||||
*.ttp
|
*.ttp
|
||||||
|
*.xz
|
||||||
|
*.zip
|
||||||
|
*.zst
|
||||||
|
|
||||||
doc/*.man
|
doc/*.man
|
||||||
doc/*.ps
|
doc/*.ps
|
||||||
doc/*.tex
|
doc/*.tex
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
url = https://github.com/upx/upx-vendor-ucl.git
|
url = https://github.com/upx/upx-vendor-ucl.git
|
||||||
branch = upx-vendor
|
branch = upx-vendor
|
||||||
shallow = true
|
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"]
|
[submodule "vendor/zlib"]
|
||||||
path = vendor/zlib
|
path = vendor/zlib
|
||||||
url = https://github.com/upx/upx-vendor-zlib.git
|
url = https://github.com/upx/upx-vendor-zlib.git
|
||||||
|
|||||||
+427
-141
@@ -1,234 +1,520 @@
|
|||||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
#
|
||||||
|
# UPX "CMake" build file; see https://cmake.org/
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
# config options
|
# Build requirements:
|
||||||
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info.")
|
# A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11
|
||||||
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options.")
|
# (older or other compilers may work but are unsupported, use at your own risk)
|
||||||
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option.")
|
|
||||||
|
# Sections of this CMakeLists.txt:
|
||||||
|
# - options
|
||||||
|
# - init
|
||||||
|
# - common compilation flags
|
||||||
|
# - targets
|
||||||
|
# - target compilation flags
|
||||||
|
# - test
|
||||||
|
# - install
|
||||||
|
# - print summary
|
||||||
|
|
||||||
|
# CMake version check; using a somewhat current CMake version is highly recommended
|
||||||
|
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt")
|
||||||
|
if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
|
||||||
|
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
|
||||||
|
else()
|
||||||
|
cmake_minimum_required(VERSION "3.8" FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# support functions and some utility
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/functions.cmake")
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# options
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
upx_cmake_include_hook(1_options)
|
||||||
|
|
||||||
|
# compilation config options
|
||||||
|
if(NOT USE_STRICT_DEFAULTS)
|
||||||
|
# permissive config defaults when building from source code tarball
|
||||||
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with Git version info." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with sanitize options." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." ON)
|
||||||
|
else()
|
||||||
|
# strict config defaults for Git developer builds
|
||||||
|
message(STATUS "===== UPX info: strict config defaults enabled")
|
||||||
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with Git version info." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with sanitize options." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# test config options (see below)
|
||||||
|
# IMPORTANT NOTE: self-pack test can only work if the host executable format is supported by UPX!
|
||||||
|
option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS "Do not run exhaustive tests" OFF)
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# init
|
# init
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
# Disallow in-source builds. Note that you will still have to manually
|
set(UPX_VERSION_STRING "4.2.4") # this should match src/version.h
|
||||||
|
|
||||||
|
upx_cmake_include_hook(2_init)
|
||||||
|
|
||||||
|
# Disallow in-source build. Note that you will still have to manually
|
||||||
# clean up a few files if you accidentally try an in-source build.
|
# clean up a few files if you accidentally try an in-source build.
|
||||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
upx_disallow_in_source_build()
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},")
|
|
||||||
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# determine git revision
|
# global settings
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER "3.14.99" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||||
|
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
|
||||||
|
cmake_policy(SET CMP0091 NEW)
|
||||||
|
endif()
|
||||||
|
# global CMake settings that default to ON
|
||||||
|
upx_cache_bool_vars(ON
|
||||||
|
CMAKE_C_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED
|
||||||
|
CMAKE_EXPORT_COMPILE_COMMANDS CMAKE_REQUIRED_QUIET
|
||||||
|
)
|
||||||
|
# internal UPX settings
|
||||||
|
upx_cache_bool_vars(OFF
|
||||||
|
UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||||
|
UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
|
||||||
|
UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD
|
||||||
|
UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST UPX_CONFIG_DISABLE_RUN_PACKED_TEST
|
||||||
|
UPX_CONFIG_REQUIRE_THREADS
|
||||||
|
)
|
||||||
|
upx_cache_bool_vars(ON UPX_CONFIG_EXPECT_THREADS)
|
||||||
|
upx_print_env_var(CC CXX)
|
||||||
|
|
||||||
|
# determine Git revision
|
||||||
set(GITREV_SHORT "")
|
set(GITREV_SHORT "")
|
||||||
set(GITREV_PLUS "")
|
set(GITREV_PLUS "")
|
||||||
find_package(Git)
|
set(GIT_DESCRIBE "")
|
||||||
if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||||
execute_process(
|
find_package(Git)
|
||||||
RESULT_VARIABLE result
|
if(Git_FOUND)
|
||||||
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
execute_process(
|
||||||
ERROR_QUIET
|
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
RESULT_VARIABLE result ERROR_QUIET
|
||||||
OUTPUT_VARIABLE GITREV_SHORT
|
OUTPUT_VARIABLE GITREV_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
string(LENGTH "${GITREV_SHORT}" l)
|
string(LENGTH "${GITREV_SHORT}" l)
|
||||||
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
||||||
execute_process(RESULT_VARIABLE result COMMAND "${GIT_EXECUTABLE}" diff --quiet)
|
execute_process(RESULT_VARIABLE result COMMAND "${GIT_EXECUTABLE}" diff --quiet)
|
||||||
if(NOT ${result} EQUAL 0)
|
if(NOT ${result} EQUAL 0)
|
||||||
set(GITREV_PLUS "+")
|
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()
|
||||||
else()
|
|
||||||
set(GITREV_SHORT "")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
|
|
||||||
set(GITREV_SHORT "")
|
|
||||||
endif()
|
|
||||||
if(GITREV_SHORT)
|
if(GITREV_SHORT)
|
||||||
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
|
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()
|
else()
|
||||||
message(STATUS "UPX_VERSION_GITREV: not set")
|
message(STATUS "UPX_VERSION_GITREV: not set")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(upx VERSION 4.0.0 LANGUAGES C CXX)
|
# CMake init
|
||||||
|
upx_set_default_build_type(Release) # default is CMAKE_BUILD_TYPE=Release
|
||||||
|
project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX)
|
||||||
|
upx_apply_build_type()
|
||||||
|
|
||||||
# set default build type to "Release"
|
# set MSVC_FRONTEND, GNU_FRONTEND and MINGW
|
||||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC"))
|
||||||
if(is_multi_config)
|
set(MSVC_FRONTEND 1)
|
||||||
set(c "${CMAKE_CONFIGURATION_TYPES}")
|
elseif (NOT DEFINED GNU_FRONTEND AND (CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^GNU" OR CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)"))
|
||||||
list(INSERT c 0 "Release")
|
set(GNU_FRONTEND 1)
|
||||||
list(INSERT c 1 "Debug")
|
endif()
|
||||||
if (CMAKE_BUILD_TYPE)
|
if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW")
|
||||||
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
|
set(MINGW 1)
|
||||||
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()
|
endif()
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# targets and compilation flags
|
# common compilation flags
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
|
include(CheckCCompilerFlag)
|
||||||
list(SORT ucl_SOURCES)
|
include(CheckFunctionExists)
|
||||||
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
include(CheckIncludeFile)
|
||||||
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
|
include(CheckStructHasMember)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
file(GLOB zlib_SOURCES "vendor/zlib/*.c")
|
upx_cmake_include_hook(3_common_compilation_flags)
|
||||||
list(SORT zlib_SOURCES)
|
|
||||||
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
|
||||||
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
|
||||||
|
|
||||||
file(GLOB upx_SOURCES "src/*.cpp" "src/util/*.cpp")
|
if(NOT DEFINED HAVE_UNISTD_H)
|
||||||
list(SORT upx_SOURCES)
|
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||||
add_executable(upx ${upx_SOURCES})
|
endif()
|
||||||
set_property(TARGET upx PROPERTY CXX_STANDARD 14)
|
if(NOT DEFINED HAVE_UTIMENSAT)
|
||||||
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
# proper checking for utimensat() is somewhat messy
|
||||||
|
check_function_exists(utimensat HAVE_UTIMENSAT_FUNCTION__)
|
||||||
|
if(HAVE_UTIMENSAT_FUNCTION__)
|
||||||
|
check_symbol_exists(utimensat "sys/types.h;fcntl.h;sys/stat.h" HAVE_UTIMENSAT_SYMBOL__)
|
||||||
|
if(HAVE_UTIMENSAT_SYMBOL__)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtim.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) # POSIX.1-2008
|
||||||
|
if(NOT HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtimespec.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) # macOS
|
||||||
|
endif()
|
||||||
|
if(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC OR HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||||
|
set(HAVE_UTIMENSAT 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UPX_CONFIG_DISABLE_WSTRICT)
|
||||||
|
# enable all basic warnings
|
||||||
|
set(warn_Wall -Wall)
|
||||||
|
set(warn_WN -W3)
|
||||||
|
else()
|
||||||
|
# enable all basic warnings, and enable lots of strict warnings
|
||||||
|
set(warn_Wall -Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings)
|
||||||
|
set(warn_WN -W4)
|
||||||
|
endif()
|
||||||
if(UPX_CONFIG_DISABLE_WERROR)
|
if(UPX_CONFIG_DISABLE_WERROR)
|
||||||
|
# warnings are just warnings
|
||||||
set(warn_Werror "")
|
set(warn_Werror "")
|
||||||
set(warn_WX "")
|
set(warn_WX "")
|
||||||
else()
|
else()
|
||||||
|
# warnings are fatal errors; annoy developers to keep the source code warning-free
|
||||||
set(warn_Werror -Werror)
|
set(warn_Werror -Werror)
|
||||||
set(warn_WX -WX)
|
set(warn_WX -WX)
|
||||||
endif()
|
endif()
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
# disable warning C5105 which may get triggered by some older versions of <windows.h>
|
||||||
|
set(warn_WX -wd5105 ${warn_WX})
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||||
# use -O2 instead of -O3 to reduce code size
|
# 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" a "${CMAKE_C_FLAGS_RELEASE}")
|
||||||
string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" b "${CMAKE_CXX_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_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)
|
set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
if(MSVC_FRONTEND OR WIN32 OR MINGW OR CYGWIN)
|
||||||
if(MSVC)
|
|
||||||
# disable silly warnings about using "deprecated" POSIX functions like fopen()
|
# disable silly warnings about using "deprecated" POSIX functions like fopen()
|
||||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
||||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
else()
|
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||||
# protect against security threats caused by misguided compiler "optimizations"
|
add_definitions(-D__USE_MINGW_ANSI_STDIO)
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
|
||||||
add_definitions(-fno-delete-null-pointer-checks)
|
|
||||||
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()
|
endif()
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
# use -funsigned-char; set __cplusplus according to selected C++ standard
|
||||||
|
add_definitions(-J -Zc:__cplusplus)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||||
|
upx_add_definitions(-Zc:preprocessor) # use new preprocessor
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
|
||||||
|
# protect against security threats caused by misguided compiler "optimizations"
|
||||||
|
upx_add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
|
||||||
|
upx_add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
||||||
|
# disable overambitious auto-vectorization until this actually gains something
|
||||||
|
upx_add_definitions(-fno-tree-vectorize)
|
||||||
|
# disable annoying clang warnings which get added by the macOS Xcode cmake generator
|
||||||
|
if(CMAKE_GENERATOR MATCHES "Xcode")
|
||||||
|
upx_add_definitions(-Wno-shorten-64-to-32)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# examine compiler configuration
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||||
|
upx_print_common_symbols()
|
||||||
|
upx_print_mingw_symbols()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# targets
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# internal settings; these may change in a future versions
|
||||||
|
set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe in UPX version 5
|
||||||
|
set(UPX_CONFIG_DISABLE_BZIP2 ON) # bzip2 is currently not used; we might need it to decompress linux kernels
|
||||||
|
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
|
||||||
|
|
||||||
|
upx_cmake_include_hook(4_targets)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_THREADS)
|
||||||
|
find_package(Threads)
|
||||||
|
endif()
|
||||||
|
# make sure that threads are indeed fully supported in C++
|
||||||
|
if(Threads_FOUND)
|
||||||
|
foreach(f std_lock_guard.cpp types_abi.cpp)
|
||||||
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
|
||||||
|
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
|
||||||
|
OUTPUT_VARIABLE output CXX_STANDARD 17)
|
||||||
|
else()
|
||||||
|
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
|
||||||
|
OUTPUT_VARIABLE output)
|
||||||
|
endif()
|
||||||
|
if(NOT result)
|
||||||
|
# failed; under MinGW be sure to use the posix-threads and NOT the win32-threads version
|
||||||
|
#message(STATUS "Threads FAILED ${f}: ${output}") # debug output from try_compile
|
||||||
|
set(Threads_FOUND OFF)
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||||
|
upx_add_glob_files(bzip2_SOURCES "vendor/bzip2/*.c")
|
||||||
|
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||||
|
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
endif() # UPX_CONFIG_DISABLE_BZIP2
|
||||||
|
|
||||||
|
upx_add_glob_files(ucl_SOURCES "vendor/ucl/src/*.c")
|
||||||
|
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||||
|
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
upx_add_glob_files(zlib_SOURCES "vendor/zlib/*.c")
|
||||||
|
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||||
|
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
upx_add_glob_files(zstd_SOURCES "vendor/zstd/lib/*/*.c")
|
||||||
|
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
|
||||||
|
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
endif() # UPX_CONFIG_DISABLE_ZSTD
|
||||||
|
|
||||||
|
upx_add_glob_files(upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
|
||||||
|
add_executable(upx ${upx_SOURCES})
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
|
||||||
|
set_property(TARGET upx PROPERTY CXX_STANDARD 17)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||||
|
target_link_libraries(upx upx_vendor_bzip2)
|
||||||
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
target_link_libraries(upx upx_vendor_zstd)
|
||||||
|
endif()
|
||||||
|
if(Threads_FOUND)
|
||||||
|
target_link_libraries(upx Threads::Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# target compilation flags
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
upx_cmake_include_hook(5_target_compilation_flags)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||||
|
set(t upx_vendor_bzip2)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
target_compile_definitions(${t} PRIVATE BZ_NO_STDIO=1)
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
|
||||||
|
elseif(GNU_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
|
||||||
|
endif() # UPX_CONFIG_DISABLE_BZIP2
|
||||||
|
|
||||||
set(t upx_vendor_ucl)
|
set(t upx_vendor_ucl)
|
||||||
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
||||||
if(MSVC)
|
upx_compile_target_debug_with_O2(${t})
|
||||||
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
upx_sanitize_target(${t})
|
||||||
else()
|
if(MSVC_FRONTEND)
|
||||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla ${warn_Werror})
|
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||||
|
elseif(GNU_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||||
endif()
|
endif()
|
||||||
|
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
|
||||||
|
|
||||||
set(t upx_vendor_zlib)
|
set(t upx_vendor_zlib)
|
||||||
if(MSVC)
|
upx_compile_target_debug_with_O2(${t})
|
||||||
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
|
upx_sanitize_target(${t})
|
||||||
else()
|
target_compile_definitions(${t} PRIVATE HAVE_VSNPRINTF=1)
|
||||||
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_UNISTD_H -DHAVE_VSNPRINTF)
|
if(HAVE_UNISTD_H)
|
||||||
# clang-15: -Wno-strict-prototypes is needed to silence the new -Wdeprecated-non-prototype warning
|
target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
|
||||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
|
|
||||||
endif()
|
endif()
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE -W3 ${warn_WX})
|
||||||
|
elseif(GNU_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
set(t upx_vendor_zstd)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1)
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
|
||||||
|
elseif(GNU_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
|
||||||
|
endif() # UPX_CONFIG_DISABLE_ZSTD
|
||||||
|
|
||||||
set(t upx)
|
set(t upx)
|
||||||
target_include_directories(${t} PRIVATE vendor)
|
target_include_directories(${t} PRIVATE vendor)
|
||||||
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
|
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
|
||||||
if(GITREV_SHORT)
|
if(GITREV_SHORT)
|
||||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
|
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()
|
endif()
|
||||||
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
|
if(Threads_FOUND)
|
||||||
# default sanitizer for Debug builds
|
target_compile_definitions(${t} PRIVATE WITH_THREADS=1)
|
||||||
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()
|
||||||
if(MSVC)
|
if(NOT UPX_CONFIG_DISABLE_WSTRICT)
|
||||||
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
|
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WSTRICT=0)
|
||||||
else()
|
|
||||||
target_compile_options(${t} PRIVATE
|
|
||||||
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith
|
|
||||||
-Wshadow -Wvla -Wwrite-strings ${warn_Werror}
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_WERROR)
|
||||||
|
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
|
||||||
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||||
|
target_compile_definitions(${t} PRIVATE WITH_BZIP2=1)
|
||||||
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||||
|
endif()
|
||||||
|
if(HAVE_UTIMENSAT)
|
||||||
|
target_compile_definitions(${t} PRIVATE USE_UTIMENSAT=1)
|
||||||
|
if(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||||
|
target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
# improve speed of the Debug versions
|
||||||
|
upx_compile_source_debug_with_O2(src/compress/compress_lzma.cpp)
|
||||||
|
upx_compile_source_debug_with_O2(src/filter/filter_impl.cpp)
|
||||||
|
#upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX})
|
||||||
|
elseif(GNU_FRONTEND)
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# "make test"
|
# test
|
||||||
|
# ctest
|
||||||
|
# make test
|
||||||
|
# ninja test
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
if(NOT CMAKE_CROSSCOMPILING)
|
upx_cmake_include_hook(6_test)
|
||||||
include(CTest)
|
|
||||||
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
|
||||||
set(upx_self_exe "$<TARGET_FILE:upx>")
|
|
||||||
add_test(NAME upx-test-cleanup COMMAND rm -f ./upx.packed${exe} ./upx.unpacked${exe})
|
include(CTest)
|
||||||
add_test(NAME upx-version COMMAND upx --version)
|
if(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
|
||||||
add_test(NAME upx-help COMMAND upx --help)
|
upx_add_test(upx-version upx --version)
|
||||||
add_test(NAME upx-self-pack COMMAND upx -3 ${upx_self_exe} -o upx.packed${exe})
|
upx_add_test(upx-version-short upx --version-short)
|
||||||
add_test(NAME upx-list COMMAND upx -l upx.packed${exe})
|
upx_add_test(upx-license upx --license)
|
||||||
add_test(NAME upx-fileinfo COMMAND upx --fileinfo upx.packed${exe})
|
upx_add_test(upx-help-1 upx --help)
|
||||||
add_test(NAME upx-test COMMAND upx -t upx.packed${exe})
|
upx_add_test(upx-help-2 upx --help-short)
|
||||||
add_test(NAME upx-unpack COMMAND upx -d upx.packed${exe} -o upx.unpacked${exe})
|
upx_add_test(upx-help-3 upx --help-verbose)
|
||||||
add_test(NAME upx-run-unpacked COMMAND ./upx.unpacked${exe} --version)
|
upx_add_test(upx-sysinfo-1 upx --sysinfo)
|
||||||
add_test(NAME upx-run-packed COMMAND ./upx.packed${exe} --version)
|
upx_add_test(upx-sysinfo-2 upx --sysinfo -v)
|
||||||
|
upx_add_test(upx-sysinfo-3 upx --sysinfo -vv)
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||||
|
# IMPORTANT NOTE: these tests can only work if the host executable format
|
||||||
|
# is supported by UPX!
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/self_pack_test.cmake")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: could add some more explicit test programs; but then, the integrated
|
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
|
||||||
# "doctest" is quite convenient and already covers a number of basic
|
|
||||||
# checks - and more complex cases better should be handled by an
|
|
||||||
# external test suite.
|
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# "make install"
|
# install
|
||||||
|
# cmake --install .
|
||||||
|
# make install
|
||||||
|
# ninja install
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
|
upx_cmake_include_hook(7_install)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
|
||||||
|
|
||||||
# installation prefix and directories
|
# installation prefix and directories
|
||||||
if(NOT CMAKE_INSTALL_PREFIX)
|
if(NOT CMAKE_INSTALL_PREFIX)
|
||||||
message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.")
|
#message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined")
|
||||||
|
message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined")
|
||||||
endif()
|
endif()
|
||||||
include(GNUInstallDirs)
|
if(CMAKE_INSTALL_PREFIX)
|
||||||
|
include(GNUInstallDirs)
|
||||||
if(DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
endif()
|
||||||
|
# install files
|
||||||
|
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||||
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||||
install(FILES
|
install(FILES
|
||||||
COPYING LICENSE NEWS README doc/upx-doc.html doc/upx-doc.txt
|
COPYING LICENSE NEWS README doc/THANKS.txt doc/upx-doc.html doc/upx-doc.txt
|
||||||
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
|
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
|
||||||
)
|
)
|
||||||
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
|
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# finally print some info about the build configuration
|
# summary
|
||||||
|
# print some info about the build configuration
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt")
|
upx_cmake_include_hook(8_summary)
|
||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt")
|
|
||||||
|
upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/print_info.cmake")
|
||||||
endif()
|
endif()
|
||||||
|
upx_print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_TRY_COMPILE_CONFIGURATION CMAKE_BUILD_TYPE)
|
||||||
function(print_var v)
|
if(Threads_FOUND)
|
||||||
if(${v})
|
message(STATUS "WITH_THREADS = 1")
|
||||||
message(STATUS "${v} = ${${v}}")
|
elseif(UPX_CONFIG_REQUIRE_THREADS)
|
||||||
endif()
|
message(FATAL_ERROR "ERROR: WITH_THREADS required")
|
||||||
endfunction()
|
elseif(UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS)
|
||||||
print_var(CMAKE_BUILD_TYPE)
|
message(FATAL_ERROR "ERROR: WITH_THREADS expected; set UPX_CONFIG_EXPECT_THREADS=OFF")
|
||||||
print_var(CMAKE_CONFIGURATION_TYPES)
|
endif()
|
||||||
print_var(CMAKE_INSTALL_PREFIX)
|
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$")
|
||||||
print_var(CMAKE_CROSSCOMPILING)
|
|
||||||
print_var(CMAKE_C_COMPILER_ID)
|
|
||||||
print_var(CMAKE_C_COMPILER_VERSION)
|
|
||||||
print_var(CMAKE_C_COMPILER_ARCHITECTURE_ID)
|
|
||||||
print_var(CMAKE_C_PLATFORM_ID)
|
|
||||||
print_var(CMAKE_C_COMPILER_ABI)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ID)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_VERSION)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
|
|
||||||
print_var(CMAKE_CXX_PLATFORM_ID)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ABI)
|
|
||||||
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\"")
|
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# extra sanity checks to detect incompatible C vs CXX settings
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
|
||||||
|
upx_platform_check_mismatch(CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID)
|
||||||
|
upx_platform_check_mismatch(CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI)
|
||||||
|
upx_platform_check_mismatch(CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
upx_cmake_include_hook(9_finish)
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt" "")
|
||||||
|
|
||||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
|
|||||||
@@ -1,42 +1,36 @@
|
|||||||
#
|
#
|
||||||
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
# NOTE: if you only have CMake 3.10 then you can invoke cmake manually like this:
|
# INFO: this Makefile is just a convenience wrapper for calling CMake
|
||||||
|
|
||||||
|
# HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this:
|
||||||
# mkdir -p build/release
|
# mkdir -p build/release
|
||||||
# cd build/release
|
# cd build/release
|
||||||
# cmake ../..
|
# cmake ../.. # run config
|
||||||
# cmake --build .
|
# make -j # and run build
|
||||||
|
|
||||||
CMAKE = cmake
|
CMAKE = cmake
|
||||||
UPX_CMAKE_BUILD_FLAGS += --parallel
|
UPX_CMAKE_BUILD_FLAGS += --parallel
|
||||||
ifneq ($(VERBOSE),)
|
ifneq ($(VERBOSE),)
|
||||||
UPX_CMAKE_BUILD_FLAGS += --verbose
|
#UPX_CMAKE_BUILD_FLAGS += --verbose # requires CMake >= 3.14
|
||||||
endif
|
UPX_CMAKE_CONFIG_FLAGS += -DCMAKE_VERBOSE_MAKEFILE=ON
|
||||||
|
|
||||||
# check git submodules
|
|
||||||
ifeq ($(wildcard ./vendor/doctest/doctest/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/lzma-sdk/C/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/ucl/include/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/zlib/crc32.c),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
endif
|
||||||
|
# enable this if you prefer Ninja for the actual builds:
|
||||||
|
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# default
|
# default
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
__check_cache = $(if $(wildcard $1/CMakeCache.txt),@true,)
|
.DEFAULT_GOAL = build/release
|
||||||
run_config = $(call __check_cache,$1) $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
|
||||||
run_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
|
||||||
|
|
||||||
default: build/release
|
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
||||||
|
run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
||||||
|
# avoid re-running run_cmake_config if .upx_cmake_config_done.txt already exists
|
||||||
|
run_config = $(if $(wildcard $1/CMakeFiles/.upx_cmake_config_done.txt),,$(call run_cmake_config,$1,$2))
|
||||||
|
run_build = $(call run_cmake_build,$1,$2)
|
||||||
|
|
||||||
build/debug: PHONY
|
build/debug: PHONY
|
||||||
$(call run_config,$@,Debug)
|
$(call run_config,$@,Debug)
|
||||||
@@ -46,40 +40,49 @@ build/release: PHONY
|
|||||||
$(call run_config,$@,Release)
|
$(call run_config,$@,Release)
|
||||||
$(call run_build,$@,Release)
|
$(call run_build,$@,Release)
|
||||||
|
|
||||||
|
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||||
|
.PHONY: PHONY
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
# shortcuts (all => debug + release)
|
||||||
|
debug: build/debug PHONY
|
||||||
|
release: build/release PHONY
|
||||||
|
all build/all: build/debug build/release PHONY
|
||||||
|
build/%/all: $$(dir $$@)debug $$(dir $$@)release PHONY ;
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# some pre-defined build configurations
|
# test
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
# force building with gcc/g++
|
CTEST = ctest
|
||||||
build/%-gcc: export CC=gcc
|
CTEST_JOBS ?= 8
|
||||||
build/%-gcc: export CXX=g++
|
CTEST_FLAGS = --output-on-failure --parallel $(CTEST_JOBS)
|
||||||
build/debug-gcc: PHONY
|
|
||||||
$(call run_config,$@,Debug)
|
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-gcc: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
# force building with clang/clang++
|
build/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||||
build/%-clang: export CC=clang
|
build/%/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
|
||||||
build/%-clang: export CXX=clang++
|
build/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
|
||||||
build/debug-clang: PHONY
|
build/%/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
|
||||||
$(call run_config,$@,Debug)
|
build/%/all+test: $$(dir $$@)debug+test $$(dir $$@)release+test PHONY ;
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-clang: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
# cross compiler: Windows mingw-w64
|
# shortcuts
|
||||||
build/%-cross-mingw64: export CC=x86_64-w64-mingw32-gcc
|
debug+test: build/debug+test PHONY
|
||||||
build/%-cross-mingw64: export CXX=x86_64-w64-mingw32-g++
|
release+test: build/release+test PHONY
|
||||||
# disable sanitize to avoid link errors on GitHub CI
|
all+test build/all+test: build/debug+test build/release+test PHONY
|
||||||
build/%-cross-mingw64: UPX_CMAKE_CONFIG_FLAGS += -DUPX_CONFIG_DISABLE_SANITIZE=1
|
|
||||||
build/debug-cross-mingw64: PHONY
|
|
||||||
$(call run_config,$@,Debug)
|
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-cross-mingw64: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
.PHONY: default PHONY
|
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||||
|
|
||||||
|
#
|
||||||
|
# END of Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
# extra pre-defined build configurations and some utility; optional
|
||||||
|
include ./misc/make/Makefile-extra.mk
|
||||||
|
|
||||||
|
# developer convenience
|
||||||
|
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
|
||||||
|
ifneq ($(wildcard ./misc/scripts/.),)
|
||||||
|
check-whitespace clang-format run-testsuite run-testsuite-all run-testsuite-debug run-testsuite-release: src/Makefile PHONY
|
||||||
|
$(MAKE) -C src $@
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|||||||
@@ -2,6 +2,40 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 4.2.4 (09 May 2024):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/17
|
||||||
|
|
||||||
|
Changes in 4.2.3 (27 Mar 2024):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/16
|
||||||
|
|
||||||
|
Changes in 4.2.2 (03 Jan 2024):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/15
|
||||||
|
|
||||||
|
Changes in 4.2.1 (01 Nov 2023):
|
||||||
|
* linux: /proc/self/exe now is optional
|
||||||
|
* windows: use SetFileTime to preserve sub-second file timestamps
|
||||||
|
* official Windows builds: revert activeCodePage change introduced in 4.2.0
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/14
|
||||||
|
|
||||||
|
Changes in 4.2.0 (26 Oct 2023):
|
||||||
|
* win32/pe and win64/pe: stricter relocation checks; please report regressions
|
||||||
|
* unix: use utimensat to preserve sub-second file timestamps
|
||||||
|
* new option '--link' to preserve hard-links (Unix only; use with care)
|
||||||
|
* add support for NO_COLOR env var; see https://no-color.org/
|
||||||
|
* disable macOS support until we fix compatibility with macOS 13+
|
||||||
|
* official Windows builds: set activeCodePage to UTF-8
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/13
|
||||||
|
|
||||||
|
Changes in 4.1.0 (08 Aug 2023):
|
||||||
|
* ELF: handle shared libraries with more than 2 PT_LOAD segments
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/11
|
||||||
|
|
||||||
|
Changes in 4.0.2 (30 Jan 2023):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/9
|
||||||
|
|
||||||
|
Changes in 4.0.1 (16 Nov 2022):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/8
|
||||||
|
|
||||||
Changes in 4.0.0 (28 Oct 2022):
|
Changes in 4.0.0 (28 Oct 2022):
|
||||||
* Switch to semantic versioning
|
* Switch to semantic versioning
|
||||||
* SECURITY NOTES: emphasize the security context in the docs
|
* SECURITY NOTES: emphasize the security context in the docs
|
||||||
@@ -9,6 +43,7 @@ Changes in 4.0.0 (28 Oct 2022):
|
|||||||
* Support easy rebuilding the stubs from source with Podman/Docker
|
* Support easy rebuilding the stubs from source with Podman/Docker
|
||||||
* Add integrated doctest C++ testing framework
|
* Add integrated doctest C++ testing framework
|
||||||
* Add support for EFI files (PE x86; Kornel Pal)
|
* 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/6
|
||||||
* bug fixes - see https://github.com/upx/upx/milestone/7
|
* bug fixes - see https://github.com/upx/upx/milestone/7
|
||||||
|
|
||||||
@@ -68,7 +103,7 @@ Changes in 3.08 (12 Dec 2011):
|
|||||||
* Compress shared library on ELF i386 only [ld.so threatens even this case].
|
* Compress shared library on ELF i386 only [ld.so threatens even this case].
|
||||||
* Attempt to support ELF on QNX 6.3.0 for armel (experimental).
|
* Attempt to support ELF on QNX 6.3.0 for armel (experimental).
|
||||||
* Better diagnostic when ELF -fPIC is needed.
|
* Better diagnostic when ELF -fPIC is needed.
|
||||||
* PT_NOTE improvements for *BSD.
|
* PT_NOTE improvements for BSD.
|
||||||
* Preserve more ELF .e_flags on ARM.
|
* Preserve more ELF .e_flags on ARM.
|
||||||
* Minor code improvements for ELF stubs.
|
* Minor code improvements for ELF stubs.
|
||||||
* Defend against another flavor of corrupt PE header.
|
* Defend against another flavor of corrupt PE header.
|
||||||
@@ -142,7 +177,7 @@ Changes in 2.92 beta (23 Jan 2007):
|
|||||||
|
|
||||||
Changes in 2.91 beta (29 Nov 2006):
|
Changes in 2.91 beta (29 Nov 2006):
|
||||||
* assorted bug fixes
|
* assorted bug fixes
|
||||||
* arm/pe: fix "missing" icon & version info resource problem for wince 5
|
* wince/arm: fix "missing" icon & version info resource problem for WinCE 5
|
||||||
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
||||||
|
|
||||||
Changes in 2.90 beta (08 Oct 2006):
|
Changes in 2.90 beta (08 Oct 2006):
|
||||||
@@ -196,7 +231,7 @@ Changes in 1.95 beta (09 Apr 2006):
|
|||||||
* win32/pe: really worked around R6002 runtime errors
|
* win32/pe: really worked around R6002 runtime errors
|
||||||
|
|
||||||
Changes in 1.94 beta (11 Mar 2006):
|
Changes in 1.94 beta (11 Mar 2006):
|
||||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
* new format: added support for wince/arm (ARM executables running on WinCE)
|
||||||
* new format: added support for linux elf/amd64
|
* new format: added support for linux elf/amd64
|
||||||
* new format: added support for linux elf/ppc32
|
* new format: added support for linux elf/ppc32
|
||||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
||||||
@@ -248,7 +283,7 @@ Changes in 1.11 beta (20 Dec 2000):
|
|||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
Changes in 1.25 (29 Jun 2004)
|
Changes in 1.25 (29 Jun 2004)
|
||||||
* INFO: http://upx.sourceforge.net is the permanent UPX home page
|
* INFO: http://upx.sourceforge.net is the new UPX home page
|
||||||
* watcom/le: don't crash on files without relocations
|
* watcom/le: don't crash on files without relocations
|
||||||
* win32/pe: stricter checks of some PE values
|
* win32/pe: stricter checks of some PE values
|
||||||
* source code: much improved portability using ACC, the
|
* source code: much improved portability using ACC, the
|
||||||
@@ -513,12 +548,12 @@ Changes in 0.40 (05 Oct 1998)
|
|||||||
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
||||||
* fixed a rare bug in dos/exe
|
* fixed a rare bug in dos/exe
|
||||||
* worked around a bug in djgpp's strip 2.8
|
* worked around a bug in djgpp's strip 2.8
|
||||||
* djgpp/coff: Allegro packfile support should work now
|
* djgpp2/coff: Allegro packfile support should work now
|
||||||
* added dos/exeh compression method (works on 386+)
|
* added dos/exeh compression method (works on 386+)
|
||||||
|
|
||||||
Changes in 0.30 (27 Jul 1998)
|
Changes in 0.30 (27 Jul 1998)
|
||||||
* fixed a serious bug in the 32-bit compressors - please don't use
|
* fixed a serious bug in the 32-bit compressors - please don't use
|
||||||
djgpp/coff and watcom/le compressed files from previous versions,
|
djgpp2/coff and watcom/le compressed files from previous versions,
|
||||||
some of them are possibly damaged !
|
some of them are possibly damaged !
|
||||||
* the 16-bit uncompressors are a little bit shorter & faster
|
* the 16-bit uncompressors are a little bit shorter & faster
|
||||||
* fixed progress indicator for VESA and SVGA text modes
|
* fixed progress indicator for VESA and SVGA text modes
|
||||||
@@ -529,6 +564,5 @@ Changes in 0.20 (05 Jul 1998)
|
|||||||
|
|
||||||
Changes in 0.05 (26 May 1998)
|
Changes in 0.05 (26 May 1998)
|
||||||
* first public beta release
|
* first public beta release
|
||||||
|
* based on experience gained from our previous packers DJP (djgpp2/coff, 1996),
|
||||||
|
lzop (1996) and mfxpak (atari/tos, 1990)
|
||||||
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ 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 programs and DLLs, macOS apps and Linux executables.
|
Windows programs and DLLs, and Linux executables.
|
||||||
|
|
||||||
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.
|
||||||
@@ -85,9 +85,9 @@ THE FUTURE
|
|||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 John F. Reiser
|
||||||
|
|
||||||
UPX is distributed with full source code under the terms of the
|
UPX is distributed with full source code under the terms of the
|
||||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
|
|||||||
+37
-2
@@ -44,7 +44,8 @@ Short overview
|
|||||||
Tools needed to build/modify the UPX sources
|
Tools needed to build/modify the UPX sources
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
- A C++ compiler that supports C++ 14: clang, gcc or msvc
|
- A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11
|
||||||
|
(older or other compilers may work but are unsupported, use at your own risk)
|
||||||
|
|
||||||
- GNU make
|
- GNU make
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ To compile the packer sources
|
|||||||
If you want to modify the stub sources you'll also need
|
If you want to modify the stub sources you'll also need
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
- Podman/Docker: see misc/rebuild-stubs-with-podman - this
|
- Podman/Docker: see misc/podman/rebuild-stubs - this
|
||||||
is the preferred way of rebuilding the stubs
|
is the preferred way of rebuilding the stubs
|
||||||
|
|
||||||
- otherwise you will need:
|
- otherwise you will need:
|
||||||
@@ -70,6 +71,40 @@ If you want to modify the stub sources you'll also need
|
|||||||
https://github.com/upx/upx-stubtools/releases
|
https://github.com/upx/upx-stubtools/releases
|
||||||
|
|
||||||
|
|
||||||
|
Developer quick start
|
||||||
|
---------------------
|
||||||
|
1) $ mkdir my-upx; cd my-upx # new directory for safety and convenience
|
||||||
|
2) $ git clone https://github.com/upx/upx.git
|
||||||
|
3) $ git clone https://github.com/upx/upx-testsuite.git
|
||||||
|
4) # Optional for re-building stubs:
|
||||||
|
4a) $ pushd upx/src/stub # my-upx/upx/src/stub
|
||||||
|
4b) $ wget https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz
|
||||||
|
# Extract to $HOME/bin/bin-upx or $HOME/local/bin/bin-upx.
|
||||||
|
# See directions in: https://github.com/upx/upx-stubtools
|
||||||
|
4c) $ make clean; make # verify that you can re-build stubs
|
||||||
|
4d) $ popd # my-upx
|
||||||
|
5) $ cd upx # my-upx/upx
|
||||||
|
6) $ git submodule update --init # compression algorithms, etc.
|
||||||
|
# DO NOT TOUCH vendor/...
|
||||||
|
# After a git merge/pull/etc, then use "git status"
|
||||||
|
# to check whether the vendor directory is clean;
|
||||||
|
# if not, then update via "git submodule update".
|
||||||
|
# If stuck, then reset via "rm -rf vendor; git submodule update --init".
|
||||||
|
7) $ mkdir -p build/debug build/release
|
||||||
|
8) $ pushd build/debug # my-upx/upx/build/debug
|
||||||
|
9) $ cmake ../.. # configure cmake
|
||||||
|
10) $ cmake --build . --verbose # optional "--verbose"
|
||||||
|
# This relies on stub/*.h, which YOU must re-build if necessary.
|
||||||
|
# When in doubt, then use "cd src/stub; make clean; make".
|
||||||
|
11) $ popd # my-upx/upx
|
||||||
|
12) $ cd src # my-upx/upx/src
|
||||||
|
12a) On MacOS: install homebrew (https:://brew.sh), then "brew install coreutils"
|
||||||
|
and put <some_prefix>/opt/coreutils/libexec/gnubin into PATH so that
|
||||||
|
"readlink -en" and "sha256sum -b" work.
|
||||||
|
13) $ make run-testsuite 2>&1 | tee testsuite.log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Misc. notes
|
Misc. notes
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
-Ivendor
|
|
||||||
-fno-strict-aliasing
|
|
||||||
-fno-strict-overflow
|
|
||||||
-funsigned-char
|
|
||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+28
-34
@@ -1,21 +1,9 @@
|
|||||||
#
|
#
|
||||||
# UPX doc Makefile - needs GNU make
|
# UPX doc Makefile - needs GNU make, sed, pod2html, pod2man and pod2text
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
BUILT_SOURCES := upx.1 upx-doc.html upx-doc.txt
|
||||||
.SUFFIXES:
|
|
||||||
SHELL = /bin/sh
|
|
||||||
|
|
||||||
# internal make variables
|
|
||||||
comma := ,
|
|
||||||
empty :=
|
|
||||||
space := $(empty) $(empty)
|
|
||||||
tab := $(empty) $(empty)
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# //
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
top_srcdir ?= ..
|
top_srcdir ?= ..
|
||||||
|
|
||||||
@@ -23,37 +11,45 @@ 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.html upx-doc.txt
|
#***********************************************************************
|
||||||
|
# targets
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
.DEFAULT_GOAL = all
|
||||||
|
|
||||||
###
|
.PHONY: PHONY
|
||||||
### targets
|
.SECONDEXPANSION:
|
||||||
###
|
.SUFFIXES:
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
all: $(BUILT_SOURCES) PHONY
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
mostlyclean clean distclean maintainer-clean: PHONY
|
||||||
rm -f $(BUILT_SOURCES) pod2htm*
|
rm -f $(BUILT_SOURCES) ./pod2htm*
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
#***********************************************************************
|
||||||
|
# rules
|
||||||
|
#***********************************************************************
|
||||||
###
|
|
||||||
### rules
|
|
||||||
###
|
|
||||||
|
|
||||||
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
||||||
|
|
||||||
%.1 : %.pod
|
%.1 : %.pod
|
||||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||||
test -s $@
|
test -s $@
|
||||||
|
# # strip version number from "Pod::Man" comment
|
||||||
|
sed -i -e 's/^\(\.\\" Automatically generated by Pod::Man\).*/\1/' $@
|
||||||
|
|
||||||
%-doc.html : %.pod
|
%-doc.html : %.pod
|
||||||
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
@rm -f pod2htm*
|
@rm -f ./pod2htm*
|
||||||
test -s $@
|
test -s $@
|
||||||
|
|
||||||
%.man : %.1
|
%.man : %.1
|
||||||
@@ -72,11 +68,9 @@ mostlyclean clean distclean maintainer-clean:
|
|||||||
pod2text < $< | $(RTRIM) > $@
|
pod2text < $< | $(RTRIM) > $@
|
||||||
test -s $@
|
test -s $@
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
###
|
# dependencies
|
||||||
### dependencies
|
#***********************************************************************
|
||||||
###
|
|
||||||
|
|
||||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -37,16 +37,20 @@ Charles W. Sandmann <sandmann@clio.rice.edu>
|
|||||||
for the idea with the stubless decompressor in djgpp2/coff
|
for the idea with the stubless decompressor in djgpp2/coff
|
||||||
Ice
|
Ice
|
||||||
for debugging the PE headersize problem down
|
for debugging the PE headersize problem down
|
||||||
|
Jens Medoch <jssg@users.sourceforge.net>
|
||||||
|
for the ps1/exe format
|
||||||
Joergen Ibsen <jibz@hotmail.com> and d'b
|
Joergen Ibsen <jibz@hotmail.com> and d'b
|
||||||
for the relocation & address optimization ideas
|
for the relocation & address optimization ideas
|
||||||
John S. Fine <johnfine@erols.com>
|
John S. Fine <johnfine@erols.com>
|
||||||
for the new version of the dos/exe decompressor
|
for the new version of the dos/exe decompressor
|
||||||
|
Kornel Pal
|
||||||
|
for the EFI support
|
||||||
Lukundoo <Lukundoo@softhome.net>
|
Lukundoo <Lukundoo@softhome.net>
|
||||||
for beta testing
|
for beta testing
|
||||||
Michael Devore
|
Michael Devore
|
||||||
for initial dos/exe device driver support
|
for initial dos/exe device driver support
|
||||||
Oleg V. Volkov <rover@lglobus.ru>
|
Oleg V. Volkov <rover@lglobus.ru>
|
||||||
for various FreeBSD specific informations
|
for various FreeBSD specific information
|
||||||
The Owl & G-RoM
|
The Owl & G-RoM
|
||||||
for the --compress-icons fix
|
for the --compress-icons fix
|
||||||
Ralph Roth <RalphRoth@gmx.net>
|
Ralph Roth <RalphRoth@gmx.net>
|
||||||
@@ -55,6 +59,6 @@ Salvador Eduardo Tropea
|
|||||||
for beta testing
|
for beta testing
|
||||||
Stefan Widmann
|
Stefan Widmann
|
||||||
for the win32/pe TLS callback support
|
for the win32/pe TLS callback support
|
||||||
The WINE project (http://www.winehq.com/)
|
The WINE project (https://www.winehq.com/)
|
||||||
for lots of useful information found in their PE loader sources
|
for lots of useful information found in their PE loader sources
|
||||||
Natascha
|
Natascha
|
||||||
+46
-44
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright (C) 2000-2022 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2024 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
@@ -15,7 +15,7 @@ the value that is manipulated by system call 45 (__NR_brk in
|
|||||||
there will be no execve() except for the execve() of the decompressor
|
there will be no execve() except for the execve() of the decompressor
|
||||||
program itself. So, the decompressor program (which contains the
|
program itself. So, the decompressor program (which contains the
|
||||||
compressed version of the original executable) must have the same
|
compressed version of the original executable) must have the same
|
||||||
brk() as the original executable. So, the second PT_LOAD
|
brk() as the original executable. So, the first PT_LOAD
|
||||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||||
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||||
All of the decompressor's code, and all of the compressed image
|
All of the decompressor's code, and all of the compressed image
|
||||||
@@ -25,35 +25,27 @@ decompressor program.
|
|||||||
The decompressor program stub is just under 2K bytes when linked.
|
The decompressor program stub is just under 2K bytes when linked.
|
||||||
After linking, the decompressor code is converted to an initialized
|
After linking, the decompressor code is converted to an initialized
|
||||||
array, and #included into the compilation of the compressor;
|
array, and #included into the compilation of the compressor;
|
||||||
see src/stub/l_le_n2b.h. To make self-contained compressed
|
see stub/i386-linux.elf-entry.h. To make self-contained compressed
|
||||||
executables even smaller, the compressor also compresses all but the
|
executables even smaller, the compressor also compresses all but the
|
||||||
startup and decompression subroutine of the decompressor itself,
|
startup and decompression subroutine of the decompressor itself,
|
||||||
saving a few hundred bytes. The startup code first decompresses the
|
saving a few hundred bytes. The startup code first decompresses the
|
||||||
rest of the decompressor, then jumps to it. A nonstandard linker
|
rest of the decompressor, then jumps to it. A nonstandard linker
|
||||||
script src/stub/l_lx_elf86.lds places both the .text and .data
|
script src/stub/src/i386-linux.elf-entry.lds arranges the SECTIONS
|
||||||
of the decompressor into the same PT_LOAD at 0x00401000. The
|
so that PackLinuxElf32x86::buildLoader() and buildLinuxLoader()
|
||||||
compressor includes the compressed bytes of the original executable
|
generate the desired stub code, which goes into PT_LOAD[1].
|
||||||
at the end of this first PT_LOAD.
|
|
||||||
|
|
||||||
At runtime, the decompressed stub lives at 0x00400000. In order for the
|
At runtime, the decompressed stub lives close beyond the brk().
|
||||||
decompressed stub to work properly at an address that is different
|
In order for the decompressed stub to work properly at an address
|
||||||
from its link-time address, the compiled code must contain no absolute
|
that is different from its link-time address, the compiled code must
|
||||||
addresses. So, the data items in l_lx_elf.c must be only parameters
|
contain no absolute addresses. So, the data items in stub code
|
||||||
and automatic (on-stack) local variables; no global data, no static data,
|
must be only parameters and automatic (on-stack) local variables;
|
||||||
and no string constants. Use "size l_le_n2b.o l_6e_n2b.o" to check
|
no global data, no static data, and no string constants. Also,
|
||||||
that both data and bss have length zero. Also, the '&' operator
|
the '&' operator may not be used to take the address of a function.
|
||||||
may not be used to take the address of a function.
|
|
||||||
|
|
||||||
The address 0x00400000 was chosen to be out of the way of the usual
|
|
||||||
load address 0x08048000, and to minimize fragmentation in kernel
|
|
||||||
page tables; one page of page tables covers 4 MiB. The address
|
|
||||||
0x00401000 was chosen as 1 page up from a 64 KiB boundary, to
|
|
||||||
make the startup code and its constants smaller.
|
|
||||||
|
|
||||||
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
||||||
and Elf32_Phdr, and then uses the Ehdr and Phdrs to control decompression
|
and Elf32_Phdr, and then uses those Ehdr and Phdrs to control decompression
|
||||||
of the PT_LOAD segments.
|
of the PT_LOAD segments. Subroutine do_xmap() of src/stub/src/
|
||||||
Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
i386-linux.elf-main.c performs the
|
||||||
"virtual execve()" using the compressed data as source, and stores
|
"virtual execve()" using the compressed data as source, and stores
|
||||||
the decompressed bytes directly into the appropriate virtual addresses.
|
the decompressed bytes directly into the appropriate virtual addresses.
|
||||||
|
|
||||||
@@ -74,22 +66,17 @@ expanding $ORIGIN in -rpath, or for application code that relies on
|
|||||||
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
||||||
and previous versions did this by default with no option. However,
|
and previous versions did this by default with no option. However,
|
||||||
too much other software erroneously assumes that /proc/self/exe
|
too much other software erroneously assumes that /proc/self/exe
|
||||||
always exists.
|
always exists. upx-4.3.0 made /proc/self/exe optional so that
|
||||||
|
chroot() and related environments can work.
|
||||||
|
For Elf formats, UPX adds an environment variable named " " [three
|
||||||
|
spaces] which saves the results of readlink("/proc/self/exe",,)
|
||||||
|
If /proc/self/exe is ENOENT, then the variable has the same value
|
||||||
|
as its name "/proc/self/exe".
|
||||||
|
|
||||||
On arm*-linux-elf there is no good address at which to retain one
|
All of the above documentation refers to ET_EXEC main programs,
|
||||||
page of the compressed executable. Pages below the usual .p_vaddr
|
which always use the same virtual addresses. An ET_DYN executable
|
||||||
0x8000 (32KiB) are rejected by the kernel. Using a page above the
|
(main program or shared library) follows much the same scheme,
|
||||||
original uncompressed brk(0) would require placing the entire initial
|
re-using the address space that the kernel chose originally.
|
||||||
compressed program above uncompressed brk(0), which would significantly
|
|
||||||
increase the running brk(0); but too many programs break if brk(0)
|
|
||||||
moves. Thus on arm*-linux-elf the compressed executable begins
|
|
||||||
with 0x8000==.p_vaddr, all pages mapped by execve() that are also
|
|
||||||
occupied by decompressed bytes are removed before overwriting, and
|
|
||||||
/proc/self/exe becomes a "(deleted)" symlink. It might be possible
|
|
||||||
to preserve /proc/self/exe if the original uncompressed executable
|
|
||||||
were created with 0x9000==.p_vaddr (one page higher than the usual
|
|
||||||
0x8000) so that the compressed page mapped at 0x8000 would linger.
|
|
||||||
[This has not been tested.]
|
|
||||||
|
|
||||||
Linux stores the pathname argument that was specified to execve()
|
Linux stores the pathname argument that was specified to execve()
|
||||||
immediately after the '\0' which terminates the character string of the
|
immediately after the '\0' which terminates the character string of the
|
||||||
@@ -99,9 +86,24 @@ records a pointer to that character string in Elf32_auxv[AT_EXECFN].
|
|||||||
The pathname is not "bound" to the file as strongly as /proc/self/exe
|
The pathname is not "bound" to the file as strongly as /proc/self/exe
|
||||||
(the file may be changed without affecting the pathname), but the
|
(the file may be changed without affecting the pathname), but the
|
||||||
pathname does provide some information. The pathname may be relative
|
pathname does provide some information. The pathname may be relative
|
||||||
to the working directory, so look before any chdir().
|
to the working directory, so look before performing any chdir().
|
||||||
|
|
||||||
The Elf formats for Linux add an environment variable named " " [three
|
On any page, then SELinux in strictest enforcing mode prohibits
|
||||||
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
simultaneous PROT_EXEC and PROT_WRITE, and also prohibits adding
|
||||||
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
PROT_EXEC if the kernel VMA struct (Virtual Memory Area struct)
|
||||||
for linux/elf386 and linux/ElfAMD.
|
that manages that page ever has had PROT_WRITE. This implies that
|
||||||
|
the only way to get PROT_EXEC is to map the page directly from a file.
|
||||||
|
Therefore, in late 2023 the various decompression stubs are being
|
||||||
|
rewritten to "bounce" the decompressed data through pages in a
|
||||||
|
memory-resident file created by the memfd_create() system call,
|
||||||
|
and subsequently mapped PROT_EXEC. Actual copying of the pages
|
||||||
|
can be avoided by careful sequence mmap() modes, but the overhead
|
||||||
|
of an additional system call is required.
|
||||||
|
|
||||||
|
The not-as-strict "targeted enforcing" mode of
|
||||||
|
SELinux seems not to demand this extra work, except for executables
|
||||||
|
that run with elevated privileges, such as various system daemons.
|
||||||
|
So "ordinary" user-mode apps can run in current "targeted enforcing"
|
||||||
|
mode. But because the actual runtime mode of SELinux is unknown
|
||||||
|
at compression time, then the memfd_create method should be used
|
||||||
|
all the time.
|
||||||
|
|||||||
Generated
+6
-10
@@ -22,7 +22,7 @@
|
|||||||
<h1 id="ABSTRACT">ABSTRACT</h1>
|
<h1 id="ABSTRACT">ABSTRACT</h1>
|
||||||
|
|
||||||
<pre><code> The Ultimate Packer for eXecutables
|
<pre><code> The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io</code></pre>
|
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>
|
<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>
|
||||||
@@ -160,7 +160,7 @@ Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
|||||||
|
|
||||||
<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>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>
|
<p><b>UPX</b> handles overlays like many other executable packers do: it simply copies the overlay after the compressed image. This works with some files, but doesn't work with others, depending on how an application actually accesses this overlaid data.</p>
|
||||||
|
|
||||||
<pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
<pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||||
|
|
||||||
@@ -779,19 +779,15 @@ http://www.oberhumer.com
|
|||||||
|
|
||||||
Laszlo Molnar <ezerotven+github@gmail.com>
|
Laszlo Molnar <ezerotven+github@gmail.com>
|
||||||
|
|
||||||
John F. Reiser <jreiser@BitWagon.com>
|
John F. Reiser <jreiser@BitWagon.com></code></pre>
|
||||||
|
|
||||||
Jens Medoch <jssg@users.sourceforge.net></code></pre>
|
|
||||||
|
|
||||||
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
||||||
|
|
||||||
<p>Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer</p>
|
<p>Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer</p>
|
||||||
|
|
||||||
<p>Copyright (C) 1996-2022 Laszlo Molnar</p>
|
<p>Copyright (C) 1996-2024 Laszlo Molnar</p>
|
||||||
|
|
||||||
<p>Copyright (C) 2000-2022 John F. Reiser</p>
|
<p>Copyright (C) 2000-2024 John F. Reiser</p>
|
||||||
|
|
||||||
<p>Copyright (C) 2002-2022 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><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>
|
||||||
|
|
||||||
|
|||||||
Generated
+5
-9
@@ -6,7 +6,7 @@ SYNOPSIS
|
|||||||
|
|
||||||
ABSTRACT
|
ABSTRACT
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
UPX is a portable, extendable, high-performance executable packer for
|
UPX is a portable, extendable, high-performance executable packer for
|
||||||
@@ -153,7 +153,7 @@ OVERLAY HANDLING OPTIONS
|
|||||||
UPX handles overlays like many other executable packers do: it simply
|
UPX handles overlays like many other executable packers do: it simply
|
||||||
copies the overlay after the compressed image. This works with some
|
copies the overlay after the compressed image. This works with some
|
||||||
files, but doesn't work with others, depending on how an application
|
files, but doesn't work with others, depending on how an application
|
||||||
actually accesses this overlayed data.
|
actually accesses this overlaid data.
|
||||||
|
|
||||||
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||||
|
|
||||||
@@ -815,16 +815,12 @@ AUTHORS
|
|||||||
|
|
||||||
John F. Reiser <jreiser@BitWagon.com>
|
John F. Reiser <jreiser@BitWagon.com>
|
||||||
|
|
||||||
Jens Medoch <jssg@users.sourceforge.net>
|
|
||||||
|
|
||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2022 Jens Medoch
|
|
||||||
|
|
||||||
UPX is distributed with full source code under the terms of the GNU
|
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
|
General Public License v2+; either under the pure GPLv2+ (see the file
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
|
.\" -*- mode: troff; coding: utf-8 -*-
|
||||||
|
.\" Automatically generated by Pod::Man
|
||||||
.\"
|
.\"
|
||||||
.\" Standard preamble:
|
.\" Standard preamble:
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
@@ -15,29 +16,12 @@
|
|||||||
.ft R
|
.ft R
|
||||||
.fi
|
.fi
|
||||||
..
|
..
|
||||||
.\" Set up some character translations and predefined strings. \*(-- will
|
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
|
||||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
|
||||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
|
||||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
|
||||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
|
||||||
.\" nothing in troff, for use with C<>.
|
|
||||||
.tr \(*W-
|
|
||||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
|
||||||
.ie n \{\
|
.ie n \{\
|
||||||
. ds -- \(*W-
|
|
||||||
. ds PI pi
|
|
||||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
|
||||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
|
||||||
. ds L" ""
|
|
||||||
. ds R" ""
|
|
||||||
. ds C` ""
|
. ds C` ""
|
||||||
. ds C' ""
|
. ds C' ""
|
||||||
'br\}
|
'br\}
|
||||||
.el\{\
|
.el\{\
|
||||||
. ds -- \|\(em\|
|
|
||||||
. ds PI \(*p
|
|
||||||
. ds L" ``
|
|
||||||
. ds R" ''
|
|
||||||
. ds C`
|
. ds C`
|
||||||
. ds C'
|
. ds C'
|
||||||
'br\}
|
'br\}
|
||||||
@@ -68,110 +52,48 @@
|
|||||||
. \}
|
. \}
|
||||||
.\}
|
.\}
|
||||||
.rr rF
|
.rr rF
|
||||||
.\"
|
|
||||||
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
|
||||||
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
|
||||||
. \" fudge factors for nroff and troff
|
|
||||||
.if n \{\
|
|
||||||
. ds #H 0
|
|
||||||
. ds #V .8m
|
|
||||||
. ds #F .3m
|
|
||||||
. ds #[ \f1
|
|
||||||
. ds #] \fP
|
|
||||||
.\}
|
|
||||||
.if t \{\
|
|
||||||
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
|
||||||
. ds #V .6m
|
|
||||||
. ds #F 0
|
|
||||||
. ds #[ \&
|
|
||||||
. ds #] \&
|
|
||||||
.\}
|
|
||||||
. \" simple accents for nroff and troff
|
|
||||||
.if n \{\
|
|
||||||
. ds ' \&
|
|
||||||
. ds ` \&
|
|
||||||
. ds ^ \&
|
|
||||||
. ds , \&
|
|
||||||
. ds ~ ~
|
|
||||||
. ds /
|
|
||||||
.\}
|
|
||||||
.if t \{\
|
|
||||||
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
|
||||||
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
|
||||||
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
|
||||||
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
|
||||||
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
|
||||||
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
|
||||||
.\}
|
|
||||||
. \" troff and (daisy-wheel) nroff accents
|
|
||||||
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
|
||||||
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
|
||||||
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
|
||||||
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
|
||||||
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
|
||||||
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
|
||||||
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
|
||||||
.ds ae a\h'-(\w'a'u*4/10)'e
|
|
||||||
.ds Ae A\h'-(\w'A'u*4/10)'E
|
|
||||||
. \" corrections for vroff
|
|
||||||
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
|
||||||
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
|
||||||
. \" for low resolution devices (crt and lpr)
|
|
||||||
.if \n(.H>23 .if \n(.V>19 \
|
|
||||||
\{\
|
|
||||||
. ds : e
|
|
||||||
. ds 8 ss
|
|
||||||
. ds o a
|
|
||||||
. ds d- d\h'-1'\(ga
|
|
||||||
. ds D- D\h'-1'\(hy
|
|
||||||
. ds th \o'bp'
|
|
||||||
. ds Th \o'LP'
|
|
||||||
. ds ae ae
|
|
||||||
. ds Ae AE
|
|
||||||
.\}
|
|
||||||
.rm #[ #] #H #V #F C
|
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "UPX 1"
|
.IX Title "UPX 1"
|
||||||
.TH UPX 1 "2022-10-28" "upx 4.0.0" " "
|
.TH UPX 1 2024-05-09 "upx 4.2.4" " "
|
||||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
.\" way too many mistakes in technical documents.
|
.\" way too many mistakes in technical documents.
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.nh
|
.nh
|
||||||
.SH "NAME"
|
.SH NAME
|
||||||
upx \- compress or expand executable files
|
upx \- compress or expand executable files
|
||||||
.SH "SYNOPSIS"
|
.SH SYNOPSIS
|
||||||
.IX Header "SYNOPSIS"
|
.IX Header "SYNOPSIS"
|
||||||
\&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR...
|
\&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR...
|
||||||
.SH "ABSTRACT"
|
.SH ABSTRACT
|
||||||
.IX Header "ABSTRACT"
|
.IX Header "ABSTRACT"
|
||||||
.Vb 3
|
.Vb 3
|
||||||
\& The Ultimate Packer for eXecutables
|
\& The Ultimate Packer for eXecutables
|
||||||
\& Copyright (c) 1996\-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
\& Copyright (c) 1996\-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
\& https://upx.github.io
|
\& https://upx.github.io
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR is a portable, extendable, high-performance executable packer for
|
\&\fBUPX\fR is a portable, extendable, high-performance executable packer for
|
||||||
several different executable formats. It achieves an excellent compression
|
several different executable formats. It achieves an excellent compression
|
||||||
ratio and offers \fI*very*\fR fast decompression. Your executables suffer
|
ratio and offers \fI*very*\fR 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.
|
||||||
.SH "DISCLAIMER"
|
.SH DISCLAIMER
|
||||||
.IX Header "DISCLAIMER"
|
.IX Header "DISCLAIMER"
|
||||||
\&\fB\s-1UPX\s0\fR comes with \s-1ABSOLUTELY NO WARRANTY\s0; for details see the file \s-1COPYING.\s0
|
\&\fBUPX\fR comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
|
||||||
.PP
|
.PP
|
||||||
Please report all problems or suggestions to the authors. Thanks.
|
Please report all problems or suggestions to the authors. Thanks.
|
||||||
.SH "SECURITY CONTEXT"
|
.SH "SECURITY CONTEXT"
|
||||||
.IX Header "SECURITY CONTEXT"
|
.IX Header "SECURITY CONTEXT"
|
||||||
\&\s-1IMPORTANT NOTE:\s0 \fB\s-1UPX\s0\fR inherits the security context of any files it handles.
|
IMPORTANT NOTE: \fBUPX\fR inherits the security context of any files it handles.
|
||||||
.PP
|
.PP
|
||||||
This means that packing, unpacking, or even testing or listing a file requires
|
This means that packing, unpacking, or even testing or listing a file requires
|
||||||
the same security considerations as actually executing the file.
|
the same security considerations as actually executing the file.
|
||||||
.PP
|
.PP
|
||||||
Use \fB\s-1UPX\s0\fR on trusted files only!
|
Use \fBUPX\fR on trusted files only!
|
||||||
.SH "DESCRIPTION"
|
.SH DESCRIPTION
|
||||||
.IX Header "DESCRIPTION"
|
.IX Header "DESCRIPTION"
|
||||||
\&\fB\s-1UPX\s0\fR is a versatile executable packer with the following features:
|
\&\fBUPX\fR is a versatile executable packer with the following features:
|
||||||
.PP
|
.PP
|
||||||
.Vb 3
|
.Vb 3
|
||||||
\& \- secure: as UPX is documented Open Source since many years any relevant
|
\& \- secure: as UPX is documented Open Source since many years any relevant
|
||||||
@@ -204,32 +126,32 @@ Use \fB\s-1UPX\s0\fR on trusted files only!
|
|||||||
\& for commercial programs
|
\& for commercial programs
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
You probably understand now why we call \fB\s-1UPX\s0\fR the "\fIultimate\fR"
|
You probably understand now why we call \fBUPX\fR the "\fIultimate\fR"
|
||||||
executable packer.
|
executable packer.
|
||||||
.SH "COMMANDS"
|
.SH COMMANDS
|
||||||
.IX Header "COMMANDS"
|
.IX Header "COMMANDS"
|
||||||
.SS "Compress"
|
.SS Compress
|
||||||
.IX Subsection "Compress"
|
.IX Subsection "Compress"
|
||||||
This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file
|
This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file
|
||||||
specified on the command line.
|
specified on the command line.
|
||||||
.SS "Decompress"
|
.SS Decompress
|
||||||
.IX Subsection "Decompress"
|
.IX Subsection "Decompress"
|
||||||
All \fB\s-1UPX\s0\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg.
|
All \fBUPX\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg.
|
||||||
\&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed.
|
\&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed.
|
||||||
.SS "Test"
|
.SS Test
|
||||||
.IX Subsection "Test"
|
.IX Subsection "Test"
|
||||||
The \fB\-t\fR command tests the integrity of the compressed and uncompressed
|
The \fB\-t\fR command tests the integrity of the compressed and uncompressed
|
||||||
data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely
|
data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely
|
||||||
decompressed. Note, that this command doesn't check the whole file, only
|
decompressed. Note, that this command doesn't check the whole file, only
|
||||||
the part that will be uncompressed during program execution. This means
|
the part that will be uncompressed during program execution. This means
|
||||||
that you should not use this command instead of a virus checker.
|
that you should not use this command instead of a virus checker.
|
||||||
.SS "List"
|
.SS List
|
||||||
.IX Subsection "List"
|
.IX Subsection "List"
|
||||||
The \fB\-l\fR command prints out some information about the compressed files
|
The \fB\-l\fR command prints out some information about the compressed files
|
||||||
specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR
|
specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR
|
||||||
shows the compressed / uncompressed size and the compression ratio of
|
shows the compressed / uncompressed size and the compression ratio of
|
||||||
\&\fIyourfile.exe\fR.
|
\&\fIyourfile.exe\fR.
|
||||||
.SH "OPTIONS"
|
.SH OPTIONS
|
||||||
.IX Header "OPTIONS"
|
.IX Header "OPTIONS"
|
||||||
\&\fB\-q\fR: be quiet, suppress warnings
|
\&\fB\-q\fR: be quiet, suppress warnings
|
||||||
.PP
|
.PP
|
||||||
@@ -239,10 +161,10 @@ shows the compressed / uncompressed size and the compression ratio of
|
|||||||
.PP
|
.PP
|
||||||
\&\fB\-\-help\fR: prints the help
|
\&\fB\-\-help\fR: prints the help
|
||||||
.PP
|
.PP
|
||||||
\&\fB\-\-version\fR: print the version of \fB\s-1UPX\s0\fR
|
\&\fB\-\-version\fR: print the version of \fBUPX\fR
|
||||||
.PP
|
.PP
|
||||||
\&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file
|
\&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file
|
||||||
after decompression with option \fB\-d\fR. [\s-1NOTE:\s0 this is work in progress and is
|
after decompression with option \fB\-d\fR. [NOTE: this is work in progress and is
|
||||||
not supported for all formats yet. If you do care, as a workaround you can
|
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 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
|
||||||
@@ -255,16 +177,16 @@ as compared to the first decompressed version.]
|
|||||||
[ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ]
|
[ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ]
|
||||||
.SH "COMPRESSION LEVELS & TUNING"
|
.SH "COMPRESSION LEVELS & TUNING"
|
||||||
.IX Header "COMPRESSION LEVELS & TUNING"
|
.IX Header "COMPRESSION LEVELS & TUNING"
|
||||||
\&\fB\s-1UPX\s0\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR,
|
\&\fBUPX\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR,
|
||||||
and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files
|
and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files
|
||||||
smaller than 512 KiB, and \fB\-7\fR otherwise.
|
smaller than 512 KiB, and \fB\-7\fR otherwise.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Compression levels 1, 2 and 3 are pretty fast.
|
Compression levels 1, 2 and 3 are pretty fast.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Compression levels 4, 5 and 6 achieve a good time/ratio performance.
|
Compression levels 4, 5 and 6 achieve a good time/ratio performance.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Compression levels 7, 8 and 9 favor compression ratio over speed.
|
Compression levels 7, 8 and 9 favor compression ratio over speed.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Compression level \fB\-\-best\fR may take a long time.
|
Compression level \fB\-\-best\fR may take a long time.
|
||||||
.PP
|
.PP
|
||||||
Note that compression level \fB\-\-best\fR can be somewhat slow for large
|
Note that compression level \fB\-\-best\fR can be somewhat slow for large
|
||||||
@@ -272,31 +194,31 @@ files, but you definitely should use it when releasing a final version
|
|||||||
of your program.
|
of your program.
|
||||||
.PP
|
.PP
|
||||||
Quick info for achieving the best compression ratio:
|
Quick info for achieving the best compression ratio:
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even
|
Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even
|
||||||
\&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR.
|
\&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
The option \fB\-\-lzma\fR enables \s-1LZMA\s0 compression, which compresses better but
|
The option \fB\-\-lzma\fR enables LZMA compression, which compresses better but
|
||||||
is *significantly slower* at decompression. You probably do not want
|
is *significantly slower* at decompression. You probably do not want
|
||||||
to use it for large files.
|
to use it for large files.
|
||||||
.Sp
|
.Sp
|
||||||
(Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and
|
(Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and
|
||||||
\&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.)
|
\&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.)
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
Try if \fB\-\-overlay=strip\fR works.
|
Try if \fB\-\-overlay=strip\fR works.
|
||||||
.IP "\(bu" 4
|
.IP \(bu 4
|
||||||
For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below.
|
For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below.
|
||||||
.SH "OVERLAY HANDLING OPTIONS"
|
.SH "OVERLAY HANDLING OPTIONS"
|
||||||
.IX Header "OVERLAY HANDLING OPTIONS"
|
.IX Header "OVERLAY HANDLING OPTIONS"
|
||||||
Info: An \*(L"overlay\*(R" means auxiliary data attached after the logical end of
|
Info: An "overlay" means auxiliary data attached after the logical end of
|
||||||
an executable, and it often contains application specific data
|
an executable, and it often contains application specific data
|
||||||
(this is a common practice to avoid an extra data file, though
|
(this is a common practice to avoid an extra data file, though
|
||||||
it would be better to use resource sections).
|
it would be better to use resource sections).
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR handles overlays like many other executable packers do: it simply
|
\&\fBUPX\fR handles overlays like many other executable packers do: it simply
|
||||||
copies the overlay after the compressed image. This works with some
|
copies the overlay after the compressed image. This works with some
|
||||||
files, but doesn't work with others, depending on how an application
|
files, but doesn't work with others, depending on how an application
|
||||||
actually accesses this overlayed data.
|
actually accesses this overlaid data.
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
\& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
\& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||||
@@ -309,8 +231,8 @@ actually accesses this overlayed data.
|
|||||||
.Ve
|
.Ve
|
||||||
.SH "ENVIRONMENT VARIABLE"
|
.SH "ENVIRONMENT VARIABLE"
|
||||||
.IX Header "ENVIRONMENT VARIABLE"
|
.IX Header "ENVIRONMENT VARIABLE"
|
||||||
The environment variable \fB\s-1UPX\s0\fR can hold a set of default
|
The environment variable \fBUPX\fR can hold a set of default
|
||||||
options for \fB\s-1UPX\s0\fR. These options are interpreted first and
|
options for \fBUPX\fR. These options are interpreted first and
|
||||||
can be overwritten by explicit command line parameters.
|
can be overwritten by explicit command line parameters.
|
||||||
For example:
|
For example:
|
||||||
.PP
|
.PP
|
||||||
@@ -321,18 +243,18 @@ For example:
|
|||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
Under DOS/Windows you must use '#' instead of '=' when setting the
|
Under DOS/Windows you must use '#' instead of '=' when setting the
|
||||||
environment variable because of a \s-1COMMAND.COM\s0 limitation.
|
environment variable because of a COMMAND.COM limitation.
|
||||||
.PP
|
.PP
|
||||||
Not all of the options are valid in the environment variable \-
|
Not all of the options are valid in the environment variable \-
|
||||||
\&\fB\s-1UPX\s0\fR will tell you.
|
\&\fBUPX\fR will tell you.
|
||||||
.PP
|
.PP
|
||||||
You can explicitly use the \fB\-\-no\-env\fR option to ignore the
|
You can explicitly use the \fB\-\-no\-env\fR option to ignore the
|
||||||
environment variable.
|
environment variable.
|
||||||
.SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
.SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
||||||
.IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
.IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
|
||||||
.SS "\s-1NOTES FOR ATARI/TOS\s0"
|
.SS "NOTES FOR ATARI/TOS"
|
||||||
.IX Subsection "NOTES FOR ATARI/TOS"
|
.IX Subsection "NOTES FOR ATARI/TOS"
|
||||||
This is the executable format used by the Atari \s-1ST/TT,\s0 a Motorola 68000
|
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 :\-).
|
||||||
@@ -349,12 +271,12 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default method gives the best results anyway.
|
\& the default method gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR BVMLINUZ/I386\s0"
|
.SS "NOTES FOR BVMLINUZ/I386"
|
||||||
.IX Subsection "NOTES FOR BVMLINUZ/I386"
|
.IX Subsection "NOTES FOR BVMLINUZ/I386"
|
||||||
Same as vmlinuz/i386.
|
Same as vmlinuz/i386.
|
||||||
.SS "\s-1NOTES FOR DOS/COM\s0"
|
.SS "NOTES FOR DOS/COM"
|
||||||
.IX Subsection "NOTES FOR DOS/COM"
|
.IX Subsection "NOTES FOR DOS/COM"
|
||||||
Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from
|
Obviously \fBUPX\fR won't work with executables that want to read data from
|
||||||
themselves (like some commandline utilities that ship with Win95/98/ME).
|
themselves (like some commandline utilities that ship with Win95/98/ME).
|
||||||
.PP
|
.PP
|
||||||
Compressed programs only work on a 286+.
|
Compressed programs only work on a 286+.
|
||||||
@@ -378,11 +300,11 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR DOS/EXE\s0"
|
.SS "NOTES FOR DOS/EXE"
|
||||||
.IX Subsection "NOTES FOR DOS/EXE"
|
.IX Subsection "NOTES FOR DOS/EXE"
|
||||||
dos/exe stands for all \*(L"normal\*(R" 16\-bit \s-1DOS\s0 executables.
|
dos/exe stands for all "normal" 16\-bit DOS executables.
|
||||||
.PP
|
.PP
|
||||||
Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from
|
Obviously \fBUPX\fR won't work with executables that want to read data from
|
||||||
themselves (like some command line utilities that ship with Win95/98/ME).
|
themselves (like some command line utilities that ship with Win95/98/ME).
|
||||||
.PP
|
.PP
|
||||||
Compressed programs only work on a 286+.
|
Compressed programs only work on a 286+.
|
||||||
@@ -399,7 +321,7 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default method gives the best results anyway.
|
\& the default method gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR DOS/SYS\s0"
|
.SS "NOTES FOR DOS/SYS"
|
||||||
.IX Subsection "NOTES FOR DOS/SYS"
|
.IX Subsection "NOTES FOR DOS/SYS"
|
||||||
Compressed programs only work on a 286+.
|
Compressed programs only work on a 286+.
|
||||||
.PP
|
.PP
|
||||||
@@ -422,20 +344,20 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR DJGPP2/COFF\s0"
|
.SS "NOTES FOR DJGPP2/COFF"
|
||||||
.IX Subsection "NOTES FOR DJGPP2/COFF"
|
.IX Subsection "NOTES FOR DJGPP2/COFF"
|
||||||
First of all, it is recommended to use \fB\s-1UPX\s0\fR *instead* of \fBstrip\fR. strip has
|
First of all, it is recommended to use \fBUPX\fR *instead* of \fBstrip\fR. strip has
|
||||||
the very bad habit of replacing your stub with its own (outdated) version.
|
the very bad habit of replacing your stub with its own (outdated) version.
|
||||||
Additionally \fB\s-1UPX\s0\fR corrects a bug/feature in strip v2.8.x: it
|
Additionally \fBUPX\fR corrects a bug/feature in strip v2.8.x: it
|
||||||
will fix the 4 KiB alignment of the stub.
|
will fix the 4 KiB alignment of the stub.
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR includes the full functionality of stubify. This means it will
|
\&\fBUPX\fR includes the full functionality of stubify. This means it will
|
||||||
automatically stubify your \s-1COFF\s0 files. Use the option \fB\-\-coff\fR to
|
automatically stubify your COFF files. Use the option \fB\-\-coff\fR to
|
||||||
disable this functionality (see below).
|
disable this functionality (see below).
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR automatically handles Allegro packfiles.
|
\&\fBUPX\fR automatically handles Allegro packfiles.
|
||||||
.PP
|
.PP
|
||||||
The \s-1DLM\s0 format (a rather exotic shared library extension) is not supported.
|
The DLM format (a rather exotic shared library extension) is not supported.
|
||||||
.PP
|
.PP
|
||||||
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 and trailing garbage will be stripped, though.
|
All debug information and trailing garbage will be stripped, though.
|
||||||
@@ -456,7 +378,7 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR LINUX\s0 [general]"
|
.SS "NOTES FOR LINUX [general]"
|
||||||
.IX Subsection "NOTES FOR LINUX [general]"
|
.IX Subsection "NOTES FOR LINUX [general]"
|
||||||
Introduction
|
Introduction
|
||||||
.PP
|
.PP
|
||||||
@@ -593,15 +515,15 @@ General notes:
|
|||||||
\& been modified after compression.
|
\& been modified after compression.
|
||||||
\& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more.
|
\& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR LINUX/ELF386\s0"
|
.SS "NOTES FOR LINUX/ELF386"
|
||||||
.IX Subsection "NOTES FOR LINUX/ELF386"
|
.IX Subsection "NOTES FOR LINUX/ELF386"
|
||||||
Please read the general Linux description first.
|
Please read the general Linux description first.
|
||||||
.PP
|
.PP
|
||||||
The linux/elf386 format decompresses directly into \s-1RAM,\s0
|
The linux/elf386 format decompresses directly into RAM,
|
||||||
uses only one exec, does not use space in /tmp,
|
uses only one exec, does not use space in /tmp,
|
||||||
and does not use /proc.
|
and does not use /proc.
|
||||||
.PP
|
.PP
|
||||||
Linux/elf386 is automatically selected for Linux \s-1ELF\s0 executables.
|
Linux/elf386 is automatically selected for Linux ELF executables.
|
||||||
.PP
|
.PP
|
||||||
Packed programs will be byte-identical to the original after uncompression.
|
Packed programs will be byte-identical to the original after uncompression.
|
||||||
.PP
|
.PP
|
||||||
@@ -641,12 +563,12 @@ Extra options available for this executable format:
|
|||||||
.Vb 1
|
.Vb 1
|
||||||
\& (none)
|
\& (none)
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR LINUX/SH386\s0"
|
.SS "NOTES FOR LINUX/SH386"
|
||||||
.IX Subsection "NOTES FOR LINUX/SH386"
|
.IX Subsection "NOTES FOR LINUX/SH386"
|
||||||
Please read the general Linux description first.
|
Please read the general Linux description first.
|
||||||
.PP
|
.PP
|
||||||
Shell scripts where the underling shell accepts a ``\-c'' argument
|
Shell scripts where the underling shell accepts a ``\-c'' argument
|
||||||
can use the Linux/sh386 format. \fB\s-1UPX\s0\fR decompresses the shell script
|
can use the Linux/sh386 format. \fBUPX\fR decompresses the shell script
|
||||||
into low memory, then maps the shell and passes the entire text of the
|
into low memory, then maps the shell and passes the entire text of the
|
||||||
script as an argument with a leading ``\-c''.
|
script as an argument with a leading ``\-c''.
|
||||||
It does not use space in /tmp, and does not use /proc.
|
It does not use space in /tmp, and does not use /proc.
|
||||||
@@ -691,7 +613,7 @@ Extra options available for this executable format:
|
|||||||
.Vb 1
|
.Vb 1
|
||||||
\& (none)
|
\& (none)
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR LINUX/386\s0"
|
.SS "NOTES FOR LINUX/386"
|
||||||
.IX Subsection "NOTES FOR LINUX/386"
|
.IX Subsection "NOTES FOR LINUX/386"
|
||||||
Please read the general Linux description first.
|
Please read the general Linux description first.
|
||||||
.PP
|
.PP
|
||||||
@@ -764,10 +686,10 @@ Extra options available for this executable format:
|
|||||||
\& format, i.e. do not try the linux/elf386 and
|
\& format, i.e. do not try the linux/elf386 and
|
||||||
\& linux/sh386 formats.
|
\& linux/sh386 formats.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR PS1/EXE\s0"
|
.SS "NOTES FOR PS1/EXE"
|
||||||
.IX Subsection "NOTES FOR PS1/EXE"
|
.IX Subsection "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 \s-1MIPS R3000\s0 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.
|
||||||
.PP
|
.PP
|
||||||
@@ -816,12 +738,12 @@ Extra options available for this executable format:
|
|||||||
\& but the compressed executable will not boot from a CD.
|
\& but the compressed executable will not boot from a CD.
|
||||||
\& Use it for console transfer only !
|
\& Use it for console transfer only !
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR RTM32/PE\s0 and \s-1ARM/PE\s0"
|
.SS "NOTES FOR RTM32/PE and ARM/PE"
|
||||||
.IX Subsection "NOTES FOR RTM32/PE and ARM/PE"
|
.IX Subsection "NOTES FOR RTM32/PE and ARM/PE"
|
||||||
Same as win32/pe.
|
Same as win32/pe.
|
||||||
.SS "\s-1NOTES FOR TMT/ADAM\s0"
|
.SS "NOTES FOR TMT/ADAM"
|
||||||
.IX Subsection "NOTES FOR TMT/ADAM"
|
.IX Subsection "NOTES FOR TMT/ADAM"
|
||||||
This format is used by the \s-1TMT\s0 Pascal compiler \- see http://www.tmt.com/ .
|
This format is used by the TMT Pascal compiler \- see http://www.tmt.com/ .
|
||||||
.PP
|
.PP
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
.PP
|
.PP
|
||||||
@@ -836,11 +758,11 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR VMLINUZ/386\s0"
|
.SS "NOTES FOR VMLINUZ/386"
|
||||||
.IX Subsection "NOTES FOR VMLINUZ/386"
|
.IX Subsection "NOTES FOR VMLINUZ/386"
|
||||||
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed
|
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed
|
||||||
bootable Linux kernel image (\*(L"vmlinuz\*(R", \*(L"zImage\*(R", \*(L"bzImage\*(R"),
|
bootable Linux kernel image ("vmlinuz", "zImage", "bzImage"),
|
||||||
gzip-decompress it and re-compress it with the \fB\s-1UPX\s0\fR compression method.
|
gzip-decompress it and re-compress it with the \fBUPX\fR compression method.
|
||||||
.PP
|
.PP
|
||||||
vmlinuz/386 is completely unrelated to the other Linux executable
|
vmlinuz/386 is completely unrelated to the other Linux executable
|
||||||
formats, and it does not share any of their drawbacks.
|
formats, and it does not share any of their drawbacks.
|
||||||
@@ -889,14 +811,14 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR WATCOM/LE\s0"
|
.SS "NOTES FOR WATCOM/LE"
|
||||||
.IX Subsection "NOTES FOR WATCOM/LE"
|
.IX Subsection "NOTES FOR WATCOM/LE"
|
||||||
\&\fB\s-1UPX\s0\fR has been successfully tested with the following extenders:
|
\&\fBUPX\fR has been successfully tested with the following extenders:
|
||||||
\s-1DOS4G, DOS4GW, PMODE/W,\s0 DOS32a, CauseWay.
|
DOS4G, DOS4GW, PMODE/W, DOS32a, CauseWay.
|
||||||
The \s-1WDOS/X\s0 extender is partly supported (for details
|
The WDOS/X extender is partly supported (for details
|
||||||
see the file bugs \s-1BUGS\s0).
|
see the file bugs BUGS).
|
||||||
.PP
|
.PP
|
||||||
DLLs and the \s-1LX\s0 format are not supported.
|
DLLs and the LX format are not supported.
|
||||||
.PP
|
.PP
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
.PP
|
.PP
|
||||||
@@ -904,12 +826,12 @@ Extra options available for this executable format:
|
|||||||
\& \-\-le Produce an unbound LE output instead of
|
\& \-\-le Produce an unbound LE output instead of
|
||||||
\& keeping the current stub.
|
\& keeping the current stub.
|
||||||
.Ve
|
.Ve
|
||||||
.SS "\s-1NOTES FOR WIN32/PE\s0"
|
.SS "NOTES FOR WIN32/PE"
|
||||||
.IX Subsection "NOTES FOR WIN32/PE"
|
.IX Subsection "NOTES FOR WIN32/PE"
|
||||||
The \s-1PE\s0 support in \fB\s-1UPX\s0\fR is quite stable now, but probably there are
|
The PE support in \fBUPX\fR is quite stable now, but probably there are
|
||||||
still some incompatibilities with some files.
|
still some incompatibilities with some files.
|
||||||
.PP
|
.PP
|
||||||
Because of the way \fB\s-1UPX\s0\fR (and other packers for this format) works, you
|
Because of the way \fBUPX\fR (and other packers for this format) works, you
|
||||||
can see increased memory usage of your compressed files because the whole
|
can see increased memory usage of your compressed files because the whole
|
||||||
program is loaded into memory at startup.
|
program is loaded into memory at startup.
|
||||||
If you start several instances of huge compressed programs you're
|
If you start several instances of huge compressed programs you're
|
||||||
@@ -922,17 +844,17 @@ smaller, but it's still there.
|
|||||||
If you're running executables from network, then compressed programs
|
If you're running executables from network, then compressed programs
|
||||||
will load faster, and require less bandwidth during execution.
|
will load faster, and require less bandwidth during execution.
|
||||||
.PP
|
.PP
|
||||||
DLLs are supported. But \s-1UPX\s0 compressed DLLs can not share common data and
|
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
|
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
|
is a waste of memory, but compressing the dll plugins of a particular
|
||||||
application may be a better idea.
|
application may be a better idea.
|
||||||
.PP
|
.PP
|
||||||
Screensavers are supported, with the restriction that the filename
|
Screensavers are supported, with the restriction that the filename
|
||||||
must end with \*(L".scr\*(R" (as screensavers are handled slightly different
|
must end with ".scr" (as screensavers are handled slightly different
|
||||||
than normal exe files).
|
than normal exe files).
|
||||||
.PP
|
.PP
|
||||||
\&\s-1UPX\s0 compressed \s-1PE\s0 files have some minor memory overhead (usually in the
|
UPX compressed PE files have some minor memory overhead (usually in the
|
||||||
10 \- 30 KiB range) which can be seen by specifying the \*(L"\-i\*(R" command
|
10 \- 30 KiB range) which can be seen by specifying the "\-i" command
|
||||||
line switch during compression.
|
line switch during compression.
|
||||||
.PP
|
.PP
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
@@ -996,16 +918,16 @@ Extra options available for this executable format:
|
|||||||
\& the compression ratio in some cases, but usually
|
\& the compression ratio in some cases, but usually
|
||||||
\& the default filter gives the best results anyway.
|
\& the default filter gives the best results anyway.
|
||||||
.Ve
|
.Ve
|
||||||
.SH "DIAGNOSTICS"
|
.SH DIAGNOSTICS
|
||||||
.IX Header "DIAGNOSTICS"
|
.IX Header "DIAGNOSTICS"
|
||||||
Exit status is normally 0; if an error occurs, exit status
|
Exit status is normally 0; if an error occurs, exit status
|
||||||
is 1. If a warning occurs, exit status is 2.
|
is 1. If a warning occurs, exit status is 2.
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR's diagnostics are intended to be self-explanatory.
|
\&\fBUPX\fR's diagnostics are intended to be self-explanatory.
|
||||||
.SH "BUGS"
|
.SH BUGS
|
||||||
.IX Header "BUGS"
|
.IX Header "BUGS"
|
||||||
Please report all bugs immediately to the authors.
|
Please report all bugs immediately to the authors.
|
||||||
.SH "AUTHORS"
|
.SH AUTHORS
|
||||||
.IX Header "AUTHORS"
|
.IX Header "AUTHORS"
|
||||||
.Vb 2
|
.Vb 2
|
||||||
\& Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
\& Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||||
@@ -1014,29 +936,25 @@ Please report all bugs immediately to the authors.
|
|||||||
\& Laszlo Molnar <ezerotven+github@gmail.com>
|
\& Laszlo Molnar <ezerotven+github@gmail.com>
|
||||||
\&
|
\&
|
||||||
\& John F. Reiser <jreiser@BitWagon.com>
|
\& John F. Reiser <jreiser@BitWagon.com>
|
||||||
\&
|
|
||||||
\& Jens Medoch <jssg@users.sourceforge.net>
|
|
||||||
.Ve
|
.Ve
|
||||||
.SH "COPYRIGHT"
|
.SH COPYRIGHT
|
||||||
.IX Header "COPYRIGHT"
|
.IX Header "COPYRIGHT"
|
||||||
Copyright (C) 1996\-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996\-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 1996\-2022 Laszlo Molnar
|
Copyright (C) 1996\-2024 Laszlo Molnar
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 2000\-2022 John F. Reiser
|
Copyright (C) 2000\-2024 John F. Reiser
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 2002\-2022 Jens Medoch
|
\&\fBUPX\fR is distributed with full source code under the terms of the
|
||||||
.PP
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
|
the file COPYING), or (at your option) under the GPLv+2 with special
|
||||||
\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
|
|
||||||
the file \s-1COPYING\s0), or (at your option) under the GPLv+2 with special
|
|
||||||
exceptions and restrictions granting the free usage for all binaries
|
exceptions and restrictions granting the free usage for all binaries
|
||||||
including commercial programs (see the file \s-1LICENSE\s0).
|
including commercial programs (see the file LICENSE).
|
||||||
.PP
|
.PP
|
||||||
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 \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
.PP
|
.PP
|
||||||
You should have received a copy of the \s-1UPX\s0 License Agreements along
|
You should have received a copy of the UPX License Agreements along
|
||||||
with this program; see the files \s-1COPYING\s0 and \s-1LICENSE.\s0 If not,
|
with this program; see the files COPYING and LICENSE. If not,
|
||||||
visit the \s-1UPX\s0 home page.
|
visit the UPX home page.
|
||||||
|
|||||||
+5
-9
@@ -13,7 +13,7 @@ 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-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ it would be better to use resource sections).
|
|||||||
B<UPX> handles overlays like many other executable packers do: it simply
|
B<UPX> handles overlays like many other executable packers do: it simply
|
||||||
copies the overlay after the compressed image. This works with some
|
copies the overlay after the compressed image. This works with some
|
||||||
files, but doesn't work with others, depending on how an application
|
files, but doesn't work with others, depending on how an application
|
||||||
actually accesses this overlayed data.
|
actually accesses this overlaid data.
|
||||||
|
|
||||||
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||||
|
|
||||||
@@ -926,19 +926,15 @@ Please report all bugs immediately to the authors.
|
|||||||
|
|
||||||
John F. Reiser <jreiser@BitWagon.com>
|
John F. Reiser <jreiser@BitWagon.com>
|
||||||
|
|
||||||
Jens Medoch <jssg@users.sourceforge.net>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2022 Jens Medoch
|
|
||||||
|
|
||||||
B<UPX> is distributed with full source code under the terms of the
|
B<UPX> is distributed with full source code under the terms of the
|
||||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-branch-clone,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-macro-parentheses,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-core.UndefinedBinaryOperatorResult,
|
||||||
|
-clang-analyzer-core.uninitialized.Assign,
|
||||||
|
-clang-analyzer-security.insecureAPI.strcpy,
|
||||||
|
clang-diagnostic-*,
|
||||||
|
performance-*,
|
||||||
|
FormatStyle: file
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
InheritParentConfig: false
|
||||||
|
...
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-assignment-in-if-condition,
|
||||||
|
-bugprone-casting-through-void,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-inc-dec-in-conditions,
|
||||||
|
-bugprone-macro-parentheses,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-sizeof-expression,
|
||||||
|
-bugprone-suspicious-include,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||||
|
clang-diagnostic-*,
|
||||||
|
performance-*,
|
||||||
|
FormatStyle: file
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
InheritParentConfig: false
|
||||||
|
...
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-assignment-in-if-condition,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-inc-dec-in-conditions,
|
||||||
|
-bugprone-macro-parentheses,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-optin.performance.Padding,
|
||||||
|
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||||
|
clang-diagnostic-*,
|
||||||
|
performance-*,
|
||||||
|
FormatStyle: file
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
InheritParentConfig: false
|
||||||
|
...
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# vim:set ft=yaml ts=2 sw=2 et:
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-assignment-in-if-condition,
|
||||||
|
-bugprone-branch-clone,
|
||||||
|
-bugprone-casting-through-void,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-macro-parentheses,
|
||||||
|
-bugprone-misplaced-widening-cast,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-core.UndefinedBinaryOperatorResult,
|
||||||
|
-clang-analyzer-deadcode.DeadStores,
|
||||||
|
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||||
|
clang-diagnostic-*,
|
||||||
|
performance-*,
|
||||||
|
-performance-no-int-to-ptr,
|
||||||
|
FormatStyle: file
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
InheritParentConfig: false
|
||||||
|
...
|
||||||
Executable
+549
@@ -0,0 +1,549 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ===- run-clang-tidy.py - Parallel clang-tidy runner --------*- python -*--===#
|
||||||
|
#
|
||||||
|
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
# See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
#
|
||||||
|
# ===-----------------------------------------------------------------------===#
|
||||||
|
# FIXME: Integrate with clang-tidy-diff.py
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Parallel clang-tidy runner
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Runs clang-tidy over all files in a compilation database. Requires clang-tidy
|
||||||
|
and clang-apply-replacements in $PATH.
|
||||||
|
|
||||||
|
Example invocations.
|
||||||
|
- Run clang-tidy on all files in the current working directory with a default
|
||||||
|
set of checks and show warnings in the cpp files and all project headers.
|
||||||
|
run-clang-tidy.py $PWD
|
||||||
|
|
||||||
|
- Fix all header guards.
|
||||||
|
run-clang-tidy.py -fix -checks=-*,llvm-header-guard
|
||||||
|
|
||||||
|
- Fix all header guards included from clang-tidy and header guards
|
||||||
|
for clang-tidy headers.
|
||||||
|
run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \
|
||||||
|
-header-filter=extra/clang-tidy
|
||||||
|
|
||||||
|
Compilation database setup:
|
||||||
|
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
|
import queue
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import threading
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
try:
|
||||||
|
import yaml
|
||||||
|
except ImportError:
|
||||||
|
yaml = None
|
||||||
|
|
||||||
|
|
||||||
|
def strtobool(val):
|
||||||
|
"""Convert a string representation of truth to a bool following LLVM's CLI argument parsing."""
|
||||||
|
|
||||||
|
val = val.lower()
|
||||||
|
if val in ["", "true", "1"]:
|
||||||
|
return True
|
||||||
|
elif val in ["false", "0"]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Return ArgumentTypeError so that argparse does not substitute its own error message
|
||||||
|
raise argparse.ArgumentTypeError(
|
||||||
|
"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_compilation_database(path):
|
||||||
|
"""Adjusts the directory until a compilation database is found."""
|
||||||
|
result = os.path.realpath("./")
|
||||||
|
while not os.path.isfile(os.path.join(result, path)):
|
||||||
|
parent = os.path.dirname(result)
|
||||||
|
if result == parent:
|
||||||
|
print("Error: could not find compilation database.")
|
||||||
|
sys.exit(1)
|
||||||
|
result = parent
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def make_absolute(f, directory):
|
||||||
|
if os.path.isabs(f):
|
||||||
|
return f
|
||||||
|
return os.path.normpath(os.path.join(directory, f))
|
||||||
|
|
||||||
|
|
||||||
|
def get_tidy_invocation(
|
||||||
|
f,
|
||||||
|
clang_tidy_binary,
|
||||||
|
checks,
|
||||||
|
tmpdir,
|
||||||
|
build_path,
|
||||||
|
header_filter,
|
||||||
|
allow_enabling_alpha_checkers,
|
||||||
|
extra_arg,
|
||||||
|
extra_arg_before,
|
||||||
|
quiet,
|
||||||
|
config_file_path,
|
||||||
|
config,
|
||||||
|
line_filter,
|
||||||
|
use_color,
|
||||||
|
plugins,
|
||||||
|
warnings_as_errors,
|
||||||
|
):
|
||||||
|
"""Gets a command line for clang-tidy."""
|
||||||
|
start = [clang_tidy_binary]
|
||||||
|
if allow_enabling_alpha_checkers:
|
||||||
|
start.append("-allow-enabling-analyzer-alpha-checkers")
|
||||||
|
if header_filter is not None:
|
||||||
|
start.append("-header-filter=" + header_filter)
|
||||||
|
if line_filter is not None:
|
||||||
|
start.append("-line-filter=" + line_filter)
|
||||||
|
if use_color is not None:
|
||||||
|
if use_color:
|
||||||
|
start.append("--use-color")
|
||||||
|
else:
|
||||||
|
start.append("--use-color=false")
|
||||||
|
if checks:
|
||||||
|
start.append("-checks=" + checks)
|
||||||
|
if tmpdir is not None:
|
||||||
|
start.append("-export-fixes")
|
||||||
|
# Get a temporary file. We immediately close the handle so clang-tidy can
|
||||||
|
# overwrite it.
|
||||||
|
(handle, name) = tempfile.mkstemp(suffix=".yaml", dir=tmpdir)
|
||||||
|
os.close(handle)
|
||||||
|
start.append(name)
|
||||||
|
for arg in extra_arg:
|
||||||
|
start.append("-extra-arg=%s" % arg)
|
||||||
|
for arg in extra_arg_before:
|
||||||
|
start.append("-extra-arg-before=%s" % arg)
|
||||||
|
start.append("-p=" + build_path)
|
||||||
|
if quiet:
|
||||||
|
start.append("-quiet")
|
||||||
|
if config_file_path:
|
||||||
|
start.append("--config-file=" + config_file_path)
|
||||||
|
elif config:
|
||||||
|
start.append("-config=" + config)
|
||||||
|
for plugin in plugins:
|
||||||
|
start.append("-load=" + plugin)
|
||||||
|
if warnings_as_errors:
|
||||||
|
start.append("--warnings-as-errors=" + warnings_as_errors)
|
||||||
|
start.append(f)
|
||||||
|
return start
|
||||||
|
|
||||||
|
|
||||||
|
def merge_replacement_files(tmpdir, mergefile):
|
||||||
|
"""Merge all replacement files in a directory into a single file"""
|
||||||
|
# The fixes suggested by clang-tidy >= 4.0.0 are given under
|
||||||
|
# the top level key 'Diagnostics' in the output yaml files
|
||||||
|
mergekey = "Diagnostics"
|
||||||
|
merged = []
|
||||||
|
for replacefile in glob.iglob(os.path.join(tmpdir, "*.yaml")):
|
||||||
|
content = yaml.safe_load(open(replacefile, "r"))
|
||||||
|
if not content:
|
||||||
|
continue # Skip empty files.
|
||||||
|
merged.extend(content.get(mergekey, []))
|
||||||
|
|
||||||
|
if merged:
|
||||||
|
# MainSourceFile: The key is required by the definition inside
|
||||||
|
# include/clang/Tooling/ReplacementsYaml.h, but the value
|
||||||
|
# is actually never used inside clang-apply-replacements,
|
||||||
|
# so we set it to '' here.
|
||||||
|
output = {"MainSourceFile": "", mergekey: merged}
|
||||||
|
with open(mergefile, "w") as out:
|
||||||
|
yaml.safe_dump(output, out)
|
||||||
|
else:
|
||||||
|
# Empty the file:
|
||||||
|
open(mergefile, "w").close()
|
||||||
|
|
||||||
|
|
||||||
|
def find_binary(arg, name, build_path):
|
||||||
|
"""Get the path for a binary or exit"""
|
||||||
|
if arg:
|
||||||
|
if shutil.which(arg):
|
||||||
|
return arg
|
||||||
|
else:
|
||||||
|
raise SystemExit(
|
||||||
|
"error: passed binary '{}' was not found or is not executable".format(
|
||||||
|
arg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
built_path = os.path.join(build_path, "bin", name)
|
||||||
|
binary = shutil.which(name) or shutil.which(built_path)
|
||||||
|
if binary:
|
||||||
|
return binary
|
||||||
|
else:
|
||||||
|
raise SystemExit(
|
||||||
|
"error: failed to find {} in $PATH or at {}".format(name, built_path)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def apply_fixes(args, clang_apply_replacements_binary, tmpdir):
|
||||||
|
"""Calls clang-apply-fixes on a given directory."""
|
||||||
|
invocation = [clang_apply_replacements_binary]
|
||||||
|
invocation.append("-ignore-insert-conflict")
|
||||||
|
if args.format:
|
||||||
|
invocation.append("-format")
|
||||||
|
if args.style:
|
||||||
|
invocation.append("-style=" + args.style)
|
||||||
|
invocation.append(tmpdir)
|
||||||
|
subprocess.call(invocation)
|
||||||
|
|
||||||
|
|
||||||
|
def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files):
|
||||||
|
"""Takes filenames out of queue and runs clang-tidy on them."""
|
||||||
|
while True:
|
||||||
|
name = queue.get()
|
||||||
|
invocation = get_tidy_invocation(
|
||||||
|
name,
|
||||||
|
clang_tidy_binary,
|
||||||
|
args.checks,
|
||||||
|
tmpdir,
|
||||||
|
build_path,
|
||||||
|
args.header_filter,
|
||||||
|
args.allow_enabling_alpha_checkers,
|
||||||
|
args.extra_arg,
|
||||||
|
args.extra_arg_before,
|
||||||
|
args.quiet,
|
||||||
|
args.config_file,
|
||||||
|
args.config,
|
||||||
|
args.line_filter,
|
||||||
|
args.use_color,
|
||||||
|
args.plugins,
|
||||||
|
args.warnings_as_errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
|
output, err = proc.communicate()
|
||||||
|
if proc.returncode != 0:
|
||||||
|
if proc.returncode < 0:
|
||||||
|
msg = "%s: terminated by signal %d\n" % (name, -proc.returncode)
|
||||||
|
err += msg.encode("utf-8")
|
||||||
|
failed_files.append(name)
|
||||||
|
with lock:
|
||||||
|
sys.stdout.write(" ".join(invocation) + "\n" + output.decode("utf-8"))
|
||||||
|
if len(err) > 0:
|
||||||
|
sys.stdout.flush()
|
||||||
|
sys.stderr.write(err.decode("utf-8"))
|
||||||
|
queue.task_done()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Runs clang-tidy over all files "
|
||||||
|
"in a compilation database. Requires "
|
||||||
|
"clang-tidy and clang-apply-replacements in "
|
||||||
|
"$PATH or in your build directory."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-allow-enabling-alpha-checkers",
|
||||||
|
action="store_true",
|
||||||
|
help="allow alpha checkers from clang-analyzer.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-clang-apply-replacements-binary",
|
||||||
|
metavar="PATH",
|
||||||
|
help="path to clang-apply-replacements binary",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-checks",
|
||||||
|
default=None,
|
||||||
|
help="checks filter, when not specified, use clang-tidy default",
|
||||||
|
)
|
||||||
|
config_group = parser.add_mutually_exclusive_group()
|
||||||
|
config_group.add_argument(
|
||||||
|
"-config",
|
||||||
|
default=None,
|
||||||
|
help="Specifies a configuration in YAML/JSON format: "
|
||||||
|
" -config=\"{Checks: '*', "
|
||||||
|
' CheckOptions: {x: y}}" '
|
||||||
|
"When the value is empty, clang-tidy will "
|
||||||
|
"attempt to find a file named .clang-tidy for "
|
||||||
|
"each source file in its parent directories.",
|
||||||
|
)
|
||||||
|
config_group.add_argument(
|
||||||
|
"-config-file",
|
||||||
|
default=None,
|
||||||
|
help="Specify the path of .clang-tidy or custom config "
|
||||||
|
"file: e.g. -config-file=/some/path/myTidyConfigFile. "
|
||||||
|
"This option internally works exactly the same way as "
|
||||||
|
"-config option after reading specified config file. "
|
||||||
|
"Use either -config-file or -config, not both.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-header-filter",
|
||||||
|
default=None,
|
||||||
|
help="regular expression matching the names of the "
|
||||||
|
"headers to output diagnostics from. Diagnostics from "
|
||||||
|
"the main file of each translation unit are always "
|
||||||
|
"displayed.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-line-filter",
|
||||||
|
default=None,
|
||||||
|
help="List of files with line ranges to filter the warnings.",
|
||||||
|
)
|
||||||
|
if yaml:
|
||||||
|
parser.add_argument(
|
||||||
|
"-export-fixes",
|
||||||
|
metavar="file_or_directory",
|
||||||
|
dest="export_fixes",
|
||||||
|
help="A directory or a yaml file to store suggested fixes in, "
|
||||||
|
"which can be applied with clang-apply-replacements. If the "
|
||||||
|
"parameter is a directory, the fixes of each compilation unit are "
|
||||||
|
"stored in individual yaml files in the directory.",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
parser.add_argument(
|
||||||
|
"-export-fixes",
|
||||||
|
metavar="directory",
|
||||||
|
dest="export_fixes",
|
||||||
|
help="A directory to store suggested fixes in, which can be applied "
|
||||||
|
"with clang-apply-replacements. The fixes of each compilation unit are "
|
||||||
|
"stored in individual yaml files in the directory.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-j",
|
||||||
|
type=int,
|
||||||
|
default=0,
|
||||||
|
help="number of tidy instances to be run in parallel.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"files", nargs="*", default=[".*"], help="files to be processed (regex on path)"
|
||||||
|
)
|
||||||
|
parser.add_argument("-fix", action="store_true", help="apply fix-its")
|
||||||
|
parser.add_argument(
|
||||||
|
"-format", action="store_true", help="Reformat code after applying fixes"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-style",
|
||||||
|
default="file",
|
||||||
|
help="The style of reformat code after applying fixes",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-use-color",
|
||||||
|
type=strtobool,
|
||||||
|
nargs="?",
|
||||||
|
const=True,
|
||||||
|
help="Use colors in diagnostics, overriding clang-tidy's"
|
||||||
|
" default behavior. This option overrides the 'UseColor"
|
||||||
|
"' option in .clang-tidy file, if any.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-p", dest="build_path", help="Path used to read a compile command database."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-extra-arg",
|
||||||
|
dest="extra_arg",
|
||||||
|
action="append",
|
||||||
|
default=[],
|
||||||
|
help="Additional argument to append to the compiler command line.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-extra-arg-before",
|
||||||
|
dest="extra_arg_before",
|
||||||
|
action="append",
|
||||||
|
default=[],
|
||||||
|
help="Additional argument to prepend to the compiler command line.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-quiet", action="store_true", help="Run clang-tidy in quiet mode"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-load",
|
||||||
|
dest="plugins",
|
||||||
|
action="append",
|
||||||
|
default=[],
|
||||||
|
help="Load the specified plugin in clang-tidy.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-warnings-as-errors",
|
||||||
|
default=None,
|
||||||
|
help="Upgrades warnings to errors. Same format as '-checks'",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
db_path = "compile_commands.json"
|
||||||
|
|
||||||
|
if args.build_path is not None:
|
||||||
|
build_path = args.build_path
|
||||||
|
else:
|
||||||
|
# Find our database
|
||||||
|
build_path = find_compilation_database(db_path)
|
||||||
|
|
||||||
|
clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path)
|
||||||
|
|
||||||
|
if args.fix:
|
||||||
|
clang_apply_replacements_binary = find_binary(
|
||||||
|
args.clang_apply_replacements_binary, "clang-apply-replacements", build_path
|
||||||
|
)
|
||||||
|
|
||||||
|
combine_fixes = False
|
||||||
|
export_fixes_dir = None
|
||||||
|
delete_fixes_dir = False
|
||||||
|
if args.export_fixes is not None:
|
||||||
|
# if a directory is given, create it if it does not exist
|
||||||
|
if args.export_fixes.endswith(os.path.sep) and not os.path.isdir(
|
||||||
|
args.export_fixes
|
||||||
|
):
|
||||||
|
os.makedirs(args.export_fixes)
|
||||||
|
|
||||||
|
if not os.path.isdir(args.export_fixes):
|
||||||
|
if not yaml:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Cannot combine fixes in one yaml file. Either install PyYAML or specify an output directory."
|
||||||
|
)
|
||||||
|
|
||||||
|
combine_fixes = True
|
||||||
|
|
||||||
|
if os.path.isdir(args.export_fixes):
|
||||||
|
export_fixes_dir = args.export_fixes
|
||||||
|
|
||||||
|
if export_fixes_dir is None and (args.fix or combine_fixes):
|
||||||
|
export_fixes_dir = tempfile.mkdtemp()
|
||||||
|
delete_fixes_dir = True
|
||||||
|
|
||||||
|
# Load the database and extract all files.
|
||||||
|
database = json.load(open(os.path.join(build_path, db_path)))
|
||||||
|
files = set(
|
||||||
|
[make_absolute(entry["file"], entry["directory"]) for entry in database]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build up a big regexy filter from all command line arguments.
|
||||||
|
file_name_re = re.compile("|".join(args.files))
|
||||||
|
|
||||||
|
# filter files with mo.group(0), and sort files
|
||||||
|
matched_files = []
|
||||||
|
for name in files:
|
||||||
|
mo = file_name_re.search(name)
|
||||||
|
if mo and mo.group(0):
|
||||||
|
matched_files.append(name)
|
||||||
|
files = sorted(matched_files)
|
||||||
|
if not files:
|
||||||
|
if delete_fixes_dir:
|
||||||
|
shutil.rmtree(export_fixes_dir)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
invocation = get_tidy_invocation(
|
||||||
|
"",
|
||||||
|
clang_tidy_binary,
|
||||||
|
args.checks,
|
||||||
|
None,
|
||||||
|
build_path,
|
||||||
|
args.header_filter,
|
||||||
|
args.allow_enabling_alpha_checkers,
|
||||||
|
args.extra_arg,
|
||||||
|
args.extra_arg_before,
|
||||||
|
args.quiet,
|
||||||
|
args.config_file,
|
||||||
|
args.config,
|
||||||
|
args.line_filter,
|
||||||
|
args.use_color,
|
||||||
|
args.plugins,
|
||||||
|
args.warnings_as_errors,
|
||||||
|
)
|
||||||
|
invocation.append("-list-checks")
|
||||||
|
invocation.append("-")
|
||||||
|
if args.quiet:
|
||||||
|
# Even with -quiet we still want to check if we can call clang-tidy.
|
||||||
|
with open(os.devnull, "w") as dev_null:
|
||||||
|
subprocess.check_call(invocation, stdout=dev_null)
|
||||||
|
else:
|
||||||
|
subprocess.check_call(invocation)
|
||||||
|
except:
|
||||||
|
print("Unable to run clang-tidy.", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
max_task = args.j
|
||||||
|
if max_task == 0:
|
||||||
|
max_task = multiprocessing.cpu_count()
|
||||||
|
|
||||||
|
return_code = 0
|
||||||
|
try:
|
||||||
|
# Spin up a bunch of tidy-launching threads.
|
||||||
|
task_queue = queue.Queue(max_task)
|
||||||
|
# List of files with a non-zero return code.
|
||||||
|
failed_files = []
|
||||||
|
lock = threading.Lock()
|
||||||
|
for _ in range(max_task):
|
||||||
|
t = threading.Thread(
|
||||||
|
target=run_tidy,
|
||||||
|
args=(
|
||||||
|
args,
|
||||||
|
clang_tidy_binary,
|
||||||
|
export_fixes_dir,
|
||||||
|
build_path,
|
||||||
|
task_queue,
|
||||||
|
lock,
|
||||||
|
failed_files,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
# Fill the queue with files.
|
||||||
|
for name in files:
|
||||||
|
if file_name_re.search(name):
|
||||||
|
task_queue.put(name)
|
||||||
|
|
||||||
|
# Wait for all threads to be done.
|
||||||
|
task_queue.join()
|
||||||
|
if len(failed_files):
|
||||||
|
return_code = 1
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
# This is a sad hack. Unfortunately subprocess goes
|
||||||
|
# bonkers with ctrl-c and we start forking merrily.
|
||||||
|
print("\nCtrl-C detected, goodbye.")
|
||||||
|
if delete_fixes_dir:
|
||||||
|
shutil.rmtree(export_fixes_dir)
|
||||||
|
os.kill(0, 9)
|
||||||
|
|
||||||
|
if combine_fixes:
|
||||||
|
print("Writing fixes to " + args.export_fixes + " ...")
|
||||||
|
try:
|
||||||
|
merge_replacement_files(export_fixes_dir, args.export_fixes)
|
||||||
|
except:
|
||||||
|
print("Error exporting fixes.\n", file=sys.stderr)
|
||||||
|
traceback.print_exc()
|
||||||
|
return_code = 1
|
||||||
|
|
||||||
|
if args.fix:
|
||||||
|
print("Applying fixes ...")
|
||||||
|
try:
|
||||||
|
apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir)
|
||||||
|
except:
|
||||||
|
print("Error applying fixes.\n", file=sys.stderr)
|
||||||
|
traceback.print_exc()
|
||||||
|
return_code = 1
|
||||||
|
|
||||||
|
if delete_fixes_dir:
|
||||||
|
shutil.rmtree(export_fixes_dir)
|
||||||
|
sys.exit(return_code)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,382 @@
|
|||||||
|
#
|
||||||
|
# UPX "CMake" build file; see https://cmake.org/
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
# set USE_STRICT_DEFAULTS
|
||||||
|
if(NOT DEFINED USE_STRICT_DEFAULTS AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/use_strict_defaults.cmake" OPTIONAL)
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED USE_STRICT_DEFAULTS)
|
||||||
|
# use permissive config defaults when building from source code tarball
|
||||||
|
set(USE_STRICT_DEFAULTS FALSE CACHE INTERNAL "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# macros
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# support config hooks; developer convenience
|
||||||
|
macro(upx_cmake_include_hook section)
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/hooks/CMakeLists.${section}.txt" OPTIONAL)
|
||||||
|
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.${section}.txt" OPTIONAL)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Disallow in-source build. Note that you will still have to manually
|
||||||
|
# clean up a few files if you accidentally try an in-source build.
|
||||||
|
macro(upx_disallow_in_source_build)
|
||||||
|
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||||
|
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||||
|
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
|
||||||
|
# try to clean up (does not work)
|
||||||
|
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt")
|
||||||
|
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache")
|
||||||
|
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# set the default build type; must be called before project() cmake init
|
||||||
|
macro(upx_set_default_build_type type)
|
||||||
|
set(upx_global_default_build_type "${type}")
|
||||||
|
get_property(upx_global_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(NOT upx_global_is_multi_config AND NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "${upx_global_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# set the default multi-config build type; must be called after project() cmake init
|
||||||
|
macro(upx_apply_build_type)
|
||||||
|
if(upx_global_is_multi_config)
|
||||||
|
set(c "${CMAKE_CONFIGURATION_TYPES}")
|
||||||
|
list(INSERT c 0 "${upx_global_default_build_type}")
|
||||||
|
if(CMAKE_BUILD_TYPE)
|
||||||
|
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
|
||||||
|
endif()
|
||||||
|
list(REMOVE_DUPLICATES c)
|
||||||
|
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
|
||||||
|
endif()
|
||||||
|
# now also set the build type for use in try_compile()
|
||||||
|
if(NOT CMAKE_TRY_COMPILE_CONFIGURATION)
|
||||||
|
if(CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
|
||||||
|
else()
|
||||||
|
set(CMAKE_TRY_COMPILE_CONFIGURATION "${upx_global_default_build_type}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# ternary conditional operator
|
||||||
|
macro(upx_ternary result_var_name condition true_value false_value)
|
||||||
|
if(${condition})
|
||||||
|
set(${result_var_name} "${true_value}")
|
||||||
|
else()
|
||||||
|
set(${result_var_name} "${false_value}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# util
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# convert to CMake bool
|
||||||
|
function(upx_make_bool_var result_var_name var_name default_value)
|
||||||
|
set(result "${default_value}")
|
||||||
|
# only query $var_name if it is defined and not empty
|
||||||
|
if(NOT ",${var_name}," STREQUAL ",,")
|
||||||
|
if(DEFINED ${var_name})
|
||||||
|
if(NOT ",${${var_name}}," STREQUAL ",,")
|
||||||
|
set(result "${${var_name}}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(${result})
|
||||||
|
set(result ON)
|
||||||
|
else()
|
||||||
|
set(result OFF)
|
||||||
|
endif()
|
||||||
|
set(${result_var_name} "${result}" PARENT_SCOPE) # return value
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_print_var) # ARGV
|
||||||
|
foreach(var_name ${ARGV})
|
||||||
|
if(DEFINED ${var_name})
|
||||||
|
if(NOT ",${${var_name}}," STREQUAL ",,")
|
||||||
|
if(${var_name})
|
||||||
|
message(STATUS "${var_name} = ${${var_name}}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_print_env_var) # ARGV
|
||||||
|
foreach(var_name ${ARGV})
|
||||||
|
if(DEFINED ENV{${var_name}})
|
||||||
|
if(NOT ",$ENV{${var_name}}," STREQUAL ",,")
|
||||||
|
message(STATUS "ENV{${var_name}} = '$ENV{${var_name}}'")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_print_have_symbol) # ARGV; needs include(CheckSymbolExists)
|
||||||
|
set(rq "${CMAKE_REQUIRED_QUIET}")
|
||||||
|
set(CMAKE_REQUIRED_QUIET ON)
|
||||||
|
foreach(symbol ${ARGV})
|
||||||
|
set(cache_var_name "HAVE_symbol_${symbol}")
|
||||||
|
check_symbol_exists("${symbol}" "limits.h;stddef.h;stdint.h" "${cache_var_name}")
|
||||||
|
if(${cache_var_name})
|
||||||
|
message(STATUS "HAVE_symbol ${symbol}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(CMAKE_REQUIRED_QUIET "${rq}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# examine compiler configuration
|
||||||
|
function(upx_print_common_symbols)
|
||||||
|
upx_print_have_symbol(__FAST_MATH__)
|
||||||
|
upx_print_have_symbol(__PIC__ __pic__ __PIE__ __pie__)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# examine MinGW/Cygwin compiler configuration
|
||||||
|
function(upx_print_mingw_symbols)
|
||||||
|
if(WIN32 OR MINGW OR CYGWIN)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)")
|
||||||
|
# runtime library: msvcrt vs ucrt vs cygwin
|
||||||
|
upx_print_have_symbol(__CRTDLL__ __CYGWIN__ __CYGWIN32__ __CYGWIN64__ __MINGW32__ __MINGW64__ __MINGW64_VERSION_MAJOR __MSVCRT__ __MSVCRT_VERSION__ _UCRT _WIN32 _WIN32_WINNT _WIN64)
|
||||||
|
# exception handing: SJLJ (setjmp/longjmp) vs DWARF vs SEH
|
||||||
|
upx_print_have_symbol(__GCC_HAVE_DWARF2_CFI_ASM __SEH__ __USING_SJLJ_EXCEPTIONS__)
|
||||||
|
# threads: win32 vs posix/pthread/winpthreads vs mcfgthread
|
||||||
|
upx_print_have_symbol(_REENTRANT __USING_MCFGTHREAD__)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# add wildcard expansions to a variable
|
||||||
|
function(upx_add_glob_files) # ARGV
|
||||||
|
set(var_name ${ARGV0})
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS "3.3")
|
||||||
|
file(GLOB files ${ARGV})
|
||||||
|
else()
|
||||||
|
file(GLOB files LIST_DIRECTORIES false ${ARGV})
|
||||||
|
endif()
|
||||||
|
set(result "")
|
||||||
|
if(DEFINED ${var_name})
|
||||||
|
set(result "${${var_name}}")
|
||||||
|
endif()
|
||||||
|
list(APPEND result "${files}")
|
||||||
|
list(SORT result)
|
||||||
|
list(REMOVE_DUPLICATES result)
|
||||||
|
#message(STATUS "upx_add_glob_files: ${var_name} = ${result}")
|
||||||
|
set(${var_name} "${result}" PARENT_SCOPE) # return value
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# remove wildcard expansions from a variable
|
||||||
|
function(upx_remove_glob_files) # ARGV
|
||||||
|
set(var_name ${ARGV0})
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
file(GLOB files ${ARGV})
|
||||||
|
set(result "")
|
||||||
|
if(DEFINED ${var_name})
|
||||||
|
set(result "${${var_name}}")
|
||||||
|
foreach(file ${files})
|
||||||
|
list(REMOVE_ITEM result "${file}")
|
||||||
|
endforeach()
|
||||||
|
list(SORT result)
|
||||||
|
list(REMOVE_DUPLICATES result)
|
||||||
|
endif()
|
||||||
|
#message(STATUS "upx_remove_glob_files: ${var_name} = ${result}")
|
||||||
|
set(${var_name} "${result}" PARENT_SCOPE) # return value
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# useful for CI jobs: allow settings via environment and cache result
|
||||||
|
function(upx_cache_bool_vars) # ARGV
|
||||||
|
set(default_value "${ARGV0}")
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
foreach(var_name ${ARGV})
|
||||||
|
set(value ${default_value})
|
||||||
|
if(DEFINED UPX_CACHE_VALUE_${var_name}) # check cache
|
||||||
|
set(value "${UPX_CACHE_VALUE_${var_name}}")
|
||||||
|
elseif(DEFINED ${var_name}) # defined via "cmake -DXXX=YYY"
|
||||||
|
set(value "${${var_name}}")
|
||||||
|
elseif(DEFINED ENV{${var_name}}) # check environment
|
||||||
|
if("$ENV{${var_name}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE|off|on|false|true)$")
|
||||||
|
set(value "$ENV{${var_name}}")
|
||||||
|
set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for status message below
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
# convert to bool
|
||||||
|
if(value)
|
||||||
|
set(value ON)
|
||||||
|
else()
|
||||||
|
set(value OFF)
|
||||||
|
endif()
|
||||||
|
# store result
|
||||||
|
if(UPX_CACHE_ORIGIN_FROM_ENV_${var_name})
|
||||||
|
message(STATUS "setting from environment: ${var_name} = ${value}")
|
||||||
|
endif()
|
||||||
|
set(${var_name} "${value}" PARENT_SCOPE) # store result
|
||||||
|
set(UPX_CACHE_VALUE_${var_name} "${value}" CACHE INTERNAL "" FORCE) # and store in cache
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_platform_check_mismatch var_name_1 var_name_2)
|
||||||
|
if(DEFINED ${var_name_1} OR DEFINED ${var_name_2})
|
||||||
|
if(NOT ",${${var_name_1}}," STREQUAL ",${${var_name_2}},")
|
||||||
|
if(UPX_CONFIG_DISABLE_WERROR)
|
||||||
|
message(WARNING "WARNING: '${var_name_1}' '${var_name_2}' mismatch")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "FATAL ERROR: '${var_name_1}' '${var_name_2}' mismatch")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# compilation flags
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
function(upx_internal_add_definitions_with_prefix) # ARGV; needs include(CheckCCompilerFlag)
|
||||||
|
set(flag_prefix "${ARGV0}")
|
||||||
|
if("${flag_prefix}" MATCHES "^empty$") # need "empty" to work around bug in old CMake versions
|
||||||
|
set(flag_prefix "")
|
||||||
|
endif()
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
set(failed "")
|
||||||
|
foreach(f ${ARGV})
|
||||||
|
set(flag "${flag_prefix}${f}")
|
||||||
|
string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" cache_var_name "HAVE_CFLAG_${flag}")
|
||||||
|
check_c_compiler_flag("${flag}" ${cache_var_name})
|
||||||
|
if(${cache_var_name})
|
||||||
|
#message(STATUS "add_definitions: ${flag}")
|
||||||
|
add_definitions("${flag}")
|
||||||
|
else()
|
||||||
|
list(APPEND failed "${f}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(failed_flags "${failed}" PARENT_SCOPE) # return value
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_add_definitions) # ARGV; needs include(CheckCCompilerFlag)
|
||||||
|
set(failed_flags "")
|
||||||
|
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
# for clang-cl try "-clang:" flag prefix first
|
||||||
|
upx_internal_add_definitions_with_prefix("-clang:" ${ARGV})
|
||||||
|
upx_internal_add_definitions_with_prefix("empty" ${failed_flags})
|
||||||
|
else()
|
||||||
|
upx_internal_add_definitions_with_prefix("empty" ${ARGV})
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# useful for CI jobs: allow target extra compile options
|
||||||
|
function(upx_add_target_extra_compile_options) # ARGV
|
||||||
|
set(t "${ARGV0}")
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
foreach(var_name ${ARGV})
|
||||||
|
if(NOT DEFINED ${var_name})
|
||||||
|
elseif(",${${var_name}}," STREQUAL ",,")
|
||||||
|
else()
|
||||||
|
set(flags "${${var_name}}")
|
||||||
|
if(NOT flags MATCHES ";") # NOTE: split into list from string only if not already a list
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER "3.8.99")
|
||||||
|
separate_arguments(flags NATIVE_COMMAND "${flags}")
|
||||||
|
else()
|
||||||
|
separate_arguments(flags)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
target_compile_options(${t} PRIVATE "${flags}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# compile a target with -O2 optimization even in Debug build
|
||||||
|
function(upx_compile_target_debug_with_O2) # ARGV
|
||||||
|
foreach(t ${ARGV})
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# compile a source file with -O2 optimization even in Debug build; messy because of CMake limitations
|
||||||
|
function(upx_compile_source_debug_with_O2) # ARGV
|
||||||
|
set(flags "$<$<CONFIG:Debug>:-O2>")
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS "3.8")
|
||||||
|
# 3.8: The COMPILE_FLAGS source file property learned to support generator expressions
|
||||||
|
if(upx_global_is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(flags "-O2")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_GENERATOR MATCHES "Xcode") # multi-config
|
||||||
|
# NOTE: Xcode does not support per-config per-source COMPILE_FLAGS (as of CMake 3.27.7)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
foreach(source ${ARGV})
|
||||||
|
if(MSVC_FRONTEND)
|
||||||
|
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
|
||||||
|
else()
|
||||||
|
get_source_file_property(prop "${source}" COMPILE_FLAGS)
|
||||||
|
if("${prop}" MATCHES "^(NOTFOUND)?$")
|
||||||
|
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
|
||||||
|
else()
|
||||||
|
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${prop} ${flags}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# sanitize a target; note that this may require special run-time support libs from your toolchain
|
||||||
|
function(upx_sanitize_target) # ARGV
|
||||||
|
foreach(t ${ARGV})
|
||||||
|
if(UPX_CONFIG_DISABLE_SANITIZE)
|
||||||
|
# no-op
|
||||||
|
elseif(MSVC_FRONTEND)
|
||||||
|
# MSVC uses -GS (similar to -fstack-protector) by default
|
||||||
|
elseif(NOT GNU_FRONTEND)
|
||||||
|
# unknown compiler
|
||||||
|
elseif(MINGW OR CYGWIN)
|
||||||
|
# avoid link errors with current MinGW-w64 versions
|
||||||
|
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
|
||||||
|
elseif(CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "9.0")
|
||||||
|
# unreliable/broken sanitize implementation before clang-9 (Sep 2019)
|
||||||
|
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
|
||||||
|
elseif(CMAKE_C_COMPILER_ID MATCHES "^GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0")
|
||||||
|
# unsupported compiler; unreliable/broken sanitize implementation before gcc-8 (May 2018)
|
||||||
|
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
|
||||||
|
else()
|
||||||
|
# default sanitizer for Debug builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
|
||||||
|
# default sanitizer for Release builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# test
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
function(upx_add_test) # ARGV
|
||||||
|
set(name "${ARGV0}")
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
add_test(NAME "${name}" COMMAND ${ARGV})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_test_depends) # ARGV
|
||||||
|
set(name "${ARGV0}")
|
||||||
|
list(REMOVE_AT ARGV 0)
|
||||||
|
get_property(prop TEST "${name}" PROPERTY DEPENDS)
|
||||||
|
if("${prop}" MATCHES "^(NOTFOUND)?$")
|
||||||
|
set_tests_properties("${name}" PROPERTIES DEPENDS "${ARGV}")
|
||||||
|
else()
|
||||||
|
set_tests_properties("${name}" PROPERTIES DEPENDS "${prop};${ARGV}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#
|
||||||
|
# UPX "CMake" build file; see https://cmake.org/
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# summary section
|
||||||
|
# print some info about the build configuration
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# generator
|
||||||
|
upx_print_var(CMAKE_GENERATOR_TOOLSET CMAKE_GENERATOR_PLATFORM)
|
||||||
|
|
||||||
|
# directories
|
||||||
|
if(NOT ",${CMAKE_BINARY_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR}," OR NOT ",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_SOURCE_DIR},")
|
||||||
|
upx_print_var(CMAKE_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# system
|
||||||
|
upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION CMAKE_HOST_SYSTEM_PROCESSOR)
|
||||||
|
upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_SYSTEM_PROCESSOR)
|
||||||
|
upx_print_var(CMAKE_ANDROID_NDK CMAKE_ANDROID_NDK_VERSION CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
|
||||||
|
upx_print_var(CMAKE_APPLE_SILICON_PROCESSOR CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT)
|
||||||
|
upx_print_Var(CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR)
|
||||||
|
|
||||||
|
# binutils
|
||||||
|
upx_print_var(CMAKE_AR CMAKE_RANLIB)
|
||||||
|
|
||||||
|
# compilers
|
||||||
|
foreach(lang IN ITEMS ASM C CXX)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_LAUNCHER)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_ID)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_VERSION)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT )
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID)
|
||||||
|
upx_print_var(CMAKE_${lang}_PLATFORM_ID)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_ABI)
|
||||||
|
upx_print_var(CMAKE_${lang}_COMPILER_TARGET)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# misc
|
||||||
|
upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE)
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
upx_print_var(APPLE CLANG CYGWIN GNU_FRONTEND GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE MSVC_TOOLSET_VERSION MSVC_VERSION MSYS UNIX WIN32 WIN64)
|
||||||
|
|
||||||
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#
|
||||||
|
# UPX "CMake" build file; see https://cmake.org/
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# test section: self-pack tests
|
||||||
|
#
|
||||||
|
# IMPORTANT NOTE: these tests can only work if the host executable format
|
||||||
|
# is supported by UPX!
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
set(emu "")
|
||||||
|
if(DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
|
||||||
|
set(emu "${CMAKE_CROSSCOMPILING_EMULATOR}")
|
||||||
|
endif()
|
||||||
|
set(exe "${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
|
set(upx_self_exe "$<TARGET_FILE:upx>")
|
||||||
|
set(fo "--force-overwrite")
|
||||||
|
|
||||||
|
#
|
||||||
|
# basic tests
|
||||||
|
#
|
||||||
|
|
||||||
|
upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe})
|
||||||
|
upx_add_test(upx-self-pack-fa upx -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe})
|
||||||
|
upx_add_test(upx-self-pack-fn upx -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe})
|
||||||
|
upx_add_test(upx-self-pack-fr upx -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe})
|
||||||
|
upx_add_test(upx-self-pack-nrv2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe})
|
||||||
|
upx_add_test(upx-self-pack-nrv2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe})
|
||||||
|
upx_add_test(upx-self-pack-nrv2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${exe})
|
||||||
|
upx_add_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe})
|
||||||
|
|
||||||
|
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
|
||||||
|
|
||||||
|
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
|
||||||
|
upx_add_test(upx-unpack-fa upx -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe})
|
||||||
|
upx_add_test(upx-unpack-fn upx -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe})
|
||||||
|
upx_add_test(upx-unpack-fr upx -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe})
|
||||||
|
upx_add_test(upx-unpack-nrv2b upx -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe})
|
||||||
|
upx_add_test(upx-unpack-nrv2d upx -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe})
|
||||||
|
upx_add_test(upx-unpack-nrv2e upx -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe})
|
||||||
|
upx_add_test(upx-unpack-lzma upx -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe})
|
||||||
|
|
||||||
|
# all unpacked files must be identical
|
||||||
|
upx_add_test(upx-compare-fa "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fa${exe})
|
||||||
|
upx_add_test(upx-compare-fn "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fn${exe})
|
||||||
|
upx_add_test(upx-compare-fr "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fr${exe})
|
||||||
|
upx_add_test(upx-compare-nrv2b "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2b${exe})
|
||||||
|
upx_add_test(upx-compare-nrv2d "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2d${exe})
|
||||||
|
upx_add_test(upx-compare-nrv2e "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2e${exe})
|
||||||
|
upx_add_test(upx-compare-lzma "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-lzma${exe})
|
||||||
|
|
||||||
|
# test dependencies
|
||||||
|
upx_test_depends(upx-list "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||||
|
upx_test_depends(upx-fileinfo "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||||
|
upx_test_depends(upx-test "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
|
||||||
|
upx_test_depends(upx-unpack upx-self-pack)
|
||||||
|
upx_test_depends(upx-unpack-fa upx-self-pack-fa)
|
||||||
|
upx_test_depends(upx-unpack-fn upx-self-pack-fn)
|
||||||
|
upx_test_depends(upx-unpack-fr upx-self-pack-fr)
|
||||||
|
upx_test_depends(upx-unpack-nrv2b upx-self-pack-nrv2b)
|
||||||
|
upx_test_depends(upx-unpack-nrv2d upx-self-pack-nrv2d)
|
||||||
|
upx_test_depends(upx-unpack-nrv2e upx-self-pack-nrv2e)
|
||||||
|
upx_test_depends(upx-unpack-lzma upx-self-pack-lzma)
|
||||||
|
upx_test_depends(upx-compare-fa "upx-unpack;upx-unpack-fa")
|
||||||
|
upx_test_depends(upx-compare-fn "upx-unpack;upx-unpack-fn")
|
||||||
|
upx_test_depends(upx-compare-fr "upx-unpack;upx-unpack-fr")
|
||||||
|
upx_test_depends(upx-compare-nrv2b "upx-unpack;upx-unpack-nrv2b")
|
||||||
|
upx_test_depends(upx-compare-nrv2d "upx-unpack;upx-unpack-nrv2d")
|
||||||
|
upx_test_depends(upx-compare-nrv2e "upx-unpack;upx-unpack-nrv2e")
|
||||||
|
upx_test_depends(upx-compare-lzma "upx-unpack;upx-unpack-lzma")
|
||||||
|
# tests with higher COST values will run first
|
||||||
|
set_tests_properties(upx-self-pack PROPERTIES COST 90)
|
||||||
|
set_tests_properties(upx-self-pack-fa PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-fn PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-fr PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-nrv2b PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-nrv2d PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-nrv2e PROPERTIES COST 20)
|
||||||
|
set_tests_properties(upx-self-pack-lzma PROPERTIES COST 30)
|
||||||
|
set_tests_properties(upx-unpack PROPERTIES COST 10)
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST)
|
||||||
|
upx_add_test(upx-run-unpacked ${emu} ./upx-unpacked${exe} --version-short)
|
||||||
|
upx_test_depends(upx-run-unpacked upx-unpack)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
|
||||||
|
upx_add_test(upx-run-packed ${emu} ./upx-packed${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-fa ${emu} ./upx-packed-fa${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-fn ${emu} ./upx-packed-fn${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-fr ${emu} ./upx-packed-fr${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-nrv2b ${emu} ./upx-packed-nrv2b${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-nrv2d ${emu} ./upx-packed-nrv2d${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-nrv2e ${emu} ./upx-packed-nrv2e${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed-lzma ${emu} ./upx-packed-lzma${exe} --version-short)
|
||||||
|
upx_test_depends(upx-run-packed upx-self-pack)
|
||||||
|
upx_test_depends(upx-run-packed-fa upx-self-pack-fa)
|
||||||
|
upx_test_depends(upx-run-packed-fn upx-self-pack-fn)
|
||||||
|
upx_test_depends(upx-run-packed-fr upx-self-pack-fr)
|
||||||
|
upx_test_depends(upx-run-packed-nrv2b upx-self-pack-nrv2b)
|
||||||
|
upx_test_depends(upx-run-packed-nrv2d upx-self-pack-nrv2d)
|
||||||
|
upx_test_depends(upx-run-packed-nrv2e upx-self-pack-nrv2e)
|
||||||
|
upx_test_depends(upx-run-packed-lzma upx-self-pack-lzma)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
# exhaustive tests
|
||||||
|
#
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
|
||||||
|
foreach(method IN ITEMS nrv2b nrv2d nrv2e lzma)
|
||||||
|
foreach(level IN ITEMS 1 2 3 4 5 6 7)
|
||||||
|
set(s "${method}-${level}")
|
||||||
|
upx_add_test(upx-self-pack-${s} upx --${method} -${level} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe})
|
||||||
|
upx_add_test(upx-list-${s} upx -l upx-packed-${s}${exe})
|
||||||
|
upx_add_test(upx-fileinfo-${s} upx --fileinfo upx-packed-${s}${exe})
|
||||||
|
upx_add_test(upx-test-${s} upx -t upx-packed-${s}${exe})
|
||||||
|
upx_add_test(upx-unpack-${s} upx -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe})
|
||||||
|
upx_add_test(upx-compare-${s} "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-${s}${exe})
|
||||||
|
upx_test_depends(upx-list-${s} upx-self-pack-${s})
|
||||||
|
upx_test_depends(upx-fileinfo-${s} upx-self-pack-${s})
|
||||||
|
upx_test_depends(upx-test-${s} upx-self-pack-${s})
|
||||||
|
upx_test_depends(upx-unpack-${s} upx-self-pack-${s})
|
||||||
|
upx_test_depends(upx-compare-${s} "upx-unpack;upx-unpack-${s}")
|
||||||
|
if(method MATCHES "lzma")
|
||||||
|
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "3${level}")
|
||||||
|
else()
|
||||||
|
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "2${level}")
|
||||||
|
endif()
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
|
||||||
|
upx_add_test(upx-run-packed-${s} ${emu} ./upx-packed-${s}${exe} --version-short)
|
||||||
|
upx_test_depends(upx-run-packed-${s} upx-self-pack-${s})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
endif () # UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
set(emu "")
|
||||||
|
set(exe "")
|
||||||
|
set(upx_self_exe "")
|
||||||
|
set(fo "")
|
||||||
|
|
||||||
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
static std::mutex lock_mutex;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::lock_guard<std::mutex> lock(lock_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// check ABI - require proper alignment of fundamental types for use in atomics
|
||||||
|
static_assert(alignof(char) == sizeof(char), "");
|
||||||
|
static_assert(alignof(signed char) == sizeof(signed char), "");
|
||||||
|
static_assert(alignof(unsigned char) == sizeof(unsigned char), "");
|
||||||
|
static_assert(alignof(short) == sizeof(short), "");
|
||||||
|
static_assert(alignof(unsigned short) == sizeof(unsigned short), "");
|
||||||
|
static_assert(alignof(int) == sizeof(int), "");
|
||||||
|
static_assert(alignof(unsigned int) == sizeof(unsigned int), "");
|
||||||
|
static_assert(alignof(long) == sizeof(long), "");
|
||||||
|
static_assert(alignof(unsigned long) == sizeof(unsigned long), "");
|
||||||
|
static_assert(alignof(ptrdiff_t) == sizeof(ptrdiff_t), "");
|
||||||
|
static_assert(alignof(size_t) == sizeof(size_t), "");
|
||||||
|
static_assert(alignof(intptr_t) == sizeof(intptr_t), "");
|
||||||
|
static_assert(alignof(uintptr_t) == sizeof(uintptr_t), "");
|
||||||
|
static_assert(alignof(void *) == sizeof(void *), "");
|
||||||
|
|
||||||
|
int main() { return 0; }
|
||||||
@@ -0,0 +1,329 @@
|
|||||||
|
#
|
||||||
|
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
ifeq ($(UPX_MAKEFILE_EXTRA_MK_INCLUDED),)
|
||||||
|
override UPX_MAKEFILE_EXTRA_MK_INCLUDED := 1
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# support functions
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
override check_defined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),$(error ERROR: variable '$1' is not defined),))
|
||||||
|
override check_undefined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),,$(error ERROR: variable '$1' is already defined)))
|
||||||
|
|
||||||
|
# return "1" or empty-string
|
||||||
|
override eq = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),,1)
|
||||||
|
override ne = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),1,)
|
||||||
|
|
||||||
|
override tolower = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
|
||||||
|
override toupper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
|
||||||
|
|
||||||
|
# canonicalize case of CMAKE_BUILD_TYPE to "Debug" and "Release"
|
||||||
|
override cm_build_type = $(if $(call eq,$1,),$(error EMPTY-build-type),$(if $(call eq,$(call tolower,$1),debug),Debug,$(if $(call eq,$(call tolower,$1),release),Release,$(if $(call eq,$(call tolower,$1),none),None,$1))))
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# extra builds: some pre-defined build configurations
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
$(call check_defined,run_config run_build)
|
||||||
|
$(call check_undefined,run_config_and_build)
|
||||||
|
|
||||||
|
define run_config_and_build
|
||||||
|
$(call run_config,$1,$2)
|
||||||
|
$(call run_build,$1,$2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
# force building with clang/clang++
|
||||||
|
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang/%: export CC = clang
|
||||||
|
build/extra/clang/%: export CXX = clang++
|
||||||
|
|
||||||
|
# force building with clang/clang++ -m32
|
||||||
|
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-m32/%: export CC = clang -m32
|
||||||
|
build/extra/clang-m32/%: export CXX = clang++ -m32
|
||||||
|
|
||||||
|
# force building with clang/clang++ -mx32
|
||||||
|
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-mx32/%: export CC = clang -mx32
|
||||||
|
build/extra/clang-mx32/%: export CXX = clang++ -mx32
|
||||||
|
|
||||||
|
# force building with clang/clang++ -m64
|
||||||
|
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-m64/%: export CC = clang -m64
|
||||||
|
build/extra/clang-m64/%: export CXX = clang++ -m64
|
||||||
|
|
||||||
|
# force building with clang/clang++ -static
|
||||||
|
build/extra/clang-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-static/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-static/%: export CC = clang -static
|
||||||
|
build/extra/clang-static/%: export CXX = clang++ -static
|
||||||
|
|
||||||
|
# force building with clang/clang++ -static-pie
|
||||||
|
build/extra/clang-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-static-pie/%: export CC = clang -static-pie -fPIE -Wno-unused-command-line-argument
|
||||||
|
build/extra/clang-static-pie/%: export CXX = clang++ -static-pie -fPIE -Wno-unused-command-line-argument
|
||||||
|
|
||||||
|
# force building with clang/clang++ -static -flto
|
||||||
|
build/extra/clang-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-static-lto/%: export CC = clang -static -flto
|
||||||
|
build/extra/clang-static-lto/%: export CXX = clang++ -static -flto
|
||||||
|
|
||||||
|
# force building with clang/clang++ C17/C++20
|
||||||
|
build/extra/clang-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-std-cxx20/%: export CC = clang -std=gnu17
|
||||||
|
build/extra/clang-std-cxx20/%: export CXX = clang++ -std=gnu++20
|
||||||
|
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
|
||||||
|
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
|
||||||
|
|
||||||
|
# force building with clang/clang++ C23/C++23
|
||||||
|
build/extra/clang-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-std-cxx23/%: export CC = clang -std=gnu2x
|
||||||
|
build/extra/clang-std-cxx23/%: export CXX = clang++ -std=gnu++2b
|
||||||
|
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
|
||||||
|
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
|
||||||
|
|
||||||
|
# force building with gcc/g++
|
||||||
|
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc/%: export CC = gcc
|
||||||
|
build/extra/gcc/%: export CXX = g++
|
||||||
|
|
||||||
|
# force building with gcc/g++ -m32
|
||||||
|
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-m32/%: export CC = gcc -m32
|
||||||
|
build/extra/gcc-m32/%: export CXX = g++ -m32
|
||||||
|
|
||||||
|
# force building with gcc/g++ -mx32
|
||||||
|
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-mx32/%: export CC = gcc -mx32
|
||||||
|
build/extra/gcc-mx32/%: export CXX = g++ -mx32
|
||||||
|
|
||||||
|
# force building with gcc/g++ -m64
|
||||||
|
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-m64/%: export CC = gcc -m64
|
||||||
|
build/extra/gcc-m64/%: export CXX = g++ -m64
|
||||||
|
|
||||||
|
# force building with gcc/g++ -static
|
||||||
|
build/extra/gcc-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-static/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-static/%: export CC = gcc -static
|
||||||
|
build/extra/gcc-static/%: export CXX = g++ -static
|
||||||
|
|
||||||
|
# force building with gcc/g++ -static-pie
|
||||||
|
build/extra/gcc-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-static-pie/%: export CC = gcc -static-pie -fPIE
|
||||||
|
build/extra/gcc-static-pie/%: export CXX = g++ -static-pie -fPIE
|
||||||
|
|
||||||
|
# force building with gcc/g++ -static -flto
|
||||||
|
build/extra/gcc-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-static-lto/%: export CC = gcc -static -flto
|
||||||
|
build/extra/gcc-static-lto/%: export CXX = g++ -static -flto
|
||||||
|
|
||||||
|
# force building with gcc/g++ C17/C++20
|
||||||
|
build/extra/gcc-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-std-cxx20/%: export CC = gcc -std=gnu17
|
||||||
|
build/extra/gcc-std-cxx20/%: export CXX = g++ -std=gnu++20
|
||||||
|
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
|
||||||
|
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
|
||||||
|
|
||||||
|
# force building with gcc/g++ C23/C++23
|
||||||
|
build/extra/gcc-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-std-cxx23/%: export CC = gcc -std=gnu2x
|
||||||
|
build/extra/gcc-std-cxx23/%: export CXX = g++ -std=gnu++2b
|
||||||
|
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
|
||||||
|
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc aarch64-linux-gnu (arm64)
|
||||||
|
build/extra/cross-linux-gnu-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-gnu-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-gnu-aarch64/%: export CC = aarch64-linux-gnu-gcc
|
||||||
|
build/extra/cross-linux-gnu-aarch64/%: export CXX = aarch64-linux-gnu-g++
|
||||||
|
build/extra/cross-linux-gnu-aarch64/%: CMAKE_SYSTEM_NAME ?= Linux
|
||||||
|
build/extra/cross-linux-gnu-aarch64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-aarch64
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc arm-linux-gnueabihf
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/%: export CC = arm-linux-gnueabihf-gcc
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_SYSTEM_NAME ?= Linux
|
||||||
|
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-arm
|
||||||
|
|
||||||
|
# cross compiler: Windows x86 win32 MinGW (i386)
|
||||||
|
build/extra/cross-windows-mingw32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-windows-mingw32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
|
||||||
|
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
|
||||||
|
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_NAME ?= Windows
|
||||||
|
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_PROCESSOR ?= X86
|
||||||
|
build/extra/cross-windows-mingw32/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
|
||||||
|
|
||||||
|
# cross compiler: Windows x64 win64 MinGW (amd64)
|
||||||
|
build/extra/cross-windows-mingw64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-windows-mingw64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
|
||||||
|
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
|
||||||
|
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_NAME ?= Windows
|
||||||
|
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_PROCESSOR ?= AMD64
|
||||||
|
build/extra/cross-windows-mingw64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
|
||||||
|
|
||||||
|
# cross compiler: macOS arm64 (aarch64)
|
||||||
|
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
|
||||||
|
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
|
||||||
|
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_NAME ?= Darwin
|
||||||
|
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_PROCESSOR ?= arm64
|
||||||
|
|
||||||
|
# cross compiler: macOS x86_64 (amd64)
|
||||||
|
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
|
||||||
|
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
|
||||||
|
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_NAME ?= Darwin
|
||||||
|
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_PROCESSOR ?= x86_64
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# C/C++ static analyzers
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# force building with clang Static Analyzer (scan-build)
|
||||||
|
SCAN_BUILD = scan-build
|
||||||
|
build/analyze/clang-analyzer/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/analyze/clang-analyzer/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/analyze/clang-analyzer/%: override CMAKE := $(SCAN_BUILD) $(CMAKE)
|
||||||
|
build/analyze/clang-analyzer/%: export CCC_CC ?= clang
|
||||||
|
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
|
||||||
|
|
||||||
|
# run clang-tidy: uses file compile_commands.json from an existing clang build;
|
||||||
|
# does not create any actual files, so purely PHONY
|
||||||
|
CLANG_TIDY_BUILD_BASE = build/extra/clang
|
||||||
|
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
|
||||||
|
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*'
|
||||||
|
build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||||
|
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp'
|
||||||
|
build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||||
|
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/
|
||||||
|
build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||||
|
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/
|
||||||
|
build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||||
|
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/
|
||||||
|
build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
|
||||||
|
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/
|
||||||
|
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-upx/$$(notdir $$@)
|
||||||
|
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-bzip2/$$(notdir $$@)
|
||||||
|
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-ucl/$$(notdir $$@)
|
||||||
|
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zlib/$$(notdir $$@)
|
||||||
|
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
|
||||||
|
|
||||||
|
# OLD names [deprecated]
|
||||||
|
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug PHONY
|
||||||
|
build/extra/scan-build/release: build/analyze/clang-analyzer/release PHONY
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# advanced: generic eXtra target
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# usage:
|
||||||
|
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
|
||||||
|
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
|
||||||
|
|
||||||
|
ifneq ($(UPX_XTARGET),)
|
||||||
|
ifneq ($(CC),)
|
||||||
|
ifneq ($(CXX),)
|
||||||
|
|
||||||
|
UPX_XTARGET := $(UPX_XTARGET)
|
||||||
|
build/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/$(UPX_XTARGET)/%: export CC := $(CC)
|
||||||
|
build/$(UPX_XTARGET)/%: export CXX := $(CXX)
|
||||||
|
# shortcuts
|
||||||
|
xtarget/all: xtarget/debug xtarget/release PHONY
|
||||||
|
xtarget/debug: build/$(UPX_XTARGET)/debug PHONY
|
||||||
|
xtarget/release: build/$(UPX_XTARGET)/release PHONY
|
||||||
|
xtarget/all+test: xtarget/debug+test xtarget/release+test PHONY
|
||||||
|
xtarget/debug+test: build/$(UPX_XTARGET)/debug+test PHONY
|
||||||
|
xtarget/release+test: build/$(UPX_XTARGET)/release+test PHONY
|
||||||
|
# set new default
|
||||||
|
.DEFAULT_GOAL := build/$(UPX_XTARGET)/release
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# assemble cmake config flags; useful for CI jobs
|
||||||
|
#
|
||||||
|
# info: by default CMake only honors the CC and CXX environment variables; make
|
||||||
|
# it easy to set other variables like CMAKE_AR or CMAKE_RANLIB
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
$(call check_undefined,__add_cmake_config)
|
||||||
|
# promote an environment or Make variable to a CMake cache entry:
|
||||||
|
__add_cmake_config = $(and $($1),-D$1="$($1)")
|
||||||
|
|
||||||
|
# pass common CMake settings
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_VERBOSE_MAKEFILE)
|
||||||
|
# pass common CMake toolchain settings
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_ADDR2LINE)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_AR)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_DLLTOOL)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_LINKER)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_NM)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJCOPY)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJDUMP)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_RANLIB)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_READELF)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_STRIP)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_TAPI)
|
||||||
|
# pass common CMake LTO toolchain settings
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_AR)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_RANLIB)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_AR)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_RANLIB)
|
||||||
|
# pass common CMake cross compilation settings
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_NAME)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_PROCESSOR)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CROSSCOMPILING_EMULATOR)
|
||||||
|
# pass UPX config options; see CMakeLists.txt
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_GITREV)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SANITIZE)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WERROR)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WSTRICT)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
|
||||||
|
# pass UPX extra compile options; see CMakeLists.txt
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
|
||||||
|
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# check git submodules
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
|
||||||
|
|
||||||
|
$(foreach 1,$(SUBMODULES),$(if $(wildcard vendor/$1/[CL]*),,\
|
||||||
|
$(error ERROR: missing git submodule '$1'; run 'git submodule update --init')))
|
||||||
|
|
||||||
|
endif # UPX_MAKEFILE_EXTRA_MK_INCLUDED
|
||||||
+4
-1
@@ -5,10 +5,13 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
|||||||
|
|
||||||
# create the image from Dockerfile
|
# create the image from Dockerfile
|
||||||
# using a rootless Podman container
|
# using a rootless Podman container
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
image=upx-stubtools-20210104-v5
|
image=upx-stubtools-20240405-v1
|
||||||
|
[[ $1 == --print-image ]] && echo "$image" && exit 0
|
||||||
|
|
||||||
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||||
|
|
||||||
podman image list "$image"
|
podman image list "$image"
|
||||||
|
echo
|
||||||
podman image tree "$image"
|
podman image tree "$image"
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# list all system packages that are installed in the image
|
||||||
|
# using a rootless Podman container
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||||
|
|
||||||
|
podman image list "$image"
|
||||||
|
echo
|
||||||
|
podman image tree "$image"
|
||||||
|
|
||||||
|
echo 'Packages:'
|
||||||
|
flags=( --read-only --rm --pull=never )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo 'Packages sorted by Installed-Size:'
|
||||||
|
podman run "${flags[@]}" "$image" bash -c $'awk \'
|
||||||
|
BEGIN {
|
||||||
|
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if ($1 == "Architecture:") arch = $2;
|
||||||
|
if ($1 == "Installed-Size:") size = $2;
|
||||||
|
if ($1 == "Package:") package = $2;
|
||||||
|
if ($1 == "") {
|
||||||
|
printf("%9d %-40s %s\\n", size, package, arch);
|
||||||
|
count += 1; total += size;
|
||||||
|
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf("%9d ===== TOTAL (%d packages)\\n", total, count);
|
||||||
|
}
|
||||||
|
\' /var/lib/dpkg/status | LC_ALL=C sort -rn'
|
||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# run an interactive shell in the image
|
||||||
|
# using a rootless Podman container
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||||
|
|
||||||
|
flags=( --read-only --rm --pull=never )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM
|
||||||
|
if [[ 1 == 1 ]]; then
|
||||||
|
# run as user upx 2000:2000
|
||||||
|
flags+=( --user 2000 )
|
||||||
|
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||||
|
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||||
|
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||||
|
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||||
|
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||||
|
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||||
|
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
|
||||||
|
flags+=( -w /home/upx/src/upx ) # set working directory
|
||||||
|
flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs
|
||||||
|
flags+=( --tmpfs /home/upx/.config:rw,exec ) # mount a writeable tmpfs
|
||||||
|
flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs
|
||||||
|
else
|
||||||
|
# run as user root 0:0
|
||||||
|
# ONLY FOR DEBUGGING THE IMAGE
|
||||||
|
# map container user/group 0 to current host user/group
|
||||||
|
flags+=( --user 0 )
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# == 0 ]]; then
|
||||||
|
podman run "${flags[@]}" "$image" bash -l
|
||||||
|
else
|
||||||
|
podman run "${flags[@]}" "$image" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# now we can rebuild the UPX stubs:
|
||||||
|
# cd /home/upx/src/upx/src/stub
|
||||||
|
# # make sure that git is clean:
|
||||||
|
# git status .
|
||||||
|
# # remove stub files and make sure that they got deleted:
|
||||||
|
# make maintainer-clean extra-clean
|
||||||
|
# git status .
|
||||||
|
# # rebuild
|
||||||
|
# make extra-all all
|
||||||
|
# # make sure that the stub files did rebuild correctly:
|
||||||
|
# git status .
|
||||||
|
# git diff .
|
||||||
|
|
||||||
|
# we can also build UPX in the container:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc/release
|
||||||
|
# make build/extra/gcc/release
|
||||||
|
# # run tests
|
||||||
|
# ./build/extra/gcc/release/upx --version
|
||||||
|
# make -C build/extra/gcc/release test
|
||||||
|
|
||||||
|
# and we can also build UPX with -m32:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc-m32/release
|
||||||
|
# make build/extra/gcc-m32/release
|
||||||
|
# # run tests
|
||||||
|
# ./build/extra/gcc-m32/release/upx --version
|
||||||
|
# make -C build/extra/gcc-m32/release test
|
||||||
|
|
||||||
|
# and we can also build UPX with -mx32: (NOTE: needs CONFIG_X86_X32_ABI on host kernel!)
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc-mx32/release
|
||||||
|
# make build/extra/gcc-mx32/release
|
||||||
|
# # run tests (needs CONFIG_X86_X32_ABI on host kernel)
|
||||||
|
# ./build/extra/gcc-mx32/release/upx --version
|
||||||
|
# make -C build/extra/gcc-mx32/release test
|
||||||
|
|
||||||
|
# and we can also rebuild the UPX docs the container:
|
||||||
|
# cd /home/upx/src/upx/doc
|
||||||
|
# make clean all
|
||||||
|
# git status .
|
||||||
|
# git diff .
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# rebuild stubs from source code
|
||||||
|
# (also see 20-image-run-shell.sh for more container usage examples)
|
||||||
|
# using a rootless Podman container
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
image="$("$argv0dir/10-create-image.sh" --print-image)"
|
||||||
|
|
||||||
|
flags=( --read-only --rm --pull=never )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
if [[ 1 == 1 ]]; then
|
||||||
|
# run as user upx 2000:2000
|
||||||
|
flags+=( --user 2000 )
|
||||||
|
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||||
|
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||||
|
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||||
|
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||||
|
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||||
|
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||||
|
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${flags[@]}" "$image" bash -c $'
|
||||||
|
set -ex; set -o pipefail
|
||||||
|
cd /home/upx/src/upx
|
||||||
|
# check whitespace
|
||||||
|
[[ -d .git ]] && bash ./misc/scripts/check_whitespace_git.sh
|
||||||
|
# rebuild docs
|
||||||
|
make -C doc clean all
|
||||||
|
# rebuild stubs
|
||||||
|
cd /home/upx/src/upx/src/stub
|
||||||
|
make maintainer-clean extra-clean
|
||||||
|
git status . || true # make sure the stub files got deleted
|
||||||
|
make extra-all all
|
||||||
|
echo "===== Rebuilt stubs. All done. ====="
|
||||||
|
exit 0
|
||||||
|
'
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
FROM docker.io/library/ubuntu:24.04
|
||||||
|
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20240405-v1
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV LANG=C.UTF-8
|
||||||
|
|
||||||
|
# install system packages
|
||||||
|
RUN dpkg --add-architecture i386 \
|
||||||
|
&& apt-get update && apt-get upgrade -y \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
aria2 bash bash-completion ca-certificates curl git less libmpc3 \
|
||||||
|
make ncurses-term perl-base tar time wget xz-utils \
|
||||||
|
libc6:i386 zlib1g:i386 \
|
||||||
|
# the following packages are not required for rebuilding the stubs, but
|
||||||
|
# they do make the image *much* more convenient and also allow building
|
||||||
|
# the full UPX binary inside the container via CMake:
|
||||||
|
7zip bfs bubblewrap busybox bzip2 bzip3 cabextract ccache chrpath cmake cpio dash diffstat \
|
||||||
|
elfutils execstack fd-find file fish fzf g++ gawk gdb gojq ht htop hyperfine jq ksh \
|
||||||
|
libzstd-dev lsb-release lz4 lzip lzop minify mksh moreutils musl neovim ninja-build \
|
||||||
|
p7zip parallel patch patchelf patchutils pax-utils proot \
|
||||||
|
python3 python3-pyasn1 python3-pycryptodome python3-pycurl python3-toml python3-yaml python3-zstd \
|
||||||
|
re2c ripgrep rsync screen strace universal-ctags unzip valgrind yash yq \
|
||||||
|
zip zlib1g-dev zoxide zsh zstd \
|
||||||
|
# extra packages for compiling with "gcc -m32" and "gcc -mx32":
|
||||||
|
g++-multilib gcc-multilib \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# install python2-minimal packages from Debian-11; REQUIRED
|
||||||
|
RUN cd /root \
|
||||||
|
&& aria2c --checksum=sha-256=85833c92314011b89bbead6f9a5a7a360b5ee4f9b95e001225afead4ebf9f7d3 \
|
||||||
|
'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
|
||||||
|
&& aria2c --checksum=sha-256=44f0cdc1a343303d31c55fcb3a6402cfe326adf749ec30e375e6e0c0c5f7c1f7 \
|
||||||
|
'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
|
||||||
|
&& dpkg -i ./*.deb \
|
||||||
|
&& rm ./*.deb \
|
||||||
|
&& if ! test -f /usr/bin/python2; then ln -s -v python2.7 /usr/bin/python2; fi \
|
||||||
|
&& ldconfig \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# manually unpack and install compat libs from Ubuntu-16.04; REQUIRED
|
||||||
|
RUN cd /root \
|
||||||
|
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
|
||||||
|
'https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \
|
||||||
|
&& mkdir packages \
|
||||||
|
&& for f in ./*.deb; do dpkg -x $f ./packages; done \
|
||||||
|
&& mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \
|
||||||
|
&& rm -rf ./*.deb ./packages \
|
||||||
|
&& ldconfig \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
|
||||||
|
RUN cd /root \
|
||||||
|
&& aria2c --checksum=sha-256=509e06639118a79d8e79489a400e134c6d3ca36bad2c6ec29648d7c1e5b81afa \
|
||||||
|
'https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz' \
|
||||||
|
&& cd /usr/local/bin \
|
||||||
|
&& tar -xoaf /root/bin-upx-20221212.tar.xz \
|
||||||
|
&& rm /root/bin-upx-20221212.tar.xz \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# install official UPX release binaries into /usr/local/bin; not required but convenient for testing
|
||||||
|
RUN cd /root \
|
||||||
|
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
|
||||||
|
&& xzversions="3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3" \
|
||||||
|
&& for v in $xzversions; do wget -q https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \
|
||||||
|
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
||||||
|
&& for v in 3.91 $xzversions; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \
|
||||||
|
&& rm -r ./upx-*.tar.* ./upx-*linux \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# create default container user upx:upx 2000:2000
|
||||||
|
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
||||||
|
&& cd /home/upx && chmod 00700 . \
|
||||||
|
# prepare ~/.cache, ~/.config and ~/.local for possible tmpfs mounts
|
||||||
|
&& mkdir -p .cache/tmp .local/bin src/upx \
|
||||||
|
&& for d in ccache fontconfig go-build mesa_shader_cache parallel tmp wine zig; do mkdir -p .cache/$d; done \
|
||||||
|
&& for d in fish git helix kak nvim; do mkdir -p .config/$d; done \
|
||||||
|
&& for d in bin include lib share state; do mkdir -p .local/$d; done \
|
||||||
|
&& ln -s .cache/wine .wine && ln -s .cache/tmp tmp \
|
||||||
|
# symlink upx-stubtools
|
||||||
|
&& ln -s /usr/local/bin/bin-upx-20221212 .local/bin/bin-upx \
|
||||||
|
# some convenience settings according to upx developer preferences
|
||||||
|
&& echo "alias md=mkdir" >> .bashrc \
|
||||||
|
&& echo "alias rd=rmdir" >> .bashrc \
|
||||||
|
&& echo 'mdd() { mkdir "$1" && cd "$1"; }' >> .bashrc \
|
||||||
|
&& echo 'm() { make "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tn() { time nice "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tnm() { time nice make "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'tnmm() { time nice make -j "$@"; }' >> .bashrc \
|
||||||
|
&& echo 'source /usr/share/bash-completion/completions/make' >> .bashrc \
|
||||||
|
&& echo 'complete -F _make m tnm tnmm' >> .bashrc \
|
||||||
|
&& echo 'eval "$(zoxide init bash)"' >> .bashrc \
|
||||||
|
&& echo "alias zz=zi\nalias y=z\nalias yy=zi" >> .bashrc \
|
||||||
|
&& echo "alias cd..='cd ..'" >> .bashrc \
|
||||||
|
&& echo "alias ..='cd ..'" >> .bashrc \
|
||||||
|
&& echo "alias .='cd ..'" >> .bashrc \
|
||||||
|
&& chown -R upx:upx . \
|
||||||
|
&& true
|
||||||
|
USER upx
|
||||||
Generated
+719
@@ -0,0 +1,719 @@
|
|||||||
|
Packages:
|
||||||
|
+++-=============================-=================================-============-================================================================================
|
||||||
|
Desired=Unknown/Install/Remove/Purge/Hold
|
||||||
|
ii 7zip 23.01+dfsg-11 amd64 7-Zip file archiver with a high compression ratio
|
||||||
|
ii apt 2.7.14build2 amd64 commandline package manager
|
||||||
|
ii aria2 1.37.0+debian-1build3 amd64 High speed download utility
|
||||||
|
ii base-files 13ubuntu10 amd64 Debian base system miscellaneous files
|
||||||
|
ii base-passwd 3.6.3build1 amd64 Debian base system master password and group files
|
||||||
|
ii bash 5.2.21-2ubuntu4 amd64 GNU Bourne Again SHell
|
||||||
|
ii bash-completion 1:2.11-8 all programmable completion for the bash shell
|
||||||
|
ii bfs 3.1.2-1build1 amd64 Breadth-first version of find(1)
|
||||||
|
ii binutils 2.42-4ubuntu2 amd64 GNU assembler, linker and binary utilities
|
||||||
|
ii binutils-common:amd64 2.42-4ubuntu2 amd64 Common files for the GNU assembler, linker and binary utilities
|
||||||
|
ii binutils-x86-64-linux-gnu 2.42-4ubuntu2 amd64 GNU binary utilities, for x86-64-linux-gnu target
|
||||||
|
ii bsdextrautils 2.39.3-9ubuntu6 amd64 extra utilities from 4.4BSD-Lite
|
||||||
|
ii bsdutils 1:2.39.3-9ubuntu6 amd64 basic utilities from 4.4BSD-Lite
|
||||||
|
ii bubblewrap 0.9.0-1build1 amd64 utility for unprivileged chroot and namespace manipulation
|
||||||
|
ii busybox 1:1.36.1-6ubuntu3 amd64 Tiny utilities for small and embedded systems
|
||||||
|
ii bzip2 1.0.8-5.1 amd64 high-quality block-sorting file compressor - utilities
|
||||||
|
ii bzip3 1.4.0-1 amd64 better, faster and stronger spiritual successor to bzip2 - utilities
|
||||||
|
ii ca-certificates 20240203 all Common CA certificates
|
||||||
|
ii cabextract 1.11-2 amd64 Microsoft Cabinet file unpacker
|
||||||
|
ii ccache 4.9.1-1 amd64 Compiler cache for fast recompilation of C/C++ code
|
||||||
|
ii chrpath 0.16-2build1 amd64 Tool to edit the rpath in ELF binaries
|
||||||
|
ii cmake 3.28.3-1build7 amd64 cross-platform, open-source make system
|
||||||
|
ii cmake-data 3.28.3-1build7 all CMake data files (modules, templates and documentation)
|
||||||
|
ii coreutils 9.4-3ubuntu6 amd64 GNU core utilities
|
||||||
|
ii cpio 2.15+dfsg-1ubuntu2 amd64 GNU cpio -- a program to manage archives of files
|
||||||
|
ii cpp 4:13.2.0-7ubuntu1 amd64 GNU C preprocessor (cpp)
|
||||||
|
ii cpp-13 13.2.0-23ubuntu4 amd64 GNU C preprocessor
|
||||||
|
ii cpp-13-x86-64-linux-gnu 13.2.0-23ubuntu4 amd64 GNU C preprocessor for x86_64-linux-gnu
|
||||||
|
ii cpp-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C preprocessor (cpp) for the amd64 architecture
|
||||||
|
ii curl 8.5.0-2ubuntu10.1 amd64 command line tool for transferring data with URL syntax
|
||||||
|
ii dash 0.5.12-6ubuntu5 amd64 POSIX-compliant shell
|
||||||
|
ii debconf 1.5.86ubuntu1 all Debian configuration management system
|
||||||
|
ii debianutils 5.17build1 amd64 Miscellaneous utilities specific to Debian
|
||||||
|
ii diffstat 1.66-1build1 amd64 produces graph of changes introduced by a diff file
|
||||||
|
ii diffutils 1:3.10-1build1 amd64 File comparison utilities
|
||||||
|
ii dpkg 1.22.6ubuntu6 amd64 Debian package management system
|
||||||
|
ii e2fsprogs 1.47.0-2.4~exp1ubuntu4 amd64 ext2/ext3/ext4 file system utilities
|
||||||
|
ii elfutils 0.190-1.1build4 amd64 collection of utilities to handle ELF objects
|
||||||
|
ii execstack 0.0.20131005-1.1ubuntu1 amd64 ELF GNU_STACK program header editing utility
|
||||||
|
ii fd-find 9.0.0-1 amd64 Simple, fast and user-friendly alternative to find
|
||||||
|
ii file 1:5.45-3build1 amd64 Recognize the type of data in a file using "magic" numbers
|
||||||
|
ii findutils 4.9.0-5build1 amd64 utilities for finding files--find, xargs
|
||||||
|
ii fish 3.7.0-1 amd64 friendly interactive shell
|
||||||
|
ii fish-common 3.7.0-1 all friendly interactive shell (architecture-independent files)
|
||||||
|
ii fzf 0.44.1-1 amd64 general-purpose command-line fuzzy finder
|
||||||
|
ii g++ 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler
|
||||||
|
ii g++-13 13.2.0-23ubuntu4 amd64 GNU C++ compiler
|
||||||
|
ii g++-13-multilib 13.2.0-23ubuntu4 amd64 GNU C++ compiler (multilib support)
|
||||||
|
ii g++-13-x86-64-linux-gnu 13.2.0-23ubuntu4 amd64 GNU C++ compiler for x86_64-linux-gnu architecture
|
||||||
|
ii g++-multilib 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler (multilib files)
|
||||||
|
ii g++-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C++ compiler for the amd64 architecture
|
||||||
|
ii gawk 1:5.2.1-2build3 amd64 GNU awk, a pattern scanning and processing language
|
||||||
|
ii gcc 4:13.2.0-7ubuntu1 amd64 GNU C compiler
|
||||||
|
ii gcc-13 13.2.0-23ubuntu4 amd64 GNU C compiler
|
||||||
|
ii gcc-13-base:amd64 13.2.0-23ubuntu4 amd64 GCC, the GNU Compiler Collection (base package)
|
||||||
|
ii gcc-13-multilib 13.2.0-23ubuntu4 amd64 GNU C compiler (multilib support)
|
||||||
|
ii gcc-13-x86-64-linux-gnu 13.2.0-23ubuntu4 amd64 GNU C compiler for the x86_64-linux-gnu architecture
|
||||||
|
ii gcc-14-base:amd64 14-20240412-0ubuntu1 amd64 GCC, the GNU Compiler Collection (base package)
|
||||||
|
ii gcc-14-base:i386 14-20240412-0ubuntu1 i386 GCC, the GNU Compiler Collection (base package)
|
||||||
|
ii gcc-multilib 4:13.2.0-7ubuntu1 amd64 GNU C compiler (multilib files)
|
||||||
|
ii gcc-x86-64-linux-gnu 4:13.2.0-7ubuntu1 amd64 GNU C compiler for the amd64 architecture
|
||||||
|
ii gdb 15.0.50.20240403-0ubuntu1 amd64 GNU Debugger
|
||||||
|
ii git 1:2.43.0-1ubuntu7 amd64 fast, scalable, distributed revision control system
|
||||||
|
ii git-man 1:2.43.0-1ubuntu7 all fast, scalable, distributed revision control system (manual pages)
|
||||||
|
ii gojq 0.12.13-1 amd64 pure Go implementation of jq (program)
|
||||||
|
ii gpgv 2.4.4-2ubuntu17 amd64 GNU privacy guard - signature verification tool
|
||||||
|
ii grep 3.11-4build1 amd64 GNU grep, egrep and fgrep
|
||||||
|
ii groff-base 1.23.0-3build2 amd64 GNU troff text-formatting system (base system components)
|
||||||
|
ii gzip 1.12-1ubuntu3 amd64 GNU compression utilities
|
||||||
|
ii hostname 3.23+nmu2ubuntu2 amd64 utility to set/show the host name or domain name
|
||||||
|
ii ht 2.1.0+repack1-5 amd64 Viewer/editor/analyser (mostly) for executables
|
||||||
|
ii htop 3.3.0-4build1 amd64 interactive processes viewer
|
||||||
|
ii hyperfine 1.18.0-2build1 amd64 Command-line benchmarking tool
|
||||||
|
ii init-system-helpers 1.66ubuntu1 all helper tools for all init systems
|
||||||
|
ii jq 1.7.1-3build1 amd64 lightweight and flexible command-line JSON processor
|
||||||
|
ii ksh 20240113 all transitional package
|
||||||
|
ii ksh93u+m 1.0.8-1 amd64 AT&T KornShell
|
||||||
|
ii less 590-2ubuntu2.1 amd64 pager program similar to more
|
||||||
|
ii lib32asan8 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector (32bit)
|
||||||
|
ii lib32atomic1 14-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions (32bit)
|
||||||
|
ii lib32gcc-13-dev 13.2.0-23ubuntu4 amd64 GCC support library (32 bit development files)
|
||||||
|
ii lib32gcc-s1 14-20240412-0ubuntu1 amd64 GCC support library (32 bit Version)
|
||||||
|
ii lib32gomp1 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library (32bit)
|
||||||
|
ii lib32itm1 14-20240412-0ubuntu1 amd64 GNU Transactional Memory Library (32bit)
|
||||||
|
ii lib32quadmath0 14-20240412-0ubuntu1 amd64 GCC Quad-Precision Math Library (32bit)
|
||||||
|
ii lib32stdc++-13-dev 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii lib32stdc++6 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3 (32 bit Version)
|
||||||
|
ii lib32ubsan1 14-20240412-0ubuntu1 amd64 UBSan -- undefined behaviour sanitizer (32bit)
|
||||||
|
ii libacl1:amd64 2.3.2-1build1 amd64 access control list - shared library
|
||||||
|
ii libapt-pkg6.0t64:amd64 2.7.14build2 amd64 package management runtime library
|
||||||
|
ii libarchive13t64:amd64 3.7.2-2 amd64 Multi-format archive and compression library (shared library)
|
||||||
|
ii libaria2-0:amd64 1.37.0+debian-1build3 amd64 C++ library interface to aria2
|
||||||
|
ii libasan8:amd64 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector
|
||||||
|
ii libasm1t64:amd64 0.190-1.1build4 amd64 library with a programmable assembler interface
|
||||||
|
ii libassuan0:amd64 2.5.6-1build1 amd64 IPC library for the GnuPG components
|
||||||
|
ii libatomic1:amd64 14-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions
|
||||||
|
ii libattr1:amd64 1:2.5.2-1build1 amd64 extended attribute handling - shared library
|
||||||
|
ii libaudit-common 1:3.1.2-2.1build1 all Dynamic library for security auditing - common files
|
||||||
|
ii libaudit1:amd64 1:3.1.2-2.1build1 amd64 Dynamic library for security auditing
|
||||||
|
ii libbabeltrace1:amd64 1.5.11-3build3 amd64 Babeltrace conversion libraries
|
||||||
|
ii libbinutils:amd64 2.42-4ubuntu2 amd64 GNU binary utilities (private shared library)
|
||||||
|
ii libblkid1:amd64 2.39.3-9ubuntu6 amd64 block device ID library
|
||||||
|
ii libbrotli1:amd64 1.1.0-2build2 amd64 library implementing brotli encoder and decoder (shared libraries)
|
||||||
|
ii libbsd0:amd64 0.12.1-1build1 amd64 utility functions from BSD systems - shared library
|
||||||
|
ii libbz2-1.0:amd64 1.0.8-5.1 amd64 high-quality block-sorting file compressor library - runtime
|
||||||
|
ii libbzip3-0:amd64 1.4.0-1 amd64 better, faster and stronger spiritual successor to bzip2 - runtime
|
||||||
|
ii libc-bin 2.39-0ubuntu8.1 amd64 GNU C Library: Binaries
|
||||||
|
ii libc-dev-bin 2.39-0ubuntu8.1 amd64 GNU C Library: Development binaries
|
||||||
|
ii libc6-dbg:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: detached debugging symbols
|
||||||
|
ii libc6-dev-i386 2.39-0ubuntu8.1 amd64 GNU C Library: 32-bit development libraries for AMD64
|
||||||
|
ii libc6-dev-x32 2.39-0ubuntu8.1 amd64 GNU C Library: X32 ABI Development Libraries for AMD64
|
||||||
|
ii libc6-dev:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: Development Libraries and Header Files
|
||||||
|
ii libc6-i386 2.39-0ubuntu8.1 amd64 GNU C Library: 32-bit shared libraries for AMD64
|
||||||
|
ii libc6-x32 2.39-0ubuntu8.1 amd64 GNU C Library: X32 ABI Shared libraries for AMD64
|
||||||
|
ii libc6:amd64 2.39-0ubuntu8.1 amd64 GNU C Library: Shared libraries
|
||||||
|
ii libc6:i386 2.39-0ubuntu8.1 i386 GNU C Library: Shared libraries
|
||||||
|
ii libcap-ng0:amd64 0.8.4-2build2 amd64 alternate POSIX capabilities library
|
||||||
|
ii libcap2:amd64 1:2.66-5ubuntu2 amd64 POSIX 1003.1e capabilities (library)
|
||||||
|
ii libcares2:amd64 1.27.0-1.0ubuntu1 amd64 asynchronous name resolver
|
||||||
|
ii libcc1-0:amd64 14-20240412-0ubuntu1 amd64 GCC cc1 plugin for GDB
|
||||||
|
ii libcom-err2:amd64 1.47.0-2.4~exp1ubuntu4 amd64 common error description library
|
||||||
|
ii libcrypt-dev:amd64 1:4.4.36-4build1 amd64 libcrypt development files
|
||||||
|
ii libcrypt1:amd64 1:4.4.36-4build1 amd64 libcrypt shared library
|
||||||
|
ii libctf-nobfd0:amd64 2.42-4ubuntu2 amd64 Compact C Type Format library (runtime, no BFD dependency)
|
||||||
|
ii libctf0:amd64 2.42-4ubuntu2 amd64 Compact C Type Format library (runtime, BFD dependency)
|
||||||
|
ii libcurl3t64-gnutls:amd64 8.5.0-2ubuntu10.1 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour)
|
||||||
|
ii libcurl4t64:amd64 8.5.0-2ubuntu10.1 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour)
|
||||||
|
ii libdb5.3t64:amd64 5.3.28+dfsg2-7 amd64 Berkeley v5.3 Database Libraries [runtime]
|
||||||
|
ii libdebconfclient0:amd64 0.271ubuntu3 amd64 Debian Configuration Management System (C-implementation library)
|
||||||
|
ii libdebuginfod-common 0.190-1.1build4 all configuration to enable the Debian debug info server
|
||||||
|
ii libdebuginfod1t64:amd64 0.190-1.1build4 amd64 library to interact with debuginfod (development files)
|
||||||
|
ii libdw1t64:amd64 0.190-1.1build4 amd64 library that provides access to the DWARF debug information
|
||||||
|
ii libelf1t64:amd64 0.190-1.1build4 amd64 library to read and write ELF files
|
||||||
|
ii liberror-perl 0.17029-2 all Perl module for error/exception handling in an OO-ish way
|
||||||
|
ii libexpat1:amd64 2.6.1-2build1 amd64 XML parsing C library - runtime library
|
||||||
|
ii libext2fs2t64:amd64 1.47.0-2.4~exp1ubuntu4 amd64 ext2/ext3/ext4 file system libraries
|
||||||
|
ii libffi8:amd64 3.4.6-1build1 amd64 Foreign Function Interface library runtime
|
||||||
|
ii libgcc-13-dev:amd64 13.2.0-23ubuntu4 amd64 GCC support library (development files)
|
||||||
|
ii libgcc-s1:amd64 14-20240412-0ubuntu1 amd64 GCC support library
|
||||||
|
ii libgcc-s1:i386 14-20240412-0ubuntu1 i386 GCC support library
|
||||||
|
ii libgcrypt20:amd64 1.10.3-2build1 amd64 LGPL Crypto library - runtime library
|
||||||
|
ii libgdbm-compat4t64:amd64 1.23-5.1build1 amd64 GNU dbm database routines (legacy support runtime version)
|
||||||
|
ii libgdbm6t64:amd64 1.23-5.1build1 amd64 GNU dbm database routines (runtime version)
|
||||||
|
ii libglib2.0-0t64:amd64 2.80.0-6ubuntu1 amd64 GLib library of C routines
|
||||||
|
ii libgmp10:amd64 2:6.3.0+dfsg-2ubuntu6 amd64 Multiprecision arithmetic library
|
||||||
|
ii libgnutls30t64:amd64 3.8.3-1.1ubuntu3.1 amd64 GNU TLS library - main runtime library
|
||||||
|
ii libgomp1:amd64 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library
|
||||||
|
ii libgpg-error0:amd64 1.47-3build2 amd64 GnuPG development runtime library
|
||||||
|
ii libgprofng0:amd64 2.42-4ubuntu2 amd64 GNU Next Generation profiler (runtime library)
|
||||||
|
ii libgssapi-krb5-2:amd64 1.20.1-6ubuntu2 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
|
||||||
|
ii libhiredis1.1.0:amd64 1.2.0-6ubuntu3 amd64 minimalistic C client library for Redis
|
||||||
|
ii libhogweed6t64:amd64 3.9.1-2.2build1 amd64 low level cryptographic library (public-key cryptos)
|
||||||
|
ii libhwasan0:amd64 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector
|
||||||
|
ii libicu74:amd64 74.2-1ubuntu3 amd64 International Components for Unicode
|
||||||
|
ii libidn2-0:amd64 2.3.7-2build1 amd64 Internationalized domain names (IDNA2008/TR46) library
|
||||||
|
ii libio-pty-perl 1:1.20-1build2 amd64 Perl module for pseudo tty IO
|
||||||
|
ii libipc-run-perl 20231003.0-1 all Perl module for running processes
|
||||||
|
ii libipt2 2.0.6-1build1 amd64 Intel Processor Trace Decoder Library
|
||||||
|
ii libisl23:amd64 0.26-3build1 amd64 manipulating sets and relations of integer points bounded by linear constraints
|
||||||
|
ii libitm1:amd64 14-20240412-0ubuntu1 amd64 GNU Transactional Memory Library
|
||||||
|
ii libjansson4:amd64 2.14-2build2 amd64 C library for encoding, decoding and manipulating JSON data
|
||||||
|
ii libjq1:amd64 1.7.1-3build1 amd64 lightweight and flexible command-line JSON processor - shared library
|
||||||
|
ii libjsoncpp25:amd64 1.9.5-6build1 amd64 library for reading and writing JSON for C++
|
||||||
|
ii libk5crypto3:amd64 1.20.1-6ubuntu2 amd64 MIT Kerberos runtime libraries - Crypto Library
|
||||||
|
ii libkeyutils1:amd64 1.6.3-3build1 amd64 Linux Key Management Utilities (library)
|
||||||
|
ii libkrb5-3:amd64 1.20.1-6ubuntu2 amd64 MIT Kerberos runtime libraries
|
||||||
|
ii libkrb5support0:amd64 1.20.1-6ubuntu2 amd64 MIT Kerberos runtime libraries - Support library
|
||||||
|
ii libldap2:amd64 2.6.7+dfsg-1~exp1ubuntu8 amd64 OpenLDAP libraries
|
||||||
|
ii liblsan0:amd64 14-20240412-0ubuntu1 amd64 LeakSanitizer -- a memory leak detector (runtime)
|
||||||
|
ii libluajit-5.1-2:amd64 2.1.0+git20231223.c525bcb+dfsg-1 amd64 Just in time compiler for Lua - library version
|
||||||
|
ii libluajit-5.1-common 2.1.0+git20231223.c525bcb+dfsg-1 all Just in time compiler for Lua - common files
|
||||||
|
ii liblz4-1:amd64 1.9.4-1build1 amd64 Fast LZ compression algorithm library - runtime
|
||||||
|
ii liblzma5:amd64 5.6.1+really5.4.5-1 amd64 XZ-format compression library
|
||||||
|
ii liblzo2-2:amd64 2.10-2build4 amd64 data compression library
|
||||||
|
ii libmagic-mgc 1:5.45-3build1 amd64 File type determination library using "magic" numbers (compiled magic file)
|
||||||
|
ii libmagic1t64:amd64 1:5.45-3build1 amd64 Recognize the type of data in a file using "magic" numbers - library
|
||||||
|
ii libmd0:amd64 1.1.0-2build1 amd64 message digest functions from BSD systems - shared library
|
||||||
|
ii libmount1:amd64 2.39.3-9ubuntu6 amd64 device mounting library
|
||||||
|
ii libmpc3:amd64 1.3.1-1build1 amd64 multiple precision complex floating-point library
|
||||||
|
ii libmpfr6:amd64 4.2.1-1build1 amd64 multiple precision floating-point computation
|
||||||
|
ii libmsgpackc2:amd64 4.0.0-3build1 amd64 binary-based efficient object serialization library
|
||||||
|
ii libmspack0t64:amd64 0.11-1.1build1 amd64 library for Microsoft compression formats (shared library)
|
||||||
|
ii libncurses6:amd64 6.4+20240113-1ubuntu2 amd64 shared libraries for terminal handling
|
||||||
|
ii libncursesw6:amd64 6.4+20240113-1ubuntu2 amd64 shared libraries for terminal handling (wide character support)
|
||||||
|
ii libnettle8t64:amd64 3.9.1-2.2build1 amd64 low level cryptographic library (symmetric and one-way cryptos)
|
||||||
|
ii libnghttp2-14:amd64 1.59.0-1build4 amd64 library implementing HTTP/2 protocol (shared library)
|
||||||
|
ii libnl-3-200:amd64 3.7.0-0.3build1 amd64 library for dealing with netlink sockets
|
||||||
|
ii libnl-genl-3-200:amd64 3.7.0-0.3build1 amd64 library for dealing with netlink sockets - generic netlink
|
||||||
|
ii libnpth0t64:amd64 1.6-3.1build1 amd64 replacement for GNU Pth using system threads
|
||||||
|
ii libonig5:amd64 6.9.9-1build1 amd64 regular expressions library
|
||||||
|
ii libp11-kit0:amd64 0.25.3-4ubuntu2 amd64 library for loading and coordinating access to PKCS#11 modules - runtime
|
||||||
|
ii libpam-modules-bin 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules for PAM - helper binaries
|
||||||
|
ii libpam-modules:amd64 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules for PAM
|
||||||
|
ii libpam-runtime 1.5.3-5ubuntu5 all Runtime support for the PAM library
|
||||||
|
ii libpam0g:amd64 1.5.3-5ubuntu5 amd64 Pluggable Authentication Modules library
|
||||||
|
ii libpcre2-32-0:amd64 10.42-4ubuntu2 amd64 New Perl Compatible Regular Expression Library - 32 bit runtime files
|
||||||
|
ii libpcre2-8-0:amd64 10.42-4ubuntu2 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files
|
||||||
|
ii libperl5.38t64:amd64 5.38.2-3.2build2 amd64 shared Perl library
|
||||||
|
ii libpipeline1:amd64 1.5.7-2 amd64 Unix process pipeline manipulation library
|
||||||
|
ii libpopt0:amd64 1.19+dfsg-1build1 amd64 lib for parsing cmdline parameters
|
||||||
|
ii libproc2-0:amd64 2:4.0.4-4ubuntu3 amd64 library for accessing process information from /proc
|
||||||
|
ii libpsl5t64:amd64 0.21.2-1.1build1 amd64 Library for Public Suffix List (shared libraries)
|
||||||
|
ii libpython2.7-minimal:amd64 2.7.18-8+deb11u1 amd64 Minimal subset of the Python language (version 2.7)
|
||||||
|
ii libpython3-stdlib:amd64 3.12.3-0ubuntu1 amd64 interactive high-level object-oriented language (default python3 version)
|
||||||
|
ii libpython3.12-minimal:amd64 3.12.3-1 amd64 Minimal subset of the Python language (version 3.12)
|
||||||
|
ii libpython3.12-stdlib:amd64 3.12.3-1 amd64 Interactive high-level object-oriented language (standard library, version 3.12)
|
||||||
|
ii libpython3.12t64:amd64 3.12.3-1 amd64 Shared Python runtime library (version 3.12)
|
||||||
|
ii libquadmath0:amd64 14-20240412-0ubuntu1 amd64 GCC Quad-Precision Math Library
|
||||||
|
ii libreadline8t64:amd64 8.2-4build1 amd64 GNU readline and history libraries, run-time libraries
|
||||||
|
ii librhash0:amd64 1.4.3-3build1 amd64 shared library for hash functions computing
|
||||||
|
ii librtmp1:amd64 2.4+20151223.gitfa8646d.1-2build7 amd64 toolkit for RTMP streams (shared library)
|
||||||
|
ii libsasl2-2:amd64 2.1.28+dfsg1-5ubuntu3 amd64 Cyrus SASL - authentication abstraction library
|
||||||
|
ii libsasl2-modules-db:amd64 2.1.28+dfsg1-5ubuntu3 amd64 Cyrus SASL - pluggable authentication modules (DB)
|
||||||
|
ii libseccomp2:amd64 2.5.5-1ubuntu3 amd64 high level interface to Linux seccomp filter
|
||||||
|
ii libselinux1:amd64 3.5-2ubuntu2 amd64 SELinux runtime shared libraries
|
||||||
|
ii libsemanage-common 3.5-1build5 all Common files for SELinux policy management libraries
|
||||||
|
ii libsemanage2:amd64 3.5-1build5 amd64 SELinux policy management library
|
||||||
|
ii libsensors-config 1:3.6.0-9build1 all lm-sensors configuration files
|
||||||
|
ii libsensors5:amd64 1:3.6.0-9build1 amd64 library to read temperature/voltage/fan sensors
|
||||||
|
ii libsepol2:amd64 3.5-2build1 amd64 SELinux library for manipulating binary security policies
|
||||||
|
ii libsframe1:amd64 2.42-4ubuntu2 amd64 Library to handle the SFrame format (runtime library)
|
||||||
|
ii libsigsegv2:amd64 2.14-1ubuntu2 amd64 Library for handling page faults in a portable way
|
||||||
|
ii libsmartcols1:amd64 2.39.3-9ubuntu6 amd64 smart column output alignment library
|
||||||
|
ii libsource-highlight-common 3.1.9-4.3build1 all architecture-independent files for source highlighting library
|
||||||
|
ii libsource-highlight4t64:amd64 3.1.9-4.3build1 amd64 source highlighting library
|
||||||
|
ii libsqlite3-0:amd64 3.45.1-1ubuntu2 amd64 SQLite 3 shared library
|
||||||
|
ii libss2:amd64 1.47.0-2.4~exp1ubuntu4 amd64 command-line interface parsing library
|
||||||
|
ii libssh-4:amd64 0.10.6-2build2 amd64 tiny C SSH library (OpenSSL flavor)
|
||||||
|
ii libssh2-1t64:amd64 1.11.0-4.1build2 amd64 SSH2 client-side library
|
||||||
|
ii libssl3t64:amd64 3.0.13-0ubuntu3 amd64 Secure Sockets Layer toolkit - shared libraries
|
||||||
|
ii libstdc++-13-dev:amd64 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii libstdc++6:amd64 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3
|
||||||
|
ii libsystemd0:amd64 255.4-1ubuntu8 amd64 systemd utility library
|
||||||
|
ii libtalloc2:amd64 2.4.2-1build2 amd64 hierarchical pool based memory allocator
|
||||||
|
ii libtasn1-6:amd64 4.19.0-3build1 amd64 Manage ASN.1 structures (runtime)
|
||||||
|
ii libtermkey1:amd64 0.22-1 amd64 library for processing keyboard input
|
||||||
|
ii libtime-duration-perl 1.21-2 all module for rounded or exact English expression of durations
|
||||||
|
ii libtimedate-perl 2.3300-2 all collection of modules to manipulate date/time information
|
||||||
|
ii libtinfo6:amd64 6.4+20240113-1ubuntu2 amd64 shared low-level terminfo library for terminal handling
|
||||||
|
ii libtree-sitter0:amd64 0.20.8-2 amd64 incremental parsing system for programming tools
|
||||||
|
ii libtsan2:amd64 14-20240412-0ubuntu1 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime)
|
||||||
|
ii libubsan1:amd64 14-20240412-0ubuntu1 amd64 UBSan -- undefined behaviour sanitizer (runtime)
|
||||||
|
ii libuchardet0:amd64 0.0.8-1build1 amd64 universal charset detection library - shared library
|
||||||
|
ii libudev1:amd64 255.4-1ubuntu8 amd64 libudev shared library
|
||||||
|
ii libunibilium4:amd64 2.1.0-3 amd64 simple, self-contained terminfo library
|
||||||
|
ii libunistring5:amd64 1.1-2build1 amd64 Unicode string library for C
|
||||||
|
ii libunwind8:amd64 1.6.2-3build1 amd64 library to determine the call-chain of a program - runtime
|
||||||
|
ii liburing2:amd64 2.5-1build1 amd64 Linux kernel io_uring access library - shared library
|
||||||
|
ii libutempter0:amd64 1.2.1-3build1 amd64 privileged helper for utmp/wtmp updates (runtime)
|
||||||
|
ii libuuid1:amd64 2.39.3-9ubuntu6 amd64 Universally Unique ID library
|
||||||
|
ii libuv1t64:amd64 1.48.0-1.1build1 amd64 asynchronous event notification library - runtime library
|
||||||
|
ii libvterm0:amd64 0.3.3-2build1 amd64 abstract terminal library
|
||||||
|
ii libx11-6:amd64 2:1.8.7-1build1 amd64 X11 client-side library
|
||||||
|
ii libx11-data 2:1.8.7-1build1 all X11 client-side library
|
||||||
|
ii libx32asan8 14-20240412-0ubuntu1 amd64 AddressSanitizer -- a fast memory error detector (x32)
|
||||||
|
ii libx32atomic1 14-20240412-0ubuntu1 amd64 support library providing __atomic built-in functions (x32)
|
||||||
|
ii libx32gcc-13-dev 13.2.0-23ubuntu4 amd64 GCC support library (x32 development files)
|
||||||
|
ii libx32gcc-s1 14-20240412-0ubuntu1 amd64 GCC support library (x32)
|
||||||
|
ii libx32gomp1 14-20240412-0ubuntu1 amd64 GCC OpenMP (GOMP) support library (x32)
|
||||||
|
ii libx32itm1 14-20240412-0ubuntu1 amd64 GNU Transactional Memory Library (x32)
|
||||||
|
ii libx32quadmath0 14-20240412-0ubuntu1 amd64 GCC Quad-Precision Math Library (x32)
|
||||||
|
ii libx32stdc++-13-dev 13.2.0-23ubuntu4 amd64 GNU Standard C++ Library v3 (development files)
|
||||||
|
ii libx32stdc++6 14-20240412-0ubuntu1 amd64 GNU Standard C++ Library v3 (x32)
|
||||||
|
ii libx32ubsan1 14-20240412-0ubuntu1 amd64 UBSan -- undefined behaviour sanitizer (x32)
|
||||||
|
ii libxau6:amd64 1:1.0.9-1build6 amd64 X11 authorisation library
|
||||||
|
ii libxcb1:amd64 1.15-1ubuntu2 amd64 X C Binding
|
||||||
|
ii libxdmcp6:amd64 1:1.1.3-0ubuntu6 amd64 X11 Display Manager Control Protocol library
|
||||||
|
ii libxml2:amd64 2.9.14+dfsg-1.3ubuntu3 amd64 GNOME XML library
|
||||||
|
ii libxxhash0:amd64 0.8.2-2build1 amd64 shared library for xxhash
|
||||||
|
ii libyaml-0-2:amd64 0.2.5-1build1 amd64 Fast YAML 1.1 parser and emitter library
|
||||||
|
ii libzstd-dev:amd64 1.5.5+dfsg2-2build1 amd64 fast lossless compression algorithm -- development files
|
||||||
|
ii libzstd1:amd64 1.5.5+dfsg2-2build1 amd64 fast lossless compression algorithm
|
||||||
|
ii linux-libc-dev:amd64 6.8.0-31.31 amd64 Linux Kernel Headers for development
|
||||||
|
ii login 1:4.13+dfsg1-4ubuntu3 amd64 system login tools
|
||||||
|
ii logsave 1.47.0-2.4~exp1ubuntu4 amd64 save the output of a command in a log file
|
||||||
|
ii lsb-release 12.0-2 all Linux Standard Base version reporting utility (minimal implementation)
|
||||||
|
ii lua-luv:amd64 1.48.0-2-2build1 amd64 libuv bindings for Lua
|
||||||
|
ii lz4 1.9.4-1build1 amd64 Fast LZ compression algorithm library - tool
|
||||||
|
ii lzip 1.24.1-1build1 amd64 lossless data compressor based on the LZMA algorithm
|
||||||
|
ii lzop 1.04-2build3 amd64 fast compression program
|
||||||
|
ii make 4.3-4.1build2 amd64 utility for directing compilation
|
||||||
|
ii man-db 2.12.0-4build2 amd64 tools for reading manual pages
|
||||||
|
ii mawk 1.3.4.20240123-1build1 amd64 Pattern scanning and text processing language
|
||||||
|
ii media-types 10.1.0 all List of standard media types and their usual file extension
|
||||||
|
ii minify 2.20.17-1 amd64 CLI implementation of the Go minify library package
|
||||||
|
ii mksh 59c-37 amd64 MirBSD Korn Shell
|
||||||
|
ii moreutils 0.69-1 amd64 additional Unix utilities
|
||||||
|
ii mount 2.39.3-9ubuntu6 amd64 tools for mounting and manipulating filesystems
|
||||||
|
ii musl:amd64 1.2.4-2 amd64 standard C library
|
||||||
|
ii ncurses-base 6.4+20240113-1ubuntu2 all basic terminal type definitions
|
||||||
|
ii ncurses-bin 6.4+20240113-1ubuntu2 amd64 terminal-related programs and man pages
|
||||||
|
ii ncurses-term 6.4+20240113-1ubuntu2 all additional terminal type definitions
|
||||||
|
ii neovim 0.9.5-6ubuntu2 amd64 heavily refactored vim fork
|
||||||
|
ii neovim-runtime 0.9.5-6ubuntu2 all heavily refactored vim fork (runtime files)
|
||||||
|
ii netbase 6.4 all Basic TCP/IP networking system
|
||||||
|
ii ninja-build 1.11.1-2 amd64 small build system closest in spirit to Make
|
||||||
|
ii openssl 3.0.13-0ubuntu3 amd64 Secure Sockets Layer toolkit - cryptographic utility
|
||||||
|
ii p7zip 16.02+transitional.1 all transitional package
|
||||||
|
ii parallel 20231122+ds-1 all build and execute command lines from standard input in parallel
|
||||||
|
ii passwd 1:4.13+dfsg1-4ubuntu3 amd64 change and administer password and group data
|
||||||
|
ii patch 2.7.6-7build3 amd64 Apply a diff file to an original
|
||||||
|
ii patchelf 0.18.0-1.1build1 amd64 modify properties of ELF executables
|
||||||
|
ii patchutils 0.4.2-1build3 amd64 Utilities to work with patches
|
||||||
|
ii pax-utils 1.3.7-1 amd64 Security-focused ELF files checking tool
|
||||||
|
ii perl 5.38.2-3.2build2 amd64 Larry Wall's Practical Extraction and Report Language
|
||||||
|
ii perl-base 5.38.2-3.2build2 amd64 minimal Perl system
|
||||||
|
ii perl-modules-5.38 5.38.2-3.2build2 all Core Perl modules
|
||||||
|
ii procps 2:4.0.4-4ubuntu3 amd64 /proc file system utilities
|
||||||
|
ii proot 5.1.0-1.3 amd64 emulate chroot, bind mount and binfmt_misc for non-root users
|
||||||
|
ii python2.7-minimal 2.7.18-8+deb11u1 amd64 Minimal subset of the Python language (version 2.7)
|
||||||
|
ii python3 3.12.3-0ubuntu1 amd64 interactive high-level object-oriented language (default python3 version)
|
||||||
|
ii python3-argcomplete 3.1.4-1 all bash tab completion for argparse (for Python 3)
|
||||||
|
ii python3-minimal 3.12.3-0ubuntu1 amd64 minimal subset of the Python language (default python3 version)
|
||||||
|
ii python3-pyasn1 0.4.8-4 all ASN.1 library for Python (Python 3 module)
|
||||||
|
ii python3-pycryptodome 3.20.0+dfsg-1 amd64 cryptographic Python library (Python 3)
|
||||||
|
ii python3-pycurl 7.45.3-1build2 amd64 Python bindings to libcurl (Python 3)
|
||||||
|
ii python3-pyelftools 0.30-1 all pure-python3 library for parsing ELF and DWARF
|
||||||
|
ii python3-toml 0.10.2-1 all library for Tom's Obvious, Minimal Language - Python 3.x
|
||||||
|
ii python3-xmltodict 0.13.0-1 all Makes working with XML feel like you are working with JSON (Python 3)
|
||||||
|
ii python3-yaml 6.0.1-2build2 amd64 YAML parser and emitter for Python3
|
||||||
|
ii python3-zstd 1.5.5.1-1build1 amd64 python bindings to Yann Collet ZSTD compression library
|
||||||
|
ii python3.12 3.12.3-1 amd64 Interactive high-level object-oriented language (version 3.12)
|
||||||
|
ii python3.12-minimal 3.12.3-1 amd64 Minimal subset of the Python language (version 3.12)
|
||||||
|
ii re2c 3.1-1build1 amd64 lexer generator for C, C++, Go and Rust
|
||||||
|
ii readline-common 8.2-4build1 all GNU readline and history libraries, common files
|
||||||
|
ii ripgrep 14.1.0-1 amd64 Recursively searches directories for a regex pattern
|
||||||
|
ii rpcsvc-proto 1.4.2-0ubuntu7 amd64 RPC protocol compiler and definitions
|
||||||
|
ii rsync 3.2.7-1ubuntu1 amd64 fast, versatile, remote (and local) file-copying tool
|
||||||
|
ii screen 4.9.1-1build1 amd64 terminal multiplexer with VT100/ANSI terminal emulation
|
||||||
|
ii sed 4.9-2build1 amd64 GNU stream editor for filtering/transforming text
|
||||||
|
ii sensible-utils 0.0.22 all Utilities for sensible alternative selection
|
||||||
|
ii strace 6.8-0ubuntu2 amd64 System call tracer
|
||||||
|
ii sysstat 12.6.1-2 amd64 system performance tools for Linux
|
||||||
|
ii sysvinit-utils 3.08-6ubuntu3 amd64 System-V-like utilities
|
||||||
|
ii tar 1.35+dfsg-3build1 amd64 GNU version of the tar archiving utility
|
||||||
|
ii time 1.9-0.2build1 amd64 GNU time program for measuring CPU resource usage
|
||||||
|
ii tzdata 2024a-2ubuntu1 all time zone and daylight-saving time data
|
||||||
|
ii ubuntu-keyring 2023.11.28.1 all GnuPG keys of the Ubuntu archive
|
||||||
|
ii ucf 3.0043+nmu1 all Update Configuration File(s): preserve user changes to config files
|
||||||
|
ii universal-ctags 5.9.20210829.0-1 amd64 build tag file indexes of source code definitions
|
||||||
|
ii unzip 6.0-28ubuntu4 amd64 De-archiver for .zip files
|
||||||
|
ii util-linux 2.39.3-9ubuntu6 amd64 miscellaneous system utilities
|
||||||
|
ii valgrind 1:3.22.0-0ubuntu3 amd64 instrumentation framework for building dynamic analysis tools
|
||||||
|
ii wget 1.21.4-1ubuntu4 amd64 retrieves files from the web
|
||||||
|
ii xz-utils 5.6.1+really5.4.5-1 amd64 XZ-format compression utilities
|
||||||
|
ii yash 2.55-2 amd64 yet another shell
|
||||||
|
ii yq 3.1.0-3 all Command-line YAML processor - jq wrapper for YAML documents
|
||||||
|
ii zip 3.0-13build1 amd64 Archiver for .zip files
|
||||||
|
ii zlib1g-dev:amd64 1:1.3.dfsg-3.1ubuntu2 amd64 compression library - development
|
||||||
|
ii zlib1g:amd64 1:1.3.dfsg-3.1ubuntu2 amd64 compression library - runtime
|
||||||
|
ii zlib1g:i386 1:1.3.dfsg-3.1ubuntu2 i386 compression library - runtime
|
||||||
|
ii zoxide 0.9.3-1 amd64 Smarter cd command for your terminal
|
||||||
|
ii zsh 5.9-6ubuntu2 amd64 shell with lots of features
|
||||||
|
ii zsh-common 5.9-6ubuntu2 all architecture independent files for Zsh
|
||||||
|
ii zstd 1.5.5+dfsg2-2build1 amd64 fast lossless compression algorithm -- CLI tool
|
||||||
|
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|
||||||
|
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
|
||||||
|
||/ Name Version Architecture Description
|
||||||
|
|
||||||
|
Packages sorted by Installed-Size:
|
||||||
|
964659 ===== TOTAL (355 packages)
|
||||||
|
76943 valgrind amd64
|
||||||
|
72249 gcc-13-x86-64-linux-gnu amd64
|
||||||
|
37841 g++-13-x86-64-linux-gnu amd64
|
||||||
|
36493 cmake amd64
|
||||||
|
35919 libicu74 amd64
|
||||||
|
35027 cpp-13-x86-64-linux-gnu amd64
|
||||||
|
29327 libperl5.38t64 amd64
|
||||||
|
21815 neovim-runtime all
|
||||||
|
21684 git amd64
|
||||||
|
20518 libstdc++-13-dev amd64
|
||||||
|
19159 perl-modules-5.38 all
|
||||||
|
16248 zsh-common all
|
||||||
|
16092 libgcc-13-dev amd64
|
||||||
|
13430 libc6 amd64
|
||||||
|
13111 libc6-dev amd64
|
||||||
|
12519 gdb amd64
|
||||||
|
12321 fish-common all
|
||||||
|
12296 libc6 i386
|
||||||
|
12003 libc6-x32 amd64
|
||||||
|
11992 libc6-i386 amd64
|
||||||
|
11569 binutils-x86-64-linux-gnu amd64
|
||||||
|
11174 libc6-dbg amd64
|
||||||
|
10984 cmake-data all
|
||||||
|
10764 libasan8 amd64
|
||||||
|
9665 libx32asan8 amd64
|
||||||
|
9556 lib32asan8 amd64
|
||||||
|
9012 libpython3.12-stdlib amd64
|
||||||
|
8905 libpython3.12t64 amd64
|
||||||
|
8893 libtsan2 amd64
|
||||||
|
8636 lib32gcc-13-dev amd64
|
||||||
|
8335 libmagic-mgc amd64
|
||||||
|
8118 libc6-dev-x32 amd64
|
||||||
|
7923 python3.12-minimal amd64
|
||||||
|
7913 perl-base amd64
|
||||||
|
7492 libx32gcc-13-dev amd64
|
||||||
|
7166 linux-libc-dev amd64
|
||||||
|
6946 libc6-dev-i386 amd64
|
||||||
|
6944 coreutils amd64
|
||||||
|
6775 neovim amd64
|
||||||
|
6743 lib32stdc++-13-dev amd64
|
||||||
|
6607 libssl3t64 amd64
|
||||||
|
6433 libx32stdc++-13-dev amd64
|
||||||
|
6237 dpkg amd64
|
||||||
|
6158 7zip amd64
|
||||||
|
5210 ripgrep amd64
|
||||||
|
5169 libpython3.12-minimal amd64
|
||||||
|
4879 libhwasan0 amd64
|
||||||
|
4341 ncurses-term all
|
||||||
|
4244 minify amd64
|
||||||
|
4103 apt amd64
|
||||||
|
3983 gojq amd64
|
||||||
|
3956 python3-pycryptodome amd64
|
||||||
|
3949 libglib2.0-0t64 amd64
|
||||||
|
3849 libgprofng0 amd64
|
||||||
|
3806 liblsan0 amd64
|
||||||
|
3721 groff-base amd64
|
||||||
|
3627 fzf amd64
|
||||||
|
3605 python2.7-minimal amd64
|
||||||
|
3443 fish amd64
|
||||||
|
3441 re2c amd64
|
||||||
|
3438 util-linux amd64
|
||||||
|
3403 libaria2-0 amd64
|
||||||
|
3382 fd-find amd64
|
||||||
|
3349 libubsan1 amd64
|
||||||
|
3244 libapt-pkg6.0t64 amd64
|
||||||
|
3157 libx32ubsan1 amd64
|
||||||
|
3111 ksh93u+m amd64
|
||||||
|
3110 libstdc++6 amd64
|
||||||
|
3109 lib32ubsan1 amd64
|
||||||
|
2995 parallel all
|
||||||
|
2966 lib32stdc++6 amd64
|
||||||
|
2957 elfutils amd64
|
||||||
|
2928 man-db amd64
|
||||||
|
2785 libpython2.7-minimal amd64
|
||||||
|
2770 libx32stdc++6 amd64
|
||||||
|
2431 zsh amd64
|
||||||
|
2419 passwd amd64
|
||||||
|
2352 libgnutls30t64 amd64
|
||||||
|
2346 libbinutils amd64
|
||||||
|
2191 ht amd64
|
||||||
|
2182 libc-bin amd64
|
||||||
|
2161 git-man all
|
||||||
|
2103 strace amd64
|
||||||
|
2078 libxml2 amd64
|
||||||
|
2032 libisl23 amd64
|
||||||
|
2009 universal-ctags amd64
|
||||||
|
1980 aria2 amd64
|
||||||
|
1900 bash amd64
|
||||||
|
1884 openssl amd64
|
||||||
|
1798 zstd amd64
|
||||||
|
1796 procps amd64
|
||||||
|
1761 libdb5.3t64 amd64
|
||||||
|
1757 libunistring5 amd64
|
||||||
|
1736 gawk amd64
|
||||||
|
1730 libsqlite3-0 amd64
|
||||||
|
1712 libp11-kit0 amd64
|
||||||
|
1634 mksh amd64
|
||||||
|
1579 ccache amd64
|
||||||
|
1504 e2fsprogs amd64
|
||||||
|
1454 bash-completion all
|
||||||
|
1452 sysstat amd64
|
||||||
|
1448 yash amd64
|
||||||
|
1396 libgcrypt20 amd64
|
||||||
|
1381 tzdata all
|
||||||
|
1362 libx11-6 amd64
|
||||||
|
1342 libx11-data all
|
||||||
|
1321 zlib1g-dev amd64
|
||||||
|
1314 hyperfine amd64
|
||||||
|
1237 libzstd-dev amd64
|
||||||
|
1186 libmpfr6 amd64
|
||||||
|
1136 zoxide amd64
|
||||||
|
1123 libpam-modules amd64
|
||||||
|
1025 libsystemd0 amd64
|
||||||
|
1014 libkrb5-3 amd64
|
||||||
|
996 screen amd64
|
||||||
|
924 libcurl4t64 amd64
|
||||||
|
916 wget amd64
|
||||||
|
905 libcurl3t64-gnutls amd64
|
||||||
|
904 libarchive13t64 amd64
|
||||||
|
884 login amd64
|
||||||
|
852 busybox amd64
|
||||||
|
843 libbrotli1 amd64
|
||||||
|
812 lua-luv amd64
|
||||||
|
785 musl amd64
|
||||||
|
780 rsync amd64
|
||||||
|
765 libdw1t64 amd64
|
||||||
|
761 libzstd1 amd64
|
||||||
|
751 libsepol2 amd64
|
||||||
|
745 libsource-highlight4t64 amd64
|
||||||
|
735 python3.12 amd64
|
||||||
|
732 xz-utils amd64
|
||||||
|
708 tar amd64
|
||||||
|
698 lib32quadmath0 amd64
|
||||||
|
672 perl amd64
|
||||||
|
647 ncurses-bin amd64
|
||||||
|
635 libpcre2-8-0 amd64
|
||||||
|
629 libonig5 amd64
|
||||||
|
624 python3-pyelftools all
|
||||||
|
602 libluajit-5.1-2 amd64
|
||||||
|
560 binutils-common amd64
|
||||||
|
556 libtinfo6 amd64
|
||||||
|
554 libpcre2-32-0 amd64
|
||||||
|
552 findutils amd64
|
||||||
|
543 libgmp10 amd64
|
||||||
|
542 gcc-13 amd64
|
||||||
|
538 libext2fs2t64 amd64
|
||||||
|
536 zip amd64
|
||||||
|
536 libldap2 amd64
|
||||||
|
520 curl amd64
|
||||||
|
512 python3-yaml amd64
|
||||||
|
508 libbabeltrace1 amd64
|
||||||
|
496 libssh-4 amd64
|
||||||
|
493 debconf all
|
||||||
|
467 libreadline8t64 amd64
|
||||||
|
452 diffutils amd64
|
||||||
|
426 base-files amd64
|
||||||
|
425 libgssapi-krb5-2 amd64
|
||||||
|
424 libnettle8t64 amd64
|
||||||
|
424 htop amd64
|
||||||
|
422 libncursesw6 amd64
|
||||||
|
415 libssh2-1t64 amd64
|
||||||
|
404 make amd64
|
||||||
|
389 python3-pyasn1 all
|
||||||
|
386 ca-certificates all
|
||||||
|
384 ncurses-base all
|
||||||
|
384 libexpat1 amd64
|
||||||
|
378 liblzma5 amd64
|
||||||
|
375 unzip amd64
|
||||||
|
374 lib32gomp1 amd64
|
||||||
|
372 libgomp1 amd64
|
||||||
|
367 libmount1 amd64
|
||||||
|
358 libjq1 amd64
|
||||||
|
357 bfs amd64
|
||||||
|
355 ninja-build amd64
|
||||||
|
351 libx32gomp1 amd64
|
||||||
|
348 mount amd64
|
||||||
|
344 libcrypt-dev amd64
|
||||||
|
344 grep amd64
|
||||||
|
340 sed amd64
|
||||||
|
337 libhogweed6t64 amd64
|
||||||
|
337 gpgv amd64
|
||||||
|
336 libncurses6 amd64
|
||||||
|
328 cpio amd64
|
||||||
|
314 libudev1 amd64
|
||||||
|
310 libctf-nobfd0 amd64
|
||||||
|
309 less amd64
|
||||||
|
305 libsource-highlight-common all
|
||||||
|
300 libquadmath0 amd64
|
||||||
|
299 libx32quadmath0 amd64
|
||||||
|
289 libblkid1 amd64
|
||||||
|
288 libsemanage2 amd64
|
||||||
|
288 bsdutils amd64
|
||||||
|
287 bsdextrautils amd64
|
||||||
|
276 libpam-runtime all
|
||||||
|
273 patchelf amd64
|
||||||
|
273 mawk amd64
|
||||||
|
270 pax-utils amd64
|
||||||
|
269 libpam-modules-bin amd64
|
||||||
|
264 libuv1t64 amd64
|
||||||
|
257 libk5crypto3 amd64
|
||||||
|
255 libipc-run-perl all
|
||||||
|
254 base-passwd amd64
|
||||||
|
245 rpcsvc-proto amd64
|
||||||
|
244 gzip amd64
|
||||||
|
237 libjsoncpp25 amd64
|
||||||
|
235 libproc2-0 amd64
|
||||||
|
235 libgcc-s1 i386
|
||||||
|
232 lz4 amd64
|
||||||
|
232 libctf0 amd64
|
||||||
|
231 moreutils amd64
|
||||||
|
231 lib32gcc-s1 amd64
|
||||||
|
230 librhash0 amd64
|
||||||
|
226 libcrypt1 amd64
|
||||||
|
224 libidn2-0 amd64
|
||||||
|
224 debianutils amd64
|
||||||
|
218 patch amd64
|
||||||
|
218 libluajit-5.1-common all
|
||||||
|
215 patchutils amd64
|
||||||
|
214 ucf all
|
||||||
|
211 libmagic1t64 amd64
|
||||||
|
208 libpam0g amd64
|
||||||
|
207 libuchardet0 amd64
|
||||||
|
206 proot amd64
|
||||||
|
202 python3-pycurl amd64
|
||||||
|
200 libselinux1 amd64
|
||||||
|
200 libnghttp2-14 amd64
|
||||||
|
199 execstack amd64
|
||||||
|
198 libtree-sitter0 amd64
|
||||||
|
197 libgcc-s1 amd64
|
||||||
|
196 libxcb1 amd64
|
||||||
|
196 libelf1t64 amd64
|
||||||
|
187 libunwind8 amd64
|
||||||
|
187 dash amd64
|
||||||
|
185 libgpg-error0 amd64
|
||||||
|
184 libx32gcc-s1 amd64
|
||||||
|
176 libcares2 amd64
|
||||||
|
172 libnl-3-200 amd64
|
||||||
|
171 libsmartcols1 amd64
|
||||||
|
163 lzip amd64
|
||||||
|
162 zlib1g amd64
|
||||||
|
159 binutils amd64
|
||||||
|
157 zlib1g i386
|
||||||
|
157 lzop amd64
|
||||||
|
157 liblzo2-2 amd64
|
||||||
|
155 liblz4-1 amd64
|
||||||
|
154 python3-argcomplete all
|
||||||
|
151 libaudit1 amd64
|
||||||
|
149 libmpc3 amd64
|
||||||
|
148 libsasl2-2 amd64
|
||||||
|
148 libcc1-0 amd64
|
||||||
|
143 libyaml-0-2 amd64
|
||||||
|
143 libseccomp2 amd64
|
||||||
|
137 librtmp1 amd64
|
||||||
|
136 libhiredis1.1.0 amd64
|
||||||
|
132 libkrb5support0 amd64
|
||||||
|
131 libipt2 amd64
|
||||||
|
130 init-system-helpers all
|
||||||
|
129 bubblewrap amd64
|
||||||
|
127 libbsd0 amd64
|
||||||
|
126 time amd64
|
||||||
|
126 libsframe1 amd64
|
||||||
|
123 libtimedate-perl all
|
||||||
|
121 libtasn1-6 amd64
|
||||||
|
120 libpopt0 amd64
|
||||||
|
115 libitm1 amd64
|
||||||
|
113 lib32itm1 amd64
|
||||||
|
112 jq amd64
|
||||||
|
111 python3-minimal amd64
|
||||||
|
110 gcc-14-base i386
|
||||||
|
110 gcc-14-base amd64
|
||||||
|
110 gcc-13-base amd64
|
||||||
|
109 bzip2 amd64
|
||||||
|
107 sysvinit-utils amd64
|
||||||
|
105 libx32itm1 amd64
|
||||||
|
105 libc-dev-bin amd64
|
||||||
|
103 libio-pty-perl amd64
|
||||||
|
100 libassuan0 amd64
|
||||||
|
99 libpsl5t64 amd64
|
||||||
|
98 libmspack0t64 amd64
|
||||||
|
97 libcap2 amd64
|
||||||
|
96 liburing2 amd64
|
||||||
|
95 libunibilium4 amd64
|
||||||
|
95 libjansson4 amd64
|
||||||
|
95 libbz2-1.0 amd64
|
||||||
|
93 media-types all
|
||||||
|
93 libvterm0 amd64
|
||||||
|
93 libgdbm6t64 amd64
|
||||||
|
90 libxxhash0 amd64
|
||||||
|
84 libuuid1 amd64
|
||||||
|
83 libtalloc2 amd64
|
||||||
|
82 python3 amd64
|
||||||
|
82 cabextract amd64
|
||||||
|
81 libbzip3-0 amd64
|
||||||
|
79 libsensors5 amd64
|
||||||
|
79 libmd0 amd64
|
||||||
|
77 readline-common all
|
||||||
|
77 python3-toml all
|
||||||
|
75 libsasl2-modules-db amd64
|
||||||
|
74 libasm1t64 amd64
|
||||||
|
74 libacl1 amd64
|
||||||
|
72 libffi8 amd64
|
||||||
|
72 diffstat amd64
|
||||||
|
69 yq all
|
||||||
|
69 libss2 amd64
|
||||||
|
69 liberror-perl all
|
||||||
|
69 libdebuginfod1t64 amd64
|
||||||
|
67 libpipeline1 amd64
|
||||||
|
66 bzip3 amd64
|
||||||
|
63 sensible-utils all
|
||||||
|
63 libtermkey1 amd64
|
||||||
|
63 file amd64
|
||||||
|
61 ksh all
|
||||||
|
60 libcap-ng0 amd64
|
||||||
|
60 libattr1 amd64
|
||||||
|
57 libcom-err2 amd64
|
||||||
|
53 libnl-genl-3-200 amd64
|
||||||
|
51 logsave amd64
|
||||||
|
51 libutempter0 amd64
|
||||||
|
50 libdebuginfod-common all
|
||||||
|
48 libmsgpackc2 amd64
|
||||||
|
47 python3-xmltodict all
|
||||||
|
47 libsigsegv2 amd64
|
||||||
|
46 hostname amd64
|
||||||
|
45 libatomic1 amd64
|
||||||
|
44 python3-zstd amd64
|
||||||
|
43 libx32atomic1 amd64
|
||||||
|
42 libnpth0t64 amd64
|
||||||
|
41 libxdmcp6 amd64
|
||||||
|
41 libkeyutils1 amd64
|
||||||
|
39 lib32atomic1 amd64
|
||||||
|
38 libdebconfclient0 amd64
|
||||||
|
37 gcc amd64
|
||||||
|
37 cpp amd64
|
||||||
|
36 netbase all
|
||||||
|
36 chrpath amd64
|
||||||
|
34 libtime-duration-perl all
|
||||||
|
34 libgdbm-compat4t64 amd64
|
||||||
|
33 libxau6 amd64
|
||||||
|
29 ubuntu-keyring all
|
||||||
|
28 g++-13 amd64
|
||||||
|
27 libpython3-stdlib amd64
|
||||||
|
26 libsemanage-common all
|
||||||
|
25 libsensors-config all
|
||||||
|
25 gcc-x86-64-linux-gnu amd64
|
||||||
|
20 cpp-x86-64-linux-gnu amd64
|
||||||
|
17 lsb-release all
|
||||||
|
17 libaudit-common all
|
||||||
|
13 g++ amd64
|
||||||
|
11 g++-x86-64-linux-gnu amd64
|
||||||
|
11 cpp-13 amd64
|
||||||
|
8 p7zip all
|
||||||
|
8 gcc-multilib amd64
|
||||||
|
6 gcc-13-multilib amd64
|
||||||
|
6 g++-multilib amd64
|
||||||
|
6 g++-13-multilib amd64
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
#! /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-20210104-v5
|
|
||||||
|
|
||||||
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 user 0 to subuid-user 1, and map container user 2000 to current host user
|
|
||||||
flags+=( --uidmap=0:1:1 --uidmap=2000:0:1 )
|
|
||||||
# map container group 0 to subgid-group 1, and map container group 2000 to current host group
|
|
||||||
flags+=( --gidmap=0:1:1 --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 ) # 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
|
|
||||||
# git status .
|
|
||||||
# # rebuild
|
|
||||||
# make all
|
|
||||||
# # make sure that the stub files did rebuild correctly:
|
|
||||||
# git status .
|
|
||||||
# git diff .
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
FROM docker.io/library/ubuntu:22.04
|
|
||||||
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 more convenient and also allow building
|
|
||||||
# the full UPX binary inside the container via CMake:
|
|
||||||
bzip2 cmake elfutils file g++ libzstd-dev lzop ninja-build patch \
|
|
||||||
patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \
|
|
||||||
&& true
|
|
||||||
|
|
||||||
# manually install compat libs from Ubuntu 16.04
|
|
||||||
RUN cd /root \
|
|
||||||
&& aria2c --checksum=sha-256=2605f43f8047fc972855bb909f1dd7af761bbfd35ae559ad689b0d55a4236d69 \
|
|
||||||
'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb' \
|
|
||||||
&& aria2c --checksum=sha-256=3973a97387bbe0e8a775995c22861d8478edee2a594e8117970f635de25b2c8a \
|
|
||||||
'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-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-20210104
|
|
||||||
RUN cd /root \
|
|
||||||
&& aria2c --checksum=sha-256=abcd8337cc656fe68d7bbb2ffe0f1e5ddce618688aa0e18c1ebcc40072843884 \
|
|
||||||
'https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz' \
|
|
||||||
&& cd /usr/local/bin \
|
|
||||||
&& tar -xoaf /root/bin-upx-20210104.tar.xz \
|
|
||||||
&& rm /root/bin-upx-20210104.tar.xz \
|
|
||||||
&& true
|
|
||||||
|
|
||||||
# install previous UPX versions into /usr/local/bin
|
|
||||||
RUN cd /root \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.92/upx-3.92-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.93/upx-3.93-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.95/upx-3.95-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.96/upx-3.96-amd64_linux.tar.xz \
|
|
||||||
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
|
||||||
&& rm ./upx-*.tar.* \
|
|
||||||
&& d=upx-3.91-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.91 \
|
|
||||||
&& d=upx-3.92-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.92 \
|
|
||||||
&& d=upx-3.93-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.93 \
|
|
||||||
&& d=upx-3.94-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.94 \
|
|
||||||
&& d=upx-3.95-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.95 \
|
|
||||||
&& d=upx-3.96-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.96 \
|
|
||||||
&& rm -rf ./upx-*linux \
|
|
||||||
&& true
|
|
||||||
|
|
||||||
# create default user upx 2000:2000
|
|
||||||
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
|
||||||
&& mkdir -p /home/upx/.local/bin /home/upx/src/upx \
|
|
||||||
&& ln -s /usr/local/bin/bin-upx-20210104 /home/upx/.local/bin/bin-upx \
|
|
||||||
&& chown -R upx:upx /home/upx \
|
|
||||||
&& true
|
|
||||||
USER upx
|
|
||||||
@@ -31,9 +31,10 @@ LC_ALL=C sort -z | xargs -0r perl -n -e '
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m,\t,) {
|
if (m,\t,) {
|
||||||
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
elsif ($ARGV =~ m,\.mk$,) { }
|
||||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||||
|
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
||||||
}
|
}
|
||||||
' || exit 1
|
' || exit 1
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ git ls-files --full-name -z | perl -0 -n -e '
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m,\t,) {
|
if (m,\t,) {
|
||||||
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
|
||||||
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
elsif ($ARGV =~ m,\.mk$,) { }
|
||||||
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
|
||||||
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
|
||||||
|
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
|
||||||
}
|
}
|
||||||
' || exit 1
|
' || exit 1
|
||||||
|
|||||||
Executable
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# simulate "readlink -en FILE"
|
||||||
|
# - result may differ from actual readlink(1) for edge cases
|
||||||
|
# - works with Python2 and Python3
|
||||||
|
#
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.exit(1)
|
||||||
|
real_path = os.path.realpath(sys.argv[1])
|
||||||
|
if not os.path.exists(real_path):
|
||||||
|
sys.exit(1)
|
||||||
|
sys.stdout.write(real_path)
|
||||||
|
sys.stdout.flush()
|
||||||
Executable
+15
@@ -0,0 +1,15 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# simulate "readlink -fn FILE" for systems that lack it (e.g. macOS-11)
|
||||||
|
# - result may differ from actual readlink(1) for edge cases
|
||||||
|
# - works with Python2 and Python3
|
||||||
|
#
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.exit(1)
|
||||||
|
real_path = os.path.realpath(sys.argv[1])
|
||||||
|
sys.stdout.write(real_path)
|
||||||
|
sys.stdout.flush()
|
||||||
Executable
+42
@@ -0,0 +1,42 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# assemble cmake config flags; useful for CI jobs
|
||||||
|
# also see misc/make/Makefile-extra.mk
|
||||||
|
|
||||||
|
cmake_config_flags=()
|
||||||
|
|
||||||
|
# promote an environment variable to a CMake cache entry:
|
||||||
|
__add_cmake_config() {
|
||||||
|
[[ -z "${!1}" ]] || cmake_config_flags+=( -D$1="${!1}" )
|
||||||
|
}
|
||||||
|
|
||||||
|
# pass common CMake settings
|
||||||
|
for v in CMAKE_VERBOSE_MAKEFILE; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
# pass common CMake toolchain settings
|
||||||
|
for v in CMAKE_ADDR2LINE CMAKE_AR CMAKE_DLLTOOL CMAKE_LINKER CMAKE_NM CMAKE_OBJCOPY CMAKE_OBJDUMP CMAKE_RANLIB CMAKE_READELF CMAKE_STRIP CMAKE_TAPI; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
# pass common CMake LTO toolchain settings
|
||||||
|
for v in CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
# pass common CMake cross compilation settings
|
||||||
|
for v in CMAKE_SYSTEM_NAME CMAKE_SYSTEM_PROCESSOR CMAKE_CROSSCOMPILING_EMULATOR; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
# pass UPX config options; see CMakeLists.txt
|
||||||
|
for v in UPX_CONFIG_DISABLE_GITREV UPX_CONFIG_DISABLE_SANITIZE UPX_CONFIG_DISABLE_WERROR UPX_CONFIG_DISABLE_WSTRICT UPX_CONFIG_DISABLE_SELF_PACK_TEST UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
# pass UPX extra compile options; see CMakeLists.txt
|
||||||
|
for v in UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2 UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD; do
|
||||||
|
__add_cmake_config $v
|
||||||
|
done
|
||||||
|
|
||||||
|
exec "${CMAKE:-cmake}" $UPX_CMAKE_CONFIG_FLAGS "${cmake_config_flags[@]}" "$@"
|
||||||
|
exit 99
|
||||||
@@ -2,24 +2,26 @@
|
|||||||
## vim:set ts=4 sw=4 et:
|
## vim:set ts=4 sw=4 et:
|
||||||
set -e; set -o pipefail
|
set -e; set -o pipefail
|
||||||
|
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||||
|
#
|
||||||
# NOTE: we are using clang-format-10.0.1 from upx-stubtools
|
# NOTE: we are using clang-format-15.0.6 from upx-stubtools
|
||||||
# see https://github.com/upx/upx-stubtools/releases
|
# see https://github.com/upx/upx-stubtools/releases
|
||||||
|
#
|
||||||
# NOTE: we use .clang-format config from upx.git/.clang-format
|
# NOTE: we use .clang-format config from upx.git/.clang-format
|
||||||
|
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
echo "ERROR: $0: cannot find clang-format-10.0.1"
|
echo "ERROR: $0: cannot find clang-format-15.0.6"
|
||||||
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
|
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -29,4 +31,4 @@ ulimit -v 1048576 || true
|
|||||||
|
|
||||||
#echo $UPX_CLANG_FORMAT
|
#echo $UPX_CLANG_FORMAT
|
||||||
exec "$UPX_CLANG_FORMAT" -style=file "$@"
|
exec "$UPX_CLANG_FORMAT" -style=file "$@"
|
||||||
exit 1
|
exit 99
|
||||||
Executable
+166
@@ -0,0 +1,166 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
# mimic running "ctest", i.e. the "test" section of CMakeLists.txt; does not redirect stdout
|
||||||
|
# (allows freely setting $upx_exe_runner, while CMake is restricted to configure-time settings)
|
||||||
|
#
|
||||||
|
# requires:
|
||||||
|
# $upx_exe (required, but with convenience fallback "./upx")
|
||||||
|
# optional settings:
|
||||||
|
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# init & checks
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# upx_exe
|
||||||
|
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||||
|
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||||
|
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||||
|
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||||
|
[[ -f $upx_exe ]] || exit 1
|
||||||
|
|
||||||
|
# set emu and run_upx
|
||||||
|
emu=()
|
||||||
|
if [[ -n $upx_exe_runner ]]; then
|
||||||
|
# usage examples:
|
||||||
|
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||||
|
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||||
|
# export upx_exe_runner="wine"
|
||||||
|
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||||
|
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||||
|
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||||
|
fi
|
||||||
|
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
|
||||||
|
# run_upx sanity check
|
||||||
|
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# see CMakeLists.txt
|
||||||
|
#
|
||||||
|
# IDEA: create a Makefile and use "make -j" so that these tests can
|
||||||
|
# run in parallel much like "ctest --parallel 8"
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# similar to cmake function upx_cache_bool_vars()
|
||||||
|
set_cmake_bool_vars() {
|
||||||
|
local default_value="$1"; shift
|
||||||
|
local var_name
|
||||||
|
for var_name do
|
||||||
|
case "${!var_name}" in
|
||||||
|
0 | FALSE | OFF | false | off) eval "export $var_name=OFF" ;;
|
||||||
|
1 | TRUE | ON | true | on) eval "export $var_name=ON" ;;
|
||||||
|
*) eval "export $var_name=$default_value" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
set -x
|
||||||
|
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_SELF_PACK_TEST
|
||||||
|
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST
|
||||||
|
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_PACKED_TEST
|
||||||
|
if [[ "${emu[0]}" == *valgrind* ]]; then # valgrind is SLOW
|
||||||
|
set_cmake_bool_vars ON UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||||
|
else
|
||||||
|
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
|
||||||
|
fi
|
||||||
|
|
||||||
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
|
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||||
|
|
||||||
|
"${run_upx[@]}" --version
|
||||||
|
"${run_upx[@]}" --version-short
|
||||||
|
"${run_upx[@]}" --license
|
||||||
|
"${run_upx[@]}" --help
|
||||||
|
"${run_upx[@]}" --help-short
|
||||||
|
"${run_upx[@]}" --help-verbose
|
||||||
|
"${run_upx[@]}" --sysinfo
|
||||||
|
"${run_upx[@]}" --sysinfo -v
|
||||||
|
"${run_upx[@]}" --sysinfo -vv
|
||||||
|
|
||||||
|
if [[ $UPX_CONFIG_DISABLE_SELF_PACK_TEST == ON ]]; then
|
||||||
|
echo "Self-pack test disabled. All done."; exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
exe=".out"
|
||||||
|
upx_self_exe=$upx_exe
|
||||||
|
fo="--force-overwrite"
|
||||||
|
|
||||||
|
"${run_upx[@]}" -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}
|
||||||
|
"${run_upx[@]}" -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe}
|
||||||
|
"${run_upx[@]}" -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe}
|
||||||
|
"${run_upx[@]}" -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe}
|
||||||
|
"${run_upx[@]}" -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe}
|
||||||
|
"${run_upx[@]}" -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe}
|
||||||
|
"${run_upx[@]}" -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${exe}
|
||||||
|
"${run_upx[@]}" -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}
|
||||||
|
|
||||||
|
"${run_upx[@]}" -l upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||||
|
"${run_upx[@]}" --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||||
|
"${run_upx[@]}" -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
|
||||||
|
|
||||||
|
"${run_upx[@]}" -d upx-packed${exe} ${fo} -o upx-unpacked${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe}
|
||||||
|
"${run_upx[@]}" -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe}
|
||||||
|
|
||||||
|
# all unpacked files must be identical
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-fa${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-fn${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-fr${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-nrv2b${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-nrv2d${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-nrv2e${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-lzma${exe}
|
||||||
|
|
||||||
|
if [[ $UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST != ON ]]; then
|
||||||
|
"${emu[@]}" ./upx-unpacked${exe} --version-short
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
|
||||||
|
"${emu[@]}" ./upx-packed${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-fa${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-fn${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-fr${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-nrv2b${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-nrv2d${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-nrv2e${exe} --version-short
|
||||||
|
"${emu[@]}" ./upx-packed-lzma${exe} --version-short
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS != ON ]]; then
|
||||||
|
set +x
|
||||||
|
for method in nrv2b nrv2d nrv2e lzma; do
|
||||||
|
for level in 1 2 3 4 5 6 7; do
|
||||||
|
s="${method}-${level}"
|
||||||
|
echo "========== $s =========="
|
||||||
|
"${run_upx[@]}" -qq --${method} -${level} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe}
|
||||||
|
"${run_upx[@]}" -qq -l upx-packed-${s}${exe}
|
||||||
|
"${run_upx[@]}" -qq --fileinfo upx-packed-${s}${exe}
|
||||||
|
"${run_upx[@]}" -qq -t upx-packed-${s}${exe}
|
||||||
|
"${run_upx[@]}" -qq -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe}
|
||||||
|
cmp -s upx-unpacked${exe} upx-unpacked-${s}${exe}
|
||||||
|
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
|
||||||
|
"${emu[@]}" ./upx-packed-${s}${exe} --version-short
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
echo "All done."
|
||||||
Executable
+425
@@ -0,0 +1,425 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
# test file system behaviour with symlinks; requires:
|
||||||
|
# $upx_exe (required, but with convenience fallback "./upx")
|
||||||
|
# optional settings:
|
||||||
|
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||||
|
# $upx_test_file
|
||||||
|
#
|
||||||
|
|
||||||
|
# IMPORTANT NOTE: this script only works on Unix
|
||||||
|
# IMPORTANT NOTE: do NOT run as user root!
|
||||||
|
umask 0022
|
||||||
|
|
||||||
|
# disable on macOS for now, see https://github.com/upx/upx/issues/612
|
||||||
|
if [[ "$(uname)" == Darwin ]]; then
|
||||||
|
case "$UPX_DEBUG_FORCE_PACK_MACOS" in
|
||||||
|
"" | "0") echo "$0: SKIPPED"; exit 0 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
id || true
|
||||||
|
echo "PWD='$PWD'"
|
||||||
|
if [[ $UID == 0 || $EUID == 0 ]]; then
|
||||||
|
echo "ERROR: do not run as root: UID=$UID EUID=$EUID"
|
||||||
|
exit 91
|
||||||
|
fi
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# init & checks
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# upx_exe
|
||||||
|
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||||
|
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||||
|
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||||
|
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||||
|
[[ -f $upx_exe ]] || exit 1
|
||||||
|
|
||||||
|
# set emu and run_upx
|
||||||
|
emu=()
|
||||||
|
if [[ -n $upx_exe_runner ]]; then
|
||||||
|
# usage examples:
|
||||||
|
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||||
|
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||||
|
# export upx_exe_runner="wine"
|
||||||
|
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||||
|
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||||
|
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||||
|
fi
|
||||||
|
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
|
||||||
|
# run_upx sanity check
|
||||||
|
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# util functions
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
exit_code=0
|
||||||
|
num_errors=0
|
||||||
|
all_errors=
|
||||||
|
|
||||||
|
failed() {
|
||||||
|
####exit $1
|
||||||
|
# log error and keep going
|
||||||
|
exit_code=1
|
||||||
|
local a="$(basename "$(dirname "$PWD")")"
|
||||||
|
local b="$(basename "$PWD")"
|
||||||
|
let num_errors+=1 || true
|
||||||
|
all_errors="${all_errors} $a/$b/$1"
|
||||||
|
echo " FAILED $b/$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_file() {
|
||||||
|
local f
|
||||||
|
for f in "$@"; do
|
||||||
|
[[ ! -L "$f" && -f "$f" ]] && continue
|
||||||
|
echo "failed '$f': not a regular file"
|
||||||
|
failed 21
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_symlink_to_file() {
|
||||||
|
local f
|
||||||
|
for f in "$@"; do
|
||||||
|
[[ -L "$f" && -f "$f" ]] && continue
|
||||||
|
echo "failed '$f': not a symlink to file"
|
||||||
|
failed 22
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_symlink_to_dir() {
|
||||||
|
local f
|
||||||
|
for f in "$@"; do
|
||||||
|
[[ -L "$f" && -d "$f" ]] && continue
|
||||||
|
echo "failed '$f': not a symlink to dir"
|
||||||
|
failed 23
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_symlink_dangling() {
|
||||||
|
local f
|
||||||
|
for f in "$@"; do
|
||||||
|
[[ -L "$f" && ! -e "$f" ]] && continue
|
||||||
|
echo "failed '$f': not a dangling symlink"
|
||||||
|
failed 24
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_directory() {
|
||||||
|
if command -v rsync >/dev/null; then
|
||||||
|
rsync -aH "$1/" "$2"
|
||||||
|
else
|
||||||
|
cp -ai "$1" "$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_files() {
|
||||||
|
# clean
|
||||||
|
local d
|
||||||
|
for d in z_dir_1 z_dir_2 z_dir_3 z_dir_4; do
|
||||||
|
if [[ -d $d ]]; then
|
||||||
|
chmod -R +rwx "./$d"
|
||||||
|
rm -rf "./$d"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir z_dir_1
|
||||||
|
cd z_dir_1
|
||||||
|
: > z_file
|
||||||
|
ln -s z_file z_symlink_file
|
||||||
|
: > z_file_link_1
|
||||||
|
ln z_file_link_1 z_file_link_2
|
||||||
|
ln -s z_file_link_1 z_symlink_file_link
|
||||||
|
mkdir z_dir
|
||||||
|
ln -s z_dir z_symlink_dir
|
||||||
|
ln -s z_file_missing z_symlink_dangling
|
||||||
|
assert_file z_file*
|
||||||
|
assert_symlink_to_file z_symlink_file
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# write-protect z_dir_2/z_file*
|
||||||
|
copy_directory z_dir_1 z_dir_2
|
||||||
|
chmod a-w z_dir_2/z_file*
|
||||||
|
|
||||||
|
# write-protect z_dir_3 itself
|
||||||
|
copy_directory z_dir_1 z_dir_3
|
||||||
|
chmod a-w z_dir_3
|
||||||
|
|
||||||
|
# write-protect everything in z_dir_4
|
||||||
|
copy_directory z_dir_1 z_dir_4
|
||||||
|
chmod -R a-w z_dir_4
|
||||||
|
}
|
||||||
|
|
||||||
|
print_header() {
|
||||||
|
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||||
|
echo -e "\n${x}\n${1}\n${x}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
enter_dir() {
|
||||||
|
cd "$1" || exit 1
|
||||||
|
echo "===== $(basename "$PWD")"
|
||||||
|
}
|
||||||
|
leave_dir() {
|
||||||
|
echo "===== $(basename "$PWD") files"
|
||||||
|
ls -lA
|
||||||
|
cd ..
|
||||||
|
}
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# setup
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
#set -x # debug
|
||||||
|
|
||||||
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
|
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||||
|
|
||||||
|
# get $test_file
|
||||||
|
if [[ -f $upx_test_file ]]; then
|
||||||
|
test_file="$(readlink -fn "$upx_test_file")"
|
||||||
|
else
|
||||||
|
for test_file in /usr/bin/gmake /usr/bin/make /usr/bin/env /bin/ls; do
|
||||||
|
if [[ -f $test_file ]]; then
|
||||||
|
test_file="$(readlink -fn "$test_file")"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
ls -l "$test_file"
|
||||||
|
file "$test_file" || true
|
||||||
|
|
||||||
|
# create and enter a tmpdir in the current directory
|
||||||
|
tmpdir="$(mktemp -d tmp-upx-test-XXXXXX)"
|
||||||
|
cd "./$tmpdir" || exit 1
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# default
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
print_header "default"
|
||||||
|
flags="-qq -2 --no-filter"
|
||||||
|
mkdir default
|
||||||
|
cd default
|
||||||
|
create_files
|
||||||
|
enter_dir z_dir_1
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_2
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_3
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_4
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# force-overwrite
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
print_header "force-overwrite"
|
||||||
|
flags="-qq -2 --no-filter --force-overwrite"
|
||||||
|
mkdir force-overwrite
|
||||||
|
cd force-overwrite
|
||||||
|
create_files
|
||||||
|
enter_dir z_dir_1
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||||
|
assert_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_file z_symlink_dir
|
||||||
|
assert_file z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_2
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||||
|
assert_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_file z_symlink_dir
|
||||||
|
assert_file z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_3
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_4
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# link
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
print_header "link"
|
||||||
|
flags="-qq -2 --no-filter --link"
|
||||||
|
mkdir link
|
||||||
|
cd link
|
||||||
|
create_files
|
||||||
|
enter_dir z_dir_1
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||||
|
assert_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_file z_symlink_dir
|
||||||
|
assert_file z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_2
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
|
||||||
|
assert_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_file z_symlink_dir
|
||||||
|
assert_file z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_3
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
enter_dir z_dir_4
|
||||||
|
"${run_upx[@]}" $flags z_symlink_file && failed 10
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
|
||||||
|
"${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
|
||||||
|
assert_symlink_to_file z_symlink_file z_symlink_file_link
|
||||||
|
assert_symlink_to_dir z_symlink_dir
|
||||||
|
assert_symlink_dangling z_symlink_dangling
|
||||||
|
leave_dir
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# done
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
cd ..
|
||||||
|
chmod -R +rwx "./$tmpdir"
|
||||||
|
rm -rf "./$tmpdir"
|
||||||
|
|
||||||
|
if [[ $exit_code == 0 ]]; then
|
||||||
|
echo "UPX testsuite passed. All done."
|
||||||
|
else
|
||||||
|
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
|
||||||
|
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
|
||||||
|
fi
|
||||||
|
exit $exit_code
|
||||||
+209
@@ -0,0 +1,209 @@
|
|||||||
|
########## begin .sha256sums.recreate
|
||||||
|
expected_sha256sums__t010_decompressed="\
|
||||||
|
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
||||||
|
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
|
||||||
|
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
|
||||||
|
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
|
||||||
|
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
|
||||||
|
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
||||||
|
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
|
||||||
|
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
||||||
|
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
|
||||||
|
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
|
||||||
|
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
|
||||||
|
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
|
||||||
|
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
||||||
|
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
|
||||||
|
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
||||||
|
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
|
||||||
|
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t020_canonicalized="\
|
||||||
|
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
|
||||||
|
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
|
||||||
|
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
|
||||||
|
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
|
||||||
|
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
|
||||||
|
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
|
||||||
|
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
|
||||||
|
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
|
||||||
|
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
|
||||||
|
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
|
||||||
|
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
|
||||||
|
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
|
||||||
|
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
|
||||||
|
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
|
||||||
|
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
|
||||||
|
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
|
||||||
|
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
||||||
|
ef49d1c9617dbb3dc1bb36ab70df8a263cd816cc5e91ad28cc62f91ccc77afa7 *amd64-linux.elf/upx-3.91
|
||||||
|
253b1542cdcd5d554eb442e263eb44e400f00e63cfd4d0d727eacec5fcdbbd00 *amd64-linux.elf/upx-3.95
|
||||||
|
d96c42d14684e7248de5712310364eafa28b337695bc0d8c37f91d593b869250 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
c1d3b9ec3157f068097f5deffddce4fc4d3d95602daa539992e0accff6af0de8 *arm-linux.elf/upx-3.95
|
||||||
|
9ca862c0c92d7e4068145024486bb85a6031bf06f9a37c6af543234e08e8ab36 *arm-wince.pe/upx-3.91.exe
|
||||||
|
9173b4e4b1ac0b92e63dc51168dbd41d38208520b0f4c17b91d22e584ad55ae4 *arm64-linux.elf/upx-3.95
|
||||||
|
8c6c5f1678fb74d2f65a1e6c28e3089a4b99b49939fabac3ca1f71183bc73ffa *armeb-linux.elf/upx-3.91
|
||||||
|
13caa682f323a0438a651f53768af9b7fb1208980d46d94c6fb984ecf4422599 *armeb-linux.elf/upx-3.95
|
||||||
|
55f30818e45da393628aa80c3518f3cf099666ae3af5014bded2196ea28ddaea *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
6b80b2be79ec38af3071fcaf8f0d0ec524e4523e7e52e2f10111862ab93ec793 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
9bb71da401ae398ca42cde73afffe0c0db29fff24f22196c4116636ab6385170 *i386-linux.elf/upx-3.91
|
||||||
|
c2375a808f989c0f8290fcd9760db0033413323d8597deb796f182f8ac38afa2 *i386-linux.elf/upx-3.95
|
||||||
|
892695e1abdc0fbbd110ee30c317fde56947f4a8b3dfe413507ee7665f109986 *i386-win32.pe/upx-3.91.exe
|
||||||
|
f76ec227836388da3174007e2c5e27fb6cb397a83297872e78befb298a65796d *i386-win32.pe/upx-3.95.exe
|
||||||
|
8f7c5b3d67c78c117c02bec8b30ec5fca7baa79a35d250a4d981cb7137f8635d *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
745ac3afd263f3a653165bd229e35c817a58c9b894a8d6fbd4e5aaf6c38c1264 *mips-linux.elf/upx-3.95
|
||||||
|
a11da76425bc3bb308de3c19e6df22f56bf12c95afcf96ee8c2d4aaeda07ac8a *mipsel-linux.elf/upx-3.91
|
||||||
|
76c458e8e9b94eceb60d8c51f602a5dec44b2617886ea0b5b7b8802c61d962e9 *mipsel-linux.elf/upx-3.95
|
||||||
|
cec277d9e6e0cbf551f697c1d52e5d29b48533efbe4269df0aafbc12731a93ed *powerpc-linux.elf/upx-3.91
|
||||||
|
92c6cec7bf40d1aa5a62a55fce95bb99d94c5b477edbea127ee0468471ddbdb3 *powerpc-linux.elf/upx-3.95
|
||||||
|
df2f12597c901196e8f10782e72fb4c294955f03a66cc4e8bf3c24414929f717 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||||
|
f7e51450a373cb49f88e3e17c268f4198429f7ad06bed57dda28161b5383196a *amd64-linux.elf/upx-3.91
|
||||||
|
15c57828824d18604519fd43349f0340ccebfddf246ab355f8f30253123132ea *amd64-linux.elf/upx-3.95
|
||||||
|
728b2feceda3cfdd849aef4402d5d4e61aa6fa6d56266e7730b148dc66f4a7b0 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
188a3581ed2bac5fdfd50e08267e2e9cf4cf3ddbfc9f5ae15643298bda4bf11c *arm-linux.elf/upx-3.95
|
||||||
|
0711f0b8531de9659f099f43f2a883d628bee8de67f927e7137c19c6d23a30bd *arm-wince.pe/upx-3.91.exe
|
||||||
|
ae6fa69b1242bdfe808d64b7bbefddfe9c1c96302627ee8c65fa2851102fc502 *arm64-linux.elf/upx-3.95
|
||||||
|
7586b4029355eff2edf25141835ee2405ab9f936956e56420315c3d3fecc8bda *armeb-linux.elf/upx-3.91
|
||||||
|
e37875b1a91ef3c88bdba113649a061b72239dbfe77b77077c51254037a982b6 *armeb-linux.elf/upx-3.95
|
||||||
|
536e5a6bb18378f3eea81be12f218f4da60ea81eddf480434aaf418610e4e52d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
386f3037b26b8b2ce49a527028d738956e7ef649b29a0ef15e32acef4a3b291a *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
5761d8e12b01163c2bf378bef813df9a621da08c4508773db992a1cce067c70c *i386-linux.elf/upx-3.91
|
||||||
|
8afc2b549e2f78987641045697afaac0378b48e84c3e946334c9e4f1a7e693fa *i386-linux.elf/upx-3.95
|
||||||
|
1cc6663f3d9e847f9fec39a52c8efe38b39a66074c0ad77a880a84dde7c68d3f *i386-win32.pe/upx-3.91.exe
|
||||||
|
edf158ec6064e9b11b677a73239a70e414fa8c4f3b8950f74e81514ccb28ef4f *i386-win32.pe/upx-3.95.exe
|
||||||
|
faa36b6601743dcc5eaedb57187a893006652b6c68acecff179ce2cd123e6209 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
6c76928b5914b5c2e072bf2f90a2c95049cc41aec6b98b1f0b3c4f84df069f02 *mips-linux.elf/upx-3.95
|
||||||
|
029c2a47f1f613c538d2f39674167489a9d1bbbb6649a06d51d2b5ea983b4924 *mipsel-linux.elf/upx-3.91
|
||||||
|
4d837edcaf344505ad1a3721ec8e5db35ddaa273a747201e460b946c0a89d6ea *mipsel-linux.elf/upx-3.95
|
||||||
|
0e24a9e58939f7aacd3482db24e04bdac406a658dbb8d5e65d71d76d455e5aa5 *powerpc-linux.elf/upx-3.91
|
||||||
|
04bd4885f37c77a34b39e76cca2fd363f794ed1611093d7fffe1ee19920ce1dd *powerpc-linux.elf/upx-3.95
|
||||||
|
3b6be5bff0e435a8dbd8529562912c58dafdcb9694d75564238f3d086048abd2 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||||
|
715de64e0911c959d0ea208db13bf23a5e635e97e73feb9e04ac9d32117e6a3f *amd64-linux.elf/upx-3.91
|
||||||
|
da805c93ffea03da2f0c0dbb1b313cf0d88ef2c0cb0ad77b0be792210106cd6c *amd64-linux.elf/upx-3.95
|
||||||
|
213e6d3c80b4d741e8c78da915d32c1a2b74072d31e86ec46a10ac2535cf8f6f *amd64-win64.pe/upx-3.95.exe
|
||||||
|
3a66e868147347208935c042517b9f0e2e30d2dbb5c004ec8df6a9ab1e42ecd5 *arm-linux.elf/upx-3.95
|
||||||
|
8d295980b1e6a8240bf75b86a9b8e4561424cbabeab01246f51e553d84b40839 *arm-wince.pe/upx-3.91.exe
|
||||||
|
194947a439c1348570e45343e404c409be3f10feb70fdd87d9bca0addc772c44 *arm64-linux.elf/upx-3.95
|
||||||
|
a01384f43803428e0bfc5f8152304eb8618ef862e4e996a4a4fa4dd9c4576833 *armeb-linux.elf/upx-3.91
|
||||||
|
f2fdba359d52bb82fbab093176a3fbf37b9cb13e8d297523ed57051c3bd401e3 *armeb-linux.elf/upx-3.95
|
||||||
|
582030394a570f92be2d31b3862ab7fb0a6f08982c793a4d41c1471d2cabb939 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
f60dc2f332f58b7fa08f551f8c33d645d71d9ee79e2a719130d10ea4091373ef *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
13887e5466a7d0fc2652aedcef44e33e6ee9b8d6f0ac21dbc4ec90fcc0613bfa *i386-linux.elf/upx-3.91
|
||||||
|
636759f884399ff05e8493a759f60ea52cd4640eb5e9760f12fc25fbf730b1ed *i386-linux.elf/upx-3.95
|
||||||
|
c4a5d27ce7d8f0f326e49489223eda188a9be61971a88758a559efb9f854611a *i386-win32.pe/upx-3.91.exe
|
||||||
|
4ca9a3dd0e0ec38cc1aa3720d9c666f86df4fbe9dcb87ef0dad56d0a47dc327a *i386-win32.pe/upx-3.95.exe
|
||||||
|
f34a020e6325d213052d9f09c775c4d292c34c51380b1ab1b22c6663645167f0 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
3006af1262a29173c46340f1ee4526fba41145f7476841d5bf6b499aa6dea0fd *mips-linux.elf/upx-3.95
|
||||||
|
6af81d3c7cb6f1388925fe2d78ea96313d91d5e17249268739de4d56857f27bd *mipsel-linux.elf/upx-3.91
|
||||||
|
9d3849cd0037ef550703c574e0ccb3032b0d27217ec02c90a0ad8592d2a229f1 *mipsel-linux.elf/upx-3.95
|
||||||
|
704b6eb2033cf3eab30cbc53c35fc85bf0cb17f904528792de33967a1406091d *powerpc-linux.elf/upx-3.91
|
||||||
|
b89b2f3b250ddd156cb857717c86a0c0325a26dd084717c64f3022277ad02be4 *powerpc-linux.elf/upx-3.95
|
||||||
|
d52f201ab041fa64a4ee4234bd0e443e883e402bb93ced9e22554bd3ef3cc9ab *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||||
|
af8536d70ecb8c0680c1c9dc45ef60dcb13fab99f0e4644d9f86216a9cf003e2 *amd64-linux.elf/upx-3.91
|
||||||
|
004a705f4981a19f35767b33bdb70b942717a701ad8635bd56ba33e347c6ed69 *amd64-linux.elf/upx-3.95
|
||||||
|
cf07c202497ab38417ec3ccb65cbb0eb9b87f6c6df40d7dc4b44616282c8e0f8 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
da153c1747e0e242cc8b90c04362f67caa0aa638562bc12fcc7fe08ebb1b4fcb *arm-linux.elf/upx-3.95
|
||||||
|
9755110ebc951c9767e376155d9c6fee9789b009ce82ae47276664f5c832557e *arm-wince.pe/upx-3.91.exe
|
||||||
|
bb9e92b577ace19da295032c294063d724655cf5b97d014053c3fb05ce478884 *arm64-linux.elf/upx-3.95
|
||||||
|
a3c639403fd7b2f035315773c1aa3f68cc0532cf5cd075defd34fa44c4bbbb7a *armeb-linux.elf/upx-3.91
|
||||||
|
3f9604a69a945d86b93f2182ee82f754881331c7ef566d0cd4dc36d7acfa1aa0 *armeb-linux.elf/upx-3.95
|
||||||
|
e6518528d60861e37cb8429376628a7f3d1d5fc90f0933facd70b4e9e0b50709 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
53280a22c34ee1733007ccf858e1f5416c0f7043a4361799087e19a4b2a7eaf4 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
a51ce8993b3577fc2ee45b52174aaadc66c2f90ff53a0148ed096a65d99d24a2 *i386-linux.elf/upx-3.91
|
||||||
|
d018260f04d1efc2b46c8b7ff5b132358e58cb062c158b08a7179fbb561b0e48 *i386-linux.elf/upx-3.95
|
||||||
|
121e4acc3fbad4954cb2d2b957d229b042beaf4b68749c4f85ebfc60fcc80d43 *i386-win32.pe/upx-3.91.exe
|
||||||
|
d604523130da29af35705d9008098ae8b4bb9e7d4743357674470252dd68b8d3 *i386-win32.pe/upx-3.95.exe
|
||||||
|
4d26f0be2b6b6c4802515a7f0dfd97998c6d23e696ae6c0393c9ac0893885a9b *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
4d3b0c7b4dabb5a7a193a0a2899f086f5dfc555106188131389678ecc137378a *mips-linux.elf/upx-3.95
|
||||||
|
be2e9fb66c087f37b58f203b406b618526296dd8c9c53e73bb622740f1e377ba *mipsel-linux.elf/upx-3.91
|
||||||
|
9da821fac44f787875727cf001ca33ed87e02c5fe477f0ebb965c5e0eb62c26c *mipsel-linux.elf/upx-3.95
|
||||||
|
98d7c0214663ae47f59244a90aabbb72a798a4ad0c74ce79d448013f5cad6893 *powerpc-linux.elf/upx-3.91
|
||||||
|
c58266817c4e38982c66e4b75e0002c6e7a51710864f930987b8670ee121ee0b *powerpc-linux.elf/upx-3.95
|
||||||
|
7fecab59271c9d4596bd79978e112a5fea72e33bd7c53c1985d187009d807724 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||||
|
977380191b474f5a7fa78e8015a279bfaa77626bc56d83185fec8761531b3029 *amd64-linux.elf/upx-3.91
|
||||||
|
4f94c9bee7a2f7deed245dc767c215654a41373be978123c3f1ef9074454c59d *amd64-linux.elf/upx-3.95
|
||||||
|
00aa338efc865f720a901afb1c19064cf137abb71d361be9b19192b0ff8a9479 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
c1908a58fcc23a9a964f2cd5f76f805a7cc9ca39480d129c6bdb8db30033840b *arm-linux.elf/upx-3.95
|
||||||
|
78ffa99aa69e2f66f864dce88e787e3b1c0c056009e0f863986d65aabd186107 *arm-wince.pe/upx-3.91.exe
|
||||||
|
245c6bb22ae2b39671503244329f1e4498277b06d600447ad81c7d41ebc872d6 *arm64-linux.elf/upx-3.95
|
||||||
|
9e359728cdb9bf6ea21a864b2c9da56809eda27d6b88828b85ab815311bf77b6 *armeb-linux.elf/upx-3.91
|
||||||
|
86edb5959b5cabad270d7c77e750bc710424b92cfb2ebaeedf3ba403382f4e93 *armeb-linux.elf/upx-3.95
|
||||||
|
b65db2766ffdd45657a07edd57426c55acce2a73a1e3559ab43903ae77574131 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
e827d64700b14e8c19de2882e66d0df0fca4cda0255ae41a66810e4c86583a93 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
c95a7ad9a5015abb1b8a163afe46b4f1529c70ca4ef9353cfb6e5c7eef60245c *i386-linux.elf/upx-3.91
|
||||||
|
21ef65f5c756f216c0f9db9475a7514e10b8e003c30bc22416ec8156cba65252 *i386-linux.elf/upx-3.95
|
||||||
|
6db34f6cdc626c4857fc7b188910562909e571eed3be2116448e244ca82eaa64 *i386-win32.pe/upx-3.91.exe
|
||||||
|
68a08dd3995681af594c66df4b94559e5900f0a09fcf822e3fc2522c3133ad69 *i386-win32.pe/upx-3.95.exe
|
||||||
|
1546ce426b3cfe38bdea18fafadee409253d5d2b452aae5476e073b29e17bb58 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
6ecc64d1fb9fb2a675980ce939b0b8142e802e7218b8ea45f2bb82205ed9242e *mips-linux.elf/upx-3.95
|
||||||
|
eb3c90f8f775e70cb2cc187b7e55d66a3bb28fa760e14a17353acd1130fd122a *mipsel-linux.elf/upx-3.91
|
||||||
|
b47964dbe65e9975d6bddfbfdd321a5e6c96b6eba79b30d0f94ec4323b796991 *mipsel-linux.elf/upx-3.95
|
||||||
|
c32a2deaa707eafaed36a4ab8fb26bb8d8c63a9743b19ad207e305553d14c7fe *powerpc-linux.elf/upx-3.91
|
||||||
|
c4dbfbd0f5021d50f1addc68273f20b49204bf26ae8c8896a0aacc7d2c5a2d47 *powerpc-linux.elf/upx-3.95
|
||||||
|
bb96ea8a29500893b729dad4afe90b09186641c32c42a70a3d2380a771f896d9 *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||||
|
de00c3bcb56d78c3fd1d1e633b3f64b884b3611abc305b9e79f4f14385178418 *amd64-linux.elf/upx-3.91
|
||||||
|
eb5aea4d780711dd59e3f86d34a49f16d3669acc6569292bf9ea445d406c5c80 *amd64-linux.elf/upx-3.95
|
||||||
|
2fae12ccc55eeac6c05ff2c6b27539c66816080647283ac2e1b22576242b6bb5 *amd64-win64.pe/upx-3.95.exe
|
||||||
|
14120b8348172a08cd7651184941820ed1c69b7a8d859e375390eee529f5c94e *arm-linux.elf/upx-3.95
|
||||||
|
a6690508c1acdaa07ce97feec0f330182c24206d8e9133949d2a42fccc1cbf27 *arm-wince.pe/upx-3.91.exe
|
||||||
|
4f30adcd3d047fad15344bf6cf3cf4f91cfbacbb121af889df8634fa4c888247 *arm64-linux.elf/upx-3.95
|
||||||
|
f85f0a70b024a050999d476420b9db88206e340b2ffff3781c491b538ae03e37 *armeb-linux.elf/upx-3.91
|
||||||
|
e1b2dc75427212dc268c6921aa2059adf5709b21f230432a4725b16e1c64b238 *armeb-linux.elf/upx-3.95
|
||||||
|
fcf64cfce9e9762e03740d2bf9e2e86d873ade1b6f4a68eb07625f516426810d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
9188a6f911b79fb8629880836b2f5787eb4d938872ba4f1a64c93e70cde9f428 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
8369ff8112aeb55a1684ce0ec16e13e6bc524b734557b49b292f9aae60edccb6 *i386-linux.elf/upx-3.91
|
||||||
|
c4e16cc1a64db618d9038ea9ba6032b7fe5aac05c0d7731b91373094a6a0f6e4 *i386-linux.elf/upx-3.95
|
||||||
|
b21cf7756542b3bab5f4a59d4036cd3176e297dceb744dec96ac365be6568dcd *i386-win32.pe/upx-3.91.exe
|
||||||
|
b1bc0d360918d51ca7b7f32f5083845e4566c7fa7a425d0451f4b10f227d1eac *i386-win32.pe/upx-3.95.exe
|
||||||
|
c40af5d1ba0531abb92587cbcbe604d4f562b685d6e7bbb40ec4d879fddf1267 *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
0865d2f1d65e2693d801b3c28d64910a009707be65598772df655c640469a4e5 *mips-linux.elf/upx-3.95
|
||||||
|
4cf108686c2419c6d82eecb2473a6d0ca0a0b47096cc01ea2b55113f84762cc7 *mipsel-linux.elf/upx-3.91
|
||||||
|
0a90a99e0ebb1e9c86e0bdf6a3eec6ca116e65b235ba1ee9029694b84cadc438 *mipsel-linux.elf/upx-3.95
|
||||||
|
4d8f85d254b1fd87bebe2fd732afd6214c98b869cda17ff0c4c566358446038a *powerpc-linux.elf/upx-3.91
|
||||||
|
bbc6179756637db10b636d7383226cb1d685866e8e9191069107725365b42f38 *powerpc-linux.elf/upx-3.95
|
||||||
|
52d7db1d6d6611d4a064c036b57044fd93d4c5762452be07188ee2ff6b1e42bc *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||||
|
ee887f19ee6a5d5f0a0ce7116a41570e106c10bc0bb25acf7eb3ee254c1ed560 *amd64-linux.elf/upx-3.91
|
||||||
|
9bd019e6442b219825f19082a20e4e73c49b24a4dee39e9e2cf0fc907ecdb46f *amd64-linux.elf/upx-3.95
|
||||||
|
382fe4b3e4f575322b746d7d45e4553ba3cf47cb4351b9900508fb52a00118ad *amd64-win64.pe/upx-3.95.exe
|
||||||
|
ae71103c2e105099ab345a648abf109b9aec3039137c90af30710dd4a4b51736 *arm-linux.elf/upx-3.95
|
||||||
|
9150f49be3fcb03a5f23b209e5db443c9b96fa4d8e20d3730195f9eafff5d8e8 *arm-wince.pe/upx-3.91.exe
|
||||||
|
100d9cee849b7996cbde2dc82df766e5104ae030055ae9b286c53b60e9e51405 *arm64-linux.elf/upx-3.95
|
||||||
|
43ded21db5b7b8355bc371e39cd3b1be05e91635e3cb6d64f9a8aea16127e157 *armeb-linux.elf/upx-3.91
|
||||||
|
b0ac3a36871630af80bb9b6ba94604b3ebc1fe05fdb6d095a7c461916fb3d231 *armeb-linux.elf/upx-3.95
|
||||||
|
36b6a947567386e325f1d3ff84a55ecbd37687e3264cfb0a57aa5e3be5ff85f9 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
|
ad02fcac751563d49cb0711d818231c1030bad9ef2b12fd54e60e2bc6510e9d6 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
|
d1b4e2c81a0baf4ad273dd96722783e9219e69049a78d536757f39761a7cfe8b *i386-linux.elf/upx-3.91
|
||||||
|
6e509d556ccd2af102d43924bd4eb1e9bed9d557e44387769032df4ede525f0d *i386-linux.elf/upx-3.95
|
||||||
|
2138186fb26cc7983ec4a4ead290573f2e8226fea4a0b9b6d668d86fb21d1573 *i386-win32.pe/upx-3.91.exe
|
||||||
|
5f286eaf28bab252a0f4f069b7b88910b9ce62327c4d15837b91ce65e4f9030e *i386-win32.pe/upx-3.95.exe
|
||||||
|
0ab25c2cd8cf53a31323464080991344479998f45fd9b215caba003f96e9e11c *m68k-atari.tos/upx-3.91.ttp
|
||||||
|
ba14b6b4e846d29bd4211fbcdb2a641f55f8a5700806af64c52182736b757f46 *mips-linux.elf/upx-3.95
|
||||||
|
40c23e16bfe68ec0a59f9651ac747db1e81f07deabc4c22a732e40e03e2b1100 *mipsel-linux.elf/upx-3.91
|
||||||
|
7d353d8381c3401c3c9765fa6091c634791ae9b7338ca5b769f63c38f8f418e7 *mipsel-linux.elf/upx-3.95
|
||||||
|
b43bd16efb19081fe0945948231486cdd1b1157d193ab7cbbd470594f46c57ca *powerpc-linux.elf/upx-3.91
|
||||||
|
7a8a24fa57d17f99b11133a0822a5e499681d09695525b80f8c61d90d06c4ac8 *powerpc-linux.elf/upx-3.95
|
||||||
|
0339ffc1d99f5b5ad12e8492b6a9dc707f705a120494a6bc453fb8617808d10a *powerpc64le-linux.elf/upx-3.95
|
||||||
|
"
|
||||||
|
########## end .sha256sums.recreate
|
||||||
Executable
+335
@@ -0,0 +1,335 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
# very first version of the upx-testsuite; requires:
|
||||||
|
# $upx_exe (required, but with convenience fallback "./upx")
|
||||||
|
# $upx_testsuite_SRCDIR (required, but with convenience fallback)
|
||||||
|
# $upx_testsuite_BUILDDIR (optional)
|
||||||
|
#
|
||||||
|
# optional settings:
|
||||||
|
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
|
||||||
|
# $UPX_TESTSUITE_VERBOSE
|
||||||
|
# $UPX_TESTSUITE_LEVEL
|
||||||
|
#
|
||||||
|
# see https://github.com/upx/upx-testsuite.git
|
||||||
|
#
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# init & checks
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# upx_exe
|
||||||
|
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
|
||||||
|
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
||||||
|
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||||
|
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||||
|
[[ -f $upx_exe ]] || exit 1
|
||||||
|
|
||||||
|
# set emu and run_upx
|
||||||
|
emu=()
|
||||||
|
if [[ -n $upx_exe_runner ]]; then
|
||||||
|
# usage examples:
|
||||||
|
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
|
||||||
|
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
|
||||||
|
# export upx_exe_runner="wine"
|
||||||
|
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
|
||||||
|
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
|
||||||
|
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
|
||||||
|
fi
|
||||||
|
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
|
||||||
|
# run_upx sanity check
|
||||||
|
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||||
|
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
|
|
||||||
|
# upx_testsuite_SRCDIR
|
||||||
|
if [[ -z $upx_testsuite_SRCDIR ]]; then
|
||||||
|
# convenience fallback: search standard locations below upx top-level directory
|
||||||
|
if [[ -d "$argv0dir/../../../upx--upx-testsuite.git/files/packed" ]]; then
|
||||||
|
upx_testsuite_SRCDIR="$argv0dir/../../../upx--upx-testsuite.git"
|
||||||
|
elif [[ -d "$argv0dir/../../../upx-testsuite.git/files/packed" ]]; then
|
||||||
|
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite.git"
|
||||||
|
elif [[ -d "$argv0dir/../../../upx-testsuite/files/packed" ]]; then
|
||||||
|
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
||||||
|
echo "invalid or missing \$upx_testsuite_SRCDIR:"
|
||||||
|
echo " please git clone https://github.com/upx/upx-testsuite.git"
|
||||||
|
echo " and set (export) the envvar upx_testsuite_SRCDIR to the local file path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
upx_testsuite_SRCDIR=$(readlink -fn "$upx_testsuite_SRCDIR") # make absolute
|
||||||
|
[[ -d $upx_testsuite_SRCDIR ]] || exit 1
|
||||||
|
|
||||||
|
# upx_testsuite_BUILDDIR
|
||||||
|
if [[ -z $upx_testsuite_BUILDDIR ]]; then
|
||||||
|
upx_testsuite_BUILDDIR="./tmp-upx-testsuite"
|
||||||
|
fi
|
||||||
|
mkdir -p "$upx_testsuite_BUILDDIR" || exit 1
|
||||||
|
upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
|
||||||
|
[[ -d $upx_testsuite_BUILDDIR ]] || exit 1
|
||||||
|
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
||||||
|
: > ./.mfxnobackup
|
||||||
|
|
||||||
|
# run_upx sanity check after "cd"
|
||||||
|
if ! "${run_upx[@]}" --version-short >/dev/null; then
|
||||||
|
echo "UPX-ERROR: FATAL: upx --version-short FAILED"
|
||||||
|
echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
|
||||||
|
echo "INFO: run_upx='${run_upx[*]}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# setup
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
#set -x # debug
|
||||||
|
|
||||||
|
exit_code=0
|
||||||
|
num_errors=0
|
||||||
|
all_errors=
|
||||||
|
|
||||||
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
|
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
|
||||||
|
|
||||||
|
case $UPX_TESTSUITE_LEVEL in
|
||||||
|
[0-8]) ;;
|
||||||
|
*) UPX_TESTSUITE_LEVEL=999 ;;
|
||||||
|
esac
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
|
||||||
|
echo "UPX testsuite SKIPPED."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf ./testsuite_1
|
||||||
|
mkdir testsuite_1 || exit 1
|
||||||
|
cd testsuite_1 || exit 1
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# support functions
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
run_upx() {
|
||||||
|
local ec=0
|
||||||
|
if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then
|
||||||
|
echo "LOG: '${run_upx[*]}' $*"
|
||||||
|
fi
|
||||||
|
"${run_upx[@]}" "$@" || ec=$?
|
||||||
|
if [[ $ec != 0 ]]; then
|
||||||
|
echo "FATAL: '${run_upx[*]}' $*"
|
||||||
|
echo " (exit code was $ec)"
|
||||||
|
exit 42
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
testsuite_header() {
|
||||||
|
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||||
|
echo -e "\n${x}\n${1}\n${x}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
testsuite_split_f() {
|
||||||
|
fd=$(dirname "$1")
|
||||||
|
fb=$(basename "$1")
|
||||||
|
fsubdir=$(basename "$fd")
|
||||||
|
# sanity checks
|
||||||
|
if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then
|
||||||
|
fd=''; fb=''; fsubdir=''
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
testsuite_check_sha() {
|
||||||
|
(cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
||||||
|
echo
|
||||||
|
cat $1/.sha256sums.current
|
||||||
|
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
||||||
|
echo "UPX-ERROR: $1 FAILED: checksum mismatch"
|
||||||
|
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||||
|
exit_code=99
|
||||||
|
let num_errors+=1 || true
|
||||||
|
all_errors="${all_errors} $1"
|
||||||
|
#exit 99
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
testsuite_check_sha_decompressed() {
|
||||||
|
(cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
|
||||||
|
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
|
||||||
|
cat $1/.sha256sums.current
|
||||||
|
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
|
||||||
|
diff -u $1/.sha256sums.expected $1/.sha256sums.current || true
|
||||||
|
exit 98
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
testsuite_use_canonicalized=1
|
||||||
|
testsuite_run_compress() {
|
||||||
|
testsuite_header $testdir
|
||||||
|
local files f
|
||||||
|
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
||||||
|
files='t020_canonicalized/*/*'
|
||||||
|
else
|
||||||
|
files='t010_decompressed/*/*'
|
||||||
|
fi
|
||||||
|
for f in $files; do
|
||||||
|
testsuite_split_f "$f"
|
||||||
|
[[ -z $fb ]] && continue
|
||||||
|
echo "# $f"
|
||||||
|
mkdir -p "$testdir/$fsubdir" "$testdir/.decompressed/$fsubdir"
|
||||||
|
run_upx -qq --prefer-ucl "$@" "$f" -o "$testdir/$fsubdir/$fb"
|
||||||
|
run_upx -qq -d "$testdir/$fsubdir/$fb" -o "$testdir/.decompressed/$fsubdir/$fb"
|
||||||
|
done
|
||||||
|
testsuite_check_sha $testdir
|
||||||
|
run_upx -qq -l "$testdir"/*/*
|
||||||
|
run_upx -qq --file-info "$testdir"/*/*
|
||||||
|
run_upx -q -t "$testdir"/*/*
|
||||||
|
if [[ $testsuite_use_canonicalized == 1 ]]; then
|
||||||
|
# check that after decompression the file matches the canonicalized version
|
||||||
|
cp t020_canonicalized/.sha256sums.expected $testdir/.decompressed/
|
||||||
|
testsuite_check_sha_decompressed $testdir/.decompressed
|
||||||
|
rm -rf "./$testdir/.decompressed"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# expected checksums
|
||||||
|
#
|
||||||
|
# To ease maintenance of this script in case of updates this section
|
||||||
|
# can be automatically re-created from the current checksums -
|
||||||
|
# see call of function recreate_expected_sha256sums below.
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
recreate_expected_sha256sums() {
|
||||||
|
local o="$1"
|
||||||
|
local files f d
|
||||||
|
echo "########## begin .sha256sums.recreate" > "$o"
|
||||||
|
files='*/.sha256sums.current'
|
||||||
|
for f in $files; do
|
||||||
|
d=$(dirname "$f")
|
||||||
|
echo "expected_sha256sums__${d}="'"\' >> "$o"
|
||||||
|
cat "$f" >> "$o"
|
||||||
|
echo '"' >> "$o"
|
||||||
|
done
|
||||||
|
echo "########## end .sha256sums.recreate" >> "$o"
|
||||||
|
}
|
||||||
|
|
||||||
|
source "$argv0dir/upx_testsuite_1-expected_sha256sums.sh" || exit 1
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# decompression tests
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
testdir=t010_decompressed
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
|
||||||
|
testsuite_header $testdir
|
||||||
|
for f in "$upx_testsuite_SRCDIR"/files/packed/*/upx-3.9[15]*; do
|
||||||
|
testsuite_split_f "$f"
|
||||||
|
[[ -z $fb ]] && continue
|
||||||
|
echo "# $f"
|
||||||
|
mkdir -p "$testdir/$fsubdir"
|
||||||
|
run_upx -qq -d "$f" -o "$testdir/$fsubdir/$fb"
|
||||||
|
done
|
||||||
|
testsuite_check_sha $testdir
|
||||||
|
|
||||||
|
# run one pack+unpack step to canonicalize the files
|
||||||
|
testdir=t020_canonicalized
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
|
||||||
|
testsuite_header $testdir
|
||||||
|
for f in t010_decompressed/*/*; do
|
||||||
|
testsuite_split_f "$f"
|
||||||
|
[[ -z $fb ]] && continue
|
||||||
|
echo "# $f"
|
||||||
|
mkdir -p "$testdir/$fsubdir/.packed"
|
||||||
|
run_upx -qq --prefer-ucl -1 "$f" -o "$testdir/$fsubdir/.packed/$fb"
|
||||||
|
run_upx -qq -d "$testdir/$fsubdir/.packed/$fb" -o "$testdir/$fsubdir/$fb"
|
||||||
|
done
|
||||||
|
testsuite_check_sha $testdir
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# compression tests
|
||||||
|
# info: we use fast compression levels because we want to
|
||||||
|
# test UPX and not the compression libraries
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 2 ]]; then
|
||||||
|
testdir=t110_compress_ucl_nrv2b_3_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --nrv2b -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 3 ]]; then
|
||||||
|
testdir=t120_compress_ucl_nrv2d_3_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --nrv2d -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 4 ]]; then
|
||||||
|
testdir=t130_compress_ucl_nrv2e_3_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --nrv2e -3 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 5 ]]; then
|
||||||
|
testdir=t140_compress_lzma_2_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --lzma -2 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 6 ]]; then
|
||||||
|
testdir=t150_compress_ucl_2_all_filters
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress -2 --all-filters
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 7 ]]; then
|
||||||
|
testdir=t160_compress_all_methods_1_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --all-methods -1 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $UPX_TESTSUITE_LEVEL -ge 8 ]]; then
|
||||||
|
testdir=t170_compress_all_methods_no_lzma_5_no_filter
|
||||||
|
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
|
||||||
|
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
|
||||||
|
fi
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# summary
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# recreate checksums from current version for an easy update in case of changes
|
||||||
|
recreate_expected_sha256sums .sha256sums.recreate
|
||||||
|
|
||||||
|
testsuite_header "UPX testsuite summary: level $UPX_TESTSUITE_LEVEL"
|
||||||
|
run_upx --version-short
|
||||||
|
echo
|
||||||
|
echo "upx_exe='$upx_exe'"
|
||||||
|
ls -l "$upx_exe"
|
||||||
|
if command -v file >/dev/null; then
|
||||||
|
file "$upx_exe" || true
|
||||||
|
fi
|
||||||
|
echo "run_upx='${run_upx[*]}'"
|
||||||
|
echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'"
|
||||||
|
echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'"
|
||||||
|
echo ".sha256sums.{expected,current} counts:"
|
||||||
|
cat ./*/.sha256sums.expected | LC_ALL=C sort | wc
|
||||||
|
cat ./*/.sha256sums.current | LC_ALL=C sort | wc
|
||||||
|
echo
|
||||||
|
if [[ $exit_code == 0 ]]; then
|
||||||
|
echo "UPX testsuite passed. All done."
|
||||||
|
else
|
||||||
|
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
|
||||||
|
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
|
||||||
|
fi
|
||||||
|
exit $exit_code
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#
|
||||||
|
# valgrind suppressions for musl libc
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
|
# musl malloc
|
||||||
|
{
|
||||||
|
musl-malloc-enframe
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:enframe
|
||||||
|
}
|
||||||
|
|
||||||
|
# these are only needed for older musl versions
|
||||||
|
|
||||||
|
{
|
||||||
|
musl-malloc-mal0_clear
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:mal0_clear
|
||||||
|
fun:calloc
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
musl-string-memchr
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:memchr
|
||||||
|
}
|
||||||
|
{
|
||||||
|
musl-string-stpcpy
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:stpcpy
|
||||||
|
}
|
||||||
|
{
|
||||||
|
musl-string-strchrnul
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:strchrnul
|
||||||
|
}
|
||||||
|
{
|
||||||
|
musl-string-strlen
|
||||||
|
Memcheck:Cond
|
||||||
|
fun:strlen
|
||||||
|
}
|
||||||
+70
-65
@@ -1,46 +1,44 @@
|
|||||||
#
|
#
|
||||||
# UPX Makefile - needs GNU make
|
# UPX src Makefile - needs GNU make and CMake >= 3.13
|
||||||
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
# IMPORTANT NOTE: this Makefile is deprecated - please
|
# NOTE: this Makefile is intended for developers - please use
|
||||||
# directly use the CMake build instead!
|
# the top-level Makefile instead
|
||||||
|
|
||||||
MAKEFLAGS += -r
|
|
||||||
.SUFFIXES:
|
|
||||||
export SHELL = /bin/sh
|
|
||||||
|
|
||||||
ifndef srcdir
|
ifndef srcdir
|
||||||
srcdir := $(dir $(lastword $(MAKEFILE_LIST)))
|
srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR')
|
|
||||||
endif
|
endif
|
||||||
ifndef top_srcdir
|
ifndef top_srcdir
|
||||||
top_srcdir := $(srcdir)/..
|
top_srcdir := $(srcdir)/..
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#***********************************************************************
|
||||||
# redirect to top-level CMake build
|
# redirect to top-level Makefile
|
||||||
#
|
#***********************************************************************
|
||||||
|
|
||||||
default: debug
|
# NOTE that the top-level Makefile .DEFAULT_GOAL is build/release
|
||||||
all: debug release
|
.DEFAULT_GOAL = build/all
|
||||||
debug: $(top_srcdir)/build/debug/upx
|
|
||||||
release: $(top_srcdir)/build/release/upx
|
|
||||||
|
|
||||||
$(top_srcdir)/build/debug/upx:
|
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||||
$(MAKE) -C $(top_srcdir) build/debug
|
.PHONY: PHONY
|
||||||
$(top_srcdir)/build/release/upx:
|
.SECONDEXPANSION:
|
||||||
$(MAKE) -C $(top_srcdir) build/release
|
.SUFFIXES:
|
||||||
|
|
||||||
.PHONY: default all debug release
|
build/debug build/release build/all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
.PHONY: $(top_srcdir)/build/debug/upx
|
build/debug+test build/release+test build/all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
.PHONY: $(top_srcdir)/build/release/upx
|
# shortcuts
|
||||||
|
debug release all: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
|
debug+test release+test all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
|
||||||
|
|
||||||
#
|
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
|
||||||
# "make run-testsuite"
|
|
||||||
#
|
|
||||||
|
|
||||||
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
|
#***********************************************************************
|
||||||
# you also can override upx_testsuite_SRCDIR
|
# make run-testsuite
|
||||||
|
# git clone https://github.com/upx/upx-testsuite.git
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# search for the UPX testsuite; you can override by setting "upx_testsuite_SRCDIR"
|
||||||
ifndef upx_testsuite_SRCDIR
|
ifndef upx_testsuite_SRCDIR
|
||||||
# search standard locations below $(top_srcdir)
|
# search standard locations below $(top_srcdir)
|
||||||
ifneq ($(wildcard $(top_srcdir)/../upx--upx-testsuite.git/files/packed/.),)
|
ifneq ($(wildcard $(top_srcdir)/../upx--upx-testsuite.git/files/packed/.),)
|
||||||
@@ -53,51 +51,58 @@ endif
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# run the UPX testsuite
|
# run the UPX testsuite
|
||||||
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
|
# The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
|
||||||
# The actual (new) checksums are in tmp-testsuite/testsuite_1/.sha256sums.recreate
|
# The actual (new) checksums are in ./tmp-upx-testsuite-*/testsuite_1/.sha256sums.recreate
|
||||||
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
|
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
|
||||||
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
|
ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
|
||||||
run-testsuite: export upx_exe := $(top_srcdir)/build/release/upx
|
run-testsuite: run-testsuite-release PHONY
|
||||||
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
run-testsuite-all: run-testsuite-debug run-testsuite-release PHONY
|
||||||
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||||
run-testsuite: $(top_srcdir)/build/release/upx
|
run-testsuite-debug: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-debug
|
||||||
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
|
||||||
.PHONY: run-testsuite
|
run-testsuite-debug: build/debug PHONY
|
||||||
|
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
|
||||||
|
run-testsuite-release: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-release
|
||||||
|
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
|
||||||
|
run-testsuite-release: build/release PHONY
|
||||||
|
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#***********************************************************************
|
||||||
# "make clang-format"
|
# make check-whitespace
|
||||||
#
|
#***********************************************************************
|
||||||
|
|
||||||
|
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
|
||||||
|
|
||||||
|
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
|
||||||
|
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
||||||
|
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
||||||
|
endif
|
||||||
|
check-whitespace: PHONY; $(CHECK_WHITESPACE)
|
||||||
|
|
||||||
|
endif # /usr/bin/env
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# make clang-format
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
|
ifneq ($(wildcard /usr/bin/env),)
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
|
||||||
CLANG_FORMAT_FILES += except.cpp except.h
|
|
||||||
CLANG_FORMAT_FILES += file.cpp file.h
|
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
|
||||||
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
|
||||||
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
|
||||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
|
||||||
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
|
||||||
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
|
||||||
clang-format:
|
|
||||||
$(top_srcdir)/misc/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(sort $(CLANG_FORMAT_FILES)))
|
|
||||||
.PHONY: clang-format
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
# Markus loves clang-format, but John hates it; find a compromise
|
||||||
# "make check-whitespace"
|
CLANG_FORMAT_EXCLUDE_FILES += stub/%.h util/miniacc.h
|
||||||
#
|
CLANG_FORMAT_EXCLUDE_FILES += p_lx_% p_mach% p_unix% p_vmlin%
|
||||||
|
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
|
||||||
|
CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
|
||||||
|
CLANG_FORMAT_FILES += $(sort $(wildcard ../misc/cmake/try_compile/*.[ch]*))
|
||||||
|
CLANG_FORMAT_FILES := $(sort $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)))
|
||||||
|
clang-format: $(CLANG_FORMAT_FILES) PHONY
|
||||||
|
@echo "running upx-clang-format"
|
||||||
|
@bash $(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
|
||||||
|
|
||||||
CHECK_WHITESPACE =
|
endif # Linux
|
||||||
ifeq ($(shell uname),Linux)
|
endif # /usr/bin/env
|
||||||
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 : ; $(CHECK_WHITESPACE)
|
|
||||||
endif
|
|
||||||
.PHONY: check-whitespace
|
|
||||||
|
|
||||||
# vim:set ts=8 sw=8 noet:
|
# vim:set ts=8 sw=8 noet:
|
||||||
|
|||||||
+379
-196
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -26,47 +26,124 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef UPX_BELE_H__
|
|
||||||
#define UPX_BELE_H__ 1
|
|
||||||
|
|
||||||
// BE - Big Endian
|
// BE - Big Endian
|
||||||
// LE - Little Endian
|
// LE - Little Endian
|
||||||
// NE - Native Endianness (aka host endianness)
|
// NE - Native Endianness (aka Host Endianness aka CPU Endianness)
|
||||||
// TE - Target Endianness (not used here, see various packers)
|
// TE - Target Endianness (not used here, see various packers)
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// some platforms may provide their own system bswapXX() functions, so rename to avoid conflicts
|
||||||
|
#undef bswap16
|
||||||
|
#undef bswap32
|
||||||
|
#undef bswap64
|
||||||
|
#define bswap16 upx_bswap16
|
||||||
|
#define bswap32 upx_bswap32
|
||||||
|
#define bswap64 upx_bswap64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// XE - eXtended Endian compatibility
|
||||||
|
// try to detect XX16 vs XX32 vs XX64 size mismatches
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if !(DEBUG)
|
||||||
|
|
||||||
|
// permissive version using "void *"
|
||||||
|
#define REQUIRE_XE16 /*empty*/
|
||||||
|
#define REQUIRE_XE24 /*empty*/
|
||||||
|
#define REQUIRE_XE32 /*empty*/
|
||||||
|
#define REQUIRE_XE64 /*empty*/
|
||||||
|
typedef void XE16;
|
||||||
|
typedef void XE24;
|
||||||
|
typedef void XE32;
|
||||||
|
typedef void XE64;
|
||||||
|
|
||||||
|
#else // permissive version
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
struct BE16;
|
||||||
|
struct BE32;
|
||||||
|
struct BE64;
|
||||||
|
struct LE16;
|
||||||
|
struct LE32;
|
||||||
|
struct LE64;
|
||||||
|
|
||||||
|
namespace bele_detail {
|
||||||
|
|
||||||
|
// Note:
|
||||||
|
// void is explicitly allowed (but there is no automatic pointer conversion because of template!)
|
||||||
|
// char is explicitly allowed
|
||||||
|
// byte is explicitly allowed
|
||||||
|
template <class T>
|
||||||
|
inline constexpr bool is_xe16_type =
|
||||||
|
upx::is_same_any_v<T, void, char, byte, upx_int16_t, upx_uint16_t, BE16, LE16>;
|
||||||
|
template <class T>
|
||||||
|
inline constexpr bool is_xe24_type = upx::is_same_any_v<T, void, char, byte>;
|
||||||
|
template <class T>
|
||||||
|
inline constexpr bool is_xe32_type =
|
||||||
|
upx::is_same_any_v<T, void, char, byte, upx_int32_t, upx_uint32_t, BE32, LE32>;
|
||||||
|
template <class T>
|
||||||
|
inline constexpr bool is_xe64_type =
|
||||||
|
upx::is_same_any_v<T, void, char, byte, upx_int64_t, upx_uint64_t, BE64, LE64>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using enable_if_xe16 = std::enable_if_t<is_xe16_type<T>, T>;
|
||||||
|
template <class T>
|
||||||
|
using enable_if_xe24 = std::enable_if_t<is_xe24_type<T>, T>;
|
||||||
|
template <class T>
|
||||||
|
using enable_if_xe32 = std::enable_if_t<is_xe32_type<T>, T>;
|
||||||
|
template <class T>
|
||||||
|
using enable_if_xe64 = std::enable_if_t<is_xe64_type<T>, T>;
|
||||||
|
|
||||||
|
} // namespace bele_detail
|
||||||
|
|
||||||
|
#define REQUIRE_XE16 template <class XE16, class = bele_detail::enable_if_xe16<XE16> >
|
||||||
|
#define REQUIRE_XE24 template <class XE24, class = bele_detail::enable_if_xe24<XE24> >
|
||||||
|
#define REQUIRE_XE32 template <class XE32, class = bele_detail::enable_if_xe32<XE32> >
|
||||||
|
#define REQUIRE_XE64 template <class XE64, class = bele_detail::enable_if_xe64<XE64> >
|
||||||
|
|
||||||
|
#endif // permissive version
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// core - NE
|
// core - NE
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
__acc_static_forceinline unsigned get_ne16(const void *p) {
|
REQUIRE_XE16
|
||||||
|
static forceinline unsigned get_ne16(const XE16 *p) noexcept {
|
||||||
upx_uint16_t v = 0;
|
upx_uint16_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline unsigned get_ne32(const void *p) {
|
REQUIRE_XE32
|
||||||
|
static forceinline unsigned get_ne32(const XE32 *p) noexcept {
|
||||||
upx_uint32_t v = 0;
|
upx_uint32_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline upx_uint64_t get_ne64(const void *p) {
|
REQUIRE_XE64
|
||||||
|
static forceinline upx_uint64_t get_ne64(const XE64 *p) noexcept {
|
||||||
upx_uint64_t v = 0;
|
upx_uint64_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne16(void *p, unsigned vv) {
|
REQUIRE_XE16
|
||||||
upx_uint16_t v = (upx_uint16_t)(vv & 0xffff);
|
static forceinline void set_ne16(XE16 *p, unsigned vv) noexcept {
|
||||||
|
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne32(void *p, unsigned vv) {
|
REQUIRE_XE32
|
||||||
|
static forceinline void set_ne32(XE32 *p, unsigned vv) noexcept {
|
||||||
upx_uint32_t v = vv;
|
upx_uint32_t v = vv;
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) {
|
REQUIRE_XE64
|
||||||
|
static forceinline void set_ne64(XE64 *p, upx_uint64_t vv) noexcept {
|
||||||
upx_uint64_t v = vv;
|
upx_uint64_t v = vv;
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
@@ -79,36 +156,46 @@ __acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) {
|
|||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
|
||||||
|
|
||||||
__acc_static_forceinline unsigned bswap16(unsigned v) {
|
// unfortunately *not* constexpr with current MSVC
|
||||||
|
static forceinline /*constexpr*/ unsigned bswap16(unsigned v) noexcept {
|
||||||
return (unsigned) _byteswap_ulong(v << 16);
|
return (unsigned) _byteswap_ulong(v << 16);
|
||||||
}
|
}
|
||||||
__acc_static_forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); }
|
static forceinline /*constexpr*/ unsigned bswap32(unsigned v) noexcept {
|
||||||
__acc_static_forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
|
return (unsigned) _byteswap_ulong(v);
|
||||||
|
}
|
||||||
|
static forceinline /*constexpr*/ upx_uint64_t bswap64(upx_uint64_t v) noexcept {
|
||||||
|
return _byteswap_uint64(v);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
__acc_static_forceinline constexpr unsigned bswap16(unsigned v) {
|
static forceinline constexpr unsigned bswap16(unsigned v) noexcept {
|
||||||
|
#if defined(__riscv) && __riscv_xlen == 64
|
||||||
|
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
||||||
|
#else
|
||||||
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
|
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
|
||||||
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
|
||||||
return __builtin_bswap32(v << 16);
|
return __builtin_bswap32(v << 16);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
__acc_static_forceinline constexpr unsigned bswap32(unsigned v) {
|
static forceinline constexpr unsigned bswap32(unsigned v) noexcept {
|
||||||
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
|
#if defined(__riscv) && __riscv_xlen == 64
|
||||||
|
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
|
||||||
|
#else
|
||||||
return __builtin_bswap32(v);
|
return __builtin_bswap32(v);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
__acc_static_forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) {
|
static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept {
|
||||||
return __builtin_bswap64(v);
|
return __builtin_bswap64(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__acc_static_forceinline constexpr unsigned no_bswap16(unsigned v) {
|
static forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
|
||||||
return v & 0xffff; // needed so that this is equivalent to bswap16() above
|
// mask is needed so that for all v: bswap16(bswap16(v)) == no_bswap16(v)
|
||||||
|
return v & 0xffff;
|
||||||
}
|
}
|
||||||
|
static forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
|
||||||
__acc_static_forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
|
static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept { return v; }
|
||||||
|
|
||||||
__acc_static_forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
|
|
||||||
|
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
#define ne16_to_be16(v) no_bswap16(v)
|
#define ne16_to_be16(v) no_bswap16(v)
|
||||||
@@ -130,111 +217,154 @@ __acc_static_forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { ret
|
|||||||
// get/set 16/32/64
|
// get/set 16/32/64
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
inline unsigned get_be16(const void *p) { return ne16_to_be16(get_ne16(p)); }
|
REQUIRE_XE16
|
||||||
inline unsigned get_be32(const void *p) { return ne32_to_be32(get_ne32(p)); }
|
inline unsigned get_be16(const XE16 *p) noexcept { return ne16_to_be16(get_ne16(p)); }
|
||||||
inline upx_uint64_t get_be64(const void *p) { return ne64_to_be64(get_ne64(p)); }
|
REQUIRE_XE32
|
||||||
inline unsigned get_le16(const void *p) { return ne16_to_le16(get_ne16(p)); }
|
inline unsigned get_be32(const XE32 *p) noexcept { return ne32_to_be32(get_ne32(p)); }
|
||||||
inline unsigned get_le32(const void *p) { return ne32_to_le32(get_ne32(p)); }
|
REQUIRE_XE64
|
||||||
inline upx_uint64_t get_le64(const void *p) { return ne64_to_le64(get_ne64(p)); }
|
inline upx_uint64_t get_be64(const XE64 *p) noexcept { return ne64_to_be64(get_ne64(p)); }
|
||||||
inline void set_be16(void *p, unsigned v) { set_ne16(p, ne16_to_be16(v)); }
|
REQUIRE_XE16
|
||||||
inline void set_be32(void *p, unsigned v) { set_ne32(p, ne32_to_be32(v)); }
|
inline unsigned get_le16(const XE16 *p) noexcept { return ne16_to_le16(get_ne16(p)); }
|
||||||
inline void set_be64(void *p, upx_uint64_t v) { set_ne64(p, ne64_to_be64(v)); }
|
REQUIRE_XE32
|
||||||
inline void set_le16(void *p, unsigned v) { set_ne16(p, ne16_to_le16(v)); }
|
inline unsigned get_le32(const XE32 *p) noexcept { return ne32_to_le32(get_ne32(p)); }
|
||||||
inline void set_le32(void *p, unsigned v) { set_ne32(p, ne32_to_le32(v)); }
|
REQUIRE_XE64
|
||||||
inline void set_le64(void *p, upx_uint64_t v) { set_ne64(p, ne64_to_le64(v)); }
|
inline upx_uint64_t get_le64(const XE64 *p) noexcept { return ne64_to_le64(get_ne64(p)); }
|
||||||
|
|
||||||
|
REQUIRE_XE16
|
||||||
|
inline void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
|
||||||
|
REQUIRE_XE64
|
||||||
|
inline void set_be64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_be64(v)); }
|
||||||
|
REQUIRE_XE16
|
||||||
|
inline void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
|
||||||
|
REQUIRE_XE64
|
||||||
|
inline void set_le64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_le64(v)); }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// get/set 24/26
|
// get/set 24/26
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
inline unsigned get_be24(const void *p) {
|
REQUIRE_XE24
|
||||||
const unsigned char *b = ACC_CCAST(const unsigned char *, p);
|
inline unsigned get_be24(const XE24 *p) noexcept {
|
||||||
|
const byte *b = ACC_CCAST(const byte *, p);
|
||||||
return (b[0] << 16) | (b[1] << 8) | (b[2] << 0);
|
return (b[0] << 16) | (b[1] << 8) | (b[2] << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_le24(const void *p) {
|
REQUIRE_XE24
|
||||||
const unsigned char *b = ACC_CCAST(const unsigned char *, p);
|
inline unsigned get_le24(const XE24 *p) noexcept {
|
||||||
|
const byte *b = ACC_CCAST(const byte *, p);
|
||||||
return (b[0] << 0) | (b[1] << 8) | (b[2] << 16);
|
return (b[0] << 0) | (b[1] << 8) | (b[2] << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_be24(void *p, unsigned v) {
|
REQUIRE_XE24
|
||||||
unsigned char *b = ACC_PCAST(unsigned char *, p);
|
inline void set_be24(XE24 *p, unsigned v) noexcept {
|
||||||
b[0] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
|
byte *b = ACC_PCAST(byte *, p);
|
||||||
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff);
|
b[0] = ACC_ICONV(byte, (v >> 16) & 0xff);
|
||||||
b[2] = ACC_ICONV(unsigned char, (v >> 0) & 0xff);
|
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
|
||||||
|
b[2] = ACC_ICONV(byte, (v >> 0) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_le24(void *p, unsigned v) {
|
REQUIRE_XE24
|
||||||
unsigned char *b = ACC_PCAST(unsigned char *, p);
|
inline void set_le24(XE24 *p, unsigned v) noexcept {
|
||||||
b[0] = ACC_ICONV(unsigned char, (v >> 0) & 0xff);
|
byte *b = ACC_PCAST(byte *, p);
|
||||||
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff);
|
b[0] = ACC_ICONV(byte, (v >> 0) & 0xff);
|
||||||
b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
|
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
|
||||||
|
b[2] = ACC_ICONV(byte, (v >> 16) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_le26(const void *p) { return get_le32(p) & 0x03ffffff; }
|
REQUIRE_XE32
|
||||||
|
inline unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline unsigned get_le19_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; }
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline unsigned get_le14_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; }
|
||||||
|
|
||||||
inline void set_le26(void *p, unsigned v) {
|
REQUIRE_XE32
|
||||||
|
inline void set_le26(XE32 *p, unsigned v) noexcept {
|
||||||
// preserve the top 6 bits
|
// preserve the top 6 bits
|
||||||
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
|
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
|
||||||
// optimized version, saving a runtime bswap32
|
// optimized version, saving a runtime bswap32
|
||||||
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
|
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
|
||||||
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
||||||
}
|
}
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline void set_le19_5(XE32 *p, unsigned v) noexcept {
|
||||||
|
set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5));
|
||||||
|
}
|
||||||
|
REQUIRE_XE32
|
||||||
|
inline void set_le14_5(XE32 *p, unsigned v) noexcept {
|
||||||
|
set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5));
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// get signed values
|
// get signed values
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
__acc_static_forceinline int sign_extend(unsigned v, unsigned bits) {
|
static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept {
|
||||||
|
#if (ACC_ARCH_M68K) // no barrel shifter
|
||||||
const unsigned sign_bit = 1u << (bits - 1);
|
const unsigned sign_bit = 1u << (bits - 1);
|
||||||
v &= sign_bit | (sign_bit - 1);
|
return ACC_ICAST(int, (v & (sign_bit - 1)) - (v & sign_bit));
|
||||||
v |= 0 - (v & sign_bit);
|
#else
|
||||||
return ACC_ICAST(int, v);
|
return ACC_ICAST(int, v << (32 - bits)) >> (32 - bits);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) {
|
static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept {
|
||||||
|
#if (ACC_ARCH_M68K) // no barrel shifter
|
||||||
const upx_uint64_t sign_bit = 1ull << (bits - 1);
|
const upx_uint64_t sign_bit = 1ull << (bits - 1);
|
||||||
v &= sign_bit | (sign_bit - 1);
|
return ACC_ICAST(upx_int64_t, (v & (sign_bit - 1)) - (v & sign_bit));
|
||||||
v |= 0 - (v & sign_bit);
|
#else
|
||||||
return ACC_ICAST(upx_int64_t, v);
|
return ACC_ICAST(upx_int64_t, v << (64 - bits)) >> (64 - bits);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be16_signed(const void *p) {
|
REQUIRE_XE16
|
||||||
|
inline int get_be16_signed(const XE16 *p) noexcept {
|
||||||
unsigned v = get_be16(p);
|
unsigned v = get_be16(p);
|
||||||
return sign_extend(v, 16);
|
return sign_extend(v, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be24_signed(const void *p) {
|
REQUIRE_XE24
|
||||||
|
inline int get_be24_signed(const XE24 *p) noexcept {
|
||||||
unsigned v = get_be24(p);
|
unsigned v = get_be24(p);
|
||||||
return sign_extend(v, 24);
|
return sign_extend(v, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be32_signed(const void *p) {
|
REQUIRE_XE32
|
||||||
|
inline int get_be32_signed(const XE32 *p) noexcept {
|
||||||
unsigned v = get_be32(p);
|
unsigned v = get_be32(p);
|
||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline upx_int64_t get_be64_signed(const void *p) {
|
REQUIRE_XE64
|
||||||
|
inline upx_int64_t get_be64_signed(const XE64 *p) noexcept {
|
||||||
upx_uint64_t v = get_be64(p);
|
upx_uint64_t v = get_be64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le16_signed(const void *p) {
|
REQUIRE_XE16
|
||||||
|
inline int get_le16_signed(const XE16 *p) noexcept {
|
||||||
unsigned v = get_le16(p);
|
unsigned v = get_le16(p);
|
||||||
return sign_extend(v, 16);
|
return sign_extend(v, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le24_signed(const void *p) {
|
REQUIRE_XE24
|
||||||
|
inline int get_le24_signed(const XE24 *p) noexcept {
|
||||||
unsigned v = get_le24(p);
|
unsigned v = get_le24(p);
|
||||||
return sign_extend(v, 24);
|
return sign_extend(v, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le32_signed(const void *p) {
|
REQUIRE_XE32
|
||||||
|
inline int get_le32_signed(const XE32 *p) noexcept {
|
||||||
unsigned v = get_le32(p);
|
unsigned v = get_le32(p);
|
||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline upx_int64_t get_le64_signed(const void *p) {
|
REQUIRE_XE64
|
||||||
|
inline upx_int64_t get_le64_signed(const XE64 *p) noexcept {
|
||||||
upx_uint64_t v = get_le64(p);
|
upx_uint64_t v = get_le64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
}
|
}
|
||||||
@@ -250,367 +380,380 @@ inline upx_int64_t get_le64_signed(const void *p) {
|
|||||||
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
|
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct alignas(1) BE16 {
|
struct alignas(1) BE16 final {
|
||||||
unsigned char d[2];
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
|
byte d[2];
|
||||||
|
|
||||||
BE16 &operator=(unsigned v) {
|
forceinline operator unsigned() const noexcept { return get_be16(d); }
|
||||||
|
|
||||||
|
forceinline BE16 &operator=(unsigned v) noexcept {
|
||||||
set_be16(d, v);
|
set_be16(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator+=(unsigned v) {
|
BE16 &operator+=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) + v);
|
set_be16(d, get_be16(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator-=(unsigned v) {
|
BE16 &operator-=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) - v);
|
set_be16(d, get_be16(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator*=(unsigned v) {
|
BE16 &operator*=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) * v);
|
set_be16(d, get_be16(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator/=(unsigned v) {
|
BE16 &operator/=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) / v);
|
set_be16(d, get_be16(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator&=(unsigned v) {
|
BE16 &operator&=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) & v);
|
set_be16(d, get_be16(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator|=(unsigned v) {
|
BE16 &operator|=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) | v);
|
set_be16(d, get_be16(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator^=(unsigned v) {
|
BE16 &operator^=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) ^ v);
|
set_be16(d, get_be16(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator<<=(unsigned v) {
|
BE16 &operator<<=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) << v);
|
set_be16(d, get_be16(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE16 &operator>>=(unsigned v) {
|
BE16 &operator>>=(unsigned v) noexcept {
|
||||||
set_be16(d, get_be16(d) >> v);
|
set_be16(d, get_be16(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator unsigned() const { return get_be16(d); }
|
bool operator==(const BE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const BE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||||
bool operator<(const BE16 &v) const { return unsigned(*this) < unsigned(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) BE32 {
|
struct alignas(1) BE32 final {
|
||||||
unsigned char d[4];
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
|
byte d[4];
|
||||||
|
|
||||||
BE32 &operator=(unsigned v) {
|
forceinline operator unsigned() const noexcept { return get_be32(d); }
|
||||||
|
|
||||||
|
forceinline BE32 &operator=(unsigned v) noexcept {
|
||||||
set_be32(d, v);
|
set_be32(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator+=(unsigned v) {
|
BE32 &operator+=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) + v);
|
set_be32(d, get_be32(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator-=(unsigned v) {
|
BE32 &operator-=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) - v);
|
set_be32(d, get_be32(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator*=(unsigned v) {
|
BE32 &operator*=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) * v);
|
set_be32(d, get_be32(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator/=(unsigned v) {
|
BE32 &operator/=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) / v);
|
set_be32(d, get_be32(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator&=(unsigned v) {
|
BE32 &operator&=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) & v);
|
set_be32(d, get_be32(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator|=(unsigned v) {
|
BE32 &operator|=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) | v);
|
set_be32(d, get_be32(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator^=(unsigned v) {
|
BE32 &operator^=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) ^ v);
|
set_be32(d, get_be32(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator<<=(unsigned v) {
|
BE32 &operator<<=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) << v);
|
set_be32(d, get_be32(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE32 &operator>>=(unsigned v) {
|
BE32 &operator>>=(unsigned v) noexcept {
|
||||||
set_be32(d, get_be32(d) >> v);
|
set_be32(d, get_be32(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator unsigned() const { return get_be32(d); }
|
bool operator==(const BE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const BE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||||
bool operator<(const BE32 &v) const { return unsigned(*this) < unsigned(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) BE64 {
|
struct alignas(1) BE64 final {
|
||||||
unsigned char d[8];
|
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||||
|
byte d[8];
|
||||||
|
|
||||||
BE64 &operator=(upx_uint64_t v) {
|
forceinline operator upx_uint64_t() const noexcept { return get_be64(d); }
|
||||||
|
|
||||||
|
forceinline BE64 &operator=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, v);
|
set_be64(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator+=(upx_uint64_t v) {
|
BE64 &operator+=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) + v);
|
set_be64(d, get_be64(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator-=(upx_uint64_t v) {
|
BE64 &operator-=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) - v);
|
set_be64(d, get_be64(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator*=(upx_uint64_t v) {
|
BE64 &operator*=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) * v);
|
set_be64(d, get_be64(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator/=(upx_uint64_t v) {
|
BE64 &operator/=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) / v);
|
set_be64(d, get_be64(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator&=(upx_uint64_t v) {
|
BE64 &operator&=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) & v);
|
set_be64(d, get_be64(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator|=(upx_uint64_t v) {
|
BE64 &operator|=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) | v);
|
set_be64(d, get_be64(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator^=(upx_uint64_t v) {
|
BE64 &operator^=(upx_uint64_t v) noexcept {
|
||||||
set_be64(d, get_be64(d) ^ v);
|
set_be64(d, get_be64(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator<<=(unsigned v) {
|
BE64 &operator<<=(unsigned v) noexcept {
|
||||||
set_be64(d, get_be64(d) << v);
|
set_be64(d, get_be64(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
BE64 &operator>>=(unsigned v) {
|
BE64 &operator>>=(unsigned v) noexcept {
|
||||||
set_be64(d, get_be64(d) >> v);
|
set_be64(d, get_be64(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator upx_uint64_t() const { return get_be64(d); }
|
bool operator==(const BE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const BE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
|
||||||
bool operator<(const BE64 &v) const { return upx_uint64_t(*this) < upx_uint64_t(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE16 {
|
struct alignas(1) LE16 final {
|
||||||
unsigned char d[2];
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
|
byte d[2];
|
||||||
|
|
||||||
LE16 &operator=(unsigned v) {
|
forceinline operator unsigned() const noexcept { return get_le16(d); }
|
||||||
|
|
||||||
|
forceinline LE16 &operator=(unsigned v) noexcept {
|
||||||
set_le16(d, v);
|
set_le16(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator+=(unsigned v) {
|
LE16 &operator+=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) + v);
|
set_le16(d, get_le16(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator-=(unsigned v) {
|
LE16 &operator-=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) - v);
|
set_le16(d, get_le16(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator*=(unsigned v) {
|
LE16 &operator*=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) * v);
|
set_le16(d, get_le16(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator/=(unsigned v) {
|
LE16 &operator/=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) / v);
|
set_le16(d, get_le16(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator&=(unsigned v) {
|
LE16 &operator&=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) & v);
|
set_le16(d, get_le16(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator|=(unsigned v) {
|
LE16 &operator|=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) | v);
|
set_le16(d, get_le16(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator^=(unsigned v) {
|
LE16 &operator^=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) ^ v);
|
set_le16(d, get_le16(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator<<=(unsigned v) {
|
LE16 &operator<<=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) << v);
|
set_le16(d, get_le16(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE16 &operator>>=(unsigned v) {
|
LE16 &operator>>=(unsigned v) noexcept {
|
||||||
set_le16(d, get_le16(d) >> v);
|
set_le16(d, get_le16(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator unsigned() const { return get_le16(d); }
|
bool operator==(const LE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const LE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||||
bool operator<(const LE16 &v) const { return unsigned(*this) < unsigned(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE32 {
|
struct alignas(1) LE32 final {
|
||||||
unsigned char d[4];
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
|
byte d[4];
|
||||||
|
|
||||||
LE32 &operator=(unsigned v) {
|
forceinline operator unsigned() const noexcept { return get_le32(d); }
|
||||||
|
|
||||||
|
forceinline LE32 &operator=(unsigned v) noexcept {
|
||||||
set_le32(d, v);
|
set_le32(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator+=(unsigned v) {
|
LE32 &operator+=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) + v);
|
set_le32(d, get_le32(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator-=(unsigned v) {
|
LE32 &operator-=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) - v);
|
set_le32(d, get_le32(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator*=(unsigned v) {
|
LE32 &operator*=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) * v);
|
set_le32(d, get_le32(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator/=(unsigned v) {
|
LE32 &operator/=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) / v);
|
set_le32(d, get_le32(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator&=(unsigned v) {
|
LE32 &operator&=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) & v);
|
set_le32(d, get_le32(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator|=(unsigned v) {
|
LE32 &operator|=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) | v);
|
set_le32(d, get_le32(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator^=(unsigned v) {
|
LE32 &operator^=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) ^ v);
|
set_le32(d, get_le32(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator<<=(unsigned v) {
|
LE32 &operator<<=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) << v);
|
set_le32(d, get_le32(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE32 &operator>>=(unsigned v) {
|
LE32 &operator>>=(unsigned v) noexcept {
|
||||||
set_le32(d, get_le32(d) >> v);
|
set_le32(d, get_le32(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator unsigned() const { return get_le32(d); }
|
bool operator==(const LE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const LE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
|
||||||
bool operator<(const LE32 &v) const { return unsigned(*this) < unsigned(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE64 {
|
struct alignas(1) LE64 final {
|
||||||
unsigned char d[8];
|
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||||
|
byte d[8];
|
||||||
|
|
||||||
LE64 &operator=(upx_uint64_t v) {
|
forceinline operator upx_uint64_t() const noexcept { return get_le64(d); }
|
||||||
|
|
||||||
|
forceinline LE64 &operator=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, v);
|
set_le64(d, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator+=(upx_uint64_t v) {
|
LE64 &operator+=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) + v);
|
set_le64(d, get_le64(d) + v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator-=(upx_uint64_t v) {
|
LE64 &operator-=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) - v);
|
set_le64(d, get_le64(d) - v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator*=(upx_uint64_t v) {
|
LE64 &operator*=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) * v);
|
set_le64(d, get_le64(d) * v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator/=(upx_uint64_t v) {
|
LE64 &operator/=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) / v);
|
set_le64(d, get_le64(d) / v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator&=(upx_uint64_t v) {
|
LE64 &operator&=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) & v);
|
set_le64(d, get_le64(d) & v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator|=(upx_uint64_t v) {
|
LE64 &operator|=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) | v);
|
set_le64(d, get_le64(d) | v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator^=(upx_uint64_t v) {
|
LE64 &operator^=(upx_uint64_t v) noexcept {
|
||||||
set_le64(d, get_le64(d) ^ v);
|
set_le64(d, get_le64(d) ^ v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator<<=(unsigned v) {
|
LE64 &operator<<=(unsigned v) noexcept {
|
||||||
set_le64(d, get_le64(d) << v);
|
set_le64(d, get_le64(d) << v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
LE64 &operator>>=(unsigned v) {
|
LE64 &operator>>=(unsigned v) noexcept {
|
||||||
set_le64(d, get_le64(d) >> v);
|
set_le64(d, get_le64(d) >> v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator upx_uint64_t() const { return get_le64(d); }
|
bool operator==(const LE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
|
||||||
|
bool operator<(const LE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
|
||||||
bool operator<(const LE64 &v) const { return upx_uint64_t(*this) < upx_uint64_t(v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// native types
|
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
|
||||||
typedef BE16 NE16;
|
|
||||||
typedef BE32 NE32;
|
|
||||||
typedef BE64 NE64;
|
|
||||||
#else
|
|
||||||
typedef LE16 NE16;
|
|
||||||
typedef LE32 NE32;
|
|
||||||
typedef LE64 NE64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// global operators (pointer addition/subtraction)
|
// global operators (pointer addition/subtraction)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const BE16 &v) {
|
inline T *operator+(T *ptr, const BE16 &v) noexcept {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator-(T *ptr, const BE16 &v) {
|
inline T *operator-(T *ptr, const BE16 &v) noexcept {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const BE32 &v) {
|
inline T *operator+(T *ptr, const BE32 &v) noexcept {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator-(T *ptr, const BE32 &v) {
|
inline T *operator-(T *ptr, const BE32 &v) noexcept {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are not implemented on purpose and will cause link-time errors
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T *operator+(T *ptr, const BE64 &v);
|
inline T *operator+(T *ptr, const LE16 &v) noexcept {
|
||||||
template <class T>
|
|
||||||
T *operator-(T *ptr, const BE64 &v);
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T *operator+(T *ptr, const LE16 &v) {
|
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator-(T *ptr, const LE16 &v) {
|
inline T *operator-(T *ptr, const LE16 &v) noexcept {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const LE32 &v) {
|
inline T *operator+(T *ptr, const LE32 &v) noexcept {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator-(T *ptr, const LE32 &v) {
|
inline T *operator-(T *ptr, const LE32 &v) noexcept {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are not implemented on purpose and will cause link-time errors
|
// these are not implemented on purpose and will cause errors
|
||||||
template <class T>
|
template <class T>
|
||||||
T *operator+(T *ptr, const LE64 &v);
|
T *operator+(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
|
||||||
template <class T>
|
template <class T>
|
||||||
T *operator-(T *ptr, const LE64 &v);
|
T *operator-(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
|
||||||
|
|
||||||
|
#if !ALLOW_INT_PLUS_MEMBUFFER
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const BE16 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const BE32 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const LE16 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const LE32 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
#endif // ALLOW_INT_PLUS_MEMBUFFER
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const BE64 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// global overloads
|
// global overloads
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
// TODO later: move these to upx namespace in util/cxxlib.h; see conf.h
|
||||||
inline unsigned ALIGN_DOWN(unsigned a, const BE32 &b) { return ALIGN_DOWN(a, unsigned(b)); }
|
inline unsigned ALIGN_DOWN(unsigned a, const BE32 &b) { return ALIGN_DOWN(a, unsigned(b)); }
|
||||||
inline unsigned ALIGN_DOWN(const BE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); }
|
inline unsigned ALIGN_DOWN(const BE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); }
|
||||||
inline unsigned ALIGN_UP(unsigned a, const BE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
inline unsigned ALIGN_UP(unsigned a, const BE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
||||||
@@ -621,6 +764,7 @@ inline unsigned ALIGN_DOWN(const LE32 &a, unsigned b) { return ALIGN_DOWN(unsign
|
|||||||
inline unsigned ALIGN_UP(unsigned a, const LE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
inline unsigned ALIGN_UP(unsigned a, const LE32 &b) { return ALIGN_UP(a, unsigned(b)); }
|
||||||
inline unsigned ALIGN_UP(const LE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); }
|
inline unsigned ALIGN_UP(const LE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); }
|
||||||
|
|
||||||
|
// TODO later: introduce upx::umax() and upx::umin()
|
||||||
inline unsigned UPX_MAX(unsigned a, const BE16 &b) { return UPX_MAX(a, unsigned(b)); }
|
inline unsigned UPX_MAX(unsigned a, const BE16 &b) { return UPX_MAX(a, unsigned(b)); }
|
||||||
inline unsigned UPX_MAX(const BE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
inline unsigned UPX_MAX(const BE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
|
||||||
inline unsigned UPX_MIN(unsigned a, const BE16 &b) { return UPX_MIN(a, unsigned(b)); }
|
inline unsigned UPX_MIN(unsigned a, const BE16 &b) { return UPX_MIN(a, unsigned(b)); }
|
||||||
@@ -665,6 +809,47 @@ int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
|||||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
// <type_traits> upx_is_integral; see conf.h
|
||||||
|
#define TT_UPX_IS_INTEGRAL(T) \
|
||||||
|
template <> \
|
||||||
|
struct upx_is_integral<T> : public std::true_type {}; \
|
||||||
|
template <> \
|
||||||
|
struct upx_is_integral<const T> : public std::true_type {}; \
|
||||||
|
template <> \
|
||||||
|
struct upx_is_integral<volatile T> : public std::true_type {}; \
|
||||||
|
template <> \
|
||||||
|
struct upx_is_integral<const volatile T> : public std::true_type {}
|
||||||
|
TT_UPX_IS_INTEGRAL(BE16);
|
||||||
|
TT_UPX_IS_INTEGRAL(BE32);
|
||||||
|
TT_UPX_IS_INTEGRAL(BE64);
|
||||||
|
TT_UPX_IS_INTEGRAL(LE16);
|
||||||
|
TT_UPX_IS_INTEGRAL(LE32);
|
||||||
|
TT_UPX_IS_INTEGRAL(LE64);
|
||||||
|
#undef TT_UPX_IS_INTEGRAL
|
||||||
|
|
||||||
|
// native types
|
||||||
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
|
typedef BE16 NE16;
|
||||||
|
typedef BE32 NE32;
|
||||||
|
typedef BE64 NE64;
|
||||||
|
#define ne16_compare be16_compare
|
||||||
|
#define ne32_compare be32_compare
|
||||||
|
#define ne64_compare be64_compare
|
||||||
|
#define ne16_compare_signed be16_compare_signed
|
||||||
|
#define ne32_compare_signed be32_compare_signed
|
||||||
|
#define ne64_compare_signed be64_compare_signed
|
||||||
|
#else
|
||||||
|
typedef LE16 NE16;
|
||||||
|
typedef LE32 NE32;
|
||||||
|
typedef LE64 NE64;
|
||||||
|
#define ne16_compare le16_compare
|
||||||
|
#define ne32_compare le32_compare
|
||||||
|
#define ne64_compare le64_compare
|
||||||
|
#define ne16_compare_signed le16_compare_signed
|
||||||
|
#define ne32_compare_signed le32_compare_signed
|
||||||
|
#define ne64_compare_signed le64_compare_signed
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Provide namespaces and classes to abstract endianness policies.
|
// Provide namespaces and classes to abstract endianness policies.
|
||||||
//
|
//
|
||||||
@@ -701,14 +886,12 @@ namespace N_BELE_RTP {
|
|||||||
|
|
||||||
// util
|
// util
|
||||||
namespace N_BELE_CTP {
|
namespace N_BELE_CTP {
|
||||||
inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) {
|
inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) noexcept {
|
||||||
return &N_BELE_RTP::be_policy;
|
return &N_BELE_RTP::be_policy;
|
||||||
}
|
}
|
||||||
inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) {
|
inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) noexcept {
|
||||||
return &N_BELE_RTP::le_policy;
|
return &N_BELE_RTP::le_policy;
|
||||||
}
|
}
|
||||||
} // namespace N_BELE_CTP
|
} // namespace N_BELE_CTP
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+37
-58
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,9 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UPX_BELE_H__
|
// this is an internal include file private to bele.h
|
||||||
#error "this is an internal include file"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -35,22 +33,24 @@
|
|||||||
|
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
// CTP - Compile-Time Polymorphism (templates)
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
#define V static inline
|
#define V static inline
|
||||||
#define S static int __acc_cdecl_qsort
|
#define VV static forceinline_constexpr
|
||||||
#define C /*empty*/
|
#define S static int __acc_cdecl_qsort
|
||||||
|
#define C noexcept
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
// RTP - Run-Time Polymorphism (virtual functions)
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
#define V virtual
|
#define V virtual
|
||||||
#define S virtual int
|
#define VV virtual
|
||||||
#define C const
|
#define S virtual int
|
||||||
|
#define C const noexcept
|
||||||
#else
|
#else
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
struct AbstractPolicy {
|
struct AbstractPolicy {
|
||||||
inline AbstractPolicy() {}
|
explicit inline AbstractPolicy() noexcept {}
|
||||||
virtual inline ~AbstractPolicy() {}
|
virtual inline ~AbstractPolicy() noexcept {}
|
||||||
V bool isBE() C = 0;
|
V bool isBE() C = 0;
|
||||||
V bool isLE() C = 0;
|
V bool isLE() C = 0;
|
||||||
|
|
||||||
@@ -80,33 +80,31 @@ struct AbstractPolicy {
|
|||||||
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:
|
private:
|
||||||
// disable copy, assignment and move assignment
|
// disable copy and move
|
||||||
AbstractPolicy(const AbstractPolicy &) = delete;
|
UPX_CXX_DISABLE_COPY_MOVE(AbstractPolicy)
|
||||||
AbstractPolicy &operator=(const AbstractPolicy &) = delete;
|
|
||||||
AbstractPolicy &operator=(AbstractPolicy &&) = delete;
|
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(AbstractPolicy)
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
#undef C
|
#undef C
|
||||||
#define C const override
|
#define C const noexcept override
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct BEPolicy
|
struct BEPolicy final
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
final : public AbstractPolicy
|
: public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline BEPolicy() {}
|
explicit inline BEPolicy() noexcept {}
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||||
#endif
|
#endif
|
||||||
V bool isBE() C { return true; }
|
VV bool isBE() C { return true; }
|
||||||
V bool isLE() C { return false; }
|
VV bool isLE() C { return false; }
|
||||||
|
|
||||||
typedef BE16 U16;
|
typedef BE16 U16;
|
||||||
typedef BE32 U32;
|
typedef BE32 U32;
|
||||||
@@ -147,27 +145,25 @@ struct BEPolicy
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disable copy, assignment and move assignment
|
// disable copy and move
|
||||||
BEPolicy(const BEPolicy &) = delete;
|
UPX_CXX_DISABLE_COPY_MOVE(BEPolicy)
|
||||||
BEPolicy &operator=(const BEPolicy &) = delete;
|
|
||||||
BEPolicy &operator=(BEPolicy &&) = delete;
|
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LEPolicy
|
struct LEPolicy final
|
||||||
#if defined(BELE_RTP)
|
#if defined(BELE_RTP)
|
||||||
final : public AbstractPolicy
|
: public AbstractPolicy
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
inline LEPolicy() {}
|
explicit inline LEPolicy() noexcept {}
|
||||||
#if defined(BELE_CTP)
|
#if defined(BELE_CTP)
|
||||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||||
#elif defined(BELE_RTP)
|
#elif defined(BELE_RTP)
|
||||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||||
#endif
|
#endif
|
||||||
V bool isBE() C { return false; }
|
VV bool isBE() C { return false; }
|
||||||
V bool isLE() C { return true; }
|
VV bool isLE() C { return true; }
|
||||||
|
|
||||||
typedef LE16 U16;
|
typedef LE16 U16;
|
||||||
typedef LE32 U32;
|
typedef LE32 U32;
|
||||||
@@ -208,42 +204,25 @@ struct LEPolicy
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disable copy, assignment and move assignment
|
// disable copy and move
|
||||||
LEPolicy(const LEPolicy &) = delete;
|
UPX_CXX_DISABLE_COPY_MOVE(LEPolicy)
|
||||||
LEPolicy &operator=(const LEPolicy &) = delete;
|
|
||||||
LEPolicy &operator=(LEPolicy &&) = delete;
|
|
||||||
// disable dynamic allocation
|
// disable dynamic allocation
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(LEPolicy)
|
||||||
};
|
};
|
||||||
|
|
||||||
// native policy (aka host policy)
|
// Native Endianness policy (aka host policy)
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
|
typedef BEPolicy NEPolicy;
|
||||||
typedef BEPolicy HostPolicy;
|
typedef BEPolicy HostPolicy;
|
||||||
#elif (ACC_ABI_LITTLE_ENDIAN)
|
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||||
|
typedef LEPolicy NEPolicy;
|
||||||
typedef LEPolicy HostPolicy;
|
typedef LEPolicy HostPolicy;
|
||||||
#else
|
#else
|
||||||
#error "ACC_ABI_ENDIAN"
|
#error "ACC_ABI_ENDIAN"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
|
||||||
struct HostAlignedPolicy {
|
|
||||||
#if defined(BELE_CTP)
|
|
||||||
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef upx_uint16_t U16;
|
|
||||||
typedef upx_uint32_t U32;
|
|
||||||
typedef upx_uint64_t U64;
|
|
||||||
|
|
||||||
static void compileTimeAssertions() {
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef V
|
#undef V
|
||||||
|
#undef VV
|
||||||
#undef S
|
#undef S
|
||||||
#undef C
|
#undef C
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,857 @@
|
|||||||
|
/* dt_check.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// doctest checks, and various tests to catch toolchain/qemu/sanitizer/valgrind/wine/etc
|
||||||
|
// problems; grown historically
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#include <cmath> // std::isinf std::isnan
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_doctest_check()
|
||||||
|
//
|
||||||
|
// honors environment variables:
|
||||||
|
// UPX_DEBUG_DOCTEST_DISABLE
|
||||||
|
// UPX_DEBUG_DOCTEST_VERBOSE
|
||||||
|
//
|
||||||
|
// HINT: set "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_doctest_check(int argc, char **argv) {
|
||||||
|
#if defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
UNUSED(argc);
|
||||||
|
UNUSED(argv);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST"))
|
||||||
|
return 0;
|
||||||
|
bool minimal = true; // don't show summary
|
||||||
|
bool duration = false; // don't show timings
|
||||||
|
bool success = false; // don't show all succeeding tests
|
||||||
|
#if DEBUG
|
||||||
|
// default for debug builds: do show the [doctest] summary
|
||||||
|
minimal = false;
|
||||||
|
#endif
|
||||||
|
const char *e = upx_getenv("UPX_DEBUG_DOCTEST_VERBOSE");
|
||||||
|
if (e && e[0]) {
|
||||||
|
if (strcmp(e, "0") == 0) {
|
||||||
|
minimal = true;
|
||||||
|
} else if (strcmp(e, "1") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
} else if (strcmp(e, "2") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
duration = true;
|
||||||
|
} else if (strcmp(e, "3") == 0) {
|
||||||
|
minimal = false;
|
||||||
|
duration = true;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doctest::Context context;
|
||||||
|
if (minimal)
|
||||||
|
context.setOption("dt-minimal", true);
|
||||||
|
if (duration)
|
||||||
|
context.setOption("dt-duration", true);
|
||||||
|
if (success)
|
||||||
|
context.setOption("dt-success", true);
|
||||||
|
// this requires that main_get_options() understands/ignores doctest "--dt-XXX" options
|
||||||
|
if (argc > 0 && argv != nullptr)
|
||||||
|
context.applyCommandLine(argc, argv);
|
||||||
|
int r = context.run();
|
||||||
|
if (r != 0)
|
||||||
|
return 1;
|
||||||
|
if (context.shouldExit())
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
#endif // DOCTEST_CONFIG_DISABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compile-time checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// need extra parenthesis because the C preprocessor does not understand C++ templates
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull)
|
||||||
|
#if !(ACC_CC_MSC) // unfortunately *not* constexpr with current MSVC
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(bswap16(0xf4f3f2f1)) == no_bswap16(0xf4f3f2f1))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(bswap32(0xf4f3f2f1)) == no_bswap32(0xf4f3f2f1))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(bswap64(0xf8f7f6f5f4f3f2f1ull)) ==
|
||||||
|
no_bswap64(0xf8f7f6f5f4f3f2f1ull))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 0, 8) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 1, 8) == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 127, 8) == 127)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 128, 8) == -128)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u - 1, 8) == -1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 256, 8) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 257, 8) == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 0, 1) == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 1, 1) == -1)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
|
||||||
|
#if 0 // does not work with MSVC
|
||||||
|
#if '\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 127)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255)
|
||||||
|
#endif
|
||||||
|
#if L'\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 < 0)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 > 0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_compiler_sanity_check()
|
||||||
|
// assert a sane architecture and compiler
|
||||||
|
// (modern compilers will optimize away most of this code)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct CheckIntegral {
|
||||||
|
struct TestT {
|
||||||
|
T a;
|
||||||
|
T x[2];
|
||||||
|
};
|
||||||
|
template <class U>
|
||||||
|
struct TestU {
|
||||||
|
U a = {};
|
||||||
|
const U b = {};
|
||||||
|
static constexpr U c = {};
|
||||||
|
U x[2] = {};
|
||||||
|
const U y[2] = {};
|
||||||
|
static constexpr U z[2] = {};
|
||||||
|
};
|
||||||
|
template <class U>
|
||||||
|
static void checkU(void) noexcept {
|
||||||
|
{
|
||||||
|
U a = {};
|
||||||
|
const U b = {};
|
||||||
|
constexpr U c = {};
|
||||||
|
U x[2] = {};
|
||||||
|
const U y[2] = {};
|
||||||
|
constexpr U z[2] = {};
|
||||||
|
assert_noexcept(a == 0);
|
||||||
|
assert_noexcept(b == 0);
|
||||||
|
assert_noexcept(c == 0);
|
||||||
|
assert_noexcept(x[0] == 0 && x[1] == 0);
|
||||||
|
assert_noexcept(y[0] == 0 && y[1] == 0);
|
||||||
|
assert_noexcept(z[0] == 0 && z[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
TestU<U> t;
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.b == 0);
|
||||||
|
assert_noexcept(t.c == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
assert_noexcept(t.y[0] == 0 && t.y[1] == 0);
|
||||||
|
assert_noexcept(t.z[0] == 0 && t.z[1] == 0);
|
||||||
|
}
|
||||||
|
#if __cplusplus <= 201703L
|
||||||
|
COMPILE_TIME_ASSERT(std::is_pod<U>::value) // std::is_pod is deprecated in C++20
|
||||||
|
#endif
|
||||||
|
COMPILE_TIME_ASSERT(std::is_standard_layout<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivial<U>::value)
|
||||||
|
// more checks, these are probably implied by std::is_trivial
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_destructible<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_copyable<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<U>::value)
|
||||||
|
// UPX extras
|
||||||
|
COMPILE_TIME_ASSERT(upx_is_integral<U>::value)
|
||||||
|
COMPILE_TIME_ASSERT(upx_is_integral_v<U>)
|
||||||
|
}
|
||||||
|
static void check(void) noexcept {
|
||||||
|
{
|
||||||
|
TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr TestT t = {};
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
TestT t;
|
||||||
|
mem_clear(&t);
|
||||||
|
assert_noexcept(t.a == 0);
|
||||||
|
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
|
||||||
|
}
|
||||||
|
checkU<T>();
|
||||||
|
checkU<typename std::add_const<T>::type>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct CheckAlignment {
|
||||||
|
static void check(void) noexcept {
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
|
struct alignas(1) Test1 {
|
||||||
|
char a;
|
||||||
|
T b;
|
||||||
|
};
|
||||||
|
struct alignas(1) Test2 {
|
||||||
|
char a;
|
||||||
|
T b[3];
|
||||||
|
};
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Test1)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Test2)
|
||||||
|
Test1 t1[7];
|
||||||
|
Test2 t2[7];
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Test1) == 1 + sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Test2) == 1 + 3 * sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||||
|
UNUSED(t1);
|
||||||
|
UNUSED(t2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class T>
|
||||||
|
struct TestBELE {
|
||||||
|
static noinline bool test(void) noexcept {
|
||||||
|
CheckIntegral<T>::check();
|
||||||
|
CheckAlignment<T>::check();
|
||||||
|
// arithmetic checks
|
||||||
|
T allbits = {};
|
||||||
|
assert_noexcept(allbits == 0);
|
||||||
|
allbits += 1;
|
||||||
|
allbits -= 2;
|
||||||
|
T v1;
|
||||||
|
v1 = 1;
|
||||||
|
v1 *= 4;
|
||||||
|
v1 /= 2;
|
||||||
|
v1 -= 1;
|
||||||
|
T v2;
|
||||||
|
v2 = 1;
|
||||||
|
assert_noexcept((v1 == v2));
|
||||||
|
assert_noexcept(!(v1 != v2));
|
||||||
|
assert_noexcept((v1 <= v2));
|
||||||
|
assert_noexcept((v1 >= v2));
|
||||||
|
assert_noexcept(!(v1 < v2));
|
||||||
|
assert_noexcept(!(v1 > v2));
|
||||||
|
v2 ^= allbits;
|
||||||
|
assert_noexcept(!(v1 == v2));
|
||||||
|
assert_noexcept((v1 != v2));
|
||||||
|
assert_noexcept((v1 <= v2));
|
||||||
|
assert_noexcept(!(v1 >= v2));
|
||||||
|
assert_noexcept((v1 < v2));
|
||||||
|
assert_noexcept(!(v1 > v2));
|
||||||
|
v2 += 2;
|
||||||
|
assert_noexcept(v1 == 1);
|
||||||
|
assert_noexcept(v2 == 0);
|
||||||
|
v1 <<= 1;
|
||||||
|
v1 |= v2;
|
||||||
|
v1 >>= 1;
|
||||||
|
v2 &= v1;
|
||||||
|
v2 /= v1;
|
||||||
|
v2 *= v1;
|
||||||
|
v1 += v2;
|
||||||
|
v1 -= v2;
|
||||||
|
assert_noexcept(v1 == 1);
|
||||||
|
assert_noexcept(v2 == 0);
|
||||||
|
if ((v1 ^ v2) != 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
struct TestNoAliasingStruct {
|
||||||
|
static noinline bool test(A *a, B *b) noexcept {
|
||||||
|
*a = 0;
|
||||||
|
*b = 0;
|
||||||
|
*b -= 3;
|
||||||
|
return *a != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class A, class B>
|
||||||
|
static forceinline bool testNoAliasing(A *a, B *b) noexcept {
|
||||||
|
return TestNoAliasingStruct<A, B>::test(a, b);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
struct TestIntegerWrap {
|
||||||
|
static inline bool inc_gt(const T x) noexcept { return x + 1 > x; }
|
||||||
|
static inline bool dec_lt(const T x) noexcept { return x - 1 < x; }
|
||||||
|
static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic exception handling checks to early catch toolchain/qemu/wine/etc problems
|
||||||
|
//
|
||||||
|
|
||||||
|
struct TestDestructor {
|
||||||
|
explicit TestDestructor(int *pp, int vv) noexcept : p(pp), v(vv) {}
|
||||||
|
virtual noinline ~TestDestructor() noexcept { *p = (*p << 2) + v; }
|
||||||
|
int *p;
|
||||||
|
int v;
|
||||||
|
};
|
||||||
|
|
||||||
|
static noinline void throwSomeValue(int x) may_throw {
|
||||||
|
if (x < 0)
|
||||||
|
throw int(x);
|
||||||
|
else
|
||||||
|
throw size_t(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline void check_exceptions_2(void (*func)(int), int *x) may_throw {
|
||||||
|
TestDestructor d(x, *x);
|
||||||
|
func(*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexcept {
|
||||||
|
bool cxx_exception_handling_works = false;
|
||||||
|
int x = 1;
|
||||||
|
try {
|
||||||
|
TestDestructor d(&x, 3);
|
||||||
|
check_exceptions_2(func, &x);
|
||||||
|
} catch (const size_t &e) {
|
||||||
|
if (e == 1 && x == 23)
|
||||||
|
cxx_exception_handling_works = true;
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
assert_noexcept(cxx_exception_handling_works);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// basic floating point checks to early catch toolchain/qemu/wine/etc problems
|
||||||
|
//
|
||||||
|
|
||||||
|
static noinline float i64_f32_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0f; }
|
||||||
|
static noinline float u64_f32_add_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a + b) / 1000000.0f;
|
||||||
|
}
|
||||||
|
static noinline float i64_f32_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0f; }
|
||||||
|
static noinline float u64_f32_sub_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a - b) / 1000000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static noinline double i64_f64_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0; }
|
||||||
|
static noinline double u64_f64_add_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a + b) / 1000000.0;
|
||||||
|
}
|
||||||
|
static noinline double i64_f64_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0; }
|
||||||
|
static noinline double u64_f64_sub_div(upx_uint64_t a, upx_uint64_t b) {
|
||||||
|
return (a - b) / 1000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Int, class Float>
|
||||||
|
struct TestFloat {
|
||||||
|
static constexpr Int X = 1000000;
|
||||||
|
static noinline Float div(Int a, Float f) { return a / f; }
|
||||||
|
static noinline Float add_div(Int a, Int b, Float f) { return Float(a + b) / f; }
|
||||||
|
static noinline Float sub_div(Int a, Int b, Float f) { return Float(a - b) / f; }
|
||||||
|
static noinline Float add_div_x(Int a, Int b) { return Float(a + b) / Float(X); }
|
||||||
|
static noinline Float sub_div_x(Int a, Int b) { return Float(a - b) / Float(X); }
|
||||||
|
static noinline void check() noexcept {
|
||||||
|
assert_noexcept(div(2 * X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(add_div(X, X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(add_div_x(X, X) == Float(2));
|
||||||
|
assert_noexcept(sub_div(3 * X, X, Float(X)) == Float(2));
|
||||||
|
assert_noexcept(sub_div_x(3 * X, X) == Float(2));
|
||||||
|
// extra debugging; floating point edge cases cause portability problems in practice
|
||||||
|
static const char envvar[] = "UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO";
|
||||||
|
if (is_envvar_true(envvar)) {
|
||||||
|
#if defined(__FAST_MATH__)
|
||||||
|
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||||
|
fprintf(stderr, "upx: WARNING: ignoring %s: __FAST_MATH__\n", envvar);
|
||||||
|
#else
|
||||||
|
assert_noexcept(std::isnan(div(0, Float(0))));
|
||||||
|
assert_noexcept(std::isinf(div(1, Float(0))));
|
||||||
|
assert_noexcept(std::isinf(div(Int(-1), Float(0))));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static noinline void check_basic_floating_point(void) noexcept {
|
||||||
|
assert_noexcept(i64_f32_add_div(1000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(u64_f32_add_div(1000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(i64_f32_sub_div(3000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(u64_f32_sub_div(3000000, 1000000) == 2.0f);
|
||||||
|
assert_noexcept(i64_f64_add_div(1000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(u64_f64_add_div(1000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(i64_f64_sub_div(3000000, 1000000) == 2.0);
|
||||||
|
assert_noexcept(u64_f64_sub_div(3000000, 1000000) == 2.0);
|
||||||
|
TestFloat<upx_int32_t, float>::check();
|
||||||
|
TestFloat<upx_uint32_t, float>::check();
|
||||||
|
TestFloat<upx_int64_t, float>::check();
|
||||||
|
TestFloat<upx_uint64_t, float>::check();
|
||||||
|
TestFloat<upx_int32_t, double>::check();
|
||||||
|
TestFloat<upx_uint32_t, double>::check();
|
||||||
|
TestFloat<upx_int64_t, double>::check();
|
||||||
|
TestFloat<upx_uint64_t, double>::check();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#include "../util/miniacc.h"
|
||||||
|
|
||||||
|
void upx_compiler_sanity_check(void) noexcept {
|
||||||
|
check_basic_floating_point();
|
||||||
|
|
||||||
|
if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST")) {
|
||||||
|
// If UPX_DEBUG_DOCTEST_DISABLE is set then we don't want to throw any
|
||||||
|
// exceptions in order to improve debugging experience.
|
||||||
|
} else {
|
||||||
|
// check working C++ exception handling to early catch toolchain/qemu/wine/etc problems
|
||||||
|
check_basic_cxx_exception_handling(throwSomeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check_basic_decltype()
|
||||||
|
{
|
||||||
|
auto a = +0;
|
||||||
|
constexpr auto b = -0;
|
||||||
|
const auto &c = -1;
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<int, decltype(a)>::value))
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<const int, decltype(b)>::value))
|
||||||
|
COMPILE_TIME_ASSERT((std::is_same<const int &, decltype(c)>::value))
|
||||||
|
UNUSED(a);
|
||||||
|
UNUSED(b);
|
||||||
|
UNUSED(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ACC_WANT_ACC_CHK_CH 1
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
|
||||||
|
#include "../util/miniacc.h"
|
||||||
|
#undef ACCCHK_ASSERT
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(char) == 1)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(short) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(int) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(long) >= 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(void *) >= 4)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(BE64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
|
||||||
|
|
||||||
|
CheckIntegral<char>::check();
|
||||||
|
CheckIntegral<signed char>::check();
|
||||||
|
CheckIntegral<unsigned char>::check();
|
||||||
|
CheckIntegral<short>::check();
|
||||||
|
CheckIntegral<int>::check();
|
||||||
|
CheckIntegral<long>::check();
|
||||||
|
CheckIntegral<long long>::check();
|
||||||
|
CheckIntegral<ptrdiff_t>::check();
|
||||||
|
CheckIntegral<size_t>::check();
|
||||||
|
CheckIntegral<upx_off_t>::check();
|
||||||
|
CheckIntegral<upx_uintptr_t>::check();
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(upx_charptr_unit_type) == 1)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
|
||||||
|
|
||||||
|
// check UPX_VERSION_xxx
|
||||||
|
{
|
||||||
|
using upx::compile_time::mem_eq;
|
||||||
|
using upx::compile_time::string_len;
|
||||||
|
static_assert(string_len(UPX_VERSION_STRING4) == 4);
|
||||||
|
static_assert(string_len(UPX_VERSION_YEAR) == 4);
|
||||||
|
static_assert(string_len(UPX_VERSION_DATE_ISO) == 10);
|
||||||
|
static_assert(string_len(UPX_VERSION_DATE) == 12 || string_len(UPX_VERSION_DATE) == 13);
|
||||||
|
static_assert(mem_eq(UPX_VERSION_STRING4, UPX_VERSION_STRING, 3));
|
||||||
|
static_assert(mem_eq(UPX_VERSION_YEAR, UPX_VERSION_DATE_ISO, 4));
|
||||||
|
static_assert(mem_eq(UPX_VERSION_YEAR, &UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 5], 4));
|
||||||
|
char buf[16];
|
||||||
|
constexpr long long v = UPX_VERSION_HEX;
|
||||||
|
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld.%lld", (v >> 16), (v >> 8) & 255, v & 255);
|
||||||
|
assert_noexcept(strcmp(buf, UPX_VERSION_STRING) == 0);
|
||||||
|
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld%lld", (v >> 16), (v >> 8) & 255, v & 255);
|
||||||
|
assert_noexcept(strcmp(buf, UPX_VERSION_STRING4) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gitrev[0]) {
|
||||||
|
size_t revlen = strlen(gitrev);
|
||||||
|
if (strncmp(gitrev, "ERROR", 5) == 0) {
|
||||||
|
assert_noexcept(revlen == 5 || revlen == 6);
|
||||||
|
} else {
|
||||||
|
assert_noexcept(revlen == 12 || revlen == 13);
|
||||||
|
}
|
||||||
|
if (revlen == 6 || revlen == 13) {
|
||||||
|
assert_noexcept(gitrev[revlen - 1] == '+');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_noexcept(UPX_RSIZE_MAX_MEM == 805306368);
|
||||||
|
|
||||||
|
#if DEBUG || 1
|
||||||
|
assert_noexcept(TestBELE<LE16>::test());
|
||||||
|
assert_noexcept(TestBELE<LE32>::test());
|
||||||
|
assert_noexcept(TestBELE<LE64>::test());
|
||||||
|
assert_noexcept(TestBELE<BE16>::test());
|
||||||
|
assert_noexcept(TestBELE<BE32>::test());
|
||||||
|
assert_noexcept(TestBELE<BE64>::test());
|
||||||
|
{
|
||||||
|
alignas(16) static const byte dd[32] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0,
|
||||||
|
0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0};
|
||||||
|
const byte *d;
|
||||||
|
const N_BELE_RTP::AbstractPolicy *bele;
|
||||||
|
d = dd + 7;
|
||||||
|
assert_noexcept(upx_adler32(d, 4) == 0x09f003f7);
|
||||||
|
assert_noexcept(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||||
|
assert_noexcept(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
|
assert_noexcept(get_be16(d) == 0xfffe);
|
||||||
|
assert_noexcept(bele->get16(d) == 0xfffe);
|
||||||
|
assert_noexcept(get_be16_signed(d) == -2);
|
||||||
|
assert_noexcept(get_be24(d) == 0xfffefd);
|
||||||
|
assert_noexcept(bele->get24(d) == 0xfffefd);
|
||||||
|
assert_noexcept(get_be24_signed(d) == -259);
|
||||||
|
assert_noexcept(get_be32(d) == 0xfffefdfc);
|
||||||
|
assert_noexcept(bele->get32(d) == 0xfffefdfc);
|
||||||
|
assert_noexcept(get_be32_signed(d) == -66052);
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
assert_noexcept(get_le16(d) == 0xfeff);
|
||||||
|
assert_noexcept(bele->get16(d) == 0xfeff);
|
||||||
|
assert_noexcept(get_le16_signed(d) == -257);
|
||||||
|
assert_noexcept(get_le24(d) == 0xfdfeff);
|
||||||
|
assert_noexcept(bele->get24(d) == 0xfdfeff);
|
||||||
|
assert_noexcept(get_le24_signed(d) == -131329);
|
||||||
|
assert_noexcept(get_le32(d) == 0xfcfdfeff);
|
||||||
|
assert_noexcept(bele->get32(d) == 0xfcfdfeff);
|
||||||
|
assert_noexcept(get_le32_signed(d) == -50462977);
|
||||||
|
assert_noexcept(get_le64_signed(d) == -506097522914230529LL);
|
||||||
|
assert_noexcept(find_be16(d, 2, 0xfffe) == 0);
|
||||||
|
assert_noexcept(find_le16(d, 2, 0xfeff) == 0);
|
||||||
|
assert_noexcept(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||||
|
assert_noexcept(find_le32(d, 4, 0xfcfdfeff) == 0);
|
||||||
|
d += 12;
|
||||||
|
assert_noexcept(get_be16_signed(d) == 32638);
|
||||||
|
assert_noexcept(get_be24_signed(d) == 8355453);
|
||||||
|
assert_noexcept(get_be32_signed(d) == 2138996092);
|
||||||
|
assert_noexcept(get_be64_signed(d) == 9186918263483431288LL);
|
||||||
|
}
|
||||||
|
#if DEBUG >= 1
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
{
|
||||||
|
const unsigned u = i;
|
||||||
|
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
|
||||||
|
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
|
||||||
|
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
|
||||||
|
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
|
||||||
|
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
|
||||||
|
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
|
||||||
|
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
|
||||||
|
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
|
||||||
|
assert_noexcept(sign_extend(u, 32) == i);
|
||||||
|
assert_noexcept(sign_extend(0u - u, 32) == -i);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const upx_uint64_t u = i;
|
||||||
|
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
|
||||||
|
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
|
||||||
|
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
|
||||||
|
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
|
||||||
|
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
|
||||||
|
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
|
||||||
|
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
|
||||||
|
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
|
||||||
|
assert_noexcept(sign_extend(u, 64) == i);
|
||||||
|
assert_noexcept(sign_extend(0ull - u, 64) == -i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned dd;
|
||||||
|
void *const d = ⅆ
|
||||||
|
dd = ne32_to_le32(0xf7f6f5f4);
|
||||||
|
assert_noexcept(get_le26(d) == 0x03f6f5f4);
|
||||||
|
set_le26(d, 0);
|
||||||
|
assert_noexcept(get_le26(d) == 0);
|
||||||
|
assert_noexcept(dd == ne32_to_le32(0xf4000000));
|
||||||
|
set_le26(d, 0xff020304);
|
||||||
|
assert_noexcept(get_le26(d) == 0x03020304);
|
||||||
|
assert_noexcept(dd == ne32_to_le32(0xf7020304));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
upx_uint16_t a = 0;
|
||||||
|
upx_uint32_t b = 0;
|
||||||
|
upx_uint64_t c = 0;
|
||||||
|
set_ne16(&a, 0x04030201); // ignore upper bits
|
||||||
|
set_ne32(&b, 0x04030201);
|
||||||
|
set_ne64(&c, 0x0807060504030201ull);
|
||||||
|
assert_noexcept(a == 0x0201);
|
||||||
|
assert_noexcept(b == 0x04030201);
|
||||||
|
assert_noexcept(c == 0x0807060504030201ull);
|
||||||
|
assert_noexcept(get_ne16(&a) == 0x0201);
|
||||||
|
assert_noexcept(get_ne32(&b) == 0x04030201);
|
||||||
|
assert_noexcept(get_ne64(&c) == 0x0807060504030201ull);
|
||||||
|
}
|
||||||
|
#endif // DEBUG
|
||||||
|
union {
|
||||||
|
short v_short;
|
||||||
|
int v_int;
|
||||||
|
long v_long;
|
||||||
|
long long v_llong;
|
||||||
|
BE16 b16;
|
||||||
|
BE32 b32;
|
||||||
|
BE64 b64;
|
||||||
|
LE16 l16;
|
||||||
|
LE32 l32;
|
||||||
|
LE64 l64;
|
||||||
|
} u;
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.b32));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.l32));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.b64));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.l64));
|
||||||
|
// check working -fno-strict-aliasing
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_short, &u.v_int));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.v_long));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_int, &u.v_llong));
|
||||||
|
assert_noexcept(testNoAliasing(&u.v_long, &u.v_llong));
|
||||||
|
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::inc_gt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::inc_gt(UINT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::dec_lt(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::dec_lt(0));
|
||||||
|
assert_noexcept(TestIntegerWrap<unsigned>::neg_eq(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(UINT_MAX));
|
||||||
|
// check working -fno-strict-overflow
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::inc_gt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::inc_gt(INT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::dec_lt(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::dec_lt(INT_MIN));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::neg_eq(0));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::neg_eq(1));
|
||||||
|
assert_noexcept(!TestIntegerWrap<int>::neg_eq(INT_MAX));
|
||||||
|
assert_noexcept(TestIntegerWrap<int>::neg_eq(INT_MIN)); // special case
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// some doctest test cases
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("assert_noexcept") {
|
||||||
|
// just to make sure that our own assert() macros do not trigger any compiler warnings
|
||||||
|
byte dummy = 0;
|
||||||
|
byte *ptr1 = &dummy;
|
||||||
|
const byte *const ptr2 = &dummy;
|
||||||
|
void *ptr3 = nullptr;
|
||||||
|
assert(true);
|
||||||
|
assert(1);
|
||||||
|
assert(ptr1);
|
||||||
|
assert(ptr2);
|
||||||
|
assert(!ptr3);
|
||||||
|
assert_noexcept(true);
|
||||||
|
assert_noexcept(1);
|
||||||
|
assert_noexcept(ptr1);
|
||||||
|
assert_noexcept(ptr2);
|
||||||
|
assert_noexcept(!ptr3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("acc_vget") {
|
||||||
|
CHECK_EQ(acc_vget_int(0, 0), 0);
|
||||||
|
CHECK_EQ(acc_vget_long(1, -1), 1);
|
||||||
|
CHECK_EQ(acc_vget_acc_int64l_t(2, 1), 2);
|
||||||
|
CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr);
|
||||||
|
if (acc_vget_int(1, 0) > 0)
|
||||||
|
return;
|
||||||
|
assert_noexcept(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ptr_invalidate_and_poison") {
|
||||||
|
int *ip = nullptr; // initialized
|
||||||
|
ptr_invalidate_and_poison(ip);
|
||||||
|
assert(ip != nullptr);
|
||||||
|
(void) ip;
|
||||||
|
double *dp; // not initialized
|
||||||
|
ptr_invalidate_and_poison(dp);
|
||||||
|
assert(dp != nullptr);
|
||||||
|
(void) dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx_getenv") {
|
||||||
|
CHECK_EQ(upx_getenv(nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx_getenv(""), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-aliasing") {
|
||||||
|
bool ok;
|
||||||
|
long v = 0;
|
||||||
|
short *ps = ACC_STATIC_CAST(short *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
int *pi = ACC_STATIC_CAST(int *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
long *pl = ACC_STATIC_CAST(long *, acc_vget_acc_hvoid_p(&v, 0));
|
||||||
|
*ps = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *ps == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pi = 0;
|
||||||
|
*pl = -1;
|
||||||
|
ok = *pi == -1;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*ps = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
*pl = 0;
|
||||||
|
*pi = -1;
|
||||||
|
ok = *pl != 0;
|
||||||
|
CHECK(ok);
|
||||||
|
UNUSED(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("working -fno-strict-overflow") {
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MAX, 0) + 1, INT_MIN);
|
||||||
|
CHECK_EQ(acc_vget_int(INT_MIN, 0) - 1, INT_MAX);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MAX, 0) + 1, LONG_MIN);
|
||||||
|
CHECK_EQ(acc_vget_long(LONG_MIN, 0) - 1, LONG_MAX);
|
||||||
|
bool ok;
|
||||||
|
int i;
|
||||||
|
i = INT_MAX;
|
||||||
|
i += 1;
|
||||||
|
ok = i == INT_MIN;
|
||||||
|
CHECK(ok);
|
||||||
|
i = INT_MIN;
|
||||||
|
i -= 1;
|
||||||
|
ok = i == INT_MAX;
|
||||||
|
CHECK(ok);
|
||||||
|
UNUSED(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc snprintf") {
|
||||||
|
// runtime check that Windows/MinGW <stdio.h> works as expected
|
||||||
|
char buf[64];
|
||||||
|
long long ll = acc_vget_int(-1, 0);
|
||||||
|
unsigned long long llu = (unsigned long long) ll;
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu);
|
||||||
|
CHECK_EQ(strcmp(buf, "-3.-2.-1.3.2.18446744073709551615"), 0);
|
||||||
|
intmax_t im = ll;
|
||||||
|
uintmax_t um = llu;
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%jd", -4, 0, 0, 0, 0, 0, 0, 0, 4, im);
|
||||||
|
CHECK_EQ(strcmp(buf, "-4.0.0.0.0.0.0.0.4.-1"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%ju", -5, 0, 0, 0, 0, 0, 0, 0, 5, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-5.0.0.0.0.0.0.0.5.18446744073709551615"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%jx", -6, 0, 0, 0, 0, 0, 0, 0, 6, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-6.0.0.0.0.0.0.0.6.ffffffffffffffff"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%#jx", -7, 0, 0, 0, 0, 0, 0, 0, 7, um);
|
||||||
|
CHECK_EQ(strcmp(buf, "-7.0.0.0.0.0.0.0.7.0xffffffffffffffff"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#X %#lx %#llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#06x %#06lX %#06llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0x001a 0X001B 0x001c"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#6x %#6lx %#6llX", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, " 0x1a 0x1b 0X1C"), 0);
|
||||||
|
snprintf(buf, sizeof(buf), "%#-6X %#-6lx %#-6llx", 26u, 27ul, 28ull);
|
||||||
|
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c "), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("libc qsort") {
|
||||||
|
// runtime check that libc qsort() never compares identical objects
|
||||||
|
// UPDATE: while only poor implementations of qsort() would actually do this
|
||||||
|
// it is probably allowed by the standard, so skip this test by default
|
||||||
|
if (!is_envvar_true("UPX_DEBUG_TEST_LIBC_QSORT"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct Elem {
|
||||||
|
upx_uint16_t id;
|
||||||
|
upx_uint16_t value;
|
||||||
|
static int __acc_cdecl_qsort compare(const void *aa, const void *bb) noexcept {
|
||||||
|
const Elem *a = (const Elem *) aa;
|
||||||
|
const Elem *b = (const Elem *) bb;
|
||||||
|
assert_noexcept(a->id != b->id); // check not IDENTICAL
|
||||||
|
return a->value < b->value ? -1 : (a->value == b->value ? 0 : 1);
|
||||||
|
}
|
||||||
|
static noinline bool check_sort(upx_sort_func_t sort, Elem *e, size_t n, bool is_stable) {
|
||||||
|
upx_uint32_t x = 5381 + (upx_rand() & 255);
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
e[i].id = (upx_uint16_t) i;
|
||||||
|
x = x * 33 + 1 + (i & 255);
|
||||||
|
e[i].value = (upx_uint16_t) ((x >> 4) & 15);
|
||||||
|
}
|
||||||
|
sort(e, n, sizeof(Elem), Elem::compare);
|
||||||
|
// verify
|
||||||
|
for (size_t i = 1; i < n; i++) {
|
||||||
|
if very_unlikely (e[i - 1].value > e[i].value)
|
||||||
|
return false;
|
||||||
|
if (is_stable)
|
||||||
|
if very_unlikely (e[i - 1].value == e[i].value && e[i - 1].id >= e[i].id)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constexpr size_t N = 4096;
|
||||||
|
Elem e[N];
|
||||||
|
for (size_t n = 0; n <= N; n = 2 * n + 1) {
|
||||||
|
// system sort functions
|
||||||
|
CHECK(Elem::check_sort(::qsort, e, n, false)); // libc qsort()
|
||||||
|
#if UPX_CONFIG_USE_STABLE_SORT
|
||||||
|
upx_sort_func_t wrap_stable_sort = [](void *aa, size_t nn, size_t, upx_compare_func_t cc) {
|
||||||
|
upx_std_stable_sort<sizeof(Elem)>(aa, nn, cc);
|
||||||
|
};
|
||||||
|
CHECK(Elem::check_sort(wrap_stable_sort, e, n, true)); // std::stable_sort()
|
||||||
|
#endif
|
||||||
|
// simple UPX sort functions
|
||||||
|
CHECK(Elem::check_sort(upx_gnomesort, e, n, true));
|
||||||
|
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n, false));
|
||||||
|
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,554 @@
|
|||||||
|
/* dt_cxxlib.cpp -- doctest check
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// lots of tests (and probably quite a number of redundant tests)
|
||||||
|
// modern compilers will optimize away much of this code
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#include <vector> // std::vector
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compile-time checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// need extra parenthesis because the C preprocessor does not understand C++ templates
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, int, char>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, char, int>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, char>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
|
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
|
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("ab") == 3)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L'a') == sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"") == 1 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"a") == 2 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"ab") == 3 * sizeof(wchar_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0LL) == sizeof(long long))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(sizeof(0)) == sizeof(size_t))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned))
|
||||||
|
#if 0
|
||||||
|
// works, but may trigger clang/gcc warnings "-Wunused-value"
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1LL, 1)) == sizeof(int))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1, 1LL)) == sizeof(long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace compile_time = upx::compile_time;
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("ab") == 2)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("abc") == 3)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("abc", "ab"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("a", ""))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("", "a"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("ab", "abc"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "ab"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "aba"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_ne("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const char *) nullptr, nullptr, 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const byte *) nullptr, nullptr, 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("", "", 0))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("abc", "abc", 3))
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::mem_eq("abc", "abz", 3))
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("std::vector") {
|
||||||
|
constexpr size_t N = 16;
|
||||||
|
std::vector<int> v(N);
|
||||||
|
CHECK(v.end() - v.begin() == N);
|
||||||
|
CHECK(&v[0] == &(*(v.begin())));
|
||||||
|
// CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal??
|
||||||
|
// TODO later: make sure that this throws
|
||||||
|
#if defined(_LIBCPP_HARDENING_MODE_DEBUG) && \
|
||||||
|
(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG)
|
||||||
|
CHECK_THROWS((void) &v[N]);
|
||||||
|
#endif
|
||||||
|
UNUSED(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// UPX_CXX_DISABLE_xxx
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyType1 {
|
||||||
|
MyType1() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(MyType1)
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyType1)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(MyType1)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyType2 {
|
||||||
|
MyType2() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyType2)
|
||||||
|
typedef MyType2<TA, TB, TC> Self;
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(Self)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(Self)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyVType1 {
|
||||||
|
MyVType1() noexcept {}
|
||||||
|
virtual ~MyVType1() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(MyVType1)
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyVType1)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(MyVType1)
|
||||||
|
};
|
||||||
|
template <class TA, class TB, int TC = 0>
|
||||||
|
struct MyVType2 {
|
||||||
|
MyVType2() noexcept {}
|
||||||
|
virtual ~MyVType2() noexcept {}
|
||||||
|
UPX_CXX_DISABLE_COPY_MOVE(MyVType2)
|
||||||
|
typedef MyVType2<TA, TB, TC> Self;
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(Self)
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Self)
|
||||||
|
};
|
||||||
|
TEST_CASE("UPX_CXX_DISABLE_xxx") {
|
||||||
|
MyType1<char, int, 1> dummy1;
|
||||||
|
MyType2<char, int, 2> dummy2;
|
||||||
|
MyVType1<char, int, 1> vdummy1;
|
||||||
|
MyVType2<char, int, 2> vdummy2;
|
||||||
|
(void) dummy1;
|
||||||
|
(void) dummy2;
|
||||||
|
(void) vdummy1;
|
||||||
|
(void) vdummy2;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace test_disable_new_delete {
|
||||||
|
|
||||||
|
struct A1 {
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
struct A2 {
|
||||||
|
int a;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(A2)
|
||||||
|
};
|
||||||
|
struct B1_A1 : public A1 {
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
struct B1_A2 : public A2 {
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
struct B2_A1 : public A1 {
|
||||||
|
int b;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A1)
|
||||||
|
};
|
||||||
|
struct B2_A2 : public A2 {
|
||||||
|
int b;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A2)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct X1 {
|
||||||
|
virtual ~X1() noexcept {}
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
struct X2 {
|
||||||
|
virtual ~X2() noexcept {}
|
||||||
|
int x;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(X2)
|
||||||
|
};
|
||||||
|
struct Y1_X1 : public X1 {
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
struct Y1_X2 : public X2 {
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
struct Y2_X1 : public X1 {
|
||||||
|
int y;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Y2_X1)
|
||||||
|
};
|
||||||
|
struct Y2_X2 : public X2 {
|
||||||
|
int y;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Y2_X2)
|
||||||
|
};
|
||||||
|
struct Z1_X1 : public X1 {
|
||||||
|
virtual ~Z1_X1() noexcept {}
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
struct Z1_X2 : public X2 {
|
||||||
|
virtual ~Z1_X2() noexcept {}
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
struct Z2_X1 : public X1 {
|
||||||
|
virtual ~Z2_X1() noexcept {}
|
||||||
|
int z;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Z2_X1)
|
||||||
|
};
|
||||||
|
struct Z2_X2 : public X2 {
|
||||||
|
virtual ~Z2_X2() noexcept {}
|
||||||
|
int z;
|
||||||
|
UPX_CXX_DISABLE_NEW_DELETE(Z2_X2)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace test_disable_new_delete
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// util
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if WITH_THREADS
|
||||||
|
TEST_CASE("upx::ptr_std_atomic_cast") {
|
||||||
|
// pointer-size
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((void **) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((uintptr_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_uintptr_t *) nullptr), nullptr);
|
||||||
|
#if 1
|
||||||
|
// more fundamental types
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((char *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((short *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((int *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((long *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((size_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int8_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int16_t *) nullptr), nullptr);
|
||||||
|
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int32_t *) nullptr), nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("upx::atomic_exchange") {
|
||||||
|
{
|
||||||
|
upx_uintptr_t x = (upx_uintptr_t) 0 - 1;
|
||||||
|
upx_uintptr_t y = upx::atomic_exchange(&x, (upx_uintptr_t) 2);
|
||||||
|
CHECK_EQ(x, 2);
|
||||||
|
CHECK_EQ(y, (upx_uintptr_t) 0 - 1);
|
||||||
|
UNUSED(y);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const int buf[2] = {101, 202};
|
||||||
|
const int *ptr_array[2] = {&buf[0], &buf[1]};
|
||||||
|
assert_noexcept(*ptr_array[0] == 101 && *ptr_array[1] == 202);
|
||||||
|
const int *p = upx::atomic_exchange(&ptr_array[0], ptr_array[1]);
|
||||||
|
CHECK_EQ(p, buf + 0);
|
||||||
|
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 202);
|
||||||
|
p = upx::atomic_exchange(&ptr_array[1], p);
|
||||||
|
CHECK_EQ(p, buf + 1);
|
||||||
|
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 101);
|
||||||
|
UNUSED(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ObjectDeleter 1") {
|
||||||
|
LE16 *o = nullptr; // object
|
||||||
|
LE32 *a = nullptr; // array
|
||||||
|
LE64 *m = nullptr; // malloc
|
||||||
|
{
|
||||||
|
auto o_deleter = upx::ObjectDeleter(&o, 1);
|
||||||
|
o = new LE16;
|
||||||
|
assert(o != nullptr);
|
||||||
|
auto a_deleter = upx::ArrayDeleter(&a, 1);
|
||||||
|
a = New(LE32, 1);
|
||||||
|
assert(a != nullptr);
|
||||||
|
auto m_deleter = upx::MallocDeleter(&m, 1);
|
||||||
|
m = (LE64 *) ::malloc(sizeof(LE64));
|
||||||
|
assert(m != nullptr);
|
||||||
|
}
|
||||||
|
assert(o == nullptr);
|
||||||
|
assert(a == nullptr);
|
||||||
|
assert(m == nullptr);
|
||||||
|
// test "const" versions
|
||||||
|
{
|
||||||
|
const auto o_deleter = upx::ObjectDeleter(&o, 1);
|
||||||
|
o = new LE16;
|
||||||
|
assert(o != nullptr);
|
||||||
|
const auto a_deleter = upx::ArrayDeleter(&a, 1);
|
||||||
|
a = New(LE32, 1);
|
||||||
|
assert(a != nullptr);
|
||||||
|
const auto m_deleter = upx::MallocDeleter(&m, 1);
|
||||||
|
m = (LE64 *) ::malloc(sizeof(LE64));
|
||||||
|
assert(m != nullptr);
|
||||||
|
}
|
||||||
|
assert(o == nullptr);
|
||||||
|
assert(a == nullptr);
|
||||||
|
assert(m == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ObjectDeleter 2") {
|
||||||
|
constexpr size_t N = 2;
|
||||||
|
BE16 *o[N]; // multiple objects
|
||||||
|
BE32 *a[N]; // multiple arrays
|
||||||
|
BE64 *m[N]; // multiple mallocs
|
||||||
|
{
|
||||||
|
auto o_deleter = upx::ObjectDeleter(o, 0);
|
||||||
|
auto a_deleter = upx::ArrayDeleter(a, 0);
|
||||||
|
auto m_deleter = upx::MallocDeleter(m, 0);
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
o[i] = new BE16;
|
||||||
|
assert(o[i] != nullptr);
|
||||||
|
o_deleter.count += 1;
|
||||||
|
a[i] = New(BE32, 1 + i);
|
||||||
|
assert(a[i] != nullptr);
|
||||||
|
a_deleter.count += 1;
|
||||||
|
m[i] = (BE64 *) ::malloc(sizeof(BE64));
|
||||||
|
assert(m[i] != nullptr);
|
||||||
|
m_deleter.count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
assert(o[i] == nullptr);
|
||||||
|
assert(a[i] == nullptr);
|
||||||
|
assert(m[i] == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::ptr_static_cast") {
|
||||||
|
// check that we do not trigger any -Wcast-align warnings
|
||||||
|
using upx::ptr_static_cast;
|
||||||
|
void *vp = nullptr;
|
||||||
|
byte *bp = nullptr;
|
||||||
|
int *ip = nullptr;
|
||||||
|
double *dp = nullptr;
|
||||||
|
|
||||||
|
assert((vp == ptr_static_cast<void *>(vp)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(bp)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(ip)));
|
||||||
|
assert((vp == ptr_static_cast<void *>(dp)));
|
||||||
|
|
||||||
|
assert((bp == ptr_static_cast<byte *>(vp)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(bp)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(ip)));
|
||||||
|
assert((bp == ptr_static_cast<byte *>(dp)));
|
||||||
|
|
||||||
|
assert((ip == ptr_static_cast<int *>(vp)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(bp)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(ip)));
|
||||||
|
assert((ip == ptr_static_cast<int *>(dp)));
|
||||||
|
|
||||||
|
assert((dp == ptr_static_cast<double *>(vp)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(bp)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(ip)));
|
||||||
|
assert((dp == ptr_static_cast<double *>(dp)));
|
||||||
|
|
||||||
|
const byte *bc = nullptr;
|
||||||
|
const int *ic = nullptr;
|
||||||
|
assert((bc == ptr_static_cast<byte *>(bp)));
|
||||||
|
assert((bc == ptr_static_cast<const byte *>(bc)));
|
||||||
|
assert((bc == ptr_static_cast<byte *>(ip)));
|
||||||
|
assert((bc == ptr_static_cast<const byte *>(ic)));
|
||||||
|
assert((ic == ptr_static_cast<int *>(bp)));
|
||||||
|
assert((ic == ptr_static_cast<const int *>(bc)));
|
||||||
|
assert((ic == ptr_static_cast<int *>(ip)));
|
||||||
|
assert((ic == ptr_static_cast<const int *>(ic)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("upx::noncopyable") {
|
||||||
|
struct Test : private upx::noncopyable {
|
||||||
|
int v = 1;
|
||||||
|
};
|
||||||
|
Test t = {};
|
||||||
|
CHECK(t.v == 1);
|
||||||
|
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
|
||||||
|
// @COMPILER_BUG @MSVC_BUG
|
||||||
|
t.v = 0;
|
||||||
|
#else
|
||||||
|
mem_clear(&t);
|
||||||
|
#endif
|
||||||
|
CHECK(t.v == 0);
|
||||||
|
constexpr Test x = {};
|
||||||
|
static_assert(x.v == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// TriBool checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class T>
|
||||||
|
struct TestTriBool {
|
||||||
|
static noinline void test(bool expect_true) {
|
||||||
|
static_assert(std::is_class<T>::value);
|
||||||
|
static_assert(std::is_nothrow_default_constructible<T>::value);
|
||||||
|
static_assert(std::is_nothrow_destructible<T>::value);
|
||||||
|
static_assert(std::is_standard_layout<T>::value);
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value);
|
||||||
|
static_assert(sizeof(typename T::value_type) == sizeof(typename T::underlying_type));
|
||||||
|
static_assert(alignof(typename T::value_type) == alignof(typename T::underlying_type));
|
||||||
|
#if defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||||
|
// broken compiler or broken ABI
|
||||||
|
#elif defined(__i386__) && defined(__GNUC__) && (__GNUC__ == 7) && !defined(__clang__)
|
||||||
|
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
|
||||||
|
// i386: "long long" enum align bug/ABI problem on older compilers
|
||||||
|
static_assert(alignof(T) <= alignof(typename T::underlying_type));
|
||||||
|
#else
|
||||||
|
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
|
||||||
|
static_assert(alignof(T) == alignof(typename T::underlying_type));
|
||||||
|
#endif
|
||||||
|
static_assert(!bool(T(false)));
|
||||||
|
static_assert(bool(T(true)));
|
||||||
|
static_assert(bool(T(T::Third)) == T::is_third_true);
|
||||||
|
static_assert(T(false) == T::False);
|
||||||
|
static_assert(T(true) == T::True);
|
||||||
|
static_assert(T(T::False) == T::False);
|
||||||
|
static_assert(T(T::True) == T::True);
|
||||||
|
static_assert(T(T::Third) == T::Third);
|
||||||
|
static_assert(T(T::Third) == T(9));
|
||||||
|
static_assert(T(8) == T(9));
|
||||||
|
static_assert(!(T(0) == T(9)));
|
||||||
|
static_assert(!(T(1) == T(9)));
|
||||||
|
static_assert(T(T::Third) == 9);
|
||||||
|
static_assert(T(8) == 9);
|
||||||
|
static_assert(!(T(0) == 9));
|
||||||
|
static_assert(!(T(1) == 9));
|
||||||
|
constexpr T array[] = {false, true, T::Third};
|
||||||
|
static_assert(array[0].isStrictFalse());
|
||||||
|
static_assert(array[1].isStrictTrue());
|
||||||
|
static_assert(array[2].isThird());
|
||||||
|
static_assert(sizeof(array) == 3 * sizeof(T));
|
||||||
|
T a;
|
||||||
|
assert(a.getValue() == T::False);
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = false;
|
||||||
|
assert(a.getValue() == T::False);
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = true;
|
||||||
|
assert(a.getValue() == T::True);
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(a.isStrictTrue());
|
||||||
|
assert(a.isStrictBool());
|
||||||
|
assert(!a.isThird());
|
||||||
|
a = T::Third;
|
||||||
|
assert(a.getValue() == T::Third);
|
||||||
|
assert(T::is_third_true == expect_true);
|
||||||
|
if (expect_true) {
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
} else {
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
}
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(!a.isStrictBool());
|
||||||
|
assert(a.isThird());
|
||||||
|
a = 99;
|
||||||
|
assert(a.getValue() == T::Third);
|
||||||
|
if (expect_true) {
|
||||||
|
assert(a);
|
||||||
|
assert(bool(a));
|
||||||
|
assert((a ? true : false));
|
||||||
|
assert((!a ? false : true));
|
||||||
|
} else {
|
||||||
|
assert(!a);
|
||||||
|
assert(!bool(a));
|
||||||
|
assert((a ? false : true));
|
||||||
|
assert((!a ? true : false));
|
||||||
|
}
|
||||||
|
assert(!a.isStrictFalse());
|
||||||
|
assert(!a.isStrictTrue());
|
||||||
|
assert(!a.isStrictBool());
|
||||||
|
assert(a.isThird());
|
||||||
|
mem_clear(&a);
|
||||||
|
assert(a.isStrictFalse());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("upx::TriBool") {
|
||||||
|
using upx::TriBool, upx::tribool;
|
||||||
|
static_assert(!tribool(false));
|
||||||
|
static_assert(tribool(true));
|
||||||
|
static_assert(!tribool(tribool::Third));
|
||||||
|
TestTriBool<tribool>::test(false);
|
||||||
|
#if DEBUG || 1
|
||||||
|
TestTriBool<TriBool<upx_int8_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint8_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int16_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint16_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int32_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint32_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int64_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_uint64_t> >::test(false);
|
||||||
|
TestTriBool<TriBool<upx_int8_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint8_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int16_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint16_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int32_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint32_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int64_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint64_t, true> >::test(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 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,24 +20,48 @@
|
|||||||
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 "../util/system_defs.h"
|
||||||
|
#include "../util/system_features.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// doctest support code implementation
|
// doctest support code implementation
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define DOCTEST_CONFIG_IMPLEMENT
|
#define DOCTEST_CONFIG_IMPLEMENT
|
||||||
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
|
||||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
|
||||||
#endif
|
|
||||||
#if defined(__MSDOS__) && defined(__DJGPP__)
|
|
||||||
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
|
||||||
#endif
|
|
||||||
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||||
|
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
#include <doctest/doctest/parts/doctest.cpp>
|
|
||||||
|
#if defined(__wasi__)
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#elif defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||||
|
#define DOCTEST_CONFIG_COLORS_NONE
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !(WITH_THREADS) && !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
||||||
|
#ifndef DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FAST_MATH__) && defined(__clang__) && (__clang_major__ + 0 >= 6)
|
||||||
|
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||||
|
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <doctest/doctest/parts/doctest.cpp>
|
||||||
|
|
||||||
|
#endif // DOCTEST_CONFIG_DISABLE
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 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,22 +20,19 @@
|
|||||||
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 "util/membuffer.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 != nullptr);
|
assert(buf != nullptr);
|
||||||
@@ -47,8 +43,7 @@ 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)
|
||||||
@@ -60,24 +55,20 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
|||||||
return upx_zlib_crc32(buf, len, crc);
|
return upx_zlib_crc32(buf, len, crc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* UNUSED */
|
#endif // UNUSED
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_compress( const upx_bytep src, unsigned src_len,
|
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
|
||||||
upx_callback_p cb,
|
upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
upx_compress_result_t cresult_buffer;
|
upx_compress_result_t cresult_buffer;
|
||||||
|
|
||||||
assert(method > 0); assert(level > 0);
|
assert(method > 0);
|
||||||
|
assert(level > 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// set available bytes in dst
|
// set available bytes in dst
|
||||||
@@ -87,68 +78,76 @@ int upx_compress( const upx_bytep src, unsigned src_len,
|
|||||||
// force users to provide *dst_len
|
// force users to provide *dst_len
|
||||||
assert(*dst_len != 0);
|
assert(*dst_len != 0);
|
||||||
#endif
|
#endif
|
||||||
// for UPX, we always require a reasonably sized outbut buffer
|
// for UPX, we always require a reasonably sized output buffer
|
||||||
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||||
|
|
||||||
if (!cresult)
|
if (!cresult)
|
||||||
cresult = &cresult_buffer;
|
cresult = &cresult_buffer;
|
||||||
memset(cresult, 0, sizeof(*cresult));
|
cresult->reset();
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->method = method;
|
cresult->debug.method = method;
|
||||||
cresult->level = level;
|
cresult->debug.level = level;
|
||||||
cresult->u_len = src_len;
|
cresult->debug.u_len = src_len;
|
||||||
cresult->c_len = 0;
|
cresult->debug.c_len = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if __acc_cte(0) {
|
const unsigned orig_dst_len = *dst_len;
|
||||||
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
||||||
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->c_len = *dst_len;
|
cresult->debug.c_len = *dst_len;
|
||||||
#endif
|
#endif
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_decompress(const upx_bytep src, unsigned src_len,
|
int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
assert(src_len < *dst_len); // must be compressed
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = nullptr;
|
cresult = nullptr;
|
||||||
|
|
||||||
if __acc_cte(0) {
|
const unsigned orig_dst_len = *dst_len;
|
||||||
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
@@ -164,38 +163,42 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
|
|||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
else if (M_IS_DEFLATE(method))
|
else if (M_IS_DEFLATE(method))
|
||||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_test_overlap( const upx_bytep buf,
|
int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len,
|
||||||
const upx_bytep tbuf,
|
unsigned *dst_len, int method, const upx_compress_result_t *cresult) {
|
||||||
unsigned src_off, unsigned src_len,
|
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = nullptr;
|
cresult = nullptr;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
assert(src_len < *dst_len); // must be compressed
|
assert(src_len < *dst_len); // must be compressed
|
||||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
assert((int)overlap_overhead > 0);
|
assert((int) overlap_overhead > 0);
|
||||||
|
|
||||||
if __acc_cte(0) {
|
const unsigned orig_dst_len = *dst_len;
|
||||||
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
@@ -207,11 +210,16 @@ int upx_test_overlap( const upx_bytep buf,
|
|||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,111 +20,146 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef __UPX_COMPRESS_H
|
// clang-format off
|
||||||
#define __UPX_COMPRESS_H 1
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
int upx_bzip2_init(void);
|
||||||
|
const char *upx_bzip2_version_string(void);
|
||||||
|
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_bzip2_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned *dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
int upx_lzma_init(void);
|
int upx_lzma_init(void);
|
||||||
const char *upx_lzma_version_string(void);
|
const char *upx_lzma_version_string(void);
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
int upx_nrv_init(void);
|
int upx_nrv_init(void);
|
||||||
const char *upx_nrv_version_string(void);
|
const char *upx_nrv_version_string(void);
|
||||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_nrv_test_overlap ( const upx_bytep buf,
|
int upx_nrv_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
int upx_ucl_init(void);
|
int upx_ucl_init(void);
|
||||||
const char *upx_ucl_version_string(void);
|
const char *upx_ucl_version_string(void);
|
||||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
|
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
|
||||||
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
|
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
int upx_zlib_init(void);
|
int upx_zlib_init(void);
|
||||||
const char *upx_zlib_version_string(void);
|
const char *upx_zlib_version_string(void);
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||||
const upx_bytep tbuf,
|
const upx_bytep tbuf,
|
||||||
unsigned src_off, unsigned src_len,
|
unsigned src_off, unsigned src_len,
|
||||||
unsigned* dst_len,
|
unsigned *dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
|
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
|
||||||
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (WITH_ZSTD)
|
||||||
#endif /* already included */
|
int upx_zstd_init(void);
|
||||||
|
const char *upx_zstd_version_string(void);
|
||||||
|
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned *dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/* compress_bzip2.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#if WITH_BZIP2
|
||||||
|
#include <bzip2/bzlib.h>
|
||||||
|
#endif
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
void bzip2_compress_config_t::reset() noexcept { mem_clear(this); }
|
||||||
|
|
||||||
|
#if WITH_BZIP2
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
#if defined(BZ_NO_STDIO) || 1
|
||||||
|
// we need to supply bz_internal_error() when building with BZ_NO_STDIO
|
||||||
|
extern "C" {
|
||||||
|
extern void bz_internal_error(int);
|
||||||
|
void bz_internal_error(int errcode) { throwInternalError("bz_internal_error %d", errcode); }
|
||||||
|
}
|
||||||
|
#endif // BZ_NO_STDIO
|
||||||
|
|
||||||
|
static int convert_errno_from_bzip2(int r) {
|
||||||
|
switch (r) {
|
||||||
|
case BZ_OK:
|
||||||
|
return UPX_E_OK;
|
||||||
|
case BZ_MEM_ERROR:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
// TODO later: convert to UPX_E_INPUT_OVERRUN, UPX_E_OUTPUT_OVERRUN
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
UNUSED(cb_parm);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
const bzip2_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_bzip2 : nullptr;
|
||||||
|
bzip2_compress_result_t *const res = &cresult->result_bzip2;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
|
int blockSize100k = (src_len + 100000 - 1) / 100000;
|
||||||
|
if (blockSize100k < 1)
|
||||||
|
blockSize100k = 1;
|
||||||
|
if (blockSize100k > 9)
|
||||||
|
blockSize100k = 9;
|
||||||
|
// idea for later: could enhance lcconf to allow setting blockSize100k
|
||||||
|
UNUSED(lcconf);
|
||||||
|
if (level <= 3 && blockSize100k > level)
|
||||||
|
blockSize100k = level;
|
||||||
|
|
||||||
|
char *dest = (char *) dst;
|
||||||
|
char *source = (char *) const_cast<byte *>(src);
|
||||||
|
r = BZ2_bzBuffToBuffCompress(dest, dst_len, source, src_len, blockSize100k, 0, 0);
|
||||||
|
return convert_errno_from_bzip2(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
UNUSED(method);
|
||||||
|
UNUSED(cresult);
|
||||||
|
char *dest = (char *) dst;
|
||||||
|
char *source = (char *) const_cast<byte *>(src);
|
||||||
|
int small = 0;
|
||||||
|
int r = BZ2_bzBuffToBuffDecompress(dest, dst_len, source, src_len, small, 0);
|
||||||
|
return convert_errno_from_bzip2(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
|
||||||
|
MemBuffer b(src_off + src_len);
|
||||||
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
|
unsigned saved_dst_len = *dst_len;
|
||||||
|
int r = upx_bzip2_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
|
return r;
|
||||||
|
if (*dst_len != saved_dst_len)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
|
// in-place buffer overlapping, so we use an extra memcmp().
|
||||||
|
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_init(void) { return 0; }
|
||||||
|
|
||||||
|
const char *upx_bzip2_version_string(void) { return BZ2_bzlibVersion(); }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
static bool check_bzip2(const int method, const int level, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_bzip2_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_bzip2_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_bzip2") { CHECK(check_bzip2(M_BZIP2, 9, 46)); }
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_bzip2_decompress") {
|
||||||
|
#if 0 // TODO later, see above
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[32];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||||
|
d_len = 32;
|
||||||
|
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 32));
|
||||||
|
r = upx_bzip2_decompress(c_data, 15, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 31;
|
||||||
|
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
#endif // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_BZIP2
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 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,34 +20,25 @@
|
|||||||
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 "util/membuffer.h"
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
#if (ACC_CC_CLANG)
|
#if (ACC_CC_CLANG)
|
||||||
# pragma clang diagnostic ignored "-Wshadow"
|
#pragma clang diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_GNUC >= 0x040200)
|
#if (ACC_CC_GNUC >= 0x040200)
|
||||||
# pragma GCC diagnostic ignored "-Wshadow"
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_MSC)
|
#if (ACC_CC_MSC)
|
||||||
# pragma warning(disable: 4456) // -Wno-shadow
|
#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
|
#endif
|
||||||
|
|
||||||
|
void lzma_compress_config_t::reset() noexcept {
|
||||||
void lzma_compress_config_t::reset()
|
|
||||||
{
|
|
||||||
pos_bits.reset();
|
pos_bits.reset();
|
||||||
lit_pos_bits.reset();
|
lit_pos_bits.reset();
|
||||||
lit_context_bits.reset();
|
lit_context_bits.reset();
|
||||||
@@ -60,7 +50,6 @@ void lzma_compress_config_t::reset()
|
|||||||
max_num_probs = 0;
|
max_num_probs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// INFO: the LZMA SDK is covered by a permissive license which allows
|
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||||
// using unmodified LZMA source code in UPX and the UPX stubs.
|
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||||
// See SPECIAL EXCEPTION below.
|
// See SPECIAL EXCEPTION below.
|
||||||
@@ -97,37 +86,34 @@ void lzma_compress_config_t::reset()
|
|||||||
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||||
// while you keep LZMA SDK code unmodified.
|
// while you keep LZMA SDK code unmodified.
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress defaults
|
// compress defaults
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int prepare(lzma_compress_result_t *res,
|
static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int method, int level,
|
||||||
unsigned src_len, int method, int level,
|
const lzma_compress_config_t *lcconf) {
|
||||||
const lzma_compress_config_t *lcconf)
|
|
||||||
{
|
|
||||||
// setup defaults
|
// setup defaults
|
||||||
res->pos_bits = 2; // 0 .. 4
|
res->pos_bits = 2; // 0 .. 4
|
||||||
res->lit_pos_bits = 0; // 0 .. 4
|
res->lit_pos_bits = 0; // 0 .. 4
|
||||||
res->lit_context_bits = 3; // 0 .. 8
|
res->lit_context_bits = 3; // 0 .. 8
|
||||||
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
||||||
res->fast_mode = 2;
|
res->fast_mode = 2; // 0 .. 2
|
||||||
res->num_fast_bytes = 64; // 5 .. 273
|
res->num_fast_bytes = 64; // 5 .. 273
|
||||||
res->match_finder_cycles = 0;
|
res->match_finder_cycles = 0;
|
||||||
// UPX overrides
|
// UPX overrides
|
||||||
res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value;
|
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_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->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->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;
|
res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value;
|
||||||
// method overrides
|
// method overrides
|
||||||
if (method >= 0x100) {
|
if (method >= 0x100) {
|
||||||
res->pos_bits = (method >> 16) & 15;
|
res->pos_bits = (method >> 16) & 15;
|
||||||
res->lit_pos_bits = (method >> 12) & 15;
|
res->lit_pos_bits = (method >> 12) & 15;
|
||||||
res->lit_context_bits = (method >> 8) & 15;
|
res->lit_context_bits = (method >> 8) & 15;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
// DEBUG - set sizes so that we use a maximum amount of stack.
|
||||||
// These settings cause res->num_probs == 3147574, i.e. we will
|
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||||
// need about 6 MiB of stack during runtime decompression.
|
// need about 6 MiB of stack during runtime decompression.
|
||||||
res->lit_pos_bits = 4;
|
res->lit_pos_bits = 4;
|
||||||
@@ -135,16 +121,15 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: tune these settings according to level
|
// TODO: tune these settings according to level
|
||||||
switch (level)
|
switch (level) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
res->dict_size = 256 * 1024;
|
res->dict_size = 256 * 1024;
|
||||||
res->fast_mode = 0;
|
res->fast_mode = 0;
|
||||||
res->num_fast_bytes = 8;
|
res->num_fast_bytes = 8;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
res->dict_size = 256 * 1024;
|
res->dict_size = 256 * 1024;
|
||||||
res->fast_mode = 0;
|
res->fast_mode = 0;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
break;
|
break;
|
||||||
@@ -159,18 +144,17 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
res->dict_size = 8 * 1024 * 1024;
|
res->dict_size = 8 * 1024 * 1024;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
res->dict_size = src_len;
|
res->dict_size = src_len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(res->pos_bits, lcconf->pos_bits);
|
oassign(res->pos_bits, lcconf->pos_bits);
|
||||||
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||||
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||||
@@ -183,21 +167,16 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
res->dict_size = src_len;
|
res->dict_size = src_len;
|
||||||
|
|
||||||
// limit num_probs
|
// limit num_probs
|
||||||
if (lcconf && lcconf->max_num_probs)
|
if (lcconf && lcconf->max_num_probs) {
|
||||||
{
|
for (;;) {
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
if (n <= lcconf->max_num_probs)
|
if (n <= lcconf->max_num_probs)
|
||||||
break;
|
break;
|
||||||
if (res->lit_pos_bits > res->lit_context_bits)
|
if (res->lit_pos_bits > res->lit_context_bits) {
|
||||||
{
|
|
||||||
if (res->lit_pos_bits == 0)
|
if (res->lit_pos_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_pos_bits -= 1;
|
res->lit_pos_bits -= 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (res->lit_context_bits == 0)
|
if (res->lit_context_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_context_bits -= 1;
|
res->lit_context_bits -= 1;
|
||||||
@@ -212,152 +191,171 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
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));
|
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);
|
NO_printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
return 0;
|
res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress - cruft because of pseudo-COM layer
|
// compress - cruft because of pseudo-COM layer
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (ACC_CC_CLANG >= 0x080000)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
|
#elif (ACC_CC_GNUC >= 0x040700)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef MSDOS
|
#undef MSDOS
|
||||||
#undef OS2
|
#undef OS2
|
||||||
#undef _WIN32
|
#undef _WIN32
|
||||||
#undef _WIN32_WCE
|
#undef _WIN32_WCE
|
||||||
#undef COMPRESS_MF_MT
|
#undef COMPRESS_MF_MT
|
||||||
#undef _NO_EXCEPTIONS
|
#undef _NO_EXCEPTIONS
|
||||||
#undef NULL
|
|
||||||
#define NULL nullptr
|
|
||||||
#include <lzma-sdk/C/Common/MyInitGuid.h>
|
#include <lzma-sdk/C/Common/MyInitGuid.h>
|
||||||
//#include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.h>
|
// #include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.h>
|
||||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.h>
|
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.h>
|
||||||
|
|
||||||
namespace MyLzma {
|
namespace MyLzma {
|
||||||
|
|
||||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
struct InStream final : public ISequentialInStream, public CMyUnknownImp {
|
||||||
{
|
virtual ~InStream() {}
|
||||||
virtual ~InStream() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
const Byte *b_buf = nullptr;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
void Init(const Byte *data, size_t size) {
|
void Init(const Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
}
|
}
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) {
|
||||||
{
|
|
||||||
size_t remain = b_size - b_pos;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain;
|
||||||
memmove(data, b_buf + b_pos, size);
|
memmove(data, b_buf + b_pos, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
struct OutStream final : public ISequentialOutStream, public CMyUnknownImp {
|
||||||
{
|
virtual ~OutStream() {}
|
||||||
virtual ~OutStream() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
Byte *b_buf = nullptr;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
|
bool overflow;
|
||||||
void Init(Byte *data, size_t size) {
|
void Init(Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
|
overflow = false;
|
||||||
}
|
}
|
||||||
HRESULT WriteByte(Byte c) {
|
HRESULT WriteByte(Byte c) {
|
||||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
if (b_pos >= b_size) {
|
||||||
|
overflow = true;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
b_buf[b_pos++] = c;
|
b_buf[b_pos++] = c;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP OutStream::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;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain, overflow = true;
|
||||||
memmove(b_buf + b_pos, data, size);
|
memmove(b_buf + b_pos, data, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return overflow ? E_FAIL : S_OK;
|
return overflow ? E_FAIL : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
|
||||||
{
|
virtual ~ProgressInfo() {}
|
||||||
virtual ~ProgressInfo() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
||||||
upx_callback_p cb;
|
upx_callback_t *cb = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
||||||
{
|
|
||||||
if (cb && cb->nprogress)
|
if (cb && cb->nprogress)
|
||||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace MyLzma
|
||||||
|
|
||||||
#include <lzma-sdk/C/Common/Alloc.cpp>
|
#include <lzma-sdk/C/Common/Alloc.cpp>
|
||||||
#include <lzma-sdk/C/Common/CRC.cpp>
|
#include <lzma-sdk/C/Common/CRC.cpp>
|
||||||
//#include <lzma-sdk/C/7zip/Common/InBuffer.cpp>
|
// #include <lzma-sdk/C/7zip/Common/InBuffer.cpp>
|
||||||
#include <lzma-sdk/C/7zip/Common/OutBuffer.cpp>
|
#include <lzma-sdk/C/7zip/Common/OutBuffer.cpp>
|
||||||
#include <lzma-sdk/C/7zip/Common/StreamUtils.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/LZInWindow.cpp>
|
||||||
//#include <lzma-sdk/C/7zip/Compress/LZ/LZOutWindow.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/LZMADecoder.cpp>
|
||||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.cpp>
|
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.cpp>
|
||||||
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
||||||
#undef RC_NORMALIZE
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
#if (ACC_CC_CLANG >= 0x080000)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#elif (ACC_CC_GNUC >= 0x040700)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_t *cb, int method, int level,
|
||||||
upx_callback_p cb,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
HRESULT rh;
|
HRESULT rh;
|
||||||
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
||||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
lzma_compress_result_t *const res = &cresult->result_lzma;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
MyLzma::InStream is; is.AddRef();
|
MyLzma::InStream is;
|
||||||
MyLzma::OutStream os; os.AddRef();
|
is.AddRef();
|
||||||
is.Init(src, src_len);
|
is.Init(src, src_len);
|
||||||
|
MyLzma::OutStream os;
|
||||||
|
os.AddRef();
|
||||||
os.Init(dst, *dst_len);
|
os.Init(dst, *dst_len);
|
||||||
|
MyLzma::ProgressInfo progress;
|
||||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
progress.AddRef();
|
||||||
progress.cb = cb;
|
progress.cb = cb; // progress.Init()
|
||||||
|
|
||||||
NCompress::NLZMA::CEncoder enc;
|
NCompress::NLZMA::CEncoder enc;
|
||||||
const PROPID propIDs[8] = {
|
constexpr unsigned NPROPS = 8;
|
||||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
static const PROPID propIDs[NPROPS] = {
|
||||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||||
NCoderPropID::kDictionarySize, // 3 ds
|
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||||
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
NCoderPropID::kDictionarySize, // 3 ds
|
||||||
NCoderPropID::kNumFastBytes, // 5 fb
|
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
||||||
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
NCoderPropID::kNumFastBytes, // 5 fb
|
||||||
NCoderPropID::kMatchFinder // 7 mf
|
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
||||||
|
NCoderPropID::kMatchFinder // 7 mf
|
||||||
};
|
};
|
||||||
PROPVARIANT pr[8];
|
PROPVARIANT pr[NPROPS];
|
||||||
const unsigned nprops = 8;
|
if (!prepare_result(res, src_len, method, level, lcconf))
|
||||||
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;
|
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[0].uintVal = res->pos_bits;
|
||||||
pr[1].uintVal = res->lit_pos_bits;
|
pr[1].uintVal = res->lit_pos_bits;
|
||||||
pr[2].uintVal = res->lit_context_bits;
|
pr[2].uintVal = res->lit_context_bits;
|
||||||
@@ -365,55 +363,59 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
pr[4].uintVal = res->fast_mode;
|
pr[4].uintVal = res->fast_mode;
|
||||||
pr[5].uintVal = res->num_fast_bytes;
|
pr[5].uintVal = res->num_fast_bytes;
|
||||||
pr[6].uintVal = res->match_finder_cycles;
|
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 {
|
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);
|
||||||
|
|
||||||
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
// reset and encode properties in UPX-style (2 bytes)
|
||||||
goto error;
|
os.b_pos = 0;
|
||||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
goto error;
|
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||||
if (os.overflow) {
|
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
||||||
//r = UPX_E_OUTPUT_OVERRUN;
|
os.WriteByte(Byte((res->lit_pos_bits << 4) | res->lit_context_bits));
|
||||||
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, nullptr, nullptr, &progress);
|
// compress
|
||||||
|
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
rh = E_OUTOFMEMORY;
|
rh = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(is.b_pos <= src_len);
|
assert(is.b_pos <= src_len);
|
||||||
assert(os.b_pos <= *dst_len);
|
assert(os.b_pos <= *dst_len);
|
||||||
if (rh == E_OUTOFMEMORY)
|
if (rh == E_OUTOFMEMORY)
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
else if (os.overflow)
|
else if (os.overflow) {
|
||||||
{
|
|
||||||
assert(os.b_pos == *dst_len);
|
assert(os.b_pos == *dst_len);
|
||||||
//r = UPX_E_OUTPUT_OVERRUN;
|
// r = UPX_E_OUTPUT_OVERRUN;
|
||||||
r = UPX_E_NOT_COMPRESSIBLE;
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
}
|
} else if (rh == S_OK) {
|
||||||
else if (rh == S_OK)
|
|
||||||
{
|
|
||||||
assert(is.b_pos == src_len);
|
assert(is.b_pos == src_len);
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dst_len = (unsigned) os.b_pos;
|
*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);
|
NO_printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
|
||||||
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len,
|
||||||
|
*dst_len);
|
||||||
|
NO_printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// decompress
|
// decompress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -425,60 +427,67 @@ error:
|
|||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
||||||
|
|
||||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
// see res->num_probs above
|
// see res->num_probs above
|
||||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
CLzmaDecoderState s;
|
||||||
|
mem_clear(&s);
|
||||||
SizeT src_out = 0, dst_out = 0;
|
SizeT src_out = 0, dst_out = 0;
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int rh;
|
int rh;
|
||||||
|
|
||||||
if (src_len < 3)
|
// decode UPX-style properties (2 bytes)
|
||||||
|
if (src_len < 3) {
|
||||||
|
r = UPX_E_INPUT_OVERRUN;
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
s.Properties.pb = src[0] & 7;
|
s.Properties.pb = src[0] & 7;
|
||||||
s.Properties.lp = (src[1] >> 4);
|
s.Properties.lp = (src[1] >> 4);
|
||||||
s.Properties.lc = src[1] & 15;
|
s.Properties.lc = src[1] & 15;
|
||||||
if (s.Properties.pb >= 5) goto error;
|
if (s.Properties.pb >= 5)
|
||||||
if (s.Properties.lp >= 5) goto error;
|
goto error;
|
||||||
if (s.Properties.lc >= 9) goto error;
|
if (s.Properties.lp >= 5)
|
||||||
// extra
|
goto error;
|
||||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
if (s.Properties.lc >= 9)
|
||||||
src += 2; src_len -= 2;
|
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)
|
if (cresult) {
|
||||||
{
|
assert(cresult->debug.method == method);
|
||||||
assert(cresult->method == method);
|
|
||||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
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_pos_bits == (unsigned) s.Properties.lp);
|
||||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
NO_printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
|
res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
UNUSED(res);
|
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));
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
if (!s.Probs)
|
if (!s.Probs) {
|
||||||
{
|
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||||
assert(src_out <= src_len);
|
assert(src_out <= src_len);
|
||||||
assert(dst_out <= *dst_len);
|
assert(dst_out <= *dst_len);
|
||||||
if (rh == 0)
|
if (rh == 0) {
|
||||||
{
|
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
if (src_out != src_len)
|
if (src_out != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
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:
|
error:
|
||||||
*dst_len = dst_out;
|
*dst_len = dst_out;
|
||||||
@@ -486,24 +495,20 @@ error:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
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)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -516,25 +521,34 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_init(void)
|
int upx_lzma_init(void) { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *upx_lzma_version_string(void)
|
const char *upx_lzma_version_string(void) { return "4.43"; }
|
||||||
{
|
|
||||||
#if (WITH_LZMA == 0x443)
|
|
||||||
return "4.43";
|
|
||||||
#else
|
|
||||||
# error "unknown WITH_LZMA version"
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("upx_lzma_decompress") {
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_lzma_decompress(c_data, 8, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,369 @@
|
|||||||
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int convert_errno_from_ucl(int r) {
|
||||||
|
switch (r) {
|
||||||
|
case UCL_E_OK:
|
||||||
|
return UPX_E_OK;
|
||||||
|
case UCL_E_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case UCL_E_OUT_OF_MEMORY:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case UCL_E_NOT_COMPRESSIBLE:
|
||||||
|
return UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
case UCL_E_INPUT_OVERRUN:
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
|
case UCL_E_OUTPUT_OVERRUN:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case UCL_E_LOOKBEHIND_OVERRUN:
|
||||||
|
return UPX_E_LOOKBEHIND_OVERRUN;
|
||||||
|
case UCL_E_EOF_NOT_FOUND:
|
||||||
|
return UPX_E_EOF_NOT_FOUND;
|
||||||
|
case UCL_E_INPUT_NOT_CONSUMED:
|
||||||
|
return UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
case UCL_E_INVALID_ARGUMENT:
|
||||||
|
return UPX_E_INVALID_ARGUMENT;
|
||||||
|
// UCL extra:
|
||||||
|
case UCL_E_OVERLAP_OVERRUN:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
||||||
|
if (state != -1 && state != 3)
|
||||||
|
return;
|
||||||
|
upx_callback_t *cb = (upx_callback_t *) user;
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||||
|
|
||||||
|
ucl_progress_callback_t cb;
|
||||||
|
cb.callback = nullptr;
|
||||||
|
cb.user = nullptr;
|
||||||
|
if (cb_parm && cb_parm->nprogress) {
|
||||||
|
cb.callback = wrap_nprogress_ucl;
|
||||||
|
cb.user = cb_parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
|
if (cconf_parm) {
|
||||||
|
// cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf));
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_uint *const res = cresult->result_ucl.result;
|
||||||
|
// assume no info available - fill in worst case results
|
||||||
|
// res[0] = 1; // min_offset_found - NOT USED
|
||||||
|
res[1] = src_len - 1; // max_offset_found
|
||||||
|
// res[2] = 2; // min_match_found - NOT USED
|
||||||
|
res[3] = src_len - 1; // max_match_found
|
||||||
|
// res[4] = 1; // min_run_found - NOT USED
|
||||||
|
res[5] = src_len; // max_run_found
|
||||||
|
res[6] = 1; // first_offset_found
|
||||||
|
// res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
|
// prepare bit-buffer settings
|
||||||
|
cconf.bb_endian = 0;
|
||||||
|
cconf.bb_size = 0;
|
||||||
|
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
|
||||||
|
static const upx_uint8_t sizes[3] = {32, 8, 16};
|
||||||
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
|
} else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimize compression params
|
||||||
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
|
cconf.max_offset = 8 * 1024 - 1;
|
||||||
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
|
cconf.max_offset = 32 * 1024 - 1;
|
||||||
|
|
||||||
|
if M_IS_NRV2B (method)
|
||||||
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else if M_IS_NRV2D (method)
|
||||||
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else if M_IS_NRV2E (method)
|
||||||
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure first_offset_found is set
|
||||||
|
if (res[6] == 0)
|
||||||
|
res[6] = 1;
|
||||||
|
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case M_NRV2B_8:
|
||||||
|
r = ucl_nrv2b_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE16:
|
||||||
|
r = ucl_nrv2b_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE32:
|
||||||
|
r = ucl_nrv2b_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_8:
|
||||||
|
r = ucl_nrv2d_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE16:
|
||||||
|
r = ucl_nrv2d_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE32:
|
||||||
|
r = ucl_nrv2d_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_8:
|
||||||
|
r = ucl_nrv2e_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE16:
|
||||||
|
r = ucl_nrv2e_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE32:
|
||||||
|
r = ucl_nrv2e_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
UNUSED(tbuf); // not needed for UCL
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case M_NRV2B_8:
|
||||||
|
r = ucl_nrv2b_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE16:
|
||||||
|
r = ucl_nrv2b_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE32:
|
||||||
|
r = ucl_nrv2b_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_8:
|
||||||
|
r = ucl_nrv2d_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE16:
|
||||||
|
r = ucl_nrv2d_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE32:
|
||||||
|
r = ucl_nrv2d_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_8:
|
||||||
|
r = ucl_nrv2e_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE16:
|
||||||
|
r = ucl_nrv2e_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE32:
|
||||||
|
r = ucl_nrv2e_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return upx_calloc(n, 1); }
|
||||||
|
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
int upx_ucl_init(void) {
|
||||||
|
if (ucl_init() != UCL_E_OK)
|
||||||
|
return -1;
|
||||||
|
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
||||||
|
return -2;
|
||||||
|
ucl_set_malloc_hooks(my_malloc, my_free);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *upx_ucl_version_string(void) { return ucl_version_string(); }
|
||||||
|
|
||||||
|
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
|
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
|
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
const int level = 3; // don't waste time
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_ucl") {
|
||||||
|
CHECK(check_ucl(M_NRV2B_8, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE16, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2D_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2E_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE32, 34));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_ucl_decompress") {
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 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,58 +20,72 @@
|
|||||||
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 "util/membuffer.h"
|
#include "../util/membuffer.h"
|
||||||
|
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
|
||||||
|
#define ZLIB_CONST 1
|
||||||
#include <zlib/zlib.h>
|
#include <zlib/zlib.h>
|
||||||
#include <zlib/deflate.h>
|
#include <zlib/deflate.h>
|
||||||
|
// NOLINTEND(clang-analyzer-optin.performance.Padding)
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset() noexcept {
|
||||||
void zlib_compress_config_t::reset()
|
mem_clear(this);
|
||||||
{
|
|
||||||
mem_clear(this, sizeof(*this));
|
|
||||||
|
|
||||||
mem_level.reset();
|
mem_level.reset();
|
||||||
window_bits.reset();
|
window_bits.reset();
|
||||||
strategy.reset();
|
strategy.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int convert_errno_from_zlib(int zr) {
|
||||||
static int convert_errno_from_zlib(int zr)
|
switch (zr) {
|
||||||
{
|
case Z_OK:
|
||||||
switch (zr)
|
return UPX_E_OK;
|
||||||
{
|
// positive values
|
||||||
case Z_OK: return UPX_E_OK;
|
case Z_STREAM_END:
|
||||||
case Z_DATA_ERROR: return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
case Z_NEED_DICT: return UPX_E_ERROR;
|
case Z_NEED_DICT:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// negative values
|
||||||
|
case Z_ERRNO:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case Z_BUF_ERROR:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case -7: // UPX extra
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
upx_callback_p cb_parm,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
UNUSED(cb_parm);
|
UNUSED(cb_parm);
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int zr;
|
int zr;
|
||||||
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
||||||
zlib_compress_result_t *res = &cresult->result_zlib;
|
zlib_compress_result_t *const res = &cresult->result_zlib;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
if (level == 10)
|
if (level == 10)
|
||||||
level = 9;
|
level = 9;
|
||||||
@@ -81,26 +94,22 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
zlib_compress_config_t::window_bits_t window_bits;
|
zlib_compress_config_t::window_bits_t window_bits;
|
||||||
zlib_compress_config_t::strategy_t strategy;
|
zlib_compress_config_t::strategy_t strategy;
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(mem_level, lcconf->mem_level);
|
oassign(mem_level, lcconf->mem_level);
|
||||||
oassign(window_bits, lcconf->window_bits);
|
oassign(window_bits, lcconf->window_bits);
|
||||||
oassign(strategy, lcconf->strategy);
|
oassign(strategy, lcconf->strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
res->dummy = 0;
|
|
||||||
|
|
||||||
z_stream s;
|
z_stream s;
|
||||||
s.zalloc = (alloc_func) nullptr;
|
s.zalloc = (alloc_func) nullptr;
|
||||||
s.zfree = (free_func) nullptr;
|
s.zfree = (free_func) nullptr;
|
||||||
s.next_in = ACC_UNCONST_CAST(upx_bytep, src);
|
s.next_in = src;
|
||||||
s.avail_in = src_len;
|
s.avail_in = src_len;
|
||||||
s.next_out = dst;
|
s.next_out = dst;
|
||||||
s.avail_out = *dst_len;
|
s.avail_out = *dst_len;
|
||||||
s.total_in = s.total_out = 0;
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
zr = (int)deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
zr = (int) deflateInit2(&s, level, Z_DEFLATED, 0 - (int) window_bits, mem_level, strategy);
|
||||||
mem_level, strategy);
|
|
||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
assert(s.state->level == level);
|
assert(s.state->level == level);
|
||||||
@@ -118,27 +127,22 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
assert(s.total_in <= src_len);
|
assert(s.total_in <= src_len);
|
||||||
assert(s.total_out <= *dst_len);
|
assert(s.total_out <= *dst_len);
|
||||||
*dst_len = s.total_out;
|
*dst_len = s.total_out;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
UNUSED(method);
|
UNUSED(method);
|
||||||
UNUSED(cresult);
|
UNUSED(cresult);
|
||||||
@@ -148,7 +152,7 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
z_stream s;
|
z_stream s;
|
||||||
s.zalloc = (alloc_func) nullptr;
|
s.zalloc = (alloc_func) nullptr;
|
||||||
s.zfree = (free_func) nullptr;
|
s.zfree = (free_func) nullptr;
|
||||||
s.next_in = ACC_UNCONST_CAST(upx_bytep, src);
|
s.next_in = src;
|
||||||
s.avail_in = src_len;
|
s.avail_in = src_len;
|
||||||
s.next_out = dst;
|
s.next_out = dst;
|
||||||
s.avail_out = *dst_len;
|
s.avail_out = *dst_len;
|
||||||
@@ -158,8 +162,11 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
zr = inflate(&s, Z_FINISH);
|
zr = inflate(&s, Z_FINISH);
|
||||||
if (zr != Z_STREAM_END)
|
if (zr != Z_STREAM_END) {
|
||||||
|
if (zr == Z_BUF_ERROR && s.avail_in == 0)
|
||||||
|
zr = -7; // UPX extra
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
zr = inflateEnd(&s);
|
zr = inflateEnd(&s);
|
||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -171,35 +178,30 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
}
|
}
|
||||||
assert(s.total_in <= src_len);
|
assert(s.total_in <= src_len);
|
||||||
assert(s.total_out <= *dst_len);
|
assert(s.total_out <= *dst_len);
|
||||||
*dst_len = s.total_out;
|
*dst_len = s.total_out;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
int upx_zlib_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
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)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -212,44 +214,35 @@ int upx_zlib_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_init(void)
|
int upx_zlib_init(void) {
|
||||||
{
|
|
||||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *upx_zlib_version_string(void)
|
const char *upx_zlib_version_string(void) { return zlibVersion(); }
|
||||||
{
|
|
||||||
return zlibVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 // UNUSED
|
||||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
return adler32(adler, (const Bytef *) buf, len);
|
return adler32(adler, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 // UNUSED
|
||||||
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
{
|
|
||||||
return crc32(crc, (const Bytef *) buf, len);
|
return crc32(crc, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Debug checks
|
// doctest checks
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if DEBUG && 1
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
#include "util/membuffer.h"
|
|
||||||
|
|
||||||
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
||||||
const unsigned u_len = 16384;
|
const unsigned u_len = 16384;
|
||||||
@@ -265,21 +258,26 @@ static bool check_zlib(const int method, const int level, const unsigned expecte
|
|||||||
d_buf.allocForDecompression(u_len);
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
c_len = c_buf.getSize() - c_extra;
|
c_len = c_buf.getSize() - c_extra;
|
||||||
r = upx_zlib_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
if (r != 0 || c_len != expected_c_len) return false;
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = d_buf.getSize();
|
d_len = d_buf.getSize();
|
||||||
r = upx_zlib_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r != 0 || d_len != u_len) return false;
|
&d_len, method, nullptr);
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = u_len - 1;
|
d_len = u_len - 1;
|
||||||
r = upx_zlib_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r == 0) return false;
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
//unsigned x_len = d_len;
|
// unsigned x_len = d_len;
|
||||||
//r = upx_zlib_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
// r = upx_zlib_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,5 +289,22 @@ TEST_CASE("compress_zlib") {
|
|||||||
|
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_zlib_decompress") {
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\xfb\xff\x1f\x15\x00\x00";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_zlib_decompress(c_data, 5, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
/* compress_zstd.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#if WITH_ZSTD
|
||||||
|
#include <zstd/lib/zstd.h>
|
||||||
|
#include <zstd/lib/zstd_errors.h>
|
||||||
|
#include <zstd/lib/compress/hist.h>
|
||||||
|
#endif
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
void zstd_compress_config_t::reset() noexcept { mem_clear(this); }
|
||||||
|
|
||||||
|
#if WITH_ZSTD
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
static int convert_errno_from_zstd(size_t zr) {
|
||||||
|
const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr);
|
||||||
|
switch (ze) {
|
||||||
|
case ZSTD_error_memory_allocation:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case ZSTD_error_srcSize_wrong:
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
|
case ZSTD_error_dstSize_tooSmall:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// TODO later: use advanced compression API for compression finetuning
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
UNUSED(cb_parm);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
size_t zr;
|
||||||
|
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
|
||||||
|
zstd_compress_result_t *const res = &cresult->result_zstd;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
|
// TODO later: map level 1..10 to zstd-level 1..22
|
||||||
|
if (level == 10)
|
||||||
|
level = 22;
|
||||||
|
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf) {
|
||||||
|
UNUSED(lcconf);
|
||||||
|
}
|
||||||
|
|
||||||
|
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
|
||||||
|
if (ZSTD_isError(zr)) {
|
||||||
|
*dst_len = 0; // TODO ???
|
||||||
|
r = convert_errno_from_zstd(zr);
|
||||||
|
assert(r != UPX_E_OK);
|
||||||
|
} else {
|
||||||
|
assert(zr <= *dst_len);
|
||||||
|
*dst_len = (unsigned) zr;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
UNUSED(method);
|
||||||
|
UNUSED(cresult);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
size_t zr;
|
||||||
|
|
||||||
|
zr = ZSTD_decompress(dst, *dst_len, src, src_len);
|
||||||
|
if (ZSTD_isError(zr)) {
|
||||||
|
*dst_len = 0; // TODO ???
|
||||||
|
r = convert_errno_from_zstd(zr);
|
||||||
|
assert(r != UPX_E_OK);
|
||||||
|
} else {
|
||||||
|
assert(zr <= *dst_len);
|
||||||
|
*dst_len = (unsigned) zr;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
|
||||||
|
MemBuffer b(src_off + src_len);
|
||||||
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
|
unsigned saved_dst_len = *dst_len;
|
||||||
|
int r = upx_zstd_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
|
return r;
|
||||||
|
if (*dst_len != saved_dst_len)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
|
// in-place buffer overlapping, so we use an extra memcmp().
|
||||||
|
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_init(void) {
|
||||||
|
if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString()) != 0)
|
||||||
|
return -2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *upx_zstd_version_string(void) { return ZSTD_VERSION_STRING; }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
static bool check_zstd(const int method, const int level, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_zstd_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_zstd_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_zstd") {
|
||||||
|
CHECK(check_zstd(M_ZSTD, 1, 19));
|
||||||
|
CHECK(check_zstd(M_ZSTD, 3, 19));
|
||||||
|
CHECK(check_zstd(M_ZSTD, 5, 19));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_zstd_decompress") {
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[32];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||||
|
d_len = 32;
|
||||||
|
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 32));
|
||||||
|
r = upx_zstd_decompress(c_data, 15, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 31;
|
||||||
|
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_ZSTD
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -1,344 +0,0 @@
|
|||||||
/* compress_ucl.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2022 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"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
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 != 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)
|
|
||||||
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,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
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// Debug checks
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#if DEBUG && 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(u_buf, u_len, c_buf + c_extra, &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(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
|
||||||
if (r != 0 || d_len != u_len) return false;
|
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
|
||||||
|
|
||||||
d_len = u_len - 1;
|
|
||||||
r = upx_ucl_decompress(c_buf + c_extra, c_len, d_buf, &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
|
|
||||||
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
+579
-543
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,58 +33,41 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_FILE;
|
return CON_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
#if 1
|
#if 1
|
||||||
fputs(s,f);
|
fputs(s, f);
|
||||||
#else
|
#else
|
||||||
/* filter out all ANSI sequences */
|
/* filter out all ANSI sequences */
|
||||||
int c;
|
int c;
|
||||||
while ((c = *s++) != 0)
|
while ((c = *s++) != 0) {
|
||||||
{
|
if (c == '\033' && *s == ']') {
|
||||||
if (c == '\033' && *s == ']')
|
|
||||||
{
|
|
||||||
while (*s && *s != 'm')
|
while (*s && *s != 'm')
|
||||||
s++;
|
s++;
|
||||||
}
|
} else
|
||||||
else
|
fputc(c, f);
|
||||||
fputc(c,f);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_file = {init, set_fg, print0, intro};
|
||||||
console_t console_file =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
FILE *con_term = nullptr;
|
FILE *con_term = nullptr;
|
||||||
|
|
||||||
@@ -36,19 +35,17 @@ FILE *con_term = nullptr;
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static console_t * const me = &console_init;
|
static console_t *const me = &console_init;
|
||||||
console_t * con = &console_init;
|
console_t *con = &console_init;
|
||||||
|
|
||||||
int con_mode = CON_INIT;
|
int con_mode = CON_INIT;
|
||||||
|
|
||||||
|
static void try_init(console_t *c, FILE *f) {
|
||||||
static void try_init(console_t *c, FILE *f)
|
|
||||||
{
|
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
assert(c->init);
|
assert(c->init);
|
||||||
k = c->init(f,opt->console,con_mode);
|
k = c->init(f, opt->console, con_mode);
|
||||||
if (k == CON_INIT)
|
if (k == CON_INIT)
|
||||||
return;
|
return;
|
||||||
#if 0
|
#if 0
|
||||||
@@ -56,8 +53,7 @@ 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 = nullptr;
|
con->init = nullptr;
|
||||||
@@ -70,41 +66,37 @@ static void try_init(console_t *c, FILE *f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_init(FILE *f) {
|
||||||
static int do_init(FILE *f)
|
|
||||||
{
|
|
||||||
assert(con_mode == CON_INIT);
|
assert(con_mode == CON_INIT);
|
||||||
|
|
||||||
try_init(&console_none,f);
|
try_init(&console_none, f);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
assert(con == &console_none);
|
assert(con == &console_none);
|
||||||
if (opt->console == CON_NONE || opt->to_stdout)
|
if (opt->console == CON_NONE || opt->to_stdout)
|
||||||
return con_mode;
|
return con_mode;
|
||||||
try_init(&console_file,f);
|
try_init(&console_file, f);
|
||||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||||
return con_mode;
|
return con_mode;
|
||||||
|
|
||||||
#if (USE_ANSI)
|
#if (USE_ANSI)
|
||||||
try_init(&console_ansi_mono,f);
|
try_init(&console_ansi_mono, f);
|
||||||
try_init(&console_ansi_color,f);
|
try_init(&console_ansi_color, f);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
try_init(&console_screen,f);
|
try_init(&console_screen, f);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_AALIB)
|
#if (USE_AALIB)
|
||||||
try_init(&console_aalib,f);
|
try_init(&console_aalib, f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return con_mode;
|
return con_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
if (con != me)
|
if (con != me)
|
||||||
return con_mode;
|
return con_mode;
|
||||||
assert(o == -1);
|
assert(o == -1);
|
||||||
@@ -114,47 +106,34 @@ static int init(FILE *f, int o, int now)
|
|||||||
return do_init(f);
|
return do_init(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
return con->set_fg(f,fg);
|
return con->set_fg(f, fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
return con->intro(f);
|
return con->intro(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_init = {init, set_fg, nullptr, intro};
|
||||||
|
|
||||||
console_t console_init =
|
void con_fprintf(FILE *f, const char *format, ...) {
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
nullptr,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void 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_safe_vsnprintf(buf, sizeof(buf), format,args);
|
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
con->print0(f,buf);
|
con->print0(f, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,44 +33,30 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_NONE;
|
return CON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(s);
|
UNUSED(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_none = {init, set_fg, print0, intro};
|
||||||
console_t console_none =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -35,16 +34,14 @@
|
|||||||
#define mask_fg 0x0f
|
#define mask_fg 0x0f
|
||||||
#define mask_bg 0xf0
|
#define mask_bg 0xf0
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int do_init(screen_t *s, int fd)
|
static int do_init(screen_t *s, int fd) {
|
||||||
{
|
|
||||||
int fg, bg;
|
int fg, bg;
|
||||||
|
|
||||||
if (s->init(s,fd) != 0)
|
if (s->init(s, fd) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
||||||
@@ -59,39 +56,32 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 nullptr;
|
return nullptr;
|
||||||
if (do_init(s,fd) != 0)
|
if (do_init(s, fd) != 0) {
|
||||||
{
|
|
||||||
s->destroy(s);
|
s->destroy(s);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static screen_t *screen = nullptr;
|
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);
|
||||||
@@ -99,16 +89,13 @@ static void __acc_cdecl_atexit do_destroy(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -117,30 +104,30 @@ static int init(FILE *f, int o, int now)
|
|||||||
|
|
||||||
if (o == CON_SCREEN)
|
if (o == CON_SCREEN)
|
||||||
n = CON_SCREEN;
|
n = CON_SCREEN;
|
||||||
else if (o == CON_INIT) /* use by default */
|
else if (o == CON_INIT) /* use by default */
|
||||||
n = CON_SCREEN;
|
n = CON_SCREEN;
|
||||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||||
n = CON_ANSI_COLOR;
|
n = CON_ANSI_COLOR;
|
||||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||||
n = CON_ANSI_MONO;
|
n = CON_ANSI_MONO;
|
||||||
else
|
else
|
||||||
return CON_INIT;
|
return CON_INIT;
|
||||||
|
|
||||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
screen = do_construct(screen_djgpp2_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_win32_construct(),fd);
|
screen = do_construct(screen_win32_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_VCSA)
|
#if (USE_SCREEN_VCSA)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_vcsa_construct(),fd);
|
screen = do_construct(screen_vcsa_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
#if (USE_SCREEN_CURSES)
|
#if (USE_SCREEN_CURSES)
|
||||||
if (!screen && o == CON_SCREEN)
|
if (!screen && o == CON_SCREEN)
|
||||||
screen = do_construct(screen_curses_construct(),fd);
|
screen = do_construct(screen_curses_construct(), fd);
|
||||||
#endif
|
#endif
|
||||||
if (!screen)
|
if (!screen)
|
||||||
return CON_INIT;
|
return CON_INIT;
|
||||||
@@ -155,19 +142,16 @@ 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;
|
||||||
else if (b == 0)
|
else if (b == 0)
|
||||||
f1 = (f2 <= 8) ? 15 : 8;
|
f1 = (f2 <= 8) ? 15 : 8;
|
||||||
@@ -175,19 +159,15 @@ static int set_fg(FILE *f, int fg)
|
|||||||
f1 = (f2 == 0) ? 15 : 0;
|
f1 = (f2 == 0) ? 15 : 0;
|
||||||
else
|
else
|
||||||
f1 = (f2 == 0) ? 8 : 0;
|
f1 = (f2 == 0) ? 8 : 0;
|
||||||
}
|
} else if (con_mode == CON_ANSI_MONO && f1 != f2) {
|
||||||
else if (con_mode == CON_ANSI_MONO && f1 != f2)
|
|
||||||
{
|
|
||||||
f1 = f2 ^ 0x08;
|
f1 = f2 ^ 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->setFg(screen,f1 & mask_fg);
|
screen->setFg(screen, f1 & mask_fg);
|
||||||
return last_fg;
|
return last_fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *ss) {
|
||||||
static void print0(FILE *f, const char *ss)
|
|
||||||
{
|
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
int old_cx = 0, old_cy = 0;
|
int old_cx = 0, old_cy = 0;
|
||||||
const int sx = screen->getCols(screen);
|
const int sx = screen->getCols(screen);
|
||||||
@@ -199,57 +179,47 @@ static void print0(FILE *f, const char *ss)
|
|||||||
// scrollUp() under Win32 is *extremely* slow.
|
// scrollUp() under Win32 is *extremely* slow.
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
|
|
||||||
screen->getCursor(screen,&old_cx,&old_cy);
|
screen->getCursor(screen, &old_cx, &old_cy);
|
||||||
cx = old_cx; cy = old_cy;
|
cx = old_cx;
|
||||||
|
cy = old_cy;
|
||||||
|
|
||||||
for (pass = 0; pass < 2; pass++)
|
for (pass = 0; pass < 2; pass++) {
|
||||||
{
|
|
||||||
const char *s = ss;
|
const char *s = ss;
|
||||||
// char buffer for pass 2
|
// char buffer for pass 2
|
||||||
char p[256+1];
|
char p[256 + 1];
|
||||||
int pi = 0, px = 0, py = 0;
|
int pi = 0, px = 0, py = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
// walk over whitespace
|
// walk over whitespace
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
if (*s == '\n') {
|
||||||
if (*s == '\n')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
} else if (*s == '\r') {
|
||||||
else if (*s == '\r')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
if (pass > 0 && cy < sy)
|
if (pass > 0 && cy < sy)
|
||||||
screen->clearLine(screen,cy);
|
screen->clearLine(screen, cy);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
// adjust cursor
|
// adjust cursor
|
||||||
if (cx >= sx)
|
if (cx >= sx) {
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
}
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// check if we should print something
|
// check if we should print something
|
||||||
if (pi > 0 && (*s == 0 || py != cy))
|
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||||
{
|
|
||||||
p[pi] = 0;
|
p[pi] = 0;
|
||||||
screen->putString(screen,p,px,py);
|
screen->putString(screen, p, px, py);
|
||||||
pi = 0;
|
pi = 0;
|
||||||
}
|
}
|
||||||
// check if we should scroll even more (this can happen
|
// check if we should scroll even more (this can happen
|
||||||
// if the string is longer than sy lines)
|
// if the string is longer than sy lines)
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen,scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy -= scroll_y;
|
cy -= scroll_y;
|
||||||
if (cy < 0)
|
if (cy < 0)
|
||||||
cy = 0;
|
cy = 0;
|
||||||
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
|||||||
// done ?
|
// done ?
|
||||||
if (*s == 0)
|
if (*s == 0)
|
||||||
break;
|
break;
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// store current char
|
// store current char
|
||||||
if (pi == 0)
|
if (pi == 0) {
|
||||||
{
|
|
||||||
px = cx;
|
px = cx;
|
||||||
py = cy;
|
py = cy;
|
||||||
}
|
}
|
||||||
@@ -273,47 +241,34 @@ static void print0(FILE *f, const char *ss)
|
|||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass == 0)
|
if (pass == 0) {
|
||||||
{
|
|
||||||
// end of pass 1 - scroll up, restore cursor
|
// end of pass 1 - scroll up, restore cursor
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen,scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy = old_cy - scroll_y;
|
cy = old_cy - scroll_y;
|
||||||
if (cy < 0)
|
if (cy < 0)
|
||||||
cy = 0;
|
cy = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
cy = old_cy;
|
cy = old_cy;
|
||||||
cx = old_cx;
|
cx = old_cx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->setCursor(screen,cx,cy);
|
screen->setCursor(screen, cx, cy);
|
||||||
screen->refresh(screen);
|
screen->refresh(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if (USE_FRAMES)
|
#if (USE_FRAMES)
|
||||||
if (screen->intro)
|
if (screen->intro)
|
||||||
return screen->intro(screen,screen_show_frames);
|
return screen->intro(screen, screen_show_frames);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_screen = {init, set_fg, print0, intro};
|
||||||
console_t console_screen =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* USE_SCREEN */
|
#endif /* USE_SCREEN */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -40,91 +40,77 @@
|
|||||||
#undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
|
|
||||||
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
||||||
# define NO_CONSOLE 1
|
#define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && defined(__linux__)
|
#if 1 && defined(__linux__)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_VCSA 1
|
#define USE_SCREEN_VCSA 1
|
||||||
# if !(HAVE_LINUX_KD_H)
|
#if !(HAVE_LINUX_KD_H)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# endif
|
#endif
|
||||||
# if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
#if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32 1
|
#define USE_SCREEN_WIN32 1
|
||||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||||
# define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32 1
|
#define USE_SCREEN_WIN32 1
|
||||||
|
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
|
||||||
|
#define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (NO_ANSI)
|
#if 0 || (NO_ANSI)
|
||||||
# undef USE_ANSI
|
#undef USE_ANSI
|
||||||
#endif
|
#endif
|
||||||
#if 0 || (NO_SCREEN)
|
#if 0 || (NO_SCREEN)
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
#endif
|
#endif
|
||||||
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||||
# define USE_CONSOLE 1
|
#define USE_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
||||||
# undef USE_CONSOLE
|
#undef USE_CONSOLE
|
||||||
# undef USE_ANSI
|
#undef USE_ANSI
|
||||||
# undef USE_SCREEN
|
#undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
#undef USE_SCREEN_VCSA
|
||||||
# undef USE_SCREEN_CURSES
|
#undef USE_SCREEN_CURSES
|
||||||
# undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
enum {
|
enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
|
||||||
CON_INIT,
|
|
||||||
CON_NONE,
|
|
||||||
CON_FILE,
|
|
||||||
CON_ANSI_MONO,
|
|
||||||
CON_ANSI_COLOR,
|
|
||||||
CON_SCREEN,
|
|
||||||
CON_UNUSED
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int (*init)(FILE *f, int, int);
|
int (*init)(FILE *f, int, int);
|
||||||
int (*set_fg)(FILE *f, int fg);
|
int (*set_fg)(FILE *f, int fg);
|
||||||
void (*print0)(FILE *f, const char *s);
|
void (*print0)(FILE *f, const char *s);
|
||||||
bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
} console_t;
|
||||||
console_t;
|
|
||||||
|
|
||||||
|
|
||||||
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
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
|
||||||
#define FG_GREEN 0x02
|
#define FG_GREEN 0x02
|
||||||
@@ -142,18 +128,17 @@ void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
|||||||
#define FG_YELLOW 0x0e
|
#define FG_YELLOW 0x0e
|
||||||
#define FG_WHITE 0x0f
|
#define FG_WHITE 0x0f
|
||||||
|
|
||||||
#define BG_BLACK 0x00
|
#define BG_BLACK 0x00
|
||||||
#define BG_BLUE 0x10
|
#define BG_BLUE 0x10
|
||||||
#define BG_GREEN 0x20
|
#define BG_GREEN 0x20
|
||||||
#define BG_CYAN 0x30
|
#define BG_CYAN 0x30
|
||||||
#define BG_RED 0x40
|
#define BG_RED 0x40
|
||||||
#define BG_VIOLET 0x50
|
#define BG_VIOLET 0x50
|
||||||
#define BG_ORANGE 0x60
|
#define BG_ORANGE 0x60
|
||||||
#define BG_WHITE 0x70
|
#define BG_WHITE 0x70
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -172,13 +157,12 @@ extern console_t console_ansi_mono;
|
|||||||
extern console_t console_ansi_color;
|
extern console_t console_ansi_color;
|
||||||
extern console_t console_screen;
|
extern console_t console_screen;
|
||||||
|
|
||||||
|
#define con_fg(f, x) con->set_fg(f, x)
|
||||||
#define con_fg(f,x) con->set_fg(f,x)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define con_fg(f,x) 0
|
#define con_fg(f, x) 0
|
||||||
#define con_fprintf fprintf
|
#define con_fprintf fprintf
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
#if (ACC_CC_GNUC >= 0x040300ul)
|
#if (ACC_CC_GNUC >= 0x040300ul)
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
#include <sys/farptr.h>
|
#include <sys/farptr.h>
|
||||||
#include <sys/movedata.h>
|
#include <sys/movedata.h>
|
||||||
#define dossel _go32_info_block.selector_for_linear_memory
|
#define dossel _go32_info_block.selector_for_linear_memory
|
||||||
#define co80 _go32_info_block.linear_address_of_primary_screen
|
#define co80 _go32_info_block.linear_address_of_primary_screen
|
||||||
#undef kbhit
|
#undef kbhit
|
||||||
|
|
||||||
#define Cell upx_uint16_t
|
#define Cell upx_uint16_t
|
||||||
@@ -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) {
|
||||||
@@ -107,7 +109,7 @@ static void refresh(screen_t *this) { UNUSED(this); }
|
|||||||
|
|
||||||
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
||||||
UNUSED(this);
|
UNUSED(this);
|
||||||
return (Cell)(((attr & 0xff) << 8) | (ch & 0xff));
|
return (Cell) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMode(const screen_t *this) {
|
static int getMode(const screen_t *this) {
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
||||||
|
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,10 +25,19 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#define WANT_WINDOWS_LEAN_H 1
|
||||||
|
#include "../util/system_headers.h"
|
||||||
|
#if (HAVE_CONIO_H)
|
||||||
|
#include <conio.h>
|
||||||
|
#endif
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// direct screen access
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
#define this self
|
#define this self
|
||||||
@@ -36,24 +45,6 @@
|
|||||||
#define mask_fg 0x0f
|
#define mask_fg 0x0f
|
||||||
#define mask_bg 0xf0
|
#define mask_bg 0xf0
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// direct screen access
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1200))
|
|
||||||
/* avoid -W4 warnings in <conio.h> */
|
|
||||||
#pragma warning(disable : 4032)
|
|
||||||
/* avoid -W4 warnings in <windows.h> */
|
|
||||||
#pragma warning(disable : 4201 4214 4514)
|
|
||||||
#endif
|
|
||||||
#if defined(__RSXNT__)
|
|
||||||
#define timeval win32_timeval /* struct timeval already in <sys/time.h> */
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
|
||||||
#if (HAVE_CONIO_H)
|
|
||||||
#include <conio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct screen_data_t {
|
struct screen_data_t {
|
||||||
HANDLE hi;
|
HANDLE hi;
|
||||||
HANDLE ho;
|
HANDLE ho;
|
||||||
@@ -76,7 +67,7 @@ struct screen_data_t {
|
|||||||
CHAR_INFO empty_line[256];
|
CHAR_INFO empty_line[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define P(x) ((SHORT)(x))
|
#define P(x) ((SHORT) (x))
|
||||||
|
|
||||||
static const COORD pos00 = {0, 0};
|
static const COORD pos00 = {0, 0};
|
||||||
static const COORD size11 = {1, 1};
|
static const COORD size11 = {1, 1};
|
||||||
@@ -111,12 +102,12 @@ static int getFg(const screen_t *this) { return this->data->attr & mask_fg; }
|
|||||||
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
||||||
|
|
||||||
static void setFg(screen_t *this, int fg) {
|
static void setFg(screen_t *this, int fg) {
|
||||||
this->data->attr = (WORD)((this->data->attr & mask_bg) | (fg & mask_fg));
|
this->data->attr = (WORD) ((this->data->attr & mask_bg) | (fg & mask_fg));
|
||||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setBg(screen_t *this, int bg) {
|
static void setBg(screen_t *this, int bg) {
|
||||||
this->data->attr = (WORD)((this->data->attr & mask_fg) | (bg & mask_bg));
|
this->data->attr = (WORD) ((this->data->attr & mask_fg) | (bg & mask_bg));
|
||||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +257,22 @@ static int init(screen_t *this, int fd) {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// check if we are running under Wine
|
||||||
|
// (this rather direct Win32 screen driver maps poorly to Unix terminals)
|
||||||
|
// ntdll.dll wine_get_version() was added in wine-0.9.59 (Apr 2008)
|
||||||
|
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
|
||||||
|
if (ntdll != nullptr) {
|
||||||
|
typedef const char *(CDECL * wine_get_version_func_t)(void);
|
||||||
|
wine_get_version_func_t wine_get_version;
|
||||||
|
wine_get_version =
|
||||||
|
(wine_get_version_func_t) (void *) GetProcAddress(ntdll, "wine_get_version");
|
||||||
|
if (wine_get_version != nullptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
this->data->cursor_x = csbi->dwCursorPosition.X;
|
this->data->cursor_x = csbi->dwCursorPosition.X;
|
||||||
this->data->cursor_y = csbi->dwCursorPosition.Y;
|
this->data->cursor_y = csbi->dwCursorPosition.Y;
|
||||||
|
|
||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UPX_SCREEN_H
|
#pragma once
|
||||||
#define __UPX_SCREEN_H 1
|
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -99,6 +98,4 @@ void screen_show_frames(screen_t *);
|
|||||||
|
|
||||||
#endif /* USE_SCREEN */
|
#endif /* USE_SCREEN */
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
+75
-23
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,39 +31,41 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
unsigned long Throwable::counter = 0;
|
/*static*/ Throwable::Stats Throwable::stats;
|
||||||
|
|
||||||
Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
|
Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
|
||||||
msg(nullptr),
|
msg(nullptr),
|
||||||
err(e),
|
err(e),
|
||||||
is_warning(w) {
|
is_warning(w) {
|
||||||
if (m)
|
if (m != nullptr) {
|
||||||
msg = strdup(m);
|
msg = strdup(m);
|
||||||
#if 0
|
assert_noexcept(msg != nullptr);
|
||||||
fprintf(stderr, "construct exception: %s %lu\n", msg, counter);
|
}
|
||||||
counter++;
|
NO_fprintf(stderr, "construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
#endif
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
|
stats.counter_current += 1;
|
||||||
|
stats.counter_total += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Throwable::Throwable(const Throwable &other) noexcept : super(other),
|
Throwable::Throwable(const Throwable &other) noexcept : super(other),
|
||||||
msg(nullptr),
|
msg(nullptr),
|
||||||
err(other.err),
|
err(other.err),
|
||||||
is_warning(other.is_warning) {
|
is_warning(other.is_warning) {
|
||||||
if (other.msg)
|
if (other.msg != nullptr) {
|
||||||
msg = strdup(other.msg);
|
msg = strdup(other.msg);
|
||||||
#if 0
|
assert_noexcept(msg != nullptr);
|
||||||
fprintf(stderr, "copy exception: %s %lu\n", msg, counter);
|
}
|
||||||
counter++;
|
NO_fprintf(stderr, "copy construct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
#endif
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
|
stats.counter_current += 1;
|
||||||
|
stats.counter_total += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Throwable::~Throwable() noexcept {
|
Throwable::~Throwable() noexcept {
|
||||||
#if 0
|
stats.counter_current -= 1;
|
||||||
counter--;
|
NO_fprintf(stderr, "destruct exception: %zu %zu %s\n", size_t(stats.counter_current),
|
||||||
fprintf(stderr, "destruct exception: %s %lu\n", msg, counter);
|
size_t(stats.counter_total), (const char *) msg);
|
||||||
#endif
|
upx::owner_free(msg);
|
||||||
if (msg)
|
|
||||||
free(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -72,7 +74,9 @@ Throwable::~Throwable() noexcept {
|
|||||||
|
|
||||||
void throwCantPack(const char *msg) {
|
void throwCantPack(const char *msg) {
|
||||||
// UGLY, but makes things easier
|
// UGLY, but makes things easier
|
||||||
if (opt->cmd == CMD_COMPRESS)
|
if (opt->cmd == CMD_NONE)
|
||||||
|
throw CantPackException(msg);
|
||||||
|
else if (opt->cmd == CMD_COMPRESS)
|
||||||
throw CantPackException(msg);
|
throw CantPackException(msg);
|
||||||
else if (opt->cmd == CMD_FILEINFO)
|
else if (opt->cmd == CMD_FILEINFO)
|
||||||
throw CantPackException(msg);
|
throw CantPackException(msg);
|
||||||
@@ -140,10 +144,58 @@ void throwEOFException(const char *msg, int e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// varargs overloads
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const char *prettyName(const char *n) noexcept {
|
template <>
|
||||||
|
void throwCantPack(const char *format, ...) {
|
||||||
|
char msg[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
throwCantPack(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void throwCantUnpack(const char *format, ...) {
|
||||||
|
char msg[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
throwCantUnpack(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void throwInternalError(const char *format, ...) {
|
||||||
|
char msg[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
throwCantUnpack(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// util
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept {
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void throwAssertFailed(const char *expr, const char *file, int line, const char *func) {
|
||||||
|
if (opt->debug.debug_level >= 1) {
|
||||||
|
throwCantPack("corrupted file; details: %s (%s: %s: %d)", expr, file, func, line);
|
||||||
|
} else {
|
||||||
|
throwCantPack("corrupted file; try '--debug' for more details");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *prettyExceptionName(const char *n) noexcept {
|
||||||
if (n == nullptr)
|
if (n == nullptr)
|
||||||
return "(null)";
|
return "(null)";
|
||||||
while (*n) {
|
while (*n) {
|
||||||
@@ -151,7 +203,7 @@ const char *prettyName(const char *n) noexcept {
|
|||||||
n++;
|
n++;
|
||||||
else if (*n == ' ')
|
else if (*n == ' ')
|
||||||
n++;
|
n++;
|
||||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++
|
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC)
|
||||||
n += 6;
|
n += 6;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|||||||
+60
-70
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -26,12 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef UPX_EXCEPT_H__
|
|
||||||
#define UPX_EXCEPT_H__ 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
const char *prettyName(const char *n) noexcept;
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// exceptions
|
// exceptions
|
||||||
@@ -44,33 +38,40 @@ protected:
|
|||||||
Throwable(const char *m = nullptr, int e = 0, bool w = false) noexcept;
|
Throwable(const char *m = nullptr, int e = 0, bool w = false) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Throwable(const Throwable &) noexcept;
|
Throwable(const Throwable &) noexcept; // copy constructor
|
||||||
virtual ~Throwable() noexcept;
|
virtual ~Throwable() noexcept;
|
||||||
const char *getMsg() const noexcept { return msg; }
|
const char *getMsg() const noexcept { return msg; }
|
||||||
int getErrno() const noexcept { return err; }
|
int getErrno() const noexcept { return err; }
|
||||||
bool isWarning() const noexcept { return is_warning; }
|
bool isWarning() const noexcept { return is_warning; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *msg = nullptr;
|
OwningPointer(char) msg = nullptr;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool is_warning = false; // can be set by subclasses
|
bool is_warning = false; // can be set by subclasses
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disable assignment
|
// disable copy assignment and move
|
||||||
Throwable &operator=(const Throwable &) = delete;
|
Throwable &operator=(const Throwable &) noexcept DELETED_FUNCTION; // copy assignment
|
||||||
|
UPX_CXX_DISABLE_MOVE(Throwable)
|
||||||
// disable dynamic allocation => force throwing by value
|
// disable dynamic allocation => force throwing by value
|
||||||
ACC_CXX_DISABLE_NEW_DELETE
|
UPX_CXX_DISABLE_NEW_DELETE(Throwable)
|
||||||
|
// disable taking the address => force passing by reference
|
||||||
|
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||||
|
UPX_CXX_DISABLE_ADDRESS(Throwable)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned long counter; // for debugging
|
// static debug stats
|
||||||
|
struct Stats {
|
||||||
|
upx_std_atomic(size_t) counter_total;
|
||||||
|
upx_std_atomic(size_t) counter_current;
|
||||||
|
};
|
||||||
|
static Stats stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exceptions can/should be caught
|
// Exceptions can/should be caught
|
||||||
class Exception : public Throwable {
|
class Exception : public Throwable {
|
||||||
typedef Throwable super;
|
typedef Throwable super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {}
|
Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {}
|
||||||
};
|
};
|
||||||
@@ -78,46 +79,40 @@ public:
|
|||||||
// Errors should not be caught (or re-thrown)
|
// Errors should not be caught (or re-thrown)
|
||||||
class Error : public Throwable {
|
class Error : public Throwable {
|
||||||
typedef Throwable super;
|
typedef Throwable super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// system exception
|
// system exceptions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class OutOfMemoryException : public Exception {
|
class OutOfMemoryException final : public Exception {
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IOException : public Exception {
|
class IOException /*not_final*/ : public Exception {
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EOFException : public IOException {
|
class EOFException final : public IOException {
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileNotFoundException : public IOException {
|
class FileNotFoundException final : public IOException {
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileAlreadyExistsException : public IOException {
|
class FileAlreadyExistsException final : public IOException {
|
||||||
typedef IOException super;
|
typedef IOException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
|
||||||
};
|
};
|
||||||
@@ -126,52 +121,45 @@ public:
|
|||||||
// application exceptions
|
// application exceptions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class OverlayException : public Exception {
|
class OverlayException final : public Exception {
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CantPackException : public Exception {
|
class CantPackException /*not_final*/ : public Exception {
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CantPackException(const char *m = nullptr, bool w = false) noexcept : 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 = nullptr, bool w = false) noexcept
|
UnknownExecutableFormatException(const char *m = nullptr, bool w = false) noexcept
|
||||||
: super(m, w) {}
|
: super(m, w) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AlreadyPackedException : public CantPackException {
|
class AlreadyPackedException final : public CantPackException {
|
||||||
typedef CantPackException super;
|
typedef CantPackException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; }
|
AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotCompressibleException : public CantPackException {
|
class NotCompressibleException final : public CantPackException {
|
||||||
typedef CantPackException super;
|
typedef CantPackException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotCompressibleException(const char *m = nullptr) noexcept : super(m) {}
|
NotCompressibleException(const char *m = nullptr) noexcept : super(m) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CantUnpackException : public Exception {
|
class CantUnpackException /*not_final*/ : public Exception {
|
||||||
typedef Exception super;
|
typedef Exception super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotPackedException : public CantUnpackException {
|
class NotPackedException final : public CantUnpackException {
|
||||||
typedef CantUnpackException super;
|
typedef CantUnpackException super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
|
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
|
||||||
};
|
};
|
||||||
@@ -180,9 +168,8 @@ public:
|
|||||||
// errors
|
// errors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class InternalError : public Error {
|
class InternalError final : public Error {
|
||||||
typedef Error super;
|
typedef Error super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
|
InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
|
||||||
};
|
};
|
||||||
@@ -191,34 +178,37 @@ public:
|
|||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#undef NORET
|
const char *prettyExceptionName(const char *n) noexcept;
|
||||||
#if 1 && defined(__GNUC__)
|
|
||||||
#define NORET __acc_noinline __attribute__((__noreturn__))
|
|
||||||
#else
|
|
||||||
#define NORET __acc_noinline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NORET void throwCantPack(const char *msg);
|
noreturn void throwCantPack(const char *msg) may_throw;
|
||||||
NORET void throwCantPackExact();
|
noreturn void throwCantPackExact() may_throw;
|
||||||
NORET void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false);
|
noreturn void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw;
|
||||||
NORET void throwNotCompressible(const char *msg = nullptr);
|
noreturn void throwNotCompressible(const char *msg = nullptr) may_throw;
|
||||||
NORET void throwAlreadyPacked(const char *msg = nullptr);
|
noreturn void throwAlreadyPacked(const char *msg = nullptr) may_throw;
|
||||||
NORET void throwAlreadyPackedByUPX(const char *msg = nullptr);
|
noreturn void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw;
|
||||||
NORET void throwCantUnpack(const char *msg);
|
noreturn void throwCantUnpack(const char *msg) may_throw;
|
||||||
NORET void throwNotPacked(const char *msg = nullptr);
|
noreturn void throwNotPacked(const char *msg = nullptr) may_throw;
|
||||||
NORET void throwFilterException();
|
noreturn void throwFilterException() may_throw;
|
||||||
NORET void throwBadLoader();
|
noreturn void throwBadLoader() may_throw;
|
||||||
NORET void throwChecksumError();
|
noreturn void throwChecksumError() may_throw;
|
||||||
NORET void throwCompressedDataViolation();
|
noreturn void throwCompressedDataViolation() may_throw;
|
||||||
NORET void throwInternalError(const char *msg);
|
noreturn void throwInternalError(const char *msg) may_throw;
|
||||||
NORET void throwOutOfMemoryException(const char *msg = nullptr);
|
noreturn void throwOutOfMemoryException(const char *msg = nullptr) may_throw;
|
||||||
NORET void throwIOException(const char *msg = nullptr, int e = 0);
|
noreturn void throwIOException(const char *msg = nullptr, int e = 0) may_throw;
|
||||||
NORET void throwEOFException(const char *msg = nullptr, int e = 0);
|
noreturn void throwEOFException(const char *msg = nullptr, int e = 0) may_throw;
|
||||||
|
|
||||||
#undef NORET
|
// some C++ template wizardry is needed to overload throwCantPack() for varargs
|
||||||
|
template <class T>
|
||||||
#endif /* __cplusplus */
|
void throwCantPack(const T *, ...) DELETED_FUNCTION;
|
||||||
|
template <>
|
||||||
#endif /* already included */
|
noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
|
template <class T>
|
||||||
|
void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
|
||||||
|
template <>
|
||||||
|
noreturn void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
|
template <class T>
|
||||||
|
void throwInternalError(const T *, ...) DELETED_FUNCTION;
|
||||||
|
template <>
|
||||||
|
noreturn void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+102
-54
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -29,20 +29,22 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// static functions
|
// static file-related util functions; will throw on error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void FileBase::chmod(const char *name, int mode) {
|
/*static*/ void FileBase::chmod(const char *name, int mode) {
|
||||||
#if (HAVE_CHMOD)
|
assert(name != nullptr && name[0] != 0);
|
||||||
|
#if HAVE_CHMOD
|
||||||
if (::chmod(name, mode) != 0)
|
if (::chmod(name, mode) != 0)
|
||||||
throwIOException(name, errno);
|
throwIOException(name, errno);
|
||||||
#else
|
#else
|
||||||
UNUSED(name);
|
UNUSED(name);
|
||||||
UNUSED(mode);
|
UNUSED(mode);
|
||||||
|
// no error
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBase::rename(const char *old_, const char *new_) {
|
/*static*/ void FileBase::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
|
||||||
@@ -51,29 +53,34 @@ void FileBase::rename(const char *old_, const char *new_) {
|
|||||||
throwIOException("rename error", errno);
|
throwIOException("rename error", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBase::unlink(const char *name) {
|
/*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
|
||||||
if (::unlink(name) != 0)
|
assert_noexcept(name != nullptr && name[0] != 0);
|
||||||
|
bool success = ::unlink(name) == 0;
|
||||||
|
#if HAVE_CHMOD
|
||||||
|
if (!success)
|
||||||
|
success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0);
|
||||||
|
#endif
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void FileBase::unlink(const char *name) {
|
||||||
|
if (!unlink_noexcept(name))
|
||||||
throwIOException(name, errno);
|
throwIOException(name, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// FileBase
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
FileBase::FileBase()
|
FileBase::~FileBase() may_throw {
|
||||||
: _fd(-1), _flags(0), _shflags(0), _mode(0), _name(nullptr), _offset(0), _length(0) {
|
|
||||||
memset(&st, 0, sizeof(st));
|
|
||||||
}
|
|
||||||
|
|
||||||
FileBase::~FileBase() {
|
|
||||||
#if 0 && defined(__GNUC__) // debug
|
#if 0 && defined(__GNUC__) // debug
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__);
|
fprintf(stderr, "%s: %s\n", _name, __PRETTY_FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
|
if (std::uncaught_exceptions() == 0)
|
||||||
// FIXME: we should use close() during exception unwinding but
|
closex(); // may_throw
|
||||||
// closex() otherwise
|
else
|
||||||
closex();
|
close_noexcept(); // currently in exception unwinding, use noexcept variant
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileBase::do_sopen() {
|
bool FileBase::do_sopen() {
|
||||||
@@ -82,7 +89,7 @@ bool FileBase::do_sopen() {
|
|||||||
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 (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
_fd = ::open(_name, _flags | (_shflags & O_SHMODE), _mode);
|
_fd = ::open(_name, _flags | (_shflags & O_SHMODE), _mode);
|
||||||
#elif defined(SH_DENYRW)
|
#elif defined(SH_DENYRW)
|
||||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||||
@@ -92,13 +99,14 @@ bool FileBase::do_sopen() {
|
|||||||
}
|
}
|
||||||
if (_fd < 0)
|
if (_fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
st.st_size = 0;
|
||||||
if (::fstat(_fd, &st) != 0)
|
if (::fstat(_fd, &st) != 0)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size;
|
_length = st.st_size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileBase::close() {
|
bool FileBase::close_noexcept() noexcept {
|
||||||
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)
|
||||||
@@ -112,11 +120,12 @@ bool FileBase::close() {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBase::closex() {
|
void FileBase::closex() may_throw {
|
||||||
if (!close())
|
if (!close_noexcept())
|
||||||
throwIOException("close failed", errno);
|
throwIOException("close failed", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return value of ::seek is the resulting file offset (same as ::tell())
|
||||||
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
@@ -125,16 +134,18 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
|||||||
if (off < 0)
|
if (off < 0)
|
||||||
throwIOException("bad seek 2");
|
throwIOException("bad seek 2");
|
||||||
off += _offset;
|
off += _offset;
|
||||||
}
|
} else if (whence == SEEK_END) {
|
||||||
if (whence == SEEK_END) {
|
|
||||||
if (off > 0)
|
if (off > 0)
|
||||||
throwIOException("bad seek 3");
|
throwIOException("bad seek 3");
|
||||||
off += _offset + _length;
|
off += _offset + _length;
|
||||||
whence = SEEK_SET;
|
whence = SEEK_SET;
|
||||||
}
|
} else if (whence == SEEK_CUR) {
|
||||||
if (::lseek(_fd, off, whence) < 0)
|
} else
|
||||||
|
throwInternalError("bad seek: whence");
|
||||||
|
upx_off_t l = ::lseek(_fd, off, whence);
|
||||||
|
if (l < 0)
|
||||||
throwIOException("seek error", errno);
|
throwIOException("seek error", errno);
|
||||||
return off - _offset;
|
return l - _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
upx_off_t FileBase::tell() const {
|
upx_off_t FileBase::tell() const {
|
||||||
@@ -154,13 +165,11 @@ void FileBase::set_extent(upx_off_t offset, upx_off_t length) {
|
|||||||
upx_off_t FileBase::st_size() const { return _length; }
|
upx_off_t FileBase::st_size() const { return _length; }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// InputFile
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
InputFile::InputFile() {}
|
|
||||||
|
|
||||||
void InputFile::sopen(const char *name, int flags, int shflags) {
|
void InputFile::sopen(const char *name, int flags, int shflags) {
|
||||||
close();
|
closex();
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
@@ -178,10 +187,10 @@ 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(SPAN_P(void) buf, upx_int64_t blen) {
|
||||||
if (!isOpen() || len < 0)
|
if (!isOpen() || blen < 0)
|
||||||
throwIOException("bad read");
|
throwIOException("bad read");
|
||||||
mem_size_assert(1, len); // sanity check
|
int len = (int) mem_size(1, blen); // sanity check
|
||||||
errno = 0;
|
errno = 0;
|
||||||
long l = acc_safe_hread(_fd, raw_bytes(buf, len), len);
|
long l = acc_safe_hread(_fd, raw_bytes(buf, len), len);
|
||||||
if (errno)
|
if (errno)
|
||||||
@@ -189,9 +198,9 @@ int InputFile::read(SPAN_P(void) buf, int len) {
|
|||||||
return (int) l;
|
return (int) l;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InputFile::readx(SPAN_P(void) buf, int len) {
|
int InputFile::readx(SPAN_P(void) buf, upx_int64_t blen) {
|
||||||
int l = this->read(buf, len);
|
int l = this->read(buf, blen);
|
||||||
if (l != len)
|
if (l != blen)
|
||||||
throwEOFException();
|
throwEOFException();
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -205,14 +214,26 @@ upx_off_t InputFile::seek(upx_off_t off, int whence) {
|
|||||||
|
|
||||||
upx_off_t InputFile::st_size_orig() const { return _length_orig; }
|
upx_off_t InputFile::st_size_orig() const { return _length_orig; }
|
||||||
|
|
||||||
|
int InputFile::dupFd() may_throw {
|
||||||
|
if (!isOpen())
|
||||||
|
throwIOException("bad dup");
|
||||||
|
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
|
||||||
|
errno = ENOSYS;
|
||||||
|
int r = -1;
|
||||||
|
#else
|
||||||
|
int r = ::dup(getFd());
|
||||||
|
#endif
|
||||||
|
if (r < 0)
|
||||||
|
throwIOException("dup", errno);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// OutputFile
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
OutputFile::OutputFile() : bytes_written(0) {}
|
|
||||||
|
|
||||||
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
|
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
|
||||||
close();
|
closex();
|
||||||
_name = name;
|
_name = name;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
@@ -234,7 +255,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();
|
closex();
|
||||||
int fd = STDOUT_FILENO;
|
int fd = STDOUT_FILENO;
|
||||||
if (!force && acc_isatty(fd))
|
if (!force && acc_isatty(fd))
|
||||||
return false;
|
return false;
|
||||||
@@ -250,22 +271,33 @@ bool OutputFile::openStdout(int flags, bool force) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputFile::write(SPAN_0(const void) buf, int len) {
|
void OutputFile::write(SPAN_0(const void) buf, upx_int64_t blen) {
|
||||||
if (!isOpen() || len < 0)
|
if (!isOpen() || blen < 0)
|
||||||
throwIOException("bad write");
|
throwIOException("bad write");
|
||||||
// allow nullptr if len == 0
|
// allow nullptr if blen == 0
|
||||||
if (len == 0)
|
if (blen == 0)
|
||||||
return;
|
return;
|
||||||
mem_size_assert(1, len); // sanity check
|
int len = (int) mem_size(1, blen); // sanity check
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#if 0
|
#if WITH_XSPAN >= 2
|
||||||
fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(),
|
NO_fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(),
|
||||||
buf.raw_base(), len);
|
buf.raw_base(), len);
|
||||||
#endif
|
#endif
|
||||||
long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len);
|
long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len);
|
||||||
if (l != len)
|
if (l != len)
|
||||||
throwIOException("write error", errno);
|
throwIOException("write error", errno);
|
||||||
bytes_written += len;
|
bytes_written += len;
|
||||||
|
#if TESTING && 0
|
||||||
|
static upx_std_atomic(bool) dumping;
|
||||||
|
if (!dumping) {
|
||||||
|
dumping = true;
|
||||||
|
char fn[64];
|
||||||
|
static int part = 0;
|
||||||
|
snprintf(fn, sizeof(fn), "upx-dump-%04d.data", part++);
|
||||||
|
OutputFile::dump(fn, buf, len);
|
||||||
|
dumping = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
upx_off_t OutputFile::st_size() const {
|
upx_off_t OutputFile::st_size() const {
|
||||||
@@ -316,7 +348,8 @@ upx_off_t OutputFile::seek(upx_off_t off, int whence) {
|
|||||||
void OutputFile::set_extent(upx_off_t offset, upx_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 && (upx_off_t) ~0u == length) {
|
if (0 == offset && 0xffffffffLL == length) { // TODO: check all callers of this method
|
||||||
|
st.st_size = 0;
|
||||||
if (::fstat(_fd, &st) != 0)
|
if (::fstat(_fd, &st) != 0)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size - offset;
|
_length = st.st_size - offset;
|
||||||
@@ -333,7 +366,7 @@ upx_off_t OutputFile::unset_extent() {
|
|||||||
return _length;
|
return _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) {
|
/*static*/ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) {
|
||||||
if (flags < 0)
|
if (flags < 0)
|
||||||
flags = O_CREAT | O_TRUNC;
|
flags = O_CREAT | O_TRUNC;
|
||||||
flags |= O_WRONLY | O_BINARY;
|
flags |= O_WRONLY | O_BINARY;
|
||||||
@@ -343,4 +376,19 @@ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int fla
|
|||||||
f.closex();
|
f.closex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("file") {
|
||||||
|
InputFile fi;
|
||||||
|
CHECK(!fi.isOpen());
|
||||||
|
CHECK(fi.getFd() == -1);
|
||||||
|
CHECK(fi.st_size() == 0);
|
||||||
|
OutputFile fo;
|
||||||
|
CHECK(!fo.isOpen());
|
||||||
|
CHECK(fo.getFd() == -1);
|
||||||
|
CHECK(fo.getBytesWritten() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+23
-26
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -26,8 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef UPX_FILE_H__
|
|
||||||
#define UPX_FILE_H__ 1
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -35,15 +33,15 @@
|
|||||||
|
|
||||||
class FileBase {
|
class FileBase {
|
||||||
protected:
|
protected:
|
||||||
FileBase();
|
explicit FileBase() noexcept = default;
|
||||||
virtual ~FileBase();
|
virtual ~FileBase() may_throw;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool close();
|
bool close_noexcept() noexcept;
|
||||||
void closex();
|
void closex() may_throw;
|
||||||
bool isOpen() const { return _fd >= 0; }
|
bool isOpen() const noexcept { return _fd >= 0; }
|
||||||
int getFd() const { return _fd; }
|
int getFd() const noexcept { return _fd; }
|
||||||
const char *getName() const { return _name; }
|
const char *getName() const noexcept { return _name; }
|
||||||
|
|
||||||
virtual upx_off_t seek(upx_off_t off, int whence);
|
virtual upx_off_t seek(upx_off_t off, int whence);
|
||||||
upx_off_t tell() const;
|
upx_off_t tell() const;
|
||||||
@@ -51,10 +49,11 @@ public:
|
|||||||
virtual void set_extent(upx_off_t offset, upx_off_t length);
|
virtual void set_extent(upx_off_t offset, upx_off_t length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// static file-related util functions
|
// static file-related util functions; will throw on error
|
||||||
static void chmod(const char *name, int mode);
|
static void chmod(const char *name, int mode) may_throw;
|
||||||
static void rename(const char *old_, const char *new_);
|
static void rename(const char *old_, const char *new_) may_throw;
|
||||||
static void unlink(const char *name);
|
static void unlink(const char *name) may_throw;
|
||||||
|
static bool unlink_noexcept(const char *name) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool do_sopen();
|
bool do_sopen();
|
||||||
@@ -78,18 +77,19 @@ class InputFile final : public FileBase {
|
|||||||
typedef FileBase super;
|
typedef FileBase super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputFile();
|
explicit InputFile() noexcept = default;
|
||||||
virtual ~InputFile() {}
|
|
||||||
|
|
||||||
void sopen(const char *name, int flags, int shflags);
|
void sopen(const char *name, int flags, int shflags);
|
||||||
void open(const char *name, int flags) { sopen(name, flags, -1); }
|
void open(const char *name, int flags) { sopen(name, flags, -1); }
|
||||||
|
|
||||||
int read(SPAN_P(void) buf, int len);
|
int read(SPAN_P(void) buf, upx_int64_t blen);
|
||||||
int readx(SPAN_P(void) buf, int len);
|
int readx(SPAN_P(void) buf, upx_int64_t blen);
|
||||||
|
|
||||||
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||||
upx_off_t st_size_orig() const;
|
upx_off_t st_size_orig() const;
|
||||||
|
|
||||||
|
noinline int dupFd() may_throw;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
upx_off_t _length_orig = 0;
|
upx_off_t _length_orig = 0;
|
||||||
};
|
};
|
||||||
@@ -102,15 +102,14 @@ class OutputFile final : public FileBase {
|
|||||||
typedef FileBase super;
|
typedef FileBase super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OutputFile();
|
explicit OutputFile() noexcept = default;
|
||||||
virtual ~OutputFile() {}
|
|
||||||
|
|
||||||
void sopen(const char *name, int flags, int shflags, int mode);
|
void sopen(const char *name, int flags, int shflags, int mode);
|
||||||
void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); }
|
void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); }
|
||||||
bool openStdout(int flags = 0, bool force = false);
|
bool openStdout(int flags = 0, bool force = false);
|
||||||
|
|
||||||
// info: allow nullptr if len == 0
|
// info: allow nullptr if blen == 0
|
||||||
void write(SPAN_0(const void) buf, int len);
|
void write(SPAN_0(const void) buf, upx_int64_t blen);
|
||||||
|
|
||||||
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
virtual upx_off_t seek(upx_off_t off, int whence) override;
|
||||||
virtual upx_off_t st_size() const override; // { return _length; }
|
virtual upx_off_t st_size() const override; // { return _length; }
|
||||||
@@ -119,7 +118,7 @@ public:
|
|||||||
|
|
||||||
upx_off_t getBytesWritten() const { return bytes_written; }
|
upx_off_t getBytesWritten() const { return bytes_written; }
|
||||||
|
|
||||||
// FIXME - these won't work when using the '--stdout' option
|
// FIXME - this won't work when using the '--stdout' option
|
||||||
void rewrite(SPAN_P(const void) buf, int len);
|
void rewrite(SPAN_P(const void) buf, int len);
|
||||||
|
|
||||||
// util
|
// util
|
||||||
@@ -129,6 +128,4 @@ protected:
|
|||||||
upx_off_t bytes_written = 0;
|
upx_off_t bytes_written = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+43
-61
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,68 +25,56 @@
|
|||||||
<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, byte *buf, unsigned buf_len) noexcept {
|
||||||
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)
|
/*static*/ const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
|
||||||
{
|
static upx_uint8_t filter_map[256];
|
||||||
static bool done = false;
|
static upx_std_once_flag init_done;
|
||||||
static unsigned char filter_map[256];
|
|
||||||
|
|
||||||
if (!done)
|
upx_std_call_once(init_done, []() noexcept {
|
||||||
{
|
// init the filter_map[] (using a lambda function)
|
||||||
// init the filter_map[]
|
assert_noexcept(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_noexcept(filter_id >= 0 && filter_id <= 255);
|
||||||
assert(filter_map[filter_id] == 0xff);
|
assert_noexcept(filter_map[filter_id] == 0xff);
|
||||||
filter_map[filter_id] = (unsigned char) i;
|
filter_map[filter_id] = (upx_uint8_t) i;
|
||||||
}
|
}
|
||||||
done = true;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (id < 0 || id > 255)
|
if (id < 0 || id > 255)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
unsigned index = filter_map[id];
|
unsigned index = filter_map[id];
|
||||||
if (index == 0xff) // empty slot
|
if (index == 0xff) // empty slot
|
||||||
return nullptr;
|
return nullptr;
|
||||||
assert(filters[index].id == id);
|
assert_noexcept(filters[index].id == id);
|
||||||
return &filters[index];
|
return &filters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ bool Filter::isValidFilter(int filter_id) {
|
||||||
bool Filter::isValidFilter(int filter_id)
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
|
||||||
{
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);
|
|
||||||
return fe != nullptr;
|
return fe != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
/*static*/ 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)
|
||||||
@@ -99,13 +87,13 @@ 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_)
|
Filter::Filter(int level) noexcept : clevel(level) { init(); }
|
||||||
{
|
|
||||||
|
void Filter::init(int id_, unsigned addvalue_) noexcept {
|
||||||
this->id = id_;
|
this->id = id_;
|
||||||
initFilter(this, nullptr, 0);
|
initFilter(this, nullptr, 0);
|
||||||
// clear input parameters
|
// clear input parameters
|
||||||
@@ -116,12 +104,11 @@ void Filter::init(int id_, unsigned addvalue_)
|
|||||||
this->n_mru = 0;
|
this->n_mru = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::filter(SPAN_0(byte) xbuf, unsigned buf_len_) {
|
||||||
bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
byte *const buf_ = raw_bytes(xbuf, 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 == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("filter-1");
|
throwInternalError("filter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -138,10 +125,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,12 +136,11 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::unfilter(SPAN_0(byte) xbuf, unsigned buf_len_, bool verify_checksum) {
|
||||||
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
byte *const buf_ = raw_bytes(xbuf, 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 == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("unfilter-1");
|
throwInternalError("unfilter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -166,24 +152,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,20 +176,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(SPAN_0(const byte) xbuf, unsigned buf_len_) {
|
||||||
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
const byte *const buf_ = raw_bytes(xbuf, 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_);
|
byte *const b = const_cast<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 == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("scan-1");
|
throwInternalError("scan-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -218,9 +200,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)
|
||||||
|
|||||||
+22
-33
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,13 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_FILTER_H
|
|
||||||
#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,16 +44,15 @@ class FilterImp;
|
|||||||
// to absolute addresses so that the buffer compresses better.
|
// to absolute addresses so that the buffer compresses better.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class Filter
|
class Filter final {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Filter(int level) { clevel = level; init(); }
|
explicit Filter(int level) noexcept;
|
||||||
void init(int id=0, unsigned addvalue=0);
|
void init(int id = 0, unsigned addvalue = 0) noexcept;
|
||||||
|
|
||||||
bool filter(upx_byte *buf, unsigned buf_len);
|
bool filter(SPAN_0(byte) buf, unsigned buf_len);
|
||||||
void unfilter(upx_byte *buf, unsigned buf_len, bool verify_checksum=false);
|
void unfilter(SPAN_0(byte) buf, unsigned buf_len, bool verify_checksum = false);
|
||||||
void verifyUnfilter();
|
void verifyUnfilter();
|
||||||
bool scan(const upx_byte *buf, unsigned buf_len);
|
bool scan(SPAN_0(const byte) buf, unsigned buf_len);
|
||||||
|
|
||||||
static bool isValidFilter(int filter_id);
|
static bool isValidFilter(int filter_id);
|
||||||
static bool isValidFilter(int filter_id, const int *allowed_filters);
|
static bool isValidFilter(int filter_id, const int *allowed_filters);
|
||||||
@@ -67,7 +60,7 @@ 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 = nullptr;
|
byte *buf = nullptr;
|
||||||
unsigned buf_len = 0;
|
unsigned buf_len = 0;
|
||||||
|
|
||||||
// Checksum of the buffer before applying the filter
|
// Checksum of the buffer before applying the filter
|
||||||
@@ -79,7 +72,7 @@ public:
|
|||||||
const int *preferred_ctos = nullptr;
|
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
|
byte cto; // call trick offset
|
||||||
|
|
||||||
// Output used by various filters. Read only.
|
// Output used by various filters. Read only.
|
||||||
unsigned calls;
|
unsigned calls;
|
||||||
@@ -87,16 +80,15 @@ public:
|
|||||||
unsigned wrongcalls;
|
unsigned wrongcalls;
|
||||||
unsigned firstcall;
|
unsigned firstcall;
|
||||||
unsigned lastcall;
|
unsigned lastcall;
|
||||||
unsigned n_mru; // ctojr only
|
unsigned n_mru; // ctojr only
|
||||||
|
|
||||||
// Read only.
|
// Read only.
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
private:
|
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,19 +96,19 @@ private:
|
|||||||
// This class is private to Filter - don't look.
|
// This class is private to Filter - don't look.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class FilterImp
|
class FilterImpl final {
|
||||||
{
|
|
||||||
friend class Filter;
|
friend class Filter;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FilterEntry
|
explicit FilterImpl() noexcept DELETED_FUNCTION;
|
||||||
{
|
|
||||||
int id; // 0 .. 255
|
struct FilterEntry {
|
||||||
|
int id; // 0 .. 255
|
||||||
unsigned min_buf_len;
|
unsigned min_buf_len;
|
||||||
unsigned max_buf_len;
|
unsigned max_buf_len;
|
||||||
int (*do_filter)(Filter *); // filter a buffer
|
int (*do_filter)(Filter *); // filter a buffer
|
||||||
int (*do_unfilter)(Filter *); // unfilter a buffer
|
int (*do_unfilter)(Filter *); // unfilter a buffer
|
||||||
int (*do_scan)(Filter *); // scan a buffer
|
int (*do_scan)(Filter *); // scan a buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
// get a specific filter entry
|
// get a specific filter entry
|
||||||
@@ -125,10 +117,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
// strictly private filter database
|
// strictly private filter database
|
||||||
static const FilterEntry filters[];
|
static const FilterEntry filters[];
|
||||||
static const int n_filters; // number of filters[]
|
static const int n_filters; // number of filters[]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+181
-250
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,434 +25,325 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 16-bit calltrick ("naive")
|
// 16-bit calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT16(f, cond, addvalue, get, set) \
|
#define CT16(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 3; \
|
byte *b_end = b + f->buf_len - 3; \
|
||||||
do { \
|
do { \
|
||||||
if (cond) \
|
if (cond) { \
|
||||||
{ \
|
b += 1; \
|
||||||
b += 1; \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(b, get(b) + (addvalue)); \
|
||||||
set(b, get(b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
b += 2 - 1; \
|
||||||
b += 2 - 1; \
|
} \
|
||||||
} \
|
} while (++b < b_end); \
|
||||||
} while (++b < b_end); \
|
if (f->lastcall) \
|
||||||
if (f->lastcall) f->lastcall += 2; \
|
f->lastcall += 2; \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9
|
// filter: e8, e9, e8e9
|
||||||
static int f_ct16_e8(Filter *f)
|
static int f_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int f_ct16_e9(Filter *f)
|
static int f_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int f_ct16_e8e9(Filter *f)
|
static int f_ct16_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9
|
// unfilter: e8, e9, e8e9
|
||||||
static int u_ct16_e8(Filter *f)
|
static int u_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int u_ct16_e9(Filter *f)
|
static int u_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int u_ct16_e8e9(Filter *f)
|
static int u_ct16_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9
|
// scan: e8, e9, e8e9
|
||||||
static int s_ct16_e8(Filter *f)
|
static int s_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s_ct16_e9(Filter *f)
|
static int s_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) }
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s_ct16_e8e9(Filter *f)
|
static int s_ct16_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9 with bswap le->be
|
// filter: e8, e9, e8e9 with bswap le->be
|
||||||
static int f_ct16_e8_bswap_le(Filter *f)
|
static int f_ct16_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct16_e9_bswap_le(Filter *f)
|
static int f_ct16_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct16_e8e9_bswap_le(Filter *f)
|
static int f_ct16_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9 with bswap le->be
|
// unfilter: e8, e9, e8e9 with bswap le->be
|
||||||
static int u_ct16_e8_bswap_le(Filter *f)
|
static int u_ct16_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct16_e9_bswap_le(Filter *f)
|
static int u_ct16_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct16_e8e9_bswap_le(Filter *f)
|
static int u_ct16_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9 with bswap le->be
|
// scan: e8, e9, e8e9 with bswap le->be
|
||||||
static int s_ct16_e8_bswap_le(Filter *f)
|
static int s_ct16_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy)
|
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct16_e9_bswap_le(Filter *f)
|
static int s_ct16_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy)
|
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct16_e8e9_bswap_le(Filter *f)
|
static int s_ct16_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9 with bswap be->le
|
// filter: e8, e9, e8e9 with bswap be->le
|
||||||
static int f_ct16_e8_bswap_be(Filter *f)
|
static int f_ct16_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct16_e9_bswap_be(Filter *f)
|
static int f_ct16_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct16_e8e9_bswap_be(Filter *f)
|
static int f_ct16_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9 with bswap be->le
|
// unfilter: e8, e9, e8e9 with bswap be->le
|
||||||
static int u_ct16_e8_bswap_be(Filter *f)
|
static int u_ct16_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct16_e9_bswap_be(Filter *f)
|
static int u_ct16_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct16_e8e9_bswap_be(Filter *f)
|
static int u_ct16_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9 with bswap be->le
|
// scan: e8, e9, e8e9 with bswap be->le
|
||||||
static int s_ct16_e8_bswap_be(Filter *f)
|
static int s_ct16_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct16_e9_bswap_be(Filter *f)
|
static int s_ct16_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct16_e8e9_bswap_be(Filter *f)
|
static int s_ct16_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef CT16
|
#undef CT16
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 32-bit calltrick ("naive")
|
// 32-bit calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT32(f, cond, addvalue, get, set) \
|
#define CT32(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 5; \
|
byte *b_end = b + f->buf_len - 5; \
|
||||||
do { \
|
do { \
|
||||||
if (cond) \
|
if (cond) { \
|
||||||
{ \
|
b += 1; \
|
||||||
b += 1; \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(b, get(b) + (addvalue)); \
|
||||||
set(b, get(b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
b += 4 - 1; \
|
||||||
b += 4 - 1; \
|
} \
|
||||||
} \
|
} while (++b < b_end); \
|
||||||
} while (++b < b_end); \
|
if (f->lastcall) \
|
||||||
if (f->lastcall) f->lastcall += 4; \
|
f->lastcall += 4; \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9
|
// filter: e8, e9, e8e9
|
||||||
static int f_ct32_e8(Filter *f)
|
static int f_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int f_ct32_e9(Filter *f)
|
static int f_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int f_ct32_e8e9(Filter *f)
|
static int f_ct32_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9
|
// unfilter: e8, e9, e8e9
|
||||||
static int u_ct32_e8(Filter *f)
|
static int u_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int u_ct32_e9(Filter *f)
|
static int u_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int u_ct32_e8e9(Filter *f)
|
static int u_ct32_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9
|
// scan: e8, e9, e8e9
|
||||||
static int s_ct32_e8(Filter *f)
|
static int s_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s_ct32_e9(Filter *f)
|
static int s_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) }
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s_ct32_e8e9(Filter *f)
|
static int s_ct32_e8e9(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9 with bswap le->be
|
// filter: e8, e9, e8e9 with bswap le->be
|
||||||
static int f_ct32_e8_bswap_le(Filter *f)
|
static int f_ct32_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct32_e9_bswap_le(Filter *f)
|
static int f_ct32_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct32_e8e9_bswap_le(Filter *f)
|
static int f_ct32_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9 with bswap le->be
|
// unfilter: e8, e9, e8e9 with bswap le->be
|
||||||
static int u_ct32_e8_bswap_le(Filter *f)
|
static int u_ct32_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct32_e9_bswap_le(Filter *f)
|
static int u_ct32_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct32_e8e9_bswap_le(Filter *f)
|
static int u_ct32_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9 with bswap le->be
|
// scan: e8, e9, e8e9 with bswap le->be
|
||||||
static int s_ct32_e8_bswap_le(Filter *f)
|
static int s_ct32_e8_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy)
|
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct32_e9_bswap_le(Filter *f)
|
static int s_ct32_e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy)
|
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct32_e8e9_bswap_le(Filter *f)
|
static int s_ct32_e8e9_bswap_le(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// filter: e8, e9, e8e9 with bswap be->le
|
// filter: e8, e9, e8e9 with bswap be->le
|
||||||
static int f_ct32_e8_bswap_be(Filter *f)
|
static int f_ct32_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct32_e9_bswap_be(Filter *f)
|
static int f_ct32_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ct32_e8e9_bswap_be(Filter *f)
|
static int f_ct32_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter: e8, e9, e8e9 with bswap be->le
|
// unfilter: e8, e9, e8e9 with bswap be->le
|
||||||
static int u_ct32_e8_bswap_be(Filter *f)
|
static int u_ct32_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct32_e9_bswap_be(Filter *f)
|
static int u_ct32_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct32_e8e9_bswap_be(Filter *f)
|
static int u_ct32_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan: e8, e9, e8e9 with bswap be->le
|
// scan: e8, e9, e8e9 with bswap be->le
|
||||||
static int s_ct32_e8_bswap_be(Filter *f)
|
static int s_ct32_e8_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct32_e9_bswap_be(Filter *f)
|
static int s_ct32_e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct32_e8e9_bswap_be(Filter *f)
|
static int s_ct32_e8e9_bswap_be(Filter *f) {
|
||||||
{
|
|
||||||
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef CT32
|
#undef CT32
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 24-bit ARM calltrick ("naive")
|
// 24-bit ARM calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 4; \
|
byte *b_end = b + f->buf_len - 4; \
|
||||||
do { \
|
do { \
|
||||||
if (cond) \
|
if (cond) { \
|
||||||
{ \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(b, get(b) + (addvalue)); \
|
||||||
set(b, get(b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
} \
|
||||||
} \
|
b += 4; \
|
||||||
b += 4; \
|
} while (b < b_end); \
|
||||||
} while (b < b_end); \
|
if (f->lastcall) \
|
||||||
if (f->lastcall) f->lastcall += 4; \
|
f->lastcall += 4; \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
static int f_ct24arm_le(Filter *f)
|
static int f_ct24arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct24arm_le(Filter *f)
|
static int u_ct24arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct24arm_le(Filter *f)
|
static int s_ct24arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CT24ARM_LE
|
#undef CT24ARM_LE
|
||||||
|
|
||||||
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 4; \
|
byte *b_end = b + f->buf_len - 4; \
|
||||||
do { \
|
do { \
|
||||||
if (cond) \
|
if (cond) { \
|
||||||
{ \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(1 + b, get(1 + b) + (addvalue)); \
|
||||||
set(1+b, get(1+b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
} \
|
||||||
} \
|
b += 4; \
|
||||||
b += 4; \
|
} while (b < b_end); \
|
||||||
} while (b < b_end); \
|
if (f->lastcall) \
|
||||||
if (f->lastcall) f->lastcall += 4; \
|
f->lastcall += 4; \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
|
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
static int f_ct24arm_be(Filter *f)
|
static int f_ct24arm_be(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
|
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct24arm_be(Filter *f)
|
static int u_ct24arm_be(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
|
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct24arm_be(Filter *f)
|
static int s_ct24arm_be(Filter *f) {
|
||||||
{
|
|
||||||
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
|
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,40 +354,80 @@ static int s_ct24arm_be(Filter *f)
|
|||||||
// 26-bit ARM calltrick ("naive")
|
// 26-bit ARM calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
#if 1 //{ old reliable
|
||||||
upx_byte *b = f->buf; \
|
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b_end = b + f->buf_len - 4; \
|
byte *b = f->buf; \
|
||||||
do { \
|
byte *b_end = b + f->buf_len - 4; \
|
||||||
if (cond) \
|
do { \
|
||||||
{ \
|
if (cond) { \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
f->lastcall = a; \
|
f->lastcall = a; \
|
||||||
set(b, get(b) + (addvalue)); \
|
set(b, get(b) + (addvalue)); \
|
||||||
f->calls++; \
|
f->calls++; \
|
||||||
} \
|
} \
|
||||||
b += 4; \
|
b += 4; \
|
||||||
} while (b < b_end); \
|
} while (b < b_end); \
|
||||||
if (f->lastcall) f->lastcall += 4; \
|
if (f->lastcall) \
|
||||||
|
f->lastcall += 4; \
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
#define ARMCT_COND (((b[3] & 0x7C) == 0x14))
|
#define ARMCT_COND (((b[3] & 0x7C) == 0x14))
|
||||||
|
|
||||||
static int f_ct26arm_le(Filter *f)
|
static int f_ct26arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26)
|
CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct26arm_le(Filter *f)
|
static int u_ct26arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26)
|
CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct26arm_le(Filter *f)
|
static int s_ct26arm_le(Filter *f) {
|
||||||
{
|
|
||||||
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
|
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else //}{ new enhanced but DIFFERENT; need new filter type!
|
||||||
|
|
||||||
|
static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
|
||||||
|
{
|
||||||
|
upx_byte *b = f->buf; // will be incremented
|
||||||
|
upx_byte *const b_end = b + f->buf_len - 4;
|
||||||
|
do {
|
||||||
|
unsigned const a = b - f->buf;
|
||||||
|
int const d = dir * (f->addvalue + (a >> 2));
|
||||||
|
unsigned const v = get_le32(f->buf); // the 32-bit instruction
|
||||||
|
if (0x05 == (0x1f & (v >> 26))) { // b, bl
|
||||||
|
f->lastcall = a;
|
||||||
|
if (dir)
|
||||||
|
set_le26(b, v + d);
|
||||||
|
f->calls++;
|
||||||
|
} else if ((0x54 == (v >> 24)) // b.cond
|
||||||
|
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|
||||||
|
) {
|
||||||
|
f->lastcall = a;
|
||||||
|
if (dir)
|
||||||
|
set_le19_5(b, (v >> 5) + d);
|
||||||
|
f->calls++;
|
||||||
|
} else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
|
||||||
|
f->lastcall = a;
|
||||||
|
if (dir)
|
||||||
|
set_le14_5(b, (v >> 5) + d);
|
||||||
|
f->calls++;
|
||||||
|
}
|
||||||
|
b += 4;
|
||||||
|
} while (b < b_end);
|
||||||
|
if (f->lastcall)
|
||||||
|
f->lastcall += 4;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int f_CTarm64_le(Filter *f) { return CTarm64(f, 1); }
|
||||||
|
|
||||||
|
static int u_CTarm64_le(Filter *f) { return CTarm64(f, -1); }
|
||||||
|
|
||||||
|
static int s_CTarm64_le(Filter *f) { return CTarm64(f, 0); }
|
||||||
|
|
||||||
|
#endif //}
|
||||||
|
|
||||||
#undef CT26ARM_LE
|
#undef CT26ARM_LE
|
||||||
#undef ARMCT_COND
|
#undef ARMCT_COND
|
||||||
|
|
||||||
|
|||||||
+36
-54
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,20 +25,17 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// filter / scan
|
// filter / scan
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int F(Filter *f)
|
static int F(Filter *f) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// filter
|
// filter
|
||||||
upx_byte *b = f->buf;
|
byte *b = f->buf;
|
||||||
#else
|
#else
|
||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const byte *b = f->buf;
|
||||||
#endif
|
#endif
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned size = f->buf_len;
|
const unsigned size = f->buf_len;
|
||||||
@@ -50,25 +47,22 @@ static int F(Filter *f)
|
|||||||
// find a 16 MiB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
// A call to a destination that is inside the buffer
|
// A call to a destination that is inside the buffer
|
||||||
// will be rewritten and marked with cto8 as first byte.
|
// will be rewritten and marked with cto8 as first byte.
|
||||||
// So, a call to a destination that is outside the buffer
|
// So, a call to a destination that is outside the buffer
|
||||||
// must not conflict with the mark.
|
// must not conflict with the mark.
|
||||||
// Note that unsigned comparison checks both edges of buffer.
|
// Note that unsigned comparison checks both edges of buffer.
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic))
|
||||||
if (!COND(b,ic))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else
|
||||||
else
|
buf[b[ic + 1]] |= 1;
|
||||||
buf[b[ic+1]] |= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getcto(f, buf) < 0)
|
if (getcto(f, buf) < 0)
|
||||||
@@ -76,35 +70,31 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
const unsigned char cto8 = f->cto;
|
const unsigned char cto8 = f->cto;
|
||||||
#ifdef U
|
#ifdef U
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic))
|
||||||
if (!COND(b,ic))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||||
#endif
|
#endif
|
||||||
if (ic - lastnoncall < 5)
|
if (ic - lastnoncall < 5) {
|
||||||
{
|
|
||||||
// check the last 4 bytes before this call
|
// check the last 4 bytes before this call
|
||||||
for (kc = 4; kc; kc--)
|
for (kc = 4; kc; kc--)
|
||||||
if (COND(b,ic-kc) && b[ic-kc+1] == cto8)
|
if (COND(b, ic - kc) && b[ic - kc + 1] == cto8)
|
||||||
break;
|
break;
|
||||||
if (kc)
|
if (kc) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// restore original
|
// restore original
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
#endif
|
#endif
|
||||||
if (b[ic+1] == cto8)
|
if (b[ic + 1] == cto8)
|
||||||
return 1; // fail - buffer not restored
|
return 1; // fail - buffer not restored
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls2++;
|
noncalls2++;
|
||||||
continue;
|
continue;
|
||||||
@@ -112,11 +102,9 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
calls++;
|
calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
lastcall = ic+1;
|
lastcall = ic + 1;
|
||||||
}
|
} else {
|
||||||
else
|
assert(b[ic + 1] != cto8); // this should not happen
|
||||||
{
|
|
||||||
assert(b[ic+1] != cto8); // this should not happen
|
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls++;
|
noncalls++;
|
||||||
}
|
}
|
||||||
@@ -133,40 +121,34 @@ static int F(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// unfilter
|
// unfilter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
static int U(Filter *f)
|
static int U(Filter *f) {
|
||||||
{
|
byte *b = f->buf;
|
||||||
upx_byte *b = f->buf;
|
|
||||||
const unsigned size5 = f->buf_len - 5;
|
const unsigned size5 = f->buf_len - 5;
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
|
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
|
|
||||||
for (ic = 0; ic < size5; ic++)
|
for (ic = 0; ic < size5; ic++)
|
||||||
if (COND(b,ic))
|
if (COND(b, ic)) {
|
||||||
{
|
jc = get_be32(b + ic + 1);
|
||||||
jc = get_be32(b+ic+1);
|
if (b[ic + 1] == f->cto) {
|
||||||
if (b[ic+1] == f->cto)
|
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||||
{
|
|
||||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
|
||||||
f->calls++;
|
f->calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
f->lastcall = ic+1;
|
f->lastcall = ic + 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
f->noncalls++;
|
f->noncalls++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
#undef U
|
#undef U
|
||||||
|
|
||||||
|
|||||||
+38
-56
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 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
|
||||||
@@ -29,20 +29,17 @@
|
|||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// filter / scan
|
// filter / scan
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int F(Filter *f)
|
static int F(Filter *f) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// filter
|
// filter
|
||||||
upx_byte *b = f->buf;
|
byte *b = f->buf;
|
||||||
#else
|
#else
|
||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const byte *b = f->buf;
|
||||||
#endif
|
#endif
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned size = f->buf_len;
|
const unsigned size = f->buf_len;
|
||||||
@@ -54,20 +51,17 @@ static int F(Filter *f)
|
|||||||
// find a 16 MiB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic, lastcall))
|
||||||
if (!COND(b,ic,lastcall))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else
|
||||||
else
|
buf[b[ic + 1]] |= 1;
|
||||||
buf[b[ic+1]] |= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getcto(f, buf) < 0)
|
if (getcto(f, buf) < 0)
|
||||||
@@ -75,35 +69,31 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
const unsigned char cto8 = f->cto;
|
const unsigned char cto8 = f->cto;
|
||||||
#ifdef U
|
#ifdef U
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic, lastcall))
|
||||||
if (!COND(b,ic,lastcall))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||||
#endif
|
#endif
|
||||||
if (ic - lastnoncall < 5)
|
if (ic - lastnoncall < 5) {
|
||||||
{
|
|
||||||
// check the last 4 bytes before this call
|
// check the last 4 bytes before this call
|
||||||
for (kc = 4; kc; kc--)
|
for (kc = 4; kc; kc--)
|
||||||
if (COND(b,ic-kc,lastcall) && b[ic-kc+1] == cto8)
|
if (COND(b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
|
||||||
break;
|
break;
|
||||||
if (kc)
|
if (kc) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// restore original
|
// restore original
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
#endif
|
#endif
|
||||||
if (b[ic+1] == cto8)
|
if (b[ic + 1] == cto8)
|
||||||
return 1; // fail - buffer not restored
|
return 1; // fail - buffer not restored
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls2++;
|
noncalls2++;
|
||||||
continue;
|
continue;
|
||||||
@@ -111,11 +101,9 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
calls++;
|
calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
lastcall = ic+1;
|
lastcall = ic + 1;
|
||||||
}
|
} else {
|
||||||
else
|
assert(b[ic + 1] != cto8); // this should not happen
|
||||||
{
|
|
||||||
assert(b[ic+1] != cto8); // this should not happen
|
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls++;
|
noncalls++;
|
||||||
}
|
}
|
||||||
@@ -132,40 +120,34 @@ static int F(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// unfilter
|
// unfilter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
static int U(Filter *f)
|
static int U(Filter *f) {
|
||||||
{
|
byte *b = f->buf;
|
||||||
upx_byte *b = f->buf;
|
|
||||||
const unsigned size5 = f->buf_len - 5;
|
const unsigned size5 = f->buf_len - 5;
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
// unsigned lastcall = 0; // lastcall is not used in COND macro
|
// unsigned lastcall = 0; // lastcall is not used in COND macro
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
|
|
||||||
for (ic = 0; ic < size5; ic++)
|
for (ic = 0; ic < size5; ic++)
|
||||||
if (COND(b,ic,lastcall))
|
if (COND(b, ic, lastcall)) {
|
||||||
{
|
jc = get_be32(b + ic + 1);
|
||||||
jc = get_be32(b+ic+1);
|
if (b[ic + 1] == f->cto) {
|
||||||
if (b[ic+1] == f->cto)
|
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||||
{
|
|
||||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
|
||||||
f->calls++;
|
f->calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
f->lastcall = ic+1;
|
f->lastcall = ic + 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
f->noncalls++;
|
f->noncalls++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
#undef U
|
#undef U
|
||||||
|
|
||||||
|
|||||||
+122
-164
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 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
|
||||||
@@ -29,111 +29,90 @@
|
|||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300))
|
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300))
|
||||||
# pragma warning(disable: 4702) // W4: unreachable code
|
#pragma warning(disable : 4702) // W4: unreachable code
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// filter / scan
|
// filter / scan
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifdef U //{
|
#ifdef U //{
|
||||||
#define NOFILT 0 // no filter
|
#define NOFILT 0 // no filter
|
||||||
#define FNOMRU 1 // filter, but not using mru
|
#define FNOMRU 1 // filter, but not using mru
|
||||||
#define MRUFLT 2 // mru filter
|
#define MRUFLT 2 // mru filter
|
||||||
|
|
||||||
static unsigned
|
static unsigned f80_call(Filter const *f) { return (1 + (0x0f & f->id)) % 3; }
|
||||||
f80_call(Filter const *f)
|
|
||||||
{
|
|
||||||
return (1+ (0x0f & f->id)) % 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned f80_jmp1(Filter const *f) { return ((1 + (0x0f & f->id)) / 3) % 3; }
|
||||||
f80_jmp1(Filter const *f)
|
|
||||||
{
|
|
||||||
return ((1+ (0x0f & f->id)) / 3) % 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned f80_jcc2(Filter const *f) { return f80_jmp1(f); }
|
||||||
f80_jcc2(Filter const *f)
|
|
||||||
{
|
|
||||||
return f80_jmp1(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define N_MRU 32 // does not have to be a power of 2
|
#define N_MRU 32 // does not have to be a power of 2
|
||||||
|
|
||||||
// Adaptively remember recent destinations.
|
// Adaptively remember recent destinations.
|
||||||
static void
|
static void update_mru(const unsigned jc, // destination address
|
||||||
update_mru(
|
const int kh, // mru[kh] is slot where found
|
||||||
unsigned const jc, // destination address
|
unsigned mru[N_MRU], // circular buffer of most recent destinations
|
||||||
int const kh, // mru[kh] is slot where found
|
int &hand, // mru[hand] is most recent destination
|
||||||
unsigned mru[N_MRU], // circular buffer of most recent destinations
|
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
|
||||||
int &hand, // mru[hand] is most recent destination
|
) {
|
||||||
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (0 > --hand) {
|
if (0 > --hand) {
|
||||||
hand = N_MRU -1;
|
hand = N_MRU - 1;
|
||||||
}
|
}
|
||||||
unsigned const t = mru[hand]; // entry which will be overwritten by jc
|
const unsigned t = mru[hand]; // entry which will be overwritten by jc
|
||||||
if (0!=t) { // have seen at least N_MRU destinations
|
if (0 != t) { // have seen at least N_MRU destinations
|
||||||
mru[kh] = t;
|
mru[kh] = t;
|
||||||
}
|
} else { // "cold cache": keep active region contiguous
|
||||||
else { // "cold cache": keep active region contiguous
|
|
||||||
if (0 > --tail) {
|
if (0 > --tail) {
|
||||||
tail = N_MRU -1;
|
tail = N_MRU - 1;
|
||||||
}
|
}
|
||||||
unsigned const t2 = mru[tail];
|
const unsigned t2 = mru[tail];
|
||||||
mru[tail] = 0;
|
mru[tail] = 0;
|
||||||
mru[kh] = t2;
|
mru[kh] = t2;
|
||||||
}
|
}
|
||||||
mru[hand] = jc;
|
mru[hand] = jc;
|
||||||
}
|
}
|
||||||
#endif //}
|
#endif //}
|
||||||
|
|
||||||
|
static int F(Filter *f) {
|
||||||
static int F(Filter *f)
|
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// filter
|
// filter
|
||||||
upx_byte *const b = f->buf;
|
byte *const b = f->buf;
|
||||||
#else
|
#else
|
||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const byte *b = f->buf;
|
||||||
#endif
|
#endif
|
||||||
const unsigned size = f->buf_len;
|
const unsigned size = f->buf_len;
|
||||||
|
|
||||||
unsigned ic, jc, kc;
|
unsigned ic, jc, kc;
|
||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
unsigned lastnoncall = size, lastcall = 0;
|
unsigned lastnoncall = size, lastcall = 0;
|
||||||
unsigned wtally[3]; memset(wtally, 0, sizeof(wtally));
|
unsigned wtally[3];
|
||||||
|
memset(wtally, 0, sizeof(wtally));
|
||||||
|
|
||||||
#ifdef U //{
|
#ifdef U //{
|
||||||
unsigned const f_call = f80_call(f);
|
const unsigned f_call = f80_call(f);
|
||||||
unsigned const f_jmp1 = f80_jmp1(f);
|
const unsigned f_jmp1 = f80_jmp1(f);
|
||||||
unsigned const f_jcc2 = f80_jcc2(f);
|
const unsigned f_jcc2 = f80_jcc2(f);
|
||||||
|
|
||||||
int hand = 0, tail = 0;
|
int hand = 0, tail = 0;
|
||||||
unsigned mru[N_MRU];
|
unsigned mru[N_MRU];
|
||||||
memset(&mru[0], 0, sizeof(mru));
|
memset(&mru[0], 0, sizeof(mru));
|
||||||
assert(N_MRU<=256);
|
assert(N_MRU <= 256);
|
||||||
f->n_mru = (MRUFLT==f_call || MRUFLT==f_jmp1 || MRUFLT==f_jcc2) ?
|
f->n_mru = (MRUFLT == f_call || MRUFLT == f_jmp1 || MRUFLT == f_jcc2) ? N_MRU : 0;
|
||||||
N_MRU : 0;
|
#endif //}
|
||||||
#endif //}
|
|
||||||
|
|
||||||
// FIXME: We must fit into 8 MiB because we steal one bit.
|
// FIXME: We must fit into 8 MiB because we steal one bit.
|
||||||
// find a 16 MiB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
int which;
|
int which;
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++)
|
||||||
if (CONDF(which,b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
|
if (CONDF(which, b, ic, lastcall) && get_le32(b + ic + 1) + ic + 1 >= size) {
|
||||||
{
|
buf[b[ic + 1]] |= 1;
|
||||||
buf[b[ic+1]] |= 1;
|
|
||||||
}
|
}
|
||||||
UNUSED(which);
|
UNUSED(which);
|
||||||
|
|
||||||
@@ -142,37 +121,33 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
const unsigned char cto8 = f->cto;
|
const unsigned char cto8 = f->cto;
|
||||||
#ifdef U
|
#ifdef U
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
|
||||||
int which;
|
int which;
|
||||||
int f_on = 0;
|
int f_on = 0;
|
||||||
if (!CONDF(which,b,ic,lastcall))
|
if (!CONDF(which, b, ic, lastcall))
|
||||||
continue;
|
continue;
|
||||||
++wtally[which];
|
++wtally[which];
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
if (2==which && NOFILT!=f_jcc2) { // 6-byte Jcc <disp32>
|
if (2 == which && NOFILT != f_jcc2) { // 6-byte Jcc <disp32>
|
||||||
// Prefix 0x0f is constant, but opcode condition 0x80..0x8f
|
// Prefix 0x0f is constant, but opcode condition 0x80..0x8f
|
||||||
// varies. Because we store the destination (or its mru index)
|
// varies. Because we store the destination (or its mru index)
|
||||||
// in be32 big endian format, the low-addressed bytes
|
// in be32 big endian format, the low-addressed bytes
|
||||||
// will tend to be constant. Swap prefix and opcode
|
// will tend to be constant. Swap prefix and opcode
|
||||||
// so that constants are together for better compression.
|
// so that constants are together for better compression.
|
||||||
unsigned char const t =
|
unsigned char const t = b[ic - 1];
|
||||||
b[ic-1];
|
b[ic - 1] = b[ic];
|
||||||
b[ic-1] = b[ic];
|
b[ic] = t;
|
||||||
b[ic] = t;
|
|
||||||
}
|
}
|
||||||
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
|
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
|
||||||
// This will require two related cto's (consecutive, or otherwise).
|
// This will require two related cto's (consecutive, or otherwise).
|
||||||
if ((0==which && MRUFLT==f_call)
|
if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|
||||||
|| (1==which && MRUFLT==f_jmp1)
|
(2 == which && MRUFLT == f_jcc2)) {
|
||||||
|| (2==which && MRUFLT==f_jcc2) ) {
|
|
||||||
f_on = 1;
|
f_on = 1;
|
||||||
// Recode the destination: narrower mru indices
|
// Recode the destination: narrower mru indices
|
||||||
// should compress better than wider addresses.
|
// should compress better than wider addresses.
|
||||||
@@ -184,62 +159,55 @@ static int F(Filter *f)
|
|||||||
kh -= N_MRU;
|
kh -= N_MRU;
|
||||||
}
|
}
|
||||||
if (mru[kh] == jc) { // destination was seen recently
|
if (mru[kh] == jc) { // destination was seen recently
|
||||||
set_be32(b+ic+1,((k<<1)|0)+cto);
|
set_be32(b + ic + 1, ((k << 1) | 0) + cto);
|
||||||
update_mru(jc, kh, mru, hand, tail);
|
update_mru(jc, kh, mru, hand, tail);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (k == N_MRU) { // loop failed; jc is not in mru[]
|
if (k == N_MRU) { // loop failed; jc is not in mru[]
|
||||||
set_be32(b+ic+1,((jc<<1)|1)+cto);
|
set_be32(b + ic + 1, ((jc << 1) | 1) + cto);
|
||||||
// Adaptively remember recent destinations.
|
// Adaptively remember recent destinations.
|
||||||
if (0 > --hand) {
|
if (0 > --hand) {
|
||||||
hand = N_MRU -1;
|
hand = N_MRU - 1;
|
||||||
}
|
}
|
||||||
mru[hand] = jc;
|
mru[hand] = jc;
|
||||||
}
|
}
|
||||||
} else
|
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
|
||||||
if ((0==which && NOFILT!=f_call)
|
(2 == which && NOFILT != f_jcc2)) {
|
||||||
|| (1==which && NOFILT!=f_jmp1)
|
|
||||||
|| (2==which && NOFILT!=f_jcc2) ) {
|
|
||||||
f_on = 1;
|
f_on = 1;
|
||||||
set_be32(b+ic+1, jc+cto);
|
set_be32(b + ic + 1, jc + cto);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (f_on) {
|
if (f_on) {
|
||||||
if (ic - lastnoncall < 5)
|
if (ic - lastnoncall < 5) {
|
||||||
{
|
// check the last 4 bytes before this call
|
||||||
// check the last 4 bytes before this call
|
for (kc = 4; kc; kc--)
|
||||||
for (kc = 4; kc; kc--)
|
if (CONDF(which, b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
|
||||||
if (CONDF(which,b,ic-kc,lastcall) && b[ic-kc+1] == cto8)
|
break;
|
||||||
break;
|
if (kc) {
|
||||||
if (kc)
|
#ifdef U
|
||||||
{
|
// restore original
|
||||||
#ifdef U
|
if (2 == which) {
|
||||||
// restore original
|
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
||||||
if (2==which) {
|
unsigned char const t = b[ic - 1];
|
||||||
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
b[ic - 1] = b[ic];
|
||||||
unsigned char const t =
|
b[ic] = t;
|
||||||
b[ic-1];
|
|
||||||
b[ic-1] = b[ic];
|
|
||||||
b[ic] = t;
|
|
||||||
}
|
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
|
||||||
#endif
|
|
||||||
if (b[ic+1] == cto8)
|
|
||||||
return 1; // fail - buffer not restored
|
|
||||||
lastnoncall = ic;
|
|
||||||
noncalls2++;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
|
#endif
|
||||||
|
if (b[ic + 1] == cto8)
|
||||||
|
return 1; // fail - buffer not restored
|
||||||
|
lastnoncall = ic;
|
||||||
|
noncalls2++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
calls++;
|
}
|
||||||
ic += 4;
|
calls++;
|
||||||
lastcall = ic+1;
|
ic += 4;
|
||||||
|
lastcall = ic + 1;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
assert(b[ic + 1] != cto8); // this should not happen
|
||||||
{
|
|
||||||
assert(b[ic+1] != cto8); // this should not happen
|
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls++;
|
noncalls++;
|
||||||
}
|
}
|
||||||
@@ -258,82 +226,72 @@ static int F(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// unfilter
|
// unfilter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
static int U(Filter *f)
|
static int U(Filter *f) {
|
||||||
{
|
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
|
|
||||||
upx_byte *const b = f->buf;
|
byte *const b = f->buf;
|
||||||
const unsigned size5 = f->buf_len - 5;
|
const unsigned size5 = f->buf_len - 5;
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
unsigned lastcall = 0;
|
unsigned lastcall = 0;
|
||||||
int hand = 0, tail = 0;
|
int hand = 0, tail = 0;
|
||||||
unsigned const f_call = f80_call(f);
|
const unsigned f_call = f80_call(f);
|
||||||
unsigned const f_jmp1 = f80_jmp1(f);
|
const unsigned f_jmp1 = f80_jmp1(f);
|
||||||
unsigned const f_jcc2 = f80_jcc2(f);
|
const unsigned f_jcc2 = f80_jcc2(f);
|
||||||
|
|
||||||
unsigned mru[N_MRU];
|
unsigned mru[N_MRU];
|
||||||
memset(&mru[0], 0, sizeof(mru));
|
memset(&mru[0], 0, sizeof(mru));
|
||||||
|
|
||||||
for (ic = 0; ic < size5; ic++) {
|
for (ic = 0; ic < size5; ic++) {
|
||||||
int which;
|
int which;
|
||||||
if (CONDU(which,b,ic,lastcall))
|
if (CONDU(which, b, ic, lastcall)) {
|
||||||
{
|
|
||||||
unsigned f_on = 0;
|
unsigned f_on = 0;
|
||||||
jc = get_be32(b+ic+1) - cto;
|
jc = get_be32(b + ic + 1) - cto;
|
||||||
if (b[ic+1] == f->cto)
|
if (b[ic + 1] == f->cto) {
|
||||||
{
|
if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|
||||||
if ((0==which && MRUFLT==f_call)
|
(2 == which && MRUFLT == f_jcc2)) {
|
||||||
|| (1==which && MRUFLT==f_jmp1)
|
|
||||||
|| (2==which && MRUFLT==f_jcc2) ) {
|
|
||||||
f_on = 1;
|
f_on = 1;
|
||||||
if (1&jc) { // 1st time at this destination
|
if (1 & jc) { // 1st time at this destination
|
||||||
jc >>= 1;
|
jc >>= 1;
|
||||||
if (0 > --hand) {
|
if (0 > --hand) {
|
||||||
hand = N_MRU -1;
|
hand = N_MRU - 1;
|
||||||
}
|
|
||||||
mru[hand] = jc;
|
|
||||||
}
|
}
|
||||||
else { // not 1st time at this destination
|
mru[hand] = jc;
|
||||||
jc >>= 1;
|
} else { // not 1st time at this destination
|
||||||
if (N_MRU <= jc) {
|
jc >>= 1;
|
||||||
throwCompressedDataViolation();
|
if (N_MRU <= jc) {
|
||||||
}
|
throwCompressedDataViolation();
|
||||||
int kh = jc + hand;
|
|
||||||
if (N_MRU <= kh) {
|
|
||||||
kh -= N_MRU;
|
|
||||||
}
|
|
||||||
jc = mru[kh];
|
|
||||||
update_mru(jc, kh, mru, hand, tail);
|
|
||||||
}
|
}
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
int kh = jc + hand;
|
||||||
} else
|
if (N_MRU <= kh) {
|
||||||
if ((0==which && NOFILT!=f_call)
|
kh -= N_MRU;
|
||||||
|| (1==which && NOFILT!=f_jmp1)
|
}
|
||||||
|| (2==which && NOFILT!=f_jcc2) ) {
|
jc = mru[kh];
|
||||||
|
update_mru(jc, kh, mru, hand, tail);
|
||||||
|
}
|
||||||
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
|
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
|
||||||
|
(2 == which && NOFILT != f_jcc2)) {
|
||||||
f_on = 1;
|
f_on = 1;
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
}
|
}
|
||||||
if (2==which && NOFILT!=f_jcc2) {
|
if (2 == which && NOFILT != f_jcc2) {
|
||||||
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
// Unswap prefix and opcode for 6-byte Jcc <disp32>
|
||||||
unsigned char const t =
|
unsigned char const t = b[ic - 1];
|
||||||
b[ic-1];
|
b[ic - 1] = b[ic];
|
||||||
b[ic-1] = b[ic];
|
b[ic] = t;
|
||||||
b[ic] = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_on) {
|
if (f_on) {
|
||||||
f->calls++;
|
f->calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
f->lastcall = lastcall = ic+1;
|
f->lastcall = lastcall = ic + 1;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
f->noncalls++;
|
f->noncalls++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-57
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2024 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
|
||||||
@@ -29,24 +29,21 @@
|
|||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// filter / scan
|
// filter / scan
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int F(Filter *f)
|
static int F(Filter *f) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// filter
|
// filter
|
||||||
upx_byte *b = f->buf;
|
byte *b = f->buf;
|
||||||
#else
|
#else
|
||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const byte *b = f->buf;
|
||||||
#endif
|
#endif
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned size = f->buf_len;
|
const unsigned size = f->buf_len;
|
||||||
unsigned const id = f->id;
|
const unsigned id = f->id;
|
||||||
|
|
||||||
unsigned ic, jc, kc;
|
unsigned ic, jc, kc;
|
||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
@@ -55,20 +52,17 @@ static int F(Filter *f)
|
|||||||
// find a 16 MiB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf, 0, 256);
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic, lastcall, id))
|
||||||
if (!COND(b,ic,lastcall,id))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else
|
||||||
else
|
buf[b[ic + 1]] |= 1;
|
||||||
buf[b[ic+1]] |= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getcto(f, buf) < 0)
|
if (getcto(f, buf) < 0)
|
||||||
@@ -76,35 +70,31 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
const unsigned char cto8 = f->cto;
|
const unsigned char cto8 = f->cto;
|
||||||
#ifdef U
|
#ifdef U
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
for (ic = 0; ic < size - 5; ic++) {
|
||||||
{
|
if (!COND(b, ic, lastcall, id))
|
||||||
if (!COND(b,ic,lastcall,id))
|
|
||||||
continue;
|
continue;
|
||||||
jc = get_le32(b+ic+1)+ic+1;
|
jc = get_le32(b + ic + 1) + ic + 1;
|
||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size) {
|
||||||
{
|
|
||||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b + ic + 1, jc + addvalue + cto);
|
||||||
#endif
|
#endif
|
||||||
if (ic - lastnoncall < 5)
|
if (ic - lastnoncall < 5) {
|
||||||
{
|
|
||||||
// check the last 4 bytes before this call
|
// check the last 4 bytes before this call
|
||||||
for (kc = 4; kc; kc--)
|
for (kc = 4; kc; kc--)
|
||||||
if (COND(b,ic-kc,lastcall,id) && b[ic-kc+1] == cto8)
|
if (COND(b, ic - kc, lastcall, id) && b[ic - kc + 1] == cto8)
|
||||||
break;
|
break;
|
||||||
if (kc)
|
if (kc) {
|
||||||
{
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
// restore original
|
// restore original
|
||||||
set_le32(b+ic+1,jc-ic-1);
|
set_le32(b + ic + 1, jc - ic - 1);
|
||||||
#endif
|
#endif
|
||||||
if (b[ic+1] == cto8)
|
if (b[ic + 1] == cto8)
|
||||||
return 1; // fail - buffer not restored
|
return 1; // fail - buffer not restored
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls2++;
|
noncalls2++;
|
||||||
continue;
|
continue;
|
||||||
@@ -112,11 +102,9 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
calls++;
|
calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
lastcall = ic+1;
|
lastcall = ic + 1;
|
||||||
}
|
} else {
|
||||||
else
|
assert(b[ic + 1] != cto8); // this should not happen
|
||||||
{
|
|
||||||
assert(b[ic+1] != cto8); // this should not happen
|
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls++;
|
noncalls++;
|
||||||
}
|
}
|
||||||
@@ -133,42 +121,36 @@ static int F(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// unfilter
|
// unfilter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
static int U(Filter *f)
|
static int U(Filter *f) {
|
||||||
{
|
byte *b = f->buf;
|
||||||
upx_byte *b = f->buf;
|
|
||||||
const unsigned size5 = f->buf_len - 5;
|
const unsigned size5 = f->buf_len - 5;
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
const unsigned cto = (unsigned)f->cto << 24;
|
const unsigned cto = (unsigned) f->cto << 24;
|
||||||
unsigned const id = f->id;
|
const unsigned id = f->id;
|
||||||
unsigned lastcall = 0;
|
unsigned lastcall = 0;
|
||||||
|
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
|
|
||||||
for (ic = 0; ic < size5; ic++)
|
for (ic = 0; ic < size5; ic++)
|
||||||
if (COND(b,ic,lastcall,id))
|
if (COND(b, ic, lastcall, id)) {
|
||||||
{
|
jc = get_be32(b + ic + 1);
|
||||||
jc = get_be32(b+ic+1);
|
if (b[ic + 1] == f->cto) {
|
||||||
if (b[ic+1] == f->cto)
|
set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
|
||||||
{
|
|
||||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
|
||||||
f->calls++;
|
f->calls++;
|
||||||
ic += 4;
|
ic += 4;
|
||||||
f->lastcall = lastcall = ic+1;
|
f->lastcall = lastcall = ic + 1;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
f->noncalls++;
|
f->noncalls++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
#undef U
|
#undef U
|
||||||
|
|
||||||
|
|||||||
+58
-85
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,145 +25,118 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 16-bit call-/swaptrick ("naive")
|
// 16-bit call-/swaptrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CTSW16(f, cond1, cond2, addvalue, get, set) \
|
#define CTSW16(f, cond1, cond2, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 3; \
|
byte *b_end = b + f->buf_len - 3; \
|
||||||
do { \
|
do { \
|
||||||
if (cond1) \
|
if (cond1) { \
|
||||||
{ \
|
b += 1; \
|
||||||
b += 1; \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(b, get(b) + (addvalue)); \
|
||||||
set(b, get(b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
b += 2 - 1; \
|
||||||
b += 2 - 1; \
|
} else if (cond2) { \
|
||||||
} \
|
b += 1; \
|
||||||
else if (cond2) \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
{ \
|
f->lastcall = a; \
|
||||||
b += 1; \
|
set(b, get(b)); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->calls++; \
|
||||||
f->lastcall = a; \
|
b += 2 - 1; \
|
||||||
set(b, get(b)); \
|
} \
|
||||||
f->calls++; \
|
} while (++b < b_end); \
|
||||||
b += 2 - 1; \
|
if (f->lastcall) \
|
||||||
} \
|
f->lastcall += 2; \
|
||||||
} while (++b < b_end); \
|
|
||||||
if (f->lastcall) f->lastcall += 2; \
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
// filter
|
// filter
|
||||||
static int f_ctsw16_e8_e9(Filter *f)
|
static int f_ctsw16_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ctsw16_e9_e8(Filter *f)
|
static int f_ctsw16_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
|
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter
|
// unfilter
|
||||||
static int u_ctsw16_e8_e9(Filter *f)
|
static int u_ctsw16_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ctsw16_e9_e8(Filter *f)
|
static int u_ctsw16_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
|
CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan
|
// scan
|
||||||
static int s_ctsw16_e8_e9(Filter *f)
|
static int s_ctsw16_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ctsw16_e9_e8(Filter *f)
|
static int s_ctsw16_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef CTSW16
|
#undef CTSW16
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 32-bit call-/swaptrick ("naive")
|
// 32-bit call-/swaptrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CTSW32(f, cond1, cond2, addvalue, get, set) \
|
#define CTSW32(f, cond1, cond2, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 5; \
|
byte *b_end = b + f->buf_len - 5; \
|
||||||
do { \
|
do { \
|
||||||
if (cond1) \
|
if (cond1) { \
|
||||||
{ \
|
b += 1; \
|
||||||
b += 1; \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->lastcall = a; \
|
||||||
f->lastcall = a; \
|
set(b, get(b) + (addvalue)); \
|
||||||
set(b, get(b) + (addvalue)); \
|
f->calls++; \
|
||||||
f->calls++; \
|
b += 4 - 1; \
|
||||||
b += 4 - 1; \
|
} else if (cond2) { \
|
||||||
} \
|
b += 1; \
|
||||||
else if (cond2) \
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
{ \
|
f->lastcall = a; \
|
||||||
b += 1; \
|
set(b, get(b)); \
|
||||||
unsigned a = (unsigned) (b - f->buf); \
|
f->calls++; \
|
||||||
f->lastcall = a; \
|
b += 4 - 1; \
|
||||||
set(b, get(b)); \
|
} \
|
||||||
f->calls++; \
|
} while (++b < b_end); \
|
||||||
b += 4 - 1; \
|
if (f->lastcall) \
|
||||||
} \
|
f->lastcall += 4; \
|
||||||
} while (++b < b_end); \
|
|
||||||
if (f->lastcall) f->lastcall += 4; \
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
// filter
|
// filter
|
||||||
static int f_ctsw32_e8_e9(Filter *f)
|
static int f_ctsw32_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f_ctsw32_e9_e8(Filter *f)
|
static int f_ctsw32_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
|
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// unfilter
|
// unfilter
|
||||||
static int u_ctsw32_e8_e9(Filter *f)
|
static int u_ctsw32_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ctsw32_e9_e8(Filter *f)
|
static int u_ctsw32_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
|
CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// scan
|
// scan
|
||||||
static int s_ctsw32_e8_e9(Filter *f)
|
static int s_ctsw32_e8_e9(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ctsw32_e9_e8(Filter *f)
|
static int s_ctsw32_e9_e8(Filter *f) {
|
||||||
{
|
|
||||||
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef CTSW32
|
#undef CTSW32
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
@@ -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-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2024 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,122 +25,108 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
#include "../filter.h"
|
||||||
|
|
||||||
#include "conf.h"
|
static unsigned umin(const unsigned a, const unsigned b) { return (a <= b) ? a : b; }
|
||||||
#include "filter.h"
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
umin(unsigned const a, unsigned const b)
|
|
||||||
{
|
|
||||||
return (a<=b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define set_dummy(p, v) ((void)0)
|
|
||||||
#define get_8(p) (*(p))
|
|
||||||
#define set_8(p, v) (*(p) = (v))
|
|
||||||
|
|
||||||
|
#define set_dummy(p, v) ((void) 0)
|
||||||
|
#define get_8(p) (*(p))
|
||||||
|
#define set_8(p, v) (*(p) = (v))
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// 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 "filter/sub16.h"
|
|
||||||
#include "filter/sub32.h"
|
|
||||||
|
|
||||||
|
#include "sub8.h"
|
||||||
|
#include "sub16.h"
|
||||||
|
#include "sub32.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// cto calltrick
|
// cto calltrick
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// cto calltrick with jmp
|
// cto calltrick with jmp
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// cto calltrick with jmp, optional jcc
|
// cto calltrick with jmp, optional jcc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
#define COND1(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||||
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f)
|
#define COND2(b, x, lc) (lc != (x) && 0xf == b[(x) -1] && 0x80 <= b[x] && b[x] <= 0x8f)
|
||||||
#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
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// cto calltrick with jmp and jcc and relative renumbering
|
// cto calltrick with jmp and jcc and relative renumbering
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define COND_CALL(which,b,x) ((which = 0), b[x] == 0xe8)
|
#define COND_CALL(which, b, x) ((which = 0), b[x] == 0xe8)
|
||||||
#define COND_JMP( which,b,x) ((which = 1), b[x] == 0xe9)
|
#define COND_JMP(which, b, x) ((which = 1), b[x] == 0xe9)
|
||||||
#define COND_JCC( which,b,lastcall,x,y,z) ((which = 2), \
|
#define COND_JCC(which, b, lastcall, x, y, z) \
|
||||||
(lastcall!=(x) && 0xf==b[y] && 0x80<=b[z] && b[z]<=0x8f))
|
((which = 2), (lastcall != (x) && 0xf == b[y] && 0x80 <= b[z] && b[z] <= 0x8f))
|
||||||
#define COND1(which,b,x) (COND_CALL(which,b,x) || COND_JMP(which,b,x))
|
#define COND1(which, b, x) (COND_CALL(which, b, x) || COND_JMP(which, b, x))
|
||||||
#define COND2(which,b,lastcall,x,y,z) COND_JCC(which,b,lastcall,x,y,z)
|
#define COND2(which, b, lastcall, x, y, z) COND_JCC(which, b, lastcall, x, y, z)
|
||||||
|
|
||||||
#define CONDF(which,b,x,lastcall) \
|
#define CONDF(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, (x) -1, x))
|
||||||
(COND1(which,b,x) || COND2(which,b,lastcall,x,(x)-1, x ))
|
#define CONDU(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, x, (x) -1))
|
||||||
#define CONDU(which,b,x,lastcall) \
|
|
||||||
(COND1(which,b,x) || COND2(which,b,lastcall,x, x ,(x)-1))
|
|
||||||
|
|
||||||
#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
|
||||||
@@ -150,25 +136,24 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#undef COND_JMP
|
#undef COND_JMP
|
||||||
#undef COND_CALL
|
#undef COND_CALL
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// PowerPC branch [incl. call] trick
|
// PowerPC branch [incl. call] trick
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// database for use in class Filter
|
// database for use in class Filter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const FilterImp::FilterEntry FilterImp::filters[] = {
|
// clang-format off
|
||||||
|
/*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = {
|
||||||
// no filter
|
// no filter
|
||||||
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
||||||
|
|
||||||
@@ -228,8 +213,13 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||||
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||||
|
|
||||||
|
#if 1 //{ old reliable
|
||||||
// 26-bit calltrick for arm64
|
// 26-bit calltrick for arm64
|
||||||
{ 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le },
|
{ 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le },
|
||||||
|
#else //}{ new enhanced, but needs new filter id
|
||||||
|
// 26-bit calltrick for arm64; also 19-bit and 14-bit
|
||||||
|
{ 0x52, 8, 0x03ffffff, f_CTarm64_le, u_CTarm64_le, s_CTarm64_le },
|
||||||
|
#endif //}
|
||||||
|
|
||||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
@@ -260,7 +250,8 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
// PowerPC branch+call trick
|
// PowerPC branch+call trick
|
||||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||||
};
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
/*static*/ const int FilterImpl::n_filters = TABLESIZE(filters);
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user