@@ -11,6 +11,36 @@ namespace details
1111inline ::std::byte *sys_mmap (void *addr, ::std::size_t len, int prot, int flags, int fd, ::std::uintmax_t offset)
1212{
1313#if defined(__linux__) && defined(__NR_mmap) && !defined(__NR_mmap2)
14+ #if defined(__s390__) || defined(__s390x__)
15+ // s390 __NR_mmap is the old single-argument entry; pass the kernel's mmap argument block.
16+ struct s390_mmap_arg_struct
17+ {
18+ unsigned long addr;
19+ unsigned long len;
20+ unsigned long prot;
21+ unsigned long flags;
22+ unsigned long fd;
23+ unsigned long offset;
24+ };
25+
26+ if constexpr (sizeof (::std::uintmax_t ) > sizeof (unsigned long ))
27+ {
28+ if (offset > static_cast <::std::uintmax_t >(::std::numeric_limits<unsigned long >::max ()))
29+ {
30+ throw_posix_error (EINVAL );
31+ }
32+ }
33+ s390_mmap_arg_struct args{
34+ reinterpret_cast <unsigned long >(addr),
35+ static_cast <unsigned long >(len),
36+ static_cast <unsigned long >(prot),
37+ static_cast <unsigned long >(flags),
38+ static_cast <unsigned long >(fd),
39+ static_cast <unsigned long >(offset)};
40+ ::std::ptrdiff_t ret{system_call<__NR_mmap, ::std::ptrdiff_t >(__builtin_addressof (args))};
41+ system_call_throw_error (ret);
42+ return reinterpret_cast <::std::byte *>(static_cast <::std::uintptr_t >(ret));
43+ #else
1444 if constexpr (sizeof (::std::uintmax_t ) > sizeof (off_t ))
1545 {
1646 if (offset > static_cast <::std::uintmax_t >(::std::numeric_limits<off_t >::max ()))
@@ -21,6 +51,7 @@ inline ::std::byte *sys_mmap(void *addr, ::std::size_t len, int prot, int flags,
2151 ::std::ptrdiff_t ret{system_call<__NR_mmap, ::std::ptrdiff_t >(addr, len, prot, flags, fd, offset)};
2252 system_call_throw_error (ret);
2353 return reinterpret_cast <::std::byte *>(static_cast <::std::uintptr_t >(ret));
54+ #endif
2455#elif defined(HAVE_MMAP64)
2556 if constexpr (sizeof (::std::uintmax_t ) > sizeof (off64_t ))
2657 {
0 commit comments