mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 01:33:36 +08:00
stdio: Remove the usage of $(fno-unit-at-a-time) for errlist.c
The errlist.c is built with -fno-toplevel-reorder to avoid compiler to reorder the compat assembly directives due an assembler issue [1] (fixed on 2.39). This patch removes the compiler flags by split the compat symbol generation in two phases. First the _sys_errlist_internal internal without any compat symbol directive is preprocessed to generate an assembly source code. This generate assembly is then used as input on a platform agnostic errlist-data.S which then creates the compat definitions. This prevents compiler to move any compat directive prior the _sys_errlist_internal definition itself. Checked on a make check run-built-tests=no on all affected ABIs. [1] https://sourceware.org/bugzilla/show_bug.cgi?id=29012
This commit is contained in:
parent
111254f3e1
commit
900fa25736
@ -1030,7 +1030,8 @@ ifeq (yes,$(build-shared))
|
||||
# Under --enable-shared, we will build a shared library of PIC objects.
|
||||
# The PIC object files are named foo.os.
|
||||
object-suffixes += .os
|
||||
CPPFLAGS-.os = -DPIC -DSHARED
|
||||
pic-cppflags = -DPIC -DSHARED
|
||||
CPPFLAGS-.os = $(pic-cppflags)
|
||||
CFLAGS-.os = $(filter %frame-pointer,$(+cflags)) $(pic-ccflag)
|
||||
libtype.os := lib%_pic.a
|
||||
# This can be changed by a sysdep makefile
|
||||
|
@ -180,6 +180,7 @@ int __vfxprintf (FILE *__fp, const char *__fmt, __gnuc_va_list,
|
||||
attribute_hidden;
|
||||
|
||||
extern const char *const _sys_errlist_internal[] attribute_hidden;
|
||||
extern const size_t _sys_errlist_internal_len attribute_hidden;
|
||||
extern const char *__get_errlist (int) attribute_hidden;
|
||||
extern const char *__get_errname (int) attribute_hidden;
|
||||
|
||||
|
@ -88,6 +88,7 @@ routines := \
|
||||
|
||||
aux := \
|
||||
errlist \
|
||||
errlist-data \
|
||||
errname \
|
||||
fxprintf \
|
||||
printf-parsemb \
|
||||
@ -211,6 +212,10 @@ tests := \
|
||||
xbug \
|
||||
# tests
|
||||
|
||||
generated += \
|
||||
errlist-data-aux-shared.S \
|
||||
errlist-data-aux.S \
|
||||
# generated
|
||||
|
||||
test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
|
||||
|
||||
@ -246,6 +251,20 @@ tests-special += $(objpfx)tst-errno-manual.out
|
||||
|
||||
include ../Rules
|
||||
|
||||
# The errlist.c is built in two phases because compiler might reorder the
|
||||
# compat_symbol directive prior the object itself and on binutils older
|
||||
# than 2.29 it might generate object sizes different than the expected ones.
|
||||
$(objpfx)errlist-data-aux-shared.S: errlist-data-gen.c
|
||||
$(make-target-directory)
|
||||
$(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S
|
||||
|
||||
$(objpfx)errlist-data-aux.S: errlist-data-gen.c
|
||||
$(make-target-directory)
|
||||
$(compile-command.c) $(pie-default) $(no-stack-protector) -S
|
||||
|
||||
$(objpfx)errlist-data.os: $(objpfx)errlist-data-aux-shared.S
|
||||
$(objpfx)errlist-data.o: $(objpfx)errlist-data-aux.S
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
LOCALES := \
|
||||
de_DE.ISO-8859-1 \
|
||||
@ -334,7 +353,6 @@ CFLAGS-isoc99_vfscanf.c += -fexceptions
|
||||
CFLAGS-isoc99_vscanf.c += -fexceptions
|
||||
CFLAGS-isoc99_fscanf.c += -fexceptions
|
||||
CFLAGS-isoc99_scanf.c += -fexceptions
|
||||
CFLAGS-errlist.c += $(fno-unit-at-a-time)
|
||||
CFLAGS-siglist.c += $(fno-unit-at-a-time)
|
||||
|
||||
# scanf14a.c and scanf16a.c test a deprecated extension which is no
|
||||
|
24
stdio-common/err_map.h
Normal file
24
stdio-common/err_map.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Internal errno names mapping definition.
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
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/>. */
|
||||
|
||||
#ifndef _ERR_MAP_H
|
||||
#define _ERR_MAP_H
|
||||
|
||||
#define ERR_MAP(n) (n)
|
||||
|
||||
#endif
|
1
stdio-common/errlist-compat-data.h
Normal file
1
stdio-common/errlist-compat-data.h
Normal file
@ -0,0 +1 @@
|
||||
/* Empty */
|
@ -1 +0,0 @@
|
||||
/* Empty. */
|
34
stdio-common/errlist-data-gen.c
Normal file
34
stdio-common/errlist-data-gen.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* Internal errno names mapping definition.
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
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 <array_length.h>
|
||||
#include <err_map.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
const char *const _sys_errlist_internal[] =
|
||||
{
|
||||
#define _S(n, str) [ERR_MAP(n)] = str,
|
||||
#include <errlist.h>
|
||||
#undef _S
|
||||
};
|
||||
const size_t _sys_errlist_internal_len = array_length (_sys_errlist_internal);
|
||||
|
||||
/* Include to get the definitions for sys_nerr/_sys_nerr. */
|
||||
#include <errlist-compat-data.h>
|
7
stdio-common/errlist-data.S
Normal file
7
stdio-common/errlist-data.S
Normal file
@ -0,0 +1,7 @@
|
||||
#ifdef SHARED
|
||||
# include "errlist-data-aux-shared.S"
|
||||
#else
|
||||
# include "errlist-data-aux.S"
|
||||
#endif
|
||||
|
||||
#include <errlist-compat-data.h>
|
@ -16,29 +16,17 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <array_length.h>
|
||||
#include <err_map.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <array_length.h>
|
||||
|
||||
#ifndef ERR_MAP
|
||||
# define ERR_MAP(n) n
|
||||
#endif
|
||||
|
||||
const char *const _sys_errlist_internal[] =
|
||||
{
|
||||
#define _S(n, str) [ERR_MAP(n)] = str,
|
||||
#include <errlist.h>
|
||||
#undef _S
|
||||
};
|
||||
#include <stdio.h>
|
||||
|
||||
const char *
|
||||
__get_errlist (int errnum)
|
||||
{
|
||||
int mapped = ERR_MAP (errnum);
|
||||
if (mapped >= 0 && mapped < array_length (_sys_errlist_internal))
|
||||
if (mapped >= 0 && mapped < _sys_errlist_internal_len)
|
||||
return _sys_errlist_internal[mapped];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include <errlist-compat.c>
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||
/* Internal errno names mapping definition. Hurd version.
|
||||
Copyright (C) 2022 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
|
||||
@ -15,7 +16,11 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ERR_MAP_H
|
||||
#define _ERR_MAP_H
|
||||
|
||||
#include <mach/error.h>
|
||||
|
||||
#define ERR_MAP(value) err_get_code (value)
|
||||
#include <stdio-common/errlist.c>
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
#define _ERRLIST_COMPAT_H
|
||||
|
||||
#include <shlib-compat.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Define new compat symbols for symbols _sys_errlist, sys_errlist,
|
||||
_sys_nerr, and sys_nerr for version VERSION with NUMBERERR times number of
|
||||
@ -27,17 +28,25 @@
|
||||
Both _sys_errlist and sys_errlist alias to _sys_errlist_internal symbol
|
||||
(defined on errlist.c) while _sys_nerr and sys_nerr created new variable
|
||||
with the expected size. */
|
||||
#define DEFINE_COMPAT_ERRLIST(NUMBERERR, VERSION) \
|
||||
const int __##VERSION##_sys_nerr = NUMBERERR; \
|
||||
strong_alias (__##VERSION##_sys_nerr, __##VERSION##__sys_nerr); \
|
||||
declare_symbol_alias (__ ## VERSION ## _sys_errlist, _sys_errlist_internal,\
|
||||
object, NUMBERERR * (ULONG_WIDTH / UCHAR_WIDTH)); \
|
||||
declare_symbol_alias (__ ## VERSION ## __sys_errlist, \
|
||||
_sys_errlist_internal, object, \
|
||||
NUMBERERR * (ULONG_WIDTH / UCHAR_WIDTH)); \
|
||||
compat_symbol (libc, __## VERSION ## _sys_nerr, sys_nerr, VERSION); \
|
||||
compat_symbol (libc, __## VERSION ## __sys_nerr, _sys_nerr, VERSION); \
|
||||
compat_symbol (libc, __## VERSION ## _sys_errlist, sys_errlist, VERSION); \
|
||||
compat_symbol (libc, __## VERSION ## __sys_errlist, _sys_errlist, VERSION);\
|
||||
#ifdef __ASSEMBLER__
|
||||
# define DEFINE_COMPAT_ERRLIST(NUMBERERR, VERSION) \
|
||||
declare_object_symbol_alias (__ ## VERSION ## _sys_errlist, \
|
||||
_sys_errlist_internal, \
|
||||
NUMBERERR * (ULONG_WIDTH / UCHAR_WIDTH)) \
|
||||
ASM_LINE_SEP \
|
||||
declare_object_symbol_alias (__ ## VERSION ## __sys_errlist, \
|
||||
_sys_errlist_internal, \
|
||||
NUMBERERR * (ULONG_WIDTH / UCHAR_WIDTH)) \
|
||||
ASM_LINE_SEP \
|
||||
compat_symbol (libc, __## VERSION ## _sys_errlist, sys_errlist, VERSION) \
|
||||
ASM_LINE_SEP \
|
||||
compat_symbol (libc, __## VERSION ## __sys_errlist, _sys_errlist, VERSION)
|
||||
#else
|
||||
# define DEFINE_COMPAT_ERRLIST(NUMBERERR, VERSION) \
|
||||
const int __##VERSION##_sys_nerr = NUMBERERR; \
|
||||
strong_alias (__##VERSION##_sys_nerr, __##VERSION##__sys_nerr); \
|
||||
compat_symbol (libc, __## VERSION ## _sys_nerr, sys_nerr, VERSION); \
|
||||
compat_symbol (libc, __## VERSION ## __sys_nerr, _sys_nerr, VERSION);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user