Merge branch 'master' of github.com:/atgreen/libffi
Add ChangeLog entry.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -19,3 +19,5 @@ autom4te.cache
|
||||
libffi.xcodeproj/xcuserdata
|
||||
libffi.xcodeproj/project.xcworkspace
|
||||
ios/
|
||||
osx/
|
||||
build_*/
|
||||
|
||||
23
ChangeLog
23
ChangeLog
@@ -1,3 +1,26 @@
|
||||
2012-11-30 Zachary Waldowski <zwaldowski@gmail.com>
|
||||
|
||||
* src/arm/ffi.c, src/dlmalloc.c, src/x86/ffi.c: Silence Clang
|
||||
warnings.
|
||||
* src/arm/sysv.S: Simplify RETLDM arguments for LLVM 3.1. More
|
||||
Clang clean-ups.
|
||||
* .gitignore: Exclude OS X generated source and build_.
|
||||
* generate-osx-source-and-headers.py: Clean up, modernize scripts.
|
||||
* generate-ios-source-and-headers.py: Ditto, and add __arm64__
|
||||
support.
|
||||
* include/ffi_common.h: Test for HAVE_STRING_H.
|
||||
* src/closures.c (open_temp_exec_file_dir): Use size_t.
|
||||
* src/prep_cif (ffi_prep_cif_core): Cast ALIGN result.
|
||||
* src/x86/ffi64.c: More Clang warning clean-ups.
|
||||
* src/aarch64/sysv.S: Use CNAME for global symbols. Only use
|
||||
.size for ELF targets.
|
||||
* src/aarch64/ffi.c: Clean up for double == long double. Clean up
|
||||
for Xcode warnings. Use Clang cache invalidation builtin. Use
|
||||
size_t in place of unsigned in many places.
|
||||
* libffi.xcodeproj/project.pbxproj: Include x86_64+aarch64 pieces
|
||||
in library. Export headers properly.
|
||||
* build-ios.sh: Remove.
|
||||
|
||||
2013-11-21 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* configure, Makefile.in, include/Makefile.in, include/ffi.h.in,
|
||||
|
||||
67
build-ios.sh
67
build-ios.sh
@@ -1,67 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PLATFORM_IOS=/Developer/Platforms/iPhoneOS.platform/
|
||||
PLATFORM_IOS_SIM=/Developer/Platforms/iPhoneSimulator.platform/
|
||||
SDK_IOS_VERSION="4.2"
|
||||
MIN_IOS_VERSION="3.0"
|
||||
OUTPUT_DIR="universal-ios"
|
||||
|
||||
build_target () {
|
||||
local platform=$1
|
||||
local sdk=$2
|
||||
local arch=$3
|
||||
local triple=$4
|
||||
local builddir=$5
|
||||
|
||||
mkdir -p "${builddir}"
|
||||
pushd "${builddir}"
|
||||
export CC="${platform}"/Developer/usr/bin/gcc-4.2
|
||||
export CFLAGS="-arch ${arch} -isysroot ${sdk} -miphoneos-version-min=${MIN_IOS_VERSION}"
|
||||
../configure --host=${triple} && make
|
||||
popd
|
||||
}
|
||||
|
||||
# Build all targets
|
||||
build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv6 arm-apple-darwin10 armv6-ios
|
||||
build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv7 arm-apple-darwin10 armv7-ios
|
||||
build_target "${PLATFORM_IOS_SIM}" "${PLATFORM_IOS_SIM}/Developer/SDKs/iPhoneSimulator${SDK_IOS_VERSION}.sdk/" i386 i386-apple-darwin10 i386-ios-sim
|
||||
|
||||
# Create universal output directories
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
mkdir -p "${OUTPUT_DIR}/include"
|
||||
mkdir -p "${OUTPUT_DIR}/include/armv6"
|
||||
mkdir -p "${OUTPUT_DIR}/include/armv7"
|
||||
mkdir -p "${OUTPUT_DIR}/include/i386"
|
||||
|
||||
# Create the universal binary
|
||||
lipo -create armv6-ios/.libs/libffi.a armv7-ios/.libs/libffi.a i386-ios-sim/.libs/libffi.a -output "${OUTPUT_DIR}/libffi.a"
|
||||
|
||||
# Copy in the headers
|
||||
copy_headers () {
|
||||
local src=$1
|
||||
local dest=$2
|
||||
|
||||
# Fix non-relative header reference
|
||||
sed 's/<ffitarget.h>/"ffitarget.h"/' < "${src}/include/ffi.h" > "${dest}/ffi.h"
|
||||
cp "${src}/include/ffitarget.h" "${dest}"
|
||||
}
|
||||
|
||||
copy_headers armv6-ios "${OUTPUT_DIR}/include/armv6"
|
||||
copy_headers armv7-ios "${OUTPUT_DIR}/include/armv7"
|
||||
copy_headers i386-ios-sim "${OUTPUT_DIR}/include/i386"
|
||||
|
||||
# Create top-level header
|
||||
(
|
||||
cat << EOF
|
||||
#ifdef __arm__
|
||||
#include <arm/arch.h>
|
||||
#ifdef _ARM_ARCH_6
|
||||
#include "include/armv6/ffi.h"
|
||||
#elif _ARM_ARCH_7
|
||||
#include "include/armv7/ffi.h"
|
||||
#endif
|
||||
#elif defined(__i386__)
|
||||
#include "include/i386/ffi.h"
|
||||
#endif
|
||||
EOF
|
||||
) > "${OUTPUT_DIR}/ffi.h"
|
||||
@@ -1,29 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
import os
|
||||
import errno
|
||||
import collections
|
||||
import sys
|
||||
|
||||
class Platform(object):
|
||||
pass
|
||||
|
||||
sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')
|
||||
|
||||
|
||||
def sdkinfo(sdkname):
|
||||
ret = {}
|
||||
for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
|
||||
kv = line.strip().split(': ', 1)
|
||||
if len(kv) == 2:
|
||||
k,v = kv
|
||||
k, v = kv
|
||||
ret[k] = v
|
||||
return ret
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >2.5
|
||||
if exc.errno == errno.EEXIST:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
sim_sdk_info = sdkinfo('iphonesimulator')
|
||||
device_sdk_info = sdkinfo('iphoneos')
|
||||
|
||||
|
||||
def latest_sdks():
|
||||
latest_sim = None
|
||||
latest_device = None
|
||||
@@ -39,36 +50,62 @@ def latest_sdks():
|
||||
|
||||
sim_sdk, device_sdk = latest_sdks()
|
||||
|
||||
class simulator_platform(Platform):
|
||||
sdk='iphonesimulator'
|
||||
arch = 'i386'
|
||||
name = 'simulator'
|
||||
triple = 'i386-apple-darwin10'
|
||||
sdkroot = sim_sdk_info['Path']
|
||||
|
||||
prefix = "#if !defined(__arm__) && defined(__i386__)\n\n"
|
||||
class simulator_platform(Platform):
|
||||
sdk = 'iphonesimulator'
|
||||
arch = 'i386'
|
||||
short_arch = arch
|
||||
triple = 'i386-apple-darwin11'
|
||||
sdkroot = sim_sdk_info['Path']
|
||||
version_min = '5.1.1'
|
||||
|
||||
prefix = "#ifdef __i386__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
|
||||
class simulator64_platform(Platform):
|
||||
sdk = 'iphonesimulator'
|
||||
arch = 'x86_64'
|
||||
short_arch = arch
|
||||
triple = 'x86_64-apple-darwin13'
|
||||
sdkroot = sim_sdk_info['Path']
|
||||
version_min = '7.0'
|
||||
|
||||
prefix = "#ifdef __x86_64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
|
||||
class device_platform(Platform):
|
||||
sdk='iphoneos'
|
||||
name = 'ios'
|
||||
sdk = 'iphoneos'
|
||||
arch = 'armv7'
|
||||
triple = 'arm-apple-darwin10'
|
||||
short_arch = 'arm'
|
||||
triple = 'arm-apple-darwin11'
|
||||
sdkroot = device_sdk_info['Path']
|
||||
version_min = '5.1.1'
|
||||
|
||||
prefix = "#ifdef __arm__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
|
||||
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
|
||||
if not os.path.exists(dst_dir):
|
||||
os.makedirs(dst_dir)
|
||||
class device64_platform(Platform):
|
||||
sdk = 'iphoneos'
|
||||
arch = 'arm64'
|
||||
short_arch = 'arm64'
|
||||
triple = 'aarch64-apple-darwin13'
|
||||
sdkroot = device_sdk_info['Path']
|
||||
version_min = '7.0'
|
||||
|
||||
prefix = "#ifdef __arm64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
|
||||
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
|
||||
mkdir_p(dst_dir)
|
||||
out_filename = filename
|
||||
|
||||
if file_suffix:
|
||||
split_name = os.path.splitext(filename)
|
||||
out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
|
||||
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:
|
||||
@@ -82,16 +119,15 @@ def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''
|
||||
|
||||
headers_seen = collections.defaultdict(set)
|
||||
|
||||
|
||||
def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
|
||||
for root, dirs, files in os.walk(src_dir, followlinks=True):
|
||||
relroot = os.path.relpath(root,src_dir)
|
||||
relroot = os.path.relpath(root, src_dir)
|
||||
|
||||
def move_dir(arch, prefix='', suffix='', files=[]):
|
||||
for file in files:
|
||||
file_suffix = None
|
||||
if file.endswith('.h'):
|
||||
if dest_include_dir:
|
||||
file_suffix = arch
|
||||
if arch:
|
||||
headers_seen[file].add(arch)
|
||||
move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)
|
||||
@@ -109,46 +145,66 @@ def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None
|
||||
move_dir(arch='arm',
|
||||
prefix="#ifdef __arm__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=files)
|
||||
files=['sysv.S', 'trampoline.S', 'ffi.c'])
|
||||
elif relroot == 'aarch64':
|
||||
move_dir(arch='arm64',
|
||||
prefix="#ifdef __arm64__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=['sysv.S', 'ffi.c'])
|
||||
elif relroot == 'x86':
|
||||
move_dir(arch='i386',
|
||||
prefix="#if !defined(__arm__) && defined(__i386__)\n\n",
|
||||
prefix="#ifdef __i386__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=files)
|
||||
files=['darwin.S', 'ffi.c'])
|
||||
move_dir(arch='x86_64',
|
||||
prefix="#ifdef __x86_64__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=['darwin64.S', 'ffi64.c'])
|
||||
|
||||
|
||||
def build_target(platform):
|
||||
def xcrun_cmd(cmd):
|
||||
return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip()
|
||||
|
||||
build_dir = 'build_' + platform.name
|
||||
if not os.path.exists(build_dir):
|
||||
os.makedirs(build_dir)
|
||||
env = dict(CC=xcrun_cmd('clang'),
|
||||
LD=xcrun_cmd('ld'),
|
||||
CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot))
|
||||
working_dir=os.getcwd()
|
||||
try:
|
||||
os.chdir(build_dir)
|
||||
subprocess.check_call(['../configure', '-host', platform.triple], env=env)
|
||||
move_source_tree('.', None, '../ios/include',
|
||||
arch=platform.arch,
|
||||
prefix=platform.prefix,
|
||||
suffix=platform.suffix)
|
||||
move_source_tree('./include', None, '../ios/include',
|
||||
arch=platform.arch,
|
||||
prefix=platform.prefix,
|
||||
suffix=platform.suffix)
|
||||
finally:
|
||||
os.chdir(working_dir)
|
||||
build_dir = 'build_' + platform.short_arch
|
||||
mkdir_p(build_dir)
|
||||
env = dict(CC=xcrun_cmd('clang'),
|
||||
LD=xcrun_cmd('ld'),
|
||||
CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=%s' % (platform.arch, platform.sdkroot, platform.version_min))
|
||||
working_dir = os.getcwd()
|
||||
try:
|
||||
os.chdir(build_dir)
|
||||
subprocess.check_call(['../configure', '-host', platform.triple], env=env)
|
||||
move_source_tree('.', None, '../ios/include',
|
||||
arch=platform.short_arch,
|
||||
prefix=platform.prefix,
|
||||
suffix=platform.suffix)
|
||||
move_source_tree('./include', None, '../ios/include',
|
||||
arch=platform.short_arch,
|
||||
prefix=platform.prefix,
|
||||
suffix=platform.suffix)
|
||||
finally:
|
||||
os.chdir(working_dir)
|
||||
|
||||
for header_name, archs in headers_seen.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
|
||||
|
||||
def make_tramp():
|
||||
with open('src/arm/trampoline.S', 'w') as tramp_out:
|
||||
p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)
|
||||
p.wait()
|
||||
|
||||
for header_name, archs in headers_seen.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
|
||||
def main():
|
||||
make_tramp()
|
||||
|
||||
move_source_tree('src', 'ios/src', 'ios/include')
|
||||
move_source_tree('include', None, 'ios/include')
|
||||
build_target(simulator_platform)
|
||||
build_target(simulator64_platform)
|
||||
build_target(device_platform)
|
||||
build_target(device64_platform)
|
||||
|
||||
for header_name, archs in headers_seen.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
|
||||
@@ -4,24 +4,36 @@ import re
|
||||
import os
|
||||
import errno
|
||||
import collections
|
||||
import sys
|
||||
|
||||
|
||||
class Platform(object):
|
||||
pass
|
||||
|
||||
sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')
|
||||
|
||||
|
||||
def sdkinfo(sdkname):
|
||||
ret = {}
|
||||
for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
|
||||
kv = line.strip().split(': ', 1)
|
||||
if len(kv) == 2:
|
||||
k,v = kv
|
||||
k, v = kv
|
||||
ret[k] = v
|
||||
return ret
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >2.5
|
||||
if exc.errno == errno.EEXIST:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
desktop_sdk_info = sdkinfo('macosx')
|
||||
|
||||
|
||||
def latest_sdks():
|
||||
latest_desktop = None
|
||||
for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
|
||||
@@ -34,35 +46,38 @@ def latest_sdks():
|
||||
|
||||
desktop_sdk = latest_sdks()
|
||||
|
||||
class desktop_platform_32(Platform):
|
||||
sdk='macosx'
|
||||
|
||||
class desktop32_platform(Platform):
|
||||
sdk = 'macosx'
|
||||
arch = 'i386'
|
||||
name = 'mac32'
|
||||
triple = 'i386-apple-darwin10'
|
||||
triple = 'i386-apple-darwin11'
|
||||
sdkroot = desktop_sdk_info['Path']
|
||||
version_min = '10.7'
|
||||
|
||||
prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n"
|
||||
prefix = "#ifdef __i386__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
class desktop_platform_64(Platform):
|
||||
sdk='macosx'
|
||||
|
||||
class desktop64_platform(Platform):
|
||||
sdk = 'macosx'
|
||||
arch = 'x86_64'
|
||||
name = 'mac'
|
||||
triple = 'x86_64-apple-darwin10'
|
||||
triple = 'x86_64-apple-darwin11'
|
||||
sdkroot = desktop_sdk_info['Path']
|
||||
version_min = '10.7'
|
||||
|
||||
prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n"
|
||||
prefix = "#ifdef __x86_64__\n\n"
|
||||
suffix = "\n\n#endif"
|
||||
|
||||
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
|
||||
if not os.path.exists(dst_dir):
|
||||
os.makedirs(dst_dir)
|
||||
|
||||
def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
|
||||
mkdir_p(dst_dir)
|
||||
out_filename = filename
|
||||
|
||||
if file_suffix:
|
||||
split_name = os.path.splitext(filename)
|
||||
out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
|
||||
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:
|
||||
@@ -76,16 +91,15 @@ def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''
|
||||
|
||||
headers_seen = collections.defaultdict(set)
|
||||
|
||||
|
||||
def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
|
||||
for root, dirs, files in os.walk(src_dir, followlinks=True):
|
||||
relroot = os.path.relpath(root,src_dir)
|
||||
relroot = os.path.relpath(root, src_dir)
|
||||
|
||||
def move_dir(arch, prefix='', suffix='', files=[]):
|
||||
for file in files:
|
||||
file_suffix = None
|
||||
if file.endswith('.h'):
|
||||
if dest_include_dir:
|
||||
file_suffix = arch
|
||||
if arch:
|
||||
headers_seen[file].add(arch)
|
||||
move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)
|
||||
@@ -101,13 +115,14 @@ def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None
|
||||
suffix=suffix)
|
||||
elif relroot == 'x86':
|
||||
move_dir(arch='i386',
|
||||
prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n",
|
||||
prefix="#ifdef __i386__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=files)
|
||||
files=['darwin.S', 'ffi.c'])
|
||||
move_dir(arch='x86_64',
|
||||
prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n",
|
||||
prefix="#ifdef __x86_64__\n\n",
|
||||
suffix="\n\n#endif",
|
||||
files=files)
|
||||
files=['darwin64.S', 'ffi64.c'])
|
||||
|
||||
|
||||
def build_target(platform):
|
||||
def xcrun_cmd(cmd):
|
||||
@@ -118,8 +133,8 @@ def build_target(platform):
|
||||
os.makedirs(build_dir)
|
||||
env = dict(CC=xcrun_cmd('clang'),
|
||||
LD=xcrun_cmd('ld'),
|
||||
CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot))
|
||||
working_dir=os.getcwd()
|
||||
CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=%s' % (platform.arch, platform.sdkroot, platform.version_min))
|
||||
working_dir = os.getcwd()
|
||||
try:
|
||||
os.chdir(build_dir)
|
||||
subprocess.check_call(['../configure', '-host', platform.triple], env=env)
|
||||
@@ -137,11 +152,12 @@ def build_target(platform):
|
||||
for header_name, archs in headers_seen.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
|
||||
|
||||
def main():
|
||||
move_source_tree('src', 'osx/src', 'osx/include')
|
||||
move_source_tree('include', None, 'osx/include')
|
||||
build_target(desktop_platform_32)
|
||||
build_target(desktop_platform_64)
|
||||
build_target(desktop32_platform)
|
||||
build_target(desktop64_platform)
|
||||
|
||||
for header_name, archs in headers_seen.iteritems():
|
||||
basename, suffix = os.path.splitext(header_name)
|
||||
|
||||
@@ -48,7 +48,7 @@ char *alloca ();
|
||||
#endif
|
||||
|
||||
/* Check for the existence of memcpy. */
|
||||
#if STDC_HEADERS
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# ifndef HAVE_MEMCPY
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,14 +49,29 @@ struct call_context
|
||||
} v [AARCH64_N_VREG];
|
||||
};
|
||||
|
||||
#if defined(__clang__) && defined(__APPLE__)
|
||||
void sys_icache_invalidate(void *start, size_t len);
|
||||
#endif
|
||||
|
||||
static inline void ffi_clear_cache(void *start, void *end)
|
||||
{
|
||||
#if defined(__clang__) && defined(__APPLE__)
|
||||
sys_icache_invalidate(start, (char *)end-(char *)start);
|
||||
#elif defined(__GNUC__)
|
||||
__builtin___clear_cache(start, end);
|
||||
#else
|
||||
#error "Missing builtin to flush instruction cache"
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *
|
||||
get_x_addr (struct call_context *context, unsigned n)
|
||||
get_x_addr (struct call_context *context, size_t n)
|
||||
{
|
||||
return &context->x[n];
|
||||
}
|
||||
|
||||
static void *
|
||||
get_s_addr (struct call_context *context, unsigned n)
|
||||
get_s_addr (struct call_context *context, size_t n)
|
||||
{
|
||||
#if defined __AARCH64EB__
|
||||
return &context->v[n].d[1].s[1];
|
||||
@@ -66,7 +81,7 @@ get_s_addr (struct call_context *context, unsigned n)
|
||||
}
|
||||
|
||||
static void *
|
||||
get_d_addr (struct call_context *context, unsigned n)
|
||||
get_d_addr (struct call_context *context, size_t n)
|
||||
{
|
||||
#if defined __AARCH64EB__
|
||||
return &context->v[n].d[1];
|
||||
@@ -76,7 +91,7 @@ get_d_addr (struct call_context *context, unsigned n)
|
||||
}
|
||||
|
||||
static void *
|
||||
get_v_addr (struct call_context *context, unsigned n)
|
||||
get_v_addr (struct call_context *context, size_t n)
|
||||
{
|
||||
return &context->v[n];
|
||||
}
|
||||
@@ -94,8 +109,10 @@ get_basic_type_addr (unsigned short type, struct call_context *context,
|
||||
return get_s_addr (context, n);
|
||||
case FFI_TYPE_DOUBLE:
|
||||
return get_d_addr (context, n);
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
return get_v_addr (context, n);
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
@@ -123,8 +140,10 @@ get_basic_type_alignment (unsigned short type)
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
return sizeof (UINT64);
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
return sizeof (long double);
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
@@ -154,8 +173,10 @@ get_basic_type_size (unsigned short type)
|
||||
return sizeof (UINT32);
|
||||
case FFI_TYPE_DOUBLE:
|
||||
return sizeof (UINT64);
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
return sizeof (long double);
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
return sizeof (UINT8);
|
||||
case FFI_TYPE_SINT8:
|
||||
@@ -186,7 +207,7 @@ ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *,
|
||||
extended_cif *),
|
||||
struct call_context *context,
|
||||
extended_cif *,
|
||||
unsigned,
|
||||
size_t,
|
||||
void (*fn)(void));
|
||||
|
||||
extern void
|
||||
@@ -305,7 +326,9 @@ is_register_candidate (ffi_type *ty)
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
@@ -365,14 +388,14 @@ is_v_register_candidate (ffi_type *ty)
|
||||
|
||||
struct arg_state
|
||||
{
|
||||
unsigned ngrn; /* Next general-purpose register number. */
|
||||
unsigned nsrn; /* Next vector register number. */
|
||||
unsigned nsaa; /* Next stack offset. */
|
||||
size_t ngrn; /* Next general-purpose register number. */
|
||||
size_t nsrn; /* Next vector register number. */
|
||||
size_t nsaa; /* Next stack offset. */
|
||||
};
|
||||
|
||||
/* Initialize a procedure call argument marshalling state. */
|
||||
static void
|
||||
arg_init (struct arg_state *state, unsigned call_frame_size)
|
||||
arg_init (struct arg_state *state, size_t call_frame_size)
|
||||
{
|
||||
state->ngrn = 0;
|
||||
state->nsrn = 0;
|
||||
@@ -382,7 +405,7 @@ arg_init (struct arg_state *state, unsigned call_frame_size)
|
||||
/* Return the number of available consecutive core argument
|
||||
registers. */
|
||||
|
||||
static unsigned
|
||||
static size_t
|
||||
available_x (struct arg_state *state)
|
||||
{
|
||||
return N_X_ARG_REG - state->ngrn;
|
||||
@@ -391,7 +414,7 @@ available_x (struct arg_state *state)
|
||||
/* Return the number of available consecutive vector argument
|
||||
registers. */
|
||||
|
||||
static unsigned
|
||||
static size_t
|
||||
available_v (struct arg_state *state)
|
||||
{
|
||||
return N_V_ARG_REG - state->nsrn;
|
||||
@@ -427,8 +450,8 @@ allocate_to_v (struct call_context *context, struct arg_state *state)
|
||||
|
||||
/* Allocate an aligned slot on the stack and return a pointer to it. */
|
||||
static void *
|
||||
allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment,
|
||||
unsigned size)
|
||||
allocate_to_stack (struct arg_state *state, void *stack, size_t alignment,
|
||||
size_t size)
|
||||
{
|
||||
void *allocation;
|
||||
|
||||
@@ -457,9 +480,11 @@ copy_basic_type (void *dest, void *source, unsigned short type)
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*(double *) dest = *(double *) source;
|
||||
break;
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
*(long double *) dest = *(long double *) source;
|
||||
break;
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
*(ffi_arg *) dest = *(UINT8 *) source;
|
||||
break;
|
||||
@@ -514,8 +539,8 @@ copy_hfa_to_reg_or_stack (void *memory,
|
||||
{
|
||||
int i;
|
||||
unsigned short type = get_homogeneous_type (ty);
|
||||
unsigned elems = element_count (ty);
|
||||
for (i = 0; i < elems; i++)
|
||||
unsigned count = element_count (ty);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
void *reg = allocate_to_v (context, state);
|
||||
copy_basic_type (reg, memory, type);
|
||||
@@ -548,11 +573,13 @@ allocate_to_register_or_stack (struct call_context *context,
|
||||
return allocate_to_d (context, state);
|
||||
state->nsrn = N_V_ARG_REG;
|
||||
break;
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
if (state->nsrn < N_V_ARG_REG)
|
||||
return allocate_to_v (context, state);
|
||||
state->nsrn = N_V_ARG_REG;
|
||||
break;
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
@@ -615,7 +642,9 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack,
|
||||
appropriate register, or if none are available, to the stack. */
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
@@ -728,7 +757,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
case FFI_SYSV:
|
||||
{
|
||||
struct call_context context;
|
||||
unsigned stack_bytes;
|
||||
size_t stack_bytes;
|
||||
|
||||
/* Figure out the total amount of stack space we need, the
|
||||
above call frame space needs to be 16 bytes aligned to
|
||||
@@ -745,7 +774,9 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
@@ -778,7 +809,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
}
|
||||
else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
|
||||
{
|
||||
unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64));
|
||||
size_t size = ALIGN (cif->rtype->size, sizeof (UINT64));
|
||||
memcpy (rvalue, get_x_addr (&context, 0), size);
|
||||
}
|
||||
else
|
||||
@@ -824,7 +855,7 @@ static unsigned char trampoline [] =
|
||||
memcpy (__tramp + 12, &__fun, sizeof (__fun)); \
|
||||
memcpy (__tramp + 20, &__ctx, sizeof (__ctx)); \
|
||||
memcpy (__tramp + 28, &__flags, sizeof (__flags)); \
|
||||
__clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \
|
||||
ffi_clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \
|
||||
})
|
||||
|
||||
ffi_status
|
||||
@@ -864,6 +895,9 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
value back into the call context. */
|
||||
|
||||
void
|
||||
ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
void *stack);
|
||||
void
|
||||
ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
void *stack)
|
||||
{
|
||||
@@ -897,11 +931,12 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
avalue[i] = allocate_to_register_or_stack (context, stack,
|
||||
&state, ty->type);
|
||||
break;
|
||||
|
||||
#endif
|
||||
case FFI_TYPE_STRUCT:
|
||||
if (is_hfa (ty))
|
||||
{
|
||||
@@ -958,11 +993,13 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
break;
|
||||
}
|
||||
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
memcpy (&avalue[i],
|
||||
allocate_to_v (context, &state),
|
||||
sizeof (*avalue));
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
FFI_ASSERT (0);
|
||||
@@ -1033,7 +1070,9 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
{
|
||||
void *addr = get_basic_type_addr (cif->rtype->type, context, 0);
|
||||
copy_basic_type (addr, rvalue, cif->rtype->type);
|
||||
@@ -1042,10 +1081,10 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
case FFI_TYPE_STRUCT:
|
||||
if (is_hfa (cif->rtype))
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
unsigned short type = get_homogeneous_type (cif->rtype);
|
||||
unsigned elems = element_count (cif->rtype);
|
||||
for (i = 0; i < elems; i++)
|
||||
for (j = 0; j < elems; i++)
|
||||
{
|
||||
void *reg = get_basic_type_addr (type, context, i);
|
||||
copy_basic_type (reg, rvalue, type);
|
||||
@@ -1054,7 +1093,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
}
|
||||
else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
|
||||
{
|
||||
unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
|
||||
size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
|
||||
memcpy (get_x_addr (context, 0), rvalue, size);
|
||||
}
|
||||
else
|
||||
@@ -1073,4 +1112,3 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
|
||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,15 +23,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
#else
|
||||
#define CNAME(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
|
||||
#define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
|
||||
#define cfi_restore(reg) .cfi_restore reg
|
||||
#define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
|
||||
|
||||
.text
|
||||
.globl ffi_call_SYSV
|
||||
.type ffi_call_SYSV, #function
|
||||
|
||||
/* ffi_call_SYSV()
|
||||
|
||||
Create a stack frame, setup an argument context, call the callee
|
||||
@@ -53,7 +63,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
extended_cif *),
|
||||
struct call_context *context,
|
||||
extended_cif *,
|
||||
unsigned required_stack_size,
|
||||
size_t required_stack_size,
|
||||
void (*fn)(void));
|
||||
|
||||
Therefore on entry we have:
|
||||
@@ -81,8 +91,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#define ffi_call_SYSV_FS (8 * 4)
|
||||
|
||||
.text
|
||||
.globl CNAME(ffi_call_SYSV)
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_call_SYSV), #function
|
||||
#endif
|
||||
.cfi_startproc
|
||||
ffi_call_SYSV:
|
||||
CNAME(ffi_call_SYSV):
|
||||
stp x29, x30, [sp, #-16]!
|
||||
cfi_adjust_cfa_offset (16)
|
||||
cfi_rel_offset (x29, 0)
|
||||
@@ -92,11 +107,11 @@ ffi_call_SYSV:
|
||||
cfi_def_cfa_register (x29)
|
||||
sub sp, sp, #ffi_call_SYSV_FS
|
||||
|
||||
stp x21, x22, [sp, 0]
|
||||
stp x21, x22, [sp, #0]
|
||||
cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS)
|
||||
cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS)
|
||||
|
||||
stp x23, x24, [sp, 16]
|
||||
stp x23, x24, [sp, #16]
|
||||
cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS)
|
||||
cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS)
|
||||
|
||||
@@ -180,7 +195,9 @@ ffi_call_SYSV:
|
||||
ret
|
||||
|
||||
.cfi_endproc
|
||||
.size ffi_call_SYSV, .-ffi_call_SYSV
|
||||
#ifdef __ELF__
|
||||
.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
|
||||
#endif
|
||||
|
||||
#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
|
||||
|
||||
@@ -221,10 +238,10 @@ ffi_call_SYSV:
|
||||
|
||||
Voila! */
|
||||
|
||||
.text
|
||||
.globl ffi_closure_SYSV
|
||||
.text
|
||||
.globl CNAME(ffi_closure_SYSV)
|
||||
.cfi_startproc
|
||||
ffi_closure_SYSV:
|
||||
CNAME(ffi_closure_SYSV):
|
||||
stp x29, x30, [sp, #-16]!
|
||||
cfi_adjust_cfa_offset (16)
|
||||
cfi_rel_offset (x29, 0)
|
||||
@@ -270,7 +287,7 @@ ffi_closure_SYSV:
|
||||
trampoline was called. */
|
||||
add x2, x29, #16
|
||||
|
||||
bl ffi_closure_SYSV_inner
|
||||
bl CNAME(ffi_closure_SYSV_inner)
|
||||
|
||||
/* Figure out if we should touch the vector registers. */
|
||||
ldr x0, [x22, #8]
|
||||
@@ -304,4 +321,6 @@ ffi_closure_SYSV:
|
||||
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ffi_closure_SYSV, .-ffi_closure_SYSV
|
||||
#ifdef __ELF__
|
||||
.size CNAME(ffi_closure_SYSV), .-CNAME(ffi_closure_SYSV)
|
||||
#endif
|
||||
|
||||
@@ -77,19 +77,19 @@ static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack)
|
||||
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;
|
||||
@@ -117,11 +117,12 @@ static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack)
|
||||
}
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
|
||||
|
||||
The vfp_space parameter is the load area for VFP regs, the return
|
||||
value is cif->vfp_used (word bitset of VFP regs used for passing
|
||||
arguments). These are only used for the VFP hard-float ABI.
|
||||
*/
|
||||
int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
register unsigned int i;
|
||||
@@ -129,7 +130,7 @@ int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
argp = stack;
|
||||
|
||||
|
||||
|
||||
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
|
||||
*(void **) argp = ecif->rvalue;
|
||||
@@ -149,6 +150,7 @@ int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
{
|
||||
// make sure we are using FFI_VFP
|
||||
@@ -160,13 +162,13 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
register ffi_type **p_arg;
|
||||
char stack_used = 0;
|
||||
char done_with_regs = 0;
|
||||
char is_vfp_type;
|
||||
int is_vfp_type;
|
||||
|
||||
/* 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 */
|
||||
@@ -194,7 +196,7 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
else if (!done_with_regs && !is_vfp_type)
|
||||
{
|
||||
char *tregp = ffi_align(p_arg, regp);
|
||||
size_t size = (*p_arg)->size;
|
||||
size_t size = (*p_arg)->size;
|
||||
size = (size < 4)? 4 : size; // pad
|
||||
/* Check if there is space left in the aligned register area to place
|
||||
* the argument */
|
||||
@@ -206,10 +208,10 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
FFI_ASSERT(regp <= argp);
|
||||
continue;
|
||||
}
|
||||
/* In case there are no arguments in the stack area yet,
|
||||
/* 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)
|
||||
else if (!stack_used)
|
||||
{
|
||||
stack_used = 1;
|
||||
done_with_regs = 1;
|
||||
@@ -231,7 +233,7 @@ int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space)
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int type_code;
|
||||
/* Round the stack up to a multiple of 8 bytes. This isn't needed
|
||||
/* 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;
|
||||
@@ -302,7 +304,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT);
|
||||
int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
|| cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
|
||||
@@ -315,7 +317,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **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) &&
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->flags == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
@@ -330,7 +332,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
|
||||
@@ -346,9 +348,9 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (small_struct)
|
||||
if (small_struct && rvalue != NULL)
|
||||
memcpy (rvalue, &temp, cif->rtype->size);
|
||||
else if (vfp_struct)
|
||||
else if (vfp_struct && rvalue != NULL)
|
||||
memcpy (rvalue, ecif.rvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
@@ -366,6 +368,7 @@ void ffi_closure_VFP (ffi_closure *);
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
unsigned int ffi_closure_inner (ffi_closure *closure, void **respp, void *args, void *vfp_args);
|
||||
unsigned int
|
||||
ffi_closure_inner (ffi_closure *closure,
|
||||
void **respp, void *args, void *vfp_args)
|
||||
@@ -375,10 +378,10 @@ ffi_closure_inner (ffi_closure *closure,
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* 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. */
|
||||
@@ -393,7 +396,7 @@ ffi_closure_inner (ffi_closure *closure,
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
static void
|
||||
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
@@ -429,12 +432,12 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*@-exportheader@*/
|
||||
static void
|
||||
static void
|
||||
ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
void **avalue, ffi_cif *cif,
|
||||
/* Used only under VFP hard-float ABI. */
|
||||
@@ -447,7 +450,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
register ffi_type **p_arg;
|
||||
char done_with_regs = 0;
|
||||
char stack_used = 0;
|
||||
char is_vfp_type;
|
||||
int is_vfp_type;
|
||||
|
||||
FFI_ASSERT(cif->abi == FFI_VFP);
|
||||
regp = stack;
|
||||
@@ -463,7 +466,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
is_vfp_type = vfp_type_p (*p_arg);
|
||||
is_vfp_type = vfp_type_p (*p_arg);
|
||||
|
||||
if(vi < cif->vfp_nargs && is_vfp_type)
|
||||
{
|
||||
@@ -474,12 +477,12 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
{
|
||||
char* tregp = ffi_align(p_arg, regp);
|
||||
|
||||
z = (*p_arg)->size;
|
||||
z = (*p_arg)->size;
|
||||
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)
|
||||
if(tregp + z <= eo_regp || !stack_used)
|
||||
{
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
*p_argv = (void*) tregp;
|
||||
@@ -518,7 +521,7 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
|
||||
p_argv++;
|
||||
argp += z;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -881,7 +884,7 @@ static int place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = reg;
|
||||
cif->vfp_args[cif->vfp_nargs++] = (typeof(*(cif->vfp_args)))reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
@@ -889,7 +892,7 @@ static int place_vfp_arg (ffi_cif *cif, ffi_type *t)
|
||||
reg += nregs;
|
||||
while (cif->vfp_used & (1 << reg))
|
||||
reg += 1;
|
||||
cif->vfp_reg_free = reg;
|
||||
cif->vfp_reg_free = (typeof(cif->vfp_reg_free))reg;
|
||||
}
|
||||
return 0;
|
||||
next_reg: ;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
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
|
||||
@@ -25,7 +25,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
@@ -59,7 +59,7 @@
|
||||
#define __SOFTFP__
|
||||
#endif
|
||||
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
we can do. */
|
||||
@ This selects the minimum architecture level required.
|
||||
#define __ARM_ARCH__ 3
|
||||
@@ -68,7 +68,7 @@
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 4
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__)
|
||||
@@ -107,60 +107,37 @@
|
||||
#define UNWIND
|
||||
#else
|
||||
#define UNWIND @
|
||||
#endif
|
||||
#endif
|
||||
|
||||
.syntax unified
|
||||
|
||||
|
||||
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.thumb
|
||||
.thumb_func
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#define ARM_FUNC_START(name) \
|
||||
.text; \
|
||||
.align 2; \
|
||||
.thumb; \
|
||||
.thumb_func; \
|
||||
ENTRY(name); \
|
||||
bx pc; \
|
||||
nop; \
|
||||
.arm; \
|
||||
UNWIND .fnstart; \
|
||||
_L__##name:
|
||||
#else
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
bx pc
|
||||
nop
|
||||
.arm
|
||||
#define ARM_FUNC_START(name) \
|
||||
.text; \
|
||||
.align 2; \
|
||||
.arm; \
|
||||
ENTRY(name); \
|
||||
UNWIND .fnstart
|
||||
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
||||
directly from other local arm routines. */
|
||||
#ifdef __APPLE__
|
||||
_L__$0:
|
||||
#else
|
||||
_L__\name:
|
||||
#endif
|
||||
.endm
|
||||
#else
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.arm
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#else
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
UNWIND .fnstart
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro RETLDM regs=, cond=, dirn=ia
|
||||
.macro RETLDM
|
||||
#if defined (__INTERWORKING__)
|
||||
.ifc "\regs",""
|
||||
ldr\cond lr, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, lr}
|
||||
.endif
|
||||
bx\cond lr
|
||||
ldr lr, [sp], #4
|
||||
bx lr
|
||||
#else
|
||||
.ifc "\regs",""
|
||||
ldr\cond pc, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, pc}
|
||||
.endif
|
||||
ldr pc, [sp], #4
|
||||
#endif
|
||||
.endm
|
||||
|
||||
@@ -171,7 +148,7 @@ _L__\name:
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
@ This assumes we are using gas.
|
||||
ARM_FUNC_START ffi_call_SYSV
|
||||
ARM_FUNC_START(ffi_call_SYSV)
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
@@ -201,14 +178,14 @@ ARM_FUNC_START ffi_call_SYSV
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL, assume no return value.
|
||||
@@ -228,7 +205,7 @@ ARM_FUNC_START ffi_call_SYSV
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
stmeqia r2, {r0, r1}
|
||||
stmiaeq r2, {r0, r1}
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
beq LSYM(Lepilogue)
|
||||
@@ -266,7 +243,7 @@ LSYM(Lepilogue):
|
||||
void *args;
|
||||
*/
|
||||
|
||||
ARM_FUNC_START ffi_closure_SYSV
|
||||
ARM_FUNC_START(ffi_closure_SYSV)
|
||||
UNWIND .pad #16
|
||||
add ip, sp, #16
|
||||
stmfd sp!, {ip, lr}
|
||||
@@ -345,7 +322,7 @@ ARM_FUNC_START ffi_closure_SYSV
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
ARM_FUNC_START ffi_call_VFP
|
||||
ARM_FUNC_START(ffi_call_VFP)
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
@@ -397,7 +374,7 @@ LSYM(Lbase_args):
|
||||
@ the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL,
|
||||
@@ -416,7 +393,7 @@ LSYM(Lbase_args):
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
fstseq s0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
fstdeq d0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
@@ -433,7 +410,7 @@ LSYM(Lepilogue_vfp):
|
||||
.size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
|
||||
|
||||
|
||||
ARM_FUNC_START ffi_closure_VFP
|
||||
ARM_FUNC_START(ffi_closure_VFP)
|
||||
fstmfdd sp!, {d0-d7}
|
||||
@ r0-r3, then d0-d7
|
||||
UNWIND .pad #80
|
||||
@@ -466,7 +443,7 @@ ARM_FUNC_START ffi_closure_VFP
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
beq .Lretdouble_struct_vfp
|
||||
|
||||
|
||||
.Lclosure_epilogue_vfp:
|
||||
add sp, sp, #72
|
||||
ldmfd sp, {sp, pc}
|
||||
|
||||
@@ -264,7 +264,7 @@ static int
|
||||
open_temp_exec_file_dir (const char *dir)
|
||||
{
|
||||
static const char suffix[] = "/ffiXXXXXX";
|
||||
int lendir = strlen (dir);
|
||||
size_t lendir = strlen (dir);
|
||||
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
|
||||
|
||||
if (!tempname)
|
||||
|
||||
@@ -1661,7 +1661,7 @@ struct malloc_chunk {
|
||||
typedef struct malloc_chunk mchunk;
|
||||
typedef struct malloc_chunk* mchunkptr;
|
||||
typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */
|
||||
typedef unsigned int bindex_t; /* Described below */
|
||||
typedef size_t bindex_t; /* Described below */
|
||||
typedef unsigned int binmap_t; /* Described below */
|
||||
typedef unsigned int flag_t; /* The type of various bit flag sets */
|
||||
|
||||
@@ -3388,7 +3388,7 @@ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
|
||||
*ss = m->seg; /* Push current record */
|
||||
m->seg.base = tbase;
|
||||
m->seg.size = tsize;
|
||||
set_segment_flags(&m->seg, mmapped);
|
||||
(void)set_segment_flags(&m->seg, mmapped);
|
||||
m->seg.next = ss;
|
||||
|
||||
/* Insert trailing fenceposts */
|
||||
@@ -3548,7 +3548,7 @@ static void* sys_alloc(mstate m, size_t nb) {
|
||||
if (!is_initialized(m)) { /* first-time initialization */
|
||||
m->seg.base = m->least_addr = tbase;
|
||||
m->seg.size = tsize;
|
||||
set_segment_flags(&m->seg, mmap_flag);
|
||||
(void)set_segment_flags(&m->seg, mmap_flag);
|
||||
m->magic = mparams.magic;
|
||||
init_bins(m);
|
||||
if (is_global(m))
|
||||
|
||||
@@ -187,7 +187,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
{
|
||||
/* Add any padding if necessary */
|
||||
if (((*ptr)->alignment - 1) & bytes)
|
||||
bytes = ALIGN(bytes, (*ptr)->alignment);
|
||||
bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment);
|
||||
|
||||
#ifdef TILE
|
||||
if (bytes < 10 * FFI_SIZEOF_ARG &&
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
/* 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);
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
register unsigned int i;
|
||||
@@ -341,7 +342,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
|
||||
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 */
|
||||
|
||||
@@ -363,9 +364,9 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
#endif
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifdef X86_WIN64
|
||||
case FFI_WIN64:
|
||||
@@ -456,16 +457,16 @@ ffi_closure_win64_inner (ffi_closure *closure, void *args) {
|
||||
void *resp = &result;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will change RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
|
||||
|
||||
|
||||
(closure->fun) (cif, resp, arg_area, closure->user_data);
|
||||
|
||||
/* The result is returned in rax. This does the right thing for
|
||||
@@ -485,10 +486,10 @@ ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will change RESP to point to the
|
||||
* structure return address. */
|
||||
@@ -552,12 +553,12 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
||||
#endif
|
||||
{
|
||||
z = (*p_arg)->size;
|
||||
|
||||
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
|
||||
|
||||
*p_argv = (void*) argp;
|
||||
}
|
||||
|
||||
|
||||
p_argv++;
|
||||
#ifdef X86_WIN64
|
||||
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
|
||||
@@ -565,7 +566,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
||||
argp += z;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -653,7 +654,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
#ifdef X86_WIN64
|
||||
#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
|
||||
#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
|
||||
if (cif->abi == FFI_WIN64)
|
||||
if (cif->abi == FFI_WIN64)
|
||||
{
|
||||
int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
|
||||
FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
|
||||
@@ -694,7 +695,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
{
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
@@ -732,7 +733,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
|
||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
|
||||
}
|
||||
|
||||
|
||||
#ifdef X86_WIN32
|
||||
if (cif->abi == FFI_SYSV)
|
||||
{
|
||||
@@ -754,7 +755,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
ffi_prep_args_raw(char *stack, extended_cif *ecif)
|
||||
{
|
||||
memcpy (stack, ecif->avalue, ecif->cif->bytes);
|
||||
@@ -773,7 +774,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
||||
|
||||
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 */
|
||||
|
||||
@@ -785,9 +786,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifdef X86_WIN32
|
||||
case FFI_SYSV:
|
||||
|
||||
@@ -168,7 +168,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_POINTER:
|
||||
{
|
||||
int size = byte_offset + type->size;
|
||||
size_t size = byte_offset + type->size;
|
||||
|
||||
if (size <= 4)
|
||||
{
|
||||
@@ -210,7 +210,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
case FFI_TYPE_STRUCT:
|
||||
{
|
||||
const int UNITS_PER_WORD = 8;
|
||||
int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
int words = ((int)type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
ffi_type **ptr;
|
||||
int i;
|
||||
enum x86_64_reg_class subclasses[MAX_CLASSES];
|
||||
@@ -242,7 +242,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
return 0;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
int pos = byte_offset / 8;
|
||||
size_t pos = byte_offset / 8;
|
||||
classes[i + pos] =
|
||||
merge_classes (subclasses[i], classes[i + pos]);
|
||||
}
|
||||
@@ -411,7 +411,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
if (ssecount)
|
||||
flags |= 1 << 11;
|
||||
cif->flags = flags;
|
||||
cif->bytes = ALIGN (bytes, 8);
|
||||
cif->bytes = (unsigned)ALIGN (bytes, 8);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user