1From 8e7921aab0aa215d32ed90db3dd150d2c5d25d49 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Tue, 12 Nov 2019 12:41:34 +0100
4Subject: [PATCH 03/20] slotinfo in struct dtv_slotinfo_list should be flexible
5 array [BZ #25097]
6
7GCC 10 will warn about subscribing inner length zero arrays.  Use a GCC
8extension in csu/libc-tls.c to allocate space for the static_slotinfo
9variable.  Adjust nptl_db so that the type description machinery does
10not attempt to determine the size of the flexible array member slotinfo.
11
12Change-Id: I51be146a7857186a4ede0bb40b332509487bdde8
13(cherry picked from commit cba932a5a9e91cffd7f4172d7e91f9b2efb1f84b)
14Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
15---
16 csu/libc-tls.c             | 34 ++++++++++++++--------------------
17 nptl_db/db-symbols.h       |  3 +++
18 nptl_db/db_info.c          |  6 ++++++
19 nptl_db/structs.def        |  2 +-
20 nptl_db/thread_dbP.h       |  4 ++++
21 sysdeps/generic/ldsodefs.h |  2 +-
22 6 files changed, 29 insertions(+), 22 deletions(-)
23
24diff --git a/csu/libc-tls.c b/csu/libc-tls.c
25index 28a79441..334baa72 100644
26--- a/csu/libc-tls.c
27+++ b/csu/libc-tls.c
28@@ -23,7 +23,7 @@
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <sys/param.h>
32-
33+#include <array_length.h>
34
35 #ifdef SHARED
36  #error makefile bug, this file is for static only
37@@ -32,17 +32,11 @@
38 dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
39
40
41-static struct
42-{
43-  struct dtv_slotinfo_list si;
44-  /* The dtv_slotinfo_list data structure does not include the actual
45-     information since it is defined as an array of size zero.  We define
46-     here the necessary entries.  Note that it is not important whether
47-     there is padding or not since we will always access the information
48-     through the 'si' element.  */
49-  struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS];
50-} static_slotinfo;
51-
52+static struct dtv_slotinfo_list static_slotinfo =
53+  {
54+   /* Allocate an array of 2 + TLS_SLOTINFO_SURPLUS elements.  */
55+   .slotinfo =  { [array_length (_dl_static_dtv) - 1] = { 0 } },
56+  };
57
58 /* Highest dtv index currently needed.  */
59 size_t _dl_tls_max_dtv_idx;
60@@ -72,16 +66,16 @@ TLS_INIT_HELPER
61 static void
62 init_slotinfo (void)
63 {
64-  /* Create the slotinfo list.  */
65-  static_slotinfo.si.len = (((char *) (&static_slotinfo + 1)
66-			     - (char *) &static_slotinfo.si.slotinfo[0])
67-			    / sizeof static_slotinfo.si.slotinfo[0]);
68-  // static_slotinfo.si.next = NULL;	already zero
69+  /* Create the slotinfo list.  Note that the type of static_slotinfo
70+     has effectively a zero-length array, so we cannot use the size of
71+     static_slotinfo to determine the array length.  */
72+  static_slotinfo.len = array_length (_dl_static_dtv);
73+  /* static_slotinfo.next = NULL; -- Already zero.  */
74
75   /* The slotinfo list.  Will be extended by the code doing dynamic
76      linking.  */
77   GL(dl_tls_max_dtv_idx) = 1;
78-  GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si;
79+  GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo;
80 }
81
82 static void
83@@ -205,8 +199,8 @@ __libc_setup_tls (void)
84   main_map->l_tls_modid = 1;
85
86   init_slotinfo ();
87-  // static_slotinfo.si.slotinfo[1].gen = 0; already zero
88-  static_slotinfo.si.slotinfo[1].map = main_map;
89+  /* static_slotinfo.slotinfo[1].gen = 0; -- Already zero.  */
90+  static_slotinfo.slotinfo[1].map = main_map;
91
92   memsz = roundup (memsz, align ?: 1);
93
94diff --git a/nptl_db/db-symbols.h b/nptl_db/db-symbols.h
95index e2f7cf63..1be6c72a 100644
96--- a/nptl_db/db-symbols.h
97+++ b/nptl_db/db-symbols.h
98@@ -25,6 +25,7 @@
99   DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
100 #define DB_STRUCT_FIELD(type, field) \
101   DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
102+#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
103 #define DB_SYMBOL(name) \
104   DB_LOOKUP_NAME (SYM_##name, name)
105 #define DB_FUNCTION(name) \
106@@ -36,6 +37,8 @@
107 # include "structs.def"
108
109 # undef DB_STRUCT
110+# undef DB_STRUCT_FIELD
111+# undef DB_STRUCT_FLEXIBLE_ARRAY
112 # undef DB_FUNCTION
113 # undef DB_SYMBOL
114 # undef DB_VARIABLE
115diff --git a/nptl_db/db_info.c b/nptl_db/db_info.c
116index 7f23cf46..16a33901 100644
117--- a/nptl_db/db_info.c
118+++ b/nptl_db/db_info.c
119@@ -56,6 +56,9 @@ extern bool __nptl_initial_report_events;
120   DB_DEFINE_DESC (name, \
121 		  8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
122 		  offset);
123+/* Flexible arrays do not have a length that can be determined.  */
124+#define FLEXIBLE_ARRAY_DESC(name, offset, obj) \
125+  DB_DEFINE_DESC (name, 8 * sizeof (obj)[0], 0, offset);
126
127 #if TLS_TCB_AT_TP
128 # define dtvp header.dtv
129@@ -77,6 +80,9 @@ DESC (_thread_db_pthread_dtvp,
130 #define DB_STRUCT_ARRAY_FIELD(type, field) \
131   ARRAY_DESC (_thread_db_##type##_##field, \
132 	      offsetof (type, field), ((type *) 0)->field)
133+#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) \
134+  FLEXIBLE_ARRAY_DESC (_thread_db_##type##_##field, \
135+		       offsetof (type, field), ((type *) 0)->field)
136 #define DB_VARIABLE(name) DESC (_thread_db_##name, 0, name)
137 #define DB_ARRAY_VARIABLE(name) ARRAY_DESC (_thread_db_##name, 0, name)
138 #define DB_SYMBOL(name)	/* Nothing.  */
139diff --git a/nptl_db/structs.def b/nptl_db/structs.def
140index 15ec77f4..f670cbce 100644
141--- a/nptl_db/structs.def
142+++ b/nptl_db/structs.def
143@@ -110,7 +110,7 @@ DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
144 DB_STRUCT (dtv_slotinfo_list)
145 DB_STRUCT_FIELD (dtv_slotinfo_list, len)
146 DB_STRUCT_FIELD (dtv_slotinfo_list, next)
147-DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
148+DB_STRUCT_FLEXIBLE_ARRAY (dtv_slotinfo_list, slotinfo)
149
150 DB_STRUCT (dtv_slotinfo)
151 DB_STRUCT_FIELD (dtv_slotinfo, gen)
152diff --git a/nptl_db/thread_dbP.h b/nptl_db/thread_dbP.h
153index bcb27640..8dbdbb5d 100644
154--- a/nptl_db/thread_dbP.h
155+++ b/nptl_db/thread_dbP.h
156@@ -37,12 +37,14 @@ enum
157   {
158 # define DB_STRUCT(type)		SYM_SIZEOF_##type,
159 # define DB_STRUCT_FIELD(type, field)	SYM_##type##_FIELD_##field,
160+# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
161 # define DB_SYMBOL(name)		SYM_##name,
162 # define DB_FUNCTION(name)		SYM_##name,
163 # define DB_VARIABLE(name)		SYM_##name, SYM_DESC_##name,
164 # include "structs.def"
165 # undef DB_STRUCT
166 # undef DB_STRUCT_FIELD
167+# undef DB_STRUCT_FLEXIBLE_ARRAY
168 # undef DB_SYMBOL
169 # undef DB_FUNCTION
170 # undef DB_VARIABLE
171@@ -90,6 +92,7 @@ struct td_thragent
172   uint32_t ta_sizeof_##type;
173 # define DB_STRUCT_FIELD(type, field) \
174   db_desc_t ta_field_##type##_##field;
175+# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
176 # define DB_SYMBOL(name) \
177   psaddr_t ta_addr_##name;
178 # define DB_FUNCTION(name) \
179@@ -100,6 +103,7 @@ struct td_thragent
180 # include "structs.def"
181 # undef DB_STRUCT
182 # undef DB_STRUCT_FIELD
183+# undef DB_STRUCT_FLEXIBLE_ARRAY
184 # undef DB_FUNCTION
185 # undef DB_SYMBOL
186 # undef DB_VARIABLE
187diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
188index 95dc8751..ef7d0e28 100644
189--- a/sysdeps/generic/ldsodefs.h
190+++ b/sysdeps/generic/ldsodefs.h
191@@ -408,7 +408,7 @@ struct rtld_global
192     {
193       size_t gen;
194       struct link_map *map;
195-    } slotinfo[0];
196+    } slotinfo[];
197   } *_dl_tls_dtv_slotinfo_list;
198   /* Number of modules in the static TLS block.  */
199   EXTERN size_t _dl_tls_static_nelem;
200--
2012.20.1
202
203