New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New RISC-V port #281

Merged
merged 3 commits into from Mar 11, 2018

Conversation

Projects
None yet
6 participants
@sorear
Copy link
Contributor

sorear commented Sep 9, 2016

This patch adds support for RISC-V. I sent it to the ML earlier but was requested to create a PR instead.

I did not write the code in this patch; it is a cleaned up and rebased version of a port by Michael Knyszek et al of UC Berkeley.

RISC-V is a free and open standard instruction set architecture originally developed at UC Berkeley and now seeing significant interest from independent hardware vendors, with interoperable prototypes from several independent groups. Alex Bradbury's recent RFC to the LLVM community has a much better explanation of what RISC-V is and why you should care about it.

While the privileged architecture is still in some flux, the architecture which is visible to user space and the C calling convention have been unchanged in nearly two years and are now considered frozen, so ports like this one are very likely to remain valid.

I am interested in being the responsible party to get this code into a mergable condition. I am familiar with the RISC-V ISA and calling convention and with libffi's broad principles of operation, but not with the details of libffi internals.

How shall we proceed?


RISC-V instruction set reference, including C calling convention and encoding details


I've run the full testsuite on qemu system and user emulation. The user emulation is the easiest way to follow along, although it's still a bit touchy. Follow the instructions on https://hub.docker.com/r/sorear/fedora-riscv-wip/ to set up an emulated RISC-V user environment (assuming you have an amd64 Linux host).

Next, build the latest qemu-user from https://github.com/arsv/riscv-qemu for an important bugfix. Build it with --enable-static --target-list=riscv64-linux-user, and copy the generated static binary riscv64-linux-user/qemu-riscv64 into the container root.

Next, install the following packages in the container:

autoconf-2.69-22.fc24.noarch
automake-1.15-7.fc25.noarch
dejagnu-1.6-1.fc25.noarch
expect-5.45-22.fc24.riscv64
tcl-8.6.6-1.fc24.riscv64
libtool-ltdl-2.4.6-11.fc24.riscv64
libtool-ltdl-devel-2.4.6-11.fc24.riscv64
tcl-devel-8.6.6-1.fc24.riscv64
expect-devel-5.45-22.fc24.riscv64
expectk-5.45-22.fc24.riscv64
libtool-2.4.6-11.fc24.riscv64
bash-4.3.43-1.fc24.riscv64
bash-doc-4.3.43-1.fc24.riscv64
make-devel-4.1-5.fc24.riscv64
make-4.1-5.fc24.riscv64
texinfo-6.1-3.fc24.riscv64
perl-5.24.0-377.fc25.riscv64
perl-libintl-1.24-3.fc24.riscv64
perl-core-5.24.0-377.fc25.riscv64
perl-libs-5.24.0-377.fc25.riscv64
perl-Encode-2.86-1.fc25.riscv64
perl-Storable-2.56-366.fc25.riscv64
perl-Unicode-Normalize-1.25-365.fc25.riscv64
perl-Unicode-EastAsianWidth-1.33-8.fc25.noarch
perl-Text-Unidecode-1.27-3.fc25.noarch
perl-IO-1.36-377.fc25.riscv64

Source noarch packages from koji, riscv64 packages from https://github.com/rwmjones/fedora-riscv.

Once the environment is set up, it is possible to check out the code, (you may need to hack config.guess to return the correct result), sh autogen.sh, ./configure --host=riscv64-unknown-linux-gnu --build=riscv64-unknown-linux-gnu, make check.

config.sub has supported RISC-V for cross compilation purposes for some time, and is already updated in libffi; config.guess does not.

unsigned small = FFI_TYPE_SMALLSTRUCT;
ffi_type *e;

/* Returning structures under n32 is a tricky thing.

This comment has been minimized.

@tromey

tromey Sep 9, 2016

Member

I suspect this comment is a leftover from the MIPS port and that the RISC-V ABI isn't also called "n32". If so this could use an update.

This comment has been minimized.

@sorear

sorear Sep 9, 2016

Contributor

Correct.

@tromey

This comment has been minimized.

Copy link
Member

tromey commented Sep 9, 2016

Thanks. I didn't really read the patch in great detail yet. One thing that came to mind is that the README needs an update to mention the new port, among other things.

@tromey

This comment has been minimized.

Copy link
Member

tromey commented Sep 12, 2016

config.sub has supported RISC-V for cross compilation purposes for some time, and is already updated in libffi; config.guess does not.

Maybe some upstream spot needs an update; but libffi doesn't include these files in the repository, so it's a separate issue.

@tromey

This comment has been minimized.

Copy link
Member

tromey commented Sep 12, 2016

I read through the rest of the code and nothing stood out for me. So if my earlier comments are addressed, I would merge this (barring of course objections from others). Thanks for doing this! And please ping me if you do push updates.

#else
#define REG_S sw
#define REG_L lw
#endif

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

You shouldn't put anything not public in this header.
Yes, we used to do a lot of this, but we've done some
amount of cleanup on some ports.
You should create an "internal.h" header for this.

#define FFI_TYPE_STRUCT_FD_SOFT (FFI_TYPE_STRUCT_FD + 256)
#define FFI_TYPE_STRUCT_DF_SOFT (FFI_TYPE_STRUCT_DF + 256)
#define FFI_TYPE_STRUCT_SOFT 16

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

This is also not public.

ecif.rvalue = rvalue;

ffi_call_asm(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn);
}

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

FWIW, there's another way to structure this code. Instead of
ffi_call -> ffi_call_asm -> ffi_prep_args -> target-function
one can merge ffi_call and ffi_prep_args so that we have
ffi_call -> ffi_call_asm -> target-function
About 5 or 6 of the targets are now structured this way. The simplest of which is probably the Alpha target.

This comment has been minimized.

@sorear

sorear Nov 6, 2016

Contributor

I can make that change, but it's unclear from the comment whether you're requesting it or "just" documenting the option.

This comment has been minimized.

@rth7680

rth7680 Nov 22, 2016

Contributor

I strongly prefer the simplified call chain. So if you would make it, I would be pleased. However, I also won't make it a blocker to acceptance.

arg_reg = 1;
count = (cif->nargs < 7) ? cif->nargs : 7;
cif->rstruct_flag = !0;
}

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

What kind of style is !0?

#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag; char isvariadic

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

There is room in the normal flags field for two more bits. That is certainly preferable to expanding the size of CIE.

set_arg0_double:
# otherwise it must be a double we're dealing with
fld fa0, FFI_SIZEOF_ARG_X0(sp)

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

This if-if x 8 structure is very inefficient. It would be much better if you could do this without any branches at all.

Without reading the risc-v abi, it would appear that there are holes left in the integer/fp register sets as one progresses through the arguments. Thus it doesn't matter what valur is in A0 when FA0 is in use and vice-versa. Thus one could simply read 8 bytes into both A0 and FA0 and perform this whole setup sequence in 16 instructions.

Which leaves us with the difference between float and double. This can easily be handled within ffi_prep_args, where you store the canonical register value instead of the C type. A glance at the ISA section 7.2 suggests that should be done via
asm("flw %0,%2; fsd %0,%1" : "=f"(tmp), "=m"(*(double *)dest) : "m"(*(float *)src));
as the register data format for single-precision is not defined.

This comment has been minimized.

@sorear

sorear Sep 23, 2016

Contributor

Agreed; always setting FA[0-7] is safe. One possible exception is that there are RISC-V implementations in the wild that trap and emulate all FP instructions, including FLD/FLW; it might be nice to have a single branch with options "set the integer registers" and "set all registers, at least one FP argument exists", but of course I have no hardware performance numbers.

REG_L t0, -FFI_SIZEOF_ARG_X5(fp)
sw a0, 0(t0)
j epilogue

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

Is the call of the actual function being delayed so that you don't have to save the flags value across the call? Except that you are saving the flags, in slot 3 of the stack frame...

The if-else-if (times 10) structure is less than efficient. You should be able to create a small computed branch construct with AUIPC to perform this efficiently. See the aarch64 port for a good example of this.

fsd fa4, FA4_OFF2(sp)
fsd fa5, FA5_OFF2(sp)
fsd fa6, FA6_OFF2(sp)
fsd fa7, FA7_OFF2(sp)

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

No ifdef for softfloat here?

cls_retstruct_small2:
REG_L a0, V0_OFF2(sp)
REG_L a1, V1_OFF2(sp)

This comment has been minimized.

@rth7680

rth7680 Sep 20, 2016

Contributor

Similar comment wrt computed branch.

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Nov 6, 2016

So it turns out there have been a couple changes to the floating-point ABI implemented in gcc:

  • sizeof(long double) is now 16 (this is a bugfix, the ABI spec said it was supposed to be 16 for some time)
  • To support hardware with only a single-precision FPU, there is a new floating-point ABI which is "hard for float, soft for double"; __riscv_hard_float is removed, we now have __riscv_flen which can be undefined, 32, or 64
  • Floating point values will never be passed in pairs of integer registers. This affects long double on RV64, and double on RV32 if using a soft-float or single-only ABI. (Floating point values which are wider than an integer register can only be accessed from memory, so passing them in register pairs doesn't help.)

None of these changes affect the realized ABI for 32-bit or 64-bit hardfloat code that doesn't use long double.

I'm going to continue work on the libffi cleanup for the old ABI, but I'll probably need to update it at some point.

@andreas-schwab

This comment has been minimized.

Copy link

andreas-schwab commented Feb 7, 2018

https://build.opensuse.org/public/build/openSUSE:Factory:RISCV/standard/riscv64/libffi/_log

of expected passes 1680

of unexpected failures 215

of unsupported tests 30

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 7, 2018

Your timing is great. I started working on this a couple days ago to match the ABI used in gcc 7 and clang 6, and also address the other review comments above.

@palmer-dabbelt

This comment has been minimized.

Copy link

palmer-dabbelt commented Feb 7, 2018

Thanks for picking this up, @sorear. If there's anything we can do to help then feel free to ask!

@sorear sorear force-pushed the sorear:riscv-master branch from 5a57b2a to 9a18b0d Feb 19, 2018

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 19, 2018

Apologies for the long wait everyone. I've addressed the review feedback and updated for the gcc 7 ABI, which turned into a nearly complete rewrite of the patch; on the positive side it is significantly shorter now.

The patch has been tested, and passes all non-unsupported tests, using gcc 7.2.0 and riscv/riscv-qemu@qemu-upstream-v4 for the 32-bit soft float, 32-bit hard float, 64-bit soft float, and 64-bit hard float configuration. Several other combinations are expected to be supported by the code but are not tested.

There is a small amount of cruft in the ffitarget.h to maintain ABI compatibility with the patch version I posted earlier. It can be removed at the next SONAME bump, or, somewhat riskier, now. (I don't know if any significant body of risc-v binaries built against libffi.so.7 exists. Fedora is still on libffi.so.6 and would not be affected.)

sorear/libffi-riscv@riscv-3.1 and sorear/libffi-riscv@riscv-3.2.1 are also available.

Build and test instructions will be posted after I have verified them.

Add RISC-V support
This patch adds support for the RISC-V architecture (https://riscv.org).

This patch has been tested using QEMU user-mode emulation and GCC 7.2.0
in the following configurations:

* -march=rv32imac -mabi=ilp32
* -march=rv32g -mabi=ilp32d
* -march=rv64imac -mabi=lp64
* -march=rv64g -mabi=lp64d

The ABI currently can be found at
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md .

@sorear sorear force-pushed the sorear:riscv-master branch from 9a18b0d to 9f28a63 Feb 19, 2018

@andreas-schwab

This comment has been minimized.

Copy link

andreas-schwab commented Feb 19, 2018

That doesn't pass the python3 tests:

Re-running test 'test_ctypes' in verbose mode
test_anon (ctypes.test.test_anon.AnonTest) ... ok
test_anon_nonmember (ctypes.test.test_anon.AnonTest) ... ok
test_anon_nonseq (ctypes.test.test_anon.AnonTest) ... ok
test_issue31490 (ctypes.test.test_anon.AnonTest) ... ok
test_nested (ctypes.test.test_anon.AnonTest) ... ok
test (ctypes.test.test_array_in_pointer.Test) ... ok
test_2 (ctypes.test.test_array_in_pointer.Test) ... ok
test_bad_subclass (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_cache (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_classcache (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_from_address (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_from_addressW (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_numeric_arrays (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_simple (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_subclass (ctypes.test.test_arrays.ArrayTestCase) ... ok
test_byval (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_callbacks (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_callbacks_2 (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_longlong_callbacks (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_pointers (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_recursive_as_param (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_shorts (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_struct_return_2H (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_struct_return_8H (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_wchar_parm (ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase) ... ok
test_byval (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_callbacks (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_callbacks_2 (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_longlong_callbacks (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_pointers (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_recursive_as_param (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_shorts (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_struct_return_2H (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_struct_return_8H (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_wchar_parm (ctypes.test.test_as_parameter.AsParamWrapperTestCase) ... ok
test_byval (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_callbacks (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_callbacks_2 (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_longlong_callbacks (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_pointers (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_recursive_as_param (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_shorts (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_struct_return_2H (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_struct_return_8H (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_wchar_parm (ctypes.test.test_as_parameter.BasicWrapTestCase) ... ok
test_anon_bitfields (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_c_wchar (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_longlong (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_mixed_1 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_mixed_2 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_mixed_3 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_mixed_4 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_multi_bitfields_size (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_nonint_types (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_signed (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_single_bitfield_size (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_uint32 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_uint32_swap_big_endian (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_uint32_swap_little_endian (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_uint64 (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_ulonglong (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_unsigned (ctypes.test.test_bitfields.BitFieldTest) ... ok
test_ints (ctypes.test.test_bitfields.C_Test) ... ok
test_shorts (ctypes.test.test_bitfields.C_Test) ... ok
test_buffer (ctypes.test.test_buffers.StringBufferTestCase) ... ok
test_buffer_interface (ctypes.test.test_buffers.StringBufferTestCase) ... ok
test_unicode_buffer (ctypes.test.test_buffers.StringBufferTestCase) ... ok
test_unicode_conversion (ctypes.test.test_buffers.StringBufferTestCase) ... ok
test_BSTR (ctypes.test.test_bytes.BytesTest) ... skipped 'Windows-specific test'
test_c_char (ctypes.test.test_bytes.BytesTest) ... ok
test_c_char_p (ctypes.test.test_bytes.BytesTest) ... ok
test_c_wchar (ctypes.test.test_bytes.BytesTest) ... ok
test_c_wchar_p (ctypes.test.test_bytes.BytesTest) ... ok
test_struct (ctypes.test.test_bytes.BytesTest) ... ok
test_struct_W (ctypes.test.test_bytes.BytesTest) ... ok
test_X (ctypes.test.test_byteswap.Test) ... skipped 'test disabled'
test_endian_double (ctypes.test.test_byteswap.Test) ... ok
test_endian_float (ctypes.test.test_byteswap.Test) ... ok
test_endian_int (ctypes.test.test_byteswap.Test) ... ok
test_endian_longlong (ctypes.test.test_byteswap.Test) ... ok
test_endian_other (ctypes.test.test_byteswap.Test) ... ok
test_endian_short (ctypes.test.test_byteswap.Test) ... ok
test_slots (ctypes.test.test_byteswap.Test) ... ok
test_struct_fields_1 (ctypes.test.test_byteswap.Test) ... ok
test_struct_fields_2 (ctypes.test.test_byteswap.Test) ... ok
test_struct_struct (ctypes.test.test_byteswap.Test) ... ok
test_unaligned_native_struct_fields (ctypes.test.test_byteswap.Test) ... ok
test_unaligned_nonnative_struct_fields (ctypes.test.test_byteswap.Test) ... ok
test_byte (ctypes.test.test_callbacks.Callbacks) ... ok
test_char (ctypes.test.test_callbacks.Callbacks) ... ok
test_char_p (ctypes.test.test_callbacks.Callbacks) ... skipped 'test disabled'
test_double (ctypes.test.test_callbacks.Callbacks) ... ok
test_float (ctypes.test.test_callbacks.Callbacks) ... ok
test_int (ctypes.test.test_callbacks.Callbacks) ... ok
test_issue12483 (ctypes.test.test_callbacks.Callbacks) ... ok
test_issue_7959 (ctypes.test.test_callbacks.Callbacks) ... ok
test_long (ctypes.test.test_callbacks.Callbacks) ... ok
test_longdouble (ctypes.test.test_callbacks.Callbacks) ... ok
test_longlong (ctypes.test.test_callbacks.Callbacks) ... ok
test_pyobject (ctypes.test.test_callbacks.Callbacks) ... ok
test_short (ctypes.test.test_callbacks.Callbacks) ... ok
test_ubyte (ctypes.test.test_callbacks.Callbacks) ... ok
test_uint (ctypes.test.test_callbacks.Callbacks) ... ok
test_ulong (ctypes.test.test_callbacks.Callbacks) ... ok
test_ulonglong (ctypes.test.test_callbacks.Callbacks) ... ok
test_unsupported_restype_1 (ctypes.test.test_callbacks.Callbacks) ... ok
test_unsupported_restype_2 (ctypes.test.test_callbacks.Callbacks) ... ok
test_ushort (ctypes.test.test_callbacks.Callbacks) ... ok
test_callback_large_struct (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... ok
test_callback_register_double (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... ok
test_callback_register_int (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... ok
test_integrate (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... ok
test_issue_8959_a (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... ok
test_issue_8959_b (ctypes.test.test_callbacks.SampleCallbacksTestCase) ... skipped "'WINFUNCTYPE' is required"
test_byte (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_char (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_char_p (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_double (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_float (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_int (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_issue12483 (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_issue_7959 (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_long (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_longdouble (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_longlong (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_pyobject (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_short (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_ubyte (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_uint (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_ulong (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_ulonglong (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_unsupported_restype_1 (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_unsupported_restype_2 (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_ushort (ctypes.test.test_callbacks.StdcallCallbacks) ... skipped "'WINFUNCTYPE' is required"
test_address2pointer (ctypes.test.test_cast.Test) ... ok
test_array2pointer (ctypes.test.test_cast.Test) ... ok
test_char_p (ctypes.test.test_cast.Test) ... ok
test_other (ctypes.test.test_cast.Test) ... ok
test_p2a_objects (ctypes.test.test_cast.Test) ... ok
test_wchar_p (ctypes.test.test_cast.Test) ... ok
test_byte (ctypes.test.test_cfuncs.CFunctions) ... ok
test_byte_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_callwithresult (ctypes.test.test_cfuncs.CFunctions) ... ok
test_double (ctypes.test.test_cfuncs.CFunctions) ... ok
test_double_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_float (ctypes.test.test_cfuncs.CFunctions) ... ok
test_float_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_int (ctypes.test.test_cfuncs.CFunctions) ... ok
test_int_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_long (ctypes.test.test_cfuncs.CFunctions) ... ok
test_long_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_longdouble (ctypes.test.test_cfuncs.CFunctions) ... ok
test_longdouble_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_longlong (ctypes.test.test_cfuncs.CFunctions) ... ok
test_longlong_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_short (ctypes.test.test_cfuncs.CFunctions) ... ok
test_short_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ubyte (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ubyte_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_uint (ctypes.test.test_cfuncs.CFunctions) ... ok
test_uint_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ulong (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ulong_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ulonglong (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ulonglong_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ushort (ctypes.test.test_cfuncs.CFunctions) ... ok
test_ushort_plus (ctypes.test.test_cfuncs.CFunctions) ... ok
test_void (ctypes.test.test_cfuncs.CFunctions) ... ok
test_byte (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_byte_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_callwithresult (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_double (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_double_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_float (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_float_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_int (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_int_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_long (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_long_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_longdouble (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_longdouble_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_longlong (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_longlong_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_short (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_short_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ubyte (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ubyte_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_uint (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_uint_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ulong (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ulong_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ulonglong (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ulonglong_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ushort (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_ushort_plus (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_void (ctypes.test.test_cfuncs.stdcallCFunctions) ... skipped "'WinDLL' is required"
test_checkretval (ctypes.test.test_checkretval.Test) ... ok
test_oledll (ctypes.test.test_checkretval.Test) ... skipped "'oledll' is required"
test_chararray (ctypes.test.test_delattr.TestCase) ... ok
test_simple (ctypes.test.test_delattr.TestCase) ... ok
test_struct (ctypes.test.test_delattr.TestCase) ... ok
test_GetLastError (ctypes.test.test_errno.Test) ... skipped 'Test specific to Windows'
test_open (ctypes.test.test_errno.Test) ... ok
test_find_on_libpath (ctypes.test.test_find.LibPathFindTest) ... ok
OpenGL libraries:
('GL', None)
('GLU', None)
('gle', None)
test_gl (ctypes.test.test_find.Test_OpenGL_libs) ... skipped 'lib_gl not available'
test_gle (ctypes.test.test_find.Test_OpenGL_libs) ... skipped 'lib_gle not available'
test_glu (ctypes.test.test_find.Test_OpenGL_libs) ... skipped 'lib_glu not available'
test_shell_injection (ctypes.test.test_find.Test_OpenGL_libs) ... ok
test_abstract (ctypes.test.test_frombuffer.Test) ... ok
test_fortran_contiguous (ctypes.test.test_frombuffer.Test) ... ok
test_from_buffer (ctypes.test.test_frombuffer.Test) ... ok
test_from_buffer_copy (ctypes.test.test_frombuffer.Test) ... ok
test_from_buffer_copy_with_offset (ctypes.test.test_frombuffer.Test) ... ok
test_from_buffer_memoryview (ctypes.test.test_frombuffer.Test) ... ok
test_from_buffer_with_offset (ctypes.test.test_frombuffer.Test) ... ok
test_abstract (ctypes.test.test_funcptr.CFuncPtrTestCase) ... ok
test_basic (ctypes.test.test_funcptr.CFuncPtrTestCase) ... ok
test_dllfunctions (ctypes.test.test_funcptr.CFuncPtrTestCase) ... ok
test_first (ctypes.test.test_funcptr.CFuncPtrTestCase) ... ok
test_structures (ctypes.test.test_funcptr.CFuncPtrTestCase) ... ok
test_byval (ctypes.test.test_functions.FunctionTestCase) ... ok
test_callbacks (ctypes.test.test_functions.FunctionTestCase) ... ok
test_callbacks_2 (ctypes.test.test_functions.FunctionTestCase) ... ok
test_doubleresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_errors (ctypes.test.test_functions.FunctionTestCase) ... ok
test_floatresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_intresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_longdoubleresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_longlong_callbacks (ctypes.test.test_functions.FunctionTestCase) ... ok
test_longlongresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_mro (ctypes.test.test_functions.FunctionTestCase) ... ok
test_pointers (ctypes.test.test_functions.FunctionTestCase) ... ok
test_sf1651235 (ctypes.test.test_functions.FunctionTestCase) ... ok
test_shorts (ctypes.test.test_functions.FunctionTestCase) ... ok
test_stringresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_struct_return_2H (ctypes.test.test_functions.FunctionTestCase) ... ok
test_struct_return_2H_stdcall (ctypes.test.test_functions.FunctionTestCase) ... skipped 'Windows-specific test'
test_struct_return_8H (ctypes.test.test_functions.FunctionTestCase) ... ok
test_struct_return_8H_stdcall (ctypes.test.test_functions.FunctionTestCase) ... skipped 'Windows-specific test'
test_voidresult (ctypes.test.test_functions.FunctionTestCase) ... ok
test_wchar_parm (ctypes.test.test_functions.FunctionTestCase) ... ok
test_wchar_result (ctypes.test.test_functions.FunctionTestCase) ... ok
test_incomplete_example (ctypes.test.test_incomplete.MyTestCase) ... ok
test_get (ctypes.test.test_init.InitTest) ... ok
test_c_char_p (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_embedded_structs (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_ints (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_ptr_struct (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_simple_struct (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_xxx (ctypes.test.test_internals.ObjectsTestCase) ... ok
test_cint_array (ctypes.test.test_keeprefs.ArrayTestCase) ... ok
test_X (ctypes.test.test_keeprefs.DeletePointerTestCase) ... skipped 'test disabled'
test_p_cint (ctypes.test.test_keeprefs.PointerTestCase) ... ok
test (ctypes.test.test_keeprefs.PointerToStructure) ... ok
test_ccharp (ctypes.test.test_keeprefs.SimpleTestCase) ... ok
test_cint (ctypes.test.test_keeprefs.SimpleTestCase) ... ok
test_ccharp_struct (ctypes.test.test_keeprefs.StructureTestCase) ... ok
test_cint_struct (ctypes.test.test_keeprefs.StructureTestCase) ... ok
test_struct_struct (ctypes.test.test_keeprefs.StructureTestCase) ... ok
test_qsort (ctypes.test.test_libc.LibTest) ... ok
test_sqrt (ctypes.test.test_libc.LibTest) ... ok
libc_name is libc.so.6
test_1703286_A (ctypes.test.test_loading.LoaderTest) ... skipped 'Windows-specific test'
test_1703286_B (ctypes.test.test_loading.LoaderTest) ... skipped 'Windows-specific test'
test_find (ctypes.test.test_loading.LoaderTest) ... ok
test_load (ctypes.test.test_loading.LoaderTest) ... ok
test_load_library (ctypes.test.test_loading.LoaderTest) ... skipped 'test specific to Windows'
test_load_ordinal_functions (ctypes.test.test_loading.LoaderTest) ... skipped 'test specific to Windows'
test_load_version (ctypes.test.test_loading.LoaderTest) ... ok
test_find (ctypes.test.test_macholib.MachOTest) ... skipped 'OSX-specific test'
test_cast (ctypes.test.test_memfunctions.MemFunctionsTest) ... ok
test_memmove (ctypes.test.test_memfunctions.MemFunctionsTest) ... ok
test_memset (ctypes.test.test_memfunctions.MemFunctionsTest) ... ok
test_overflow (ctypes.test.test_memfunctions.MemFunctionsTest) ... skipped 'test disabled'
test_string_at (ctypes.test.test_memfunctions.MemFunctionsTest) ... ok
test_wstring_at (ctypes.test.test_memfunctions.MemFunctionsTest) ... ok
test_alignments (ctypes.test.test_numbers.NumberTestCase) ... ok
test_bool_from_address (ctypes.test.test_numbers.NumberTestCase) ... skipped 'test disabled'
test_bool_values (ctypes.test.test_numbers.NumberTestCase) ... ok
test_byref (ctypes.test.test_numbers.NumberTestCase) ... ok
test_char_from_address (ctypes.test.test_numbers.NumberTestCase) ... ok
test_default_init (ctypes.test.test_numbers.NumberTestCase) ... ok
test_float_from_address (ctypes.test.test_numbers.NumberTestCase) ... ok
test_float_overflow (ctypes.test.test_numbers.NumberTestCase) ... ok
test_floats (ctypes.test.test_numbers.NumberTestCase) ... ok
test_from_param (ctypes.test.test_numbers.NumberTestCase) ... ok
test_init (ctypes.test.test_numbers.NumberTestCase) ... ok
test_int_from_address (ctypes.test.test_numbers.NumberTestCase) ... ok
test_integers (ctypes.test.test_numbers.NumberTestCase) ... ok
test_perf (ctypes.test.test_numbers.NumberTestCase) ... skipped 'test disabled'
test_signed_values (ctypes.test.test_numbers.NumberTestCase) ... ok
test_sizes (ctypes.test.test_numbers.NumberTestCase) ... ok
test_typeerror (ctypes.test.test_numbers.NumberTestCase) ... ok
test_unsigned_values (ctypes.test.test_numbers.NumberTestCase) ... ok
test_valid_ranges (ctypes.test.test_numbers.NumberTestCase) ... skipped 'test disabled'
test (ctypes.test.test_objects.TestCase) ... ok
test_abstract (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_array_pointers (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_byref_pointer (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_byref_pointerpointer (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_cstrings (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_cw_strings (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_int_pointers (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_issue31311 (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_noctypes_argtype (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_subclasses (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_subclasses_c_wchar_p (ctypes.test.test_parameters.SimpleTypesTestCase) ... ok
test_endian_types (ctypes.test.test_pep3118.Test) ... ok
test_native_types (ctypes.test.test_pep3118.Test) ... ok
test_simple (ctypes.test.test_pickling.PickleTest_0) ... ok
test_struct (ctypes.test.test_pickling.PickleTest_0) ... ok
test_unpickable (ctypes.test.test_pickling.PickleTest_0) ... ok
test_wchar (ctypes.test.test_pickling.PickleTest_0) ... ok
test_simple (ctypes.test.test_pickling.PickleTest_1) ... ok
test_struct (ctypes.test.test_pickling.PickleTest_1) ... ok
test_unpickable (ctypes.test.test_pickling.PickleTest_1) ... ok
test_wchar (ctypes.test.test_pickling.PickleTest_1) ... ok
test_simple (ctypes.test.test_pickling.PickleTest_2) ... ok
test_struct (ctypes.test.test_pickling.PickleTest_2) ... ok
test_unpickable (ctypes.test.test_pickling.PickleTest_2) ... ok
test_wchar (ctypes.test.test_pickling.PickleTest_2) ... ok
test_simple (ctypes.test.test_pickling.PickleTest_3) ... ok
test_struct (ctypes.test.test_pickling.PickleTest_3) ... ok
test_unpickable (ctypes.test.test_pickling.PickleTest_3) ... ok
test_wchar (ctypes.test.test_pickling.PickleTest_3) ... ok
test_simple (ctypes.test.test_pickling.PickleTest_4) ... ok
test_struct (ctypes.test.test_pickling.PickleTest_4) ... ok
test_unpickable (ctypes.test.test_pickling.PickleTest_4) ... ok
test_wchar (ctypes.test.test_pickling.PickleTest_4) ... ok
test_abstract (ctypes.test.test_pointers.PointersTestCase) ... ok
test_basic (ctypes.test.test_pointers.PointersTestCase) ... ok
test_basics (ctypes.test.test_pointers.PointersTestCase) ... ok
test_bug_1467852 (ctypes.test.test_pointers.PointersTestCase) ... ok
test_c_void_p (ctypes.test.test_pointers.PointersTestCase) ... ok
test_callbacks_with_pointers (ctypes.test.test_pointers.PointersTestCase) ... ok
test_change_pointers (ctypes.test.test_pointers.PointersTestCase) ... ok
test_charpp (ctypes.test.test_pointers.PointersTestCase)
Test that a character pointer-to-pointer is correctly passed ... ok
test_from_address (ctypes.test.test_pointers.PointersTestCase) ... ok
test_other (ctypes.test.test_pointers.PointersTestCase) ... ok
test_pass_pointers (ctypes.test.test_pointers.PointersTestCase) ... ok
test_pointer_crash (ctypes.test.test_pointers.PointersTestCase) ... ok
test_pointer_type_name (ctypes.test.test_pointers.PointersTestCase) ... ok
test_pointer_type_str_name (ctypes.test.test_pointers.PointersTestCase) ... ok
test_pointers_bool (ctypes.test.test_pointers.PointersTestCase) ... ok
test (ctypes.test.test_prototypes.ArrayTest) ... ok
test_POINTER_c_char_arg (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_c_char_p_arg (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_c_void_p_arg (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_c_void_p_arg_with_c_wchar_p (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_instance (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_int_pointer_arg (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_paramflags (ctypes.test.test_prototypes.CharPointersTestCase) ... ok
test_POINTER_c_wchar_arg (ctypes.test.test_prototypes.WCharPointersTestCase) ... ok
test_c_wchar_p_arg (ctypes.test.test_prototypes.WCharPointersTestCase) ... ok
test_PyBytes_FromStringAndSize (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_PyLong_Long (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_PyOS_snprintf (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_PyObj_FromPtr (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_PyString_FromString (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_pyobject_repr (ctypes.test.test_python_api.PythonAPITestCase) ... ok
test_FloatDivisionError (ctypes.test.test_random_things.CallbackTracbackTestCase) ... ok
test_IntegerDivisionError (ctypes.test.test_random_things.CallbackTracbackTestCase) ... ok
test_TypeErrorDivisionError (ctypes.test.test_random_things.CallbackTracbackTestCase) ... ok
test_ValueError (ctypes.test.test_random_things.CallbackTracbackTestCase) ... ok
test (ctypes.test.test_random_things.call_function_TestCase) ... skipped 'Windows-specific test'
test_callback (ctypes.test.test_refcounts.AnotherLeak) ... ok
test_1 (ctypes.test.test_refcounts.RefcountTestCase) ... ok
test_refcount (ctypes.test.test_refcounts.RefcountTestCase) ... ok
test_char (ctypes.test.test_repr.ReprTest) ... ok
test_numbers (ctypes.test.test_repr.ReprTest) ... ok
test_from_dll (ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase) ... ok
test_from_dll_refcount (ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase) ... ok
test_with_prototype (ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase) ... ok
test_without_prototype (ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase) ... ok
test_compare (ctypes.test.test_simplesubclasses.Test) ... ok
test_ignore_retval (ctypes.test.test_simplesubclasses.Test) ... ok
test_int_callback (ctypes.test.test_simplesubclasses.Test) ... ok
test_int_struct (ctypes.test.test_simplesubclasses.Test) ... ok
test_16 (ctypes.test.test_sizes.SizesTestCase) ... ok
test_32 (ctypes.test.test_sizes.SizesTestCase) ... ok
test_64 (ctypes.test.test_sizes.SizesTestCase) ... ok
test_8 (ctypes.test.test_sizes.SizesTestCase) ... ok
test_size_t (ctypes.test.test_sizes.SizesTestCase) ... ok
test_ssize_t (ctypes.test.test_sizes.SizesTestCase) ... ok
test_char_array (ctypes.test.test_slicing.SlicesTestCase) ... ok
test_char_ptr (ctypes.test.test_slicing.SlicesTestCase) ... ok
test_char_ptr_with_free (ctypes.test.test_slicing.SlicesTestCase) ... ok
test_getslice_cint (ctypes.test.test_slicing.SlicesTestCase) ... ok
test_setslice_cint (ctypes.test.test_slicing.SlicesTestCase) ... ok
test_wchar_ptr (ctypes.test.test_slicing.SlicesTestCase) ... ok
test__POINTER_c_char (ctypes.test.test_stringptr.StringPtrTestCase) ... ok
test__c_char_p (ctypes.test.test_stringptr.StringPtrTestCase) ... ok
test_functions (ctypes.test.test_stringptr.StringPtrTestCase) ... ok
test (ctypes.test.test_strings.StringArrayTestCase) ... ok
test_c_buffer_raw (ctypes.test.test_strings.StringArrayTestCase) ... ok
test_c_buffer_value (ctypes.test.test_strings.StringArrayTestCase) ... ok
test_param_1 (ctypes.test.test_strings.StringArrayTestCase) ... ok
test_param_2 (ctypes.test.test_strings.StringArrayTestCase) ... ok
test_basic_strings (ctypes.test.test_strings.StringTestCase) ... skipped 'test disabled'
test_initialized_strings (ctypes.test.test_strings.StringTestCase) ... skipped 'test disabled'
test_perf (ctypes.test.test_strings.StringTestCase) ... skipped 'test disabled'
test_sized_strings (ctypes.test.test_strings.StringTestCase) ... skipped 'test disabled'
test_toolong (ctypes.test.test_strings.StringTestCase) ... skipped 'test disabled'
test (ctypes.test.test_strings.WStringArrayTestCase) ... ok
test_nonbmp (ctypes.test.test_strings.WStringArrayTestCase) ... ok
test_basic_wstrings (ctypes.test.test_strings.WStringTestCase) ... skipped 'test disabled'
test_toolong (ctypes.test.test_strings.WStringTestCase) ... skipped 'test disabled'
test_wchar (ctypes.test.test_strings.WStringTestCase) ... ok
test_1_A (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test_1_B (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test_2 (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test_3 (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test_4 (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test___get__ (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test___set__ (ctypes.test.test_struct_fields.StructFieldsTestCase) ... ok
test (ctypes.test.test_structures.PointerMemberTestCase) ... ok
test_none_to_pointer_fields (ctypes.test.test_structures.PointerMemberTestCase) ... ok
test_abstract_class (ctypes.test.test_structures.StructureTestCase) ... ok
test_conflicting_initializers (ctypes.test.test_structures.StructureTestCase) ... ok
test_empty (ctypes.test.test_structures.StructureTestCase) ... ok
test_fields (ctypes.test.test_structures.StructureTestCase) ... ok
test_huge_field_name (ctypes.test.test_structures.StructureTestCase) ... ok
test_init_errors (ctypes.test.test_structures.StructureTestCase) ... ok
test_initializers (ctypes.test.test_structures.StructureTestCase) ... ok
test_intarray_fields (ctypes.test.test_structures.StructureTestCase) ... ok
test_invalid_field_types (ctypes.test.test_structures.StructureTestCase) ... ok
test_invalid_name (ctypes.test.test_structures.StructureTestCase) ... ok
test_keyword_initializers (ctypes.test.test_structures.StructureTestCase) ... ok
test_methods (ctypes.test.test_structures.StructureTestCase) ... ok
test_nested_initializers (ctypes.test.test_structures.StructureTestCase) ... ok
test_packed (ctypes.test.test_structures.StructureTestCase) ... ok
test_packed_c_limits (ctypes.test.test_structures.StructureTestCase) ... ok
test_pass_by_value (ctypes.test.test_structures.StructureTestCase) ... FAIL
test_positional_args (ctypes.test.test_structures.StructureTestCase) ... ok
test_simple_structs (ctypes.test.test_structures.StructureTestCase) ... ok
test_struct_alignment (ctypes.test.test_structures.StructureTestCase) ... ok
test_structures_with_wchar (ctypes.test.test_structures.StructureTestCase) ... ok
test_subclass_creation (ctypes.test.test_structures.StructureTestCase) ... skipped 'test disabled'
test_unions (ctypes.test.test_structures.StructureTestCase) ... ok
test_subclass (ctypes.test.test_structures.SubclassesTest) ... ok
test_subclass_delayed (ctypes.test.test_structures.SubclassesTest) ... ok
test_contains_itself (ctypes.test.test_structures.TestRecursiveStructure) ... ok
test_vice_versa (ctypes.test.test_structures.TestRecursiveStructure) ... ok
test_native (ctypes.test.test_unaligned_structures.TestStructures) ... ok
test_swapped (ctypes.test.test_unaligned_structures.TestStructures) ... ok
test_buffers (ctypes.test.test_unicode.StringTestCase) ... ok
test_func (ctypes.test.test_unicode.StringTestCase) ... ok
test_wcslen (ctypes.test.test_unicode.StringTestCase) ... ok
test_buffers (ctypes.test.test_unicode.UnicodeTestCase) ... ok
test_wcslen (ctypes.test.test_unicode.UnicodeTestCase) ... ok
test_frozentable (ctypes.test.test_values.PythonValuesTestCase) ... ok
test_optimizeflag (ctypes.test.test_values.PythonValuesTestCase) ... ok
test_undefined (ctypes.test.test_values.PythonValuesTestCase) ... ok
test_an_integer (ctypes.test.test_values.ValuesTestCase) ... ok
test_undefined (ctypes.test.test_values.ValuesTestCase) ... ok
test_array_invalid_length (ctypes.test.test_varsize_struct.VarSizeTest) ... ok
test_resize (ctypes.test.test_varsize_struct.VarSizeTest) ... ok
test_zerosized_array (ctypes.test.test_varsize_struct.VarSizeTest) ... ok
test_SEH (ctypes.test.test_win32.FunctionCallTestCase) ... skipped 'Windows-specific test'
test_noargs (ctypes.test.test_win32.FunctionCallTestCase) ... skipped 'Windows-specific test'
test_struct_by_value (ctypes.test.test_win32.Structures) ... ok
test_winerror (ctypes.test.test_win32.TestWinError) ... skipped 'Windows-specific test'
test_COMError (ctypes.test.test_win32.TestWintypes) ... skipped 'Windows-specific test'
test_HWND (ctypes.test.test_win32.TestWintypes) ... skipped 'Windows-specific test'
test_PARAM (ctypes.test.test_win32.TestWintypes) ... skipped 'Windows-specific test'
test_callconv_1 (ctypes.test.test_win32.WindowsTestCase) ... skipped 'Windows-specific test'
test_callconv_2 (ctypes.test.test_win32.WindowsTestCase) ... skipped 'Windows-specific test'
test_variant_bool (ctypes.test.test_wintypes.WinTypesTest) ... test test_ctypes failed
skipped 'Windows-only test'

======================================================================
FAIL: test_pass_by_value (ctypes.test.test_structures.StructureTestCase)

Traceback (most recent call last):
File "/home/abuild/rpmbuild/BUILD/Python-3.6.4/Lib/ctypes/test/test_structures.py", line 416, in test_pass_by_value
self.assertEqual(s.first, 0xdeadbeef)
AssertionError: 195948557 != 3735928559


Ran 467 tests in 6.712s

FAILED (failures=1, skipped=87)

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 20, 2018

@andreas-schwab Find the list of architectures that get CTYPES_PASS_BY_REF_HACK in Modules/_ctypes/callproc.c and add __riscv to it. Unless I am mistaken we are following libffi.texi correctly:

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.

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 20, 2018

Once riscv/riscv-gnu-toolchain#325 is merged something like the following script (UNTESTED!) will work:

set -x -e
mkdir root
export ROOT="$PWD/root"
export root="$PWD/root"

mkdir "$root/cflags"
printf '#!/bin/sh\nexec "$ROOT/install/bin/riscv64-unknown-linux-gnu-gcc" $FORCE_CFLAGS "$@"\n' > "$root/cflags/riscv64-unknown-linux-gnu-gcc"
chmod +x "$root/cflags/riscv64-unknown-linux-gnu-gcc"
printf '#!/bin/sh\nexec "$ROOT/install/bin/riscv64-unknown-linux-gnu-gcc" $FORCE_CFLAGS "$@"\n' > "$root/cflags/riscv64-unknown-linux-gnu-g++"
chmod +x "$root/cflags/riscv64-unknown-linux-gnu-g++"

cd "$root"
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
cd "$root/riscv-gnu-toolchain"
mkdir "$root/install"
./configure --enable-multilib --prefix="$root/install"
make -j4 linux
make -j4 build-qemu
make -j4 stamps/build-dejagnu

cd "$root"
git clone -b riscv-master https://github.com/sorear/libffi-riscv
export PATH="$root/cflags:$root/riscv-gnu-toolchain/scripts/wrapper/qemu:$root/install/bin:$PATH"
export RISC_V_SYSROOT="$root/install/sysroot"

for variant in rv32imac-ilp32 rv32gc-ilp32d rv64imac-lp64 rv64gc-lp64d
do
    export FORCE_CFLAGS="$(echo $variant | sed 's/\(.*\)-\(.*\)/-march=\1 -mabi=\2/')"
    mkdir "$root/libffi-riscv/build-$variant"
    cd "$root/libffi-riscv/build-$variant"
    ../configure --host=riscv64-unknown-linux-gnu
    make
    LD_LIBRARY_PATH="$PWD/.libs" make check RUNTESTFLAGS="--target_board=riscv-sim"
done
@andreas-schwab

This comment has been minimized.

Copy link

andreas-schwab commented Feb 20, 2018

Thanks, this works now. That commit isn't part of python 3.6 yet.

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 26, 2018

@tromey @rth7680 Poking this. I've largely rewritten the port to address the review comments and the ABI changes that occurred prior to the gcc-7.1 release, so it needs a new review I'm afraid.

@atgreen
Copy link
Member

atgreen left a comment

This looks great to me, although it is missing README content. Could you please add that?

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Feb 26, 2018

@atgreen Updated README to mention RISC-V. The columns are a little bit too narrow to enumerate hard float / soft float as well as 32 / 64, and I'm not sure if I should mention that only 64-bit hard float has been tested "natively" (qemu-system-riscv64), the others using a cross-compiler.

Also added a configure.host bit which I missed earlier (I didn't catch it because I forgot to rerun autogen.sh after switching from 3.1 to master, I'm surprised this worked at all.)

Might make sense to squash at this point?

Also regarding testing, we are currently UNSUPPORTED on the Go closure and complex number tests.

@sorear

This comment has been minimized.

Copy link
Contributor

sorear commented Mar 7, 2018

@atgreen @rth7680 It's been 2 weeks and the Debian team is asking me for a status update

@atgreen atgreen merged commit 3840d49 into libffi:master Mar 11, 2018

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment