Skip to content

Revise alltypes.h update process. NFC #24773

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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 130 additions & 101 deletions system/lib/libc/musl/arch/emscripten/bits/alltypes.h
Original file line number Diff line number Diff line change
@@ -1,61 +1,59 @@
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __USE_TIME_BITS64 1

#define __BYTE_ORDER __LITTLE_ENDIAN

#define __LONG_MAX __LONG_MAX__

/*
* The .h version of this file is generated from the .h.in.
* See update_alltypes.sh.
*/
#define _Addr __PTRDIFF_TYPE__
#define _Int64 __INT64_TYPE__
#define _Reg __PTRDIFF_TYPE__

#if __GNUC__ >= 3
#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
typedef __builtin_va_list va_list;
#define __DEFINED_va_list
#endif
#define __BYTE_ORDER 1234
#define __LONG_MAX __LONG_MAX__

#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
typedef __builtin_va_list __isoc_va_list;
#define __DEFINED___isoc_va_list
#ifndef __cplusplus
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
typedef __WCHAR_TYPE__ wchar_t;
#define __DEFINED_wchar_t
#endif

#else
#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
typedef struct __va_list * va_list;
#define __DEFINED_va_list
#endif

#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
typedef struct __va_list * __isoc_va_list;
#define __DEFINED___isoc_va_list
#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
typedef __WINT_TYPE__ wint_t;
#define __DEFINED_wint_t
#endif


// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64
#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
typedef int blkcnt_t;
#define __DEFINED_blkcnt_t
#endif

#ifndef __cplusplus
#ifdef __WCHAR_TYPE__
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
typedef __WCHAR_TYPE__ wchar_t;
#define __DEFINED_wchar_t
#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
typedef int blksize_t;
#define __DEFINED_blksize_t
#endif

#else
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
typedef int wchar_t;
#define __DEFINED_wchar_t
#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
typedef int clock_t;
#define __DEFINED_clock_t
#endif

#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
typedef unsigned int dev_t;
#define __DEFINED_dev_t
#endif

#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
typedef int suseconds_t;
#define __DEFINED_suseconds_t
#endif
#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
typedef __WINT_TYPE__ wint_t;
#define __DEFINED_wint_t

#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
typedef unsigned int wctype_t;
#define __DEFINED_wctype_t
#endif


#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 0
#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
typedef float float_t;
#define __DEFINED_float_t
Expand All @@ -66,76 +64,49 @@ typedef double double_t;
#define __DEFINED_double_t
#endif

#else
#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
typedef long double float_t;
#define __DEFINED_float_t
#endif

#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
typedef long double double_t;
#define __DEFINED_double_t
#ifndef __cplusplus
#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
typedef struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;
#define __DEFINED_max_align_t
#endif

#elif defined(__GNUC__)
#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
typedef struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t;
#define __DEFINED_max_align_t
#endif

#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
typedef _Int64 time_t;
#define __DEFINED_time_t
#else
#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
typedef struct { alignas(8) long long __ll; long double __ld; } max_align_t;
#define __DEFINED_max_align_t
#endif

#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
typedef int suseconds_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */
#define __DEFINED_suseconds_t
#endif


// For canvas transfer implementation in Emscripten, use an extra control field
// to pass a pointer to a string denoting the WebGL canvases to transfer.
#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
typedef struct {
union {
int __i[10];
volatile int __vi[10];
unsigned long __s[10];
} __u;
#ifdef __EMSCRIPTEN__
// For canvas transfer implementation in Emscripten, use an extra control field
// to pass a pointer to a string denoting the WebGL canvases to transfer.
const char *_a_transferredcanvases;
#endif
} pthread_attr_t;
typedef struct { union { int __i[10]; volatile int __vi[10]; unsigned long __s[10]; } __u; const char *_a_transferredcanvases; } pthread_attr_t;
#define __DEFINED_pthread_attr_t
#endif


// TODO(kleisauke): Remove these two typedefs.
#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *__p[6]; } __u; } pthread_mutex_t;
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void * /*volatile*/__p[6]; } __u; } pthread_mutex_t;
#define __DEFINED_pthread_mutex_t
#endif

#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *__p[6]; } __u; } mtx_t;
typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void * /*volatile*/__p[6]; } __u; } mtx_t;
#define __DEFINED_mtx_t
#endif

#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
#define __DEFINED_pthread_cond_t
#endif

#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
#define __DEFINED_cnd_t
#endif

#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t;
#define __DEFINED_pthread_rwlock_t
#endif

#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
#define __DEFINED_pthread_barrier_t
#endif

#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __USE_TIME_BITS64 1

#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
typedef unsigned _Addr size_t;
Expand Down Expand Up @@ -172,29 +143,39 @@ typedef _Reg register_t;
#define __DEFINED_register_t
#endif

#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
typedef _Int64 time_t;
#define __DEFINED_time_t
#endif

#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
typedef _Int64 suseconds_t;
#define __DEFINED_suseconds_t
#endif


#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
typedef signed char int8_t;
#define __DEFINED_int8_t
#endif

#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
typedef short int16_t;
typedef signed short int16_t;
#define __DEFINED_int16_t
#endif

#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
typedef int int32_t;
typedef signed int int32_t;
#define __DEFINED_int32_t
#endif

#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
typedef _Int64 int64_t;
typedef signed _Int64 int64_t;
#define __DEFINED_int64_t
#endif

#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
typedef _Int64 intmax_t;
typedef signed _Int64 intmax_t;
#define __DEFINED_intmax_t
#endif

Expand Down Expand Up @@ -250,17 +231,17 @@ typedef unsigned _Int64 ino_t;
#endif

#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
typedef unsigned int dev_t;
typedef unsigned _Int64 dev_t;
#define __DEFINED_dev_t
#endif

#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
typedef int blksize_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */
typedef long blksize_t;
#define __DEFINED_blksize_t
#endif

#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
typedef int blkcnt_t;
typedef _Int64 blkcnt_t;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these look like real ABI changes. Perhaps we should try to make this changes actually NFC and do any ABI changes as followups? (or land them first).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit tricky to review, but blkcnt_t should still be 32-bit, see:

// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64
#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
typedef int blkcnt_t;
#define __DEFINED_blkcnt_t
#endif

These 32-bit type overrides originate from alltypes.h.in:

// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64
TYPEDEF int blkcnt_t;
TYPEDEF int blksize_t;
TYPEDEF int clock_t;
TYPEDEF unsigned int dev_t;
TYPEDEF int suseconds_t;
TYPEDEF unsigned int wctype_t;

(and alltypes.h is generated from this file)

The musl default definitions starts at line 95:

Also, other.test_gen_struct_info still passes on this branch, any ABI break would likely have caused it to fail.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With commit 6809780 and the following local change:

--- a/tools/system_libs.py
+++ b/tools/system_libs.py
@@ -62,7 +62,7 @@ def glob_in_path(path, glob_pattern, excludes=()):
 def get_base_cflags(build_dir, force_object_files=False, preprocess=True):
   # Always build system libraries with debug information.  Non-debug builds
   # will ignore this at link time because we link with `-strip-debug`.
-  flags = ['-g', '-sSTRICT', '-Werror']
+  flags = ['-sSTRICT', '-Werror']
   if settings.LTO and not force_object_files:
     flags += ['-flto=' + settings.LTO]
   if settings.RELOCATABLE:

I now see:

$ ./embuilder.py build sysroot libc{,-mt} --force
$ ./embuilder.py build sysroot libc{,-mt} --force --wasm64
$ sha256sum cache/sysroot/lib/wasm{32,64}-emscripten/libc{,-mt}.a
dd54801051079bd19040b4d826ded15f7352be10af1ad70d7aa74ce3befb6239  cache/sysroot/lib/wasm32-emscripten/libc.a
6fafd19332c11860b2365efec265fc037080ec97d1a84fafcca9ff338461bd70  cache/sysroot/lib/wasm32-emscripten/libc-mt.a
0310ba126aa4ca060538b6203105b71bfb115c24bcf82d6412c50e0fe041b74c  cache/sysroot/lib/wasm64-emscripten/libc.a
66ff6308831fb3df57cc884c10207f73135f4399920e871e83a85f9ee1ac9ab0  cache/sysroot/lib/wasm64-emscripten/libc-mt.a
$ git checkout revise-musl-alltypes-h
$ ./embuilder.py build sysroot libc{,-mt} --force
$ ./embuilder.py build sysroot libc{,-mt} --force --wasm64
$ sha256sum cache/sysroot/lib/wasm{32,64}-emscripten/libc{,-mt}.a
dd54801051079bd19040b4d826ded15f7352be10af1ad70d7aa74ce3befb6239  cache/sysroot/lib/wasm32-emscripten/libc.a
6fafd19332c11860b2365efec265fc037080ec97d1a84fafcca9ff338461bd70  cache/sysroot/lib/wasm32-emscripten/libc-mt.a
0310ba126aa4ca060538b6203105b71bfb115c24bcf82d6412c50e0fe041b74c  cache/sysroot/lib/wasm64-emscripten/libc.a
66ff6308831fb3df57cc884c10207f73135f4399920e871e83a85f9ee1ac9ab0  cache/sysroot/lib/wasm64-emscripten/libc-mt.a

So, when built without debug information, the libc static libraries are byte-for-byte identical to those built from the main branch.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit tricky to review, but blkcnt_t should still be 32-bit, see:

// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64
#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
typedef int blkcnt_t;
#define __DEFINED_blkcnt_t
#endif

These 32-bit type overrides originate from alltypes.h.in:

// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64
TYPEDEF int blkcnt_t;
TYPEDEF int blksize_t;
TYPEDEF int clock_t;
TYPEDEF unsigned int dev_t;
TYPEDEF int suseconds_t;
TYPEDEF unsigned int wctype_t;

(and alltypes.h is generated from this file)
The musl default definitions starts at line 95:

Also, other.test_gen_struct_info still passes on this branch, any ABI break would likely have caused it to fail.

Oh that is rather annoying/strange. It makes things like git grep typedef.*blkcnt_t a little annoying.

Can you add a comment to the end of the emscripen-specific file saying something like this:

// END EMSCRIPTEN-SPECIFIC DEFINITIONS
//
// Below here are the shared musl definitions.  The emscripten-specific definitions above will take precedence
// due to the `__DEFINED_` macro system.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I added a comment via 4eba06a. We could perhaps consider marking this file with linguist-generated=true in .gitattributes to ensure the diff is hidden by default, though I don't feel strongly about it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, I don't think this file should change often, and when it does I really want to see the details since this is ABI-defining stuff.

#define __DEFINED_blkcnt_t
#endif

Expand All @@ -274,13 +255,14 @@ typedef unsigned _Int64 fsfilcnt_t;
#define __DEFINED_fsfilcnt_t
#endif


#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
typedef unsigned wint_t;
#define __DEFINED_wint_t
#endif

#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
typedef unsigned int wctype_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */
typedef unsigned long wctype_t;
#define __DEFINED_wctype_t
#endif

Expand All @@ -296,22 +278,17 @@ typedef int clockid_t;
#endif

#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
typedef int clock_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */
typedef long clock_t;
#define __DEFINED_clock_t
#endif

#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
typedef struct { long long __ll; long double __ld; } max_align_t;
#define __DEFINED_max_align_t
#endif

#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
struct timeval { time_t tv_sec; suseconds_t tv_usec; };
#define __DEFINED_struct_timeval
#endif

#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
struct timespec { time_t tv_sec; long tv_nsec; };
struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); };
#define __DEFINED_struct_timespec
#endif

Expand Down Expand Up @@ -396,12 +373,28 @@ typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t;
#endif


#if defined(__NEED_struct__IO_FILE) && !defined(__DEFINED_struct__IO_FILE)
struct _IO_FILE { char __x; };
#define __DEFINED_struct__IO_FILE
#endif

#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
typedef struct _IO_FILE FILE;
#define __DEFINED_FILE
#endif


#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
typedef __builtin_va_list va_list;
#define __DEFINED_va_list
#endif

#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
typedef __builtin_va_list __isoc_va_list;
#define __DEFINED___isoc_va_list
#endif


#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
#define __DEFINED_mbstate_t
Expand Down Expand Up @@ -443,6 +436,42 @@ typedef unsigned short sa_family_t;
#endif


#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t;
#define __DEFINED_pthread_attr_t
#endif

#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t;
#define __DEFINED_pthread_mutex_t
#endif

#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t;
#define __DEFINED_mtx_t
#endif

#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t;
#define __DEFINED_pthread_cond_t
#endif

#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t;
#define __DEFINED_cnd_t
#endif

#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t;
#define __DEFINED_pthread_rwlock_t
#endif

#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
typedef struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t;
#define __DEFINED_pthread_barrier_t
#endif


#undef _Addr
#undef _Int64
#undef _Reg
Loading