Skip to content

Commit 318dccc

Browse files
borsTristan Roachflba-eb
committed
Auto merge of #3038 - gh-tr:rebased/20221216, r=JohnTitor
Add support for QNX/Neutrino 7.1 Test cases (ctest2, all succeed): QNX/Neutrino 7.1 x86_64: 9884 QNX/Neutrino 7.1 aarch64: 9766 Co-authored-by: Tristan Roach <troach@qnx.com> Co-authored-by: Florian Bartels <Florian.Bartels@elektrobit.com>
2 parents 07636f6 + 720151f commit 318dccc

File tree

6 files changed

+5091
-49
lines changed

6 files changed

+5091
-49
lines changed

libc-test/build.rs

+252
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn do_ctest() {
6161
t if t.contains("wasi") => return test_wasi(t),
6262
t if t.contains("windows") => return test_windows(t),
6363
t if t.contains("vxworks") => return test_vxworks(t),
64+
t if t.contains("nto-qnx") => return test_neutrino(t),
6465
t => panic!("unknown target {}", t),
6566
}
6667
}
@@ -2654,6 +2655,257 @@ fn test_emscripten(target: &str) {
26542655
cfg.generate("../src/lib.rs", "main.rs");
26552656
}
26562657

2658+
fn test_neutrino(target: &str) {
2659+
assert!(target.contains("nto-qnx"));
2660+
2661+
let mut cfg = ctest_cfg();
2662+
2663+
headers! { cfg:
2664+
"ctype.h",
2665+
"dirent.h",
2666+
"dlfcn.h",
2667+
"sys/elf.h",
2668+
"fcntl.h",
2669+
"glob.h",
2670+
"grp.h",
2671+
"iconv.h",
2672+
"ifaddrs.h",
2673+
"limits.h",
2674+
"sys/link.h",
2675+
"locale.h",
2676+
"sys/malloc.h",
2677+
"rcheck/malloc.h",
2678+
"malloc.h",
2679+
"mqueue.h",
2680+
"net/if.h",
2681+
"net/if_arp.h",
2682+
"net/route.h",
2683+
"netdb.h",
2684+
"netinet/in.h",
2685+
"netinet/ip.h",
2686+
"netinet/tcp.h",
2687+
"netinet/udp.h",
2688+
"netinet/ip_var.h",
2689+
"sys/poll.h",
2690+
"pthread.h",
2691+
"pwd.h",
2692+
"regex.h",
2693+
"resolv.h",
2694+
"sys/sched.h",
2695+
"sched.h",
2696+
"semaphore.h",
2697+
"shadow.h",
2698+
"signal.h",
2699+
"spawn.h",
2700+
"stddef.h",
2701+
"stdint.h",
2702+
"stdio.h",
2703+
"stdlib.h",
2704+
"string.h",
2705+
"sys/sysctl.h",
2706+
"sys/file.h",
2707+
"sys/inotify.h",
2708+
"sys/ioctl.h",
2709+
"sys/ipc.h",
2710+
"sys/mman.h",
2711+
"sys/mount.h",
2712+
"sys/msg.h",
2713+
"sys/resource.h",
2714+
"sys/sem.h",
2715+
"sys/socket.h",
2716+
"sys/stat.h",
2717+
"sys/statvfs.h",
2718+
"sys/swap.h",
2719+
"sys/termio.h",
2720+
"sys/time.h",
2721+
"sys/times.h",
2722+
"sys/types.h",
2723+
"sys/uio.h",
2724+
"sys/un.h",
2725+
"sys/utsname.h",
2726+
"sys/wait.h",
2727+
"syslog.h",
2728+
"termios.h",
2729+
"time.h",
2730+
"sys/time.h",
2731+
"ucontext.h",
2732+
"unistd.h",
2733+
"utime.h",
2734+
"utmp.h",
2735+
"wchar.h",
2736+
"aio.h",
2737+
"nl_types.h",
2738+
"langinfo.h",
2739+
"unix.h",
2740+
"nbutil.h",
2741+
"aio.h",
2742+
"net/bpf.h",
2743+
"net/if_dl.h",
2744+
"sys/syspage.h",
2745+
2746+
// TODO: The following header file doesn't appear as part of the default headers
2747+
// found in a standard installation of Neutrino 7.1 SDP. The structures/
2748+
// functions dependent on it are currently commented out.
2749+
//"sys/asyncmsg.h",
2750+
}
2751+
2752+
// Create and include a header file containing
2753+
// items which are not included in any official
2754+
// header file.
2755+
let internal_header = "internal.h";
2756+
let out_dir = env::var("OUT_DIR").unwrap();
2757+
cfg.header(internal_header);
2758+
cfg.include(&out_dir);
2759+
std::fs::write(
2760+
out_dir.to_owned() + "/" + internal_header,
2761+
"#ifndef __internal_h__
2762+
#define __internal_h__
2763+
void __my_thread_exit(const void **);
2764+
#endif",
2765+
)
2766+
.unwrap();
2767+
2768+
cfg.type_name(move |ty, is_struct, is_union| {
2769+
match ty {
2770+
// Just pass all these through, no need for a "struct" prefix
2771+
"FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
2772+
| "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
2773+
| "Elf32_Chdr" | "Elf64_Chdr" | "aarch64_qreg_t" | "syspage_entry_info"
2774+
| "syspage_array_info" => ty.to_string(),
2775+
2776+
"Ioctl" => "int".to_string(),
2777+
2778+
t if is_union => format!("union {}", t),
2779+
2780+
t if t.ends_with("_t") => t.to_string(),
2781+
2782+
// put `struct` in front of all structs:.
2783+
t if is_struct => format!("struct {}", t),
2784+
2785+
t => t.to_string(),
2786+
}
2787+
});
2788+
2789+
cfg.field_name(move |_struct_, field| match field {
2790+
"type_" => "type".to_string(),
2791+
2792+
s => s.to_string(),
2793+
});
2794+
2795+
cfg.volatile_item(|i| {
2796+
use ctest::VolatileItemKind::*;
2797+
match i {
2798+
// The following fields are volatie but since we cannot express that in
2799+
// Rust types, we have to explicitly tell the checker about it here:
2800+
StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => true,
2801+
StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec_tod_adjust" => true,
2802+
StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec" => true,
2803+
StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec_stable" => true,
2804+
StructField(ref n, ref f) if n == "intrspin" && f == "value" => true,
2805+
_ => false,
2806+
}
2807+
});
2808+
2809+
cfg.skip_type(move |ty| {
2810+
match ty {
2811+
// FIXME: `sighandler_t` type is incorrect, see:
2812+
// https://github.com/rust-lang/libc/issues/1359
2813+
"sighandler_t" => true,
2814+
2815+
// Does not exist in Neutrino
2816+
"locale_t" => true,
2817+
2818+
_ => false,
2819+
}
2820+
});
2821+
2822+
cfg.skip_struct(move |ty| {
2823+
if ty.starts_with("__c_anonymous_") {
2824+
return true;
2825+
}
2826+
match ty {
2827+
"Elf64_Phdr" | "Elf32_Phdr" => true,
2828+
2829+
// FIXME: This is actually a union, not a struct
2830+
"sigval" => true,
2831+
2832+
// union
2833+
"_channel_connect_attr" => true,
2834+
2835+
_ => false,
2836+
}
2837+
});
2838+
2839+
cfg.skip_const(move |name| {
2840+
match name {
2841+
// These signal "functions" are actually integer values that are casted to a fn ptr
2842+
// This causes the compiler to err because of "illegal cast of int to ptr".
2843+
"SIG_DFL" => true,
2844+
"SIG_IGN" => true,
2845+
"SIG_ERR" => true,
2846+
2847+
_ => false,
2848+
}
2849+
});
2850+
2851+
cfg.skip_fn(move |name| {
2852+
// skip those that are manually verified
2853+
match name {
2854+
// FIXME: https://github.com/rust-lang/libc/issues/1272
2855+
"execv" | "execve" | "execvp" | "execvpe" => true,
2856+
2857+
// wrong signature
2858+
"signal" => true,
2859+
2860+
// wrong signature of callback ptr
2861+
"__cxa_atexit" => true,
2862+
2863+
// FIXME: Our API is unsound. The Rust API allows aliasing
2864+
// pointers, but the C API requires pointers not to alias.
2865+
// We should probably be at least using `&`/`&mut` here, see:
2866+
// https://github.com/gnzlbg/ctest/issues/68
2867+
"lio_listio" => true,
2868+
2869+
// 2 fields are actually unions which we're simply representing
2870+
// as structures.
2871+
"ChannelConnectAttr" => true,
2872+
2873+
// fields contains unions
2874+
"SignalKillSigval" => true,
2875+
"SignalKillSigval_r" => true,
2876+
2877+
// Not defined in any headers. Defined to work around a
2878+
// stack unwinding bug.
2879+
"__my_thread_exit" => true,
2880+
2881+
_ => false,
2882+
}
2883+
});
2884+
2885+
cfg.skip_field_type(move |struct_, field| {
2886+
// sigval is actually a union, but we pretend it's a struct
2887+
struct_ == "sigevent" && field == "sigev_value" ||
2888+
// Anonymous structures
2889+
struct_ == "_idle_hook" && field == "time"
2890+
});
2891+
2892+
cfg.skip_field(move |struct_, field| {
2893+
(struct_ == "__sched_param" && field == "reserved") ||
2894+
(struct_ == "sched_param" && field == "reserved") ||
2895+
(struct_ == "sigevent" && field == "__sigev_un1") || // union
2896+
(struct_ == "sigevent" && field == "__sigev_un2") || // union
2897+
// sighandler_t type is super weird
2898+
(struct_ == "sigaction" && field == "sa_sigaction") ||
2899+
// does not exist
2900+
(struct_ == "syspage_entry" && field == "__reserved") ||
2901+
false // keep me for smaller diffs when something is added above
2902+
});
2903+
2904+
cfg.skip_static(move |name| (name == "__dso_handle"));
2905+
2906+
cfg.generate("../src/lib.rs", "main.rs");
2907+
}
2908+
26572909
fn test_vxworks(target: &str) {
26582910
assert!(target.contains("vxworks"));
26592911

0 commit comments

Comments
 (0)