slotinfo in struct dtv_slotinfo_list should be flexible array [BZ #25097]

GCC 10 will warn about subscribing inner length zero arrays.  Use a GCC
extension in csu/libc-tls.c to allocate space for the static_slotinfo
variable.  Adjust nptl_db so that the type description machinery does
not attempt to determine the size of the flexible array member slotinfo.

Change-Id: I51be146a7857186a4ede0bb40b332509487bdde8
This commit is contained in:
Florian Weimer 2019-11-12 12:41:34 +01:00
parent 42b926d303
commit cba932a5a9
6 changed files with 29 additions and 22 deletions

View File

@ -23,7 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
#include <array_length.h>
#ifdef SHARED
#error makefile bug, this file is for static only
@ -32,17 +32,11 @@
dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
{
struct dtv_slotinfo_list si;
/* The dtv_slotinfo_list data structure does not include the actual
information since it is defined as an array of size zero. We define
here the necessary entries. Note that it is not important whether
there is padding or not since we will always access the information
through the 'si' element. */
struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS];
} static_slotinfo;
static struct dtv_slotinfo_list static_slotinfo =
{
/* Allocate an array of 2 + TLS_SLOTINFO_SURPLUS elements. */
.slotinfo = { [array_length (_dl_static_dtv) - 1] = { 0 } },
};
/* Highest dtv index currently needed. */
size_t _dl_tls_max_dtv_idx;
@ -72,16 +66,16 @@ TLS_INIT_HELPER
static void
init_slotinfo (void)
{
/* Create the slotinfo list. */
static_slotinfo.si.len = (((char *) (&static_slotinfo + 1)
- (char *) &static_slotinfo.si.slotinfo[0])
/ sizeof static_slotinfo.si.slotinfo[0]);
// static_slotinfo.si.next = NULL; already zero
/* Create the slotinfo list. Note that the type of static_slotinfo
has effectively a zero-length array, so we cannot use the size of
static_slotinfo to determine the array length. */
static_slotinfo.len = array_length (_dl_static_dtv);
/* static_slotinfo.next = NULL; -- Already zero. */
/* The slotinfo list. Will be extended by the code doing dynamic
linking. */
GL(dl_tls_max_dtv_idx) = 1;
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si;
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo;
}
static void
@ -205,8 +199,8 @@ __libc_setup_tls (void)
main_map->l_tls_modid = 1;
init_slotinfo ();
// static_slotinfo.si.slotinfo[1].gen = 0; already zero
static_slotinfo.si.slotinfo[1].map = main_map;
/* static_slotinfo.slotinfo[1].gen = 0; -- Already zero. */
static_slotinfo.slotinfo[1].map = main_map;
memsz = roundup (memsz, align ?: 1);

View File

@ -25,6 +25,7 @@
DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
#define DB_STRUCT_FIELD(type, field) \
DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
#define DB_SYMBOL(name) \
DB_LOOKUP_NAME (SYM_##name, name)
#define DB_FUNCTION(name) \
@ -36,6 +37,8 @@
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_FUNCTION
# undef DB_SYMBOL
# undef DB_VARIABLE

View File

@ -56,6 +56,9 @@ extern bool __nptl_initial_report_events;
DB_DEFINE_DESC (name, \
8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
offset);
/* Flexible arrays do not have a length that can be determined. */
#define FLEXIBLE_ARRAY_DESC(name, offset, obj) \
DB_DEFINE_DESC (name, 8 * sizeof (obj)[0], 0, offset);
#if TLS_TCB_AT_TP
# define dtvp header.dtv
@ -77,6 +80,9 @@ DESC (_thread_db_pthread_dtvp,
#define DB_STRUCT_ARRAY_FIELD(type, field) \
ARRAY_DESC (_thread_db_##type##_##field, \
offsetof (type, field), ((type *) 0)->field)
#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) \
FLEXIBLE_ARRAY_DESC (_thread_db_##type##_##field, \
offsetof (type, field), ((type *) 0)->field)
#define DB_VARIABLE(name) DESC (_thread_db_##name, 0, name)
#define DB_ARRAY_VARIABLE(name) ARRAY_DESC (_thread_db_##name, 0, name)
#define DB_SYMBOL(name) /* Nothing. */

View File

@ -110,7 +110,7 @@ DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
DB_STRUCT (dtv_slotinfo_list)
DB_STRUCT_FIELD (dtv_slotinfo_list, len)
DB_STRUCT_FIELD (dtv_slotinfo_list, next)
DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
DB_STRUCT_FLEXIBLE_ARRAY (dtv_slotinfo_list, slotinfo)
DB_STRUCT (dtv_slotinfo)
DB_STRUCT_FIELD (dtv_slotinfo, gen)

View File

@ -37,12 +37,14 @@ enum
{
# define DB_STRUCT(type) SYM_SIZEOF_##type,
# define DB_STRUCT_FIELD(type, field) SYM_##type##_FIELD_##field,
# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
# define DB_SYMBOL(name) SYM_##name,
# define DB_FUNCTION(name) SYM_##name,
# define DB_VARIABLE(name) SYM_##name, SYM_DESC_##name,
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_SYMBOL
# undef DB_FUNCTION
# undef DB_VARIABLE
@ -90,6 +92,7 @@ struct td_thragent
uint32_t ta_sizeof_##type;
# define DB_STRUCT_FIELD(type, field) \
db_desc_t ta_field_##type##_##field;
# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
# define DB_SYMBOL(name) \
psaddr_t ta_addr_##name;
# define DB_FUNCTION(name) \
@ -100,6 +103,7 @@ struct td_thragent
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_FUNCTION
# undef DB_SYMBOL
# undef DB_VARIABLE

View File

@ -420,7 +420,7 @@ struct rtld_global
{
size_t gen;
struct link_map *map;
} slotinfo[0];
} slotinfo[];
} *_dl_tls_dtv_slotinfo_list;
/* Number of modules in the static TLS block. */
EXTERN size_t _dl_tls_static_nelem;