Comparar commits
946 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| ed1cc99506 | |||
| f66cb26c58 | |||
| 707412d1b6 | |||
| a7ebdc5453 | |||
| dc35957f63 | |||
| 0711483bb7 | |||
| f4f5ff1887 | |||
| 33a4fa3203 | |||
| 8b22412e55 | |||
| 92d721d9d0 | |||
| 0f06d0b8ce | |||
| e321ec4c6f | |||
| 2f2892ff08 | |||
| 1dd559e80e | |||
| b7fb1b7e5a | |||
| eb60877793 | |||
| 5907ce0a02 | |||
| 5a1d431e51 | |||
| 0552c4a001 | |||
| 96d017869a | |||
| ddc2688af8 | |||
| baa60b6198 | |||
| 8abdddf11a | |||
| 9141018b27 | |||
| 3370fecdf2 | |||
| 5e91f76f0f | |||
| 557b3e1c93 | |||
| 3f65e56ccd | |||
| 5bd2cba2c2 | |||
| 3de7eb58a7 | |||
| 41eb294ce6 | |||
| ba94f2ebe0 | |||
| 7912248950 | |||
| 5d27c255b3 | |||
| 80e86e3b83 | |||
| 3a759f1eea | |||
| a09e503f19 | |||
| da4524b05c | |||
| 1a98283709 | |||
| acca8c5ac9 | |||
| 55eabb84e4 | |||
| 90ba9fce2a | |||
| 76b3982ddd | |||
| c946f80d5b | |||
| 8d350c7d99 | |||
| 7cd7fb8d6c | |||
| b12e563340 | |||
| 9c0aadce1e | |||
| b8d538b1b4 | |||
| 0219cd71b9 | |||
| 899fcbdfcc | |||
| 79fed6e32f | |||
| 55263ca11d | |||
| fe1f4a3bac | |||
| dd4fda55b5 | |||
| 2aae506110 | |||
| aae54a6f41 | |||
| 89da58adec | |||
| 57ef003eb9 | |||
| d378a64096 | |||
| 58ac91bc10 | |||
| 97602c0bf8 | |||
| 8523c487c1 | |||
| 3580b58bf6 | |||
| 9b26a4d5ce | |||
| c43fc68bc8 | |||
| df07539331 | |||
| 563931750b | |||
| 6b090de7b1 | |||
| d8863ef95f | |||
| 36f9595ce7 | |||
| 48565e6305 | |||
| 3727f9583b | |||
| 4a6bbf0b3c | |||
| 7513a7157f | |||
| e7dbdb6ead | |||
| db5f101bfc | |||
| 3c06e8b6fd | |||
| 28f94cbd0b | |||
| 6f37cbd946 | |||
| 396281263b | |||
| a00e8ac201 | |||
| b1772a89c1 | |||
| 58f07ff045 | |||
| 12f99d4fc7 | |||
| 05da0a6877 | |||
| 46ce871f34 | |||
| 4b22c2f044 | |||
| 4014828eff | |||
| bc87a62d59 | |||
| f6862442d3 | |||
| bff7f57eb8 | |||
| e19024ca0d | |||
| 73997e4799 | |||
| ffa97aa438 | |||
| d08244dfd8 | |||
| 2e0d367045 | |||
| 0f1fb2e6a1 | |||
| 672e362ed8 | |||
| bcae16c441 | |||
| 19b8f5cb59 | |||
| 68b37156d8 | |||
| d9237b64c0 | |||
| da037b38e3 | |||
| 62f864f4ab | |||
| bf89f1d37d | |||
| 3dc986e609 | |||
| 2f5e874201 | |||
| 05291932f8 | |||
| 72aa450ecb | |||
| 926ea21fe0 | |||
| 657a077cdb | |||
| 9a90f56845 | |||
| 7d36e0d63b | |||
| 865d5ed7a1 | |||
| 9dd91ee17e | |||
| 425ea821d7 | |||
| bea5049a2f | |||
| eae1e34696 | |||
| e63b6b00bc | |||
| e5b3ed226b | |||
| d5ce354c87 | |||
| e280838989 | |||
| 2309054b1f | |||
| 9dcc44a76b | |||
| 7a417c6d3b | |||
| 425ab15ae1 | |||
| c75ff4f118 | |||
| 75d3dd19ec | |||
| 4cd556555e | |||
| feebe921af | |||
| 92929308bd | |||
| ca4f14b555 | |||
| a7bcfacbd9 | |||
| e097b4820d | |||
| 566ec7974c | |||
| c735d6c420 | |||
| cf54ca9551 | |||
| 9f1da1b562 | |||
| f5a3dbf82b | |||
| 89f83e796a | |||
| 977a9e49c5 | |||
| 7ee0a4b39f | |||
| 4268e3a1d2 | |||
| 860b9a266a | |||
| c39d752ccb | |||
| 15db1cf385 | |||
| 38d684d1e6 | |||
| ccb1bc514b | |||
| 27c46a2c8e | |||
| ff2f1d237a | |||
| 402f4c162c | |||
| 81013a98b4 | |||
| 971dd622c7 | |||
| 0045d31e2d | |||
| caef8f4ebc | |||
| 6116c1ae71 | |||
| 03ecf2b0bb | |||
| d4a5005273 | |||
| 7522f29f0a | |||
| 09f0a2e4a6 | |||
| aa846929f3 | |||
| b378af7cb1 | |||
| 8b549a487f | |||
| 005f659eaa | |||
| a5aad94f24 | |||
| 52a6926da3 | |||
| b3c0f003bb | |||
| 3d2360bc56 | |||
| 1267f51d8c | |||
| e7328001a4 | |||
| fc7b53e809 | |||
| 50637cb3c2 | |||
| 11b4203874 | |||
| 60beb432eb | |||
| 64331c9cf0 | |||
| 00088d4093 | |||
| 472f3660e0 | |||
| 3c13cc8c4d | |||
| 0792ac8eee | |||
| 4952af4ffe | |||
| 3fcca7ef56 | |||
| e93244fef2 | |||
| acf75ce7fe | |||
| 7560b6e53d | |||
| f5346bbec2 | |||
| 41958889fb | |||
| d439a7811d | |||
| 4951c00d23 | |||
| 202cd0d45e | |||
| 1502db6095 | |||
| e8eea9e68e | |||
| 396eb9f283 | |||
| 378f400226 | |||
| 37e02dfbd5 | |||
| dce66ec8ec | |||
| 2fef67a08d | |||
| 50a17583c7 | |||
| bfe2c7df83 | |||
| b3186dde12 | |||
| 628a33eb76 | |||
| 4373e66b1e | |||
| 2e67b0ad9f | |||
| a4cbe0635f | |||
| 8563419280 | |||
| 0974bd4a90 | |||
| e1d47adc99 | |||
| e5e171d913 | |||
| 1e313227b8 | |||
| 8d45a9e0cd | |||
| 95568d76d3 | |||
| d4a3442468 | |||
| e262de22ea | |||
| 49243f1891 | |||
| 1a099ba549 | |||
| 2367133b4f | |||
| c648a1933d | |||
| 598acf08da | |||
| 208a8dee90 | |||
| e9fb299565 | |||
| 17a514ecd0 | |||
| 38ac62cedd | |||
| ce280731af | |||
| 751fb57f71 | |||
| be7d90abbf | |||
| d59585dd4f | |||
| 7a695707a2 | |||
| 4e590c9450 | |||
| b069d1c9e9 | |||
| 9fa1f7b981 | |||
| 4a68e4cd9d | |||
| 8320b6fd7c | |||
| e40cf0a1c4 | |||
| 19106985d7 | |||
| 3d817c54da | |||
| ca31877107 | |||
| f5f9afefb0 | |||
| d42863603e | |||
| 2c19cf3e31 | |||
| e7dc918c6a | |||
| 64c9e8212a | |||
| 499c39f13d | |||
| bccdae735b | |||
| 58120730a5 | |||
| 5b8db8a680 | |||
| 0acfd583c8 | |||
| 402b7ef67e | |||
| 6944871c42 | |||
| b60da35689 | |||
| 5204feddb1 | |||
| 68156df66b | |||
| a9e8b27285 | |||
| b8f470ddbd | |||
| 9d075dd1d1 | |||
| 4b802c6f60 | |||
| 8ce9344dd0 | |||
| cb2b386791 | |||
| 7ee4681c10 | |||
| 82c0ea9df2 | |||
| 9070d80880 | |||
| 45c53caf94 | |||
| c4947618c1 | |||
| 941ed59c37 | |||
| d76bbec1ab | |||
| f5a1d98cf9 | |||
| b0e6d837f0 | |||
| b1cfb1b733 | |||
| 26a1212546 | |||
| 03b05aaae9 | |||
| f41c87d7c9 | |||
| b74deb5e35 | |||
| 240e2db637 | |||
| 441947b6a4 | |||
| 194bdaffcd | |||
| db6e9ff4c6 | |||
| 57261a1164 | |||
| 0b116bb409 | |||
| a5ad2e5de2 | |||
| b6928ff6c0 | |||
| 4b03dd321c | |||
| f7eefbd3d7 | |||
| b23f7f9b27 | |||
| b95bc7e4c4 | |||
| 1593c0c347 | |||
| c154663455 | |||
| 13bc1901dc | |||
| 4f28322ac2 | |||
| 756e2ced8b | |||
| 1dc78b5209 | |||
| 3464093273 | |||
| 4487214494 | |||
| 6d7e222946 | |||
| d12a6a3178 | |||
| ed9d609c35 | |||
| b86f359d93 | |||
| 02080dfcf8 | |||
| 2768d25884 | |||
| 7bdf9896d2 | |||
| 3b4f84ded8 | |||
| 69abc52731 | |||
| 1671b1fb8b | |||
| 8735f4ef5c | |||
| 86967b5786 | |||
| ca8ceeb130 | |||
| 41d6f8eeea | |||
| 27b7805608 | |||
| fef39f7013 | |||
| b414b54c6b | |||
| ccdbb20ad0 | |||
| eb7e47bf29 | |||
| 53988c7184 | |||
| 9092b2bdc5 | |||
| 068353aa5b | |||
| 95a17ddbf0 | |||
| 6c8c455f5b | |||
| 282032e178 | |||
| af63e6a80d | |||
| a46ba0da29 | |||
| f7738bf65b | |||
| bb11d1fe37 | |||
| d02a2deb52 | |||
| 46105d849d | |||
| f16b6c3482 | |||
| a9cb497045 | |||
| d529a34ecb | |||
| 5394029dc5 | |||
| 28247737ca | |||
| 6448c2d8fb | |||
| 4460ccc8ec | |||
| 2b02a3c533 | |||
| 6705513b86 | |||
| 4bd8d12481 | |||
| ccaf3c283b | |||
| ce4276a0cb | |||
| 709e316e56 | |||
| e46635d6ab | |||
| 0af8677ba4 | |||
| 9ab13daf09 | |||
| 17977fbabc | |||
| 83854047b7 | |||
| 28e56fd587 | |||
| 29fc6308b8 | |||
| 14a7df128d | |||
| dd4ef89d0a | |||
| 830ec91cbf | |||
| aee2d55fab | |||
| 89ed7982e7 | |||
| 9f702c89ab | |||
| 2f76efd0f6 | |||
| fae18c72c3 | |||
| 1586f6ee2b | |||
| 4ce6214526 | |||
| e370e4b65e | |||
| 944de2d3f5 | |||
| f32146368d | |||
| 8d45e9b016 | |||
| 70227861ff | |||
| 20e542516b | |||
| 73ad21df73 | |||
| a67fe7e43d | |||
| a15ddd9f88 | |||
| b27f9bf930 | |||
| d5c28f98f1 | |||
| 16b283ed00 | |||
| 97b43889a1 | |||
| 05efa12411 | |||
| 3e60495232 | |||
| 45522b0710 | |||
| d67d25eb7b | |||
| 2538690fb4 | |||
| 4c23b2518e | |||
| 9daade9816 | |||
| 5f925f0070 | |||
| 38b0cd7780 | |||
| e46391042b | |||
| 553a03b05f | |||
| 24c1cc4efe | |||
| f6eabe7b58 | |||
| de2de1fdc7 | |||
| 8184ac8843 | |||
| a57d82d4cd | |||
| a266ef7337 | |||
| b30ca23180 | |||
| db5c8f00fc | |||
| d1bbacb06e | |||
| bff4e3b0fd | |||
| 14248ddbd9 | |||
| 391f39d291 | |||
| b4354efa8b | |||
| 686588a6e5 | |||
| 294267a605 | |||
| 7b53b9108b | |||
| 15be9ab501 | |||
| 7cfcd2daef | |||
| 6070429eec | |||
| b5f41ef6c7 | |||
| 716588a8fb | |||
| 95bc92f005 | |||
| 23425abe9d | |||
| 3bab5e1e78 | |||
| 79ed7e81b1 | |||
| a59e58cc94 | |||
| 72bd12e394 | |||
| 2c667ca016 | |||
| 209c4d724f | |||
| 95cf641f50 | |||
| 85750fd065 | |||
| 402b5c7f81 | |||
| be6f52b796 | |||
| f4e6c6ad94 | |||
| 99fe59cee9 | |||
| 0e80ba8b91 | |||
| 8965efdce1 | |||
| 1393a94804 | |||
| 52e558d877 | |||
| d9948105f1 | |||
| 87c91c1c04 | |||
| f15e471371 | |||
| fc0a83933d | |||
| f1cf2fe218 | |||
| 7a5679cb65 | |||
| 571b4604db | |||
| 29e15a40db | |||
| 6fb2286fa4 | |||
| ab2f78c7b4 | |||
| f9b918a05b | |||
| a46cde174a | |||
| 6eee0f8741 | |||
| 28d31bb9f6 | |||
| 23128be17f | |||
| 130885fda7 | |||
| c4fc42f8f4 | |||
| 21e73c5fb9 | |||
| b635bf5591 | |||
| be594bb1f6 | |||
| 543e3fca98 | |||
| b385d76dc6 | |||
| 2adc88fec3 | |||
| 2a9e2ceb61 | |||
| 47fa804469 | |||
| f70c01eee7 | |||
| eb4ea07a2d | |||
| 55cd72baaa | |||
| 940076d101 | |||
| 93ebb9f7a9 | |||
| 1a17ea52d8 | |||
| 68bc0c0c7c | |||
| 0e7dd6b350 | |||
| b3b0bf3845 | |||
| ddc32f1e43 | |||
| c9de508a2c | |||
| fac68bca4e | |||
| eaf250c3c6 | |||
| 8b99772d29 | |||
| 862a32e97e | |||
| 6cfb84d6ee | |||
| 2fda7ca6f6 | |||
| f2aecb53bc | |||
| 05fdc2f17a | |||
| b9868b993c | |||
| 573d8eefd1 | |||
| 51d64f29e6 | |||
| a39ab60ae5 | |||
| ba9671fae5 | |||
| a9340f354d | |||
| f9d6b069f7 | |||
| c363d5790d | |||
| 15a50d2a26 | |||
| bffc188151 | |||
| e78205430c | |||
| 4ef76d4f85 | |||
| 967da46793 | |||
| 46899503bd | |||
| 2dcf0f774c | |||
| d669db0cab | |||
| f8aabcc50a | |||
| 4bb3ece8dc | |||
| 495a7765d2 | |||
| 225296f253 | |||
| 52e6900e7a | |||
| 557bff1465 | |||
| add32ac107 | |||
| f7699b98fb | |||
| 05a8ec1fec | |||
| 004e63c433 | |||
| 898f41b95a | |||
| 859a6a75aa | |||
| b90dae6448 | |||
| dc1ddf4cff | |||
| 46ef5d86c3 | |||
| ac63a6b125 | |||
| 72778c97df | |||
| b4b86081f9 | |||
| e4a47a4ca5 | |||
| 79c60f6d4e | |||
| 4c4d55e0dc | |||
| 9504416beb | |||
| 99586d9b3f | |||
| 65b19cbbd3 | |||
| 7b64f4443d | |||
| abb2e857be | |||
| df10745963 | |||
| 3d729595d1 | |||
| 96a38d1895 | |||
| b4c1390af8 | |||
| e9604ac212 | |||
| ea3a4b34ea | |||
| 79a0d92161 | |||
| b10c40260c | |||
| 9e056d2097 | |||
| 8a250c5994 | |||
| e311ac3269 | |||
| 28078a2d0c | |||
| 7def8c1bbf | |||
| 24ca11387e | |||
| bccc9583c1 | |||
| 9643747b17 | |||
| c695848092 | |||
| 5011613e4c | |||
| 6cc7f69a59 | |||
| db6678637b | |||
| 93892e12a2 | |||
| c196aab89d | |||
| 54a7718b88 | |||
| cec6e6175a | |||
| bc5036bd34 | |||
| 021826eb1b | |||
| facd071967 | |||
| 486e81ad77 | |||
| 872cd3d7c0 | |||
| ca9851b311 | |||
| 2fa0940d45 | |||
| 3485338386 | |||
| 786a821f3f | |||
| da1c9c5ea5 | |||
| 93d8cce7ac | |||
| 5086ba2a3b | |||
| 4cf8611dcd | |||
| 101e9d705a | |||
| 7d8bfa1b62 | |||
| 5dcf9e2f41 | |||
| cdf18b6c4d | |||
| 609ce3b6e0 | |||
| 3ba8be2e21 | |||
| 6b13a97ce4 | |||
| 130e40957e | |||
| a7b28317d7 | |||
| 29fcd0fdcf | |||
| 9d5f63e543 | |||
| 208c28ead2 | |||
| 447d5ee94b | |||
| bb443add17 | |||
| cb954773ed | |||
| 89749c7eb1 | |||
| 30146f8744 | |||
| a623f374b1 | |||
| b41584feb3 | |||
| 77d5bbb767 | |||
| 171d428d3a | |||
| 61254c6cc4 | |||
| 44b3a8952e | |||
| 0fc8c5e7e9 | |||
| 6d969eb92f | |||
| 26ea0f81ca | |||
| dc45e38f11 | |||
| 9d5db40d3f | |||
| 9e25d52679 | |||
| 1f98d4f6ff | |||
| b73883ce1d | |||
| 7af42da5d2 | |||
| cf75057b67 | |||
| e5b1841030 | |||
| 57325a22a5 | |||
| c640166cf8 | |||
| 4b4c362c03 | |||
| c71bfb1602 | |||
| 022e6349c1 | |||
| 917671ac9a | |||
| a108975d78 | |||
| 62d31c5902 | |||
| 5d28314ee3 | |||
| 1b22109f95 | |||
| e5c05bfd66 | |||
| 62e97858d7 | |||
| b9da9b977e | |||
| f121b6c039 | |||
| c48b13bc0a | |||
| 26abb9beb9 | |||
| 02cc7d53b7 | |||
| 67136b5986 | |||
| 58d5175fde | |||
| c511c4063e | |||
| 6429611b3c | |||
| 3cea53ddca | |||
| d661e58fc3 | |||
| e140b6e4e2 | |||
| e1025d9337 | |||
| f1acc483c3 | |||
| 0e25e979a2 | |||
| 0c129ff02e | |||
| 05234082a9 | |||
| bdc44962a1 | |||
| e96a59965e | |||
| 507f3fc74b | |||
| 22d997fcd9 | |||
| 89a98ca51b | |||
| 9834abe3ab | |||
| 54ffc2c138 | |||
| 4785c4f11e | |||
| 9d5b0deb61 | |||
| 9c0b540ddc | |||
| c124a9f2b8 | |||
| 8b0e08f9df | |||
| 9ee115d1a0 | |||
| a7ebf431a8 | |||
| d85330d54a | |||
| f8f93c7351 | |||
| ee1fd4944f | |||
| 5117fa06b8 | |||
| 2ac1552bf7 | |||
| 94c2647d25 | |||
| 6b2f067435 | |||
| 3e2471d0a0 | |||
| f0b1d33398 | |||
| bae955f7c5 | |||
| b747e71583 | |||
| 48160da4b7 | |||
| d17df6a9db | |||
| df7a9ec977 | |||
| f2157420f2 | |||
| ae9c56416f | |||
| 1dec6a541a | |||
| c75157ffd8 | |||
| fa77d03fea | |||
| 618f4c533c | |||
| 9b77631dd5 | |||
| 7aa22df1e2 | |||
| ee0ff79820 | |||
| ca772e8a9c | |||
| 8af05c14be | |||
| 20f230e910 | |||
| 8af51875b6 | |||
| a4ead757f6 | |||
| 0cc6bc9e2e | |||
| 00a551d2b1 | |||
| b6f1652aab | |||
| b304555389 | |||
| 456af457bb | |||
| e9cb67844d | |||
| ff12099078 | |||
| 4068c6da1a | |||
| 2f839a41c0 | |||
| d9c13aefe3 | |||
| 7bfa1c27bf | |||
| f6986352ee | |||
| 2eb51bbb13 | |||
| 77ef1e75c8 | |||
| ae11a9d77c | |||
| 30648be2ed | |||
| e5958a2a15 | |||
| 8d3b41ea4d | |||
| 2d7f82af75 | |||
| 9c93a94834 | |||
| 13a9861d18 | |||
| f7d1a91aad | |||
| 121b8e0a64 | |||
| 36ebf4a034 | |||
| 0a752616b7 | |||
| edd21a959b | |||
| dfe9779401 | |||
| d64bc68562 | |||
| f29a57ceb2 | |||
| 529c8e36f2 | |||
| 108abcdec4 | |||
| 1ae7d8373f | |||
| 8eb4860ec6 | |||
| 7ae188c42b | |||
| 125a65ee8a | |||
| 98c3353a07 | |||
| 683ba59fae | |||
| 38abd739d3 | |||
| df58c84b5a | |||
| 513bb215db | |||
| 77be329ed0 | |||
| 1f223fbe13 | |||
| c6a21ab661 | |||
| 6d59f0bd3f | |||
| 74972e267a | |||
| 6c2134ba0e | |||
| 7bf53b0588 | |||
| eaff635df5 | |||
| 88ad275b44 | |||
| fe6143ca49 | |||
| 724432aa02 | |||
| 9686a4b1bd | |||
| 7f8fab8ec0 | |||
| 5a985a143b | |||
| f9154f8c2e | |||
| 287879a7f5 | |||
| 3c82302545 | |||
| b331783c01 | |||
| 1882210db4 | |||
| 12bd185a9b | |||
| 3dbaa7984f | |||
| 40f00b1dcb | |||
| 98bb38cb03 | |||
| e1b4c8d616 | |||
| 5d7c015348 | |||
| a90e7c82b3 | |||
| 6c0c9e7d7c | |||
| 461b35f6ef | |||
| 81ca040918 | |||
| 5dc6bfb195 | |||
| b0d3657e56 | |||
| 822913c85f | |||
| ce0ac250e1 | |||
| 22e98986e5 | |||
| 3f7fc39362 | |||
| 024c845d06 | |||
| 4bb1e29cf3 | |||
| fa7bdc4fcd | |||
| ab0708340c | |||
| 34723a2e17 | |||
| d4c4d2bb13 | |||
| 80090df8e4 | |||
| 05dc68db7b | |||
| 1bcde2cbf2 | |||
| 9a5f5851ba | |||
| 8c7152bb9f | |||
| 5580e39447 | |||
| f29d58c0f0 | |||
| d69e62363e | |||
| 0e0af9dcaa | |||
| 85fee142b3 | |||
| a1b5a934f4 | |||
| 996b533634 | |||
| 11fab2e58e | |||
| 437df3b6d4 | |||
| 663c2fdbac | |||
| 4eb0e9f8aa | |||
| 00a17b60f8 | |||
| fb5f00db61 | |||
| 0105055c3e | |||
| efe147b731 | |||
| 9585302dc5 | |||
| 7432c0775b | |||
| 8666ac7b85 | |||
| 827cbfd03c | |||
| 64a5e8f236 | |||
| 6a60315011 | |||
| a234334f69 | |||
| d71acbd909 | |||
| 33e672d135 | |||
| a26a696e34 | |||
| c63827d5a0 | |||
| 998f9f6ad0 | |||
| 0e188d3bff | |||
| 4a0867c5f2 | |||
| 4fb1955303 | |||
| ef202cd8b8 | |||
| 3648b4539b | |||
| b78ac9355a | |||
| f023994074 | |||
| a47e77bdf9 | |||
| 13773c267d | |||
| deccbf6d9a | |||
| ec1f92c16a | |||
| 5436e605b0 | |||
| 949ae6a7aa | |||
| b957c563c6 | |||
| 36c73e1d64 | |||
| d8f0925466 | |||
| 77d1b2f648 | |||
| 7a82dd3baf | |||
| 7c5573199f | |||
| 55146b70bd | |||
| c2a26458e8 | |||
| 6be895f83c | |||
| fcae79eb9a | |||
| 9a342d979f | |||
| a48a7c321d | |||
| fd167bc19f | |||
| 11f794c9df | |||
| 30b353fabe | |||
| 61590a115c | |||
| 982dfbdd61 | |||
| 9a5605f5de | |||
| 5d62055838 | |||
| 3e886a8a5b | |||
| eb1d4736b0 | |||
| affcdf49f9 | |||
| 06a4a3f8af | |||
| eb58d23656 | |||
| ed2ee11af8 | |||
| 6ed833bf28 | |||
| 196e8af786 | |||
| 17aafbc595 | |||
| 1dcf8cf36c | |||
| 3fc6bc7e53 | |||
| fce337b823 | |||
| 6e3c4a856c | |||
| 05f44f3c62 | |||
| d609eed733 | |||
| 65c4e6ad94 | |||
| 6fc11568c0 | |||
| 494aa6e090 | |||
| abab91748c | |||
| f86ef41980 | |||
| a22191c1fb | |||
| db2a6b239e | |||
| 25726a3df9 | |||
| a95c4d673d | |||
| b6b53d7b83 | |||
| 573a5c6a53 | |||
| 7db8868043 | |||
| 7ee89a6e1d | |||
| 5e22b1cd27 | |||
| 2e5eee5092 | |||
| b341608130 | |||
| e6e8ffb1c3 | |||
| 60c851972e | |||
| dcfc552254 | |||
| 8bb92f5c19 | |||
| 0ca338ade0 | |||
| 272424d379 | |||
| 6d72f33da7 | |||
| c0fab06356 | |||
| 1423a7ce91 | |||
| 053a432804 | |||
| f50129baa3 | |||
| 9150e8f188 | |||
| b637ab3ceb | |||
| 32d38dd876 | |||
| a04f4bd4b2 | |||
| ad68219568 | |||
| af117d810d | |||
| 5d764abdc6 | |||
| a9e9c69265 | |||
| 461e86eb82 | |||
| 7e87ffa0fd | |||
| 7bfa698796 | |||
| 285f64ed62 | |||
| b13b1d7b70 | |||
| 212e0cd812 | |||
| 589a8e101d | |||
| b8b4169b1a | |||
| e8aac64083 | |||
| 8e3ae9bb85 | |||
| 14a549928f | |||
| 83e1fb715e | |||
| aeeac8e343 | |||
| 5fc6d50486 | |||
| edc7c111cb | |||
| 05a754bc92 | |||
| dff58c56fb | |||
| 58709a1d32 | |||
| 554567fa82 | |||
| 3ad51db9c2 | |||
| 007d74ee23 | |||
| cd15214d77 | |||
| 32eca24468 | |||
| a96e25ef5d | |||
| 5087fb1904 | |||
| 2c4af20cb0 | |||
| 78cdc63b76 | |||
| 6ef191563a | |||
| daf616be22 | |||
| 278dc84bb9 | |||
| 686a2931e6 | |||
| 5be5a0e417 | |||
| cd2d1dbb76 | |||
| 68a92623d0 | |||
| 81b3255577 | |||
| fc33a22f27 | |||
| 5267c76580 | |||
| 2908b993a3 | |||
| 1c172bf513 | |||
| aa037e4a0c | |||
| 10dd04e03c | |||
| 560f75c755 | |||
| f2ce65fb84 | |||
| eb1d463889 | |||
| 8d021cb29c | |||
| 70faac1b6a | |||
| abaf425a36 | |||
| 95a0333057 | |||
| a49bba636a | |||
| e252ef2cb2 | |||
| 4ca6be8892 | |||
| 29227a2c9e | |||
| be4326eb83 | |||
| 72cc002d5a | |||
| 0efce8e9b4 | |||
| 398b12f176 | |||
| 4ca2eaaeda | |||
| 8711ab4738 | |||
| d58faad8de | |||
| 8f44698c58 | |||
| 14b2f05881 | |||
| 663071fbb8 | |||
| 098e79c301 | |||
| 5f18808f7d | |||
| cb19b706d5 | |||
| e2ed1db1e1 | |||
| fc748c6a8b | |||
| 294f136297 | |||
| f3fc29497e | |||
| 6e01d29355 | |||
| 749725adba | |||
| 5538031da1 | |||
| dd0153f4e3 | |||
| 690cf60b8c | |||
| cce40a97f2 | |||
| ed0d95ae1f | |||
| 1e28ec4a6a | |||
| 6b4daa5f16 | |||
| 3075fd0cf5 | |||
| b7470fd09f | |||
| 4b8bf1149e | |||
| d9567609de | |||
| 9944e202c8 | |||
| 923b59e2a0 | |||
| bd7d13136f | |||
| a08aa84884 | |||
| 5be48aaae8 | |||
| 8530ec12b7 | |||
| d777506b74 | |||
| 6e9a57421e | |||
| c6d47a49cd | |||
| 13c48da980 | |||
| df0658406c | |||
| ea548c34cf | |||
| 28824d4b6f | |||
| 341a1e3810 | |||
| dcf4a926f6 | |||
| c12bdbb8a1 | |||
| 261706d808 | |||
| 904c3f4072 | |||
| 4a885ac56e | |||
| a51745868d | |||
| 9dd2d6c18c | |||
| 8aae405584 | |||
| 4a119e6012 | |||
| e3041177c7 | |||
| 607f83cf96 | |||
| 2c1fd46e24 |
+8
-18
@@ -1,18 +1,8 @@
|
||||
.libs
|
||||
.deps
|
||||
*.o
|
||||
*.lo
|
||||
.dirstamp
|
||||
*.la
|
||||
Makefile
|
||||
config.log
|
||||
config.status
|
||||
*~
|
||||
fficonfig.h
|
||||
include/ffi.h
|
||||
include/ffitarget.h
|
||||
libffi.pc
|
||||
libtool
|
||||
stamp-h1
|
||||
libffi*gz
|
||||
autom4te.cache
|
||||
build
|
||||
build.eclipse
|
||||
build.number
|
||||
.metadata
|
||||
bin
|
||||
jnalib/contrib/ntservice/dist
|
||||
jnalib/contrib/platform/dist
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
2
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
-16014
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,476 +0,0 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
|
||||
# defaults of its own if none are provided.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
save_CFLAGS=$CFLAGS
|
||||
AC_PROG_CC
|
||||
CFLAGS=$save_CFLAGS
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(mmap)
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
case "$host" in
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd* | amd64-*-openbsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
i?86-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-solaris2.1[[0-9]]*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-*)
|
||||
TARGET=X86; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
;;
|
||||
|
||||
sh-*-* | sh[[34]]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
;;
|
||||
|
||||
x86_64-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-cygwin* | x86_64-*-mingw*)
|
||||
TARGET=X86_WIN64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
|
||||
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
|
||||
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
|
||||
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
|
||||
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
|
||||
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
|
||||
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
|
||||
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
|
||||
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||||
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||||
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||||
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||||
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
|
||||
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
libffi_cv_as_cfi_pseudo_op, [
|
||||
libffi_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
[libffi_cv_as_cfi_pseudo_op=yes],
|
||||
[libffi_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
|
||||
if test x$TARGET = xSPARC; then
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
|
||||
libffi_cv_as_ascii_pseudo_op, [
|
||||
libffi_cv_as_ascii_pseudo_op=unknown
|
||||
# Check if we have .ascii
|
||||
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
|
||||
[libffi_cv_as_ascii_pseudo_op=yes],
|
||||
[libffi_cv_as_ascii_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .ascii.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .string pseudo-op support],
|
||||
libffi_cv_as_string_pseudo_op, [
|
||||
libffi_cv_as_string_pseudo_op=unknown
|
||||
# Check if we have .string
|
||||
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
|
||||
[libffi_cv_as_string_pseudo_op=yes],
|
||||
[libffi_cv_as_string_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .string.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86_WIN64; then
|
||||
LT_SYS_SYMBOL_USCORE
|
||||
if test "x$sys_symbol_underscore" = xyes; then
|
||||
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
*-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
echo '.section .eh_frame,"a",@unwind' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
|
||||
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
elif grep '.section.*eh_frame.*#alloc' conftest.c \
|
||||
| grep -v '#write' > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive.])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if grep '\.hidden.*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test x"$GCC" != x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
fi
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,404 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi @VERSION@ - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
The basic API is described in the README file.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing
|
||||
and unpacking on architectures for which it can be avoided.
|
||||
|
||||
The closure API allows interpreted functions to be packaged up
|
||||
inside a C function pointer, so that they can be called as C functions,
|
||||
with no understanding on the client side that they are interpreted.
|
||||
It can also be used in other cases in which it is necessary to package
|
||||
up a user specified parameter and a function pointer as a single
|
||||
function pointer.
|
||||
|
||||
The closure API must be implemented in order to get its functionality,
|
||||
e.g. for use by gij. Routines are provided to emulate the raw API
|
||||
if the underlying platform doesn't allow faster implementation.
|
||||
|
||||
More details on the raw and cloure API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef @TARGET@
|
||||
#define @TARGET@
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t */
|
||||
/* can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != 9223372036854775807
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != 9223372036854775807
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c */
|
||||
extern ffi_type ffi_type_void;
|
||||
extern ffi_type ffi_type_uint8;
|
||||
extern ffi_type ffi_type_sint8;
|
||||
extern ffi_type ffi_type_uint16;
|
||||
extern ffi_type ffi_type_sint16;
|
||||
extern ffi_type ffi_type_uint32;
|
||||
extern ffi_type ffi_type_sint32;
|
||||
extern ffi_type ffi_type_uint64;
|
||||
extern ffi_type ffi_type_sint64;
|
||||
extern ffi_type ffi_type_float;
|
||||
extern ffi_type ffi_type_double;
|
||||
extern ffi_type ffi_type_pointer;
|
||||
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
extern ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef unsigned FFI_TYPE;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == 9223372036854775807
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter */
|
||||
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
|
||||
/* longs and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
#ifdef __GNUC__
|
||||
} ffi_closure __attribute__((aligned (8)));
|
||||
#else
|
||||
} ffi_closure;
|
||||
#endif
|
||||
|
||||
void *ffi_closure_alloc (size_t size, void **code);
|
||||
void ffi_closure_free (void *);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
/* Useful for eliminating compiler warnings */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks) */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_POINTER
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,324 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
|
||||
based on darwin.S by John Hornkvist
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
.set r0,0
|
||||
.set r1,1
|
||||
.set r2,2
|
||||
.set r3,3
|
||||
.set r4,4
|
||||
.set r5,5
|
||||
.set r6,6
|
||||
.set r7,7
|
||||
.set r8,8
|
||||
.set r9,9
|
||||
.set r10,10
|
||||
.set r11,11
|
||||
.set r12,12
|
||||
.set r13,13
|
||||
.set r14,14
|
||||
.set r15,15
|
||||
.set r16,16
|
||||
.set r17,17
|
||||
.set r18,18
|
||||
.set r19,19
|
||||
.set r20,20
|
||||
.set r21,21
|
||||
.set r22,22
|
||||
.set r23,23
|
||||
.set r24,24
|
||||
.set r25,25
|
||||
.set r26,26
|
||||
.set r27,27
|
||||
.set r28,28
|
||||
.set r29,29
|
||||
.set r30,30
|
||||
.set r31,31
|
||||
.set f0,0
|
||||
.set f1,1
|
||||
.set f2,2
|
||||
.set f3,3
|
||||
.set f4,4
|
||||
.set f5,5
|
||||
.set f6,6
|
||||
.set f7,7
|
||||
.set f8,8
|
||||
.set f9,9
|
||||
.set f10,10
|
||||
.set f11,11
|
||||
.set f12,12
|
||||
.set f13,13
|
||||
.set f14,14
|
||||
.set f15,15
|
||||
.set f16,16
|
||||
.set f17,17
|
||||
.set f18,18
|
||||
.set f19,19
|
||||
.set f20,20
|
||||
.set f21,21
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#define JUMPTARGET(name) name
|
||||
#define L(x) x
|
||||
.file "aix.S"
|
||||
.toc
|
||||
|
||||
/* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
|
||||
* unsigned int flags, unsigned int *rvalue,
|
||||
* void (*fn)(),
|
||||
* void (*prep_args)(extended_cif*, unsigned *const));
|
||||
* r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args
|
||||
*/
|
||||
|
||||
.csect .text[PR]
|
||||
.align 2
|
||||
.globl ffi_call_AIX
|
||||
.globl .ffi_call_AIX
|
||||
.csect ffi_call_AIX[DS]
|
||||
ffi_call_AIX:
|
||||
#ifdef __64BIT__
|
||||
.llong .ffi_call_AIX, TOC[tc0], 0
|
||||
.csect .text[PR]
|
||||
.ffi_call_AIX:
|
||||
/* Save registers we use. */
|
||||
mflr r0
|
||||
|
||||
std r28,-32(r1)
|
||||
std r29,-24(r1)
|
||||
std r30,-16(r1)
|
||||
std r31, -8(r1)
|
||||
|
||||
std r0, 16(r1)
|
||||
mr r28, r1 /* our AP. */
|
||||
stdux r1, r1, r4
|
||||
|
||||
/* Save arguments over call... */
|
||||
mr r31, r5 /* flags, */
|
||||
mr r30, r6 /* rvalue, */
|
||||
mr r29, r7 /* function address. */
|
||||
std r2, 40(r1)
|
||||
|
||||
/* Call ffi_prep_args. */
|
||||
mr r4, r1
|
||||
bl .ffi_prep_args
|
||||
|
||||
/* Now do the call. */
|
||||
ld r0, 0(r29)
|
||||
ld r2, 8(r29)
|
||||
ld r11, 16(r29)
|
||||
/* Set up cr1 with bits 4-7 of the flags. */
|
||||
mtcrf 0x40, r31
|
||||
mtctr r0
|
||||
/* Load all those argument registers. */
|
||||
// We have set up a nice stack frame, just load it into registers.
|
||||
ld r3, 40+(1*8)(r1)
|
||||
ld r4, 40+(2*8)(r1)
|
||||
ld r5, 40+(3*8)(r1)
|
||||
ld r6, 40+(4*8)(r1)
|
||||
nop
|
||||
ld r7, 40+(5*8)(r1)
|
||||
ld r8, 40+(6*8)(r1)
|
||||
ld r9, 40+(7*8)(r1)
|
||||
ld r10,40+(8*8)(r1)
|
||||
|
||||
L1:
|
||||
/* Load all the FP registers. */
|
||||
bf 6,L2 // 2f + 0x18
|
||||
lfd f1,-32-(13*8)(r28)
|
||||
lfd f2,-32-(12*8)(r28)
|
||||
lfd f3,-32-(11*8)(r28)
|
||||
lfd f4,-32-(10*8)(r28)
|
||||
nop
|
||||
lfd f5,-32-(9*8)(r28)
|
||||
lfd f6,-32-(8*8)(r28)
|
||||
lfd f7,-32-(7*8)(r28)
|
||||
lfd f8,-32-(6*8)(r28)
|
||||
nop
|
||||
lfd f9,-32-(5*8)(r28)
|
||||
lfd f10,-32-(4*8)(r28)
|
||||
lfd f11,-32-(3*8)(r28)
|
||||
lfd f12,-32-(2*8)(r28)
|
||||
nop
|
||||
lfd f13,-32-(1*8)(r28)
|
||||
|
||||
L2:
|
||||
/* Make the call. */
|
||||
bctrl
|
||||
ld r2, 40(r1)
|
||||
|
||||
/* Now, deal with the return value. */
|
||||
mtcrf 0x01, r31
|
||||
|
||||
bt 30, L(done_return_value)
|
||||
bt 29, L(fp_return_value)
|
||||
std r3, 0(r30)
|
||||
|
||||
/* Fall through... */
|
||||
|
||||
L(done_return_value):
|
||||
/* Restore the registers we used and return. */
|
||||
mr r1, r28
|
||||
ld r0, 16(r28)
|
||||
ld r28, -32(r1)
|
||||
mtlr r0
|
||||
ld r29, -24(r1)
|
||||
ld r30, -16(r1)
|
||||
ld r31, -8(r1)
|
||||
blr
|
||||
|
||||
L(fp_return_value):
|
||||
bf 28, L(float_return_value)
|
||||
stfd f1, 0(r30)
|
||||
bf 31, L(done_return_value)
|
||||
stfd f2, 8(r30)
|
||||
b L(done_return_value)
|
||||
L(float_return_value):
|
||||
stfs f1, 0(r30)
|
||||
b L(done_return_value)
|
||||
|
||||
#else /* ! __64BIT__ */
|
||||
|
||||
.long .ffi_call_AIX, TOC[tc0], 0
|
||||
.csect .text[PR]
|
||||
.ffi_call_AIX:
|
||||
/* Save registers we use. */
|
||||
mflr r0
|
||||
|
||||
stw r28,-16(r1)
|
||||
stw r29,-12(r1)
|
||||
stw r30, -8(r1)
|
||||
stw r31, -4(r1)
|
||||
|
||||
stw r0, 8(r1)
|
||||
mr r28, r1 /* out AP. */
|
||||
stwux r1, r1, r4
|
||||
|
||||
/* Save arguments over call... */
|
||||
mr r31, r5 /* flags, */
|
||||
mr r30, r6 /* rvalue, */
|
||||
mr r29, r7 /* function address, */
|
||||
stw r2, 20(r1)
|
||||
|
||||
/* Call ffi_prep_args. */
|
||||
mr r4, r1
|
||||
bl .ffi_prep_args
|
||||
|
||||
/* Now do the call. */
|
||||
lwz r0, 0(r29)
|
||||
lwz r2, 4(r29)
|
||||
lwz r11, 8(r29)
|
||||
/* Set up cr1 with bits 4-7 of the flags. */
|
||||
mtcrf 0x40, r31
|
||||
mtctr r0
|
||||
/* Load all those argument registers. */
|
||||
// We have set up a nice stack frame, just load it into registers.
|
||||
lwz r3, 20+(1*4)(r1)
|
||||
lwz r4, 20+(2*4)(r1)
|
||||
lwz r5, 20+(3*4)(r1)
|
||||
lwz r6, 20+(4*4)(r1)
|
||||
nop
|
||||
lwz r7, 20+(5*4)(r1)
|
||||
lwz r8, 20+(6*4)(r1)
|
||||
lwz r9, 20+(7*4)(r1)
|
||||
lwz r10,20+(8*4)(r1)
|
||||
|
||||
L1:
|
||||
/* Load all the FP registers. */
|
||||
bf 6,L2 // 2f + 0x18
|
||||
lfd f1,-16-(13*8)(r28)
|
||||
lfd f2,-16-(12*8)(r28)
|
||||
lfd f3,-16-(11*8)(r28)
|
||||
lfd f4,-16-(10*8)(r28)
|
||||
nop
|
||||
lfd f5,-16-(9*8)(r28)
|
||||
lfd f6,-16-(8*8)(r28)
|
||||
lfd f7,-16-(7*8)(r28)
|
||||
lfd f8,-16-(6*8)(r28)
|
||||
nop
|
||||
lfd f9,-16-(5*8)(r28)
|
||||
lfd f10,-16-(4*8)(r28)
|
||||
lfd f11,-16-(3*8)(r28)
|
||||
lfd f12,-16-(2*8)(r28)
|
||||
nop
|
||||
lfd f13,-16-(1*8)(r28)
|
||||
|
||||
L2:
|
||||
/* Make the call. */
|
||||
bctrl
|
||||
lwz r2, 20(r1)
|
||||
|
||||
/* Now, deal with the return value. */
|
||||
mtcrf 0x01, r31
|
||||
|
||||
bt 30, L(done_return_value)
|
||||
bt 29, L(fp_return_value)
|
||||
stw r3, 0(r30)
|
||||
bf 28, L(done_return_value)
|
||||
stw r4, 4(r30)
|
||||
|
||||
/* Fall through... */
|
||||
|
||||
L(done_return_value):
|
||||
/* Restore the registers we used and return. */
|
||||
mr r1, r28
|
||||
lwz r0, 8(r28)
|
||||
lwz r28,-16(r1)
|
||||
mtlr r0
|
||||
lwz r29,-12(r1)
|
||||
lwz r30, -8(r1)
|
||||
lwz r31, -4(r1)
|
||||
blr
|
||||
|
||||
L(fp_return_value):
|
||||
bf 28, L(float_return_value)
|
||||
stfd f1, 0(r30)
|
||||
b L(done_return_value)
|
||||
L(float_return_value):
|
||||
stfs f1, 0(r30)
|
||||
b L(done_return_value)
|
||||
#endif
|
||||
.long 0
|
||||
.byte 0,0,0,1,128,4,0,0
|
||||
//END(ffi_call_AIX)
|
||||
|
||||
.csect .text[PR]
|
||||
.align 2
|
||||
.globl ffi_call_DARWIN
|
||||
.globl .ffi_call_DARWIN
|
||||
.csect ffi_call_DARWIN[DS]
|
||||
ffi_call_DARWIN:
|
||||
#ifdef __64BIT__
|
||||
.llong .ffi_call_DARWIN, TOC[tc0], 0
|
||||
#else
|
||||
.long .ffi_call_DARWIN, TOC[tc0], 0
|
||||
#endif
|
||||
.csect .text[PR]
|
||||
.ffi_call_DARWIN:
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,0,0,0,0,0,0,0
|
||||
//END(ffi_call_DARWIN)
|
||||
@@ -1,443 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
|
||||
based on darwin_closure.S
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
.set r0,0
|
||||
.set r1,1
|
||||
.set r2,2
|
||||
.set r3,3
|
||||
.set r4,4
|
||||
.set r5,5
|
||||
.set r6,6
|
||||
.set r7,7
|
||||
.set r8,8
|
||||
.set r9,9
|
||||
.set r10,10
|
||||
.set r11,11
|
||||
.set r12,12
|
||||
.set r13,13
|
||||
.set r14,14
|
||||
.set r15,15
|
||||
.set r16,16
|
||||
.set r17,17
|
||||
.set r18,18
|
||||
.set r19,19
|
||||
.set r20,20
|
||||
.set r21,21
|
||||
.set r22,22
|
||||
.set r23,23
|
||||
.set r24,24
|
||||
.set r25,25
|
||||
.set r26,26
|
||||
.set r27,27
|
||||
.set r28,28
|
||||
.set r29,29
|
||||
.set r30,30
|
||||
.set r31,31
|
||||
.set f0,0
|
||||
.set f1,1
|
||||
.set f2,2
|
||||
.set f3,3
|
||||
.set f4,4
|
||||
.set f5,5
|
||||
.set f6,6
|
||||
.set f7,7
|
||||
.set f8,8
|
||||
.set f9,9
|
||||
.set f10,10
|
||||
.set f11,11
|
||||
.set f12,12
|
||||
.set f13,13
|
||||
.set f14,14
|
||||
.set f15,15
|
||||
.set f16,16
|
||||
.set f17,17
|
||||
.set f18,18
|
||||
.set f19,19
|
||||
.set f20,20
|
||||
.set f21,21
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define JUMPTARGET(name) name
|
||||
#define L(x) x
|
||||
.file "aix_closure.S"
|
||||
.toc
|
||||
LC..60:
|
||||
.tc L..60[TC],L..60
|
||||
.csect .text[PR]
|
||||
.align 2
|
||||
|
||||
.csect .text[PR]
|
||||
.align 2
|
||||
.globl ffi_closure_ASM
|
||||
.globl .ffi_closure_ASM
|
||||
.csect ffi_closure_ASM[DS]
|
||||
ffi_closure_ASM:
|
||||
#ifdef __64BIT__
|
||||
.llong .ffi_closure_ASM, TOC[tc0], 0
|
||||
.csect .text[PR]
|
||||
.ffi_closure_ASM:
|
||||
/* we want to build up an area for the parameters passed */
|
||||
/* in registers (both floating point and integer) */
|
||||
|
||||
/* we store gpr 3 to gpr 10 (aligned to 4)
|
||||
in the parents outgoing area */
|
||||
std r3, 48+(0*8)(r1)
|
||||
std r4, 48+(1*8)(r1)
|
||||
std r5, 48+(2*8)(r1)
|
||||
std r6, 48+(3*8)(r1)
|
||||
mflr r0
|
||||
|
||||
std r7, 48+(4*8)(r1)
|
||||
std r8, 48+(5*8)(r1)
|
||||
std r9, 48+(6*8)(r1)
|
||||
std r10, 48+(7*8)(r1)
|
||||
std r0, 16(r1) /* save the return address */
|
||||
|
||||
|
||||
/* 48 Bytes (Linkage Area) */
|
||||
/* 64 Bytes (params) */
|
||||
/* 16 Bytes (result) */
|
||||
/* 104 Bytes (13*8 from FPR) */
|
||||
/* 8 Bytes (alignment) */
|
||||
/* 240 Bytes */
|
||||
|
||||
stdu r1, -240(r1) /* skip over caller save area
|
||||
keep stack aligned to 16 */
|
||||
|
||||
/* next save fpr 1 to fpr 13 (aligned to 8) */
|
||||
stfd f1, 128+(0*8)(r1)
|
||||
stfd f2, 128+(1*8)(r1)
|
||||
stfd f3, 128+(2*8)(r1)
|
||||
stfd f4, 128+(3*8)(r1)
|
||||
stfd f5, 128+(4*8)(r1)
|
||||
stfd f6, 128+(5*8)(r1)
|
||||
stfd f7, 128+(6*8)(r1)
|
||||
stfd f8, 128+(7*8)(r1)
|
||||
stfd f9, 128+(8*8)(r1)
|
||||
stfd f10, 128+(9*8)(r1)
|
||||
stfd f11, 128+(10*8)(r1)
|
||||
stfd f12, 128+(11*8)(r1)
|
||||
stfd f13, 128+(12*8)(r1)
|
||||
|
||||
/* set up registers for the routine that actually does the work */
|
||||
/* get the context pointer from the trampoline */
|
||||
mr r3, r11
|
||||
|
||||
/* now load up the pointer to the result storage */
|
||||
addi r4, r1, 112
|
||||
|
||||
/* now load up the pointer to the saved gpr registers */
|
||||
addi r5, r1, 288
|
||||
|
||||
/* now load up the pointer to the saved fpr registers */
|
||||
addi r6, r1, 128
|
||||
|
||||
/* make the call */
|
||||
bl .ffi_closure_helper_DARWIN
|
||||
nop
|
||||
|
||||
/* now r3 contains the return type */
|
||||
/* so use it to look up in a table */
|
||||
/* so we know how to deal with each type */
|
||||
|
||||
/* look up the proper starting point in table */
|
||||
/* by using return type as offset */
|
||||
ld r4, LC..60(2) /* get address of jump table */
|
||||
sldi r3, r3, 4 /* now multiply return type by 16 */
|
||||
ld r0, 240+16(r1) /* load return address */
|
||||
add r3, r3, r4 /* add contents of table to table address */
|
||||
mtctr r3
|
||||
bctr /* jump to it */
|
||||
|
||||
/* Each fragment must be exactly 16 bytes long (4 instructions).
|
||||
Align to 16 byte boundary for cache and dispatch efficiency. */
|
||||
.align 4
|
||||
|
||||
L..60:
|
||||
/* case FFI_TYPE_VOID */
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_INT */
|
||||
lwa r3, 112+4(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_FLOAT */
|
||||
lfs f1, 112+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_DOUBLE */
|
||||
lfd f1, 112+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_LONGDOUBLE */
|
||||
lfd f1, 112+0(r1)
|
||||
mtlr r0
|
||||
lfd f2, 112+8(r1)
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_UINT8 */
|
||||
lbz r3, 112+7(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT8 */
|
||||
lbz r3, 112+7(r1)
|
||||
mtlr r0
|
||||
extsb r3, r3
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_UINT16 */
|
||||
lhz r3, 112+6(r1)
|
||||
mtlr r0
|
||||
L..finish:
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT16 */
|
||||
lha r3, 112+6(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_UINT32 */
|
||||
lwz r3, 112+4(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT32 */
|
||||
lwa r3, 112+4(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_UINT64 */
|
||||
ld r3, 112+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT64 */
|
||||
ld r3, 112+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_STRUCT */
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_POINTER */
|
||||
ld r3, 112+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 240
|
||||
blr
|
||||
|
||||
#else /* ! __64BIT__ */
|
||||
|
||||
.long .ffi_closure_ASM, TOC[tc0], 0
|
||||
.csect .text[PR]
|
||||
.ffi_closure_ASM:
|
||||
/* we want to build up an area for the parameters passed */
|
||||
/* in registers (both floating point and integer) */
|
||||
|
||||
/* we store gpr 3 to gpr 10 (aligned to 4)
|
||||
in the parents outgoing area */
|
||||
stw r3, 24+(0*4)(r1)
|
||||
stw r4, 24+(1*4)(r1)
|
||||
stw r5, 24+(2*4)(r1)
|
||||
stw r6, 24+(3*4)(r1)
|
||||
mflr r0
|
||||
|
||||
stw r7, 24+(4*4)(r1)
|
||||
stw r8, 24+(5*4)(r1)
|
||||
stw r9, 24+(6*4)(r1)
|
||||
stw r10, 24+(7*4)(r1)
|
||||
stw r0, 8(r1)
|
||||
|
||||
/* 24 Bytes (Linkage Area) */
|
||||
/* 32 Bytes (params) */
|
||||
/* 16 Bytes (result) */
|
||||
/* 104 Bytes (13*8 from FPR) */
|
||||
/* 176 Bytes */
|
||||
|
||||
stwu r1, -176(r1) /* skip over caller save area
|
||||
keep stack aligned to 16 */
|
||||
|
||||
/* next save fpr 1 to fpr 13 (aligned to 8) */
|
||||
stfd f1, 72+(0*8)(r1)
|
||||
stfd f2, 72+(1*8)(r1)
|
||||
stfd f3, 72+(2*8)(r1)
|
||||
stfd f4, 72+(3*8)(r1)
|
||||
stfd f5, 72+(4*8)(r1)
|
||||
stfd f6, 72+(5*8)(r1)
|
||||
stfd f7, 72+(6*8)(r1)
|
||||
stfd f8, 72+(7*8)(r1)
|
||||
stfd f9, 72+(8*8)(r1)
|
||||
stfd f10, 72+(9*8)(r1)
|
||||
stfd f11, 72+(10*8)(r1)
|
||||
stfd f12, 72+(11*8)(r1)
|
||||
stfd f13, 72+(12*8)(r1)
|
||||
|
||||
/* set up registers for the routine that actually does the work */
|
||||
/* get the context pointer from the trampoline */
|
||||
mr r3, r11
|
||||
|
||||
/* now load up the pointer to the result storage */
|
||||
addi r4, r1, 56
|
||||
|
||||
/* now load up the pointer to the saved gpr registers */
|
||||
addi r5, r1, 200
|
||||
|
||||
/* now load up the pointer to the saved fpr registers */
|
||||
addi r6, r1, 72
|
||||
|
||||
/* make the call */
|
||||
bl .ffi_closure_helper_DARWIN
|
||||
nop
|
||||
|
||||
/* now r3 contains the return type */
|
||||
/* so use it to look up in a table */
|
||||
/* so we know how to deal with each type */
|
||||
|
||||
/* look up the proper starting point in table */
|
||||
/* by using return type as offset */
|
||||
lwz r4, LC..60(2) /* get address of jump table */
|
||||
slwi r3, r3, 4 /* now multiply return type by 4 */
|
||||
lwz r0, 176+8(r1) /* load return address */
|
||||
add r3, r3, r4 /* add contents of table to table address */
|
||||
mtctr r3
|
||||
bctr /* jump to it */
|
||||
|
||||
/* Each fragment must be exactly 16 bytes long (4 instructions).
|
||||
Align to 16 byte boundary for cache and dispatch efficiency. */
|
||||
.align 4
|
||||
|
||||
L..60:
|
||||
/* case FFI_TYPE_VOID */
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_INT */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_FLOAT */
|
||||
lfs f1, 56+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_DOUBLE */
|
||||
lfd f1, 56+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_LONGDOUBLE */
|
||||
lfd f1, 56+0(r1)
|
||||
mtlr r0
|
||||
lfd f2, 56+8(r1)
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_UINT8 */
|
||||
lbz r3, 56+3(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT8 */
|
||||
lbz r3, 56+3(r1)
|
||||
mtlr r0
|
||||
extsb r3, r3
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_UINT16 */
|
||||
lhz r3, 56+2(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT16 */
|
||||
lha r3, 56+2(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_UINT32 */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_SINT32 */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
|
||||
/* case FFI_TYPE_UINT64 */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
lwz r4, 56+4(r1)
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_SINT64 */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
lwz r4, 56+4(r1)
|
||||
b L..finish
|
||||
|
||||
/* case FFI_TYPE_STRUCT */
|
||||
mtlr r0
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_POINTER */
|
||||
lwz r3, 56+0(r1)
|
||||
mtlr r0
|
||||
L..finish:
|
||||
addi r1, r1, 176
|
||||
blr
|
||||
#endif
|
||||
/* END(ffi_closure_ASM) */
|
||||
@@ -1,31 +0,0 @@
|
||||
stand-alone
|
||||
msvcc-warning
|
||||
ffi_last_abi
|
||||
win64-struct-args
|
||||
stdcall-x86-closure-fix
|
||||
ml64-safeseh
|
||||
debug-build
|
||||
win64-underscore
|
||||
x86_pcrel_test
|
||||
aix-ibm-xlc
|
||||
fix-grammar
|
||||
sparc-v8-aggregate-returns
|
||||
hpux-mallinfo
|
||||
copyright-updates
|
||||
ios
|
||||
fix-xfails
|
||||
interix
|
||||
ppc64-darwin
|
||||
irix
|
||||
sparc-abi-check
|
||||
ungccify
|
||||
ios-fixes
|
||||
bad-abi-fix
|
||||
msvcc
|
||||
fix_maxopt
|
||||
fix-ppc32
|
||||
darwin-EH-fix
|
||||
more-openbsd
|
||||
more-openbsd-mips
|
||||
minix
|
||||
interix-patch
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,122 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc
|
||||
|
||||
Common internal definitions and macros. Only necessary for building
|
||||
libffi.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef FFI_COMMON_H
|
||||
#define FFI_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <fficonfig.h>
|
||||
|
||||
/* Do not move this. Some versions of AIX are very picky about where
|
||||
this is positioned. */
|
||||
#ifdef __GNUC__
|
||||
/* mingw64 defines this already in malloc.h. */
|
||||
#ifndef alloca
|
||||
# define alloca __builtin_alloca
|
||||
#endif
|
||||
# define MAYBE_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# ifdef _MSC_VER
|
||||
# define alloca _alloca
|
||||
# else
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Check for the existence of memcpy. */
|
||||
#if STDC_HEADERS
|
||||
# include <string.h>
|
||||
#else
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(FFI_DEBUG)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef FFI_DEBUG
|
||||
void ffi_assert(char *expr, char *file, int line);
|
||||
void ffi_stop_here(void);
|
||||
void ffi_type_test(ffi_type *a, char *file, int line);
|
||||
|
||||
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
|
||||
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
|
||||
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
|
||||
#else
|
||||
#define FFI_ASSERT(x)
|
||||
#define FFI_ASSERT_AT(x, f, l)
|
||||
#define FFI_ASSERT_VALID_TYPE(x)
|
||||
#endif
|
||||
|
||||
#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
|
||||
#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
|
||||
|
||||
/* Extended cif, used in callback from assembly routine */
|
||||
typedef struct
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void *rvalue;
|
||||
void **avalue;
|
||||
} extended_cif;
|
||||
|
||||
/* Terse sized type definitions. */
|
||||
#if defined(_MSC_VER) || defined(__sgi)
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed char SINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed short SINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed int SINT32;
|
||||
# ifdef _MSC_VER
|
||||
typedef unsigned __int64 UINT64;
|
||||
typedef signed __int64 SINT64;
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
typedef uint64_t UINT64;
|
||||
typedef int64_t SINT64;
|
||||
# endif
|
||||
#else
|
||||
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
|
||||
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
|
||||
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
|
||||
typedef signed int SINT16 __attribute__((__mode__(__HI__)));
|
||||
typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
|
||||
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
|
||||
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
|
||||
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
|
||||
#endif
|
||||
|
||||
typedef float FLOAT32;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,726 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Forward declares. */
|
||||
static int vfp_type_p (ffi_type *);
|
||||
static void layout_vfp_args (ffi_cif *);
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
|
||||
The vfp_space parameter is the load area for VFP regs, the return
|
||||
value is cif->vfp_used (word bitset of VFP regs used for passing
|
||||
arguments). These are only used for the VFP hard-float ABI.
|
||||
*/
|
||||
int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
register unsigned int i, vi = 0;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*(void **) argp = ecif->rvalue;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0);
|
||||
i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
/* Allocated in VFP registers. */
|
||||
if (ecif->cif->abi == FFI_VFP
|
||||
&& vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg))
|
||||
{
|
||||
float* vfp_slot = vfp_space + ecif->cif->vfp_args[vi++];
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
*((float*)vfp_slot) = *((float*)*p_argv);
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
*((double*)vfp_slot) = *((double*)*p_argv);
|
||||
else
|
||||
memcpy(vfp_slot, *p_argv, (*p_arg)->size);
|
||||
p_argv++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Align if necessary */
|
||||
if (((*p_arg)->alignment - 1) & (unsigned) argp) {
|
||||
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
|
||||
}
|
||||
|
||||
if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||||
argp = (char *) ALIGN(argp, 4);
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
memcpy(argp, *p_argv, (*p_arg)->size);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
/* Indicate the VFP registers used. */
|
||||
return ecif->cif->vfp_used;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int type_code;
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
everywhere, but it is on some platforms, and it doesn't harm anything
|
||||
when it isn't needed. */
|
||||
cif->bytes = (cif->bytes + 7) & ~7;
|
||||
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags = (unsigned) FFI_TYPE_SINT64;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
if (cif->abi == FFI_VFP
|
||||
&& (type_code = vfp_type_p (cif->rtype)) != 0)
|
||||
{
|
||||
/* A Composite Type passed in VFP registers, either
|
||||
FFI_TYPE_STRUCT_VFP_FLOAT or FFI_TYPE_STRUCT_VFP_DOUBLE. */
|
||||
cif->flags = (unsigned) type_code;
|
||||
}
|
||||
else if (cif->rtype->size <= 4)
|
||||
/* A Composite Type not larger than 4 bytes is returned in r0. */
|
||||
cif->flags = (unsigned)FFI_TYPE_INT;
|
||||
else
|
||||
/* A Composite Type larger than 4 bytes, or whose size cannot
|
||||
be determined statically ... is stored in memory at an
|
||||
address passed [in r0]. */
|
||||
cif->flags = (unsigned)FFI_TYPE_STRUCT;
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Map out the register placements of VFP register args.
|
||||
The VFP hard-float calling conventions are slightly more sophisticated than
|
||||
the base calling conventions, so we do it here instead of in ffi_prep_args(). */
|
||||
if (cif->abi == FFI_VFP)
|
||||
layout_vfp_args (cif);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Prototypes for assembly functions, in sysv.S */
|
||||
extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
|
||||
extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT);
|
||||
int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
unsigned int temp;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->flags == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else if (small_struct)
|
||||
ecif.rvalue = &temp;
|
||||
else if (vfp_struct)
|
||||
{
|
||||
/* Largest case is double x 4. */
|
||||
ecif.rvalue = alloca(32);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
break;
|
||||
|
||||
case FFI_VFP:
|
||||
ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (small_struct)
|
||||
memcpy (rvalue, &temp, cif->rtype->size);
|
||||
else if (vfp_struct)
|
||||
memcpy (rvalue, ecif.rvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
/** private members **/
|
||||
|
||||
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
|
||||
void** args, ffi_cif* cif, float *vfp_stack);
|
||||
|
||||
void ffi_closure_SYSV (ffi_closure *);
|
||||
|
||||
void ffi_closure_VFP (ffi_closure *);
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int
|
||||
ffi_closure_SYSV_inner (closure, respp, args, vfp_args)
|
||||
ffi_closure *closure;
|
||||
void **respp;
|
||||
void *args;
|
||||
void *vfp_args;
|
||||
{
|
||||
// our various things...
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will re-set RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
|
||||
|
||||
(closure->fun) (cif, *respp, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
float *vfp_stack)
|
||||
/*@=exportheader@*/
|
||||
{
|
||||
register unsigned int i, vi = 0;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
if ( cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*rvalue = *(void **) argp;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = avalue;
|
||||
|
||||
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
size_t alignment;
|
||||
|
||||
if (cif->abi == FFI_VFP
|
||||
&& vi < cif->vfp_nargs && vfp_type_p (*p_arg))
|
||||
{
|
||||
*p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]);
|
||||
continue;
|
||||
}
|
||||
|
||||
alignment = (*p_arg)->alignment;
|
||||
if (alignment < 4)
|
||||
alignment = 4;
|
||||
/* Align if necessary */
|
||||
if ((alignment - 1) & (unsigned) argp) {
|
||||
argp = (char *) ALIGN(argp, alignment);
|
||||
}
|
||||
|
||||
z = (*p_arg)->size;
|
||||
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
|
||||
*p_argv = (void*) argp;
|
||||
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* How to make a trampoline. */
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void *ffi_closure_trampoline_table_page;
|
||||
|
||||
typedef struct ffi_trampoline_table ffi_trampoline_table;
|
||||
typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
|
||||
|
||||
struct ffi_trampoline_table {
|
||||
/* contigious writable and executable pages */
|
||||
vm_address_t config_page;
|
||||
vm_address_t trampoline_page;
|
||||
|
||||
/* free list tracking */
|
||||
uint16_t free_count;
|
||||
ffi_trampoline_table_entry *free_list;
|
||||
ffi_trampoline_table_entry *free_list_pool;
|
||||
|
||||
ffi_trampoline_table *prev;
|
||||
ffi_trampoline_table *next;
|
||||
};
|
||||
|
||||
struct ffi_trampoline_table_entry {
|
||||
void *(*trampoline)();
|
||||
ffi_trampoline_table_entry *next;
|
||||
};
|
||||
|
||||
/* Override the standard architecture trampoline size */
|
||||
// XXX TODO - Fix
|
||||
#undef FFI_TRAMPOLINE_SIZE
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
|
||||
/* The trampoline configuration is placed at 4080 bytes prior to the trampoline's entry point */
|
||||
#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - 4080));
|
||||
|
||||
/* The first 16 bytes of the config page are unused, as they are unaddressable from the trampoline page. */
|
||||
#define FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET 16
|
||||
|
||||
/* Total number of trampolines that fit in one trampoline table */
|
||||
#define FFI_TRAMPOLINE_COUNT ((PAGE_SIZE - FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) / FFI_TRAMPOLINE_SIZE)
|
||||
|
||||
static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static ffi_trampoline_table *ffi_trampoline_tables = NULL;
|
||||
|
||||
static ffi_trampoline_table *
|
||||
ffi_trampoline_table_alloc ()
|
||||
{
|
||||
ffi_trampoline_table *table = NULL;
|
||||
|
||||
/* Loop until we can allocate two contigious pages */
|
||||
while (table == NULL) {
|
||||
vm_address_t config_page = 0x0;
|
||||
kern_return_t kt;
|
||||
|
||||
/* Try to allocate two pages */
|
||||
kt = vm_allocate (mach_task_self (), &config_page, PAGE_SIZE*2, VM_FLAGS_ANYWHERE);
|
||||
if (kt != KERN_SUCCESS) {
|
||||
fprintf(stderr, "vm_allocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now drop the second half of the allocation to make room for the trampoline table */
|
||||
vm_address_t trampoline_page = config_page+PAGE_SIZE;
|
||||
kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_SIZE);
|
||||
if (kt != KERN_SUCCESS) {
|
||||
fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Remap the trampoline table to directly follow the config page */
|
||||
vm_prot_t cur_prot;
|
||||
vm_prot_t max_prot;
|
||||
|
||||
kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_SIZE, 0x0, FALSE, mach_task_self (), (vm_address_t) &ffi_closure_trampoline_table_page, FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
|
||||
|
||||
/* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */
|
||||
if (kt != KERN_SUCCESS) {
|
||||
/* Log unexpected failures */
|
||||
if (kt != KERN_NO_SPACE) {
|
||||
fprintf(stderr, "vm_remap() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
vm_deallocate (mach_task_self (), config_page, PAGE_SIZE);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have valid trampoline and config pages */
|
||||
table = calloc (1, sizeof(ffi_trampoline_table));
|
||||
table->free_count = FFI_TRAMPOLINE_COUNT;
|
||||
table->config_page = config_page;
|
||||
table->trampoline_page = trampoline_page;
|
||||
|
||||
/* Create and initialize the free list */
|
||||
table->free_list_pool = calloc(FFI_TRAMPOLINE_COUNT, sizeof(ffi_trampoline_table_entry));
|
||||
|
||||
uint16_t i;
|
||||
for (i = 0; i < table->free_count; i++) {
|
||||
ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
|
||||
entry->trampoline = (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
|
||||
|
||||
if (i < table->free_count - 1)
|
||||
entry->next = &table->free_list_pool[i+1];
|
||||
}
|
||||
|
||||
table->free_list = table->free_list_pool;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void *
|
||||
ffi_closure_alloc (size_t size, void **code)
|
||||
{
|
||||
/* Create the closure */
|
||||
ffi_closure *closure = malloc(size);
|
||||
if (closure == NULL)
|
||||
return NULL;
|
||||
|
||||
pthread_mutex_lock(&ffi_trampoline_lock);
|
||||
|
||||
/* Check for an active trampoline table with available entries. */
|
||||
ffi_trampoline_table *table = ffi_trampoline_tables;
|
||||
if (table == NULL || table->free_list == NULL) {
|
||||
table = ffi_trampoline_table_alloc ();
|
||||
if (table == NULL) {
|
||||
free(closure);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Insert the new table at the top of the list */
|
||||
table->next = ffi_trampoline_tables;
|
||||
if (table->next != NULL)
|
||||
table->next->prev = table;
|
||||
|
||||
ffi_trampoline_tables = table;
|
||||
}
|
||||
|
||||
/* Claim the free entry */
|
||||
ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
|
||||
ffi_trampoline_tables->free_list = entry->next;
|
||||
ffi_trampoline_tables->free_count--;
|
||||
entry->next = NULL;
|
||||
|
||||
pthread_mutex_unlock(&ffi_trampoline_lock);
|
||||
|
||||
/* Initialize the return values */
|
||||
*code = entry->trampoline;
|
||||
closure->trampoline_table = table;
|
||||
closure->trampoline_table_entry = entry;
|
||||
|
||||
return closure;
|
||||
}
|
||||
|
||||
void
|
||||
ffi_closure_free (void *ptr)
|
||||
{
|
||||
ffi_closure *closure = ptr;
|
||||
|
||||
pthread_mutex_lock(&ffi_trampoline_lock);
|
||||
|
||||
/* Fetch the table and entry references */
|
||||
ffi_trampoline_table *table = closure->trampoline_table;
|
||||
ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
|
||||
|
||||
/* Return the entry to the free list */
|
||||
entry->next = table->free_list;
|
||||
table->free_list = entry;
|
||||
table->free_count++;
|
||||
|
||||
/* If all trampolines within this table are free, and at least one other table exists, deallocate
|
||||
* the table */
|
||||
if (table->free_count == FFI_TRAMPOLINE_COUNT && ffi_trampoline_tables != table) {
|
||||
/* Remove from the list */
|
||||
if (table->prev != NULL)
|
||||
table->prev->next = table->next;
|
||||
|
||||
if (table->next != NULL)
|
||||
table->next->prev = table->prev;
|
||||
|
||||
/* Deallocate pages */
|
||||
kern_return_t kt;
|
||||
kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE);
|
||||
if (kt != KERN_SUCCESS)
|
||||
fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
||||
|
||||
kt = vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE);
|
||||
if (kt != KERN_SUCCESS)
|
||||
fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
|
||||
|
||||
/* Deallocate free list */
|
||||
free (table->free_list_pool);
|
||||
free (table);
|
||||
} else if (ffi_trampoline_tables != table) {
|
||||
/* Otherwise, bump this table to the top of the list */
|
||||
table->prev = NULL;
|
||||
table->next = ffi_trampoline_tables;
|
||||
if (ffi_trampoline_tables != NULL)
|
||||
ffi_trampoline_tables->prev = table;
|
||||
|
||||
ffi_trampoline_tables = table;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&ffi_trampoline_lock);
|
||||
|
||||
/* Free the closure */
|
||||
free (closure);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
|
||||
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned char *insns = (unsigned char *)(CTX); \
|
||||
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
|
||||
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
|
||||
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
|
||||
*(unsigned int*) &__tramp[12] = __ctx; \
|
||||
*(unsigned int*) &__tramp[16] = __fun; \
|
||||
__clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping. */ \
|
||||
__clear_cache(insns, insns + 3 * sizeof (unsigned int)); \
|
||||
/* Clear instruction \
|
||||
mapping. */ \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
/* the cif must already be prep'ed */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
void (*closure_func)(ffi_closure*) = NULL;
|
||||
|
||||
if (cif->abi == FFI_SYSV)
|
||||
closure_func = &ffi_closure_SYSV;
|
||||
else if (cif->abi == FFI_VFP)
|
||||
closure_func = &ffi_closure_VFP;
|
||||
else
|
||||
FFI_ASSERT (0);
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
|
||||
config[0] = closure;
|
||||
config[1] = closure_func;
|
||||
#else
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
|
||||
closure_func, \
|
||||
codeloc);
|
||||
#endif
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Below are routines for VFP hard-float support. */
|
||||
|
||||
static int rec_vfp_type_p (ffi_type *t, int *elt, int *elnum)
|
||||
{
|
||||
switch (t->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*elt = (int) t->type;
|
||||
*elnum = 1;
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT_VFP_FLOAT:
|
||||
*elt = FFI_TYPE_FLOAT;
|
||||
*elnum = t->size / sizeof (float);
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT_VFP_DOUBLE:
|
||||
*elt = FFI_TYPE_DOUBLE;
|
||||
*elnum = t->size / sizeof (double);
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT:;
|
||||
{
|
||||
int base_elt = 0, total_elnum = 0;
|
||||
ffi_type **el = t->elements;
|
||||
while (*el)
|
||||
{
|
||||
int el_elt = 0, el_elnum = 0;
|
||||
if (! rec_vfp_type_p (*el, &el_elt, &el_elnum)
|
||||
|| (base_elt && base_elt != el_elt)
|
||||
|| total_elnum + el_elnum > 4)
|
||||
return 0;
|
||||
base_elt = el_elt;
|
||||
total_elnum += el_elnum;
|
||||
el++;
|
||||
}
|
||||
*elnum = total_elnum;
|
||||
*elt = base_elt;
|
||||
return 1;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vfp_type_p (ffi_type *t)
|
||||
{
|
||||
int elt, elnum;
|
||||
if (rec_vfp_type_p (t, &elt, &elnum))
|
||||
{
|
||||
if (t->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
if (elnum == 1)
|
||||
t->type = elt;
|
||||
else
|
||||
t->type = (elt == FFI_TYPE_FLOAT
|
||||
? FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
: FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
}
|
||||
return (int) t->type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
{
|
||||
int reg = cif->vfp_reg_free;
|
||||
int nregs = t->size / sizeof (float);
|
||||
int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| t->type == FFI_TYPE_FLOAT) ? 1 : 2);
|
||||
/* Align register number. */
|
||||
if ((reg & 1) && align == 2)
|
||||
reg++;
|
||||
while (reg + nregs <= 16)
|
||||
{
|
||||
int s, new_used = 0;
|
||||
for (s = reg; s < reg + nregs; s++)
|
||||
{
|
||||
new_used |= (1 << s);
|
||||
if (cif->vfp_used & (1 << s))
|
||||
{
|
||||
reg += align;
|
||||
goto next_reg;
|
||||
}
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
{
|
||||
reg += nregs;
|
||||
while (cif->vfp_used & (1 << reg))
|
||||
reg += 1;
|
||||
cif->vfp_reg_free = reg;
|
||||
}
|
||||
return;
|
||||
next_reg: ;
|
||||
}
|
||||
}
|
||||
|
||||
static void layout_vfp_args (ffi_cif *cif)
|
||||
{
|
||||
int i;
|
||||
/* Init VFP fields */
|
||||
cif->vfp_used = 0;
|
||||
cif->vfp_nargs = 0;
|
||||
cif->vfp_reg_free = 0;
|
||||
memset (cif->vfp_args, -1, 16); /* Init to -1. */
|
||||
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
ffi_type *t = cif->arg_types[i];
|
||||
if (vfp_type_p (t))
|
||||
place_vfp_arg (cif, t);
|
||||
}
|
||||
}
|
||||
@@ -1,421 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
|
||||
|
||||
AVR32 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned int, unsigned int, unsigned int*, unsigned int,
|
||||
void (*fn)(void));
|
||||
extern void ffi_closure_SYSV (ffi_closure *);
|
||||
|
||||
unsigned int pass_struct_on_stack(ffi_type *type)
|
||||
{
|
||||
if(type->type != FFI_TYPE_STRUCT)
|
||||
return 0;
|
||||
|
||||
if(type->alignment < type->size &&
|
||||
!(type->size == 4 || type->size == 8) &&
|
||||
!(type->size == 8 && type->alignment >= 4))
|
||||
return 1;
|
||||
|
||||
if(type->size == 3 || type->size == 5 || type->size == 6 ||
|
||||
type->size == 7)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
* has been allocated for the function's arguments
|
||||
*
|
||||
* This is annoyingly complex since we need to keep track of used
|
||||
* registers.
|
||||
*/
|
||||
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
unsigned int i;
|
||||
void **p_argv;
|
||||
ffi_type **p_arg;
|
||||
char *reg_base = stack;
|
||||
char *stack_base = stack + 20;
|
||||
unsigned int stack_offset = 0;
|
||||
unsigned int reg_mask = 0;
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
/* If cif->flags is struct then we know it's not passed in registers */
|
||||
if(ecif->cif->flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*(void**)reg_base = ecif->rvalue;
|
||||
reg_mask |= 1;
|
||||
}
|
||||
|
||||
for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
|
||||
i++, p_arg++)
|
||||
{
|
||||
size_t z = (*p_arg)->size;
|
||||
int alignment = (*p_arg)->alignment;
|
||||
int type = (*p_arg)->type;
|
||||
char *addr = 0;
|
||||
|
||||
if(z % 4 != 0)
|
||||
z += (4 - z % 4);
|
||||
|
||||
if(reg_mask != 0x1f)
|
||||
{
|
||||
if(pass_struct_on_stack(*p_arg))
|
||||
{
|
||||
addr = stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
else if(z == sizeof(int))
|
||||
{
|
||||
char index = 0;
|
||||
|
||||
while((reg_mask >> index) & 1)
|
||||
index++;
|
||||
|
||||
addr = reg_base + (index * 4);
|
||||
reg_mask |= (1 << index);
|
||||
}
|
||||
else if(z == 2 * sizeof(int))
|
||||
{
|
||||
if(!((reg_mask >> 1) & 1))
|
||||
{
|
||||
addr = reg_base + 4;
|
||||
reg_mask |= (3 << 1);
|
||||
}
|
||||
else if(!((reg_mask >> 3) & 1))
|
||||
{
|
||||
addr = reg_base + 12;
|
||||
reg_mask |= (3 << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!addr)
|
||||
{
|
||||
addr = stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
|
||||
if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
|
||||
type = (*p_arg)->elements[0]->type;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
|
||||
break;
|
||||
default:
|
||||
memcpy(addr, *p_argv, z);
|
||||
}
|
||||
|
||||
p_argv++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
if((reg_mask & (1 << i)) == 0)
|
||||
printf("r%d: (unused)\n", 12 - i);
|
||||
else
|
||||
printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < stack_offset / 4; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
* everywhere, but it is on some platforms, and it doesn't harm
|
||||
* anything when it isn't needed. */
|
||||
cif->bytes = (cif->bytes + 7) & ~7;
|
||||
|
||||
/* Flag to indicate that he return value is in fact a struct */
|
||||
cif->rstruct_flag = 0;
|
||||
|
||||
/* Set the return type flag */
|
||||
switch(cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT8;
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT16;
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT32;
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT64;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
cif->rstruct_flag = 1;
|
||||
if(!pass_struct_on_stack(cif->rtype))
|
||||
{
|
||||
if(cif->rtype->size <= 1)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT8;
|
||||
else if(cif->rtype->size <= 2)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT16;
|
||||
else if(cif->rtype->size <= 4)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT32;
|
||||
else if(cif->rtype->size <= 8)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT64;
|
||||
else
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
}
|
||||
else
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
break;
|
||||
default:
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
unsigned int size = 0, i = 0;
|
||||
ffi_type **p_arg;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
|
||||
|
||||
/* If the return value is a struct and we don't have a return value
|
||||
* address then we need to make one */
|
||||
|
||||
/* If cif->flags is struct then it's not suitable for registers */
|
||||
if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch(cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
|
||||
ecif.rvalue, cif->rstruct_flag, fn);
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif)
|
||||
{
|
||||
register unsigned int i, reg_mask = 0;
|
||||
register void **p_argv;
|
||||
register ffi_type **p_arg;
|
||||
register char *reg_base = stack;
|
||||
register char *stack_base = stack + 20;
|
||||
register unsigned int stack_offset = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < cif->nargs + 7; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If cif->flags is struct then we know it's not passed in registers */
|
||||
if(cif->flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*rvalue = *(void **)reg_base;
|
||||
reg_mask |= 1;
|
||||
}
|
||||
|
||||
p_argv = avalue;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
{
|
||||
size_t z = (*p_arg)->size;
|
||||
int alignment = (*p_arg)->alignment;
|
||||
|
||||
*p_argv = 0;
|
||||
|
||||
if(z % 4 != 0)
|
||||
z += (4 - z % 4);
|
||||
|
||||
if(reg_mask != 0x1f)
|
||||
{
|
||||
if(pass_struct_on_stack(*p_arg))
|
||||
{
|
||||
*p_argv = (void*)stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
else if(z <= sizeof(int))
|
||||
{
|
||||
char index = 0;
|
||||
|
||||
while((reg_mask >> index) & 1)
|
||||
index++;
|
||||
|
||||
*p_argv = (void*)reg_base + (index * 4);
|
||||
reg_mask |= (1 << index);
|
||||
}
|
||||
else if(z == 2 * sizeof(int))
|
||||
{
|
||||
if(!((reg_mask >> 1) & 1))
|
||||
{
|
||||
*p_argv = (void*)reg_base + 4;
|
||||
reg_mask |= (3 << 1);
|
||||
}
|
||||
else if(!((reg_mask >> 3) & 1))
|
||||
{
|
||||
*p_argv = (void*)reg_base + 12;
|
||||
reg_mask |= (3 << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!*p_argv)
|
||||
{
|
||||
*p_argv = (void*)stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
|
||||
if((*p_arg)->type != FFI_TYPE_STRUCT ||
|
||||
(*p_arg)->elements[1] == NULL)
|
||||
{
|
||||
if(alignment == 1)
|
||||
**(unsigned int**)p_argv <<= 24;
|
||||
else if(alignment == 2)
|
||||
**(unsigned int**)p_argv <<= 16;
|
||||
}
|
||||
|
||||
p_argv++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
|
||||
void *args)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
unsigned int i, size = 0;
|
||||
ffi_type **p_arg;
|
||||
|
||||
cif = closure->cif;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
|
||||
|
||||
arg_area = (void **)alloca(size);
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each element in that
|
||||
* array points to the corresponding value on the stack; and if the
|
||||
* function returns a structure, it will re-set RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
|
||||
|
||||
(closure->fun)(cif, *respp, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
FFI_ASSERT(cif->abi == FFI_SYSV);
|
||||
|
||||
unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
|
||||
unsigned int __fun = (unsigned int)(&ffi_closure_SYSV);
|
||||
unsigned int __ctx = (unsigned int)(codeloc);
|
||||
unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag);
|
||||
unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner);
|
||||
*(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */
|
||||
*(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */
|
||||
*(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */
|
||||
*(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */
|
||||
*(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */
|
||||
*(unsigned int*) &__tramp[20] = __ctx;
|
||||
*(unsigned int*) &__tramp[24] = __rstruct_flag;
|
||||
*(unsigned int*) &__tramp[28] = __inner;
|
||||
*(unsigned int*) &__tramp[32] = __fun;
|
||||
syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
@@ -1,580 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1998, 2007, 2008 Red Hat, Inc.
|
||||
Copyright (c) 2000 Hewlett Packard Company
|
||||
|
||||
IA64 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "ia64_flags.h"
|
||||
|
||||
/* A 64-bit pointer value. In LP64 mode, this is effectively a plain
|
||||
pointer. In ILP32 mode, it's a pointer that's been extended to
|
||||
64 bits by "addp4". */
|
||||
typedef void *PTR64 __attribute__((mode(DI)));
|
||||
|
||||
/* Memory image of fp register contents. This is the implementation
|
||||
specific format used by ldf.fill/stf.spill. All we care about is
|
||||
that it wants a 16 byte aligned slot. */
|
||||
typedef struct
|
||||
{
|
||||
UINT64 x[2] __attribute__((aligned(16)));
|
||||
} fpreg;
|
||||
|
||||
|
||||
/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner. */
|
||||
|
||||
struct ia64_args
|
||||
{
|
||||
fpreg fp_regs[8]; /* Contents of 8 fp arg registers. */
|
||||
UINT64 gp_regs[8]; /* Contents of 8 gp arg registers. */
|
||||
UINT64 other_args[]; /* Arguments passed on stack, variable size. */
|
||||
};
|
||||
|
||||
|
||||
/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes. */
|
||||
|
||||
static inline void *
|
||||
endian_adjust (void *addr, size_t len)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN__
|
||||
return addr + (8 - len);
|
||||
#else
|
||||
return addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Store VALUE to ADDR in the current cpu implementation's fp spill format.
|
||||
This is a macro instead of a function, so that it works for all 3 floating
|
||||
point types without type conversions. Type conversion to long double breaks
|
||||
the denorm support. */
|
||||
|
||||
#define stf_spill(addr, value) \
|
||||
asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
|
||||
|
||||
/* Load a value from ADDR, which is in the current cpu implementation's
|
||||
fp spill format. As above, this must also be a macro. */
|
||||
|
||||
#define ldf_fill(result, addr) \
|
||||
asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));
|
||||
|
||||
/* Return the size of the C type associated with with TYPE. Which will
|
||||
be one of the FFI_IA64_TYPE_HFA_* values. */
|
||||
|
||||
static size_t
|
||||
hfa_type_size (int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_IA64_TYPE_HFA_FLOAT:
|
||||
return sizeof(float);
|
||||
case FFI_IA64_TYPE_HFA_DOUBLE:
|
||||
return sizeof(double);
|
||||
case FFI_IA64_TYPE_HFA_LDOUBLE:
|
||||
return sizeof(__float80);
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Load from ADDR a value indicated by TYPE. Which will be one of
|
||||
the FFI_IA64_TYPE_HFA_* values. */
|
||||
|
||||
static void
|
||||
hfa_type_load (fpreg *fpaddr, int type, void *addr)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_IA64_TYPE_HFA_FLOAT:
|
||||
stf_spill (fpaddr, *(float *) addr);
|
||||
return;
|
||||
case FFI_IA64_TYPE_HFA_DOUBLE:
|
||||
stf_spill (fpaddr, *(double *) addr);
|
||||
return;
|
||||
case FFI_IA64_TYPE_HFA_LDOUBLE:
|
||||
stf_spill (fpaddr, *(__float80 *) addr);
|
||||
return;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Load VALUE into ADDR as indicated by TYPE. Which will be one of
|
||||
the FFI_IA64_TYPE_HFA_* values. */
|
||||
|
||||
static void
|
||||
hfa_type_store (int type, void *addr, fpreg *fpaddr)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_IA64_TYPE_HFA_FLOAT:
|
||||
{
|
||||
float result;
|
||||
ldf_fill (result, fpaddr);
|
||||
*(float *) addr = result;
|
||||
break;
|
||||
}
|
||||
case FFI_IA64_TYPE_HFA_DOUBLE:
|
||||
{
|
||||
double result;
|
||||
ldf_fill (result, fpaddr);
|
||||
*(double *) addr = result;
|
||||
break;
|
||||
}
|
||||
case FFI_IA64_TYPE_HFA_LDOUBLE:
|
||||
{
|
||||
__float80 result;
|
||||
ldf_fill (result, fpaddr);
|
||||
*(__float80 *) addr = result;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Is TYPE a struct containing floats, doubles, or extended doubles,
|
||||
all of the same fp type? If so, return the element type. Return
|
||||
FFI_TYPE_VOID if not. */
|
||||
|
||||
static int
|
||||
hfa_element_type (ffi_type *type, int nested)
|
||||
{
|
||||
int element = FFI_TYPE_VOID;
|
||||
|
||||
switch (type->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* We want to return VOID for raw floating-point types, but the
|
||||
synthetic HFA type if we're nested within an aggregate. */
|
||||
if (nested)
|
||||
element = FFI_IA64_TYPE_HFA_FLOAT;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
/* Similarly. */
|
||||
if (nested)
|
||||
element = FFI_IA64_TYPE_HFA_DOUBLE;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* Similarly, except that that HFA is true for double extended,
|
||||
but not quad precision. Both have sizeof == 16, so tell the
|
||||
difference based on the precision. */
|
||||
if (LDBL_MANT_DIG == 64 && nested)
|
||||
element = FFI_IA64_TYPE_HFA_LDOUBLE;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
ffi_type **ptr = &type->elements[0];
|
||||
|
||||
for (ptr = &type->elements[0]; *ptr ; ptr++)
|
||||
{
|
||||
int sub_element = hfa_element_type (*ptr, 1);
|
||||
if (sub_element == FFI_TYPE_VOID)
|
||||
return FFI_TYPE_VOID;
|
||||
|
||||
if (element == FFI_TYPE_VOID)
|
||||
element = sub_element;
|
||||
else if (element != sub_element)
|
||||
return FFI_TYPE_VOID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FFI_TYPE_VOID;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
/* Perform machine dependent cif processing. */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int flags;
|
||||
|
||||
/* Adjust cif->bytes to include space for the bits of the ia64_args frame
|
||||
that precedes the integer register portion. The estimate that the
|
||||
generic bits did for the argument space required is good enough for the
|
||||
integer component. */
|
||||
cif->bytes += offsetof(struct ia64_args, gp_regs[0]);
|
||||
if (cif->bytes < sizeof(struct ia64_args))
|
||||
cif->bytes = sizeof(struct ia64_args);
|
||||
|
||||
/* Set the return type flag. */
|
||||
flags = cif->rtype->type;
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision,
|
||||
and encode quad precision as a two-word integer structure. */
|
||||
if (LDBL_MANT_DIG != 64)
|
||||
flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
size_t size = cif->rtype->size;
|
||||
int hfa_type = hfa_element_type (cif->rtype, 0);
|
||||
|
||||
if (hfa_type != FFI_TYPE_VOID)
|
||||
{
|
||||
size_t nelts = size / hfa_type_size (hfa_type);
|
||||
if (nelts <= 8)
|
||||
flags = hfa_type | (size << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size <= 32)
|
||||
flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cif->flags = flags;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
|
||||
|
||||
void
|
||||
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
struct ia64_args *stack;
|
||||
long i, avn, gpcount, fpcount;
|
||||
ffi_type **p_arg;
|
||||
|
||||
FFI_ASSERT (cif->abi == FFI_UNIX);
|
||||
|
||||
/* If we have no spot for a return value, make one. */
|
||||
if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID)
|
||||
rvalue = alloca (cif->rtype->size);
|
||||
|
||||
/* Allocate the stack frame. */
|
||||
stack = alloca (cif->bytes);
|
||||
|
||||
gpcount = fpcount = 0;
|
||||
avn = cif->nargs;
|
||||
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
||||
{
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_UINT8:
|
||||
stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_SINT32:
|
||||
stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_UINT32:
|
||||
stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
|
||||
break;
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (gpcount < 8 && fpcount < 8)
|
||||
stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]);
|
||||
stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
if (gpcount < 8 && fpcount < 8)
|
||||
stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]);
|
||||
stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
if (gpcount & 1)
|
||||
gpcount++;
|
||||
if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
|
||||
stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]);
|
||||
memcpy (&stack->gp_regs[gpcount], avalue[i], 16);
|
||||
gpcount += 2;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
size_t size = (*p_arg)->size;
|
||||
size_t align = (*p_arg)->alignment;
|
||||
int hfa_type = hfa_element_type (*p_arg, 0);
|
||||
|
||||
FFI_ASSERT (align <= 16);
|
||||
if (align == 16 && (gpcount & 1))
|
||||
gpcount++;
|
||||
|
||||
if (hfa_type != FFI_TYPE_VOID)
|
||||
{
|
||||
size_t hfa_size = hfa_type_size (hfa_type);
|
||||
size_t offset = 0;
|
||||
size_t gp_offset = gpcount * 8;
|
||||
|
||||
while (fpcount < 8
|
||||
&& offset < size
|
||||
&& gp_offset < 8 * 8)
|
||||
{
|
||||
hfa_type_load (&stack->fp_regs[fpcount], hfa_type,
|
||||
avalue[i] + offset);
|
||||
offset += hfa_size;
|
||||
gp_offset += hfa_size;
|
||||
fpcount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (&stack->gp_regs[gpcount], avalue[i], size);
|
||||
gpcount += (size + 7) / 8;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
ffi_call_unix (stack, rvalue, fn, cif->flags);
|
||||
}
|
||||
|
||||
/* Closures represent a pair consisting of a function pointer, and
|
||||
some user data. A closure is invoked by reinterpreting the closure
|
||||
as a function pointer, and branching to it. Thus we can make an
|
||||
interpreted function callable as a C function: We turn the
|
||||
interpreter itself, together with a pointer specifying the
|
||||
interpreted procedure, into a closure.
|
||||
|
||||
For IA64, function pointer are already pairs consisting of a code
|
||||
pointer, and a gp pointer. The latter is needed to access global
|
||||
variables. Here we set up such a pair as the first two words of
|
||||
the closure (in the "trampoline" area), but we replace the gp
|
||||
pointer with a pointer to the closure itself. We also add the real
|
||||
gp pointer to the closure. This allows the function entry code to
|
||||
both retrieve the user data, and to restire the correct gp pointer. */
|
||||
|
||||
extern void ffi_closure_unix ();
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
/* The layout of a function descriptor. A C function pointer really
|
||||
points to one of these. */
|
||||
struct ia64_fd
|
||||
{
|
||||
UINT64 code_pointer;
|
||||
UINT64 gp;
|
||||
};
|
||||
|
||||
struct ffi_ia64_trampoline_struct
|
||||
{
|
||||
UINT64 code_pointer; /* Pointer to ffi_closure_unix. */
|
||||
UINT64 fake_gp; /* Pointer to closure, installed as gp. */
|
||||
UINT64 real_gp; /* Real gp value. */
|
||||
};
|
||||
|
||||
struct ffi_ia64_trampoline_struct *tramp;
|
||||
struct ia64_fd *fd;
|
||||
|
||||
FFI_ASSERT (cif->abi == FFI_UNIX);
|
||||
|
||||
tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp;
|
||||
fd = (struct ia64_fd *)(void *)ffi_closure_unix;
|
||||
|
||||
tramp->code_pointer = fd->code_pointer;
|
||||
tramp->real_gp = fd->gp;
|
||||
tramp->fake_gp = (UINT64)(PTR64)codeloc;
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
|
||||
UINT64
|
||||
ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
|
||||
void *rvalue, void *r8)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avalue;
|
||||
ffi_type **p_arg;
|
||||
long i, avn, gpcount, fpcount;
|
||||
|
||||
cif = closure->cif;
|
||||
avn = cif->nargs;
|
||||
avalue = alloca (avn * sizeof (void *));
|
||||
|
||||
/* If the structure return value is passed in memory get that location
|
||||
from r8 so as to pass the value directly back to the caller. */
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
rvalue = r8;
|
||||
|
||||
gpcount = fpcount = 0;
|
||||
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
||||
{
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1);
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2);
|
||||
break;
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4);
|
||||
break;
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
avalue[i] = &stack->gp_regs[gpcount++];
|
||||
break;
|
||||
case FFI_TYPE_POINTER:
|
||||
avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*));
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (gpcount < 8 && fpcount < 8)
|
||||
{
|
||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||
float result;
|
||||
avalue[i] = addr;
|
||||
ldf_fill (result, addr);
|
||||
*(float *)addr = result;
|
||||
}
|
||||
else
|
||||
avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);
|
||||
gpcount++;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
if (gpcount < 8 && fpcount < 8)
|
||||
{
|
||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||
double result;
|
||||
avalue[i] = addr;
|
||||
ldf_fill (result, addr);
|
||||
*(double *)addr = result;
|
||||
}
|
||||
else
|
||||
avalue[i] = &stack->gp_regs[gpcount];
|
||||
gpcount++;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
if (gpcount & 1)
|
||||
gpcount++;
|
||||
if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
|
||||
{
|
||||
fpreg *addr = &stack->fp_regs[fpcount++];
|
||||
__float80 result;
|
||||
avalue[i] = addr;
|
||||
ldf_fill (result, addr);
|
||||
*(__float80 *)addr = result;
|
||||
}
|
||||
else
|
||||
avalue[i] = &stack->gp_regs[gpcount];
|
||||
gpcount += 2;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
size_t size = (*p_arg)->size;
|
||||
size_t align = (*p_arg)->alignment;
|
||||
int hfa_type = hfa_element_type (*p_arg, 0);
|
||||
|
||||
FFI_ASSERT (align <= 16);
|
||||
if (align == 16 && (gpcount & 1))
|
||||
gpcount++;
|
||||
|
||||
if (hfa_type != FFI_TYPE_VOID)
|
||||
{
|
||||
size_t hfa_size = hfa_type_size (hfa_type);
|
||||
size_t offset = 0;
|
||||
size_t gp_offset = gpcount * 8;
|
||||
void *addr = alloca (size);
|
||||
|
||||
avalue[i] = addr;
|
||||
|
||||
while (fpcount < 8
|
||||
&& offset < size
|
||||
&& gp_offset < 8 * 8)
|
||||
{
|
||||
hfa_type_store (hfa_type, addr + offset,
|
||||
&stack->fp_regs[fpcount]);
|
||||
offset += hfa_size;
|
||||
gp_offset += hfa_size;
|
||||
fpcount += 1;
|
||||
}
|
||||
|
||||
if (offset < size)
|
||||
memcpy (addr + offset, (char *)stack->gp_regs + gp_offset,
|
||||
size - offset);
|
||||
}
|
||||
else
|
||||
avalue[i] = &stack->gp_regs[gpcount];
|
||||
|
||||
gpcount += (size + 7) / 8;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
closure->fun (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,716 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - (c) 2003-2004 Randolph Chung <tausq@debian.org>
|
||||
(c) 2008 Red Hat, Inc.
|
||||
|
||||
HPPA Foreign Function Interface
|
||||
HP-UX PA ABI support (c) 2006 Free Software Foundation, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1))
|
||||
|
||||
#define MIN_STACK_SIZE 64
|
||||
#define FIRST_ARG_SLOT 9
|
||||
#define DEBUG_LEVEL 0
|
||||
|
||||
#define fldw(addr, fpreg) \
|
||||
__asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
|
||||
#define fstw(fpreg, addr) \
|
||||
__asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
|
||||
#define fldd(addr, fpreg) \
|
||||
__asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
|
||||
#define fstd(fpreg, addr) \
|
||||
__asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
|
||||
|
||||
#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
|
||||
|
||||
static inline int ffi_struct_type(ffi_type *t)
|
||||
{
|
||||
size_t sz = t->size;
|
||||
|
||||
/* Small structure results are passed in registers,
|
||||
larger ones are passed by pointer. Note that
|
||||
small structures of size 2, 4 and 8 differ from
|
||||
the corresponding integer types in that they have
|
||||
different alignment requirements. */
|
||||
|
||||
if (sz <= 1)
|
||||
return FFI_TYPE_UINT8;
|
||||
else if (sz == 2)
|
||||
return FFI_TYPE_SMALL_STRUCT2;
|
||||
else if (sz == 3)
|
||||
return FFI_TYPE_SMALL_STRUCT3;
|
||||
else if (sz == 4)
|
||||
return FFI_TYPE_SMALL_STRUCT4;
|
||||
else if (sz == 5)
|
||||
return FFI_TYPE_SMALL_STRUCT5;
|
||||
else if (sz == 6)
|
||||
return FFI_TYPE_SMALL_STRUCT6;
|
||||
else if (sz == 7)
|
||||
return FFI_TYPE_SMALL_STRUCT7;
|
||||
else if (sz <= 8)
|
||||
return FFI_TYPE_SMALL_STRUCT8;
|
||||
else
|
||||
return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */
|
||||
}
|
||||
|
||||
/* PA has a downward growing stack, which looks like this:
|
||||
|
||||
Offset
|
||||
[ Variable args ]
|
||||
SP = (4*(n+9)) arg word N
|
||||
...
|
||||
SP-52 arg word 4
|
||||
[ Fixed args ]
|
||||
SP-48 arg word 3
|
||||
SP-44 arg word 2
|
||||
SP-40 arg word 1
|
||||
SP-36 arg word 0
|
||||
[ Frame marker ]
|
||||
...
|
||||
SP-20 RP
|
||||
SP-4 previous SP
|
||||
|
||||
The first four argument words on the stack are reserved for use by
|
||||
the callee. Instead, the general and floating registers replace
|
||||
the first four argument slots. Non FP arguments are passed solely
|
||||
in the general registers. FP arguments are passed in both general
|
||||
and floating registers when using libffi.
|
||||
|
||||
Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23.
|
||||
Non-FP 64-bit args are passed in register pairs, starting
|
||||
on an odd numbered register (i.e. r25+r26 and r23+r24).
|
||||
FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L.
|
||||
FP 64-bit arguments are passed in fr5 and fr7.
|
||||
|
||||
The registers are allocated in the same manner as stack slots.
|
||||
This allows the callee to save its arguments on the stack if
|
||||
necessary:
|
||||
|
||||
arg word 3 -> gr23 or fr7L
|
||||
arg word 2 -> gr24 or fr6L or fr7R
|
||||
arg word 1 -> gr25 or fr5L
|
||||
arg word 0 -> gr26 or fr4L or fr5R
|
||||
|
||||
Note that fr4R and fr6R are never used for arguments (i.e.,
|
||||
doubles are not passed in fr4 or fr6).
|
||||
|
||||
The rest of the arguments are passed on the stack starting at SP-52,
|
||||
but 64-bit arguments need to be aligned to an 8-byte boundary
|
||||
|
||||
This means we can have holes either in the register allocation,
|
||||
or in the stack. */
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
|
||||
The following code will put everything into the stack frame
|
||||
(which was allocated by the asm routine), and on return
|
||||
the asm routine will load the arguments that should be
|
||||
passed by register into the appropriate registers
|
||||
|
||||
NOTE: We load floating point args in this function... that means we
|
||||
assume gcc will not mess with fp regs in here. */
|
||||
|
||||
void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)
|
||||
{
|
||||
register unsigned int i;
|
||||
register ffi_type **p_arg;
|
||||
register void **p_argv;
|
||||
unsigned int slot = FIRST_ARG_SLOT;
|
||||
char *dest_cpy;
|
||||
size_t len;
|
||||
|
||||
debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack,
|
||||
ecif, bytes);
|
||||
|
||||
p_arg = ecif->cif->arg_types;
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = 0; i < ecif->cif->nargs; i++)
|
||||
{
|
||||
int type = (*p_arg)->type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv),
|
||||
slot);
|
||||
*(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
/* Align slot for 64-bit type. */
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
*(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* First 4 args go in fr4L - fr7L. */
|
||||
debug(3, "Storing UINT32(float) in slot %u\n", slot);
|
||||
*(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
|
||||
switch (slot - FIRST_ARG_SLOT)
|
||||
{
|
||||
/* First 4 args go in fr4L - fr7L. */
|
||||
case 0: fldw(stack - slot, fr4); break;
|
||||
case 1: fldw(stack - slot, fr5); break;
|
||||
case 2: fldw(stack - slot, fr6); break;
|
||||
case 3: fldw(stack - slot, fr7); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
/* Align slot for 64-bit type. */
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
debug(3, "Storing UINT64(double) at slot %u\n", slot);
|
||||
*(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
|
||||
switch (slot - FIRST_ARG_SLOT)
|
||||
{
|
||||
/* First 2 args go in fr5, fr7. */
|
||||
case 1: fldd(stack - slot, fr5); break;
|
||||
case 3: fldd(stack - slot, fr7); break;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef PA_HPUX
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* Long doubles are passed in the same manner as structures
|
||||
larger than 8 bytes. */
|
||||
*(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
|
||||
/* Structs smaller or equal than 4 bytes are passed in one
|
||||
register. Structs smaller or equal 8 bytes are passed in two
|
||||
registers. Larger structures are passed by pointer. */
|
||||
|
||||
len = (*p_arg)->size;
|
||||
if (len <= 4)
|
||||
{
|
||||
dest_cpy = (char *)(stack - slot) + 4 - len;
|
||||
memcpy(dest_cpy, (char *)*p_argv, len);
|
||||
}
|
||||
else if (len <= 8)
|
||||
{
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
dest_cpy = (char *)(stack - slot) + 8 - len;
|
||||
memcpy(dest_cpy, (char *)*p_argv, len);
|
||||
}
|
||||
else
|
||||
*(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
|
||||
slot++;
|
||||
p_arg++;
|
||||
p_argv++;
|
||||
}
|
||||
|
||||
/* Make sure we didn't mess up and scribble on the stack. */
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
debug(5, "Stack setup:\n");
|
||||
for (n = 0; n < (bytes + 3) / 4; n++)
|
||||
{
|
||||
if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); }
|
||||
debug(5, "%08x ", *(stack - n));
|
||||
}
|
||||
debug(5, "\n");
|
||||
}
|
||||
|
||||
FFI_ASSERT(slot * 4 <= bytes);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void ffi_size_stack_pa32(ffi_cif *cif)
|
||||
{
|
||||
ffi_type **ptr;
|
||||
int i;
|
||||
int z = 0; /* # stack slots */
|
||||
|
||||
for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++)
|
||||
{
|
||||
int type = (*ptr)->type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
z += 2 + (z & 1); /* must start on even regs, so we may waste one */
|
||||
break;
|
||||
|
||||
#ifdef PA_HPUX
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
case FFI_TYPE_STRUCT:
|
||||
z += 1; /* pass by ptr, callee will copy */
|
||||
break;
|
||||
|
||||
default: /* <= 32-bit values */
|
||||
z++;
|
||||
}
|
||||
}
|
||||
|
||||
/* We can fit up to 6 args in the default 64-byte stack frame,
|
||||
if we need more, we need more stack. */
|
||||
if (z <= 6)
|
||||
cif->bytes = MIN_STACK_SIZE; /* min stack size */
|
||||
else
|
||||
cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE);
|
||||
|
||||
debug(3, "Calculated stack size is %u bytes\n", cif->bytes);
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing. */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
#ifdef PA_HPUX
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* Long doubles are treated like a structure. */
|
||||
cif->flags = FFI_TYPE_STRUCT;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* For the return type we have to check the size of the structures.
|
||||
If the size is smaller or equal 4 bytes, the result is given back
|
||||
in one register. If the size is smaller or equal 8 bytes than we
|
||||
return the result in two registers. But if the size is bigger than
|
||||
8 bytes, we work with pointers. */
|
||||
cif->flags = ffi_struct_type(cif->rtype);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
cif->flags = FFI_TYPE_UINT64;
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Lucky us, because of the unique PA ABI we get to do our
|
||||
own stack sizing. */
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_PA32:
|
||||
ffi_size_stack_pa32(cif);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
|
||||
extended_cif *, unsigned, unsigned, unsigned *,
|
||||
void (*fn)(void));
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have a return
|
||||
value address then we need to make one. */
|
||||
|
||||
if (rvalue == NULL
|
||||
#ifdef PA_HPUX
|
||||
&& (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
|| cif->rtype->type == FFI_TYPE_LONGDOUBLE))
|
||||
#else
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
#endif
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_PA32:
|
||||
debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
|
||||
ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if FFI_CLOSURES
|
||||
/* This is more-or-less an inverse of ffi_call -- we have arguments on
|
||||
the stack, and we need to fill them into a cif structure and invoke
|
||||
the user function. This really ought to be in asm to make sure
|
||||
the compiler doesn't do things we don't expect. */
|
||||
ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avalue;
|
||||
void *rvalue;
|
||||
UINT32 ret[2]; /* function can return up to 64-bits in registers */
|
||||
ffi_type **p_arg;
|
||||
char *tmp;
|
||||
int i, avn;
|
||||
unsigned int slot = FIRST_ARG_SLOT;
|
||||
register UINT32 r28 asm("r28");
|
||||
|
||||
cif = closure->cif;
|
||||
|
||||
/* If returning via structure, callee will write to our pointer. */
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
rvalue = (void *)r28;
|
||||
else
|
||||
rvalue = &ret[0];
|
||||
|
||||
avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);
|
||||
avn = cif->nargs;
|
||||
p_arg = cif->arg_types;
|
||||
|
||||
for (i = 0; i < avn; i++)
|
||||
{
|
||||
int type = (*p_arg)->type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
avalue[i] = (void *)(stack - slot);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
#ifdef PA_LINUX
|
||||
/* The closure call is indirect. In Linux, floating point
|
||||
arguments in indirect calls with a prototype are passed
|
||||
in the floating point registers instead of the general
|
||||
registers. So, we need to replace what was previously
|
||||
stored in the current slot with the value in the
|
||||
corresponding floating point register. */
|
||||
switch (slot - FIRST_ARG_SLOT)
|
||||
{
|
||||
case 0: fstw(fr4, (void *)(stack - slot)); break;
|
||||
case 1: fstw(fr5, (void *)(stack - slot)); break;
|
||||
case 2: fstw(fr6, (void *)(stack - slot)); break;
|
||||
case 3: fstw(fr7, (void *)(stack - slot)); break;
|
||||
}
|
||||
#endif
|
||||
avalue[i] = (void *)(stack - slot);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
#ifdef PA_LINUX
|
||||
/* See previous comment for FFI_TYPE_FLOAT. */
|
||||
switch (slot - FIRST_ARG_SLOT)
|
||||
{
|
||||
case 1: fstd(fr5, (void *)(stack - slot)); break;
|
||||
case 3: fstd(fr7, (void *)(stack - slot)); break;
|
||||
}
|
||||
#endif
|
||||
avalue[i] = (void *)(stack - slot);
|
||||
break;
|
||||
|
||||
#ifdef PA_HPUX
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* Long doubles are treated like a big structure. */
|
||||
avalue[i] = (void *) *(stack - slot);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* Structs smaller or equal than 4 bytes are passed in one
|
||||
register. Structs smaller or equal 8 bytes are passed in two
|
||||
registers. Larger structures are passed by pointer. */
|
||||
if((*p_arg)->size <= 4)
|
||||
{
|
||||
avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -
|
||||
(*p_arg)->size;
|
||||
}
|
||||
else if ((*p_arg)->size <= 8)
|
||||
{
|
||||
slot += (slot & 1) ? 1 : 2;
|
||||
avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -
|
||||
(*p_arg)->size;
|
||||
}
|
||||
else
|
||||
avalue[i] = (void *) *(stack - slot);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
|
||||
slot++;
|
||||
p_arg++;
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
|
||||
ret[1]);
|
||||
|
||||
/* Store the result using the lower 2 bytes of the flags. */
|
||||
switch (cif->flags)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
*(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24);
|
||||
break;
|
||||
case FFI_TYPE_SINT8:
|
||||
*(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24);
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
*(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16);
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
*(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16);
|
||||
break;
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
*(stack - FIRST_ARG_SLOT) = ret[0];
|
||||
break;
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
*(stack - FIRST_ARG_SLOT) = ret[0];
|
||||
*(stack - FIRST_ARG_SLOT - 1) = ret[1];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
fldd(rvalue, fr4);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
fldw(rvalue, fr4);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* Don't need a return value, done by caller. */
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SMALL_STRUCT2:
|
||||
case FFI_TYPE_SMALL_STRUCT3:
|
||||
case FFI_TYPE_SMALL_STRUCT4:
|
||||
tmp = (void*)(stack - FIRST_ARG_SLOT);
|
||||
tmp += 4 - cif->rtype->size;
|
||||
memcpy((void*)tmp, &ret[0], cif->rtype->size);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SMALL_STRUCT5:
|
||||
case FFI_TYPE_SMALL_STRUCT6:
|
||||
case FFI_TYPE_SMALL_STRUCT7:
|
||||
case FFI_TYPE_SMALL_STRUCT8:
|
||||
{
|
||||
unsigned int ret2[2];
|
||||
int off;
|
||||
|
||||
/* Right justify ret[0] and ret[1] */
|
||||
switch (cif->flags)
|
||||
{
|
||||
case FFI_TYPE_SMALL_STRUCT5: off = 3; break;
|
||||
case FFI_TYPE_SMALL_STRUCT6: off = 2; break;
|
||||
case FFI_TYPE_SMALL_STRUCT7: off = 1; break;
|
||||
default: off = 0; break;
|
||||
}
|
||||
|
||||
memset (ret2, 0, sizeof (ret2));
|
||||
memcpy ((char *)ret2 + off, ret, 8 - off);
|
||||
|
||||
*(stack - FIRST_ARG_SLOT) = ret2[0];
|
||||
*(stack - FIRST_ARG_SLOT - 1) = ret2[1];
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
case FFI_TYPE_VOID:
|
||||
break;
|
||||
|
||||
default:
|
||||
debug(0, "assert with cif->flags: %d\n",cif->flags);
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Fill in a closure to refer to the specified fun and user_data.
|
||||
cif specifies the argument and result types for fun.
|
||||
The cif must already be prep'ed. */
|
||||
|
||||
extern void ffi_closure_pa32(void);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
UINT32 *tramp = (UINT32 *)(closure->tramp);
|
||||
#ifdef PA_HPUX
|
||||
UINT32 *tmp;
|
||||
#endif
|
||||
|
||||
FFI_ASSERT (cif->abi == FFI_PA32);
|
||||
|
||||
/* Make a small trampoline that will branch to our
|
||||
handler function. Use PC-relative addressing. */
|
||||
|
||||
#ifdef PA_LINUX
|
||||
tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */
|
||||
tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */
|
||||
tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1 ; load plabel */
|
||||
tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */
|
||||
tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */
|
||||
tramp[5] = 0xeac0c000; /* bv%r0(%r22) ; branch to handler */
|
||||
tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */
|
||||
tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2);
|
||||
|
||||
/* Flush d/icache -- have to flush up 2 two lines because of
|
||||
alignment. */
|
||||
__asm__ volatile(
|
||||
"fdc 0(%0)\n\t"
|
||||
"fdc %1(%0)\n\t"
|
||||
"fic 0(%%sr4, %0)\n\t"
|
||||
"fic %1(%%sr4, %0)\n\t"
|
||||
"sync\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n"
|
||||
:
|
||||
: "r"((unsigned long)tramp & ~31),
|
||||
"r"(32 /* stride */)
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
#ifdef PA_HPUX
|
||||
tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */
|
||||
tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */
|
||||
tramp[2] = 0x4aa10038; /* ldw 28(%r21),%r1 ; load plabel */
|
||||
tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */
|
||||
tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */
|
||||
tramp[5] = 0x02c010b4; /* ldsid (%r22),%r20 ; load space id */
|
||||
tramp[6] = 0x00141820; /* mtsp %r20,%sr0 ; into %sr0 */
|
||||
tramp[7] = 0xe2c00000; /* be 0(%sr0,%r22) ; branch to handler */
|
||||
tramp[8] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */
|
||||
tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2);
|
||||
|
||||
/* Flush d/icache -- have to flush three lines because of alignment. */
|
||||
__asm__ volatile(
|
||||
"copy %1,%0\n\t"
|
||||
"fdc,m %2(%0)\n\t"
|
||||
"fdc,m %2(%0)\n\t"
|
||||
"fdc,m %2(%0)\n\t"
|
||||
"ldsid (%1),%0\n\t"
|
||||
"mtsp %0,%%sr0\n\t"
|
||||
"copy %1,%0\n\t"
|
||||
"fic,m %2(%%sr0,%0)\n\t"
|
||||
"fic,m %2(%%sr0,%0)\n\t"
|
||||
"fic,m %2(%%sr0,%0)\n\t"
|
||||
"sync\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n"
|
||||
: "=&r" ((unsigned long)tmp)
|
||||
: "r" ((unsigned long)tramp & ~31),
|
||||
"r" (32/* stride */)
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
#endif
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,183 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
prep_cif.c - Copyright (c) 2011 Anthony Green
|
||||
Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __builtin_expect(x, expected_value) (x)
|
||||
#endif
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
#define UNLIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
/* Round up to FFI_SIZEOF_ARG. */
|
||||
|
||||
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
|
||||
|
||||
/* Perform machine independent initialization of aggregate type
|
||||
specifications. */
|
||||
|
||||
static ffi_status initialize_aggregate(ffi_type *arg)
|
||||
{
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(arg != NULL);
|
||||
|
||||
FFI_ASSERT(arg->elements != NULL);
|
||||
FFI_ASSERT(arg->size == 0);
|
||||
FFI_ASSERT(arg->alignment == 0);
|
||||
|
||||
ptr = &(arg->elements[0]);
|
||||
|
||||
if (UNLIKELY(ptr == 0))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
while ((*ptr) != NULL)
|
||||
{
|
||||
if (UNLIKELY(((*ptr)->size == 0)
|
||||
&& (initialize_aggregate((*ptr)) != FFI_OK)))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
arg->size = ALIGN(arg->size, (*ptr)->alignment);
|
||||
arg->size += (*ptr)->size;
|
||||
|
||||
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
|
||||
arg->alignment : (*ptr)->alignment;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Structure size includes tail padding. This is important for
|
||||
structures that fit in one register on ABIs like the PowerPC64
|
||||
Linux ABI that right justify small structs in a register.
|
||||
It's also needed for nested structure layout, for example
|
||||
struct A { long a; char b; }; struct B { struct A x; char y; };
|
||||
should find y at an offset of 2*sizeof(long) and result in a
|
||||
total size of 3*sizeof(long). */
|
||||
arg->size = ALIGN (arg->size, arg->alignment);
|
||||
|
||||
if (arg->size == 0)
|
||||
return FFI_BAD_TYPEDEF;
|
||||
else
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
#ifndef __CRIS__
|
||||
/* The CRIS ABI specifies structure elements to have byte
|
||||
alignment only, so it completely overrides this functions,
|
||||
which assumes "natural" alignment and padding. */
|
||||
|
||||
/* Perform machine independent ffi_cif preparation, then call
|
||||
machine dependent routine. */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
||||
ffi_type *rtype, ffi_type **atypes)
|
||||
{
|
||||
unsigned bytes = 0;
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(cif != NULL);
|
||||
if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
cif->abi = abi;
|
||||
cif->arg_types = atypes;
|
||||
cif->nargs = nargs;
|
||||
cif->rtype = rtype;
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
/* Initialize the return type if necessary */
|
||||
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the return type */
|
||||
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
||||
|
||||
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
|
||||
/* Make space for the return structure pointer */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
#ifdef SPARC
|
||||
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
|
||||
#endif
|
||||
)
|
||||
bytes = STACK_ARG_SIZE(sizeof(void*));
|
||||
#endif
|
||||
|
||||
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
|
||||
{
|
||||
|
||||
/* Initialize any uninitialized aggregate type definitions */
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type, do this
|
||||
check after the initialization. */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
#if !defined X86_ANY && !defined S390 && !defined PA
|
||||
#ifdef SPARC
|
||||
if (((*ptr)->type == FFI_TYPE_STRUCT
|
||||
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
||||
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
|
||||
&& cif->abi != FFI_V9))
|
||||
bytes += sizeof(void*);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Add any padding if necessary */
|
||||
if (((*ptr)->alignment - 1) & bytes)
|
||||
bytes = ALIGN(bytes, (*ptr)->alignment);
|
||||
|
||||
bytes += STACK_ARG_SIZE((*ptr)->size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cif->bytes = bytes;
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
return ffi_prep_cif_machdep(cif);
|
||||
}
|
||||
#endif /* not __CRIS__ */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
{
|
||||
return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,640 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi64.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
|
||||
Copyright (c) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
x86-64 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __builtin_expect(x, expected_value) (x)
|
||||
#endif
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
#define UNLIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define MAX_GPR_REGS 6
|
||||
#define MAX_SSE_REGS 8
|
||||
|
||||
struct register_args
|
||||
{
|
||||
/* Registers for argument passing. */
|
||||
UINT64 gpr[MAX_GPR_REGS];
|
||||
__int128_t sse[MAX_SSE_REGS];
|
||||
};
|
||||
|
||||
extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
|
||||
void *raddr, void (*fnaddr)(void), unsigned ssecount);
|
||||
|
||||
/* All reference to register classes here is identical to the code in
|
||||
gcc/config/i386/i386.c. Do *not* change one without the other. */
|
||||
|
||||
/* Register class used for passing given 64bit part of the argument.
|
||||
These represent classes as documented by the PS ABI, with the
|
||||
exception of SSESF, SSEDF classes, that are basically SSE class,
|
||||
just gcc will use SF or DFmode move instead of DImode to avoid
|
||||
reformatting penalties.
|
||||
|
||||
Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
|
||||
whenever possible (upper half does contain padding). */
|
||||
enum x86_64_reg_class
|
||||
{
|
||||
X86_64_NO_CLASS,
|
||||
X86_64_INTEGER_CLASS,
|
||||
X86_64_INTEGERSI_CLASS,
|
||||
X86_64_SSE_CLASS,
|
||||
X86_64_SSESF_CLASS,
|
||||
X86_64_SSEDF_CLASS,
|
||||
X86_64_SSEUP_CLASS,
|
||||
X86_64_X87_CLASS,
|
||||
X86_64_X87UP_CLASS,
|
||||
X86_64_COMPLEX_X87_CLASS,
|
||||
X86_64_MEMORY_CLASS
|
||||
};
|
||||
|
||||
#define MAX_CLASSES 4
|
||||
|
||||
#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
|
||||
|
||||
/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
|
||||
of this code is to classify each 8bytes of incoming argument by the register
|
||||
class and assign registers accordingly. */
|
||||
|
||||
/* Return the union class of CLASS1 and CLASS2.
|
||||
See the x86-64 PS ABI for details. */
|
||||
|
||||
static enum x86_64_reg_class
|
||||
merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
|
||||
{
|
||||
/* Rule #1: If both classes are equal, this is the resulting class. */
|
||||
if (class1 == class2)
|
||||
return class1;
|
||||
|
||||
/* Rule #2: If one of the classes is NO_CLASS, the resulting class is
|
||||
the other class. */
|
||||
if (class1 == X86_64_NO_CLASS)
|
||||
return class2;
|
||||
if (class2 == X86_64_NO_CLASS)
|
||||
return class1;
|
||||
|
||||
/* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
|
||||
if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
|
||||
return X86_64_MEMORY_CLASS;
|
||||
|
||||
/* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
|
||||
if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
|
||||
|| (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
|
||||
return X86_64_INTEGERSI_CLASS;
|
||||
if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
|
||||
|| class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
|
||||
return X86_64_INTEGER_CLASS;
|
||||
|
||||
/* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
|
||||
MEMORY is used. */
|
||||
if (class1 == X86_64_X87_CLASS
|
||||
|| class1 == X86_64_X87UP_CLASS
|
||||
|| class1 == X86_64_COMPLEX_X87_CLASS
|
||||
|| class2 == X86_64_X87_CLASS
|
||||
|| class2 == X86_64_X87UP_CLASS
|
||||
|| class2 == X86_64_COMPLEX_X87_CLASS)
|
||||
return X86_64_MEMORY_CLASS;
|
||||
|
||||
/* Rule #6: Otherwise class SSE is used. */
|
||||
return X86_64_SSE_CLASS;
|
||||
}
|
||||
|
||||
/* Classify the argument of type TYPE and mode MODE.
|
||||
CLASSES will be filled by the register class used to pass each word
|
||||
of the operand. The number of words is returned. In case the parameter
|
||||
should be passed in memory, 0 is returned. As a special case for zero
|
||||
sized containers, classes[0] will be NO_CLASS and 1 is returned.
|
||||
|
||||
See the x86-64 PS ABI for details.
|
||||
*/
|
||||
static int
|
||||
classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
size_t byte_offset)
|
||||
{
|
||||
switch (type->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
{
|
||||
int size = byte_offset + type->size;
|
||||
|
||||
if (size <= 4)
|
||||
{
|
||||
classes[0] = X86_64_INTEGERSI_CLASS;
|
||||
return 1;
|
||||
}
|
||||
else if (size <= 8)
|
||||
{
|
||||
classes[0] = X86_64_INTEGER_CLASS;
|
||||
return 1;
|
||||
}
|
||||
else if (size <= 12)
|
||||
{
|
||||
classes[0] = X86_64_INTEGER_CLASS;
|
||||
classes[1] = X86_64_INTEGERSI_CLASS;
|
||||
return 2;
|
||||
}
|
||||
else if (size <= 16)
|
||||
{
|
||||
classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
FFI_ASSERT (0);
|
||||
}
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (!(byte_offset % 8))
|
||||
classes[0] = X86_64_SSESF_CLASS;
|
||||
else
|
||||
classes[0] = X86_64_SSE_CLASS;
|
||||
return 1;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
classes[0] = X86_64_SSEDF_CLASS;
|
||||
return 1;
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
classes[0] = X86_64_X87_CLASS;
|
||||
classes[1] = X86_64_X87UP_CLASS;
|
||||
return 2;
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
const int UNITS_PER_WORD = 8;
|
||||
int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
ffi_type **ptr;
|
||||
int i;
|
||||
enum x86_64_reg_class subclasses[MAX_CLASSES];
|
||||
|
||||
/* If the struct is larger than 32 bytes, pass it on the stack. */
|
||||
if (type->size > 32)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < words; i++)
|
||||
classes[i] = X86_64_NO_CLASS;
|
||||
|
||||
/* Zero sized arrays or structures are NO_CLASS. We return 0 to
|
||||
signalize memory class, so handle it as special case. */
|
||||
if (!words)
|
||||
{
|
||||
classes[0] = X86_64_NO_CLASS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Merge the fields of structure. */
|
||||
for (ptr = type->elements; *ptr != NULL; ptr++)
|
||||
{
|
||||
int num;
|
||||
|
||||
byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
|
||||
|
||||
num = classify_argument (*ptr, subclasses, byte_offset % 8);
|
||||
if (num == 0)
|
||||
return 0;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
int pos = byte_offset / 8;
|
||||
classes[i + pos] =
|
||||
merge_classes (subclasses[i], classes[i + pos]);
|
||||
}
|
||||
|
||||
byte_offset += (*ptr)->size;
|
||||
}
|
||||
|
||||
if (words > 2)
|
||||
{
|
||||
/* When size > 16 bytes, if the first one isn't
|
||||
X86_64_SSE_CLASS or any other ones aren't
|
||||
X86_64_SSEUP_CLASS, everything should be passed in
|
||||
memory. */
|
||||
if (classes[0] != X86_64_SSE_CLASS)
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < words; i++)
|
||||
if (classes[i] != X86_64_SSEUP_CLASS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Final merger cleanup. */
|
||||
for (i = 0; i < words; i++)
|
||||
{
|
||||
/* If one class is MEMORY, everything should be passed in
|
||||
memory. */
|
||||
if (classes[i] == X86_64_MEMORY_CLASS)
|
||||
return 0;
|
||||
|
||||
/* The X86_64_SSEUP_CLASS should be always preceded by
|
||||
X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
|
||||
if (classes[i] == X86_64_SSEUP_CLASS
|
||||
&& classes[i - 1] != X86_64_SSE_CLASS
|
||||
&& classes[i - 1] != X86_64_SSEUP_CLASS)
|
||||
{
|
||||
/* The first one should never be X86_64_SSEUP_CLASS. */
|
||||
FFI_ASSERT (i != 0);
|
||||
classes[i] = X86_64_SSE_CLASS;
|
||||
}
|
||||
|
||||
/* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
|
||||
everything should be passed in memory. */
|
||||
if (classes[i] == X86_64_X87UP_CLASS
|
||||
&& (classes[i - 1] != X86_64_X87_CLASS))
|
||||
{
|
||||
/* The first one should never be X86_64_X87UP_CLASS. */
|
||||
FFI_ASSERT (i != 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
return 0; /* Never reached. */
|
||||
}
|
||||
|
||||
/* Examine the argument and return set number of register required in each
|
||||
class. Return zero iff parameter should be passed in memory, otherwise
|
||||
the number of registers. */
|
||||
|
||||
static int
|
||||
examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
|
||||
_Bool in_return, int *pngpr, int *pnsse)
|
||||
{
|
||||
int i, n, ngpr, nsse;
|
||||
|
||||
n = classify_argument (type, classes, 0);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
ngpr = nsse = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
switch (classes[i])
|
||||
{
|
||||
case X86_64_INTEGER_CLASS:
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
ngpr++;
|
||||
break;
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSESF_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
nsse++;
|
||||
break;
|
||||
case X86_64_NO_CLASS:
|
||||
case X86_64_SSEUP_CLASS:
|
||||
break;
|
||||
case X86_64_X87_CLASS:
|
||||
case X86_64_X87UP_CLASS:
|
||||
case X86_64_COMPLEX_X87_CLASS:
|
||||
return in_return != 0;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
*pngpr = ngpr;
|
||||
*pnsse = nsse;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing. */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
size_t bytes;
|
||||
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
flags = cif->rtype->type;
|
||||
if (flags != FFI_TYPE_VOID)
|
||||
{
|
||||
n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
|
||||
if (n == 0)
|
||||
{
|
||||
/* The return value is passed in memory. A pointer to that
|
||||
memory is the first argument. Allocate a register for it. */
|
||||
gprcount++;
|
||||
/* We don't have to do anything in asm for the return. */
|
||||
flags = FFI_TYPE_VOID;
|
||||
}
|
||||
else if (flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
/* Mark which registers the result appears in. */
|
||||
_Bool sse0 = SSE_CLASS_P (classes[0]);
|
||||
_Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
|
||||
if (sse0 && !sse1)
|
||||
flags |= 1 << 8;
|
||||
else if (!sse0 && sse1)
|
||||
flags |= 1 << 9;
|
||||
else if (sse0 && sse1)
|
||||
flags |= 1 << 10;
|
||||
/* Mark the true size of the structure. */
|
||||
flags |= cif->rtype->size << 12;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go over all arguments and determine the way they should be passed.
|
||||
If it's in a register and there is space for it, let that be so. If
|
||||
not, add it's size to the stack byte count. */
|
||||
for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
|
||||
{
|
||||
if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = cif->arg_types[i]->alignment;
|
||||
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
bytes = ALIGN (bytes, align);
|
||||
bytes += cif->arg_types[i]->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
gprcount += ngpr;
|
||||
ssecount += nsse;
|
||||
}
|
||||
}
|
||||
if (ssecount)
|
||||
flags |= 1 << 11;
|
||||
cif->flags = flags;
|
||||
cif->bytes = ALIGN (bytes, 8);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
char *stack, *argp;
|
||||
ffi_type **arg_types;
|
||||
int gprcount, ssecount, ngpr, nsse, i, avn;
|
||||
_Bool ret_in_memory;
|
||||
struct register_args *reg_args;
|
||||
|
||||
/* Can't call 32-bit mode from 64-bit mode. */
|
||||
FFI_ASSERT (cif->abi == FFI_UNIX64);
|
||||
|
||||
/* If the return value is a struct and we don't have a return value
|
||||
address then we need to make one. Note the setting of flags to
|
||||
VOID above in ffi_prep_cif_machdep. */
|
||||
ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& (cif->flags & 0xff) == FFI_TYPE_VOID);
|
||||
if (rvalue == NULL && ret_in_memory)
|
||||
rvalue = alloca (cif->rtype->size);
|
||||
|
||||
/* Allocate the space for the arguments, plus 4 words of temp space. */
|
||||
stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
|
||||
reg_args = (struct register_args *) stack;
|
||||
argp = stack + sizeof (struct register_args);
|
||||
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
/* If the return value is passed in memory, add the pointer as the
|
||||
first integer argument. */
|
||||
if (ret_in_memory)
|
||||
reg_args->gpr[gprcount++] = (long) rvalue;
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
for (i = 0; i < avn; ++i)
|
||||
{
|
||||
size_t size = arg_types[i]->size;
|
||||
int n;
|
||||
|
||||
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
|
||||
if (n == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = arg_types[i]->alignment;
|
||||
|
||||
/* Stack arguments are *always* at least 8 byte aligned. */
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
/* Pass this argument in memory. */
|
||||
argp = (void *) ALIGN (argp, align);
|
||||
memcpy (argp, avalue[i], size);
|
||||
argp += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The argument is passed entirely in registers. */
|
||||
char *a = (char *) avalue[i];
|
||||
int j;
|
||||
|
||||
for (j = 0; j < n; j++, a += 8, size -= 8)
|
||||
{
|
||||
switch (classes[j])
|
||||
{
|
||||
case X86_64_INTEGER_CLASS:
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
reg_args->gpr[gprcount] = 0;
|
||||
memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8);
|
||||
gprcount++;
|
||||
break;
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
reg_args->sse[ssecount++] = *(UINT64 *) a;
|
||||
break;
|
||||
case X86_64_SSESF_CLASS:
|
||||
reg_args->sse[ssecount++] = *(UINT32 *) a;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
|
||||
cif->flags, rvalue, fn, ssecount);
|
||||
}
|
||||
|
||||
|
||||
extern void ffi_closure_unix64(void);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
volatile unsigned short *tramp;
|
||||
|
||||
/* Sanity check on the cif ABI. */
|
||||
{
|
||||
int abi = cif->abi;
|
||||
if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
tramp = (volatile unsigned short *) &closure->tramp[0];
|
||||
|
||||
tramp[0] = 0xbb49; /* mov <code>, %r11 */
|
||||
*(void * volatile *) &tramp[1] = ffi_closure_unix64;
|
||||
tramp[5] = 0xba49; /* mov <data>, %r10 */
|
||||
*(void * volatile *) &tramp[6] = codeloc;
|
||||
|
||||
/* Set the carry bit iff the function uses any sse registers.
|
||||
This is clc or stc, together with the first byte of the jmp. */
|
||||
tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
|
||||
|
||||
tramp[11] = 0xe3ff; /* jmp *%r11 */
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
int
|
||||
ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
|
||||
struct register_args *reg_args, char *argp)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avalue;
|
||||
ffi_type **arg_types;
|
||||
long i, avn;
|
||||
int gprcount, ssecount, ngpr, nsse;
|
||||
int ret;
|
||||
|
||||
cif = closure->cif;
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
ret = cif->rtype->type;
|
||||
if (ret != FFI_TYPE_VOID)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
|
||||
if (n == 0)
|
||||
{
|
||||
/* The return value goes in memory. Arrange for the closure
|
||||
return value to go directly back to the original caller. */
|
||||
rvalue = (void *) reg_args->gpr[gprcount++];
|
||||
/* We don't have to do anything in asm for the return. */
|
||||
ret = FFI_TYPE_VOID;
|
||||
}
|
||||
else if (ret == FFI_TYPE_STRUCT && n == 2)
|
||||
{
|
||||
/* Mark which register the second word of the structure goes in. */
|
||||
_Bool sse0 = SSE_CLASS_P (classes[0]);
|
||||
_Bool sse1 = SSE_CLASS_P (classes[1]);
|
||||
if (!sse0 && sse1)
|
||||
ret |= 1 << 8;
|
||||
else if (sse0 && !sse1)
|
||||
ret |= 1 << 9;
|
||||
}
|
||||
}
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
for (i = 0; i < avn; ++i)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
int n;
|
||||
|
||||
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
|
||||
if (n == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = arg_types[i]->alignment;
|
||||
|
||||
/* Stack arguments are *always* at least 8 byte aligned. */
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
/* Pass this argument in memory. */
|
||||
argp = (void *) ALIGN (argp, align);
|
||||
avalue[i] = argp;
|
||||
argp += arg_types[i]->size;
|
||||
}
|
||||
/* If the argument is in a single register, or two consecutive
|
||||
integer registers, then we can use that address directly. */
|
||||
else if (n == 1
|
||||
|| (n == 2 && !(SSE_CLASS_P (classes[0])
|
||||
|| SSE_CLASS_P (classes[1]))))
|
||||
{
|
||||
/* The argument is in a single register. */
|
||||
if (SSE_CLASS_P (classes[0]))
|
||||
{
|
||||
avalue[i] = ®_args->sse[ssecount];
|
||||
ssecount += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
avalue[i] = ®_args->gpr[gprcount];
|
||||
gprcount += n;
|
||||
}
|
||||
}
|
||||
/* Otherwise, allocate space to make them consecutive. */
|
||||
else
|
||||
{
|
||||
char *a = alloca (16);
|
||||
int j;
|
||||
|
||||
avalue[i] = a;
|
||||
for (j = 0; j < n; j++, a += 8)
|
||||
{
|
||||
if (SSE_CLASS_P (classes[j]))
|
||||
memcpy (a, ®_args->sse[ssecount++], 8);
|
||||
else
|
||||
memcpy (a, ®_args->gpr[gprcount++], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
closure->fun (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Tell assembly how to perform return type promotions. */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,575 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010,
|
||||
Free Software Foundation, Inc.
|
||||
based on ppc_closure.S
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define L(x) x
|
||||
|
||||
#if defined(__ppc64__)
|
||||
#define MODE_CHOICE(x, y) y
|
||||
#else
|
||||
#define MODE_CHOICE(x, y) x
|
||||
#endif
|
||||
|
||||
#define machine_choice MODE_CHOICE(ppc7400,ppc64)
|
||||
|
||||
; Define some pseudo-opcodes for size-independent load & store of GPRs ...
|
||||
#define lgu MODE_CHOICE(lwzu, ldu)
|
||||
#define lg MODE_CHOICE(lwz,ld)
|
||||
#define sg MODE_CHOICE(stw,std)
|
||||
#define sgu MODE_CHOICE(stwu,stdu)
|
||||
|
||||
; ... and the size of GPRs and their storage indicator.
|
||||
#define GPR_BYTES MODE_CHOICE(4,8)
|
||||
#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
|
||||
#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
|
||||
|
||||
; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
|
||||
#define LINKAGE_SIZE MODE_CHOICE(24,48)
|
||||
#define PARAM_AREA MODE_CHOICE(32,64)
|
||||
|
||||
#define SAVED_CR_OFFSET MODE_CHOICE(4,8) /* save position for CR */
|
||||
#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */
|
||||
|
||||
/* WARNING: if ffi_type is changed... here be monsters.
|
||||
Offsets of items within the result type. */
|
||||
#define FFI_TYPE_TYPE MODE_CHOICE(6,10)
|
||||
#define FFI_TYPE_ELEM MODE_CHOICE(8,16)
|
||||
|
||||
#define SAVED_FPR_COUNT 13
|
||||
#define FPR_SIZE 8
|
||||
/* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */
|
||||
#define RESULT_BYTES MODE_CHOICE(16,176)
|
||||
|
||||
; The whole stack frame **MUST** be 16byte-aligned.
|
||||
#define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL)
|
||||
#define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES))
|
||||
|
||||
#define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE)
|
||||
#define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA)
|
||||
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
||||
; We no longer need the pic symbol stub for Darwin >= 9.
|
||||
#define BLCLS_HELP _ffi_closure_helper_DARWIN
|
||||
#define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p
|
||||
#define PASS_STR_FLOATS _darwin64_pass_struct_floats
|
||||
#undef WANT_STUB
|
||||
#else
|
||||
#define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub
|
||||
#define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub
|
||||
#define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub
|
||||
#define WANT_STUB
|
||||
#endif
|
||||
|
||||
/* m32/m64
|
||||
|
||||
The stack layout looks like this:
|
||||
|
||||
| Additional params... | | Higher address
|
||||
~ ~ ~
|
||||
| Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS
|
||||
|--------------------------------------------| |
|
||||
| TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
|
||||
|--------------------------------------------| |
|
||||
| Reserved 2*4/8 | |
|
||||
|--------------------------------------------| |
|
||||
| Space for callee`s LR 4/8 | |
|
||||
|--------------------------------------------| |
|
||||
| Saved CR [low word for m64] 4/8 | |
|
||||
|--------------------------------------------| |
|
||||
| Current backchain pointer 4/8 |-/ Parent`s frame.
|
||||
|--------------------------------------------| <+ <<< on entry to
|
||||
| Result Bytes 16/176 | |
|
||||
|--------------------------------------------| |
|
||||
~ padding to 16-byte alignment ~ ~
|
||||
|--------------------------------------------| |
|
||||
| NUM_FPR_ARG_REGISTERS slots | |
|
||||
| here fp13 .. fp1 13*8 | |
|
||||
|--------------------------------------------| |
|
||||
| R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS
|
||||
|--------------------------------------------| |
|
||||
| TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
|
||||
|--------------------------------------------| | stack |
|
||||
| Reserved [compiler,binder] 2*4/8 | | grows |
|
||||
|--------------------------------------------| | down V
|
||||
| Space for callees LR 4/8 | |
|
||||
|--------------------------------------------| | lower addresses
|
||||
| Saved CR [low word for m64] 4/8 | |
|
||||
|--------------------------------------------| | stack pointer here
|
||||
| Current backchain pointer 4/8 |-/ during
|
||||
|--------------------------------------------| <<< call.
|
||||
|
||||
*/
|
||||
|
||||
.file "darwin_closure.S"
|
||||
|
||||
.machine machine_choice
|
||||
|
||||
.text
|
||||
.globl _ffi_closure_ASM
|
||||
.align LOG2_GPR_BYTES
|
||||
_ffi_closure_ASM:
|
||||
LFB1:
|
||||
Lstartcode:
|
||||
mflr r0 /* extract return address */
|
||||
sg r0,SAVED_LR_OFFSET(r1) /* save the return address */
|
||||
LCFI0:
|
||||
sgu r1,-SAVE_SIZE(r1) /* skip over caller save area
|
||||
keep stack aligned to 16. */
|
||||
LCFI1:
|
||||
/* We want to build up an area for the parameters passed
|
||||
in registers. (both floating point and integer) */
|
||||
|
||||
/* Put gpr 3 to gpr 10 in the parents outgoing area...
|
||||
... the remainder of any params that overflowed the regs will
|
||||
follow here. */
|
||||
sg r3, (PARENT_PARM_BASE )(r1)
|
||||
sg r4, (PARENT_PARM_BASE + GPR_BYTES )(r1)
|
||||
sg r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1)
|
||||
sg r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1)
|
||||
sg r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1)
|
||||
sg r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1)
|
||||
sg r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1)
|
||||
sg r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1)
|
||||
|
||||
/* We save fpr 1 to fpr 14 in our own save frame. */
|
||||
stfd f1, (FP_SAVE_BASE )(r1)
|
||||
stfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
|
||||
stfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
|
||||
stfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
|
||||
stfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
|
||||
stfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
|
||||
stfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
|
||||
stfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
|
||||
stfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
|
||||
stfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
|
||||
stfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
|
||||
stfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
|
||||
stfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
|
||||
|
||||
/* Set up registers for the routine that actually does the work
|
||||
get the context pointer from the trampoline. */
|
||||
mr r3,r11
|
||||
|
||||
/* Now load up the pointer to the result storage. */
|
||||
addi r4,r1,(SAVE_SIZE-RESULT_BYTES)
|
||||
|
||||
/* Now load up the pointer to the saved gpr registers. */
|
||||
addi r5,r1,PARENT_PARM_BASE
|
||||
|
||||
/* Now load up the pointer to the saved fpr registers. */
|
||||
addi r6,r1,FP_SAVE_BASE
|
||||
|
||||
/* Make the call. */
|
||||
bl BLCLS_HELP
|
||||
|
||||
/* r3 contains the rtype pointer... save it since we will need
|
||||
it later. */
|
||||
sg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type
|
||||
lg r0,0(r3) ; size => r0
|
||||
lhz r3,FFI_TYPE_TYPE(r3) ; type => r3
|
||||
|
||||
/* The helper will have intercepted struture returns and inserted
|
||||
the caller`s destination address for structs returned by ref. */
|
||||
|
||||
/* r3 contains the return type so use it to look up in a table
|
||||
so we know how to deal with each type. */
|
||||
|
||||
addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here. */
|
||||
bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */
|
||||
mflr r4 /* Move to r4. */
|
||||
slwi r3,r3,4 /* Now multiply return type by 16. */
|
||||
add r3,r3,r4 /* Add contents of table to table address. */
|
||||
mtctr r3
|
||||
bctr /* Jump to it. */
|
||||
LFE1:
|
||||
/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
|
||||
(4 instructions). For cache effectiveness we align to a 16 byte boundary
|
||||
first. */
|
||||
|
||||
.align 4
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
Lget_ret_type0_addr:
|
||||
blrl
|
||||
|
||||
/* case FFI_TYPE_VOID */
|
||||
Lret_type0:
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_INT */
|
||||
Lret_type1:
|
||||
lg r3,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_FLOAT */
|
||||
Lret_type2:
|
||||
lfs f1,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_DOUBLE */
|
||||
Lret_type3:
|
||||
lfd f1,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_LONGDOUBLE */
|
||||
Lret_type4:
|
||||
lfd f1,0(r5)
|
||||
lfd f2,8(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_UINT8 */
|
||||
Lret_type5:
|
||||
#if defined(__ppc64__)
|
||||
lbz r3,7(r5)
|
||||
#else
|
||||
lbz r3,3(r5)
|
||||
#endif
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_SINT8 */
|
||||
Lret_type6:
|
||||
#if defined(__ppc64__)
|
||||
lbz r3,7(r5)
|
||||
#else
|
||||
lbz r3,3(r5)
|
||||
#endif
|
||||
extsb r3,r3
|
||||
b Lfinish
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_UINT16 */
|
||||
Lret_type7:
|
||||
#if defined(__ppc64__)
|
||||
lhz r3,6(r5)
|
||||
#else
|
||||
lhz r3,2(r5)
|
||||
#endif
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_SINT16 */
|
||||
Lret_type8:
|
||||
#if defined(__ppc64__)
|
||||
lha r3,6(r5)
|
||||
#else
|
||||
lha r3,2(r5)
|
||||
#endif
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_UINT32 */
|
||||
Lret_type9:
|
||||
#if defined(__ppc64__)
|
||||
lwz r3,4(r5)
|
||||
#else
|
||||
lwz r3,0(r5)
|
||||
#endif
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_SINT32 */
|
||||
Lret_type10:
|
||||
#if defined(__ppc64__)
|
||||
lwz r3,4(r5)
|
||||
#else
|
||||
lwz r3,0(r5)
|
||||
#endif
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_UINT64 */
|
||||
Lret_type11:
|
||||
#if defined(__ppc64__)
|
||||
lg r3,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
#else
|
||||
lwz r3,0(r5)
|
||||
lwz r4,4(r5)
|
||||
b Lfinish
|
||||
#endif
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_SINT64 */
|
||||
Lret_type12:
|
||||
#if defined(__ppc64__)
|
||||
lg r3,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
#else
|
||||
lwz r3,0(r5)
|
||||
lwz r4,4(r5)
|
||||
b Lfinish
|
||||
#endif
|
||||
nop
|
||||
|
||||
/* case FFI_TYPE_STRUCT */
|
||||
Lret_type13:
|
||||
#if defined(__ppc64__)
|
||||
lg r3,0(r5) ; we need at least this...
|
||||
cmpi 0,r0,4
|
||||
bgt Lstructend ; not a special small case
|
||||
b Lsmallstruct ; see if we need more.
|
||||
#else
|
||||
cmpi 0,r0,4
|
||||
bgt Lfinish ; not by value
|
||||
lg r3,0(r5)
|
||||
b Lfinish
|
||||
#endif
|
||||
/* case FFI_TYPE_POINTER */
|
||||
Lret_type14:
|
||||
lg r3,0(r5)
|
||||
b Lfinish
|
||||
nop
|
||||
nop
|
||||
|
||||
#if defined(__ppc64__)
|
||||
Lsmallstruct:
|
||||
beq Lfour ; continuation of Lret13.
|
||||
cmpi 0,r0,3
|
||||
beq Lfinish ; don`t adjust this - can`t be any floats here...
|
||||
srdi r3,r3,48
|
||||
cmpi 0,r0,2
|
||||
beq Lfinish ; .. or here ..
|
||||
srdi r3,r3,8
|
||||
b Lfinish ; .. or here.
|
||||
|
||||
Lfour:
|
||||
lg r6,LINKAGE_SIZE(r1) ; get the result type
|
||||
lg r6,FFI_TYPE_ELEM(r6) ; elements array pointer
|
||||
lg r6,0(r6) ; first element
|
||||
lhz r0,FFI_TYPE_TYPE(r6) ; OK go the type
|
||||
cmpi 0,r0,2 ; FFI_TYPE_FLOAT
|
||||
bne Lfourint
|
||||
lfs f1,0(r5) ; just one float in the struct.
|
||||
b Lfinish
|
||||
|
||||
Lfourint:
|
||||
srdi r3,r3,32 ; four bytes.
|
||||
b Lfinish
|
||||
|
||||
Lstructend:
|
||||
lg r3,LINKAGE_SIZE(r1) ; get the result type
|
||||
bl STRUCT_RETVALUE_P
|
||||
cmpi 0,r3,0
|
||||
beq Lfinish ; nope.
|
||||
/* Recover a pointer to the results. */
|
||||
addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
|
||||
lg r3,0(r11) ; we need at least this...
|
||||
lg r4,8(r11)
|
||||
cmpi 0,r0,16
|
||||
beq Lfinish ; special case 16 bytes we don't consider floats.
|
||||
|
||||
/* OK, frustratingly, the process of saving the struct to mem might have
|
||||
messed with the FPRs, so we have to re-load them :(.
|
||||
We`ll use our FPRs space again - calling:
|
||||
void darwin64_pass_struct_floats (ffi_type *s, char *src,
|
||||
unsigned *nfpr, double **fprs)
|
||||
We`ll temporarily pinch the first two slots of the param area for local
|
||||
vars used by the routine. */
|
||||
xor r6,r6,r6
|
||||
addi r5,r1,PARENT_PARM_BASE ; some space
|
||||
sg r6,0(r5) ; *nfpr zeroed.
|
||||
addi r6,r5,8 ; **fprs
|
||||
addi r3,r1,FP_SAVE_BASE ; pointer to FPRs space
|
||||
sg r3,0(r6)
|
||||
mr r4,r11 ; the struct is here...
|
||||
lg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type.
|
||||
bl PASS_STR_FLOATS ; get struct floats into FPR save space.
|
||||
/* See if we used any floats */
|
||||
lwz r0,(SAVE_SIZE-RESULT_BYTES)(r1)
|
||||
cmpi 0,r0,0
|
||||
beq Lstructints ; nope.
|
||||
/* OK load `em up... */
|
||||
lfd f1, (FP_SAVE_BASE )(r1)
|
||||
lfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
|
||||
lfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
|
||||
lfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
|
||||
lfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
|
||||
lfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
|
||||
lfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
|
||||
lfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
|
||||
lfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
|
||||
lfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
|
||||
lfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
|
||||
lfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
|
||||
lfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
|
||||
|
||||
/* point back at our saved struct. */
|
||||
Lstructints:
|
||||
addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
|
||||
lg r3,0(r11) ; we end up picking the
|
||||
lg r4,8(r11) ; first two again.
|
||||
lg r5,16(r11)
|
||||
lg r6,24(r11)
|
||||
lg r7,32(r11)
|
||||
lg r8,40(r11)
|
||||
lg r9,48(r11)
|
||||
lg r10,56(r11)
|
||||
#endif
|
||||
|
||||
/* case done */
|
||||
Lfinish:
|
||||
addi r1,r1,SAVE_SIZE /* Restore stack pointer. */
|
||||
lg r0,SAVED_LR_OFFSET(r1) /* Get return address. */
|
||||
mtlr r0 /* Reset link register. */
|
||||
blr
|
||||
Lendcode:
|
||||
.align 1
|
||||
|
||||
/* END(ffi_closure_ASM) */
|
||||
|
||||
/* EH frame stuff. */
|
||||
#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
|
||||
/* 176, 400 */
|
||||
#define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90)
|
||||
#define EH_FRAME_OFFSETB MODE_CHOICE(1,3)
|
||||
|
||||
.static_data
|
||||
.align LOG2_GPR_BYTES
|
||||
LLFB1$non_lazy_ptr:
|
||||
.g_long Lstartcode
|
||||
|
||||
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
|
||||
EH_frame1:
|
||||
.set L$set$0,LECIE1-LSCIE1
|
||||
.long L$set$0 ; Length of Common Information Entry
|
||||
LSCIE1:
|
||||
.long 0x0 ; CIE Identifier Tag
|
||||
.byte 0x1 ; CIE Version
|
||||
.ascii "zR\0" ; CIE Augmentation
|
||||
.byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
|
||||
.byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
|
||||
.byte 0x41 ; CIE RA Column
|
||||
.byte 0x1 ; uleb128 0x1; Augmentation size
|
||||
.byte 0x90 ; FDE Encoding (indirect pcrel)
|
||||
.byte 0xc ; DW_CFA_def_cfa
|
||||
.byte 0x1 ; uleb128 0x1
|
||||
.byte 0x0 ; uleb128 0x0
|
||||
.align LOG2_GPR_BYTES
|
||||
LECIE1:
|
||||
.globl _ffi_closure_ASM.eh
|
||||
_ffi_closure_ASM.eh:
|
||||
LSFDE1:
|
||||
.set L$set$1,LEFDE1-LASFDE1
|
||||
.long L$set$1 ; FDE Length
|
||||
|
||||
LASFDE1:
|
||||
.long LASFDE1-EH_frame1 ; FDE CIE offset
|
||||
.g_long LLFB1$non_lazy_ptr-. ; FDE initial location
|
||||
.set L$set$3,LFE1-Lstartcode
|
||||
.g_long L$set$3 ; FDE address range
|
||||
.byte 0x0 ; uleb128 0x0; Augmentation size
|
||||
.byte 0x4 ; DW_CFA_advance_loc4
|
||||
.set L$set$3,LCFI1-LCFI0
|
||||
.long L$set$3
|
||||
.byte 0xe ; DW_CFA_def_cfa_offset
|
||||
.byte EH_FRAME_OFFSETA,EH_FRAME_OFFSETB ; uleb128 176,1/190,3
|
||||
.byte 0x4 ; DW_CFA_advance_loc4
|
||||
.set L$set$4,LCFI0-Lstartcode
|
||||
.long L$set$4
|
||||
.byte 0x11 ; DW_CFA_offset_extended_sf
|
||||
.byte 0x41 ; uleb128 0x41
|
||||
.byte 0x7e ; sleb128 -2
|
||||
.align LOG2_GPR_BYTES
|
||||
LEFDE1:
|
||||
.align 1
|
||||
|
||||
#ifdef WANT_STUB
|
||||
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
||||
.align 5
|
||||
L_ffi_closure_helper_DARWIN$stub:
|
||||
.indirect_symbol _ffi_closure_helper_DARWIN
|
||||
mflr r0
|
||||
bcl 20,31,"L00000000001$spb"
|
||||
"L00000000001$spb":
|
||||
mflr r11
|
||||
addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")
|
||||
mtlr r0
|
||||
lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11)
|
||||
mtctr r12
|
||||
bctr
|
||||
.lazy_symbol_pointer
|
||||
L_ffi_closure_helper_DARWIN$lazy_ptr:
|
||||
.indirect_symbol _ffi_closure_helper_DARWIN
|
||||
.long dyld_stub_binding_helper
|
||||
|
||||
#if defined(__ppc64__)
|
||||
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
||||
.align 5
|
||||
L_darwin64_struct_ret_by_value_p$stub:
|
||||
.indirect_symbol _darwin64_struct_ret_by_value_p
|
||||
mflr r0
|
||||
bcl 20,31,"L00000000002$spb"
|
||||
"L00000000002$spb":
|
||||
mflr r11
|
||||
addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")
|
||||
mtlr r0
|
||||
lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11)
|
||||
mtctr r12
|
||||
bctr
|
||||
.lazy_symbol_pointer
|
||||
L_darwin64_struct_ret_by_value_p$lazy_ptr:
|
||||
.indirect_symbol _darwin64_struct_ret_by_value_p
|
||||
.long dyld_stub_binding_helper
|
||||
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
||||
.align 5
|
||||
L_darwin64_pass_struct_floats$stub:
|
||||
.indirect_symbol _darwin64_pass_struct_floats
|
||||
mflr r0
|
||||
bcl 20,31,"L00000000003$spb"
|
||||
"L00000000003$spb":
|
||||
mflr r11
|
||||
addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")
|
||||
mtlr r0
|
||||
lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11)
|
||||
mtctr r12
|
||||
bctr
|
||||
.lazy_symbol_pointer
|
||||
L_darwin64_pass_struct_floats$lazy_ptr:
|
||||
.indirect_symbol _darwin64_pass_struct_floats
|
||||
.long dyld_stub_binding_helper
|
||||
# endif
|
||||
#endif
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,189 +0,0 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
SUBDIRS = include testsuite man
|
||||
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
|
||||
src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
|
||||
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
|
||||
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
|
||||
src/ia64/unix.S \
|
||||
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
|
||||
src/mips/ffitarget.h \
|
||||
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
|
||||
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
|
||||
src/powerpc/ffi.c src/powerpc/sysv.S \
|
||||
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
|
||||
src/powerpc/ppc_closure.S src/powerpc/asm.h \
|
||||
src/powerpc/aix.S src/powerpc/darwin.S \
|
||||
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
|
||||
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
|
||||
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
|
||||
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
|
||||
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
|
||||
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
|
||||
src/sparc/ffi.c src/x86/darwin64.S \
|
||||
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/win64.S \
|
||||
src/x86/darwin.S src/x86/freebsd.S \
|
||||
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
|
||||
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
|
||||
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h \
|
||||
src/dlmalloc.c \
|
||||
src/moxie/ffi.c src/moxie/eabi.S \
|
||||
libtool-version ChangeLog.libffi m4/libtool.m4 \
|
||||
m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4
|
||||
|
||||
info_TEXINFOS = doc/libffi.texi
|
||||
|
||||
## ################################################################
|
||||
|
||||
##
|
||||
## This section is for make and multilib madness.
|
||||
##
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
# values defined in terms of make variables, as is the case for CC and
|
||||
# friends when we are called from the top level Makefile.
|
||||
AM_MAKEFLAGS = \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
|
||||
"CFLAGS=$(CFLAGS)" \
|
||||
"CXXFLAGS=$(CXXFLAGS)" \
|
||||
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
|
||||
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
|
||||
"INSTALL=$(INSTALL)" \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
|
||||
"JC1FLAGS=$(JC1FLAGS)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
|
||||
"MAKE=$(MAKE)" \
|
||||
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
|
||||
"SHELL=$(SHELL)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"infodir=$(infodir)" \
|
||||
"libdir=$(libdir)" \
|
||||
"mandir=$(mandir)" \
|
||||
"prefix=$(prefix)" \
|
||||
"AR=$(AR)" \
|
||||
"AS=$(AS)" \
|
||||
"CC=$(CC)" \
|
||||
"CXX=$(CXX)" \
|
||||
"LD=$(LD)" \
|
||||
"NM=$(NM)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
"DESTDIR=$(DESTDIR)"
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
|
||||
|
||||
lib_LTLIBRARIES = libffi.la
|
||||
noinst_LTLIBRARIES = libffi_convenience.la
|
||||
|
||||
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
||||
src/raw_api.c src/java_raw_api.c src/closures.c
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libffi.pc
|
||||
|
||||
nodist_libffi_la_SOURCES =
|
||||
|
||||
if MIPS
|
||||
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
|
||||
endif
|
||||
if X86
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
|
||||
endif
|
||||
if X86_FREEBSD
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
|
||||
endif
|
||||
if X86_WIN32
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
|
||||
endif
|
||||
if X86_WIN64
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
|
||||
endif
|
||||
if X86_DARWIN
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
|
||||
endif
|
||||
if SPARC
|
||||
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
|
||||
endif
|
||||
if ALPHA
|
||||
nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
|
||||
endif
|
||||
if IA64
|
||||
nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
|
||||
endif
|
||||
if M32R
|
||||
nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
|
||||
endif
|
||||
if M68K
|
||||
nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
|
||||
endif
|
||||
if POWERPC
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
|
||||
endif
|
||||
if POWERPC_AIX
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
|
||||
endif
|
||||
if POWERPC_DARWIN
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
|
||||
endif
|
||||
if POWERPC_FREEBSD
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
|
||||
endif
|
||||
if ARM
|
||||
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
|
||||
endif
|
||||
if AVR32
|
||||
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
|
||||
endif
|
||||
if LIBFFI_CRIS
|
||||
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
|
||||
endif
|
||||
if FRV
|
||||
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
|
||||
endif
|
||||
if S390
|
||||
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
|
||||
endif
|
||||
if X86_64
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
endif
|
||||
if SH
|
||||
nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
|
||||
endif
|
||||
if SH64
|
||||
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
|
||||
endif
|
||||
if PA_LINUX
|
||||
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
|
||||
endif
|
||||
if PA_HPUX
|
||||
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
|
||||
endif
|
||||
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
|
||||
AM_CFLAGS = -Wall -g -fexceptions
|
||||
|
||||
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
|
||||
|
||||
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
# No install-html or install-pdf support in automake yet
|
||||
.PHONY: install-html install-pdf
|
||||
install-html:
|
||||
install-pdf:
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
-15940
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,464 +0,0 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
AC_PROG_CC
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(mmap)
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
case "$host" in
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd* | amd64-*-openbsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
i?86-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-solaris2.1[[0-9]]*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-*)
|
||||
TARGET=X86; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
;;
|
||||
|
||||
sh-*-* | sh[[34]]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
;;
|
||||
|
||||
x86_64-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-cygwin* | x86_64-*-mingw*)
|
||||
TARGET=X86_WIN64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
|
||||
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
|
||||
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
|
||||
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
|
||||
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
|
||||
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
|
||||
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
|
||||
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
|
||||
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||||
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||||
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||||
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||||
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
|
||||
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
libffi_cv_as_cfi_pseudo_op, [
|
||||
libffi_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
[libffi_cv_as_cfi_pseudo_op=yes],
|
||||
[libffi_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
|
||||
if test x$TARGET = xSPARC; then
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | $EGREP -i 'illegal|warning' > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
|
||||
libffi_cv_as_ascii_pseudo_op, [
|
||||
libffi_cv_as_ascii_pseudo_op=unknown
|
||||
# Check if we have .ascii
|
||||
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
|
||||
[libffi_cv_as_ascii_pseudo_op=yes],
|
||||
[libffi_cv_as_ascii_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .ascii.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .string pseudo-op support],
|
||||
libffi_cv_as_string_pseudo_op, [
|
||||
libffi_cv_as_string_pseudo_op=unknown
|
||||
# Check if we have .string
|
||||
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
|
||||
[libffi_cv_as_string_pseudo_op=yes],
|
||||
[libffi_cv_as_string_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .string.])
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
*-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
echo '.section .eh_frame,"a",@unwind' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
|
||||
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
elif grep '.section.*eh_frame.*#alloc' conftest.c \
|
||||
| grep -v '#write' > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive.])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if grep '\.hidden.*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test x"$GCC" != x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
fi
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,50 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
|
||||
Target configuration macros for AVR32.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag
|
||||
|
||||
/* Definitions for closures */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 36
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
@@ -1,383 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1998 Cygnus Solutions
|
||||
Copyright (c) 2004 Simon Posnjak
|
||||
Copyright (c) 2005 Axis Communications AB
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
CRIS Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
|
||||
|
||||
static ffi_status
|
||||
initialize_aggregate_packed_struct (ffi_type * arg)
|
||||
{
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT (arg != NULL);
|
||||
|
||||
FFI_ASSERT (arg->elements != NULL);
|
||||
FFI_ASSERT (arg->size == 0);
|
||||
FFI_ASSERT (arg->alignment == 0);
|
||||
|
||||
ptr = &(arg->elements[0]);
|
||||
|
||||
while ((*ptr) != NULL)
|
||||
{
|
||||
if (((*ptr)->size == 0)
|
||||
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
FFI_ASSERT (ffi_type_test ((*ptr)));
|
||||
|
||||
arg->size += (*ptr)->size;
|
||||
|
||||
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
|
||||
arg->alignment : (*ptr)->alignment;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (arg->size == 0)
|
||||
return FFI_BAD_TYPEDEF;
|
||||
else
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
int
|
||||
ffi_prep_args (char *stack, extended_cif * ecif)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int struct_count = 0;
|
||||
void **p_argv;
|
||||
char *argp;
|
||||
ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
z = (*p_arg)->size;
|
||||
if (z <= 4)
|
||||
{
|
||||
memcpy (argp, *p_argv, z);
|
||||
z = 4;
|
||||
}
|
||||
else if (z <= 8)
|
||||
{
|
||||
memcpy (argp, *p_argv, z);
|
||||
z = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int uiLocOnStack;
|
||||
z = sizeof (void *);
|
||||
uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
|
||||
struct_count = struct_count + (*p_arg)->size;
|
||||
*(unsigned int *) argp =
|
||||
(unsigned int) (UINT32 *) (stack + uiLocOnStack);
|
||||
memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof (int))
|
||||
{
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp =
|
||||
(unsigned int) *(UINT8 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp =
|
||||
(unsigned int) *(UINT16 *) (*p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT (0);
|
||||
}
|
||||
z = sizeof (int);
|
||||
}
|
||||
else if (z == sizeof (int))
|
||||
*(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
|
||||
else
|
||||
memcpy (argp, *p_argv, z);
|
||||
break;
|
||||
}
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return (struct_count);
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_cif (ffi_cif * cif,
|
||||
ffi_abi abi, unsigned int nargs,
|
||||
ffi_type * rtype, ffi_type ** atypes)
|
||||
{
|
||||
unsigned bytes = 0;
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT (cif != NULL);
|
||||
FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
|
||||
|
||||
cif->abi = abi;
|
||||
cif->arg_types = atypes;
|
||||
cif->nargs = nargs;
|
||||
cif->rtype = rtype;
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
if ((cif->rtype->size == 0)
|
||||
&& (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
FFI_ASSERT_VALID_TYPE (cif->rtype);
|
||||
|
||||
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
|
||||
{
|
||||
if (((*ptr)->size == 0)
|
||||
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
FFI_ASSERT_VALID_TYPE (*ptr);
|
||||
|
||||
if (((*ptr)->alignment - 1) & bytes)
|
||||
bytes = ALIGN (bytes, (*ptr)->alignment);
|
||||
if ((*ptr)->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
if ((*ptr)->size > 8)
|
||||
{
|
||||
bytes += (*ptr)->size;
|
||||
bytes += sizeof (void *);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*ptr)->size > 4)
|
||||
bytes += 8;
|
||||
else
|
||||
bytes += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
bytes += STACK_ARG_SIZE ((*ptr)->size);
|
||||
}
|
||||
|
||||
cif->bytes = bytes;
|
||||
|
||||
return ffi_prep_cif_machdep (cif);
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_cif_machdep (ffi_cif * cif)
|
||||
{
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
|
||||
extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn) ())
|
||||
__attribute__ ((__visibility__ ("hidden")));
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca (cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Because the following variables are not exported outside libffi, we
|
||||
mark them hidden. */
|
||||
|
||||
/* Assembly code for the jump stub. */
|
||||
extern const char ffi_cris_trampoline_template[]
|
||||
__attribute__ ((__visibility__ ("hidden")));
|
||||
|
||||
/* Offset into ffi_cris_trampoline_template of where to put the
|
||||
ffi_prep_closure_inner function. */
|
||||
extern const int ffi_cris_trampoline_fn_offset
|
||||
__attribute__ ((__visibility__ ("hidden")));
|
||||
|
||||
/* Offset into ffi_cris_trampoline_template of where to put the
|
||||
closure data. */
|
||||
extern const int ffi_cris_trampoline_closure_offset
|
||||
__attribute__ ((__visibility__ ("hidden")));
|
||||
|
||||
/* This function is sibling-called (jumped to) by the closure
|
||||
trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
|
||||
PARAMS[4] to simplify handling of a straddling parameter. A copy
|
||||
of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
|
||||
put at the appropriate place in CLOSURE which is then executed and
|
||||
the return value is passed back to the caller. */
|
||||
|
||||
static unsigned long long
|
||||
ffi_prep_closure_inner (void **params, ffi_closure* closure)
|
||||
{
|
||||
char *register_args = (char *) params;
|
||||
void *struct_ret = params[5];
|
||||
char *stack_args = params[6];
|
||||
char *ptr = register_args;
|
||||
ffi_cif *cif = closure->cif;
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
|
||||
/* Max room needed is number of arguments as 64-bit values. */
|
||||
void **avalue = alloca (closure->cif->nargs * sizeof(void *));
|
||||
int i;
|
||||
int doing_regs;
|
||||
long long llret = 0;
|
||||
|
||||
/* Find the address of each argument. */
|
||||
for (i = 0, doing_regs = 1; i < cif->nargs; i++)
|
||||
{
|
||||
/* Types up to and including 8 bytes go by-value. */
|
||||
if (arg_types[i]->size <= 4)
|
||||
{
|
||||
avalue[i] = ptr;
|
||||
ptr += 4;
|
||||
}
|
||||
else if (arg_types[i]->size <= 8)
|
||||
{
|
||||
avalue[i] = ptr;
|
||||
ptr += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
|
||||
|
||||
/* Passed by-reference, so copy the pointer. */
|
||||
avalue[i] = *(void **) ptr;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
/* If we've handled more arguments than fit in registers, start
|
||||
looking at the those passed on the stack. Step over the
|
||||
first one if we had a straddling parameter. */
|
||||
if (doing_regs && ptr >= register_args + 4*4)
|
||||
{
|
||||
ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
|
||||
doing_regs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
(closure->fun) (cif,
|
||||
|
||||
cif->rtype->type == FFI_TYPE_STRUCT
|
||||
/* The caller allocated space for the return
|
||||
structure, and passed a pointer to this space in
|
||||
R9. */
|
||||
? struct_ret
|
||||
|
||||
/* We take advantage of being able to ignore that
|
||||
the high part isn't set if the return value is
|
||||
not in R10:R11, but in R10 only. */
|
||||
: (void *) &llret,
|
||||
|
||||
avalue, closure->user_data);
|
||||
|
||||
return llret;
|
||||
}
|
||||
|
||||
/* API function: Prepare the trampoline. */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif *, void *, void **, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
void *innerfn = ffi_prep_closure_inner;
|
||||
FFI_ASSERT (cif->abi == FFI_SYSV);
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
memcpy (closure->tramp, ffi_cris_trampoline_template,
|
||||
FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
|
||||
memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
|
||||
&innerfn, sizeof (void *));
|
||||
memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
|
||||
&codeloc, sizeof (void *));
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for CRIS.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
|
||||
#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
|
||||
#define FFI_TRAMPOLINE_SIZE \
|
||||
(FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2004 Red Hat, Inc.
|
||||
Target configuration macros for FR-V
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
#ifdef FRV
|
||||
FFI_EABI,
|
||||
FFI_DEFAULT_ABI = FFI_EABI,
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#ifdef __FRV_FDPIC__
|
||||
/* Trampolines are 8 4-byte instructions long. */
|
||||
#define FFI_TRAMPOLINE_SIZE (8*4)
|
||||
#else
|
||||
/* Trampolines are 5 4-byte instructions long. */
|
||||
#define FFI_TRAMPOLINE_SIZE (5*4)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for IA-64.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_UNIX, /* Linux and all Unix variants use the same conventions */
|
||||
FFI_DEFAULT_ABI = FFI_UNIX,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
|
||||
/* can be interpreted as a C function */
|
||||
/* descriptor: */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2004 Renesas Technology.
|
||||
Target configuration macros for M32R.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi
|
||||
{
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_CLOSURES 0
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for Motorola 68K.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for MIPS.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifdef linux
|
||||
# include <asm/sgidefs.h>
|
||||
#elif defined(__rtems__)
|
||||
/*
|
||||
* Subprogram calling convention - copied from sgidefs.h
|
||||
*/
|
||||
#define _MIPS_SIM_ABI32 1
|
||||
#define _MIPS_SIM_NABI32 2
|
||||
#define _MIPS_SIM_ABI64 3
|
||||
#else
|
||||
# include <sgidefs.h>
|
||||
#endif
|
||||
|
||||
# ifndef _ABIN32
|
||||
# define _ABIN32 _MIPS_SIM_NABI32
|
||||
# endif
|
||||
# ifndef _ABI64
|
||||
# define _ABI64 _MIPS_SIM_ABI64
|
||||
# endif
|
||||
# ifndef _ABIO32
|
||||
# define _ABIO32 _MIPS_SIM_ABI32
|
||||
# endif
|
||||
|
||||
#if !defined(_MIPS_SIM)
|
||||
-- something is very wrong --
|
||||
#else
|
||||
# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
|
||||
# define FFI_MIPS_N32
|
||||
# else
|
||||
# if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
|
||||
# define FFI_MIPS_O32
|
||||
# else
|
||||
-- this is an unsupported platform --
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
#else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# if _MIPS_SIM == _ABIN32
|
||||
# define FFI_SIZEOF_JAVA_RAW 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define FFI_FLAG_BITS 2
|
||||
|
||||
/* SGI's strange assembler requires that we multiply by 4 rather
|
||||
than shift left by FFI_FLAG_BITS */
|
||||
|
||||
#define FFI_ARGS_D FFI_TYPE_DOUBLE
|
||||
#define FFI_ARGS_F FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
|
||||
#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
|
||||
|
||||
/* Needed for N32 structure returns */
|
||||
#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8
|
||||
#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
|
||||
|
||||
#if 0
|
||||
/* The SGI assembler can't handle this.. */
|
||||
#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
|
||||
/* (and so on) */
|
||||
#else
|
||||
/* ...so we calculate these by hand! */
|
||||
#define FFI_TYPE_STRUCT_D 61
|
||||
#define FFI_TYPE_STRUCT_F 45
|
||||
#define FFI_TYPE_STRUCT_DD 253
|
||||
#define FFI_TYPE_STRUCT_FF 173
|
||||
#define FFI_TYPE_STRUCT_FD 237
|
||||
#define FFI_TYPE_STRUCT_DF 189
|
||||
#define FFI_TYPE_STRUCT_SMALL 93
|
||||
#define FFI_TYPE_STRUCT_SMALL2 109
|
||||
|
||||
/* and for n32 soft float, add 16 * 2^4 */
|
||||
#define FFI_TYPE_STRUCT_D_SOFT 317
|
||||
#define FFI_TYPE_STRUCT_F_SOFT 301
|
||||
#define FFI_TYPE_STRUCT_DD_SOFT 509
|
||||
#define FFI_TYPE_STRUCT_FF_SOFT 429
|
||||
#define FFI_TYPE_STRUCT_FD_SOFT 493
|
||||
#define FFI_TYPE_STRUCT_DF_SOFT 445
|
||||
#define FFI_TYPE_STRUCT_SOFT 16
|
||||
#endif
|
||||
|
||||
#ifdef LIBFFI_ASM
|
||||
#define v0 $2
|
||||
#define v1 $3
|
||||
#define a0 $4
|
||||
#define a1 $5
|
||||
#define a2 $6
|
||||
#define a3 $7
|
||||
#define a4 $8
|
||||
#define a5 $9
|
||||
#define a6 $10
|
||||
#define a7 $11
|
||||
#define t0 $8
|
||||
#define t1 $9
|
||||
#define t2 $10
|
||||
#define t3 $11
|
||||
#define t4 $12
|
||||
#define t5 $13
|
||||
#define t6 $14
|
||||
#define t7 $15
|
||||
#define t8 $24
|
||||
#define t9 $25
|
||||
#define ra $31
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
# define REG_L lw
|
||||
# define REG_S sw
|
||||
# define SUBU subu
|
||||
# define ADDU addu
|
||||
# define SRL srl
|
||||
# define LI li
|
||||
#else /* !FFI_MIPS_O32 */
|
||||
# define REG_L ld
|
||||
# define REG_S sd
|
||||
# define SUBU dsubu
|
||||
# define ADDU daddu
|
||||
# define SRL dsrl
|
||||
# define LI dli
|
||||
# if (_MIPS_SIM==_ABI64)
|
||||
# define LA dla
|
||||
# define EH_FRAME_ALIGN 3
|
||||
# define FDE_ADDR_BYTES .8byte
|
||||
# else
|
||||
# define LA la
|
||||
# define EH_FRAME_ALIGN 2
|
||||
# define FDE_ADDR_BYTES .4byte
|
||||
# endif /* _MIPS_SIM==_ABI64 */
|
||||
#endif /* !FFI_MIPS_O32 */
|
||||
#else /* !LIBFFI_ASM */
|
||||
# ifdef __GNUC__
|
||||
# ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
typedef unsigned int ffi_arg __attribute__((__mode__(__SI__)));
|
||||
typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
|
||||
#else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
typedef unsigned int ffi_arg __attribute__((__mode__(__DI__)));
|
||||
typedef signed int ffi_sarg __attribute__((__mode__(__DI__)));
|
||||
# endif
|
||||
# else
|
||||
# ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
typedef __uint32_t ffi_arg;
|
||||
typedef __int32_t ffi_sarg;
|
||||
# else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
typedef __uint64_t ffi_arg;
|
||||
typedef __int64_t ffi_sarg;
|
||||
# endif
|
||||
# endif /* __GNUC__ */
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_O32,
|
||||
FFI_N32,
|
||||
FFI_N64,
|
||||
FFI_O32_SOFT_FLOAT,
|
||||
FFI_N32_SOFT_FLOAT,
|
||||
FFI_N64_SOFT_FLOAT,
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
#ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_O32,
|
||||
#endif
|
||||
#else
|
||||
# if _MIPS_SIM==_ABI64
|
||||
# ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT,
|
||||
# else
|
||||
FFI_DEFAULT_ABI = FFI_N64,
|
||||
# endif
|
||||
# else
|
||||
# ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT,
|
||||
# else
|
||||
FFI_DEFAULT_ABI = FFI_N32,
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
|
||||
#endif /* !LIBFFI_ASM */
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if defined(FFI_MIPS_O32)
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 20
|
||||
#else
|
||||
/* N32/N64. */
|
||||
# define FFI_CLOSURES 1
|
||||
#if _MIPS_SIM==_ABI64
|
||||
#define FFI_TRAMPOLINE_SIZE 52
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 20
|
||||
#endif
|
||||
#endif /* FFI_MIPS_O32 */
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2009 Anthony Green
|
||||
Target configuration macros for Moxie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
#ifdef MOXIE
|
||||
FFI_EABI,
|
||||
FFI_DEFAULT_ABI = FFI_EABI,
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 0
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
/* Trampolines are 5 4-byte instructions long. */
|
||||
#define FFI_TRAMPOLINE_SIZE (5*4)
|
||||
|
||||
#endif
|
||||
@@ -1,77 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for hppa.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
#ifdef PA_LINUX
|
||||
FFI_PA32,
|
||||
FFI_DEFAULT_ABI = FFI_PA32,
|
||||
#endif
|
||||
|
||||
#ifdef PA_HPUX
|
||||
FFI_PA32,
|
||||
FFI_DEFAULT_ABI = FFI_PA32,
|
||||
#endif
|
||||
|
||||
#ifdef PA64_HPUX
|
||||
#error "PA64_HPUX FFI is not yet implemented"
|
||||
FFI_PA64,
|
||||
FFI_DEFAULT_ABI = FFI_PA64,
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#ifdef PA_LINUX
|
||||
#define FFI_TRAMPOLINE_SIZE 32
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 40
|
||||
#endif
|
||||
|
||||
#define FFI_TYPE_SMALL_STRUCT2 -1
|
||||
#define FFI_TYPE_SMALL_STRUCT3 -2
|
||||
#define FFI_TYPE_SMALL_STRUCT4 -3
|
||||
#define FFI_TYPE_SMALL_STRUCT5 -4
|
||||
#define FFI_TYPE_SMALL_STRUCT6 -5
|
||||
#define FFI_TYPE_SMALL_STRUCT7 -6
|
||||
#define FFI_TYPE_SMALL_STRUCT8 -7
|
||||
#endif
|
||||
@@ -1,171 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Round up to FFI_SIZEOF_ARG. */
|
||||
|
||||
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
|
||||
|
||||
/* Perform machine independent initialization of aggregate type
|
||||
specifications. */
|
||||
|
||||
static ffi_status initialize_aggregate(ffi_type *arg)
|
||||
{
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(arg != NULL);
|
||||
|
||||
FFI_ASSERT(arg->elements != NULL);
|
||||
FFI_ASSERT(arg->size == 0);
|
||||
FFI_ASSERT(arg->alignment == 0);
|
||||
|
||||
ptr = &(arg->elements[0]);
|
||||
|
||||
while ((*ptr) != NULL)
|
||||
{
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
arg->size = ALIGN(arg->size, (*ptr)->alignment);
|
||||
arg->size += (*ptr)->size;
|
||||
|
||||
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
|
||||
arg->alignment : (*ptr)->alignment;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Structure size includes tail padding. This is important for
|
||||
structures that fit in one register on ABIs like the PowerPC64
|
||||
Linux ABI that right justify small structs in a register.
|
||||
It's also needed for nested structure layout, for example
|
||||
struct A { long a; char b; }; struct B { struct A x; char y; };
|
||||
should find y at an offset of 2*sizeof(long) and result in a
|
||||
total size of 3*sizeof(long). */
|
||||
arg->size = ALIGN (arg->size, arg->alignment);
|
||||
|
||||
if (arg->size == 0)
|
||||
return FFI_BAD_TYPEDEF;
|
||||
else
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
#ifndef __CRIS__
|
||||
/* The CRIS ABI specifies structure elements to have byte
|
||||
alignment only, so it completely overrides this functions,
|
||||
which assumes "natural" alignment and padding. */
|
||||
|
||||
/* Perform machine independent ffi_cif preparation, then call
|
||||
machine dependent routine. */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
||||
ffi_type *rtype, ffi_type **atypes)
|
||||
{
|
||||
unsigned bytes = 0;
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(cif != NULL);
|
||||
FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
|
||||
|
||||
cif->abi = abi;
|
||||
cif->arg_types = atypes;
|
||||
cif->nargs = nargs;
|
||||
cif->rtype = rtype;
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
/* Initialize the return type if necessary */
|
||||
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the return type */
|
||||
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
||||
|
||||
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
|
||||
/* Make space for the return structure pointer */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
#ifdef SPARC
|
||||
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
|
||||
#endif
|
||||
)
|
||||
bytes = STACK_ARG_SIZE(sizeof(void*));
|
||||
#endif
|
||||
|
||||
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
|
||||
{
|
||||
|
||||
/* Initialize any uninitialized aggregate type definitions */
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type, do this
|
||||
check after the initialization. */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
#if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
|
||||
#ifdef SPARC
|
||||
if (((*ptr)->type == FFI_TYPE_STRUCT
|
||||
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
||||
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
|
||||
&& cif->abi != FFI_V9))
|
||||
bytes += sizeof(void*);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Add any padding if necessary */
|
||||
if (((*ptr)->alignment - 1) & bytes)
|
||||
bytes = ALIGN(bytes, (*ptr)->alignment);
|
||||
|
||||
bytes += STACK_ARG_SIZE((*ptr)->size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cif->bytes = bytes;
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
return ffi_prep_cif_machdep(cif);
|
||||
}
|
||||
#endif /* not __CRIS__ */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
{
|
||||
return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for S390.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#if defined (__s390x__)
|
||||
#ifndef S390X
|
||||
#define S390X
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#ifdef S390X
|
||||
#define FFI_TRAMPOLINE_SIZE 32
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#endif
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for SuperH.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for SuperH - SHmedia.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS long long flags2
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 32
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for SPARC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#if defined(__arch64__) || defined(__sparcv9)
|
||||
#ifndef SPARC64
|
||||
#define SPARC64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_V8,
|
||||
FFI_V8PLUS,
|
||||
FFI_V9,
|
||||
#ifdef SPARC64
|
||||
FFI_DEFAULT_ABI = FFI_V9,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_V8,
|
||||
#endif
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#ifdef SPARC64
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003, 2010 Red Hat, Inc.
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Target configuration macros for x86 and x86-64.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#if defined (X86_64) && defined (__i386__)
|
||||
#undef X86_64
|
||||
#define X86
|
||||
#endif
|
||||
|
||||
#ifdef X86_WIN64
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
|
||||
#endif
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
#ifdef X86_WIN64
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 ffi_arg;
|
||||
typedef __int64 ffi_sarg;
|
||||
#else
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef long long ffi_sarg;
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
#endif
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
/* ---- Intel x86 Win32 ---------- */
|
||||
#ifdef X86_WIN32
|
||||
FFI_SYSV,
|
||||
FFI_STDCALL,
|
||||
/* TODO: Add fastcall support for the sake of completeness */
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#endif
|
||||
|
||||
#ifdef X86_WIN64
|
||||
FFI_WIN64,
|
||||
FFI_DEFAULT_ABI = FFI_WIN64,
|
||||
#else
|
||||
|
||||
/* ---- Intel x86 and AMD x86-64 - */
|
||||
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__) || defined(__i386) || defined(__amd64))
|
||||
FFI_SYSV,
|
||||
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
|
||||
#if defined(__i386__) || defined(__i386)
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_UNIX64,
|
||||
#endif
|
||||
#endif
|
||||
#endif /* X86_WIN64 */
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
|
||||
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
|
||||
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
|
||||
|
||||
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
#else
|
||||
#ifdef X86_WIN32
|
||||
#define FFI_TRAMPOLINE_SIZE 13
|
||||
#else
|
||||
#ifdef X86_WIN64
|
||||
#define FFI_TRAMPOLINE_SIZE 29
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
#define FFI_NO_RAW_API 1
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 10
|
||||
#endif
|
||||
#endif
|
||||
#ifndef X86_WIN64
|
||||
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,125 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
asm.h - Copyright (c) 1998 Geoffrey Keating
|
||||
|
||||
PowerPC Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define ASM_GLOBAL_DIRECTIVE .globl
|
||||
|
||||
|
||||
#define C_SYMBOL_NAME(name) name
|
||||
/* Macro for a label. */
|
||||
#ifdef __STDC__
|
||||
#define C_LABEL(name) name##:
|
||||
#else
|
||||
#define C_LABEL(name) name/**/:
|
||||
#endif
|
||||
|
||||
/* This seems to always be the case on PPC. */
|
||||
#define ALIGNARG(log2) log2
|
||||
/* For ELF we need the `.type' directive to make shared libs work right. */
|
||||
#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
|
||||
#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
|
||||
|
||||
/* If compiled for profiling, call `_mcount' at the start of each function. */
|
||||
#ifdef PROF
|
||||
/* The mcount code relies on a the return address being on the stack
|
||||
to locate our caller and so it can restore it; so store one just
|
||||
for its benefit. */
|
||||
#ifdef PIC
|
||||
#define CALL_MCOUNT \
|
||||
.pushsection; \
|
||||
.section ".data"; \
|
||||
.align ALIGNARG(2); \
|
||||
0:.long 0; \
|
||||
.previous; \
|
||||
mflr %r0; \
|
||||
stw %r0,4(%r1); \
|
||||
bl _GLOBAL_OFFSET_TABLE_@local-4; \
|
||||
mflr %r11; \
|
||||
lwz %r0,0b@got(%r11); \
|
||||
bl JUMPTARGET(_mcount);
|
||||
#else /* PIC */
|
||||
#define CALL_MCOUNT \
|
||||
.section ".data"; \
|
||||
.align ALIGNARG(2); \
|
||||
0:.long 0; \
|
||||
.previous; \
|
||||
mflr %r0; \
|
||||
lis %r11,0b@ha; \
|
||||
stw %r0,4(%r1); \
|
||||
addi %r0,%r11,0b@l; \
|
||||
bl JUMPTARGET(_mcount);
|
||||
#endif /* PIC */
|
||||
#else /* PROF */
|
||||
#define CALL_MCOUNT /* Do nothing. */
|
||||
#endif /* PROF */
|
||||
|
||||
#define ENTRY(name) \
|
||||
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
|
||||
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
|
||||
.align ALIGNARG(2); \
|
||||
C_LABEL(name) \
|
||||
CALL_MCOUNT
|
||||
|
||||
#define EALIGN_W_0 /* No words to insert. */
|
||||
#define EALIGN_W_1 nop
|
||||
#define EALIGN_W_2 nop;nop
|
||||
#define EALIGN_W_3 nop;nop;nop
|
||||
#define EALIGN_W_4 EALIGN_W_3;nop
|
||||
#define EALIGN_W_5 EALIGN_W_4;nop
|
||||
#define EALIGN_W_6 EALIGN_W_5;nop
|
||||
#define EALIGN_W_7 EALIGN_W_6;nop
|
||||
|
||||
/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
|
||||
past a 2^align boundary. */
|
||||
#ifdef PROF
|
||||
#define EALIGN(name, alignt, words) \
|
||||
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
|
||||
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
|
||||
.align ALIGNARG(2); \
|
||||
C_LABEL(name) \
|
||||
CALL_MCOUNT \
|
||||
b 0f; \
|
||||
.align ALIGNARG(alignt); \
|
||||
EALIGN_W_##words; \
|
||||
0:
|
||||
#else /* PROF */
|
||||
#define EALIGN(name, alignt, words) \
|
||||
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
|
||||
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
|
||||
.align ALIGNARG(alignt); \
|
||||
EALIGN_W_##words; \
|
||||
C_LABEL(name)
|
||||
#endif
|
||||
|
||||
#define END(name) \
|
||||
ASM_SIZE_DIRECTIVE(name)
|
||||
|
||||
#ifdef PIC
|
||||
#define JUMPTARGET(name) name##@plt
|
||||
#else
|
||||
#define JUMPTARGET(name) name
|
||||
#endif
|
||||
|
||||
/* Local labels stripped out by the linker. */
|
||||
#define L(x) .L##x
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,171 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Round up to FFI_SIZEOF_ARG. */
|
||||
|
||||
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
|
||||
|
||||
/* Perform machine independent initialization of aggregate type
|
||||
specifications. */
|
||||
|
||||
static ffi_status initialize_aggregate(ffi_type *arg)
|
||||
{
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(arg != NULL);
|
||||
|
||||
FFI_ASSERT(arg->elements != NULL);
|
||||
FFI_ASSERT(arg->size == 0);
|
||||
FFI_ASSERT(arg->alignment == 0);
|
||||
|
||||
ptr = &(arg->elements[0]);
|
||||
|
||||
while ((*ptr) != NULL)
|
||||
{
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
arg->size = ALIGN(arg->size, (*ptr)->alignment);
|
||||
arg->size += (*ptr)->size;
|
||||
|
||||
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
|
||||
arg->alignment : (*ptr)->alignment;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Structure size includes tail padding. This is important for
|
||||
structures that fit in one register on ABIs like the PowerPC64
|
||||
Linux ABI that right justify small structs in a register.
|
||||
It's also needed for nested structure layout, for example
|
||||
struct A { long a; char b; }; struct B { struct A x; char y; };
|
||||
should find y at an offset of 2*sizeof(long) and result in a
|
||||
total size of 3*sizeof(long). */
|
||||
arg->size = ALIGN (arg->size, arg->alignment);
|
||||
|
||||
if (arg->size == 0)
|
||||
return FFI_BAD_TYPEDEF;
|
||||
else
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
#ifndef __CRIS__
|
||||
/* The CRIS ABI specifies structure elements to have byte
|
||||
alignment only, so it completely overrides this functions,
|
||||
which assumes "natural" alignment and padding. */
|
||||
|
||||
/* Perform machine independent ffi_cif preparation, then call
|
||||
machine dependent routine. */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
||||
ffi_type *rtype, ffi_type **atypes)
|
||||
{
|
||||
unsigned bytes = 0;
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
FFI_ASSERT(cif != NULL);
|
||||
FFI_ASSERT(abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI);
|
||||
|
||||
cif->abi = abi;
|
||||
cif->arg_types = atypes;
|
||||
cif->nargs = nargs;
|
||||
cif->rtype = rtype;
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
/* Initialize the return type if necessary */
|
||||
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the return type */
|
||||
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
||||
|
||||
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
|
||||
/* Make space for the return structure pointer */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
#ifdef SPARC
|
||||
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
|
||||
#endif
|
||||
)
|
||||
bytes = STACK_ARG_SIZE(sizeof(void*));
|
||||
#endif
|
||||
|
||||
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
|
||||
{
|
||||
|
||||
/* Initialize any uninitialized aggregate type definitions */
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
/* Perform a sanity check on the argument type, do this
|
||||
check after the initialization. */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
#if !defined X86_ANY && !defined S390 && !defined PA
|
||||
#ifdef SPARC
|
||||
if (((*ptr)->type == FFI_TYPE_STRUCT
|
||||
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
||||
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
|
||||
&& cif->abi != FFI_V9))
|
||||
bytes += sizeof(void*);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Add any padding if necessary */
|
||||
if (((*ptr)->alignment - 1) & bytes)
|
||||
bytes = ALIGN(bytes, (*ptr)->alignment);
|
||||
|
||||
bytes += STACK_ARG_SIZE((*ptr)->size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cif->bytes = bytes;
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
return ffi_prep_cif_machdep(cif);
|
||||
}
|
||||
#endif /* not __CRIS__ */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
{
|
||||
return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,627 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi64.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
|
||||
Copyright (c) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
x86-64 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define MAX_GPR_REGS 6
|
||||
#define MAX_SSE_REGS 8
|
||||
|
||||
struct register_args
|
||||
{
|
||||
/* Registers for argument passing. */
|
||||
UINT64 gpr[MAX_GPR_REGS];
|
||||
__int128_t sse[MAX_SSE_REGS];
|
||||
};
|
||||
|
||||
extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
|
||||
void *raddr, void (*fnaddr)(void), unsigned ssecount);
|
||||
|
||||
/* All reference to register classes here is identical to the code in
|
||||
gcc/config/i386/i386.c. Do *not* change one without the other. */
|
||||
|
||||
/* Register class used for passing given 64bit part of the argument.
|
||||
These represent classes as documented by the PS ABI, with the
|
||||
exception of SSESF, SSEDF classes, that are basically SSE class,
|
||||
just gcc will use SF or DFmode move instead of DImode to avoid
|
||||
reformatting penalties.
|
||||
|
||||
Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
|
||||
whenever possible (upper half does contain padding). */
|
||||
enum x86_64_reg_class
|
||||
{
|
||||
X86_64_NO_CLASS,
|
||||
X86_64_INTEGER_CLASS,
|
||||
X86_64_INTEGERSI_CLASS,
|
||||
X86_64_SSE_CLASS,
|
||||
X86_64_SSESF_CLASS,
|
||||
X86_64_SSEDF_CLASS,
|
||||
X86_64_SSEUP_CLASS,
|
||||
X86_64_X87_CLASS,
|
||||
X86_64_X87UP_CLASS,
|
||||
X86_64_COMPLEX_X87_CLASS,
|
||||
X86_64_MEMORY_CLASS
|
||||
};
|
||||
|
||||
#define MAX_CLASSES 4
|
||||
|
||||
#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
|
||||
|
||||
/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
|
||||
of this code is to classify each 8bytes of incoming argument by the register
|
||||
class and assign registers accordingly. */
|
||||
|
||||
/* Return the union class of CLASS1 and CLASS2.
|
||||
See the x86-64 PS ABI for details. */
|
||||
|
||||
static enum x86_64_reg_class
|
||||
merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
|
||||
{
|
||||
/* Rule #1: If both classes are equal, this is the resulting class. */
|
||||
if (class1 == class2)
|
||||
return class1;
|
||||
|
||||
/* Rule #2: If one of the classes is NO_CLASS, the resulting class is
|
||||
the other class. */
|
||||
if (class1 == X86_64_NO_CLASS)
|
||||
return class2;
|
||||
if (class2 == X86_64_NO_CLASS)
|
||||
return class1;
|
||||
|
||||
/* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
|
||||
if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
|
||||
return X86_64_MEMORY_CLASS;
|
||||
|
||||
/* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
|
||||
if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
|
||||
|| (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
|
||||
return X86_64_INTEGERSI_CLASS;
|
||||
if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
|
||||
|| class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
|
||||
return X86_64_INTEGER_CLASS;
|
||||
|
||||
/* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
|
||||
MEMORY is used. */
|
||||
if (class1 == X86_64_X87_CLASS
|
||||
|| class1 == X86_64_X87UP_CLASS
|
||||
|| class1 == X86_64_COMPLEX_X87_CLASS
|
||||
|| class2 == X86_64_X87_CLASS
|
||||
|| class2 == X86_64_X87UP_CLASS
|
||||
|| class2 == X86_64_COMPLEX_X87_CLASS)
|
||||
return X86_64_MEMORY_CLASS;
|
||||
|
||||
/* Rule #6: Otherwise class SSE is used. */
|
||||
return X86_64_SSE_CLASS;
|
||||
}
|
||||
|
||||
/* Classify the argument of type TYPE and mode MODE.
|
||||
CLASSES will be filled by the register class used to pass each word
|
||||
of the operand. The number of words is returned. In case the parameter
|
||||
should be passed in memory, 0 is returned. As a special case for zero
|
||||
sized containers, classes[0] will be NO_CLASS and 1 is returned.
|
||||
|
||||
See the x86-64 PS ABI for details.
|
||||
*/
|
||||
static int
|
||||
classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
size_t byte_offset)
|
||||
{
|
||||
switch (type->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
{
|
||||
int size = byte_offset + type->size;
|
||||
|
||||
if (size <= 4)
|
||||
{
|
||||
classes[0] = X86_64_INTEGERSI_CLASS;
|
||||
return 1;
|
||||
}
|
||||
else if (size <= 8)
|
||||
{
|
||||
classes[0] = X86_64_INTEGER_CLASS;
|
||||
return 1;
|
||||
}
|
||||
else if (size <= 12)
|
||||
{
|
||||
classes[0] = X86_64_INTEGER_CLASS;
|
||||
classes[1] = X86_64_INTEGERSI_CLASS;
|
||||
return 2;
|
||||
}
|
||||
else if (size <= 16)
|
||||
{
|
||||
classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
FFI_ASSERT (0);
|
||||
}
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (!(byte_offset % 8))
|
||||
classes[0] = X86_64_SSESF_CLASS;
|
||||
else
|
||||
classes[0] = X86_64_SSE_CLASS;
|
||||
return 1;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
classes[0] = X86_64_SSEDF_CLASS;
|
||||
return 1;
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
classes[0] = X86_64_X87_CLASS;
|
||||
classes[1] = X86_64_X87UP_CLASS;
|
||||
return 2;
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
const int UNITS_PER_WORD = 8;
|
||||
int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
ffi_type **ptr;
|
||||
int i;
|
||||
enum x86_64_reg_class subclasses[MAX_CLASSES];
|
||||
|
||||
/* If the struct is larger than 32 bytes, pass it on the stack. */
|
||||
if (type->size > 32)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < words; i++)
|
||||
classes[i] = X86_64_NO_CLASS;
|
||||
|
||||
/* Zero sized arrays or structures are NO_CLASS. We return 0 to
|
||||
signalize memory class, so handle it as special case. */
|
||||
if (!words)
|
||||
{
|
||||
classes[0] = X86_64_NO_CLASS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Merge the fields of structure. */
|
||||
for (ptr = type->elements; *ptr != NULL; ptr++)
|
||||
{
|
||||
int num;
|
||||
|
||||
byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
|
||||
|
||||
num = classify_argument (*ptr, subclasses, byte_offset % 8);
|
||||
if (num == 0)
|
||||
return 0;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
int pos = byte_offset / 8;
|
||||
classes[i + pos] =
|
||||
merge_classes (subclasses[i], classes[i + pos]);
|
||||
}
|
||||
|
||||
byte_offset += (*ptr)->size;
|
||||
}
|
||||
|
||||
if (words > 2)
|
||||
{
|
||||
/* When size > 16 bytes, if the first one isn't
|
||||
X86_64_SSE_CLASS or any other ones aren't
|
||||
X86_64_SSEUP_CLASS, everything should be passed in
|
||||
memory. */
|
||||
if (classes[0] != X86_64_SSE_CLASS)
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < words; i++)
|
||||
if (classes[i] != X86_64_SSEUP_CLASS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Final merger cleanup. */
|
||||
for (i = 0; i < words; i++)
|
||||
{
|
||||
/* If one class is MEMORY, everything should be passed in
|
||||
memory. */
|
||||
if (classes[i] == X86_64_MEMORY_CLASS)
|
||||
return 0;
|
||||
|
||||
/* The X86_64_SSEUP_CLASS should be always preceded by
|
||||
X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
|
||||
if (classes[i] == X86_64_SSEUP_CLASS
|
||||
&& classes[i - 1] != X86_64_SSE_CLASS
|
||||
&& classes[i - 1] != X86_64_SSEUP_CLASS)
|
||||
{
|
||||
/* The first one should never be X86_64_SSEUP_CLASS. */
|
||||
FFI_ASSERT (i != 0);
|
||||
classes[i] = X86_64_SSE_CLASS;
|
||||
}
|
||||
|
||||
/* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
|
||||
everything should be passed in memory. */
|
||||
if (classes[i] == X86_64_X87UP_CLASS
|
||||
&& (classes[i - 1] != X86_64_X87_CLASS))
|
||||
{
|
||||
/* The first one should never be X86_64_X87UP_CLASS. */
|
||||
FFI_ASSERT (i != 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
return 0; /* Never reached. */
|
||||
}
|
||||
|
||||
/* Examine the argument and return set number of register required in each
|
||||
class. Return zero iff parameter should be passed in memory, otherwise
|
||||
the number of registers. */
|
||||
|
||||
static int
|
||||
examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
|
||||
_Bool in_return, int *pngpr, int *pnsse)
|
||||
{
|
||||
int i, n, ngpr, nsse;
|
||||
|
||||
n = classify_argument (type, classes, 0);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
ngpr = nsse = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
switch (classes[i])
|
||||
{
|
||||
case X86_64_INTEGER_CLASS:
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
ngpr++;
|
||||
break;
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSESF_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
nsse++;
|
||||
break;
|
||||
case X86_64_NO_CLASS:
|
||||
case X86_64_SSEUP_CLASS:
|
||||
break;
|
||||
case X86_64_X87_CLASS:
|
||||
case X86_64_X87UP_CLASS:
|
||||
case X86_64_COMPLEX_X87_CLASS:
|
||||
return in_return != 0;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
*pngpr = ngpr;
|
||||
*pnsse = nsse;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing. */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
size_t bytes;
|
||||
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
flags = cif->rtype->type;
|
||||
if (flags != FFI_TYPE_VOID)
|
||||
{
|
||||
n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
|
||||
if (n == 0)
|
||||
{
|
||||
/* The return value is passed in memory. A pointer to that
|
||||
memory is the first argument. Allocate a register for it. */
|
||||
gprcount++;
|
||||
/* We don't have to do anything in asm for the return. */
|
||||
flags = FFI_TYPE_VOID;
|
||||
}
|
||||
else if (flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
/* Mark which registers the result appears in. */
|
||||
_Bool sse0 = SSE_CLASS_P (classes[0]);
|
||||
_Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
|
||||
if (sse0 && !sse1)
|
||||
flags |= 1 << 8;
|
||||
else if (!sse0 && sse1)
|
||||
flags |= 1 << 9;
|
||||
else if (sse0 && sse1)
|
||||
flags |= 1 << 10;
|
||||
/* Mark the true size of the structure. */
|
||||
flags |= cif->rtype->size << 12;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go over all arguments and determine the way they should be passed.
|
||||
If it's in a register and there is space for it, let that be so. If
|
||||
not, add it's size to the stack byte count. */
|
||||
for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
|
||||
{
|
||||
if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = cif->arg_types[i]->alignment;
|
||||
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
bytes = ALIGN (bytes, align);
|
||||
bytes += cif->arg_types[i]->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
gprcount += ngpr;
|
||||
ssecount += nsse;
|
||||
}
|
||||
}
|
||||
if (ssecount)
|
||||
flags |= 1 << 11;
|
||||
cif->flags = flags;
|
||||
cif->bytes = ALIGN (bytes, 8);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
char *stack, *argp;
|
||||
ffi_type **arg_types;
|
||||
int gprcount, ssecount, ngpr, nsse, i, avn;
|
||||
_Bool ret_in_memory;
|
||||
struct register_args *reg_args;
|
||||
|
||||
/* Can't call 32-bit mode from 64-bit mode. */
|
||||
FFI_ASSERT (cif->abi == FFI_UNIX64);
|
||||
|
||||
/* If the return value is a struct and we don't have a return value
|
||||
address then we need to make one. Note the setting of flags to
|
||||
VOID above in ffi_prep_cif_machdep. */
|
||||
ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& (cif->flags & 0xff) == FFI_TYPE_VOID);
|
||||
if (rvalue == NULL && ret_in_memory)
|
||||
rvalue = alloca (cif->rtype->size);
|
||||
|
||||
/* Allocate the space for the arguments, plus 4 words of temp space. */
|
||||
stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
|
||||
reg_args = (struct register_args *) stack;
|
||||
argp = stack + sizeof (struct register_args);
|
||||
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
/* If the return value is passed in memory, add the pointer as the
|
||||
first integer argument. */
|
||||
if (ret_in_memory)
|
||||
reg_args->gpr[gprcount++] = (long) rvalue;
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
for (i = 0; i < avn; ++i)
|
||||
{
|
||||
size_t size = arg_types[i]->size;
|
||||
int n;
|
||||
|
||||
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
|
||||
if (n == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = arg_types[i]->alignment;
|
||||
|
||||
/* Stack arguments are *always* at least 8 byte aligned. */
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
/* Pass this argument in memory. */
|
||||
argp = (void *) ALIGN (argp, align);
|
||||
memcpy (argp, avalue[i], size);
|
||||
argp += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The argument is passed entirely in registers. */
|
||||
char *a = (char *) avalue[i];
|
||||
int j;
|
||||
|
||||
for (j = 0; j < n; j++, a += 8, size -= 8)
|
||||
{
|
||||
switch (classes[j])
|
||||
{
|
||||
case X86_64_INTEGER_CLASS:
|
||||
case X86_64_INTEGERSI_CLASS:
|
||||
reg_args->gpr[gprcount] = 0;
|
||||
memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8);
|
||||
gprcount++;
|
||||
break;
|
||||
case X86_64_SSE_CLASS:
|
||||
case X86_64_SSEDF_CLASS:
|
||||
reg_args->sse[ssecount++] = *(UINT64 *) a;
|
||||
break;
|
||||
case X86_64_SSESF_CLASS:
|
||||
reg_args->sse[ssecount++] = *(UINT32 *) a;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
|
||||
cif->flags, rvalue, fn, ssecount);
|
||||
}
|
||||
|
||||
|
||||
extern void ffi_closure_unix64(void);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
volatile unsigned short *tramp;
|
||||
|
||||
tramp = (volatile unsigned short *) &closure->tramp[0];
|
||||
|
||||
tramp[0] = 0xbb49; /* mov <code>, %r11 */
|
||||
*(void * volatile *) &tramp[1] = ffi_closure_unix64;
|
||||
tramp[5] = 0xba49; /* mov <data>, %r10 */
|
||||
*(void * volatile *) &tramp[6] = codeloc;
|
||||
|
||||
/* Set the carry bit iff the function uses any sse registers.
|
||||
This is clc or stc, together with the first byte of the jmp. */
|
||||
tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
|
||||
|
||||
tramp[11] = 0xe3ff; /* jmp *%r11 */
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
int
|
||||
ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
|
||||
struct register_args *reg_args, char *argp)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **avalue;
|
||||
ffi_type **arg_types;
|
||||
long i, avn;
|
||||
int gprcount, ssecount, ngpr, nsse;
|
||||
int ret;
|
||||
|
||||
cif = closure->cif;
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
gprcount = ssecount = 0;
|
||||
|
||||
ret = cif->rtype->type;
|
||||
if (ret != FFI_TYPE_VOID)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
|
||||
if (n == 0)
|
||||
{
|
||||
/* The return value goes in memory. Arrange for the closure
|
||||
return value to go directly back to the original caller. */
|
||||
rvalue = (void *) reg_args->gpr[gprcount++];
|
||||
/* We don't have to do anything in asm for the return. */
|
||||
ret = FFI_TYPE_VOID;
|
||||
}
|
||||
else if (ret == FFI_TYPE_STRUCT && n == 2)
|
||||
{
|
||||
/* Mark which register the second word of the structure goes in. */
|
||||
_Bool sse0 = SSE_CLASS_P (classes[0]);
|
||||
_Bool sse1 = SSE_CLASS_P (classes[1]);
|
||||
if (!sse0 && sse1)
|
||||
ret |= 1 << 8;
|
||||
else if (sse0 && !sse1)
|
||||
ret |= 1 << 9;
|
||||
}
|
||||
}
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
for (i = 0; i < avn; ++i)
|
||||
{
|
||||
enum x86_64_reg_class classes[MAX_CLASSES];
|
||||
int n;
|
||||
|
||||
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
|
||||
if (n == 0
|
||||
|| gprcount + ngpr > MAX_GPR_REGS
|
||||
|| ssecount + nsse > MAX_SSE_REGS)
|
||||
{
|
||||
long align = arg_types[i]->alignment;
|
||||
|
||||
/* Stack arguments are *always* at least 8 byte aligned. */
|
||||
if (align < 8)
|
||||
align = 8;
|
||||
|
||||
/* Pass this argument in memory. */
|
||||
argp = (void *) ALIGN (argp, align);
|
||||
avalue[i] = argp;
|
||||
argp += arg_types[i]->size;
|
||||
}
|
||||
/* If the argument is in a single register, or two consecutive
|
||||
integer registers, then we can use that address directly. */
|
||||
else if (n == 1
|
||||
|| (n == 2 && !(SSE_CLASS_P (classes[0])
|
||||
|| SSE_CLASS_P (classes[1]))))
|
||||
{
|
||||
/* The argument is in a single register. */
|
||||
if (SSE_CLASS_P (classes[0]))
|
||||
{
|
||||
avalue[i] = ®_args->sse[ssecount];
|
||||
ssecount += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
avalue[i] = ®_args->gpr[gprcount];
|
||||
gprcount += n;
|
||||
}
|
||||
}
|
||||
/* Otherwise, allocate space to make them consecutive. */
|
||||
else
|
||||
{
|
||||
char *a = alloca (16);
|
||||
int j;
|
||||
|
||||
avalue[i] = a;
|
||||
for (j = 0; j < n; j++, a += 8)
|
||||
{
|
||||
if (SSE_CLASS_P (classes[j]))
|
||||
memcpy (a, ®_args->sse[ssecount++], 8);
|
||||
else
|
||||
memcpy (a, ®_args->gpr[gprcount++], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
closure->fun (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Tell assembly how to perform return type promotions. */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
@@ -1,35 +0,0 @@
|
||||
/* Area: ffi_prep_cif, ffi_prep_closure
|
||||
Purpose: Test error return for bad ABIs.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/6/2007 */
|
||||
|
||||
/* { dg-do run { xfail *-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void
|
||||
dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
|
||||
void** args __UNUSED__, void* userdata __UNUSED__)
|
||||
{}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type* arg_types[1];
|
||||
|
||||
arg_types[0] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
|
||||
arg_types) == FFI_BAD_ABI);
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
|
||||
arg_types) == FFI_OK);
|
||||
|
||||
cif.abi= 255;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/* Area: ffi_prep_cif
|
||||
Purpose: Test error return for bad typedefs.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/6/2007 */
|
||||
|
||||
/* { dg-do run { xfail *-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type* arg_types[1];
|
||||
|
||||
arg_types[0] = NULL;
|
||||
|
||||
ffi_type badType = ffi_type_void;
|
||||
|
||||
badType.size = 0;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
|
||||
arg_types) == FFI_BAD_TYPEDEF);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
externo
-16016
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,180 +0,0 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CC_MAXOPT
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Try to turn on "good" C optimization flags for various compilers and
|
||||
# architectures, for some definition of "good". (In our case, good for
|
||||
# FFTW and hopefully for other scientific codes. Modify as needed.)
|
||||
#
|
||||
# The user can override the flags by setting the CFLAGS environment
|
||||
# variable. The user can also specify --enable-portable-binary in order to
|
||||
# disable any optimization flags that might result in a binary that only
|
||||
# runs on the host architecture.
|
||||
#
|
||||
# Note also that the flags assume that ANSI C aliasing rules are followed
|
||||
# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point
|
||||
# computations can be re-ordered as needed.
|
||||
#
|
||||
# Requires macros: AX_CHECK_COMPILER_FLAGS, AX_COMPILER_VENDOR,
|
||||
# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2008 Matteo Frigo
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 11
|
||||
|
||||
AC_DEFUN([AX_CC_MAXOPT],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AX_COMPILER_VENDOR])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
|
||||
AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
|
||||
acx_maxopt_portable=$withval, acx_maxopt_portable=no)
|
||||
|
||||
# Try to determine "good" native compiler flags if none specified via CFLAGS
|
||||
if test "$ac_test_CFLAGS" != "set"; then
|
||||
CFLAGS=""
|
||||
case $ax_cv_c_compiler_vendor in
|
||||
dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
|
||||
if test "x$acx_maxopt_portable" = xno; then
|
||||
CFLAGS="$CFLAGS -arch host"
|
||||
fi;;
|
||||
|
||||
sun) CFLAGS="-native -fast -xO5 -dalign"
|
||||
if test "x$acx_maxopt_portable" = xyes; then
|
||||
CFLAGS="$CFLAGS -xarch=generic"
|
||||
fi;;
|
||||
|
||||
hp) CFLAGS="+Oall +Optrs_ansi +DSnative"
|
||||
if test "x$acx_maxopt_portable" = xyes; then
|
||||
CFLAGS="$CFLAGS +DAportable"
|
||||
fi;;
|
||||
|
||||
ibm) if test "x$acx_maxopt_portable" = xno; then
|
||||
xlc_opt="-qarch=auto -qtune=auto"
|
||||
else
|
||||
xlc_opt="-qtune=auto"
|
||||
fi
|
||||
AX_CHECK_COMPILER_FLAGS($xlc_opt,
|
||||
CFLAGS="-O3 -qansialias -w $xlc_opt",
|
||||
[CFLAGS="-O3 -qansialias -w"
|
||||
echo "******************************************************"
|
||||
echo "* You seem to have the IBM C compiler. It is *"
|
||||
echo "* recommended for best performance that you use: *"
|
||||
echo "* *"
|
||||
echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
|
||||
echo "* ^^^ ^^^ *"
|
||||
echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *"
|
||||
echo "* CPU you have. (Set the CFLAGS environment var. *"
|
||||
echo "* and re-run configure.) For more info, man cc. *"
|
||||
echo "******************************************************"])
|
||||
;;
|
||||
|
||||
intel) CFLAGS="-O3 -ansi_alias"
|
||||
if test "x$acx_maxopt_portable" = xno; then
|
||||
icc_archflag=unknown
|
||||
icc_flags=""
|
||||
case $host_cpu in
|
||||
i686*|x86_64*)
|
||||
# icc accepts gcc assembly syntax, so these should work:
|
||||
AX_GCC_X86_CPUID(0)
|
||||
AX_GCC_X86_CPUID(1)
|
||||
case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
|
||||
*:756e6547:*:*) # Intel
|
||||
case $ax_cv_gcc_x86_cpuid_1 in
|
||||
*6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
|
||||
*f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
|
||||
*f??:*:*:*) icc_flags="-xN -xW -xK";;
|
||||
esac ;;
|
||||
esac ;;
|
||||
esac
|
||||
if test "x$icc_flags" != x; then
|
||||
for flag in $icc_flags; do
|
||||
AX_CHECK_COMPILER_FLAGS($flag, [icc_archflag=$flag; break])
|
||||
done
|
||||
fi
|
||||
AC_MSG_CHECKING([for icc architecture flag])
|
||||
AC_MSG_RESULT($icc_archflag)
|
||||
if test "x$icc_archflag" != xunknown; then
|
||||
CFLAGS="$CFLAGS $icc_archflag"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
gnu)
|
||||
# default optimization flags for gcc on all systems
|
||||
CFLAGS="-O3 -fomit-frame-pointer"
|
||||
|
||||
# -malign-double for x86 systems
|
||||
AX_CHECK_COMPILER_FLAGS(-malign-double, CFLAGS="$CFLAGS -malign-double")
|
||||
|
||||
# -fstrict-aliasing for gcc-2.95+
|
||||
AX_CHECK_COMPILER_FLAGS(-fstrict-aliasing,
|
||||
CFLAGS="$CFLAGS -fstrict-aliasing")
|
||||
|
||||
# note that we enable "unsafe" fp optimization with other compilers, too
|
||||
AX_CHECK_COMPILER_FLAGS(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
|
||||
|
||||
AX_GCC_ARCHFLAG($acx_maxopt_portable)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$CFLAGS"; then
|
||||
echo ""
|
||||
echo "********************************************************"
|
||||
echo "* WARNING: Don't know the best CFLAGS for this system *"
|
||||
echo "* Use ./configure CFLAGS=... to specify your own flags *"
|
||||
echo "* (otherwise, a default of CFLAGS=-O3 will be used) *"
|
||||
echo "********************************************************"
|
||||
echo ""
|
||||
CFLAGS="-O3"
|
||||
fi
|
||||
|
||||
AX_CHECK_COMPILER_FLAGS($CFLAGS, [], [
|
||||
echo ""
|
||||
echo "********************************************************"
|
||||
echo "* WARNING: The guessed CFLAGS don't seem to work with *"
|
||||
echo "* your compiler. *"
|
||||
echo "* Use ./configure CFLAGS=... to specify your own flags *"
|
||||
echo "********************************************************"
|
||||
echo ""
|
||||
CFLAGS=""
|
||||
])
|
||||
|
||||
fi
|
||||
])
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
-16016
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,488 +0,0 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
|
||||
# defaults of its own if none are provided.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
save_CFLAGS=$CFLAGS
|
||||
AC_PROG_CC
|
||||
CFLAGS=$save_CFLAGS
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(mmap)
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
case "$host" in
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd* | amd64-*-openbsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
i?86-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-solaris2.1[[0-9]]*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-*)
|
||||
TARGET=X86; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
;;
|
||||
|
||||
sh-*-* | sh[[34]]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
;;
|
||||
|
||||
x86_64-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-cygwin* | x86_64-*-mingw*)
|
||||
TARGET=X86_WIN64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
|
||||
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
|
||||
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
|
||||
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
|
||||
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
|
||||
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
|
||||
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
|
||||
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
|
||||
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||||
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||||
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||||
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||||
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
|
||||
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
libffi_cv_as_cfi_pseudo_op, [
|
||||
libffi_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
[libffi_cv_as_cfi_pseudo_op=yes],
|
||||
[libffi_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
|
||||
if test x$TARGET = xSPARC; then
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
|
||||
libffi_cv_as_ascii_pseudo_op, [
|
||||
libffi_cv_as_ascii_pseudo_op=unknown
|
||||
# Check if we have .ascii
|
||||
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
|
||||
[libffi_cv_as_ascii_pseudo_op=yes],
|
||||
[libffi_cv_as_ascii_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .ascii.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .string pseudo-op support],
|
||||
libffi_cv_as_string_pseudo_op, [
|
||||
libffi_cv_as_string_pseudo_op=unknown
|
||||
# Check if we have .string
|
||||
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
|
||||
[libffi_cv_as_string_pseudo_op=yes],
|
||||
[libffi_cv_as_string_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .string.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86_WIN64; then
|
||||
LT_SYS_SYMBOL_USCORE
|
||||
if test "x$sys_symbol_underscore" = xyes; then
|
||||
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=0
|
||||
case "$target" in
|
||||
*arm*-apple-darwin*)
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=1
|
||||
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
|
||||
[Cannot use PROT_EXEC on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
*-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
|
||||
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
echo '.section .eh_frame,"a",@unwind' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
|
||||
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
elif grep '.section.*eh_frame.*#alloc' conftest.c \
|
||||
| grep -v '#write' > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if grep '\.hidden.*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test x"$GCC" != x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
fi
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,615 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
|
||||
Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
Code to allocate and deallocate memory for closures.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if defined __linux__ && !defined _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
|
||||
# if __gnu_linux__
|
||||
/* This macro indicates it may be forbidden to map anonymous memory
|
||||
with both write and execute permission. Code compiled when this
|
||||
option is defined will attempt to map such pages once, but if it
|
||||
fails, it falls back to creating a temporary file in a writable and
|
||||
executable filesystem and mapping pages from it into separate
|
||||
locations in the virtual memory space, one location writable and
|
||||
another executable. */
|
||||
# define FFI_MMAP_EXEC_WRIT 1
|
||||
# define HAVE_MNTENT 1
|
||||
# endif
|
||||
# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
|
||||
/* Windows systems may have Data Execution Protection (DEP) enabled,
|
||||
which requires the use of VirtualMalloc/VirtualFree to alloc/free
|
||||
executable memory. */
|
||||
# define FFI_MMAP_EXEC_WRIT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
|
||||
# ifdef __linux__
|
||||
/* When defined to 1 check for SELinux and if SELinux is active,
|
||||
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
|
||||
might cause audit messages. */
|
||||
# define FFI_MMAP_EXEC_SELINUX 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
# if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
|
||||
|
||||
# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
|
||||
|
||||
#define USE_LOCKS 1
|
||||
#define USE_DL_PREFIX 1
|
||||
#ifdef __GNUC__
|
||||
#ifndef USE_BUILTIN_FFS
|
||||
#define USE_BUILTIN_FFS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* We need to use mmap, not sbrk. */
|
||||
#define HAVE_MORECORE 0
|
||||
|
||||
/* We could, in theory, support mremap, but it wouldn't buy us anything. */
|
||||
#define HAVE_MREMAP 0
|
||||
|
||||
/* We have no use for this, so save some code and data. */
|
||||
#define NO_MALLINFO 1
|
||||
|
||||
/* We need all allocations to be in regular segments, otherwise we
|
||||
lose track of the corresponding code address. */
|
||||
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
|
||||
|
||||
/* Don't allocate more than a page unless needed. */
|
||||
#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
/* Don't release single pages, to avoid a worst-case scenario of
|
||||
continuously allocating and releasing single pages, but release
|
||||
pairs of pages, which should do just as well given that allocations
|
||||
are likely to be small. */
|
||||
#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#if !defined(X86_WIN32) && !defined(X86_WIN64)
|
||||
#ifdef HAVE_MNTENT
|
||||
#include <mntent.h>
|
||||
#endif /* HAVE_MNTENT */
|
||||
#include <sys/param.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* We don't want sys/mman.h to be included after we redefine mmap and
|
||||
dlmunmap. */
|
||||
#include <sys/mman.h>
|
||||
#define LACKS_SYS_MMAN_H 1
|
||||
|
||||
#if FFI_MMAP_EXEC_SELINUX
|
||||
#include <sys/statfs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int selinux_enabled = -1;
|
||||
|
||||
static int
|
||||
selinux_enabled_check (void)
|
||||
{
|
||||
struct statfs sfs;
|
||||
FILE *f;
|
||||
char *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (statfs ("/selinux", &sfs) >= 0
|
||||
&& (unsigned int) sfs.f_type == 0xf97cff8cU)
|
||||
return 1;
|
||||
f = fopen ("/proc/mounts", "r");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
while (getline (&buf, &len, f) >= 0)
|
||||
{
|
||||
char *p = strchr (buf, ' ');
|
||||
if (p == NULL)
|
||||
break;
|
||||
p = strchr (p + 1, ' ');
|
||||
if (p == NULL)
|
||||
break;
|
||||
if (strncmp (p + 1, "selinuxfs ", 10) == 0)
|
||||
{
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
|
||||
: (selinux_enabled = selinux_enabled_check ()))
|
||||
|
||||
#else
|
||||
|
||||
#define is_selinux_enabled() 0
|
||||
|
||||
#endif /* !FFI_MMAP_EXEC_SELINUX */
|
||||
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* Cygwin is Linux-like, but not quite that Linux-like. */
|
||||
#define is_selinux_enabled() 0
|
||||
|
||||
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
|
||||
|
||||
/* Declare all functions defined in dlmalloc.c as static. */
|
||||
static void *dlmalloc(size_t);
|
||||
static void dlfree(void*);
|
||||
static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
|
||||
static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
|
||||
static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
|
||||
static void *dlvalloc(size_t) MAYBE_UNUSED;
|
||||
static int dlmallopt(int, int) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
|
||||
static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
|
||||
static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
|
||||
static void *dlpvalloc(size_t) MAYBE_UNUSED;
|
||||
static int dlmalloc_trim(size_t) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
|
||||
static void dlmalloc_stats(void) MAYBE_UNUSED;
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
|
||||
/* Use these for mmap and munmap within dlmalloc.c. */
|
||||
static void *dlmmap(void *, size_t, int, int, int, off_t);
|
||||
static int dlmunmap(void *, size_t);
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
|
||||
|
||||
#define mmap dlmmap
|
||||
#define munmap dlmunmap
|
||||
|
||||
#include "dlmalloc.c"
|
||||
|
||||
#undef mmap
|
||||
#undef munmap
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
|
||||
|
||||
/* A mutex used to synchronize access to *exec* variables in this file. */
|
||||
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* A file descriptor of a temporary file from which we'll map
|
||||
executable pages. */
|
||||
static int execfd = -1;
|
||||
|
||||
/* The amount of space already allocated from the temporary file. */
|
||||
static size_t execsize = 0;
|
||||
|
||||
/* Open a temporary file name, and immediately unlink it. */
|
||||
static int
|
||||
open_temp_exec_file_name (char *name)
|
||||
{
|
||||
int fd = mkstemp (name);
|
||||
|
||||
if (fd != -1)
|
||||
unlink (name);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Open a temporary file in the named directory. */
|
||||
static int
|
||||
open_temp_exec_file_dir (const char *dir)
|
||||
{
|
||||
static const char suffix[] = "/ffiXXXXXX";
|
||||
int lendir = strlen (dir);
|
||||
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
|
||||
|
||||
if (!tempname)
|
||||
return -1;
|
||||
|
||||
memcpy (tempname, dir, lendir);
|
||||
memcpy (tempname + lendir, suffix, sizeof (suffix));
|
||||
|
||||
return open_temp_exec_file_name (tempname);
|
||||
}
|
||||
|
||||
/* Open a temporary file in the directory in the named environment
|
||||
variable. */
|
||||
static int
|
||||
open_temp_exec_file_env (const char *envvar)
|
||||
{
|
||||
const char *value = getenv (envvar);
|
||||
|
||||
if (!value)
|
||||
return -1;
|
||||
|
||||
return open_temp_exec_file_dir (value);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MNTENT
|
||||
/* Open a temporary file in an executable and writable mount point
|
||||
listed in the mounts file. Subsequent calls with the same mounts
|
||||
keep searching for mount points in the same file. Providing NULL
|
||||
as the mounts file closes the file. */
|
||||
static int
|
||||
open_temp_exec_file_mnt (const char *mounts)
|
||||
{
|
||||
static const char *last_mounts;
|
||||
static FILE *last_mntent;
|
||||
|
||||
if (mounts != last_mounts)
|
||||
{
|
||||
if (last_mntent)
|
||||
endmntent (last_mntent);
|
||||
|
||||
last_mounts = mounts;
|
||||
|
||||
if (mounts)
|
||||
last_mntent = setmntent (mounts, "r");
|
||||
else
|
||||
last_mntent = NULL;
|
||||
}
|
||||
|
||||
if (!last_mntent)
|
||||
return -1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int fd;
|
||||
struct mntent mnt;
|
||||
char buf[MAXPATHLEN * 3];
|
||||
|
||||
if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (hasmntopt (&mnt, "ro")
|
||||
|| hasmntopt (&mnt, "noexec")
|
||||
|| access (mnt.mnt_dir, W_OK))
|
||||
continue;
|
||||
|
||||
fd = open_temp_exec_file_dir (mnt.mnt_dir);
|
||||
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_MNTENT */
|
||||
|
||||
/* Instructions to look for a location to hold a temporary file that
|
||||
can be mapped in for execution. */
|
||||
static struct
|
||||
{
|
||||
int (*func)(const char *);
|
||||
const char *arg;
|
||||
int repeat;
|
||||
} open_temp_exec_file_opts[] = {
|
||||
{ open_temp_exec_file_env, "TMPDIR", 0 },
|
||||
{ open_temp_exec_file_dir, "/tmp", 0 },
|
||||
{ open_temp_exec_file_dir, "/var/tmp", 0 },
|
||||
{ open_temp_exec_file_dir, "/dev/shm", 0 },
|
||||
{ open_temp_exec_file_env, "HOME", 0 },
|
||||
#ifdef HAVE_MNTENT
|
||||
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
|
||||
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
|
||||
#endif /* HAVE_MNTENT */
|
||||
};
|
||||
|
||||
/* Current index into open_temp_exec_file_opts. */
|
||||
static int open_temp_exec_file_opts_idx = 0;
|
||||
|
||||
/* Reset a current multi-call func, then advances to the next entry.
|
||||
If we're at the last, go back to the first and return nonzero,
|
||||
otherwise return zero. */
|
||||
static int
|
||||
open_temp_exec_file_opts_next (void)
|
||||
{
|
||||
if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
|
||||
open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
|
||||
|
||||
open_temp_exec_file_opts_idx++;
|
||||
if (open_temp_exec_file_opts_idx
|
||||
== (sizeof (open_temp_exec_file_opts)
|
||||
/ sizeof (*open_temp_exec_file_opts)))
|
||||
{
|
||||
open_temp_exec_file_opts_idx = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return a file descriptor of a temporary zero-sized file in a
|
||||
writable and exexutable filesystem. */
|
||||
static int
|
||||
open_temp_exec_file (void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
do
|
||||
{
|
||||
fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
|
||||
(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
|
||||
|
||||
if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
|
||||
|| fd == -1)
|
||||
{
|
||||
if (open_temp_exec_file_opts_next ())
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (fd == -1);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Map in a chunk of memory from the temporary exec file into separate
|
||||
locations in the virtual memory address space, one writable and one
|
||||
executable. Returns the address of the writable portion, after
|
||||
storing an offset to the corresponding executable portion at the
|
||||
last word of the requested chunk. */
|
||||
static void *
|
||||
dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (execfd == -1)
|
||||
{
|
||||
open_temp_exec_file_opts_idx = 0;
|
||||
retry_open:
|
||||
execfd = open_temp_exec_file ();
|
||||
if (execfd == -1)
|
||||
return MFAIL;
|
||||
}
|
||||
|
||||
offset = execsize;
|
||||
|
||||
if (ftruncate (execfd, offset + length))
|
||||
return MFAIL;
|
||||
|
||||
flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
|
||||
flags |= MAP_SHARED;
|
||||
|
||||
ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
|
||||
flags, execfd, offset);
|
||||
if (ptr == MFAIL)
|
||||
{
|
||||
if (!offset)
|
||||
{
|
||||
close (execfd);
|
||||
goto retry_open;
|
||||
}
|
||||
ftruncate (execfd, offset);
|
||||
return MFAIL;
|
||||
}
|
||||
else if (!offset
|
||||
&& open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
|
||||
open_temp_exec_file_opts_next ();
|
||||
|
||||
start = mmap (start, length, prot, flags, execfd, offset);
|
||||
|
||||
if (start == MFAIL)
|
||||
{
|
||||
munmap (ptr, length);
|
||||
ftruncate (execfd, offset);
|
||||
return start;
|
||||
}
|
||||
|
||||
mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
|
||||
|
||||
execsize += length;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Map in a writable and executable chunk of memory if possible.
|
||||
Failing that, fall back to dlmmap_locked. */
|
||||
static void *
|
||||
dlmmap (void *start, size_t length, int prot,
|
||||
int flags, int fd, off_t offset)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
assert (start == NULL && length % malloc_getpagesize == 0
|
||||
&& prot == (PROT_READ | PROT_WRITE)
|
||||
&& flags == (MAP_PRIVATE | MAP_ANONYMOUS)
|
||||
&& fd == -1 && offset == 0);
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
printf ("mapping in %zi\n", length);
|
||||
#endif
|
||||
|
||||
if (execfd == -1 && !is_selinux_enabled ())
|
||||
{
|
||||
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
|
||||
|
||||
if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
|
||||
/* Cool, no need to mess with separate segments. */
|
||||
return ptr;
|
||||
|
||||
/* If MREMAP_DUP is ever introduced and implemented, try mmap
|
||||
with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
|
||||
MREMAP_DUP and prot at this point. */
|
||||
}
|
||||
|
||||
if (execsize == 0 || execfd == -1)
|
||||
{
|
||||
pthread_mutex_lock (&open_temp_exec_file_mutex);
|
||||
ptr = dlmmap_locked (start, length, prot, flags, offset);
|
||||
pthread_mutex_unlock (&open_temp_exec_file_mutex);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return dlmmap_locked (start, length, prot, flags, offset);
|
||||
}
|
||||
|
||||
/* Release memory at the given address, as well as the corresponding
|
||||
executable page if it's separate. */
|
||||
static int
|
||||
dlmunmap (void *start, size_t length)
|
||||
{
|
||||
/* We don't bother decreasing execsize or truncating the file, since
|
||||
we can't quite tell whether we're unmapping the end of the file.
|
||||
We don't expect frequent deallocation anyway. If we did, we
|
||||
could locate pages in the file by writing to the pages being
|
||||
deallocated and checking that the file contents change.
|
||||
Yuck. */
|
||||
msegmentptr seg = segment_holding (gm, start);
|
||||
void *code;
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
printf ("unmapping %zi\n", length);
|
||||
#endif
|
||||
|
||||
if (seg && (code = add_segment_exec_offset (start, seg)) != start)
|
||||
{
|
||||
int ret = munmap (code, length);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return munmap (start, length);
|
||||
}
|
||||
|
||||
#if FFI_CLOSURE_FREE_CODE
|
||||
/* Return segment holding given code address. */
|
||||
static msegmentptr
|
||||
segment_holding_code (mstate m, char* addr)
|
||||
{
|
||||
msegmentptr sp = &m->seg;
|
||||
for (;;) {
|
||||
if (addr >= add_segment_exec_offset (sp->base, sp)
|
||||
&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
|
||||
return sp;
|
||||
if ((sp = sp->next) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
|
||||
|
||||
/* Allocate a chunk of memory with the given size. Returns a pointer
|
||||
to the writable address, and sets *CODE to the executable
|
||||
corresponding virtual address. */
|
||||
void *
|
||||
ffi_closure_alloc (size_t size, void **code)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (!code)
|
||||
return NULL;
|
||||
|
||||
ptr = dlmalloc (size);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
msegmentptr seg = segment_holding (gm, ptr);
|
||||
|
||||
*code = add_segment_exec_offset (ptr, seg);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Release a chunk of memory allocated with ffi_closure_alloc. If
|
||||
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
|
||||
writable or the executable address given. Otherwise, only the
|
||||
writable address can be provided here. */
|
||||
void
|
||||
ffi_closure_free (void *ptr)
|
||||
{
|
||||
#if FFI_CLOSURE_FREE_CODE
|
||||
msegmentptr seg = segment_holding_code (gm, ptr);
|
||||
|
||||
if (seg)
|
||||
ptr = sub_segment_exec_offset (ptr, seg);
|
||||
#endif
|
||||
|
||||
dlfree (ptr);
|
||||
}
|
||||
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
/* Do some internal sanity testing to make sure allocation and
|
||||
deallocation of pages are working as intended. */
|
||||
int main ()
|
||||
{
|
||||
void *p[3];
|
||||
#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
|
||||
#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
|
||||
GET (0, malloc_getpagesize / 2);
|
||||
GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
|
||||
PUT (1);
|
||||
GET (1, 2 * malloc_getpagesize);
|
||||
GET (2, malloc_getpagesize / 2);
|
||||
PUT (1);
|
||||
PUT (0);
|
||||
PUT (2);
|
||||
return 0;
|
||||
}
|
||||
#endif /* FFI_CLOSURE_TEST */
|
||||
# else /* ! FFI_MMAP_EXEC_WRIT */
|
||||
|
||||
/* On many systems, memory returned by malloc is writable and
|
||||
executable, so just use it. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *
|
||||
ffi_closure_alloc (size_t size, void **code)
|
||||
{
|
||||
if (!code)
|
||||
return NULL;
|
||||
|
||||
return *code = malloc (size);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_closure_free (void *ptr)
|
||||
{
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
# endif /* ! FFI_MMAP_EXEC_WRIT */
|
||||
#endif /* FFI_CLOSURES */
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PLATFORM_IOS=/Developer/Platforms/iPhoneOS.platform/
|
||||
PLATFORM_IOS_SIM=/Developer/Platforms/iPhoneSimulator.platform/
|
||||
SDK_IOS_VERSION="4.1"
|
||||
|
||||
mkdir -p "build-ios"
|
||||
pushd "build-ios"
|
||||
export CC="${PLATFORM_IOS}"/Developer/usr/bin/gcc-4.2
|
||||
export CFLAGS="-arch armv6 -isysroot ${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/"
|
||||
../configure --host=arm-apple-darwin10 && make
|
||||
popd
|
||||
-4506
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,197 +0,0 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
SUBDIRS = include testsuite man
|
||||
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
|
||||
src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
|
||||
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
|
||||
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
|
||||
src/ia64/unix.S \
|
||||
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
|
||||
src/mips/ffitarget.h \
|
||||
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
|
||||
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
|
||||
src/powerpc/ffi.c src/powerpc/sysv.S \
|
||||
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
|
||||
src/powerpc/ppc_closure.S src/powerpc/asm.h \
|
||||
src/powerpc/aix.S src/powerpc/darwin.S \
|
||||
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
|
||||
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
|
||||
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
|
||||
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
|
||||
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
|
||||
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
|
||||
src/sparc/ffi.c src/x86/darwin64.S \
|
||||
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/win64.S \
|
||||
src/x86/darwin.S src/x86/freebsd.S \
|
||||
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
|
||||
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
|
||||
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h \
|
||||
src/dlmalloc.c \
|
||||
src/moxie/ffi.c src/moxie/eabi.S \
|
||||
libtool-version ChangeLog.libffi m4/libtool.m4 \
|
||||
m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4
|
||||
|
||||
info_TEXINFOS = doc/libffi.texi
|
||||
|
||||
## ################################################################
|
||||
|
||||
##
|
||||
## This section is for make and multilib madness.
|
||||
##
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
# values defined in terms of make variables, as is the case for CC and
|
||||
# friends when we are called from the top level Makefile.
|
||||
AM_MAKEFLAGS = \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
|
||||
"CFLAGS=$(CFLAGS)" \
|
||||
"CXXFLAGS=$(CXXFLAGS)" \
|
||||
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
|
||||
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
|
||||
"INSTALL=$(INSTALL)" \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
|
||||
"JC1FLAGS=$(JC1FLAGS)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
|
||||
"MAKE=$(MAKE)" \
|
||||
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
|
||||
"SHELL=$(SHELL)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"infodir=$(infodir)" \
|
||||
"libdir=$(libdir)" \
|
||||
"mandir=$(mandir)" \
|
||||
"prefix=$(prefix)" \
|
||||
"AR=$(AR)" \
|
||||
"AS=$(AS)" \
|
||||
"CC=$(CC)" \
|
||||
"CXX=$(CXX)" \
|
||||
"LD=$(LD)" \
|
||||
"NM=$(NM)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
"DESTDIR=$(DESTDIR)"
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
|
||||
|
||||
lib_LTLIBRARIES = libffi.la
|
||||
noinst_LTLIBRARIES = libffi_convenience.la
|
||||
|
||||
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
||||
src/raw_api.c src/java_raw_api.c src/closures.c
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libffi.pc
|
||||
|
||||
nodist_libffi_la_SOURCES =
|
||||
|
||||
if MIPS
|
||||
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
|
||||
endif
|
||||
if X86
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
|
||||
endif
|
||||
if X86_FREEBSD
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
|
||||
endif
|
||||
if X86_WIN32
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
|
||||
endif
|
||||
if X86_WIN64
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
|
||||
endif
|
||||
if X86_DARWIN
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
|
||||
endif
|
||||
if SPARC
|
||||
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
|
||||
endif
|
||||
if ALPHA
|
||||
nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
|
||||
endif
|
||||
if IA64
|
||||
nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
|
||||
endif
|
||||
if M32R
|
||||
nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
|
||||
endif
|
||||
if M68K
|
||||
nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
|
||||
endif
|
||||
if POWERPC
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
|
||||
endif
|
||||
if POWERPC_AIX
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
|
||||
endif
|
||||
if POWERPC_DARWIN
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
|
||||
endif
|
||||
if POWERPC_FREEBSD
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
|
||||
endif
|
||||
if ARM
|
||||
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
|
||||
endif
|
||||
if AVR32
|
||||
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
|
||||
endif
|
||||
if LIBFFI_CRIS
|
||||
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
|
||||
endif
|
||||
if FRV
|
||||
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
|
||||
endif
|
||||
if S390
|
||||
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
|
||||
endif
|
||||
if X86_64
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
endif
|
||||
if SH
|
||||
nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
|
||||
endif
|
||||
if SH64
|
||||
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
|
||||
endif
|
||||
if PA_LINUX
|
||||
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
|
||||
endif
|
||||
if PA_HPUX
|
||||
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
|
||||
endif
|
||||
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
|
||||
AM_CFLAGS = -Wall -g -fexceptions
|
||||
if FFI_DEBUG
|
||||
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
|
||||
# MSVC, it can link against the debug CRT.
|
||||
AM_CFLAGS += -DFFI_DEBUG
|
||||
else
|
||||
# Build opt.
|
||||
AM_CFLAGS += -O2
|
||||
endif
|
||||
|
||||
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
|
||||
|
||||
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
# No install-html or install-pdf support in automake yet
|
||||
.PHONY: install-html install-pdf
|
||||
install-html:
|
||||
install-pdf:
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,478 +0,0 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
|
||||
# defaults of its own if none are provided.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
save_CFLAGS=$CFLAGS
|
||||
AC_PROG_CC
|
||||
CFLAGS=$save_CFLAGS
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(mmap)
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
case "$host" in
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd* | amd64-*-openbsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
i?86-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-solaris2.1[[0-9]]*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-*)
|
||||
TARGET=X86; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
;;
|
||||
|
||||
sh-*-* | sh[[34]]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
;;
|
||||
|
||||
x86_64-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-cygwin* | x86_64-*-mingw*)
|
||||
TARGET=X86_WIN64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
|
||||
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
|
||||
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
|
||||
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
|
||||
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
|
||||
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
|
||||
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
|
||||
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
|
||||
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||||
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||||
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||||
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||||
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
|
||||
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
libffi_cv_as_cfi_pseudo_op, [
|
||||
libffi_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
[libffi_cv_as_cfi_pseudo_op=yes],
|
||||
[libffi_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
|
||||
if test x$TARGET = xSPARC; then
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
|
||||
libffi_cv_as_ascii_pseudo_op, [
|
||||
libffi_cv_as_ascii_pseudo_op=unknown
|
||||
# Check if we have .ascii
|
||||
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
|
||||
[libffi_cv_as_ascii_pseudo_op=yes],
|
||||
[libffi_cv_as_ascii_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .ascii.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .string pseudo-op support],
|
||||
libffi_cv_as_string_pseudo_op, [
|
||||
libffi_cv_as_string_pseudo_op=unknown
|
||||
# Check if we have .string
|
||||
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
|
||||
[libffi_cv_as_string_pseudo_op=yes],
|
||||
[libffi_cv_as_string_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .string.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86_WIN64; then
|
||||
LT_SYS_SYMBOL_USCORE
|
||||
if test "x$sys_symbol_underscore" = xyes; then
|
||||
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
*-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
echo '.section .eh_frame,"a",@unwind' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
|
||||
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
elif grep '.section.*eh_frame.*#alloc' conftest.c \
|
||||
| grep -v '#write' > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if grep '\.hidden.*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test x"$GCC" != x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
fi
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,196 +0,0 @@
|
||||
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to the flags needed for the .section .eh_frame directive. */
|
||||
#undef EH_FRAME_FLAGS
|
||||
|
||||
/* Define this if you want extra debugging. */
|
||||
#undef FFI_DEBUG
|
||||
|
||||
/* Cannot use malloc on this target, so, we revert to alternative means */
|
||||
#undef FFI_MMAP_EXEC_WRIT
|
||||
|
||||
/* Define this is you do not want support for the raw API. */
|
||||
#undef FFI_NO_RAW_API
|
||||
|
||||
/* Define this is you do not want support for aggregate types. */
|
||||
#undef FFI_NO_STRUCTS
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if your assembler supports .ascii. */
|
||||
#undef HAVE_AS_ASCII_PSEUDO_OP
|
||||
|
||||
/* Define if your assembler supports .cfi_* directives. */
|
||||
#undef HAVE_AS_CFI_PSEUDO_OP
|
||||
|
||||
/* Define if your assembler supports .register. */
|
||||
#undef HAVE_AS_REGISTER_PSEUDO_OP
|
||||
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs.
|
||||
*/
|
||||
#undef HAVE_AS_SPARC_UA_PCREL
|
||||
|
||||
/* Define if your assembler supports .string. */
|
||||
#undef HAVE_AS_STRING_PSEUDO_OP
|
||||
|
||||
/* Define if your assembler supports unwind section type. */
|
||||
#undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
|
||||
|
||||
/* Define if your assembler supports PC relative relocs. */
|
||||
#undef HAVE_AS_X86_PCREL
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define if __attribute__((visibility("hidden"))) is supported. */
|
||||
#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
#undef HAVE_MMAP_ANON
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
#undef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
#undef HAVE_MMAP_FILE
|
||||
|
||||
/* Define if .eh_frame sections should be read-only. */
|
||||
#undef HAVE_RO_EH_FRAME
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* The size of `double', as computed by sizeof. */
|
||||
#undef SIZEOF_DOUBLE
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_DOUBLE
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at runtime.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define this if you are using Purify and want to suppress spurious messages.
|
||||
*/
|
||||
#undef USING_PURIFY
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,504 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1998, 2008 Red Hat, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Forward declares. */
|
||||
static int vfp_type_p (ffi_type *);
|
||||
static void layout_vfp_args (ffi_cif *);
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
|
||||
The vfp_space parameter is the load area for VFP regs, the return
|
||||
value is cif->vfp_used (word bitset of VFP regs used for passing
|
||||
arguments). These are only used for the VFP hard-float ABI.
|
||||
*/
|
||||
int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
register unsigned int i, vi = 0;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*(void **) argp = ecif->rvalue;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0);
|
||||
i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
/* Allocated in VFP registers. */
|
||||
if (ecif->cif->abi == FFI_VFP
|
||||
&& vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg))
|
||||
{
|
||||
float* vfp_slot = vfp_space + ecif->cif->vfp_args[vi++];
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
*((float*)vfp_slot) = *((float*)*p_argv);
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
*((double*)vfp_slot) = *((double*)*p_argv);
|
||||
else
|
||||
memcpy(vfp_slot, *p_argv, (*p_arg)->size);
|
||||
p_argv++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Align if necessary */
|
||||
if (((*p_arg)->alignment - 1) & (unsigned) argp) {
|
||||
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
|
||||
}
|
||||
|
||||
if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||||
argp = (char *) ALIGN(argp, 4);
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
memcpy(argp, *p_argv, (*p_arg)->size);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
/* Indicate the VFP registers used. */
|
||||
return ecif->cif->vfp_used;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int type_code;
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
everywhere, but it is on some platforms, and it doesn't harm anything
|
||||
when it isn't needed. */
|
||||
cif->bytes = (cif->bytes + 7) & ~7;
|
||||
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags = (unsigned) FFI_TYPE_SINT64;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
if (cif->abi == FFI_VFP
|
||||
&& (type_code = vfp_type_p (cif->rtype)) != 0)
|
||||
{
|
||||
/* A Composite Type passed in VFP registers, either
|
||||
FFI_TYPE_STRUCT_VFP_FLOAT or FFI_TYPE_STRUCT_VFP_DOUBLE. */
|
||||
cif->flags = (unsigned) type_code;
|
||||
}
|
||||
else if (cif->rtype->size <= 4)
|
||||
/* A Composite Type not larger than 4 bytes is returned in r0. */
|
||||
cif->flags = (unsigned)FFI_TYPE_INT;
|
||||
else
|
||||
/* A Composite Type larger than 4 bytes, or whose size cannot
|
||||
be determined statically ... is stored in memory at an
|
||||
address passed [in r0]. */
|
||||
cif->flags = (unsigned)FFI_TYPE_STRUCT;
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Map out the register placements of VFP register args.
|
||||
The VFP hard-float calling conventions are slightly more sophisticated than
|
||||
the base calling conventions, so we do it here instead of in ffi_prep_args(). */
|
||||
if (cif->abi == FFI_VFP)
|
||||
layout_vfp_args (cif);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Prototypes for assembly functions, in sysv.S */
|
||||
extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
|
||||
extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT);
|
||||
int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
unsigned int temp;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->flags == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else if (small_struct)
|
||||
ecif.rvalue = &temp;
|
||||
else if (vfp_struct)
|
||||
{
|
||||
/* Largest case is double x 4. */
|
||||
ecif.rvalue = alloca(32);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
break;
|
||||
|
||||
case FFI_VFP:
|
||||
ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (small_struct)
|
||||
memcpy (rvalue, &temp, cif->rtype->size);
|
||||
else if (vfp_struct)
|
||||
memcpy (rvalue, ecif.rvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
/** private members **/
|
||||
|
||||
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
|
||||
void** args, ffi_cif* cif, float *vfp_stack);
|
||||
|
||||
void ffi_closure_SYSV (ffi_closure *);
|
||||
|
||||
void ffi_closure_VFP (ffi_closure *);
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int
|
||||
ffi_closure_SYSV_inner (closure, respp, args, vfp_args)
|
||||
ffi_closure *closure;
|
||||
void **respp;
|
||||
void *args;
|
||||
void *vfp_args;
|
||||
{
|
||||
// our various things...
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will re-set RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
|
||||
|
||||
(closure->fun) (cif, *respp, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
float *vfp_stack)
|
||||
/*@=exportheader@*/
|
||||
{
|
||||
register unsigned int i, vi = 0;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
if ( cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*rvalue = *(void **) argp;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = avalue;
|
||||
|
||||
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
size_t alignment;
|
||||
|
||||
if (cif->abi == FFI_VFP
|
||||
&& vi < cif->vfp_nargs && vfp_type_p (*p_arg))
|
||||
{
|
||||
*p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]);
|
||||
continue;
|
||||
}
|
||||
|
||||
alignment = (*p_arg)->alignment;
|
||||
if (alignment < 4)
|
||||
alignment = 4;
|
||||
/* Align if necessary */
|
||||
if ((alignment - 1) & (unsigned) argp) {
|
||||
argp = (char *) ALIGN(argp, alignment);
|
||||
}
|
||||
|
||||
z = (*p_arg)->size;
|
||||
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
|
||||
*p_argv = (void*) argp;
|
||||
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* How to make a trampoline. */
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
|
||||
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned char *insns = (unsigned char *)(CTX); \
|
||||
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
|
||||
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
|
||||
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
|
||||
*(unsigned int*) &__tramp[12] = __ctx; \
|
||||
*(unsigned int*) &__tramp[16] = __fun; \
|
||||
__clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping. */ \
|
||||
__clear_cache(insns, insns + 3 * sizeof (unsigned int)); \
|
||||
/* Clear instruction \
|
||||
mapping. */ \
|
||||
})
|
||||
|
||||
|
||||
/* the cif must already be prep'ed */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
void (*closure_func)(ffi_closure*) = NULL;
|
||||
|
||||
if (cif->abi == FFI_SYSV)
|
||||
closure_func = &ffi_closure_SYSV;
|
||||
else if (cif->abi == FFI_VFP)
|
||||
closure_func = &ffi_closure_VFP;
|
||||
else
|
||||
FFI_ASSERT (0);
|
||||
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
|
||||
closure_func, \
|
||||
codeloc);
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Below are routines for VFP hard-float support. */
|
||||
|
||||
static int rec_vfp_type_p (ffi_type *t, int *elt, int *elnum)
|
||||
{
|
||||
switch (t->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*elt = (int) t->type;
|
||||
*elnum = 1;
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT_VFP_FLOAT:
|
||||
*elt = FFI_TYPE_FLOAT;
|
||||
*elnum = t->size / sizeof (float);
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT_VFP_DOUBLE:
|
||||
*elt = FFI_TYPE_DOUBLE;
|
||||
*elnum = t->size / sizeof (double);
|
||||
return 1;
|
||||
|
||||
case FFI_TYPE_STRUCT:;
|
||||
{
|
||||
int base_elt = 0, total_elnum = 0;
|
||||
ffi_type **el = t->elements;
|
||||
while (*el)
|
||||
{
|
||||
int el_elt = 0, el_elnum = 0;
|
||||
if (! rec_vfp_type_p (*el, &el_elt, &el_elnum)
|
||||
|| (base_elt && base_elt != el_elt)
|
||||
|| total_elnum + el_elnum > 4)
|
||||
return 0;
|
||||
base_elt = el_elt;
|
||||
total_elnum += el_elnum;
|
||||
el++;
|
||||
}
|
||||
*elnum = total_elnum;
|
||||
*elt = base_elt;
|
||||
return 1;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vfp_type_p (ffi_type *t)
|
||||
{
|
||||
int elt, elnum;
|
||||
if (rec_vfp_type_p (t, &elt, &elnum))
|
||||
{
|
||||
if (t->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
if (elnum == 1)
|
||||
t->type = elt;
|
||||
else
|
||||
t->type = (elt == FFI_TYPE_FLOAT
|
||||
? FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
: FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
}
|
||||
return (int) t->type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
{
|
||||
int reg = cif->vfp_reg_free;
|
||||
int nregs = t->size / sizeof (float);
|
||||
int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| t->type == FFI_TYPE_FLOAT) ? 1 : 2);
|
||||
/* Align register number. */
|
||||
if ((reg & 1) && align == 2)
|
||||
reg++;
|
||||
while (reg + nregs <= 16)
|
||||
{
|
||||
int s, new_used = 0;
|
||||
for (s = reg; s < reg + nregs; s++)
|
||||
{
|
||||
new_used |= (1 << s);
|
||||
if (cif->vfp_used & (1 << s))
|
||||
{
|
||||
reg += align;
|
||||
goto next_reg;
|
||||
}
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
{
|
||||
reg += nregs;
|
||||
while (cif->vfp_used & (1 << reg))
|
||||
reg += 1;
|
||||
cif->vfp_reg_free = reg;
|
||||
}
|
||||
return;
|
||||
next_reg: ;
|
||||
}
|
||||
}
|
||||
|
||||
static void layout_vfp_args (ffi_cif *cif)
|
||||
{
|
||||
int i;
|
||||
/* Init VFP fields */
|
||||
cif->vfp_used = 0;
|
||||
cif->vfp_nargs = 0;
|
||||
cif->vfp_reg_free = 0;
|
||||
memset (cif->vfp_args, -1, 16); /* Init to -1. */
|
||||
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
ffi_type *t = cif->arg_types[i];
|
||||
if (vfp_type_p (t))
|
||||
place_vfp_arg (cif, t);
|
||||
}
|
||||
}
|
||||
@@ -1,466 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
#else
|
||||
#define CNAME(x) x
|
||||
#endif
|
||||
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
#define LSYM(x) .x
|
||||
#else
|
||||
#define LSYM(x) x
|
||||
#endif
|
||||
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
we can do. */
|
||||
@ This selects the minimum architecture level required.
|
||||
#define __ARM_ARCH__ 3
|
||||
|
||||
#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 4
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 5
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
|| defined(__ARM_ARCH_6M__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 6
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|
||||
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|
||||
|| defined(__ARM_ARCH_7EM__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 7
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__ >= 5
|
||||
# define call_reg(x) blx x
|
||||
#elif defined (__ARM_ARCH_4T__)
|
||||
# define call_reg(x) mov lr, pc ; bx x
|
||||
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
|
||||
# define __INTERWORKING__
|
||||
# endif
|
||||
#else
|
||||
# define call_reg(x) mov lr, pc ; mov pc, x
|
||||
#endif
|
||||
|
||||
/* Conditionally compile unwinder directives. */
|
||||
#ifdef __ARM_EABI__
|
||||
#define UNWIND
|
||||
#else
|
||||
#define UNWIND @
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.thumb
|
||||
.thumb_func
|
||||
ENTRY(\name)
|
||||
bx pc
|
||||
nop
|
||||
.arm
|
||||
UNWIND .fnstart
|
||||
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
||||
directly from other local arm routines. */
|
||||
_L__\name:
|
||||
.endm
|
||||
#else
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.arm
|
||||
ENTRY(\name)
|
||||
UNWIND .fnstart
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro RETLDM regs=, cond=, dirn=ia
|
||||
#if defined (__INTERWORKING__)
|
||||
.ifc "\regs",""
|
||||
ldr\cond lr, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, lr}
|
||||
.endif
|
||||
bx\cond lr
|
||||
#else
|
||||
.ifc "\regs",""
|
||||
ldr\cond pc, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, pc}
|
||||
.endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
|
||||
@ r0: fn
|
||||
@ r1: &ecif
|
||||
@ r2: cif->bytes
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
@ This assumes we are using gas.
|
||||
ARM_FUNC_START ffi_call_SYSV
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
mov fp, sp
|
||||
|
||||
UNWIND .setfp fp, sp
|
||||
|
||||
@ Make room for all of the new args.
|
||||
sub sp, fp, r2
|
||||
|
||||
@ Place all of the ffi_prep_args in position
|
||||
mov r0, sp
|
||||
@ r1 already set
|
||||
|
||||
@ Call ffi_prep_args(stack, &ecif)
|
||||
bl ffi_prep_args
|
||||
|
||||
@ move first 4 parameters in registers
|
||||
ldmia sp, {r0-r3}
|
||||
|
||||
@ and adjust stack
|
||||
sub lr, fp, sp @ cif->bytes == fp - sp
|
||||
ldr ip, [fp] @ load fn() in advance
|
||||
cmp lr, #16
|
||||
movhs lr, #16
|
||||
add sp, sp, lr
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL, assume no return value.
|
||||
cmp r2, #0
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return INT
|
||||
cmp r3, #FFI_TYPE_INT
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_FLOAT
|
||||
#endif
|
||||
streq r0, [r2]
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return INT64
|
||||
cmp r3, #FFI_TYPE_SINT64
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
stmeqia r2, {r0, r1}
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return FLOAT
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
stfeqs f0, [r2]
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return DOUBLE or LONGDOUBLE
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
stfeqd f0, [r2]
|
||||
#endif
|
||||
|
||||
LSYM(Lepilogue):
|
||||
RETLDM "r0-r3,fp"
|
||||
|
||||
.ffi_call_SYSV_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
|
||||
|
||||
|
||||
/*
|
||||
unsigned int FFI_HIDDEN
|
||||
ffi_closure_SYSV_inner (closure, respp, args)
|
||||
ffi_closure *closure;
|
||||
void **respp;
|
||||
void *args;
|
||||
*/
|
||||
|
||||
ARM_FUNC_START ffi_closure_SYSV
|
||||
UNWIND .pad #16
|
||||
add ip, sp, #16
|
||||
stmfd sp!, {ip, lr}
|
||||
UNWIND .save {r0, lr}
|
||||
add r2, sp, #8
|
||||
UNWIND .pad #16
|
||||
sub sp, sp, #16
|
||||
str sp, [sp, #8]
|
||||
add r1, sp, #8
|
||||
bl ffi_closure_SYSV_inner
|
||||
cmp r0, #FFI_TYPE_INT
|
||||
beq .Lretint
|
||||
|
||||
cmp r0, #FFI_TYPE_FLOAT
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretint
|
||||
#else
|
||||
beq .Lretfloat
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_DOUBLE
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretlonglong
|
||||
#else
|
||||
beq .Lretdouble
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_LONGDOUBLE
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretlonglong
|
||||
#else
|
||||
beq .Lretlongdouble
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_SINT64
|
||||
beq .Lretlonglong
|
||||
.Lclosure_epilogue:
|
||||
add sp, sp, #16
|
||||
ldmfd sp, {sp, pc}
|
||||
.Lretint:
|
||||
ldr r0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretlonglong:
|
||||
ldr r0, [sp]
|
||||
ldr r1, [sp, #4]
|
||||
b .Lclosure_epilogue
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
.Lretfloat:
|
||||
ldfs f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretdouble:
|
||||
ldfd f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretlongdouble:
|
||||
ldfd f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
#endif
|
||||
|
||||
.ffi_closure_SYSV_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
||||
|
||||
|
||||
/* Below are VFP hard-float ABI call and closure implementations.
|
||||
Add VFP FPU directive here. */
|
||||
.fpu vfp
|
||||
|
||||
@ r0: fn
|
||||
@ r1: &ecif
|
||||
@ r2: cif->bytes
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
ARM_FUNC_START ffi_call_VFP
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
mov fp, sp
|
||||
UNWIND .setfp fp, sp
|
||||
|
||||
@ Make room for all of the new args.
|
||||
sub sp, sp, r2
|
||||
|
||||
@ Make room for loading VFP args
|
||||
sub sp, sp, #64
|
||||
|
||||
@ Place all of the ffi_prep_args in position
|
||||
mov r0, sp
|
||||
@ r1 already set
|
||||
sub r2, fp, #64 @ VFP scratch space
|
||||
|
||||
@ Call ffi_prep_args(stack, &ecif, vfp_space)
|
||||
bl ffi_prep_args
|
||||
|
||||
@ Load VFP register args if needed
|
||||
cmp r0, #0
|
||||
beq LSYM(Lbase_args)
|
||||
|
||||
@ Load only d0 if possible
|
||||
cmp r0, #3
|
||||
sub ip, fp, #64
|
||||
flddle d0, [ip]
|
||||
fldmiadgt ip, {d0-d7}
|
||||
|
||||
LSYM(Lbase_args):
|
||||
@ move first 4 parameters in registers
|
||||
ldmia sp, {r0-r3}
|
||||
|
||||
@ and adjust stack
|
||||
sub lr, ip, sp @ cif->bytes == (fp - 64) - sp
|
||||
ldr ip, [fp] @ load fn() in advance
|
||||
cmp lr, #16
|
||||
movhs lr, #16
|
||||
add sp, sp, lr
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for
|
||||
@ the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL,
|
||||
@ assume no return value.
|
||||
cmp r2, #0
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_INT
|
||||
streq r0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_SINT64
|
||||
stmeqia r2, {r0, r1}
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
fstseq s0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
fstdeq d0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
cmpne r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
fstmiadeq r2, {d0-d3}
|
||||
|
||||
LSYM(Lepilogue_vfp):
|
||||
RETLDM "r0-r3,fp"
|
||||
|
||||
.ffi_call_VFP_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
|
||||
|
||||
|
||||
ARM_FUNC_START ffi_closure_VFP
|
||||
fstmfdd sp!, {d0-d7}
|
||||
@ r0-r3, then d0-d7
|
||||
UNWIND .pad #80
|
||||
add ip, sp, #80
|
||||
stmfd sp!, {ip, lr}
|
||||
UNWIND .save {r0, lr}
|
||||
add r2, sp, #72
|
||||
add r3, sp, #8
|
||||
UNWIND .pad #72
|
||||
sub sp, sp, #72
|
||||
str sp, [sp, #64]
|
||||
add r1, sp, #64
|
||||
bl ffi_closure_SYSV_inner
|
||||
|
||||
cmp r0, #FFI_TYPE_INT
|
||||
beq .Lretint_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_FLOAT
|
||||
beq .Lretfloat_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_DOUBLE
|
||||
cmpne r0, #FFI_TYPE_LONGDOUBLE
|
||||
beq .Lretdouble_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_SINT64
|
||||
beq .Lretlonglong_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
beq .Lretfloat_struct_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
beq .Lretdouble_struct_vfp
|
||||
|
||||
.Lclosure_epilogue_vfp:
|
||||
add sp, sp, #72
|
||||
ldmfd sp, {sp, pc}
|
||||
|
||||
.Lretfloat_vfp:
|
||||
flds s0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretdouble_vfp:
|
||||
fldd d0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretint_vfp:
|
||||
ldr r0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretlonglong_vfp:
|
||||
ldmia sp, {r0, r1}
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretfloat_struct_vfp:
|
||||
fldmiad sp, {d0-d1}
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretdouble_struct_vfp:
|
||||
fldmiad sp, {d0-d3}
|
||||
b .Lclosure_epilogue_vfp
|
||||
|
||||
.ffi_closure_VFP_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
@@ -1,610 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
closures.c - Copyright (c) 2007 Red Hat, Inc.
|
||||
Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
|
||||
|
||||
Code to allocate and deallocate memory for closures.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if defined __linux__ && !defined _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#ifndef FFI_MMAP_EXEC_WRIT
|
||||
# if __gnu_linux__
|
||||
/* This macro indicates it may be forbidden to map anonymous memory
|
||||
with both write and execute permission. Code compiled when this
|
||||
option is defined will attempt to map such pages once, but if it
|
||||
fails, it falls back to creating a temporary file in a writable and
|
||||
executable filesystem and mapping pages from it into separate
|
||||
locations in the virtual memory space, one location writable and
|
||||
another executable. */
|
||||
# define FFI_MMAP_EXEC_WRIT 1
|
||||
# define HAVE_MNTENT 1
|
||||
# endif
|
||||
# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
|
||||
/* Windows systems may have Data Execution Protection (DEP) enabled,
|
||||
which requires the use of VirtualMalloc/VirtualFree to alloc/free
|
||||
executable memory. */
|
||||
# define FFI_MMAP_EXEC_WRIT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
|
||||
# ifdef __linux__
|
||||
/* When defined to 1 check for SELinux and if SELinux is active,
|
||||
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
|
||||
might cause audit messages. */
|
||||
# define FFI_MMAP_EXEC_SELINUX 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
# if FFI_MMAP_EXEC_WRIT
|
||||
|
||||
#define USE_LOCKS 1
|
||||
#define USE_DL_PREFIX 1
|
||||
#ifdef __GNUC__
|
||||
#ifndef USE_BUILTIN_FFS
|
||||
#define USE_BUILTIN_FFS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* We need to use mmap, not sbrk. */
|
||||
#define HAVE_MORECORE 0
|
||||
|
||||
/* We could, in theory, support mremap, but it wouldn't buy us anything. */
|
||||
#define HAVE_MREMAP 0
|
||||
|
||||
/* We have no use for this, so save some code and data. */
|
||||
#define NO_MALLINFO 1
|
||||
|
||||
/* We need all allocations to be in regular segments, otherwise we
|
||||
lose track of the corresponding code address. */
|
||||
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
|
||||
|
||||
/* Don't allocate more than a page unless needed. */
|
||||
#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
/* Don't release single pages, to avoid a worst-case scenario of
|
||||
continuously allocating and releasing single pages, but release
|
||||
pairs of pages, which should do just as well given that allocations
|
||||
are likely to be small. */
|
||||
#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#if !defined(X86_WIN32) && !defined(X86_WIN64)
|
||||
#ifdef HAVE_MNTENT
|
||||
#include <mntent.h>
|
||||
#endif /* HAVE_MNTENT */
|
||||
#include <sys/param.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* We don't want sys/mman.h to be included after we redefine mmap and
|
||||
dlmunmap. */
|
||||
#include <sys/mman.h>
|
||||
#define LACKS_SYS_MMAN_H 1
|
||||
|
||||
#if FFI_MMAP_EXEC_SELINUX
|
||||
#include <sys/statfs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int selinux_enabled = -1;
|
||||
|
||||
static int
|
||||
selinux_enabled_check (void)
|
||||
{
|
||||
struct statfs sfs;
|
||||
FILE *f;
|
||||
char *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (statfs ("/selinux", &sfs) >= 0
|
||||
&& (unsigned int) sfs.f_type == 0xf97cff8cU)
|
||||
return 1;
|
||||
f = fopen ("/proc/mounts", "r");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
while (getline (&buf, &len, f) >= 0)
|
||||
{
|
||||
char *p = strchr (buf, ' ');
|
||||
if (p == NULL)
|
||||
break;
|
||||
p = strchr (p + 1, ' ');
|
||||
if (p == NULL)
|
||||
break;
|
||||
if (strncmp (p + 1, "selinuxfs ", 10) == 0)
|
||||
{
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
|
||||
: (selinux_enabled = selinux_enabled_check ()))
|
||||
|
||||
#else
|
||||
|
||||
#define is_selinux_enabled() 0
|
||||
|
||||
#endif /* !FFI_MMAP_EXEC_SELINUX */
|
||||
|
||||
#elif defined (__CYGWIN__)
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* Cygwin is Linux-like, but not quite that Linux-like. */
|
||||
#define is_selinux_enabled() 0
|
||||
|
||||
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
|
||||
|
||||
/* Declare all functions defined in dlmalloc.c as static. */
|
||||
static void *dlmalloc(size_t);
|
||||
static void dlfree(void*);
|
||||
static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
|
||||
static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
|
||||
static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
|
||||
static void *dlvalloc(size_t) MAYBE_UNUSED;
|
||||
static int dlmallopt(int, int) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
|
||||
static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
|
||||
static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
|
||||
static void *dlpvalloc(size_t) MAYBE_UNUSED;
|
||||
static int dlmalloc_trim(size_t) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
|
||||
static void dlmalloc_stats(void) MAYBE_UNUSED;
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
|
||||
/* Use these for mmap and munmap within dlmalloc.c. */
|
||||
static void *dlmmap(void *, size_t, int, int, int, off_t);
|
||||
static int dlmunmap(void *, size_t);
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
|
||||
|
||||
#define mmap dlmmap
|
||||
#define munmap dlmunmap
|
||||
|
||||
#include "dlmalloc.c"
|
||||
|
||||
#undef mmap
|
||||
#undef munmap
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__)
|
||||
|
||||
/* A mutex used to synchronize access to *exec* variables in this file. */
|
||||
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* A file descriptor of a temporary file from which we'll map
|
||||
executable pages. */
|
||||
static int execfd = -1;
|
||||
|
||||
/* The amount of space already allocated from the temporary file. */
|
||||
static size_t execsize = 0;
|
||||
|
||||
/* Open a temporary file name, and immediately unlink it. */
|
||||
static int
|
||||
open_temp_exec_file_name (char *name)
|
||||
{
|
||||
int fd = mkstemp (name);
|
||||
|
||||
if (fd != -1)
|
||||
unlink (name);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Open a temporary file in the named directory. */
|
||||
static int
|
||||
open_temp_exec_file_dir (const char *dir)
|
||||
{
|
||||
static const char suffix[] = "/ffiXXXXXX";
|
||||
int lendir = strlen (dir);
|
||||
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
|
||||
|
||||
if (!tempname)
|
||||
return -1;
|
||||
|
||||
memcpy (tempname, dir, lendir);
|
||||
memcpy (tempname + lendir, suffix, sizeof (suffix));
|
||||
|
||||
return open_temp_exec_file_name (tempname);
|
||||
}
|
||||
|
||||
/* Open a temporary file in the directory in the named environment
|
||||
variable. */
|
||||
static int
|
||||
open_temp_exec_file_env (const char *envvar)
|
||||
{
|
||||
const char *value = getenv (envvar);
|
||||
|
||||
if (!value)
|
||||
return -1;
|
||||
|
||||
return open_temp_exec_file_dir (value);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MNTENT
|
||||
/* Open a temporary file in an executable and writable mount point
|
||||
listed in the mounts file. Subsequent calls with the same mounts
|
||||
keep searching for mount points in the same file. Providing NULL
|
||||
as the mounts file closes the file. */
|
||||
static int
|
||||
open_temp_exec_file_mnt (const char *mounts)
|
||||
{
|
||||
static const char *last_mounts;
|
||||
static FILE *last_mntent;
|
||||
|
||||
if (mounts != last_mounts)
|
||||
{
|
||||
if (last_mntent)
|
||||
endmntent (last_mntent);
|
||||
|
||||
last_mounts = mounts;
|
||||
|
||||
if (mounts)
|
||||
last_mntent = setmntent (mounts, "r");
|
||||
else
|
||||
last_mntent = NULL;
|
||||
}
|
||||
|
||||
if (!last_mntent)
|
||||
return -1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int fd;
|
||||
struct mntent mnt;
|
||||
char buf[MAXPATHLEN * 3];
|
||||
|
||||
if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (hasmntopt (&mnt, "ro")
|
||||
|| hasmntopt (&mnt, "noexec")
|
||||
|| access (mnt.mnt_dir, W_OK))
|
||||
continue;
|
||||
|
||||
fd = open_temp_exec_file_dir (mnt.mnt_dir);
|
||||
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_MNTENT */
|
||||
|
||||
/* Instructions to look for a location to hold a temporary file that
|
||||
can be mapped in for execution. */
|
||||
static struct
|
||||
{
|
||||
int (*func)(const char *);
|
||||
const char *arg;
|
||||
int repeat;
|
||||
} open_temp_exec_file_opts[] = {
|
||||
{ open_temp_exec_file_env, "TMPDIR", 0 },
|
||||
{ open_temp_exec_file_dir, "/tmp", 0 },
|
||||
{ open_temp_exec_file_dir, "/var/tmp", 0 },
|
||||
{ open_temp_exec_file_dir, "/dev/shm", 0 },
|
||||
{ open_temp_exec_file_env, "HOME", 0 },
|
||||
#ifdef HAVE_MNTENT
|
||||
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
|
||||
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
|
||||
#endif /* HAVE_MNTENT */
|
||||
};
|
||||
|
||||
/* Current index into open_temp_exec_file_opts. */
|
||||
static int open_temp_exec_file_opts_idx = 0;
|
||||
|
||||
/* Reset a current multi-call func, then advances to the next entry.
|
||||
If we're at the last, go back to the first and return nonzero,
|
||||
otherwise return zero. */
|
||||
static int
|
||||
open_temp_exec_file_opts_next (void)
|
||||
{
|
||||
if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
|
||||
open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
|
||||
|
||||
open_temp_exec_file_opts_idx++;
|
||||
if (open_temp_exec_file_opts_idx
|
||||
== (sizeof (open_temp_exec_file_opts)
|
||||
/ sizeof (*open_temp_exec_file_opts)))
|
||||
{
|
||||
open_temp_exec_file_opts_idx = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return a file descriptor of a temporary zero-sized file in a
|
||||
writable and exexutable filesystem. */
|
||||
static int
|
||||
open_temp_exec_file (void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
do
|
||||
{
|
||||
fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
|
||||
(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
|
||||
|
||||
if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
|
||||
|| fd == -1)
|
||||
{
|
||||
if (open_temp_exec_file_opts_next ())
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (fd == -1);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Map in a chunk of memory from the temporary exec file into separate
|
||||
locations in the virtual memory address space, one writable and one
|
||||
executable. Returns the address of the writable portion, after
|
||||
storing an offset to the corresponding executable portion at the
|
||||
last word of the requested chunk. */
|
||||
static void *
|
||||
dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (execfd == -1)
|
||||
{
|
||||
open_temp_exec_file_opts_idx = 0;
|
||||
retry_open:
|
||||
execfd = open_temp_exec_file ();
|
||||
if (execfd == -1)
|
||||
return MFAIL;
|
||||
}
|
||||
|
||||
offset = execsize;
|
||||
|
||||
if (ftruncate (execfd, offset + length))
|
||||
return MFAIL;
|
||||
|
||||
flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
|
||||
flags |= MAP_SHARED;
|
||||
|
||||
ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
|
||||
flags, execfd, offset);
|
||||
if (ptr == MFAIL)
|
||||
{
|
||||
if (!offset)
|
||||
{
|
||||
close (execfd);
|
||||
goto retry_open;
|
||||
}
|
||||
ftruncate (execfd, offset);
|
||||
return MFAIL;
|
||||
}
|
||||
else if (!offset
|
||||
&& open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
|
||||
open_temp_exec_file_opts_next ();
|
||||
|
||||
start = mmap (start, length, prot, flags, execfd, offset);
|
||||
|
||||
if (start == MFAIL)
|
||||
{
|
||||
munmap (ptr, length);
|
||||
ftruncate (execfd, offset);
|
||||
return start;
|
||||
}
|
||||
|
||||
mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
|
||||
|
||||
execsize += length;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Map in a writable and executable chunk of memory if possible.
|
||||
Failing that, fall back to dlmmap_locked. */
|
||||
static void *
|
||||
dlmmap (void *start, size_t length, int prot,
|
||||
int flags, int fd, off_t offset)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
assert (start == NULL && length % malloc_getpagesize == 0
|
||||
&& prot == (PROT_READ | PROT_WRITE)
|
||||
&& flags == (MAP_PRIVATE | MAP_ANONYMOUS)
|
||||
&& fd == -1 && offset == 0);
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
printf ("mapping in %zi\n", length);
|
||||
#endif
|
||||
|
||||
if (execfd == -1 && !is_selinux_enabled ())
|
||||
{
|
||||
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
|
||||
|
||||
if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
|
||||
/* Cool, no need to mess with separate segments. */
|
||||
return ptr;
|
||||
|
||||
/* If MREMAP_DUP is ever introduced and implemented, try mmap
|
||||
with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
|
||||
MREMAP_DUP and prot at this point. */
|
||||
}
|
||||
|
||||
if (execsize == 0 || execfd == -1)
|
||||
{
|
||||
pthread_mutex_lock (&open_temp_exec_file_mutex);
|
||||
ptr = dlmmap_locked (start, length, prot, flags, offset);
|
||||
pthread_mutex_unlock (&open_temp_exec_file_mutex);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return dlmmap_locked (start, length, prot, flags, offset);
|
||||
}
|
||||
|
||||
/* Release memory at the given address, as well as the corresponding
|
||||
executable page if it's separate. */
|
||||
static int
|
||||
dlmunmap (void *start, size_t length)
|
||||
{
|
||||
/* We don't bother decreasing execsize or truncating the file, since
|
||||
we can't quite tell whether we're unmapping the end of the file.
|
||||
We don't expect frequent deallocation anyway. If we did, we
|
||||
could locate pages in the file by writing to the pages being
|
||||
deallocated and checking that the file contents change.
|
||||
Yuck. */
|
||||
msegmentptr seg = segment_holding (gm, start);
|
||||
void *code;
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
printf ("unmapping %zi\n", length);
|
||||
#endif
|
||||
|
||||
if (seg && (code = add_segment_exec_offset (start, seg)) != start)
|
||||
{
|
||||
int ret = munmap (code, length);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return munmap (start, length);
|
||||
}
|
||||
|
||||
#if FFI_CLOSURE_FREE_CODE
|
||||
/* Return segment holding given code address. */
|
||||
static msegmentptr
|
||||
segment_holding_code (mstate m, char* addr)
|
||||
{
|
||||
msegmentptr sp = &m->seg;
|
||||
for (;;) {
|
||||
if (addr >= add_segment_exec_offset (sp->base, sp)
|
||||
&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
|
||||
return sp;
|
||||
if ((sp = sp->next) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) */
|
||||
|
||||
/* Allocate a chunk of memory with the given size. Returns a pointer
|
||||
to the writable address, and sets *CODE to the executable
|
||||
corresponding virtual address. */
|
||||
void *
|
||||
ffi_closure_alloc (size_t size, void **code)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (!code)
|
||||
return NULL;
|
||||
|
||||
ptr = dlmalloc (size);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
msegmentptr seg = segment_holding (gm, ptr);
|
||||
|
||||
*code = add_segment_exec_offset (ptr, seg);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Release a chunk of memory allocated with ffi_closure_alloc. If
|
||||
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
|
||||
writable or the executable address given. Otherwise, only the
|
||||
writable address can be provided here. */
|
||||
void
|
||||
ffi_closure_free (void *ptr)
|
||||
{
|
||||
#if FFI_CLOSURE_FREE_CODE
|
||||
msegmentptr seg = segment_holding_code (gm, ptr);
|
||||
|
||||
if (seg)
|
||||
ptr = sub_segment_exec_offset (ptr, seg);
|
||||
#endif
|
||||
|
||||
dlfree (ptr);
|
||||
}
|
||||
|
||||
|
||||
#if FFI_CLOSURE_TEST
|
||||
/* Do some internal sanity testing to make sure allocation and
|
||||
deallocation of pages are working as intended. */
|
||||
int main ()
|
||||
{
|
||||
void *p[3];
|
||||
#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
|
||||
#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
|
||||
GET (0, malloc_getpagesize / 2);
|
||||
GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
|
||||
PUT (1);
|
||||
GET (1, 2 * malloc_getpagesize);
|
||||
GET (2, malloc_getpagesize / 2);
|
||||
PUT (1);
|
||||
PUT (0);
|
||||
PUT (2);
|
||||
return 0;
|
||||
}
|
||||
#endif /* FFI_CLOSURE_TEST */
|
||||
# else /* ! FFI_MMAP_EXEC_WRIT */
|
||||
|
||||
/* On many systems, memory returned by malloc is writable and
|
||||
executable, so just use it. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *
|
||||
ffi_closure_alloc (size_t size, void **code)
|
||||
{
|
||||
if (!code)
|
||||
return NULL;
|
||||
|
||||
return *code = malloc (size);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_closure_free (void *ptr)
|
||||
{
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
# endif /* ! FFI_MMAP_EXEC_WRIT */
|
||||
#endif /* FFI_CLOSURES */
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,421 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi @VERSION@ - Copyright (c) 2011 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
The basic API is described in the README file.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing
|
||||
and unpacking on architectures for which it can be avoided.
|
||||
|
||||
The closure API allows interpreted functions to be packaged up
|
||||
inside a C function pointer, so that they can be called as C functions,
|
||||
with no understanding on the client side that they are interpreted.
|
||||
It can also be used in other cases in which it is necessary to package
|
||||
up a user specified parameter and a function pointer as a single
|
||||
function pointer.
|
||||
|
||||
The closure API must be implemented in order to get its functionality,
|
||||
e.g. for use by gij. Routines are provided to emulate the raw API
|
||||
if the underlying platform doesn't allow faster implementation.
|
||||
|
||||
More details on the raw and cloure API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef @TARGET@
|
||||
#define @TARGET@
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t */
|
||||
/* can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c */
|
||||
extern ffi_type ffi_type_void;
|
||||
extern ffi_type ffi_type_uint8;
|
||||
extern ffi_type ffi_type_sint8;
|
||||
extern ffi_type ffi_type_uint16;
|
||||
extern ffi_type ffi_type_sint16;
|
||||
extern ffi_type ffi_type_uint32;
|
||||
extern ffi_type ffi_type_sint32;
|
||||
extern ffi_type ffi_type_uint64;
|
||||
extern ffi_type ffi_type_sint64;
|
||||
extern ffi_type ffi_type_float;
|
||||
extern ffi_type ffi_type_double;
|
||||
extern ffi_type ffi_type_pointer;
|
||||
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
extern ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef unsigned FFI_TYPE;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter */
|
||||
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
|
||||
/* longs and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
#ifdef __GNUC__
|
||||
} ffi_closure __attribute__((aligned (8)));
|
||||
#else
|
||||
} ffi_closure;
|
||||
#endif
|
||||
|
||||
void *ffi_closure_alloc (size_t size, void **code);
|
||||
void ffi_closure_free (void *);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
/* Useful for eliminating compiler warnings */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks) */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_POINTER
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,356 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Cloned from raw_api.c
|
||||
|
||||
Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
|
||||
Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
|
||||
|
||||
$Id $
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* This defines a Java- and 64-bit specific variant of the raw API. */
|
||||
/* It assumes that "raw" argument blocks look like Java stacks on a */
|
||||
/* 64-bit machine. Arguments that can be stored in a single stack */
|
||||
/* stack slots (longs, doubles) occupy 128 bits, but only the first */
|
||||
/* 64 bits are actually used. */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
|
||||
|
||||
size_t
|
||||
ffi_java_raw_size (ffi_cif *cif)
|
||||
{
|
||||
size_t result = 0;
|
||||
int i;
|
||||
|
||||
ffi_type **at = cif->arg_types;
|
||||
|
||||
for (i = cif->nargs-1; i >= 0; i--, at++)
|
||||
{
|
||||
switch((*at) -> type) {
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
result += 2 * FFI_SIZEOF_JAVA_RAW;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* No structure parameters in Java. */
|
||||
abort();
|
||||
default:
|
||||
result += FFI_SIZEOF_JAVA_RAW;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
|
||||
{
|
||||
unsigned i;
|
||||
ffi_type **tp = cif->arg_types;
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
|
||||
for (i = 0; i < cif->nargs; i++, tp++, args++)
|
||||
{
|
||||
switch ((*tp)->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
*args = (void*) ((char*)(raw++) + 3);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT16:
|
||||
*args = (void*) ((char*)(raw++) + 2);
|
||||
break;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 8
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*args = (void *)raw;
|
||||
raw += 2;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
*args = (void*) &(raw++)->ptr;
|
||||
break;
|
||||
|
||||
default:
|
||||
*args = raw;
|
||||
raw +=
|
||||
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* WORDS_BIGENDIAN */
|
||||
|
||||
#if !PDP
|
||||
|
||||
/* then assume little endian */
|
||||
for (i = 0; i < cif->nargs; i++, tp++, args++)
|
||||
{
|
||||
#if FFI_SIZEOF_JAVA_RAW == 8
|
||||
switch((*tp)->type) {
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*args = (void*) raw;
|
||||
raw += 2;
|
||||
break;
|
||||
default:
|
||||
*args = (void*) raw++;
|
||||
}
|
||||
#else /* FFI_SIZEOF_JAVA_RAW != 8 */
|
||||
*args = (void*) raw;
|
||||
raw +=
|
||||
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
|
||||
#endif /* FFI_SIZEOF_JAVA_RAW == 8 */
|
||||
}
|
||||
|
||||
#else
|
||||
#error "pdp endian not supported"
|
||||
#endif /* ! PDP */
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
}
|
||||
|
||||
void
|
||||
ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
|
||||
{
|
||||
unsigned i;
|
||||
ffi_type **tp = cif->arg_types;
|
||||
|
||||
for (i = 0; i < cif->nargs; i++, tp++, args++)
|
||||
{
|
||||
switch ((*tp)->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(UINT32*)(raw++) = *(UINT8*) (*args);
|
||||
#else
|
||||
(raw++)->uint = *(UINT8*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT8:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(SINT32*)(raw++) = *(SINT8*) (*args);
|
||||
#else
|
||||
(raw++)->sint = *(SINT8*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(UINT32*)(raw++) = *(UINT16*) (*args);
|
||||
#else
|
||||
(raw++)->uint = *(UINT16*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(SINT32*)(raw++) = *(SINT16*) (*args);
|
||||
#else
|
||||
(raw++)->sint = *(SINT16*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT32:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(UINT32*)(raw++) = *(UINT32*) (*args);
|
||||
#else
|
||||
(raw++)->uint = *(UINT32*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT32:
|
||||
#if WORDS_BIGENDIAN
|
||||
*(SINT32*)(raw++) = *(SINT32*) (*args);
|
||||
#else
|
||||
(raw++)->sint = *(SINT32*) (*args);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
(raw++)->flt = *(FLOAT32*) (*args);
|
||||
break;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 8
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
raw->uint = *(UINT64*) (*args);
|
||||
raw += 2;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
(raw++)->ptr = **(void***) args;
|
||||
break;
|
||||
|
||||
default:
|
||||
#if FFI_SIZEOF_JAVA_RAW == 8
|
||||
FFI_ASSERT(0); /* Should have covered all cases */
|
||||
#else
|
||||
memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
|
||||
raw +=
|
||||
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
static void
|
||||
ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
|
||||
{
|
||||
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
*(UINT64 *)rvalue <<= 32;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_INT:
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4
|
||||
case FFI_TYPE_POINTER:
|
||||
#endif
|
||||
*(SINT64 *)rvalue <<= 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
|
||||
{
|
||||
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
*(UINT64 *)rvalue >>= 32;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_INT:
|
||||
*(SINT64 *)rvalue >>= 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This is a generic definition of ffi_raw_call, to be used if the
|
||||
* native system does not provide a machine-specific implementation.
|
||||
* Having this, allows code to be written for the raw API, without
|
||||
* the need for system-specific code to handle input in that format;
|
||||
* these following couple of functions will handle the translation forth
|
||||
* and back automatically. */
|
||||
|
||||
void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
ffi_java_raw *raw)
|
||||
{
|
||||
void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
ffi_java_raw_to_ptrarray (cif, raw, avalue);
|
||||
ffi_call (cif, fn, rvalue, avalue);
|
||||
ffi_java_rvalue_to_raw (cif, rvalue);
|
||||
}
|
||||
|
||||
#if FFI_CLOSURES /* base system provides closures */
|
||||
|
||||
static void
|
||||
ffi_java_translate_args (ffi_cif *cif, void *rvalue,
|
||||
void **avalue, void *user_data)
|
||||
{
|
||||
ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
|
||||
ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
|
||||
|
||||
ffi_java_ptrarray_to_raw (cif, avalue, raw);
|
||||
(*cl->fun) (cif, rvalue, raw, cl->user_data);
|
||||
ffi_java_raw_to_rvalue (cif, rvalue);
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
ffi_status status;
|
||||
|
||||
status = ffi_prep_closure_loc ((ffi_closure*) cl,
|
||||
cif,
|
||||
&ffi_java_translate_args,
|
||||
codeloc,
|
||||
codeloc);
|
||||
if (status == FFI_OK)
|
||||
{
|
||||
cl->fun = fun;
|
||||
cl->user_data = user_data;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Again, here is the generic version of ffi_prep_raw_closure, which
|
||||
* will install an intermediate "hub" for translation of arguments from
|
||||
* the pointer-array format, to the raw format */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data)
|
||||
{
|
||||
return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
|
||||
}
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
#endif /* !FFI_NATIVE_RAW_API */
|
||||
#endif /* !FFI_NO_RAW_API */
|
||||
@@ -1,242 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for MIPS.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifdef linux
|
||||
# include <asm/sgidefs.h>
|
||||
#elif defined(__rtems__)
|
||||
/*
|
||||
* Subprogram calling convention - copied from sgidefs.h
|
||||
*/
|
||||
#define _MIPS_SIM_ABI32 1
|
||||
#define _MIPS_SIM_NABI32 2
|
||||
#define _MIPS_SIM_ABI64 3
|
||||
#else
|
||||
# include <sgidefs.h>
|
||||
#endif
|
||||
|
||||
# ifndef _ABIN32
|
||||
# define _ABIN32 _MIPS_SIM_NABI32
|
||||
# endif
|
||||
# ifndef _ABI64
|
||||
# define _ABI64 _MIPS_SIM_ABI64
|
||||
# endif
|
||||
# ifndef _ABIO32
|
||||
# define _ABIO32 _MIPS_SIM_ABI32
|
||||
# endif
|
||||
|
||||
#if !defined(_MIPS_SIM)
|
||||
-- something is very wrong --
|
||||
#else
|
||||
# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
|
||||
# define FFI_MIPS_N32
|
||||
# else
|
||||
# if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
|
||||
# define FFI_MIPS_O32
|
||||
# else
|
||||
-- this is an unsupported platform --
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
#else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# if _MIPS_SIM == _ABIN32
|
||||
# define FFI_SIZEOF_JAVA_RAW 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define FFI_FLAG_BITS 2
|
||||
|
||||
/* SGI's strange assembler requires that we multiply by 4 rather
|
||||
than shift left by FFI_FLAG_BITS */
|
||||
|
||||
#define FFI_ARGS_D FFI_TYPE_DOUBLE
|
||||
#define FFI_ARGS_F FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
|
||||
#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
|
||||
#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
|
||||
|
||||
/* Needed for N32 structure returns */
|
||||
#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8
|
||||
#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
|
||||
|
||||
#if 0
|
||||
/* The SGI assembler can't handle this.. */
|
||||
#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
|
||||
/* (and so on) */
|
||||
#else
|
||||
/* ...so we calculate these by hand! */
|
||||
#define FFI_TYPE_STRUCT_D 61
|
||||
#define FFI_TYPE_STRUCT_F 45
|
||||
#define FFI_TYPE_STRUCT_DD 253
|
||||
#define FFI_TYPE_STRUCT_FF 173
|
||||
#define FFI_TYPE_STRUCT_FD 237
|
||||
#define FFI_TYPE_STRUCT_DF 189
|
||||
#define FFI_TYPE_STRUCT_SMALL 93
|
||||
#define FFI_TYPE_STRUCT_SMALL2 109
|
||||
|
||||
/* and for n32 soft float, add 16 * 2^4 */
|
||||
#define FFI_TYPE_STRUCT_D_SOFT 317
|
||||
#define FFI_TYPE_STRUCT_F_SOFT 301
|
||||
#define FFI_TYPE_STRUCT_DD_SOFT 509
|
||||
#define FFI_TYPE_STRUCT_FF_SOFT 429
|
||||
#define FFI_TYPE_STRUCT_FD_SOFT 493
|
||||
#define FFI_TYPE_STRUCT_DF_SOFT 445
|
||||
#define FFI_TYPE_STRUCT_SOFT 16
|
||||
#endif
|
||||
|
||||
#ifdef LIBFFI_ASM
|
||||
#define v0 $2
|
||||
#define v1 $3
|
||||
#define a0 $4
|
||||
#define a1 $5
|
||||
#define a2 $6
|
||||
#define a3 $7
|
||||
#define a4 $8
|
||||
#define a5 $9
|
||||
#define a6 $10
|
||||
#define a7 $11
|
||||
#define t0 $8
|
||||
#define t1 $9
|
||||
#define t2 $10
|
||||
#define t3 $11
|
||||
#define t4 $12
|
||||
#define t5 $13
|
||||
#define t6 $14
|
||||
#define t7 $15
|
||||
#define t8 $24
|
||||
#define t9 $25
|
||||
#define ra $31
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
# define REG_L lw
|
||||
# define REG_S sw
|
||||
# define SUBU subu
|
||||
# define ADDU addu
|
||||
# define SRL srl
|
||||
# define LI li
|
||||
#else /* !FFI_MIPS_O32 */
|
||||
# define REG_L ld
|
||||
# define REG_S sd
|
||||
# define SUBU dsubu
|
||||
# define ADDU daddu
|
||||
# define SRL dsrl
|
||||
# define LI dli
|
||||
# if (_MIPS_SIM==_ABI64)
|
||||
# define LA dla
|
||||
# define EH_FRAME_ALIGN 3
|
||||
# define FDE_ADDR_BYTES .8byte
|
||||
# else
|
||||
# define LA la
|
||||
# define EH_FRAME_ALIGN 2
|
||||
# define FDE_ADDR_BYTES .4byte
|
||||
# endif /* _MIPS_SIM==_ABI64 */
|
||||
#endif /* !FFI_MIPS_O32 */
|
||||
#else /* !LIBFFI_ASM */
|
||||
# ifdef __GNUC__
|
||||
# ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
typedef unsigned int ffi_arg __attribute__((__mode__(__SI__)));
|
||||
typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
|
||||
#else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
typedef unsigned int ffi_arg __attribute__((__mode__(__DI__)));
|
||||
typedef signed int ffi_sarg __attribute__((__mode__(__DI__)));
|
||||
# endif
|
||||
# else
|
||||
# ifdef FFI_MIPS_O32
|
||||
/* O32 stack frames have 32bit integer args */
|
||||
typedef __uint32_t ffi_arg;
|
||||
typedef __int32_t ffi_sarg;
|
||||
# else
|
||||
/* N32 and N64 frames have 64bit integer args */
|
||||
typedef __uint64_t ffi_arg;
|
||||
typedef __int64_t ffi_sarg;
|
||||
# endif
|
||||
# endif /* __GNUC__ */
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_O32,
|
||||
FFI_N32,
|
||||
FFI_N64,
|
||||
FFI_O32_SOFT_FLOAT,
|
||||
FFI_N32_SOFT_FLOAT,
|
||||
FFI_N64_SOFT_FLOAT,
|
||||
FFI_LAST_ABI,
|
||||
|
||||
#ifdef FFI_MIPS_O32
|
||||
#ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_O32
|
||||
#endif
|
||||
#else
|
||||
# if _MIPS_SIM==_ABI64
|
||||
# ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT
|
||||
# else
|
||||
FFI_DEFAULT_ABI = FFI_N64
|
||||
# endif
|
||||
# else
|
||||
# ifdef __mips_soft_float
|
||||
FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT
|
||||
# else
|
||||
FFI_DEFAULT_ABI = FFI_N32
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
} ffi_abi;
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
|
||||
#endif /* !LIBFFI_ASM */
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if defined(FFI_MIPS_O32)
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 20
|
||||
#else
|
||||
/* N32/N64. */
|
||||
# define FFI_CLOSURES 1
|
||||
#if _MIPS_SIM==_ABI64
|
||||
#define FFI_TRAMPOLINE_SIZE 52
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 20
|
||||
#endif
|
||||
#endif /* FFI_MIPS_O32 */
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,195 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MSVC wrappificator.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Timothy Wall <twalljava@dev.java.net>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Daniel Witte <dwitte@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
|
||||
# format and translated into something sensible for cl or ml.
|
||||
#
|
||||
|
||||
args="-nologo -W3"
|
||||
md=-MD
|
||||
cl="cl"
|
||||
ml="ml"
|
||||
output=
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1
|
||||
in
|
||||
-fexceptions)
|
||||
# Don't enable exceptions for now.
|
||||
#args="$args -EHac"
|
||||
shift 1
|
||||
;;
|
||||
-m32)
|
||||
shift 1
|
||||
;;
|
||||
-m64)
|
||||
cl="cl" # "$MSVC/x86_amd64/cl"
|
||||
ml="ml64" # "$MSVC/x86_amd64/ml64"
|
||||
shift 1
|
||||
;;
|
||||
-O0)
|
||||
args="$args -Od"
|
||||
shift 1
|
||||
;;
|
||||
-O*)
|
||||
# If we're optimizing, make sure we explicitly turn on some optimizations
|
||||
# that are implicitly disabled by debug symbols (-Zi).
|
||||
args="$args $1 -OPT:REF -OPT:ICF -INCREMENTAL:NO"
|
||||
shift 1
|
||||
;;
|
||||
-g)
|
||||
# Enable debug symbol generation.
|
||||
args="$args -Zi -DEBUG"
|
||||
shift 1
|
||||
;;
|
||||
-DFFI_DEBUG)
|
||||
# Link against debug CRT and enable runtime error checks.
|
||||
args="$args -RTC1"
|
||||
defines="$defines $1"
|
||||
md=-MDd
|
||||
shift 1
|
||||
;;
|
||||
-c)
|
||||
args="$args -c"
|
||||
args="$(echo $args | sed 's%/Fe%/Fo%g')"
|
||||
single="-c"
|
||||
shift 1
|
||||
;;
|
||||
-D*=*)
|
||||
name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
|
||||
value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
|
||||
args="$args -D${name}='$value'"
|
||||
defines="$defines -D${name}='$value'"
|
||||
shift 1
|
||||
;;
|
||||
-D*)
|
||||
args="$args $1"
|
||||
defines="$defines $1"
|
||||
shift 1
|
||||
;;
|
||||
-I)
|
||||
args="$args -I$2"
|
||||
includes="$includes -I$2"
|
||||
shift 2
|
||||
;;
|
||||
-I*)
|
||||
args="$args $1"
|
||||
includes="$includes $1"
|
||||
shift 1
|
||||
;;
|
||||
-W|-Wextra)
|
||||
# TODO map extra warnings
|
||||
shift 1
|
||||
;;
|
||||
-Wall)
|
||||
# -Wall on MSVC is overzealous, and we already build with -W3. Nothing
|
||||
# to do here.
|
||||
shift 1
|
||||
;;
|
||||
-Werror)
|
||||
args="$args -WX"
|
||||
shift 1
|
||||
;;
|
||||
-W*)
|
||||
# TODO map specific warnings
|
||||
shift 1
|
||||
;;
|
||||
-S)
|
||||
args="$args -FAs"
|
||||
shift 1
|
||||
;;
|
||||
-o)
|
||||
outdir="$(dirname $2)"
|
||||
base="$(basename $2|sed 's/\.[^.]*//g')"
|
||||
if [ -n "$single" ]; then
|
||||
output="-Fo$2"
|
||||
else
|
||||
output="-Fe$2"
|
||||
fi
|
||||
if [ -n "$assembly" ]; then
|
||||
args="$args $output"
|
||||
else
|
||||
args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*.S)
|
||||
src=$1
|
||||
assembly="true"
|
||||
shift 1
|
||||
;;
|
||||
*.c)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
# Assume it's an MSVC argument, and pass it through.
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$assembly" ]; then
|
||||
if [ -z "$outdir" ]; then
|
||||
outdir="."
|
||||
fi
|
||||
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
|
||||
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
|
||||
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
|
||||
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
|
||||
args="-nologo -safeseh $single $output $ppsrc"
|
||||
|
||||
echo "$ml $args"
|
||||
eval "\"$ml\" $args"
|
||||
result=$?
|
||||
|
||||
# required to fix ml64 broken output?
|
||||
#mv *.obj $outdir
|
||||
else
|
||||
args="$md $args"
|
||||
echo "$cl $args"
|
||||
eval "\"$cl\" $args"
|
||||
result=$?
|
||||
fi
|
||||
|
||||
exit $result
|
||||
|
||||
@@ -1,496 +0,0 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
AX_ENABLE_BUILDDIR
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
|
||||
# defaults of its own if none are provided.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
save_CFLAGS=$CFLAGS
|
||||
AC_PROG_CC
|
||||
CFLAGS=$save_CFLAGS
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AX_CC_MAXOPT
|
||||
AX_CFLAGS_WARN_ALL
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -fexceptions"
|
||||
fi
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS(mmap)
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
case "$host" in
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd* | amd64-*-openbsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
i?86-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-solaris2.1[[0-9]]*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
i?86-*-*)
|
||||
TARGET=X86; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin* | powerpc64-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd* | powerpc-*-openbsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
;;
|
||||
|
||||
sh-*-* | sh[[34]]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
;;
|
||||
|
||||
x86_64-*-darwin*)
|
||||
TARGET=X86_DARWIN; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-cygwin* | x86_64-*-mingw*)
|
||||
TARGET=X86_WIN64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
x86_64-*-*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
|
||||
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
|
||||
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
|
||||
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
|
||||
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
|
||||
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
|
||||
AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
|
||||
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
|
||||
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
|
||||
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
||||
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
|
||||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
|
||||
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
|
||||
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
|
||||
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
|
||||
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
|
||||
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
libffi_cv_as_cfi_pseudo_op, [
|
||||
libffi_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
[libffi_cv_as_cfi_pseudo_op=yes],
|
||||
[libffi_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
|
||||
if test x$TARGET = xSPARC; then
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
|
||||
libffi_cv_as_ascii_pseudo_op, [
|
||||
libffi_cv_as_ascii_pseudo_op=unknown
|
||||
# Check if we have .ascii
|
||||
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
|
||||
[libffi_cv_as_ascii_pseudo_op=yes],
|
||||
[libffi_cv_as_ascii_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .ascii.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .string pseudo-op support],
|
||||
libffi_cv_as_string_pseudo_op, [
|
||||
libffi_cv_as_string_pseudo_op=unknown
|
||||
# Check if we have .string
|
||||
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
|
||||
[libffi_cv_as_string_pseudo_op=yes],
|
||||
[libffi_cv_as_string_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .string.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86_WIN64; then
|
||||
LT_SYS_SYMBOL_USCORE
|
||||
if test "x$sys_symbol_underscore" = xyes; then
|
||||
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=0
|
||||
case "$target" in
|
||||
*arm*-apple-darwin*)
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=1
|
||||
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
|
||||
[Cannot use PROT_EXEC on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
*-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
|
||||
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
echo '.section .eh_frame,"a",@unwind' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
|
||||
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
elif grep '.section.*eh_frame.*#alloc' conftest.c \
|
||||
| grep -v '#write' > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if grep '\.hidden.*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test x"$GCC" != x"no"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
fi
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,183 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MSVC wrappificator.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Timothy Wall <twalljava@dev.java.net>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Daniel Witte <dwitte@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
|
||||
# format and translated into something sensible for cl or ml.
|
||||
#
|
||||
|
||||
args="-nologo"
|
||||
md=-MD
|
||||
cl="cl"
|
||||
ml="ml"
|
||||
output=
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1
|
||||
in
|
||||
-fexceptions)
|
||||
# Don't enable exceptions for now.
|
||||
#args="$args -EHac"
|
||||
shift 1
|
||||
;;
|
||||
-m32)
|
||||
shift 1
|
||||
;;
|
||||
-m64)
|
||||
cl="cl" # "$MSVC/x86_amd64/cl"
|
||||
ml="ml64" # "$MSVC/x86_amd64/ml64"
|
||||
shift 1
|
||||
;;
|
||||
-O*)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
-g)
|
||||
# Can't specify -RTC1 or -Zi in opt. -Gy is ok. Use -OPT:REF?
|
||||
args="$args -D_DEBUG -RTC1 -Zi"
|
||||
md=-MDd
|
||||
shift 1
|
||||
;;
|
||||
-c)
|
||||
args="$args -c"
|
||||
args="$(echo $args | sed 's%/Fe%/Fo%g')"
|
||||
single="-c"
|
||||
shift 1
|
||||
;;
|
||||
-D*=*)
|
||||
name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
|
||||
value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
|
||||
args="$args -D${name}='$value'"
|
||||
defines="$defines -D${name}='$value'"
|
||||
shift 1
|
||||
;;
|
||||
-D*)
|
||||
args="$args $1"
|
||||
defines="$defines $1"
|
||||
shift 1
|
||||
;;
|
||||
-I)
|
||||
args="$args -I$2"
|
||||
includes="$includes -I$2"
|
||||
shift 2
|
||||
;;
|
||||
-I*)
|
||||
args="$args $1"
|
||||
includes="$includes $1"
|
||||
shift 1
|
||||
;;
|
||||
-W|-Wextra)
|
||||
# TODO map extra warnings
|
||||
shift 1
|
||||
;;
|
||||
-Wall)
|
||||
# -Wall on MSVC is overzealous. Use -W3 instead.
|
||||
args="$args -W3"
|
||||
shift 1
|
||||
;;
|
||||
-Werror)
|
||||
args="$args -WX"
|
||||
shift 1
|
||||
;;
|
||||
-W*)
|
||||
# TODO map specific warnings
|
||||
shift 1
|
||||
;;
|
||||
-S)
|
||||
args="$args -FAs"
|
||||
shift 1
|
||||
;;
|
||||
-o)
|
||||
outdir="$(dirname $2)"
|
||||
base="$(basename $2|sed 's/\.[^.]*//g')"
|
||||
if [ -n "$single" ]; then
|
||||
output="-Fo$2"
|
||||
else
|
||||
output="-Fe$2"
|
||||
fi
|
||||
if [ -n "$assembly" ]; then
|
||||
args="$args $output"
|
||||
else
|
||||
args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*.S)
|
||||
src=$1
|
||||
assembly="true"
|
||||
shift 1
|
||||
;;
|
||||
*.c)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
# Assume it's an MSVC argument, and pass it through.
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$assembly" ]; then
|
||||
if [ -z "$outdir" ]; then
|
||||
outdir="."
|
||||
fi
|
||||
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
|
||||
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
|
||||
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
|
||||
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
|
||||
args="-nologo -safeseh $single $output $ppsrc"
|
||||
|
||||
echo "$ml $args"
|
||||
eval "\"$ml\" $args"
|
||||
result=$?
|
||||
|
||||
# required to fix ml64 broken output?
|
||||
#mv *.obj $outdir
|
||||
else
|
||||
args="$md $args"
|
||||
echo "$cl $args"
|
||||
eval "\"$cl\" $args"
|
||||
result=$?
|
||||
fi
|
||||
|
||||
exit $result
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário