]>
Commit | Line | Data |
---|---|---|
3fb55878 UD |
1 | /* Thread-local storage handling in the ELF dynamic linker. Generic version. |
2 | Copyright (C) 2002 Free Software Foundation, Inc. | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <assert.h> | |
aed283dd | 21 | #include <signal.h> |
a52d1562 | 22 | #include <stdlib.h> |
aed283dd UD |
23 | #include <unistd.h> |
24 | #include <sys/param.h> | |
3fb55878 | 25 | |
aed283dd | 26 | #include <abort-instr.h> |
d555194c | 27 | #include <tls.h> |
3fb55878 UD |
28 | |
29 | /* We don't need any of this if TLS is not supported. */ | |
30 | #ifdef USE_TLS | |
31 | ||
fc093be1 UD |
32 | # include <dl-tls.h> |
33 | # include <ldsodefs.h> | |
d4468ab7 | 34 | |
3fb55878 | 35 | /* Value used for dtv entries for which the allocation is delayed. */ |
aed283dd UD |
36 | # define TLS_DTV_UNALLOCATED ((void *) -1l) |
37 | ||
38 | ||
39 | /* Out-of-memory handler. */ | |
fc093be1 | 40 | # ifdef SHARED |
aed283dd UD |
41 | static void |
42 | __attribute__ ((__noreturn__)) | |
43 | oom (void) | |
44 | { | |
45 | static const char msg[] = "\ | |
46 | cannot allocate memory for thread-local data: ABORT\n"; | |
47 | ||
48 | __libc_write (STDERR_FILENO, msg, sizeof (msg) - 1); | |
49 | ||
50 | /* Kill ourself. */ | |
51 | __kill (__getpid (), SIGKILL); | |
52 | ||
53 | /* Just in case something goes wrong with the kill. */ | |
54 | while (1) | |
55 | { | |
fc093be1 | 56 | # ifdef ABORT_INSTRUCTION |
aed283dd | 57 | ABORT_INSTRUCTION; |
fc093be1 | 58 | # endif |
aed283dd UD |
59 | } |
60 | } | |
fc093be1 | 61 | # endif |
aed283dd | 62 | |
3fb55878 UD |
63 | |
64 | ||
65 | size_t | |
66 | internal_function | |
67 | _dl_next_tls_modid (void) | |
68 | { | |
69 | size_t result; | |
70 | ||
71 | if (__builtin_expect (GL(dl_tls_dtv_gaps), false)) | |
72 | { | |
aed283dd UD |
73 | size_t disp = 0; |
74 | struct dtv_slotinfo_list *runp = GL(dl_tls_dtv_slotinfo_list); | |
75 | ||
76 | /* Note that this branch will never be executed during program | |
77 | start since there are no gaps at that time. Therefore it | |
78 | does not matter that the dl_tls_dtv_slotinfo is not allocated | |
79 | yet when the function is called for the first times. */ | |
fc093be1 UD |
80 | result = GL(dl_tls_static_nelem) + 1; |
81 | /* If the following would not be true we mustn't have assumed | |
82 | there is a gap. */ | |
83 | assert (result <= GL(dl_tls_max_dtv_idx)); | |
3fb55878 UD |
84 | do |
85 | { | |
aed283dd | 86 | while (result - disp < runp->len) |
fc093be1 UD |
87 | { |
88 | if (runp->slotinfo[result - disp].map == NULL) | |
89 | break; | |
3fb55878 | 90 | |
fc093be1 UD |
91 | ++result; |
92 | assert (result <= GL(dl_tls_max_dtv_idx) + 1); | |
93 | } | |
aed283dd UD |
94 | |
95 | if (result - disp < runp->len) | |
3fb55878 | 96 | break; |
aed283dd UD |
97 | |
98 | disp += runp->len; | |
99 | } | |
100 | while ((runp = runp->next) != NULL); | |
101 | ||
fc093be1 | 102 | if (result >= GL(dl_tls_max_dtv_idx)) |
aed283dd UD |
103 | { |
104 | /* The new index must indeed be exactly one higher than the | |
105 | previous high. */ | |
fc093be1 | 106 | assert (result == GL(dl_tls_max_dtv_idx)); |
aed283dd UD |
107 | |
108 | /* There is no gap anymore. */ | |
109 | GL(dl_tls_dtv_gaps) = false; | |
110 | ||
111 | goto nogaps; | |
112 | } | |
3fb55878 UD |
113 | } |
114 | else | |
aed283dd UD |
115 | { |
116 | /* No gaps, allocate a new entry. */ | |
117 | nogaps: | |
118 | result = ++GL(dl_tls_max_dtv_idx); | |
119 | } | |
3fb55878 UD |
120 | |
121 | return result; | |
122 | } | |
123 | ||
124 | ||
125 | void | |
126 | internal_function | |
aed283dd | 127 | _dl_determine_tlsoffset (void) |
3fb55878 | 128 | { |
aed283dd UD |
129 | struct dtv_slotinfo *slotinfo; |
130 | size_t max_align = __alignof__ (void *); | |
3fb55878 | 131 | size_t offset; |
aed283dd | 132 | size_t cnt; |
3fb55878 | 133 | |
aed283dd UD |
134 | /* The first element of the dtv slot info list is allocated. */ |
135 | assert (GL(dl_tls_dtv_slotinfo_list) != NULL); | |
136 | /* There is at this point only one element in the | |
137 | dl_tls_dtv_slotinfo_list list. */ | |
138 | assert (GL(dl_tls_dtv_slotinfo_list)->next == NULL); | |
a52d1562 | 139 | |
3fb55878 UD |
140 | # if TLS_TCB_AT_TP |
141 | /* We simply start with zero. */ | |
142 | offset = 0; | |
143 | ||
aed283dd UD |
144 | slotinfo = GL(dl_tls_dtv_slotinfo_list)->slotinfo; |
145 | for (cnt = 1; slotinfo[cnt].map != NULL; ++cnt) | |
3fb55878 | 146 | { |
aed283dd UD |
147 | assert (cnt < GL(dl_tls_dtv_slotinfo_list)->len); |
148 | ||
149 | max_align = MAX (max_align, slotinfo[cnt].map->l_tls_align); | |
3fb55878 UD |
150 | |
151 | /* Compute the offset of the next TLS block. */ | |
aed283dd UD |
152 | offset = roundup (offset + slotinfo[cnt].map->l_tls_blocksize, |
153 | slotinfo[cnt].map->l_tls_align); | |
3fb55878 UD |
154 | |
155 | /* XXX For some architectures we perhaps should store the | |
156 | negative offset. */ | |
aed283dd | 157 | slotinfo[cnt].map->l_tls_offset = offset; |
3fb55878 | 158 | } |
8d4b5a8a UD |
159 | |
160 | /* The thread descriptor (pointed to by the thread pointer) has its | |
161 | own alignment requirement. Adjust the static TLS size | |
cd30b01e | 162 | and TLS offsets appropriately. */ |
b123d06e UD |
163 | // XXX How to deal with this. We cannot simply add zero bytes |
164 | // XXX after the first (closest to the TCB) TLS block since this | |
165 | // XXX would invalidate the offsets the linker creates for the LE | |
166 | // XXX model. | |
cd30b01e UD |
167 | |
168 | GL(dl_tls_static_size) = offset + TLS_TCB_SIZE; | |
3fb55878 | 169 | # elif TLS_DTV_AT_TP |
aed283dd | 170 | /* The TLS blocks start right after the TCB. */ |
3fb55878 | 171 | offset = TLS_TCB_SIZE; |
3fb55878 | 172 | |
aed283dd UD |
173 | /* The first block starts right after the TCB. */ |
174 | slotinfo = GL(dl_tls_dtv_slotinfo_list)->slotinfo; | |
175 | if (slotinfo[1].map != NULL) | |
3fb55878 | 176 | { |
aed283dd | 177 | size_t prev_size |
3fb55878 | 178 | |
aed283dd UD |
179 | offset = roundup (offset, slotinfo[1].map->l_tls_align); |
180 | slotinfo[1].map->l_tls_offset = offset; | |
181 | max_align = slotinfo[1].map->l_tls_align; | |
182 | prev_size = slotinfo[1].map->l_tls_blocksize; | |
3fb55878 | 183 | |
aed283dd UD |
184 | for (cnt = 2; slotinfo[cnt].map != NULL; ++cnt) |
185 | { | |
186 | assert (cnt < GL(dl_tls_dtv_slotinfo_list)->len); | |
187 | ||
188 | max_align = MAX (max_align, slotinfo[cnt].map->l_tls_align); | |
189 | ||
190 | /* Compute the offset of the next TLS block. */ | |
191 | offset = roundup (offset + prev_size, | |
192 | slotinfo[cnt].map->l_tls_align); | |
193 | ||
194 | /* XXX For some architectures we perhaps should store the | |
195 | negative offset. */ | |
196 | slotinfo[cnt].map->l_tls_offset = offset; | |
197 | ||
198 | prev_size = slotinfo[cnt].map->l_tls_blocksize; | |
199 | } | |
cd30b01e | 200 | |
aed283dd | 201 | offset += prev_size; |
3fb55878 | 202 | } |
cd30b01e | 203 | |
aed283dd | 204 | GL(dl_tls_static_size) = offset; |
3fb55878 UD |
205 | # else |
206 | # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" | |
207 | # endif | |
cd30b01e UD |
208 | |
209 | /* The alignment requirement for the static TLS block. */ | |
210 | GL(dl_tls_static_align) = MAX (TLS_TCB_ALIGN, max_align); | |
3fb55878 UD |
211 | } |
212 | ||
213 | ||
a52d1562 UD |
214 | void * |
215 | internal_function | |
216 | _dl_allocate_tls (void) | |
217 | { | |
218 | void *result; | |
219 | dtv_t *dtv; | |
aed283dd | 220 | size_t dtv_length; |
a52d1562 UD |
221 | |
222 | /* Allocate a correctly aligned chunk of memory. */ | |
223 | /* XXX For now */ | |
224 | assert (GL(dl_tls_static_align) <= GL(dl_pagesize)); | |
aed283dd UD |
225 | # ifdef MAP_ANON |
226 | # define _dl_zerofd (-1) | |
227 | # else | |
228 | # define _dl_zerofd GL(dl_zerofd) | |
a52d1562 UD |
229 | if ((dl_zerofd) == -1) |
230 | GL(dl_zerofd) = _dl_sysdep_open_zero_fill (); | |
aed283dd UD |
231 | # define MAP_ANON 0 |
232 | # endif | |
a52d1562 UD |
233 | result = __mmap (0, GL(dl_tls_static_size), PROT_READ|PROT_WRITE, |
234 | MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); | |
235 | ||
aed283dd UD |
236 | /* We allocate a few more elements in the dtv than are needed for the |
237 | initial set of modules. This should avoid in most cases expansions | |
238 | of the dtv. */ | |
239 | dtv_length = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS; | |
240 | dtv = (dtv_t *) malloc ((dtv_length + 2) * sizeof (dtv_t)); | |
a52d1562 UD |
241 | if (result != MAP_FAILED && dtv != NULL) |
242 | { | |
aed283dd UD |
243 | struct dtv_slotinfo_list *listp; |
244 | bool first_block = true; | |
245 | size_t total = 0; | |
a52d1562 UD |
246 | |
247 | # if TLS_TCB_AT_TP | |
248 | /* The TCB follows the TLS blocks. */ | |
249 | result = (char *) result + GL(dl_tls_static_size) - TLS_TCB_SIZE; | |
250 | # endif | |
251 | ||
aed283dd UD |
252 | /* This is the initial length of the dtv. */ |
253 | dtv[0].counter = dtv_length; | |
254 | /* Fill in the generation number. */ | |
255 | dtv[1].counter = GL(dl_tls_generation) = 0; | |
256 | /* Initialize all of the rest of the dtv with zero to indicate | |
257 | nothing there. */ | |
258 | memset (dtv + 2, '\0', dtv_length * sizeof (dtv_t)); | |
259 | ||
260 | /* We have to look prepare the dtv for all currently loaded | |
261 | modules using TLS. For those which are dynamically loaded we | |
262 | add the values indicating deferred allocation. */ | |
263 | listp = GL(dl_tls_dtv_slotinfo_list); | |
264 | while (1) | |
a52d1562 | 265 | { |
aed283dd UD |
266 | size_t cnt; |
267 | ||
268 | for (cnt = first_block ? 1 : 0; cnt < listp->len; ++cnt) | |
a52d1562 | 269 | { |
aed283dd UD |
270 | struct link_map *map; |
271 | void *dest; | |
272 | ||
273 | /* Check for the total number of used slots. */ | |
274 | if (total + cnt >= GL(dl_tls_max_dtv_idx)) | |
275 | break; | |
276 | ||
277 | map = listp->slotinfo[cnt].map; | |
278 | if (map == NULL) | |
279 | /* Unused entry. */ | |
280 | continue; | |
281 | ||
282 | if (map->l_type == lt_loaded) | |
283 | { | |
284 | /* For dynamically loaded modules we simply store | |
285 | the value indicating deferred allocation. */ | |
286 | dtv[1 + map->l_tls_modid].pointer = TLS_DTV_UNALLOCATED; | |
287 | continue; | |
288 | } | |
289 | ||
290 | assert (map->l_tls_modid == cnt); | |
291 | assert (map->l_tls_blocksize >= map->l_tls_initimage_size); | |
a52d1562 | 292 | # if TLS_TCB_AT_TP |
aed283dd UD |
293 | assert (map->l_tls_offset >= map->l_tls_blocksize); |
294 | dest = (char *) result - map->l_tls_offset; | |
a52d1562 | 295 | # elif TLS_DTV_AT_TP |
aed283dd | 296 | dest = (char *) result + map->l_tls_offset; |
a52d1562 UD |
297 | # else |
298 | # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" | |
299 | # endif | |
300 | ||
aed283dd UD |
301 | /* We don't have to clear the BSS part of the TLS block |
302 | since mmap is used to allocate the memory which | |
303 | guarantees it is initialized to zero. */ | |
304 | dtv[1 + cnt].pointer = memcpy (dest, map->l_tls_initimage, | |
305 | map->l_tls_initimage_size); | |
a52d1562 | 306 | } |
aed283dd UD |
307 | |
308 | total += cnt; | |
309 | if (total >= GL(dl_tls_max_dtv_idx)) | |
310 | break; | |
311 | ||
312 | listp = listp->next; | |
313 | assert (listp != NULL); | |
a52d1562 UD |
314 | } |
315 | ||
316 | /* Add the dtv to the thread data structures. */ | |
317 | INSTALL_DTV (result, dtv); | |
318 | } | |
319 | else if (result != NULL) | |
320 | { | |
321 | free (result); | |
322 | result = NULL; | |
323 | } | |
324 | ||
325 | return result; | |
326 | } | |
e4138261 UD |
327 | INTDEF(_dl_allocate_tls) |
328 | ||
329 | ||
330 | void | |
331 | internal_function | |
332 | _dl_deallocate_tls (void *tcb) | |
333 | { | |
334 | dtv_t *dtv = GET_DTV (tcb); | |
335 | ||
336 | /* The array starts with dtv[-1]. */ | |
337 | free (dtv - 1); | |
338 | ||
339 | munmap (tcb, GL(dl_tls_static_size)); | |
340 | } | |
341 | ||
a52d1562 UD |
342 | |
343 | ||
aed283dd | 344 | # ifdef SHARED |
3fb55878 UD |
345 | /* The __tls_get_addr function has two basic forms which differ in the |
346 | arguments. The IA-64 form takes two parameters, the module ID and | |
347 | offset. The form used, among others, on IA-32 takes a reference to | |
348 | a special structure which contain the same information. The second | |
349 | form seems to be more often used (in the moment) so we default to | |
350 | it. Users of the IA-64 form have to provide adequate definitions | |
351 | of the following macros. */ | |
aed283dd UD |
352 | # ifndef GET_ADDR_ARGS |
353 | # define GET_ADDR_ARGS tls_index *ti | |
354 | # endif | |
355 | # ifndef GET_ADDR_MODULE | |
356 | # define GET_ADDR_MODULE ti->ti_module | |
357 | # endif | |
358 | # ifndef GET_ADDR_OFFSET | |
359 | # define GET_ADDR_OFFSET ti->ti_offset | |
360 | # endif | |
361 | /* Systems which do not have tls_index also probably have to define | |
362 | DONT_USE_TLS_INDEX. */ | |
363 | ||
364 | # ifndef __TLS_GET_ADDR | |
365 | # define __TLS_GET_ADDR __tls_get_addr | |
366 | # endif | |
367 | ||
368 | ||
369 | /* Return the symbol address given the map of the module it is in and | |
370 | the symbol record. This is used in dl-sym.c. */ | |
371 | void * | |
372 | internal_function | |
373 | _dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref) | |
374 | { | |
375 | # ifndef DONT_USE_TLS_INDEX | |
376 | tls_index tmp = | |
377 | { | |
378 | .ti_module = map->l_tls_modid, | |
379 | .ti_offset = ref->st_value | |
380 | }; | |
381 | ||
382 | return __TLS_GET_ADDR (&tmp); | |
383 | # else | |
384 | return __TLS_GET_ADDR (map->l_tls_modid, ref->st_value); | |
385 | # endif | |
386 | } | |
387 | ||
388 | ||
389 | static void * | |
390 | allocate_and_init (struct link_map *map) | |
391 | { | |
392 | void *newp; | |
393 | ||
394 | newp = __libc_memalign (map->l_tls_align, map->l_tls_blocksize); | |
395 | if (newp == NULL) | |
396 | oom (); | |
3fb55878 | 397 | |
aed283dd UD |
398 | /* Initialize the memory. */ |
399 | memset (__mempcpy (newp, map->l_tls_initimage, map->l_tls_initimage_size), | |
400 | '\0', map->l_tls_blocksize - map->l_tls_initimage_size); | |
3fb55878 | 401 | |
aed283dd UD |
402 | return newp; |
403 | } | |
404 | ||
405 | ||
406 | /* The generic dynamic and local dynamic model cannot be used in | |
407 | statically linked applications. */ | |
3fb55878 UD |
408 | void * |
409 | __tls_get_addr (GET_ADDR_ARGS) | |
410 | { | |
411 | dtv_t *dtv = THREAD_DTV (); | |
aed283dd UD |
412 | struct link_map *the_map = NULL; |
413 | void *p; | |
414 | ||
415 | if (__builtin_expect (dtv[0].counter != GL(dl_tls_generation), 0)) | |
416 | { | |
417 | struct dtv_slotinfo_list *listp; | |
418 | size_t idx; | |
419 | ||
420 | /* The global dl_tls_dtv_slotinfo array contains for each module | |
421 | index the generation counter current when the entry was | |
422 | created. This array never shrinks so that all module indices | |
423 | which were valid at some time can be used to access it. | |
424 | Before the first use of a new module index in this function | |
425 | the array was extended appropriately. Access also does not | |
426 | have to be guarded against modifications of the array. It is | |
427 | assumed that pointer-size values can be read atomically even | |
428 | in SMP environments. It is possible that other threads at | |
429 | the same time dynamically load code and therefore add to the | |
430 | slotinfo list. This is a problem since we must not pick up | |
431 | any information about incomplete work. The solution to this | |
432 | is to ignore all dtv slots which were created after the one | |
433 | we are currently interested. We know that dynamic loading | |
434 | for this module is completed and this is the last load | |
435 | operation we know finished. */ | |
436 | idx = GET_ADDR_MODULE; | |
437 | listp = GL(dl_tls_dtv_slotinfo_list); | |
438 | while (idx >= listp->len) | |
439 | { | |
440 | idx -= listp->len; | |
441 | listp = listp->next; | |
442 | } | |
3fb55878 | 443 | |
aed283dd UD |
444 | if (dtv[0].counter < listp->slotinfo[idx].gen) |
445 | { | |
446 | /* The generation counter for the slot is higher than what | |
447 | the current dtv implements. We have to update the whole | |
448 | dtv but only those entries with a generation counter <= | |
449 | the one for the entry we need. */ | |
450 | size_t new_gen = listp->slotinfo[idx].gen; | |
451 | size_t total = 0; | |
452 | ||
453 | /* We have to look through the entire dtv slotinfo list. */ | |
454 | listp = GL(dl_tls_dtv_slotinfo_list); | |
455 | do | |
456 | { | |
457 | size_t cnt; | |
458 | ||
459 | for (cnt = total = 0 ? 1 : 0; cnt < listp->len; ++cnt) | |
460 | { | |
461 | size_t gen = listp->slotinfo[cnt].gen; | |
462 | struct link_map *map; | |
463 | size_t modid; | |
464 | ||
465 | if (gen > new_gen) | |
466 | /* This is a slot for a generation younger than | |
467 | the one we are handling now. It might be | |
468 | incompletely set up so ignore it. */ | |
469 | continue; | |
470 | ||
471 | /* If the entry is older than the current dtv layout | |
472 | we know we don't have to handle it. */ | |
473 | if (gen <= dtv[0].counter) | |
474 | continue; | |
475 | ||
476 | /* If there is no map this means the entry is empty. */ | |
477 | map = listp->slotinfo[cnt].map; | |
478 | if (map == NULL) | |
479 | { | |
480 | /* If this modid was used at some point the memory | |
481 | might still be allocated. */ | |
482 | if (dtv[total + cnt].pointer != TLS_DTV_UNALLOCATED) | |
483 | free (dtv[total + cnt].pointer); | |
484 | ||
485 | continue; | |
486 | } | |
487 | ||
488 | /* Check whether the current dtv array is large enough. */ | |
489 | modid = map->l_tls_modid; | |
490 | assert (total + cnt == modid); | |
491 | if (dtv[-1].counter < modid) | |
492 | { | |
493 | /* Reallocate the dtv. */ | |
494 | dtv_t *newp; | |
495 | size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS; | |
496 | size_t oldsize = dtv[-1].counter; | |
497 | ||
498 | assert (map->l_tls_modid <= newsize); | |
499 | ||
500 | newp = (dtv_t *) realloc (&dtv[-1], | |
501 | (2 + newsize) | |
502 | * sizeof (dtv_t)); | |
503 | if (newp == NULL) | |
504 | oom (); | |
505 | ||
506 | newp[0].counter = newsize; | |
507 | ||
508 | /* Clear the newly allocate part. */ | |
509 | memset (newp + 2 + oldsize, '\0', | |
510 | (newsize - oldsize) * sizeof (dtv_t)); | |
511 | ||
512 | /* Point dtv to the generation counter. */ | |
513 | dtv = &newp[1]; | |
514 | ||
515 | /* Install this new dtv in the thread data | |
516 | structures. */ | |
517 | INSTALL_NEW_DTV (dtv); | |
518 | } | |
519 | ||
520 | /* If there is currently memory allocate for this | |
521 | dtv entry free it. */ | |
522 | /* XXX Ideally we will at some point create a memory | |
523 | pool. */ | |
524 | if (dtv[modid].pointer != TLS_DTV_UNALLOCATED) | |
525 | /* Note that free is called for NULL is well. We | |
526 | deallocate even if it is this dtv entry we are | |
527 | supposed to load. The reason is that we call | |
528 | memalign and not malloc. */ | |
529 | free (dtv[modid].pointer); | |
530 | ||
531 | /* This module is loaded dynamically- We defer | |
532 | memory allocation. */ | |
533 | dtv[modid].pointer = TLS_DTV_UNALLOCATED; | |
534 | ||
535 | if (modid == GET_ADDR_MODULE) | |
536 | the_map = map; | |
537 | } | |
538 | ||
539 | total += listp->len; | |
540 | } | |
541 | while ((listp = listp->next) != NULL); | |
3fb55878 | 542 | |
aed283dd UD |
543 | /* This will be the new maximum generation counter. */ |
544 | dtv[0].counter = new_gen; | |
545 | } | |
546 | } | |
547 | ||
548 | p = dtv[GET_ADDR_MODULE].pointer; | |
549 | ||
550 | if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0)) | |
551 | { | |
552 | /* The allocation was deferred. Do it now. */ | |
553 | if (the_map == NULL) | |
554 | { | |
555 | /* Find the link map for this module. */ | |
556 | size_t idx = GET_ADDR_MODULE; | |
557 | struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list); | |
558 | ||
559 | while (idx >= listp->len) | |
560 | { | |
561 | idx -= listp->len; | |
562 | listp = listp->next; | |
563 | } | |
564 | ||
565 | the_map = listp->slotinfo[idx].map; | |
566 | } | |
567 | ||
568 | p = dtv[GET_ADDR_MODULE].pointer = allocate_and_init (the_map); | |
569 | } | |
570 | ||
571 | return (char *) p + GET_ADDR_OFFSET; | |
3fb55878 | 572 | } |
aed283dd | 573 | # endif |
3fb55878 UD |
574 | |
575 | #endif /* use TLS */ |