├── .editorconfig ├── .gitattributes ├── .github ├── CONTRIBUTING.md ├── SECURITY.md └── dependabot.yml ├── .gitignore ├── .markdownlint.json ├── .netconfig ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── README.md ├── RELEASE.md ├── build.zig ├── build.zig.zon ├── dotnet-tools.json ├── example.zig ├── fficonfig.zig.h ├── global.json ├── include ├── ffi.h.in ├── ffi_cfi.h ├── ffi_common.h └── tramp.h ├── lib ├── closure.zig ├── default.zig ├── ffi.zig ├── ffi │ ├── aarch64.zig │ ├── arc.zig │ ├── arm.zig │ ├── csky.zig │ ├── loongarch64.zig │ ├── m68k.zig │ ├── mips.zig │ ├── powerpc.zig │ ├── riscv.zig │ ├── s390x.zig │ ├── sparc.zig │ ├── x86.zig │ └── xtensa.zig ├── function.zig └── utils.zig └── src ├── aarch64 ├── ffi.c ├── ffitarget.h ├── internal.h ├── sysv.S └── win64_armasm.S ├── alpha ├── ffi.c ├── ffitarget.h ├── internal.h └── osf.S ├── arc ├── arcompact.S ├── ffi.c └── ffitarget.h ├── arm ├── ffi.c ├── ffitarget.h ├── internal.h ├── sysv.S └── sysv_msvc_arm32.S ├── avr32 ├── ffi.c ├── ffitarget.h └── sysv.S ├── bfin ├── ffi.c ├── ffitarget.h └── sysv.S ├── closures.c ├── cris ├── ffi.c ├── ffitarget.h └── sysv.S ├── csky ├── ffi.c ├── ffitarget.h └── sysv.S ├── debug.c ├── dlmalloc.c ├── frv ├── eabi.S ├── ffi.c └── ffitarget.h ├── ia64 ├── ffi.c ├── ffitarget.h ├── ia64_flags.h └── unix.S ├── java_raw_api.c ├── kvx ├── asm.h ├── ffi.c ├── ffitarget.h └── sysv.S ├── loongarch64 ├── ffi.c ├── ffitarget.h └── sysv.S ├── m32r ├── ffi.c ├── ffitarget.h └── sysv.S ├── m68k ├── ffi.c ├── ffitarget.h └── sysv.S ├── m88k ├── ffi.c ├── ffitarget.h └── obsd.S ├── metag ├── ffi.c ├── ffitarget.h └── sysv.S ├── microblaze ├── ffi.c ├── ffitarget.h └── sysv.S ├── mips ├── ffi.c ├── ffitarget.h ├── n32.S └── o32.S ├── moxie ├── eabi.S ├── ffi.c └── ffitarget.h ├── or1k ├── ffi.c ├── ffitarget.h └── sysv.S ├── pa ├── ffi.c ├── ffi64.c ├── ffitarget.h ├── hpux32.S ├── hpux64.S └── linux.S ├── powerpc ├── aix.S ├── aix_closure.S ├── asm.h ├── darwin.S ├── darwin_closure.S ├── ffi.c ├── ffi_darwin.c ├── ffi_linux64.c ├── ffi_powerpc.h ├── ffi_sysv.c ├── ffitarget.h ├── internal.h ├── linux64.S ├── linux64_closure.S ├── ppc_closure.S └── sysv.S ├── prep_cif.c ├── raw_api.c ├── riscv ├── ffi.c ├── ffitarget.h └── sysv.S ├── s390 ├── ffi.c ├── ffitarget.h ├── internal.h └── sysv.S ├── sh ├── ffi.c ├── ffitarget.h └── sysv.S ├── sh64 ├── ffi.c ├── ffitarget.h └── sysv.S ├── sparc ├── ffi.c ├── ffi64.c ├── ffitarget.h ├── internal.h ├── v8.S └── v9.S ├── tile ├── ffi.c ├── ffitarget.h └── tile.S ├── tramp.c ├── types.c ├── vax ├── elfbsd.S ├── ffi.c └── ffitarget.h ├── wasm32 ├── ffi.c └── ffitarget.h ├── x86 ├── asmnames.h ├── ffi.c ├── ffi64.c ├── ffitarget.h ├── ffiw64.c ├── internal.h ├── internal64.h ├── sysv.S ├── sysv_intel.S ├── unix64.S ├── win64.S └── win64_intel.S └── xtensa ├── ffi.c ├── ffitarget.h └── sysv.S /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 4 6 | indent_style = space 7 | insert_final_newline = true 8 | max_line_length = 120 9 | tab_width = 4 10 | trim_trailing_whitespace = true 11 | 12 | [*.json] 13 | indent_size = 2 14 | 15 | [*.jsonc] 16 | indent_size = 2 17 | 18 | [*.vsconfig] 19 | indent_size = 2 20 | 21 | [*.yaml] 22 | indent_size = 2 23 | 24 | [*.yml] 25 | indent_size = 2 26 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text 2 | *.verified.* text eol=lf 3 | *.ico binary 4 | *.png binary 5 | *.zig eol=lf 6 | *.zon eol=lf 7 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This repository is a fork that only makes build system changes and provides Zig 4 | bindings. As such, most issues and pull requests should be directed 5 | [upstream](https://github.com/libffi/libffi). That said, if your issue or pull 6 | request is related to our fork's changes, then please see 7 | [our organization contribution guide](https://github.com/vezel-dev/.github/blob/master/CONTRIBUTING.md). 8 | 9 | Please note that, if you send a pull request and it is merged, it is quite 10 | likely that the record of your contribution will be lost, even though the change 11 | itself is kept. This happens because we rebase the `master` branch periodically 12 | and try to keep the number of commits on top of upstream to a minimum. 13 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | This repository is a fork that only makes build system changes and provides Zig 4 | bindings. As such, most security issues should be directed 5 | [upstream](https://github.com/libffi/libffi). That said, if you wish to report a 6 | security issue that is related to our fork's changes, then please see 7 | [our organization security policy](https://github.com/vezel-dev/.github/security/policy). 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/dependabot-2.0.json 2 | version: 2 3 | updates: 4 | - package-ecosystem: dotnet-sdk 5 | directories: 6 | - / 7 | schedule: 8 | interval: daily 9 | timezone: Europe/Copenhagen 10 | time: "12:00" 11 | open-pull-requests-limit: 25 12 | labels: [] 13 | - package-ecosystem: nuget 14 | directories: 15 | - / 16 | schedule: 17 | interval: daily 18 | timezone: Europe/Copenhagen 19 | time: "12:00" 20 | open-pull-requests-limit: 25 21 | labels: [] 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.zig-cache 2 | /zig-out 3 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint/main/schema/markdownlint-config-schema.json", 3 | "default": true, 4 | "MD001": true, 5 | "MD003": { 6 | "style": "atx" 7 | }, 8 | "MD004": { 9 | "style": "asterisk" 10 | }, 11 | "MD005": true, 12 | "MD007": { 13 | "start_indented": false, 14 | "start_indent": 4, 15 | "indent": 4 16 | }, 17 | "MD009": { 18 | "br_spaces": 0, 19 | "strict": true 20 | }, 21 | "MD010": { 22 | "spaces_per_tab": 4 23 | }, 24 | "MD011": true, 25 | "MD012": true, 26 | "MD013": { 27 | "code_blocks": false, 28 | "headings": false, 29 | "tables": false 30 | }, 31 | "MD014": true, 32 | "MD018": true, 33 | "MD019": true, 34 | "MD020": true, 35 | "MD021": true, 36 | "MD022": true, 37 | "MD023": true, 38 | "MD024": true, 39 | "MD025": true, 40 | "MD026": { 41 | "punctuation": "!,.:;?" 42 | }, 43 | "MD027": true, 44 | "MD028": true, 45 | "MD029": { 46 | "style": "ordered" 47 | }, 48 | "MD030": true, 49 | "MD031": true, 50 | "MD032": true, 51 | "MD033": { 52 | "allowed_elements": [ 53 | "div", 54 | "img", 55 | "p", 56 | "strong" 57 | ] 58 | }, 59 | "MD034": true, 60 | "MD035": { 61 | "style": "--------------------------------------------------------------------------------" 62 | }, 63 | "MD036": { 64 | "punctuation": "!,.:;?" 65 | }, 66 | "MD037": true, 67 | "MD038": true, 68 | "MD039": true, 69 | "MD040": { 70 | "language_only": true 71 | }, 72 | "MD041": true, 73 | "MD042": true, 74 | "MD043": false, 75 | "MD044": true, 76 | "MD045": true, 77 | "MD046": { 78 | "style": "fenced" 79 | }, 80 | "MD047": true, 81 | "MD048": { 82 | "style": "backtick" 83 | }, 84 | "MD049": { 85 | "style": "asterisk" 86 | }, 87 | "MD050": { 88 | "style": "asterisk" 89 | }, 90 | "MD051": true, 91 | "MD052": true, 92 | "MD053": { 93 | "ignored_definitions": [] 94 | }, 95 | "MD054": { 96 | "url_inline": false 97 | }, 98 | "MD055": { 99 | "style": "leading_and_trailing" 100 | }, 101 | "MD056": true, 102 | "MD058": true 103 | } 104 | -------------------------------------------------------------------------------- /.netconfig: -------------------------------------------------------------------------------- 1 | [file ".editorconfig"] 2 | url = https://github.com/vezel-dev/.github/blob/master/syn/.editorconfig 3 | sha = 25cfbb6a508a9fcf8444ef283ddfe7b2e5121bca 4 | etag = df90691e6bc4d301e82e508fca55eed234028a335c3615cf916db00cb4a053f1 5 | weak 6 | [file ".gitattributes"] 7 | url = https://github.com/vezel-dev/.github/blob/master/syn/.gitattributes 8 | sha = 428d38cccf66c6af406248aabc81d870c6fbd5d3 9 | etag = f2a79dbd60628d2022614ccd48cb1d437fc6be1140215719fc52788df76d5d39 10 | weak 11 | [file ".markdownlint.json"] 12 | url = https://github.com/vezel-dev/.github/blob/master/syn/.markdownlint.json 13 | sha = 72ec690564533b1ad756f452be9b3ea5075ad124 14 | etag = 6d74ad50782defb281b210a627cae9d255cbb419cdc705b0571f1653dbe02300 15 | weak 16 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chdsbd.github-code-owners", 4 | "codezombiech.gitignore", 5 | "davidanson.vscode-markdownlint", 6 | "editorconfig.editorconfig", 7 | "github.vscode-github-actions", 8 | "github.vscode-pull-request-github", 9 | "llvm-vs-code-extensions.vscode-clangd", 10 | "redhat.vscode-yaml", 11 | "yy0931.gitconfig-lsp", 12 | "ziglang.vscode-zig" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | ".zig-cache": true, 4 | "zig-out": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | libffi - Copyright (c) 1996-2024 Anthony Green, Red Hat, Inc and others. 2 | See source files for details. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | ``Software''), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vezel libffi Fork 2 | 3 | > [!WARNING] 4 | > [This repository has moved to Codeberg.](https://codeberg.org/vezel/libffi) 5 | > Please update your `build.zig.zon` as necessary. The GitHub repository has 6 | > been archived and will not see further development. 7 | 8 | This is a friendly fork of [libffi](https://sourceware.org/libffi). The notable 9 | changes made in this fork are the additions of a [Zig](https://ziglang.org) 10 | build script, making it easy to integrate libffi into Zig projects using the Zig 11 | package manager, and a set of idiomatic Zig bindings for libffi's main API. 12 | Additionally, to reduce the package download size, we have removed a large 13 | number of files that are unnecessary when using libffi in a Zig project. 14 | Importantly, **all library source code is identical to upstream**, so in terms 15 | of API/ABI compatibility, using this fork is no different from linking to a 16 | system libffi package. 17 | 18 | ## Usage 19 | 20 | The minimum Zig version supported by this project can be found in the 21 | `minimum_zig_version` field of the [`build.zig.zon`](build.zig.zon) file. We 22 | generally try to track the latest release of Zig. But do note that the `master` 23 | branch may sometimes contain code that only works with a `master` build of Zig. 24 | 25 | Please note that the `master` branch is rebased on top of upstream periodically. 26 | **You should use a release tag rather than `master`.** For example: 27 | 28 | ```bash 29 | zig fetch --save=libffi https://github.com/vezel-dev/libffi/archive/vX.Y.Z-B.tar.gz 30 | # Or, to use Git: 31 | zig fetch --save=libffi git+https://github.com/vezel-dev/libffi.git#vX.Y.Z-B 32 | ``` 33 | 34 | (You can find the latest version on the 35 | [releases page](https://github.com/vezel-dev/libffi/releases).) 36 | 37 | Consume the library in your `build.zig`: 38 | 39 | ```zig 40 | const libffi = b.dependency("libffi", .{ 41 | .target = target, 42 | .optimize = optimize, 43 | }); 44 | 45 | exe.root_module.addImport("ffi", libffi.module("ffi")); 46 | 47 | if (b.systemIntegrationOption("ffi", .{})) { 48 | exe.root_module.linkSystemLibrary("ffi", .{}); 49 | } else { 50 | exe.root_module.linkLibrary(libffi.artifact("ffi")); 51 | } 52 | ``` 53 | 54 | You can now use the Zig bindings in your code. See [`example.zig`](example.zig) 55 | for basic usage. 56 | 57 | ## License 58 | 59 | This project is licensed under the terms found in [`LICENSE`](LICENSE); this 60 | file is unchanged from upstream. 61 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | Every upstream release should have a corresponding release branch and tag here. 4 | The branch should be named `release/vX.Y.Z`; that is, unlike normal Vezel 5 | convention, even a patch release gets a unique branch. The tag should be named 6 | `vX.Y.Z-B`, where B represents our one-based fork version. B is incremented 7 | whenever we make fixes to the Zig build script or bindings within the same 8 | upstream release cycle, and is reset for any new X/Y/Z combination. 9 | 10 | This is the procedure for creating a new release from an upstream release: 11 | 12 | 1. Run `git checkout -b release/vX.Y.Z vX.Y.Z` to create and switch to the new 13 | release branch. 14 | 2. Cherry-pick our fork's commit range from `master` and resolve any conflicts 15 | in the process. 16 | 3. Adjust the libffi version in [`build.zig.zon`](build.zig.zon) and commit the 17 | changes. 18 | 4. Make sure `zig build test` works. Try cross-compiling for any targets that 19 | had changes in the upstream release. 20 | 5. Push the release branch. 21 | 6. Run `git tag vX.Y.Z-B -m vX.Y.Z-B -s` to create and sign a release tag, and 22 | then push it. 23 | 7. Go to the [releases page](https://github.com/vezel-dev/libffi/releases) to 24 | create a release from the new tag. The release notes should just be a link to 25 | the upstream release, such as 26 | [this one](https://github.com/libffi/libffi/releases/tag/v3.4.6). 27 | 28 | (Obviously, step 2 will be easier if `master` is not lagging behind upstream.) 29 | 30 | The procedure for creating a release that only includes fixes to the Zig build 31 | script or bindings is simpler: Just commit the fix to the release branch and 32 | then proceed from step 4. Remember to increment the B value! 33 | 34 | If something goes wrong, you can run `git tag -d vX.Y.Z-B` and 35 | `git push origin :vX.Y.Z-B` to delete the tag until you resolve the issue(s), 36 | and then repeat whichever steps are necessary. 37 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .libffi, 3 | .fingerprint = 0x806ae679b444fbef, 4 | .version = "3.4.8", 5 | .minimum_zig_version = "0.14.0", 6 | .paths = .{ 7 | "LICENSE", 8 | "README.md", 9 | "build.zig", 10 | "build.zig.zon", 11 | "fficonfig.zig.h", 12 | "include", 13 | "lib", 14 | "src", 15 | }, 16 | .dependencies = .{}, 17 | } 18 | -------------------------------------------------------------------------------- /dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-config": { 6 | "version": "1.2.0", 7 | "commands": [ 8 | "dotnet-config" 9 | ] 10 | }, 11 | "dotnet-file": { 12 | "version": "1.7.1", 13 | "commands": [ 14 | "dotnet-file" 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example.zig: -------------------------------------------------------------------------------- 1 | const builtin = @import("builtin"); 2 | const std = @import("std"); 3 | const ffi = @import("ffi"); 4 | 5 | const stdio = @cImport(@cInclude("stdio.h")); 6 | 7 | pub fn main() anyerror!void { 8 | std.debug.print("Calling C puts() on {s}-{s}.\n", .{ @tagName(builtin.cpu.arch), @tagName(builtin.os.tag) }); 9 | 10 | var func: ffi.Function = undefined; 11 | var params = [_]*ffi.Type{ 12 | ffi.types.pointer, 13 | }; 14 | 15 | try func.prepare(.default, params.len, params[0..], ffi.types.sint32); 16 | 17 | var result: ffi.uarg = undefined; 18 | var args: [params.len]*anyopaque = .{ 19 | @ptrCast(@constCast(&"Hello World")), 20 | }; 21 | 22 | func.call(&stdio.puts, args[0..], &result); 23 | 24 | if (result == stdio.EOF) 25 | return error.IOError; 26 | } 27 | -------------------------------------------------------------------------------- /fficonfig.zig.h: -------------------------------------------------------------------------------- 1 | /* Template used by build.zig. */ 2 | 3 | /* Define if building universal (internal helper macro) */ 4 | #undef AC_APPLE_UNIVERSAL_BUILD 5 | 6 | /* Define to the flags needed for the .section .eh_frame directive. */ 7 | #undef EH_FRAME_FLAGS 8 | 9 | /* Define this if you want extra debugging. */ 10 | #undef FFI_DEBUG 11 | 12 | /* Define this if you want statically defined trampolines */ 13 | #undef FFI_EXEC_STATIC_TRAMP 14 | 15 | /* Cannot use PROT_EXEC on this target, so, we revert to alternative means */ 16 | #undef FFI_EXEC_TRAMPOLINE_TABLE 17 | 18 | /* Define this if you want to enable pax emulated trampolines (experimental) 19 | */ 20 | #undef FFI_MMAP_EXEC_EMUTRAMP_PAX 21 | 22 | /* Cannot use malloc on this target, so, we revert to alternative means */ 23 | #undef FFI_MMAP_EXEC_WRIT 24 | 25 | /* Define this if you do not want support for the raw API. */ 26 | #undef FFI_NO_RAW_API 27 | 28 | /* Define this if you do not want support for aggregate types. */ 29 | #undef FFI_NO_STRUCTS 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #undef HAVE_ALLOCA_H 33 | 34 | /* Define if your compiler supports pointer authentication. */ 35 | #undef HAVE_ARM64E_PTRAUTH 36 | 37 | /* Define if your assembler supports .cfi_* directives. */ 38 | #undef HAVE_AS_CFI_PSEUDO_OP 39 | 40 | /* Define if your assembler supports .register. */ 41 | #undef HAVE_AS_REGISTER_PSEUDO_OP 42 | 43 | /* Define if the compiler uses zarch features. */ 44 | #undef HAVE_AS_S390_ZARCH 45 | 46 | /* Define if your assembler and linker support unaligned PC relative relocs. 47 | */ 48 | #undef HAVE_AS_SPARC_UA_PCREL 49 | 50 | /* Define if your assembler supports unwind section type. */ 51 | #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE 52 | 53 | /* Define if your assembler supports PC relative relocs. */ 54 | #undef HAVE_AS_X86_PCREL 55 | 56 | /* Define to 1 if you have the header file. */ 57 | #undef HAVE_DLFCN_H 58 | 59 | /* Define if __attribute__((visibility("hidden"))) is supported. */ 60 | #undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 61 | 62 | /* Define to 1 if you have the header file. */ 63 | #undef HAVE_INTTYPES_H 64 | 65 | /* Define if you have the long double type and it is bigger than a double */ 66 | #undef HAVE_LONG_DOUBLE 67 | 68 | /* Define if you support more than one size of the long double type */ 69 | #undef HAVE_LONG_DOUBLE_VARIANT 70 | 71 | /* Define to 1 if you have the `memcpy' function. */ 72 | #undef HAVE_MEMCPY 73 | 74 | /* Define to 1 if you have the `memfd_create' function. */ 75 | #undef HAVE_MEMFD_CREATE 76 | 77 | /* Define if .eh_frame sections should be read-only. */ 78 | #undef HAVE_RO_EH_FRAME 79 | 80 | /* Define to 1 if you have the header file. */ 81 | #undef HAVE_STDINT_H 82 | 83 | /* Define to 1 if you have the header file. */ 84 | #undef HAVE_STDIO_H 85 | 86 | /* Define to 1 if you have the header file. */ 87 | #undef HAVE_STDLIB_H 88 | 89 | /* Define to 1 if you have the header file. */ 90 | #undef HAVE_STRINGS_H 91 | 92 | /* Define to 1 if you have the header file. */ 93 | #undef HAVE_STRING_H 94 | 95 | /* Define to 1 if you have the header file. */ 96 | #undef HAVE_SYS_MEMFD_H 97 | 98 | /* Define to 1 if you have the header file. */ 99 | #undef HAVE_SYS_STAT_H 100 | 101 | /* Define to 1 if you have the header file. */ 102 | #undef HAVE_SYS_TYPES_H 103 | 104 | /* Define to 1 if you have the header file. */ 105 | #undef HAVE_UNISTD_H 106 | 107 | /* Define to 1 if GNU symbol versioning is used for libatomic. */ 108 | #undef LIBFFI_GNU_SYMBOL_VERSIONING 109 | 110 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 111 | #undef LT_OBJDIR 112 | 113 | /* Name of package */ 114 | #undef PACKAGE 115 | 116 | /* Define to the address where bug reports for this package should be sent. */ 117 | #undef PACKAGE_BUGREPORT 118 | 119 | /* Define to the full name of this package. */ 120 | #undef PACKAGE_NAME 121 | 122 | /* Define to the full name and version of this package. */ 123 | #undef PACKAGE_STRING 124 | 125 | /* Define to the one symbol short name of this package. */ 126 | #undef PACKAGE_TARNAME 127 | 128 | /* Define to the home page for this package. */ 129 | #undef PACKAGE_URL 130 | 131 | /* Define to the version of this package. */ 132 | #undef PACKAGE_VERSION 133 | 134 | /* The size of `double', as computed by sizeof. */ 135 | #undef SIZEOF_DOUBLE 136 | 137 | /* The size of `long double', as computed by sizeof. */ 138 | #undef SIZEOF_LONG_DOUBLE 139 | 140 | /* The size of `size_t', as computed by sizeof. */ 141 | #undef SIZEOF_SIZE_T 142 | 143 | /* Define to 1 if all of the C90 standard headers exist (not just the ones 144 | required in a freestanding environment). This macro is provided for 145 | backward compatibility; new code need not use it. */ 146 | #undef STDC_HEADERS 147 | 148 | /* Define if symbols are underscored. */ 149 | #undef SYMBOL_UNDERSCORE 150 | 151 | /* Define this if you are using Purify and want to suppress spurious messages. 152 | */ 153 | #undef USING_PURIFY 154 | 155 | /* Version number of package */ 156 | #undef VERSION 157 | 158 | /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most 159 | significant byte first (like Motorola and SPARC, unlike Intel). */ 160 | #if defined AC_APPLE_UNIVERSAL_BUILD 161 | #if defined __BIG_ENDIAN__ 162 | #define WORDS_BIGENDIAN 1 163 | #endif 164 | #else 165 | #ifndef WORDS_BIGENDIAN 166 | #undef WORDS_BIGENDIAN 167 | #endif 168 | #endif 169 | 170 | #ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 171 | #ifdef LIBFFI_ASM 172 | #ifdef __APPLE__ 173 | #define FFI_HIDDEN(name) .private_extern name 174 | #else 175 | #define FFI_HIDDEN(name) .hidden name 176 | #endif 177 | #else 178 | #define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) 179 | #endif 180 | #else 181 | #ifdef LIBFFI_ASM 182 | #define FFI_HIDDEN(name) 183 | #else 184 | #define FFI_HIDDEN 185 | #endif 186 | #endif 187 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/global.json", 3 | "sdk": { 4 | "version": "9.0.300", 5 | "rollForward": "disable", 6 | "allowPrelease": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /include/ffi_cfi.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc. 3 | 4 | Conditionally assemble cfi directives. Only necessary for building libffi. 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the ``Software''), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, 10 | modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef FFI_CFI_H 29 | #define FFI_CFI_H 30 | 31 | #ifdef HAVE_AS_CFI_PSEUDO_OP 32 | 33 | # define cfi_startproc .cfi_startproc 34 | # define cfi_endproc .cfi_endproc 35 | # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off 36 | # define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg 37 | # define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off 38 | # define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off 39 | # define cfi_offset(reg, off) .cfi_offset reg, off 40 | # define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off 41 | # define cfi_register(r1, r2) .cfi_register r1, r2 42 | # define cfi_return_column(reg) .cfi_return_column reg 43 | # define cfi_restore(reg) .cfi_restore reg 44 | # define cfi_same_value(reg) .cfi_same_value reg 45 | # define cfi_undefined(reg) .cfi_undefined reg 46 | # define cfi_remember_state .cfi_remember_state 47 | # define cfi_restore_state .cfi_restore_state 48 | # define cfi_window_save .cfi_window_save 49 | # define cfi_personality(enc, exp) .cfi_personality enc, exp 50 | # define cfi_lsda(enc, exp) .cfi_lsda enc, exp 51 | # define cfi_escape(...) .cfi_escape __VA_ARGS__ 52 | # define cfi_window_save .cfi_window_save 53 | 54 | #else 55 | 56 | # define cfi_startproc 57 | # define cfi_endproc 58 | # define cfi_def_cfa(reg, off) 59 | # define cfi_def_cfa_register(reg) 60 | # define cfi_def_cfa_offset(off) 61 | # define cfi_adjust_cfa_offset(off) 62 | # define cfi_offset(reg, off) 63 | # define cfi_rel_offset(reg, off) 64 | # define cfi_register(r1, r2) 65 | # define cfi_return_column(reg) 66 | # define cfi_restore(reg) 67 | # define cfi_same_value(reg) 68 | # define cfi_undefined(reg) 69 | # define cfi_remember_state 70 | # define cfi_restore_state 71 | # define cfi_window_save 72 | # define cfi_personality(enc, exp) 73 | # define cfi_lsda(enc, exp) 74 | # define cfi_escape(...) 75 | # define cfi_window_save 76 | 77 | #endif /* HAVE_AS_CFI_PSEUDO_OP */ 78 | #endif /* FFI_CFI_H */ 79 | -------------------------------------------------------------------------------- /include/ffi_common.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green 3 | Copyright (C) 2007 Free Software Foundation, Inc 4 | Copyright (c) 1996 Red Hat, Inc. 5 | 6 | Common internal definitions and macros. Only necessary for building 7 | libffi. 8 | 9 | Permission is hereby granted, free of charge, to any person 10 | obtaining a copy of this software and associated documentation 11 | files (the ``Software''), to deal in the Software without 12 | restriction, including without limitation the rights to use, copy, 13 | modify, merge, publish, distribute, sublicense, and/or sell copies 14 | of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 | DEALINGS IN THE SOFTWARE. 28 | 29 | ----------------------------------------------------------------------- */ 30 | 31 | #ifndef FFI_COMMON_H 32 | #define FFI_COMMON_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #include 39 | 40 | /* Do not move this. Some versions of AIX are very picky about where 41 | this is positioned. */ 42 | #ifdef __GNUC__ 43 | # if HAVE_ALLOCA_H 44 | # include 45 | # else 46 | /* mingw64 defines this already in malloc.h. */ 47 | # ifndef alloca 48 | # define alloca __builtin_alloca 49 | # endif 50 | # endif 51 | # define MAYBE_UNUSED __attribute__((__unused__)) 52 | # define NORETURN __attribute__((__noreturn__)) 53 | #else 54 | # define MAYBE_UNUSED 55 | # define NORETURN 56 | # if HAVE_ALLOCA_H 57 | # include 58 | # else 59 | # ifdef _AIX 60 | # pragma alloca 61 | # else 62 | # ifndef alloca /* predefined by HP cc +Olibcalls */ 63 | # ifdef _MSC_VER 64 | # define alloca _alloca 65 | # else 66 | char *alloca (); 67 | # endif 68 | # endif 69 | # endif 70 | # endif 71 | #endif 72 | 73 | /* Check for the existence of memcpy. */ 74 | #if STDC_HEADERS 75 | # include 76 | #else 77 | # ifndef HAVE_MEMCPY 78 | # define memcpy(d, s, n) bcopy ((s), (d), (n)) 79 | # endif 80 | #endif 81 | 82 | #if defined(FFI_DEBUG) 83 | #include 84 | #endif 85 | 86 | #ifndef __SANITIZE_ADDRESS__ 87 | # ifdef __clang__ 88 | # if __has_feature(address_sanitizer) 89 | # define FFI_ASAN 90 | # endif 91 | # endif 92 | #endif 93 | #ifdef __SANITIZE_ADDRESS__ 94 | #define FFI_ASAN 95 | #endif 96 | 97 | #ifdef FFI_ASAN 98 | #define FFI_ASAN_NO_SANITIZE __attribute__((no_sanitize_address)) 99 | #else 100 | #define FFI_ASAN_NO_SANITIZE 101 | #endif 102 | 103 | #ifdef FFI_DEBUG 104 | NORETURN void ffi_assert(const char *expr, const char *file, int line); 105 | void ffi_stop_here(void); 106 | void ffi_type_test(ffi_type *a, const char *file, int line); 107 | 108 | #define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) 109 | #define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) 110 | #define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) 111 | #else 112 | #define FFI_ASSERT(x) 113 | #define FFI_ASSERT_AT(x, f, l) 114 | #define FFI_ASSERT_VALID_TYPE(x) 115 | #endif 116 | 117 | /* v cast to size_t and aligned up to a multiple of a */ 118 | #define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) 119 | /* v cast to size_t and aligned down to a multiple of a */ 120 | #define FFI_ALIGN_DOWN(v, a) (((size_t) (v)) & -a) 121 | 122 | /* Perform machine dependent cif processing */ 123 | ffi_status ffi_prep_cif_machdep(ffi_cif *cif); 124 | ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, 125 | unsigned int nfixedargs, unsigned int ntotalargs); 126 | 127 | 128 | #if HAVE_LONG_DOUBLE_VARIANT 129 | /* Used to adjust size/alignment of ffi types. */ 130 | void ffi_prep_types (ffi_abi abi); 131 | #endif 132 | 133 | /* Used internally, but overridden by some architectures */ 134 | ffi_status ffi_prep_cif_core(ffi_cif *cif, 135 | ffi_abi abi, 136 | unsigned int isvariadic, 137 | unsigned int nfixedargs, 138 | unsigned int ntotalargs, 139 | ffi_type *rtype, 140 | ffi_type **atypes); 141 | 142 | /* Translate a data pointer to a code pointer. Needed for closures on 143 | some targets. */ 144 | void *ffi_data_to_code_pointer (void *data) FFI_HIDDEN; 145 | 146 | /* The arch code calls this to determine if a given closure has a 147 | static trampoline. */ 148 | int ffi_tramp_is_present (void *closure) FFI_HIDDEN; 149 | 150 | /* Return a file descriptor of a temporary zero-sized file in a 151 | writable and executable filesystem. */ 152 | int open_temp_exec_file(void) FFI_HIDDEN; 153 | 154 | /* Extended cif, used in callback from assembly routine */ 155 | typedef struct 156 | { 157 | ffi_cif *cif; 158 | void *rvalue; 159 | void **avalue; 160 | } extended_cif; 161 | 162 | /* Terse sized type definitions. */ 163 | #if defined(_MSC_VER) || defined(__sgi) || defined(__SUNPRO_C) 164 | typedef unsigned char UINT8; 165 | typedef signed char SINT8; 166 | typedef unsigned short UINT16; 167 | typedef signed short SINT16; 168 | typedef unsigned int UINT32; 169 | typedef signed int SINT32; 170 | # ifdef _MSC_VER 171 | typedef unsigned __int64 UINT64; 172 | typedef signed __int64 SINT64; 173 | # else 174 | # include 175 | typedef uint64_t UINT64; 176 | typedef int64_t SINT64; 177 | # endif 178 | #else 179 | typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); 180 | typedef signed int SINT8 __attribute__((__mode__(__QI__))); 181 | typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); 182 | typedef signed int SINT16 __attribute__((__mode__(__HI__))); 183 | typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); 184 | typedef signed int SINT32 __attribute__((__mode__(__SI__))); 185 | typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); 186 | typedef signed int SINT64 __attribute__((__mode__(__DI__))); 187 | #endif 188 | 189 | typedef float FLOAT32; 190 | 191 | #ifndef __GNUC__ 192 | #define __builtin_expect(x, expected_value) (x) 193 | #endif 194 | #define LIKELY(x) __builtin_expect(!!(x),1) 195 | #define UNLIKELY(x) __builtin_expect((x)!=0,0) 196 | 197 | #ifdef __cplusplus 198 | } 199 | #endif 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /include/tramp.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi_tramp.h - Copyright (C) 2021 Microsoft, Inc. 3 | 4 | Static trampoline definitions. 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the ``Software''), to deal in the Software without 9 | restriction, including without limitation the rights to use, copy, 10 | modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef FFI_TRAMP_H 29 | #define FFI_TRAMP_H 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | int ffi_tramp_is_supported(void); 36 | void *ffi_tramp_alloc (int flags); 37 | void ffi_tramp_set_parms (void *tramp, void *data, void *code); 38 | void *ffi_tramp_get_addr (void *tramp); 39 | void ffi_tramp_free (void *tramp); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif /* FFI_TRAMP_H */ 46 | -------------------------------------------------------------------------------- /lib/closure.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const ffi = @import("ffi.zig"); 4 | const utils = @import("utils.zig"); 5 | 6 | pub fn Code(Fn: type) type { 7 | if (@typeInfo(Fn) != .@"fn") 8 | @compileError("Fn must be a function type."); 9 | 10 | return struct { 11 | closure: *ffi.Closure, 12 | trampoline: *const Fn, 13 | 14 | pub fn free( 15 | self: @This(), 16 | ) void { 17 | ffi.ffi_closure_free(self.closure); 18 | } 19 | 20 | pub fn prepare( 21 | self: @This(), 22 | function: *ffi.Function, 23 | wrapper: *const fn (*ffi.Function, *anyopaque, ?[*]*anyopaque, ?*anyopaque) callconv(.c) void, 24 | datum: ?*anyopaque, 25 | ) ffi.Error!void { 26 | return utils.wrap( 27 | ffi.ffi_prep_closure_loc(self.closure, function, wrapper, datum, @ptrCast(self.trampoline)), 28 | ); 29 | } 30 | }; 31 | } 32 | 33 | pub fn allocCode(Fn: type) ffi.Error!Code(Fn) { 34 | var trampoline: *const Fn = undefined; 35 | 36 | return if (ffi.ffi_closure_alloc(@sizeOf(ffi.Closure), @ptrCast(&trampoline))) |closure| .{ 37 | .closure = closure, 38 | .trampoline = trampoline, 39 | } else error.OutOfMemory; 40 | } 41 | -------------------------------------------------------------------------------- /lib/default.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const closure = @import("closure.zig"); 4 | const ffi = @import("ffi.zig"); 5 | const function = @import("function.zig"); 6 | 7 | pub const Abi = enum(i32) { 8 | sysv = 1, 9 | _, 10 | 11 | pub const default: Abi = .sysv; 12 | }; 13 | 14 | pub fn Function(TAbi: type) type { 15 | return extern struct { 16 | abi: TAbi, 17 | param_count: c_uint, 18 | param_types: ?[*]*ffi.Type, 19 | return_type: *ffi.Type, 20 | bytes: c_uint, 21 | flags: c_uint, 22 | 23 | pub const prepare = function.prepare; 24 | 25 | pub const prepareVarArgs = function.prepareVarArgs; 26 | 27 | pub const call = function.call; 28 | }; 29 | } 30 | 31 | pub fn Closure(TFunction: type, size: comptime_int) type { 32 | return extern struct { 33 | trampoline: extern union { 34 | dynamic: [size]c_char, 35 | static: *anyopaque, 36 | } align(8), 37 | function: *TFunction, 38 | wrapper: *const fn (*TFunction, *anyopaque, ?[*]*anyopaque, ?*anyopaque) callconv(.c) void, 39 | datum: ?*anyopaque, 40 | 41 | pub const Code = closure.Code; 42 | 43 | pub const allocCode = closure.allocCode; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /lib/ffi/aarch64.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const closure = @import("../closure.zig"); 6 | const default = @import("../default.zig"); 7 | const ffi = @import("../ffi.zig"); 8 | const function = @import("../function.zig"); 9 | 10 | pub const have_complex_type = builtin.os.tag != .windows; 11 | 12 | const arg_longlong = builtin.abi == .gnuilp32 or builtin.os.tag == .windows; 13 | 14 | pub const uarg = if (arg_longlong) c_ulonglong else c_ulong; 15 | pub const sarg = if (arg_longlong) c_longlong else c_long; 16 | 17 | pub const Abi = enum(i32) { 18 | sysv = 1, 19 | win64 = 2, 20 | _, 21 | 22 | pub const default: Abi = if (builtin.os.tag == .windows) .win64 else .sysv; 23 | }; 24 | 25 | pub const Function = if (builtin.os.tag.isDarwin()) extern struct { 26 | abi: Abi, 27 | param_count: c_uint, 28 | param_types: ?[*]*ffi.Type, 29 | return_type: *ffi.Type, 30 | bytes: c_uint, 31 | flags: c_uint, 32 | _private1: c_uint, 33 | 34 | pub const prepare = function.prepare; 35 | 36 | pub const prepareVarArgs = function.prepareVarArgs; 37 | 38 | pub const call = function.call; 39 | } else if (builtin.os.tag == .windows) extern struct { 40 | abi: Abi, 41 | param_count: c_uint, 42 | param_types: ?[*]*ffi.Type, 43 | return_type: *ffi.Type, 44 | bytes: c_uint, 45 | flags: c_uint, 46 | _private1: c_uint, 47 | 48 | pub const prepare = function.prepare; 49 | 50 | pub const prepareVarArgs = function.prepareVarArgs; 51 | 52 | pub const call = function.call; 53 | } else default.Function(Abi); 54 | 55 | pub const Closure = if (builtin.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) extern struct { 56 | trampoline_table: *anyopaque align(8), 57 | trampoline_table_entry: *anyopaque, 58 | function: *Function, 59 | wrapper: *const fn (*Function, *anyopaque, ?[*]*anyopaque, ?*anyopaque) callconv(.c) void, 60 | datum: ?*anyopaque, 61 | 62 | pub const Code = closure.Code; 63 | 64 | pub const allocCode = closure.allocCode; 65 | } else default.Closure(Function, 24); 66 | -------------------------------------------------------------------------------- /lib/ffi/arc.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | 5 | pub const Abi = enum(i32) { 6 | arcompact = 1, 7 | _, 8 | 9 | pub const default: Abi = .arcompact; 10 | }; 11 | 12 | pub const Function = default.Function(Abi); 13 | 14 | pub const Closure = default.Closure(Function, 12); 15 | -------------------------------------------------------------------------------- /lib/ffi/arm.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const closure = @import("../closure.zig"); 6 | const default = @import("../default.zig"); 7 | const ffi = @import("../ffi.zig"); 8 | const function = @import("../function.zig"); 9 | 10 | pub const have_complex_type = builtin.os.tag != .windows; 11 | 12 | pub const Abi = enum(i32) { 13 | sysv = 1, 14 | vfp = 2, 15 | _, 16 | 17 | pub const default: Abi = if (builtin.abi.floatAbi() != .soft or builtin.os.tag == .windows) .vfp else .sysv; 18 | }; 19 | 20 | pub const Function = extern struct { 21 | abi: Abi, 22 | param_count: c_uint, 23 | param_types: ?[*]*ffi.Type, 24 | return_type: *ffi.Type, 25 | bytes: c_uint, 26 | flags: c_uint, 27 | _private1: c_int, 28 | _private2: c_ushort, 29 | _private3: c_ushort, 30 | _private4: [16]i8, 31 | 32 | pub const prepare = function.prepare; 33 | 34 | pub const prepareVarArgs = function.prepareVarArgs; 35 | 36 | pub const call = function.call; 37 | }; 38 | 39 | pub const Closure = if (builtin.os.tag.isDarwin()) extern struct { 40 | trampoline_table: *anyopaque align(8), 41 | trampoline_table_entry: *anyopaque, 42 | function: *Function, 43 | wrapper: *const fn (*Function, *anyopaque, ?[*]*anyopaque, ?*anyopaque) callconv(.c) void, 44 | datum: ?*anyopaque, 45 | 46 | pub const Code = closure.Code; 47 | 48 | pub const allocCode = closure.allocCode; 49 | } else default.Closure(Function, if (builtin.os.tag == .windows) 16 else 12); 50 | -------------------------------------------------------------------------------- /lib/ffi/csky.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | 5 | pub const Abi = default.Abi; 6 | 7 | pub const Function = default.Function(Abi); 8 | 9 | pub const Closure = default.Closure(Function, 24); 10 | -------------------------------------------------------------------------------- /lib/ffi/loongarch64.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const default = @import("../default.zig"); 6 | const ffi = @import("../ffi.zig"); 7 | const function = @import("../function.zig"); 8 | 9 | pub const Abi = enum(i32) { 10 | lp64s = 1, 11 | lp64f = 2, 12 | lp64d = 3, 13 | _, 14 | 15 | pub const default: Abi = switch (builtin.abi) { 16 | // TODO: Add muslsf and muslf32 with LLVM 20 / Zig 0.15.0. 17 | .gnusf => .lp64s, 18 | .gnuf32 => .lp64f, 19 | else => .lp64d, 20 | }; 21 | }; 22 | 23 | pub const Function = extern struct { 24 | abi: Abi, 25 | param_count: c_uint, 26 | param_types: ?[*]*ffi.Type, 27 | return_type: *ffi.Type, 28 | bytes: c_uint, 29 | flags: c_uint, 30 | _private1: c_uint, 31 | _private2: c_uint, 32 | 33 | pub const prepare = function.prepare; 34 | 35 | pub const prepareVarArgs = function.prepareVarArgs; 36 | 37 | pub const call = function.call; 38 | }; 39 | 40 | pub const Closure = default.Closure(Function, 24); 41 | -------------------------------------------------------------------------------- /lib/ffi/m68k.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | 5 | pub const Abi = default.Abi; 6 | 7 | pub const Function = default.Function(Abi); 8 | 9 | pub const Closure = default.Closure(Function, 16); 10 | -------------------------------------------------------------------------------- /lib/ffi/mips.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const default = @import("../default.zig"); 6 | const ffi = @import("../ffi.zig"); 7 | const function = @import("../function.zig"); 8 | 9 | pub const have_long_double = switch (builtin.cpu.arch) { 10 | .mips64, .mips64el => switch (builtin.os.tag) { 11 | .freebsd, .linux, .openbsd => true, 12 | else => false, 13 | }, 14 | else => false, 15 | }; 16 | pub const have_complex_type = true; 17 | 18 | const arg_64 = switch (builtin.cpu.arch) { 19 | .mips, .mipsel => false, 20 | .mips64, .mips64el => true, 21 | else => unreachable, 22 | }; 23 | 24 | pub const uarg = if (arg_64) u64 else u32; 25 | pub const sarg = if (arg_64) i64 else i32; 26 | 27 | pub const Abi = enum(i32) { 28 | o32 = 1, 29 | n32 = 2, 30 | n64 = 3, 31 | o32_soft_float = 4, 32 | n32_soft_float = 5, 33 | n64_soft_float = 6, 34 | _, 35 | 36 | pub const default: Abi = switch (builtin.cpu.arch) { 37 | .mips, .mipsel => if (builtin.abi.floatAbi() == .soft) .o32_soft_float else .o32, 38 | .mips64, .mips64el => if (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32) .n32 else .n64, 39 | else => unreachable, 40 | }; 41 | }; 42 | 43 | pub const Function = extern struct { 44 | abi: Abi, 45 | param_count: c_uint, 46 | param_types: ?[*]*ffi.Type, 47 | return_type: *ffi.Type, 48 | bytes: c_uint, 49 | flags: c_uint, 50 | _private1: c_uint, 51 | _private2: c_uint, 52 | 53 | pub const prepare = function.prepare; 54 | 55 | pub const prepareVarArgs = function.prepareVarArgs; 56 | 57 | pub const call = function.call; 58 | }; 59 | 60 | pub const Closure = default.Closure(Function, switch (builtin.cpu.arch) { 61 | .mips, .mipsel => 20, 62 | .mips64, .mips64el => switch (builtin.abi) { 63 | .gnuabin32, .muslabin32 => 20, 64 | else => 56, 65 | }, 66 | }); 67 | -------------------------------------------------------------------------------- /lib/ffi/powerpc.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const default = @import("../default.zig"); 6 | const ffi = @import("../ffi.zig"); 7 | const function = @import("../function.zig"); 8 | 9 | pub const have_long_double = switch (builtin.os.tag) { 10 | .freebsd, .netbsd, .openbsd => builtin.cpu.arch == .powerpc, 11 | .linux => true, 12 | else => false, 13 | }; 14 | 15 | pub const Abi = if (builtin.os.tag.isDarwin() or builtin.os.tag == .aix) enum(i32) { 16 | aix = 1, 17 | darwin = 2, 18 | _, 19 | 20 | pub const default: Abi = if (builtin.os.tag.isDarwin()) .darwin else .aix; 21 | } else if (builtin.cpu.arch.isPowerPC64()) packed struct(i32) { 22 | linux_align_structs: bool, 23 | linux_long_double_128: bool, 24 | linux_long_double_128_ieee: bool, 25 | linux: bool, 26 | _pad: i28 = 0, 27 | 28 | pub const default: Abi = .{ 29 | .linux_align_structs = !(builtin.cpu.arch == .powerpc64 and builtin.abi.isGnu()), 30 | .linux_long_double_128 = !builtin.abi.isMusl(), 31 | .linux_long_double_128_ieee = false, 32 | .linux = true, 33 | }; 34 | } else packed struct(i32) { 35 | sysv_soft_float: bool, 36 | sysv_return_structs: bool, 37 | sysv_long_double_128_ibm: bool, 38 | sysv: bool, 39 | sysv_long_double_128: bool, 40 | _pad: i27 = 0, 41 | 42 | pub const default: Abi = .{ 43 | .sysv_soft_float = false, 44 | .sysv_return_structs = switch (builtin.os.tag) { 45 | .freebsd, .netbsd, .openbsd => true, 46 | else => false, 47 | }, 48 | .sysv_long_double_128_ibm = !builtin.abi.isMusl(), 49 | .sysv = true, 50 | .sysv_long_double_128 = !builtin.abi.isMusl(), 51 | }; 52 | }; 53 | 54 | pub const Function = if (!builtin.os.tag.isDarwin() and builtin.os.tag != .aix) extern struct { 55 | abi: Abi, 56 | param_count: c_uint, 57 | param_types: ?[*]*ffi.Type, 58 | return_type: *ffi.Type, 59 | bytes: c_uint, 60 | flags: c_uint, 61 | _private1: c_uint, 62 | 63 | pub const prepare = function.prepare; 64 | 65 | pub const prepareVarArgs = function.prepareVarArgs; 66 | 67 | pub const call = function.call; 68 | } else default.Function(Abi); 69 | 70 | pub const Closure = default.Closure(Function, if (builtin.cpu.arch == .powerpc64le) 71 | 32 72 | else if (builtin.cpu.arch.isPowerPC64() or builtin.os.tag == .aix) 73 | if (builtin.os.tag.isDarwin()) 48 else 24 74 | else 75 | 40); 76 | -------------------------------------------------------------------------------- /lib/ffi/riscv.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | const ffi = @import("../ffi.zig"); 5 | const function = @import("../function.zig"); 6 | 7 | pub const Abi = default.Abi; 8 | 9 | pub const Function = extern struct { 10 | abi: Abi, 11 | param_count: c_uint, 12 | param_types: ?[*]*ffi.Type, 13 | return_type: *ffi.Type, 14 | bytes: c_uint, 15 | flags: c_uint, 16 | _private1: c_uint, 17 | _private2: c_uint, 18 | 19 | pub const prepare = function.prepare; 20 | 21 | pub const prepareVarArgs = function.prepareVarArgs; 22 | 23 | pub const call = function.call; 24 | }; 25 | 26 | pub const Closure = default.Closure(Function, 24); 27 | -------------------------------------------------------------------------------- /lib/ffi/s390x.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | 5 | pub const have_complex_type = true; 6 | 7 | pub const Abi = default.Abi; 8 | 9 | pub const Function = default.Function(Abi); 10 | 11 | pub const Closure = default.Closure(Function, 32); 12 | -------------------------------------------------------------------------------- /lib/ffi/sparc.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const default = @import("../default.zig"); 6 | const ffi = @import("../ffi.zig"); 7 | const function = @import("../function.zig"); 8 | 9 | pub const have_complex_type = true; 10 | 11 | pub const Abi = if (builtin.cpu.arch == .sparc64) enum(i32) { 12 | v9 = 1, 13 | _, 14 | 15 | pub const default: Abi = .v9; 16 | } else enum(i32) { 17 | v8 = 1, 18 | _, 19 | 20 | pub const default: Abi = .v8; 21 | }; 22 | 23 | pub const Function = if (builtin.cpu.arch == .sparc64) extern struct { 24 | abi: Abi, 25 | param_count: c_uint, 26 | param_types: ?[*]*ffi.Type, 27 | return_type: *ffi.Type, 28 | bytes: c_uint, 29 | flags: c_uint, 30 | _private1: c_uint, 31 | 32 | pub const prepare = function.prepare; 33 | 34 | pub const prepareVarArgs = function.prepareVarArgs; 35 | 36 | pub const call = function.call; 37 | } else default.Function(Abi); 38 | 39 | pub const Closure = default.Closure(Function, if (builtin.cpu.arch == .sparc64) 24 else 16); 40 | -------------------------------------------------------------------------------- /lib/ffi/x86.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const builtin = @import("builtin"); 4 | 5 | const default = @import("../default.zig"); 6 | 7 | pub const have_complex_type = true; 8 | 9 | const arg_longlong = if (builtin.cpu.arch == .x86_64) switch (builtin.abi) { 10 | .gnux32, .muslx32 => true, 11 | else => builtin.os.tag == .windows, 12 | } else false; 13 | 14 | pub const uarg = if (arg_longlong) c_ulonglong else c_ulong; 15 | pub const sarg = if (arg_longlong) c_longlong else c_long; 16 | 17 | pub const Abi = if (builtin.os.tag == .windows) 18 | if (builtin.cpu.arch == .x86_64) enum(i32) { 19 | win64 = 1, 20 | gnuw64 = 2, 21 | _, 22 | 23 | pub const default: Abi = if (builtin.abi == .msvc or builtin.abi == .itanium) .win64 else .gnuw64; 24 | } else enum(i32) { 25 | sysv = 1, 26 | stdcall = 2, 27 | thiscall = 3, 28 | fastcall = 4, 29 | cdecl = 5, 30 | pascal = 6, 31 | register = 7, 32 | _, 33 | 34 | pub const default: Abi = .cdecl; 35 | } 36 | else if (builtin.cpu.arch == .x86_64) enum(i32) { 37 | unix64 = 2, 38 | win64 = 3, 39 | gnuw64 = 4, 40 | _, 41 | 42 | pub const default: Abi = .unix64; 43 | } else enum(i32) { 44 | sysv = 1, 45 | thiscall = 3, 46 | fastcall = 4, 47 | stdcall = 5, 48 | pascal = 6, 49 | register = 7, 50 | cdecl = 8, 51 | _, 52 | 53 | pub const default: Abi = .sysv; 54 | }; 55 | 56 | pub const Function = default.Function(Abi); 57 | 58 | pub const Closure = default.Closure(Function, if (builtin.cpu.arch == .x86_64) 32 else 16); 59 | -------------------------------------------------------------------------------- /lib/ffi/xtensa.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const default = @import("../default.zig"); 4 | 5 | pub const Abi = default.Abi; 6 | 7 | pub const Function = default.Function(Abi); 8 | 9 | pub const Closure = default.Closure(Function, 24); 10 | -------------------------------------------------------------------------------- /lib/function.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const ffi = @import("ffi.zig"); 4 | const utils = @import("utils.zig"); 5 | 6 | pub fn prepare( 7 | self: *ffi.Function, 8 | abi: ffi.Abi, 9 | param_count: c_uint, 10 | param_types: ?[*]*ffi.Type, 11 | return_type: *ffi.Type, 12 | ) ffi.Error!void { 13 | return utils.wrap(ffi.ffi_prep_cif(self, abi, param_count, return_type, param_types)); 14 | } 15 | 16 | pub fn prepareVarArgs( 17 | self: *ffi.Function, 18 | abi: ffi.Abi, 19 | fixed_param_count: c_uint, 20 | var_param_count: c_uint, 21 | param_types: ?[*]*ffi.Type, 22 | return_type: *ffi.Type, 23 | ) ffi.Error!void { 24 | return utils.wrap( 25 | ffi.ffi_prep_cif_var( 26 | self, 27 | abi, 28 | fixed_param_count, 29 | fixed_param_count + var_param_count, 30 | return_type, 31 | param_types, 32 | ), 33 | ); 34 | } 35 | 36 | pub fn call( 37 | self: *ffi.Function, 38 | callee: anytype, 39 | args: ?[*]*anyopaque, 40 | result: ?*anyopaque, 41 | ) void { 42 | const ty = @typeInfo(@TypeOf(callee)); 43 | 44 | switch (ty) { 45 | .pointer => |ptr| if (@typeInfo(ptr.child) != .@"fn") 46 | @compileError("callee must have function pointer type."), 47 | else => {}, 48 | } 49 | 50 | ffi.ffi_call(self, @ptrCast(callee), result, args); 51 | } 52 | -------------------------------------------------------------------------------- /lib/utils.zig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | const ffi = @import("ffi.zig"); 4 | 5 | pub fn wrap(status: ffi.Status) ffi.Error!void { 6 | return switch (status) { 7 | .ok => {}, 8 | .bad_type_definition => error.BadTypeDefinition, 9 | .bad_abi => error.BadAbi, 10 | .bad_argument_type => error.BadArgumentType, 11 | _ => error.Unexpected, 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/aarch64/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | ``Software''), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 21 | 22 | #ifndef LIBFFI_TARGET_H 23 | #define LIBFFI_TARGET_H 24 | 25 | #ifndef LIBFFI_H 26 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 27 | #endif 28 | 29 | #ifndef LIBFFI_ASM 30 | #ifdef __ILP32__ 31 | #define FFI_SIZEOF_ARG 8 32 | #define FFI_SIZEOF_JAVA_RAW 4 33 | typedef unsigned long long ffi_arg; 34 | typedef signed long long ffi_sarg; 35 | #elif defined(_WIN32) 36 | #define FFI_SIZEOF_ARG 8 37 | typedef unsigned long long ffi_arg; 38 | typedef signed long long ffi_sarg; 39 | #else 40 | typedef unsigned long ffi_arg; 41 | typedef signed long ffi_sarg; 42 | #endif 43 | 44 | typedef enum ffi_abi 45 | { 46 | FFI_FIRST_ABI = 0, 47 | FFI_SYSV, 48 | FFI_WIN64, 49 | FFI_LAST_ABI, 50 | #if defined(_WIN32) 51 | FFI_DEFAULT_ABI = FFI_WIN64 52 | #else 53 | FFI_DEFAULT_ABI = FFI_SYSV 54 | #endif 55 | } ffi_abi; 56 | #endif 57 | 58 | /* ---- Definitions for closures ----------------------------------------- */ 59 | 60 | #define FFI_CLOSURES 1 61 | #define FFI_NATIVE_RAW_API 0 62 | 63 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 64 | 65 | #ifdef __MACH__ 66 | #define FFI_TRAMPOLINE_SIZE 16 67 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 16 68 | #else 69 | #error "No trampoline table implementation" 70 | #endif 71 | 72 | #else 73 | #define FFI_TRAMPOLINE_SIZE 24 74 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 75 | #endif 76 | 77 | #ifdef _WIN32 78 | #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic 79 | #endif 80 | #define FFI_TARGET_SPECIFIC_VARIADIC 81 | 82 | /* ---- Internal ---- */ 83 | 84 | #if defined (__APPLE__) 85 | #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs 86 | #elif !defined(_WIN32) && !defined(__ANDROID__) 87 | /* iOS, Windows and Android reserve x18 for the system. Disable Go closures until 88 | a new static chain is chosen. */ 89 | #define FFI_GO_CLOSURES 1 90 | #endif 91 | 92 | #ifndef _WIN32 93 | /* No complex type on Windows */ 94 | #define FFI_TARGET_HAS_COMPLEX_TYPE 95 | #endif 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/aarch64/internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Permission is hereby granted, free of charge, to any person obtaining 3 | a copy of this software and associated documentation files (the 4 | ``Software''), to deal in the Software without restriction, including 5 | without limitation the rights to use, copy, modify, merge, publish, 6 | distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so, subject to 8 | the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be 11 | included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 17 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 19 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 20 | 21 | #define AARCH64_RET_VOID 0 22 | #define AARCH64_RET_INT64 1 23 | #define AARCH64_RET_INT128 2 24 | 25 | #define AARCH64_RET_UNUSED3 3 26 | #define AARCH64_RET_UNUSED4 4 27 | #define AARCH64_RET_UNUSED5 5 28 | #define AARCH64_RET_UNUSED6 6 29 | #define AARCH64_RET_UNUSED7 7 30 | 31 | /* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4, 32 | so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT). */ 33 | #define AARCH64_RET_S4 8 34 | #define AARCH64_RET_S3 9 35 | #define AARCH64_RET_S2 10 36 | #define AARCH64_RET_S1 11 37 | 38 | #define AARCH64_RET_D4 12 39 | #define AARCH64_RET_D3 13 40 | #define AARCH64_RET_D2 14 41 | #define AARCH64_RET_D1 15 42 | 43 | #define AARCH64_RET_Q4 16 44 | #define AARCH64_RET_Q3 17 45 | #define AARCH64_RET_Q2 18 46 | #define AARCH64_RET_Q1 19 47 | 48 | /* Note that each of the sub-64-bit integers gets two entries. */ 49 | #define AARCH64_RET_UINT8 20 50 | #define AARCH64_RET_UINT16 22 51 | #define AARCH64_RET_UINT32 24 52 | 53 | #define AARCH64_RET_SINT8 26 54 | #define AARCH64_RET_SINT16 28 55 | #define AARCH64_RET_SINT32 30 56 | 57 | #define AARCH64_RET_MASK 31 58 | 59 | #define AARCH64_RET_IN_MEM (1 << 5) 60 | #define AARCH64_RET_NEED_COPY (1 << 6) 61 | 62 | #define AARCH64_FLAG_ARG_V_BIT 7 63 | #define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT) 64 | #define AARCH64_FLAG_VARARG (1 << 8) 65 | 66 | #define N_X_ARG_REG 8 67 | #define N_V_ARG_REG 8 68 | #define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8) 69 | 70 | #if defined(FFI_EXEC_STATIC_TRAMP) 71 | /* 72 | * For the trampoline code table mapping, a mapping size of 16K is chosen to 73 | * cover the base page sizes of 4K and 16K. 74 | */ 75 | #define AARCH64_TRAMP_MAP_SHIFT 14 76 | #define AARCH64_TRAMP_MAP_SIZE (1 << AARCH64_TRAMP_MAP_SHIFT) 77 | #define AARCH64_TRAMP_SIZE 32 78 | 79 | #endif 80 | 81 | /* Helpers for writing assembly compatible with arm ptr auth */ 82 | #ifdef LIBFFI_ASM 83 | 84 | #if defined(HAVE_ARM64E_PTRAUTH) 85 | /* ARM64E ABI For Darwin */ 86 | #define SIGN_LR pacibsp 87 | #define SIGN_LR_WITH_REG(x) pacib lr, x 88 | #define AUTH_LR_AND_RET retab 89 | #define AUTH_LR_WITH_REG(x) autib lr, x 90 | #define BRANCH_AND_LINK_TO_REG blraaz 91 | #define SIGN_LR_LINUX_ONLY 92 | #define BRANCH_TO_REG braaz 93 | #define PAC_CFI_WINDOW_SAVE 94 | #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 95 | /* Linux PAC Support */ 96 | #elif defined(__ARM_FEATURE_PAC_DEFAULT) 97 | #define GNU_PROPERTY_AARCH64_POINTER_AUTH (1 << 1) 98 | #define PAC_CFI_WINDOW_SAVE cfi_window_save 99 | #define TMP_REG x9 100 | #define BRANCH_TO_REG br 101 | #define BRANCH_AND_LINK_TO_REG blr 102 | #define SIGN_LR_LINUX_ONLY SIGN_LR 103 | /* Which key to sign with? */ 104 | #if (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 105 | /* Signed with A-key */ 106 | #define SIGN_LR hint #25 /* paciasp */ 107 | #define AUTH_LR hint #29 /* autiasp */ 108 | #else 109 | /* Signed with B-key */ 110 | #define SIGN_LR hint #27 /* pacibsp */ 111 | #define AUTH_LR hint #31 /* autibsp */ 112 | #endif /* __ARM_FEATURE_PAC_DEFAULT */ 113 | #define AUTH_LR_WITH_REG(x) _auth_lr_with_reg x 114 | .macro _auth_lr_with_reg modifier 115 | mov TMP_REG, sp 116 | mov sp, \modifier 117 | AUTH_LR 118 | mov sp, TMP_REG 119 | .endm 120 | #define SIGN_LR_WITH_REG(x) _sign_lr_with_reg x 121 | .macro _sign_lr_with_reg modifier 122 | mov TMP_REG, sp 123 | mov sp, \modifier 124 | SIGN_LR 125 | mov sp, TMP_REG 126 | .endm 127 | #define AUTH_LR_AND_RET _auth_lr_and_ret modifier 128 | .macro _auth_lr_and_ret modifier 129 | AUTH_LR 130 | ret 131 | .endm 132 | #undef TMP_REG 133 | 134 | /* No Pointer Auth */ 135 | #else 136 | #define SIGN_LR 137 | #define SIGN_LR_WITH_REG(x) 138 | #define AUTH_LR_AND_RET ret 139 | #define AUTH_LR_WITH_REG(x) 140 | #define BRANCH_AND_LINK_TO_REG blr 141 | #define SIGN_LR_LINUX_ONLY 142 | #define BRANCH_TO_REG br 143 | #define PAC_CFI_WINDOW_SAVE 144 | #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 145 | #endif /* HAVE_ARM64E_PTRAUTH */ 146 | #endif /* LIBFFI_ASM */ 147 | -------------------------------------------------------------------------------- /src/alpha/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for Alpha. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_OSF, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_OSF 44 | } ffi_abi; 45 | #endif 46 | 47 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 48 | #define FFI_TARGET_HAS_COMPLEX_TYPE 49 | 50 | /* ---- Definitions for closures ----------------------------------------- */ 51 | 52 | #define FFI_CLOSURES 1 53 | #define FFI_GO_CLOSURES 1 54 | #define FFI_TRAMPOLINE_SIZE 24 55 | #define FFI_NATIVE_RAW_API 0 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/alpha/internal.h: -------------------------------------------------------------------------------- 1 | #define ALPHA_ST_VOID 0 2 | #define ALPHA_ST_INT 1 3 | #define ALPHA_ST_FLOAT 2 4 | #define ALPHA_ST_DOUBLE 3 5 | #define ALPHA_ST_CPLXF 4 6 | #define ALPHA_ST_CPLXD 5 7 | 8 | #define ALPHA_LD_VOID 0 9 | #define ALPHA_LD_INT64 1 10 | #define ALPHA_LD_INT32 2 11 | #define ALPHA_LD_UINT16 3 12 | #define ALPHA_LD_SINT16 4 13 | #define ALPHA_LD_UINT8 5 14 | #define ALPHA_LD_SINT8 6 15 | #define ALPHA_LD_FLOAT 7 16 | #define ALPHA_LD_DOUBLE 8 17 | #define ALPHA_LD_CPLXF 9 18 | #define ALPHA_LD_CPLXD 10 19 | 20 | #define ALPHA_ST_SHIFT 0 21 | #define ALPHA_LD_SHIFT 8 22 | #define ALPHA_RET_IN_MEM 0x10000 23 | #define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S)) 24 | -------------------------------------------------------------------------------- /src/arc/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) 4 | Target configuration macros for ARC. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- Generic type definitions ----------------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi 41 | { 42 | FFI_FIRST_ABI = 0, 43 | #if __SIZEOF_POINTER__ == 8 44 | FFI_ARC64, 45 | #else 46 | FFI_ARCOMPACT, 47 | #endif 48 | FFI_LAST_ABI, 49 | #if __SIZEOF_POINTER__ == 8 50 | FFI_DEFAULT_ABI = FFI_ARC64 51 | #else 52 | FFI_DEFAULT_ABI = FFI_ARCOMPACT 53 | #endif 54 | } ffi_abi; 55 | #endif 56 | 57 | #define FFI_CLOSURES 1 58 | #define FFI_GO_CLOSURES 1 59 | #if __SIZEOF_POINTER__ == 8 60 | #define FFI_TRAMPOLINE_SIZE 24 61 | #else 62 | #define FFI_TRAMPOLINE_SIZE 12 63 | #endif 64 | 65 | #define FFI_NATIVE_RAW_API 0 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/arm/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2010 CodeSourcery 4 | Copyright (c) 1996-2003 Red Hat, Inc. 5 | 6 | Target configuration macros for ARM. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | 28 | ----------------------------------------------------------------------- */ 29 | 30 | #ifndef LIBFFI_TARGET_H 31 | #define LIBFFI_TARGET_H 32 | 33 | #ifndef LIBFFI_H 34 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_VFP, 45 | FFI_LAST_ABI, 46 | #if defined(__ARM_PCS_VFP) || defined(_WIN32) 47 | FFI_DEFAULT_ABI = FFI_VFP, 48 | #else 49 | FFI_DEFAULT_ABI = FFI_SYSV, 50 | #endif 51 | } ffi_abi; 52 | #endif 53 | 54 | #define FFI_EXTRA_CIF_FIELDS \ 55 | int vfp_used; \ 56 | unsigned short vfp_reg_free, vfp_nargs; \ 57 | signed char vfp_args[16] \ 58 | 59 | #define FFI_TARGET_SPECIFIC_VARIADIC 60 | #ifndef _WIN32 61 | #define FFI_TARGET_HAS_COMPLEX_TYPE 62 | #endif 63 | 64 | /* ---- Definitions for closures ----------------------------------------- */ 65 | 66 | #define FFI_CLOSURES 1 67 | #define FFI_GO_CLOSURES 1 68 | #define FFI_NATIVE_RAW_API 0 69 | 70 | #if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE 71 | 72 | #ifdef __MACH__ 73 | #define FFI_TRAMPOLINE_SIZE 12 74 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET 8 75 | #else 76 | #error "No trampoline table implementation" 77 | #endif 78 | 79 | #else 80 | #ifdef _WIN32 81 | #define FFI_TRAMPOLINE_SIZE 16 82 | #define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12 83 | #else 84 | #define FFI_TRAMPOLINE_SIZE 12 85 | #endif 86 | #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE 87 | #endif 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/arm/internal.h: -------------------------------------------------------------------------------- 1 | #define ARM_TYPE_VFP_S 0 2 | #define ARM_TYPE_VFP_D 1 3 | #define ARM_TYPE_VFP_N 2 4 | #define ARM_TYPE_INT64 3 5 | #define ARM_TYPE_INT 4 6 | #define ARM_TYPE_VOID 5 7 | #define ARM_TYPE_STRUCT 6 8 | 9 | #if defined(FFI_EXEC_STATIC_TRAMP) 10 | /* 11 | * For the trampoline table mapping, a mapping size of 4K (base page size) 12 | * is chosen. 13 | */ 14 | #define ARM_TRAMP_MAP_SHIFT 12 15 | #define ARM_TRAMP_MAP_SIZE (1 << ARM_TRAMP_MAP_SHIFT) 16 | #define ARM_TRAMP_SIZE 20 17 | #endif 18 | -------------------------------------------------------------------------------- /src/avr32/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2009 Bradley Smith 4 | Target configuration macros for AVR32. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_SYSV, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_SYSV 44 | } ffi_abi; 45 | #endif 46 | 47 | #define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag 48 | 49 | /* Definitions for closures */ 50 | 51 | #define FFI_CLOSURES 1 52 | #define FFI_TRAMPOLINE_SIZE 36 53 | #define FFI_NATIVE_RAW_API 0 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/avr32/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 2009 Bradley Smith 3 | 4 | AVR32 Foreign Function Interface 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | --------------------------------------------------------------------- */ 25 | 26 | #define LIBFFI_ASM 27 | #include 28 | #include 29 | 30 | /* r12: ffi_prep_args 31 | * r11: &ecif 32 | * r10: size 33 | * r9: cif->flags 34 | * r8: ecif.rvalue 35 | * sp+0: cif->rstruct_flag 36 | * sp+4: fn */ 37 | 38 | .text 39 | .align 1 40 | .globl ffi_call_SYSV 41 | .type ffi_call_SYSV, @function 42 | ffi_call_SYSV: 43 | stm --sp, r0,r1,lr 44 | stm --sp, r8-r12 45 | mov r0, sp 46 | 47 | /* Make room for all of the new args. */ 48 | sub sp, r10 49 | /* Pad to make way for potential skipped registers */ 50 | sub sp, 20 51 | 52 | /* Call ffi_prep_args(stack, &ecif). */ 53 | /* r11 already set */ 54 | mov r1, r12 55 | mov r12, sp 56 | icall r1 57 | 58 | /* Save new argument size */ 59 | mov r1, r12 60 | 61 | /* Move first 5 parameters in registers. */ 62 | ldm sp++, r8-r12 63 | 64 | /* call (fn) (...). */ 65 | ld.w r1, r0[36] 66 | icall r1 67 | 68 | /* Remove the space we pushed for the args. */ 69 | mov sp, r0 70 | 71 | /* Load r1 with the rstruct flag. */ 72 | ld.w r1, sp[32] 73 | 74 | /* Load r9 with the return type code. */ 75 | ld.w r9, sp[12] 76 | 77 | /* Load r8 with the return value pointer. */ 78 | ld.w r8, sp[16] 79 | 80 | /* If the return value pointer is NULL, assume no return value. */ 81 | cp.w r8, 0 82 | breq .Lend 83 | 84 | /* Check if return type is actually a struct */ 85 | cp.w r1, 0 86 | breq 1f 87 | 88 | /* Return 8bit */ 89 | cp.w r9, FFI_TYPE_UINT8 90 | breq .Lstore8 91 | 92 | /* Return 16bit */ 93 | cp.w r9, FFI_TYPE_UINT16 94 | breq .Lstore16 95 | 96 | 1: 97 | /* Return 32bit */ 98 | cp.w r9, FFI_TYPE_UINT32 99 | breq .Lstore32 100 | cp.w r9, FFI_TYPE_UINT16 101 | breq .Lstore32 102 | cp.w r9, FFI_TYPE_UINT8 103 | breq .Lstore32 104 | 105 | /* Return 64bit */ 106 | cp.w r9, FFI_TYPE_UINT64 107 | breq .Lstore64 108 | 109 | /* Didn't match anything */ 110 | bral .Lend 111 | 112 | .Lstore64: 113 | st.w r8[0], r11 114 | st.w r8[4], r10 115 | bral .Lend 116 | 117 | .Lstore32: 118 | st.w r8[0], r12 119 | bral .Lend 120 | 121 | .Lstore16: 122 | st.h r8[0], r12 123 | bral .Lend 124 | 125 | .Lstore8: 126 | st.b r8[0], r12 127 | bral .Lend 128 | 129 | .Lend: 130 | sub sp, -20 131 | ldm sp++, r0,r1,pc 132 | 133 | .size ffi_call_SYSV, . - ffi_call_SYSV 134 | 135 | 136 | /* r12: __ctx 137 | * r11: __rstruct_flag 138 | * r10: __inner */ 139 | 140 | .align 1 141 | .globl ffi_closure_SYSV 142 | .type ffi_closure_SYSV, @function 143 | ffi_closure_SYSV: 144 | stm --sp, r0,lr 145 | mov r0, r11 146 | mov r8, r10 147 | sub r10, sp, -8 148 | sub sp, 12 149 | st.w sp[8], sp 150 | sub r11, sp, -8 151 | icall r8 152 | 153 | /* Check if return type is actually a struct */ 154 | cp.w r0, 0 155 | breq 1f 156 | 157 | /* Return 8bit */ 158 | cp.w r12, FFI_TYPE_UINT8 159 | breq .Lget8 160 | 161 | /* Return 16bit */ 162 | cp.w r12, FFI_TYPE_UINT16 163 | breq .Lget16 164 | 165 | 1: 166 | /* Return 32bit */ 167 | cp.w r12, FFI_TYPE_UINT32 168 | breq .Lget32 169 | cp.w r12, FFI_TYPE_UINT16 170 | breq .Lget32 171 | cp.w r12, FFI_TYPE_UINT8 172 | breq .Lget32 173 | 174 | /* Return 64bit */ 175 | cp.w r12, FFI_TYPE_UINT64 176 | breq .Lget64 177 | 178 | /* Didn't match anything */ 179 | bral .Lclend 180 | 181 | .Lget64: 182 | ld.w r11, sp[0] 183 | ld.w r10, sp[4] 184 | bral .Lclend 185 | 186 | .Lget32: 187 | ld.w r12, sp[0] 188 | bral .Lclend 189 | 190 | .Lget16: 191 | ld.uh r12, sp[0] 192 | bral .Lclend 193 | 194 | .Lget8: 195 | ld.ub r12, sp[0] 196 | bral .Lclend 197 | 198 | .Lclend: 199 | sub sp, -12 200 | ldm sp++, r0,lr 201 | sub sp, -20 202 | mov pc, lr 203 | 204 | .size ffi_closure_SYSV, . - ffi_closure_SYSV 205 | 206 | #if defined __ELF__ && defined __linux__ 207 | .section .note.GNU-stack,"",@progbits 208 | #endif 209 | -------------------------------------------------------------------------------- /src/bfin/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca 3 | 4 | Blackfin Foreign Function Interface 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_ASM 31 | typedef unsigned long ffi_arg; 32 | typedef signed long ffi_sarg; 33 | 34 | typedef enum ffi_abi { 35 | FFI_FIRST_ABI = 0, 36 | FFI_SYSV, 37 | FFI_LAST_ABI, 38 | FFI_DEFAULT_ABI = FFI_SYSV 39 | } ffi_abi; 40 | #endif 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /src/bfin/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca , 3 | Paulo Pizarro 4 | 5 | Blackfin Foreign Function Interface 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | ``Software''), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | ----------------------------------------------------------------------- */ 27 | 28 | #define LIBFFI_ASM 29 | #include 30 | #include 31 | 32 | .text 33 | .align 4 34 | 35 | /* 36 | There is a "feature" in the bfin toolchain that it puts a _ before function names 37 | that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV 38 | */ 39 | .global _ffi_call_SYSV; 40 | .type _ffi_call_SYSV, STT_FUNC; 41 | .func ffi_call_SYSV 42 | 43 | /* 44 | cif->bytes = R0 (fp+8) 45 | &ecif = R1 (fp+12) 46 | ffi_prep_args = R2 (fp+16) 47 | ret_type = stack (fp+20) 48 | ecif.rvalue = stack (fp+24) 49 | fn = stack (fp+28) 50 | got (fp+32) 51 | 52 | There is room for improvement here (we can use temporary registers 53 | instead of saving the values in the memory) 54 | REGS: 55 | P5 => Stack pointer (function arguments) 56 | R5 => cif->bytes 57 | R4 => ret->type 58 | 59 | FP-20 = P3 60 | FP-16 = SP (parameters area) 61 | FP-12 = SP (temp) 62 | FP-08 = function return part 1 [R0] 63 | FP-04 = function return part 2 [R1] 64 | */ 65 | 66 | _ffi_call_SYSV: 67 | .prologue: 68 | LINK 20; 69 | [FP-20] = P3; 70 | [FP+8] = R0; 71 | [FP+12] = R1; 72 | [FP+16] = R2; 73 | 74 | .allocate_stack: 75 | //alocate cif->bytes into the stack 76 | R1 = [FP+8]; 77 | R0 = SP; 78 | R0 = R0 - R1; 79 | R1 = 4; 80 | R0 = R0 - R1; 81 | [FP-12] = SP; 82 | SP = R0; 83 | [FP-16] = SP; 84 | 85 | .call_prep_args: 86 | //get the addr of prep_args 87 | P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4]; 88 | P1 = [P0]; 89 | P3 = [P0+4]; 90 | R0 = [FP-16];//SP (parameter area) 91 | R1 = [FP+12];//ecif 92 | call (P1); 93 | 94 | .call_user_function: 95 | //ajust SP so as to allow the user function access the parameters on the stack 96 | SP = [FP-16]; //point to function parameters 97 | R0 = [SP]; 98 | R1 = [SP+4]; 99 | R2 = [SP+8]; 100 | //load user function address 101 | P0 = FP; 102 | P0 +=28; 103 | P1 = [P0]; 104 | P1 = [P1]; 105 | P3 = [P0+4]; 106 | /* 107 | For functions returning aggregate values (struct) occupying more than 8 bytes, 108 | the caller allocates the return value object on the stack and the address 109 | of this object is passed to the callee as a hidden argument in register P0. 110 | */ 111 | P0 = [FP+24]; 112 | 113 | call (P1); 114 | SP = [FP-12]; 115 | .compute_return: 116 | P2 = [FP-20]; 117 | [FP-8] = R0; 118 | [FP-4] = R1; 119 | 120 | R0 = [FP+20]; 121 | R1 = R0 << 2; 122 | 123 | R0 = [P2+.rettable@GOT17M4]; 124 | R0 = R1 + R0; 125 | P2 = R0; 126 | R1 = [P2]; 127 | 128 | P2 = [FP+-20]; 129 | R0 = [P2+.rettable@GOT17M4]; 130 | R0 = R1 + R0; 131 | P2 = R0; 132 | R0 = [FP-8]; 133 | R1 = [FP-4]; 134 | jump (P2); 135 | 136 | /* 137 | #define FFIBFIN_RET_VOID 0 138 | #define FFIBFIN_RET_BYTE 1 139 | #define FFIBFIN_RET_HALFWORD 2 140 | #define FFIBFIN_RET_INT64 3 141 | #define FFIBFIN_RET_INT32 4 142 | */ 143 | .align 4 144 | .align 4 145 | .rettable: 146 | .dd .epilogue - .rettable 147 | .dd .rbyte - .rettable; 148 | .dd .rhalfword - .rettable; 149 | .dd .rint64 - .rettable; 150 | .dd .rint32 - .rettable; 151 | 152 | .rbyte: 153 | P0 = [FP+24]; 154 | R0 = R0.B (Z); 155 | [P0] = R0; 156 | JUMP .epilogue 157 | .rhalfword: 158 | P0 = [FP+24]; 159 | R0 = R0.L; 160 | [P0] = R0; 161 | JUMP .epilogue 162 | .rint64: 163 | P0 = [FP+24];// &rvalue 164 | [P0] = R0; 165 | [P0+4] = R1; 166 | JUMP .epilogue 167 | .rint32: 168 | P0 = [FP+24]; 169 | [P0] = R0; 170 | .epilogue: 171 | R0 = [FP+8]; 172 | R1 = [FP+12]; 173 | R2 = [FP+16]; 174 | P3 = [FP-20]; 175 | UNLINK; 176 | RTS; 177 | 178 | .size _ffi_call_SYSV,.-_ffi_call_SYSV; 179 | .endfunc 180 | -------------------------------------------------------------------------------- /src/cris/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for CRIS. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_SYSV, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_SYSV 44 | } ffi_abi; 45 | #endif 46 | 47 | /* ---- Definitions for closures ----------------------------------------- */ 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36 51 | #define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4) 52 | #define FFI_TRAMPOLINE_SIZE \ 53 | (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE) 54 | #define FFI_NATIVE_RAW_API 0 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/cris/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 2004 Simon Posnjak 3 | Copyright (c) 2005 Axis Communications AB 4 | 5 | CRIS Foreign Function Interface 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | ``Software''), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #define LIBFFI_ASM 28 | #include 29 | #define CONCAT(x,y) x ## y 30 | #define XCONCAT(x,y) CONCAT (x, y) 31 | #define L(x) XCONCAT (__USER_LABEL_PREFIX__, x) 32 | 33 | .text 34 | 35 | ;; OK, when we get called we should have this (according to 36 | ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3). 37 | ;; 38 | ;; R10: ffi_prep_args (func. pointer) 39 | ;; R11: &ecif 40 | ;; R12: cif->bytes 41 | ;; R13: fig->flags 42 | ;; sp+0: ecif.rvalue 43 | ;; sp+4: fn (function pointer to the function that we need to call) 44 | 45 | .globl L(ffi_call_SYSV) 46 | .type L(ffi_call_SYSV),@function 47 | .hidden L(ffi_call_SYSV) 48 | 49 | L(ffi_call_SYSV): 50 | ;; Save the regs to the stack. 51 | push $srp 52 | ;; Used for stack pointer saving. 53 | push $r6 54 | ;; Used for function address pointer. 55 | push $r7 56 | ;; Used for stack pointer saving. 57 | push $r8 58 | ;; We save fig->flags to stack we will need them after we 59 | ;; call The Function. 60 | push $r13 61 | 62 | ;; Saving current stack pointer. 63 | move.d $sp,$r8 64 | move.d $sp,$r6 65 | 66 | ;; Move address of ffi_prep_args to r13. 67 | move.d $r10,$r13 68 | 69 | ;; Make room on the stack for the args of fn. 70 | sub.d $r12,$sp 71 | 72 | ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are: 73 | ;; r10 <-- stack pointer 74 | ;; r11 <-- &ecif (already there) 75 | move.d $sp,$r10 76 | 77 | ;; Call the function. 78 | jsr $r13 79 | 80 | ;; Save the size of the structures which are passed on stack. 81 | move.d $r10,$r7 82 | 83 | ;; Move first four args in to r10..r13. 84 | move.d [$sp+0],$r10 85 | move.d [$sp+4],$r11 86 | move.d [$sp+8],$r12 87 | move.d [$sp+12],$r13 88 | 89 | ;; Adjust the stack and check if any parameters are given on stack. 90 | addq 16,$sp 91 | sub.d $r7,$r6 92 | cmp.d $sp,$r6 93 | 94 | bpl go_on 95 | nop 96 | 97 | go_on_no_params_on_stack: 98 | move.d $r6,$sp 99 | 100 | go_on: 101 | ;; Discover if we need to put rval address in to r9. 102 | move.d [$r8+0],$r7 103 | cmpq FFI_TYPE_STRUCT,$r7 104 | bne call_now 105 | nop 106 | 107 | ;; Move rval address to $r9. 108 | move.d [$r8+20],$r9 109 | 110 | call_now: 111 | ;; Move address of The Function in to r7. 112 | move.d [$r8+24],$r7 113 | 114 | ;; Call The Function. 115 | jsr $r7 116 | 117 | ;; Reset stack. 118 | move.d $r8,$sp 119 | 120 | ;; Load rval type (fig->flags) in to r13. 121 | pop $r13 122 | 123 | ;; Detect rval type. 124 | cmpq FFI_TYPE_VOID,$r13 125 | beq epilogue 126 | 127 | cmpq FFI_TYPE_STRUCT,$r13 128 | beq epilogue 129 | 130 | cmpq FFI_TYPE_DOUBLE,$r13 131 | beq return_double_or_longlong 132 | 133 | cmpq FFI_TYPE_UINT64,$r13 134 | beq return_double_or_longlong 135 | 136 | cmpq FFI_TYPE_SINT64,$r13 137 | beq return_double_or_longlong 138 | nop 139 | 140 | ;; Just return the 32 bit value. 141 | ba return 142 | nop 143 | 144 | return_double_or_longlong: 145 | ;; Load half of the rval to r10 and the other half to r11. 146 | move.d [$sp+16],$r13 147 | move.d $r10,[$r13] 148 | addq 4,$r13 149 | move.d $r11,[$r13] 150 | ba epilogue 151 | nop 152 | 153 | return: 154 | ;; Load the rval to r10. 155 | move.d [$sp+16],$r13 156 | move.d $r10,[$r13] 157 | 158 | epilogue: 159 | pop $r8 160 | pop $r7 161 | pop $r6 162 | Jump [$sp+] 163 | 164 | .size ffi_call_SYSV,.-ffi_call_SYSV 165 | 166 | /* Save R10..R13 into an array, somewhat like varargs. Copy the next 167 | argument too, to simplify handling of any straddling parameter. 168 | Save R9 and SP after those. Jump to function handling the rest. 169 | Since this is a template, copied and the main function filled in by 170 | the user. */ 171 | 172 | .globl L(ffi_cris_trampoline_template) 173 | .type L(ffi_cris_trampoline_template),@function 174 | .hidden L(ffi_cris_trampoline_template) 175 | 176 | L(ffi_cris_trampoline_template): 177 | 0: 178 | /* The value we get for "PC" is right after the prefix instruction, 179 | two bytes from the beginning, i.e. 0b+2. */ 180 | move.d $r10,[$pc+2f-(0b+2)] 181 | move.d $pc,$r10 182 | 1: 183 | addq 2f-1b+4,$r10 184 | move.d $r11,[$r10+] 185 | move.d $r12,[$r10+] 186 | move.d $r13,[$r10+] 187 | move.d [$sp],$r11 188 | move.d $r11,[$r10+] 189 | move.d $r9,[$r10+] 190 | move.d $sp,[$r10+] 191 | subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10 192 | move.d 0,$r11 193 | 3: 194 | jump 0 195 | 2: 196 | .size ffi_cris_trampoline_template,.-0b 197 | 198 | /* This macro create a constant usable as "extern const int \name" in 199 | C from within libffi, when \name has no prefix decoration. */ 200 | 201 | .macro const name,value 202 | .globl \name 203 | .type \name,@object 204 | .hidden \name 205 | \name: 206 | .dword \value 207 | .size \name,4 208 | .endm 209 | 210 | /* Constants for offsets within the trampoline. We could do this with 211 | just symbols, avoiding memory contents and memory accesses, but the 212 | C usage code would look a bit stranger. */ 213 | 214 | const L(ffi_cris_trampoline_fn_offset),2b-4-0b 215 | const L(ffi_cris_trampoline_closure_offset),3b-4-0b 216 | -------------------------------------------------------------------------------- /src/csky/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2010 CodeSourcery 4 | Copyright (c) 1996-2003 Red Hat, Inc. 5 | 6 | Target configuration macros for CSKY. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | 28 | ----------------------------------------------------------------------- */ 29 | 30 | #ifndef LIBFFI_TARGET_H 31 | #define LIBFFI_TARGET_H 32 | 33 | #ifndef LIBFFI_H 34 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV, 46 | } ffi_abi; 47 | #endif 48 | 49 | #ifdef __CSKYABIV2__ 50 | #define FFI_ASM_ARGREG_SIZE 16 51 | #define TRAMPOLINE_SIZE 16 52 | #define FFI_TRAMPOLINE_SIZE 24 53 | #else 54 | #define FFI_ASM_ARGREG_SIZE 24 55 | #define TRAMPOLINE_SIZE 20 56 | #define FFI_TRAMPOLINE_SIZE 28 57 | #endif 58 | 59 | /* ---- Definitions for closures ----------------------------------------- */ 60 | 61 | #define FFI_CLOSURES 1 62 | #define FFI_NATIVE_RAW_API 0 63 | #endif 64 | -------------------------------------------------------------------------------- /src/debug.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | debug.c - Copyright (c) 1996 Red Hat, Inc. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | ``Software''), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | DEALINGS IN THE SOFTWARE. 23 | ----------------------------------------------------------------------- */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | /* General debugging routines */ 31 | 32 | void ffi_stop_here(void) 33 | { 34 | /* This function is only useful for debugging purposes. 35 | Place a breakpoint on ffi_stop_here to be notified of 36 | significant events. */ 37 | } 38 | 39 | /* This function should only be called via the FFI_ASSERT() macro */ 40 | 41 | NORETURN void ffi_assert(const char *expr, const char *file, int line) 42 | { 43 | fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line); 44 | ffi_stop_here(); 45 | abort(); 46 | } 47 | 48 | /* Perform a sanity check on an ffi_type structure */ 49 | 50 | void ffi_type_test(ffi_type *a, const char *file, int line) 51 | { 52 | FFI_ASSERT_AT(a != NULL, file, line); 53 | 54 | FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); 55 | FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); 56 | FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); 57 | FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX) 58 | || a->elements != NULL, file, line); 59 | FFI_ASSERT_AT(a->type != FFI_TYPE_COMPLEX 60 | || (a->elements != NULL 61 | && a->elements[0] != NULL && a->elements[1] == NULL), 62 | file, line); 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/frv/eabi.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | eabi.S - Copyright (c) 2004 Anthony Green 3 | 4 | FR-V Assembly glue. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #define LIBFFI_ASM 27 | #include 28 | #include 29 | 30 | .globl ffi_prep_args_EABI 31 | 32 | .text 33 | .p2align 4 34 | .globl ffi_call_EABI 35 | .type ffi_call_EABI, @function 36 | 37 | # gr8 : ffi_prep_args 38 | # gr9 : &ecif 39 | # gr10: cif->bytes 40 | # gr11: fig->flags 41 | # gr12: ecif.rvalue 42 | # gr13: fn 43 | 44 | ffi_call_EABI: 45 | addi sp, #-80, sp 46 | sti fp, @(sp, #24) 47 | addi sp, #24, fp 48 | movsg lr, gr5 49 | 50 | /* Make room for the new arguments. */ 51 | /* subi sp, fp, gr10 */ 52 | 53 | /* Store return address and incoming args on stack. */ 54 | sti gr5, @(fp, #8) 55 | sti gr8, @(fp, #-4) 56 | sti gr9, @(fp, #-8) 57 | sti gr10, @(fp, #-12) 58 | sti gr11, @(fp, #-16) 59 | sti gr12, @(fp, #-20) 60 | sti gr13, @(fp, #-24) 61 | 62 | sub sp, gr10, sp 63 | 64 | /* Call ffi_prep_args. */ 65 | ldi @(fp, #-4), gr4 66 | addi sp, #0, gr8 67 | ldi @(fp, #-8), gr9 68 | #ifdef __FRV_FDPIC__ 69 | ldd @(gr4, gr0), gr14 70 | calll @(gr14, gr0) 71 | #else 72 | calll @(gr4, gr0) 73 | #endif 74 | 75 | /* ffi_prep_args returns the new stack pointer. */ 76 | mov gr8, gr4 77 | 78 | ldi @(sp, #0), gr8 79 | ldi @(sp, #4), gr9 80 | ldi @(sp, #8), gr10 81 | ldi @(sp, #12), gr11 82 | ldi @(sp, #16), gr12 83 | ldi @(sp, #20), gr13 84 | 85 | /* Always copy the return value pointer into the hidden 86 | parameter register. This is only strictly necessary 87 | when we're returning an aggregate type, but it doesn't 88 | hurt to do this all the time, and it saves a branch. */ 89 | ldi @(fp, #-20), gr3 90 | 91 | /* Use the ffi_prep_args return value for the new sp. */ 92 | mov gr4, sp 93 | 94 | /* Call the target function. */ 95 | ldi @(fp, -24), gr4 96 | #ifdef __FRV_FDPIC__ 97 | ldd @(gr4, gr0), gr14 98 | calll @(gr14, gr0) 99 | #else 100 | calll @(gr4, gr0) 101 | #endif 102 | 103 | /* Store the result. */ 104 | ldi @(fp, #-16), gr10 /* fig->flags */ 105 | ldi @(fp, #-20), gr4 /* ecif.rvalue */ 106 | 107 | /* Is the return value stored in two registers? */ 108 | cmpi gr10, #8, icc0 109 | bne icc0, 0, .L2 110 | /* Yes, save them. */ 111 | sti gr8, @(gr4, #0) 112 | sti gr9, @(gr4, #4) 113 | bra .L3 114 | .L2: 115 | /* Is the return value a structure? */ 116 | cmpi gr10, #-1, icc0 117 | beq icc0, 0, .L3 118 | /* No, save a 4 byte return value. */ 119 | sti gr8, @(gr4, #0) 120 | .L3: 121 | 122 | /* Restore the stack, and return. */ 123 | ldi @(fp, 8), gr5 124 | ld @(fp, gr0), fp 125 | addi sp,#80,sp 126 | jmpl @(gr5,gr0) 127 | .size ffi_call_EABI, .-ffi_call_EABI 128 | 129 | -------------------------------------------------------------------------------- /src/frv/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2004 Red Hat, Inc. 4 | Target configuration macros for FR-V 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- System specific configurations ----------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_EABI, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_EABI 46 | } ffi_abi; 47 | #endif 48 | 49 | /* ---- Definitions for closures ----------------------------------------- */ 50 | 51 | #define FFI_CLOSURES 1 52 | #define FFI_NATIVE_RAW_API 0 53 | 54 | #ifdef __FRV_FDPIC__ 55 | /* Trampolines are 8 4-byte instructions long. */ 56 | #define FFI_TRAMPOLINE_SIZE (8*4) 57 | #else 58 | /* Trampolines are 5 4-byte instructions long. */ 59 | #define FFI_TRAMPOLINE_SIZE (5*4) 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/ia64/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for IA-64. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long long ffi_arg; 37 | typedef signed long long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_UNIX, /* Linux and all Unix variants use the same conventions */ 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_UNIX 44 | } ffi_abi; 45 | #endif 46 | 47 | /* ---- Definitions for closures ----------------------------------------- */ 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */ 51 | /* can be interpreted as a C function */ 52 | /* descriptor: */ 53 | #define FFI_TARGET_SPECIFIC_VARIADIC 1 54 | #define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/ia64/ia64_flags.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company 3 | 4 | IA64/unix Foreign Function Interface 5 | 6 | Original author: Hans Boehm, HP Labs 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | ----------------------------------------------------------------------- */ 28 | 29 | /* "Type" codes used between assembly and C. When used as a part of 30 | a cfi->flags value, the low byte will be these extra type codes, 31 | and bits 8-31 will be the actual size of the type. */ 32 | 33 | /* Small structures containing N words in integer registers. */ 34 | #define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1) 35 | 36 | /* Homogeneous Floating Point Aggregates (HFAs) which are returned 37 | in FP registers. */ 38 | #define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2) 39 | #define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3) 40 | #define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4) 41 | -------------------------------------------------------------------------------- /src/kvx/asm.h: -------------------------------------------------------------------------------- 1 | /* args are passed on registers from r0 up to r11 => 12*8 bytes */ 2 | #define REG_ARGS_SIZE (12*8) 3 | #define KVX_REGISTER_SIZE (8) 4 | #define KVX_ABI_SLOT_SIZE (KVX_REGISTER_SIZE) 5 | #define KVX_ABI_MAX_AGGREGATE_IN_REG_SIZE (4*KVX_ABI_SLOT_SIZE) 6 | -------------------------------------------------------------------------------- /src/kvx/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2020 Kalray 3 | 4 | KVX Target configuration macros 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- System specific configurations ----------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi { 41 | FFI_FIRST_ABI = 0, 42 | FFI_SYSV, 43 | FFI_LAST_ABI, 44 | FFI_DEFAULT_ABI = FFI_SYSV 45 | } ffi_abi; 46 | 47 | /* Those values are set depending on return type 48 | * they are used in the assembly code in sysv.S 49 | */ 50 | typedef enum kvx_intext_method { 51 | KVX_RET_NONE = 0, 52 | KVX_RET_SXBD = 1, 53 | KVX_RET_SXHD = 2, 54 | KVX_RET_SXWD = 3, 55 | KVX_RET_ZXBD = 4, 56 | KVX_RET_ZXHD = 5, 57 | KVX_RET_ZXWD = 6 58 | } kvx_intext_method; 59 | 60 | #endif 61 | 62 | /* ---- Definitions for closures ----------------------------------------- */ 63 | 64 | /* This is only to allow Python to compile 65 | * but closures are not supported yet 66 | */ 67 | #define FFI_CLOSURES 1 68 | #define FFI_TRAMPOLINE_SIZE 0 69 | 70 | #define FFI_NATIVE_RAW_API 0 71 | #define FFI_TARGET_SPECIFIC_VARIADIC 1 72 | #define FFI_TARGET_HAS_COMPLEX_TYPE 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /src/kvx/sysv.S: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Kalray 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | ``Software''), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 21 | 22 | #if defined(__kvx__) 23 | #define LIBFFI_ASM 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | .text 30 | .global ffi_call_SYSV 31 | .type ffi_call_SYSV, @function 32 | .type ffi_prep_args, @function 33 | .align 8 34 | 35 | /* ffi_call_SYSV 36 | 37 | r0: total size to allocate on stack 38 | r1: size of arg slots 39 | r2: extended cif structure, DO NOT REMOVE: it is used by ffi_prep_args() 40 | r3: return value address 41 | r4: function to call 42 | r5: integer sign extension method to be used 43 | */ 44 | ffi_call_SYSV: 45 | addd $r12 = $r12, -64 46 | so (-32)[$r12] = $r20r21r22r23 47 | ;; 48 | sd (0)[$r12] = $r24 49 | ;; 50 | get $r23 = $ra 51 | copyd $r20 = $r12 52 | sbfd $r12 = $r0, $r12 53 | ;; 54 | copyd $r0 = $r12 55 | copyd $r21 = $r3 56 | copyd $r22 = $r4 57 | copyd $r24 = $r5 58 | call ffi_prep_args 59 | ;; 60 | lo $r8r9r10r11 = (64)[$r12] 61 | ;; 62 | lo $r4r5r6r7 = (32)[$r12] 63 | ;; 64 | lo $r0r1r2r3 = (0)[$r12] 65 | copyd $r12 = $r0 66 | /* $r15 is the register used by the ABI to return big (>32 bytes) 67 | * structs by value. 68 | * It is also referred to as the "struct register" in the ABI. 69 | */ 70 | copyd $r15 = $r21 71 | icall $r22 72 | ;; 73 | pcrel $r4 = @pcrel(.Ltable) 74 | cb.deqz $r24 ? .Lend 75 | ;; 76 | addx8d $r24 = $r24, $r4 77 | ;; 78 | igoto $r24 79 | ;; 80 | .Ltable: 81 | 0: /* we should never arrive here */ 82 | goto .Lerror 83 | nop 84 | ;; 85 | 1: /* Sign extend byte to double */ 86 | sxbd $r0 = $r0 87 | goto .Lend 88 | ;; 89 | 2: /* Sign extend half to double */ 90 | sxhd $r0 = $r0 91 | goto .Lend 92 | ;; 93 | 3: /* Sign extend word to double */ 94 | sxwd $r0 = $r0 95 | goto .Lend 96 | ;; 97 | 4: /* Zero extend byte to double */ 98 | zxbd $r0 = $r0 99 | goto .Lend 100 | ;; 101 | 5: /* Zero extend half to double */ 102 | zxhd $r0 = $r0 103 | goto .Lend 104 | ;; 105 | 6: /* Zero extend word to double */ 106 | zxwd $r0 = $r0 107 | /* Fallthrough to .Lend */ 108 | ;; 109 | .Lend: 110 | ld $r24 = (0)[$r12] 111 | ;; 112 | set $ra = $r23 113 | lo $r20r21r22r23 = (32)[$r20] 114 | addd $r12 = $r20, 64 115 | ;; 116 | ret 117 | ;; 118 | .Lerror: 119 | errop 120 | ;; 121 | 122 | #endif /* __kvx__ */ 123 | 124 | #if defined __ELF__ && defined __linux__ 125 | .section .note.GNU-stack,"",%progbits 126 | #endif 127 | 128 | -------------------------------------------------------------------------------- /src/loongarch64/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2022 Xu Chenghua 3 | 2022 Cheng Lulu 4 | 5 | Target configuration macros for LoongArch. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | ``Software''), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | 27 | ----------------------------------------------------------------------- */ 28 | 29 | #ifndef LIBFFI_TARGET_H 30 | #define LIBFFI_TARGET_H 31 | 32 | #ifndef LIBFFI_H 33 | #error \ 34 | "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | #ifndef __loongarch__ 38 | #error \ 39 | "libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler." 40 | #endif 41 | 42 | #ifndef LIBFFI_ASM 43 | 44 | typedef unsigned long ffi_arg; 45 | typedef signed long ffi_sarg; 46 | 47 | typedef enum ffi_abi 48 | { 49 | FFI_FIRST_ABI = 0, 50 | FFI_LP64S, 51 | FFI_LP64F, 52 | FFI_LP64D, 53 | FFI_LAST_ABI, 54 | 55 | #if defined(__loongarch64) 56 | #if defined(__loongarch_soft_float) 57 | FFI_DEFAULT_ABI = FFI_LP64S 58 | #elif defined(__loongarch_single_float) 59 | FFI_DEFAULT_ABI = FFI_LP64F 60 | #elif defined(__loongarch_double_float) 61 | FFI_DEFAULT_ABI = FFI_LP64D 62 | #else 63 | #error unsupported LoongArch floating-point ABI 64 | #endif 65 | #else 66 | #error unsupported LoongArch base architecture 67 | #endif 68 | } ffi_abi; 69 | 70 | #endif /* LIBFFI_ASM */ 71 | 72 | /* ---- Definitions for closures ----------------------------------------- */ 73 | 74 | #define FFI_CLOSURES 1 75 | #define FFI_GO_CLOSURES 1 76 | #define FFI_TRAMPOLINE_SIZE 24 77 | #define FFI_NATIVE_RAW_API 0 78 | #define FFI_EXTRA_CIF_FIELDS \ 79 | unsigned loongarch_nfixedargs; \ 80 | unsigned loongarch_unused; 81 | #define FFI_TARGET_SPECIFIC_VARIADIC 82 | #endif 83 | -------------------------------------------------------------------------------- /src/m32r/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2004 Renesas Technology. 4 | Target configuration macros for M32R. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- Generic type definitions ----------------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi 41 | { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | #endif 48 | 49 | #define FFI_CLOSURES 0 50 | #define FFI_TRAMPOLINE_SIZE 24 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/m32r/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 2004 Renesas Technology 3 | 4 | M32R Foreign Function Interface 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #define LIBFFI_ASM 27 | #include 28 | #include 29 | #ifdef HAVE_MACHINE_ASM_H 30 | #include 31 | #else 32 | /* XXX these lose for some platforms, I'm sure. */ 33 | #define CNAME(x) x 34 | #define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x): 35 | #endif 36 | 37 | .text 38 | 39 | /* R0: ffi_prep_args */ 40 | /* R1: &ecif */ 41 | /* R2: cif->bytes */ 42 | /* R3: fig->flags */ 43 | /* sp+0: ecif.rvalue */ 44 | /* sp+4: fn */ 45 | 46 | /* This assumes we are using gas. */ 47 | ENTRY(ffi_call_SYSV) 48 | /* Save registers. */ 49 | push fp 50 | push lr 51 | push r3 52 | push r2 53 | push r1 54 | push r0 55 | mv fp, sp 56 | 57 | /* Make room for all of the new args. */ 58 | sub sp, r2 59 | 60 | /* Place all of the ffi_prep_args in position. */ 61 | mv lr, r0 62 | mv r0, sp 63 | /* R1 already set. */ 64 | 65 | /* And call. */ 66 | jl lr 67 | 68 | /* Move first 4 parameters in registers... */ 69 | ld r0, @(0,sp) 70 | ld r1, @(4,sp) 71 | ld r2, @(8,sp) 72 | ld r3, @(12,sp) 73 | 74 | /* ...and adjust the stack. */ 75 | ld lr, @(8,fp) 76 | cmpi lr, #16 77 | bc adjust_stack 78 | ldi lr, #16 79 | adjust_stack: 80 | add sp, lr 81 | 82 | /* Call the function. */ 83 | ld lr, @(28,fp) 84 | jl lr 85 | 86 | /* Remove the space we pushed for the args. */ 87 | mv sp, fp 88 | 89 | /* Load R2 with the pointer to storage for the return value. */ 90 | ld r2, @(24,sp) 91 | 92 | /* Load R3 with the return type code. */ 93 | ld r3, @(12,sp) 94 | 95 | /* If the return value pointer is NULL, assume no return value. */ 96 | beqz r2, epilogue 97 | 98 | /* Return INT. */ 99 | ldi r4, #FFI_TYPE_INT 100 | bne r3, r4, return_double 101 | st r0, @r2 102 | bra epilogue 103 | 104 | return_double: 105 | /* Return DOUBLE or LONGDOUBLE. */ 106 | ldi r4, #FFI_TYPE_DOUBLE 107 | bne r3, r4, epilogue 108 | st r0, @r2 109 | st r1, @(4,r2) 110 | 111 | epilogue: 112 | pop r0 113 | pop r1 114 | pop r2 115 | pop r3 116 | pop lr 117 | pop fp 118 | jmp lr 119 | 120 | .ffi_call_SYSV_end: 121 | .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) 122 | -------------------------------------------------------------------------------- /src/m68k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for Motorola 68K. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_SYSV, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_SYSV 44 | } ffi_abi; 45 | #endif 46 | 47 | /* ---- Definitions for closures ----------------------------------------- */ 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 16 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /src/m88k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * m88k Foreign Function Interface 26 | */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_ASM 32 | typedef unsigned long ffi_arg; 33 | typedef signed long ffi_sarg; 34 | 35 | typedef enum ffi_abi { 36 | FFI_FIRST_ABI = 0, 37 | FFI_OBSD, 38 | FFI_DEFAULT_ABI = FFI_OBSD, 39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 40 | } ffi_abi; 41 | #endif 42 | 43 | /* ---- Definitions for closures ----------------------------------------- */ 44 | 45 | #define FFI_CLOSURES 1 46 | #define FFI_TRAMPOLINE_SIZE 0x14 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/m88k/obsd.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * m88k Foreign Function Interface 26 | */ 27 | 28 | #define LIBFFI_ASM 29 | #include 30 | #include 31 | 32 | .text 33 | 34 | /* 35 | * ffi_cacheflush_OBSD(unsigned int addr, %r2 36 | * unsigned int size); %r3 37 | */ 38 | .align 4 39 | .globl ffi_cacheflush_OBSD 40 | .type ffi_cacheflush_OBSD,@function 41 | ffi_cacheflush_OBSD: 42 | tb0 0, %r0, 451 43 | or %r0, %r0, %r0 44 | jmp %r1 45 | .size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD 46 | 47 | /* 48 | * ffi_call_OBSD(unsigned bytes, %r2 49 | * extended_cif *ecif, %r3 50 | * unsigned flags, %r4 51 | * void *rvalue, %r5 52 | * void (*fn)()); %r6 53 | */ 54 | .align 4 55 | .globl ffi_call_OBSD 56 | .type ffi_call_OBSD,@function 57 | ffi_call_OBSD: 58 | subu %r31, %r31, 32 59 | st %r30, %r31, 4 60 | st %r1, %r31, 0 61 | addu %r30, %r31, 32 62 | 63 | | Save the few arguments we'll need after ffi_prep_args() 64 | st.d %r4, %r31, 8 65 | st %r6, %r31, 16 66 | 67 | | Allocate room for the image of r2-r9, and the stack space for 68 | | the args (rounded to a 16-byte boundary) 69 | addu %r2, %r2, (8 * 4) + 15 70 | clr %r2, %r2, 4<0> 71 | subu %r31, %r31, %r2 72 | 73 | | Fill register and stack image 74 | or %r2, %r31, %r0 75 | #ifdef PIC 76 | bsr ffi_prep_args#plt 77 | #else 78 | bsr ffi_prep_args 79 | #endif 80 | 81 | | Save pointer to return struct address, if any 82 | or %r12, %r2, %r0 83 | 84 | | Get function pointer 85 | subu %r4, %r30, 32 86 | ld %r1, %r4, 16 87 | 88 | | Fetch the register arguments 89 | ld.d %r2, %r31, (0 * 4) 90 | ld.d %r4, %r31, (2 * 4) 91 | ld.d %r6, %r31, (4 * 4) 92 | ld.d %r8, %r31, (6 * 4) 93 | addu %r31, %r31, (8 * 4) 94 | 95 | | Invoke the function 96 | jsr %r1 97 | 98 | | Restore stack now that we don't need the args anymore 99 | subu %r31, %r30, 32 100 | 101 | | Figure out what to return as the function's return value 102 | ld %r5, %r31, 12 | rvalue 103 | ld %r4, %r31, 8 | flags 104 | 105 | bcnd eq0, %r5, 9f 106 | 107 | bb0 0, %r4, 1f | CIF_FLAGS_INT 108 | st %r2, %r5, 0 109 | br 9f 110 | 111 | 1: 112 | bb0 1, %r4, 1f | CIF_FLAGS_DINT 113 | st.d %r2, %r5, 0 114 | br 9f 115 | 116 | 1: 117 | 9: 118 | ld %r1, %r31, 0 119 | ld %r30, %r31, 4 120 | jmp.n %r1 121 | addu %r31, %r31, 32 122 | .size ffi_call_OBSD, . - ffi_call_OBSD 123 | 124 | /* 125 | * ffi_closure_OBSD(ffi_closure *closure); %r13 126 | */ 127 | .align 4 128 | .globl ffi_closure_OBSD 129 | .type ffi_closure_OBSD, @function 130 | ffi_closure_OBSD: 131 | subu %r31, %r31, 16 132 | st %r30, %r31, 4 133 | st %r1, %r31, 0 134 | addu %r30, %r31, 16 135 | 136 | | Make room on the stack for saved register arguments and return 137 | | value 138 | subu %r31, %r31, (8 * 4) + (2 * 4) 139 | st.d %r2, %r31, (0 * 4) 140 | st.d %r4, %r31, (2 * 4) 141 | st.d %r6, %r31, (4 * 4) 142 | st.d %r8, %r31, (6 * 4) 143 | 144 | | Invoke the closure function 145 | or %r5, %r30, 0 | calling stack 146 | addu %r4, %r31, 0 | saved registers 147 | addu %r3, %r31, (8 * 4) | return value 148 | or %r2, %r13, %r0 | closure 149 | #ifdef PIC 150 | bsr ffi_closure_OBSD_inner#plt 151 | #else 152 | bsr ffi_closure_OBSD_inner 153 | #endif 154 | 155 | | Figure out what to return as the function's return value 156 | bb0 0, %r2, 1f | CIF_FLAGS_INT 157 | ld %r2, %r31, (8 * 4) 158 | br 9f 159 | 160 | 1: 161 | bb0 1, %r2, 1f | CIF_FLAGS_DINT 162 | ld.d %r2, %r31, (8 * 4) 163 | br 9f 164 | 165 | 1: 166 | 9: 167 | subu %r31, %r30, 16 168 | ld %r1, %r31, 0 169 | ld %r30, %r31, 4 170 | jmp.n %r1 171 | addu %r31, %r31, 16 172 | .size ffi_closure_OBSD,.-ffi_closure_OBSD 173 | 174 | /* 175 | * ffi_closure_struct_OBSD(ffi_closure *closure); %r13 176 | */ 177 | .align 4 178 | .globl ffi_closure_struct_OBSD 179 | .type ffi_closure_struct_OBSD, @function 180 | ffi_closure_struct_OBSD: 181 | subu %r31, %r31, 16 182 | st %r30, %r31, 4 183 | st %r1, %r31, 0 184 | addu %r30, %r31, 16 185 | 186 | | Make room on the stack for saved register arguments 187 | subu %r31, %r31, (8 * 4) 188 | st.d %r2, %r31, (0 * 4) 189 | st.d %r4, %r31, (2 * 4) 190 | st.d %r6, %r31, (4 * 4) 191 | st.d %r8, %r31, (6 * 4) 192 | 193 | | Invoke the closure function 194 | or %r5, %r30, 0 | calling stack 195 | addu %r4, %r31, 0 | saved registers 196 | or %r3, %r12, 0 | return value 197 | or %r2, %r13, %r0 | closure 198 | #ifdef PIC 199 | bsr ffi_closure_OBSD_inner#plt 200 | #else 201 | bsr ffi_closure_OBSD_inner 202 | #endif 203 | 204 | subu %r31, %r30, 16 205 | ld %r1, %r31, 0 206 | ld %r30, %r31, 4 207 | jmp.n %r1 208 | addu %r31, %r31, 16 209 | .size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD 210 | -------------------------------------------------------------------------------- /src/metag/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2013 Imagination Technologies Ltd. 3 | Target configuration macros for Meta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | #ifndef LIBFFI_ASM 35 | typedef unsigned long ffi_arg; 36 | typedef signed long ffi_sarg; 37 | 38 | typedef enum ffi_abi { 39 | FFI_FIRST_ABI = 0, 40 | FFI_SYSV, 41 | FFI_DEFAULT_ABI = FFI_SYSV, 42 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1, 43 | } ffi_abi; 44 | #endif 45 | 46 | /* ---- Definitions for closures ----------------------------------------- */ 47 | 48 | #define FFI_CLOSURES 1 49 | #define FFI_TRAMPOLINE_SIZE 48 50 | #define FFI_NATIVE_RAW_API 0 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /src/microblaze/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc 3 | 4 | Target configuration macros for MicroBlaze. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | #ifndef LIBFFI_ASM 35 | typedef unsigned long ffi_arg; 36 | typedef signed long ffi_sarg; 37 | 38 | typedef enum ffi_abi { 39 | FFI_FIRST_ABI = 0, 40 | FFI_SYSV, 41 | FFI_LAST_ABI, 42 | FFI_DEFAULT_ABI = FFI_SYSV 43 | } ffi_abi; 44 | #endif 45 | 46 | /* Definitions for closures */ 47 | 48 | #define FFI_CLOSURES 1 49 | #define FFI_NATIVE_RAW_API 0 50 | 51 | #define FFI_TRAMPOLINE_SIZE (4*8) 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/moxie/eabi.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | eabi.S - Copyright (c) 2012, 2013 Anthony Green 3 | 4 | Moxie Assembly glue. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #define LIBFFI_ASM 27 | #include 28 | #include 29 | 30 | .globl ffi_prep_args_EABI 31 | 32 | .text 33 | .p2align 4 34 | .globl ffi_call_EABI 35 | .type ffi_call_EABI, @function 36 | 37 | # $r0 : ffi_prep_args 38 | # $r1 : &ecif 39 | # $r2 : cif->bytes 40 | # $r3 : fig->flags 41 | # $r4 : ecif.rvalue 42 | # $r5 : fn 43 | 44 | ffi_call_EABI: 45 | push $sp, $r6 46 | push $sp, $r7 47 | push $sp, $r8 48 | dec $sp, 24 49 | 50 | /* Store incoming args on stack. */ 51 | sto.l 0($sp), $r0 /* ffi_prep_args */ 52 | sto.l 4($sp), $r1 /* ecif */ 53 | sto.l 8($sp), $r2 /* bytes */ 54 | sto.l 12($sp), $r3 /* flags */ 55 | sto.l 16($sp), $r4 /* &rvalue */ 56 | sto.l 20($sp), $r5 /* fn */ 57 | 58 | /* Call ffi_prep_args. */ 59 | mov $r6, $r4 /* Save result buffer */ 60 | mov $r7, $r5 /* Save the target fn */ 61 | mov $r8, $r3 /* Save the flags */ 62 | sub $sp, $r2 /* Allocate stack space */ 63 | mov $r0, $sp /* We can stomp over $r0 */ 64 | /* $r1 is already set up */ 65 | jsra ffi_prep_args 66 | 67 | /* Load register arguments. */ 68 | ldo.l $r0, 0($sp) 69 | ldo.l $r1, 4($sp) 70 | ldo.l $r2, 8($sp) 71 | ldo.l $r3, 12($sp) 72 | ldo.l $r4, 16($sp) 73 | ldo.l $r5, 20($sp) 74 | 75 | /* Call the target function. */ 76 | jsr $r7 77 | 78 | ldi.l $r7, 0xffffffff 79 | cmp $r8, $r7 80 | beq retstruct 81 | 82 | ldi.l $r7, 4 83 | cmp $r8, $r7 84 | bgt ret2reg 85 | 86 | st.l ($r6), $r0 87 | jmpa retdone 88 | 89 | ret2reg: 90 | st.l ($r6), $r0 91 | sto.l 4($r6), $r1 92 | 93 | retstruct: 94 | retdone: 95 | /* Return. */ 96 | ldo.l $r6, -4($fp) 97 | ldo.l $r7, -8($fp) 98 | ldo.l $r8, -12($fp) 99 | ret 100 | .size ffi_call_EABI, .-ffi_call_EABI 101 | 102 | -------------------------------------------------------------------------------- /src/moxie/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012, 2013 Anthony Green 3 | Target configuration macros for Moxie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | /* ---- System specific configurations ----------------------------------- */ 31 | 32 | #ifndef LIBFFI_ASM 33 | typedef unsigned long ffi_arg; 34 | typedef signed long ffi_sarg; 35 | 36 | typedef enum ffi_abi { 37 | FFI_FIRST_ABI = 0, 38 | FFI_EABI, 39 | FFI_DEFAULT_ABI = FFI_EABI, 40 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 41 | } ffi_abi; 42 | #endif 43 | 44 | /* ---- Definitions for closures ----------------------------------------- */ 45 | 46 | #define FFI_CLOSURES 1 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | /* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */ 50 | #define FFI_TRAMPOLINE_SIZE (12) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/or1k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2014 Sebastian Macke 3 | 4 | OpenRISC Target configuration macros 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- System specific configurations ----------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi { 41 | FFI_FIRST_ABI = 0, 42 | FFI_SYSV, 43 | FFI_LAST_ABI, 44 | FFI_DEFAULT_ABI = FFI_SYSV 45 | } ffi_abi; 46 | #endif 47 | 48 | /* ---- Definitions for closures ----------------------------------------- */ 49 | 50 | #define FFI_CLOSURES 1 51 | #define FFI_NATIVE_RAW_API 0 52 | #define FFI_TRAMPOLINE_SIZE (24) 53 | 54 | #define FFI_TARGET_SPECIFIC_VARIADIC 1 55 | #define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs; 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /src/or1k/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 2014 Sebastian Macke 3 | 4 | OpenRISC Foreign Function Interface 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #define LIBFFI_ASM 28 | #include 29 | #include 30 | 31 | .text 32 | .globl ffi_call_SYSV 33 | .type ffi_call_SYSV, @function 34 | /* 35 | r3: size to allocate on stack 36 | r4: extended cif structure 37 | r5: function pointer ffi_prep_args 38 | r6: ret address 39 | r7: function to call 40 | r8: flag for return type 41 | */ 42 | 43 | ffi_call_SYSV: 44 | /* Store registers used on stack */ 45 | l.sw -4(r1), r9 /* return address */ 46 | l.sw -8(r1), r1 /* stack address */ 47 | l.sw -12(r1), r14 /* callee saved registers */ 48 | l.sw -16(r1), r16 49 | l.sw -20(r1), r18 50 | l.sw -24(r1), r20 51 | 52 | l.ori r14, r1, 0x0 /* save stack pointer */ 53 | l.addi r1, r1, -24 54 | 55 | l.ori r16, r7, 0x0 /* save function address */ 56 | l.ori r18, r6, 0x0 /* save ret address */ 57 | l.ori r20, r8, 0x0 /* save flag */ 58 | 59 | l.sub r1, r1, r3 /* reserve space on stack */ 60 | 61 | /* Call ffi_prep_args */ 62 | l.ori r3, r1, 0x0 /* first argument stack address, second already ecif */ 63 | l.jalr r5 64 | l.nop 65 | 66 | /* Load register arguments and call*/ 67 | 68 | l.lwz r3, 0(r1) 69 | l.lwz r4, 4(r1) 70 | l.lwz r5, 8(r1) 71 | l.lwz r6, 12(r1) 72 | l.lwz r7, 16(r1) 73 | l.lwz r8, 20(r1) 74 | l.ori r1, r11, 0x0 /* new stack pointer */ 75 | l.jalr r16 76 | l.nop 77 | 78 | /* handle return values */ 79 | 80 | l.sfeqi r20, FFI_TYPE_STRUCT 81 | l.bf ret /* structs don't return an rvalue */ 82 | l.nop 83 | 84 | /* copy ret address */ 85 | 86 | l.sfeqi r20, FFI_TYPE_UINT64 87 | l.bnf four_byte_ret /* 8 byte value is returned */ 88 | l.nop 89 | 90 | l.sw 4(r18), r12 91 | 92 | four_byte_ret: 93 | l.sw 0(r18), r11 94 | 95 | ret: 96 | /* return */ 97 | l.ori r1, r14, 0x0 /* reset stack pointer */ 98 | l.lwz r9, -4(r1) 99 | l.lwz r1, -8(r1) 100 | l.lwz r14, -12(r1) 101 | l.lwz r16, -16(r1) 102 | l.lwz r18, -20(r1) 103 | l.lwz r20, -24(r1) 104 | l.jr r9 105 | l.nop 106 | 107 | .size ffi_call_SYSV, .-ffi_call_SYSV 108 | -------------------------------------------------------------------------------- /src/pa/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for hppa. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- System specific configurations ----------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | 44 | #ifdef PA_LINUX 45 | FFI_PA32, 46 | FFI_LAST_ABI, 47 | FFI_DEFAULT_ABI = FFI_PA32 48 | #endif 49 | 50 | #ifdef PA_HPUX 51 | FFI_PA32, 52 | FFI_LAST_ABI, 53 | FFI_DEFAULT_ABI = FFI_PA32 54 | #endif 55 | 56 | #ifdef PA64_HPUX 57 | FFI_PA64, 58 | FFI_LAST_ABI, 59 | FFI_DEFAULT_ABI = FFI_PA64 60 | #endif 61 | } ffi_abi; 62 | #endif 63 | 64 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 65 | 66 | /* ---- Definitions for closures ----------------------------------------- */ 67 | 68 | #define FFI_CLOSURES 1 69 | #define FFI_NATIVE_RAW_API 0 70 | #if defined(PA64_HPUX) 71 | #define FFI_TRAMPOLINE_SIZE 32 72 | #else 73 | #define FFI_TRAMPOLINE_SIZE 12 74 | #endif 75 | 76 | #define FFI_TYPE_SMALL_STRUCT1 -1 77 | #define FFI_TYPE_SMALL_STRUCT2 -2 78 | #define FFI_TYPE_SMALL_STRUCT3 -3 79 | #define FFI_TYPE_SMALL_STRUCT4 -4 80 | #define FFI_TYPE_SMALL_STRUCT5 -5 81 | #define FFI_TYPE_SMALL_STRUCT6 -6 82 | #define FFI_TYPE_SMALL_STRUCT7 -7 83 | #define FFI_TYPE_SMALL_STRUCT8 -8 84 | 85 | /* linux.S and hpux32.S expect FFI_TYPE_COMPLEX is the last generic type. */ 86 | #define FFI_PA_TYPE_LAST FFI_TYPE_COMPLEX 87 | 88 | /* If new generic types are added, the jump tables in linux.S and hpux32.S 89 | likely need updating. */ 90 | #if FFI_TYPE_LAST != FFI_PA_TYPE_LAST 91 | # error "You likely have broken jump tables" 92 | #endif 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/powerpc/asm.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | asm.h - Copyright (c) 1998 Geoffrey Keating 3 | 4 | PowerPC Assembly glue. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #define ASM_GLOBAL_DIRECTIVE .globl 27 | 28 | 29 | #define C_SYMBOL_NAME(name) name 30 | /* Macro for a label. */ 31 | #ifdef __STDC__ 32 | #define C_LABEL(name) name##: 33 | #else 34 | #define C_LABEL(name) name/**/: 35 | #endif 36 | 37 | /* This seems to always be the case on PPC. */ 38 | #define ALIGNARG(log2) log2 39 | /* For ELF we need the `.type' directive to make shared libs work right. */ 40 | #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; 41 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name 42 | 43 | /* If compiled for profiling, call `_mcount' at the start of each function. */ 44 | #ifdef PROF 45 | /* The mcount code relies on the return address being on the stack 46 | to locate our caller and so it can restore it; so store one just 47 | for its benefit. */ 48 | #ifdef PIC 49 | #define CALL_MCOUNT \ 50 | .pushsection; \ 51 | .section ".data"; \ 52 | .align ALIGNARG(2); \ 53 | 0:.long 0; \ 54 | .previous; \ 55 | mflr %r0; \ 56 | stw %r0,4(%r1); \ 57 | bl _GLOBAL_OFFSET_TABLE_@local-4; \ 58 | mflr %r11; \ 59 | lwz %r0,0b@got(%r11); \ 60 | bl JUMPTARGET(_mcount); 61 | #else /* PIC */ 62 | #define CALL_MCOUNT \ 63 | .section ".data"; \ 64 | .align ALIGNARG(2); \ 65 | 0:.long 0; \ 66 | .previous; \ 67 | mflr %r0; \ 68 | lis %r11,0b@ha; \ 69 | stw %r0,4(%r1); \ 70 | addi %r0,%r11,0b@l; \ 71 | bl JUMPTARGET(_mcount); 72 | #endif /* PIC */ 73 | #else /* PROF */ 74 | #define CALL_MCOUNT /* Do nothing. */ 75 | #endif /* PROF */ 76 | 77 | #define ENTRY(name) \ 78 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ 79 | ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ 80 | .align ALIGNARG(2); \ 81 | C_LABEL(name) \ 82 | CALL_MCOUNT 83 | 84 | #define EALIGN_W_0 /* No words to insert. */ 85 | #define EALIGN_W_1 nop 86 | #define EALIGN_W_2 nop;nop 87 | #define EALIGN_W_3 nop;nop;nop 88 | #define EALIGN_W_4 EALIGN_W_3;nop 89 | #define EALIGN_W_5 EALIGN_W_4;nop 90 | #define EALIGN_W_6 EALIGN_W_5;nop 91 | #define EALIGN_W_7 EALIGN_W_6;nop 92 | 93 | /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes 94 | past a 2^align boundary. */ 95 | #ifdef PROF 96 | #define EFFI_ALIGN(name, alignt, words) \ 97 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ 98 | ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ 99 | .align ALIGNARG(2); \ 100 | C_LABEL(name) \ 101 | CALL_MCOUNT \ 102 | b 0f; \ 103 | .align ALIGNARG(alignt); \ 104 | EALIGN_W_##words; \ 105 | 0: 106 | #else /* PROF */ 107 | #define EFFI_ALIGN(name, alignt, words) \ 108 | ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ 109 | ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ 110 | .align ALIGNARG(alignt); \ 111 | EALIGN_W_##words; \ 112 | C_LABEL(name) 113 | #endif 114 | 115 | #define END(name) \ 116 | ASM_SIZE_DIRECTIVE(name) 117 | 118 | #ifdef PIC 119 | #define JUMPTARGET(name) name##@plt 120 | #else 121 | #define JUMPTARGET(name) name 122 | #endif 123 | 124 | /* Local labels stripped out by the linker. */ 125 | #define L(x) .L##x 126 | -------------------------------------------------------------------------------- /src/powerpc/ffi.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi.c - Copyright (C) 2013 IBM 3 | Copyright (C) 2011 Anthony Green 4 | Copyright (C) 2011 Kyle Moffett 5 | Copyright (C) 2008 Red Hat, Inc 6 | Copyright (C) 2007, 2008 Free Software Foundation, Inc 7 | Copyright (c) 1998 Geoffrey Keating 8 | 9 | PowerPC Foreign Function Interface 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining 12 | a copy of this software and associated documentation files (the 13 | ``Software''), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included 20 | in all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | OTHER DEALINGS IN THE SOFTWARE. 29 | ----------------------------------------------------------------------- */ 30 | 31 | #include "ffi.h" 32 | #include "ffi_common.h" 33 | #include "ffi_powerpc.h" 34 | #include "internal.h" 35 | #include 36 | 37 | #if HAVE_LONG_DOUBLE_VARIANT 38 | /* Adjust ffi_type_longdouble. */ 39 | void FFI_HIDDEN 40 | ffi_prep_types (ffi_abi abi) 41 | { 42 | # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 43 | # ifdef POWERPC64 44 | ffi_prep_types_linux64 (abi); 45 | # else 46 | ffi_prep_types_sysv (abi); 47 | # endif 48 | # endif 49 | } 50 | #endif 51 | 52 | /* Perform machine dependent cif processing */ 53 | ffi_status FFI_HIDDEN 54 | ffi_prep_cif_machdep (ffi_cif *cif) 55 | { 56 | #ifdef POWERPC64 57 | return ffi_prep_cif_linux64 (cif); 58 | #else 59 | return ffi_prep_cif_sysv (cif); 60 | #endif 61 | } 62 | 63 | ffi_status FFI_HIDDEN 64 | ffi_prep_cif_machdep_var (ffi_cif *cif, 65 | unsigned int nfixedargs MAYBE_UNUSED, 66 | unsigned int ntotalargs MAYBE_UNUSED) 67 | { 68 | #ifdef POWERPC64 69 | return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs); 70 | #else 71 | return ffi_prep_cif_sysv (cif); 72 | #endif 73 | } 74 | 75 | static void 76 | ffi_call_int (ffi_cif *cif, 77 | void (*fn) (void), 78 | void *rvalue, 79 | void **avalue, 80 | void *closure) 81 | { 82 | /* The final SYSV ABI says that structures smaller or equal 8 bytes 83 | are returned in r3/r4. A draft ABI used by linux instead returns 84 | them in memory. 85 | 86 | We bounce-buffer SYSV small struct return values so that sysv.S 87 | can write r3 and r4 to memory without worrying about struct size. 88 | 89 | For ELFv2 ABI, use a bounce buffer for homogeneous structs too, 90 | for similar reasons. This bounce buffer must be aligned to 16 91 | bytes for use with homogeneous structs of vectors (float128). */ 92 | float128 smst_buffer[8]; 93 | extended_cif ecif; 94 | 95 | ecif.cif = cif; 96 | ecif.avalue = avalue; 97 | 98 | ecif.rvalue = rvalue; 99 | if ((cif->flags & FLAG_RETURNS_SMST) != 0) 100 | ecif.rvalue = smst_buffer; 101 | /* Ensure that we have a valid struct return value. 102 | FIXME: Isn't this just papering over a user problem? */ 103 | else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT) 104 | ecif.rvalue = alloca (cif->rtype->size); 105 | 106 | #ifdef POWERPC64 107 | ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure, 108 | -(long) cif->bytes); 109 | #else 110 | ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes); 111 | #endif 112 | 113 | /* Check for a bounce-buffered return value */ 114 | if (rvalue && ecif.rvalue == smst_buffer) 115 | { 116 | unsigned int rsize = cif->rtype->size; 117 | #ifndef __LITTLE_ENDIAN__ 118 | /* The SYSV ABI returns a structure of up to 4 bytes in size 119 | left-padded in r3. */ 120 | # ifndef POWERPC64 121 | if (rsize <= 4) 122 | memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize); 123 | else 124 | # endif 125 | /* The SYSV ABI returns a structure of up to 8 bytes in size 126 | left-padded in r3/r4, and the ELFv2 ABI similarly returns a 127 | structure of up to 8 bytes in size left-padded in r3. But 128 | note that a structure of a single float is not paddded. */ 129 | if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0) 130 | memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize); 131 | else 132 | #endif 133 | memcpy (rvalue, smst_buffer, rsize); 134 | } 135 | } 136 | 137 | void 138 | ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) 139 | { 140 | ffi_call_int (cif, fn, rvalue, avalue, NULL); 141 | } 142 | 143 | void 144 | ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, 145 | void *closure) 146 | { 147 | ffi_call_int (cif, fn, rvalue, avalue, closure); 148 | } 149 | 150 | ffi_status 151 | ffi_prep_closure_loc (ffi_closure *closure, 152 | ffi_cif *cif, 153 | void (*fun) (ffi_cif *, void *, void **, void *), 154 | void *user_data, 155 | void *codeloc) 156 | { 157 | #ifdef POWERPC64 158 | return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc); 159 | #else 160 | return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc); 161 | #endif 162 | } 163 | 164 | ffi_status 165 | ffi_prep_go_closure (ffi_go_closure *closure, 166 | ffi_cif *cif, 167 | void (*fun) (ffi_cif *, void *, void **, void *)) 168 | { 169 | #ifdef POWERPC64 170 | closure->tramp = ffi_go_closure_linux64; 171 | #else 172 | closure->tramp = ffi_go_closure_sysv; 173 | #endif 174 | closure->cif = cif; 175 | closure->fun = fun; 176 | return FFI_OK; 177 | } 178 | 179 | #ifdef FFI_EXEC_STATIC_TRAMP 180 | void * 181 | ffi_tramp_arch (size_t *tramp_size, size_t *map_size) 182 | { 183 | extern void *trampoline_code_table; 184 | *tramp_size = PPC_TRAMP_SIZE; 185 | *map_size = PPC_TRAMP_MAP_SIZE; 186 | #if defined (_CALL_AIX) || _CALL_ELF == 1 187 | /* The caller wants the entry point address of the trampoline code, 188 | not the address of the function descriptor. */ 189 | return *(void **)trampoline_code_table; 190 | #else 191 | return &trampoline_code_table; 192 | #endif 193 | } 194 | #endif 195 | -------------------------------------------------------------------------------- /src/powerpc/ffi_powerpc.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi_powerpc.h - Copyright (C) 2013 IBM 3 | Copyright (C) 2011 Anthony Green 4 | Copyright (C) 2011 Kyle Moffett 5 | Copyright (C) 2008 Red Hat, Inc 6 | Copyright (C) 2007, 2008 Free Software Foundation, Inc 7 | Copyright (c) 1998 Geoffrey Keating 8 | 9 | PowerPC Foreign Function Interface 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining 12 | a copy of this software and associated documentation files (the 13 | ``Software''), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included 20 | in all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | OTHER DEALINGS IN THE SOFTWARE. 29 | ----------------------------------------------------------------------- */ 30 | 31 | enum { 32 | /* The assembly depends on these exact flags. */ 33 | /* These go in cr7 */ 34 | FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ 35 | FLAG_RETURNS_NOTHING = 1 << (31-30), 36 | FLAG_RETURNS_FP = 1 << (31-29), 37 | FLAG_RETURNS_VEC = 1 << (31-28), 38 | 39 | /* These go in cr6 */ 40 | FLAG_RETURNS_64BITS = 1 << (31-27), 41 | FLAG_RETURNS_128BITS = 1 << (31-26), 42 | 43 | FLAG_COMPAT = 1 << (31- 8), /* Not used by assembly */ 44 | 45 | /* These go in cr1 */ 46 | FLAG_ARG_NEEDS_COPY = 1 << (31- 7), /* Used by sysv code */ 47 | FLAG_ARG_NEEDS_PSAVE = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */ 48 | FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ 49 | FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), 50 | FLAG_RETVAL_REFERENCE = 1 << (31- 4), 51 | FLAG_VEC_ARGUMENTS = 1 << (31- 3), 52 | }; 53 | 54 | typedef union 55 | { 56 | float f; 57 | double d; 58 | } ffi_dblfl; 59 | 60 | #if defined(__FLOAT128_TYPE__) && defined(__HAVE_FLOAT128) 61 | typedef _Float128 float128; 62 | #elif defined(__FLOAT128__) 63 | typedef __float128 float128; 64 | #else 65 | typedef char float128[16] __attribute__((aligned(16))); 66 | #endif 67 | 68 | void FFI_HIDDEN ffi_closure_SYSV (void); 69 | void FFI_HIDDEN ffi_go_closure_sysv (void); 70 | void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *, 71 | unsigned, void *, int); 72 | 73 | void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); 74 | ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); 75 | ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv (ffi_closure *, 76 | ffi_cif *, 77 | void (*) (ffi_cif *, void *, 78 | void **, void *), 79 | void *, void *); 80 | int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_cif *, 81 | void (*) (ffi_cif *, void *, 82 | void **, void *), 83 | void *, void *, unsigned long *, 84 | ffi_dblfl *, unsigned long *); 85 | 86 | void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *, 87 | unsigned long, void *, long); 88 | void FFI_HIDDEN ffi_closure_LINUX64 (void); 89 | void FFI_HIDDEN ffi_go_closure_linux64 (void); 90 | 91 | void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); 92 | ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *); 93 | ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, 94 | unsigned int); 95 | void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); 96 | ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *, ffi_cif *, 97 | void (*) (ffi_cif *, void *, 98 | void **, void *), 99 | void *, void *); 100 | int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_cif *, 101 | void (*) (ffi_cif *, void *, 102 | void **, void *), 103 | void *, void *, 104 | unsigned long *, ffi_dblfl *, 105 | float128 *); 106 | -------------------------------------------------------------------------------- /src/powerpc/internal.h: -------------------------------------------------------------------------------- 1 | #ifdef FFI_EXEC_STATIC_TRAMP 2 | /* For the trampoline code table mapping, a mapping size of 64K is chosen. */ 3 | #define PPC_TRAMP_MAP_SHIFT 16 4 | #define PPC_TRAMP_MAP_SIZE (1 << PPC_TRAMP_MAP_SHIFT) 5 | # ifdef __PCREL__ 6 | # define PPC_TRAMP_SIZE 24 7 | # else 8 | # define PPC_TRAMP_SIZE 40 9 | # endif /* __PCREL__ */ 10 | #endif /* FFI_EXEC_STATIC_TRAMP */ 11 | -------------------------------------------------------------------------------- /src/powerpc/sysv.S: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | sysv.S - Copyright (c) 1998 Geoffrey Keating 3 | Copyright (C) 2007 Free Software Foundation, Inc 4 | 5 | PowerPC Assembly glue. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | ``Software''), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | ----------------------------------------------------------------------- */ 27 | 28 | #define LIBFFI_ASM 29 | #include 30 | #include 31 | #include 32 | 33 | #ifndef POWERPC64 34 | FFI_HIDDEN(ffi_call_SYSV) 35 | ENTRY(ffi_call_SYSV) 36 | .cfi_startproc 37 | /* Save the old stack pointer as AP. */ 38 | mr %r10,%r1 39 | .cfi_def_cfa_register 10 40 | 41 | /* Allocate the stack space we need. */ 42 | stwux %r1,%r1,%r8 43 | /* Save registers we use. */ 44 | mflr %r9 45 | stw %r28,-16(%r10) 46 | stw %r29,-12(%r10) 47 | stw %r30, -8(%r10) 48 | stw %r31, -4(%r10) 49 | stw %r9, 4(%r10) 50 | .cfi_offset 65, 4 51 | .cfi_offset 31, -4 52 | .cfi_offset 30, -8 53 | .cfi_offset 29, -12 54 | .cfi_offset 28, -16 55 | 56 | /* Save arguments over call... */ 57 | stw %r7, -20(%r10) /* closure, */ 58 | mr %r31,%r6 /* flags, */ 59 | mr %r30,%r5 /* rvalue, */ 60 | mr %r29,%r4 /* function address, */ 61 | mr %r28,%r10 /* our AP. */ 62 | .cfi_def_cfa_register 28 63 | 64 | /* Call ffi_prep_args_SYSV. */ 65 | mr %r4,%r1 66 | bl ffi_prep_args_SYSV@local 67 | 68 | /* Now do the call. */ 69 | /* Set up cr1 with bits 4-7 of the flags. */ 70 | mtcrf 0x40,%r31 71 | /* Get the address to call into CTR. */ 72 | mtctr %r29 73 | /* Load all those argument registers. */ 74 | lwz %r3,-24-(8*4)(%r28) 75 | lwz %r4,-24-(7*4)(%r28) 76 | lwz %r5,-24-(6*4)(%r28) 77 | lwz %r6,-24-(5*4)(%r28) 78 | bf- 5,1f 79 | nop 80 | lwz %r7,-24-(4*4)(%r28) 81 | lwz %r8,-24-(3*4)(%r28) 82 | lwz %r9,-24-(2*4)(%r28) 83 | lwz %r10,-24-(1*4)(%r28) 84 | nop 85 | 1: 86 | 87 | #ifndef __NO_FPRS__ 88 | /* Load all the FP registers. */ 89 | bf- 6,2f 90 | lfd %f1,-24-(8*4)-(8*8)(%r28) 91 | lfd %f2,-24-(8*4)-(7*8)(%r28) 92 | lfd %f3,-24-(8*4)-(6*8)(%r28) 93 | lfd %f4,-24-(8*4)-(5*8)(%r28) 94 | nop 95 | lfd %f5,-24-(8*4)-(4*8)(%r28) 96 | lfd %f6,-24-(8*4)-(3*8)(%r28) 97 | lfd %f7,-24-(8*4)-(2*8)(%r28) 98 | lfd %f8,-24-(8*4)-(1*8)(%r28) 99 | #endif 100 | 2: 101 | 102 | /* Make the call. */ 103 | lwz %r11, -20(%r28) 104 | bctrl 105 | 106 | /* Now, deal with the return value. */ 107 | mtcrf 0x03,%r31 /* cr6-cr7 */ 108 | bt- 31,L(small_struct_return_value) 109 | bt- 30,L(done_return_value) 110 | #ifndef __NO_FPRS__ 111 | bt- 29,L(fp_return_value) 112 | #endif 113 | stw %r3,0(%r30) 114 | bf+ 27,L(done_return_value) 115 | stw %r4,4(%r30) 116 | bf 26,L(done_return_value) 117 | stw %r5,8(%r30) 118 | stw %r6,12(%r30) 119 | /* Fall through... */ 120 | 121 | L(done_return_value): 122 | /* Restore the registers we used and return. */ 123 | lwz %r9, 4(%r28) 124 | lwz %r31, -4(%r28) 125 | mtlr %r9 126 | lwz %r30, -8(%r28) 127 | lwz %r29,-12(%r28) 128 | lwz %r28,-16(%r28) 129 | .cfi_remember_state 130 | /* At this point we don't have a cfa register. Say all our 131 | saved regs have been restored. */ 132 | .cfi_same_value 65 133 | .cfi_same_value 31 134 | .cfi_same_value 30 135 | .cfi_same_value 29 136 | .cfi_same_value 28 137 | /* Hopefully this works.. */ 138 | .cfi_def_cfa_register 1 139 | .cfi_offset 1, 0 140 | lwz %r1,0(%r1) 141 | .cfi_same_value 1 142 | blr 143 | 144 | #ifndef __NO_FPRS__ 145 | L(fp_return_value): 146 | .cfi_restore_state 147 | bf 27,L(float_return_value) 148 | stfd %f1,0(%r30) 149 | bf 26,L(done_return_value) 150 | stfd %f2,8(%r30) 151 | b L(done_return_value) 152 | L(float_return_value): 153 | stfs %f1,0(%r30) 154 | b L(done_return_value) 155 | #endif 156 | 157 | L(small_struct_return_value): 158 | /* 159 | * The C code always allocates a properly-aligned 8-byte bounce 160 | * buffer to make this assembly code very simple. Just write out 161 | * r3 and r4 to the buffer to allow the C code to handle the rest. 162 | */ 163 | stw %r3, 0(%r30) 164 | stw %r4, 4(%r30) 165 | b L(done_return_value) 166 | .cfi_endproc 167 | 168 | END(ffi_call_SYSV) 169 | 170 | #if defined __ELF__ && defined __linux__ 171 | .section .note.GNU-stack,"",@progbits 172 | #endif 173 | #endif 174 | -------------------------------------------------------------------------------- /src/riscv/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - 2014 Michael Knyszek 3 | 4 | Target configuration macros for RISC-V. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef __riscv 36 | #error "libffi was configured for a RISC-V target but this does not appear to be a RISC-V compiler." 37 | #endif 38 | 39 | #ifndef LIBFFI_ASM 40 | 41 | typedef unsigned long ffi_arg; 42 | typedef signed long ffi_sarg; 43 | 44 | /* FFI_UNUSED_NN and riscv_unused are to maintain ABI compatibility with a 45 | distributed Berkeley patch from 2014, and can be removed at SONAME bump */ 46 | typedef enum ffi_abi { 47 | FFI_FIRST_ABI = 0, 48 | FFI_SYSV, 49 | FFI_UNUSED_1, 50 | FFI_UNUSED_2, 51 | FFI_UNUSED_3, 52 | FFI_LAST_ABI, 53 | 54 | FFI_DEFAULT_ABI = FFI_SYSV 55 | } ffi_abi; 56 | 57 | #endif /* LIBFFI_ASM */ 58 | 59 | /* ---- Definitions for closures ----------------------------------------- */ 60 | 61 | #define FFI_CLOSURES 1 62 | #define FFI_GO_CLOSURES 1 63 | #define FFI_TRAMPOLINE_SIZE 24 64 | #define FFI_NATIVE_RAW_API 0 65 | #define FFI_EXTRA_CIF_FIELDS unsigned riscv_nfixedargs; unsigned riscv_unused; 66 | #define FFI_TARGET_SPECIFIC_VARIADIC 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /src/s390/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for S390. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #if defined (__s390x__) 36 | #ifndef S390X 37 | #define S390X 38 | #endif 39 | #endif 40 | 41 | /* ---- System specific configurations ----------------------------------- */ 42 | 43 | #ifndef LIBFFI_ASM 44 | typedef unsigned long ffi_arg; 45 | typedef signed long ffi_sarg; 46 | 47 | typedef enum ffi_abi { 48 | FFI_FIRST_ABI = 0, 49 | FFI_SYSV, 50 | FFI_LAST_ABI, 51 | FFI_DEFAULT_ABI = FFI_SYSV 52 | } ffi_abi; 53 | #endif 54 | 55 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 56 | #define FFI_TARGET_HAS_COMPLEX_TYPE 57 | 58 | /* ---- Definitions for closures ----------------------------------------- */ 59 | 60 | #define FFI_CLOSURES 1 61 | #define FFI_GO_CLOSURES 1 62 | #ifdef S390X 63 | #define FFI_TRAMPOLINE_SIZE 32 64 | #else 65 | #define FFI_TRAMPOLINE_SIZE 16 66 | #endif 67 | #define FFI_NATIVE_RAW_API 0 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /src/s390/internal.h: -------------------------------------------------------------------------------- 1 | /* If these values change, sysv.S must be adapted! */ 2 | #define FFI390_RET_DOUBLE 0 3 | #define FFI390_RET_FLOAT 1 4 | #define FFI390_RET_INT64 2 5 | #define FFI390_RET_INT32 3 6 | #define FFI390_RET_VOID 4 7 | 8 | #define FFI360_RET_MASK 7 9 | #define FFI390_RET_IN_MEM 8 10 | 11 | #define FFI390_RET_STRUCT (FFI390_RET_VOID | FFI390_RET_IN_MEM) 12 | 13 | 14 | #if defined(FFI_EXEC_STATIC_TRAMP) 15 | /* 16 | * For the trampoline code table mapping, a mapping size of 4K is chosen. 17 | */ 18 | #define FFI390_TRAMP_MAP_SHIFT 12 19 | #define FFI390_TRAMP_MAP_SIZE (1 << FFI390_TRAMP_MAP_SHIFT) 20 | #define FFI390_TRAMP_SIZE 16 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/sh/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for SuperH. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- Generic type definitions ----------------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | #endif 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 16 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /src/sh64/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for SuperH - SHmedia. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- Generic type definitions ----------------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | 48 | #define FFI_EXTRA_CIF_FIELDS long long flags2 49 | #endif 50 | 51 | /* ---- Definitions for closures ----------------------------------------- */ 52 | 53 | #define FFI_CLOSURES 1 54 | #define FFI_TRAMPOLINE_SIZE 32 55 | #define FFI_NATIVE_RAW_API 0 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /src/sparc/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for SPARC. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- System specific configurations ----------------------------------- */ 36 | 37 | #if defined(__arch64__) || defined(__sparcv9) 38 | #ifndef SPARC64 39 | #define SPARC64 40 | #endif 41 | #endif 42 | 43 | #ifndef LIBFFI_ASM 44 | typedef unsigned long ffi_arg; 45 | typedef signed long ffi_sarg; 46 | 47 | typedef enum ffi_abi { 48 | FFI_FIRST_ABI = 0, 49 | #ifdef SPARC64 50 | FFI_V9, 51 | FFI_DEFAULT_ABI = FFI_V9, 52 | #else 53 | FFI_V8, 54 | FFI_DEFAULT_ABI = FFI_V8, 55 | #endif 56 | FFI_LAST_ABI 57 | } ffi_abi; 58 | #endif 59 | 60 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 1 61 | #define FFI_TARGET_HAS_COMPLEX_TYPE 1 62 | 63 | #ifdef SPARC64 64 | # define FFI_TARGET_SPECIFIC_VARIADIC 1 65 | # define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs 66 | #endif 67 | 68 | /* ---- Definitions for closures ----------------------------------------- */ 69 | 70 | #define FFI_CLOSURES 1 71 | #define FFI_GO_CLOSURES 1 72 | #define FFI_NATIVE_RAW_API 0 73 | 74 | #ifdef SPARC64 75 | #define FFI_TRAMPOLINE_SIZE 24 76 | #else 77 | #define FFI_TRAMPOLINE_SIZE 16 78 | #endif 79 | 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /src/sparc/internal.h: -------------------------------------------------------------------------------- 1 | #define SPARC_RET_VOID 0 2 | #define SPARC_RET_STRUCT 1 3 | #define SPARC_RET_UINT8 2 4 | #define SPARC_RET_SINT8 3 5 | #define SPARC_RET_UINT16 4 6 | #define SPARC_RET_SINT16 5 7 | #define SPARC_RET_UINT32 6 8 | #define SP_V9_RET_SINT32 7 /* v9 only */ 9 | #define SP_V8_RET_CPLX16 7 /* v8 only */ 10 | #define SPARC_RET_INT64 8 11 | #define SPARC_RET_INT128 9 12 | 13 | /* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */ 14 | #define SPARC_RET_F_8 10 15 | #define SPARC_RET_F_6 11 16 | #define SPARC_RET_F_4 12 17 | #define SPARC_RET_F_2 13 18 | #define SP_V9_RET_F_3 14 /* v9 only */ 19 | #define SP_V8_RET_CPLX8 14 /* v8 only */ 20 | #define SPARC_RET_F_1 15 21 | 22 | #define SPARC_FLAG_RET_MASK 15 23 | #define SPARC_FLAG_RET_IN_MEM 32 24 | #define SPARC_FLAG_FP_ARGS 64 25 | 26 | #define SPARC_SIZEMASK_SHIFT 8 27 | -------------------------------------------------------------------------------- /src/tile/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Tilera Corp. 3 | Target configuration macros for TILE. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #ifndef LIBFFI_TARGET_H 27 | #define LIBFFI_TARGET_H 28 | 29 | #ifndef LIBFFI_H 30 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 31 | #endif 32 | 33 | #ifndef LIBFFI_ASM 34 | 35 | #include 36 | 37 | typedef uint_reg_t ffi_arg; 38 | typedef int_reg_t ffi_sarg; 39 | 40 | typedef enum ffi_abi { 41 | FFI_FIRST_ABI = 0, 42 | FFI_UNIX, 43 | FFI_LAST_ABI, 44 | FFI_DEFAULT_ABI = FFI_UNIX 45 | } ffi_abi; 46 | #endif 47 | 48 | /* ---- Definitions for closures ----------------------------------------- */ 49 | #define FFI_CLOSURES 1 50 | 51 | #ifdef __tilegx__ 52 | /* We always pass 8-byte values, even in -m32 mode. */ 53 | # define FFI_SIZEOF_ARG 8 54 | # ifdef __LP64__ 55 | # define FFI_TRAMPOLINE_SIZE (8 * 5) /* 5 bundles */ 56 | # else 57 | # define FFI_TRAMPOLINE_SIZE (8 * 3) /* 3 bundles */ 58 | # endif 59 | #else 60 | # define FFI_SIZEOF_ARG 4 61 | # define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */ 62 | #endif 63 | #define FFI_NATIVE_RAW_API 0 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/types.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | types.c - Copyright (c) 1996, 1998, 2024 Red Hat, Inc. 3 | 4 | Predefined ffi_types needed by libffi. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | /* Hide the basic type definitions from the header file, so that we 28 | can redefine them here as "const". */ 29 | #define LIBFFI_HIDE_BASIC_TYPES 30 | 31 | #include 32 | #include 33 | 34 | /* Type definitions */ 35 | 36 | #define FFI_TYPEDEF(name, type, id, maybe_const)\ 37 | struct struct_align_##name { \ 38 | char c; \ 39 | type x; \ 40 | }; \ 41 | FFI_EXTERN \ 42 | maybe_const ffi_type ffi_type_##name = { \ 43 | sizeof(type), \ 44 | offsetof(struct struct_align_##name, x), \ 45 | id, NULL \ 46 | } 47 | 48 | #define FFI_COMPLEX_TYPEDEF(name, type, maybe_const) \ 49 | static ffi_type *ffi_elements_complex_##name [2] = { \ 50 | (ffi_type *)(&ffi_type_##name), NULL \ 51 | }; \ 52 | struct struct_align_complex_##name { \ 53 | char c; \ 54 | _Complex type x; \ 55 | }; \ 56 | FFI_EXTERN \ 57 | maybe_const ffi_type ffi_type_complex_##name = { \ 58 | sizeof(_Complex type), \ 59 | offsetof(struct struct_align_complex_##name, x), \ 60 | FFI_TYPE_COMPLEX, \ 61 | (ffi_type **)ffi_elements_complex_##name \ 62 | } 63 | 64 | /* Size and alignment are fake here. They must not be 0. */ 65 | FFI_EXTERN const ffi_type ffi_type_void = { 66 | 1, 1, FFI_TYPE_VOID, NULL 67 | }; 68 | 69 | FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8, const); 70 | FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8, const); 71 | FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16, const); 72 | FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16, const); 73 | FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32, const); 74 | FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32, const); 75 | FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64, const); 76 | FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64, const); 77 | 78 | FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const); 79 | 80 | FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const); 81 | FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const); 82 | 83 | #if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ 84 | #define FFI_LDBL_CONST const 85 | #else 86 | #define FFI_LDBL_CONST 87 | #endif 88 | 89 | #ifdef __alpha__ 90 | /* Even if we're not configured to default to 128-bit long double, 91 | maintain binary compatibility, as -mlong-double-128 can be used 92 | at any time. */ 93 | /* Validate the hard-coded number below. */ 94 | # if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4 95 | # error FFI_TYPE_LONGDOUBLE out of date 96 | # endif 97 | const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; 98 | #else 99 | FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE, FFI_LDBL_CONST); 100 | #endif 101 | 102 | #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 103 | FFI_COMPLEX_TYPEDEF(float, float, const); 104 | FFI_COMPLEX_TYPEDEF(double, double, const); 105 | FFI_COMPLEX_TYPEDEF(longdouble, long double, FFI_LDBL_CONST); 106 | #endif 107 | -------------------------------------------------------------------------------- /src/vax/elfbsd.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * vax Foreign Function Interface 26 | */ 27 | 28 | #define LIBFFI_ASM 29 | #include 30 | #include 31 | 32 | .text 33 | 34 | /* 35 | * void * %r0 36 | * ffi_call_elfbsd(extended_cif *ecif, 4(%ap) 37 | * unsigned bytes, 8(%ap) 38 | * unsigned flags, 12(%ap) 39 | * void *rvalue, 16(%ap) 40 | * void (*fn)()); 20(%ap) 41 | */ 42 | .globl ffi_call_elfbsd 43 | .type ffi_call_elfbsd,@function 44 | .align 2 45 | ffi_call_elfbsd: 46 | .word 0x00c # save R2 and R3 47 | 48 | # Allocate stack space for the args 49 | subl2 8(%ap), %sp 50 | 51 | # Call ffi_prep_args 52 | pushl %sp 53 | pushl 4(%ap) 54 | calls $2, ffi_prep_args 55 | 56 | # Get function pointer 57 | movl 20(%ap), %r1 58 | 59 | # Build a CALLS frame 60 | ashl $-2, 8(%ap), %r0 61 | pushl %r0 # argument stack usage 62 | movl %sp, %r0 # future %ap 63 | # saved registers 64 | bbc $11, 0(%r1), 1f 65 | pushl %r11 66 | 1: bbc $10, 0(%r1), 1f 67 | pushl %r10 68 | 1: bbc $9, 0(%r1), 1f 69 | pushl %r9 70 | 1: bbc $8, 0(%r1), 1f 71 | pushl %r8 72 | 1: bbc $7, 0(%r1), 1f 73 | pushl %r7 74 | 1: bbc $6, 0(%r1), 1f 75 | pushl %r6 76 | 1: bbc $5, 0(%r1), 1f 77 | pushl %r5 78 | 1: bbc $4, 0(%r1), 1f 79 | pushl %r4 80 | 1: bbc $3, 0(%r1), 1f 81 | pushl %r3 82 | 1: bbc $2, 0(%r1), 1f 83 | pushl %r2 84 | 1: 85 | pushal 9f 86 | pushl %fp 87 | pushl %ap 88 | movl 16(%ap), %r3 # struct return address, if needed 89 | movl %r0, %ap 90 | movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask 91 | bisl2 $0x20000000, %r0 # calls frame 92 | movzwl 0(%r1), %r2 93 | bicw2 $0xf003, %r2 # only keep R11-R2 94 | ashl $16, %r2, %r2 95 | bisl2 %r2, %r0 # saved register mask of the called function 96 | pushl %r0 97 | pushl $0 98 | movl %sp, %fp 99 | 100 | # Invoke the function 101 | pushal 2(%r1) # skip procedure entry mask 102 | movl %r3, %r1 103 | bicpsw $0x000f 104 | rsb 105 | 106 | 9: 107 | # Copy return value if necessary 108 | tstl 16(%ap) 109 | jeql 9f 110 | movl 16(%ap), %r2 111 | 112 | bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR 113 | movb %r0, 0(%r2) 114 | brb 9f 115 | 1: 116 | bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT 117 | movw %r0, 0(%r2) 118 | brb 9f 119 | 1: 120 | bbc $2, 12(%ap), 1f # CIF_FLAGS_INT 121 | movl %r0, 0(%r2) 122 | brb 9f 123 | 1: 124 | bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT 125 | movq %r0, 0(%r2) 126 | brb 9f 127 | 1: 128 | movl %r1, %r0 # might have been a struct 129 | #brb 9f 130 | 131 | 9: 132 | ret 133 | 134 | /* 135 | * ffi_closure_elfbsd(void); 136 | * invoked with %r0: ffi_closure *closure 137 | */ 138 | .globl ffi_closure_elfbsd 139 | .type ffi_closure_elfbsd, @function 140 | .align 2 141 | ffi_closure_elfbsd: 142 | .word 0 143 | 144 | # Allocate room on stack for return value 145 | subl2 $8, %sp 146 | 147 | # Invoke the closure function 148 | pushal 4(%ap) # calling stack 149 | pushal 4(%sp) # return value 150 | pushl %r0 # closure 151 | calls $3, ffi_closure_elfbsd_inner 152 | 153 | # Copy return value if necessary 154 | bitb $1, %r0 # CIF_FLAGS_CHAR 155 | beql 1f 156 | movb 0(%sp), %r0 157 | brb 9f 158 | 1: 159 | bitb $2, %r0 # CIF_FLAGS_SHORT 160 | beql 1f 161 | movw 0(%sp), %r0 162 | brb 9f 163 | 1: 164 | bitb $4, %r0 # CIF_FLAGS_INT 165 | beql 1f 166 | movl 0(%sp), %r0 167 | brb 9f 168 | 1: 169 | bitb $8, %r0 # CIF_FLAGS_DINT 170 | beql 1f 171 | movq 0(%sp), %r0 172 | #brb 9f 173 | 1: 174 | 175 | 9: 176 | ret 177 | 178 | /* 179 | * ffi_closure_struct_elfbsd(void); 180 | * invoked with %r0: ffi_closure *closure 181 | * %r1: struct return address 182 | */ 183 | .globl ffi_closure_struct_elfbsd 184 | .type ffi_closure_struct_elfbsd, @function 185 | .align 2 186 | ffi_closure_struct_elfbsd: 187 | .word 0 188 | 189 | # Invoke the closure function 190 | pushal 4(%ap) # calling stack 191 | pushl %r1 # return value 192 | pushl %r0 # closure 193 | calls $3, ffi_closure_elfbsd_inner 194 | 195 | ret 196 | -------------------------------------------------------------------------------- /src/vax/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * vax Foreign Function Interface 26 | */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_ASM 32 | typedef unsigned long ffi_arg; 33 | typedef signed long ffi_sarg; 34 | 35 | typedef enum ffi_abi { 36 | FFI_FIRST_ABI = 0, 37 | FFI_ELFBSD, 38 | FFI_DEFAULT_ABI = FFI_ELFBSD, 39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 40 | } ffi_abi; 41 | #endif 42 | 43 | /* ---- Definitions for closures ----------------------------------------- */ 44 | 45 | #define FFI_CLOSURES 1 46 | #define FFI_TRAMPOLINE_SIZE 15 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/wasm32/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2018-2023 Hood Chatham, Brion Vibber, Kleis Auke Wolthuizen, and others. 3 | 4 | Target configuration macros for wasm32. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- Generic type definitions ----------------------------------------- */ 36 | 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | // TODO: https://github.com/emscripten-core/emscripten/issues/9868 41 | typedef void (*ffi_fp)(void); 42 | 43 | typedef enum ffi_abi { 44 | FFI_FIRST_ABI = 0, 45 | FFI_WASM32, // "raw", no structures, varargs, or closures (not implemented!) 46 | FFI_WASM32_EMSCRIPTEN, // structures, varargs, and split 64-bit params 47 | FFI_LAST_ABI, 48 | #ifdef __EMSCRIPTEN__ 49 | FFI_DEFAULT_ABI = FFI_WASM32_EMSCRIPTEN 50 | #else 51 | FFI_DEFAULT_ABI = FFI_WASM32 52 | #endif 53 | } ffi_abi; 54 | 55 | #define FFI_CLOSURES 1 56 | // #define FFI_GO_CLOSURES 0 57 | #define FFI_TRAMPOLINE_SIZE 4 58 | // #define FFI_NATIVE_RAW_API 0 59 | #define FFI_TARGET_SPECIFIC_VARIADIC 1 60 | #define FFI_EXTRA_CIF_FIELDS unsigned int nfixedargs 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/x86/asmnames.h: -------------------------------------------------------------------------------- 1 | #ifndef ASMNAMES_H 2 | #define ASMNAMES_H 3 | 4 | #define C2(X, Y) X ## Y 5 | #define C1(X, Y) C2(X, Y) 6 | #ifdef __USER_LABEL_PREFIX__ 7 | # define C(X) C1(__USER_LABEL_PREFIX__, X) 8 | #else 9 | # define C(X) X 10 | #endif 11 | 12 | #ifdef __APPLE__ 13 | # define L(X) C1(L, X) 14 | #else 15 | # define L(X) C1(.L, X) 16 | #endif 17 | 18 | #if defined(__ELF__) && defined(__PIC__) 19 | # define PLT(X) X@PLT 20 | #else 21 | # define PLT(X) X 22 | #endif 23 | 24 | #ifdef __ELF__ 25 | # define ENDF(X) .type X,@function; .size X, . - X 26 | #else 27 | # define ENDF(X) 28 | #endif 29 | 30 | #endif /* ASMNAMES_H */ 31 | -------------------------------------------------------------------------------- /src/x86/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green 3 | Copyright (c) 1996-2003, 2010 Red Hat, Inc. 4 | Copyright (C) 2008 Free Software Foundation, Inc. 5 | 6 | Target configuration macros for x86 and x86-64. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | 28 | ----------------------------------------------------------------------- */ 29 | 30 | #ifndef LIBFFI_TARGET_H 31 | #define LIBFFI_TARGET_H 32 | 33 | #ifndef LIBFFI_H 34 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 35 | #endif 36 | 37 | /* ---- System specific configurations ----------------------------------- */ 38 | 39 | /* For code common to all platforms on x86 and x86_64. */ 40 | #define X86_ANY 41 | 42 | #if defined (X86_64) && defined (__i386__) 43 | #undef X86_64 44 | #warning ****************************************************** 45 | #warning ********** X86 IS DEFINED **************************** 46 | #warning ****************************************************** 47 | #define X86 48 | #endif 49 | 50 | #ifdef X86_WIN64 51 | #define FFI_SIZEOF_ARG 8 52 | #define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ 53 | #endif 54 | 55 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 56 | #ifndef _MSC_VER 57 | #define FFI_TARGET_HAS_COMPLEX_TYPE 58 | #endif 59 | 60 | /* ---- Generic type definitions ----------------------------------------- */ 61 | 62 | #ifndef LIBFFI_ASM 63 | #ifdef X86_WIN64 64 | #ifdef _MSC_VER 65 | typedef unsigned __int64 ffi_arg; 66 | typedef __int64 ffi_sarg; 67 | #else 68 | typedef unsigned long long ffi_arg; 69 | typedef long long ffi_sarg; 70 | #endif 71 | #else 72 | #if defined __x86_64__ && defined __ILP32__ 73 | #define FFI_SIZEOF_ARG 8 74 | #define FFI_SIZEOF_JAVA_RAW 4 75 | typedef unsigned long long ffi_arg; 76 | typedef long long ffi_sarg; 77 | #else 78 | typedef unsigned long ffi_arg; 79 | typedef signed long ffi_sarg; 80 | #endif 81 | #endif 82 | 83 | typedef enum ffi_abi { 84 | #if defined(X86_WIN64) 85 | FFI_FIRST_ABI = 0, 86 | FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */ 87 | FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */ 88 | FFI_LAST_ABI, 89 | #ifdef __GNUC__ 90 | FFI_DEFAULT_ABI = FFI_GNUW64 91 | #else 92 | FFI_DEFAULT_ABI = FFI_WIN64 93 | #endif 94 | 95 | #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) 96 | FFI_FIRST_ABI = 1, 97 | FFI_UNIX64, 98 | FFI_WIN64, 99 | FFI_EFI64 = FFI_WIN64, 100 | FFI_GNUW64, 101 | FFI_LAST_ABI, 102 | FFI_DEFAULT_ABI = FFI_UNIX64 103 | 104 | #elif defined(X86_WIN32) 105 | FFI_FIRST_ABI = 0, 106 | FFI_SYSV = 1, 107 | FFI_STDCALL = 2, 108 | FFI_THISCALL = 3, 109 | FFI_FASTCALL = 4, 110 | FFI_MS_CDECL = 5, 111 | FFI_PASCAL = 6, 112 | FFI_REGISTER = 7, 113 | FFI_LAST_ABI, 114 | FFI_DEFAULT_ABI = FFI_MS_CDECL 115 | #else 116 | FFI_FIRST_ABI = 0, 117 | FFI_SYSV = 1, 118 | FFI_THISCALL = 3, 119 | FFI_FASTCALL = 4, 120 | FFI_STDCALL = 5, 121 | FFI_PASCAL = 6, 122 | FFI_REGISTER = 7, 123 | FFI_MS_CDECL = 8, 124 | FFI_LAST_ABI, 125 | FFI_DEFAULT_ABI = FFI_SYSV 126 | #endif 127 | } ffi_abi; 128 | #endif 129 | 130 | /* ---- Definitions for closures ----------------------------------------- */ 131 | 132 | #define FFI_CLOSURES 1 133 | #define FFI_GO_CLOSURES 1 134 | 135 | #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) 136 | #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) 137 | #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) 138 | #define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) 139 | 140 | #if defined (X86_64) || defined(X86_WIN64) \ 141 | || (defined (__x86_64__) && defined (X86_DARWIN)) 142 | /* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP 143 | + 8 bytes of pointer. */ 144 | # define FFI_TRAMPOLINE_SIZE 32 145 | # define FFI_NATIVE_RAW_API 0 146 | #else 147 | /* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused 148 | bytes. */ 149 | # define FFI_TRAMPOLINE_SIZE 16 150 | # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ 151 | #endif 152 | 153 | #if !defined(GENERATE_LIBFFI_MAP) && defined(__CET__) 154 | # include 155 | # if (__CET__ & 1) != 0 156 | # define ENDBR_PRESENT 157 | # endif 158 | # define _CET_NOTRACK notrack 159 | #else 160 | # define _CET_ENDBR 161 | # define _CET_NOTRACK 162 | #endif 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /src/x86/internal.h: -------------------------------------------------------------------------------- 1 | #define X86_RET_FLOAT 0 2 | #define X86_RET_DOUBLE 1 3 | #define X86_RET_LDOUBLE 2 4 | #define X86_RET_SINT8 3 5 | #define X86_RET_SINT16 4 6 | #define X86_RET_UINT8 5 7 | #define X86_RET_UINT16 6 8 | #define X86_RET_INT64 7 9 | #define X86_RET_INT32 8 10 | #define X86_RET_VOID 9 11 | #define X86_RET_STRUCTPOP 10 12 | #define X86_RET_STRUCTARG 11 13 | #define X86_RET_STRUCT_1B 12 14 | #define X86_RET_STRUCT_2B 13 15 | #define X86_RET_UNUSED14 14 16 | #define X86_RET_UNUSED15 15 17 | 18 | #define X86_RET_TYPE_MASK 15 19 | #define X86_RET_POP_SHIFT 4 20 | 21 | #define R_EAX 0 22 | #define R_EDX 1 23 | #define R_ECX 2 24 | 25 | #ifdef __PCC__ 26 | # define HAVE_FASTCALL 0 27 | #else 28 | # define HAVE_FASTCALL 1 29 | #endif 30 | 31 | #if defined(FFI_EXEC_STATIC_TRAMP) 32 | /* 33 | * For the trampoline code table mapping, a mapping size of 4K (base page size) 34 | * is chosen. 35 | */ 36 | #define X86_TRAMP_MAP_SHIFT 12 37 | #define X86_TRAMP_MAP_SIZE (1 << X86_TRAMP_MAP_SHIFT) 38 | #ifdef ENDBR_PRESENT 39 | #define X86_TRAMP_SIZE 44 40 | #else 41 | #define X86_TRAMP_SIZE 40 42 | #endif 43 | #endif 44 | -------------------------------------------------------------------------------- /src/x86/internal64.h: -------------------------------------------------------------------------------- 1 | #define UNIX64_RET_VOID 0 2 | #define UNIX64_RET_UINT8 1 3 | #define UNIX64_RET_UINT16 2 4 | #define UNIX64_RET_UINT32 3 5 | #define UNIX64_RET_SINT8 4 6 | #define UNIX64_RET_SINT16 5 7 | #define UNIX64_RET_SINT32 6 8 | #define UNIX64_RET_INT64 7 9 | #define UNIX64_RET_XMM32 8 10 | #define UNIX64_RET_XMM64 9 11 | #define UNIX64_RET_X87 10 12 | #define UNIX64_RET_X87_2 11 13 | #define UNIX64_RET_ST_XMM0_RAX 12 14 | #define UNIX64_RET_ST_RAX_XMM0 13 15 | #define UNIX64_RET_ST_XMM0_XMM1 14 16 | #define UNIX64_RET_ST_RAX_RDX 15 17 | 18 | #define UNIX64_RET_LAST 15 19 | 20 | #define UNIX64_FLAG_RET_IN_MEM (1 << 10) 21 | #define UNIX64_FLAG_XMM_ARGS (1 << 11) 22 | #define UNIX64_SIZE_SHIFT 12 23 | 24 | #if defined(FFI_EXEC_STATIC_TRAMP) 25 | /* 26 | * For the trampoline code table mapping, a mapping size of 4K (base page size) 27 | * is chosen. 28 | */ 29 | #define UNIX64_TRAMP_MAP_SHIFT 12 30 | #define UNIX64_TRAMP_MAP_SIZE (1 << UNIX64_TRAMP_MAP_SHIFT) 31 | #ifdef ENDBR_PRESENT 32 | #define UNIX64_TRAMP_SIZE 40 33 | #else 34 | #define UNIX64_TRAMP_SIZE 32 35 | #endif 36 | #endif 37 | -------------------------------------------------------------------------------- /src/x86/win64.S: -------------------------------------------------------------------------------- 1 | #ifdef __x86_64__ 2 | #define LIBFFI_ASM 3 | #include 4 | #include 5 | #include 6 | #include "asmnames.h" 7 | 8 | #if defined(HAVE_AS_CFI_PSEUDO_OP) 9 | .cfi_sections .debug_frame 10 | #endif 11 | 12 | #ifdef X86_WIN64 13 | #define SEH(...) __VA_ARGS__ 14 | #define arg0 %rcx 15 | #define arg1 %rdx 16 | #define arg2 %r8 17 | #define arg3 %r9 18 | #else 19 | #define SEH(...) 20 | #define arg0 %rdi 21 | #define arg1 %rsi 22 | #define arg2 %rdx 23 | #define arg3 %rcx 24 | #endif 25 | 26 | /* This macro allows the safe creation of jump tables without an 27 | actual table. The entry points into the table are all 8 bytes. 28 | The use of ORG asserts that we're at the correct location. */ 29 | /* ??? The clang assembler doesn't handle .org with symbolic expressions. */ 30 | #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) 31 | # define E(BASE, X) .balign 8 32 | #else 33 | # define E(BASE, X) .balign 8; .org BASE + (X) * 8 34 | #endif 35 | 36 | .text 37 | 38 | /* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10) 39 | 40 | Bit o trickiness here -- FRAME is the base of the stack frame 41 | for this function. This has been allocated by ffi_call. We also 42 | deallocate some of the stack that has been alloca'd. */ 43 | 44 | .align 8 45 | .globl C(ffi_call_win64) 46 | FFI_HIDDEN(C(ffi_call_win64)) 47 | 48 | SEH(.seh_proc ffi_call_win64) 49 | C(ffi_call_win64): 50 | cfi_startproc 51 | _CET_ENDBR 52 | /* Set up the local stack frame and install it in rbp/rsp. */ 53 | movq (%rsp), %rax 54 | movq %rbp, (arg1) 55 | movq %rax, 8(arg1) 56 | movq arg1, %rbp 57 | cfi_def_cfa(%rbp, 16) 58 | cfi_rel_offset(%rbp, 0) 59 | SEH(.seh_pushreg %rbp) 60 | SEH(.seh_setframe %rbp, 0) 61 | SEH(.seh_endprologue) 62 | movq arg0, %rsp 63 | 64 | movq arg2, %r10 65 | 66 | /* Load all slots into both general and xmm registers. */ 67 | movq (%rsp), %rcx 68 | movsd (%rsp), %xmm0 69 | movq 8(%rsp), %rdx 70 | movsd 8(%rsp), %xmm1 71 | movq 16(%rsp), %r8 72 | movsd 16(%rsp), %xmm2 73 | movq 24(%rsp), %r9 74 | movsd 24(%rsp), %xmm3 75 | 76 | call *16(%rbp) 77 | 78 | movl 24(%rbp), %ecx 79 | movq 32(%rbp), %r8 80 | leaq 0f(%rip), %r10 81 | cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx 82 | leaq (%r10, %rcx, 8), %r10 83 | ja 99f 84 | _CET_NOTRACK jmp *%r10 85 | 86 | /* Below, we're space constrained most of the time. Thus we eschew the 87 | modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */ 88 | #define epilogue \ 89 | leaveq; \ 90 | cfi_remember_state; \ 91 | cfi_def_cfa(%rsp, 8); \ 92 | cfi_restore(%rbp); \ 93 | ret; \ 94 | cfi_restore_state 95 | 96 | .align 8 97 | 0: 98 | E(0b, FFI_TYPE_VOID) 99 | epilogue 100 | E(0b, FFI_TYPE_INT) 101 | movslq %eax, %rax 102 | movq %rax, (%r8) 103 | epilogue 104 | E(0b, FFI_TYPE_FLOAT) 105 | movss %xmm0, (%r8) 106 | epilogue 107 | E(0b, FFI_TYPE_DOUBLE) 108 | movsd %xmm0, (%r8) 109 | epilogue 110 | // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here. 111 | E(0b, FFI_TYPE_DOUBLE + 1) 112 | call PLT(C(abort)) 113 | E(0b, FFI_TYPE_UINT8) 114 | movzbl %al, %eax 115 | movq %rax, (%r8) 116 | epilogue 117 | E(0b, FFI_TYPE_SINT8) 118 | movsbq %al, %rax 119 | jmp 98f 120 | E(0b, FFI_TYPE_UINT16) 121 | movzwl %ax, %eax 122 | movq %rax, (%r8) 123 | epilogue 124 | E(0b, FFI_TYPE_SINT16) 125 | movswq %ax, %rax 126 | jmp 98f 127 | E(0b, FFI_TYPE_UINT32) 128 | movl %eax, %eax 129 | movq %rax, (%r8) 130 | epilogue 131 | E(0b, FFI_TYPE_SINT32) 132 | movslq %eax, %rax 133 | movq %rax, (%r8) 134 | epilogue 135 | E(0b, FFI_TYPE_UINT64) 136 | 98: movq %rax, (%r8) 137 | epilogue 138 | E(0b, FFI_TYPE_SINT64) 139 | movq %rax, (%r8) 140 | epilogue 141 | E(0b, FFI_TYPE_STRUCT) 142 | epilogue 143 | E(0b, FFI_TYPE_POINTER) 144 | movq %rax, (%r8) 145 | epilogue 146 | E(0b, FFI_TYPE_COMPLEX) 147 | call PLT(C(abort)) 148 | E(0b, FFI_TYPE_SMALL_STRUCT_1B) 149 | movb %al, (%r8) 150 | epilogue 151 | E(0b, FFI_TYPE_SMALL_STRUCT_2B) 152 | movw %ax, (%r8) 153 | epilogue 154 | E(0b, FFI_TYPE_SMALL_STRUCT_4B) 155 | movl %eax, (%r8) 156 | epilogue 157 | 158 | .align 8 159 | 99: call PLT(C(abort)) 160 | 161 | epilogue 162 | 163 | cfi_endproc 164 | SEH(.seh_endproc) 165 | 166 | 167 | /* 32 bytes of outgoing register stack space, 8 bytes of alignment, 168 | 16 bytes of result, 32 bytes of xmm registers. */ 169 | #define ffi_clo_FS (32+8+16+32) 170 | #define ffi_clo_OFF_R (32+8) 171 | #define ffi_clo_OFF_X (32+8+16) 172 | 173 | .align 8 174 | .globl C(ffi_go_closure_win64) 175 | FFI_HIDDEN(C(ffi_go_closure_win64)) 176 | 177 | SEH(.seh_proc ffi_go_closure_win64) 178 | C(ffi_go_closure_win64): 179 | cfi_startproc 180 | _CET_ENDBR 181 | /* Save all integer arguments into the incoming reg stack space. */ 182 | movq %rcx, 8(%rsp) 183 | movq %rdx, 16(%rsp) 184 | movq %r8, 24(%rsp) 185 | movq %r9, 32(%rsp) 186 | 187 | movq 8(%r10), %rcx /* load cif */ 188 | movq 16(%r10), %rdx /* load fun */ 189 | movq %r10, %r8 /* closure is user_data */ 190 | jmp 0f 191 | cfi_endproc 192 | SEH(.seh_endproc) 193 | 194 | .align 8 195 | .globl C(ffi_closure_win64) 196 | FFI_HIDDEN(C(ffi_closure_win64)) 197 | 198 | SEH(.seh_proc ffi_closure_win64) 199 | C(ffi_closure_win64): 200 | cfi_startproc 201 | _CET_ENDBR 202 | /* Save all integer arguments into the incoming reg stack space. */ 203 | movq %rcx, 8(%rsp) 204 | movq %rdx, 16(%rsp) 205 | movq %r8, 24(%rsp) 206 | movq %r9, 32(%rsp) 207 | 208 | movq FFI_TRAMPOLINE_SIZE(%r10), %rcx /* load cif */ 209 | movq FFI_TRAMPOLINE_SIZE+8(%r10), %rdx /* load fun */ 210 | movq FFI_TRAMPOLINE_SIZE+16(%r10), %r8 /* load user_data */ 211 | 0: 212 | subq $ffi_clo_FS, %rsp 213 | cfi_adjust_cfa_offset(ffi_clo_FS) 214 | SEH(.seh_stackalloc ffi_clo_FS) 215 | SEH(.seh_endprologue) 216 | 217 | /* Save all sse arguments into the stack frame. */ 218 | movsd %xmm0, ffi_clo_OFF_X(%rsp) 219 | movsd %xmm1, ffi_clo_OFF_X+8(%rsp) 220 | movsd %xmm2, ffi_clo_OFF_X+16(%rsp) 221 | movsd %xmm3, ffi_clo_OFF_X+24(%rsp) 222 | 223 | leaq ffi_clo_OFF_R(%rsp), %r9 224 | call PLT(C(ffi_closure_win64_inner)) 225 | 226 | /* Load the result into both possible result registers. */ 227 | movq ffi_clo_OFF_R(%rsp), %rax 228 | movsd ffi_clo_OFF_R(%rsp), %xmm0 229 | 230 | addq $ffi_clo_FS, %rsp 231 | cfi_adjust_cfa_offset(-ffi_clo_FS) 232 | ret 233 | 234 | cfi_endproc 235 | SEH(.seh_endproc) 236 | 237 | #if defined(FFI_EXEC_STATIC_TRAMP) 238 | .align 8 239 | .globl C(ffi_closure_win64_alt) 240 | FFI_HIDDEN(C(ffi_closure_win64_alt)) 241 | 242 | SEH(.seh_proc ffi_closure_win64_alt) 243 | C(ffi_closure_win64_alt): 244 | _CET_ENDBR 245 | movq 8(%rsp), %r10 246 | addq $16, %rsp 247 | jmp C(ffi_closure_win64) 248 | SEH(.seh_endproc) 249 | #endif 250 | #endif /* __x86_64__ */ 251 | 252 | #if defined __ELF__ && defined __linux__ 253 | .section .note.GNU-stack,"",@progbits 254 | #endif 255 | -------------------------------------------------------------------------------- /src/xtensa/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2013 Tensilica, Inc. 3 | Target configuration macros for XTENSA. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #ifndef LIBFFI_TARGET_H 27 | #define LIBFFI_TARGET_H 28 | 29 | #ifndef LIBFFI_H 30 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 31 | #endif 32 | 33 | #ifndef LIBFFI_ASM 34 | typedef unsigned long ffi_arg; 35 | typedef signed long ffi_sarg; 36 | 37 | typedef enum ffi_abi { 38 | FFI_FIRST_ABI = 0, 39 | FFI_SYSV, 40 | FFI_LAST_ABI, 41 | FFI_DEFAULT_ABI = FFI_SYSV 42 | } ffi_abi; 43 | #endif 44 | 45 | #define FFI_REGISTER_NARGS 6 46 | #define XTENSA_STACK_ALIGNMENT 16 47 | #define FFI_REGISTER_ARGS_SPACE ((FFI_REGISTER_NARGS * 4 + \ 48 | XTENSA_STACK_ALIGNMENT - 1) & \ 49 | -XTENSA_STACK_ALIGNMENT) 50 | 51 | /* ---- Definitions for closures ----------------------------------------- */ 52 | 53 | #define FFI_CLOSURES 1 54 | #define FFI_NATIVE_RAW_API 0 55 | #define FFI_TRAMPOLINE_SIZE 24 56 | 57 | #endif 58 | --------------------------------------------------------------------------------