mirror of
https://gitee.com/openharmony/third_party_libffi
synced 2024-11-26 20:50:43 +00:00
update OpenHarmony 2.0 Canary
This commit is contained in:
parent
9c23556a03
commit
8645466be1
15
.gitattributes
vendored
Normal file
15
.gitattributes
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.trp filter=lfs diff=lfs merge=lfs -text
|
||||
*.apk filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.asm filter=lfs diff=lfs merge=lfs -text
|
||||
*.8svn filter=lfs diff=lfs merge=lfs -text
|
||||
*.9svn filter=lfs diff=lfs merge=lfs -text
|
||||
*.dylib filter=lfs diff=lfs merge=lfs -text
|
||||
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||
*.a filter=lfs diff=lfs merge=lfs -text
|
||||
*.so filter=lfs diff=lfs merge=lfs -text
|
||||
*.bin filter=lfs diff=lfs merge=lfs -text
|
||||
*.dll filter=lfs diff=lfs merge=lfs -text
|
90
BUILD.gn
Executable file
90
BUILD.gn
Executable file
@ -0,0 +1,90 @@
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
if (target_cpu == "arm") {
|
||||
config("ffi_config") {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
include_dirs = [
|
||||
".",
|
||||
"./include",
|
||||
"./src/arm",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
"-DTARGET=ARM",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-implicit-function-declaration",
|
||||
"-Wno-extern-initializer",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_source_set("ffi_source") {
|
||||
sources = [
|
||||
"src/prep_cif.c",
|
||||
"src/types.c",
|
||||
"src/raw_api.c",
|
||||
"src/java_raw_api.c",
|
||||
"src/closures.c",
|
||||
"src/arm/ffi.c",
|
||||
"src/arm/sysv.S",
|
||||
]
|
||||
|
||||
configs = [
|
||||
":ffi_config",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
config("ffi_config") {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
include_dirs = [
|
||||
".",
|
||||
"./include",
|
||||
"./src/aarch64",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
"-DTARGET=AARCH64",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-implicit-function-declaration",
|
||||
"-Wno-extern-initializer",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_source_set("ffi_source") {
|
||||
sources = [
|
||||
"src/prep_cif.c",
|
||||
"src/types.c",
|
||||
"src/raw_api.c",
|
||||
"src/java_raw_api.c",
|
||||
"src/closures.c",
|
||||
"src/aarch64/ffi.c",
|
||||
"src/aarch64/sysv.S",
|
||||
]
|
||||
|
||||
configs = [
|
||||
":ffi_config",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("ffi_public_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_shared_library("ffi") {
|
||||
deps = [
|
||||
":ffi_source",
|
||||
]
|
||||
|
||||
public_configs = [
|
||||
":ffi_public_config",
|
||||
]
|
||||
|
||||
part_name = "multimedia_histreamer"
|
||||
subsystem_name = "multimedia"
|
||||
}
|
7407
ChangeLog.old
Normal file
7407
ChangeLog.old
Normal file
File diff suppressed because it is too large
Load Diff
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
libffi - Copyright (c) 1996-2019 Anthony Green, Red Hat, Inc and others.
|
||||
See source files for details.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
353
LICENSE-BUILDTOOLS
Normal file
353
LICENSE-BUILDTOOLS
Normal file
@ -0,0 +1,353 @@
|
||||
The libffi source distribution contains certain code that is not part
|
||||
of libffi, and is only used as tooling to assist with the building and
|
||||
testing of libffi. This includes the msvcc.sh script used to wrap the
|
||||
Microsoft compiler with GNU compatible command-line options,
|
||||
make_sunver.pl, and the libffi test code distributed in the
|
||||
testsuite/libffi.bhaible directory. This code is distributed with
|
||||
libffi for the purpose of convenience only, and libffi is in no way
|
||||
derived from this code.
|
||||
|
||||
msvcc.sh an testsuite/libffi.bhaible are both distributed under the
|
||||
terms of the GNU GPL version 2, as below.
|
||||
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
159
Makefile.am
Normal file
159
Makefile.am
Normal file
@ -0,0 +1,159 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = include testsuite man
|
||||
if BUILD_DOCS
|
||||
## This hack is needed because it doesn't seem possible to make a
|
||||
## conditional info_TEXINFOS in Automake. At least Automake 1.14
|
||||
## either gives errors -- if this attempted in the most
|
||||
## straightforward way -- or simply unconditionally tries to build the
|
||||
## info file.
|
||||
SUBDIRS += doc
|
||||
endif
|
||||
|
||||
EXTRA_DIST = LICENSE ChangeLog.old \
|
||||
m4/libtool.m4 m4/lt~obsolete.m4 \
|
||||
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
|
||||
m4/ltversion.m4 src/debug.c msvcc.sh \
|
||||
generate-darwin-source-and-headers.py \
|
||||
libffi.xcodeproj/project.pbxproj \
|
||||
libtool-ldflags libtool-version configure.host README.md \
|
||||
libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl
|
||||
|
||||
# local.exp is generated by configure
|
||||
DISTCLEANFILES = local.exp
|
||||
|
||||
# Subdir rules rely on $(FLAGS_TO_PASS)
|
||||
FLAGS_TO_PASS = $(AM_MAKEFLAGS)
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libffi.pc
|
||||
|
||||
toolexeclib_LTLIBRARIES = libffi.la
|
||||
noinst_LTLIBRARIES = libffi_convenience.la
|
||||
|
||||
libffi_la_SOURCES = src/prep_cif.c src/types.c \
|
||||
src/raw_api.c src/java_raw_api.c src/closures.c
|
||||
|
||||
if FFI_DEBUG
|
||||
libffi_la_SOURCES += src/debug.c
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
src/aarch64/ffitarget.h src/aarch64/internal.h \
|
||||
src/alpha/ffitarget.h src/alpha/internal.h \
|
||||
src/arc/ffitarget.h \
|
||||
src/arm/ffitarget.h src/arm/internal.h \
|
||||
src/avr32/ffitarget.h \
|
||||
src/bfin/ffitarget.h \
|
||||
src/cris/ffitarget.h \
|
||||
src/frv/ffitarget.h \
|
||||
src/ia64/ffitarget.h src/ia64/ia64_flags.h \
|
||||
src/m32r/ffitarget.h \
|
||||
src/m68k/ffitarget.h \
|
||||
src/m88k/ffitarget.h \
|
||||
src/metag/ffitarget.h \
|
||||
src/microblaze/ffitarget.h \
|
||||
src/mips/ffitarget.h \
|
||||
src/moxie/ffitarget.h \
|
||||
src/nios2/ffitarget.h \
|
||||
src/or1k/ffitarget.h \
|
||||
src/pa/ffitarget.h \
|
||||
src/powerpc/ffitarget.h src/powerpc/asm.h src/powerpc/ffi_powerpc.h \
|
||||
src/riscv/ffitarget.h \
|
||||
src/s390/ffitarget.h src/s390/internal.h \
|
||||
src/sh/ffitarget.h \
|
||||
src/sh64/ffitarget.h \
|
||||
src/sparc/ffitarget.h src/sparc/internal.h \
|
||||
src/tile/ffitarget.h \
|
||||
src/vax/ffitarget.h \
|
||||
src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h src/x86/asmnames.h \
|
||||
src/xtensa/ffitarget.h \
|
||||
src/dlmalloc.c
|
||||
|
||||
EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \
|
||||
src/aarch64/win64_armasm.S src/alpha/ffi.c src/alpha/osf.S \
|
||||
src/arc/ffi.c src/arc/arcompact.S src/arm/ffi.c \
|
||||
src/arm/sysv.S src/arm/ffi.c src/arm/sysv_msvc_arm32.S \
|
||||
src/avr32/ffi.c src/avr32/sysv.S src/bfin/ffi.c \
|
||||
src/bfin/sysv.S src/cris/ffi.c src/cris/sysv.S src/frv/ffi.c \
|
||||
src/frv/eabi.S src/ia64/ffi.c src/ia64/unix.S src/m32r/ffi.c \
|
||||
src/m32r/sysv.S src/m68k/ffi.c src/m68k/sysv.S src/m88k/ffi.c \
|
||||
src/m88k/obsd.S src/metag/ffi.c src/metag/sysv.S \
|
||||
src/microblaze/ffi.c src/microblaze/sysv.S src/mips/ffi.c \
|
||||
src/mips/o32.S src/mips/n32.S src/moxie/ffi.c \
|
||||
src/moxie/eabi.S src/nios2/ffi.c src/nios2/sysv.S \
|
||||
src/or1k/ffi.c src/or1k/sysv.S src/pa/ffi.c src/pa/linux.S \
|
||||
src/pa/hpux32.S src/powerpc/ffi.c src/powerpc/ffi_sysv.c \
|
||||
src/powerpc/ffi_linux64.c src/powerpc/sysv.S \
|
||||
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
|
||||
src/powerpc/ppc_closure.S src/powerpc/aix.S \
|
||||
src/powerpc/darwin.S src/powerpc/aix_closure.S \
|
||||
src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c \
|
||||
src/riscv/ffi.c src/riscv/sysv.S src/s390/ffi.c \
|
||||
src/s390/sysv.S src/sh/ffi.c src/sh/sysv.S src/sh64/ffi.c \
|
||||
src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \
|
||||
src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \
|
||||
src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \
|
||||
src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \
|
||||
src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \
|
||||
src/xtensa/ffi.c src/xtensa/sysv.S
|
||||
|
||||
TARGET_OBJ = @TARGET_OBJ@
|
||||
libffi_la_LIBADD = $(TARGET_OBJ)
|
||||
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
EXTRA_libffi_convenience_la_SOURCES = $(EXTRA_libffi_la_SOURCES)
|
||||
libffi_convenience_la_LIBADD = $(libffi_la_LIBADD)
|
||||
libffi_convenience_la_DEPENDENCIES = $(libffi_la_DEPENDENCIES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS))
|
||||
|
||||
AM_CFLAGS =
|
||||
if FFI_DEBUG
|
||||
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
|
||||
# MSVC, it can link against the debug CRT.
|
||||
AM_CFLAGS += -DFFI_DEBUG
|
||||
endif
|
||||
|
||||
if LIBFFI_BUILD_VERSIONED_SHLIB
|
||||
if LIBFFI_BUILD_VERSIONED_SHLIB_GNU
|
||||
libffi_version_script = -Wl,--version-script,libffi.map
|
||||
libffi_version_dep = libffi.map
|
||||
endif
|
||||
if LIBFFI_BUILD_VERSIONED_SHLIB_SUN
|
||||
libffi_version_script = -Wl,-M,libffi.map-sun
|
||||
libffi_version_dep = libffi.map-sun
|
||||
libffi.map-sun : libffi.map $(top_srcdir)/make_sunver.pl \
|
||||
$(libffi_la_OBJECTS) $(libffi_la_LIBADD)
|
||||
perl $(top_srcdir)/make_sunver.pl libffi.map \
|
||||
`echo $(libffi_la_OBJECTS) $(libffi_la_LIBADD) | \
|
||||
sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
|
||||
> $@ || (rm -f $@ ; exit 1)
|
||||
endif
|
||||
else
|
||||
libffi_version_script =
|
||||
libffi_version_dep =
|
||||
endif
|
||||
libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
|
||||
|
||||
libffi.map: $(top_srcdir)/libffi.map.in
|
||||
$(COMPILE) -D$(TARGET) -E -x assembler-with-cpp -o $@ $<
|
||||
|
||||
libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
|
||||
libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
|
||||
|
||||
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
|
||||
dist-hook:
|
||||
d=`(cd $(distdir); pwd)`; (cd doc; make pdf; cp *.pdf $$d/doc)
|
||||
if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog
|
||||
s=`awk '/was released on/{ print NR; exit}' $(top_srcdir)/README.md`; tail -n +$$(($$s-1)) $(top_srcdir)/README.md > $(distdir)/README.md
|
||||
|
2024
Makefile.in
Normal file
2024
Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
70
OAT.xml
Executable file
70
OAT.xml
Executable file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Notes:
|
||||
This is project config file for OpenHarmony OSS Audit Tool, if you have any questions or concerns, please email chenyaxun@huawei.com.
|
||||
-->
|
||||
<!-- OAT(OSS Audit Tool) configuration guide:
|
||||
basedir: Root dir, the basedir + project path is the real source file location.
|
||||
licensefile:
|
||||
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
|
||||
|
||||
tasklist(only for batch mode):
|
||||
1. task: Define oat check thread, each task will start a new thread.
|
||||
2. task name: Only an name, no practical effect.
|
||||
3. task policy: Default policy for projects under this task, this field is required and the specified policy must defined in policylist.
|
||||
4. task filter: Default filefilter for projects under this task, this field is required and the specified filefilter must defined in filefilterlist.
|
||||
5. task project: Projects to be checked, the path field define the source root dir of the project.
|
||||
|
||||
|
||||
policyList:
|
||||
1. policy: All policyitems will be merged to default OAT.xml rules, the name of policy doesn't affect OAT check process.
|
||||
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
|
||||
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
3. policyitem type:
|
||||
"compatibility" is used to check license compatibility in the specified path;
|
||||
"license" is used to check source license header in the specified path;
|
||||
"copyright" is used to check source copyright header in the specified path;
|
||||
"import" is used to check source dependency in the specified path, such as import ... ,include ...
|
||||
"filetype" is used to check file type in the specified path, supported file types: archive, binary
|
||||
"filename" is used to check whether the specified file exists in the specified path(support projectroot in default OAT.xml), supported file names: LICENSE, README, README.OpenSource
|
||||
|
||||
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
|
||||
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
|
||||
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
|
||||
7. policyitem filefilter: Used to bind filefilter which define filter rules.
|
||||
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
|
||||
|
||||
Note:If the text contains special characters, please escape them according to the following rules:
|
||||
" == >
|
||||
& == >
|
||||
' == >
|
||||
< == >
|
||||
> == >
|
||||
-->
|
||||
<configuration>
|
||||
<oatconfig>
|
||||
<licensefile></licensefile>
|
||||
<policylist>
|
||||
<policy name="projectPolicy" desc="">
|
||||
</policy>
|
||||
</policylist>
|
||||
<filefilterlist>
|
||||
<filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
|
||||
<filteritem type="filepath" name=".*" desc="The files involved in compilation are the MIT protocol.They are used in dynamic link mode."/>
|
||||
</filefilter>
|
||||
</filefilterlist>
|
||||
</oatconfig>
|
||||
</configuration>
|
10
README.OpenSource
Normal file
10
README.OpenSource
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"Name": "libffi",
|
||||
"License": "MIT License",
|
||||
"License File": "LICENSE",
|
||||
"Version Number": "3.3",
|
||||
"Upstream URL": "https://sourceware.org/libffi/",
|
||||
"Description": "The libffi library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run-time."
|
||||
}
|
||||
]
|
36
README.en.md
36
README.en.md
@ -1,36 +0,0 @@
|
||||
# third_party_libffi
|
||||
|
||||
#### Description
|
||||
Third-party open-source software libffi | 三方开源软件libffi
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
489
README.md
489
README.md
@ -1,37 +1,472 @@
|
||||
# third_party_libffi
|
||||
|
||||
#### 介绍
|
||||
Third-party open-source software libffi | 三方开源软件libffi
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
libffi-3.3 was released on November 23, 2019. Check the libffi web
|
||||
page for updates: <URL:http://sourceware.org/libffi/>.
|
||||
|
||||
|
||||
#### 安装教程
|
||||
What is libffi?
|
||||
===============
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
Compilers for high level languages generate code that follow certain
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the "calling
|
||||
convention". The "calling convention" is essentially a set of
|
||||
assumptions made by the compiler about where function arguments will
|
||||
be found on entry to a function. A "calling convention" also specifies
|
||||
where the return value for a function is found.
|
||||
|
||||
#### 使用说明
|
||||
Some programs may not know at the time of compilation what arguments
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
told at run-time about the number and types of arguments used to call
|
||||
a given function. Libffi can be used in such programs to provide a
|
||||
bridge from the interpreter program to compiled code.
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
The libffi library provides a portable, high level programming
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
call any function specified by a call interface description at run
|
||||
time.
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
FFI stands for Foreign Function Interface. A foreign function
|
||||
interface is the popular name for the interface that allows code
|
||||
written in one language to call code written in another language. The
|
||||
libffi library really only provides the lowest, machine dependent
|
||||
layer of a fully featured foreign function interface. A layer must
|
||||
exist above libffi that handles type conversions for values passed
|
||||
between the two languages.
|
||||
|
||||
|
||||
#### 特技
|
||||
Supported Platforms
|
||||
===================
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
Libffi has been ported to many different platforms.
|
||||
|
||||
At the time of release, the following basic configurations have been
|
||||
tested:
|
||||
|
||||
| Architecture | Operating System | Compiler |
|
||||
| --------------- | ---------------- | ----------------------- |
|
||||
| AArch64 (ARM64) | iOS | Clang |
|
||||
| AArch64 | Linux | GCC |
|
||||
| AArch64 | Windows | MSVC |
|
||||
| Alpha | Linux | GCC |
|
||||
| Alpha | Tru64 | GCC |
|
||||
| ARC | Linux | GCC |
|
||||
| ARM | Linux | GCC |
|
||||
| ARM | iOS | GCC |
|
||||
| ARM | Windows | MSVC |
|
||||
| AVR32 | Linux | GCC |
|
||||
| Blackfin | uClinux | GCC |
|
||||
| HPPA | HPUX | GCC |
|
||||
| IA-64 | Linux | GCC |
|
||||
| M68K | FreeMiNT | GCC |
|
||||
| M68K | Linux | GCC |
|
||||
| M68K | RTEMS | GCC |
|
||||
| M88K | OpenBSD/mvme88k | GCC |
|
||||
| Meta | Linux | GCC |
|
||||
| MicroBlaze | Linux | GCC |
|
||||
| MIPS | IRIX | GCC |
|
||||
| MIPS | Linux | GCC |
|
||||
| MIPS | RTEMS | GCC |
|
||||
| MIPS64 | Linux | GCC |
|
||||
| Moxie | Bare metal | GCC |
|
||||
| Nios II | Linux | GCC |
|
||||
| OpenRISC | Linux | GCC |
|
||||
| PowerPC 32-bit | AIX | IBM XL C |
|
||||
| PowerPC 64-bit | AIX | IBM XL C |
|
||||
| PowerPC | AMIGA | GCC |
|
||||
| PowerPC | Linux | GCC |
|
||||
| PowerPC | Mac OSX | GCC |
|
||||
| PowerPC | FreeBSD | GCC |
|
||||
| PowerPC 64-bit | FreeBSD | GCC |
|
||||
| PowerPC 64-bit | Linux ELFv1 | GCC |
|
||||
| PowerPC 64-bit | Linux ELFv2 | GCC |
|
||||
| RISC-V 32-bit | Linux | GCC |
|
||||
| RISC-V 64-bit | Linux | GCC |
|
||||
| S390 | Linux | GCC |
|
||||
| S390X | Linux | GCC |
|
||||
| SPARC | Linux | GCC |
|
||||
| SPARC | Solaris | GCC |
|
||||
| SPARC | Solaris | Oracle Solaris Studio C |
|
||||
| SPARC64 | Linux | GCC |
|
||||
| SPARC64 | FreeBSD | GCC |
|
||||
| SPARC64 | Solaris | Oracle Solaris Studio C |
|
||||
| TILE-Gx/TILEPro | Linux | GCC |
|
||||
| VAX | OpenBSD/vax | GCC |
|
||||
| X86 | FreeBSD | GCC |
|
||||
| X86 | GNU HURD | GCC |
|
||||
| X86 | Interix | GCC |
|
||||
| X86 | kFreeBSD | GCC |
|
||||
| X86 | Linux | GCC |
|
||||
| X86 | Mac OSX | GCC |
|
||||
| X86 | OpenBSD | GCC |
|
||||
| X86 | OS/2 | GCC |
|
||||
| X86 | Solaris | GCC |
|
||||
| X86 | Solaris | Oracle Solaris Studio C |
|
||||
| X86 | Windows/Cygwin | GCC |
|
||||
| X86 | Windows/MingW | GCC |
|
||||
| X86-64 | FreeBSD | GCC |
|
||||
| X86-64 | Linux | GCC |
|
||||
| X86-64 | Linux/x32 | GCC |
|
||||
| X86-64 | OpenBSD | GCC |
|
||||
| X86-64 | Solaris | Oracle Solaris Studio C |
|
||||
| X86-64 | Windows/Cygwin | GCC |
|
||||
| X86-64 | Windows/MingW | GCC |
|
||||
| X86-64 | Mac OSX | GCC |
|
||||
| Xtensa | Linux | GCC |
|
||||
|
||||
Please send additional platform test results to
|
||||
libffi-discuss@sourceware.org.
|
||||
|
||||
Installing libffi
|
||||
=================
|
||||
|
||||
First you must configure the distribution for your particular
|
||||
system. Go to the directory you wish to build libffi in and run the
|
||||
"configure" program found in the root directory of the libffi source
|
||||
distribution. Note that building libffi requires a C99 compatible
|
||||
compiler.
|
||||
|
||||
If you're building libffi directly from git hosted sources, configure
|
||||
won't exist yet; run ./autogen.sh first. This will require that you
|
||||
install autoconf, automake and libtool.
|
||||
|
||||
You may want to tell configure where to install the libffi library and
|
||||
header files. To do that, use the ``--prefix`` configure switch. Libffi
|
||||
will install under /usr/local by default.
|
||||
|
||||
If you want to enable extra run-time debugging checks use the the
|
||||
``--enable-debug`` configure switch. This is useful when your program dies
|
||||
mysteriously while using libffi.
|
||||
|
||||
Another useful configure switch is ``--enable-purify-safety``. Using this
|
||||
will add some extra code which will suppress certain warnings when you
|
||||
are using Purify with libffi. Only use this switch when using
|
||||
Purify, as it will slow down the library.
|
||||
|
||||
If you don't want to build documentation, use the ``--disable-docs``
|
||||
configure switch.
|
||||
|
||||
It's also possible to build libffi on Windows platforms with
|
||||
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
|
||||
wrapper script during configuration like so:
|
||||
|
||||
path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL"
|
||||
|
||||
For 64-bit Windows builds, use ``CC="path/to/msvcc.sh -m64"`` and
|
||||
``CXX="path/to/msvcc.sh -m64"``. You may also need to specify
|
||||
``--build`` appropriately.
|
||||
|
||||
It is also possible to build libffi on Windows platforms with the LLVM
|
||||
project's clang-cl compiler, like below:
|
||||
|
||||
path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP"
|
||||
|
||||
When building with MSVC under a MingW environment, you may need to
|
||||
remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
|
||||
command. ('cygpath' is not present in MingW, and is not required when
|
||||
using MingW-style paths.)
|
||||
|
||||
To build static library for ARM64 with MSVC using visual studio solution, msvc_build folder have
|
||||
aarch64/Ffi_staticLib.sln
|
||||
required header files in aarch64/aarch64_include/
|
||||
|
||||
|
||||
SPARC Solaris builds require the use of the GNU assembler and linker.
|
||||
Point ``AS`` and ``LD`` environment variables at those tool prior to
|
||||
configuration.
|
||||
|
||||
For iOS builds, the ``libffi.xcodeproj`` Xcode project is available.
|
||||
|
||||
Configure has many other options. Use ``configure --help`` to see them all.
|
||||
|
||||
Once configure has finished, type "make". Note that you must be using
|
||||
GNU make. You can ftp GNU make from ftp.gnu.org:/pub/gnu/make .
|
||||
|
||||
To ensure that libffi is working as advertised, type "make check".
|
||||
This will require that you have DejaGNU installed.
|
||||
|
||||
To install the library and header files, type ``make install``.
|
||||
|
||||
|
||||
History
|
||||
=======
|
||||
|
||||
See the git log for details at http://github.com/libffi/libffi.
|
||||
|
||||
3.3 Nov-23-19
|
||||
Add RISC-V support.
|
||||
New API in support of GO closures.
|
||||
Add IEEE754 binary128 long double support for 64-bit Power
|
||||
Default to Microsoft's 64 bit long double ABI with Visual C++.
|
||||
GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
|
||||
Add Windows on ARM64 (WOA) support.
|
||||
Add Windows 32-bit ARM support.
|
||||
Raw java (gcj) API deprecated.
|
||||
Add pre-built PDF documentation to source distribution.
|
||||
Many new tests cases and bug fixes.
|
||||
|
||||
3.2.1 Nov-12-14
|
||||
Build fix for non-iOS AArch64 targets.
|
||||
|
||||
3.2 Nov-11-14
|
||||
Add C99 Complex Type support (currently only supported on
|
||||
s390).
|
||||
Add support for PASCAL and REGISTER calling conventions on x86
|
||||
Windows/Linux.
|
||||
Add OpenRISC and Cygwin-64 support.
|
||||
Bug fixes.
|
||||
|
||||
3.1 May-19-14
|
||||
Add AArch64 (ARM64) iOS support.
|
||||
Add Nios II support.
|
||||
Add m88k and DEC VAX support.
|
||||
Add support for stdcall, thiscall, and fastcall on non-Windows
|
||||
32-bit x86 targets such as Linux.
|
||||
Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi
|
||||
fixes.
|
||||
Make the testsuite more robust: eliminate several spurious
|
||||
failures, and respect the $CC and $CXX environment variables.
|
||||
Archive off the manually maintained ChangeLog in favor of git
|
||||
log.
|
||||
|
||||
3.0.13 Mar-17-13
|
||||
Add Meta support.
|
||||
Add missing Moxie bits.
|
||||
Fix stack alignment bug on 32-bit x86.
|
||||
Build fix for m68000 targets.
|
||||
Build fix for soft-float Power targets.
|
||||
Fix the install dir location for some platforms when building
|
||||
with GCC (OS X, Solaris).
|
||||
Fix Cygwin regression.
|
||||
|
||||
3.0.12 Feb-11-13
|
||||
Add Moxie support.
|
||||
Add AArch64 support.
|
||||
Add Blackfin support.
|
||||
Add TILE-Gx/TILEPro support.
|
||||
Add MicroBlaze support.
|
||||
Add Xtensa support.
|
||||
Add support for PaX enabled kernels with MPROTECT.
|
||||
Add support for native vendor compilers on
|
||||
Solaris and AIX.
|
||||
Work around LLVM/GCC interoperability issue on x86_64.
|
||||
|
||||
3.0.11 Apr-11-12
|
||||
Lots of build fixes.
|
||||
Add support for variadic functions (ffi_prep_cif_var).
|
||||
Add Linux/x32 support.
|
||||
Add thiscall, fastcall and MSVC cdecl support on Windows.
|
||||
Add Amiga and newer MacOS support.
|
||||
Add m68k FreeMiNT support.
|
||||
Integration with iOS' xcode build tools.
|
||||
Fix Octeon and MC68881 support.
|
||||
Fix code pessimizations.
|
||||
|
||||
3.0.10 Aug-23-11
|
||||
Add support for Apple's iOS.
|
||||
Add support for ARM VFP ABI.
|
||||
Add RTEMS support for MIPS and M68K.
|
||||
Fix instruction cache clearing problems on
|
||||
ARM and SPARC.
|
||||
Fix the N64 build on mips-sgi-irix6.5.
|
||||
Enable builds with Microsoft's compiler.
|
||||
Enable x86 builds with Oracle's Solaris compiler.
|
||||
Fix support for calling code compiled with Oracle's Sparc
|
||||
Solaris compiler.
|
||||
Testsuite fixes for Tru64 Unix.
|
||||
Additional platform support.
|
||||
|
||||
3.0.9 Dec-31-09
|
||||
Add AVR32 and win64 ports. Add ARM softfp support.
|
||||
Many fixes for AIX, Solaris, HP-UX, *BSD.
|
||||
Several PowerPC and x86-64 bug fixes.
|
||||
Build DLL for windows.
|
||||
|
||||
3.0.8 Dec-19-08
|
||||
Add *BSD, BeOS, and PA-Linux support.
|
||||
|
||||
3.0.7 Nov-11-08
|
||||
Fix for ppc FreeBSD.
|
||||
(thanks to Andreas Tobler)
|
||||
|
||||
3.0.6 Jul-17-08
|
||||
Fix for closures on sh.
|
||||
Mark the sh/sh64 stack as non-executable.
|
||||
(both thanks to Kaz Kojima)
|
||||
|
||||
3.0.5 Apr-3-08
|
||||
Fix libffi.pc file.
|
||||
Fix #define ARM for IcedTea users.
|
||||
Fix x86 closure bug.
|
||||
|
||||
3.0.4 Feb-24-08
|
||||
Fix x86 OpenBSD configury.
|
||||
|
||||
3.0.3 Feb-22-08
|
||||
Enable x86 OpenBSD thanks to Thomas Heller, and
|
||||
x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
|
||||
Clean up test instruction in README.
|
||||
|
||||
3.0.2 Feb-21-08
|
||||
Improved x86 FreeBSD support.
|
||||
Thanks to Björn König.
|
||||
|
||||
3.0.1 Feb-15-08
|
||||
Fix instruction cache flushing bug on MIPS.
|
||||
Thanks to David Daney.
|
||||
|
||||
3.0.0 Feb-15-08
|
||||
Many changes, mostly thanks to the GCC project.
|
||||
Cygnus Solutions is now Red Hat.
|
||||
|
||||
[10 years go by...]
|
||||
|
||||
1.20 Oct-5-98
|
||||
Raffaele Sena produces ARM port.
|
||||
|
||||
1.19 Oct-5-98
|
||||
Fixed x86 long double and long long return support.
|
||||
m68k bug fixes from Andreas Schwab.
|
||||
Patch for DU assembler compatibility for the Alpha from Richard
|
||||
Henderson.
|
||||
|
||||
1.18 Apr-17-98
|
||||
Bug fixes and MIPS configuration changes.
|
||||
|
||||
1.17 Feb-24-98
|
||||
Bug fixes and m68k port from Andreas Schwab. PowerPC port from
|
||||
Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
|
||||
|
||||
1.16 Feb-11-98
|
||||
Richard Henderson produces Alpha port.
|
||||
|
||||
1.15 Dec-4-97
|
||||
Fixed an n32 ABI bug. New libtool, auto* support.
|
||||
|
||||
1.14 May-13-97
|
||||
libtool is now used to generate shared and static libraries.
|
||||
Fixed a minor portability problem reported by Russ McManus
|
||||
<mcmanr@eq.gs.com>.
|
||||
|
||||
1.13 Dec-2-96
|
||||
Added --enable-purify-safety to keep Purify from complaining
|
||||
about certain low level code.
|
||||
Sparc fix for calling functions with < 6 args.
|
||||
Linux x86 a.out fix.
|
||||
|
||||
1.12 Nov-22-96
|
||||
Added missing ffi_type_void, needed for supporting void return
|
||||
types. Fixed test case for non MIPS machines. Cygnus Support
|
||||
is now Cygnus Solutions.
|
||||
|
||||
1.11 Oct-30-96
|
||||
Added notes about GNU make.
|
||||
|
||||
1.10 Oct-29-96
|
||||
Added configuration fix for non GNU compilers.
|
||||
|
||||
1.09 Oct-29-96
|
||||
Added --enable-debug configure switch. Clean-ups based on LCLint
|
||||
feedback. ffi_mips.h is always installed. Many configuration
|
||||
fixes. Fixed ffitest.c for sparc builds.
|
||||
|
||||
1.08 Oct-15-96
|
||||
Fixed n32 problem. Many clean-ups.
|
||||
|
||||
1.07 Oct-14-96
|
||||
Gordon Irlam rewrites v8.S again. Bug fixes.
|
||||
|
||||
1.06 Oct-14-96
|
||||
Gordon Irlam improved the sparc port.
|
||||
|
||||
1.05 Oct-14-96
|
||||
Interface changes based on feedback.
|
||||
|
||||
1.04 Oct-11-96
|
||||
Sparc port complete (modulo struct passing bug).
|
||||
|
||||
1.03 Oct-10-96
|
||||
Passing struct args, and returning struct values works for
|
||||
all architectures/calling conventions. Expanded tests.
|
||||
|
||||
1.02 Oct-9-96
|
||||
Added SGI n32 support. Fixed bugs in both o32 and Linux support.
|
||||
Added "make test".
|
||||
|
||||
1.01 Oct-8-96
|
||||
Fixed float passing bug in mips version. Restructured some
|
||||
of the code. Builds cleanly with SGI tools.
|
||||
|
||||
1.00 Oct-7-96
|
||||
First release. No public announcement.
|
||||
|
||||
Authors & Credits
|
||||
=================
|
||||
|
||||
libffi was originally written by Anthony Green <green@moxielogic.com>.
|
||||
|
||||
The developers of the GNU Compiler Collection project have made
|
||||
innumerable valuable contributions. See the ChangeLog file for
|
||||
details.
|
||||
|
||||
Some of the ideas behind libffi were inspired by Gianni Mariani's free
|
||||
gencall library for Silicon Graphics machines.
|
||||
|
||||
The closure mechanism was designed and implemented by Kresten Krab
|
||||
Thorup.
|
||||
|
||||
Major processor architecture ports were contributed by the following
|
||||
developers:
|
||||
|
||||
aarch64 Marcus Shawcroft, James Greenhalgh
|
||||
alpha Richard Henderson
|
||||
arc Hackers at Synopsis
|
||||
arm Raffaele Sena
|
||||
avr32 Bradley Smith
|
||||
blackfin Alexandre Keunecke I. de Mendonca
|
||||
cris Simon Posnjak, Hans-Peter Nilsson
|
||||
frv Anthony Green
|
||||
ia64 Hans Boehm
|
||||
m32r Kazuhiro Inaoka
|
||||
m68k Andreas Schwab
|
||||
m88k Miod Vallat
|
||||
metag Hackers at Imagination Technologies
|
||||
microblaze Nathan Rossi
|
||||
mips Anthony Green, Casey Marshall
|
||||
mips64 David Daney
|
||||
moxie Anthony Green
|
||||
nios ii Sandra Loosemore
|
||||
openrisc Sebastian Macke
|
||||
pa Randolph Chung, Dave Anglin, Andreas Tobler
|
||||
powerpc Geoffrey Keating, Andreas Tobler,
|
||||
David Edelsohn, John Hornkvist
|
||||
powerpc64 Jakub Jelinek
|
||||
riscv Michael Knyszek, Andrew Waterman, Stef O'Rear
|
||||
s390 Gerhard Tonn, Ulrich Weigand
|
||||
sh Kaz Kojima
|
||||
sh64 Kaz Kojima
|
||||
sparc Anthony Green, Gordon Irlam
|
||||
tile-gx/tilepro Walter Lee
|
||||
vax Miod Vallat
|
||||
x86 Anthony Green, Jon Beniston
|
||||
x86-64 Bo Thorsen
|
||||
xtensa Chris Zankel
|
||||
|
||||
Jesper Skov and Andrew Haley both did more than their fair share of
|
||||
stepping through the code and tracking down bugs.
|
||||
|
||||
Thanks also to Tom Tromey for bug fixes, documentation and
|
||||
configuration help.
|
||||
|
||||
Thanks to Jim Blandy, who provided some useful feedback on the libffi
|
||||
interface.
|
||||
|
||||
Andreas Tobler has done a tremendous amount of work on the testsuite.
|
||||
|
||||
Alex Oliva solved the executable page problem for SElinux.
|
||||
|
||||
The list above is almost certainly incomplete and inaccurate. I'm
|
||||
happy to make corrections or additions upon request.
|
||||
|
||||
If you have a problem, or have found a bug, please send a note to the
|
||||
author at green@moxielogic.com, or the project mailing list at
|
||||
libffi-discuss@sourceware.org.
|
||||
|
479
acinclude.m4
Normal file
479
acinclude.m4
Normal file
@ -0,0 +1,479 @@
|
||||
# mmap(2) blacklisting. Some platforms provide the mmap library routine
|
||||
# but don't support all of the features we need from it.
|
||||
AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
|
||||
[
|
||||
AC_CHECK_HEADER([sys/mman.h],
|
||||
[libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
|
||||
AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
|
||||
if test "$libffi_header_sys_mman_h" != yes \
|
||||
|| test "$libffi_func_mmap" != yes; then
|
||||
ac_cv_func_mmap_file=no
|
||||
ac_cv_func_mmap_dev_zero=no
|
||||
ac_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
|
||||
ac_cv_func_mmap_file,
|
||||
[# Add a system to this blacklist if
|
||||
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
|
||||
# memory area containing the same data that you'd get if you applied
|
||||
# read() to the same fd. The only system known to have a problem here
|
||||
# is VMS, where text files have record structure.
|
||||
case "$host_os" in
|
||||
vms* | ultrix*)
|
||||
ac_cv_func_mmap_file=no ;;
|
||||
*)
|
||||
ac_cv_func_mmap_file=yes;;
|
||||
esac])
|
||||
AC_CACHE_CHECK([whether mmap from /dev/zero works],
|
||||
ac_cv_func_mmap_dev_zero,
|
||||
[# Add a system to this blacklist if it has mmap() but /dev/zero
|
||||
# does not exist, or if mmapping /dev/zero does not give anonymous
|
||||
# zeroed pages with both the following properties:
|
||||
# 1. If you map N consecutive pages in with one call, and then
|
||||
# unmap any subset of those pages, the pages that were not
|
||||
# explicitly unmapped remain accessible.
|
||||
# 2. If you map two adjacent blocks of memory and then unmap them
|
||||
# both at once, they must both go away.
|
||||
# Systems known to be in this category are Windows (all variants),
|
||||
# VMS, and Darwin.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
|
||||
ac_cv_func_mmap_dev_zero=no ;;
|
||||
*)
|
||||
ac_cv_func_mmap_dev_zero=yes;;
|
||||
esac])
|
||||
|
||||
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
|
||||
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
|
||||
[AC_TRY_COMPILE(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
],
|
||||
[int n = MAP_ANONYMOUS;],
|
||||
ac_cv_decl_map_anon=yes,
|
||||
ac_cv_decl_map_anon=no)])
|
||||
|
||||
if test $ac_cv_decl_map_anon = no; then
|
||||
ac_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
|
||||
ac_cv_func_mmap_anon,
|
||||
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
|
||||
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||
# doesn't give anonymous zeroed pages with the same properties listed
|
||||
# above for use of /dev/zero.
|
||||
# Systems known to be in this category are Windows, VMS, and SCO Unix.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | sco* | udk* )
|
||||
ac_cv_func_mmap_anon=no ;;
|
||||
*)
|
||||
ac_cv_func_mmap_anon=yes;;
|
||||
esac])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ac_cv_func_mmap_file = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_FILE, 1,
|
||||
[Define if read-only mmap of a plain file works.])
|
||||
fi
|
||||
if test $ac_cv_func_mmap_dev_zero = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
|
||||
[Define if mmap of /dev/zero works.])
|
||||
fi
|
||||
if test $ac_cv_func_mmap_anon = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_ANON, 1,
|
||||
[Define if mmap with MAP_ANON(YMOUS) works.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl ----------------------------------------------------------------------
|
||||
dnl This whole bit snagged from libstdc++-v3, via libatomic.
|
||||
|
||||
dnl
|
||||
dnl LIBFFI_ENABLE
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
|
||||
dnl
|
||||
dnl See docs/html/17_intro/configury.html#enable for documentation.
|
||||
dnl
|
||||
m4_define([LIBFFI_ENABLE],[dnl
|
||||
m4_define([_g_switch],[--enable-$1])dnl
|
||||
m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
|
||||
AC_ARG_ENABLE($1,_g_help,
|
||||
m4_bmatch([$5],
|
||||
[^permit ],
|
||||
[[
|
||||
case "$enableval" in
|
||||
m4_bpatsubst([$5],[permit ])) ;;
|
||||
*) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
|
||||
dnl Idea for future: generate a URL pointing to
|
||||
dnl "onlinedocs/configopts.html#whatever"
|
||||
esac
|
||||
]],
|
||||
[^$],
|
||||
[[
|
||||
case "$enableval" in
|
||||
yes|no) ;;
|
||||
*) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
|
||||
esac
|
||||
]],
|
||||
[[$5]]),
|
||||
[enable_]m4_bpatsubst([$1],-,_)[=][$2])
|
||||
m4_undefine([_g_switch])dnl
|
||||
m4_undefine([_g_help])dnl
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl If GNU ld is in use, check to see if tricky linker opts can be used. If
|
||||
dnl the native linker is in use, all variables will be defined to something
|
||||
dnl safe (like an empty string).
|
||||
dnl
|
||||
dnl Defines:
|
||||
dnl SECTION_LDFLAGS='-Wl,--gc-sections' if possible
|
||||
dnl OPT_LDFLAGS='-Wl,-O1' if possible
|
||||
dnl LD (as a side effect of testing)
|
||||
dnl Sets:
|
||||
dnl with_gnu_ld
|
||||
dnl libat_ld_is_gold (possibly)
|
||||
dnl libat_gnu_ld_version (possibly)
|
||||
dnl
|
||||
dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
|
||||
dnl set libat_gnu_ld_version to 12345. Zeros cause problems.
|
||||
dnl
|
||||
AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
|
||||
# If we're not using GNU ld, then there's no point in even trying these
|
||||
# tests. Check for that first. We should have already tested for gld
|
||||
# by now (in libtool), but require it now just to be safe...
|
||||
test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
|
||||
test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
|
||||
AC_REQUIRE([AC_PROG_LD])
|
||||
AC_REQUIRE([AC_PROG_AWK])
|
||||
|
||||
# The name set by libtool depends on the version of libtool. Shame on us
|
||||
# for depending on an impl detail, but c'est la vie. Older versions used
|
||||
# ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
|
||||
# top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
|
||||
# makes sense). We'll test with_gnu_ld everywhere else, so if that isn't
|
||||
# set (hence we're using an older libtool), then set it.
|
||||
if test x${with_gnu_ld+set} != xset; then
|
||||
if test x${ac_cv_prog_gnu_ld+set} != xset; then
|
||||
# We got through "ac_require(ac_prog_ld)" and still not set? Huh?
|
||||
with_gnu_ld=no
|
||||
else
|
||||
with_gnu_ld=$ac_cv_prog_gnu_ld
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start by getting the version number. I think the libtool test already
|
||||
# does some of this, but throws away the result.
|
||||
libat_ld_is_gold=no
|
||||
if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
|
||||
libat_ld_is_gold=yes
|
||||
fi
|
||||
changequote(,)
|
||||
ldver=`$LD --version 2>/dev/null |
|
||||
sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
|
||||
changequote([,])
|
||||
libat_gnu_ld_version=`echo $ldver | \
|
||||
$AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
|
||||
|
||||
# Set --gc-sections.
|
||||
if test "$with_gnu_ld" = "notbroken"; then
|
||||
# GNU ld it is! Joy and bunny rabbits!
|
||||
|
||||
# All these tests are for C++; save the language and the compiler flags.
|
||||
# Need to do this so that g++ won't try to link in libstdc++
|
||||
ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS='-x c++ -Wl,--gc-sections'
|
||||
|
||||
# Check for -Wl,--gc-sections
|
||||
# XXX This test is broken at the moment, as symbols required for linking
|
||||
# are now in libsupc++ (not built yet). In addition, this test has
|
||||
# cored on solaris in the past. In addition, --gc-sections doesn't
|
||||
# really work at the moment (keeps on discarding used sections, first
|
||||
# .eh_frame and now some of the glibc sections for iconv).
|
||||
# Bzzzzt. Thanks for playing, maybe next time.
|
||||
AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
|
||||
AC_TRY_RUN([
|
||||
int main(void)
|
||||
{
|
||||
try { throw 1; }
|
||||
catch (...) { };
|
||||
return 0;
|
||||
}
|
||||
], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
|
||||
if test "$ac_test_CFLAGS" = set; then
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
else
|
||||
# this is the suspicious part
|
||||
CFLAGS=''
|
||||
fi
|
||||
if test "$ac_sectionLDflags" = "yes"; then
|
||||
SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_sectionLDflags)
|
||||
fi
|
||||
|
||||
# Set linker optimization flags.
|
||||
if test x"$with_gnu_ld" = x"yes"; then
|
||||
OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
|
||||
fi
|
||||
|
||||
AC_SUBST(SECTION_LDFLAGS)
|
||||
AC_SUBST(OPT_LDFLAGS)
|
||||
])
|
||||
|
||||
|
||||
dnl
|
||||
dnl If GNU ld is in use, check to see if tricky linker opts can be used. If
|
||||
dnl the native linker is in use, all variables will be defined to something
|
||||
dnl safe (like an empty string).
|
||||
dnl
|
||||
dnl Defines:
|
||||
dnl SECTION_LDFLAGS='-Wl,--gc-sections' if possible
|
||||
dnl OPT_LDFLAGS='-Wl,-O1' if possible
|
||||
dnl LD (as a side effect of testing)
|
||||
dnl Sets:
|
||||
dnl with_gnu_ld
|
||||
dnl libat_ld_is_gold (possibly)
|
||||
dnl libat_gnu_ld_version (possibly)
|
||||
dnl
|
||||
dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
|
||||
dnl set libat_gnu_ld_version to 12345. Zeros cause problems.
|
||||
dnl
|
||||
AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
|
||||
# If we're not using GNU ld, then there's no point in even trying these
|
||||
# tests. Check for that first. We should have already tested for gld
|
||||
# by now (in libtool), but require it now just to be safe...
|
||||
test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
|
||||
test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
|
||||
AC_REQUIRE([AC_PROG_LD])
|
||||
AC_REQUIRE([AC_PROG_AWK])
|
||||
|
||||
# The name set by libtool depends on the version of libtool. Shame on us
|
||||
# for depending on an impl detail, but c'est la vie. Older versions used
|
||||
# ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
|
||||
# top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
|
||||
# makes sense). We'll test with_gnu_ld everywhere else, so if that isn't
|
||||
# set (hence we're using an older libtool), then set it.
|
||||
if test x${with_gnu_ld+set} != xset; then
|
||||
if test x${ac_cv_prog_gnu_ld+set} != xset; then
|
||||
# We got through "ac_require(ac_prog_ld)" and still not set? Huh?
|
||||
with_gnu_ld=no
|
||||
else
|
||||
with_gnu_ld=$ac_cv_prog_gnu_ld
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start by getting the version number. I think the libtool test already
|
||||
# does some of this, but throws away the result.
|
||||
libat_ld_is_gold=no
|
||||
if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
|
||||
libat_ld_is_gold=yes
|
||||
fi
|
||||
libat_ld_is_lld=no
|
||||
if $LD --version 2>/dev/null | grep 'LLD '> /dev/null 2>&1; then
|
||||
libat_ld_is_lld=yes
|
||||
fi
|
||||
changequote(,)
|
||||
ldver=`$LD --version 2>/dev/null |
|
||||
sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
|
||||
changequote([,])
|
||||
libat_gnu_ld_version=`echo $ldver | \
|
||||
$AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
|
||||
|
||||
# Set --gc-sections.
|
||||
if test "$with_gnu_ld" = "notbroken"; then
|
||||
# GNU ld it is! Joy and bunny rabbits!
|
||||
|
||||
# All these tests are for C++; save the language and the compiler flags.
|
||||
# Need to do this so that g++ won't try to link in libstdc++
|
||||
ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS='-x c++ -Wl,--gc-sections'
|
||||
|
||||
# Check for -Wl,--gc-sections
|
||||
# XXX This test is broken at the moment, as symbols required for linking
|
||||
# are now in libsupc++ (not built yet). In addition, this test has
|
||||
# cored on solaris in the past. In addition, --gc-sections doesn't
|
||||
# really work at the moment (keeps on discarding used sections, first
|
||||
# .eh_frame and now some of the glibc sections for iconv).
|
||||
# Bzzzzt. Thanks for playing, maybe next time.
|
||||
AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
|
||||
AC_TRY_RUN([
|
||||
int main(void)
|
||||
{
|
||||
try { throw 1; }
|
||||
catch (...) { };
|
||||
return 0;
|
||||
}
|
||||
], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
|
||||
if test "$ac_test_CFLAGS" = set; then
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
else
|
||||
# this is the suspicious part
|
||||
CFLAGS=''
|
||||
fi
|
||||
if test "$ac_sectionLDflags" = "yes"; then
|
||||
SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_sectionLDflags)
|
||||
fi
|
||||
|
||||
# Set linker optimization flags.
|
||||
if test x"$with_gnu_ld" = x"yes"; then
|
||||
OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
|
||||
fi
|
||||
|
||||
AC_SUBST(SECTION_LDFLAGS)
|
||||
AC_SUBST(OPT_LDFLAGS)
|
||||
])
|
||||
|
||||
|
||||
dnl
|
||||
dnl Add version tags to symbols in shared library (or not), additionally
|
||||
dnl marking other symbols as private/local (or not).
|
||||
dnl
|
||||
dnl --enable-symvers=style adds a version script to the linker call when
|
||||
dnl creating the shared library. The choice of version script is
|
||||
dnl controlled by 'style'.
|
||||
dnl --disable-symvers does not.
|
||||
dnl + Usage: LIBFFI_ENABLE_SYMVERS[(DEFAULT)]
|
||||
dnl Where DEFAULT is either 'yes' or 'no'. Passing `yes' tries to
|
||||
dnl choose a default style based on linker characteristics. Passing
|
||||
dnl 'no' disables versioning.
|
||||
dnl
|
||||
AC_DEFUN([LIBFFI_ENABLE_SYMVERS], [
|
||||
|
||||
LIBFFI_ENABLE(symvers,yes,[=STYLE],
|
||||
[enables symbol versioning of the shared library],
|
||||
[permit yes|no|gnu*|sun])
|
||||
|
||||
# If we never went through the LIBFFI_CHECK_LINKER_FEATURES macro, then we
|
||||
# don't know enough about $LD to do tricks...
|
||||
AC_REQUIRE([LIBFFI_CHECK_LINKER_FEATURES])
|
||||
|
||||
# Turn a 'yes' into a suitable default.
|
||||
if test x$enable_symvers = xyes ; then
|
||||
# FIXME The following test is too strict, in theory.
|
||||
if test $enable_shared = no || test "x$LD" = x; then
|
||||
enable_symvers=no
|
||||
else
|
||||
if test $with_gnu_ld = yes ; then
|
||||
enable_symvers=gnu
|
||||
else
|
||||
case ${target_os} in
|
||||
# Sun symbol versioning exists since Solaris 2.5.
|
||||
solaris2.[[5-9]]* | solaris2.1[[0-9]]*)
|
||||
enable_symvers=sun ;;
|
||||
*)
|
||||
enable_symvers=no ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if 'sun' was requested on non-Solaris 2 platforms.
|
||||
if test x$enable_symvers = xsun ; then
|
||||
case ${target_os} in
|
||||
solaris2*)
|
||||
# All fine.
|
||||
;;
|
||||
*)
|
||||
# Unlikely to work.
|
||||
AC_MSG_WARN([=== You have requested Sun symbol versioning, but])
|
||||
AC_MSG_WARN([=== you are not targetting Solaris 2.])
|
||||
AC_MSG_WARN([=== Symbol versioning will be disabled.])
|
||||
enable_symvers=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Check to see if libgcc_s exists, indicating that shared libgcc is possible.
|
||||
if test $enable_symvers != no; then
|
||||
AC_MSG_CHECKING([for shared libgcc])
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=' -lgcc_s'
|
||||
AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes, libat_shared_libgcc=no)
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
if test $libat_shared_libgcc = no; then
|
||||
cat > conftest.c <<EOF
|
||||
int main (void) { return 0; }
|
||||
EOF
|
||||
changequote(,)dnl
|
||||
libat_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
|
||||
-shared -shared-libgcc -o conftest.so \
|
||||
conftest.c -v 2>&1 >/dev/null \
|
||||
| sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
|
||||
changequote([,])dnl
|
||||
rm -f conftest.c conftest.so
|
||||
if test x${libat_libgcc_s_suffix+set} = xset; then
|
||||
CFLAGS=" -lgcc_s$libat_libgcc_s_suffix"
|
||||
AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes)
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($libat_shared_libgcc)
|
||||
fi
|
||||
|
||||
# For GNU ld, we need at least this version. The format is described in
|
||||
# LIBFFI_CHECK_LINKER_FEATURES above.
|
||||
libat_min_gnu_ld_version=21400
|
||||
# XXXXXXXXXXX libat_gnu_ld_version=21390
|
||||
|
||||
# Check to see if unspecified "yes" value can win, given results above.
|
||||
# Change "yes" into either "no" or a style name.
|
||||
if test $enable_symvers != no && test $libat_shared_libgcc = yes; then
|
||||
if test $with_gnu_ld = yes; then
|
||||
if test $libat_gnu_ld_version -ge $libat_min_gnu_ld_version ; then
|
||||
enable_symvers=gnu
|
||||
elif test $libat_ld_is_gold = yes ; then
|
||||
enable_symvers=gnu
|
||||
elif test $libat_ld_is_lld = yes ; then
|
||||
enable_symvers=gnu
|
||||
else
|
||||
# The right tools, the right setup, but too old. Fallbacks?
|
||||
AC_MSG_WARN(=== Linker version $libat_gnu_ld_version is too old for)
|
||||
AC_MSG_WARN(=== full symbol versioning support in this release of GCC.)
|
||||
AC_MSG_WARN(=== You would need to upgrade your binutils to version)
|
||||
AC_MSG_WARN(=== $libat_min_gnu_ld_version or later and rebuild GCC.)
|
||||
if test $libat_gnu_ld_version -ge 21200 ; then
|
||||
# Globbing fix is present, proper block support is not.
|
||||
dnl AC_MSG_WARN([=== Dude, you are soooo close. Maybe we can fake it.])
|
||||
dnl enable_symvers=???
|
||||
AC_MSG_WARN([=== Symbol versioning will be disabled.])
|
||||
enable_symvers=no
|
||||
else
|
||||
# 2.11 or older.
|
||||
AC_MSG_WARN([=== Symbol versioning will be disabled.])
|
||||
enable_symvers=no
|
||||
fi
|
||||
fi
|
||||
elif test $enable_symvers = sun; then
|
||||
: All interesting versions of Sun ld support sun style symbol versioning.
|
||||
else
|
||||
# just fail for now
|
||||
AC_MSG_WARN([=== You have requested some kind of symbol versioning, but])
|
||||
AC_MSG_WARN([=== either you are not using a supported linker, or you are])
|
||||
AC_MSG_WARN([=== not building a shared libgcc_s (which is required).])
|
||||
AC_MSG_WARN([=== Symbol versioning will be disabled.])
|
||||
enable_symvers=no
|
||||
fi
|
||||
fi
|
||||
if test $enable_symvers = gnu; then
|
||||
AC_DEFINE(LIBFFI_GNU_SYMBOL_VERSIONING, 1,
|
||||
[Define to 1 if GNU symbol versioning is used for libatomic.])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB, test $enable_symvers != no)
|
||||
AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_GNU, test $enable_symvers = gnu)
|
||||
AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_SUN, test $enable_symvers = sun)
|
||||
AC_MSG_NOTICE(versioning on shared library symbols is $enable_symvers)
|
||||
])
|
2118
aclocal.m4
vendored
Normal file
2118
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
348
compile
Executable file
348
compile
Executable file
@ -0,0 +1,348 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
||||
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1466
config.guess
vendored
Normal file
1466
config.guess
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1836
config.sub
vendored
Normal file
1836
config.sub
vendored
Normal file
File diff suppressed because it is too large
Load Diff
394
configure.ac
Normal file
394
configure.ac
Normal file
@ -0,0 +1,394 @@
|
||||
dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.68)
|
||||
|
||||
AC_INIT([libffi], [3.3], [http://github.com/libffi/libffi/issues])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
case "${host}" in
|
||||
frv*-elf)
|
||||
LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/
|
||||
;;
|
||||
esac
|
||||
|
||||
AX_ENABLE_BUILDDIR
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
|
||||
# We must force CC to /not/ be precious variables; otherwise
|
||||
# the wrong, non-multilib-adjusted value will be used in multilibs.
|
||||
# As a side effect, we have to subst CFLAGS ourselves.
|
||||
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
|
||||
# defaults of its own if none are provided.
|
||||
|
||||
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
|
||||
m4_define([_AC_ARG_VAR_PRECIOUS],[])
|
||||
save_CFLAGS=$CFLAGS
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
CFLAGS=$save_CFLAGS
|
||||
m4_undefine([_AC_ARG_VAR_PRECIOUS])
|
||||
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Test for 64-bit build.
|
||||
AC_CHECK_SIZEOF([size_t])
|
||||
|
||||
AX_COMPILER_VENDOR
|
||||
AX_CC_MAXOPT
|
||||
# The AX_CFLAGS_WARN_ALL macro doesn't currently work for sunpro
|
||||
# compiler.
|
||||
if test "$ax_cv_c_compiler_vendor" != "sun"; then
|
||||
AX_CFLAGS_WARN_ALL
|
||||
fi
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -fexceptions"
|
||||
fi
|
||||
|
||||
cat > local.exp <<EOF
|
||||
set CC_FOR_TARGET "$CC"
|
||||
set CXX_FOR_TARGET "$CXX"
|
||||
EOF
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
AC_CHECK_FUNCS([mmap mkostemp])
|
||||
AC_FUNC_MMAP_BLACKLIST
|
||||
|
||||
dnl The -no-testsuite modules omit the test subdir.
|
||||
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
|
||||
|
||||
TARGETDIR="unknown"
|
||||
HAVE_LONG_DOUBLE_VARIANT=0
|
||||
|
||||
. ${srcdir}/configure.host
|
||||
|
||||
if test -n "${UNSUPPORTED}"; then
|
||||
AC_MSG_ERROR(["libffi has not been ported to $host."])
|
||||
fi
|
||||
|
||||
AC_SUBST(AM_RUNTESTFLAGS)
|
||||
AC_SUBST(AM_LTLDFLAGS)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
AC_CHECK_SIZEOF(double)
|
||||
AC_CHECK_SIZEOF(long double)
|
||||
|
||||
# Also AC_SUBST this variable for ffi.h.
|
||||
if test -z "$HAVE_LONG_DOUBLE"; then
|
||||
HAVE_LONG_DOUBLE=0
|
||||
if test $ac_cv_sizeof_long_double != 0; then
|
||||
if test $HAVE_LONG_DOUBLE_VARIANT != 0; then
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE_VARIANT, 1, [Define if you support more than one size of the long double type])
|
||||
HAVE_LONG_DOUBLE=1
|
||||
else
|
||||
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
|
||||
HAVE_LONG_DOUBLE=1
|
||||
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_LONG_DOUBLE)
|
||||
AC_SUBST(HAVE_LONG_DOUBLE_VARIANT)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
GCC_AS_CFI_PSEUDO_OP
|
||||
|
||||
case "$TARGET" in
|
||||
SPARC)
|
||||
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
|
||||
libffi_cv_as_sparc_ua_pcrel, [
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
|
||||
[libffi_cv_as_sparc_ua_pcrel=yes],
|
||||
[libffi_cv_as_sparc_ua_pcrel=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"])
|
||||
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
|
||||
[Define if your assembler and linker support unaligned PC relative relocs.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
libffi_cv_as_register_pseudo_op, [
|
||||
libffi_cv_as_register_pseudo_op=unknown
|
||||
# Check if we have .register
|
||||
AC_TRY_COMPILE(,[asm (".register %g2, #scratch");],
|
||||
[libffi_cv_as_register_pseudo_op=yes],
|
||||
[libffi_cv_as_register_pseudo_op=no])
|
||||
])
|
||||
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .register.])
|
||||
fi
|
||||
;;
|
||||
|
||||
X86*)
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
;;
|
||||
|
||||
S390)
|
||||
AC_CACHE_CHECK([compiler uses zarch features],
|
||||
libffi_cv_as_s390_zarch, [
|
||||
libffi_cv_as_s390_zarch=no
|
||||
echo 'void foo(void) { bar(); bar(); }' > conftest.c
|
||||
if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then
|
||||
if grep -q brasl conftest.s; then
|
||||
libffi_cv_as_s390_zarch=yes
|
||||
fi
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_s390_zarch" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_S390_ZARCH, 1,
|
||||
[Define if the compiler uses zarch features.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
|
||||
AC_ARG_ENABLE(pax_emutramp,
|
||||
[ --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC],
|
||||
if test "$enable_pax_emutramp" = "yes"; then
|
||||
AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1,
|
||||
[Define this if you want to enable pax emulated trampolines])
|
||||
fi)
|
||||
|
||||
LT_SYS_SYMBOL_USCORE
|
||||
if test "x$sys_symbol_underscore" = xyes; then
|
||||
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
|
||||
fi
|
||||
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=0
|
||||
case "$target" in
|
||||
*arm*-apple-* | aarch64-apple-*)
|
||||
FFI_EXEC_TRAMPOLINE_TABLE=1
|
||||
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
|
||||
[Cannot use PROT_EXEC on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
*-apple-* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)
|
||||
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
|
||||
[Cannot use malloc on this target, so, we revert to
|
||||
alternative means])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
|
||||
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
|
||||
|
||||
if test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([toolchain supports unwind section type],
|
||||
libffi_cv_as_x86_64_unwind_section_type, [
|
||||
cat > conftest1.s << EOF
|
||||
.text
|
||||
.globl foo
|
||||
foo:
|
||||
jmp bar
|
||||
.section .eh_frame,"a",@unwind
|
||||
bar:
|
||||
EOF
|
||||
|
||||
cat > conftest2.c << EOF
|
||||
extern void foo();
|
||||
int main(){foo();}
|
||||
EOF
|
||||
|
||||
libffi_cv_as_x86_64_unwind_section_type=no
|
||||
# we ensure that we can compile _and_ link an assembly file containing an @unwind section
|
||||
# since the compiler can support it and not the linker (ie old binutils)
|
||||
if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \
|
||||
$CC conftest2.c conftest1.o > /dev/null 2>&1 ; then
|
||||
libffi_cv_as_x86_64_unwind_section_type=yes
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
|
||||
[Define if your assembler supports unwind section type.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
|
||||
if $CC $CFLAGS -c -fpic -fexceptions -o conftest.o conftest.c > /dev/null 2>&1; then
|
||||
objdump -h conftest.o > conftest.dump 2>&1
|
||||
libffi_eh_frame_line=`grep -n eh_frame conftest.dump | cut -d: -f 1`
|
||||
if test "x$libffi_eh_frame_line" != "x"; then
|
||||
libffi_test_line=`expr $libffi_eh_frame_line + 1`p
|
||||
sed -n $libffi_test_line conftest.dump > conftest.line
|
||||
if grep READONLY conftest.line > /dev/null; then
|
||||
libffi_cv_ro_eh_frame=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test "x$libffi_cv_ro_eh_frame" = xyes; then
|
||||
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
|
||||
[Define if .eh_frame sections should be read-only.])
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "a",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
else
|
||||
AC_DEFINE(EH_FRAME_FLAGS, "aw",
|
||||
[Define to the flags needed for the .section .eh_frame directive. ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
||||
libffi_cv_hidden_visibility_attribute, [
|
||||
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c
|
||||
libffi_cv_hidden_visibility_attribute=no
|
||||
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
|
||||
if egrep '(\.hidden|\.private_extern).*foo' conftest.s >/dev/null; then
|
||||
libffi_cv_hidden_visibility_attribute=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.*
|
||||
])
|
||||
if test $libffi_cv_hidden_visibility_attribute = yes; then
|
||||
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
|
||||
[Define if __attribute__((visibility("hidden"))) is supported.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(docs,
|
||||
AC_HELP_STRING([--disable-docs],
|
||||
[Disable building of docs (default: no)]),
|
||||
[enable_docs=no],
|
||||
[enable_docs=yes])
|
||||
AM_CONDITIONAL(BUILD_DOCS, [test x$enable_docs = xyes])
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#ifdef __APPLE__
|
||||
#define FFI_HIDDEN(name) .private_extern name
|
||||
#else
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#endif
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_SUBST(TARGET)
|
||||
AC_SUBST(TARGETDIR)
|
||||
|
||||
changequote(<,>)
|
||||
TARGET_OBJ=
|
||||
for i in $SOURCES; do
|
||||
TARGET_OBJ="${TARGET_OBJ} src/${TARGETDIR}/"`echo $i | sed 's/[cS]$/lo/'`
|
||||
done
|
||||
changequote([,])
|
||||
AC_SUBST(TARGET_OBJ)
|
||||
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug debugging mode],
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(structs,
|
||||
[ --disable-structs omit code for struct support],
|
||||
if test "$enable_structs" = "no"; then
|
||||
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this if you do not want support for aggregate types.])
|
||||
fi)
|
||||
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
|
||||
|
||||
AC_ARG_ENABLE(raw-api,
|
||||
[ --disable-raw-api make the raw api unavailable],
|
||||
if test "$enable_raw_api" = "no"; then
|
||||
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this if you do not want support for the raw API.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(purify-safety,
|
||||
[ --enable-purify-safety purify-safe mode],
|
||||
if test "$enable_purify_safety" = "yes"; then
|
||||
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
|
||||
fi)
|
||||
|
||||
AC_ARG_ENABLE(multi-os-directory,
|
||||
[ --disable-multi-os-directory
|
||||
disable use of gcc --print-multi-os-directory to change the library installation directory])
|
||||
|
||||
# These variables are only ever used when we cross-build to X86_WIN32.
|
||||
# And we only support this with GCC, so...
|
||||
if test "x$GCC" = "xyes"; then
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
toolexecdir='${exec_prefix}'/'$(target_alias)'
|
||||
toolexeclibdir='${toolexecdir}'/lib
|
||||
else
|
||||
toolexecdir='${libdir}'/gcc-lib/'$(target_alias)'
|
||||
toolexeclibdir='${libdir}'
|
||||
fi
|
||||
if test x"$enable_multi_os_directory" != x"no"; then
|
||||
multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(toolexecdir)
|
||||
else
|
||||
toolexeclibdir='${libdir}'
|
||||
fi
|
||||
AC_SUBST(toolexeclibdir)
|
||||
|
||||
# Check linker support.
|
||||
LIBFFI_ENABLE_SYMVERS
|
||||
|
||||
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
|
||||
AC_CONFIG_COMMANDS(src, [
|
||||
test -d src || mkdir src
|
||||
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
], [TARGETDIR="$TARGETDIR"])
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile doc/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
# Copy this file instead of using AC_CONFIG_LINK in order to support
|
||||
# compiling with MSVC, which won't understand cygwin style symlinks.
|
||||
cp ${srcdir}/src/$TARGETDIR/ffitarget.h include/ffitarget.h
|
303
configure.host
Normal file
303
configure.host
Normal file
@ -0,0 +1,303 @@
|
||||
# configure.host
|
||||
#
|
||||
# This shell script handles all host based configuration for libffi.
|
||||
#
|
||||
|
||||
# THIS TABLE IS SORTED. KEEP IT THAT WAY.
|
||||
# Most of the time we can define all the variables all at once...
|
||||
case "${host}" in
|
||||
aarch64*-*-cygwin* | aarch64*-*-mingw* | aarch64*-*-win* )
|
||||
TARGET=ARM_WIN64; TARGETDIR=aarch64
|
||||
MSVC=1
|
||||
;;
|
||||
|
||||
aarch64*-*-*)
|
||||
TARGET=AARCH64; TARGETDIR=aarch64
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
alpha*-*-*)
|
||||
TARGET=ALPHA; TARGETDIR=alpha;
|
||||
# Support 128-bit long double, changeable via command-line switch.
|
||||
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
|
||||
SOURCES="ffi.c osf.S"
|
||||
;;
|
||||
|
||||
arc*-*-*)
|
||||
TARGET=ARC; TARGETDIR=arc
|
||||
SOURCES="ffi.c arcompact.S"
|
||||
;;
|
||||
|
||||
arm*-*-cygwin* | arm*-*-mingw* | arm*-*-win* )
|
||||
TARGET=ARM_WIN32; TARGETDIR=arm
|
||||
MSVC=1
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
bfin*)
|
||||
TARGET=BFIN; TARGETDIR=bfin
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
frv-*-*)
|
||||
TARGET=FRV; TARGETDIR=frv
|
||||
SOURCES="ffi.c eabi.S"
|
||||
;;
|
||||
|
||||
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
|
||||
TARGET=PA_LINUX; TARGETDIR=pa
|
||||
SOURCES="ffi.c linux.S"
|
||||
;;
|
||||
hppa*64-*-hpux*)
|
||||
TARGET=PA64_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
hppa*-*-hpux*)
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
SOURCES="ffi.c hpux32.S"
|
||||
;;
|
||||
|
||||
i?86-*-freebsd* | i?86-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
i?86-*-cygwin* | i?86-*-mingw* | i?86-*-win* | i?86-*-os2* | i?86-*-interix* \
|
||||
| x86_64-*-cygwin* | x86_64-*-mingw* | x86_64-*-win* )
|
||||
TARGETDIR=x86
|
||||
if test $ac_cv_sizeof_size_t = 4; then
|
||||
TARGET=X86_WIN32
|
||||
else
|
||||
TARGET=X86_WIN64
|
||||
fi
|
||||
if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then
|
||||
MSVC=1
|
||||
fi
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
# or cross-build and select where to install dlls appropriately.
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
|
||||
else
|
||||
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
|
||||
fi
|
||||
;;
|
||||
|
||||
i?86-*-darwin* | x86_64-*-darwin* | i?86-*-ios | x86_64-*-ios)
|
||||
TARGETDIR=x86
|
||||
if test $ac_cv_sizeof_size_t = 4; then
|
||||
TARGET=X86_DARWIN
|
||||
else
|
||||
TARGET=X86_64
|
||||
fi
|
||||
;;
|
||||
|
||||
i?86-*-* | x86_64-*-* | amd64-*)
|
||||
TARGETDIR=x86
|
||||
if test $ac_cv_sizeof_size_t = 4; then
|
||||
case "$host" in
|
||||
x86_64-*x32|x86_64-x32-*)
|
||||
TARGET_X32=yes
|
||||
TARGET=X86_64
|
||||
;;
|
||||
*)
|
||||
echo 'int foo (void) { return __x86_64__; }' > conftest.c
|
||||
if $CC $CFLAGS -Werror -S conftest.c -o conftest.s > /dev/null 2>&1; then
|
||||
TARGET_X32=yes
|
||||
TARGET=X86_64
|
||||
else
|
||||
TARGET=X86;
|
||||
fi
|
||||
rm -f conftest.*
|
||||
;;
|
||||
esac
|
||||
else
|
||||
TARGET=X86_64;
|
||||
fi
|
||||
;;
|
||||
|
||||
ia64*-*-*)
|
||||
TARGET=IA64; TARGETDIR=ia64
|
||||
SOURCES="ffi.c unix.S"
|
||||
;;
|
||||
|
||||
m32r*-*-*)
|
||||
TARGET=M32R; TARGETDIR=m32r
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
m68k-*-*)
|
||||
TARGET=M68K; TARGETDIR=m68k
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
m88k-*-*)
|
||||
TARGET=M88K; TARGETDIR=m88k
|
||||
SOURCES="ffi.c obsd.S"
|
||||
;;
|
||||
|
||||
microblaze*-*-*)
|
||||
TARGET=MICROBLAZE; TARGETDIR=microblaze
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
moxie-*-*)
|
||||
TARGET=MOXIE; TARGETDIR=moxie
|
||||
SOURCES="ffi.c eabi.S"
|
||||
;;
|
||||
|
||||
metag-*-*)
|
||||
TARGET=METAG; TARGETDIR=metag
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
mips*-*linux* | mips*-*-openbsd*)
|
||||
# Support 128-bit long double for NewABI.
|
||||
HAVE_LONG_DOUBLE='defined(__mips64)'
|
||||
TARGET=MIPS; TARGETDIR=mips
|
||||
;;
|
||||
|
||||
nios2*-linux*)
|
||||
TARGET=NIOS2; TARGETDIR=nios2
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
or1k*-*-*)
|
||||
TARGET=OR1K; TARGETDIR=or1k
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
powerpc*-*-linux* | powerpc-*-sysv*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
HAVE_LONG_DOUBLE_VARIANT=1
|
||||
;;
|
||||
powerpc-*-amigaos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-darwin* | powerpc64-*-darwin*)
|
||||
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-aix* | rs6000-*-aix*)
|
||||
TARGET=POWERPC_AIX; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*)
|
||||
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
|
||||
HAVE_LONG_DOUBLE_VARIANT=1
|
||||
;;
|
||||
powerpc64-*-freebsd*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
powerpc*-*-rtems*)
|
||||
TARGET=POWERPC; TARGETDIR=powerpc
|
||||
;;
|
||||
|
||||
riscv*-*)
|
||||
TARGET=RISCV; TARGETDIR=riscv
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
s390-*-* | s390x-*-*)
|
||||
TARGET=S390; TARGETDIR=s390
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
sh-*-* | sh[34]*-*-*)
|
||||
TARGET=SH; TARGETDIR=sh
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
sh64-*-* | sh5*-*-*)
|
||||
TARGET=SH64; TARGETDIR=sh64
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
|
||||
sparc*-*-*)
|
||||
TARGET=SPARC; TARGETDIR=sparc
|
||||
SOURCES="ffi.c ffi64.c v8.S v9.S"
|
||||
;;
|
||||
|
||||
tile*-*)
|
||||
TARGET=TILE; TARGETDIR=tile
|
||||
SOURCES="ffi.c tile.S"
|
||||
;;
|
||||
|
||||
vax-*-*)
|
||||
TARGET=VAX; TARGETDIR=vax
|
||||
SOURCES="ffi.c elfbsd.S"
|
||||
;;
|
||||
|
||||
xtensa*-*)
|
||||
TARGET=XTENSA; TARGETDIR=xtensa
|
||||
SOURCES="ffi.c sysv.S"
|
||||
;;
|
||||
esac
|
||||
|
||||
# ... but some of the cases above share configury.
|
||||
case "${TARGET}" in
|
||||
ARM_WIN32)
|
||||
SOURCES="ffi.c sysv_msvc_arm32.S"
|
||||
;;
|
||||
ARM_WIN64)
|
||||
SOURCES="ffi.c win64_armasm.S"
|
||||
;;
|
||||
MIPS)
|
||||
SOURCES="ffi.c o32.S n32.S"
|
||||
;;
|
||||
POWERPC)
|
||||
SOURCES="ffi.c ffi_sysv.c ffi_linux64.c sysv.S ppc_closure.S"
|
||||
SOURCES="${SOURCES} linux64.S linux64_closure.S"
|
||||
;;
|
||||
POWERPC_AIX)
|
||||
SOURCES="ffi_darwin.c aix.S aix_closure.S"
|
||||
;;
|
||||
POWERPC_DARWIN)
|
||||
SOURCES="ffi_darwin.c darwin.S darwin_closure.S"
|
||||
;;
|
||||
POWERPC_FREEBSD)
|
||||
SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S"
|
||||
;;
|
||||
X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)
|
||||
if test "$MSVC" = 1; then
|
||||
SOURCES="ffi.c sysv_intel.S"
|
||||
else
|
||||
SOURCES="ffi.c sysv.S"
|
||||
fi
|
||||
;;
|
||||
X86_64)
|
||||
if test x"$TARGET_X32" = xyes; then
|
||||
SOURCES="ffi64.c unix64.S"
|
||||
else
|
||||
SOURCES="ffi64.c unix64.S ffiw64.c win64.S"
|
||||
fi
|
||||
;;
|
||||
X86_WIN64)
|
||||
if test "$MSVC" = 1; then
|
||||
SOURCES="ffiw64.c win64_intel.S"
|
||||
else
|
||||
SOURCES="ffiw64.c win64.S"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If we failed to configure SOURCES, we can't do anything.
|
||||
if test -z "${SOURCES}"; then
|
||||
UNSUPPORTED=1
|
||||
fi
|
791
depcomp
Executable file
791
depcomp
Executable file
@ -0,0 +1,791 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The second -e expression handles DOS-style file names with drive
|
||||
# letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E \
|
||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
3
doc/Makefile.am
Normal file
3
doc/Makefile.am
Normal file
@ -0,0 +1,3 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
info_TEXINFOS = libffi.texi
|
814
doc/Makefile.in
Normal file
814
doc/Makefile.in
Normal file
@ -0,0 +1,814 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = doc
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
|
||||
$(top_srcdir)/m4/ax_append_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
|
||||
$(top_srcdir)/m4/ax_configure_args.m4 \
|
||||
$(top_srcdir)/m4/ax_enable_builddir.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
|
||||
$(top_srcdir)/m4/ax_require_defined.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/version.texi \
|
||||
$(srcdir)/stamp-vti $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/fficonfig.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
|
||||
am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
|
||||
am__v_DVIPS_0 = @echo " DVIPS " $@;
|
||||
am__v_DVIPS_1 =
|
||||
AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
|
||||
am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
|
||||
am__v_MAKEINFO_0 = @echo " MAKEINFO" $@;
|
||||
am__v_MAKEINFO_1 =
|
||||
AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
|
||||
am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
|
||||
am__v_INFOHTML_0 = @echo " INFOHTML" $@;
|
||||
am__v_INFOHTML_1 =
|
||||
AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
|
||||
am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
|
||||
am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@;
|
||||
am__v_TEXI2DVI_1 =
|
||||
AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
|
||||
am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
|
||||
am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@;
|
||||
am__v_TEXI2PDF_1 =
|
||||
AM_V_texinfo = $(am__v_texinfo_@AM_V@)
|
||||
am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
|
||||
am__v_texinfo_0 = -q
|
||||
am__v_texinfo_1 =
|
||||
AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
|
||||
am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
|
||||
am__v_texidevnull_0 = > /dev/null
|
||||
am__v_texidevnull_1 =
|
||||
INFO_DEPS = $(srcdir)/libffi.info
|
||||
am__TEXINFO_TEX_DIR = $(srcdir)
|
||||
DVIS = libffi.dvi
|
||||
PDFS = libffi.pdf
|
||||
PSS = libffi.ps
|
||||
HTMLS = libffi.html
|
||||
TEXINFOS = libffi.texi
|
||||
TEXI2DVI = texi2dvi
|
||||
TEXI2PDF = $(TEXI2DVI) --pdf --batch
|
||||
MAKEINFOHTML = $(MAKEINFO) --html
|
||||
AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
|
||||
DVIPS = dvips
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__installdirs = "$(DESTDIR)$(infodir)"
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in mdate-sh texinfo.tex
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_LTLDFLAGS = @AM_LTLDFLAGS@
|
||||
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASDEPMODE = @CCASDEPMODE@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
|
||||
HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OPT_LDFLAGS = @OPT_LDFLAGS@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PRTDIAG = @PRTDIAG@
|
||||
RANLIB = @RANLIB@
|
||||
SECTION_LDFLAGS = @SECTION_LDFLAGS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
TARGET = @TARGET@
|
||||
TARGETDIR = @TARGETDIR@
|
||||
TARGET_OBJ = @TARGET_OBJ@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
ax_enable_builddir_sed = @ax_enable_builddir_sed@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sys_symbol_underscore = @sys_symbol_underscore@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
toolexecdir = @toolexecdir@
|
||||
toolexeclibdir = @toolexeclibdir@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
info_TEXINFOS = libffi.texi
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .dvi .html .info .pdf .ps .texi
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu doc/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
.texi.info:
|
||||
$(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
|
||||
am__cwd=`pwd` && $(am__cd) $(srcdir) && \
|
||||
rm -rf $$backupdir && mkdir $$backupdir && \
|
||||
if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
|
||||
for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
|
||||
if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
|
||||
done; \
|
||||
else :; fi && \
|
||||
cd "$$am__cwd"; \
|
||||
if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $@ $<; \
|
||||
then \
|
||||
rc=0; \
|
||||
$(am__cd) $(srcdir); \
|
||||
else \
|
||||
rc=$$?; \
|
||||
$(am__cd) $(srcdir) && \
|
||||
$$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
|
||||
fi; \
|
||||
rm -rf $$backupdir; exit $$rc
|
||||
|
||||
.texi.dvi:
|
||||
$(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
|
||||
$(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
|
||||
$<
|
||||
|
||||
.texi.pdf:
|
||||
$(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
|
||||
$(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
|
||||
$<
|
||||
|
||||
.texi.html:
|
||||
$(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
|
||||
$(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $(@:.html=.htp) $<; \
|
||||
then \
|
||||
rm -rf $@ && mv $(@:.html=.htp) $@; \
|
||||
else \
|
||||
rm -rf $(@:.html=.htp); exit 1; \
|
||||
fi
|
||||
$(srcdir)/libffi.info: libffi.texi $(srcdir)/version.texi
|
||||
libffi.dvi: libffi.texi $(srcdir)/version.texi
|
||||
libffi.pdf: libffi.texi $(srcdir)/version.texi
|
||||
libffi.html: libffi.texi $(srcdir)/version.texi
|
||||
$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
|
||||
$(srcdir)/stamp-vti: libffi.texi $(top_srcdir)/configure
|
||||
@(dir=.; test -f ./libffi.texi || dir=$(srcdir); \
|
||||
set `$(SHELL) $(srcdir)/mdate-sh $$dir/libffi.texi`; \
|
||||
echo "@set UPDATED $$1 $$2 $$3"; \
|
||||
echo "@set UPDATED-MONTH $$2 $$3"; \
|
||||
echo "@set EDITION $(VERSION)"; \
|
||||
echo "@set VERSION $(VERSION)") > vti.tmp$$$$ && \
|
||||
(cmp -s vti.tmp$$$$ $(srcdir)/version.texi \
|
||||
|| (echo "Updating $(srcdir)/version.texi" && \
|
||||
cp vti.tmp$$$$ $(srcdir)/version.texi.tmp$$$$ && \
|
||||
mv $(srcdir)/version.texi.tmp$$$$ $(srcdir)/version.texi)) && \
|
||||
rm -f vti.tmp$$$$ $(srcdir)/version.texi.$$$$
|
||||
@cp $(srcdir)/version.texi $@
|
||||
|
||||
mostlyclean-vti:
|
||||
-rm -f vti.tmp* $(srcdir)/version.texi.tmp*
|
||||
|
||||
maintainer-clean-vti:
|
||||
@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
|
||||
.dvi.ps:
|
||||
$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
|
||||
$(DVIPS) $(AM_V_texinfo) -o $@ $<
|
||||
|
||||
uninstall-dvi-am:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(DVIS)'; test -n "$(dvidir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(dvidir)/$$f"; \
|
||||
done
|
||||
|
||||
uninstall-html-am:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
|
||||
done
|
||||
|
||||
uninstall-info-am:
|
||||
@$(PRE_UNINSTALL)
|
||||
@if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
|
||||
if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
|
||||
then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
|
||||
done; \
|
||||
else :; fi
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
(if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
|
||||
echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
|
||||
rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
|
||||
else :; fi); \
|
||||
done
|
||||
|
||||
uninstall-pdf-am:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
|
||||
done
|
||||
|
||||
uninstall-ps-am:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(PSS)'; test -n "$(psdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(psdir)/$$f"; \
|
||||
done
|
||||
|
||||
dist-info: $(INFO_DEPS)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for base in $$list; do \
|
||||
case $$base in \
|
||||
$(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
esac; \
|
||||
if test -f $$base; then d=.; else d=$(srcdir); fi; \
|
||||
base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
|
||||
if test -f $$file; then \
|
||||
relfile=`expr "$$file" : "$$d/\(.*\)"`; \
|
||||
test -f "$(distdir)/$$relfile" || \
|
||||
cp -p $$file "$(distdir)/$$relfile"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
done
|
||||
|
||||
mostlyclean-aminfo:
|
||||
-rm -rf libffi.t2d libffi.t2p
|
||||
|
||||
clean-aminfo:
|
||||
-test -z "libffi.dvi libffi.pdf libffi.ps libffi.html" \
|
||||
|| rm -rf libffi.dvi libffi.pdf libffi.ps libffi.html
|
||||
|
||||
maintainer-clean-aminfo:
|
||||
@list='$(INFO_DEPS)'; for i in $$list; do \
|
||||
i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
|
||||
rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
|
||||
done
|
||||
tags TAGS:
|
||||
|
||||
ctags CTAGS:
|
||||
|
||||
cscope cscopelist:
|
||||
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-info
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(INFO_DEPS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(infodir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am: $(DVIS)
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am: $(HTMLS)
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am: $(INFO_DEPS)
|
||||
|
||||
install-data-am: install-info-am
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am: $(DVIS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(DVIS)'; test -n "$(dvidir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
|
||||
done
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am: $(HTMLS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
$(am__strip_dir) \
|
||||
d2=$$d$$p; \
|
||||
if test -d "$$d2"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
|
||||
echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
$(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
|
||||
else \
|
||||
list2="$$list2 $$d2"; \
|
||||
fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
|
||||
done; }
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am: $(INFO_DEPS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
|
||||
fi; \
|
||||
for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
esac; \
|
||||
if test -f $$file; then d=.; else d=$(srcdir); fi; \
|
||||
file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
|
||||
for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
|
||||
$$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
|
||||
if test -f $$ifile; then \
|
||||
echo "$$ifile"; \
|
||||
else : ; fi; \
|
||||
done; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
|
||||
@$(POST_INSTALL)
|
||||
@if $(am__can_run_installinfo); then \
|
||||
list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
|
||||
for file in $$list; do \
|
||||
relfile=`echo "$$file" | sed 's|^.*/||'`; \
|
||||
echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
|
||||
install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
|
||||
done; \
|
||||
else : ; fi
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am: $(PDFS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am: $(PSS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(PSS)'; test -n "$(psdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
|
||||
maintainer-clean-generic maintainer-clean-vti
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
|
||||
mostlyclean-libtool mostlyclean-vti
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am: $(PDFS)
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am: $(PSS)
|
||||
|
||||
uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
|
||||
uninstall-pdf-am uninstall-ps-am
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
|
||||
clean-libtool cscopelist-am ctags-am dist-info distclean \
|
||||
distclean-generic distclean-libtool distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-aminfo maintainer-clean-generic \
|
||||
maintainer-clean-vti mostlyclean mostlyclean-aminfo \
|
||||
mostlyclean-generic mostlyclean-libtool mostlyclean-vti pdf \
|
||||
pdf-am ps ps-am tags-am uninstall uninstall-am \
|
||||
uninstall-dvi-am uninstall-html-am uninstall-info-am \
|
||||
uninstall-pdf-am uninstall-ps-am
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
1016
doc/libffi.info
Normal file
1016
doc/libffi.info
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/libffi.pdf
Normal file
BIN
doc/libffi.pdf
Normal file
Binary file not shown.
997
doc/libffi.texi
Normal file
997
doc/libffi.texi
Normal file
@ -0,0 +1,997 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename libffi.info
|
||||
@include version.texi
|
||||
@settitle libffi: the portable foreign function interface library
|
||||
@setchapternewpage off
|
||||
@c %**end of header
|
||||
|
||||
@c Merge the standard indexes into a single one.
|
||||
@syncodeindex fn cp
|
||||
@syncodeindex vr cp
|
||||
@syncodeindex ky cp
|
||||
@syncodeindex pg cp
|
||||
@syncodeindex tp cp
|
||||
|
||||
@copying
|
||||
|
||||
This manual is for libffi, a portable foreign function interface
|
||||
library.
|
||||
|
||||
Copyright @copyright{} 2008--2019 Anthony Green and Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@end copying
|
||||
|
||||
@dircategory Development
|
||||
@direntry
|
||||
* libffi: (libffi). Portable foreign function interface library.
|
||||
@end direntry
|
||||
|
||||
@titlepage
|
||||
@title libffi: a foreign function interface library
|
||||
@subtitle For Version @value{VERSION} of libffi
|
||||
@author Anthony Green
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
@end titlepage
|
||||
|
||||
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top libffi
|
||||
|
||||
@insertcopying
|
||||
|
||||
@menu
|
||||
* Introduction:: What is libffi?
|
||||
* Using libffi:: How to use libffi.
|
||||
* Missing Features:: Things libffi can't do.
|
||||
* Index:: Index.
|
||||
@end menu
|
||||
|
||||
@end ifnottex
|
||||
|
||||
|
||||
@node Introduction
|
||||
@chapter What is libffi?
|
||||
|
||||
Compilers for high level languages generate code that follow certain
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the @dfn{calling
|
||||
convention}. The calling convention is a set of assumptions made by
|
||||
the compiler about where function arguments will be found on entry to
|
||||
a function. A calling convention also specifies where the return
|
||||
value for a function is found. The calling convention is also
|
||||
sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}.
|
||||
@cindex calling convention
|
||||
@cindex ABI
|
||||
@cindex Application Binary Interface
|
||||
|
||||
Some programs may not know at the time of compilation what arguments
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
told at run-time about the number and types of arguments used to call
|
||||
a given function. @samp{Libffi} can be used in such programs to
|
||||
provide a bridge from the interpreter program to compiled code.
|
||||
|
||||
The @samp{libffi} library provides a portable, high level programming
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
call any function specified by a call interface description at run
|
||||
time.
|
||||
|
||||
@acronym{FFI} stands for Foreign Function Interface. A foreign
|
||||
function interface is the popular name for the interface that allows
|
||||
code written in one language to call code written in another language.
|
||||
The @samp{libffi} library really only provides the lowest, machine
|
||||
dependent layer of a fully featured foreign function interface. A
|
||||
layer must exist above @samp{libffi} that handles type conversions for
|
||||
values passed between the two languages.
|
||||
@cindex FFI
|
||||
@cindex Foreign Function Interface
|
||||
|
||||
|
||||
@node Using libffi
|
||||
@chapter Using libffi
|
||||
|
||||
@menu
|
||||
* The Basics:: The basic libffi API.
|
||||
* Simple Example:: A simple example.
|
||||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
* Closure Example:: A closure example.
|
||||
* Thread Safety:: Thread safety.
|
||||
@end menu
|
||||
|
||||
|
||||
@node The Basics
|
||||
@section The Basics
|
||||
|
||||
@samp{Libffi} assumes that you have a pointer to the function you wish
|
||||
to call and that you know the number and types of arguments to pass
|
||||
it, as well as the return type of the function.
|
||||
|
||||
The first thing you must do is create an @code{ffi_cif} object that
|
||||
matches the signature of the function you wish to call. This is a
|
||||
separate step because it is common to make multiple calls using a
|
||||
single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for
|
||||
Call InterFace. To prepare a call interface object, use the function
|
||||
@code{ffi_prep_cif}.
|
||||
@cindex cif
|
||||
|
||||
@findex ffi_prep_cif
|
||||
@defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
|
||||
This initializes @var{cif} according to the given parameters.
|
||||
|
||||
@var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what
|
||||
you want. @ref{Multiple ABIs} for more information.
|
||||
|
||||
@var{nargs} is the number of arguments that this function accepts.
|
||||
|
||||
@var{rtype} is a pointer to an @code{ffi_type} structure that
|
||||
describes the return type of the function. @xref{Types}.
|
||||
|
||||
@var{argtypes} is a vector of @code{ffi_type} pointers.
|
||||
@var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0,
|
||||
this argument is ignored.
|
||||
|
||||
@code{ffi_prep_cif} returns a @code{libffi} status code, of type
|
||||
@code{ffi_status}. This will be either @code{FFI_OK} if everything
|
||||
worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type}
|
||||
objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
|
||||
is invalid.
|
||||
@end defun
|
||||
|
||||
If the function being called is variadic (varargs) then
|
||||
@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
|
||||
|
||||
@findex ffi_prep_cif_var
|
||||
@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
|
||||
This initializes @var{cif} according to the given parameters for
|
||||
a call to a variadic function. In general its operation is the
|
||||
same as for @code{ffi_prep_cif} except that:
|
||||
|
||||
@var{nfixedargs} is the number of fixed arguments, prior to any
|
||||
variadic arguments. It must be greater than zero.
|
||||
|
||||
@var{ntotalargs} the total number of arguments, including variadic
|
||||
and fixed arguments. @var{argtypes} must have this many elements.
|
||||
|
||||
Note that, different cif's must be prepped for calls to the same
|
||||
function when different numbers of arguments are passed.
|
||||
|
||||
Also note that a call to @code{ffi_prep_cif_var} with
|
||||
@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to
|
||||
@code{ffi_prep_cif}.
|
||||
|
||||
@end defun
|
||||
|
||||
Note that the resulting @code{ffi_cif} holds pointers to all the
|
||||
@code{ffi_type} objects that were used during initialization. You
|
||||
must ensure that these type objects have a lifetime at least as long
|
||||
as that of the @code{ffi_cif}.
|
||||
|
||||
To call a function using an initialized @code{ffi_cif}, use the
|
||||
@code{ffi_call} function:
|
||||
|
||||
@findex ffi_call
|
||||
@defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues})
|
||||
This calls the function @var{fn} according to the description given in
|
||||
@var{cif}. @var{cif} must have already been prepared using
|
||||
@code{ffi_prep_cif}.
|
||||
|
||||
@var{rvalue} is a pointer to a chunk of memory that will hold the
|
||||
result of the function call. This must be large enough to hold the
|
||||
result, no smaller than the system register size (generally 32 or 64
|
||||
bits), and must be suitably aligned; it is the caller's responsibility
|
||||
to ensure this. If @var{cif} declares that the function returns
|
||||
@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
|
||||
ignored.
|
||||
|
||||
In most situations, @samp{libffi} will handle promotion according to
|
||||
the ABI. However, for historical reasons, there is a special case
|
||||
with return values that must be handled by your code. In particular,
|
||||
for integral (not @code{struct}) types that are narrower than the
|
||||
system register size, the return value will be widened by
|
||||
@samp{libffi}. @samp{libffi} provides a type, @code{ffi_arg}, that
|
||||
can be used as the return type. For example, if the CIF was defined
|
||||
with a return type of @code{char}, @samp{libffi} will try to store a
|
||||
full @code{ffi_arg} into the return value.
|
||||
|
||||
@var{avalues} is a vector of @code{void *} pointers that point to the
|
||||
memory locations holding the argument values for a call. If @var{cif}
|
||||
declares that the function has no arguments (i.e., @var{nargs} was 0),
|
||||
then @var{avalues} is ignored. Note that argument values may be
|
||||
modified by the callee (for instance, structs passed by value); the
|
||||
burden of copying pass-by-value arguments is placed on the caller.
|
||||
|
||||
Note that while the return value must be register-sized, arguments
|
||||
should exactly match their declared type. For example, if an argument
|
||||
is a @code{short}, then the entry in @var{avalues} should point to an
|
||||
object declared as @code{short}; but if the return type is
|
||||
@code{short}, then @var{rvalue} should point to an object declared as
|
||||
a larger type -- usually @code{ffi_arg}.
|
||||
@end defun
|
||||
|
||||
|
||||
@node Simple Example
|
||||
@section Simple Example
|
||||
|
||||
Here is a trivial example that calls @code{puts} a few times.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
int main()
|
||||
@{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
void *values[1];
|
||||
char *s;
|
||||
ffi_arg rc;
|
||||
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
values[0] = &s;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_sint, args) == FFI_OK)
|
||||
@{
|
||||
s = "Hello World!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
/* rc now holds the result of the call to puts */
|
||||
|
||||
/* values holds a pointer to the function's arg, so to
|
||||
call puts() again all we need to do is change the
|
||||
value of s */
|
||||
s = "This is cool!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
@}
|
||||
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
|
||||
@node Types
|
||||
@section Types
|
||||
|
||||
@menu
|
||||
* Primitive Types:: Built-in types.
|
||||
* Structures:: Structure types.
|
||||
* Size and Alignment:: Size and alignment of types.
|
||||
* Arrays Unions Enums:: Arrays, unions, and enumerations.
|
||||
* Type Example:: Structure type example.
|
||||
* Complex:: Complex types.
|
||||
* Complex Type Example:: Complex type example.
|
||||
@end menu
|
||||
|
||||
@node Primitive Types
|
||||
@subsection Primitive Types
|
||||
|
||||
@code{Libffi} provides a number of built-in type descriptors that can
|
||||
be used to describe argument and return types:
|
||||
|
||||
@table @code
|
||||
@item ffi_type_void
|
||||
@tindex ffi_type_void
|
||||
The type @code{void}. This cannot be used for argument types, only
|
||||
for return values.
|
||||
|
||||
@item ffi_type_uint8
|
||||
@tindex ffi_type_uint8
|
||||
An unsigned, 8-bit integer type.
|
||||
|
||||
@item ffi_type_sint8
|
||||
@tindex ffi_type_sint8
|
||||
A signed, 8-bit integer type.
|
||||
|
||||
@item ffi_type_uint16
|
||||
@tindex ffi_type_uint16
|
||||
An unsigned, 16-bit integer type.
|
||||
|
||||
@item ffi_type_sint16
|
||||
@tindex ffi_type_sint16
|
||||
A signed, 16-bit integer type.
|
||||
|
||||
@item ffi_type_uint32
|
||||
@tindex ffi_type_uint32
|
||||
An unsigned, 32-bit integer type.
|
||||
|
||||
@item ffi_type_sint32
|
||||
@tindex ffi_type_sint32
|
||||
A signed, 32-bit integer type.
|
||||
|
||||
@item ffi_type_uint64
|
||||
@tindex ffi_type_uint64
|
||||
An unsigned, 64-bit integer type.
|
||||
|
||||
@item ffi_type_sint64
|
||||
@tindex ffi_type_sint64
|
||||
A signed, 64-bit integer type.
|
||||
|
||||
@item ffi_type_float
|
||||
@tindex ffi_type_float
|
||||
The C @code{float} type.
|
||||
|
||||
@item ffi_type_double
|
||||
@tindex ffi_type_double
|
||||
The C @code{double} type.
|
||||
|
||||
@item ffi_type_uchar
|
||||
@tindex ffi_type_uchar
|
||||
The C @code{unsigned char} type.
|
||||
|
||||
@item ffi_type_schar
|
||||
@tindex ffi_type_schar
|
||||
The C @code{signed char} type. (Note that there is not an exact
|
||||
equivalent to the C @code{char} type in @code{libffi}; ordinarily you
|
||||
should either use @code{ffi_type_schar} or @code{ffi_type_uchar}
|
||||
depending on whether @code{char} is signed.)
|
||||
|
||||
@item ffi_type_ushort
|
||||
@tindex ffi_type_ushort
|
||||
The C @code{unsigned short} type.
|
||||
|
||||
@item ffi_type_sshort
|
||||
@tindex ffi_type_sshort
|
||||
The C @code{short} type.
|
||||
|
||||
@item ffi_type_uint
|
||||
@tindex ffi_type_uint
|
||||
The C @code{unsigned int} type.
|
||||
|
||||
@item ffi_type_sint
|
||||
@tindex ffi_type_sint
|
||||
The C @code{int} type.
|
||||
|
||||
@item ffi_type_ulong
|
||||
@tindex ffi_type_ulong
|
||||
The C @code{unsigned long} type.
|
||||
|
||||
@item ffi_type_slong
|
||||
@tindex ffi_type_slong
|
||||
The C @code{long} type.
|
||||
|
||||
@item ffi_type_longdouble
|
||||
@tindex ffi_type_longdouble
|
||||
On platforms that have a C @code{long double} type, this is defined.
|
||||
On other platforms, it is not.
|
||||
|
||||
@item ffi_type_pointer
|
||||
@tindex ffi_type_pointer
|
||||
A generic @code{void *} pointer. You should use this for all
|
||||
pointers, regardless of their real type.
|
||||
|
||||
@item ffi_type_complex_float
|
||||
@tindex ffi_type_complex_float
|
||||
The C @code{_Complex float} type.
|
||||
|
||||
@item ffi_type_complex_double
|
||||
@tindex ffi_type_complex_double
|
||||
The C @code{_Complex double} type.
|
||||
|
||||
@item ffi_type_complex_longdouble
|
||||
@tindex ffi_type_complex_longdouble
|
||||
The C @code{_Complex long double} type.
|
||||
On platforms that have a C @code{long double} type, this is defined.
|
||||
On other platforms, it is not.
|
||||
@end table
|
||||
|
||||
Each of these is of type @code{ffi_type}, so you must take the address
|
||||
when passing to @code{ffi_prep_cif}.
|
||||
|
||||
|
||||
@node Structures
|
||||
@subsection Structures
|
||||
|
||||
@samp{libffi} is perfectly happy passing structures back and forth.
|
||||
You must first describe the structure to @samp{libffi} by creating a
|
||||
new @code{ffi_type} object for it.
|
||||
|
||||
@tindex ffi_type
|
||||
@deftp {Data type} ffi_type
|
||||
The @code{ffi_type} has the following members:
|
||||
@table @code
|
||||
@item size_t size
|
||||
This is set by @code{libffi}; you should initialize it to zero.
|
||||
|
||||
@item unsigned short alignment
|
||||
This is set by @code{libffi}; you should initialize it to zero.
|
||||
|
||||
@item unsigned short type
|
||||
For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
|
||||
|
||||
@item ffi_type **elements
|
||||
This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
|
||||
objects. There is one element per field of the struct.
|
||||
|
||||
Note that @samp{libffi} has no special support for bit-fields. You
|
||||
must manage these manually.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
The @code{size} and @code{alignment} fields will be filled in by
|
||||
@code{ffi_prep_cif} or @code{ffi_prep_cif_var}, as needed.
|
||||
|
||||
@node Size and Alignment
|
||||
@subsection Size and Alignment
|
||||
|
||||
@code{libffi} will set the @code{size} and @code{alignment} fields of
|
||||
an @code{ffi_type} object for you. It does so using its knowledge of
|
||||
the ABI.
|
||||
|
||||
You might expect that you can simply read these fields for a type that
|
||||
has been laid out by @code{libffi}. However, there are some caveats.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The size or alignment of some of the built-in types may vary depending
|
||||
on the chosen ABI.
|
||||
|
||||
@item
|
||||
The size and alignment of a new structure type will not be set by
|
||||
@code{libffi} until it has been passed to @code{ffi_prep_cif} or
|
||||
@code{ffi_get_struct_offsets}.
|
||||
|
||||
@item
|
||||
A structure type cannot be shared across ABIs. Instead each ABI needs
|
||||
its own copy of the structure type.
|
||||
@end itemize
|
||||
|
||||
So, before examining these fields, it is safest to pass the
|
||||
@code{ffi_type} object to @code{ffi_prep_cif} or
|
||||
@code{ffi_get_struct_offsets} first. This function will do all the
|
||||
needed setup.
|
||||
|
||||
@example
|
||||
ffi_type *desired_type;
|
||||
ffi_abi desired_abi;
|
||||
@dots{}
|
||||
ffi_cif cif;
|
||||
if (ffi_prep_cif (&cif, desired_abi, 0, desired_type, NULL) == FFI_OK)
|
||||
@{
|
||||
size_t size = desired_type->size;
|
||||
unsigned short alignment = desired_type->alignment;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@code{libffi} also provides a way to get the offsets of the members of
|
||||
a structure.
|
||||
|
||||
@findex ffi_get_struct_offsets
|
||||
@defun ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
|
||||
Compute the offset of each element of the given structure type.
|
||||
@var{abi} is the ABI to use; this is needed because in some cases the
|
||||
layout depends on the ABI.
|
||||
|
||||
@var{offsets} is an out parameter. The caller is responsible for
|
||||
providing enough space for all the results to be written -- one
|
||||
element per element type in @var{struct_type}. If @var{offsets} is
|
||||
@code{NULL}, then the type will be laid out but not otherwise
|
||||
modified. This can be useful for accessing the type's size or layout,
|
||||
as mentioned above.
|
||||
|
||||
This function returns @code{FFI_OK} on success; @code{FFI_BAD_ABI} if
|
||||
@var{abi} is invalid; or @code{FFI_BAD_TYPEDEF} if @var{struct_type}
|
||||
is invalid in some way. Note that only @code{FFI_STRUCT} types are
|
||||
valid here.
|
||||
@end defun
|
||||
|
||||
@node Arrays Unions Enums
|
||||
@subsection Arrays, Unions, and Enumerations
|
||||
|
||||
@subsubsection Arrays
|
||||
|
||||
@samp{libffi} does not have direct support for arrays or unions.
|
||||
However, they can be emulated using structures.
|
||||
|
||||
To emulate an array, simply create an @code{ffi_type} using
|
||||
@code{FFI_TYPE_STRUCT} with as many members as there are elements in
|
||||
the array.
|
||||
|
||||
@example
|
||||
ffi_type array_type;
|
||||
ffi_type **elements
|
||||
int i;
|
||||
|
||||
elements = malloc ((n + 1) * sizeof (ffi_type *));
|
||||
for (i = 0; i < n; ++i)
|
||||
elements[i] = array_element_type;
|
||||
elements[n] = NULL;
|
||||
|
||||
array_type.size = array_type.alignment = 0;
|
||||
array_type.type = FFI_TYPE_STRUCT;
|
||||
array_type.elements = elements;
|
||||
@end example
|
||||
|
||||
Note that arrays cannot be passed or returned by value in C --
|
||||
structure types created like this should only be used to refer to
|
||||
members of real @code{FFI_TYPE_STRUCT} objects.
|
||||
|
||||
However, a phony array type like this will not cause any errors from
|
||||
@samp{libffi} if you use it as an argument or return type. This may
|
||||
be confusing.
|
||||
|
||||
@subsubsection Unions
|
||||
|
||||
A union can also be emulated using @code{FFI_TYPE_STRUCT}. In this
|
||||
case, however, you must make sure that the size and alignment match
|
||||
the real requirements of the union.
|
||||
|
||||
One simple way to do this is to ensue that each element type is laid
|
||||
out. Then, give the new structure type a single element; the size of
|
||||
the largest element; and the largest alignment seen as well.
|
||||
|
||||
This example uses the @code{ffi_prep_cif} trick to ensure that each
|
||||
element type is laid out.
|
||||
|
||||
@example
|
||||
ffi_abi desired_abi;
|
||||
ffi_type union_type;
|
||||
ffi_type **union_elements;
|
||||
|
||||
int i;
|
||||
ffi_type element_types[2];
|
||||
|
||||
element_types[1] = NULL;
|
||||
|
||||
union_type.size = union_type.alignment = 0;
|
||||
union_type.type = FFI_TYPE_STRUCT;
|
||||
union_type.elements = element_types;
|
||||
|
||||
for (i = 0; union_elements[i]; ++i)
|
||||
@{
|
||||
ffi_cif cif;
|
||||
if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
|
||||
@{
|
||||
if (union_elements[i]->size > union_type.size)
|
||||
@{
|
||||
union_type.size = union_elements[i];
|
||||
size = union_elements[i]->size;
|
||||
@}
|
||||
if (union_elements[i]->alignment > union_type.alignment)
|
||||
union_type.alignment = union_elements[i]->alignment;
|
||||
@}
|
||||
@}
|
||||
@end example
|
||||
|
||||
@subsubsection Enumerations
|
||||
|
||||
@code{libffi} does not have any special support for C @code{enum}s.
|
||||
Although any given @code{enum} is implemented using a specific
|
||||
underlying integral type, exactly which type will be used cannot be
|
||||
determined by @code{libffi} -- it may depend on the values in the
|
||||
enumeration or on compiler flags such as @option{-fshort-enums}.
|
||||
@xref{Structures unions enumerations and bit-fields implementation, , , gcc},
|
||||
for more information about how GCC handles enumerations.
|
||||
|
||||
@node Type Example
|
||||
@subsection Type Example
|
||||
|
||||
The following example initializes a @code{ffi_type} object
|
||||
representing the @code{tm} struct from Linux's @file{time.h}.
|
||||
|
||||
Here is how the struct is defined:
|
||||
|
||||
@example
|
||||
struct tm @{
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
/* Those are for future use. */
|
||||
long int __tm_gmtoff__;
|
||||
__const char *__tm_zone__;
|
||||
@};
|
||||
@end example
|
||||
|
||||
Here is the corresponding code to describe this struct to
|
||||
@code{libffi}:
|
||||
|
||||
@example
|
||||
@{
|
||||
ffi_type tm_type;
|
||||
ffi_type *tm_type_elements[12];
|
||||
int i;
|
||||
|
||||
tm_type.size = tm_type.alignment = 0;
|
||||
tm_type.type = FFI_TYPE_STRUCT;
|
||||
tm_type.elements = &tm_type_elements;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
tm_type_elements[i] = &ffi_type_sint;
|
||||
|
||||
tm_type_elements[9] = &ffi_type_slong;
|
||||
tm_type_elements[10] = &ffi_type_pointer;
|
||||
tm_type_elements[11] = NULL;
|
||||
|
||||
/* tm_type can now be used to represent tm argument types and
|
||||
return types for ffi_prep_cif() */
|
||||
@}
|
||||
@end example
|
||||
|
||||
@node Complex
|
||||
@subsection Complex Types
|
||||
|
||||
@samp{libffi} supports the complex types defined by the C99
|
||||
standard (@code{_Complex float}, @code{_Complex double} and
|
||||
@code{_Complex long double} with the built-in type descriptors
|
||||
@code{ffi_type_complex_float}, @code{ffi_type_complex_double} and
|
||||
@code{ffi_type_complex_longdouble}.
|
||||
|
||||
Custom complex types like @code{_Complex int} can also be used.
|
||||
An @code{ffi_type} object has to be defined to describe the
|
||||
complex type to @samp{libffi}.
|
||||
|
||||
@tindex ffi_type
|
||||
@deftp {Data type} ffi_type
|
||||
@table @code
|
||||
@item size_t size
|
||||
This must be manually set to the size of the complex type.
|
||||
|
||||
@item unsigned short alignment
|
||||
This must be manually set to the alignment of the complex type.
|
||||
|
||||
@item unsigned short type
|
||||
For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}.
|
||||
|
||||
@item ffi_type **elements
|
||||
|
||||
This is a @samp{NULL}-terminated array of pointers to
|
||||
@code{ffi_type} objects. The first element is set to the
|
||||
@code{ffi_type} of the complex's base type. The second element
|
||||
must be set to @code{NULL}.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
The section @ref{Complex Type Example} shows a way to determine
|
||||
the @code{size} and @code{alignment} members in a platform
|
||||
independent way.
|
||||
|
||||
For platforms that have no complex support in @code{libffi} yet,
|
||||
the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort
|
||||
the program if they encounter a complex type.
|
||||
|
||||
@node Complex Type Example
|
||||
@subsection Complex Type Example
|
||||
|
||||
This example demonstrates how to use complex types:
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
#include <complex.h>
|
||||
|
||||
void complex_fn(_Complex float cf,
|
||||
_Complex double cd,
|
||||
_Complex long double cld)
|
||||
@{
|
||||
printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
|
||||
(float)creal (cf), (float)cimag (cf),
|
||||
(float)creal (cd), (float)cimag (cd),
|
||||
(float)creal (cld), (float)cimag (cld));
|
||||
@}
|
||||
|
||||
int main()
|
||||
@{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[3];
|
||||
void *values[3];
|
||||
_Complex float cf;
|
||||
_Complex double cd;
|
||||
_Complex long double cld;
|
||||
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_complex_float;
|
||||
args[1] = &ffi_type_complex_double;
|
||||
args[2] = &ffi_type_complex_longdouble;
|
||||
values[0] = &cf;
|
||||
values[1] = &cd;
|
||||
values[2] = &cld;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
|
||||
&ffi_type_void, args) == FFI_OK)
|
||||
@{
|
||||
cf = 1.0 + 20.0 * I;
|
||||
cd = 300.0 + 4000.0 * I;
|
||||
cld = 50000.0 + 600000.0 * I;
|
||||
/* Call the function */
|
||||
ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
|
||||
@}
|
||||
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
This is an example for defining a custom complex type descriptor
|
||||
for compilers that support them:
|
||||
|
||||
@example
|
||||
/*
|
||||
* This macro can be used to define new complex type descriptors
|
||||
* in a platform independent way.
|
||||
*
|
||||
* name: Name of the new descriptor is ffi_type_complex_<name>.
|
||||
* type: The C base type of the complex type.
|
||||
*/
|
||||
#define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
|
||||
static ffi_type *ffi_elements_complex_##name [2] = @{ \
|
||||
(ffi_type *)(&ffitype), NULL \
|
||||
@}; \
|
||||
struct struct_align_complex_##name @{ \
|
||||
char c; \
|
||||
_Complex type x; \
|
||||
@}; \
|
||||
ffi_type ffi_type_complex_##name = @{ \
|
||||
sizeof(_Complex type), \
|
||||
offsetof(struct struct_align_complex_##name, x), \
|
||||
FFI_TYPE_COMPLEX, \
|
||||
(ffi_type **)ffi_elements_complex_##name \
|
||||
@}
|
||||
|
||||
/* Define new complex type descriptors using the macro: */
|
||||
/* ffi_type_complex_sint */
|
||||
FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
|
||||
/* ffi_type_complex_uchar */
|
||||
FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
|
||||
@end example
|
||||
|
||||
The new type descriptors can then be used like one of the built-in
|
||||
type descriptors in the previous example.
|
||||
|
||||
@node Multiple ABIs
|
||||
@section Multiple ABIs
|
||||
|
||||
A given platform may provide multiple different ABIs at once. For
|
||||
instance, the x86 platform has both @samp{stdcall} and @samp{fastcall}
|
||||
functions.
|
||||
|
||||
@code{libffi} provides some support for this. However, this is
|
||||
necessarily platform-specific.
|
||||
|
||||
@c FIXME: document the platforms
|
||||
|
||||
@node The Closure API
|
||||
@section The Closure API
|
||||
|
||||
@code{libffi} also provides a way to write a generic function -- a
|
||||
function that can accept and decode any combination of arguments.
|
||||
This can be useful when writing an interpreter, or to provide wrappers
|
||||
for arbitrary functions.
|
||||
|
||||
This facility is called the @dfn{closure API}. Closures are not
|
||||
supported on all platforms; you can check the @code{FFI_CLOSURES}
|
||||
define to determine whether they are supported on the current
|
||||
platform.
|
||||
@cindex closures
|
||||
@cindex closure API
|
||||
@findex FFI_CLOSURES
|
||||
|
||||
Because closures work by assembling a tiny function at runtime, they
|
||||
require special allocation on platforms that have a non-executable
|
||||
heap. Memory management for closures is handled by a pair of
|
||||
functions:
|
||||
|
||||
@findex ffi_closure_alloc
|
||||
@defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code})
|
||||
Allocate a chunk of memory holding @var{size} bytes. This returns a
|
||||
pointer to the writable address, and sets *@var{code} to the
|
||||
corresponding executable address.
|
||||
|
||||
@var{size} should be sufficient to hold a @code{ffi_closure} object.
|
||||
@end defun
|
||||
|
||||
@findex ffi_closure_free
|
||||
@defun void ffi_closure_free (void *@var{writable})
|
||||
Free memory allocated using @code{ffi_closure_alloc}. The argument is
|
||||
the writable address that was returned.
|
||||
@end defun
|
||||
|
||||
|
||||
Once you have allocated the memory for a closure, you must construct a
|
||||
@code{ffi_cif} describing the function call. Finally you can prepare
|
||||
the closure function:
|
||||
|
||||
@findex ffi_prep_closure_loc
|
||||
@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
|
||||
Prepare a closure function. The arguments to
|
||||
@code{ffi_prep_closure_loc} are:
|
||||
|
||||
@table @var
|
||||
@item closure
|
||||
The address of a @code{ffi_closure} object; this is the writable
|
||||
address returned by @code{ffi_closure_alloc}.
|
||||
|
||||
@item cif
|
||||
The @code{ffi_cif} describing the function parameters. Note that this
|
||||
object, and the types to which it refers, must be kept alive until the
|
||||
closure itself is freed.
|
||||
|
||||
@item user_data
|
||||
An arbitrary datum that is passed, uninterpreted, to your closure
|
||||
function.
|
||||
|
||||
@item codeloc
|
||||
The executable address returned by @code{ffi_closure_alloc}.
|
||||
|
||||
@item fun
|
||||
The function which will be called when the closure is invoked. It is
|
||||
called with the arguments:
|
||||
|
||||
@table @var
|
||||
@item cif
|
||||
The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
|
||||
|
||||
@item ret
|
||||
A pointer to the memory used for the function's return value.
|
||||
|
||||
If the function is declared as returning @code{void}, then this value
|
||||
is garbage and should not be used.
|
||||
|
||||
Otherwise, @var{fun} must fill the object to which this points,
|
||||
following the same special promotion behavior as @code{ffi_call}.
|
||||
That is, in most cases, @var{ret} points to an object of exactly the
|
||||
size of the type specified when @var{cif} was constructed. However,
|
||||
integral types narrower than the system register size are widened. In
|
||||
these cases your program may assume that @var{ret} points to an
|
||||
@code{ffi_arg} object.
|
||||
|
||||
@item args
|
||||
A vector of pointers to memory holding the arguments to the function.
|
||||
|
||||
@item user_data
|
||||
The same @var{user_data} that was passed to
|
||||
@code{ffi_prep_closure_loc}.
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
|
||||
went ok, and one of the other @code{ffi_status} values on error.
|
||||
|
||||
After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
|
||||
to the appropriate pointer-to-function type.
|
||||
@end defun
|
||||
|
||||
You may see old code referring to @code{ffi_prep_closure}. This
|
||||
function is deprecated, as it cannot handle the need for separate
|
||||
writable and executable addresses.
|
||||
|
||||
@node Closure Example
|
||||
@section Closure Example
|
||||
|
||||
A trivial example that creates a new @code{puts} by binding
|
||||
@code{fputs} with @code{stdout}.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
/* Acts like puts with the file given at time of enclosure. */
|
||||
void puts_binding(ffi_cif *cif, void *ret, void* args[],
|
||||
void *stream)
|
||||
@{
|
||||
*(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
|
||||
@}
|
||||
|
||||
typedef int (*puts_t)(char *);
|
||||
|
||||
int main()
|
||||
@{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
ffi_closure *closure;
|
||||
|
||||
void *bound_puts;
|
||||
int rc;
|
||||
|
||||
/* Allocate closure and bound_puts */
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
||||
|
||||
if (closure)
|
||||
@{
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_sint, args) == FFI_OK)
|
||||
@{
|
||||
/* Initialize the closure, setting stream to stdout */
|
||||
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
||||
stdout, bound_puts) == FFI_OK)
|
||||
@{
|
||||
rc = ((puts_t)bound_puts)("Hello World!");
|
||||
/* rc now holds the result of the call to fputs */
|
||||
@}
|
||||
@}
|
||||
@}
|
||||
|
||||
/* Deallocate both closure, and bound_puts */
|
||||
ffi_closure_free(closure);
|
||||
|
||||
return 0;
|
||||
@}
|
||||
|
||||
@end example
|
||||
|
||||
@node Thread Safety
|
||||
@section Thread Safety
|
||||
|
||||
@code{libffi} is not completely thread-safe. However, many parts are,
|
||||
and if you follow some simple rules, you can use it safely in a
|
||||
multi-threaded program.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{ffi_prep_cif} may modify the @code{ffi_type} objects passed to
|
||||
it. It is best to ensure that only a single thread prepares a given
|
||||
@code{ffi_cif} at a time.
|
||||
|
||||
@item
|
||||
On some platforms, @code{ffi_prep_cif} may modify the size and
|
||||
alignment of some types, depending on the chosen ABI. On these
|
||||
platforms, if you switch between ABIs, you must ensure that there is
|
||||
only one call to @code{ffi_prep_cif} at a time.
|
||||
|
||||
Currently the only affected platform is PowerPC and the only affected
|
||||
type is @code{long double}.
|
||||
@end itemize
|
||||
|
||||
@node Missing Features
|
||||
@chapter Missing Features
|
||||
|
||||
@code{libffi} is missing a few features. We welcome patches to add
|
||||
support for these.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Variadic closures.
|
||||
|
||||
@item
|
||||
There is no support for bit fields in structures.
|
||||
|
||||
@item
|
||||
The ``raw'' API is undocumented.
|
||||
@c anything else?
|
||||
|
||||
@item
|
||||
The Go API is undocumented.
|
||||
@end itemize
|
||||
|
||||
Note that variadic support is very new and tested on a relatively
|
||||
small number of platforms.
|
||||
|
||||
@node Index
|
||||
@unnumbered Index
|
||||
|
||||
@printindex cp
|
||||
|
||||
@bye
|
228
doc/mdate-sh
Executable file
228
doc/mdate-sh
Executable file
@ -0,0 +1,228 @@
|
||||
#!/bin/sh
|
||||
# Get modification time of a file or directory and pretty-print it.
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1995-2018 Free Software Foundation, Inc.
|
||||
# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
|
||||
emulate sh
|
||||
NULLCMD=:
|
||||
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
|
||||
# is contrary to our usage. Disable this feature.
|
||||
alias -g '${1+"$@"}'='"$@"'
|
||||
setopt NO_GLOB_SUBST
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No file. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: mdate-sh [--help] [--version] FILE
|
||||
|
||||
Pretty-print the modification day of FILE, in the format:
|
||||
1 January 1970
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "mdate-sh $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
error ()
|
||||
{
|
||||
echo "$0: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
# Prevent date giving response in another language.
|
||||
LANG=C
|
||||
export LANG
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
LC_TIME=C
|
||||
export LC_TIME
|
||||
|
||||
# Use UTC to get reproducible result.
|
||||
TZ=UTC0
|
||||
export TZ
|
||||
|
||||
# GNU ls changes its time format in response to the TIME_STYLE
|
||||
# variable. Since we cannot assume 'unset' works, revert this
|
||||
# variable to its documented default.
|
||||
if test "${TIME_STYLE+set}" = set; then
|
||||
TIME_STYLE=posix-long-iso
|
||||
export TIME_STYLE
|
||||
fi
|
||||
|
||||
save_arg1=$1
|
||||
|
||||
# Find out how to get the extended ls output of a file or directory.
|
||||
if ls -L /dev/null 1>/dev/null 2>&1; then
|
||||
ls_command='ls -L -l -d'
|
||||
else
|
||||
ls_command='ls -l -d'
|
||||
fi
|
||||
# Avoid user/group names that might have spaces, when possible.
|
||||
if ls -n /dev/null 1>/dev/null 2>&1; then
|
||||
ls_command="$ls_command -n"
|
||||
fi
|
||||
|
||||
# A 'ls -l' line looks as follows on OS/2.
|
||||
# drwxrwx--- 0 Aug 11 2001 foo
|
||||
# This differs from Unix, which adds ownership information.
|
||||
# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
|
||||
#
|
||||
# To find the date, we split the line on spaces and iterate on words
|
||||
# until we find a month. This cannot work with files whose owner is a
|
||||
# user named "Jan", or "Feb", etc. However, it's unlikely that '/'
|
||||
# will be owned by a user whose name is a month. So we first look at
|
||||
# the extended ls output of the root directory to decide how many
|
||||
# words should be skipped to get the date.
|
||||
|
||||
# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
|
||||
set x`$ls_command /`
|
||||
|
||||
# Find which argument is the month.
|
||||
month=
|
||||
command=
|
||||
until test $month
|
||||
do
|
||||
test $# -gt 0 || error "failed parsing '$ls_command /' output"
|
||||
shift
|
||||
# Add another shift to the command.
|
||||
command="$command shift;"
|
||||
case $1 in
|
||||
Jan) month=January; nummonth=1;;
|
||||
Feb) month=February; nummonth=2;;
|
||||
Mar) month=March; nummonth=3;;
|
||||
Apr) month=April; nummonth=4;;
|
||||
May) month=May; nummonth=5;;
|
||||
Jun) month=June; nummonth=6;;
|
||||
Jul) month=July; nummonth=7;;
|
||||
Aug) month=August; nummonth=8;;
|
||||
Sep) month=September; nummonth=9;;
|
||||
Oct) month=October; nummonth=10;;
|
||||
Nov) month=November; nummonth=11;;
|
||||
Dec) month=December; nummonth=12;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -n "$month" || error "failed parsing '$ls_command /' output"
|
||||
|
||||
# Get the extended ls output of the file or directory.
|
||||
set dummy x`eval "$ls_command \"\\\$save_arg1\""`
|
||||
|
||||
# Remove all preceding arguments
|
||||
eval $command
|
||||
|
||||
# Because of the dummy argument above, month is in $2.
|
||||
#
|
||||
# On a POSIX system, we should have
|
||||
#
|
||||
# $# = 5
|
||||
# $1 = file size
|
||||
# $2 = month
|
||||
# $3 = day
|
||||
# $4 = year or time
|
||||
# $5 = filename
|
||||
#
|
||||
# On Darwin 7.7.0 and 7.6.0, we have
|
||||
#
|
||||
# $# = 4
|
||||
# $1 = day
|
||||
# $2 = month
|
||||
# $3 = year or time
|
||||
# $4 = filename
|
||||
|
||||
# Get the month.
|
||||
case $2 in
|
||||
Jan) month=January; nummonth=1;;
|
||||
Feb) month=February; nummonth=2;;
|
||||
Mar) month=March; nummonth=3;;
|
||||
Apr) month=April; nummonth=4;;
|
||||
May) month=May; nummonth=5;;
|
||||
Jun) month=June; nummonth=6;;
|
||||
Jul) month=July; nummonth=7;;
|
||||
Aug) month=August; nummonth=8;;
|
||||
Sep) month=September; nummonth=9;;
|
||||
Oct) month=October; nummonth=10;;
|
||||
Nov) month=November; nummonth=11;;
|
||||
Dec) month=December; nummonth=12;;
|
||||
esac
|
||||
|
||||
case $3 in
|
||||
???*) day=$1;;
|
||||
*) day=$3; shift;;
|
||||
esac
|
||||
|
||||
# Here we have to deal with the problem that the ls output gives either
|
||||
# the time of day or the year.
|
||||
case $3 in
|
||||
*:*) set `date`; eval year=\$$#
|
||||
case $2 in
|
||||
Jan) nummonthtod=1;;
|
||||
Feb) nummonthtod=2;;
|
||||
Mar) nummonthtod=3;;
|
||||
Apr) nummonthtod=4;;
|
||||
May) nummonthtod=5;;
|
||||
Jun) nummonthtod=6;;
|
||||
Jul) nummonthtod=7;;
|
||||
Aug) nummonthtod=8;;
|
||||
Sep) nummonthtod=9;;
|
||||
Oct) nummonthtod=10;;
|
||||
Nov) nummonthtod=11;;
|
||||
Dec) nummonthtod=12;;
|
||||
esac
|
||||
# For the first six month of the year the time notation can also
|
||||
# be used for files modified in the last year.
|
||||
if (expr $nummonth \> $nummonthtod) > /dev/null;
|
||||
then
|
||||
year=`expr $year - 1`
|
||||
fi;;
|
||||
*) year=$3;;
|
||||
esac
|
||||
|
||||
# The result.
|
||||
echo $day $month $year
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
4
doc/stamp-vti
Normal file
4
doc/stamp-vti
Normal file
@ -0,0 +1,4 @@
|
||||
@set UPDATED 22 November 2019
|
||||
@set UPDATED-MONTH November 2019
|
||||
@set EDITION 3.3
|
||||
@set VERSION 3.3
|
11727
doc/texinfo.tex
Normal file
11727
doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
4
doc/version.texi
Normal file
4
doc/version.texi
Normal file
@ -0,0 +1,4 @@
|
||||
@set UPDATED 22 November 2019
|
||||
@set UPDATED-MONTH November 2019
|
||||
@set EDITION 3.3
|
||||
@set VERSION 3.3
|
177
fficonfig.h
Executable file
177
fficonfig.h
Executable file
@ -0,0 +1,177 @@
|
||||
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Define to the flags needed for the .section .eh_frame directive. */
|
||||
#define EH_FRAME_FLAGS "a"
|
||||
|
||||
/* Define this if you want extra debugging. */
|
||||
/* #undef FFI_DEBUG */
|
||||
|
||||
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
|
||||
#define FFI_EXEC_TRAMPOLINE_TABLE 0
|
||||
|
||||
/* Define this if you want to enable pax emulated trampolines */
|
||||
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
|
||||
|
||||
/* Cannot use malloc on this target, so, we revert to alternative means */
|
||||
#define FFI_MMAP_EXEC_WRIT 1
|
||||
|
||||
/* Define this if you do not want support for the raw API. */
|
||||
/* #undef FFI_NO_RAW_API */
|
||||
|
||||
/* Define this if you do not want support for aggregate types. */
|
||||
/* #undef FFI_NO_STRUCTS */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
/* #undef HAVE_ALLOCA */
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used */
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define if your assembler supports .ascii. */
|
||||
/* #undef HAVE_AS_ASCII_PSEUDO_OP */
|
||||
|
||||
/* Define if your assembler supports .cfi_* directives. */
|
||||
/* #undef HAVE_AS_CFI_PSEUDO_OP */
|
||||
|
||||
/* Define if your assembler supports .register. */
|
||||
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
|
||||
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs.
|
||||
*/
|
||||
/* #undef HAVE_AS_SPARC_UA_PCREL */
|
||||
|
||||
/* Define if your assembler supports .string. */
|
||||
/* #undef HAVE_AS_STRING_PSEUDO_OP */
|
||||
|
||||
/* Define if your assembler supports unwind section type. */
|
||||
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
|
||||
|
||||
/* Define if your assembler supports PC relative relocs. */
|
||||
/* #undef HAVE_AS_X86_PCREL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define if __attribute__((visibility("hidden"))) is supported. */
|
||||
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
#ifdef __LP64__
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
#else
|
||||
#define HAVE_LONG_DOUBLE 0
|
||||
#endif
|
||||
|
||||
/* Define if you support more than one size of the long double type */
|
||||
#define HAVE_LONG_DOUBLE_VARIANT 0
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
#define HAVE_MKOSTEMP
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
/* #undef HAVE_MMAP */
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
/* #undef HAVE_MMAP_ANON */
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
/* #undef HAVE_MMAP_DEV_ZERO */
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
/* #undef HAVE_MMAP_FILE */
|
||||
|
||||
/* Define if .eh_frame sections should be read-only. */
|
||||
#define HAVE_RO_EH_FRAME 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
/* #undef HAVE_STDLIB_H */
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
/* #undef HAVE_STRING_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
/* #undef HAVE_SYS_MMAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
/* #undef HAVE_SYS_STAT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
/* #undef HAVE_SYS_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
|
||||
/* The size of `double', as computed by sizeof. */
|
||||
#define SIZEOF_DOUBLE 8
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
#else
|
||||
#define SIZEOF_LONG_DOUBLE 8
|
||||
#endif
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* Define if symbols are underscored. */
|
||||
/* #undef SYMBOL_UNDERSCORE */
|
||||
|
||||
/* Define this if you are using Purify and want to suppress spurious messages.
|
||||
*/
|
||||
/* #undef USING_PURIFY */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
#if defined __BIG_ENDIAN__
|
||||
#define WORDS_BIGENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#ifdef __APPLE__
|
||||
#define FFI_HIDDEN(name) .private_extern name
|
||||
#else
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#endif
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
214
fficonfig.h.in
Normal file
214
fficonfig.h.in
Normal file
@ -0,0 +1,214 @@
|
||||
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to the flags needed for the .section .eh_frame directive. */
|
||||
#undef EH_FRAME_FLAGS
|
||||
|
||||
/* Define this if you want extra debugging. */
|
||||
#undef FFI_DEBUG
|
||||
|
||||
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
|
||||
#undef FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
/* Define this if you want to enable pax emulated trampolines */
|
||||
#undef FFI_MMAP_EXEC_EMUTRAMP_PAX
|
||||
|
||||
/* Cannot use malloc on this target, so, we revert to alternative means */
|
||||
#undef FFI_MMAP_EXEC_WRIT
|
||||
|
||||
/* Define this if you do not want support for the raw API. */
|
||||
#undef FFI_NO_RAW_API
|
||||
|
||||
/* Define this if you do not want support for aggregate types. */
|
||||
#undef FFI_NO_STRUCTS
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if your assembler supports .cfi_* directives. */
|
||||
#undef HAVE_AS_CFI_PSEUDO_OP
|
||||
|
||||
/* Define if your assembler supports .register. */
|
||||
#undef HAVE_AS_REGISTER_PSEUDO_OP
|
||||
|
||||
/* Define if the compiler uses zarch features. */
|
||||
#undef HAVE_AS_S390_ZARCH
|
||||
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs.
|
||||
*/
|
||||
#undef HAVE_AS_SPARC_UA_PCREL
|
||||
|
||||
/* Define if your assembler supports unwind section type. */
|
||||
#undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
|
||||
|
||||
/* Define if your assembler supports PC relative relocs. */
|
||||
#undef HAVE_AS_X86_PCREL
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define if __attribute__((visibility("hidden"))) is supported. */
|
||||
#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you support more than one size of the long double type */
|
||||
#undef HAVE_LONG_DOUBLE_VARIANT
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
#undef HAVE_MKOSTEMP
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
#undef HAVE_MMAP_ANON
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
#undef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
#undef HAVE_MMAP_FILE
|
||||
|
||||
/* Define if .eh_frame sections should be read-only. */
|
||||
#undef HAVE_RO_EH_FRAME
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if GNU symbol versioning is used for libatomic. */
|
||||
#undef LIBFFI_GNU_SYMBOL_VERSIONING
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* The size of `double', as computed by sizeof. */
|
||||
#undef SIZEOF_DOUBLE
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_DOUBLE
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at runtime.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define if symbols are underscored. */
|
||||
#undef SYMBOL_UNDERSCORE
|
||||
|
||||
/* Define this if you are using Purify and want to suppress spurious messages.
|
||||
*/
|
||||
#undef USING_PURIFY
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#ifdef __APPLE__
|
||||
#define FFI_HIDDEN(name) .private_extern name
|
||||
#else
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#endif
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
|
203
generate-darwin-source-and-headers.py
Executable file
203
generate-darwin-source-and-headers.py
Executable file
@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python
|
||||
import subprocess
|
||||
import os
|
||||
import errno
|
||||
import collections
|
||||
import glob
|
||||
import argparse
|
||||
|
||||
class Platform(object):
|
||||
pass
|
||||
|
||||
class simulator_platform(Platform):
|
||||
directory = 'darwin_ios'
|
||||
sdk = 'iphonesimulator'
|
||||
arch = 'i386'
|
||||
triple = 'i386-apple-darwin11'
|
||||
version_min = '-miphoneos-version-min=7.0'
|
||||
|
||||
prefix = "#ifdef __i386__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
src_dir = 'x86'
|
||||
src_files = ['sysv.S', 'ffi.c', 'internal.h']
|
||||
|
||||
|
||||
class simulator64_platform(Platform):
|
||||
directory = 'darwin_ios'
|
||||
sdk = 'iphonesimulator'
|
||||
arch = 'x86_64'
|
||||
triple = 'x86_64-apple-darwin13'
|
||||
version_min = '-miphoneos-version-min=7.0'
|
||||
|
||||
prefix = "#ifdef __x86_64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
src_dir = 'x86'
|
||||
src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
|
||||
|
||||
|
||||
class device_platform(Platform):
|
||||
directory = 'darwin_ios'
|
||||
sdk = 'iphoneos'
|
||||
arch = 'armv7'
|
||||
triple = 'arm-apple-darwin11'
|
||||
version_min = '-miphoneos-version-min=7.0'
|
||||
|
||||
prefix = "#ifdef __arm__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
src_dir = 'arm'
|
||||
src_files = ['sysv.S', 'ffi.c', 'internal.h']
|
||||
|
||||
|
||||
class device64_platform(Platform):
|
||||
directory = 'darwin_ios'
|
||||
sdk = 'iphoneos'
|
||||
arch = 'arm64'
|
||||
triple = 'aarch64-apple-darwin13'
|
||||
version_min = '-miphoneos-version-min=7.0'
|
||||
|
||||
prefix = "#ifdef __arm64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
src_dir = 'aarch64'
|
||||
src_files = ['sysv.S', 'ffi.c', 'internal.h']
|
||||
|
||||
|
||||
class desktop32_platform(Platform):
|
||||
directory = 'darwin_osx'
|
||||
sdk = 'macosx'
|
||||
arch = 'i386'
|
||||
triple = 'i386-apple-darwin10'
|
||||
version_min = '-mmacosx-version-min=10.6'
|
||||
src_dir = 'x86'
|
||||
src_files = ['sysv.S', 'ffi.c', 'internal.h']
|
||||
|
||||
prefix = "#ifdef __i386__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
|
||||
class desktop64_platform(Platform):
|
||||
directory = 'darwin_osx'
|
||||
sdk = 'macosx'
|
||||
arch = 'x86_64'
|
||||
triple = 'x86_64-apple-darwin10'
|
||||
version_min = '-mmacosx-version-min=10.6'
|
||||
|
||||
prefix = "#ifdef __x86_64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
src_dir = 'x86'
|
||||
src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >2.5
|
||||
if exc.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
|
||||
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
|
||||
mkdir_p(dst_dir)
|
||||
out_filename = filename
|
||||
|
||||
if file_suffix:
|
||||
if filename in ['internal64.h', 'asmnames.h', 'internal.h']:
|
||||
out_filename = filename
|
||||
else:
|
||||
split_name = os.path.splitext(filename)
|
||||
out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
|
||||
|
||||
with open(os.path.join(src_dir, filename)) as in_file:
|
||||
with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
|
||||
if prefix:
|
||||
out_file.write(prefix)
|
||||
|
||||
out_file.write(in_file.read())
|
||||
|
||||
if suffix:
|
||||
out_file.write(suffix)
|
||||
|
||||
|
||||
def list_files(src_dir, pattern=None, filelist=None):
|
||||
if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern))
|
||||
for file in filelist:
|
||||
yield os.path.basename(file)
|
||||
|
||||
|
||||
def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None):
|
||||
for filename in list_files(src_dir, pattern=pattern, filelist=filelist):
|
||||
move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix)
|
||||
|
||||
|
||||
def copy_src_platform_files(platform):
|
||||
src_dir = os.path.join('src', platform.src_dir)
|
||||
dst_dir = os.path.join(platform.directory, 'src', platform.src_dir)
|
||||
copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix)
|
||||
|
||||
|
||||
def build_target(platform, platform_headers):
|
||||
def xcrun_cmd(cmd):
|
||||
return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch)
|
||||
|
||||
tag='%s-%s' % (platform.sdk, platform.arch)
|
||||
build_dir = 'build_%s' % tag
|
||||
mkdir_p(build_dir)
|
||||
env = dict(CC=xcrun_cmd('clang'),
|
||||
LD=xcrun_cmd('ld'),
|
||||
CFLAGS='%s' % (platform.version_min))
|
||||
working_dir = os.getcwd()
|
||||
try:
|
||||
os.chdir(build_dir)
|
||||
subprocess.check_call(['../configure', '-host', platform.triple], env=env)
|
||||
finally:
|
||||
os.chdir(working_dir)
|
||||
|
||||
for src_dir in [build_dir, os.path.join(build_dir, 'include')]:
|
||||
copy_files(src_dir,
|
||||
os.path.join(platform.directory, 'include'),
|
||||
pattern='*.h',
|
||||
file_suffix=platform.arch,
|
||||
prefix=platform.prefix,
|
||||
suffix=platform.suffix)
|
||||
|
||||
for filename in list_files(src_dir, pattern='*.h'):
|
||||
platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix))
|
||||
|
||||
|
||||
def generate_source_and_headers(generate_osx=True, generate_ios=True):
|
||||
copy_files('src', 'darwin_common/src', pattern='*.c')
|
||||
copy_files('include', 'darwin_common/include', pattern='*.h')
|
||||
|
||||
if generate_ios:
|
||||
copy_src_platform_files(simulator_platform)
|
||||
copy_src_platform_files(simulator64_platform)
|
||||
copy_src_platform_files(device_platform)
|
||||
copy_src_platform_files(device64_platform)
|
||||
if generate_osx:
|
||||
copy_src_platform_files(desktop32_platform)
|
||||
copy_src_platform_files(desktop64_platform)
|
||||
|
||||
platform_headers = collections.defaultdict(set)
|
||||
|
||||
if generate_ios:
|
||||
build_target(simulator_platform, platform_headers)
|
||||
build_target(simulator64_platform, platform_headers)
|
||||
build_target(device_platform, platform_headers)
|
||||
build_target(device64_platform, platform_headers)
|
||||
if generate_osx:
|
||||
build_target(desktop32_platform, platform_headers)
|
||||
build_target(desktop64_platform, platform_headers)
|
||||
|
||||
mkdir_p('darwin_common/include')
|
||||
for header_name, tag_tuples in platform_headers.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
with open(os.path.join('darwin_common/include', header_name), 'w') as header:
|
||||
for tag_tuple in tag_tuples:
|
||||
header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--only-ios', action='store_true', default=False)
|
||||
parser.add_argument('--only-osx', action='store_true', default=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx)
|
9
include/Makefile.am
Normal file
9
include/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
|
||||
DISTCLEANFILES=ffitarget.h
|
||||
noinst_HEADERS=ffi_common.h ffi_cfi.h
|
||||
EXTRA_DIST=ffi.h.in
|
||||
|
||||
nodist_include_HEADERS = ffi.h ffitarget.h
|
607
include/Makefile.in
Normal file
607
include/Makefile.in
Normal file
@ -0,0 +1,607 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = include
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
|
||||
$(top_srcdir)/m4/ax_append_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
|
||||
$(top_srcdir)/m4/ax_configure_args.m4 \
|
||||
$(top_srcdir)/m4/ax_enable_builddir.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
|
||||
$(top_srcdir)/m4/ax_require_defined.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
|
||||
$(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/fficonfig.h
|
||||
CONFIG_CLEAN_FILES = ffi.h
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(includedir)"
|
||||
HEADERS = $(nodist_include_HEADERS) $(noinst_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ffi.h.in
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_LTLDFLAGS = @AM_LTLDFLAGS@
|
||||
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASDEPMODE = @CCASDEPMODE@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
|
||||
HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OPT_LDFLAGS = @OPT_LDFLAGS@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PRTDIAG = @PRTDIAG@
|
||||
RANLIB = @RANLIB@
|
||||
SECTION_LDFLAGS = @SECTION_LDFLAGS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
TARGET = @TARGET@
|
||||
TARGETDIR = @TARGETDIR@
|
||||
TARGET_OBJ = @TARGET_OBJ@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
ax_enable_builddir_sed = @ax_enable_builddir_sed@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sys_symbol_underscore = @sys_symbol_underscore@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
toolexecdir = @toolexecdir@
|
||||
toolexeclibdir = @toolexeclibdir@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
DISTCLEANFILES = ffitarget.h
|
||||
noinst_HEADERS = ffi_common.h ffi_cfi.h
|
||||
EXTRA_DIST = ffi.h.in
|
||||
nodist_include_HEADERS = ffi.h ffitarget.h
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign include/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
ffi.h: $(top_builddir)/config.status $(srcdir)/ffi.h.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-nodist_includeHEADERS: $(nodist_include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-nodist_includeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(HEADERS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(includedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-nodist_includeHEADERS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-nodist_includeHEADERS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool cscopelist-am ctags ctags-am distclean \
|
||||
distclean-generic distclean-libtool distclean-tags distdir dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man \
|
||||
install-nodist_includeHEADERS install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
|
||||
uninstall-am uninstall-nodist_includeHEADERS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
500
include/ffi-aarch64.h
Executable file
500
include/ffi-aarch64.h
Executable file
@ -0,0 +1,500 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi 3.2.9999 - Copyright (c) 2011, 2014 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Most of the API is documented in doc/libffi.texi.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing and
|
||||
unpacking on architectures for which it can be avoided. Routines
|
||||
are provided to emulate the raw API if the underlying platform
|
||||
doesn't allow faster implementation.
|
||||
|
||||
More details on the raw API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef AARCH64
|
||||
#define AARCH64
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
/* Need minimal decorations for DLLs to works on Windows. GCC has
|
||||
autoimport and autoexport. Rely on Libtool to help MSVC export
|
||||
from a DLL, but always declare data to be imported for MSVC
|
||||
clients. This costs an extra indirection for MSVC clients using
|
||||
the static version of the library, but don't worry about that.
|
||||
Besides, as a workaround, they can define FFI_BUILDING if they
|
||||
*know* they are going to link with the static library. */
|
||||
#if defined _WIN32 && !defined FFI_STATIC_BUILD
|
||||
#ifdef FFI_BUILDING
|
||||
#define FFI_EXTERN __declspec(dllexport)
|
||||
#else
|
||||
#define FFI_EXTERN __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define FFI_EXTERN extern
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t
|
||||
can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c. */
|
||||
FFI_EXTERN ffi_type ffi_type_void;
|
||||
FFI_EXTERN ffi_type ffi_type_uint8;
|
||||
FFI_EXTERN ffi_type ffi_type_sint8;
|
||||
FFI_EXTERN ffi_type ffi_type_uint16;
|
||||
FFI_EXTERN ffi_type ffi_type_sint16;
|
||||
FFI_EXTERN ffi_type ffi_type_uint32;
|
||||
FFI_EXTERN ffi_type ffi_type_sint32;
|
||||
FFI_EXTERN ffi_type ffi_type_uint64;
|
||||
FFI_EXTERN ffi_type ffi_type_sint64;
|
||||
FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#if 1
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
FFI_EXTERN ffi_type ffi_type_complex_float;
|
||||
FFI_EXTERN ffi_type ffi_type_complex_double;
|
||||
#if 1
|
||||
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
|
||||
#else
|
||||
#define ffi_type_complex_longdouble ffi_type_complex_double
|
||||
#endif
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
unsigned isVariadic;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
FFI_EXTERN void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
FFI_EXTERN void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
FFI_EXTERN size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter
|
||||
packing, even on 64-bit machines. I.e. on 64-bit machines longs
|
||||
and doubles are followed by an empty 64-bit word. */
|
||||
FFI_EXTERN
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
FFI_EXTERN void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
FFI_EXTERN void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
FFI_EXTERN size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
} ffi_closure
|
||||
#ifdef __GNUC__
|
||||
__attribute__((aligned (8)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifndef __GNUC__
|
||||
# ifdef __sgi
|
||||
# pragma pack 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FFI_EXTERN void *ffi_closure_alloc (size_t size, void **code);
|
||||
FFI_EXTERN void ffi_closure_free (void *);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
|
||||
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
__attribute__((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
#ifdef __sgi
|
||||
# pragma pack 8
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the translation, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
#if FFI_GO_CLOSURES
|
||||
|
||||
typedef struct {
|
||||
void *tramp;
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
} ffi_go_closure;
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*));
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure);
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
size_t *offsets);
|
||||
|
||||
/* Useful for eliminating compiler warnings. */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif /* !LIBFFI_ASM */
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if 1
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
#define FFI_TYPE_COMPLEX 15
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks). */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
500
include/ffi-arm.h
Executable file
500
include/ffi-arm.h
Executable file
@ -0,0 +1,500 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi 3.2.9999 - Copyright (c) 2011, 2014 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Most of the API is documented in doc/libffi.texi.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing and
|
||||
unpacking on architectures for which it can be avoided. Routines
|
||||
are provided to emulate the raw API if the underlying platform
|
||||
doesn't allow faster implementation.
|
||||
|
||||
More details on the raw API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef ARM
|
||||
#define ARM
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
/* Need minimal decorations for DLLs to works on Windows. GCC has
|
||||
autoimport and autoexport. Rely on Libtool to help MSVC export
|
||||
from a DLL, but always declare data to be imported for MSVC
|
||||
clients. This costs an extra indirection for MSVC clients using
|
||||
the static version of the library, but don't worry about that.
|
||||
Besides, as a workaround, they can define FFI_BUILDING if they
|
||||
*know* they are going to link with the static library. */
|
||||
#if defined _MSC_VER && !defined FFI_STATIC_BUILD
|
||||
#ifdef FFI_BUILDING
|
||||
#define FFI_EXTERN __declspec(dllexport)
|
||||
#else
|
||||
#define FFI_EXTERN __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define FFI_EXTERN extern
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t
|
||||
can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c. */
|
||||
FFI_EXTERN ffi_type ffi_type_void;
|
||||
FFI_EXTERN ffi_type ffi_type_uint8;
|
||||
FFI_EXTERN ffi_type ffi_type_sint8;
|
||||
FFI_EXTERN ffi_type ffi_type_uint16;
|
||||
FFI_EXTERN ffi_type ffi_type_sint16;
|
||||
FFI_EXTERN ffi_type ffi_type_uint32;
|
||||
FFI_EXTERN ffi_type ffi_type_sint32;
|
||||
FFI_EXTERN ffi_type ffi_type_uint64;
|
||||
FFI_EXTERN ffi_type ffi_type_sint64;
|
||||
FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#if 0
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
FFI_EXTERN ffi_type ffi_type_complex_float;
|
||||
FFI_EXTERN ffi_type ffi_type_complex_double;
|
||||
#if 0
|
||||
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
|
||||
#else
|
||||
#define ffi_type_complex_longdouble ffi_type_complex_double
|
||||
#endif
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
unsigned isVariadic;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
FFI_EXTERN void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
FFI_EXTERN void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
FFI_EXTERN size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter
|
||||
packing, even on 64-bit machines. I.e. on 64-bit machines longs
|
||||
and doubles are followed by an empty 64-bit word. */
|
||||
FFI_EXTERN
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
FFI_EXTERN void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
FFI_EXTERN void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
FFI_EXTERN size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
} ffi_closure
|
||||
#ifdef __GNUC__
|
||||
__attribute__((aligned (8)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifndef __GNUC__
|
||||
# ifdef __sgi
|
||||
# pragma pack 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FFI_EXTERN void *ffi_closure_alloc (size_t size, void **code);
|
||||
FFI_EXTERN void ffi_closure_free (void *);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
|
||||
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
__attribute__((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
#ifdef __sgi
|
||||
# pragma pack 8
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the translation, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_EXTERN ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
#if FFI_GO_CLOSURES
|
||||
|
||||
typedef struct {
|
||||
void *tramp;
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
} ffi_go_closure;
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*));
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure);
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_EXTERN
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
FFI_EXTERN
|
||||
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
size_t *offsets);
|
||||
|
||||
/* Useful for eliminating compiler warnings. */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif /* !LIBFFI_ASM */
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if 0
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
#define FFI_TYPE_COMPLEX 15
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks). */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
21
include/ffi.h
Executable file
21
include/ffi.h
Executable file
@ -0,0 +1,21 @@
|
||||
/* Include the correct ffi.h automatically. This helps us create prefixes
|
||||
* with multi-lib Linux and OSX/iOS universal builds. To avoid listing all
|
||||
* possible architectures here, we try the configured target arch first and then
|
||||
* include the most common multilib/universal setups in the #elif ladder */
|
||||
#ifdef __arm__
|
||||
#include "ffi-arm.h"
|
||||
#elif defined(__i386__) || defined(_M_IX86)
|
||||
#include "ffi-x86.h"
|
||||
#elif defined(__x86_64__) || defined(_M_X64)
|
||||
#include "ffi-x86_64.h"
|
||||
#elif defined(__arm__) || defined(_M_ARM)
|
||||
#include "ffi-arm.h"
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "ffi-aarch64.h"
|
||||
#elif defined(__powerpc__) || defined(_M_PPC)
|
||||
#include "ffi-powerpc.h"
|
||||
#elif defined(__powerpc64__)
|
||||
#include "ffi-powerpc64.h"
|
||||
#else
|
||||
#error "Unsupported Architecture"
|
||||
#endif
|
515
include/ffi.h.in
Normal file
515
include/ffi.h.in
Normal file
@ -0,0 +1,515 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi @VERSION@ - Copyright (c) 2011, 2014, 2019 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Most of the API is documented in doc/libffi.texi.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing and
|
||||
unpacking on architectures for which it can be avoided. Routines
|
||||
are provided to emulate the raw API if the underlying platform
|
||||
doesn't allow faster implementation.
|
||||
|
||||
More details on the raw API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef @TARGET@
|
||||
#define @TARGET@
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t
|
||||
can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
/* Need minimal decorations for DLLs to work on Windows. GCC has
|
||||
autoimport and autoexport. Always mark externally visible symbols
|
||||
as dllimport for MSVC clients, even if it means an extra indirection
|
||||
when using the static version of the library.
|
||||
Besides, as a workaround, they can define FFI_BUILDING if they
|
||||
*know* they are going to link with the static library. */
|
||||
#if defined _MSC_VER
|
||||
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
|
||||
# define FFI_API __declspec(dllexport)
|
||||
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
|
||||
# define FFI_API __declspec(dllimport)
|
||||
# else /* Building/linking static library */
|
||||
# define FFI_API
|
||||
# endif
|
||||
#else
|
||||
# define FFI_API
|
||||
#endif
|
||||
|
||||
/* The externally visible type declarations also need the MSVC DLL
|
||||
decorations, or they will not be exported from the object file. */
|
||||
#if defined LIBFFI_HIDE_BASIC_TYPES
|
||||
# define FFI_EXTERN FFI_API
|
||||
#else
|
||||
# define FFI_EXTERN extern FFI_API
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c. */
|
||||
FFI_EXTERN ffi_type ffi_type_void;
|
||||
FFI_EXTERN ffi_type ffi_type_uint8;
|
||||
FFI_EXTERN ffi_type ffi_type_sint8;
|
||||
FFI_EXTERN ffi_type ffi_type_uint16;
|
||||
FFI_EXTERN ffi_type ffi_type_sint16;
|
||||
FFI_EXTERN ffi_type ffi_type_uint32;
|
||||
FFI_EXTERN ffi_type ffi_type_sint32;
|
||||
FFI_EXTERN ffi_type ffi_type_uint64;
|
||||
FFI_EXTERN ffi_type ffi_type_sint64;
|
||||
FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
FFI_EXTERN ffi_type ffi_type_complex_float;
|
||||
FFI_EXTERN ffi_type ffi_type_complex_double;
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
|
||||
#else
|
||||
#define ffi_type_complex_longdouble ffi_type_complex_double
|
||||
#endif
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
|
||||
FFI_API
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
FFI_API size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter
|
||||
packing, even on 64-bit machines. I.e. on 64-bit machines longs
|
||||
and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
FFI_API
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue) __attribute__((deprecated));
|
||||
#endif
|
||||
|
||||
FFI_API
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
|
||||
FFI_API
|
||||
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
|
||||
FFI_API
|
||||
size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
#if @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
} ffi_closure
|
||||
#ifdef __GNUC__
|
||||
__attribute__((aligned (8)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifndef __GNUC__
|
||||
# ifdef __sgi
|
||||
# pragma pack 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FFI_API void *ffi_closure_alloc (size_t size, void **code);
|
||||
FFI_API void ffi_closure_free (void *);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
|
||||
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
__attribute__((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
#ifdef __sgi
|
||||
# pragma pack 8
|
||||
#endif
|
||||
typedef struct {
|
||||
#if @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
#if @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the translation, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
FFI_API ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data) __attribute__((deprecated));
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc) __attribute__((deprecated));
|
||||
#endif
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
#if FFI_GO_CLOSURES
|
||||
|
||||
typedef struct {
|
||||
void *tramp;
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
} ffi_go_closure;
|
||||
|
||||
FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*));
|
||||
|
||||
FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure);
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_API
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
size_t *offsets);
|
||||
|
||||
/* Useful for eliminating compiler warnings. */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
#define FFI_TYPE_COMPLEX 15
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks). */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
55
include/ffi_cfi.h
Normal file
55
include/ffi_cfi.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc.
|
||||
|
||||
Conditionally assemble cfi directives. Only necessary for building libffi.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef FFI_CFI_H
|
||||
#define FFI_CFI_H
|
||||
|
||||
#ifdef HAVE_AS_CFI_PSEUDO_OP
|
||||
|
||||
# define cfi_startproc .cfi_startproc
|
||||
# define cfi_endproc .cfi_endproc
|
||||
# define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
|
||||
# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
|
||||
# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
|
||||
# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
|
||||
# define cfi_offset(reg, off) .cfi_offset reg, off
|
||||
# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
|
||||
# define cfi_register(r1, r2) .cfi_register r1, r2
|
||||
# define cfi_return_column(reg) .cfi_return_column reg
|
||||
# define cfi_restore(reg) .cfi_restore reg
|
||||
# define cfi_same_value(reg) .cfi_same_value reg
|
||||
# define cfi_undefined(reg) .cfi_undefined reg
|
||||
# define cfi_remember_state .cfi_remember_state
|
||||
# define cfi_restore_state .cfi_restore_state
|
||||
# define cfi_window_save .cfi_window_save
|
||||
# define cfi_personality(enc, exp) .cfi_personality enc, exp
|
||||
# define cfi_lsda(enc, exp) .cfi_lsda enc, exp
|
||||
# define cfi_escape(...) .cfi_escape __VA_ARGS__
|
||||
|
||||
#else
|
||||
|
||||
# define cfi_startproc
|
||||
# define cfi_endproc
|
||||
# define cfi_def_cfa(reg, off)
|
||||
# define cfi_def_cfa_register(reg)
|
||||
# define cfi_def_cfa_offset(off)
|
||||
# define cfi_adjust_cfa_offset(off)
|
||||
# define cfi_offset(reg, off)
|
||||
# define cfi_rel_offset(reg, off)
|
||||
# define cfi_register(r1, r2)
|
||||
# define cfi_return_column(reg)
|
||||
# define cfi_restore(reg)
|
||||
# define cfi_same_value(reg)
|
||||
# define cfi_undefined(reg)
|
||||
# define cfi_remember_state
|
||||
# define cfi_restore_state
|
||||
# define cfi_window_save
|
||||
# define cfi_personality(enc, exp)
|
||||
# define cfi_lsda(enc, exp)
|
||||
# define cfi_escape(...)
|
||||
|
||||
#endif /* HAVE_AS_CFI_PSEUDO_OP */
|
||||
#endif /* FFI_CFI_H */
|
153
include/ffi_common.h
Normal file
153
include/ffi_common.h
Normal file
@ -0,0 +1,153 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green
|
||||
Copyright (C) 2007 Free Software Foundation, Inc
|
||||
Copyright (c) 1996 Red Hat, Inc.
|
||||
|
||||
Common internal definitions and macros. Only necessary for building
|
||||
libffi.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef FFI_COMMON_H
|
||||
#define FFI_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <fficonfig.h>
|
||||
|
||||
/* Do not move this. Some versions of AIX are very picky about where
|
||||
this is positioned. */
|
||||
#ifdef __GNUC__
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
/* mingw64 defines this already in malloc.h. */
|
||||
# ifndef alloca
|
||||
# define alloca __builtin_alloca
|
||||
# endif
|
||||
# endif
|
||||
# define MAYBE_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# ifdef _MSC_VER
|
||||
# define alloca _alloca
|
||||
# else
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Check for the existence of memcpy. */
|
||||
#if STDC_HEADERS
|
||||
# include <string.h>
|
||||
#else
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(FFI_DEBUG)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef FFI_DEBUG
|
||||
void ffi_assert(char *expr, char *file, int line);
|
||||
void ffi_stop_here(void);
|
||||
void ffi_type_test(ffi_type *a, char *file, int line);
|
||||
|
||||
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
|
||||
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
|
||||
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
|
||||
#else
|
||||
#define FFI_ASSERT(x)
|
||||
#define FFI_ASSERT_AT(x, f, l)
|
||||
#define FFI_ASSERT_VALID_TYPE(x)
|
||||
#endif
|
||||
|
||||
/* v cast to size_t and aligned up to a multiple of a */
|
||||
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
|
||||
/* v cast to size_t and aligned down to a multiple of a */
|
||||
#define FFI_ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
|
||||
ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
|
||||
unsigned int nfixedargs, unsigned int ntotalargs);
|
||||
|
||||
|
||||
#if HAVE_LONG_DOUBLE_VARIANT
|
||||
/* Used to adjust size/alignment of ffi types. */
|
||||
void ffi_prep_types (ffi_abi abi);
|
||||
#endif
|
||||
|
||||
/* Used internally, but overridden by some architectures */
|
||||
ffi_status ffi_prep_cif_core(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int isvariadic,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
/* Translate a data pointer to a code pointer. Needed for closures on
|
||||
some targets. */
|
||||
void *ffi_data_to_code_pointer (void *data) FFI_HIDDEN;
|
||||
|
||||
/* Extended cif, used in callback from assembly routine */
|
||||
typedef struct
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void *rvalue;
|
||||
void **avalue;
|
||||
} extended_cif;
|
||||
|
||||
/* Terse sized type definitions. */
|
||||
#if defined(_MSC_VER) || defined(__sgi) || defined(__SUNPRO_C)
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed char SINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed short SINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed int SINT32;
|
||||
# ifdef _MSC_VER
|
||||
typedef unsigned __int64 UINT64;
|
||||
typedef signed __int64 SINT64;
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
typedef uint64_t UINT64;
|
||||
typedef int64_t SINT64;
|
||||
# endif
|
||||
#else
|
||||
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
|
||||
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
|
||||
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
|
||||
typedef signed int SINT16 __attribute__((__mode__(__HI__)));
|
||||
typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
|
||||
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
|
||||
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
|
||||
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
|
||||
#endif
|
||||
|
||||
typedef float FLOAT32;
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __builtin_expect(x, expected_value) (x)
|
||||
#endif
|
||||
#define LIKELY(x) __builtin_expect(!!(x),1)
|
||||
#define UNLIKELY(x) __builtin_expect((x)!=0,0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
88
include/ffitarget-aarch64.h
Executable file
88
include/ffitarget-aarch64.h
Executable file
@ -0,0 +1,88 @@
|
||||
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
#ifdef __ILP32__
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
#define FFI_SIZEOF_JAVA_RAW 4
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#elif defined(_M_ARM64)
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#else
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
#endif
|
||||
|
||||
typedef enum ffi_abi
|
||||
{
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_LAST_ABI,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
|
||||
#else
|
||||
#error "No trampoline table implementation"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
/* ---- Internal ---- */
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
|
||||
#elif !defined(_M_ARM64)
|
||||
/* iOS and Windows reserve x18 for the system. Disable Go closures until
|
||||
a new static chain is chosen. */
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#endif
|
||||
|
||||
#ifndef _M_ARM64
|
||||
/* No complex type on Windows */
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
#endif
|
||||
|
||||
#endif
|
82
include/ffitarget-arm.h
Executable file
82
include/ffitarget-arm.h
Executable file
@ -0,0 +1,82 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 2010 CodeSourcery
|
||||
Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
|
||||
Target configuration macros for ARM.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_VFP,
|
||||
FFI_LAST_ABI,
|
||||
#ifdef __ARM_PCS_VFP
|
||||
FFI_DEFAULT_ABI = FFI_VFP,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#endif
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS \
|
||||
int vfp_used; \
|
||||
unsigned short vfp_reg_free, vfp_nargs; \
|
||||
signed char vfp_args[16] \
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
|
||||
#else
|
||||
#error "No trampoline table implementation"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
#endif
|
21
include/ffitarget.h
Executable file
21
include/ffitarget.h
Executable file
@ -0,0 +1,21 @@
|
||||
/* Include the correct ffitarget.h automatically. This helps us create prefixes
|
||||
* with multi-lib Linux and OSX/iOS universal builds. To avoid listing all
|
||||
* possible architectures here, we try the configured target arch first and then
|
||||
* include the most common multilib/universal setups in the #elif ladder */
|
||||
#ifdef __arm__
|
||||
#include "ffitarget-arm.h"
|
||||
#elif defined(__i386__) || defined(_M_IX86)
|
||||
#include "ffitarget-x86.h"
|
||||
#elif defined(__x86_64__) || defined(_M_X64)
|
||||
#include "ffitarget-x86_64.h"
|
||||
#elif defined(__arm__) || defined(_M_ARM)
|
||||
#include "ffitarget-arm.h"
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#include "ffitarget-aarch64.h"
|
||||
#elif defined(__powerpc__) || defined(_M_PPC)
|
||||
#include "ffitarget-powerpc.h"
|
||||
#elif defined(__powerpc64__)
|
||||
#include "ffitarget-powerpc64.h"
|
||||
#else
|
||||
#error "Unsupported Architecture"
|
||||
#endif
|
518
install-sh
Executable file
518
install-sh
Executable file
@ -0,0 +1,518 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2018-03-11.20; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dstbase=`basename "$src"`
|
||||
case $dst in
|
||||
*/) dst=$dst$dstbase;;
|
||||
*) dst=$dst/$dstbase;;
|
||||
esac
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
case $dstdir in
|
||||
*/) dstdirslash=$dstdir;;
|
||||
*) dstdirslash=$dstdir/;;
|
||||
esac
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p' feature.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=${dstdirslash}_inst.$$_
|
||||
rmtmp=${dstdirslash}_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
80
libffi.map.in
Normal file
80
libffi.map.in
Normal file
@ -0,0 +1,80 @@
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_H
|
||||
#include <fficonfig.h>
|
||||
#include <ffitarget.h>
|
||||
|
||||
/* These version numbers correspond to the libtool-version abi numbers,
|
||||
not to the libffi release numbers. */
|
||||
|
||||
LIBFFI_BASE_7.0 {
|
||||
global:
|
||||
/* Exported data variables. */
|
||||
ffi_type_void;
|
||||
ffi_type_uint8;
|
||||
ffi_type_sint8;
|
||||
ffi_type_uint16;
|
||||
ffi_type_sint16;
|
||||
ffi_type_uint32;
|
||||
ffi_type_sint32;
|
||||
ffi_type_uint64;
|
||||
ffi_type_sint64;
|
||||
ffi_type_float;
|
||||
ffi_type_double;
|
||||
ffi_type_longdouble;
|
||||
ffi_type_pointer;
|
||||
|
||||
/* Exported functions. */
|
||||
ffi_call;
|
||||
ffi_prep_cif;
|
||||
ffi_prep_cif_var;
|
||||
|
||||
ffi_raw_call;
|
||||
ffi_ptrarray_to_raw;
|
||||
ffi_raw_to_ptrarray;
|
||||
ffi_raw_size;
|
||||
|
||||
ffi_java_raw_call;
|
||||
ffi_java_ptrarray_to_raw;
|
||||
ffi_java_raw_to_ptrarray;
|
||||
ffi_java_raw_size;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
LIBFFI_BASE_7.1 {
|
||||
global:
|
||||
ffi_get_struct_offsets;
|
||||
} LIBFFI_BASE_7.0;
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
LIBFFI_COMPLEX_7.0 {
|
||||
global:
|
||||
/* Exported data variables. */
|
||||
ffi_type_complex_float;
|
||||
ffi_type_complex_double;
|
||||
ffi_type_complex_longdouble;
|
||||
} LIBFFI_BASE_7.0;
|
||||
#endif
|
||||
|
||||
#if FFI_CLOSURES
|
||||
LIBFFI_CLOSURE_7.0 {
|
||||
global:
|
||||
ffi_closure_alloc;
|
||||
ffi_closure_free;
|
||||
ffi_prep_closure;
|
||||
ffi_prep_closure_loc;
|
||||
ffi_prep_raw_closure;
|
||||
ffi_prep_raw_closure_loc;
|
||||
ffi_prep_java_raw_closure;
|
||||
ffi_prep_java_raw_closure_loc;
|
||||
} LIBFFI_BASE_7.0;
|
||||
#endif
|
||||
|
||||
#if FFI_GO_CLOSURES
|
||||
LIBFFI_GO_CLOSURE_7.0 {
|
||||
global:
|
||||
ffi_call_go;
|
||||
ffi_prep_go_closure;
|
||||
} LIBFFI_CLOSURE_7.0;
|
||||
#endif
|
11
libffi.pc.in
Normal file
11
libffi.pc.in
Normal file
@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
toolexeclibdir=@toolexeclibdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: @PACKAGE_NAME@
|
||||
Description: Library supporting Foreign Function Interfaces
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${toolexeclibdir} -lffi
|
||||
Cflags: -I${includedir}
|
1043
libffi.xcodeproj/project.pbxproj
Normal file
1043
libffi.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
106
libtool-ldflags
Executable file
106
libtool-ldflags
Executable file
@ -0,0 +1,106 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Script to translate LDFLAGS into a form suitable for use with libtool.
|
||||
|
||||
# Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
|
||||
# Contributed by CodeSourcery, LLC.
|
||||
|
||||
# This script is designed to be used from a Makefile that uses libtool
|
||||
# to build libraries as follows:
|
||||
#
|
||||
# LTLDFLAGS = $(shell libtool-ldflags $(LDFLAGS))
|
||||
#
|
||||
# Then, use (LTLDFLAGS) in place of $(LDFLAGS) in your link line.
|
||||
|
||||
# The output of the script. This string is built up as we process the
|
||||
# arguments.
|
||||
result=
|
||||
prev_arg=
|
||||
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-f*|--*)
|
||||
# Libtool does not ascribe any special meaning options
|
||||
# that begin with -f or with a double-dash. So, it will
|
||||
# think these options are linker options, and prefix them
|
||||
# with "-Wl,". Then, the compiler driver will ignore the
|
||||
# options. So, we prefix these options with -Xcompiler to
|
||||
# make clear to libtool that they are in fact compiler
|
||||
# options.
|
||||
case $prev_arg in
|
||||
-Xpreprocessor|-Xcompiler|-Xlinker)
|
||||
# This option is already prefixed; don't prefix it again.
|
||||
;;
|
||||
*)
|
||||
result="$result -Xcompiler"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# We do not want to add -Xcompiler to other options because
|
||||
# that would prevent libtool itself from recognizing them.
|
||||
;;
|
||||
esac
|
||||
prev_arg=$arg
|
||||
|
||||
# If $(LDFLAGS) is (say):
|
||||
# a "b'c d" e
|
||||
# then the user expects that:
|
||||
# $(LD) $(LDFLAGS)
|
||||
# will pass three arguments to $(LD):
|
||||
# 1) a
|
||||
# 2) b'c d
|
||||
# 3) e
|
||||
# We must ensure, therefore, that the arguments are appropriately
|
||||
# quoted so that using:
|
||||
# libtool --mode=link ... $(LTLDFLAGS)
|
||||
# will result in the same number of arguments being passed to
|
||||
# libtool. In other words, when this script was invoked, the shell
|
||||
# removed one level of quoting, present in $(LDFLAGS); we have to put
|
||||
# it back.
|
||||
|
||||
# Quote any embedded single quotes.
|
||||
case $arg in
|
||||
*"'"*)
|
||||
# The following command creates the script:
|
||||
# 1s,^X,,;s|'|'"'"'|g
|
||||
# which removes a leading X, and then quotes and embedded single
|
||||
# quotes.
|
||||
sed_script="1s,^X,,;s|'|'\"'\"'|g"
|
||||
# Add a leading "X" so that if $arg starts with a dash,
|
||||
# the echo command will not try to interpret the argument
|
||||
# as a command-line option.
|
||||
arg="X$arg"
|
||||
# Generate the quoted string.
|
||||
quoted_arg=`echo "$arg" | sed -e "$sed_script"`
|
||||
;;
|
||||
*)
|
||||
quoted_arg=$arg
|
||||
;;
|
||||
esac
|
||||
# Surround the entire argument with single quotes.
|
||||
quoted_arg="'"$quoted_arg"'"
|
||||
|
||||
# Add it to the string.
|
||||
result="$result $quoted_arg"
|
||||
done
|
||||
|
||||
# Output the string we have built up.
|
||||
echo "$result"
|
29
libtool-version
Normal file
29
libtool-version
Normal file
@ -0,0 +1,29 @@
|
||||
# This file is used to maintain libtool version info for libffi. See
|
||||
# the libtool manual to understand the meaning of the fields. This is
|
||||
# a separate file so that version updates don't involve re-running
|
||||
# automake.
|
||||
#
|
||||
# Here are a set of rules to help you update your library version
|
||||
# information:
|
||||
#
|
||||
# 1. Start with version information of `0:0:0' for each libtool library.
|
||||
#
|
||||
# 2. Update the version information only immediately before a public
|
||||
# release of your software. More frequent updates are unnecessary,
|
||||
# and only guarantee that the current interface number gets larger
|
||||
# faster.
|
||||
#
|
||||
# 3. If the library source code has changed at all since the last
|
||||
# update, then increment revision (`c:r:a' becomes `c:r+1:a').
|
||||
#
|
||||
# 4. If any interfaces have been added, removed, or changed since the
|
||||
# last update, increment current, and set revision to 0.
|
||||
#
|
||||
# 5. If any interfaces have been added since the last public release,
|
||||
# then increment age.
|
||||
#
|
||||
# 6. If any interfaces have been removed since the last public
|
||||
# release, then set age to 0.
|
||||
#
|
||||
# CURRENT:REVISION:AGE
|
||||
8:0:1
|
13
m4/asmcfi.m4
Normal file
13
m4/asmcfi.m4
Normal file
@ -0,0 +1,13 @@
|
||||
AC_DEFUN([GCC_AS_CFI_PSEUDO_OP],
|
||||
[AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
gcc_cv_as_cfi_pseudo_op, [
|
||||
gcc_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],,
|
||||
[gcc_cv_as_cfi_pseudo_op=yes],
|
||||
[gcc_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
|
||||
[Define if your assembler supports .cfi_* directives.])
|
||||
fi
|
||||
])
|
50
m4/ax_append_flag.m4
Normal file
50
m4/ax_append_flag.m4
Normal file
@ -0,0 +1,50 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
|
||||
# added in between.
|
||||
#
|
||||
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
|
||||
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
|
||||
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
|
||||
# FLAG.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 8
|
||||
|
||||
AC_DEFUN([AX_APPEND_FLAG],
|
||||
[dnl
|
||||
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
|
||||
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
|
||||
AS_VAR_SET_IF(FLAGS,[
|
||||
AS_CASE([" AS_VAR_GET(FLAGS) "],
|
||||
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
|
||||
[
|
||||
AS_VAR_APPEND(FLAGS,[" $1"])
|
||||
AC_RUN_LOG([: FLAGS="$FLAGS"])
|
||||
])
|
||||
],
|
||||
[
|
||||
AS_VAR_SET(FLAGS,[$1])
|
||||
AC_RUN_LOG([: FLAGS="$FLAGS"])
|
||||
])
|
||||
AS_VAR_POPDEF([FLAGS])dnl
|
||||
])dnl AX_APPEND_FLAG
|
194
m4/ax_cc_maxopt.m4
Normal file
194
m4/ax_cc_maxopt.m4
Normal file
@ -0,0 +1,194 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CC_MAXOPT
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Try to turn on "good" C optimization flags for various compilers and
|
||||
# architectures, for some definition of "good". (In our case, good for
|
||||
# FFTW and hopefully for other scientific codes. Modify as needed.)
|
||||
#
|
||||
# The user can override the flags by setting the CFLAGS environment
|
||||
# variable. The user can also specify --enable-portable-binary in order to
|
||||
# disable any optimization flags that might result in a binary that only
|
||||
# runs on the host architecture.
|
||||
#
|
||||
# Note also that the flags assume that ANSI C aliasing rules are followed
|
||||
# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point
|
||||
# computations can be re-ordered as needed.
|
||||
#
|
||||
# Requires macros: AX_CHECK_COMPILE_FLAG, AX_COMPILER_VENDOR,
|
||||
# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2008 Matteo Frigo
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 17
|
||||
|
||||
AC_DEFUN([AX_CC_MAXOPT],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AX_COMPILER_VENDOR])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
|
||||
AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
|
||||
acx_maxopt_portable=$enableval, acx_maxopt_portable=no)
|
||||
|
||||
# Try to determine "good" native compiler flags if none specified via CFLAGS
|
||||
if test "$ac_test_CFLAGS" != "set"; then
|
||||
CFLAGS=""
|
||||
case $ax_cv_c_compiler_vendor in
|
||||
dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
|
||||
if test "x$acx_maxopt_portable" = xno; then
|
||||
CFLAGS="$CFLAGS -arch host"
|
||||
fi;;
|
||||
|
||||
sun) CFLAGS="-native -fast -xO5 -dalign"
|
||||
if test "x$acx_maxopt_portable" = xyes; then
|
||||
CFLAGS="$CFLAGS -xarch=generic"
|
||||
fi;;
|
||||
|
||||
hp) CFLAGS="+Oall +Optrs_ansi +DSnative"
|
||||
if test "x$acx_maxopt_portable" = xyes; then
|
||||
CFLAGS="$CFLAGS +DAportable"
|
||||
fi;;
|
||||
|
||||
ibm) if test "x$acx_maxopt_portable" = xno; then
|
||||
xlc_opt="-qarch=auto -qtune=auto"
|
||||
else
|
||||
xlc_opt="-qtune=auto"
|
||||
fi
|
||||
AX_CHECK_COMPILE_FLAG($xlc_opt,
|
||||
CFLAGS="-O3 -qansialias -w $xlc_opt",
|
||||
[CFLAGS="-O3 -qansialias -w"
|
||||
echo "******************************************************"
|
||||
echo "* You seem to have the IBM C compiler. It is *"
|
||||
echo "* recommended for best performance that you use: *"
|
||||
echo "* *"
|
||||
echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
|
||||
echo "* ^^^ ^^^ *"
|
||||
echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *"
|
||||
echo "* CPU you have. (Set the CFLAGS environment var. *"
|
||||
echo "* and re-run configure.) For more info, man cc. *"
|
||||
echo "******************************************************"])
|
||||
;;
|
||||
|
||||
intel) CFLAGS="-O3 -ansi_alias"
|
||||
if test "x$acx_maxopt_portable" = xno; then
|
||||
icc_archflag=unknown
|
||||
icc_flags=""
|
||||
case $host_cpu in
|
||||
i686*|x86_64*)
|
||||
# icc accepts gcc assembly syntax, so these should work:
|
||||
AX_GCC_X86_CPUID(0)
|
||||
AX_GCC_X86_CPUID(1)
|
||||
case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
|
||||
*:756e6547:6c65746e:49656e69) # Intel
|
||||
case $ax_cv_gcc_x86_cpuid_1 in
|
||||
*0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) icc_flags="-xK" ;;
|
||||
*0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;;
|
||||
*0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;;
|
||||
*0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;;
|
||||
*1?6[[7d]]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;;
|
||||
*1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;;
|
||||
*2?6[[ad]]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;;
|
||||
*3?6[[ae]]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
|
||||
*3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;
|
||||
*000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;;
|
||||
*00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;;
|
||||
esac ;;
|
||||
esac ;;
|
||||
esac
|
||||
if test "x$icc_flags" != x; then
|
||||
for flag in $icc_flags; do
|
||||
AX_CHECK_COMPILE_FLAG($flag, [icc_archflag=$flag; break])
|
||||
done
|
||||
fi
|
||||
AC_MSG_CHECKING([for icc architecture flag])
|
||||
AC_MSG_RESULT($icc_archflag)
|
||||
if test "x$icc_archflag" != xunknown; then
|
||||
CFLAGS="$CFLAGS $icc_archflag"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
gnu)
|
||||
# default optimization flags for gcc on all systems
|
||||
CFLAGS="-O3 -fomit-frame-pointer"
|
||||
|
||||
# -malign-double for x86 systems
|
||||
# libffi local change -- don't align double, as it changes the ABI
|
||||
# AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double")
|
||||
|
||||
# -fstrict-aliasing for gcc-2.95+
|
||||
AX_CHECK_COMPILE_FLAG(-fstrict-aliasing,
|
||||
CFLAGS="$CFLAGS -fstrict-aliasing")
|
||||
|
||||
# note that we enable "unsafe" fp optimization with other compilers, too
|
||||
AX_CHECK_COMPILE_FLAG(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
|
||||
|
||||
AX_GCC_ARCHFLAG($acx_maxopt_portable)
|
||||
;;
|
||||
|
||||
microsoft)
|
||||
# default optimization flags for MSVC opt builds
|
||||
CFLAGS="-O2"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$CFLAGS"; then
|
||||
echo ""
|
||||
echo "********************************************************"
|
||||
echo "* WARNING: Don't know the best CFLAGS for this system *"
|
||||
echo "* Use ./configure CFLAGS=... to specify your own flags *"
|
||||
echo "* (otherwise, a default of CFLAGS=-O3 will be used) *"
|
||||
echo "********************************************************"
|
||||
echo ""
|
||||
CFLAGS="-O3"
|
||||
fi
|
||||
|
||||
AX_CHECK_COMPILE_FLAG($CFLAGS, [], [
|
||||
echo ""
|
||||
echo "********************************************************"
|
||||
echo "* WARNING: The guessed CFLAGS don't seem to work with *"
|
||||
echo "* your compiler. *"
|
||||
echo "* Use ./configure CFLAGS=... to specify your own flags *"
|
||||
echo "********************************************************"
|
||||
echo ""
|
||||
CFLAGS=""
|
||||
])
|
||||
|
||||
fi
|
||||
])
|
122
m4/ax_cflags_warn_all.m4
Normal file
122
m4/ax_cflags_warn_all.m4
Normal file
@ -0,0 +1,122 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||
# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||
# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Try to find a compiler option that enables most reasonable warnings.
|
||||
#
|
||||
# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
|
||||
# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
|
||||
#
|
||||
# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
|
||||
# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
|
||||
# Intel compilers. For a given compiler, the Fortran flags are much more
|
||||
# experimental than their C equivalents.
|
||||
#
|
||||
# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
|
||||
# - $2 add-value-if-not-found : nothing
|
||||
# - $3 action-if-found : add value to shellvariable
|
||||
# - $4 action-if-not-found : nothing
|
||||
#
|
||||
# NOTE: These macros depend on AX_APPEND_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 16
|
||||
|
||||
AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
|
||||
AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
|
||||
AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
|
||||
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
|
||||
VAR,[VAR="no, unknown"
|
||||
ac_save_[]FLAGS="$[]FLAGS"
|
||||
for ac_arg dnl
|
||||
in "-warn all % -warn all" dnl Intel
|
||||
"-pedantic % -Wall" dnl GCC
|
||||
"-xstrconst % -v" dnl Solaris C
|
||||
"-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
|
||||
"-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
|
||||
"-ansi -ansiE % -fullwarn" dnl IRIX
|
||||
"+ESlit % +w1" dnl HP-UX C
|
||||
"-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
|
||||
"-h conform % -h msglevel 2" dnl Cray C (Unicos)
|
||||
#
|
||||
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
|
||||
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
|
||||
done
|
||||
FLAGS="$ac_save_[]FLAGS"
|
||||
])
|
||||
AS_VAR_POPDEF([FLAGS])dnl
|
||||
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
|
||||
case ".$VAR" in
|
||||
.ok|.ok,*) m4_ifvaln($3,$3) ;;
|
||||
.|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
|
||||
*) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
|
||||
esac
|
||||
AS_VAR_POPDEF([VAR])dnl
|
||||
])dnl AX_FLAGS_WARN_ALL
|
||||
dnl implementation tactics:
|
||||
dnl the for-argument contains a list of options. The first part of
|
||||
dnl these does only exist to detect the compiler - usually it is
|
||||
dnl a global option to enable -ansi or -extrawarnings. All other
|
||||
dnl compilers will fail about it. That was needed since a lot of
|
||||
dnl compilers will give false positives for some option-syntax
|
||||
dnl like -Woption or -Xoption as they think of it is a pass-through
|
||||
dnl to later compile stages or something. The "%" is used as a
|
||||
dnl delimiter. A non-option comment can be given after "%%" marks
|
||||
dnl which will be shown but not added to the respective C/CXXFLAGS.
|
||||
|
||||
AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
|
||||
AC_LANG_PUSH([C])
|
||||
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||
AC_LANG_POP([C])
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
|
||||
AC_LANG_PUSH([C++])
|
||||
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
|
||||
AC_LANG_PUSH([Fortran])
|
||||
AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
|
||||
AC_LANG_POP([Fortran])
|
||||
])
|
53
m4/ax_check_compile_flag.m4
Normal file
53
m4/ax_check_compile_flag.m4
Normal file
@ -0,0 +1,53 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 6
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_VAR_IF(CACHEVAR,yes,
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
88
m4/ax_compiler_vendor.m4
Normal file
88
m4/ax_compiler_vendor.m4
Normal file
@ -0,0 +1,88 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_COMPILER_VENDOR
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
|
||||
# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
|
||||
# watcom, etc. The vendor is returned in the cache variable
|
||||
# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2008 Matteo Frigo
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 17
|
||||
|
||||
AC_DEFUN([AX_COMPILER_VENDOR],
|
||||
[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
|
||||
dnl Please add if possible support to ax_compiler_version.m4
|
||||
[# note: don't check for gcc first since some other compilers define __GNUC__
|
||||
vendors="intel: __ICC,__ECC,__INTEL_COMPILER
|
||||
ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__
|
||||
pathscale: __PATHCC__,__PATHSCALE__
|
||||
clang: __clang__
|
||||
cray: _CRAYC
|
||||
fujitsu: __FUJITSU
|
||||
sdcc: SDCC, __SDCC
|
||||
gnu: __GNUC__
|
||||
sun: __SUNPRO_C,__SUNPRO_CC
|
||||
hp: __HP_cc,__HP_aCC
|
||||
dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
|
||||
borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
|
||||
comeau: __COMO__
|
||||
kai: __KCC
|
||||
lcc: __LCC__
|
||||
sgi: __sgi,sgi
|
||||
microsoft: _MSC_VER
|
||||
metrowerks: __MWERKS__
|
||||
watcom: __WATCOMC__
|
||||
portland: __PGI
|
||||
tcc: __TINYC__
|
||||
unknown: UNKNOWN"
|
||||
for ventest in $vendors; do
|
||||
case $ventest in
|
||||
*:) vendor=$ventest; continue ;;
|
||||
*) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;;
|
||||
esac
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
|
||||
#if !($vencpp)
|
||||
thisisanerror;
|
||||
#endif
|
||||
])], [break])
|
||||
done
|
||||
ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
|
||||
])
|
||||
])
|
49
m4/ax_configure_args.m4
Normal file
49
m4/ax_configure_args.m4
Normal file
@ -0,0 +1,49 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_configure_args.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CONFIGURE_ARGS
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Helper macro for AX_ENABLE_BUILDDIR.
|
||||
#
|
||||
# The traditional way of starting a subdir-configure is running the script
|
||||
# with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have
|
||||
# to rely on eval'ing $ac_configure_args however some old autoconf
|
||||
# versions do not provide that. To ensure maximum portability of autoconf
|
||||
# extension macros this helper can be AC_REQUIRE'd so that
|
||||
# $ac_configure_args will always be present.
|
||||
#
|
||||
# Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
|
||||
# spoiled now and must be replaced by "eval + exit $?".
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# AC_DEFUN([AX_ENABLE_SUBDIR],[dnl
|
||||
# AC_REQUIRE([AX_CONFIGURE_ARGS])dnl
|
||||
# eval $SHELL $ac_configure_args || exit $?
|
||||
# ...])
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 14
|
||||
|
||||
AC_DEFUN([AX_CONFIGURE_ARGS],[
|
||||
# [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args
|
||||
if test "${ac_configure_args+set}" != "set" ; then
|
||||
ac_configure_args=
|
||||
for ac_arg in ${1+"[$]@"}; do
|
||||
ac_configure_args="$ac_configure_args '$ac_arg'"
|
||||
done
|
||||
fi
|
||||
])
|
302
m4/ax_enable_builddir.m4
Normal file
302
m4/ax_enable_builddir.m4
Normal file
@ -0,0 +1,302 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])]
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# If the current configure was run within the srcdir then we move all
|
||||
# configure-files into a subdir and let the configure steps continue
|
||||
# there. We provide an option --disable-builddir to suppress the move into
|
||||
# a separate builddir.
|
||||
#
|
||||
# Defaults:
|
||||
#
|
||||
# $1 = $host (overridden with $HOST)
|
||||
# $2 = Makefile.mk
|
||||
# $3 = -all
|
||||
#
|
||||
# This macro must be called before AM_INIT_AUTOMAKE. It creates a default
|
||||
# toplevel srcdir Makefile from the information found in the created
|
||||
# toplevel builddir Makefile. It just copies the variables and
|
||||
# rule-targets, each extended with a default rule-execution that recurses
|
||||
# into the build directory of the current "HOST". You can override the
|
||||
# auto-detection through `config.guess` and build-time of course, as in
|
||||
#
|
||||
# make HOST=i386-mingw-cross
|
||||
#
|
||||
# which can of course set at configure time as well using
|
||||
#
|
||||
# configure --host=i386-mingw-cross
|
||||
#
|
||||
# After the default has been created, additional rules can be appended
|
||||
# that will not just recurse into the subdirectories and only ever exist
|
||||
# in the srcdir toplevel makefile - these parts are read from the $2 =
|
||||
# Makefile.mk file
|
||||
#
|
||||
# The automatic rules are usually scanning the toplevel Makefile for lines
|
||||
# like '#### $host |$builddir' to recognize the place where to recurse
|
||||
# into. Usually, the last one is the only one used. However, almost all
|
||||
# targets have an additional "*-all" rule which makes the script to
|
||||
# recurse into _all_ variants of the current HOST (!!) setting. The "-all"
|
||||
# suffix can be overridden for the macro as well.
|
||||
#
|
||||
# a special rule is only given for things like "dist" that will copy the
|
||||
# tarball from the builddir to the sourcedir (or $(PUB)) for reason of
|
||||
# convenience.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 30
|
||||
|
||||
AC_DEFUN([AX_ENABLE_BUILDDIR],[
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])[]dnl
|
||||
AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl
|
||||
AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl
|
||||
AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl
|
||||
AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
|
||||
AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
|
||||
AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
|
||||
AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
|
||||
SUB="."
|
||||
AC_ARG_ENABLE([builddir], AS_HELP_STRING(
|
||||
[--disable-builddir],[disable automatic build in subdir of sources])
|
||||
,[SUB="$enableval"], [SUB="auto"])
|
||||
if test ".$ac_srcdir_defaulted" != ".no" ; then
|
||||
if test ".$srcdir" = ".." ; then
|
||||
if test -f config.status ; then
|
||||
AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build)
|
||||
else
|
||||
test ".$SUB" = "." && SUB="."
|
||||
test ".$SUB" = ".no" && SUB="."
|
||||
test ".$TARGET" = "." && TARGET="$target"
|
||||
test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])"
|
||||
if test ".$SUB" != ".." ; then # we know where to go and
|
||||
AS_MKDIR_P([$SUB])
|
||||
echo __.$SUB.__ > $SUB/conftest.tmp
|
||||
cd $SUB
|
||||
if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then
|
||||
rm conftest.tmp
|
||||
AC_MSG_RESULT([continue configure in default builddir "./$SUB"])
|
||||
else
|
||||
AC_MSG_ERROR([could not change to default builddir "./$SUB"])
|
||||
fi
|
||||
srcdir=`echo "$SUB" |
|
||||
sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'`
|
||||
# going to restart from subdirectory location
|
||||
test -f $srcdir/config.log && mv $srcdir/config.log .
|
||||
test -f $srcdir/confdefs.h && mv $srcdir/confdefs.h .
|
||||
test -f $srcdir/conftest.log && mv $srcdir/conftest.log .
|
||||
test -f $srcdir/$cache_file && mv $srcdir/$cache_file .
|
||||
AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})
|
||||
case "[$]0" in # restart
|
||||
[[\\/]]* | ?:[[\\/]]*) # Absolute name
|
||||
eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
|
||||
*) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
|
||||
esac ; exit $?
|
||||
fi
|
||||
fi
|
||||
fi fi
|
||||
test ".$SUB" = ".auto" && SUB="."
|
||||
dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"
|
||||
AC_PATH_PROG(SED,gsed sed, sed)
|
||||
AUX="$am_aux_dir"
|
||||
AS_VAR_POPDEF([SED])dnl
|
||||
AS_VAR_POPDEF([AUX])dnl
|
||||
AS_VAR_POPDEF([SUB])dnl
|
||||
AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status ..............
|
||||
AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
|
||||
AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl
|
||||
AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl
|
||||
AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
|
||||
AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
|
||||
pushdef([END],[Makefile.mk])dnl
|
||||
pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl
|
||||
SRC="$ax_enable_builddir_srcdir"
|
||||
if test ".$SUB" = ".." ; then
|
||||
if test -f "$TOP/Makefile" ; then
|
||||
AC_MSG_NOTICE([skipping TOP/Makefile - left untouched])
|
||||
else
|
||||
AC_MSG_NOTICE([skipping TOP/Makefile - not created])
|
||||
fi
|
||||
else
|
||||
if test -f "$SRC/Makefile" ; then
|
||||
a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile`
|
||||
test "$a" != "$b" && rm "$SRC/Makefile"
|
||||
fi
|
||||
if test -f "$SRC/Makefile" ; then
|
||||
echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk
|
||||
echo " []@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk
|
||||
eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"
|
||||
if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null
|
||||
then rm $SRC/Makefile ; fi
|
||||
cp $tmp/conftemp.mk $SRC/makefiles.mk~ ## DEBUGGING
|
||||
fi
|
||||
if test ! -f "$SRC/Makefile" ; then
|
||||
AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile])
|
||||
x='`' ; cat >$tmp/conftemp.sed <<_EOF
|
||||
/^\$/n
|
||||
x
|
||||
/^\$/bS
|
||||
x
|
||||
/\\\\\$/{H;d;}
|
||||
{H;s/.*//;x;}
|
||||
bM
|
||||
:S
|
||||
x
|
||||
/\\\\\$/{h;d;}
|
||||
{h;s/.*//;x;}
|
||||
:M
|
||||
s/\\(\\n\\) /\\1 /g
|
||||
/^ /d
|
||||
/^[[ ]]*[[\\#]]/d
|
||||
/^VPATH *=/d
|
||||
s/^srcdir *=.*/srcdir = ./
|
||||
s/^top_srcdir *=.*/top_srcdir = ./
|
||||
/[[:=]]/!d
|
||||
/^\\./d
|
||||
dnl Now handle rules (i.e. lines containing ":" but not " = ").
|
||||
/ = /b
|
||||
/ .= /b
|
||||
/:/!b
|
||||
s/:.*/:/
|
||||
s/ / /g
|
||||
s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g
|
||||
s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/
|
||||
s/ / /g
|
||||
/^all all[]_ALL[[ :]]/i\\
|
||||
all-configured : all[]_ALL
|
||||
dnl dist-all exists... and would make for dist-all-all
|
||||
s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g
|
||||
/[]_ALL[]_ALL/d
|
||||
a\\
|
||||
@ HOST="\$(HOST)\" \\\\\\
|
||||
; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
|
||||
; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
|
||||
; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
|
||||
; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\
|
||||
; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\
|
||||
; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
|
||||
; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\
|
||||
; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
|
||||
; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done
|
||||
dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree)
|
||||
/dist[]_ALL *:/a\\
|
||||
@ HOST="\$(HOST)\" \\\\\\
|
||||
; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
|
||||
; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
|
||||
; found=$x echo \$\$BUILD | wc -w $x \\\\\\
|
||||
; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\
|
||||
; if test "\$\$found" -eq "0" ; then : \\\\\\
|
||||
; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
|
||||
; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
|
||||
; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\
|
||||
; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
|
||||
dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree)
|
||||
/dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\
|
||||
@ HOST="\$(HOST)\" \\\\\\
|
||||
; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\
|
||||
; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
|
||||
; found=$x echo \$\$BUILD | wc -w $x \\\\\\
|
||||
; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\
|
||||
; if test "\$\$found" -eq "0" ; then : \\\\\\
|
||||
; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
|
||||
; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
|
||||
; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\
|
||||
; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
|
||||
dnl special rule add-on: "distclean" removes all local builddirs completely
|
||||
/distclean[]_ALL *:/a\\
|
||||
@ HOST="\$(HOST)\" \\\\\\
|
||||
; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
|
||||
; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\
|
||||
; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
|
||||
; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\
|
||||
; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
|
||||
; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
|
||||
; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\
|
||||
; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
|
||||
; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\
|
||||
; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\
|
||||
; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile
|
||||
_EOF
|
||||
cp "$tmp/conftemp.sed" "$SRC/makefile.sed~" ## DEBUGGING
|
||||
$SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile
|
||||
if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then
|
||||
AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])])
|
||||
cat $SRC/END >>$SRC/Makefile
|
||||
fi ; xxxx="####"
|
||||
echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile
|
||||
# sanity check
|
||||
if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then
|
||||
AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts])
|
||||
$SED -e '/^@ HOST=/s/^/ /' -e '/^; /s/^/ /' $SRC/Makefile \
|
||||
>$SRC/Makefile~
|
||||
(test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null
|
||||
fi
|
||||
else
|
||||
xxxx="\\#\\#\\#\\#"
|
||||
# echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed
|
||||
echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed
|
||||
$SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp
|
||||
cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~" ## DEBUGGING
|
||||
cp "$tmp/mkfile.tmp" "$SRC/makefiles.out~" ## DEBUGGING
|
||||
if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then
|
||||
AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure])
|
||||
rm "$tmp/mkfile.tmp"
|
||||
else
|
||||
AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure])
|
||||
mv "$tmp/mkfile.tmp" "$SRC/Makefile"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)])
|
||||
xxxx="####"
|
||||
echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile
|
||||
fi
|
||||
popdef([END])dnl
|
||||
AS_VAR_POPDEF([SED])dnl
|
||||
AS_VAR_POPDEF([AUX])dnl
|
||||
AS_VAR_POPDEF([SRC])dnl
|
||||
AS_VAR_POPDEF([TOP])dnl
|
||||
AS_VAR_POPDEF([SUB])dnl
|
||||
],[dnl
|
||||
ax_enable_builddir_srcdir="$srcdir" # $srcdir
|
||||
ax_enable_builddir_host="$HOST" # $HOST / $host
|
||||
ax_enable_builddir_version="$VERSION" # $VERSION
|
||||
ax_enable_builddir_package="$PACKAGE" # $PACKAGE
|
||||
ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX
|
||||
ax_enable_builddir_sed="$ax_enable_builddir_sed" # $SED
|
||||
ax_enable_builddir="$ax_enable_builddir" # $SUB
|
||||
])dnl
|
||||
])
|
267
m4/ax_gcc_archflag.m4
Normal file
267
m4/ax_gcc_archflag.m4
Normal file
@ -0,0 +1,267 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro tries to guess the "native" arch corresponding to the target
|
||||
# architecture for use with gcc's -march=arch or -mtune=arch flags. If
|
||||
# found, the cache variable $ax_cv_gcc_archflag is set to this flag and
|
||||
# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to
|
||||
# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is
|
||||
# to add $ax_cv_gcc_archflag to the end of $CFLAGS.
|
||||
#
|
||||
# PORTABLE? should be either [yes] (default) or [no]. In the former case,
|
||||
# the flag is set to -mtune (or equivalent) so that the architecture is
|
||||
# only used for tuning, but the instruction set used is still portable. In
|
||||
# the latter case, the flag is set to -march (or equivalent) so that
|
||||
# architecture-specific instructions are enabled.
|
||||
#
|
||||
# The user can specify --with-gcc-arch=<arch> in order to override the
|
||||
# macro's choice of architecture, or --without-gcc-arch to disable this.
|
||||
#
|
||||
# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
|
||||
# called unless the user specified --with-gcc-arch manually.
|
||||
#
|
||||
# Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID
|
||||
#
|
||||
# (The main emphasis here is on recent CPUs, on the principle that doing
|
||||
# high-performance computing on old hardware is uncommon.)
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2008 Matteo Frigo
|
||||
# Copyright (c) 2014 Tsukasa Oi
|
||||
# Copyright (c) 2017-2018 Alexey Kopytov
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 22
|
||||
|
||||
AC_DEFUN([AX_GCC_ARCHFLAG],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_REQUIRE([AC_PROG_SED])
|
||||
AC_REQUIRE([AX_COMPILER_VENDOR])
|
||||
|
||||
AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
|
||||
ax_gcc_arch=$withval, ax_gcc_arch=yes)
|
||||
|
||||
AC_MSG_CHECKING([for gcc architecture flag])
|
||||
AC_MSG_RESULT([])
|
||||
AC_CACHE_VAL(ax_cv_gcc_archflag,
|
||||
[
|
||||
ax_cv_gcc_archflag="unknown"
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
|
||||
if test "x$ax_gcc_arch" = xyes; then
|
||||
ax_gcc_arch=""
|
||||
if test "$cross_compiling" = no; then
|
||||
case $host_cpu in
|
||||
i[[3456]]86*|x86_64*|amd64*) # use cpuid codes
|
||||
AX_GCC_X86_CPUID(0)
|
||||
AX_GCC_X86_CPUID(1)
|
||||
case $ax_cv_gcc_x86_cpuid_0 in
|
||||
*:756e6547:6c65746e:49656e69) # Intel
|
||||
case $ax_cv_gcc_x86_cpuid_1 in
|
||||
*5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
|
||||
*5[[123]]?:*:*:*) ax_gcc_arch=pentium ;;
|
||||
*0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;
|
||||
*0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
|
||||
*0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
|
||||
*0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
|
||||
*0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;;
|
||||
*0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;;
|
||||
*000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
|
||||
*000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;;
|
||||
# fallback
|
||||
*5??:*:*:*) ax_gcc_arch=pentium ;;
|
||||
*??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;
|
||||
*6??:*:*:*) ax_gcc_arch=pentiumpro ;;
|
||||
*00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
|
||||
esac ;;
|
||||
*:68747541:444d4163:69746e65) # AMD
|
||||
case $ax_cv_gcc_x86_cpuid_1 in
|
||||
*5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
|
||||
*5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
|
||||
*5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
|
||||
*6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
|
||||
*6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
|
||||
*6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
|
||||
*000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
|
||||
*002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
|
||||
*010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
|
||||
*050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
|
||||
*060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
|
||||
*060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
|
||||
*063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
|
||||
*07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
|
||||
# fallback
|
||||
*0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
|
||||
*020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
|
||||
*05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
|
||||
*060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
|
||||
*061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
|
||||
*06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
|
||||
*070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
|
||||
*???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;
|
||||
esac ;;
|
||||
*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)
|
||||
case $ax_cv_gcc_x86_cpuid_1 in
|
||||
*54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
|
||||
*5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;;
|
||||
*66?:*:*:*) ax_gcc_arch=winchip2 ;;
|
||||
*6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
|
||||
*6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
|
||||
esac ;;
|
||||
esac
|
||||
if test x"$ax_gcc_arch" = x; then # fallback
|
||||
case $host_cpu in
|
||||
i586*) ax_gcc_arch=pentium ;;
|
||||
i686*) ax_gcc_arch=pentiumpro ;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
|
||||
sparc*)
|
||||
AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
|
||||
cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
|
||||
cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`
|
||||
case $cputype in
|
||||
*ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
|
||||
*ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
|
||||
*ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
|
||||
*supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
|
||||
*hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
|
||||
*cypress*) ax_gcc_arch=cypress ;;
|
||||
esac ;;
|
||||
|
||||
alphaev5) ax_gcc_arch=ev5 ;;
|
||||
alphaev56) ax_gcc_arch=ev56 ;;
|
||||
alphapca56) ax_gcc_arch="pca56 ev56" ;;
|
||||
alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
|
||||
alphaev6) ax_gcc_arch=ev6 ;;
|
||||
alphaev67) ax_gcc_arch=ev67 ;;
|
||||
alphaev68) ax_gcc_arch="ev68 ev67" ;;
|
||||
alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
|
||||
alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
|
||||
alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
|
||||
|
||||
powerpc*)
|
||||
cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
|
||||
cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`
|
||||
case $cputype in
|
||||
*750*) ax_gcc_arch="750 G3" ;;
|
||||
*740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
|
||||
*74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
|
||||
*74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
|
||||
*970*) ax_gcc_arch="970 G5 power4";;
|
||||
*POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
|
||||
*POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
|
||||
603ev|8240) ax_gcc_arch="$cputype 603e 603";;
|
||||
*POWER7*) ax_gcc_arch="power7";;
|
||||
*POWER8*) ax_gcc_arch="power8";;
|
||||
*POWER9*) ax_gcc_arch="power9";;
|
||||
*POWER10*) ax_gcc_arch="power10";;
|
||||
*) ax_gcc_arch=$cputype ;;
|
||||
esac
|
||||
ax_gcc_arch="$ax_gcc_arch powerpc"
|
||||
;;
|
||||
aarch64)
|
||||
cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
|
||||
cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
|
||||
cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
|
||||
case $cpuimpl in
|
||||
0x42) case $cpuarch in
|
||||
8) case $cpuvar in
|
||||
0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
0x43) case $cpuarch in
|
||||
8) case $cpuvar in
|
||||
0x0) ax_gcc_arch="thunderx armv8-a native" ;;
|
||||
0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi # not cross-compiling
|
||||
fi # guess arch
|
||||
|
||||
if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
|
||||
if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
|
||||
flag_prefixes="-mtune="
|
||||
if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi
|
||||
# -mcpu=$arch and m$arch generate nonportable code on every arch except
|
||||
# x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
|
||||
case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac
|
||||
else
|
||||
flag_prefixes="-march= -mcpu= -m"
|
||||
fi
|
||||
for flag_prefix in $flag_prefixes; do
|
||||
for arch in $ax_gcc_arch; do
|
||||
flag="$flag_prefix$arch"
|
||||
AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then
|
||||
if test "x[]m4_default([$1],yes)" = xyes; then
|
||||
if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi
|
||||
fi
|
||||
fi; ax_cv_gcc_archflag=$flag; break])
|
||||
done
|
||||
test "x$ax_cv_gcc_archflag" = xunknown || break
|
||||
done
|
||||
fi
|
||||
|
||||
fi # $GCC=yes
|
||||
])
|
||||
AC_MSG_CHECKING([for gcc architecture flag])
|
||||
AC_MSG_RESULT($ax_cv_gcc_archflag)
|
||||
if test "x$ax_cv_gcc_archflag" = xunknown; then
|
||||
m4_default([$3],:)
|
||||
else
|
||||
m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
|
||||
fi
|
||||
])
|
89
m4/ax_gcc_x86_cpuid.m4
Normal file
89
m4/ax_gcc_x86_cpuid.m4
Normal file
@ -0,0 +1,89 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_GCC_X86_CPUID(OP)
|
||||
# AX_GCC_X86_CPUID_COUNT(OP, COUNT)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# On Pentium and later x86 processors, with gcc or a compiler that has a
|
||||
# compatible syntax for inline assembly instructions, run a small program
|
||||
# that executes the cpuid instruction with input OP. This can be used to
|
||||
# detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT
|
||||
# parameter that gets passed into register ECX before calling cpuid.
|
||||
#
|
||||
# On output, the values of the eax, ebx, ecx, and edx registers are stored
|
||||
# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
|
||||
# ax_cv_gcc_x86_cpuid_OP.
|
||||
#
|
||||
# If the cpuid instruction fails (because you are running a
|
||||
# cross-compiler, or because you are not using gcc, or because you are on
|
||||
# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
|
||||
# is set to the string "unknown".
|
||||
#
|
||||
# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2008 Matteo Frigo
|
||||
# Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 10
|
||||
|
||||
AC_DEFUN([AX_GCC_X86_CPUID],
|
||||
[AX_GCC_X86_CPUID_COUNT($1, 0)
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_GCC_X86_CPUID_COUNT],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_LANG_PUSH([C])
|
||||
AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
|
||||
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
|
||||
int op = $1, level = $2, eax, ebx, ecx, edx;
|
||||
FILE *f;
|
||||
__asm__ __volatile__ ("xchg %%ebx, %1\n"
|
||||
"cpuid\n"
|
||||
"xchg %%ebx, %1\n"
|
||||
: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
|
||||
: "a" (op), "2" (level));
|
||||
|
||||
f = fopen("conftest_cpuid", "w"); if (!f) return 1;
|
||||
fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
|
||||
fclose(f);
|
||||
return 0;
|
||||
])],
|
||||
[ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
|
||||
[ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
|
||||
[ax_cv_gcc_x86_cpuid_$1=unknown])])
|
||||
AC_LANG_POP([C])
|
||||
])
|
37
m4/ax_require_defined.m4
Normal file
37
m4/ax_require_defined.m4
Normal file
@ -0,0 +1,37 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_REQUIRE_DEFINED(MACRO)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
|
||||
# been defined and thus are available for use. This avoids random issues
|
||||
# where a macro isn't expanded. Instead the configure script emits a
|
||||
# non-fatal:
|
||||
#
|
||||
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
|
||||
#
|
||||
# It's like AC_REQUIRE except it doesn't expand the required macro.
|
||||
#
|
||||
# Here's an example:
|
||||
#
|
||||
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 2
|
||||
|
||||
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
|
||||
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
|
||||
])dnl AX_REQUIRE_DEFINED
|
8372
m4/libtool.m4
vendored
Normal file
8372
m4/libtool.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
437
m4/ltoptions.m4
vendored
Normal file
437
m4/ltoptions.m4
vendored
Normal file
@ -0,0 +1,437 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 8 ltoptions.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||
|
||||
|
||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ------------------------------------------
|
||||
m4_define([_LT_MANGLE_OPTION],
|
||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ---------------------------------------
|
||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||
# saved as a flag.
|
||||
m4_define([_LT_SET_OPTION],
|
||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
[m4_warning([Unknown $1 option '$2'])])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||
# ------------------------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
m4_define([_LT_IF_OPTION],
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||
|
||||
|
||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||
# -------------------------------------------------------
|
||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||
# are set.
|
||||
m4_define([_LT_UNLESS_OPTIONS],
|
||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||
[m4_define([$0_found])])])[]dnl
|
||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||
])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||
# ----------------------------------------
|
||||
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||
# the unknown option and exit.
|
||||
m4_defun([_LT_SET_OPTIONS],
|
||||
[# Set options
|
||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||
|
||||
m4_if([$1],[LT_INIT],[
|
||||
dnl
|
||||
dnl Simply set some default values (i.e off) if boolean options were not
|
||||
dnl specified:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||
])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||
])
|
||||
dnl
|
||||
dnl If no reference was made to various pairs of opposing options, then
|
||||
dnl we run the default mode handler for the pair. For example, if neither
|
||||
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
|
||||
dnl archives by default:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||
[_LT_ENABLE_FAST_INSTALL])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
|
||||
[_LT_WITH_AIX_SONAME([aix])])
|
||||
])
|
||||
])# _LT_SET_OPTIONS
|
||||
|
||||
|
||||
## --------------------------------- ##
|
||||
## Macros to handle LT_INIT options. ##
|
||||
## --------------------------------- ##
|
||||
|
||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||
# -----------------------------------------
|
||||
m4_define([_LT_MANGLE_DEFUN],
|
||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||
# -----------------------------------------------
|
||||
m4_define([LT_OPTION_DEFINE],
|
||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||
])# LT_OPTION_DEFINE
|
||||
|
||||
|
||||
# dlopen
|
||||
# ------
|
||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'dlopen' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||
|
||||
|
||||
# win32-dll
|
||||
# ---------
|
||||
# Declare package support for building win32 dll's.
|
||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||
[enable_win32_dll=yes
|
||||
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||
AC_CHECK_TOOL(AS, as, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||
;;
|
||||
esac
|
||||
|
||||
test -z "$AS" && AS=as
|
||||
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||
|
||||
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||
|
||||
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||
])# win32-dll
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'win32-dll' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||
|
||||
|
||||
# _LT_ENABLE_SHARED([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-shared flag, and supports the 'shared' and
|
||||
# 'disable-shared' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_SHARED],
|
||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([shared],
|
||||
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_shared=yes ;;
|
||||
no) enable_shared=no ;;
|
||||
*)
|
||||
enable_shared=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||
|
||||
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||
[Whether or not to build shared libraries])
|
||||
])# _LT_ENABLE_SHARED
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_STATIC([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-static flag, and support the 'static' and
|
||||
# 'disable-static' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_STATIC],
|
||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([static],
|
||||
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_static=yes ;;
|
||||
no) enable_static=no ;;
|
||||
*)
|
||||
enable_static=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_static=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||
|
||||
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||
[Whether or not to build static libraries])
|
||||
])# _LT_ENABLE_STATIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --enable-fast-install flag, and support the 'fast-install'
|
||||
# and 'disable-fast-install' LT_INIT options.
|
||||
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
|
||||
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([fast-install],
|
||||
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_fast_install=yes ;;
|
||||
no) enable_fast_install=no ;;
|
||||
*)
|
||||
enable_fast_install=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for pkg in $enableval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_fast_install=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||
|
||||
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||
[Whether or not to optimize for fast installation])dnl
|
||||
])# _LT_ENABLE_FAST_INSTALL
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||
|
||||
# Old names:
|
||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the 'fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the 'disable-fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||
|
||||
|
||||
# _LT_WITH_AIX_SONAME([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
|
||||
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
|
||||
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
|
||||
m4_define([_LT_WITH_AIX_SONAME],
|
||||
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
|
||||
shared_archive_member_spec=
|
||||
case $host,$enable_shared in
|
||||
power*-*-aix[[5-9]]*,yes)
|
||||
AC_MSG_CHECKING([which variant of shared library versioning to provide])
|
||||
AC_ARG_WITH([aix-soname],
|
||||
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
|
||||
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
|
||||
[case $withval in
|
||||
aix|svr4|both)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
|
||||
;;
|
||||
esac
|
||||
lt_cv_with_aix_soname=$with_aix_soname],
|
||||
[AC_CACHE_VAL([lt_cv_with_aix_soname],
|
||||
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
|
||||
with_aix_soname=$lt_cv_with_aix_soname])
|
||||
AC_MSG_RESULT([$with_aix_soname])
|
||||
if test aix != "$with_aix_soname"; then
|
||||
# For the AIX way of multilib, we name the shared archive member
|
||||
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
|
||||
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
|
||||
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
|
||||
# the AIX toolchain works better with OBJECT_MODE set (default 32).
|
||||
if test 64 = "${OBJECT_MODE-32}"; then
|
||||
shared_archive_member_spec=shr_64
|
||||
else
|
||||
shared_archive_member_spec=shr
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
with_aix_soname=aix
|
||||
;;
|
||||
esac
|
||||
|
||||
_LT_DECL([], [shared_archive_member_spec], [0],
|
||||
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
|
||||
])# _LT_WITH_AIX_SONAME
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
|
||||
|
||||
|
||||
# _LT_WITH_PIC([MODE])
|
||||
# --------------------
|
||||
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
|
||||
# LT_INIT options.
|
||||
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
|
||||
m4_define([_LT_WITH_PIC],
|
||||
[AC_ARG_WITH([pic],
|
||||
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||
[lt_p=${PACKAGE-default}
|
||||
case $withval in
|
||||
yes|no) pic_mode=$withval ;;
|
||||
*)
|
||||
pic_mode=default
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
|
||||
for lt_pkg in $withval; do
|
||||
IFS=$lt_save_ifs
|
||||
if test "X$lt_pkg" = "X$lt_p"; then
|
||||
pic_mode=yes
|
||||
fi
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
;;
|
||||
esac],
|
||||
[pic_mode=m4_default([$1], [default])])
|
||||
|
||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||
])# _LT_WITH_PIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||
|
||||
# Old name:
|
||||
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the 'pic-only' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||
|
||||
## ----------------- ##
|
||||
## LTDL_INIT Options ##
|
||||
## ----------------- ##
|
||||
|
||||
m4_define([_LTDL_MODE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||
[m4_define([_LTDL_MODE], [recursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||
[m4_define([_LTDL_MODE], [subproject])])
|
||||
|
||||
m4_define([_LTDL_TYPE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||
[m4_define([_LTDL_TYPE], [installable])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||
[m4_define([_LTDL_TYPE], [convenience])])
|
124
m4/ltsugar.m4
vendored
Normal file
124
m4/ltsugar.m4
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6 ltsugar.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||
|
||||
|
||||
# lt_join(SEP, ARG1, [ARG2...])
|
||||
# -----------------------------
|
||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||
# associated separator.
|
||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||
# versions in m4sugar had bugs.
|
||||
m4_define([lt_join],
|
||||
[m4_if([$#], [1], [],
|
||||
[$#], [2], [[$2]],
|
||||
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
m4_define([_lt_join],
|
||||
[m4_if([$#$2], [2], [],
|
||||
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
|
||||
|
||||
# lt_car(LIST)
|
||||
# lt_cdr(LIST)
|
||||
# ------------
|
||||
# Manipulate m4 lists.
|
||||
# These macros are necessary as long as will still need to support
|
||||
# Autoconf-2.59, which quotes differently.
|
||||
m4_define([lt_car], [[$1]])
|
||||
m4_define([lt_cdr],
|
||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||
[$#], 1, [],
|
||||
[m4_dquote(m4_shift($@))])])
|
||||
m4_define([lt_unquote], $1)
|
||||
|
||||
|
||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||
# ------------------------------------------
|
||||
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
|
||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||
# than defined and empty).
|
||||
#
|
||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||
m4_define([lt_append],
|
||||
[m4_define([$1],
|
||||
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||
|
||||
|
||||
|
||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||
# ----------------------------------------------------------
|
||||
# Produce a SEP delimited list of all paired combinations of elements of
|
||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||
# has the form PREFIXmINFIXSUFFIXn.
|
||||
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||
m4_define([lt_combine],
|
||||
[m4_if(m4_eval([$# > 3]), [1],
|
||||
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||
[[m4_foreach([_Lt_prefix], [$2],
|
||||
[m4_foreach([_Lt_suffix],
|
||||
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||
|
||||
|
||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||
# -----------------------------------------------------------------------
|
||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||
m4_define([lt_if_append_uniq],
|
||||
[m4_ifdef([$1],
|
||||
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||
[lt_append([$1], [$2], [$3])$4],
|
||||
[$5])],
|
||||
[lt_append([$1], [$2], [$3])$4])])
|
||||
|
||||
|
||||
# lt_dict_add(DICT, KEY, VALUE)
|
||||
# -----------------------------
|
||||
m4_define([lt_dict_add],
|
||||
[m4_define([$1($2)], [$3])])
|
||||
|
||||
|
||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||
# --------------------------------------------
|
||||
m4_define([lt_dict_add_subkey],
|
||||
[m4_define([$1($2:$3)], [$4])])
|
||||
|
||||
|
||||
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||
# ----------------------------------
|
||||
m4_define([lt_dict_fetch],
|
||||
[m4_ifval([$3],
|
||||
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||
|
||||
|
||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([lt_if_dict_fetch],
|
||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||
[$5],
|
||||
[$6])])
|
||||
|
||||
|
||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||
# --------------------------------------------------------------
|
||||
m4_define([lt_dict_filter],
|
||||
[m4_if([$5], [], [],
|
||||
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||
])
|
23
m4/ltversion.m4
vendored
Normal file
23
m4/ltversion.m4
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 4179 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.6'
|
||||
macro_revision='2.4.6'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
99
m4/lt~obsolete.m4
vendored
Normal file
99
m4/lt~obsolete.m4
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5 lt~obsolete.m4
|
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||
#
|
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
|
||||
# which have later been changed to m4_define as they aren't part of the
|
||||
# exported API, or moved to Autoconf or Automake where they belong.
|
||||
#
|
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||
# and doesn't know about Autoconf macros at all.)
|
||||
#
|
||||
# So we provide this file, which has a silly filename so it's always
|
||||
# included after everything else. This provides aclocal with the
|
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||
# because those macros already exist, or will be overwritten later.
|
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||
#
|
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||
# Yes, that means every name once taken will need to remain here until
|
||||
# we give up compatibility with versions before 1.7, at which point
|
||||
# we need to keep only those names which we still refer to.
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
333
make_sunver.pl
Normal file
333
make_sunver.pl
Normal file
@ -0,0 +1,333 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# make_sunver.pl
|
||||
#
|
||||
# This script takes at least two arguments, a GNU style version script and
|
||||
# a list of object and archive files, and generates a corresponding Sun
|
||||
# style version script as follows:
|
||||
#
|
||||
# Each glob pattern, C++ mangled pattern or literal in the input script is
|
||||
# matched against all global symbols in the input objects, emitting those
|
||||
# that matched (or nothing if no match was found).
|
||||
# A comment with the original pattern and its type is left in the output
|
||||
# file to make it easy to understand the matches.
|
||||
#
|
||||
# It uses elfdump when present (native), GNU readelf otherwise.
|
||||
# It depends on the GNU version of c++filt, since it must understand the
|
||||
# GNU mangling style.
|
||||
|
||||
use FileHandle;
|
||||
use IPC::Open2;
|
||||
|
||||
# Enforce C locale.
|
||||
$ENV{'LC_ALL'} = "C";
|
||||
$ENV{'LANG'} = "C";
|
||||
|
||||
# Input version script, GNU style.
|
||||
my $symvers = shift;
|
||||
|
||||
##########
|
||||
# Get all the symbols from the library, match them, and add them to a hash.
|
||||
|
||||
my %sym_hash = ();
|
||||
|
||||
# List of objects and archives to process.
|
||||
my @OBJECTS = ();
|
||||
|
||||
# List of shared objects to omit from processing.
|
||||
my @SHAREDOBJS = ();
|
||||
|
||||
# Filter out those input archives that have corresponding shared objects to
|
||||
# avoid adding all symbols matched in the archive to the output map.
|
||||
foreach $file (@ARGV) {
|
||||
if (($so = $file) =~ s/\.a$/.so/ && -e $so) {
|
||||
printf STDERR "omitted $file -> $so\n";
|
||||
push (@SHAREDOBJS, $so);
|
||||
} else {
|
||||
push (@OBJECTS, $file);
|
||||
}
|
||||
}
|
||||
|
||||
# We need to detect and ignore hidden symbols. Solaris nm can only detect
|
||||
# this in the harder to parse default output format, and GNU nm not at all,
|
||||
# so use elfdump -s in the native case and GNU readelf -s otherwise.
|
||||
# GNU objdump -t cannot be used since it produces a variable number of
|
||||
# columns.
|
||||
|
||||
# The path to elfdump.
|
||||
my $elfdump = "/usr/ccs/bin/elfdump";
|
||||
|
||||
if (-f $elfdump) {
|
||||
open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!;
|
||||
my $skip_arsym = 0;
|
||||
|
||||
while (<ELFDUMP>) {
|
||||
chomp;
|
||||
|
||||
# Ignore empty lines.
|
||||
if (/^$/) {
|
||||
# End of archive symbol table, stop skipping.
|
||||
$skip_arsym = 0 if $skip_arsym;
|
||||
next;
|
||||
}
|
||||
|
||||
# Keep skipping until end of archive symbol table.
|
||||
next if ($skip_arsym);
|
||||
|
||||
# Ignore object name header for individual objects and archives.
|
||||
next if (/:$/);
|
||||
|
||||
# Ignore table header lines.
|
||||
next if (/^Symbol Table Section:/);
|
||||
next if (/index.*value.*size/);
|
||||
|
||||
# Start of archive symbol table: start skipping.
|
||||
if (/^Symbol Table: \(archive/) {
|
||||
$skip_arsym = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
# Split table.
|
||||
(undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split;
|
||||
|
||||
# Error out for unknown input.
|
||||
die "unknown input line:\n$_" unless defined($bind);
|
||||
|
||||
# Ignore local symbols.
|
||||
next if ($bind eq "LOCL");
|
||||
# Ignore hidden symbols.
|
||||
next if ($oth eq "H");
|
||||
# Ignore undefined symbols.
|
||||
next if ($shndx eq "UNDEF");
|
||||
# Error out for unhandled cases.
|
||||
if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") {
|
||||
die "unhandled symbol:\n$_";
|
||||
}
|
||||
|
||||
# Remember symbol.
|
||||
$sym_hash{$name}++;
|
||||
}
|
||||
close ELFDUMP or die "$elfdump error";
|
||||
} else {
|
||||
open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!;
|
||||
# Process each symbol.
|
||||
while (<READELF>) {
|
||||
chomp;
|
||||
|
||||
# Ignore empty lines.
|
||||
next if (/^$/);
|
||||
|
||||
# Ignore object name header.
|
||||
next if (/^File: .*$/);
|
||||
|
||||
# Ignore table header lines.
|
||||
next if (/^Symbol table.*contains.*:/);
|
||||
next if (/Num:.*Value.*Size/);
|
||||
|
||||
# Split table.
|
||||
(undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split;
|
||||
|
||||
# Error out for unknown input.
|
||||
die "unknown input line:\n$_" unless defined($bind);
|
||||
|
||||
# Ignore local symbols.
|
||||
next if ($bind eq "LOCAL");
|
||||
# Ignore hidden symbols.
|
||||
next if ($vis eq "HIDDEN");
|
||||
# Ignore undefined symbols.
|
||||
next if ($ndx eq "UND");
|
||||
# Error out for unhandled cases.
|
||||
if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") {
|
||||
die "unhandled symbol:\n$_";
|
||||
}
|
||||
|
||||
# Remember symbol.
|
||||
$sym_hash{$name}++;
|
||||
}
|
||||
close READELF or die "readelf error";
|
||||
}
|
||||
|
||||
##########
|
||||
# The various types of glob patterns.
|
||||
#
|
||||
# A glob pattern that is to be applied to the demangled name: 'cxx'.
|
||||
# A glob patterns that applies directly to the name in the .o files: 'glob'.
|
||||
# This pattern is ignored; used for local variables (usually just '*'): 'ign'.
|
||||
|
||||
# The type of the current pattern.
|
||||
my $glob = 'glob';
|
||||
|
||||
# We're currently inside `extern "C++"', which Sun ld doesn't understand.
|
||||
my $in_extern = 0;
|
||||
|
||||
# The c++filt command to use. This *must* be GNU c++filt; the Sun Studio
|
||||
# c++filt doesn't handle the GNU mangling style.
|
||||
my $cxxfilt = $ENV{'CXXFILT'} || "c++filt";
|
||||
|
||||
# The current version name.
|
||||
my $current_version = "";
|
||||
|
||||
# Was there any attempt to match a symbol to this version?
|
||||
my $matches_attempted;
|
||||
|
||||
# The number of versions which matched this symbol.
|
||||
my $matched_symbols;
|
||||
|
||||
open F,$symvers or die $!;
|
||||
|
||||
# Print information about generating this file
|
||||
print "# This file was generated by make_sunver.pl. DO NOT EDIT!\n";
|
||||
print "# It was generated by:\n";
|
||||
printf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV);
|
||||
printf "# Omitted archives with corresponding shared libraries: %s\n",
|
||||
(join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0;
|
||||
print "#\n\n";
|
||||
|
||||
while (<F>) {
|
||||
# Lines of the form '};'
|
||||
if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) {
|
||||
$glob = 'glob';
|
||||
if ($in_extern) {
|
||||
$in_extern--;
|
||||
print "$1##$2\n";
|
||||
} else {
|
||||
print;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# Lines of the form '} SOME_VERSION_NAME_1.0;'
|
||||
if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) {
|
||||
$glob = 'glob';
|
||||
# We tried to match symbols agains this version, but none matched.
|
||||
# Emit dummy hidden symbol to avoid marking this version WEAK.
|
||||
if ($matches_attempted && $matched_symbols == 0) {
|
||||
print " hidden:\n";
|
||||
print " .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n";
|
||||
}
|
||||
print; next;
|
||||
}
|
||||
|
||||
# Comment and blank lines
|
||||
if (/^[ \t]*\#/) { print; next; }
|
||||
if (/^[ \t]*$/) { print; next; }
|
||||
|
||||
# Lines of the form '{'
|
||||
if (/^([ \t]*){$/) {
|
||||
if ($in_extern) {
|
||||
print "$1##{\n";
|
||||
} else {
|
||||
print;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# Lines of the form 'SOME_VERSION_NAME_1.1 {'
|
||||
if (/^([A-Z0-9_.]+)[ \t]+{$/) {
|
||||
# Record version name.
|
||||
$current_version = $1;
|
||||
# Reset match attempts, #matched symbols for this version.
|
||||
$matches_attempted = 0;
|
||||
$matched_symbols = 0;
|
||||
print;
|
||||
next;
|
||||
}
|
||||
|
||||
# Ignore 'global:'
|
||||
if (/^[ \t]*global:$/) { print; next; }
|
||||
|
||||
# After 'local:', globs should be ignored, they won't be exported.
|
||||
if (/^[ \t]*local:$/) {
|
||||
$glob = 'ign';
|
||||
print;
|
||||
next;
|
||||
}
|
||||
|
||||
# After 'extern "C++"', globs are C++ patterns
|
||||
if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) {
|
||||
$in_extern++;
|
||||
$glob = 'cxx';
|
||||
# Need to comment, Sun ld cannot handle this.
|
||||
print "$1##$2\n"; next;
|
||||
}
|
||||
|
||||
# Chomp newline now we're done with passing through the input file.
|
||||
chomp;
|
||||
|
||||
# Catch globs. Note that '{}' is not allowed in globs by this script,
|
||||
# so only '*' and '[]' are available.
|
||||
if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) {
|
||||
my $ws = $1;
|
||||
my $ptn = $2;
|
||||
# Turn the glob into a regex by replacing '*' with '.*', '?' with '.'.
|
||||
# Keep $ptn so we can still print the original form.
|
||||
($pattern = $ptn) =~ s/\*/\.\*/g;
|
||||
$pattern =~ s/\?/\./g;
|
||||
|
||||
if ($glob eq 'ign') {
|
||||
# We're in a local: * section; just continue.
|
||||
print "$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Print the glob commented for human readers.
|
||||
print "$ws##$ptn ($glob)\n";
|
||||
# We tried to match a symbol to this version.
|
||||
$matches_attempted++;
|
||||
|
||||
if ($glob eq 'glob') {
|
||||
my %ptn_syms = ();
|
||||
|
||||
# Match ptn against symbols in %sym_hash.
|
||||
foreach my $sym (keys %sym_hash) {
|
||||
# Maybe it matches one of the patterns based on the symbol in
|
||||
# the .o file.
|
||||
$ptn_syms{$sym}++ if ($sym =~ /^$pattern$/);
|
||||
}
|
||||
|
||||
foreach my $sym (sort keys(%ptn_syms)) {
|
||||
$matched_symbols++;
|
||||
print "$ws$sym;\n";
|
||||
}
|
||||
} elsif ($glob eq 'cxx') {
|
||||
my %dem_syms = ();
|
||||
|
||||
# Verify that we're actually using GNU c++filt. Other versions
|
||||
# most likely cannot handle GNU style symbol mangling.
|
||||
my $cxxout = `$cxxfilt --version 2>&1`;
|
||||
$cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function";
|
||||
|
||||
# Talk to c++filt through a pair of file descriptors.
|
||||
# Need to start a fresh instance per pattern, otherwise the
|
||||
# process grows to 500+ MB.
|
||||
my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!;
|
||||
|
||||
# Match ptn against symbols in %sym_hash.
|
||||
foreach my $sym (keys %sym_hash) {
|
||||
# No? Well, maybe its demangled form matches one of those
|
||||
# patterns.
|
||||
printf FILTOUT "%s\n",$sym;
|
||||
my $dem = <FILTIN>;
|
||||
chomp $dem;
|
||||
$dem_syms{$sym}++ if ($dem =~ /^$pattern$/);
|
||||
}
|
||||
|
||||
close FILTOUT or die "c++filt error";
|
||||
close FILTIN or die "c++filt error";
|
||||
# Need to wait for the c++filt process to avoid lots of zombies.
|
||||
waitpid $pid, 0;
|
||||
|
||||
foreach my $sym (sort keys(%dem_syms)) {
|
||||
$matched_symbols++;
|
||||
print "$ws$sym;\n";
|
||||
}
|
||||
} else {
|
||||
# No? Well, then ignore it.
|
||||
}
|
||||
next;
|
||||
}
|
||||
# Important sanity check. This script can't handle lots of formats
|
||||
# that GNU ld can, so be sure to error out if one is seen!
|
||||
die "strange line `$_'";
|
||||
}
|
||||
close F;
|
8
man/Makefile.am
Normal file
8
man/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
|
||||
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
|
||||
|
||||
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
|
||||
|
561
man/Makefile.in
Normal file
561
man/Makefile.in
Normal file
@ -0,0 +1,561 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = man
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
|
||||
$(top_srcdir)/m4/ax_append_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
|
||||
$(top_srcdir)/m4/ax_configure_args.m4 \
|
||||
$(top_srcdir)/m4/ax_enable_builddir.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
|
||||
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
|
||||
$(top_srcdir)/m4/ax_require_defined.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/fficonfig.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
man3dir = $(mandir)/man3
|
||||
am__installdirs = "$(DESTDIR)$(man3dir)"
|
||||
NROFF = nroff
|
||||
MANS = $(man_MANS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_LTLDFLAGS = @AM_LTLDFLAGS@
|
||||
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CCASDEPMODE = @CCASDEPMODE@
|
||||
CCASFLAGS = @CCASFLAGS@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
|
||||
HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OPT_LDFLAGS = @OPT_LDFLAGS@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PRTDIAG = @PRTDIAG@
|
||||
RANLIB = @RANLIB@
|
||||
SECTION_LDFLAGS = @SECTION_LDFLAGS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
TARGET = @TARGET@
|
||||
TARGETDIR = @TARGETDIR@
|
||||
TARGET_OBJ = @TARGET_OBJ@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
ax_enable_builddir_sed = @ax_enable_builddir_sed@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sys_symbol_underscore = @sys_symbol_underscore@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
toolexecdir = @toolexecdir@
|
||||
toolexeclibdir = @toolexeclibdir@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
|
||||
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign man/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-man3: $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list1=''; \
|
||||
list2='$(man_MANS)'; \
|
||||
test -n "$(man3dir)" \
|
||||
&& test -n "`echo $$list1$$list2`" \
|
||||
|| exit 0; \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \
|
||||
{ for i in $$list1; do echo "$$i"; done; \
|
||||
if test -n "$$list2"; then \
|
||||
for i in $$list2; do echo "$$i"; done \
|
||||
| sed -n '/\.3[a-z]*$$/p'; \
|
||||
fi; \
|
||||
} | while read p; do \
|
||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; echo "$$p"; \
|
||||
done | \
|
||||
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
|
||||
sed 'N;N;s,\n, ,g' | { \
|
||||
list=; while read file base inst; do \
|
||||
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
|
||||
fi; \
|
||||
done; \
|
||||
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
|
||||
done; }
|
||||
|
||||
uninstall-man3:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list=''; test -n "$(man3dir)" || exit 0; \
|
||||
files=`{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.3[a-z]*$$/p'; \
|
||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
||||
dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
|
||||
tags TAGS:
|
||||
|
||||
ctags CTAGS:
|
||||
|
||||
cscope cscopelist:
|
||||
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(MANS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(man3dir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-man
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man: install-man3
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man3
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||
cscopelist-am ctags-am distclean distclean-generic \
|
||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-man3 install-pdf install-pdf-am install-ps \
|
||||
install-ps-am install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
|
||||
ps ps-am tags-am uninstall uninstall-am uninstall-man \
|
||||
uninstall-man3
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
41
man/ffi.3
Normal file
41
man/ffi.3
Normal file
@ -0,0 +1,41 @@
|
||||
.Dd February 15, 2008
|
||||
.Dt FFI 3
|
||||
.Sh NAME
|
||||
.Nm FFI
|
||||
.Nd Foreign Function Interface
|
||||
.Sh LIBRARY
|
||||
libffi, -lffi
|
||||
.Sh SYNOPSIS
|
||||
.In ffi.h
|
||||
.Ft ffi_status
|
||||
.Fo ffi_prep_cif
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "ffi_abi abi"
|
||||
.Fa "unsigned int nargs"
|
||||
.Fa "ffi_type *rtype"
|
||||
.Fa "ffi_type **atypes"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo ffi_prep_cif_var
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "ffi_abi abi"
|
||||
.Fa "unsigned int nfixedargs"
|
||||
.Fa "unsigned int ntotalargs"
|
||||
.Fa "ffi_type *rtype"
|
||||
.Fa "ffi_type **atypes"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo ffi_call
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "void (*fn)(void)"
|
||||
.Fa "void *rvalue"
|
||||
.Fa "void **avalue"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The foreign function interface provides a mechanism by which a function can
|
||||
generate a call to another function at runtime without requiring knowledge of
|
||||
the called function's interface at compile time.
|
||||
.Sh SEE ALSO
|
||||
.Xr ffi_prep_cif 3 ,
|
||||
.Xr ffi_prep_cif_var 3 ,
|
||||
.Xr ffi_call 3
|
103
man/ffi_call.3
Normal file
103
man/ffi_call.3
Normal file
@ -0,0 +1,103 @@
|
||||
.Dd February 15, 2008
|
||||
.Dt ffi_call 3
|
||||
.Sh NAME
|
||||
.Nm ffi_call
|
||||
.Nd Invoke a foreign function.
|
||||
.Sh SYNOPSIS
|
||||
.In ffi.h
|
||||
.Ft void
|
||||
.Fo ffi_call
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "void (*fn)(void)"
|
||||
.Fa "void *rvalue"
|
||||
.Fa "void **avalue"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm ffi_call
|
||||
function provides a simple mechanism for invoking a function without
|
||||
requiring knowledge of the function's interface at compile time.
|
||||
.Fa fn
|
||||
is called with the values retrieved from the pointers in the
|
||||
.Fa avalue
|
||||
array. The return value from
|
||||
.Fa fn
|
||||
is placed in storage pointed to by
|
||||
.Fa rvalue .
|
||||
.Fa cif
|
||||
contains information describing the data types, sizes and alignments of the
|
||||
arguments to and return value from
|
||||
.Fa fn ,
|
||||
and must be initialized with
|
||||
.Nm ffi_prep_cif
|
||||
before it is used with
|
||||
.Nm ffi_call .
|
||||
.Pp
|
||||
.Fa rvalue
|
||||
must point to storage that is sizeof(ffi_arg) or larger for non-floating point
|
||||
types. For smaller-sized return value types, the
|
||||
.Nm ffi_arg
|
||||
or
|
||||
.Nm ffi_sarg
|
||||
integral type must be used to hold
|
||||
the return value.
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal
|
||||
#include <ffi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned char
|
||||
foo(unsigned int, float);
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *arg_types[2];
|
||||
void *arg_values[2];
|
||||
ffi_status status;
|
||||
|
||||
// Because the return value from foo() is smaller than sizeof(long), it
|
||||
// must be passed as ffi_arg or ffi_sarg.
|
||||
ffi_arg result;
|
||||
|
||||
// Specify the data type of each argument. Available types are defined
|
||||
// in <ffi/ffi.h>.
|
||||
arg_types[0] = &ffi_type_uint;
|
||||
arg_types[1] = &ffi_type_float;
|
||||
|
||||
// Prepare the ffi_cif structure.
|
||||
if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
|
||||
2, &ffi_type_uint8, arg_types)) != FFI_OK)
|
||||
{
|
||||
// Handle the ffi_status error.
|
||||
}
|
||||
|
||||
// Specify the values of each argument.
|
||||
unsigned int arg1 = 42;
|
||||
float arg2 = 5.1;
|
||||
|
||||
arg_values[0] = &arg1;
|
||||
arg_values[1] = &arg2;
|
||||
|
||||
// Invoke the function.
|
||||
ffi_call(&cif, FFI_FN(foo), &result, arg_values);
|
||||
|
||||
// The ffi_arg 'result' now contains the unsigned char returned from foo(),
|
||||
// which can be accessed by a typecast.
|
||||
printf("result is %hhu", (unsigned char)result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The target function.
|
||||
unsigned char
|
||||
foo(unsigned int x, float y)
|
||||
{
|
||||
unsigned char result = x - y;
|
||||
return result;
|
||||
}
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr ffi 3 ,
|
||||
.Xr ffi_prep_cif 3
|
68
man/ffi_prep_cif.3
Normal file
68
man/ffi_prep_cif.3
Normal file
@ -0,0 +1,68 @@
|
||||
.Dd February 15, 2008
|
||||
.Dt ffi_prep_cif 3
|
||||
.Sh NAME
|
||||
.Nm ffi_prep_cif
|
||||
.Nd Prepare a
|
||||
.Nm ffi_cif
|
||||
structure for use with
|
||||
.Nm ffi_call
|
||||
.
|
||||
.Sh SYNOPSIS
|
||||
.In ffi.h
|
||||
.Ft ffi_status
|
||||
.Fo ffi_prep_cif
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "ffi_abi abi"
|
||||
.Fa "unsigned int nargs"
|
||||
.Fa "ffi_type *rtype"
|
||||
.Fa "ffi_type **atypes"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm ffi_prep_cif
|
||||
function prepares a
|
||||
.Nm ffi_cif
|
||||
structure for use with
|
||||
.Nm ffi_call
|
||||
.
|
||||
.Fa abi
|
||||
specifies a set of calling conventions to use.
|
||||
.Fa atypes
|
||||
is an array of
|
||||
.Fa nargs
|
||||
pointers to
|
||||
.Nm ffi_type
|
||||
structs that describe the data type, size and alignment of each argument.
|
||||
.Fa rtype
|
||||
points to an
|
||||
.Nm ffi_type
|
||||
that describes the data type, size and alignment of the
|
||||
return value. Note that to call a variadic function
|
||||
.Nm ffi_prep_cif_var
|
||||
must be used instead.
|
||||
.Sh RETURN VALUES
|
||||
Upon successful completion,
|
||||
.Nm ffi_prep_cif
|
||||
returns
|
||||
.Nm FFI_OK .
|
||||
It will return
|
||||
.Nm FFI_BAD_TYPEDEF
|
||||
if
|
||||
.Fa cif
|
||||
is
|
||||
.Nm NULL
|
||||
or
|
||||
.Fa atypes
|
||||
or
|
||||
.Fa rtype
|
||||
is malformed. If
|
||||
.Fa abi
|
||||
does not refer to a valid ABI,
|
||||
.Nm FFI_BAD_ABI
|
||||
will be returned. Available ABIs are
|
||||
defined in
|
||||
.Nm <ffitarget.h> .
|
||||
.Sh SEE ALSO
|
||||
.Xr ffi 3 ,
|
||||
.Xr ffi_call 3 ,
|
||||
.Xr ffi_prep_cif_var 3
|
73
man/ffi_prep_cif_var.3
Normal file
73
man/ffi_prep_cif_var.3
Normal file
@ -0,0 +1,73 @@
|
||||
.Dd January 25, 2011
|
||||
.Dt ffi_prep_cif_var 3
|
||||
.Sh NAME
|
||||
.Nm ffi_prep_cif_var
|
||||
.Nd Prepare a
|
||||
.Nm ffi_cif
|
||||
structure for use with
|
||||
.Nm ffi_call
|
||||
for variadic functions.
|
||||
.Sh SYNOPSIS
|
||||
.In ffi.h
|
||||
.Ft ffi_status
|
||||
.Fo ffi_prep_cif_var
|
||||
.Fa "ffi_cif *cif"
|
||||
.Fa "ffi_abi abi"
|
||||
.Fa "unsigned int nfixedargs"
|
||||
.Fa "unsigned int ntotalargs"
|
||||
.Fa "ffi_type *rtype"
|
||||
.Fa "ffi_type **atypes"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm ffi_prep_cif_var
|
||||
function prepares a
|
||||
.Nm ffi_cif
|
||||
structure for use with
|
||||
.Nm ffi_call
|
||||
for variadic functions.
|
||||
.Fa abi
|
||||
specifies a set of calling conventions to use.
|
||||
.Fa atypes
|
||||
is an array of
|
||||
.Fa ntotalargs
|
||||
pointers to
|
||||
.Nm ffi_type
|
||||
structs that describe the data type, size and alignment of each argument.
|
||||
.Fa rtype
|
||||
points to an
|
||||
.Nm ffi_type
|
||||
that describes the data type, size and alignment of the
|
||||
return value.
|
||||
.Fa nfixedargs
|
||||
must contain the number of fixed (non-variadic) arguments.
|
||||
Note that to call a non-variadic function
|
||||
.Nm ffi_prep_cif
|
||||
must be used.
|
||||
.Sh RETURN VALUES
|
||||
Upon successful completion,
|
||||
.Nm ffi_prep_cif_var
|
||||
returns
|
||||
.Nm FFI_OK .
|
||||
It will return
|
||||
.Nm FFI_BAD_TYPEDEF
|
||||
if
|
||||
.Fa cif
|
||||
is
|
||||
.Nm NULL
|
||||
or
|
||||
.Fa atypes
|
||||
or
|
||||
.Fa rtype
|
||||
is malformed. If
|
||||
.Fa abi
|
||||
does not refer to a valid ABI,
|
||||
.Nm FFI_BAD_ABI
|
||||
will be returned. Available ABIs are
|
||||
defined in
|
||||
.Nm <ffitarget.h>
|
||||
.
|
||||
.Sh SEE ALSO
|
||||
.Xr ffi 3 ,
|
||||
.Xr ffi_call 3 ,
|
||||
.Xr ffi_prep_cif 3
|
215
missing
Executable file
215
missing
Executable file
@ -0,0 +1,215 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=https://www.perl.org/
|
||||
flex_URL=https://github.com/westes/flex
|
||||
gnu_software_URL=https://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
33
msvc_build/aarch64/Ffi_staticLib.sln
Normal file
33
msvc_build/aarch64/Ffi_staticLib.sln
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28302.56
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ffi_staticLib_arm64", "Ffi_staticLib.vcxproj", "{115502C0-BE05-4767-BF19-5C87D805FAD6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x64.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x86.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x64.ActiveCfg = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x86.ActiveCfg = Release|ARM64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {241C54C7-20DD-4897-9376-E6B6D1B43BD5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
130
msvc_build/aarch64/Ffi_staticLib.vcxproj
Normal file
130
msvc_build/aarch64/Ffi_staticLib.vcxproj
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{115502C0-BE05-4767-BF19-5C87D805FAD6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>FfistaticLib</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Ffi_staticLib_arm64</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>FFI_BUILDING_DLL;_DEBUG;_LIB;USE_DL_PREFIX;ARM64;_M_ARM64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<OmitFramePointers>
|
||||
</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>FFI_BUILDING_DLL;USE_DL_PREFIX;ARM64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<AdditionalUsingDirectories>..\..\src;..\..\src\aarch64;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include=".\aarch64_include\ffi.h" />
|
||||
<ClInclude Include=".\aarch64_include\fficonfig.h" />
|
||||
<ClInclude Include="..\..\src\aarch64\ffitarget.h" />
|
||||
<ClInclude Include="..\include\ffi_cfi.h" />
|
||||
<ClInclude Include="..\include\ffi_common.h" />
|
||||
<ClInclude Include="..\..\src\aarch64\internal.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\closures.c" />
|
||||
<ClCompile Include="..\..\src\dlmalloc.c" />
|
||||
<ClCompile Include="..\..\src\aarch64\ffi.c" />
|
||||
<ClCompile Include="..\..\src\prep_cif.c" />
|
||||
<ClCompile Include="..\..\src\types.c" />
|
||||
</ItemGroup>
|
||||
<!--ItemGroup>
|
||||
<Object Include="..\..\..\..\Downloads\libffi-master-win64\src\aarch64\win64_armasm.obj" />
|
||||
</ItemGroup-->
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\src\aarch64\win64_armasm.S">
|
||||
<!--ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild -->
|
||||
<Command>
|
||||
cl /FA /EP /nologo /I"..\..\include" /I".\aarch64_include" /I"..\..\src\aarch64" "%(FullPath)" > $(IntDir)win64_armasm.i
|
||||
armasm64 $(IntDir)win64_armasm.i /I"src\" /I"..\..\include" /I"..\..\src\aarch64" -o "$(IntDir)win64_armasm.obj"
|
||||
</Command>
|
||||
<Outputs>win64_armasm.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
57
msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
Normal file
57
msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\ffi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffi_cfi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffi_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\fficonfig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffitarget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\internal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\closures.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dlmalloc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ffi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\prep_cif.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\types.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="src\win64_armasm.S" />
|
||||
</ItemGroup>
|
||||
</Project>
|
4
msvc_build/aarch64/Ffi_staticLib.vcxproj.user
Normal file
4
msvc_build/aarch64/Ffi_staticLib.vcxproj.user
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
511
msvc_build/aarch64/aarch64_include/ffi.h
Normal file
511
msvc_build/aarch64/aarch64_include/ffi.h
Normal file
@ -0,0 +1,511 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Most of the API is documented in doc/libffi.texi.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing and
|
||||
unpacking on architectures for which it can be avoided. Routines
|
||||
are provided to emulate the raw API if the underlying platform
|
||||
doesn't allow faster implementation.
|
||||
|
||||
More details on the raw API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef AARCH64
|
||||
#define AARCH64
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t
|
||||
can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
/* Need minimal decorations for DLLs to work on Windows. GCC has
|
||||
autoimport and autoexport. Always mark externally visible symbols
|
||||
as dllimport for MSVC clients, even if it means an extra indirection
|
||||
when using the static version of the library.
|
||||
Besides, as a workaround, they can define FFI_BUILDING if they
|
||||
*know* they are going to link with the static library. */
|
||||
#if defined _MSC_VER
|
||||
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
|
||||
# define FFI_API __declspec(dllexport)
|
||||
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
|
||||
# define FFI_API __declspec(dllimport)
|
||||
# else /* Building/linking static library */
|
||||
# define FFI_API
|
||||
# endif
|
||||
#else
|
||||
# define FFI_API
|
||||
#endif
|
||||
|
||||
/* The externally visible type declarations also need the MSVC DLL
|
||||
decorations, or they will not be exported from the object file. */
|
||||
#if defined LIBFFI_HIDE_BASIC_TYPES
|
||||
# define FFI_EXTERN FFI_API
|
||||
#else
|
||||
# define FFI_EXTERN extern FFI_API
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c. */
|
||||
FFI_EXTERN ffi_type ffi_type_void;
|
||||
FFI_EXTERN ffi_type ffi_type_uint8;
|
||||
FFI_EXTERN ffi_type ffi_type_sint8;
|
||||
FFI_EXTERN ffi_type ffi_type_uint16;
|
||||
FFI_EXTERN ffi_type ffi_type_sint16;
|
||||
FFI_EXTERN ffi_type ffi_type_uint32;
|
||||
FFI_EXTERN ffi_type ffi_type_sint32;
|
||||
FFI_EXTERN ffi_type ffi_type_uint64;
|
||||
FFI_EXTERN ffi_type ffi_type_sint64;
|
||||
FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#ifndef _M_ARM64
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
FFI_EXTERN ffi_type ffi_type_complex_float;
|
||||
FFI_EXTERN ffi_type ffi_type_complex_double;
|
||||
#if 1
|
||||
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
|
||||
#else
|
||||
#define ffi_type_complex_longdouble ffi_type_complex_double
|
||||
#endif
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
|
||||
FFI_API
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
FFI_API size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter
|
||||
packing, even on 64-bit machines. I.e. on 64-bit machines longs
|
||||
and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
FFI_API
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
FFI_API
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
FFI_API
|
||||
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
FFI_API
|
||||
size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
} ffi_closure
|
||||
#ifdef __GNUC__
|
||||
__attribute__((aligned (8)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifndef __GNUC__
|
||||
# ifdef __sgi
|
||||
# pragma pack 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FFI_API void *ffi_closure_alloc (size_t size, void **code);
|
||||
FFI_API void ffi_closure_free (void *);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data)
|
||||
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
|
||||
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
__attribute__((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
#ifdef __sgi
|
||||
# pragma pack 8
|
||||
#endif
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
#if 0
|
||||
void *trampoline_table;
|
||||
void *trampoline_table_entry;
|
||||
#else
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
#endif
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* If this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the translation, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
FFI_API ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
#if FFI_GO_CLOSURES
|
||||
|
||||
typedef struct {
|
||||
void *tramp;
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
} ffi_go_closure;
|
||||
|
||||
FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*));
|
||||
|
||||
FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure);
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
FFI_API
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
FFI_API
|
||||
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
size_t *offsets);
|
||||
|
||||
/* Useful for eliminating compiler warnings. */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#ifndef _M_ARM64
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
#define FFI_TYPE_COMPLEX 15
|
||||
/* This should always refer to the last type code (for sanity checks). */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
219
msvc_build/aarch64/aarch64_include/fficonfig.h
Normal file
219
msvc_build/aarch64/aarch64_include/fficonfig.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
|
||||
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define to the flags needed for the .section .eh_frame directive. */
|
||||
#define EH_FRAME_FLAGS "a"
|
||||
|
||||
/* Define this if you want extra debugging. */
|
||||
/* #undef FFI_DEBUG */
|
||||
|
||||
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
|
||||
/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
|
||||
|
||||
/* Define this if you want to enable pax emulated trampolines */
|
||||
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
|
||||
|
||||
/* Cannot use malloc on this target, so, we revert to alternative means */
|
||||
/* #undef FFI_MMAP_EXEC_WRIT */
|
||||
|
||||
/* Define this if you do not want support for the raw API. */
|
||||
/* #undef FFI_NO_RAW_API */
|
||||
|
||||
/* Define this if you do not want support for aggregate types. */
|
||||
/* #undef FFI_NO_STRUCTS */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/*#define HAVE_ALLOCA_H 1 */
|
||||
|
||||
/* Define if your assembler supports .cfi_* directives. */
|
||||
#define HAVE_AS_CFI_PSEUDO_OP 1
|
||||
|
||||
/* Define if your assembler supports .register. */
|
||||
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
|
||||
|
||||
/* Define if the compiler uses zarch features. */
|
||||
/* #undef HAVE_AS_S390_ZARCH */
|
||||
|
||||
/* Define if your assembler and linker support unaligned PC relative relocs.
|
||||
*/
|
||||
/* #undef HAVE_AS_SPARC_UA_PCREL */
|
||||
|
||||
/* Define if your assembler supports unwind section type. */
|
||||
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
|
||||
|
||||
/* Define if your assembler supports PC relative relocs. */
|
||||
/* #undef HAVE_AS_X86_PCREL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define if __attribute__((visibility("hidden"))) is supported. */
|
||||
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
|
||||
/* Define if you support more than one size of the long double type */
|
||||
/* #undef HAVE_LONG_DOUBLE_VARIANT */
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
#define HAVE_MKOSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
#define HAVE_MMAP_ANON 1
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
#define HAVE_MMAP_DEV_ZERO 1
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
#define HAVE_MMAP_FILE 1
|
||||
|
||||
/* Define if .eh_frame sections should be read-only. */
|
||||
#define HAVE_RO_EH_FRAME 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
//#define HAVE_STDLIB_H 0
|
||||
#define LACKS_STDLIB_H 1
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if GNU symbol versioning is used for libatomic. */
|
||||
#define LIBFFI_GNU_SYMBOL_VERSIONING 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libffi"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libffi"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libffi 3.3-rc0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libffi"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "3.3-rc0"
|
||||
|
||||
/* The size of `double', as computed by sizeof. */
|
||||
#define SIZEOF_DOUBLE 8
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_DOUBLE 8
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at runtime.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if symbols are underscored. */
|
||||
/* #undef SYMBOL_UNDERSCORE */
|
||||
|
||||
/* Define this if you are using Purify and want to suppress spurious messages.
|
||||
*/
|
||||
/* #undef USING_PURIFY */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "3.3-rc0"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
|
||||
#ifdef LIBFFI_ASM
|
||||
#ifdef __APPLE__
|
||||
#define FFI_HIDDEN(name) .private_extern name
|
||||
#else
|
||||
#define FFI_HIDDEN(name) .hidden name
|
||||
#endif
|
||||
#else
|
||||
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
#else
|
||||
#ifdef LIBFFI_ASM
|
||||
#define FFI_HIDDEN(name)
|
||||
#else
|
||||
#define FFI_HIDDEN
|
||||
#endif
|
||||
#endif
|
||||
|
353
msvcc.sh
Executable file
353
msvcc.sh
Executable file
@ -0,0 +1,353 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MSVC wrappificator.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Timothy Wall <twalljava@dev.java.net>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Daniel Witte <dwitte@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
|
||||
# format and translated into something sensible for cl or ml.
|
||||
#
|
||||
|
||||
args_orig=$@
|
||||
args="-nologo -W3"
|
||||
linkargs=
|
||||
static_crt=
|
||||
debug_crt=
|
||||
cl="cl"
|
||||
ml="ml"
|
||||
safeseh="-safeseh"
|
||||
output=
|
||||
libpaths=
|
||||
libversion=7
|
||||
verbose=
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1
|
||||
in
|
||||
--verbose)
|
||||
verbose=1
|
||||
shift 1
|
||||
;;
|
||||
--version)
|
||||
args="-help"
|
||||
shift 1
|
||||
;;
|
||||
-fexceptions)
|
||||
# Don't enable exceptions for now.
|
||||
#args="$args -EHac"
|
||||
shift 1
|
||||
;;
|
||||
-m32)
|
||||
shift 1
|
||||
;;
|
||||
-m64)
|
||||
ml="ml64" # "$MSVC/x86_amd64/ml64"
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-marm)
|
||||
ml='armasm'
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-marm64)
|
||||
ml='armasm64'
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-clang-cl)
|
||||
cl="clang-cl"
|
||||
shift 1
|
||||
;;
|
||||
-O0)
|
||||
args="$args -Od"
|
||||
shift 1
|
||||
;;
|
||||
-O*)
|
||||
# Runtime error checks (enabled by setting -RTC1 in the -DFFI_DEBUG
|
||||
# case below) are not compatible with optimization flags and will
|
||||
# cause the build to fail. Therefore, drop the optimization flag if
|
||||
# -DFFI_DEBUG is also set.
|
||||
case $args_orig in
|
||||
*-DFFI_DEBUG*)
|
||||
args="$args"
|
||||
;;
|
||||
*)
|
||||
# The ax_cc_maxopt.m4 macro from the upstream autoconf-archive
|
||||
# project doesn't support MSVC and therefore ends up trying to
|
||||
# use -O3. Use the equivalent "max optimization" flag for MSVC
|
||||
# instead of erroring out.
|
||||
case $1 in
|
||||
-O3)
|
||||
args="$args -O2"
|
||||
;;
|
||||
*)
|
||||
args="$args $1"
|
||||
;;
|
||||
esac
|
||||
opt="true"
|
||||
;;
|
||||
esac
|
||||
shift 1
|
||||
;;
|
||||
-g)
|
||||
# Enable debug symbol generation.
|
||||
args="$args -Zi"
|
||||
shift 1
|
||||
;;
|
||||
-DFFI_DEBUG)
|
||||
# Enable runtime error checks.
|
||||
args="$args -RTC1"
|
||||
defines="$defines $1"
|
||||
shift 1
|
||||
;;
|
||||
-DUSE_STATIC_RTL)
|
||||
# Link against static CRT.
|
||||
static_crt=1
|
||||
shift 1
|
||||
;;
|
||||
-DUSE_DEBUG_RTL)
|
||||
# Link against debug CRT.
|
||||
debug_crt=1
|
||||
shift 1
|
||||
;;
|
||||
-c)
|
||||
args="$args -c"
|
||||
args="$(echo $args | sed 's%/Fe%/Fo%g')"
|
||||
single="-c"
|
||||
shift 1
|
||||
;;
|
||||
-D*=*)
|
||||
name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
|
||||
value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
|
||||
args="$args -D${name}='$value'"
|
||||
defines="$defines -D${name}='$value'"
|
||||
shift 1
|
||||
;;
|
||||
-D*)
|
||||
args="$args $1"
|
||||
defines="$defines $1"
|
||||
shift 1
|
||||
;;
|
||||
-I)
|
||||
p=$(cygpath -m $2)
|
||||
args="$args -I$p"
|
||||
includes="$includes -I$p"
|
||||
shift 2
|
||||
;;
|
||||
-I*)
|
||||
p=$(cygpath -m ${1#-I})
|
||||
args="$args -I$p"
|
||||
includes="$includes -I$p"
|
||||
shift 1
|
||||
;;
|
||||
-L)
|
||||
p=$(cygpath -m $2)
|
||||
linkargs="$linkargs -LIBPATH:$p"
|
||||
shift 2
|
||||
;;
|
||||
-L*)
|
||||
p=$(cygpath -m ${1#-L})
|
||||
linkargs="$linkargs -LIBPATH:$p"
|
||||
shift 1
|
||||
;;
|
||||
-link)
|
||||
# add next argument verbatim to linker args
|
||||
linkargs="$linkargs $2"
|
||||
shift 2
|
||||
;;
|
||||
-l*)
|
||||
case $1
|
||||
in
|
||||
-lffi)
|
||||
linkargs="$linkargs lib${1#-l}-${libversion}.lib"
|
||||
;;
|
||||
*)
|
||||
# ignore other libraries like -lm, hope they are
|
||||
# covered by MSVCRT
|
||||
# linkargs="$linkargs ${1#-l}.lib"
|
||||
;;
|
||||
esac
|
||||
shift 1
|
||||
;;
|
||||
-W|-Wextra)
|
||||
# TODO map extra warnings
|
||||
shift 1
|
||||
;;
|
||||
-Wall)
|
||||
# -Wall on MSVC is overzealous, and we already build with -W3. Nothing
|
||||
# to do here.
|
||||
shift 1
|
||||
;;
|
||||
-pedantic)
|
||||
# libffi tests -pedantic with -Wall, so drop it also.
|
||||
shift 1
|
||||
;;
|
||||
-warn)
|
||||
# ignore -warn all from libtool as well.
|
||||
if test "$2" = "all"; then
|
||||
shift 2
|
||||
else
|
||||
args="$args -warn"
|
||||
shift 1
|
||||
fi
|
||||
;;
|
||||
-Werror)
|
||||
args="$args -WX"
|
||||
shift 1
|
||||
;;
|
||||
-W*)
|
||||
# TODO map specific warnings
|
||||
shift 1
|
||||
;;
|
||||
-S)
|
||||
args="$args -FAs"
|
||||
shift 1
|
||||
;;
|
||||
-o)
|
||||
outdir="$(dirname $2)"
|
||||
base="$(basename $2|sed 's/\.[^.]*//g')"
|
||||
if [ -n "$single" ]; then
|
||||
output="-Fo$2"
|
||||
else
|
||||
output="-Fe$2"
|
||||
fi
|
||||
armasm_output="-o $2"
|
||||
if [ -n "$assembly" ]; then
|
||||
args="$args $output"
|
||||
else
|
||||
args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*.S)
|
||||
src=$1
|
||||
assembly="true"
|
||||
shift 1
|
||||
;;
|
||||
*.c)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
# Assume it's an MSVC argument, and pass it through.
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$linkargs" ]; then
|
||||
|
||||
# If -Zi is specified, certain optimizations are implicitly disabled
|
||||
# by MSVC. Add back those optimizations if this is an optimized build.
|
||||
# NOTE: These arguments must come after all others.
|
||||
if [ -n "$opt" ]; then
|
||||
linkargs="$linkargs -OPT:REF -OPT:ICF -INCREMENTAL:NO"
|
||||
fi
|
||||
|
||||
args="$args -link $linkargs"
|
||||
fi
|
||||
|
||||
if [ -n "$static_crt" ]; then
|
||||
md=-MT
|
||||
else
|
||||
md=-MD
|
||||
fi
|
||||
|
||||
if [ -n "$debug_crt" ]; then
|
||||
md="${md}d"
|
||||
fi
|
||||
|
||||
if [ -n "$assembly" ]; then
|
||||
if [ -z "$outdir" ]; then
|
||||
outdir="."
|
||||
fi
|
||||
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
|
||||
|
||||
if [ $ml = "armasm" ]; then
|
||||
defines="$defines -D_M_ARM"
|
||||
fi
|
||||
|
||||
if [ $ml = "armasm64" ]; then
|
||||
defines="$defines -D_M_ARM64"
|
||||
fi
|
||||
|
||||
if test -n "$verbose"; then
|
||||
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
|
||||
fi
|
||||
|
||||
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
|
||||
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
|
||||
if [ $ml = "armasm" ]; then
|
||||
args="-nologo -g -oldit $armasm_output $ppsrc -errorReport:prompt"
|
||||
elif [ $ml = "armasm64" ]; then
|
||||
args="-nologo -g $armasm_output $ppsrc -errorReport:prompt"
|
||||
else
|
||||
args="-nologo $safeseh $single $output $ppsrc"
|
||||
fi
|
||||
|
||||
if test -n "$verbose"; then
|
||||
echo "$ml $args"
|
||||
fi
|
||||
|
||||
eval "\"$ml\" $args"
|
||||
result=$?
|
||||
|
||||
# required to fix ml64 broken output?
|
||||
#mv *.obj $outdir
|
||||
else
|
||||
args="$md $args"
|
||||
|
||||
if test -n "$verbose"; then
|
||||
echo "$cl $args"
|
||||
fi
|
||||
# Return an error code of 1 if an invalid command line parameter is passed
|
||||
# instead of just ignoring it. Any output that is not a warning or an
|
||||
# error is filtered so this command behaves more like gcc. cl.exe prints
|
||||
# the name of the compiled file otherwise, which breaks the dejagnu checks
|
||||
# for excess warnings and errors.
|
||||
eval "(\"$cl\" $args 2>&1 1>&3 | \
|
||||
awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1 | \
|
||||
awk '/warning|error/'"
|
||||
result=$?
|
||||
fi
|
||||
|
||||
exit $result
|
||||
|
||||
# vim: noai:ts=4:sw=4
|
1009
src/aarch64/ffi.c
Normal file
1009
src/aarch64/ffi.c
Normal file
File diff suppressed because it is too large
Load Diff
92
src/aarch64/ffitarget.h
Normal file
92
src/aarch64/ffitarget.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
#ifdef __ILP32__
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
#define FFI_SIZEOF_JAVA_RAW 4
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#elif defined(_M_ARM64)
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#else
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
#endif
|
||||
|
||||
typedef enum ffi_abi
|
||||
{
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_LAST_ABI,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
|
||||
#else
|
||||
#error "No trampoline table implementation"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef _M_ARM64
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
|
||||
#endif
|
||||
|
||||
/* ---- Internal ---- */
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
|
||||
#elif !defined(_M_ARM64)
|
||||
/* iOS and Windows reserve x18 for the system. Disable Go closures until
|
||||
a new static chain is chosen. */
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#endif
|
||||
|
||||
#ifndef _M_ARM64
|
||||
/* No complex type on Windows */
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
#endif
|
||||
|
||||
#endif
|
67
src/aarch64/internal.h
Normal file
67
src/aarch64/internal.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#define AARCH64_RET_VOID 0
|
||||
#define AARCH64_RET_INT64 1
|
||||
#define AARCH64_RET_INT128 2
|
||||
|
||||
#define AARCH64_RET_UNUSED3 3
|
||||
#define AARCH64_RET_UNUSED4 4
|
||||
#define AARCH64_RET_UNUSED5 5
|
||||
#define AARCH64_RET_UNUSED6 6
|
||||
#define AARCH64_RET_UNUSED7 7
|
||||
|
||||
/* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4,
|
||||
so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT). */
|
||||
#define AARCH64_RET_S4 8
|
||||
#define AARCH64_RET_S3 9
|
||||
#define AARCH64_RET_S2 10
|
||||
#define AARCH64_RET_S1 11
|
||||
|
||||
#define AARCH64_RET_D4 12
|
||||
#define AARCH64_RET_D3 13
|
||||
#define AARCH64_RET_D2 14
|
||||
#define AARCH64_RET_D1 15
|
||||
|
||||
#define AARCH64_RET_Q4 16
|
||||
#define AARCH64_RET_Q3 17
|
||||
#define AARCH64_RET_Q2 18
|
||||
#define AARCH64_RET_Q1 19
|
||||
|
||||
/* Note that each of the sub-64-bit integers gets two entries. */
|
||||
#define AARCH64_RET_UINT8 20
|
||||
#define AARCH64_RET_UINT16 22
|
||||
#define AARCH64_RET_UINT32 24
|
||||
|
||||
#define AARCH64_RET_SINT8 26
|
||||
#define AARCH64_RET_SINT16 28
|
||||
#define AARCH64_RET_SINT32 30
|
||||
|
||||
#define AARCH64_RET_MASK 31
|
||||
|
||||
#define AARCH64_RET_IN_MEM (1 << 5)
|
||||
#define AARCH64_RET_NEED_COPY (1 << 6)
|
||||
|
||||
#define AARCH64_FLAG_ARG_V_BIT 7
|
||||
#define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT)
|
||||
|
||||
#define N_X_ARG_REG 8
|
||||
#define N_V_ARG_REG 8
|
||||
#define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8)
|
440
src/aarch64/sysv.S
Normal file
440
src/aarch64/sysv.S
Normal file
@ -0,0 +1,440 @@
|
||||
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#if defined(__aarch64__) || defined(__arm64__)
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
#else
|
||||
#define CNAME(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __AARCH64EB__
|
||||
# define BE(X) X
|
||||
#else
|
||||
# define BE(X) 0
|
||||
#endif
|
||||
|
||||
#ifdef __ILP32__
|
||||
#define PTR_REG(n) w##n
|
||||
#else
|
||||
#define PTR_REG(n) x##n
|
||||
#endif
|
||||
|
||||
#ifdef __ILP32__
|
||||
#define PTR_SIZE 4
|
||||
#else
|
||||
#define PTR_SIZE 8
|
||||
#endif
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
/* ffi_call_SYSV
|
||||
extern void ffi_call_SYSV (void *stack, void *frame,
|
||||
void (*fn)(void), void *rvalue,
|
||||
int flags, void *closure);
|
||||
|
||||
Therefore on entry we have:
|
||||
|
||||
x0 stack
|
||||
x1 frame
|
||||
x2 fn
|
||||
x3 rvalue
|
||||
x4 flags
|
||||
x5 closure
|
||||
*/
|
||||
|
||||
cfi_startproc
|
||||
CNAME(ffi_call_SYSV):
|
||||
/* Use a stack frame allocated by our caller. */
|
||||
cfi_def_cfa(x1, 32);
|
||||
stp x29, x30, [x1]
|
||||
mov x29, x1
|
||||
mov sp, x0
|
||||
cfi_def_cfa_register(x29)
|
||||
cfi_rel_offset (x29, 0)
|
||||
cfi_rel_offset (x30, 8)
|
||||
|
||||
mov x9, x2 /* save fn */
|
||||
mov x8, x3 /* install structure return */
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
mov x18, x5 /* install static chain */
|
||||
#endif
|
||||
stp x3, x4, [x29, #16] /* save rvalue and flags */
|
||||
|
||||
/* Load the vector argument passing registers, if necessary. */
|
||||
tbz w4, #AARCH64_FLAG_ARG_V_BIT, 1f
|
||||
ldp q0, q1, [sp, #0]
|
||||
ldp q2, q3, [sp, #32]
|
||||
ldp q4, q5, [sp, #64]
|
||||
ldp q6, q7, [sp, #96]
|
||||
1:
|
||||
/* Load the core argument passing registers, including
|
||||
the structure return pointer. */
|
||||
ldp x0, x1, [sp, #16*N_V_ARG_REG + 0]
|
||||
ldp x2, x3, [sp, #16*N_V_ARG_REG + 16]
|
||||
ldp x4, x5, [sp, #16*N_V_ARG_REG + 32]
|
||||
ldp x6, x7, [sp, #16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Deallocate the context, leaving the stacked arguments. */
|
||||
add sp, sp, #CALL_CONTEXT_SIZE
|
||||
|
||||
blr x9 /* call fn */
|
||||
|
||||
ldp x3, x4, [x29, #16] /* reload rvalue and flags */
|
||||
|
||||
/* Partially deconstruct the stack frame. */
|
||||
mov sp, x29
|
||||
cfi_def_cfa_register (sp)
|
||||
ldp x29, x30, [x29]
|
||||
|
||||
/* Save the return value as directed. */
|
||||
adr x5, 0f
|
||||
and w4, w4, #AARCH64_RET_MASK
|
||||
add x5, x5, x4, lsl #3
|
||||
br x5
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes.
|
||||
For integer data, note that we're storing into ffi_arg
|
||||
and therefore we want to extend to 64 bits; these types
|
||||
have two consecutive entries allocated for them. */
|
||||
.align 4
|
||||
0: ret /* VOID */
|
||||
nop
|
||||
1: str x0, [x3] /* INT64 */
|
||||
ret
|
||||
2: stp x0, x1, [x3] /* INT128 */
|
||||
ret
|
||||
3: brk #1000 /* UNUSED */
|
||||
ret
|
||||
4: brk #1000 /* UNUSED */
|
||||
ret
|
||||
5: brk #1000 /* UNUSED */
|
||||
ret
|
||||
6: brk #1000 /* UNUSED */
|
||||
ret
|
||||
7: brk #1000 /* UNUSED */
|
||||
ret
|
||||
8: st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */
|
||||
ret
|
||||
9: st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */
|
||||
ret
|
||||
10: stp s0, s1, [x3] /* S2 */
|
||||
ret
|
||||
11: str s0, [x3] /* S1 */
|
||||
ret
|
||||
12: st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */
|
||||
ret
|
||||
13: st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */
|
||||
ret
|
||||
14: stp d0, d1, [x3] /* D2 */
|
||||
ret
|
||||
15: str d0, [x3] /* D1 */
|
||||
ret
|
||||
16: str q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
17: str q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
18: stp q0, q1, [x3] /* Q2 */
|
||||
ret
|
||||
19: str q0, [x3] /* Q1 */
|
||||
ret
|
||||
20: uxtb w0, w0 /* UINT8 */
|
||||
str x0, [x3]
|
||||
21: ret /* reserved */
|
||||
nop
|
||||
22: uxth w0, w0 /* UINT16 */
|
||||
str x0, [x3]
|
||||
23: ret /* reserved */
|
||||
nop
|
||||
24: mov w0, w0 /* UINT32 */
|
||||
str x0, [x3]
|
||||
25: ret /* reserved */
|
||||
nop
|
||||
26: sxtb x0, w0 /* SINT8 */
|
||||
str x0, [x3]
|
||||
27: ret /* reserved */
|
||||
nop
|
||||
28: sxth x0, w0 /* SINT16 */
|
||||
str x0, [x3]
|
||||
29: ret /* reserved */
|
||||
nop
|
||||
30: sxtw x0, w0 /* SINT32 */
|
||||
str x0, [x3]
|
||||
31: ret /* reserved */
|
||||
nop
|
||||
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_call_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_call_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_call_SYSV), #function
|
||||
.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
|
||||
#endif
|
||||
|
||||
/* ffi_closure_SYSV
|
||||
|
||||
Closure invocation glue. This is the low level code invoked directly by
|
||||
the closure trampoline to setup and call a closure.
|
||||
|
||||
On entry x17 points to a struct ffi_closure, x16 has been clobbered
|
||||
all other registers are preserved.
|
||||
|
||||
We allocate a call context and save the argument passing registers,
|
||||
then invoked the generic C ffi_closure_SYSV_inner() function to do all
|
||||
the real work, on return we load the result passing registers back from
|
||||
the call context.
|
||||
*/
|
||||
|
||||
#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
|
||||
|
||||
.align 4
|
||||
CNAME(ffi_closure_SYSV_V):
|
||||
cfi_startproc
|
||||
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
|
||||
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
|
||||
cfi_rel_offset (x29, 0)
|
||||
cfi_rel_offset (x30, 8)
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
b 0f
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_closure_SYSV_V)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_SYSV_V))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_SYSV_V), #function
|
||||
.size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)
|
||||
#endif
|
||||
|
||||
.align 4
|
||||
cfi_startproc
|
||||
CNAME(ffi_closure_SYSV):
|
||||
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
|
||||
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
|
||||
cfi_rel_offset (x29, 0)
|
||||
cfi_rel_offset (x30, 8)
|
||||
0:
|
||||
mov x29, sp
|
||||
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */
|
||||
ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */
|
||||
.Ldo_closure:
|
||||
add x3, sp, #16 /* load context */
|
||||
add x4, sp, #ffi_closure_SYSV_FS /* load stack */
|
||||
add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */
|
||||
mov x6, x8 /* load struct_rval */
|
||||
bl CNAME(ffi_closure_SYSV_inner)
|
||||
|
||||
/* Load the return value as directed. */
|
||||
adr x1, 0f
|
||||
and w0, w0, #AARCH64_RET_MASK
|
||||
add x1, x1, x0, lsl #3
|
||||
add x3, sp, #16+CALL_CONTEXT_SIZE
|
||||
br x1
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes. */
|
||||
.align 4
|
||||
0: b 99f /* VOID */
|
||||
nop
|
||||
1: ldr x0, [x3] /* INT64 */
|
||||
b 99f
|
||||
2: ldp x0, x1, [x3] /* INT128 */
|
||||
b 99f
|
||||
3: brk #1000 /* UNUSED */
|
||||
nop
|
||||
4: brk #1000 /* UNUSED */
|
||||
nop
|
||||
5: brk #1000 /* UNUSED */
|
||||
nop
|
||||
6: brk #1000 /* UNUSED */
|
||||
nop
|
||||
7: brk #1000 /* UNUSED */
|
||||
nop
|
||||
8: ldr s3, [x3, #12] /* S4 */
|
||||
nop
|
||||
9: ldr s2, [x3, #8] /* S3 */
|
||||
nop
|
||||
10: ldp s0, s1, [x3] /* S2 */
|
||||
b 99f
|
||||
11: ldr s0, [x3] /* S1 */
|
||||
b 99f
|
||||
12: ldr d3, [x3, #24] /* D4 */
|
||||
nop
|
||||
13: ldr d2, [x3, #16] /* D3 */
|
||||
nop
|
||||
14: ldp d0, d1, [x3] /* D2 */
|
||||
b 99f
|
||||
15: ldr d0, [x3] /* D1 */
|
||||
b 99f
|
||||
16: ldr q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
17: ldr q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
18: ldp q0, q1, [x3] /* Q2 */
|
||||
b 99f
|
||||
19: ldr q0, [x3] /* Q1 */
|
||||
b 99f
|
||||
20: ldrb w0, [x3, #BE(7)] /* UINT8 */
|
||||
b 99f
|
||||
21: brk #1000 /* reserved */
|
||||
nop
|
||||
22: ldrh w0, [x3, #BE(6)] /* UINT16 */
|
||||
b 99f
|
||||
23: brk #1000 /* reserved */
|
||||
nop
|
||||
24: ldr w0, [x3, #BE(4)] /* UINT32 */
|
||||
b 99f
|
||||
25: brk #1000 /* reserved */
|
||||
nop
|
||||
26: ldrsb x0, [x3, #BE(7)] /* SINT8 */
|
||||
b 99f
|
||||
27: brk #1000 /* reserved */
|
||||
nop
|
||||
28: ldrsh x0, [x3, #BE(6)] /* SINT16 */
|
||||
b 99f
|
||||
29: brk #1000 /* reserved */
|
||||
nop
|
||||
30: ldrsw x0, [x3, #BE(4)] /* SINT32 */
|
||||
nop
|
||||
31: /* reserved */
|
||||
99: ldp x29, x30, [sp], #ffi_closure_SYSV_FS
|
||||
cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
|
||||
cfi_restore (x29)
|
||||
cfi_restore (x30)
|
||||
ret
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_closure_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_SYSV), #function
|
||||
.size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)
|
||||
#endif
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#include <mach/machine/vm_param.h>
|
||||
.align PAGE_MAX_SHIFT
|
||||
CNAME(ffi_closure_trampoline_table_page):
|
||||
.rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
|
||||
adr x16, -PAGE_MAX_SIZE
|
||||
ldp x17, x16, [x16]
|
||||
br x16
|
||||
nop /* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */
|
||||
.endr
|
||||
|
||||
.globl CNAME(ffi_closure_trampoline_table_page)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_trampoline_table_page), #function
|
||||
.size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
|
||||
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
.align 4
|
||||
CNAME(ffi_go_closure_SYSV_V):
|
||||
cfi_startproc
|
||||
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
|
||||
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
|
||||
cfi_rel_offset (x29, 0)
|
||||
cfi_rel_offset (x30, 8)
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
b 0f
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_go_closure_SYSV_V)
|
||||
FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_go_closure_SYSV_V), #function
|
||||
.size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)
|
||||
#endif
|
||||
|
||||
.align 4
|
||||
cfi_startproc
|
||||
CNAME(ffi_go_closure_SYSV):
|
||||
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
|
||||
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
|
||||
cfi_rel_offset (x29, 0)
|
||||
cfi_rel_offset (x30, 8)
|
||||
0:
|
||||
mov x29, sp
|
||||
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
|
||||
mov x2, x18 /* load user_data */
|
||||
b .Ldo_closure
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_go_closure_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_go_closure_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_go_closure_SYSV), #function
|
||||
.size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)
|
||||
#endif
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
#endif /* __arm64__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
506
src/aarch64/win64_armasm.S
Normal file
506
src/aarch64/win64_armasm.S
Normal file
@ -0,0 +1,506 @@
|
||||
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
|
||||
OPT 2 /*disable listing */
|
||||
/* For some macros to add unwind information */
|
||||
#include "ksarm64.h"
|
||||
OPT 1 /*re-enable listing */
|
||||
|
||||
#define BE(X) 0
|
||||
#define PTR_REG(n) x##n
|
||||
#define PTR_SIZE 8
|
||||
|
||||
IMPORT ffi_closure_SYSV_inner
|
||||
EXPORT ffi_call_SYSV
|
||||
EXPORT ffi_closure_SYSV_V
|
||||
EXPORT ffi_closure_SYSV
|
||||
EXPORT extend_hfa_type
|
||||
EXPORT compress_hfa_type
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
EXPORT ffi_go_closure_SYSV_V
|
||||
EXPORT ffi_go_closure_SYSV
|
||||
#endif
|
||||
|
||||
TEXTAREA, ALLIGN=8
|
||||
|
||||
/* ffi_call_SYSV
|
||||
extern void ffi_call_SYSV (void *stack, void *frame,
|
||||
void (*fn)(void), void *rvalue,
|
||||
int flags, void *closure);
|
||||
Therefore on entry we have:
|
||||
x0 stack
|
||||
x1 frame
|
||||
x2 fn
|
||||
x3 rvalue
|
||||
x4 flags
|
||||
x5 closure
|
||||
*/
|
||||
|
||||
NESTED_ENTRY ffi_call_SYSV_fake
|
||||
|
||||
/* For unwind information, Windows has to store fp and lr */
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-32!
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_SYSV
|
||||
/* Use a stack frame allocated by our caller. */
|
||||
stp x29, x30, [x1]
|
||||
mov x29, x1
|
||||
mov sp, x0
|
||||
|
||||
mov x9, x2 /* save fn */
|
||||
mov x8, x3 /* install structure return */
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
/*mov x18, x5 install static chain */
|
||||
#endif
|
||||
stp x3, x4, [x29, #16] /* save rvalue and flags */
|
||||
|
||||
/* Load the vector argument passing registers, if necessary. */
|
||||
tbz x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1
|
||||
ldp q0, q1, [sp, #0]
|
||||
ldp q2, q3, [sp, #32]
|
||||
ldp q4, q5, [sp, #64]
|
||||
ldp q6, q7, [sp, #96]
|
||||
|
||||
ffi_call_SYSV_L1
|
||||
/* Load the core argument passing registers, including
|
||||
the structure return pointer. */
|
||||
ldp x0, x1, [sp, #16*N_V_ARG_REG + 0]
|
||||
ldp x2, x3, [sp, #16*N_V_ARG_REG + 16]
|
||||
ldp x4, x5, [sp, #16*N_V_ARG_REG + 32]
|
||||
ldp x6, x7, [sp, #16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Deallocate the context, leaving the stacked arguments. */
|
||||
add sp, sp, #CALL_CONTEXT_SIZE
|
||||
|
||||
blr x9 /* call fn */
|
||||
|
||||
ldp x3, x4, [x29, #16] /* reload rvalue and flags */
|
||||
|
||||
/* Partially deconstruct the stack frame. */
|
||||
mov sp, x29
|
||||
ldp x29, x30, [x29]
|
||||
|
||||
/* Save the return value as directed. */
|
||||
adr x5, ffi_call_SYSV_return
|
||||
and w4, w4, #AARCH64_RET_MASK
|
||||
add x5, x5, x4, lsl #3
|
||||
br x5
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes.
|
||||
For integer data, note that we're storing into ffi_arg
|
||||
and therefore we want to extend to 64 bits; these types
|
||||
have two consecutive entries allocated for them. */
|
||||
ALIGN 4
|
||||
ffi_call_SYSV_return
|
||||
ret /* VOID */
|
||||
nop
|
||||
str x0, [x3] /* INT64 */
|
||||
ret
|
||||
stp x0, x1, [x3] /* INT128 */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */
|
||||
ret
|
||||
st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */
|
||||
ret
|
||||
stp s0, s1, [x3] /* S2 */
|
||||
ret
|
||||
str s0, [x3] /* S1 */
|
||||
ret
|
||||
st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */
|
||||
ret
|
||||
st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */
|
||||
ret
|
||||
stp d0, d1, [x3] /* D2 */
|
||||
ret
|
||||
str d0, [x3] /* D1 */
|
||||
ret
|
||||
str q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
str q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
stp q0, q1, [x3] /* Q2 */
|
||||
ret
|
||||
str q0, [x3] /* Q1 */
|
||||
ret
|
||||
uxtb w0, w0 /* UINT8 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
uxth w0, w0 /* UINT16 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
mov w0, w0 /* UINT32 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxtb x0, w0 /* SINT8 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxth x0, w0 /* SINT16 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxtw x0, w0 /* SINT32 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
|
||||
|
||||
NESTED_END ffi_call_SYSV_fake
|
||||
|
||||
|
||||
/* ffi_closure_SYSV
|
||||
Closure invocation glue. This is the low level code invoked directly by
|
||||
the closure trampoline to setup and call a closure.
|
||||
On entry x17 points to a struct ffi_closure, x16 has been clobbered
|
||||
all other registers are preserved.
|
||||
We allocate a call context and save the argument passing registers,
|
||||
then invoked the generic C ffi_closure_SYSV_inner() function to do all
|
||||
the real work, on return we load the result passing registers back from
|
||||
the call context.
|
||||
*/
|
||||
|
||||
#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
|
||||
|
||||
NESTED_ENTRY ffi_closure_SYSV_V
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
|
||||
b ffi_closure_SYSV_save_argument
|
||||
NESTED_END ffi_closure_SYSV_V
|
||||
|
||||
NESTED_ENTRY ffi_closure_SYSV
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
ffi_closure_SYSV_save_argument
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */
|
||||
ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */
|
||||
|
||||
do_closure
|
||||
add x3, sp, #16 /* load context */
|
||||
add x4, sp, #ffi_closure_SYSV_FS /* load stack */
|
||||
add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */
|
||||
mov x6, x8 /* load struct_rval */
|
||||
|
||||
bl ffi_closure_SYSV_inner
|
||||
|
||||
/* Load the return value as directed. */
|
||||
adr x1, ffi_closure_SYSV_return_base
|
||||
and w0, w0, #AARCH64_RET_MASK
|
||||
add x1, x1, x0, lsl #3
|
||||
add x3, sp, #16+CALL_CONTEXT_SIZE
|
||||
br x1
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes. */
|
||||
ALIGN 8
|
||||
ffi_closure_SYSV_return_base
|
||||
b ffi_closure_SYSV_epilog /* VOID */
|
||||
nop
|
||||
ldr x0, [x3] /* INT64 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldp x0, x1, [x3] /* INT128 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
ldr s3, [x3, #12] /* S4 */
|
||||
nop
|
||||
ldr s2, [x3, #8] /* S3 */
|
||||
nop
|
||||
ldp s0, s1, [x3] /* S2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr s0, [x3] /* S1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr d3, [x3, #24] /* D4 */
|
||||
nop
|
||||
ldr d2, [x3, #16] /* D3 */
|
||||
nop
|
||||
ldp d0, d1, [x3] /* D2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr d0, [x3] /* D1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
ldr q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
ldp q0, q1, [x3] /* Q2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr q0, [x3] /* Q1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldrb w0, [x3, #BE(7)] /* UINT8 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrh w0, [x3, #BE(6)] /* UINT16 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldr w0, [x3, #BE(4)] /* UINT32 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsb x0, [x3, #BE(7)] /* SINT8 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsh x0, [x3, #BE(6)] /* SINT16 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsw x0, [x3, #BE(4)] /* SINT32 */
|
||||
nop
|
||||
/* reserved */
|
||||
|
||||
ffi_closure_SYSV_epilog
|
||||
EPILOG_RESTORE_REG_PAIR x29, x30, #ffi_closure_SYSV_FS!
|
||||
EPILOG_RETURN
|
||||
NESTED_END ffi_closure_SYSV
|
||||
|
||||
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
NESTED_ENTRY ffi_go_closure_SYSV_V
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
b ffi_go_closure_SYSV_save_argument
|
||||
NESTED_END ffi_go_closure_SYSV_V
|
||||
|
||||
NESTED_ENTRY ffi_go_closure_SYSV
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
ffi_go_closure_SYSV_save_argument
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
|
||||
mov x2, x18 /* load user_data */
|
||||
b do_closure
|
||||
NESTED_END ffi_go_closure_SYSV
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
|
||||
/* void extend_hfa_type (void *dest, void *src, int h) */
|
||||
|
||||
LEAF_ENTRY extend_hfa_type
|
||||
|
||||
adr x3, extend_hfa_type_jump_base
|
||||
and w2, w2, #AARCH64_RET_MASK
|
||||
sub x2, x2, #AARCH64_RET_S4
|
||||
add x3, x3, x2, lsl #4
|
||||
br x3
|
||||
|
||||
ALIGN 4
|
||||
extend_hfa_type_jump_base
|
||||
ldp s16, s17, [x1] /* S4 */
|
||||
ldp s18, s19, [x1, #8]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp s16, s17, [x1] /* S3 */
|
||||
ldr s18, [x1, #8]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp s16, s17, [x1] /* S2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr s16, [x1] /* S1 */
|
||||
b extend_hfa_type_store_1
|
||||
nop
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D4 */
|
||||
ldp d18, d19, [x1, #16]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D3 */
|
||||
ldr d18, [x1, #16]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr d16, [x1] /* D1 */
|
||||
b extend_hfa_type_store_1
|
||||
nop
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q4 */
|
||||
ldp q18, q19, [x1, #16]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q3 */
|
||||
ldr q18, [x1, #16]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* Q1 */
|
||||
b extend_hfa_type_store_1
|
||||
|
||||
extend_hfa_type_store_4
|
||||
str q19, [x0, #48]
|
||||
extend_hfa_type_store_3
|
||||
str q18, [x0, #32]
|
||||
extend_hfa_type_store_2
|
||||
str q17, [x0, #16]
|
||||
extend_hfa_type_store_1
|
||||
str q16, [x0]
|
||||
ret
|
||||
|
||||
LEAF_END extend_hfa_type
|
||||
|
||||
|
||||
/* void compress_hfa_type (void *dest, void *reg, int h) */
|
||||
|
||||
LEAF_ENTRY compress_hfa_type
|
||||
|
||||
adr x3, compress_hfa_type_jump_base
|
||||
and w2, w2, #AARCH64_RET_MASK
|
||||
sub x2, x2, #AARCH64_RET_S4
|
||||
add x3, x3, x2, lsl #4
|
||||
br x3
|
||||
|
||||
ALIGN 4
|
||||
compress_hfa_type_jump_base
|
||||
ldp q16, q17, [x1] /* S4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
st4 { v16.s, v17.s, v18.s, v19.s }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* S3 */
|
||||
ldr q18, [x1, #32]
|
||||
st3 { v16.s, v17.s, v18.s }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* S2 */
|
||||
st2 { v16.s, v17.s }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* S1 */
|
||||
st1 { v16.s }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* D4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
st4 { v16.d, v17.d, v18.d, v19.d }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* D3 */
|
||||
ldr q18, [x1, #32]
|
||||
st3 { v16.d, v17.d, v18.d }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* D2 */
|
||||
st2 { v16.d, v17.d }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* D1 */
|
||||
st1 { v16.d }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
b compress_hfa_type_store_q4
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q3 */
|
||||
ldr q18, [x1, #32]
|
||||
b compress_hfa_type_store_q3
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q2 */
|
||||
stp q16, q17, [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* Q1 */
|
||||
str q16, [x0]
|
||||
ret
|
||||
|
||||
compress_hfa_type_store_q4
|
||||
str q19, [x0, #48]
|
||||
compress_hfa_type_store_q3
|
||||
str q18, [x0, #32]
|
||||
stp q16, q17, [x0]
|
||||
ret
|
||||
|
||||
LEAF_END compress_hfa_type
|
||||
|
||||
END
|
521
src/alpha/ffi.c
Normal file
521
src/alpha/ffi.c
Normal file
@ -0,0 +1,521 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Alpha Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal.h"
|
||||
|
||||
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
|
||||
all further uses in this file will refer to the 128-bit type. */
|
||||
#if defined(__LONG_DOUBLE_128__)
|
||||
# if FFI_TYPE_LONGDOUBLE != 4
|
||||
# error FFI_TYPE_LONGDOUBLE out of date
|
||||
# endif
|
||||
#else
|
||||
# undef FFI_TYPE_LONGDOUBLE
|
||||
# define FFI_TYPE_LONGDOUBLE 4
|
||||
#endif
|
||||
|
||||
extern void ffi_call_osf(void *stack, void *frame, unsigned flags,
|
||||
void *raddr, void (*fn)(void), void *closure)
|
||||
FFI_HIDDEN;
|
||||
extern void ffi_closure_osf(void) FFI_HIDDEN;
|
||||
extern void ffi_go_closure_osf(void) FFI_HIDDEN;
|
||||
|
||||
/* Promote a float value to its in-register double representation.
|
||||
Unlike actually casting to double, this does not trap on NaN. */
|
||||
static inline UINT64 lds(void *ptr)
|
||||
{
|
||||
UINT64 ret;
|
||||
asm("lds %0,%1" : "=f"(ret) : "m"(*(UINT32 *)ptr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* And the reverse. */
|
||||
static inline void sts(void *ptr, UINT64 val)
|
||||
{
|
||||
asm("sts %1,%0" : "=m"(*(UINT32 *)ptr) : "f"(val));
|
||||
}
|
||||
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
int flags, i, avn;
|
||||
ffi_type *rtype, *itype;
|
||||
|
||||
if (cif->abi != FFI_OSF)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
/* Compute the size of the argument area. */
|
||||
for (i = 0, avn = cif->nargs; i < avn; i++)
|
||||
{
|
||||
itype = cif->arg_types[i];
|
||||
switch (itype->type)
|
||||
{
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* All take one 8 byte slot. */
|
||||
bytes += 8;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* Passed by value in N slots. */
|
||||
bytes += FFI_ALIGN(itype->size, FFI_SIZEOF_ARG);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* _Complex long double passed by reference; others in 2 slots. */
|
||||
if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE)
|
||||
bytes += 8;
|
||||
else
|
||||
bytes += 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the return type flag */
|
||||
rtype = cif->rtype;
|
||||
switch (rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID);
|
||||
break;
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32);
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT);
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE);
|
||||
break;
|
||||
case FFI_TYPE_UINT8:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8);
|
||||
break;
|
||||
case FFI_TYPE_SINT8:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8);
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16);
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16);
|
||||
break;
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);
|
||||
break;
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* Passed in memory, with a hidden pointer. */
|
||||
flags = ALPHA_RET_IN_MEM;
|
||||
break;
|
||||
case FFI_TYPE_COMPLEX:
|
||||
itype = rtype->elements[0];
|
||||
switch (itype->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_CPLXF, ALPHA_LD_CPLXF);
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_CPLXD, ALPHA_LD_CPLXD);
|
||||
break;
|
||||
default:
|
||||
if (rtype->size <= 8)
|
||||
flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);
|
||||
else
|
||||
flags = ALPHA_RET_IN_MEM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
cif->flags = flags;
|
||||
|
||||
/* Include the hidden structure pointer in args requirement. */
|
||||
if (flags == ALPHA_RET_IN_MEM)
|
||||
bytes += 8;
|
||||
/* Minimum size is 6 slots, so that ffi_call_osf can pop them. */
|
||||
if (bytes < 6*8)
|
||||
bytes = 6*8;
|
||||
cif->bytes = bytes;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
extend_basic_type(void *valp, int type, int argn)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
return *(SINT8 *)valp;
|
||||
case FFI_TYPE_UINT8:
|
||||
return *(UINT8 *)valp;
|
||||
case FFI_TYPE_SINT16:
|
||||
return *(SINT16 *)valp;
|
||||
case FFI_TYPE_UINT16:
|
||||
return *(UINT16 *)valp;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (argn < 6)
|
||||
return lds(valp);
|
||||
/* FALLTHRU */
|
||||
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
/* Note that unsigned 32-bit quantities are sign extended. */
|
||||
return *(SINT32 *)valp;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
return *(UINT64 *)valp;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
unsigned long *argp;
|
||||
long i, avn, argn, flags = cif->flags;
|
||||
ffi_type **arg_types;
|
||||
void *frame;
|
||||
|
||||
/* If the return value is a struct and we don't have a return
|
||||
value address then we need to make one. */
|
||||
if (rvalue == NULL && flags == ALPHA_RET_IN_MEM)
|
||||
rvalue = alloca(cif->rtype->size);
|
||||
|
||||
/* Allocate the space for the arguments, plus 4 words of temp
|
||||
space for ffi_call_osf. */
|
||||
argp = frame = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
|
||||
frame += cif->bytes;
|
||||
|
||||
argn = 0;
|
||||
if (flags == ALPHA_RET_IN_MEM)
|
||||
argp[argn++] = (unsigned long)rvalue;
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
for (i = 0, avn = cif->nargs; i < avn; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
void *valp = avalue[i];
|
||||
int type = ty->type;
|
||||
size_t size;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
argp[argn] = extend_basic_type(valp, type, argn);
|
||||
argn++;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
by_reference:
|
||||
/* Note that 128-bit long double is passed by reference. */
|
||||
argp[argn++] = (unsigned long)valp;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_STRUCT:
|
||||
size = ty->size;
|
||||
memcpy(argp + argn, valp, size);
|
||||
argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
type = ty->elements[0]->type;
|
||||
if (type == FFI_TYPE_LONGDOUBLE)
|
||||
goto by_reference;
|
||||
|
||||
/* Most complex types passed as two separate arguments. */
|
||||
size = ty->elements[0]->size;
|
||||
argp[argn] = extend_basic_type(valp, type, argn);
|
||||
argp[argn + 1] = extend_basic_type(valp + size, type, argn + 1);
|
||||
argn += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
flags = (flags >> ALPHA_ST_SHIFT) & 0xff;
|
||||
ffi_call_osf(argp, frame, flags, rvalue, fn, closure);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
ffi_call_int(cif, fn, rvalue, avalue, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
ffi_call_int(cif, fn, rvalue, avalue, closure);
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
unsigned int *tramp;
|
||||
|
||||
if (cif->abi != FFI_OSF)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
tramp = (unsigned int *) &closure->tramp[0];
|
||||
tramp[0] = 0x47fb0401; /* mov $27,$1 */
|
||||
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
|
||||
tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
|
||||
tramp[3] = 0x47ff041f; /* nop */
|
||||
*(void **) &tramp[4] = ffi_closure_osf;
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
/* Flush the Icache.
|
||||
|
||||
Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
|
||||
instead, since both Compaq as and gas can handle it.
|
||||
|
||||
0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>. */
|
||||
asm volatile ("call_pal 0x86" : : : "memory");
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_go_closure (ffi_go_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*))
|
||||
{
|
||||
if (cif->abi != FFI_OSF)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
closure->tramp = (void *)ffi_go_closure_osf;
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
long FFI_HIDDEN
|
||||
ffi_closure_osf_inner (ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *rvalue, unsigned long *argp)
|
||||
{
|
||||
void **avalue;
|
||||
ffi_type **arg_types;
|
||||
long i, avn, argn, flags;
|
||||
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
flags = cif->flags;
|
||||
argn = 0;
|
||||
|
||||
/* Copy the caller's structure return address to that the closure
|
||||
returns the data directly to the caller. */
|
||||
if (flags == ALPHA_RET_IN_MEM)
|
||||
{
|
||||
rvalue = (void *) argp[0];
|
||||
argn = 1;
|
||||
}
|
||||
|
||||
arg_types = cif->arg_types;
|
||||
|
||||
/* Grab the addresses of the arguments from the stack frame. */
|
||||
for (i = 0, avn = cif->nargs; i < avn; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
int type = ty->type;
|
||||
void *valp = &argp[argn];
|
||||
size_t size;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
argn += 1;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_STRUCT:
|
||||
size = ty->size;
|
||||
argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* Floats coming from registers need conversion from double
|
||||
back to float format. */
|
||||
if (argn < 6)
|
||||
{
|
||||
valp = &argp[argn - 6];
|
||||
sts(valp, argp[argn - 6]);
|
||||
}
|
||||
argn += 1;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
if (argn < 6)
|
||||
valp = &argp[argn - 6];
|
||||
argn += 1;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
by_reference:
|
||||
/* 128-bit long double is passed by reference. */
|
||||
valp = (void *)argp[argn];
|
||||
argn += 1;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
type = ty->elements[0]->type;
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
/* Passed as separate arguments, but they wind up sequential. */
|
||||
break;
|
||||
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
/* Passed as separate arguments. Disjoint, but there's room
|
||||
enough in one slot to hold the pair. */
|
||||
size = ty->elements[0]->size;
|
||||
memcpy(valp + size, valp + 8, size);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* Passed as separate arguments. Disjoint, and each piece
|
||||
may need conversion back to float. */
|
||||
if (argn < 6)
|
||||
{
|
||||
valp = &argp[argn - 6];
|
||||
sts(valp, argp[argn - 6]);
|
||||
}
|
||||
if (argn + 1 < 6)
|
||||
sts(valp + 4, argp[argn + 1 - 6]);
|
||||
else
|
||||
*(UINT32 *)(valp + 4) = argp[argn + 1];
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
/* Passed as separate arguments. Only disjoint if one part
|
||||
is in fp regs and the other is on the stack. */
|
||||
if (argn < 5)
|
||||
valp = &argp[argn - 6];
|
||||
else if (argn == 5)
|
||||
{
|
||||
valp = alloca(16);
|
||||
((UINT64 *)valp)[0] = argp[5 - 6];
|
||||
((UINT64 *)valp)[1] = argp[6];
|
||||
}
|
||||
break;
|
||||
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
goto by_reference;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
argn += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
avalue[i] = valp;
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
fun (cif, rvalue, avalue, user_data);
|
||||
|
||||
/* Tell ffi_closure_osf how to perform return type promotions. */
|
||||
return (flags >> ALPHA_LD_SHIFT) & 0xff;
|
||||
}
|
57
src/alpha/ffitarget.h
Normal file
57
src/alpha/ffitarget.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for Alpha.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_OSF,
|
||||
FFI_LAST_ABI,
|
||||
FFI_DEFAULT_ABI = FFI_OSF
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 24
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
23
src/alpha/internal.h
Normal file
23
src/alpha/internal.h
Normal file
@ -0,0 +1,23 @@
|
||||
#define ALPHA_ST_VOID 0
|
||||
#define ALPHA_ST_INT 1
|
||||
#define ALPHA_ST_FLOAT 2
|
||||
#define ALPHA_ST_DOUBLE 3
|
||||
#define ALPHA_ST_CPLXF 4
|
||||
#define ALPHA_ST_CPLXD 5
|
||||
|
||||
#define ALPHA_LD_VOID 0
|
||||
#define ALPHA_LD_INT64 1
|
||||
#define ALPHA_LD_INT32 2
|
||||
#define ALPHA_LD_UINT16 3
|
||||
#define ALPHA_LD_SINT16 4
|
||||
#define ALPHA_LD_UINT8 5
|
||||
#define ALPHA_LD_SINT8 6
|
||||
#define ALPHA_LD_FLOAT 7
|
||||
#define ALPHA_LD_DOUBLE 8
|
||||
#define ALPHA_LD_CPLXF 9
|
||||
#define ALPHA_LD_CPLXD 10
|
||||
|
||||
#define ALPHA_ST_SHIFT 0
|
||||
#define ALPHA_LD_SHIFT 8
|
||||
#define ALPHA_RET_IN_MEM 0x10000
|
||||
#define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S))
|
282
src/alpha/osf.S
Normal file
282
src/alpha/osf.S
Normal file
@ -0,0 +1,282 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat
|
||||
|
||||
Alpha/OSF Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
|
||||
.arch ev6
|
||||
.text
|
||||
|
||||
/* Aid in building a direct addressed jump table, 4 insns per entry. */
|
||||
.macro E index
|
||||
.align 4
|
||||
.org 99b + \index * 16
|
||||
.endm
|
||||
|
||||
/* ffi_call_osf (void *stack, void *frame, unsigned flags,
|
||||
void *raddr, void (*fnaddr)(void), void *closure)
|
||||
|
||||
Bit o trickiness here -- FRAME is the base of the stack frame
|
||||
for this function. This has been allocated by ffi_call. We also
|
||||
deallocate some of the stack that has been alloca'd. */
|
||||
|
||||
.align 4
|
||||
.globl ffi_call_osf
|
||||
.ent ffi_call_osf
|
||||
FFI_HIDDEN(ffi_call_osf)
|
||||
|
||||
ffi_call_osf:
|
||||
cfi_startproc
|
||||
cfi_def_cfa($17, 32)
|
||||
mov $16, $30
|
||||
stq $26, 0($17)
|
||||
stq $15, 8($17)
|
||||
mov $17, $15
|
||||
.prologue 0
|
||||
cfi_def_cfa_register($15)
|
||||
cfi_rel_offset($26, 0)
|
||||
cfi_rel_offset($15, 8)
|
||||
|
||||
stq $18, 16($17) # save flags into frame
|
||||
stq $19, 24($17) # save rvalue into frame
|
||||
mov $20, $27 # fn into place for call
|
||||
mov $21, $1 # closure into static chain
|
||||
|
||||
# Load up all of the (potential) argument registers.
|
||||
ldq $16, 0($30)
|
||||
ldt $f16, 0($30)
|
||||
ldt $f17, 8($30)
|
||||
ldq $17, 8($30)
|
||||
ldt $f18, 16($30)
|
||||
ldq $18, 16($30)
|
||||
ldt $f19, 24($30)
|
||||
ldq $19, 24($30)
|
||||
ldt $f20, 32($30)
|
||||
ldq $20, 32($30)
|
||||
ldt $f21, 40($30)
|
||||
ldq $21, 40($30)
|
||||
|
||||
# Deallocate the register argument area.
|
||||
lda $30, 48($30)
|
||||
|
||||
jsr $26, ($27), 0
|
||||
0:
|
||||
ldah $29, 0($26) !gpdisp!1
|
||||
ldq $2, 24($15) # reload rvalue
|
||||
lda $29, 0($29) !gpdisp!1
|
||||
ldq $3, 16($15) # reload flags
|
||||
lda $1, 99f-0b($26)
|
||||
ldq $26, 0($15)
|
||||
ldq $15, 8($15)
|
||||
cfi_restore($26)
|
||||
cfi_restore($15)
|
||||
cfi_def_cfa($sp, 0)
|
||||
cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void
|
||||
addq $3, $3, $3
|
||||
s8addq $3, $1, $1 # 99f + stcode * 16
|
||||
jmp $31, ($1), $st_int
|
||||
|
||||
.align 4
|
||||
99:
|
||||
E ALPHA_ST_VOID
|
||||
ret
|
||||
E ALPHA_ST_INT
|
||||
$st_int:
|
||||
stq $0, 0($2)
|
||||
ret
|
||||
E ALPHA_ST_FLOAT
|
||||
sts $f0, 0($2)
|
||||
ret
|
||||
E ALPHA_ST_DOUBLE
|
||||
stt $f0, 0($2)
|
||||
ret
|
||||
E ALPHA_ST_CPLXF
|
||||
sts $f0, 0($2)
|
||||
sts $f1, 4($2)
|
||||
ret
|
||||
E ALPHA_ST_CPLXD
|
||||
stt $f0, 0($2)
|
||||
stt $f1, 8($2)
|
||||
ret
|
||||
|
||||
cfi_endproc
|
||||
.end ffi_call_osf
|
||||
|
||||
/* ffi_closure_osf(...)
|
||||
|
||||
Receives the closure argument in $1. */
|
||||
|
||||
#define CLOSURE_FS (16*8)
|
||||
|
||||
.align 4
|
||||
.globl ffi_go_closure_osf
|
||||
.ent ffi_go_closure_osf
|
||||
FFI_HIDDEN(ffi_go_closure_osf)
|
||||
|
||||
ffi_go_closure_osf:
|
||||
cfi_startproc
|
||||
ldgp $29, 0($27)
|
||||
subq $30, CLOSURE_FS, $30
|
||||
cfi_adjust_cfa_offset(CLOSURE_FS)
|
||||
stq $26, 0($30)
|
||||
.prologue 1
|
||||
cfi_rel_offset($26, 0)
|
||||
|
||||
stq $16, 10*8($30)
|
||||
stq $17, 11*8($30)
|
||||
stq $18, 12*8($30)
|
||||
|
||||
ldq $16, 8($1) # load cif
|
||||
ldq $17, 16($1) # load fun
|
||||
mov $1, $18 # closure is user_data
|
||||
br $do_closure
|
||||
|
||||
cfi_endproc
|
||||
.end ffi_go_closure_osf
|
||||
|
||||
.align 4
|
||||
.globl ffi_closure_osf
|
||||
.ent ffi_closure_osf
|
||||
FFI_HIDDEN(ffi_closure_osf)
|
||||
|
||||
ffi_closure_osf:
|
||||
cfi_startproc
|
||||
ldgp $29, 0($27)
|
||||
subq $30, CLOSURE_FS, $30
|
||||
cfi_adjust_cfa_offset(CLOSURE_FS)
|
||||
stq $26, 0($30)
|
||||
.prologue 1
|
||||
cfi_rel_offset($26, 0)
|
||||
|
||||
# Store all of the potential argument registers in va_list format.
|
||||
stq $16, 10*8($30)
|
||||
stq $17, 11*8($30)
|
||||
stq $18, 12*8($30)
|
||||
|
||||
ldq $16, 24($1) # load cif
|
||||
ldq $17, 32($1) # load fun
|
||||
ldq $18, 40($1) # load user_data
|
||||
|
||||
$do_closure:
|
||||
stq $19, 13*8($30)
|
||||
stq $20, 14*8($30)
|
||||
stq $21, 15*8($30)
|
||||
stt $f16, 4*8($30)
|
||||
stt $f17, 5*8($30)
|
||||
stt $f18, 6*8($30)
|
||||
stt $f19, 7*8($30)
|
||||
stt $f20, 8*8($30)
|
||||
stt $f21, 9*8($30)
|
||||
|
||||
# Call ffi_closure_osf_inner to do the bulk of the work.
|
||||
lda $19, 2*8($30)
|
||||
lda $20, 10*8($30)
|
||||
jsr $26, ffi_closure_osf_inner
|
||||
0:
|
||||
ldah $29, 0($26) !gpdisp!2
|
||||
lda $2, 99f-0b($26)
|
||||
s4addq $0, 0, $1 # ldcode * 4
|
||||
ldq $0, 16($30) # preload return value
|
||||
s4addq $1, $2, $1 # 99f + ldcode * 16
|
||||
lda $29, 0($29) !gpdisp!2
|
||||
ldq $26, 0($30)
|
||||
cfi_restore($26)
|
||||
jmp $31, ($1), $load_32
|
||||
|
||||
.macro epilogue
|
||||
addq $30, CLOSURE_FS, $30
|
||||
cfi_adjust_cfa_offset(-CLOSURE_FS)
|
||||
ret
|
||||
.align 4
|
||||
cfi_adjust_cfa_offset(CLOSURE_FS)
|
||||
.endm
|
||||
|
||||
.align 4
|
||||
99:
|
||||
E ALPHA_LD_VOID
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_INT64
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_INT32
|
||||
$load_32:
|
||||
sextl $0, $0
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_UINT16
|
||||
zapnot $0, 3, $0
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_SINT16
|
||||
#ifdef __alpha_bwx__
|
||||
sextw $0, $0
|
||||
#else
|
||||
sll $0, 48, $0
|
||||
sra $0, 48, $0
|
||||
#endif
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_UINT8
|
||||
and $0, 0xff, $0
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_SINT8
|
||||
#ifdef __alpha_bwx__
|
||||
sextb $0, $0
|
||||
#else
|
||||
sll $0, 56, $0
|
||||
sra $0, 56, $0
|
||||
#endif
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_FLOAT
|
||||
lds $f0, 16($sp)
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_DOUBLE
|
||||
ldt $f0, 16($sp)
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_CPLXF
|
||||
lds $f0, 16($sp)
|
||||
lds $f1, 20($sp)
|
||||
epilogue
|
||||
|
||||
E ALPHA_LD_CPLXD
|
||||
ldt $f0, 16($sp)
|
||||
ldt $f1, 24($sp)
|
||||
epilogue
|
||||
|
||||
cfi_endproc
|
||||
.end ffi_closure_osf
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
135
src/arc/arcompact.S
Normal file
135
src/arc/arcompact.S
Normal file
@ -0,0 +1,135 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com)
|
||||
|
||||
ARCompact Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#define CNAME(x) x
|
||||
#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x):
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
/* R0: ffi_prep_args */
|
||||
/* R1: &ecif */
|
||||
/* R2: cif->bytes */
|
||||
/* R3: fig->flags */
|
||||
/* R4: ecif.rvalue */
|
||||
/* R5: fn */
|
||||
ENTRY(ffi_call_ARCompact)
|
||||
/* Save registers. */
|
||||
st.a fp, [sp, -4] /* fp + 20, fp */
|
||||
push_s blink /* fp + 16, blink */
|
||||
st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */
|
||||
push_s r3 /* fp + 8, fig->flags */
|
||||
st.a r5, [sp, -4] /* fp + 4, fn */
|
||||
push_s r2 /* fp + 0, cif->bytes */
|
||||
mov fp, sp
|
||||
|
||||
/* Make room for all of the new args. */
|
||||
sub sp, sp, r2
|
||||
|
||||
/* Place all of the ffi_prep_args in position. */
|
||||
/* ffi_prep_args(char *stack, extended_cif *ecif) */
|
||||
/* R1 already set. */
|
||||
|
||||
/* And call. */
|
||||
jl_s.d [r0]
|
||||
mov_s r0, sp
|
||||
|
||||
ld.ab r12, [fp, 4] /* cif->bytes */
|
||||
ld.ab r11, [fp, 4] /* fn */
|
||||
|
||||
/* Move first 8 parameters in registers... */
|
||||
ld_s r0, [sp]
|
||||
ld_s r1, [sp, 4]
|
||||
ld_s r2, [sp, 8]
|
||||
ld_s r3, [sp, 12]
|
||||
ld r4, [sp, 16]
|
||||
ld r5, [sp, 20]
|
||||
ld r6, [sp, 24]
|
||||
ld r7, [sp, 28]
|
||||
|
||||
/* ...and adjust the stack. */
|
||||
min r12, r12, 32
|
||||
|
||||
/* Call the function. */
|
||||
jl.d [r11]
|
||||
add sp, sp, r12
|
||||
|
||||
mov sp, fp
|
||||
pop_s r3 /* fig->flags, return type */
|
||||
pop_s r2 /* ecif.rvalue, pointer for return value */
|
||||
|
||||
/* If the return value pointer is NULL, assume no return value. */
|
||||
breq.d r2, 0, epilogue
|
||||
pop_s blink
|
||||
|
||||
/* Return INT. */
|
||||
brne r3, FFI_TYPE_INT, return_double
|
||||
b.d epilogue
|
||||
st_s r0, [r2]
|
||||
|
||||
return_double:
|
||||
brne r3, FFI_TYPE_DOUBLE, epilogue
|
||||
st_s r0, [r2]
|
||||
st_s r1, [r2,4]
|
||||
|
||||
epilogue:
|
||||
j_s.d [blink]
|
||||
ld.ab fp, [sp, 4]
|
||||
|
||||
ENTRY(ffi_closure_ARCompact)
|
||||
st.a r0, [sp, -32]
|
||||
st_s r1, [sp, 4]
|
||||
st_s r2, [sp, 8]
|
||||
st_s r3, [sp, 12]
|
||||
st r4, [sp, 16]
|
||||
st r5, [sp, 20]
|
||||
st r6, [sp, 24]
|
||||
st r7, [sp, 28]
|
||||
|
||||
/* pointer to arguments */
|
||||
mov_s r2, sp
|
||||
|
||||
/* return value goes here */
|
||||
sub sp, sp, 8
|
||||
mov_s r1, sp
|
||||
|
||||
push_s blink
|
||||
|
||||
bl.d ffi_closure_inner_ARCompact
|
||||
mov_s r0, r8 /* codeloc, set by trampoline */
|
||||
|
||||
pop_s blink
|
||||
|
||||
/* set return value to r1:r0 */
|
||||
pop_s r0
|
||||
pop_s r1
|
||||
j_s.d [blink]
|
||||
add_s sp, sp, 32
|
266
src/arc/ffi.c
Normal file
266
src/arc/ffi.c
Normal file
@ -0,0 +1,266 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
|
||||
|
||||
ARC Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/cachectl.h>
|
||||
|
||||
/* for little endian ARC, the code is in fact stored as mixed endian for
|
||||
performance reasons */
|
||||
#if __BIG_ENDIAN__
|
||||
#define CODE_ENDIAN(x) (x)
|
||||
#else
|
||||
#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16))
|
||||
#endif
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack
|
||||
space has been allocated for the function's arguments. */
|
||||
|
||||
void
|
||||
ffi_prep_args (char *stack, extended_cif * ecif)
|
||||
{
|
||||
unsigned int i;
|
||||
void **p_argv;
|
||||
char *argp;
|
||||
ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*(void **) argp = ecif->rvalue;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
int alignment;
|
||||
|
||||
/* align alignment to 4 */
|
||||
alignment = (((*p_arg)->alignment - 1) | 3) + 1;
|
||||
|
||||
/* Align if necessary. */
|
||||
if ((alignment - 1) & (unsigned) argp)
|
||||
argp = (char *) FFI_ALIGN (argp, alignment);
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof (int))
|
||||
{
|
||||
z = sizeof (int);
|
||||
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
memcpy (argp, *p_argv, (*p_arg)->size);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT (0);
|
||||
}
|
||||
}
|
||||
else if (z == sizeof (int))
|
||||
{
|
||||
*(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
memcpy (argp, *p_argv, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Double or long long 64bit. */
|
||||
memcpy (argp, *p_argv, z);
|
||||
}
|
||||
}
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing. */
|
||||
ffi_status
|
||||
ffi_prep_cif_machdep (ffi_cif * cif)
|
||||
{
|
||||
/* Set the return type flag. */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
cif->flags = FFI_TYPE_DOUBLE;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
default:
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern void ffi_call_ARCompact (void (*)(char *, extended_cif *),
|
||||
extended_cif *, unsigned, unsigned,
|
||||
unsigned *, void (*fn) (void));
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif * cif, void (*fn) (void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have
|
||||
a return value address then we need to make one. */
|
||||
if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca (cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_ARCOMPACT:
|
||||
ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue,
|
||||
ffi_arg * args)
|
||||
{
|
||||
void **arg_area, **p_argv;
|
||||
ffi_cif *cif = closure->cif;
|
||||
char *argp = (char *) args;
|
||||
ffi_type **p_argt;
|
||||
int i;
|
||||
|
||||
arg_area = (void **) alloca (cif->nargs * sizeof (void *));
|
||||
|
||||
/* handle hidden argument */
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
rvalue = *(void **) argp;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
p_argv = arg_area;
|
||||
|
||||
for (i = 0, p_argt = cif->arg_types; i < cif->nargs;
|
||||
i++, p_argt++, p_argv++)
|
||||
{
|
||||
size_t z;
|
||||
int alignment;
|
||||
|
||||
/* align alignment to 4 */
|
||||
alignment = (((*p_argt)->alignment - 1) | 3) + 1;
|
||||
|
||||
/* Align if necessary. */
|
||||
if ((alignment - 1) & (unsigned) argp)
|
||||
argp = (char *) FFI_ALIGN (argp, alignment);
|
||||
|
||||
z = (*p_argt)->size;
|
||||
*p_argv = (void *) argp;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
(closure->fun) (cif, rvalue, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
extern void ffi_closure_ARCompact (void);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif,
|
||||
void (*fun) (ffi_cif *, void *, void **, void *),
|
||||
void *user_data, void *codeloc)
|
||||
{
|
||||
uint32_t *tramp = (uint32_t *) & (closure->tramp[0]);
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_ARCOMPACT:
|
||||
FFI_ASSERT (tramp == codeloc);
|
||||
tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */
|
||||
tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */
|
||||
tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
53
src/arc/ffitarget.h
Normal file
53
src/arc/ffitarget.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
|
||||
Target configuration macros for ARC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi
|
||||
{
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_ARCOMPACT,
|
||||
FFI_LAST_ABI,
|
||||
FFI_DEFAULT_ABI = FFI_ARCOMPACT
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
854
src/arm/ffi.c
Normal file
854
src/arm/ffi.c
Normal file
@ -0,0 +1,854 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2011 Timothy Wall
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
Copyright (c) 2011 Anthony Green
|
||||
Copyright (c) 2011 Free Software Foundation
|
||||
Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#include <mach/machine/vm_param.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef _M_ARM
|
||||
extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
|
||||
#else
|
||||
extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Forward declares. */
|
||||
static int vfp_type_p (const ffi_type *);
|
||||
static void layout_vfp_args (ffi_cif *);
|
||||
|
||||
static void *
|
||||
ffi_align (ffi_type *ty, void *p)
|
||||
{
|
||||
/* Align if necessary */
|
||||
size_t alignment;
|
||||
#ifdef _WIN32_WCE
|
||||
alignment = 4;
|
||||
#else
|
||||
alignment = ty->alignment;
|
||||
if (alignment < 4)
|
||||
alignment = 4;
|
||||
#endif
|
||||
return (void *) FFI_ALIGN (p, alignment);
|
||||
}
|
||||
|
||||
static size_t
|
||||
ffi_put_arg (ffi_type *ty, void *src, void *dst)
|
||||
{
|
||||
size_t z = ty->size;
|
||||
|
||||
switch (ty->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(UINT32 *)dst = *(SINT8 *)src;
|
||||
break;
|
||||
case FFI_TYPE_UINT8:
|
||||
*(UINT32 *)dst = *(UINT8 *)src;
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
*(UINT32 *)dst = *(SINT16 *)src;
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
*(UINT32 *)dst = *(UINT16 *)src;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
#ifndef _MSC_VER
|
||||
case FFI_TYPE_FLOAT:
|
||||
#endif
|
||||
*(UINT32 *)dst = *(UINT32 *)src;
|
||||
break;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// casting a float* to a UINT32* doesn't work on Windows
|
||||
case FFI_TYPE_FLOAT:
|
||||
*(uintptr_t *)dst = 0;
|
||||
*(float *)dst = *(float *)src;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*(UINT64 *)dst = *(UINT64 *)src;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_COMPLEX:
|
||||
memcpy (dst, src, z);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return FFI_ALIGN (z, 4);
|
||||
}
|
||||
|
||||
/* ffi_prep_args is called once stack space has been allocated
|
||||
for the function's arguments.
|
||||
|
||||
The vfp_space parameter is the load area for VFP regs, the return
|
||||
value is cif->vfp_used (word bitset of VFP regs used for passing
|
||||
arguments). These are only used for the VFP hard-float ABI.
|
||||
*/
|
||||
static void
|
||||
ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,
|
||||
void **avalue, char *argp)
|
||||
{
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
int i, n;
|
||||
|
||||
if (flags == ARM_TYPE_STRUCT)
|
||||
{
|
||||
*(void **) argp = rvalue;
|
||||
argp += 4;
|
||||
}
|
||||
|
||||
for (i = 0, n = cif->nargs; i < n; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
argp = ffi_align (ty, argp);
|
||||
argp += ffi_put_arg (ty, avalue[i], argp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
|
||||
void **avalue, char *stack, char *vfp_space)
|
||||
{
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
int i, n, vi = 0;
|
||||
char *argp, *regp, *eo_regp;
|
||||
char stack_used = 0;
|
||||
char done_with_regs = 0;
|
||||
|
||||
/* The first 4 words on the stack are used for values
|
||||
passed in core registers. */
|
||||
regp = stack;
|
||||
eo_regp = argp = regp + 16;
|
||||
|
||||
/* If the function returns an FFI_TYPE_STRUCT in memory,
|
||||
that address is passed in r0 to the function. */
|
||||
if (flags == ARM_TYPE_STRUCT)
|
||||
{
|
||||
*(void **) regp = rvalue;
|
||||
regp += 4;
|
||||
}
|
||||
|
||||
for (i = 0, n = cif->nargs; i < n; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
void *a = avalue[i];
|
||||
int is_vfp_type = vfp_type_p (ty);
|
||||
|
||||
/* Allocated in VFP registers. */
|
||||
if (vi < cif->vfp_nargs && is_vfp_type)
|
||||
{
|
||||
char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;
|
||||
ffi_put_arg (ty, a, vfp_slot);
|
||||
continue;
|
||||
}
|
||||
/* Try allocating in core registers. */
|
||||
else if (!done_with_regs && !is_vfp_type)
|
||||
{
|
||||
char *tregp = ffi_align (ty, regp);
|
||||
size_t size = ty->size;
|
||||
size = (size < 4) ? 4 : size; // pad
|
||||
/* Check if there is space left in the aligned register
|
||||
area to place the argument. */
|
||||
if (tregp + size <= eo_regp)
|
||||
{
|
||||
regp = tregp + ffi_put_arg (ty, a, tregp);
|
||||
done_with_regs = (regp == argp);
|
||||
// ensure we did not write into the stack area
|
||||
FFI_ASSERT (regp <= argp);
|
||||
continue;
|
||||
}
|
||||
/* In case there are no arguments in the stack area yet,
|
||||
the argument is passed in the remaining core registers
|
||||
and on the stack. */
|
||||
else if (!stack_used)
|
||||
{
|
||||
stack_used = 1;
|
||||
done_with_regs = 1;
|
||||
argp = tregp + ffi_put_arg (ty, a, tregp);
|
||||
FFI_ASSERT (eo_regp < argp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Base case, arguments are passed on the stack */
|
||||
stack_used = 1;
|
||||
argp = ffi_align (ty, argp);
|
||||
argp += ffi_put_arg (ty, a, argp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
int flags = 0, cabi = cif->abi;
|
||||
size_t bytes = cif->bytes;
|
||||
|
||||
/* Map out the register placements of VFP register args. The VFP
|
||||
hard-float calling conventions are slightly more sophisticated
|
||||
than the base calling conventions, so we do it here instead of
|
||||
in ffi_prep_args(). */
|
||||
if (cabi == FFI_VFP)
|
||||
layout_vfp_args (cif);
|
||||
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
flags = ARM_TYPE_VOID;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
flags = ARM_TYPE_INT;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
flags = ARM_TYPE_INT64;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_COMPLEX:
|
||||
if (cabi == FFI_VFP)
|
||||
{
|
||||
int h = vfp_type_p (cif->rtype);
|
||||
|
||||
flags = ARM_TYPE_VFP_N;
|
||||
if (h == 0x100 + FFI_TYPE_FLOAT)
|
||||
flags = ARM_TYPE_VFP_S;
|
||||
if (h == 0x100 + FFI_TYPE_DOUBLE)
|
||||
flags = ARM_TYPE_VFP_D;
|
||||
if (h != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* A Composite Type not larger than 4 bytes is returned in r0.
|
||||
A Composite Type larger than 4 bytes, or whose size cannot
|
||||
be determined statically ... is stored in memory at an
|
||||
address passed [in r0]. */
|
||||
if (cif->rtype->size <= 4)
|
||||
flags = ARM_TYPE_INT;
|
||||
else
|
||||
{
|
||||
flags = ARM_TYPE_STRUCT;
|
||||
bytes += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
everywhere, but it is on some platforms, and it doesn't harm anything
|
||||
when it isn't needed. */
|
||||
bytes = FFI_ALIGN (bytes, 8);
|
||||
|
||||
/* Minimum stack space is the 4 register arguments that we pop. */
|
||||
if (bytes < 4*4)
|
||||
bytes = 4*4;
|
||||
|
||||
cif->bytes = bytes;
|
||||
cif->flags = flags;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing for variadic calls */
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep_var (ffi_cif * cif,
|
||||
unsigned int nfixedargs, unsigned int ntotalargs)
|
||||
{
|
||||
/* VFP variadic calls actually use the SYSV ABI */
|
||||
if (cif->abi == FFI_VFP)
|
||||
cif->abi = FFI_SYSV;
|
||||
|
||||
return ffi_prep_cif_machdep (cif);
|
||||
}
|
||||
|
||||
/* Prototypes for assembly functions, in sysv.S. */
|
||||
|
||||
struct call_frame
|
||||
{
|
||||
void *fp;
|
||||
void *lr;
|
||||
void *rvalue;
|
||||
int flags;
|
||||
void *closure;
|
||||
};
|
||||
|
||||
extern void ffi_call_SYSV (void *stack, struct call_frame *,
|
||||
void (*fn) (void)) FFI_HIDDEN;
|
||||
extern void ffi_call_VFP (void *vfp_space, struct call_frame *,
|
||||
void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;
|
||||
|
||||
static void
|
||||
ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
int flags = cif->flags;
|
||||
ffi_type *rtype = cif->rtype;
|
||||
size_t bytes, rsize, vfp_size;
|
||||
char *stack, *vfp_space, *new_rvalue;
|
||||
struct call_frame *frame;
|
||||
|
||||
rsize = 0;
|
||||
if (rvalue == NULL)
|
||||
{
|
||||
/* If the return value is a struct and we don't have a return
|
||||
value address then we need to make one. Otherwise the return
|
||||
value is in registers and we can ignore them. */
|
||||
if (flags == ARM_TYPE_STRUCT)
|
||||
rsize = rtype->size;
|
||||
else
|
||||
flags = ARM_TYPE_VOID;
|
||||
}
|
||||
else if (flags == ARM_TYPE_VFP_N)
|
||||
{
|
||||
/* Largest case is double x 4. */
|
||||
rsize = 32;
|
||||
}
|
||||
else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)
|
||||
rsize = 4;
|
||||
|
||||
/* Largest case. */
|
||||
vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);
|
||||
|
||||
bytes = cif->bytes;
|
||||
stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);
|
||||
|
||||
vfp_space = NULL;
|
||||
if (vfp_size)
|
||||
{
|
||||
vfp_space = stack;
|
||||
stack += vfp_size;
|
||||
}
|
||||
|
||||
frame = (struct call_frame *)(stack + bytes);
|
||||
|
||||
new_rvalue = rvalue;
|
||||
if (rsize)
|
||||
new_rvalue = (void *)(frame + 1);
|
||||
|
||||
frame->rvalue = new_rvalue;
|
||||
frame->flags = flags;
|
||||
frame->closure = closure;
|
||||
|
||||
if (vfp_space)
|
||||
{
|
||||
ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);
|
||||
ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);
|
||||
ffi_call_SYSV (stack, frame, fn);
|
||||
}
|
||||
|
||||
if (rvalue && rvalue != new_rvalue)
|
||||
memcpy (rvalue, new_rvalue, rtype->size);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, closure);
|
||||
}
|
||||
|
||||
static void *
|
||||
ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
|
||||
char *argp, void **avalue)
|
||||
{
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
int i, n;
|
||||
|
||||
if (cif->flags == ARM_TYPE_STRUCT)
|
||||
{
|
||||
rvalue = *(void **) argp;
|
||||
argp += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cif->rtype->size && cif->rtype->size < 4)
|
||||
*(uint32_t *) rvalue = 0;
|
||||
}
|
||||
|
||||
for (i = 0, n = cif->nargs; i < n; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
size_t z = ty->size;
|
||||
|
||||
argp = ffi_align (ty, argp);
|
||||
avalue[i] = (void *) argp;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
static void *
|
||||
ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,
|
||||
char *vfp_space, void **avalue)
|
||||
{
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
int i, n, vi = 0;
|
||||
char *argp, *regp, *eo_regp;
|
||||
char done_with_regs = 0;
|
||||
char stack_used = 0;
|
||||
|
||||
regp = stack;
|
||||
eo_regp = argp = regp + 16;
|
||||
|
||||
if (cif->flags == ARM_TYPE_STRUCT)
|
||||
{
|
||||
rvalue = *(void **) regp;
|
||||
regp += 4;
|
||||
}
|
||||
|
||||
for (i = 0, n = cif->nargs; i < n; i++)
|
||||
{
|
||||
ffi_type *ty = arg_types[i];
|
||||
int is_vfp_type = vfp_type_p (ty);
|
||||
size_t z = ty->size;
|
||||
|
||||
if (vi < cif->vfp_nargs && is_vfp_type)
|
||||
{
|
||||
avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;
|
||||
continue;
|
||||
}
|
||||
else if (!done_with_regs && !is_vfp_type)
|
||||
{
|
||||
char *tregp = ffi_align (ty, regp);
|
||||
|
||||
z = (z < 4) ? 4 : z; // pad
|
||||
|
||||
/* If the arguments either fits into the registers or uses registers
|
||||
and stack, while we haven't read other things from the stack */
|
||||
if (tregp + z <= eo_regp || !stack_used)
|
||||
{
|
||||
/* Because we're little endian, this is what it turns into. */
|
||||
avalue[i] = (void *) tregp;
|
||||
regp = tregp + z;
|
||||
|
||||
/* If we read past the last core register, make sure we
|
||||
have not read from the stack before and continue
|
||||
reading after regp. */
|
||||
if (regp > eo_regp)
|
||||
{
|
||||
FFI_ASSERT (!stack_used);
|
||||
argp = regp;
|
||||
}
|
||||
if (regp >= eo_regp)
|
||||
{
|
||||
done_with_regs = 1;
|
||||
stack_used = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
stack_used = 1;
|
||||
argp = ffi_align (ty, argp);
|
||||
avalue[i] = (void *) argp;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
struct closure_frame
|
||||
{
|
||||
char vfp_space[8*8] __attribute__((aligned(8)));
|
||||
char result[8*4];
|
||||
char argp[];
|
||||
};
|
||||
|
||||
int FFI_HIDDEN
|
||||
ffi_closure_inner_SYSV (ffi_cif *cif,
|
||||
void (*fun) (ffi_cif *, void *, void **, void *),
|
||||
void *user_data,
|
||||
struct closure_frame *frame)
|
||||
{
|
||||
void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
|
||||
void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,
|
||||
frame->argp, avalue);
|
||||
fun (cif, rvalue, avalue, user_data);
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
int FFI_HIDDEN
|
||||
ffi_closure_inner_VFP (ffi_cif *cif,
|
||||
void (*fun) (ffi_cif *, void *, void **, void *),
|
||||
void *user_data,
|
||||
struct closure_frame *frame)
|
||||
{
|
||||
void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
|
||||
void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,
|
||||
frame->vfp_space, avalue);
|
||||
fun (cif, rvalue, avalue, user_data);
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
void ffi_closure_SYSV (void) FFI_HIDDEN;
|
||||
void ffi_closure_VFP (void) FFI_HIDDEN;
|
||||
void ffi_go_closure_SYSV (void) FFI_HIDDEN;
|
||||
void ffi_go_closure_VFP (void) FFI_HIDDEN;
|
||||
|
||||
/* the cif must already be prep'ed */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure * closure,
|
||||
ffi_cif * cif,
|
||||
void (*fun) (ffi_cif *, void *, void **, void *),
|
||||
void *user_data, void *codeloc)
|
||||
{
|
||||
void (*closure_func) (void) = ffi_closure_SYSV;
|
||||
|
||||
if (cif->abi == FFI_VFP)
|
||||
{
|
||||
/* We only need take the vfp path if there are vfp arguments. */
|
||||
if (cif->vfp_used)
|
||||
closure_func = ffi_closure_VFP;
|
||||
}
|
||||
else if (cif->abi != FFI_SYSV)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
|
||||
config[0] = closure;
|
||||
config[1] = closure_func;
|
||||
#else
|
||||
|
||||
#ifndef _M_ARM
|
||||
memcpy(closure->tramp, ffi_arm_trampoline, 8);
|
||||
#else
|
||||
// cast away function type so MSVC doesn't set the lower bit of the function pointer
|
||||
memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
|
||||
#endif
|
||||
|
||||
#if defined (__QNX__)
|
||||
msync(closure->tramp, 8, 0x1000000); /* clear data map */
|
||||
msync(codeloc, 8, 0x1000000); /* clear insn map */
|
||||
#elif defined(_MSC_VER)
|
||||
FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
|
||||
#else
|
||||
__clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
|
||||
__clear_cache(codeloc, codeloc + 8); /* clear insn map */
|
||||
#endif
|
||||
#ifdef _M_ARM
|
||||
*(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
|
||||
#else
|
||||
*(void (**)(void))(closure->tramp + 8) = closure_func;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
|
||||
void (*fun) (ffi_cif *, void *, void **, void *))
|
||||
{
|
||||
void (*closure_func) (void) = ffi_go_closure_SYSV;
|
||||
|
||||
if (cif->abi == FFI_VFP)
|
||||
{
|
||||
/* We only need take the vfp path if there are vfp arguments. */
|
||||
if (cif->vfp_used)
|
||||
closure_func = ffi_go_closure_VFP;
|
||||
}
|
||||
else if (cif->abi != FFI_SYSV)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
closure->tramp = closure_func;
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Below are routines for VFP hard-float support. */
|
||||
|
||||
/* A subroutine of vfp_type_p. Given a structure type, return the type code
|
||||
of the first non-structure element. Recurse for structure elements.
|
||||
Return -1 if the structure is in fact empty, i.e. no nested elements. */
|
||||
|
||||
static int
|
||||
is_hfa0 (const ffi_type *ty)
|
||||
{
|
||||
ffi_type **elements = ty->elements;
|
||||
int i, ret = -1;
|
||||
|
||||
if (elements != NULL)
|
||||
for (i = 0; elements[i]; ++i)
|
||||
{
|
||||
ret = elements[i]->type;
|
||||
if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
ret = is_hfa0 (elements[i]);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* A subroutine of vfp_type_p. Given a structure type, return true if all
|
||||
of the non-structure elements are the same as CANDIDATE. */
|
||||
|
||||
static int
|
||||
is_hfa1 (const ffi_type *ty, int candidate)
|
||||
{
|
||||
ffi_type **elements = ty->elements;
|
||||
int i;
|
||||
|
||||
if (elements != NULL)
|
||||
for (i = 0; elements[i]; ++i)
|
||||
{
|
||||
int t = elements[i]->type;
|
||||
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
if (!is_hfa1 (elements[i], candidate))
|
||||
return 0;
|
||||
}
|
||||
else if (t != candidate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine if TY is an homogenous floating point aggregate (HFA).
|
||||
That is, a structure consisting of 1 to 4 members of all the same type,
|
||||
where that type is a floating point scalar.
|
||||
|
||||
Returns non-zero iff TY is an HFA. The result is an encoded value where
|
||||
bits 0-7 contain the type code, and bits 8-10 contain the element count. */
|
||||
|
||||
static int
|
||||
vfp_type_p (const ffi_type *ty)
|
||||
{
|
||||
ffi_type **elements;
|
||||
int candidate, i;
|
||||
size_t size, ele_count;
|
||||
|
||||
/* Quickest tests first. */
|
||||
candidate = ty->type;
|
||||
switch (ty->type)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
ele_count = 1;
|
||||
goto done;
|
||||
case FFI_TYPE_COMPLEX:
|
||||
candidate = ty->elements[0]->type;
|
||||
if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)
|
||||
return 0;
|
||||
ele_count = 2;
|
||||
goto done;
|
||||
case FFI_TYPE_STRUCT:
|
||||
break;
|
||||
}
|
||||
|
||||
/* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */
|
||||
size = ty->size;
|
||||
if (size < 4 || size > 32)
|
||||
return 0;
|
||||
|
||||
/* Find the type of the first non-structure member. */
|
||||
elements = ty->elements;
|
||||
candidate = elements[0]->type;
|
||||
if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
candidate = is_hfa0 (elements[i]);
|
||||
if (candidate >= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first member is not a floating point type, it's not an HFA.
|
||||
Also quickly re-check the size of the structure. */
|
||||
switch (candidate)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
ele_count = size / sizeof(float);
|
||||
if (size != ele_count * sizeof(float))
|
||||
return 0;
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
ele_count = size / sizeof(double);
|
||||
if (size != ele_count * sizeof(double))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (ele_count > 4)
|
||||
return 0;
|
||||
|
||||
/* Finally, make sure that all scalar elements are the same type. */
|
||||
for (i = 0; elements[i]; ++i)
|
||||
{
|
||||
int t = elements[i]->type;
|
||||
if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
if (!is_hfa1 (elements[i], candidate))
|
||||
return 0;
|
||||
}
|
||||
else if (t != candidate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* All tests succeeded. Encode the result. */
|
||||
done:
|
||||
return (ele_count << 8) | candidate;
|
||||
}
|
||||
|
||||
static int
|
||||
place_vfp_arg (ffi_cif *cif, int h)
|
||||
{
|
||||
unsigned short reg = cif->vfp_reg_free;
|
||||
int align = 1, nregs = h >> 8;
|
||||
|
||||
if ((h & 0xff) == FFI_TYPE_DOUBLE)
|
||||
align = 2, nregs *= 2;
|
||||
|
||||
/* Align register number. */
|
||||
if ((reg & 1) && align == 2)
|
||||
reg++;
|
||||
|
||||
while (reg + nregs <= 16)
|
||||
{
|
||||
int s, new_used = 0;
|
||||
for (s = reg; s < reg + nregs; s++)
|
||||
{
|
||||
new_used |= (1 << s);
|
||||
if (cif->vfp_used & (1 << s))
|
||||
{
|
||||
reg += align;
|
||||
goto next_reg;
|
||||
}
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
{
|
||||
reg += nregs;
|
||||
while (cif->vfp_used & (1 << reg))
|
||||
reg += 1;
|
||||
cif->vfp_reg_free = reg;
|
||||
}
|
||||
return 0;
|
||||
next_reg:;
|
||||
}
|
||||
// done, mark all regs as used
|
||||
cif->vfp_reg_free = 16;
|
||||
cif->vfp_used = 0xFFFF;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
layout_vfp_args (ffi_cif * cif)
|
||||
{
|
||||
unsigned int i;
|
||||
/* Init VFP fields */
|
||||
cif->vfp_used = 0;
|
||||
cif->vfp_nargs = 0;
|
||||
cif->vfp_reg_free = 0;
|
||||
memset (cif->vfp_args, -1, 16); /* Init to -1. */
|
||||
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
int h = vfp_type_p (cif->arg_types[i]);
|
||||
if (h && place_vfp_arg (cif, h) == 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __arm__ or _M_ARM */
|
89
src/arm/ffitarget.h
Normal file
89
src/arm/ffitarget.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 2010 CodeSourcery
|
||||
Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
|
||||
Target configuration macros for ARM.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_VFP,
|
||||
FFI_LAST_ABI,
|
||||
#if defined(__ARM_PCS_VFP) || defined(_M_ARM)
|
||||
FFI_DEFAULT_ABI = FFI_VFP,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#endif
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_EXTRA_CIF_FIELDS \
|
||||
int vfp_used; \
|
||||
unsigned short vfp_reg_free, vfp_nargs; \
|
||||
signed char vfp_args[16] \
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#ifndef _M_ARM
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
|
||||
#else
|
||||
#error "No trampoline table implementation"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#endif
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
#endif
|
7
src/arm/internal.h
Normal file
7
src/arm/internal.h
Normal file
@ -0,0 +1,7 @@
|
||||
#define ARM_TYPE_VFP_S 0
|
||||
#define ARM_TYPE_VFP_D 1
|
||||
#define ARM_TYPE_VFP_N 2
|
||||
#define ARM_TYPE_INT64 3
|
||||
#define ARM_TYPE_INT 4
|
||||
#define ARM_TYPE_VOID 5
|
||||
#define ARM_TYPE_STRUCT 6
|
385
src/arm/sysv.S
Normal file
385
src/arm/sysv.S
Normal file
@ -0,0 +1,385 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __arm__
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
|
||||
/* GCC 4.8 provides __ARM_ARCH; construct it otherwise. */
|
||||
#ifndef __ARM_ARCH
|
||||
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|
||||
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|
||||
|| defined(__ARM_ARCH_7EM__)
|
||||
# define __ARM_ARCH 7
|
||||
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
|| defined(__ARM_ARCH_6M__)
|
||||
# define __ARM_ARCH 6
|
||||
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__)
|
||||
# define __ARM_ARCH 5
|
||||
# else
|
||||
# define __ARM_ARCH 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Conditionally compile unwinder directives. */
|
||||
#ifdef __ARM_EABI__
|
||||
# define UNWIND(...) __VA_ARGS__
|
||||
#else
|
||||
# define UNWIND(...)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)
|
||||
.cfi_sections .debug_frame
|
||||
#endif
|
||||
|
||||
#define CONCAT(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
# define CNAME(X) CONCAT (__USER_LABEL_PREFIX__, X)
|
||||
#else
|
||||
# define CNAME(X) X
|
||||
#endif
|
||||
#ifdef __ELF__
|
||||
# define SIZE(X) .size CNAME(X), . - CNAME(X)
|
||||
# define TYPE(X, Y) .type CNAME(X), Y
|
||||
#else
|
||||
# define SIZE(X)
|
||||
# define TYPE(X, Y)
|
||||
#endif
|
||||
|
||||
#define ARM_FUNC_START_LOCAL(name) \
|
||||
.align 3; \
|
||||
TYPE(CNAME(name), %function); \
|
||||
CNAME(name):
|
||||
|
||||
#define ARM_FUNC_START(name) \
|
||||
.globl CNAME(name); \
|
||||
FFI_HIDDEN(CNAME(name)); \
|
||||
ARM_FUNC_START_LOCAL(name)
|
||||
|
||||
#define ARM_FUNC_END(name) \
|
||||
SIZE(name)
|
||||
|
||||
/* Aid in defining a jump table with 8 bytes between entries. */
|
||||
/* ??? The clang assembler doesn't handle .if with symbolic expressions. */
|
||||
#ifdef __clang__
|
||||
# define E(index)
|
||||
#else
|
||||
# define E(index) \
|
||||
.if . - 0b - 8*index; \
|
||||
.error "type table out of sync"; \
|
||||
.endif
|
||||
#endif
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
.arm
|
||||
|
||||
#ifndef __clang__
|
||||
/* We require interworking on LDM, which implies ARMv5T,
|
||||
which implies the existance of BLX. */
|
||||
.arch armv5t
|
||||
#endif
|
||||
|
||||
/* Note that we use STC and LDC to encode VFP instructions,
|
||||
so that we do not need ".fpu vfp", nor get that added to
|
||||
the object file attributes. These will not be executed
|
||||
unless the FFI_VFP abi is used. */
|
||||
|
||||
@ r0: stack
|
||||
@ r1: frame
|
||||
@ r2: fn
|
||||
@ r3: vfp_used
|
||||
|
||||
ARM_FUNC_START(ffi_call_VFP)
|
||||
UNWIND(.fnstart)
|
||||
cfi_startproc
|
||||
|
||||
cmp r3, #3 @ load only d0 if possible
|
||||
#ifdef __clang__
|
||||
vldrle d0, [sp]
|
||||
vldmgt sp, {d0-d7}
|
||||
#else
|
||||
ldcle p11, cr0, [r0] @ vldrle d0, [sp]
|
||||
ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7}
|
||||
#endif
|
||||
add r0, r0, #64 @ discard the vfp register args
|
||||
/* FALLTHRU */
|
||||
ARM_FUNC_END(ffi_call_VFP)
|
||||
|
||||
ARM_FUNC_START(ffi_call_SYSV)
|
||||
stm r1, {fp, lr}
|
||||
mov fp, r1
|
||||
|
||||
@ This is a bit of a lie wrt the origin of the unwind info, but
|
||||
@ now we've got the usual frame pointer and two saved registers.
|
||||
UNWIND(.save {fp,lr})
|
||||
UNWIND(.setfp fp, sp)
|
||||
cfi_def_cfa(fp, 8)
|
||||
cfi_rel_offset(fp, 0)
|
||||
cfi_rel_offset(lr, 4)
|
||||
|
||||
mov sp, r0 @ install the stack pointer
|
||||
mov lr, r2 @ move the fn pointer out of the way
|
||||
ldr ip, [fp, #16] @ install the static chain
|
||||
ldmia sp!, {r0-r3} @ move first 4 parameters in registers.
|
||||
blx lr @ call fn
|
||||
|
||||
@ Load r2 with the pointer to storage for the return value
|
||||
@ Load r3 with the return type code
|
||||
ldr r2, [fp, #8]
|
||||
ldr r3, [fp, #12]
|
||||
|
||||
@ Deallocate the stack with the arguments.
|
||||
mov sp, fp
|
||||
cfi_def_cfa_register(sp)
|
||||
|
||||
@ Store values stored in registers.
|
||||
.align 3
|
||||
add pc, pc, r3, lsl #3
|
||||
nop
|
||||
0:
|
||||
E(ARM_TYPE_VFP_S)
|
||||
#ifdef __clang__
|
||||
vstr s0, [r2]
|
||||
#else
|
||||
stc p10, cr0, [r2] @ vstr s0, [r2]
|
||||
#endif
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_D)
|
||||
#ifdef __clang__
|
||||
vstr d0, [r2]
|
||||
#else
|
||||
stc p11, cr0, [r2] @ vstr d0, [r2]
|
||||
#endif
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_N)
|
||||
#ifdef __clang__
|
||||
vstm r2, {d0-d3}
|
||||
#else
|
||||
stc p11, cr0, [r2], {8} @ vstm r2, {d0-d3}
|
||||
#endif
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_INT64)
|
||||
str r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT)
|
||||
str r0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VOID)
|
||||
pop {fp,pc}
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT)
|
||||
pop {fp,pc}
|
||||
|
||||
cfi_endproc
|
||||
UNWIND(.fnend)
|
||||
ARM_FUNC_END(ffi_call_SYSV)
|
||||
|
||||
|
||||
/*
|
||||
int ffi_closure_inner_* (cif, fun, user_data, frame)
|
||||
*/
|
||||
|
||||
ARM_FUNC_START(ffi_go_closure_SYSV)
|
||||
cfi_startproc
|
||||
stmdb sp!, {r0-r3} @ save argument regs
|
||||
cfi_adjust_cfa_offset(16)
|
||||
ldr r0, [ip, #4] @ load cif
|
||||
ldr r1, [ip, #8] @ load fun
|
||||
mov r2, ip @ load user_data
|
||||
b 0f
|
||||
cfi_endproc
|
||||
ARM_FUNC_END(ffi_go_closure_SYSV)
|
||||
|
||||
ARM_FUNC_START(ffi_closure_SYSV)
|
||||
UNWIND(.fnstart)
|
||||
cfi_startproc
|
||||
stmdb sp!, {r0-r3} @ save argument regs
|
||||
cfi_adjust_cfa_offset(16)
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
|
||||
#endif
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
|
||||
0:
|
||||
add ip, sp, #16 @ compute entry sp
|
||||
sub sp, sp, #64+32 @ allocate frame
|
||||
cfi_adjust_cfa_offset(64+32)
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
/* Remember that EABI unwind info only applies at call sites.
|
||||
We need do nothing except note the save of the stack pointer
|
||||
and the link registers. */
|
||||
UNWIND(.save {sp,lr})
|
||||
cfi_adjust_cfa_offset(8)
|
||||
cfi_rel_offset(lr, 4)
|
||||
|
||||
add r3, sp, #8 @ load frame
|
||||
bl CNAME(ffi_closure_inner_SYSV)
|
||||
|
||||
@ Load values returned in registers.
|
||||
add r2, sp, #8+64 @ load result
|
||||
adr r3, CNAME(ffi_closure_ret)
|
||||
add pc, r3, r0, lsl #3
|
||||
cfi_endproc
|
||||
UNWIND(.fnend)
|
||||
ARM_FUNC_END(ffi_closure_SYSV)
|
||||
|
||||
ARM_FUNC_START(ffi_go_closure_VFP)
|
||||
cfi_startproc
|
||||
stmdb sp!, {r0-r3} @ save argument regs
|
||||
cfi_adjust_cfa_offset(16)
|
||||
ldr r0, [ip, #4] @ load cif
|
||||
ldr r1, [ip, #8] @ load fun
|
||||
mov r2, ip @ load user_data
|
||||
b 0f
|
||||
cfi_endproc
|
||||
ARM_FUNC_END(ffi_go_closure_VFP)
|
||||
|
||||
ARM_FUNC_START(ffi_closure_VFP)
|
||||
UNWIND(.fnstart)
|
||||
cfi_startproc
|
||||
stmdb sp!, {r0-r3} @ save argument regs
|
||||
cfi_adjust_cfa_offset(16)
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
|
||||
#endif
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
|
||||
0:
|
||||
add ip, sp, #16
|
||||
sub sp, sp, #64+32 @ allocate frame
|
||||
cfi_adjust_cfa_offset(64+32)
|
||||
#ifdef __clang__
|
||||
vstm sp, {d0-d7}
|
||||
#else
|
||||
stc p11, cr0, [sp], {16} @ vstm sp, {d0-d7}
|
||||
#endif
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
/* See above. */
|
||||
UNWIND(.save {sp,lr})
|
||||
cfi_adjust_cfa_offset(8)
|
||||
cfi_rel_offset(lr, 4)
|
||||
|
||||
add r3, sp, #8 @ load frame
|
||||
bl CNAME(ffi_closure_inner_VFP)
|
||||
|
||||
@ Load values returned in registers.
|
||||
add r2, sp, #8+64 @ load result
|
||||
adr r3, CNAME(ffi_closure_ret)
|
||||
add pc, r3, r0, lsl #3
|
||||
cfi_endproc
|
||||
UNWIND(.fnend)
|
||||
ARM_FUNC_END(ffi_closure_VFP)
|
||||
|
||||
/* Load values returned in registers for both closure entry points.
|
||||
Note that we use LDM with SP in the register set. This is deprecated
|
||||
by ARM, but not yet unpredictable. */
|
||||
|
||||
ARM_FUNC_START_LOCAL(ffi_closure_ret)
|
||||
cfi_startproc
|
||||
cfi_rel_offset(sp, 0)
|
||||
cfi_rel_offset(lr, 4)
|
||||
0:
|
||||
E(ARM_TYPE_VFP_S)
|
||||
#ifdef __clang__
|
||||
vldr s0, [r2]
|
||||
#else
|
||||
ldc p10, cr0, [r2] @ vldr s0, [r2]
|
||||
#endif
|
||||
ldm sp, {sp,pc}
|
||||
E(ARM_TYPE_VFP_D)
|
||||
#ifdef __clang__
|
||||
vldr d0, [r2]
|
||||
#else
|
||||
ldc p11, cr0, [r2] @ vldr d0, [r2]
|
||||
#endif
|
||||
ldm sp, {sp,pc}
|
||||
E(ARM_TYPE_VFP_N)
|
||||
#ifdef __clang__
|
||||
vldm r2, {d0-d3}
|
||||
#else
|
||||
ldc p11, cr0, [r2], {8} @ vldm r2, {d0-d3}
|
||||
#endif
|
||||
ldm sp, {sp,pc}
|
||||
E(ARM_TYPE_INT64)
|
||||
ldr r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT)
|
||||
ldr r0, [r2]
|
||||
ldm sp, {sp,pc}
|
||||
E(ARM_TYPE_VOID)
|
||||
ldm sp, {sp,pc}
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT)
|
||||
ldm sp, {sp,pc}
|
||||
cfi_endproc
|
||||
ARM_FUNC_END(ffi_closure_ret)
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
#include <mach/machine/vm_param.h>
|
||||
|
||||
.align PAGE_MAX_SHIFT
|
||||
ARM_FUNC_START(ffi_closure_trampoline_table_page)
|
||||
.rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
|
||||
adr ip, #-PAGE_MAX_SIZE @ the config page is PAGE_MAX_SIZE behind the trampoline page
|
||||
sub ip, #8 @ account for pc bias
|
||||
ldr pc, [ip, #4] @ jump to ffi_closure_SYSV or ffi_closure_VFP
|
||||
.endr
|
||||
ARM_FUNC_END(ffi_closure_trampoline_table_page)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
ARM_FUNC_START(ffi_arm_trampoline)
|
||||
0: adr ip, 0b
|
||||
ldr pc, 1f
|
||||
1: .long 0
|
||||
ARM_FUNC_END(ffi_arm_trampoline)
|
||||
|
||||
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
|
||||
#endif /* __arm__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
311
src/arm/sysv_msvc_arm32.S
Normal file
311
src/arm/sysv_msvc_arm32.S
Normal file
@ -0,0 +1,311 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
Copyright (c) 2019 Microsoft Corporation.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
#include "ksarm.h"
|
||||
|
||||
|
||||
; 8 byte aligned AREA to support 8 byte aligned jump tables
|
||||
MACRO
|
||||
NESTED_ENTRY_FFI $FuncName, $AreaName, $ExceptHandler
|
||||
|
||||
; compute the function's labels
|
||||
__DeriveFunctionLabels $FuncName
|
||||
|
||||
; determine the area we will put the function into
|
||||
__FuncArea SETS "|.text|"
|
||||
IF "$AreaName" != ""
|
||||
__FuncArea SETS "$AreaName"
|
||||
ENDIF
|
||||
|
||||
; set up the exception handler itself
|
||||
__FuncExceptionHandler SETS ""
|
||||
IF "$ExceptHandler" != ""
|
||||
__FuncExceptionHandler SETS "|$ExceptHandler|"
|
||||
ENDIF
|
||||
|
||||
; switch to the specified area, jump tables require 8 byte alignment
|
||||
AREA $__FuncArea,CODE,CODEALIGN,ALIGN=3,READONLY
|
||||
|
||||
; export the function name
|
||||
__ExportProc $FuncName
|
||||
|
||||
; flush any pending literal pool stuff
|
||||
ROUT
|
||||
|
||||
; reset the state of the unwind code tracking
|
||||
__ResetUnwindState
|
||||
|
||||
MEND
|
||||
|
||||
; MACRO
|
||||
; TABLE_ENTRY $Type, $Table
|
||||
;$Type_$Table
|
||||
; MEND
|
||||
|
||||
#define E(index,table) return_##index##_##table
|
||||
|
||||
; r0: stack
|
||||
; r1: frame
|
||||
; r2: fn
|
||||
; r3: vfp_used
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_call_VFP_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_VFP
|
||||
cmp r3, #3 ; load only d0 if possible
|
||||
vldrle d0, [r0]
|
||||
vldmgt r0, {d0-d7}
|
||||
add r0, r0, #64 ; discard the vfp register args
|
||||
b ffi_call_SYSV
|
||||
NESTED_END ffi_call_VFP_fake
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_call_SYSV_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_SYSV
|
||||
stm r1, {fp, lr}
|
||||
mov fp, r1
|
||||
|
||||
mov sp, r0 ; install the stack pointer
|
||||
mov lr, r2 ; move the fn pointer out of the way
|
||||
ldr ip, [fp, #16] ; install the static chain
|
||||
ldmia sp!, {r0-r3} ; move first 4 parameters in registers.
|
||||
blx lr ; call fn
|
||||
|
||||
; Load r2 with the pointer to storage for the return value
|
||||
; Load r3 with the return type code
|
||||
ldr r2, [fp, #8]
|
||||
ldr r3, [fp, #12]
|
||||
|
||||
; Deallocate the stack with the arguments.
|
||||
mov sp, fp
|
||||
|
||||
; Store values stored in registers.
|
||||
ALIGN 8
|
||||
lsl r3, #3
|
||||
add r3, r3, pc
|
||||
add r3, #8
|
||||
mov pc, r3
|
||||
|
||||
|
||||
E(ARM_TYPE_VFP_S, ffi_call)
|
||||
ALIGN 8
|
||||
vstr s0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_D, ffi_call)
|
||||
ALIGN 8
|
||||
vstr d0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_N, ffi_call)
|
||||
ALIGN 8
|
||||
vstm r2, {d0-d3}
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_INT64, ffi_call)
|
||||
ALIGN 8
|
||||
str r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT, ffi_call)
|
||||
ALIGN 8
|
||||
str r0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VOID, ffi_call)
|
||||
ALIGN 8
|
||||
pop {fp,pc}
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT, ffi_call)
|
||||
ALIGN 8
|
||||
cmp r3, #ARM_TYPE_STRUCT
|
||||
pop {fp,pc}
|
||||
NESTED_END ffi_call_SYSV_fake
|
||||
|
||||
IMPORT |ffi_closure_inner_SYSV|
|
||||
/*
|
||||
int ffi_closure_inner_SYSV
|
||||
(
|
||||
cif, ; r0
|
||||
fun, ; r1
|
||||
user_data, ; r2
|
||||
frame ; r3
|
||||
)
|
||||
*/
|
||||
|
||||
NESTED_ENTRY_FFI ffi_go_closure_SYSV
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
ldr r0, [ip, #4] ; load cif
|
||||
ldr r1, [ip, #8] ; load fun
|
||||
mov r2, ip ; load user_data
|
||||
b ffi_go_closure_SYSV_0
|
||||
NESTED_END ffi_go_closure_SYSV
|
||||
|
||||
; r3: ffi_closure
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_closure_SYSV_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
ALTERNATE_ENTRY ffi_closure_SYSV
|
||||
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; ffi_closure->cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; ffi_closure->fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; ffi_closure->user_data
|
||||
|
||||
ALTERNATE_ENTRY ffi_go_closure_SYSV_0
|
||||
add ip, sp, #16 ; compute entry sp
|
||||
|
||||
sub sp, sp, #64+32 ; allocate frame parameter (sizeof(vfp_space) = 64, sizeof(result) = 32)
|
||||
mov r3, sp ; set frame parameter
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
bl ffi_closure_inner_SYSV ; call the Python closure
|
||||
|
||||
; Load values returned in registers.
|
||||
add r2, sp, #64+8 ; address of closure_frame->result
|
||||
bl ffi_closure_ret ; move result to correct register or memory for type
|
||||
|
||||
ldmfd sp!, {ip,lr}
|
||||
mov sp, ip ; restore stack pointer
|
||||
mov pc, lr
|
||||
NESTED_END ffi_closure_SYSV_fake
|
||||
|
||||
IMPORT |ffi_closure_inner_VFP|
|
||||
/*
|
||||
int ffi_closure_inner_VFP
|
||||
(
|
||||
cif, ; r0
|
||||
fun, ; r1
|
||||
user_data, ; r2
|
||||
frame ; r3
|
||||
)
|
||||
*/
|
||||
|
||||
NESTED_ENTRY_FFI ffi_go_closure_VFP
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
ldr r0, [ip, #4] ; load cif
|
||||
ldr r1, [ip, #8] ; load fun
|
||||
mov r2, ip ; load user_data
|
||||
b ffi_go_closure_VFP_0
|
||||
NESTED_END ffi_go_closure_VFP
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
; r3: closure
|
||||
NESTED_ENTRY_FFI ffi_closure_VFP_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_closure_VFP
|
||||
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; load cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; load fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; load user_data
|
||||
|
||||
ALTERNATE_ENTRY ffi_go_closure_VFP_0
|
||||
add ip, sp, #16 ; compute entry sp
|
||||
sub sp, sp, #32 ; save space for closure_frame->result
|
||||
vstmdb sp!, {d0-d7} ; push closure_frame->vfp_space
|
||||
|
||||
mov r3, sp ; save closure_frame
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
bl ffi_closure_inner_VFP
|
||||
|
||||
; Load values returned in registers.
|
||||
add r2, sp, #64+8 ; load result
|
||||
bl ffi_closure_ret
|
||||
ldmfd sp!, {ip,lr}
|
||||
mov sp, ip ; restore stack pointer
|
||||
mov pc, lr
|
||||
NESTED_END ffi_closure_VFP_fake
|
||||
|
||||
/* Load values returned in registers for both closure entry points.
|
||||
Note that we use LDM with SP in the register set. This is deprecated
|
||||
by ARM, but not yet unpredictable. */
|
||||
|
||||
NESTED_ENTRY_FFI ffi_closure_ret
|
||||
stmdb sp!, {fp,lr}
|
||||
|
||||
ALIGN 8
|
||||
lsl r0, #3
|
||||
add r0, r0, pc
|
||||
add r0, #8
|
||||
mov pc, r0
|
||||
|
||||
E(ARM_TYPE_VFP_S, ffi_closure)
|
||||
ALIGN 8
|
||||
vldr s0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VFP_D, ffi_closure)
|
||||
ALIGN 8
|
||||
vldr d0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VFP_N, ffi_closure)
|
||||
ALIGN 8
|
||||
vldm r2, {d0-d3}
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_INT64, ffi_closure)
|
||||
ALIGN 8
|
||||
ldr r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT, ffi_closure)
|
||||
ALIGN 8
|
||||
ldr r0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VOID, ffi_closure)
|
||||
ALIGN 8
|
||||
b call_epilogue
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT, ffi_closure)
|
||||
ALIGN 8
|
||||
b call_epilogue
|
||||
call_epilogue
|
||||
ldmfd sp!, {fp,pc}
|
||||
NESTED_END ffi_closure_ret
|
||||
|
||||
AREA |.trampoline|, DATA, THUMB, READONLY
|
||||
EXPORT |ffi_arm_trampoline|
|
||||
|ffi_arm_trampoline| DATA
|
||||
thisproc adr ip, thisproc
|
||||
stmdb sp!, {ip, r0}
|
||||
ldr pc, [pc, #0]
|
||||
DCD 0
|
||||
;ENDP
|
||||
|
||||
END
|
423
src/avr32/ffi.c
Normal file
423
src/avr32/ffi.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2011 Anthony Green
|
||||
Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
|
||||
|
||||
AVR32 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned int, unsigned int, unsigned int*, unsigned int,
|
||||
void (*fn)(void));
|
||||
extern void ffi_closure_SYSV (ffi_closure *);
|
||||
|
||||
unsigned int pass_struct_on_stack(ffi_type *type)
|
||||
{
|
||||
if(type->type != FFI_TYPE_STRUCT)
|
||||
return 0;
|
||||
|
||||
if(type->alignment < type->size &&
|
||||
!(type->size == 4 || type->size == 8) &&
|
||||
!(type->size == 8 && type->alignment >= 4))
|
||||
return 1;
|
||||
|
||||
if(type->size == 3 || type->size == 5 || type->size == 6 ||
|
||||
type->size == 7)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
* has been allocated for the function's arguments
|
||||
*
|
||||
* This is annoyingly complex since we need to keep track of used
|
||||
* registers.
|
||||
*/
|
||||
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
unsigned int i;
|
||||
void **p_argv;
|
||||
ffi_type **p_arg;
|
||||
char *reg_base = stack;
|
||||
char *stack_base = stack + 20;
|
||||
unsigned int stack_offset = 0;
|
||||
unsigned int reg_mask = 0;
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
/* If cif->flags is struct then we know it's not passed in registers */
|
||||
if(ecif->cif->flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*(void**)reg_base = ecif->rvalue;
|
||||
reg_mask |= 1;
|
||||
}
|
||||
|
||||
for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
|
||||
i++, p_arg++)
|
||||
{
|
||||
size_t z = (*p_arg)->size;
|
||||
int alignment = (*p_arg)->alignment;
|
||||
int type = (*p_arg)->type;
|
||||
char *addr = 0;
|
||||
|
||||
if(z % 4 != 0)
|
||||
z += (4 - z % 4);
|
||||
|
||||
if(reg_mask != 0x1f)
|
||||
{
|
||||
if(pass_struct_on_stack(*p_arg))
|
||||
{
|
||||
addr = stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
else if(z == sizeof(int))
|
||||
{
|
||||
char index = 0;
|
||||
|
||||
while((reg_mask >> index) & 1)
|
||||
index++;
|
||||
|
||||
addr = reg_base + (index * 4);
|
||||
reg_mask |= (1 << index);
|
||||
}
|
||||
else if(z == 2 * sizeof(int))
|
||||
{
|
||||
if(!((reg_mask >> 1) & 1))
|
||||
{
|
||||
addr = reg_base + 4;
|
||||
reg_mask |= (3 << 1);
|
||||
}
|
||||
else if(!((reg_mask >> 3) & 1))
|
||||
{
|
||||
addr = reg_base + 12;
|
||||
reg_mask |= (3 << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!addr)
|
||||
{
|
||||
addr = stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
|
||||
if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
|
||||
type = (*p_arg)->elements[0]->type;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
|
||||
break;
|
||||
default:
|
||||
memcpy(addr, *p_argv, z);
|
||||
}
|
||||
|
||||
p_argv++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < 5; i++)
|
||||
{
|
||||
if((reg_mask & (1 << i)) == 0)
|
||||
printf("r%d: (unused)\n", 12 - i);
|
||||
else
|
||||
printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < stack_offset / 4; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
* everywhere, but it is on some platforms, and it doesn't harm
|
||||
* anything when it isn't needed. */
|
||||
cif->bytes = (cif->bytes + 7) & ~7;
|
||||
|
||||
/* Flag to indicate that he return value is in fact a struct */
|
||||
cif->rstruct_flag = 0;
|
||||
|
||||
/* Set the return type flag */
|
||||
switch(cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT8;
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT16;
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT32;
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT64;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
cif->rstruct_flag = 1;
|
||||
if(!pass_struct_on_stack(cif->rtype))
|
||||
{
|
||||
if(cif->rtype->size <= 1)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT8;
|
||||
else if(cif->rtype->size <= 2)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT16;
|
||||
else if(cif->rtype->size <= 4)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT32;
|
||||
else if(cif->rtype->size <= 8)
|
||||
cif->flags = (unsigned)FFI_TYPE_UINT64;
|
||||
else
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
}
|
||||
else
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
break;
|
||||
default:
|
||||
cif->flags = (unsigned)cif->rtype->type;
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
unsigned int size = 0, i = 0;
|
||||
ffi_type **p_arg;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
|
||||
|
||||
/* If the return value is a struct and we don't have a return value
|
||||
* address then we need to make one */
|
||||
|
||||
/* If cif->flags is struct then it's not suitable for registers */
|
||||
if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch(cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
|
||||
ecif.rvalue, cif->rstruct_flag, fn);
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif)
|
||||
{
|
||||
register unsigned int i, reg_mask = 0;
|
||||
register void **p_argv;
|
||||
register ffi_type **p_arg;
|
||||
register char *reg_base = stack;
|
||||
register char *stack_base = stack + 20;
|
||||
register unsigned int stack_offset = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < cif->nargs + 7; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If cif->flags is struct then we know it's not passed in registers */
|
||||
if(cif->flags == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*rvalue = *(void **)reg_base;
|
||||
reg_mask |= 1;
|
||||
}
|
||||
|
||||
p_argv = avalue;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
{
|
||||
size_t z = (*p_arg)->size;
|
||||
int alignment = (*p_arg)->alignment;
|
||||
|
||||
*p_argv = 0;
|
||||
|
||||
if(z % 4 != 0)
|
||||
z += (4 - z % 4);
|
||||
|
||||
if(reg_mask != 0x1f)
|
||||
{
|
||||
if(pass_struct_on_stack(*p_arg))
|
||||
{
|
||||
*p_argv = (void*)stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
else if(z <= sizeof(int))
|
||||
{
|
||||
char index = 0;
|
||||
|
||||
while((reg_mask >> index) & 1)
|
||||
index++;
|
||||
|
||||
*p_argv = (void*)reg_base + (index * 4);
|
||||
reg_mask |= (1 << index);
|
||||
}
|
||||
else if(z == 2 * sizeof(int))
|
||||
{
|
||||
if(!((reg_mask >> 1) & 1))
|
||||
{
|
||||
*p_argv = (void*)reg_base + 4;
|
||||
reg_mask |= (3 << 1);
|
||||
}
|
||||
else if(!((reg_mask >> 3) & 1))
|
||||
{
|
||||
*p_argv = (void*)reg_base + 12;
|
||||
reg_mask |= (3 << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!*p_argv)
|
||||
{
|
||||
*p_argv = (void*)stack_base + stack_offset;
|
||||
stack_offset += z;
|
||||
}
|
||||
|
||||
if((*p_arg)->type != FFI_TYPE_STRUCT ||
|
||||
(*p_arg)->elements[1] == NULL)
|
||||
{
|
||||
if(alignment == 1)
|
||||
**(unsigned int**)p_argv <<= 24;
|
||||
else if(alignment == 2)
|
||||
**(unsigned int**)p_argv <<= 16;
|
||||
}
|
||||
|
||||
p_argv++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Debugging */
|
||||
for(i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
|
||||
void *args)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
unsigned int i, size = 0;
|
||||
ffi_type **p_arg;
|
||||
|
||||
cif = closure->cif;
|
||||
|
||||
for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
|
||||
size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
|
||||
|
||||
arg_area = (void **)alloca(size);
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each element in that
|
||||
* array points to the corresponding value on the stack; and if the
|
||||
* function returns a structure, it will re-set RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
|
||||
|
||||
(closure->fun)(cif, *respp, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
|
||||
ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
if (cif->abi != FFI_SYSV)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
|
||||
unsigned int __fun = (unsigned int)(&ffi_closure_SYSV);
|
||||
unsigned int __ctx = (unsigned int)(codeloc);
|
||||
unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag);
|
||||
unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner);
|
||||
*(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */
|
||||
*(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */
|
||||
*(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */
|
||||
*(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */
|
||||
*(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */
|
||||
*(unsigned int*) &__tramp[20] = __ctx;
|
||||
*(unsigned int*) &__tramp[24] = __rstruct_flag;
|
||||
*(unsigned int*) &__tramp[28] = __inner;
|
||||
*(unsigned int*) &__tramp[32] = __fun;
|
||||
syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user