Merge pull request #17702 from rootbeer/correct-libc-nonshared
Fix libc_nonshared.a
This commit is contained in:
83
lib/libc/glibc/README.md
vendored
Normal file
83
lib/libc/glibc/README.md
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
# Zig GNU C Library ("glibc") Support
|
||||
|
||||
Zig supports building binaries that will dynamically link against the
|
||||
[GNU C Library ("glibc")](https://www.gnu.org/software/libc/) when run.
|
||||
This support extends across a range of glibc versions.
|
||||
|
||||
By default, Zig binaries will not depend on any external C library, but
|
||||
they can be linked against one with the `-lc` option. The target ABI defines
|
||||
which C library: `musl` for the [musl C library](https://musl.libc.org/) or
|
||||
`gnu` for the GNU C library.
|
||||
|
||||
A specific GNU C library version can be chosen with an appropriate
|
||||
`-target`. For example, `-target native-native-gnu.2.19` will use the
|
||||
default CPU and OS targets, but will link in a run-time dependency on
|
||||
glibc v2.19 (or later). Use `zig env` to show the default target and
|
||||
version.
|
||||
|
||||
Glibc symbols are defined in the `std.c.` namespace in Zig, though the
|
||||
`std.os.` namespace is generally what should be used to access C-library
|
||||
APIs in Zig code (it is defined depending on the linked C library).
|
||||
|
||||
See `src/glibc.zig` for how Zig will build the glibc components. The
|
||||
generated shared object files are sufficient only for compile-time
|
||||
linking. They are stub libraries that only indicate that which symbols
|
||||
will be present at run-time, along with their type and size. The symbols
|
||||
do not reference an actual implementation.
|
||||
|
||||
## Targets
|
||||
|
||||
The GNU C Library supports a very wide set of platforms and architectures.
|
||||
The current Zig support for glibc only includes Linux.
|
||||
|
||||
Zig supports glibc versions back to v2.17 (2012) as the Zig standard
|
||||
library depends on symbols that were introduced in 2.17.
|
||||
|
||||
## Glibc stubs
|
||||
|
||||
The file `lib/libc/glibc/abilist` is a Zig-specific binary blob that
|
||||
defines the supported glibc versions and the set of symbols each version
|
||||
must define. See https://github.com/ziglang/glibc-abi-tool for the
|
||||
tooling to generate this blob. The code in `glibc.zig` parses the abilist
|
||||
to build version-specific stub libraries on demand.
|
||||
|
||||
The generated stub library is used for compile-time linking, with the
|
||||
expectation that at run-time the real glibc library will provide the
|
||||
actual symbol implementations.
|
||||
|
||||
### Public Headers
|
||||
|
||||
The glibc headers are in `lib/libc/include/generic-glibc/`. These are
|
||||
customized and have a couple Zig-specific `#ifdef`s to make the single set
|
||||
of headers represent any of the supported glibc versions. There are
|
||||
currently a handful of patches to these headers to represent new features
|
||||
(e.g. `reallocarray`) or changes in implementation (e.g., the `stat()`
|
||||
family of functions).
|
||||
|
||||
The related Zig https://github.com/ziglang/universal-headers is a project
|
||||
designed to more robustly build multi-version header files suitable for
|
||||
compilation across a variety of target C library versions.
|
||||
|
||||
## Glibc static C-Runtime object files and libraries
|
||||
|
||||
Linking against glibc also implies linking against several, generally
|
||||
"invisible" glibc C Runtime libraries: `crti.o`, `crtn.o`, `Scrt1.o` and
|
||||
`libc_nonshared.a`. These objects are linked into generated Zig binaries
|
||||
and are not run-time linking dependencies. Generally they provide
|
||||
bootstrapping, initialization, and mapping of un-versioned public APIs to
|
||||
glibc-private versioned APIs.
|
||||
|
||||
Like the public headers, these files contain a couple customiziations for
|
||||
Zig to be able to build for any supported glibc version. E.g., for glibc
|
||||
versions before v2.32, `libc_nonshared.a` contained stubs that directed
|
||||
the `fstat()` call to a versioned `__fxstat()` call.
|
||||
|
||||
These files used for these objects are in `lib/libc/glibc`. See the
|
||||
`tools/update_glibc.zig` tool for updating content in here from the
|
||||
upstream glibc.
|
||||
|
||||
# More Information
|
||||
|
||||
See
|
||||
https://github.com/ziglang/zig/commit/2314051acaad37dd5630dd7eca08571d620d6496
|
||||
for an example commit that updates glibc (to v2.38).
|
||||
12
lib/libc/glibc/include/libc-symbols.h
vendored
12
lib/libc/glibc/include/libc-symbols.h
vendored
@@ -155,6 +155,18 @@
|
||||
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))) \
|
||||
__attribute_copy__ (name);
|
||||
|
||||
/* Zig patch. weak_hidden_alias was removed from glibc v2.36 (v2.37?), Zig
|
||||
needs it for the v2.32 and earlier {f,l,}stat wrappers, so only include
|
||||
in this header for 2.32 and earlier. */
|
||||
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 32) || __GLIBC__ < 2
|
||||
# define weak_hidden_alias(name, aliasname) \
|
||||
_weak_hidden_alias (name, aliasname)
|
||||
# define _weak_hidden_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname \
|
||||
__attribute__ ((weak, alias (#name), __visibility__ ("hidden"))) \
|
||||
__attribute_copy__ (name);
|
||||
#endif
|
||||
|
||||
/* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */
|
||||
# define weak_extern(symbol) _weak_extern (weak symbol)
|
||||
# define _weak_extern(expr) _Pragma (#expr)
|
||||
|
||||
55
lib/libc/glibc/io/fstat-2.32.c
vendored
Normal file
55
lib/libc/glibc/io/fstat-2.32.c
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstat
|
||||
#undef __fstat
|
||||
int
|
||||
attribute_hidden
|
||||
__fstat (int fd, struct stat *buf)
|
||||
{
|
||||
return __fxstat (_STAT_VER, fd, buf);
|
||||
}
|
||||
|
||||
weak_hidden_alias (__fstat, fstat)
|
||||
52
lib/libc/glibc/io/fstat64-2.32.c
vendored
Normal file
52
lib/libc/glibc/io/fstat64-2.32.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstat64
|
||||
int
|
||||
attribute_hidden
|
||||
fstat64 (int fd, struct stat64 *buf)
|
||||
{
|
||||
return __fxstat64 (_STAT_VER, fd, buf);
|
||||
}
|
||||
52
lib/libc/glibc/io/fstatat-2.32.c
vendored
Normal file
52
lib/libc/glibc/io/fstatat-2.32.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstatat
|
||||
int
|
||||
attribute_hidden
|
||||
fstatat (int fd, const char *file, struct stat *buf, int flag)
|
||||
{
|
||||
return __fxstatat (_STAT_VER, fd, file, buf, flag);
|
||||
}
|
||||
52
lib/libc/glibc/io/fstatat64-2.32.c
vendored
Normal file
52
lib/libc/glibc/io/fstatat64-2.32.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstatat64
|
||||
int
|
||||
attribute_hidden
|
||||
fstatat64 (int fd, const char *file, struct stat64 *buf, int flag)
|
||||
{
|
||||
return __fxstatat64 (_STAT_VER, fd, file, buf, flag);
|
||||
}
|
||||
55
lib/libc/glibc/io/lstat-2.32.c
vendored
Normal file
55
lib/libc/glibc/io/lstat-2.32.c
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef lstat
|
||||
#undef __lstat
|
||||
int
|
||||
attribute_hidden
|
||||
__lstat (const char *file, struct stat *buf)
|
||||
{
|
||||
return __lxstat (_STAT_VER, file, buf);
|
||||
}
|
||||
|
||||
weak_hidden_alias (__lstat, lstat)
|
||||
52
lib/libc/glibc/io/lstat64-2.32.c
vendored
Normal file
52
lib/libc/glibc/io/lstat64-2.32.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef lstat64
|
||||
int
|
||||
attribute_hidden
|
||||
lstat64 (const char *file, struct stat64 *buf)
|
||||
{
|
||||
return __lxstat64 (_STAT_VER, file, buf);
|
||||
}
|
||||
55
lib/libc/glibc/io/mknod-2.32.c
vendored
Normal file
55
lib/libc/glibc/io/mknod-2.32.c
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
int
|
||||
attribute_hidden
|
||||
__mknod (const char *path, mode_t mode, dev_t dev)
|
||||
{
|
||||
return __xmknod (_MKNOD_VER, path, mode, &dev);
|
||||
}
|
||||
|
||||
weak_hidden_alias (__mknod, mknod)
|
||||
53
lib/libc/glibc/io/mknodat-2.32.c
vendored
Normal file
53
lib/libc/glibc/io/mknodat-2.32.c
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/* Copyright (C) 1995-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
int
|
||||
attribute_hidden
|
||||
mknodat (int fd, const char *path, mode_t mode, dev_t dev)
|
||||
{
|
||||
return __xmknodat (_MKNOD_VER, fd, path, mode, &dev);
|
||||
}
|
||||
54
lib/libc/glibc/io/stat-2.32.c
vendored
Normal file
54
lib/libc/glibc/io/stat-2.32.c
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef stat
|
||||
int
|
||||
attribute_hidden
|
||||
__stat (const char *file, struct stat *buf)
|
||||
{
|
||||
return __xstat (_STAT_VER, file, buf);
|
||||
}
|
||||
|
||||
weak_hidden_alias (__stat, stat)
|
||||
52
lib/libc/glibc/io/stat64-2.32.c
vendored
Normal file
52
lib/libc/glibc/io/stat64-2.32.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef stat64
|
||||
int
|
||||
attribute_hidden
|
||||
stat64 (const char *file, struct stat64 *buf)
|
||||
{
|
||||
return __xstat64 (_STAT_VER, file, buf);
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned int st_dev;
|
||||
unsigned int st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned int st_rdev;
|
||||
long int st_size;
|
||||
unsigned long int st_atime_sec;
|
||||
unsigned long int st_mtime_sec;
|
||||
unsigned long int st_ctime_sec;
|
||||
unsigned int st_blksize;
|
||||
int st_blocks;
|
||||
unsigned int st_flags;
|
||||
unsigned int st_gen;
|
||||
};
|
||||
|
||||
/* Definition of `struct stat64' used in the kernel. */
|
||||
struct kernel_stat64
|
||||
{
|
||||
unsigned long st_dev;
|
||||
unsigned long st_ino;
|
||||
unsigned long st_rdev;
|
||||
long st_size;
|
||||
unsigned long st_blocks;
|
||||
|
||||
unsigned int st_mode;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned int st_blksize;
|
||||
unsigned int st_nlink;
|
||||
unsigned int __pad0;
|
||||
|
||||
unsigned long st_atime_sec;
|
||||
unsigned long st_atimensec;
|
||||
unsigned long st_mtime_sec;
|
||||
unsigned long st_mtimensec;
|
||||
unsigned long st_ctime_sec;
|
||||
unsigned long st_ctimensec;
|
||||
long __glibc_reserved[3];
|
||||
};
|
||||
|
||||
/* Definition of `struct stat' used by glibc 2.0. */
|
||||
struct glibc2_stat
|
||||
{
|
||||
__dev_t st_dev;
|
||||
__ino_t st_ino;
|
||||
__mode_t st_mode;
|
||||
__nlink_t st_nlink;
|
||||
__uid_t st_uid;
|
||||
__gid_t st_gid;
|
||||
__dev_t st_rdev;
|
||||
__off_t st_size;
|
||||
__time_t st_atime_sec;
|
||||
__time_t st_mtime_sec;
|
||||
__time_t st_ctime_sec;
|
||||
unsigned int st_blksize;
|
||||
int st_blocks;
|
||||
unsigned int st_flags;
|
||||
unsigned int st_gen;
|
||||
};
|
||||
|
||||
/* Definition of `struct stat' used by glibc 2.1. */
|
||||
struct glibc21_stat
|
||||
{
|
||||
__dev_t st_dev;
|
||||
__ino64_t st_ino;
|
||||
__mode_t st_mode;
|
||||
__nlink_t st_nlink;
|
||||
__uid_t st_uid;
|
||||
__gid_t st_gid;
|
||||
__dev_t st_rdev;
|
||||
__off_t st_size;
|
||||
__time_t st_atime_sec;
|
||||
__time_t st_mtime_sec;
|
||||
__time_t st_ctime_sec;
|
||||
__blkcnt64_t st_blocks;
|
||||
__blksize_t st_blksize;
|
||||
unsigned int st_flags;
|
||||
unsigned int st_gen;
|
||||
int __pad3;
|
||||
long __glibc_reserved[4];
|
||||
};
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 1
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel.. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned short int __pad1;
|
||||
#define _HAVE___PAD1
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
unsigned short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
unsigned short int __pad2;
|
||||
#define _HAVE___PAD2
|
||||
unsigned long int st_size;
|
||||
unsigned long int st_blksize;
|
||||
unsigned long int st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
unsigned long int __glibc_reserved4;
|
||||
#define _HAVE___UNUSED4
|
||||
unsigned long int __glibc_reserved5;
|
||||
#define _HAVE___UNUSED5
|
||||
};
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64___PAD1
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT64___ST_INO
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,36 +0,0 @@
|
||||
/* definition of "struct stat" from the kernel */
|
||||
struct kernel_stat {
|
||||
unsigned long st_dev; /* dev_t is 32 bits on parisc */
|
||||
unsigned long st_ino; /* 32 bits */
|
||||
unsigned short st_mode; /* 16 bits */
|
||||
unsigned short st_nlink; /* 16 bits */
|
||||
unsigned short st_reserved1; /* old st_uid */
|
||||
unsigned short st_reserved2; /* old st_gid */
|
||||
unsigned long st_rdev;
|
||||
unsigned long st_size;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
long st_blksize;
|
||||
long st_blocks;
|
||||
unsigned long __glibc_reserved1; /* ACL stuff */
|
||||
unsigned long __glibc_reserved2; /* network */
|
||||
unsigned long __glibc_reserved3; /* network */
|
||||
unsigned long __glibc_reserved4; /* cnodes */
|
||||
unsigned short __glibc_reserved5; /* netsite */
|
||||
short st_fstype;
|
||||
unsigned long st_realdev;
|
||||
unsigned short st_basemode;
|
||||
unsigned short st_spareshort;
|
||||
unsigned long st_uid;
|
||||
unsigned long st_gid;
|
||||
unsigned long st_spare4[3];
|
||||
};
|
||||
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel.. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned short int __pad1;
|
||||
#define _HAVE___PAD1
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
unsigned short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
unsigned short int __pad2;
|
||||
#define _HAVE___PAD2
|
||||
unsigned long int st_size;
|
||||
unsigned long int st_blksize;
|
||||
unsigned long int st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
unsigned long int __glibc_reserved4;
|
||||
#define _HAVE___UNUSED4
|
||||
unsigned long int __glibc_reserved5;
|
||||
#define _HAVE___UNUSED5
|
||||
};
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64___PAD1
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT64___ST_INO
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,2 +0,0 @@
|
||||
/* Empty, it is overridden by an architecture which might require copy to or
|
||||
from a kernel_stat stat struct to glibc export stat{64}. */
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel.. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned short int __pad1;
|
||||
#define _HAVE___PAD1
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
unsigned short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
unsigned short int __pad2;
|
||||
#define _HAVE___PAD2
|
||||
unsigned long int st_size;
|
||||
unsigned long int st_blksize;
|
||||
unsigned long int st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
unsigned long int __glibc_reserved4;
|
||||
#define _HAVE___UNUSED4
|
||||
unsigned long int __glibc_reserved5;
|
||||
#define _HAVE___UNUSED5
|
||||
};
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64___PAD1
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT64___ST_INO
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,75 +0,0 @@
|
||||
#ifndef _KERNEL_STAT_H
|
||||
#define _KERNEL_STAT_H
|
||||
|
||||
#include <sgidefs.h>
|
||||
/* As tempting as it is to define XSTAT_IS_XSTAT64 for n64, the
|
||||
userland data structures are not identical, because of different
|
||||
padding. */
|
||||
/* Definition of `struct stat' used in the kernel. */
|
||||
#if _MIPS_SIM != _ABIO32
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned int st_dev;
|
||||
unsigned int __pad1[3];
|
||||
unsigned long long st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
int st_uid;
|
||||
int st_gid;
|
||||
unsigned int st_rdev;
|
||||
unsigned int __pad2[3];
|
||||
long long st_size;
|
||||
unsigned int st_atime_sec;
|
||||
unsigned int st_atime_nsec;
|
||||
unsigned int st_mtime_sec;
|
||||
unsigned int st_mtime_nsec;
|
||||
unsigned int st_ctime_sec;
|
||||
unsigned int st_ctime_nsec;
|
||||
unsigned int st_blksize;
|
||||
unsigned int __pad3;
|
||||
unsigned long long st_blocks;
|
||||
};
|
||||
#else
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned long int st_dev;
|
||||
long int __pad1[3]; /* Reserved for network id */
|
||||
unsigned long int st_ino;
|
||||
unsigned long int st_mode;
|
||||
unsigned long int st_nlink;
|
||||
long int st_uid;
|
||||
long int st_gid;
|
||||
unsigned long int st_rdev;
|
||||
long int __pad2[2];
|
||||
long int st_size;
|
||||
long int __pad3;
|
||||
unsigned int st_atime_sec;
|
||||
unsigned int st_atime_nsec;
|
||||
unsigned int st_mtime_sec;
|
||||
unsigned int st_mtime_nsec;
|
||||
unsigned int st_ctime_sec;
|
||||
unsigned int st_ctime_nsec;
|
||||
long int st_blksize;
|
||||
long int st_blocks;
|
||||
char st_fstype[16]; /* Filesystem type name, unsupported */
|
||||
long st_pad4[8];
|
||||
/* Linux specific fields */
|
||||
unsigned int st_flags;
|
||||
unsigned int st_gen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 0
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#if _MIPS_SIM == _ABI64
|
||||
# define STATFS_IS_STATFS64 1
|
||||
#else
|
||||
# define STATFS_IS_STATFS64 0
|
||||
#endif
|
||||
/* MIPS64 has unsigned 32 bit timestamps fields, so use statx as well. */
|
||||
#if _MIPS_SIM == _ABI64
|
||||
# define STAT_HAS_TIME32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel.. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned short int __pad1;
|
||||
#define _HAVE___PAD1
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
unsigned short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
unsigned short int __pad2;
|
||||
#define _HAVE___PAD2
|
||||
unsigned long int st_size;
|
||||
unsigned long int st_blksize;
|
||||
unsigned long int st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
unsigned long int __glibc_reserved4;
|
||||
#define _HAVE___UNUSED4
|
||||
unsigned long int __glibc_reserved5;
|
||||
#define _HAVE___UNUSED5
|
||||
};
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64___PAD1
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT64___ST_INO
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel.. */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned short int __pad1;
|
||||
#define _HAVE___PAD1
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
unsigned short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
unsigned short int __pad2;
|
||||
#define _HAVE___PAD2
|
||||
unsigned long int st_size;
|
||||
unsigned long int st_blksize;
|
||||
unsigned long int st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
unsigned long int __glibc_reserved4;
|
||||
#define _HAVE___UNUSED4
|
||||
unsigned long int __glibc_reserved5;
|
||||
#define _HAVE___UNUSED5
|
||||
};
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64___PAD1
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT64___ST_INO
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Definition of `struct stat' used in the kernel */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned short int st_dev;
|
||||
unsigned long int st_ino;
|
||||
unsigned short int st_mode;
|
||||
short int st_nlink;
|
||||
unsigned short int st_uid;
|
||||
unsigned short int st_gid;
|
||||
unsigned short int st_rdev;
|
||||
long int st_size;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
long int st_blksize;
|
||||
long int st_blocks;
|
||||
unsigned long int __glibc_reserved4;
|
||||
unsigned long int __glibc_reserved5;
|
||||
};
|
||||
|
||||
#define _HAVE___UNUSED4
|
||||
#define _HAVE___UNUSED5
|
||||
|
||||
#define _HAVE_STAT___UNUSED4
|
||||
#define _HAVE_STAT___UNUSED5
|
||||
#define _HAVE_STAT___PAD1
|
||||
#define _HAVE_STAT___PAD2
|
||||
#define _HAVE_STAT64___UNUSED4
|
||||
#define _HAVE_STAT64___UNUSED5
|
||||
#define _HAVE_STAT64___PAD2
|
||||
#define _HAVE_STAT_NSEC
|
||||
#define _HAVE_STAT64_NSEC
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 1
|
||||
#define XSTAT_IS_XSTAT64 0
|
||||
#define STATFS_IS_STATFS64 0
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef _KERNEL_STAT_H
|
||||
#define _KERNEL_STAT_H
|
||||
|
||||
/* Definition of `struct stat' used in the kernel */
|
||||
struct kernel_stat
|
||||
{
|
||||
unsigned int st_dev;
|
||||
unsigned long int st_ino;
|
||||
unsigned int st_mode;
|
||||
short int st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned int st_rdev;
|
||||
long int st_size;
|
||||
long int st_atime_sec;
|
||||
long int st_mtime_sec;
|
||||
long int st_ctime_sec;
|
||||
long int st_blksize;
|
||||
long int st_blocks;
|
||||
unsigned long int __glibc_reserved1;
|
||||
unsigned long int __glibc_reserved2;
|
||||
};
|
||||
|
||||
/* Definition of `struct stat64' used in the kernel. */
|
||||
struct kernel_stat64
|
||||
{
|
||||
unsigned long int st_dev;
|
||||
unsigned long int st_ino;
|
||||
unsigned long int st_nlink;
|
||||
|
||||
unsigned int st_mode;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned int __pad0;
|
||||
|
||||
unsigned long int st_rdev;
|
||||
long int st_size;
|
||||
long int st_blksize;
|
||||
long int st_blocks;
|
||||
|
||||
unsigned long int st_atime_sec;
|
||||
unsigned long int st_atime_nsec;
|
||||
unsigned long int st_mtime_sec;
|
||||
unsigned long int st_mtime_nsec;
|
||||
unsigned long int st_ctime_sec;
|
||||
unsigned long int st_ctime_nsec;
|
||||
long int __glibc_reserved[3];
|
||||
};
|
||||
|
||||
#define STAT_IS_KERNEL_STAT 0
|
||||
#define STAT64_IS_KERNEL_STAT64 0
|
||||
#define XSTAT_IS_XSTAT64 1
|
||||
#ifdef __arch64__
|
||||
# define STATFS_IS_STATFS64 1
|
||||
#else
|
||||
# define STATFS_IS_STATFS64 0
|
||||
#endif
|
||||
#endif /* _KERNEL_STAT_H */
|
||||
6
lib/libc/include/generic-glibc/string.h
vendored
6
lib/libc/include/generic-glibc/string.h
vendored
@@ -501,6 +501,11 @@ extern char *stpncpy (char *__restrict __dest,
|
||||
__THROW __nonnull ((1, 2));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* strlcpy and strlcat introduced in glibc 2.38
|
||||
* https://sourceware.org/git/?p=glibc.git;a=commit;h=2e0bbbfbf95fc9e22692e93658a6fbdd2d4554da
|
||||
*/
|
||||
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2
|
||||
#ifdef __USE_MISC
|
||||
/* Copy at most N - 1 characters from SRC to DEST. */
|
||||
extern size_t strlcpy (char *__restrict __dest,
|
||||
@@ -513,6 +518,7 @@ extern size_t strlcat (char *__restrict __dest,
|
||||
const char *__restrict __src, size_t __n)
|
||||
__THROW __nonnull ((1, 2)) __attr_access ((__read_write__, 1, 3));
|
||||
#endif
|
||||
#endif /* glibc v2.38 and later */
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Compare S1 and S2 as strings holding name & indices/version numbers. */
|
||||
|
||||
@@ -660,9 +660,6 @@ test "readAllAlloc" {
|
||||
}
|
||||
|
||||
test "Dir.statFile" {
|
||||
// TODO: Re-enable once https://github.com/ziglang/zig/issues/17034 is solved
|
||||
if (builtin.os.tag == .linux and builtin.link_libc and builtin.abi == .gnu) return error.SkipZigTest;
|
||||
|
||||
try testWithAllSupportedPathTypes(struct {
|
||||
fn impl(ctx: *TestContext) !void {
|
||||
const test_file_name = try ctx.transformPath("test_file");
|
||||
|
||||
@@ -20,7 +20,7 @@ pub const Lib = struct {
|
||||
};
|
||||
|
||||
pub const ABI = struct {
|
||||
all_versions: []const Version,
|
||||
all_versions: []const Version, // all defined versions (one abilist from v2.0.0 up to current)
|
||||
all_targets: []const target_util.ArchOsAbi,
|
||||
/// The bytes from the file verbatim, starting from the u16 number
|
||||
/// of function inclusions.
|
||||
@@ -172,6 +172,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
|
||||
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const target_ver = target.os.version_range.linux.glibc;
|
||||
const nonshared_stat = target_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) != .gt;
|
||||
const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt;
|
||||
|
||||
// In all cases in this function, we add the C compiler flags to
|
||||
@@ -276,54 +277,72 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
|
||||
},
|
||||
.libc_nonshared_a => {
|
||||
const s = path.sep_str;
|
||||
const linux_prefix = lib_libc_glibc ++
|
||||
"sysdeps" ++ s ++ "unix" ++ s ++ "sysv" ++ s ++ "linux" ++ s;
|
||||
const Flavor = enum { nonshared, shared };
|
||||
const Dep = struct {
|
||||
path: []const u8,
|
||||
flavor: Flavor = .shared,
|
||||
exclude: bool = false,
|
||||
include: bool = true,
|
||||
};
|
||||
const deps = [_]Dep{
|
||||
.{ .path = lib_libc_glibc ++ "stdlib" ++ s ++ "atexit.c" },
|
||||
.{ .path = lib_libc_glibc ++ "stdlib" ++ s ++ "at_quick_exit.c" },
|
||||
.{ .path = lib_libc_glibc ++ "sysdeps" ++ s ++ "pthread" ++ s ++ "pthread_atfork.c" },
|
||||
.{ .path = lib_libc_glibc ++ "debug" ++ s ++ "stack_chk_fail_local.c" },
|
||||
|
||||
// libc_nonshared.a redirected stat functions to xstat until glibc 2.33,
|
||||
// when they were finally versioned like other symbols.
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "stdlib" ++ s ++ "atexit.c",
|
||||
.flavor = .nonshared,
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "stat-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "stdlib" ++ s ++ "at_quick_exit.c",
|
||||
.flavor = .nonshared,
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "fstat-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "sysdeps" ++ s ++ "pthread" ++ s ++ "pthread_atfork.c",
|
||||
.flavor = .nonshared,
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "lstat-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "debug" ++ s ++ "stack_chk_fail_local.c",
|
||||
.flavor = .nonshared,
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "stat64-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{ .path = lib_libc_glibc ++ "csu" ++ s ++ "errno.c" },
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "fstat64-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "lstat64-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "fstatat-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "fstatat64-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "mknodat-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "io" ++ s ++ "mknod-2.32.c",
|
||||
.include = nonshared_stat,
|
||||
},
|
||||
|
||||
// __libc_start_main used to require statically linked init/fini callbacks
|
||||
// until glibc 2.34 when they were assimilated into the shared library.
|
||||
.{
|
||||
.path = lib_libc_glibc ++ "csu" ++ s ++ "elf-init-2.33.c",
|
||||
.exclude = !start_old_init_fini,
|
||||
.include = start_old_init_fini,
|
||||
},
|
||||
.{ .path = linux_prefix ++ "stat.c" },
|
||||
.{ .path = linux_prefix ++ "fstat.c" },
|
||||
.{ .path = linux_prefix ++ "lstat.c" },
|
||||
.{ .path = linux_prefix ++ "stat64.c" },
|
||||
.{ .path = linux_prefix ++ "fstat64.c" },
|
||||
.{ .path = linux_prefix ++ "lstat64.c" },
|
||||
.{ .path = linux_prefix ++ "fstatat.c" },
|
||||
.{ .path = linux_prefix ++ "fstatat64.c" },
|
||||
.{ .path = linux_prefix ++ "mknodat.c" },
|
||||
.{ .path = lib_libc_glibc ++ "io" ++ s ++ "mknod.c" },
|
||||
.{ .path = linux_prefix ++ "stat_t64_cp.c" },
|
||||
};
|
||||
|
||||
var files_buf: [deps.len]Compilation.CSourceFile = undefined;
|
||||
var files_index: usize = 0;
|
||||
|
||||
for (deps) |dep| {
|
||||
if (dep.exclude) continue;
|
||||
if (!dep.include) continue;
|
||||
|
||||
var args = std.ArrayList([]const u8).init(arena);
|
||||
try args.appendSlice(&[_][]const u8{
|
||||
@@ -347,13 +366,6 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
|
||||
try args.append("-DCAN_USE_REGISTER_ASM_EBP");
|
||||
}
|
||||
|
||||
const shared_def = switch (dep.flavor) {
|
||||
.nonshared => "-DLIBC_NONSHARED=1",
|
||||
// glibc passes `-DSHARED` for these. However, empirically if
|
||||
// we do that here we will see undefined symbols such as `__GI_memcpy`.
|
||||
// So we pass the same thing as for nonshared.
|
||||
.shared => "-DLIBC_NONSHARED=1",
|
||||
};
|
||||
try args.appendSlice(&[_][]const u8{
|
||||
"-D_LIBC_REENTRANT",
|
||||
"-include",
|
||||
@@ -363,7 +375,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
|
||||
"-include",
|
||||
try lib_path(comp, arena, lib_libc_glibc ++ "include" ++ path.sep_str ++ "libc-symbols.h"),
|
||||
"-DPIC",
|
||||
shared_def,
|
||||
"-DLIBC_NONSHARED=1",
|
||||
"-DTOP_NAMESPACE=glibc",
|
||||
});
|
||||
files_buf[files_index] = .{
|
||||
|
||||
@@ -79,9 +79,12 @@ pub fn cmdTargets(
|
||||
try jws.objectField("glibc");
|
||||
try jws.beginArray();
|
||||
for (glibc_abi.all_versions) |ver| {
|
||||
const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});
|
||||
defer allocator.free(tmp);
|
||||
try jws.write(tmp);
|
||||
// Actual glibc minimum is architecture specific. This just covers the broadest minimum.
|
||||
if (ver.order(target.glibc_min_version) != .lt) {
|
||||
const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});
|
||||
defer allocator.free(tmp);
|
||||
try jws.write(tmp);
|
||||
}
|
||||
}
|
||||
try jws.endArray();
|
||||
|
||||
|
||||
@@ -11,10 +11,16 @@ pub const ArchOsAbi = struct {
|
||||
os: std.Target.Os.Tag,
|
||||
abi: std.Target.Abi,
|
||||
os_ver: ?std.SemanticVersion = null,
|
||||
|
||||
// Minimum glibc version that provides support for the arch/os (for
|
||||
// .abi = .gnu). For most entries, the .glibc_min is null,
|
||||
// meaning the Zig minimum required by the standard library (see
|
||||
// glibc_min_version) is sufficient.
|
||||
glibc_min: ?std.SemanticVersion = null,
|
||||
};
|
||||
|
||||
pub const available_libcs = [_]ArchOsAbi{
|
||||
.{ .arch = .aarch64_be, .os = .linux, .abi = .gnu },
|
||||
.{ .arch = .aarch64_be, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 17, .patch = 0 } },
|
||||
.{ .arch = .aarch64_be, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .aarch64_be, .os = .windows, .abi = .gnu },
|
||||
.{ .arch = .aarch64, .os = .linux, .abi = .gnu },
|
||||
@@ -54,14 +60,14 @@ pub const available_libcs = [_]ArchOsAbi{
|
||||
.{ .arch = .mips, .os = .linux, .abi = .gnueabi },
|
||||
.{ .arch = .mips, .os = .linux, .abi = .gnueabihf },
|
||||
.{ .arch = .mips, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .powerpc64le, .os = .linux, .abi = .gnu },
|
||||
.{ .arch = .powerpc64le, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 19, .patch = 0 } },
|
||||
.{ .arch = .powerpc64le, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .powerpc64, .os = .linux, .abi = .gnu },
|
||||
.{ .arch = .powerpc64, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabi },
|
||||
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf },
|
||||
.{ .arch = .powerpc, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .riscv64, .os = .linux, .abi = .gnu },
|
||||
.{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } },
|
||||
.{ .arch = .riscv64, .os = .linux, .abi = .musl },
|
||||
.{ .arch = .s390x, .os = .linux, .abi = .gnu },
|
||||
.{ .arch = .s390x, .os = .linux, .abi = .musl },
|
||||
@@ -76,6 +82,9 @@ pub const available_libcs = [_]ArchOsAbi{
|
||||
.{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 10, .minor = 7, .patch = 0 } },
|
||||
};
|
||||
|
||||
/// Minimum glibc version, due to dependencies from the Zig standard library on glibc symbols
|
||||
pub const glibc_min_version: std.SemanticVersion = .{ .major = 2, .minor = 17, .patch = 0 };
|
||||
|
||||
pub fn libCGenericName(target: std.Target) [:0]const u8 {
|
||||
switch (target.os.tag) {
|
||||
.windows => return "mingw",
|
||||
@@ -154,6 +163,12 @@ pub fn canBuildLibC(target: std.Target) bool {
|
||||
const ver = target.os.version_range.semver;
|
||||
return ver.min.order(libc.os_ver.?) != .lt;
|
||||
}
|
||||
// Ensure glibc (aka *-linux-gnu) version is supported
|
||||
if (target.isGnuLibC()) {
|
||||
const min_glibc_ver = libc.glibc_min orelse glibc_min_version;
|
||||
const target_glibc_ver = target.os.version_range.linux.glibc;
|
||||
return target_glibc_ver.order(min_glibc_ver) != .lt;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// To run executables linked against a specific glibc version, the
|
||||
// run-time glibc version needs to be new enough. Check the host's glibc
|
||||
// version. Note that this does not allow for translation/vm/emulation
|
||||
// services to run these tests.
|
||||
const running_glibc_ver: ?std.SemanticVersion = switch (builtin.os.tag) {
|
||||
.linux => builtin.os.version_range.linux.glibc,
|
||||
else => null,
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test");
|
||||
@@ -17,4 +27,95 @@ pub fn build(b: *std.Build) void {
|
||||
_ = exe.getEmittedBin();
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
|
||||
// Build & run against a sampling of supported glibc versions
|
||||
for ([_][]const u8{
|
||||
"native-linux-gnu.2.17", // Currently oldest supported, see #17769
|
||||
"native-linux-gnu.2.23",
|
||||
"native-linux-gnu.2.28",
|
||||
"native-linux-gnu.2.33",
|
||||
"native-linux-gnu.2.38",
|
||||
"native-linux-gnu",
|
||||
}) |t| {
|
||||
const target = b.resolveTargetQuery(std.Target.Query.parse(
|
||||
.{ .arch_os_abi = t },
|
||||
) catch unreachable);
|
||||
|
||||
const glibc_ver = target.result.os.version_range.linux.glibc;
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = t,
|
||||
.root_source_file = .{ .path = "glibc_runtime_check.zig" },
|
||||
.target = target,
|
||||
});
|
||||
exe.linkLibC();
|
||||
|
||||
// Only try running the test if the host glibc is known to be good enough. Ideally, the Zig
|
||||
// test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453
|
||||
if (running_glibc_ver) |running_ver| {
|
||||
if (glibc_ver.order(running_ver) == .lt) {
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.skip_foreign_checks = true;
|
||||
run_cmd.expectExitCode(0);
|
||||
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
}
|
||||
const check = exe.checkObject();
|
||||
|
||||
// __errno_location is always a dynamically linked symbol
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __errno_location");
|
||||
|
||||
// before v2.32 fstatat redirects through __fxstatat, afterwards its a
|
||||
// normal dynamic symbol
|
||||
if (glibc_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) == .lt) {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __fxstatat");
|
||||
|
||||
check.checkInSymtab();
|
||||
check.checkContains("FUNC LOCAL HIDDEN fstatat");
|
||||
} else {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT fstatat");
|
||||
|
||||
check.checkInSymtab();
|
||||
check.checkNotPresent("FUNC LOCAL HIDDEN fstatat");
|
||||
}
|
||||
|
||||
// before v2.26 reallocarray is not supported
|
||||
if (glibc_ver.order(.{ .major = 2, .minor = 26, .patch = 0 }) == .lt) {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkNotPresent("reallocarray");
|
||||
} else {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT reallocarray");
|
||||
}
|
||||
|
||||
// before v2.38 strlcpy is not supported
|
||||
if (glibc_ver.order(.{ .major = 2, .minor = 38, .patch = 0 }) == .lt) {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkNotPresent("strlcpy");
|
||||
} else {
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT strlcpy");
|
||||
}
|
||||
|
||||
// v2.16 introduced getauxval(), so always present
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT getauxval");
|
||||
|
||||
// Always have a dynamic "exit" reference
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT exit");
|
||||
|
||||
// An atexit local symbol is defined, and depends on undefined dynamic
|
||||
// __cxa_atexit.
|
||||
check.checkInSymtab();
|
||||
check.checkContains("FUNC LOCAL HIDDEN atexit");
|
||||
check.checkInDynamicSymtab();
|
||||
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __cxa_atexit");
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
}
|
||||
}
|
||||
|
||||
116
test/link/glibc_compat/glibc_runtime_check.zig
Normal file
116
test/link/glibc_compat/glibc_runtime_check.zig
Normal file
@@ -0,0 +1,116 @@
|
||||
// A zig test case that exercises some glibc symbols that have uncovered
|
||||
// problems in the past. This test must be compiled against a glibc.
|
||||
//
|
||||
// The build.zig tests the binary built from this source to see that
|
||||
// symbols are statically or dynamically linked, as expected.
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const c_malloc = @cImport(
|
||||
@cInclude("malloc.h"), // for reallocarray
|
||||
);
|
||||
|
||||
const c_stdlib = @cImport(
|
||||
@cInclude("stdlib.h"), // for atexit
|
||||
);
|
||||
|
||||
const c_string = @cImport(
|
||||
@cInclude("string.h"), // for strlcpy
|
||||
);
|
||||
|
||||
// Version of glibc this test is being built to run against
|
||||
const glibc_ver = builtin.target.os.version_range.linux.glibc;
|
||||
|
||||
// PR #17034 - fstat moved between libc_nonshared and libc
|
||||
fn checkStat() !void {
|
||||
const cwdFd = std.fs.cwd().fd;
|
||||
|
||||
var stat = std.mem.zeroes(std.c.Stat);
|
||||
var result = std.c.fstatat(cwdFd, "a_file_that_definitely_does_not_exist", &stat, 0);
|
||||
assert(result == -1);
|
||||
assert(std.c.getErrno(result) == .NOENT);
|
||||
|
||||
result = std.c.stat("a_file_that_definitely_does_not_exist", &stat);
|
||||
assert(result == -1);
|
||||
assert(std.c.getErrno(result) == .NOENT);
|
||||
}
|
||||
|
||||
// PR #17607 - reallocarray not visible in headers
|
||||
fn checkReallocarray() !void {
|
||||
// reallocarray was introduced in v2.26
|
||||
if (comptime glibc_ver.order(.{ .major = 2, .minor = 26, .patch = 0 }) == .lt) {
|
||||
if (@hasDecl(c_malloc, "reallocarray")) {
|
||||
@compileError("Before v2.26 'malloc.h' does not define 'reallocarray'");
|
||||
}
|
||||
} else {
|
||||
return try checkReallocarray_v2_26();
|
||||
}
|
||||
}
|
||||
|
||||
fn checkReallocarray_v2_26() !void {
|
||||
const size = 16;
|
||||
const tenX = c_malloc.reallocarray(c_malloc.NULL, 10, size);
|
||||
const elevenX = c_malloc.reallocarray(tenX, 11, size);
|
||||
|
||||
assert(tenX != c_malloc.NULL);
|
||||
assert(elevenX != c_malloc.NULL);
|
||||
}
|
||||
|
||||
// getauxval introduced in v2.16
|
||||
fn checkGetAuxVal() !void {
|
||||
if (comptime glibc_ver.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
|
||||
if (@hasDecl(std.c, "getauxval")) {
|
||||
@compileError("Before v2.16 glibc does not define 'getauxval'");
|
||||
}
|
||||
} else {
|
||||
try checkGetAuxVal_v2_16();
|
||||
}
|
||||
}
|
||||
|
||||
fn checkGetAuxVal_v2_16() !void {
|
||||
const base = std.c.getauxval(std.elf.AT_BASE);
|
||||
const pgsz = std.c.getauxval(std.elf.AT_PAGESZ);
|
||||
|
||||
assert(base != 0);
|
||||
assert(pgsz != 0);
|
||||
}
|
||||
|
||||
// strlcpy introduced in v2.38, which is newer than many installed glibcs
|
||||
fn checkStrlcpy() !void {
|
||||
if (comptime glibc_ver.order(.{ .major = 2, .minor = 38, .patch = 0 }) == .lt) {
|
||||
if (@hasDecl(c_string, "strlcpy")) {
|
||||
@compileError("Before v2.38 glibc does not define 'strlcpy'");
|
||||
}
|
||||
} else {
|
||||
try checkStrlcpy_v2_38();
|
||||
}
|
||||
}
|
||||
|
||||
fn checkStrlcpy_v2_38() !void {
|
||||
var buf: [99]u8 = undefined;
|
||||
const used = c_string.strlcpy(&buf, "strlcpy works!", buf.len);
|
||||
assert(used == 15);
|
||||
}
|
||||
|
||||
// atexit is part of libc_nonshared, so ensure its linked in correctly
|
||||
fn forceExit0Callback() callconv(.C) void {
|
||||
std.c.exit(0); // Override the main() exit code
|
||||
}
|
||||
|
||||
fn checkAtExit() !void {
|
||||
const result = c_stdlib.atexit(forceExit0Callback);
|
||||
assert(result == 0);
|
||||
}
|
||||
|
||||
pub fn main() !u8 {
|
||||
try checkStat();
|
||||
try checkReallocarray();
|
||||
try checkStrlcpy();
|
||||
|
||||
try checkGetAuxVal();
|
||||
try checkAtExit();
|
||||
|
||||
std.c.exit(1); // overridden by atexit() callback
|
||||
}
|
||||
Reference in New Issue
Block a user