Print this page
10366 ld(1) should support GNU-style linker sets
10581 ld(1) should know kernel modules are a thing
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/libld/common/relocate.c
+++ new/usr/src/cmd/sgs/libld/common/relocate.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 1988 AT&T
24 24 * All Rights Reserved
25 25 *
26 26 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
27 27 */
28 28
29 29 /*
30 30 * set-up for relocations
31 31 */
32 32
33 33 #define ELF_TARGET_AMD64
34 34 #define ELF_TARGET_SPARC
35 35
36 36 #include <string.h>
37 37 #include <stdio.h>
38 38 #include <alloca.h>
39 39 #include <debug.h>
40 40 #include "msg.h"
41 41 #include "_libld.h"
42 42
43 43 /*
44 44 * Set up the relocation table flag test macros so that they use the
45 45 * relocation table for the current target machine.
46 46 */
47 47 #define IS_PLT(X) RELTAB_IS_PLT(X, ld_targ.t_mr.mr_reloc_table)
48 48 #define IS_GOT_RELATIVE(X) \
49 49 RELTAB_IS_GOT_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
50 50 #define IS_GOT_PC(X) RELTAB_IS_GOT_PC(X, ld_targ.t_mr.mr_reloc_table)
51 51 #define IS_GOTPCREL(X) RELTAB_IS_GOTPCREL(X, ld_targ.t_mr.mr_reloc_table)
52 52 #define IS_GOT_BASED(X) RELTAB_IS_GOT_BASED(X, ld_targ.t_mr.mr_reloc_table)
53 53 #define IS_GOT_OPINS(X) RELTAB_IS_GOT_OPINS(X, ld_targ.t_mr.mr_reloc_table)
54 54 #define IS_GOT_REQUIRED(X) \
55 55 RELTAB_IS_GOT_REQUIRED(X, ld_targ.t_mr.mr_reloc_table)
56 56 #define IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
57 57 #define IS_ADD_RELATIVE(X) \
58 58 RELTAB_IS_ADD_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
59 59 #define IS_REGISTER(X) RELTAB_IS_REGISTER(X, ld_targ.t_mr.mr_reloc_table)
60 60 #define IS_NOTSUP(X) RELTAB_IS_NOTSUP(X, ld_targ.t_mr.mr_reloc_table)
61 61 #define IS_SEG_RELATIVE(X) \
62 62 RELTAB_IS_SEG_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
63 63 #define IS_EXTOFFSET(X) RELTAB_IS_EXTOFFSET(X, ld_targ.t_mr.mr_reloc_table)
64 64 #define IS_SEC_RELATIVE(X) \
65 65 RELTAB_IS_SEC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
66 66 #define IS_TLS_INS(X) RELTAB_IS_TLS_INS(X, ld_targ.t_mr.mr_reloc_table)
67 67 #define IS_TLS_GD(X) RELTAB_IS_TLS_GD(X, ld_targ.t_mr.mr_reloc_table)
68 68 #define IS_TLS_LD(X) RELTAB_IS_TLS_LD(X, ld_targ.t_mr.mr_reloc_table)
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
69 69 #define IS_TLS_IE(X) RELTAB_IS_TLS_IE(X, ld_targ.t_mr.mr_reloc_table)
70 70 #define IS_TLS_LE(X) RELTAB_IS_TLS_LE(X, ld_targ.t_mr.mr_reloc_table)
71 71 #define IS_LOCALBND(X) RELTAB_IS_LOCALBND(X, ld_targ.t_mr.mr_reloc_table)
72 72 #define IS_SIZE(X) RELTAB_IS_SIZE(X, ld_targ.t_mr.mr_reloc_table)
73 73
74 74 /*
75 75 * Structure to hold copy relocation items.
76 76 */
77 77 typedef struct copy_rel {
78 78 Sym_desc *c_sdp; /* symbol descriptor to be copied */
79 - Addr c_val; /* original symbol value */
79 + Addr c_val; /* original symbol value */
80 80 } Copy_rel;
81 81
82 82 /*
83 83 * For each copy relocation symbol, determine if the symbol is:
84 - * 1) to be *disp* relocated at runtime
84 + * 1) to be *disp* relocated at runtime
85 85 * 2) a reference symbol for *disp* relocation
86 86 * 3) possibly *disp* relocated at ld time.
87 87 *
88 88 * The first and the second are serious errors.
89 89 */
90 90 static void
91 91 is_disp_copied(Ofl_desc *ofl, Copy_rel *crp)
92 92 {
93 93 Ifl_desc *ifl = crp->c_sdp->sd_file;
94 94 Sym_desc *sdp = crp->c_sdp;
95 95 Addr symaddr = crp->c_val;
96 96 Is_desc *irel;
97 97 Aliste idx;
98 98 Conv_inv_buf_t inv_buf;
99 99
100 100 /*
101 101 * This symbol may not be *disp* relocated at run time, but could
102 102 * already have been *disp* relocated when the shared object was
103 103 * created. Warn the user.
104 104 */
105 105 if ((ifl->ifl_flags & FLG_IF_DISPDONE) &&
106 106 (ofl->ofl_flags & FLG_OF_VERBOSE))
107 107 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
108 108 conv_reloc_type(ifl->ifl_ehdr->e_machine,
109 109 ld_targ.t_m.m_r_copy, 0, &inv_buf),
110 110 ifl->ifl_name, demangle(sdp->sd_name));
111 111
112 112 if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0)
113 113 return;
114 114
115 115 /*
116 116 * Traverse the input relocation sections.
117 117 */
118 118 for (APLIST_TRAVERSE(ifl->ifl_relsect, idx, irel)) {
119 119 Sym_desc *rsdp;
120 120 Is_desc *trel;
121 121 Rel *rend, *reloc;
122 122 Xword rsize, entsize;
123 123
124 124 trel = ifl->ifl_isdesc[irel->is_shdr->sh_info];
125 125 rsize = irel->is_shdr->sh_size;
126 126 entsize = irel->is_shdr->sh_entsize;
127 127 reloc = (Rel *)irel->is_indata->d_buf;
128 128
129 129 /*
130 130 * Decide entry size
131 131 */
132 132 if ((entsize == 0) || (entsize > rsize)) {
133 133 if (irel->is_shdr->sh_type == SHT_RELA)
134 134 entsize = sizeof (Rela);
135 135 else
136 136 entsize = sizeof (Rel);
137 137 }
138 138
139 139 /*
140 140 * Traverse the relocation entries.
141 141 */
142 142 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
143 143 reloc < rend;
144 144 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
145 145 const char *str;
146 146 Word rstndx;
147 147
148 148 if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info,
149 149 ld_targ.t_m.m_mach)) == 0)
150 150 continue;
151 151
152 152 /*
153 153 * Determine if symbol is referenced from a relocation.
154 154 */
155 155 rstndx = (Word) ELF_R_SYM(reloc->r_info);
156 156 rsdp = ifl->ifl_oldndx[rstndx];
157 157 if (rsdp == sdp) {
158 158 if ((str = demangle(rsdp->sd_name)) !=
159 159 rsdp->sd_name) {
160 160 char *_str = alloca(strlen(str) + 1);
161 161 (void) strcpy(_str, str);
162 162 str = (const char *)_str;
163 163 }
164 164 ld_eprintf(ofl, ERR_WARNING,
165 165 MSG_INTL(MSG_REL_DISPREL1),
166 166 conv_reloc_type(ifl->ifl_ehdr->e_machine,
167 167 (uint_t)ELF_R_TYPE(reloc->r_info,
168 168 ld_targ.t_m.m_mach),
169 169 0, &inv_buf), ifl->ifl_name, str,
170 170 MSG_INTL(MSG_STR_UNKNOWN),
171 171 EC_XWORD(reloc->r_offset),
172 172 demangle(sdp->sd_name));
173 173 }
174 174
175 175 /*
176 176 * Determine whether the relocation entry is relocating
177 177 * this symbol.
178 178 */
179 179 if ((sdp->sd_isc != trel) ||
180 180 (reloc->r_offset < symaddr) ||
181 181 (reloc->r_offset >=
182 182 (symaddr + sdp->sd_sym->st_size)))
183 183 continue;
184 184
185 185 /*
186 186 * This symbol is truely *disp* relocated, so should
187 187 * really be fixed by user.
188 188 */
189 189 if ((str = demangle(sdp->sd_name)) != sdp->sd_name) {
190 190 char *_str = alloca(strlen(str) + 1);
191 191 (void) strcpy(_str, str);
192 192 str = (const char *)_str;
193 193 }
194 194 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
195 195 conv_reloc_type(ifl->ifl_ehdr->e_machine,
196 196 (uint_t)ELF_R_TYPE(reloc->r_info,
197 197 ld_targ.t_m.m_mach), 0, &inv_buf),
198 198 ifl->ifl_name, demangle(rsdp->sd_name), str,
199 199 EC_XWORD(reloc->r_offset), str);
200 200 }
201 201 }
202 202 }
203 203
204 204 /*
205 205 * The number of symbols provided by some objects can be very large. Use a
206 206 * binary search to match the associated value to a symbol table entry.
207 207 */
208 208 static int
209 209 disp_bsearch(const void *key, const void *array)
210 210 {
211 211 Addr kvalue, avalue;
212 212 Ssv_desc *ssvp = (Ssv_desc *)array;
213 213
214 214 kvalue = *((Addr *)key);
215 215 avalue = ssvp->ssv_value;
216 216
217 217 if (avalue > kvalue)
218 218 return (-1);
219 219 if ((avalue < kvalue) &&
220 220 ((avalue + ssvp->ssv_sdp->sd_sym->st_size) <= kvalue))
221 221 return (1);
222 222 return (0);
223 223 }
224 224
225 225 /*
226 226 * Given a sorted list of symbols, look for a symbol in which the relocation
227 227 * offset falls between the [sym.st_value - sym.st_value + sym.st_size]. Since
228 228 * the symbol list is maintained in sorted order, we can bail once the
229 229 * relocation offset becomes less than the symbol values. The symbol is
230 230 * returned for use in error diagnostics.
231 231 */
232 232 static Sym_desc *
233 233 disp_scansyms(Ifl_desc * ifl, Rel_desc *rld, Boolean rlocal, int inspect,
234 234 Ofl_desc *ofl)
235 235 {
236 236 Sym_desc *tsdp, *rsdp;
237 237 Sym *rsym, *tsym;
238 238 Ssv_desc *ssvp;
239 239 uchar_t rtype, ttype;
240 240 Addr value;
241 241
242 242 /*
243 243 * Sorted symbol values have been uniquified by adding their associated
244 244 * section offset. Uniquify the relocation offset by adding its
245 245 * associated section offset, and search for the symbol.
246 246 */
247 247 value = rld->rel_roffset;
248 248 if (rld->rel_isdesc->is_shdr)
249 249 value += rld->rel_isdesc->is_shdr->sh_offset;
250 250
251 251 if ((ssvp = bsearch((void *)&value, (void *)ifl->ifl_sortsyms,
252 252 ifl->ifl_sortcnt, sizeof (Ssv_desc), &disp_bsearch)) != 0)
253 253 tsdp = ssvp->ssv_sdp;
254 254 else
255 255 tsdp = 0;
256 256
257 257 if (inspect)
258 258 return (tsdp);
259 259
260 260 /*
261 261 * Determine the relocation reference symbol and its type.
262 262 */
263 263 rsdp = rld->rel_sym;
264 264 rsym = rsdp->sd_sym;
265 265 rtype = ELF_ST_TYPE(rsym->st_info);
266 266
267 267 /*
268 268 * If there is no target symbol to match the relocation offset, then the
269 269 * offset is effectively local data. If the relocation symbol is global
270 270 * data we have a potential for this displacement relocation to be
271 271 * invalidated should the global symbol be copied.
272 272 */
273 273 if (tsdp == 0) {
274 274 if ((rlocal == TRUE) ||
275 275 ((rtype != STT_OBJECT) && (rtype != STT_SECTION)))
276 276 return (tsdp);
277 277 } else {
278 278 /*
279 279 * If both symbols are local, no copy relocations can occur to
280 280 * either symbol. Note, this test is very similar to the test
281 281 * used in ld_sym_adjust_vis().
282 282 */
283 283 if ((rlocal == TRUE) && (SYM_IS_HIDDEN(tsdp) ||
284 284 (ELF_ST_BIND(tsdp->sd_sym->st_info) != STB_GLOBAL) ||
285 285 ((ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM)) &&
286 286 ((tsdp->sd_flags & MSK_SY_NOAUTO) == 0))))
287 287 return (tsdp);
288 288
289 289 /*
290 290 * Determine the relocation target symbols type.
291 291 */
292 292 tsym = tsdp->sd_sym;
293 293 ttype = ELF_ST_TYPE(tsym->st_info);
294 294
295 295 /*
296 296 * If the reference symbol is local, and the target isn't a
297 297 * data element, then no copy relocations can occur to either
298 298 * symbol. Note, this catches pc-relative relocations against
299 299 * the _GLOBAL_OFFSET_TABLE_, which is effectively treated as
300 300 * a local symbol.
301 301 */
302 302 if ((rlocal == TRUE) && (ttype != STT_OBJECT) &&
303 303 (ttype != STT_SECTION))
304 304 return (tsdp);
305 305
306 306 /*
307 307 * Finally, one of the symbols must reference a data element.
308 308 */
309 309 if ((rtype != STT_OBJECT) && (rtype != STT_SECTION) &&
310 310 (ttype != STT_OBJECT) && (ttype != STT_SECTION))
311 311 return (tsdp);
312 312 }
313 313
314 314 /*
315 315 * We have two global symbols, at least one of which is a data item.
316 316 * The last case where a displacement relocation can be ignored, is
317 317 * if the reference symbol is included in the target symbol.
318 318 */
319 319 value = rsym->st_value;
320 320 if ((rld->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
321 321 value += rld->rel_raddend;
322 322
323 323 if ((rld->rel_roffset >= value) &&
324 324 (rld->rel_roffset < (value + rsym->st_size)))
325 325 return (tsdp);
326 326
327 327 /*
328 328 * We have a displacement relocation that could be compromised by a
329 329 * copy relocation of one of the associated data items.
330 330 */
331 331 rld->rel_flags |= FLG_REL_DISP;
332 332 return (tsdp);
333 333 }
334 334
335 335 void
336 336 ld_disp_errmsg(const char *msg, Rel_desc *rsp, Ofl_desc *ofl)
337 337 {
338 338 Sym_desc *sdp;
339 339 const char *str;
340 340 Ifl_desc *ifl = rsp->rel_isdesc->is_file;
341 341 Conv_inv_buf_t inv_buf;
342 342
343 343 if ((sdp = disp_scansyms(ifl, rsp, 0, 1, ofl)) != 0)
344 344 str = demangle(sdp->sd_name);
345 345 else
346 346 str = MSG_INTL(MSG_STR_UNKNOWN);
347 347
348 348 ld_eprintf(ofl, ERR_WARNING, msg,
349 349 conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
350 350 0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp), str,
351 351 EC_OFF(rsp->rel_roffset));
352 352 }
353 353
354 354 /*
355 355 * qsort(3C) comparison routine used for the disp_sortsyms().
356 356 */
357 357 static int
358 358 disp_qsort(const void * s1, const void * s2)
359 359 {
360 360 Ssv_desc *ssvp1 = ((Ssv_desc *)s1);
361 361 Ssv_desc *ssvp2 = ((Ssv_desc *)s2);
362 362 Addr val1 = ssvp1->ssv_value;
363 363 Addr val2 = ssvp2->ssv_value;
364 364
365 365 if (val1 > val2)
366 366 return (1);
367 367 if (val1 < val2)
368 368 return (-1);
369 369 return (0);
370 370 }
371 371
372 372 /*
373 373 * Determine whether a displacement relocation is between a local and global
374 374 * symbol pair. One symbol is used to perform the relocation, and the other
375 375 * is the destination offset of the relocation.
376 376 */
377 377 static uintptr_t
378 378 disp_inspect(Ofl_desc *ofl, Rel_desc *rld, Boolean rlocal)
379 379 {
380 380 Is_desc *isp = rld->rel_isdesc;
381 381 Ifl_desc *ifl = rld->rel_isdesc->is_file;
382 382
383 383 /*
384 384 * If the input files symbols haven't been sorted yet, do so.
385 385 */
386 386 if (ifl->ifl_sortsyms == 0) {
387 387 Word ondx, nndx;
388 388
389 389 if ((ifl->ifl_sortsyms = libld_malloc((ifl->ifl_symscnt + 1) *
390 390 sizeof (Ssv_desc))) == 0)
391 391 return (S_ERROR);
392 392
393 393 for (ondx = 0, nndx = 0; ondx < ifl->ifl_symscnt; ondx++) {
394 394 Sym_desc *sdp;
395 395 Addr value;
396 396
397 397 /*
398 398 * As symbol resolution has already occurred, various
399 399 * symbols from this object may have been satisfied
400 400 * from other objects. Only select symbols from this
401 401 * object. For the displacement test, we only really
402 402 * need to observe data definitions, however, later as
403 403 * part of providing warning disgnostics, relating the
404 404 * relocation offset to a symbol is desirable. Thus,
405 405 * collect all symbols that define a memory area.
406 406 */
407 407 if (((sdp = ifl->ifl_oldndx[ondx]) == 0) ||
408 408 (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
409 409 (sdp->sd_sym->st_shndx >= SHN_LORESERVE) ||
410 410 (sdp->sd_ref != REF_REL_NEED) ||
411 411 (sdp->sd_file != ifl) ||
412 412 (sdp->sd_sym->st_size == 0))
413 413 continue;
414 414
415 415 /*
416 416 * As a further optimization for later checking, mark
417 417 * this section if this a global data definition.
418 418 */
419 419 if (sdp->sd_isc && (ondx >= ifl->ifl_locscnt))
420 420 sdp->sd_isc->is_flags |= FLG_IS_GDATADEF;
421 421
422 422 /*
423 423 * Capture the symbol. Within relocatable objects, a
424 424 * symbols value is its offset within its associated
425 425 * section. Add the section offset to this value to
426 426 * uniquify the symbol.
427 427 */
428 428 value = sdp->sd_sym->st_value;
429 429 if (sdp->sd_isc && sdp->sd_isc->is_shdr)
430 430 value += sdp->sd_isc->is_shdr->sh_offset;
431 431
432 432 ifl->ifl_sortsyms[nndx].ssv_value = value;
433 433 ifl->ifl_sortsyms[nndx].ssv_sdp = sdp;
434 434 nndx++;
435 435 }
436 436
437 437 /*
438 438 * Sort the list based on the symbols value (address).
439 439 */
440 440 if ((ifl->ifl_sortcnt = nndx) != 0)
441 441 qsort(ifl->ifl_sortsyms, nndx, sizeof (Ssv_desc),
442 442 &disp_qsort);
443 443 }
444 444
445 445 /*
446 446 * If the reference symbol is local, and the section being relocated
447 447 * contains no global definitions, neither can be the target of a copy
448 448 * relocation.
449 449 */
450 450 if ((rlocal == FALSE) && ((isp->is_flags & FLG_IS_GDATADEF) == 0))
451 451 return (1);
452 452
453 453 /*
454 454 * Otherwise determine whether this relocation symbol and its offset
455 455 * could be candidates for a copy relocation.
456 456 */
457 457 if (ifl->ifl_sortcnt)
458 458 (void) disp_scansyms(ifl, rld, rlocal, 0, ofl);
459 459 return (1);
460 460 }
461 461
462 462 /*
463 463 * Return a Rel_cachebuf with an available Rel_desc entry from the
464 464 * specified cache, allocating a cache buffer if necessary.
465 465 *
466 466 * entry:
467 467 * ofl - Output file descriptor
468 468 * rcp - Relocation cache to allocate the descriptor from.
469 469 * One of &ofl->ofl_actrels or &ofl->ofl_outrels.
470 470 *
471 471 * exit:
472 472 * Returns the allocated descriptor, or NULL if the allocation fails.
473 473 */
474 474 static Rel_cachebuf *
475 475 ld_add_rel_cache(Ofl_desc *ofl, Rel_cache *rcp)
476 476 {
477 477 Rel_cachebuf *rcbp;
478 478 size_t nelts, size, alloc_cnt;
479 479
480 480 /*
481 481 * If there is space available in the present cache bucket, return the
482 482 * next free entry.
483 483 */
484 484 alloc_cnt = aplist_nitems(rcp->rc_list);
485 485 if (rcp->rc_list &&
486 486 ((rcbp = rcp->rc_list->apl_data[alloc_cnt - 1]) != NULL) &&
487 487 (rcbp->rc_free < rcbp->rc_end))
488 488 return (rcbp);
489 489
490 490 /*
491 491 * Allocate a new bucket. As we cannot know the number of relocations
492 492 * we'll have in the active and output cache until after the link is
493 493 * complete, the size of the bucket is a heuristic.
494 494 *
495 495 * In general, if the output object is an executable, or a sharable
496 496 * object, then the size of the active relocation list will be nearly
497 497 * the same as the number of input relocations, and the output
498 498 * relocation list will be very short. If the output object is a
499 499 * relocatable object, then the reverse is true. Therefore, the initial
500 500 * allocation for the appropriate list is sized to fit all the input
501 501 * allocations in a single shot.
502 502 *
503 503 * All other allocations are done in units of REL_CACHEBUF_ALLOC,
504 504 * which is chosen to be large enough to cover most common cases,
505 505 * but small enough that not using it fully is inconsequential.
506 506 *
507 507 * In an ideal scenario, this results in one allocation on each list.
508 508 */
509 509 nelts = REL_CACHEBUF_ALLOC;
510 510 if ((alloc_cnt == 0) && (ofl->ofl_relocincnt > REL_CACHEBUF_ALLOC)) {
511 511 Boolean is_rel = (ofl->ofl_flags & FLG_OF_RELOBJ) != 0;
512 512
513 513 if (((rcp == &ofl->ofl_actrels) && !is_rel) ||
514 514 ((rcp == &ofl->ofl_outrels) && is_rel))
515 515 nelts = ofl->ofl_relocincnt;
516 516 }
517 517
518 518 /*
519 519 * Compute the total number of bytes to allocate. The first element
520 520 * of the array is built into the Rel_cachebuf header, so we subtract
521 521 * one from nelts.
522 522 */
523 523 size = sizeof (Rel_cachebuf) + ((nelts - 1) * sizeof (Rel_desc));
524 524
525 525 if (((rcbp = libld_malloc(size)) == NULL) ||
526 526 (aplist_append(&rcp->rc_list, rcbp, AL_CNT_OFL_RELS) == NULL))
527 527 return (NULL);
528 528
529 529 rcbp->rc_free = rcbp->rc_arr;
530 530 rcbp->rc_end = rcbp->rc_arr + nelts;
531 531
532 532 return (rcbp);
533 533 }
534 534
535 535 /*
536 536 * Allocate a Rel_aux descriptor and attach it to the given Rel_desc,
537 537 * allocating an auxiliary cache buffer if necessary.
538 538 *
539 539 * entry:
540 540 * ofl - Output file descriptor
541 541 * rdp - Rel_desc descriptor that requires an auxiliary block
542 542 *
543 543 * exit:
544 544 * Returns TRUE on success, and FALSE if the allocation fails.
545 545 * On success, the caller is responsible for initializing the
546 546 * auxiliary block properly.
547 547 */
548 548 static Boolean
549 549 ld_add_rel_aux(Ofl_desc *ofl, Rel_desc *rdesc)
550 550 {
551 551 Rel_aux_cachebuf *racp = NULL;
552 552 size_t size;
553 553
554 554 /*
555 555 * If there is space available in the present cache bucket, use it.
556 556 * Otherwise, allocate a new bucket.
557 557 */
558 558 if (ofl->ofl_relaux) {
559 559 racp = ofl->ofl_relaux->apl_data[
560 560 ofl->ofl_relaux->apl_nitems - 1];
561 561
562 562 if (racp && (racp->rac_free >= racp->rac_end))
563 563 racp = NULL;
564 564 }
565 565 if (racp == NULL) {
566 566 /*
567 567 * Compute the total number of bytes to allocate. The first
568 568 * element of the array is built into the Rel_aux_cachebuf
569 569 * header, so we subtract one from the number of elements.
570 570 */
571 571 size = sizeof (Rel_aux_cachebuf) +
572 572 ((RELAUX_CACHEBUF_ALLOC - 1) * sizeof (Rel_aux));
573 573 if (((racp = libld_malloc(size)) == NULL) ||
574 574 (aplist_append(&ofl->ofl_relaux, racp, AL_CNT_OFL_RELS) ==
575 575 NULL))
576 576 return (FALSE);
577 577
578 578 racp->rac_free = racp->rac_arr;
579 579 racp->rac_end = racp->rac_arr + RELAUX_CACHEBUF_ALLOC;
580 580 }
581 581
582 582 /* Take an auxiliary descriptor from the cache and add it to rdesc */
583 583 rdesc->rel_aux = racp->rac_free++;
584 584
585 585 return (TRUE);
586 586 }
587 587
588 588 /*
589 589 * Enter a copy of the given Rel_desc relocation descriptor, and
590 590 * any associated auxiliary Rel_aux it may reference, into the
591 591 * specified relocation cache.
592 592 *
593 593 * entry:
594 594 * ofl - Output file descriptor
595 595 * rcp - Relocation descriptor cache to recieve relocation
596 596 * rdesc - Rel_desc image to be inserted
597 597 * flags - Flags to add to rdest->rel_flags in the inserted descriptor
598 598 *
599 599 * exit:
600 600 * Returns the pointer to the inserted descriptor on success.
601 601 * Returns NULL if an allocation error occurs.
602 602 */
603 603 Rel_desc *
604 604 ld_reloc_enter(Ofl_desc *ofl, Rel_cache *rcp, Rel_desc *rdesc, Word flags)
605 605 {
606 606 Rel_desc *arsp;
607 607 Rel_aux *auxp;
608 608 Rel_cachebuf *rcbp;
609 609
610 610
611 611 /*
612 612 * If no relocation cache structures are available, allocate a new
613 613 * one and link it to the buffer list.
614 614 */
615 615 rcbp = ld_add_rel_cache(ofl, rcp);
616 616 if (rcbp == NULL)
617 617 return (NULL);
618 618 arsp = rcbp->rc_free;
619 619
620 620 /*
621 621 * If there is an auxiliary block on the original, allocate
622 622 * one for the clone. Save the pointer, because the struct copy
623 623 * below will crush it.
624 624 */
625 625 if (rdesc->rel_aux != NULL) {
626 626 if (!ld_add_rel_aux(ofl, arsp))
627 627 return (NULL);
628 628 auxp = arsp->rel_aux;
629 629 }
630 630
631 631 /* Copy contents of the original into the clone */
632 632 *arsp = *rdesc;
633 633
634 634 /*
635 635 * If there is an auxiliary block, restore the clone's pointer to
636 636 * it, and copy the auxiliary contents.
637 637 */
638 638 if (rdesc->rel_aux != NULL) {
639 639 arsp->rel_aux = auxp;
640 640 *auxp = *rdesc->rel_aux;
641 641 }
642 642 arsp->rel_flags |= flags;
643 643
644 644 rcbp->rc_free++;
645 645 rcp->rc_cnt++;
646 646
647 647 return (arsp);
648 648 }
649 649
650 650 /*
651 651 * Initialize a relocation descriptor auxiliary block to default
652 652 * values.
653 653 *
654 654 * entry:
655 655 * rdesc - Relocation descriptor, with a non-NULL rel_aux field
656 656 * pointing at the auxiliary block to be initialized.
657 657 *
658 658 * exit:
659 659 * Each field in rdesc->rel_aux has been set to its default value
660 660 */
661 661 static void
662 662 ld_init_rel_aux(Rel_desc *rdesc)
663 663 {
664 664 Rel_aux *rap = rdesc->rel_aux;
665 665
666 666 /*
667 667 * The default output section is the one the input section
668 668 * is assigned to, assuming that there is an input section.
669 669 * Failing that, NULL is the only possibility, and we expect
670 670 * that the caller will assign an explicit value.
671 671 */
672 672 rap->ra_osdesc = (rdesc->rel_isdesc == NULL) ? NULL :
673 673 rdesc->rel_isdesc->is_osdesc;
674 674
675 675 /* The ra_usym defaults to the value in rel_sym */
676 676 rap->ra_usym = rdesc->rel_sym;
677 677
678 678 /* Remaining fields are zeroed */
679 679 rap->ra_move = NULL;
680 680 rap->ra_typedata = 0;
681 681 }
682 682
683 683 /*
684 684 * The ld_reloc_set_aux_XXX() functions are used to set the value of an
685 685 * auxiliary relocation item on a relocation descriptor that exists in
686 686 * the active or output relocation cache. These descriptors are created
687 687 * via a call to ld_reloc_enter().
688 688 *
689 689 * These functions preserve the illusion that every relocation descriptor
690 690 * has a non-NULL auxiliary block into which values can be set, while
691 691 * only creating an auxiliary block if one is actually necessary, preventing
692 692 * the large memory allocations that would otherwise occur. They operate
693 693 * as follows:
694 694 *
695 695 * - If an auxiliary block already exists, set the desired value and
696 696 * and return TRUE.
697 697 *
698 698 * - If no auxiliary block exists, but the desired value is the default
699 699 * value for the specified item, then no auxiliary block is needed,
700 700 * and TRUE is returned.
701 701 *
702 702 * - If no auxiliary block exists, and the desired value is not the
703 703 * default for the specified item, allocate an auxiliary block for
704 704 * the descriptor, initialize its contents to default values for all
705 705 * items, set the specified value, and return TRUE.
706 706 *
707 707 * - If an auxiliary block needs to be added, but the allocation fails,
708 708 * an error is issued, and FALSE is returned.
709 709 *
710 710 * Note that we only provide an ld_reloc_set_aux_XXX() function for those
711 711 * auxiliary items that libld actually modifies in Rel_desc descriptors
712 712 * in the active or output caches. If another one is needed, add it here.
713 713 *
714 714 * The PROCESS_NULL_REL_AUX macro is used to provide a single implementation
715 715 * for the logic that determines if an auxiliary block is needed or not,
716 716 * and handles the details of allocating and initializing it. It accepts
717 717 * one argument, _isdefault_predicate, which should be a call to the
718 718 * RELAUX_ISDEFAULT_xxx() macro appropriate for the auxiliary item
719 719 */
720 720
721 721 #define PROCESS_NULL_REL_AUX(_isdefault_predicate) \
722 722 if (rdesc->rel_aux == NULL) { \
723 723 /* If requested value is the default, no need for aux block */ \
724 724 if (_isdefault_predicate) \
725 725 return (TRUE); \
726 726 /* Allocate and attach an auxiliary block */ \
727 727 if (!ld_add_rel_aux(ofl, rdesc)) \
728 728 return (FALSE); \
729 729 /* Initialize the auxiliary block with default values */ \
730 730 ld_init_rel_aux(rdesc); \
731 731 }
732 732
733 733 Boolean
734 734 ld_reloc_set_aux_osdesc(Ofl_desc *ofl, Rel_desc *rdesc, Os_desc *osp)
735 735 {
736 736 PROCESS_NULL_REL_AUX(RELAUX_ISDEFAULT_OSDESC(rdesc, osp))
737 737 rdesc->rel_aux->ra_osdesc = osp;
738 738 return (TRUE);
739 739 }
740 740
741 741 Boolean
742 742 ld_reloc_set_aux_usym(Ofl_desc *ofl, Rel_desc *rdesc, Sym_desc *sdp)
743 743 {
744 744 PROCESS_NULL_REL_AUX(RELAUX_ISDEFAULT_USYM(rdesc, sdp))
745 745 rdesc->rel_aux->ra_usym = sdp;
746 746 return (TRUE);
747 747 }
748 748
749 749 #undef PROCESS_NULL_REL_AUX
750 750
751 751 /*
752 752 * Return a descriptive name for the symbol associated with the
753 753 * given relocation descriptor. This will be the actual symbol
754 754 * name if one exists, or a suitable alternative otherwise.
755 755 *
756 756 * entry:
757 757 * rsp - Relocation descriptor
758 758 */
759 759 const char *
760 760 ld_reloc_sym_name(Rel_desc *rsp)
761 761 {
762 762 Sym_desc *sdp = rsp->rel_sym;
763 763
764 764 if (sdp != NULL) {
765 765 /* If the symbol has a valid name use it */
766 766 if (sdp->sd_name && *sdp->sd_name)
767 767 return (demangle(sdp->sd_name));
768 768
769 769 /*
770 770 * If the symbol is STT_SECTION, and the corresponding
771 771 * section symbol has the specially prepared string intended
772 772 * for this use, use that string. The string is of the form
773 773 * secname (section)
774 774 */
775 775 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
776 776 (sdp->sd_isc != NULL) && (sdp->sd_isc->is_sym_name != NULL))
777 777 return (demangle(sdp->sd_isc->is_sym_name));
778 778 } else {
779 779 /*
780 780 * Use an empty name for a register relocation with
781 781 * no symbol.
782 782 */
783 783 if (IS_REGISTER(rsp->rel_rtype))
784 784 return (MSG_ORIG(MSG_STR_EMPTY));
785 785 }
786 786
787 787 /* If all else fails, report it as <unknown> */
788 788 return (MSG_INTL(MSG_STR_UNKNOWN));
789 789 }
790 790
791 791 /*
792 792 * Add an active relocation record.
793 793 */
794 794 uintptr_t
795 795 ld_add_actrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl)
796 796 {
797 797 Rel_desc *arsp;
798 798
799 799 if ((arsp = ld_reloc_enter(ofl, &ofl->ofl_actrels, rsp, flags)) == NULL)
800 800 return (S_ERROR);
801 801
802 802 /*
803 803 * Any GOT relocation reference requires the creation of a .got table.
804 804 * Most references to a .got require a .got entry, which is accounted
805 805 * for with the ofl_gotcnt counter. However, some references are
806 806 * relative to the .got table, but require no .got entry. This test
807 807 * insures a .got is created regardless of the type of reference.
808 808 */
809 809 if (IS_GOT_REQUIRED(arsp->rel_rtype))
810 810 ofl->ofl_flags |= FLG_OF_BLDGOT;
811 811
812 812 /*
813 813 * If this is a displacement relocation generate a warning.
814 814 */
815 815 if (arsp->rel_flags & FLG_REL_DISP) {
816 816 ofl->ofl_dtflags_1 |= DF_1_DISPRELDNE;
817 817
818 818 if (ofl->ofl_flags & FLG_OF_VERBOSE)
819 819 ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl);
820 820 }
821 821
822 822 DBG_CALL(Dbg_reloc_ars_entry(ofl->ofl_lml, ELF_DBG_LD,
823 823 arsp->rel_isdesc->is_shdr->sh_type, ld_targ.t_m.m_mach, arsp));
824 824 return (1);
825 825 }
826 826
827 827 /*
828 828 * In the platform specific machrel.XXX.c files, we sometimes write
829 829 * a value directly into the got/plt. These function can be used when
830 830 * the running linker has the opposite byte order of the object being
831 831 * produced.
832 832 */
833 833 Word
834 834 ld_bswap_Word(Word v)
835 835 {
836 836 return (BSWAP_WORD(v));
837 837 }
838 838
839 839
840 840 Xword
841 841 ld_bswap_Xword(Xword v)
842 842 {
843 843 return (BSWAP_XWORD(v));
844 844 }
845 845
846 846
847 847 uintptr_t
848 848 ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
849 849 {
850 850 Sym_desc *sdp = rsp->rel_sym;
851 851 ofl_flag_t flags = ofl->ofl_flags;
852 852 Gotndx *gnp;
853 853
854 854 /*
855 855 * If this is the first time we've seen this symbol in a GOT
856 856 * relocation we need to assign it a GOT token. Once we've got
857 857 * all of the GOT's assigned we can assign the actual indexes.
858 858 */
859 859 if ((gnp = (*ld_targ.t_mr.mr_find_got_ndx)(sdp->sd_GOTndxs,
860 860 GOT_REF_GENERIC, ofl, rsp)) == 0) {
861 861 Word rtype = rsp->rel_rtype;
862 862
863 863 if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), NULL,
864 864 GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
865 865 return (S_ERROR);
866 866
867 867 /*
868 868 * Initialize the GOT table entry.
869 869 *
870 870 * For global symbols, we clear the GOT table entry and create
871 871 * a GLOB_DAT relocation against the symbol.
872 872 *
873 873 * For local symbols, we enter the symbol value into a GOT
874 874 * table entry and create a relative relocation if all of
875 875 * the following hold:
876 876 *
877 877 * - Output is a shared object
878 878 * - Symbol is not ABS
879 879 * - Relocation is not against one of the special sections
880 880 * (COMMON, ...)
881 881 * - This is not one of the generated symbols we have
882 882 * to update after the output object has been fully
883 883 * laid out (_START_, _END_, ...)
884 884 *
885 885 * Local symbols that don't meet the above requirements
886 886 * are processed as is.
887 887 */
888 888 if (local == TRUE) {
889 889 if ((flags & FLG_OF_SHAROBJ) &&
890 890 (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
891 891 ((sdp->sd_sym->st_shndx != SHN_ABS)) ||
892 892 (sdp->sd_aux && sdp->sd_aux->sa_symspec))) {
893 893 if (ld_add_actrel((FLG_REL_GOT | FLG_REL_GOTCL),
894 894 rsp, ofl) == S_ERROR)
895 895 return (S_ERROR);
896 896
897 897 rsp->rel_rtype = ld_targ.t_m.m_r_relative;
898 898
899 899 if ((*ld_targ.t_mr.mr_add_outrel)
900 900 ((FLG_REL_GOT | FLG_REL_ADVAL),
901 901 rsp, ofl) == S_ERROR)
902 902 return (S_ERROR);
903 903
904 904 rsp->rel_rtype = rtype;
905 905 } else {
906 906 if (ld_add_actrel(FLG_REL_GOT, rsp,
907 907 ofl) == S_ERROR)
908 908 return (S_ERROR);
909 909 }
910 910 } else {
911 911 rsp->rel_rtype = ld_targ.t_m.m_r_glob_dat;
912 912 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_GOT,
913 913 rsp, ofl) == S_ERROR)
914 914 return (S_ERROR);
915 915 rsp->rel_rtype = rtype;
916 916 }
917 917 } else {
918 918 if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
919 919 GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
920 920 return (S_ERROR);
921 921 }
922 922
923 923 /*
924 924 * Perform relocation to GOT table entry.
925 925 */
926 926 return (ld_add_actrel(NULL, rsp, ofl));
927 927 }
928 928
929 929 /*
930 930 * Perform relocations for PLT's
931 931 */
932 932 uintptr_t
933 933 ld_reloc_plt(Rel_desc *rsp, Ofl_desc *ofl)
934 934 {
935 935 Sym_desc *sdp = rsp->rel_sym;
936 936
937 937 switch (ld_targ.t_m.m_mach) {
938 938 case EM_AMD64:
939 939 /*
940 940 * AMD64 TLS code sequences do not use a unique TLS
941 941 * relocation to reference the __tls_get_addr() function call.
942 942 */
943 943 if ((ofl->ofl_flags & FLG_OF_EXEC) &&
944 944 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) ==
945 945 0))
946 946 return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
947 947 break;
948 948
949 949 case EM_386:
950 950 /*
951 951 * GNUC IA32 TLS code sequences do not use a unique TLS
952 952 * relocation to reference the ___tls_get_addr() function call.
953 953 */
954 954 if ((ofl->ofl_flags & FLG_OF_EXEC) &&
955 955 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) ==
956 956 0))
957 957 return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
958 958 break;
959 959 }
960 960
961 961 /*
962 962 * if (not PLT yet assigned)
963 963 * then
964 964 * assign PLT index to symbol
965 965 * build output JMP_SLOT relocation
966 966 * fi
967 967 */
968 968 if (sdp->sd_aux->sa_PLTndx == 0) {
969 969 Word ortype = rsp->rel_rtype;
970 970
971 971 (*ld_targ.t_mr.mr_assign_plt_ndx)(sdp, ofl);
972 972
973 973 /*
974 974 * If this symbol is binding to a lazy loadable, or deferred
975 975 * dependency, then identify the symbol.
976 976 */
977 977 if (sdp->sd_file) {
978 978 if (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD)
979 979 sdp->sd_flags |= FLG_SY_LAZYLD;
980 980 if (sdp->sd_file->ifl_flags & FLG_IF_DEFERRED)
981 981 sdp->sd_flags |= FLG_SY_DEFERRED;
982 982 }
983 983
984 984 rsp->rel_rtype = ld_targ.t_m.m_r_jmp_slot;
985 985 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_PLT, rsp, ofl) ==
986 986 S_ERROR)
987 987 return (S_ERROR);
988 988 rsp->rel_rtype = ortype;
989 989 }
990 990
991 991 /*
992 992 * Perform relocation to PLT table entry.
993 993 */
994 994 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
995 995 IS_ADD_RELATIVE(rsp->rel_rtype)) {
996 996 Word ortype = rsp->rel_rtype;
997 997
998 998 rsp->rel_rtype = ld_targ.t_m.m_r_relative;
999 999 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_ADVAL, rsp, ofl) ==
1000 1000 S_ERROR)
1001 1001 return (S_ERROR);
1002 1002 rsp->rel_rtype = ortype;
1003 1003 return (1);
1004 1004 } else
1005 1005 return (ld_add_actrel(NULL, rsp, ofl));
1006 1006 }
1007 1007
1008 1008 /*
1009 1009 * Round up to the next power of 2. Used to ensure section alignments that can
1010 1010 * be used for copy relocation symbol alignments are sane values.
1011 1011 */
1012 1012 static Word
1013 1013 nlpo2(Word val)
1014 1014 {
1015 1015 val--;
1016 1016 val |= (val >> 1);
1017 1017 val |= (val >> 2);
1018 1018 val |= (val >> 4);
1019 1019 val |= (val >> 8);
1020 1020 val |= (val >> 16);
1021 1021 return (++val);
1022 1022 }
1023 1023
1024 1024 /*
1025 1025 * process GLOBAL undefined and ref_dyn_need symbols.
1026 1026 */
1027 1027 static uintptr_t
1028 1028 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl)
1029 1029 {
1030 1030 Sym_desc *_sdp, *sdp = rsp->rel_sym;
1031 1031 Sym_aux *sap = sdp->sd_aux;
1032 1032 Sym *sym = sdp->sd_sym;
1033 1033 Addr stval;
1034 1034
1035 1035 /*
1036 1036 * Reference is to a function so simply create a plt entry for it.
1037 1037 */
1038 1038 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
1039 1039 return (ld_reloc_plt(rsp, ofl));
1040 1040
1041 1041 /*
1042 1042 * Catch absolutes - these may cause a text relocation.
1043 1043 */
1044 1044 if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sym->st_shndx == SHN_ABS)) {
1045 1045 if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0)
1046 1046 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1047 1047
1048 1048 /*
1049 1049 * If -zabsexec is set then promote the ABSOLUTE symbol to
1050 1050 * current the current object and perform the relocation now.
1051 1051 */
1052 1052 sdp->sd_ref = REF_REL_NEED;
1053 1053 return (ld_add_actrel(NULL, rsp, ofl));
1054 1054 }
1055 1055
1056 1056 /*
1057 1057 * If the relocation is against a writable section simply compute the
1058 1058 * necessary output relocation. As an optimization, if the symbol has
1059 1059 * already been transformed into a copy relocation then we can perform
1060 1060 * the relocation directly (copy relocations should only be generated
1061 1061 * for references from the text segment and these relocations are
1062 1062 * normally carried out before we get to the data segment relocations).
1063 1063 */
1064 1064 if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) &&
1065 1065 (RELAUX_GET_OSDESC(rsp)->os_shdr->sh_flags & SHF_WRITE)) {
1066 1066 if (sdp->sd_flags & FLG_SY_MVTOCOMM)
1067 1067 return (ld_add_actrel(NULL, rsp, ofl));
1068 1068 else
1069 1069 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1070 1070 }
1071 1071
1072 1072 /*
1073 1073 * If the reference isn't to an object (normally because a .type
1074 1074 * directive wasn't defined in some assembler source), then apply
1075 1075 * a generic relocation (this has a tendency to result in text
1076 1076 * relocations).
1077 1077 */
1078 1078 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) {
1079 1079 Conv_inv_buf_t inv_buf;
1080 1080
1081 1081 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
1082 1082 conv_sym_info_type(sdp->sd_file->ifl_ehdr->e_machine,
1083 1083 ELF_ST_TYPE(sym->st_info), 0, &inv_buf),
1084 1084 rsp->rel_isdesc->is_file->ifl_name,
1085 1085 ld_reloc_sym_name(rsp), sdp->sd_file->ifl_name);
1086 1086 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1087 1087 }
1088 1088
1089 1089 /*
1090 1090 * Prepare for generating a copy relocation.
1091 1091 *
1092 1092 * If this symbol is one of an alias pair, we need to ensure both
1093 1093 * symbols become part of the output (the strong symbol will be used to
1094 1094 * maintain the symbols state). And, if we did raise the precedence of
1095 1095 * a symbol we need to check and see if this is a weak symbol. If it is
1096 1096 * we want to use it's strong counter part.
1097 1097 *
1098 1098 * The results of this logic should be:
1099 1099 * ra_usym: assigned to strong
1100 1100 * rel_sym: assigned to symbol to perform
1101 1101 * copy_reloc against (weak or strong).
1102 1102 */
1103 1103 if (sap->sa_linkndx) {
1104 1104 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1105 1105
1106 1106 if (_sdp->sd_ref < sdp->sd_ref) {
1107 1107 _sdp->sd_ref = sdp->sd_ref;
1108 1108 _sdp->sd_flags |= FLG_SY_REFRSD;
1109 1109
1110 1110 /*
1111 1111 * As we're going to replicate a symbol from a shared
1112 1112 * object, retain its correct binding status.
1113 1113 */
1114 1114 if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL)
1115 1115 _sdp->sd_flags |= FLG_SY_GLOBREF;
1116 1116
1117 1117 } else if (_sdp->sd_ref > sdp->sd_ref) {
1118 1118 sdp->sd_ref = _sdp->sd_ref;
1119 1119 sdp->sd_flags |= FLG_SY_REFRSD;
1120 1120
1121 1121 /*
1122 1122 * As we're going to replicate a symbol from a shared
1123 1123 * object, retain its correct binding status.
1124 1124 */
1125 1125 if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL)
1126 1126 sdp->sd_flags |= FLG_SY_GLOBREF;
1127 1127 }
1128 1128
1129 1129 /*
1130 1130 * If this is a weak symbol then we want to move the strong
1131 1131 * symbol into local .bss. If there is a copy_reloc to be
1132 1132 * performed, that should still occur against the WEAK symbol.
1133 1133 */
1134 1134 if (((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1135 1135 (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1136 1136 !ld_reloc_set_aux_usym(ofl, rsp, _sdp))
1137 1137 return (S_ERROR);
1138 1138 } else
1139 1139 _sdp = 0;
1140 1140
1141 1141 /*
1142 1142 * If the reference is to an object then allocate space for the object
1143 1143 * within the executables .bss. Relocations will now be performed from
1144 1144 * this new location. If the original shared objects data is
1145 1145 * initialized, then generate a copy relocation that will copy the data
1146 1146 * to the executables .bss at runtime.
1147 1147 */
1148 1148 if (!(RELAUX_GET_USYM(rsp)->sd_flags & FLG_SY_MVTOCOMM)) {
1149 1149 Word rtype = rsp->rel_rtype, w2align;
1150 1150 Copy_rel cr;
1151 1151
1152 1152 /*
1153 1153 * Diagnose the original copy reference, as this symbol
1154 1154 * information will be overridden with the new destination.
1155 1155 */
1156 1156 DBG_CALL(Dbg_syms_copy_reloc(ofl, sdp, 0));
1157 1157
1158 1158 /*
1159 1159 * Indicate that the symbol(s) against which we're relocating
1160 1160 * have been moved to the executables common. Also, insure that
1161 1161 * the symbol(s) remain marked as global, as the shared object
1162 1162 * from which they are copied must be able to relocate to the
1163 1163 * new common location within the executable.
1164 1164 *
1165 1165 * Note that even though a new symbol has been generated in the
1166 1166 * output files' .bss, the symbol must remain REF_DYN_NEED and
1167 1167 * not be promoted to REF_REL_NEED. sym_validate() still needs
1168 1168 * to carry out a number of checks against the symbols binding
1169 1169 * that are triggered by the REF_DYN_NEED state.
1170 1170 */
1171 1171 sdp->sd_flags |=
1172 1172 (FLG_SY_MVTOCOMM | FLG_SY_DEFAULT | FLG_SY_EXPDEF);
1173 1173 sdp->sd_flags &= ~MSK_SY_LOCAL;
1174 1174 sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
1175 1175 if (_sdp) {
1176 1176 _sdp->sd_flags |= (FLG_SY_MVTOCOMM |
1177 1177 FLG_SY_DEFAULT | FLG_SY_EXPDEF);
1178 1178 _sdp->sd_flags &= ~MSK_SY_LOCAL;
1179 1179 _sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
1180 1180
1181 1181 /*
1182 1182 * Make sure the symbol has a reference in case of any
1183 1183 * error diagnostics against it (perhaps this belongs
1184 1184 * to a version that isn't allowable for this build).
1185 1185 * The resulting diagnostic (see sym_undef_entry())
1186 1186 * might seem a little bogus, as the symbol hasn't
1187 1187 * really been referenced by this file, but has been
1188 1188 * promoted as a consequence of its alias reference.
1189 1189 */
1190 1190 if (!(_sdp->sd_aux->sa_rfile))
1191 1191 _sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile;
1192 1192 }
1193 1193
1194 1194 /*
1195 1195 * Assign the symbol to the bss.
1196 1196 */
1197 1197 _sdp = RELAUX_GET_USYM(rsp);
1198 1198 stval = _sdp->sd_sym->st_value;
1199 1199 if (ld_sym_copy(_sdp) == S_ERROR)
1200 1200 return (S_ERROR);
1201 1201 _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON;
1202 1202 _sdp->sd_flags |= FLG_SY_SPECSEC;
1203 1203
1204 1204 /*
1205 1205 * Ensure the symbol has sufficient alignment. The symbol
1206 1206 * definition has no alignment information that can be used,
1207 1207 * hence we use a heuristic. Historically, twice the native
1208 1208 * word alignment was sufficient for any data type, however,
1209 1209 * the developer may have requested larger alignments (pragma
1210 1210 * align). The most conservative approach is to use a power
1211 1211 * of two alignment, determined from the alignment of the
1212 1212 * section containing the symbol definition. Note that this
1213 1213 * can result in some bloat to the .bss as the not every item
1214 1214 * of copied data might need the section alignment.
1215 1215 *
1216 1216 * COMMON symbols carry their alignment requirements in the
1217 1217 * symbols st_value field. This alignment is applied to the
1218 1218 * symbol when it is eventually transformed into .bss.
1219 1219 */
1220 1220 w2align = ld_targ.t_m.m_word_align * 2;
1221 1221 if (_sdp->sd_sym->st_size < w2align)
1222 1222 _sdp->sd_sym->st_value = ld_targ.t_m.m_word_align;
1223 1223 else {
1224 1224 Shdr *shdr;
1225 1225 Word isalign;
1226 1226
1227 1227 if (_sdp->sd_isc &&
1228 1228 ((shdr = _sdp->sd_isc->is_shdr) != NULL) &&
1229 1229 ((isalign = shdr->sh_addralign) != 0))
1230 1230 _sdp->sd_sym->st_value = nlpo2(isalign);
1231 1231 else
1232 1232 _sdp->sd_sym->st_value = w2align;
1233 1233 }
1234 1234
1235 1235 /*
1236 1236 * Whether or not the symbol references initialized data we
1237 1237 * generate a copy relocation - this differs from the past
1238 1238 * where we would not create the COPY_RELOC if we were binding
1239 1239 * against .bss. This is done for *two* reasons.
1240 1240 *
1241 1241 * - If the symbol in the shared object changes to a
1242 1242 * initialized data - we need the COPY to pick it up.
1243 1243 * - Without the COPY RELOC we can't tell that the symbol
1244 1244 * from the COPY'd object has been moved and all bindings
1245 1245 * to it should bind here.
1246 1246 *
1247 1247 * Keep this symbol in the copy relocation list to check the
1248 1248 * validity later.
1249 1249 */
1250 1250 cr.c_sdp = _sdp;
1251 1251 cr.c_val = stval;
1252 1252 if (alist_append(&ofl->ofl_copyrels, &cr, sizeof (Copy_rel),
1253 1253 AL_CNT_OFL_COPYRELS) == NULL)
1254 1254 return (S_ERROR);
1255 1255
1256 1256 rsp->rel_rtype = ld_targ.t_m.m_r_copy;
1257 1257 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_BSS, rsp, ofl) ==
1258 1258 S_ERROR)
1259 1259 return (S_ERROR);
1260 1260 rsp->rel_rtype = rtype;
1261 1261
1262 1262 /*
1263 1263 * If this symbol is a protected symbol, warn the user. A
1264 1264 * potential issue exists as the copy relocated symbol within
1265 1265 * the executable can be visible to others, whereas the shared
1266 1266 * object that defined the original copy data symbol is pre-
1267 1267 * bound to reference it's own definition. Any modification
1268 1268 * of the symbols data could lead to inconsistencies for the
1269 1269 * various users.
1270 1270 */
1271 1271 if (_sdp->sd_flags & FLG_SY_PROT) {
1272 1272 Conv_inv_buf_t inv_buf;
1273 1273
1274 1274 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_COPY),
1275 1275 conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine,
1276 1276 ld_targ.t_m.m_r_copy, 0, &inv_buf),
1277 1277 _sdp->sd_file->ifl_name, _sdp->sd_name);
1278 1278 }
1279 1279 DBG_CALL(Dbg_syms_copy_reloc(ofl, _sdp,
1280 1280 _sdp->sd_sym->st_value));
1281 1281 }
1282 1282 return (ld_add_actrel(NULL, rsp, ofl));
1283 1283 }
1284 1284
1285 1285 /*
1286 1286 * All relocations should have been handled by the other routines. This
1287 1287 * routine is here as a catch all, if we do enter it we've goofed - but
1288 1288 * we'll try and do the best we can.
1289 1289 */
1290 1290 static uintptr_t
1291 1291 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl)
1292 1292 {
1293 1293 Ifl_desc *ifl = rsp->rel_isdesc->is_file;
1294 1294 Conv_inv_buf_t inv_buf;
1295 1295
1296 1296 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
1297 1297 conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
1298 1298 0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp));
1299 1299
1300 1300 /*
1301 1301 * If building a shared object then put the relocation off
1302 1302 * until runtime.
1303 1303 */
1304 1304 if (ofl->ofl_flags & FLG_OF_SHAROBJ)
1305 1305 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1306 1306
1307 1307 /*
1308 1308 * Otherwise process relocation now.
1309 1309 */
1310 1310 return (ld_add_actrel(NULL, rsp, ofl));
1311 1311 }
1312 1312
1313 1313 /*
1314 1314 * Process relocations when building a relocatable object. Typically, there
1315 1315 * aren't many relocations that can be caught at this point, most are simply
1316 1316 * passed through to the output relocatable object.
1317 1317 */
1318 1318 static uintptr_t
1319 1319 reloc_relobj(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1320 1320 {
1321 1321 Word rtype = rsp->rel_rtype;
1322 1322 Sym_desc *sdp = rsp->rel_sym;
1323 1323 Is_desc *isp = rsp->rel_isdesc;
1324 1324 Word oflags = NULL;
1325 1325
1326 1326 /*
1327 1327 * Determine if we can do any relocations at this point. We can if:
1328 1328 *
1329 1329 * this is local_symbol and a non-GOT relocation, and
1330 1330 * the relocation is pc-relative, and
1331 1331 * the relocation is against a symbol in same section
1332 1332 */
1333 1333 if (local && !IS_GOT_RELATIVE(rtype) &&
1334 1334 !IS_GOT_BASED(rtype) && !IS_GOT_PC(rtype) &&
1335 1335 IS_PC_RELATIVE(rtype) &&
1336 1336 ((sdp->sd_isc) && (sdp->sd_isc->is_osdesc == isp->is_osdesc)))
1337 1337 return (ld_add_actrel(NULL, rsp, ofl));
1338 1338
1339 1339 /*
1340 1340 * If -zredlocsym is in effect, translate all local symbol relocations
1341 1341 * to be against section symbols, since section symbols are the only
1342 1342 * local symbols which will be added to the .symtab.
1343 1343 */
1344 1344 if (local && (((ofl->ofl_flags & FLG_OF_REDLSYM) &&
1345 1345 (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL)) ||
1346 1346 ((sdp->sd_flags & FLG_SY_ELIM) &&
1347 1347 (ofl->ofl_flags & FLG_OF_PROCRED)))) {
1348 1348 /*
1349 1349 * But if this is PIC code, don't allow it for now.
1350 1350 */
1351 1351 if (IS_GOT_RELATIVE(rsp->rel_rtype)) {
1352 1352 Ifl_desc *ifl = rsp->rel_isdesc->is_file;
1353 1353 Conv_inv_buf_t inv_buf;
1354 1354
1355 1355 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_PICREDLOC),
1356 1356 ld_reloc_sym_name(rsp), ifl->ifl_name,
1357 1357 conv_reloc_type(ifl->ifl_ehdr->e_machine,
1358 1358 rsp->rel_rtype, 0, &inv_buf));
1359 1359 return (S_ERROR);
1360 1360 }
1361 1361
1362 1362 /*
1363 1363 * Indicate that this relocation should be processed the same
1364 1364 * as a section symbol. For RELA, indicate that the addend
1365 1365 * also needs to be applied to this relocation.
1366 1366 */
1367 1367 if ((rsp->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
1368 1368 oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL;
1369 1369 else
1370 1370 oflags = FLG_REL_SCNNDX;
1371 1371 }
1372 1372
1373 1373 if ((rsp->rel_flags & FLG_REL_RELA) == 0) {
1374 1374 /*
1375 1375 * Intel (Rel) relocations do not contain an addend. Any
1376 1376 * addend is contained within the file at the location
1377 1377 * identified by the relocation offset. Therefore, if we're
1378 1378 * processing a section symbol, or a -zredlocsym relocation
1379 1379 * (that basically transforms a local symbol reference into
1380 1380 * a section reference), perform an active relocation to
1381 1381 * propagate any addend.
1382 1382 */
1383 1383 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) ||
1384 1384 (oflags == FLG_REL_SCNNDX))
1385 1385 if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR)
1386 1386 return (S_ERROR);
1387 1387 }
1388 1388 return ((*ld_targ.t_mr.mr_add_outrel)(oflags, rsp, ofl));
1389 1389 }
1390 1390
1391 1391 /*
1392 1392 * Perform any generic TLS validations before passing control to machine
1393 1393 * specific routines. At this point we know we are dealing with an executable
1394 1394 * or shared object - relocatable objects have already been processed.
1395 1395 */
1396 1396 static uintptr_t
1397 1397 reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1398 1398 {
1399 1399 Word rtype = rsp->rel_rtype;
1400 1400 ofl_flag_t flags = ofl->ofl_flags;
1401 1401 Ifl_desc *ifl = rsp->rel_isdesc->is_file;
1402 1402 Half mach = ifl->ifl_ehdr->e_machine;
1403 1403 Sym_desc *sdp = rsp->rel_sym;
1404 1404 unsigned char type;
1405 1405 Conv_inv_buf_t inv_buf1, inv_buf2;
1406 1406
1407 1407 /*
1408 1408 * All TLS relocations are illegal in a static executable.
1409 1409 */
1410 1410 if (OFL_IS_STATIC_EXEC(ofl)) {
1411 1411 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
1412 1412 conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1413 1413 ld_reloc_sym_name(rsp));
1414 1414 return (S_ERROR);
1415 1415 }
1416 1416
1417 1417 /*
1418 1418 * Any TLS relocation must be against a STT_TLS symbol, all others
1419 1419 * are illegal.
1420 1420 */
1421 1421 if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) {
1422 1422 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
1423 1423 conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1424 1424 ld_reloc_sym_name(rsp),
1425 1425 conv_sym_info_type(mach, type, 0, &inv_buf2));
1426 1426 return (S_ERROR);
1427 1427 }
1428 1428
1429 1429 /*
1430 1430 * A dynamic executable can not use the LD or LE reference models to
1431 1431 * reference an external symbol. A shared object can not use the LD
1432 1432 * reference model to reference an external symbol.
1433 1433 */
1434 1434 if (!local && (IS_TLS_LD(rtype) ||
1435 1435 ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) {
1436 1436 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
1437 1437 conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1438 1438 ld_reloc_sym_name(rsp), sdp->sd_file->ifl_name);
1439 1439 return (S_ERROR);
1440 1440 }
1441 1441
1442 1442 /*
1443 1443 * The TLS LE model is only allowed for dynamic executables. The TLS IE
1444 1444 * model is allowed for shared objects, but this model has restrictions.
1445 1445 * This model can only be used freely in dependencies that are loaded
1446 1446 * immediately as part of process initialization. However, during the
1447 1447 * initial runtime handshake with libc that establishes the thread
1448 1448 * pointer, a small backup TLS reservation is created. This area can
1449 1449 * be used by objects that are loaded after threads are initialized.
1450 1450 * However, this area is limited in size and may have already been
1451 1451 * used. This area is intended for specialized applications, and does
1452 1452 * not provide the degree of flexibility dynamic TLS can offer. Under
1453 1453 * -z verbose indicate this restriction to the user.
1454 1454 */
1455 1455 if ((flags & FLG_OF_EXEC) == 0) {
1456 1456 if (IS_TLS_LE(rtype)) {
1457 1457 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSLE),
1458 1458 conv_reloc_type(mach, rtype, 0, &inv_buf1),
1459 1459 ifl->ifl_name, ld_reloc_sym_name(rsp));
1460 1460 return (S_ERROR);
1461 1461
1462 1462 } else if ((IS_TLS_IE(rtype)) &&
1463 1463 (flags & FLG_OF_VERBOSE)) {
1464 1464 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_TLSIE),
1465 1465 conv_reloc_type(mach, rtype, 0, &inv_buf1),
1466 1466 ifl->ifl_name, ld_reloc_sym_name(rsp));
1467 1467 }
1468 1468 }
1469 1469
1470 1470 return ((*ld_targ.t_mr.mr_reloc_TLS)(local, rsp, ofl));
1471 1471 }
1472 1472
1473 1473 uintptr_t
1474 1474 ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
1475 1475 const char *isname, Word isscnndx)
1476 1476 {
1477 1477 Word rtype = reld->rel_rtype;
1478 1478 ofl_flag_t flags = ofl->ofl_flags;
1479 1479 Sym_desc *sdp = reld->rel_sym;
1480 1480 Sym_aux *sap;
1481 1481 Boolean local;
1482 1482 Conv_inv_buf_t inv_buf;
1483 1483
1484 1484 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, ld_targ.t_m.m_mach,
1485 1485 ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname, isscnndx,
1486 1486 ld_reloc_sym_name(reld)));
1487 1487
1488 1488 /*
1489 1489 * Indicate this symbol is being used for relocation and therefore must
1490 1490 * have its output address updated accordingly (refer to update_osym()).
1491 1491 */
1492 1492 sdp->sd_flags |= FLG_SY_UPREQD;
1493 1493
1494 1494 /*
1495 1495 * Indicate the section this symbol is defined in has been referenced,
1496 1496 * therefor it *is not* a candidate for elimination.
1497 1497 */
1498 1498 if (sdp->sd_isc) {
1499 1499 sdp->sd_isc->is_flags |= FLG_IS_SECTREF;
1500 1500 sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF;
1501 1501 }
1502 1502
1503 1503 if (!ld_reloc_set_aux_usym(ofl, reld, sdp))
1504 1504 return (S_ERROR);
1505 1505
1506 1506 /*
1507 1507 * Determine if this symbol is actually an alias to another symbol. If
1508 1508 * so, and the alias is not REF_DYN_SEEN, set ra_usym to point to the
1509 1509 * weak symbols strong counter-part. The one exception is if the
1510 1510 * FLG_SY_MVTOCOMM flag is set on the weak symbol. If this is the case,
1511 1511 * the strong is only here because of its promotion, and the weak symbol
1512 1512 * should still be used for the relocation reference (see reloc_exec()).
1513 1513 */
1514 1514 sap = sdp->sd_aux;
1515 1515 if (sap && sap->sa_linkndx &&
1516 1516 ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1517 1517 (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1518 1518 (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) {
1519 1519 Sym_desc *_sdp;
1520 1520
1521 1521 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1522 1522 if ((_sdp->sd_ref != REF_DYN_SEEN) &&
1523 1523 !ld_reloc_set_aux_usym(ofl, reld, _sdp))
1524 1524 return (S_ERROR);
1525 1525 }
1526 1526
1527 1527 /*
1528 1528 * Determine whether this symbol should be bound locally or not.
1529 1529 * Symbols are bound locally if one of the following is true:
1530 1530 *
1531 1531 * - the symbol is of type STB_LOCAL.
1532 1532 *
1533 1533 * - the output image is not a relocatable object and the relocation
1534 1534 * is relative to the .got.
1535 1535 *
1536 1536 * - the section being relocated is of type SHT_SUNW_dof. These
1537 1537 * sections must be bound to the functions in the containing
1538 1538 * object and can not be interposed upon.
1539 1539 *
1540 1540 * - the symbol has been reduced (scoped to a local or symbolic) and
1541 1541 * reductions are being processed.
1542 1542 *
1543 1543 * - the -Bsymbolic flag is in use when building a shared object,
1544 1544 * and the symbol hasn't explicitly been defined as nodirect.
1545 1545 *
1546 1546 * - an executable (fixed address) is being created, and the symbol
1547 1547 * is defined in the executable.
1548 1548 *
1549 1549 * - the relocation is against a segment which will not be loaded
1550 1550 * into memory. In this case, the relocation must be resolved
1551 1551 * now, as ld.so.1 can not process relocations against unmapped
1552 1552 * segments.
1553 1553 */
1554 1554 local = FALSE;
1555 1555 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1556 1556 local = TRUE;
1557 1557 } else if (!(reld->rel_flags & FLG_REL_LOAD)) {
1558 1558 local = TRUE;
1559 1559 } else if (sdp->sd_sym->st_shndx != SHN_UNDEF) {
1560 1560 if (reld->rel_isdesc &&
1561 1561 reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) {
1562 1562 local = TRUE;
1563 1563 } else if (!(flags & FLG_OF_RELOBJ) &&
1564 1564 (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) {
1565 1565 local = TRUE;
1566 1566 } else if ((sdp->sd_ref == REF_REL_NEED) &&
1567 1567 ((sdp->sd_flags & FLG_SY_CAP) == 0)) {
1568 1568 /*
1569 1569 * Global symbols may have been individually reduced in
1570 1570 * scope. If the whole object is to be self contained,
1571 1571 * such as when generating an executable or a symbolic
1572 1572 * shared object, make sure all relocation symbol
1573 1573 * references (sections too) are treated locally. Note,
1574 1574 * explicit no-direct symbols should not be bound to
1575 1575 * locally.
1576 1576 */
1577 1577 if ((sdp->sd_flags &
1578 1578 (FLG_SY_HIDDEN | FLG_SY_PROTECT)))
1579 1579 local = TRUE;
1580 1580 else if ((flags & FLG_OF_EXEC) ||
1581 1581 ((flags & FLG_OF_SYMBOLIC) &&
1582 1582 ((sdp->sd_flags & FLG_SY_NDIR) == 0))) {
1583 1583 local = TRUE;
1584 1584 }
1585 1585 }
1586 1586 }
1587 1587
1588 1588 /*
1589 1589 * If this is a PC_RELATIVE relocation, the relocation could be
1590 1590 * compromised if the relocated address is later used as a copy
1591 1591 * relocated symbol (PSARC 1999/636, bugid 4187211). Scan the input
1592 1592 * files symbol table to cross reference this relocation offset.
1593 1593 */
1594 1594 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
1595 1595 IS_PC_RELATIVE(rtype) &&
1596 1596 (IS_GOT_PC(rtype) == 0) &&
1597 1597 (IS_PLT(rtype) == 0)) {
1598 1598 if (disp_inspect(ofl, reld, local) == S_ERROR)
1599 1599 return (S_ERROR);
1600 1600 }
1601 1601
1602 1602 /*
1603 1603 * GOT based relocations must bind to the object being built - since
1604 1604 * they are relevant to the current GOT. If not building a relocatable
1605 1605 * object - give a appropriate error message.
1606 1606 */
1607 1607 if (!local && !(flags & FLG_OF_RELOBJ) &&
1608 1608 IS_GOT_BASED(rtype)) {
1609 1609 Ifl_desc *ifl = reld->rel_isdesc->is_file;
1610 1610
1611 1611 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
1612 1612 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1613 1613 0, &inv_buf), ifl->ifl_name, demangle(sdp->sd_name));
1614 1614 return (S_ERROR);
1615 1615 }
1616 1616
1617 1617 /*
1618 1618 * TLS symbols can only have TLS relocations.
1619 1619 */
1620 1620 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) &&
1621 1621 (IS_TLS_INS(rtype) == 0)) {
1622 1622 /*
1623 1623 * The above test is relaxed if the target section is
1624 1624 * non-allocable.
1625 1625 */
1626 1626 if (RELAUX_GET_OSDESC(reld)->os_shdr->sh_flags & SHF_ALLOC) {
1627 1627 Ifl_desc *ifl = reld->rel_isdesc->is_file;
1628 1628
1629 1629 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
1630 1630 conv_reloc_type(ifl->ifl_ehdr->e_machine,
1631 1631 rtype, 0, &inv_buf), ifl->ifl_name,
1632 1632 demangle(sdp->sd_name));
1633 1633 return (S_ERROR);
1634 1634 }
1635 1635 }
1636 1636
1637 1637 /*
1638 1638 * Select the relocation to perform.
1639 1639 */
1640 1640 if (IS_REGISTER(rtype)) {
1641 1641 if (ld_targ.t_mr.mr_reloc_register == NULL) {
1642 1642 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
1643 1643 return (S_ERROR);
1644 1644 }
1645 1645 return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1646 1646 }
1647 1647
1648 1648 if (flags & FLG_OF_RELOBJ)
1649 1649 return (reloc_relobj(local, reld, ofl));
1650 1650
1651 1651 if (IS_TLS_INS(rtype))
1652 1652 return (reloc_TLS(local, reld, ofl));
1653 1653
1654 1654 if (IS_GOT_OPINS(rtype)) {
1655 1655 if (ld_targ.t_mr.mr_reloc_GOTOP == NULL) {
1656 1656 assert(0);
1657 1657 return (S_ERROR);
1658 1658 }
1659 1659 return ((*ld_targ.t_mr.mr_reloc_GOTOP)(local, reld, ofl));
1660 1660 }
1661 1661
1662 1662 if (IS_GOT_RELATIVE(rtype))
1663 1663 return (ld_reloc_GOT_relative(local, reld, ofl));
1664 1664
1665 1665 if (local)
1666 1666 return ((*ld_targ.t_mr.mr_reloc_local)(reld, ofl));
1667 1667
1668 1668 if ((IS_PLT(rtype) || ((sdp->sd_flags & FLG_SY_CAP) &&
1669 1669 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_FUNC))) &&
1670 1670 ((flags & FLG_OF_BFLAG) == 0))
1671 1671 return (ld_reloc_plt(reld, ofl));
1672 1672
1673 1673 if ((sdp->sd_ref == REF_REL_NEED) ||
1674 1674 (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) ||
1675 1675 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE))
1676 1676 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, reld, ofl));
1677 1677
1678 1678 if (sdp->sd_ref == REF_DYN_NEED)
1679 1679 return (reloc_exec(reld, ofl));
1680 1680
1681 1681 /*
1682 1682 * IS_NOT_REL(rtype)
1683 1683 */
1684 1684 return (reloc_generic(reld, ofl));
1685 1685 }
1686 1686
1687 1687 /*
1688 1688 * Given a relocation that references a local symbol from a discarded COMDAT
1689 1689 * section, replace the symbol with the corresponding symbol from the section
1690 1690 * that was kept.
1691 1691 *
1692 1692 * entry:
1693 1693 * reld - Relocation
1694 1694 * sdp - Symbol to be replaced. Must be a local symbol (STB_LOCAL).
1695 1695 * reject - Address of variable to receive rejection code
1696 1696 * if no replacement symbol is found.
1697 1697 *
1698 1698 * exit:
1699 1699 * Returns address of replacement symbol descriptor if one was
1700 1700 * found, and NULL otherwise. The result is also cached in
1701 1701 * ofl->ofl_sr_cache as an optimization to speed following calls
1702 1702 * for the same value of sdp.
1703 1703 *
1704 1704 * On success (non-NULL result), *reject is set to RLXREL_REJ_NONE.
1705 1705 * On failure (NULL result), *reject is filled in with a code
1706 1706 * describing the underlying reason.
1707 1707 *
1708 1708 * note:
1709 1709 * The word "COMDAT" is used to refer to actual COMDAT sections, COMDAT
1710 1710 * groups tied together with an SHF_GROUP section, and .gnu.linkonce
1711 1711 * sections which provide a simplified COMDAT requirement. COMDAT
1712 1712 * sections are identified with the FLG_IS_COMDAT section flag.
1713 1713 *
1714 1714 * In principle, this sort of sloppy relocation remapping is
1715 1715 * a questionable practice. All self-referential sections should
1716 1716 * be in a common SHF_GROUP so that they are all kept or removed
1717 1717 * together. The problem is that there is no way to ensure that the
1718 1718 * two sections are similar enough that the replacement section will
1719 1719 * really supply the correct information. However, we see a couple of
1720 1720 * situations where it is useful to do this: (1) Older Sun C compilers
1721 1721 * generated DWARF sections that would refer to one of the COMDAT
1722 1722 * sections, and (2) gcc, when its GNU linkonce COMDAT feature is enabled.
1723 1723 * It turns out that the GNU ld does these sloppy remappings.
1724 1724 *
1725 1725 * The GNU ld takes an approach that hard wires special section
1726 1726 * names and treats them specially. We avoid that practice and
1727 1727 * try to get the necessary work done relying only on the ELF
1728 1728 * attributes of the sections and symbols involved. This means
1729 1729 * that our heuristic is somewhat different than theirs, but the
1730 1730 * end result is close enough to solve the same problem.
1731 1731 *
1732 1732 * gcc is in the process of converting to SHF_GROUP. This will
1733 1733 * eventually phase out the need for sloppy relocations, and
1734 1734 * then this logic won't be needed. In the meantime, relaxed relocation
1735 1735 * processing allows us to interoperate.
1736 1736 */
1737 1737 static Sym_desc *
1738 1738 sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp,
1739 1739 Rlxrel_rej *reject)
1740 1740 {
1741 1741 Is_desc *rep_isp;
1742 1742 Sym *sym, *rep_sym;
1743 1743 Is_desc *isp;
1744 1744 Ifl_desc *ifl;
1745 1745 Conv_inv_buf_t inv_buf;
1746 1746 Word scnndx, symscnt;
1747 1747 Sym_desc **oldndx, *rep_sdp;
1748 1748 const char *is_name;
1749 1749
1750 1750
1751 1751 /*
1752 1752 * Sloppy relocations are never applied to .eh_frame or
1753 1753 * .gcc_except_table sections. The entries in these sections
1754 1754 * for discarded sections are better left uninitialized.
1755 1755 *
1756 1756 * We match these sections by name, because on most platforms they
1757 1757 * are SHT_PROGBITS, and cannot be identified otherwise. On amd64
1758 1758 * architectures, .eh_frame is SHT_AMD64_UNWIND, but that is ambiguous
1759 1759 * (.eh_frame_hdr is also SHT_AMD64_UNWIND), so we still match it by
1760 1760 * name.
1761 1761 */
1762 1762 is_name = reld->rel_isdesc->is_name;
1763 1763 if (((is_name[1] == 'e') &&
1764 1764 (strcmp(is_name, MSG_ORIG(MSG_SCN_EHFRAME)) == 0)) ||
1765 1765 ((is_name[1] == 'g') &&
1766 1766 (strcmp(is_name, MSG_ORIG(MSG_SCN_GCC_X_TBL)) == 0))) {
1767 1767 *reject = RLXREL_REJ_TARGET;
1768 1768 return (NULL);
1769 1769 }
1770 1770
1771 1771 /*
1772 1772 * If we looked up the same symbol on the previous call, we can
1773 1773 * return the cached value.
1774 1774 */
1775 1775 if (sdp == ofl->ofl_sr_cache.sr_osdp) {
1776 1776 *reject = ofl->ofl_sr_cache.sr_rej;
1777 1777 return (ofl->ofl_sr_cache.sr_rsdp);
1778 1778 }
1779 1779
1780 1780 ofl->ofl_sr_cache.sr_osdp = sdp;
1781 1781 sym = sdp->sd_sym;
1782 1782 isp = sdp->sd_isc;
1783 1783 ifl = sdp->sd_file;
1784 1784
1785 1785 /*
1786 1786 * When a COMDAT section is discarded in favor of another COMDAT
1787 1787 * section, the replacement is recorded in its section descriptor
1788 1788 * (is_comdatkeep). We must validate the replacement before using
1789 1789 * it. The replacement section must:
1790 1790 * - Not have been discarded
1791 1791 * - Have the same size (*)
1792 1792 * - Have the same section type
1793 1793 * - Have the same SHF_GROUP flag setting (either on or off)
1794 1794 * - Must be a COMDAT section of one form or the other.
1795 1795 *
1796 1796 * (*) One might imagine that the replacement section could be
1797 1797 * larger than the original, rather than the exact size. However,
1798 1798 * we have verified that this is the same policy used by the GNU
1799 1799 * ld. If the sections are not the same size, the chance of them
1800 1800 * being interchangeable drops significantly.
1801 1801 */
1802 1802 if (((rep_isp = isp->is_comdatkeep) == NULL) ||
1803 1803 ((rep_isp->is_flags & FLG_IS_DISCARD) != 0) ||
1804 1804 ((rep_isp->is_flags & FLG_IS_COMDAT) == 0) ||
1805 1805 (isp->is_indata->d_size != rep_isp->is_indata->d_size) ||
1806 1806 (isp->is_shdr->sh_type != rep_isp->is_shdr->sh_type) ||
1807 1807 ((isp->is_shdr->sh_flags & SHF_GROUP) !=
1808 1808 (rep_isp->is_shdr->sh_flags & SHF_GROUP))) {
1809 1809 *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SECTION;
1810 1810 return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1811 1811 }
1812 1812
1813 1813 /*
1814 1814 * We found the kept COMDAT section. Now, look at all of the
1815 1815 * symbols from the input file that contains it to find the
1816 1816 * symbol that corresponds to the one we started with:
1817 1817 * - Hasn't been discarded
1818 1818 * - Has section index of kept section
1819 1819 * - If one symbol has a name, the other must have
1820 1820 * the same name. The st_name field of a symbol
1821 1821 * is 0 if there is no name, and is a string
1822 1822 * table offset otherwise. The string table
1823 1823 * offsets may well not agree --- it is the
1824 1824 * actual string that matters.
1825 1825 * - Type and binding attributes match (st_info)
1826 1826 * - Values match (st_value)
1827 1827 * - Sizes match (st_size)
1828 1828 * - Visibility matches (st_other)
1829 1829 */
1830 1830 scnndx = rep_isp->is_scnndx;
1831 1831 oldndx = rep_isp->is_file->ifl_oldndx;
1832 1832 symscnt = rep_isp->is_file->ifl_symscnt;
1833 1833 while (symscnt--) {
1834 1834 rep_sdp = *oldndx++;
1835 1835 if ((rep_sdp == NULL) || (rep_sdp->sd_flags & FLG_SY_ISDISC) ||
1836 1836 ((rep_sym = rep_sdp->sd_sym)->st_shndx != scnndx) ||
1837 1837 ((sym->st_name == 0) != (rep_sym->st_name == 0)) ||
1838 1838 ((sym->st_name != 0) &&
1839 1839 (strcmp(sdp->sd_name, rep_sdp->sd_name) != 0)) ||
1840 1840 (sym->st_info != rep_sym->st_info) ||
1841 1841 (sym->st_value != rep_sym->st_value) ||
1842 1842 (sym->st_size != rep_sym->st_size) ||
1843 1843 (sym->st_other != rep_sym->st_other))
1844 1844 continue;
1845 1845
1846 1846
1847 1847 if (ofl->ofl_flags & FLG_OF_VERBOSE) {
1848 1848 if (sym->st_name != 0) {
1849 1849 ld_eprintf(ofl, ERR_WARNING,
1850 1850 MSG_INTL(MSG_REL_SLOPCDATNAM),
1851 1851 conv_reloc_type(ifl->ifl_ehdr->e_machine,
1852 1852 reld->rel_rtype, 0, &inv_buf),
1853 1853 ifl->ifl_name,
1854 1854 EC_WORD(reld->rel_isdesc->is_scnndx),
1855 1855 reld->rel_isdesc->is_name,
1856 1856 rep_sdp->sd_name,
1857 1857 EC_WORD(isp->is_scnndx), isp->is_name,
1858 1858 rep_sdp->sd_file->ifl_name);
1859 1859 } else {
1860 1860 ld_eprintf(ofl, ERR_WARNING,
1861 1861 MSG_INTL(MSG_REL_SLOPCDATNONAM),
1862 1862 conv_reloc_type(ifl->ifl_ehdr->e_machine,
1863 1863 reld->rel_rtype, 0, &inv_buf),
1864 1864 ifl->ifl_name,
1865 1865 EC_WORD(reld->rel_isdesc->is_scnndx),
1866 1866 reld->rel_isdesc->is_name,
1867 1867 EC_WORD(isp->is_scnndx), isp->is_name,
1868 1868 rep_sdp->sd_file->ifl_name);
1869 1869 }
1870 1870 }
1871 1871 DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml, rep_sdp));
1872 1872 *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_NONE;
1873 1873 return (ofl->ofl_sr_cache.sr_rsdp = rep_sdp);
1874 1874 }
1875 1875
1876 1876 /* If didn't return above, we didn't find it */
1877 1877 *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SYMBOL;
1878 1878 return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1879 1879 }
1880 1880
1881 1881 /*
1882 1882 * Generate relocation descriptor and dispatch
1883 1883 */
1884 1884 static uintptr_t
1885 1885 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
1886 1886 Rel *reloc)
1887 1887 {
1888 1888 Ifl_desc *ifl = isp->is_file;
1889 1889 Word rtype = reld->rel_rtype;
1890 1890 Sym_desc *sdp;
1891 1891 Conv_inv_buf_t inv_buf;
1892 1892
1893 1893 /*
1894 1894 * Make sure the relocation is in the valid range.
1895 1895 */
1896 1896 if (rtype >= ld_targ.t_m.m_r_num) {
1897 1897 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT),
1898 1898 ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
1899 1899 rtype);
1900 1900 return (S_ERROR);
1901 1901 }
1902 1902
1903 1903 ofl->ofl_entrelscnt++;
1904 1904
1905 1905 /*
1906 1906 * Special case: a register symbol associated with symbol index 0 is
1907 1907 * initialized (i.e., relocated) to a constant from the r_addend field
1908 1908 * rather than from a symbol value.
1909 1909 */
1910 1910 if (IS_REGISTER(rtype) && (rsndx == 0)) {
1911 1911 reld->rel_sym = NULL;
1912 1912 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1913 1913 ld_targ.t_m.m_mach, isp->is_shdr->sh_type,
1914 1914 (void *)reloc, isp->is_name, isp->is_scnndx,
1915 1915 ld_reloc_sym_name(reld)));
1916 1916 if (ld_targ.t_mr.mr_reloc_register == NULL) {
1917 1917 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
1918 1918 return (S_ERROR);
1919 1919 }
1920 1920 return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1921 1921 }
1922 1922
1923 1923 /*
1924 1924 * If this is a STT_SECTION symbol, make sure the associated
1925 1925 * section has a descriptive non-NULL is_sym_name field that can
1926 1926 * be accessed by ld_reloc_sym_name() to satisfy debugging output
1927 1927 * and errors.
1928 1928 *
1929 1929 * In principle, we could add this string to every input section
1930 1930 * as it is created, but we defer it until we see a relocation
1931 1931 * symbol that might need it. Not every section will have such
1932 1932 * a relocation, so we create fewer of them this way.
1933 1933 */
1934 1934 sdp = reld->rel_sym = ifl->ifl_oldndx[rsndx];
1935 1935 if ((sdp != NULL) &&
1936 1936 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
1937 1937 (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL) &&
1938 1938 (sdp->sd_isc->is_sym_name == NULL) &&
1939 1939 (ld_stt_section_sym_name(sdp->sd_isc) == NULL))
1940 1940 return (S_ERROR);
1941 1941
1942 1942 /*
1943 1943 * If for some reason we have a null relocation record issue a
1944 1944 * warning and continue (the compiler folks can get into this
1945 1945 * state some time). Normal users should never see this error.
1946 1946 */
1947 1947 if (rtype == ld_targ.t_m.m_r_none) {
1948 1948 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1949 1949 ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type,
1950 1950 (void *)reloc, isp->is_name, isp->is_scnndx,
1951 1951 ld_reloc_sym_name(reld)));
1952 1952 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
1953 1953 ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
1954 1954 return (1);
1955 1955 }
1956 1956
1957 1957 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
1958 1958 IS_NOTSUP(rtype)) {
1959 1959 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
1960 1960 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1961 1961 0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
1962 1962 isp->is_name);
1963 1963 return (S_ERROR);
1964 1964 }
1965 1965
1966 1966 /*
1967 1967 * If we are here, we know that the relocation requires reference
1968 1968 * symbol. If no symbol is assigned, this is a fatal error.
1969 1969 */
1970 1970 if (sdp == NULL) {
1971 1971 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
1972 1972 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1973 1973 0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
1974 1974 isp->is_name, EC_XWORD(reloc->r_offset));
1975 1975 return (S_ERROR);
1976 1976 }
1977 1977
1978 1978 if (sdp->sd_flags & FLG_SY_IGNORE)
1979 1979 return (1);
1980 1980
1981 1981 /*
1982 1982 * If this symbol is part of a DISCARDED section attempt to find another
1983 1983 * definition.
1984 1984 */
1985 1985 if (sdp->sd_flags & FLG_SY_ISDISC) {
1986 1986 Sym_desc *nsdp = NULL;
1987 1987 Rlxrel_rej reject;
1988 1988
1989 1989 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1990 1990 /*
1991 1991 * If "-z relaxreloc", and the input section is COMDAT
1992 1992 * that has been assigned to an output section, then
1993 1993 * determine if this is a reference to a discarded
1994 1994 * COMDAT section that can be replaced with a COMDAT
1995 1995 * that has been kept.
1996 1996 */
1997 1997 if ((ofl->ofl_flags1 & FLG_OF1_RLXREL) &&
1998 1998 sdp->sd_isc->is_osdesc &&
1999 1999 (sdp->sd_isc->is_flags & FLG_IS_COMDAT) &&
2000 2000 ((nsdp = sloppy_comdat_reloc(ofl, reld,
2001 2001 sdp, &reject)) == NULL)) {
2002 2002 Shdr *is_shdr = reld->rel_isdesc->is_shdr;
2003 2003
2004 2004 /*
2005 2005 * A matching symbol was not found. We will
2006 2006 * ignore this relocation. Determine whether
2007 2007 * or not to issue a warning.
2008 2008 * Warnings are always issued under -z verbose,
2009 2009 * but otherwise, we will follow the lead of
2010 2010 * the GNU ld and suppress them for certain
2011 2011 * cases:
2012 2012 *
2013 2013 * - It is a non-allocable debug section.
2014 2014 * The GNU ld tests for these by name,
2015 2015 * but we are willing to extend it to
2016 2016 * any non-allocable section.
2017 2017 * - The target section is excluded from
2018 2018 * sloppy relocations by policy.
2019 2019 */
2020 2020 if (((ofl->ofl_flags & FLG_OF_VERBOSE) != 0) ||
2021 2021 ((is_shdr->sh_flags & SHF_ALLOC) &&
2022 2022 (reject != RLXREL_REJ_TARGET)))
2023 2023 ld_eprintf(ofl, ERR_WARNING,
2024 2024 MSG_INTL(MSG_REL_SLOPCDATNOSYM),
2025 2025 conv_reloc_type(
2026 2026 ifl->ifl_ehdr->e_machine,
2027 2027 reld->rel_rtype, 0, &inv_buf),
2028 2028 ifl->ifl_name,
2029 2029 EC_WORD(isp->is_scnndx),
2030 2030 isp->is_name,
2031 2031 ld_reloc_sym_name(reld),
2032 2032 EC_WORD(sdp->sd_isc->is_scnndx),
2033 2033 sdp->sd_isc->is_name);
2034 2034 return (1);
2035 2035 }
2036 2036 } else if ((sdp != NULL) && sdp->sd_name && *sdp->sd_name)
2037 2037 nsdp = ld_sym_find(sdp->sd_name, SYM_NOHASH, NULL, ofl);
2038 2038
2039 2039 if (nsdp == NULL) {
2040 2040 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC),
2041 2041 conv_reloc_type(ifl->ifl_ehdr->e_machine,
2042 2042 reld->rel_rtype, 0, &inv_buf), ifl->ifl_name,
2043 2043 EC_WORD(isp->is_scnndx), isp->is_name,
2044 2044 ld_reloc_sym_name(reld),
2045 2045 EC_WORD(sdp->sd_isc->is_scnndx),
2046 2046 sdp->sd_isc->is_name);
2047 2047 return (S_ERROR);
2048 2048 }
2049 2049 ifl->ifl_oldndx[rsndx] = sdp = nsdp;
2050 2050 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
2051 2051 (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL) &&
2052 2052 (sdp->sd_isc->is_sym_name == NULL) &&
2053 2053 (ld_stt_section_sym_name(sdp->sd_isc) == NULL))
2054 2054 return (S_ERROR);
2055 2055 }
2056 2056
2057 2057 /*
2058 2058 * If this is a global symbol, determine whether its visibility needs
2059 2059 * adjusting.
2060 2060 */
2061 2061 if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0))
2062 2062 ld_sym_adjust_vis(sdp, ofl);
2063 2063
2064 2064 /*
2065 2065 * Ignore any relocation against a section that will not be in the
2066 2066 * output file (has been stripped).
2067 2067 */
2068 2068 if ((sdp->sd_isc == 0) &&
2069 2069 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))
2070 2070 return (1);
2071 2071
2072 2072 /*
2073 2073 * If the input section exists, but the section has not been associated
2074 2074 * to an output section, then this is a little suspicious.
2075 2075 */
2076 2076 if (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0) &&
2077 2077 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
2078 2078 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_RELINVSEC),
2079 2079 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2080 2080 0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2081 2081 isp->is_name, EC_WORD(sdp->sd_isc->is_scnndx),
2082 2082 sdp->sd_isc->is_name);
2083 2083 return (1);
2084 2084 }
2085 2085
2086 2086 /*
2087 2087 * If the symbol for this relocation is invalid (which should have
2088 2088 * generated a message during symbol processing), or the relocation
2089 2089 * record's symbol reference is in any other way invalid, then it's
2090 2090 * about time we gave up.
2091 2091 */
2092 2092 if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
2093 2093 (rsndx >= ifl->ifl_symscnt)) {
2094 2094 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
2095 2095 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2096 2096 0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2097 2097 isp->is_name, ld_reloc_sym_name(reld),
2098 2098 EC_XWORD(reloc->r_offset), EC_WORD(rsndx));
2099 2099 return (S_ERROR);
2100 2100 }
2101 2101
2102 2102 /*
2103 2103 * Size relocations against section symbols are presently unsupported.
2104 2104 * There is a question as to whether the input section size, or output
2105 2105 * section size would be used. Until an explicit requirement is
2106 2106 * established for either case, we'll punt.
2107 2107 */
2108 2108 if (IS_SIZE(rtype) &&
2109 2109 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
2110 2110 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE),
2111 2111 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2112 2112 0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2113 2113 isp->is_name);
2114 2114 return (S_ERROR);
2115 2115 }
2116 2116
2117 2117 reld->rel_sym = sdp;
2118 2118 if (reld->rel_aux)
2119 2119 reld->rel_aux->ra_usym = sdp;
2120 2120 return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name,
2121 2121 isp->is_scnndx));
2122 2122 }
2123 2123
2124 2124 static uintptr_t
2125 2125 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect)
2126 2126 {
2127 2127 Rel *rend; /* end of relocation section data */
2128 2128 Rel *reloc; /* current relocation entry */
2129 2129 Xword rsize; /* size of relocation section data */
2130 2130 Xword entsize; /* size of relocation entry */
2131 2131 Rel_desc reld; /* relocation descriptor */
2132 2132 Rel_aux rel_aux;
2133 2133 Shdr * shdr;
2134 2134 Word flags = 0;
2135 2135 uintptr_t ret = 1;
2136 2136
2137 2137 shdr = rsect->is_shdr;
2138 2138 rsize = shdr->sh_size;
2139 2139 reloc = (Rel *)rsect->is_indata->d_buf;
2140 2140
2141 2141 /*
2142 2142 * Decide entry size.
2143 2143 */
2144 2144 if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) {
2145 2145 if (shdr->sh_type == SHT_RELA)
2146 2146 entsize = sizeof (Rela);
2147 2147 else
2148 2148 entsize = sizeof (Rel);
2149 2149 }
2150 2150
2151 2151 /*
2152 2152 * Build up the basic information in for the Rel_desc structure.
2153 2153 */
2154 2154 reld.rel_isdesc = isect;
2155 2155 reld.rel_aux = &rel_aux;
2156 2156 ld_init_rel_aux(&reld);
2157 2157 rel_aux.ra_osdesc = osect;
2158 2158
2159 2159 if ((ofl->ofl_flags & FLG_OF_RELOBJ) ||
2160 2160 (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD)))
2161 2161 flags |= FLG_REL_LOAD;
2162 2162
2163 2163 if (shdr->sh_info == 0)
2164 2164 flags |= FLG_REL_NOINFO;
2165 2165
2166 2166 DBG_CALL(Dbg_reloc_proc(ofl->ofl_lml, osect, isect, rsect));
2167 2167
2168 2168 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
2169 2169 reloc < rend;
2170 2170 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
2171 2171 Word rsndx;
2172 2172
2173 2173 /*
2174 2174 * Initialize the relocation record information and process
2175 2175 * the individual relocation. Reinitialize the flags to
2176 2176 * insure we don't carry any state over from the previous
2177 2177 * relocation records processing.
2178 2178 */
2179 2179 reld.rel_flags = flags;
2180 2180 rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld,
2181 2181 &rel_aux.ra_typedata, (void *)reloc);
2182 2182
2183 2183 /*
2184 2184 * Determine whether or not to pass an auxiliary block
2185 2185 * in with this Rel_desc. It is not needed if both the
2186 2186 * osdesc and typedata fields have default values.
2187 2187 */
2188 2188 reld.rel_aux =
2189 2189 (RELAUX_ISDEFAULT_OSDESC(&reld, rel_aux.ra_osdesc) &&
2190 2190 RELAUX_ISDEFAULT_TYPEDATA(&reld, rel_aux.ra_typedata)) ?
2191 2191 NULL : &rel_aux;
2192 2192
2193 2193 if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR)
2194 2194 ret = S_ERROR;
2195 2195 }
2196 2196 return (ret);
2197 2197 }
2198 2198
2199 2199 static uintptr_t
2200 2200 reloc_segments(int wr_flag, Ofl_desc *ofl)
2201 2201 {
2202 2202 Aliste idx1;
2203 2203 Sg_desc *sgp;
2204 2204 Is_desc *isp;
2205 2205
2206 2206 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
2207 2207 Os_desc *osp;
2208 2208 Aliste idx2;
2209 2209
2210 2210 if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag)
2211 2211 continue;
2212 2212
2213 2213 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
2214 2214 Is_desc *risp;
2215 2215 Aliste idx3;
2216 2216
2217 2217 osp->os_szoutrels = 0;
2218 2218 for (APLIST_TRAVERSE(osp->os_relisdescs, idx3, risp)) {
2219 2219 Word indx;
2220 2220
2221 2221 /*
2222 2222 * Determine the input section that this
2223 2223 * relocation information refers to.
2224 2224 */
2225 2225 indx = risp->is_shdr->sh_info;
2226 2226 isp = risp->is_file->ifl_isdesc[indx];
2227 2227
2228 2228 /*
2229 2229 * Do not process relocations against sections
2230 2230 * which are being discarded (COMDAT)
2231 2231 */
2232 2232 if (isp->is_flags & FLG_IS_DISCARD)
2233 2233 continue;
2234 2234
2235 2235 if (reloc_section(ofl, isp, risp, osp) ==
2236 2236 S_ERROR)
2237 2237 return (S_ERROR);
2238 2238 }
2239 2239
2240 2240 /*
2241 2241 * Check for relocations against non-writable
2242 2242 * allocatable sections.
2243 2243 */
2244 2244 if (osp->os_szoutrels &&
2245 2245 (sgp->sg_phdr.p_type == PT_LOAD) &&
2246 2246 ((sgp->sg_phdr.p_flags & PF_W) == 0)) {
2247 2247 ofl->ofl_flags |= FLG_OF_TEXTREL;
2248 2248 ofl->ofl_dtflags |= DF_TEXTREL;
2249 2249 }
2250 2250 }
2251 2251 }
2252 2252
2253 2253 return (1);
2254 2254 }
2255 2255
2256 2256 /*
↓ open down ↓ |
2162 lines elided |
↑ open up ↑ |
2257 2257 * Move Section related function
2258 2258 * Get move entry
2259 2259 */
2260 2260 static Move *
2261 2261 get_move_entry(Is_desc *rsect, Xword roffset)
2262 2262 {
2263 2263 Ifl_desc *ifile = rsect->is_file;
2264 2264 Shdr *rshdr = rsect->is_shdr;
2265 2265 Is_desc *misp;
2266 2266 Shdr *mshdr;
2267 - Xword midx;
2267 + Xword midx;
2268 2268 Move *mvp;
2269 2269
2270 2270 /*
2271 2271 * Set info for the target move section
2272 2272 */
2273 2273 misp = ifile->ifl_isdesc[rshdr->sh_info];
2274 2274 mshdr = misp->is_shdr;
2275 2275
2276 2276 if (mshdr->sh_entsize == 0)
2277 2277 return (NULL);
2278 2278
2279 2279 /*
2280 2280 * If this is an invalid entry, return NULL.
2281 2281 */
2282 2282 midx = roffset / mshdr->sh_entsize;
2283 2283 if ((midx * mshdr->sh_entsize) >= mshdr->sh_size)
2284 2284 return (NULL);
2285 2285
2286 2286 mvp = (Move *)misp->is_indata->d_buf;
2287 2287 mvp += midx;
2288 2288 return (mvp);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
2289 2289 }
2290 2290
2291 2291 /*
2292 2292 * Relocation against Move Table.
2293 2293 */
2294 2294 static uintptr_t
2295 2295 process_movereloc(Ofl_desc *ofl, Is_desc *rsect)
2296 2296 {
2297 2297 Ifl_desc *file = rsect->is_file;
2298 2298 Rel *rend, *reloc;
2299 - Xword rsize, entsize;
2300 - Rel_desc reld;
2299 + Xword rsize, entsize;
2300 + Rel_desc reld;
2301 2301 Rel_aux rel_aux;
2302 2302
2303 2303 rsize = rsect->is_shdr->sh_size;
2304 2304 reloc = (Rel *)rsect->is_indata->d_buf;
2305 2305
2306 2306 /*
2307 2307 * Decide entry size.
2308 2308 */
2309 2309 entsize = rsect->is_shdr->sh_entsize;
2310 2310 if ((entsize == 0) ||
2311 2311 (entsize > rsect->is_shdr->sh_size)) {
2312 2312 if (rsect->is_shdr->sh_type == SHT_RELA)
2313 2313 entsize = sizeof (Rela);
2314 2314 else
2315 2315 entsize = sizeof (Rel);
2316 2316 }
2317 2317
2318 2318 /*
2319 2319 * The requirement for move data ensures that we have to supply a
2320 2320 * Rel_aux auxiliary block.
2321 2321 */
2322 2322 reld.rel_aux = &rel_aux;
2323 2323 ld_init_rel_aux(&reld);
2324 2324
2325 2325 /*
2326 2326 * Go through the relocation entries.
2327 2327 */
2328 2328 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
2329 2329 reloc < rend;
2330 2330 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
2331 2331 Sym_desc *psdp;
2332 2332 Move *mvp;
2333 2333 Word rsndx;
2334 2334
2335 2335 /*
2336 2336 * Initialize the relocation record information.
2337 2337 */
2338 2338 reld.rel_flags = FLG_REL_LOAD;
2339 2339 rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld,
2340 2340 &rel_aux.ra_typedata, (void *)reloc);
2341 2341
2342 2342 if (((mvp = get_move_entry(rsect, reloc->r_offset)) == NULL) ||
2343 2343 ((rel_aux.ra_move =
2344 2344 libld_malloc(sizeof (Mv_reloc))) == NULL))
2345 2345 return (S_ERROR);
2346 2346
2347 2347 psdp = file->ifl_oldndx[ELF_M_SYM(mvp->m_info)];
2348 2348 rel_aux.ra_move->mr_move = mvp;
2349 2349 rel_aux.ra_move->mr_sym = psdp;
2350 2350
2351 2351 if (psdp->sd_flags & FLG_SY_PAREXPN) {
2352 2352 int _num, num = mvp->m_repeat;
2353 2353
2354 2354 rel_aux.ra_osdesc = ofl->ofl_isparexpn->is_osdesc;
2355 2355 reld.rel_isdesc = ofl->ofl_isparexpn;
2356 2356 reld.rel_roffset = mvp->m_poffset;
2357 2357
2358 2358 for (_num = 0; _num < num; _num++) {
2359 2359 reld.rel_roffset +=
2360 2360 /* LINTED */
2361 2361 (_num * ELF_M_SIZE(mvp->m_info));
2362 2362
2363 2363 /*
2364 2364 * Generate Reld
2365 2365 */
2366 2366 if (process_reld(ofl,
2367 2367 rsect, &reld, rsndx, reloc) == S_ERROR)
2368 2368 return (S_ERROR);
2369 2369 }
2370 2370 } else {
2371 2371 /*
2372 2372 * Generate Reld
2373 2373 */
2374 2374 reld.rel_flags |= FLG_REL_MOVETAB;
2375 2375 rel_aux.ra_osdesc = ofl->ofl_osmove;
2376 2376 reld.rel_isdesc = ld_os_first_isdesc(ofl->ofl_osmove);
2377 2377
2378 2378 if (process_reld(ofl,
2379 2379 rsect, &reld, rsndx, reloc) == S_ERROR)
2380 2380 return (S_ERROR);
2381 2381 }
2382 2382 }
2383 2383 return (1);
2384 2384 }
2385 2385
2386 2386 /*
2387 2387 * This function is similar to reloc_init().
2388 2388 *
2389 2389 * This function is called when the SHT_SUNW_move table is expanded and there
2390 2390 * are relocations against the SHT_SUNW_move section.
2391 2391 */
2392 2392 static uintptr_t
2393 2393 reloc_movesections(Ofl_desc *ofl)
2394 2394 {
2395 2395 Aliste idx;
2396 2396 Is_desc *risp;
2397 2397 uintptr_t ret = 1;
2398 2398
2399 2399 /*
2400 2400 * Generate/Expand relocation entries
2401 2401 */
2402 2402 for (APLIST_TRAVERSE(ofl->ofl_ismoverel, idx, risp)) {
2403 2403 if (process_movereloc(ofl, risp) == S_ERROR)
2404 2404 ret = S_ERROR;
2405 2405 }
2406 2406
2407 2407 return (ret);
2408 2408 }
2409 2409
2410 2410 /*
2411 2411 * Count the number of output relocation entries, global offset table entries,
2412 2412 * and procedure linkage table entries. This function searches the segment and
2413 2413 * outsect lists and passes each input reloc section to process_reloc().
2414 2414 * It allocates space for any output relocations needed. And builds up
2415 2415 * the relocation structures for later processing.
2416 2416 */
2417 2417 uintptr_t
2418 2418 ld_reloc_init(Ofl_desc *ofl)
2419 2419 {
2420 2420 Aliste idx;
2421 2421 Is_desc *isp;
2422 2422 Sym_desc *sdp;
2423 2423
2424 2424 DBG_CALL(Dbg_basic_collect(ofl->ofl_lml));
2425 2425
2426 2426 /*
2427 2427 * At this point we have finished processing all input symbols. Make
2428 2428 * sure we add any absolute (internal) symbols before continuing with
2429 2429 * any relocation processing.
2430 2430 */
2431 2431 if (ld_sym_spec(ofl) == S_ERROR)
2432 2432 return (S_ERROR);
2433 2433
2434 2434 ofl->ofl_gotcnt = ld_targ.t_m.m_got_xnumber;
2435 2435
2436 2436 /*
2437 2437 * Process all of the relocations against NON-writable segments
2438 2438 * followed by relocations against the writable segments.
2439 2439 *
2440 2440 * This separation is so that when the writable segments are processed
2441 2441 * we know whether or not a COPYRELOC will be produced for any symbols.
2442 2442 * If relocations aren't processed in this order, a COPYRELOC and a
2443 2443 * regular relocation can be produced against the same symbol. The
2444 2444 * regular relocation would be redundant.
2445 2445 */
2446 2446 if (reloc_segments(0, ofl) == S_ERROR)
2447 2447 return (S_ERROR);
2448 2448
2449 2449 if (reloc_segments(PF_W, ofl) == S_ERROR)
2450 2450 return (S_ERROR);
2451 2451
2452 2452 /*
2453 2453 * Process any extra relocations. These are relocation sections that
2454 2454 * have a NULL sh_info.
2455 2455 */
2456 2456 for (APLIST_TRAVERSE(ofl->ofl_extrarels, idx, isp)) {
2457 2457 if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR)
2458 2458 return (S_ERROR);
2459 2459 }
2460 2460
2461 2461 /*
2462 2462 * If there were relocation against move table,
2463 2463 * process the relocation sections.
2464 2464 */
2465 2465 if (reloc_movesections(ofl) == S_ERROR)
2466 2466 return (S_ERROR);
2467 2467
2468 2468 /*
2469 2469 * Now all the relocations are pre-processed,
2470 2470 * check the validity of copy relocations.
2471 2471 */
2472 2472 if (ofl->ofl_copyrels) {
2473 2473 Copy_rel *crp;
2474 2474
2475 2475 for (ALIST_TRAVERSE(ofl->ofl_copyrels, idx, crp)) {
2476 2476 /*
2477 2477 * If there were no displacement relocation
2478 2478 * in this file, don't worry about it.
2479 2479 */
2480 2480 if (crp->c_sdp->sd_file->ifl_flags &
2481 2481 (FLG_IF_DISPPEND | FLG_IF_DISPDONE))
2482 2482 is_disp_copied(ofl, crp);
2483 2483 }
2484 2484 }
2485 2485
2486 2486 /*
2487 2487 * GOT sections are created for dynamic executables and shared objects
2488 2488 * if the FLG_OF_BLDGOT is set, or explicit reference has been made to
2489 2489 * a GOT symbol.
2490 2490 */
2491 2491 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
2492 2492 ((ofl->ofl_flags & FLG_OF_BLDGOT) ||
2493 2493 ((((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL),
2494 2494 SYM_NOHASH, NULL, ofl)) != NULL) ||
2495 2495 ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
2496 2496 SYM_NOHASH, NULL, ofl)) != NULL)) &&
2497 2497 (sdp->sd_ref != REF_DYN_SEEN)))) {
2498 2498 if (ld_make_got(ofl) == S_ERROR)
2499 2499 return (S_ERROR);
2500 2500
2501 2501 /* Allocate the GOT if required by target */
2502 2502 if ((ld_targ.t_mr.mr_allocate_got != NULL) &&
2503 2503 ((*ld_targ.t_mr.mr_allocate_got)(ofl) == S_ERROR))
2504 2504 return (S_ERROR);
2505 2505 }
2506 2506
2507 2507 return (1);
2508 2508 }
2509 2509
2510 2510 /*
2511 2511 * Simple comparison routine to be used by qsort() for
2512 2512 * the sorting of the output relocation list.
2513 2513 *
2514 2514 * The reloc_compare() routine results in a relocation
2515 2515 * table which is located on:
2516 2516 *
2517 2517 * file referenced (NEEDED NDX)
2518 2518 * referenced symbol
2519 2519 * relocation offset
2520 2520 *
2521 2521 * This provides the most efficient traversal of the relocation
2522 2522 * table at run-time.
2523 2523 */
2524 2524 static int
2525 2525 reloc_compare(Reloc_list *i, Reloc_list *j)
2526 2526 {
2527 2527
2528 2528 /*
2529 2529 * first - sort on neededndx
2530 2530 */
2531 2531 if (i->rl_key1 > j->rl_key1)
2532 2532 return (1);
2533 2533 if (i->rl_key1 < j->rl_key1)
2534 2534 return (-1);
2535 2535
2536 2536 /*
2537 2537 * Then sort on symbol
2538 2538 */
2539 2539 if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2)
2540 2540 return (1);
2541 2541 if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2)
2542 2542 return (-1);
2543 2543
2544 2544 /*
2545 2545 * i->key2 == j->key2
2546 2546 *
2547 2547 * At this point we fall back to key2 (offsets) to
2548 2548 * sort the output relocations. Ideally this will
2549 2549 * make for the most efficient processing of these
2550 2550 * relocations at run-time.
2551 2551 */
2552 2552 if (i->rl_key3 > j->rl_key3)
2553 2553 return (1);
2554 2554 if (i->rl_key3 < j->rl_key3)
2555 2555 return (-1);
2556 2556 return (0);
2557 2557 }
2558 2558
2559 2559 static uintptr_t
2560 2560 do_sorted_outrelocs(Ofl_desc *ofl)
2561 2561 {
2562 2562 Rel_desc *orsp;
2563 2563 Rel_cachebuf *rcbp;
2564 2564 Aliste idx;
2565 2565 Reloc_list *sorted_list;
2566 2566 Word index = 0;
2567 2567 int debug = 0;
2568 2568 uintptr_t error = 1;
2569 2569 Boolean remain_seen = FALSE;
2570 2570
2571 2571 if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) *
2572 2572 ofl->ofl_reloccnt))) == NULL)
2573 2573 return (S_ERROR);
2574 2574
2575 2575 /*
2576 2576 * All but the PLT output relocations are sorted in the output file
2577 2577 * based upon their sym_desc. By doing this multiple relocations
2578 2578 * against the same symbol are grouped together, thus when the object
2579 2579 * is later relocated by ld.so.1 it will take advantage of the symbol
2580 2580 * cache that ld.so.1 has. This can significantly reduce the runtime
2581 2581 * relocation cost of a dynamic object.
2582 2582 *
2583 2583 * PLT relocations are not sorted because the order of the PLT
2584 2584 * relocations is used by ld.so.1 to determine what symbol a PLT
2585 2585 * relocation is against.
2586 2586 */
2587 2587 REL_CACHE_TRAVERSE(&ofl->ofl_outrels, idx, rcbp, orsp) {
2588 2588 if (debug == 0) {
2589 2589 DBG_CALL(Dbg_reloc_dooutrel(ofl->ofl_lml,
2590 2590 ld_targ.t_m.m_rel_sht_type));
2591 2591 debug = 1;
2592 2592 }
2593 2593
2594 2594 /*
2595 2595 * If it's a PLT relocation we output it now in the
2596 2596 * order that it was originally processed.
2597 2597 */
2598 2598 if (orsp->rel_flags & FLG_REL_PLT) {
2599 2599 if ((*ld_targ.t_mr.mr_perform_outreloc)
2600 2600 (orsp, ofl, &remain_seen) == S_ERROR)
2601 2601 error = S_ERROR;
2602 2602 continue;
2603 2603 }
2604 2604
2605 2605 if ((orsp->rel_rtype == ld_targ.t_m.m_r_relative) ||
2606 2606 (orsp->rel_rtype == ld_targ.t_m.m_r_register)) {
2607 2607 sorted_list[index].rl_key1 = 0;
2608 2608 sorted_list[index].rl_key2 =
2609 2609 /* LINTED */
2610 2610 (Sym_desc *)(uintptr_t)orsp->rel_rtype;
2611 2611 } else {
2612 2612 sorted_list[index].rl_key1 =
2613 2613 orsp->rel_sym->sd_file->ifl_neededndx;
2614 2614 sorted_list[index].rl_key2 = orsp->rel_sym;
2615 2615 }
2616 2616
2617 2617 if (orsp->rel_flags & FLG_REL_GOT) {
2618 2618 sorted_list[index].rl_key3 =
2619 2619 (*ld_targ.t_mr.mr_calc_got_offset)(orsp, ofl);
2620 2620 } else {
2621 2621 if (orsp->rel_rtype == ld_targ.t_m.m_r_register) {
2622 2622 sorted_list[index].rl_key3 = 0;
2623 2623 } else {
2624 2624 sorted_list[index].rl_key3 = orsp->rel_roffset +
2625 2625 (Xword)_elf_getxoff(orsp->
2626 2626 rel_isdesc->is_indata) +
2627 2627 orsp->rel_isdesc->is_osdesc->
2628 2628 os_shdr->sh_addr;
2629 2629 }
2630 2630 }
2631 2631
2632 2632 sorted_list[index++].rl_rsp = orsp;
2633 2633 }
2634 2634
2635 2635 qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list),
2636 2636 (int (*)(const void *, const void *))reloc_compare);
2637 2637
2638 2638 /*
2639 2639 * All output relocations have now been sorted, go through
2640 2640 * and process each relocation.
2641 2641 */
2642 2642 for (index = 0; index < ofl->ofl_reloccnt; index++) {
2643 2643 if ((*ld_targ.t_mr.mr_perform_outreloc)
2644 2644 (sorted_list[index].rl_rsp, ofl, &remain_seen) == S_ERROR)
2645 2645 error = S_ERROR;
2646 2646 }
2647 2647
2648 2648 /* Guidance: Use -z text when building shared objects */
2649 2649 if (remain_seen && OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
2650 2650 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_TEXT));
2651 2651
2652 2652 return (error);
2653 2653 }
2654 2654
2655 2655 /*
2656 2656 * Process relocations. Finds every input relocation section for each output
2657 2657 * section and invokes reloc_section() to relocate that section.
2658 2658 */
2659 2659 uintptr_t
2660 2660 ld_reloc_process(Ofl_desc *ofl)
2661 2661 {
2662 2662 Sg_desc *sgp;
2663 2663 Os_desc *osp;
2664 2664 Word ndx = 0;
2665 2665 ofl_flag_t flags = ofl->ofl_flags;
2666 2666 Shdr *shdr;
2667 2667
2668 2668 DBG_CALL(Dbg_basic_relocate(ofl->ofl_lml));
2669 2669
2670 2670 /*
2671 2671 * Determine the index of the symbol table that will be referenced by
2672 2672 * the relocation entries.
2673 2673 */
2674 2674 if (OFL_ALLOW_DYNSYM(ofl))
2675 2675 /* LINTED */
2676 2676 ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
2677 2677 else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
2678 2678 /* LINTED */
2679 2679 ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
2680 2680
2681 2681 /*
2682 2682 * Re-initialize counters. These are used to provide relocation
2683 2683 * offsets within the output buffers.
2684 2684 */
2685 2685 ofl->ofl_relocpltsz = 0;
2686 2686 ofl->ofl_relocgotsz = 0;
2687 2687 ofl->ofl_relocbsssz = 0;
2688 2688
2689 2689 /*
2690 2690 * Now that the output file is created and symbol update has occurred,
2691 2691 * process the relocations collected in process_reloc().
2692 2692 */
2693 2693 if (do_sorted_outrelocs(ofl) == S_ERROR)
2694 2694 return (S_ERROR);
2695 2695
2696 2696 if ((*ld_targ.t_mr.mr_do_activerelocs)(ofl) == S_ERROR)
2697 2697 return (S_ERROR);
2698 2698
2699 2699 if ((flags & FLG_OF_COMREL) == 0) {
2700 2700 Aliste idx1;
2701 2701
2702 2702 /*
2703 2703 * Process the relocation sections. For each relocation
2704 2704 * section generated for the output image update its shdr
2705 2705 * information to reflect the symbol table it needs (sh_link)
2706 2706 * and the section to which the relocation must be applied
2707 2707 * (sh_info).
2708 2708 */
2709 2709 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
2710 2710 Os_desc *osp;
2711 2711 Aliste idx2;
2712 2712
2713 2713 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
2714 2714 if (osp->os_relosdesc == 0)
2715 2715 continue;
2716 2716
2717 2717 shdr = osp->os_relosdesc->os_shdr;
2718 2718 shdr->sh_link = ndx;
2719 2719 /* LINTED */
2720 2720 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2721 2721 }
2722 2722 }
2723 2723
2724 2724 /*
2725 2725 * Since the .rel[a] section is not tied to any specific
2726 2726 * section, we'd not have found it above.
2727 2727 */
2728 2728 if ((osp = ofl->ofl_osrel) != NULL) {
2729 2729 shdr = osp->os_shdr;
2730 2730 shdr->sh_link = ndx;
2731 2731 shdr->sh_info = 0;
2732 2732 }
2733 2733 } else {
2734 2734 /*
2735 2735 * We only have two relocation sections here, (PLT's,
2736 2736 * coalesced) so just hit them directly instead of stepping
2737 2737 * over the output sections.
2738 2738 */
2739 2739 if ((osp = ofl->ofl_osrelhead) != NULL) {
2740 2740 shdr = osp->os_shdr;
2741 2741 shdr->sh_link = ndx;
2742 2742 shdr->sh_info = 0;
2743 2743 }
2744 2744 if (((osp = ofl->ofl_osplt) != NULL) && osp->os_relosdesc) {
2745 2745 shdr = osp->os_relosdesc->os_shdr;
2746 2746 shdr->sh_link = ndx;
2747 2747 /* LINTED */
2748 2748 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2749 2749 }
2750 2750 }
2751 2751
2752 2752 /*
2753 2753 * If the -z text option was given, and we have output relocations
2754 2754 * against a non-writable, allocatable section, issue a diagnostic and
2755 2755 * return (the actual entries that caused this error would have been
2756 2756 * output during the relocating section phase).
2757 2757 */
2758 2758 if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) ==
2759 2759 (FLG_OF_PURETXT | FLG_OF_TEXTREL)) {
2760 2760 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
2761 2761 return (S_ERROR);
2762 2762 }
2763 2763
2764 2764 /*
2765 2765 * Finally, initialize the first got entry with the address of the
2766 2766 * .dynamic section (_DYNAMIC).
2767 2767 */
2768 2768 if (flags & FLG_OF_DYNAMIC) {
2769 2769 if ((*ld_targ.t_mr.mr_fillin_gotplt)(ofl) == S_ERROR)
2770 2770 return (S_ERROR);
2771 2771 }
2772 2772
2773 2773 /*
2774 2774 * Now that any GOT information has been written, display the debugging
2775 2775 * information if required.
2776 2776 */
2777 2777 if ((osp = ofl->ofl_osgot) != NULL)
2778 2778 DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1,
2779 2779 ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
2780 2780
2781 2781 return (1);
2782 2782 }
2783 2783
2784 2784 /*
2785 2785 * If the -z text option was given, and we have output relocations against a
2786 2786 * non-writable, allocatable section, issue a diagnostic. Print offending
2787 2787 * symbols in tabular form similar to the way undefined symbols are presented.
2788 2788 * Called from reloc_count(). The actual fatal error condition is triggered on
2789 2789 * in reloc_process() above.
2790 2790 *
2791 2791 * Note. For historic reasons -ztext is not a default option (however all OS
2792 2792 * shared object builds use this option). It can be argued that this option
2793 2793 * should also be default when generating an a.out (see 1163979). However, if
2794 2794 * an a.out contains text relocations it is either because the user is creating
2795 2795 * something pretty weird (they've used the -b or -znodefs options), or because
2796 2796 * the library against which they're building wasn't constructed correctly (ie.
2797 2797 * a function has a NOTYPE type, in which case the a.out won't generate an
2798 2798 * associated plt). In the latter case the builder of the a.out can't do
2799 2799 * anything to fix the error - thus we've chosen not to give the user an error,
2800 2800 * or warning, for this case.
2801 2801 */
2802 2802 void
2803 2803 ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl,
2804 2804 Boolean *remain_seen)
2805 2805 {
2806 2806
2807 2807 /*
2808 2808 * -ztextoff
2809 2809 */
2810 2810 if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)
2811 2811 return;
2812 2812
2813 2813 /*
2814 2814 * Only give relocation errors against loadable read-only segments.
2815 2815 */
2816 2816 if ((orsp->rel_rtype == ld_targ.t_m.m_r_register) || (!osp) ||
2817 2817 (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) ||
2818 2818 (osp->os_sgdesc->sg_phdr.p_flags & PF_W))
2819 2819 return;
2820 2820
2821 2821 /*
2822 2822 * If we are in -ztextwarn mode, it's a silent error if a relocation is
2823 2823 * due to a 'WEAK REFERENCE'. This is because if the symbol is not
2824 2824 * provided at run-time we will not perform a text-relocation.
2825 2825 */
2826 2826 if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) &&
2827 2827 (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) &&
2828 2828 (orsp->rel_sym->sd_sym->st_shndx == SHN_UNDEF))
2829 2829 return;
2830 2830
2831 2831 if (*remain_seen == FALSE) {
2832 2832 /*
2833 2833 * If building with '-ztext' then emit a fatal error. If
2834 2834 * building a executable then only emit a 'warning'.
2835 2835 */
2836 2836 const char *str1 = (ofl->ofl_flags & FLG_OF_PURETXT) ?
2837 2837 MSG_INTL(MSG_REL_RMN_ITM_11) : MSG_INTL(MSG_REL_RMN_ITM_13);
2838 2838
2839 2839 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), str1,
2840 2840 MSG_INTL(MSG_REL_RMN_ITM_31), MSG_INTL(MSG_REL_RMN_ITM_12),
2841 2841 MSG_INTL(MSG_REL_RMN_ITM_2), MSG_INTL(MSG_REL_RMN_ITM_32));
2842 2842
2843 2843 *remain_seen = TRUE;
2844 2844 }
2845 2845
2846 2846 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2),
2847 2847 ld_reloc_sym_name(orsp), EC_OFF(orsp->rel_roffset),
2848 2848 orsp->rel_isdesc->is_file->ifl_name);
2849 2849 }
2850 2850
2851 2851 /*
2852 2852 * Generic encapsulation for generating a TLS got index.
2853 2853 */
2854 2854 uintptr_t
2855 2855 ld_assign_got_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl, Sym_desc *sdp,
2856 2856 Gotndx *gnp, Gotref gref, Word rflag, Word ortype, Word rtype1, Word rtype2)
2857 2857 {
2858 2858 Word rflags;
2859 2859
2860 2860 if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
2861 2861 gref, ofl, rsp, sdp) == S_ERROR)
2862 2862 return (S_ERROR);
2863 2863
2864 2864 rflags = FLG_REL_GOT | rflag;
2865 2865 if (local)
2866 2866 rflags |= FLG_REL_SCNNDX;
2867 2867 rsp->rel_rtype = rtype1;
2868 2868
2869 2869 if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) == S_ERROR)
2870 2870 return (S_ERROR);
2871 2871
2872 2872 if (local && (gref == GOT_REF_TLSIE)) {
2873 2873 /*
2874 2874 * If this is a local LE TLS symbol, then the symbol won't be
2875 2875 * available at runtime. The value of the local symbol will
2876 2876 * be placed in the associated got entry, and the got
2877 2877 * relocation is reassigned to a section symbol.
2878 2878 */
2879 2879 if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2880 2880 return (S_ERROR);
2881 2881 }
2882 2882
2883 2883 if (rtype2) {
2884 2884 rflags = FLG_REL_GOT | rflag;
2885 2885 rsp->rel_rtype = rtype2;
2886 2886
2887 2887 if (local) {
2888 2888 if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2889 2889 return (S_ERROR);
2890 2890 } else {
2891 2891 if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) ==
2892 2892 S_ERROR)
2893 2893 return (S_ERROR);
2894 2894 }
2895 2895 }
2896 2896
2897 2897 rsp->rel_rtype = ortype;
2898 2898
2899 2899 return (1);
2900 2900 }
2901 2901
2902 2902 /*
2903 2903 * Move Section related function
2904 2904 */
2905 2905 static void
2906 2906 newroffset_for_move(Sym_desc *sdp, Move *mvp, Xword offset1, Xword *offset2)
2907 2907 {
2908 2908 Mv_desc *mdp;
2909 2909 Aliste idx;
2910 2910
2911 2911 /*
2912 2912 * Search for matching move entry.
2913 2913 */
2914 2914 for (ALIST_TRAVERSE(sdp->sd_move, idx, mdp)) {
2915 2915 if (mdp->md_move == mvp) {
2916 2916 /*
2917 2917 * Update r_offset
2918 2918 */
2919 2919 *offset2 = (Xword)((mdp->md_oidx - 1) * sizeof (Move) +
2920 2920 offset1 % sizeof (Move));
2921 2921 return;
2922 2922 }
2923 2923 }
2924 2924 }
2925 2925
2926 2926 void
2927 2927 ld_adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp)
2928 2928 {
2929 2929 Move *move = arsp->rel_aux->ra_move->mr_move;
2930 2930 Sym_desc *psdp = arsp->rel_aux->ra_move->mr_sym;
2931 2931 Xword newoffset;
2932 2932
2933 2933 if (arsp->rel_flags & FLG_REL_MOVETAB) {
2934 2934 /*
2935 2935 * We are relocating the move table itself.
2936 2936 */
2937 2937 newroffset_for_move(psdp, move, arsp->rel_roffset,
2938 2938 &newoffset);
2939 2939 DBG_CALL(Dbg_move_adjmovereloc(ofl->ofl_lml, arsp->rel_roffset,
2940 2940 newoffset, psdp->sd_name));
2941 2941 arsp->rel_roffset = newoffset;
2942 2942 } else {
2943 2943 /*
2944 2944 * We are expanding the partial symbol. So we are generating
2945 2945 * the relocation entry relocating the expanded partial symbol.
2946 2946 */
2947 2947 arsp->rel_roffset += psdp->sd_sym->st_value -
2948 2948 ofl->ofl_isparexpn->is_osdesc->os_shdr->sh_addr;
2949 2949 DBG_CALL(Dbg_move_adjexpandreloc(ofl->ofl_lml,
2950 2950 arsp->rel_roffset, psdp->sd_name));
2951 2951 }
2952 2952 }
2953 2953
↓ open down ↓ |
643 lines elided |
↑ open up ↑ |
2954 2954 /*
2955 2955 * Partially Initialized Symbol Handling routines
2956 2956 * For RELA architecture, the second argument is reld->rel_raddend. For REL
2957 2957 * architecure, the second argument is the value stored at the relocation
2958 2958 * target address.
2959 2959 */
2960 2960 Sym_desc *
2961 2961 ld_am_I_partial(Rel_desc *reld, Xword val)
2962 2962 {
2963 2963 Ifl_desc *ifile = reld->rel_sym->sd_isc->is_file;
2964 - int nlocs = ifile->ifl_locscnt, i;
2964 + int nlocs = ifile->ifl_locscnt, i;
2965 2965
2966 2966 for (i = 1; i < nlocs; i++) {
2967 2967 Sym *osym;
2968 2968 Sym_desc *symd = ifile->ifl_oldndx[i];
2969 2969
2970 2970 if ((osym = symd->sd_osym) == 0)
2971 2971 continue;
2972 2972 if ((symd->sd_flags & FLG_SY_PAREXPN) == 0)
2973 2973 continue;
2974 2974 if ((osym->st_value <= val) &&
2975 2975 (osym->st_value + osym->st_size > val))
2976 2976 return (symd);
2977 2977 }
2978 2978 return (NULL);
2979 2979 }
2980 2980
2981 2981 /*
2982 2982 * Return True (1) if the code processing the given relocation
2983 2983 * needs to perform byte swapping when accessing the section data.
2984 2984 */
2985 2985 int
2986 2986 ld_swap_reloc_data(Ofl_desc *ofl, Rel_desc *rsp)
2987 2987 {
2988 2988 /*
2989 2989 * In a cross-link situation where the linker host and target
2990 2990 * have opposite byte orders, it can be necessary to swap bytes
2991 2991 * when doing relocation processing. This is indicated by the
2992 2992 * presence of the FLG_OF1_ENCDIFF flag bit. However, swapping
2993 2993 * is only needed for the section types that libelf doesn't
2994 2994 * automatically xlate.
2995 2995 */
2996 2996 if ((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) {
2997 2997 switch (RELAUX_GET_OSDESC(rsp)->os_shdr->sh_type) {
2998 2998 case SHT_PROGBITS:
2999 2999 return (1);
3000 3000
3001 3001 case SHT_SPARC_GOTDATA:
3002 3002 if (ld_targ.t_m.m_mach ==
3003 3003 LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9))
3004 3004 return (1);
3005 3005 break;
3006 3006
3007 3007 case SHT_AMD64_UNWIND:
3008 3008 if (ld_targ.t_m.m_mach == EM_AMD64)
3009 3009 return (1);
3010 3010 break;
3011 3011 }
3012 3012 }
3013 3013
3014 3014 /*
3015 3015 * If FLG_OF1_ENCDIFF isn't set, or the section isn't
3016 3016 * progbits (or similar), then no swapping is needed.
3017 3017 */
3018 3018 return (0);
3019 3019 }
3020 3020
3021 3021
3022 3022
3023 3023 /*
3024 3024 * Obtain the current value at the given relocation target.
3025 3025 *
3026 3026 * entry:
3027 3027 * ofl - Output file descriptor
3028 3028 * rsp - Relocation record
3029 3029 * data - Pointer to relocation target
3030 3030 * value - Address of variable to recieve value
3031 3031 *
3032 3032 * exit:
3033 3033 * The value of the data at the relocation target has
3034 3034 * been stored in value.
3035 3035 */
3036 3036 int
3037 3037 ld_reloc_targval_get(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword *value)
3038 3038 {
3039 3039 const Rel_entry *rep;
3040 3040
3041 3041 rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
3042 3042
3043 3043 switch (rep->re_fsize) {
3044 3044 case 1:
3045 3045 /* LINTED */
3046 3046 *value = (Xword) *((uchar_t *)data);
3047 3047 break;
3048 3048 case 2:
3049 3049 {
3050 3050 Half v;
3051 3051 uchar_t *v_bytes = (uchar_t *)&v;
3052 3052
3053 3053 if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3054 3054 UL_ASSIGN_BSWAP_HALF(v_bytes, data);
3055 3055 } else {
3056 3056 UL_ASSIGN_HALF(v_bytes, data);
3057 3057 }
3058 3058 *value = (Xword) v;
3059 3059 }
3060 3060 break;
3061 3061 case 4:
3062 3062 {
3063 3063 Word v;
3064 3064 uchar_t *v_bytes = (uchar_t *)&v;
3065 3065
3066 3066 if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3067 3067 UL_ASSIGN_BSWAP_WORD(v_bytes, data);
3068 3068 } else {
3069 3069 UL_ASSIGN_WORD(v_bytes, data);
3070 3070 }
3071 3071 *value = (Xword) v;
3072 3072 }
3073 3073 break;
3074 3074 default:
3075 3075 {
3076 3076 Conv_inv_buf_t inv_buf;
3077 3077 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
3078 3078 conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
3079 3079 0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
3080 3080 ld_reloc_sym_name(rsp), (int)rep->re_fsize);
3081 3081 }
3082 3082 return (0);
3083 3083 }
3084 3084 return (1);
3085 3085 }
3086 3086
3087 3087
3088 3088 /*
3089 3089 * Set the value at the given relocation target.
3090 3090 *
3091 3091 * entry:
3092 3092 * ofl - Output file descriptor
3093 3093 * rsp - Relocation record
3094 3094 * data - Pointer to relocation target
3095 3095 * value - Address of variable to recieve value
3096 3096 *
3097 3097 * exit:
3098 3098 * The value of the data at the relocation target has
3099 3099 * been stored in value.
3100 3100 */
3101 3101 int
3102 3102 ld_reloc_targval_set(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword value)
3103 3103 {
3104 3104 const Rel_entry *rep;
3105 3105
3106 3106 rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
3107 3107
3108 3108 switch (rep->re_fsize) {
3109 3109 case 1:
3110 3110 /* LINTED */
3111 3111 *((uchar_t *)data) = (uchar_t)value;
3112 3112 break;
3113 3113 case 2:
3114 3114 {
3115 3115 Half v = (Half)value;
3116 3116 uchar_t *v_bytes = (uchar_t *)&v;
3117 3117
3118 3118 if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3119 3119 UL_ASSIGN_BSWAP_HALF(data, v_bytes);
3120 3120 } else {
3121 3121 UL_ASSIGN_HALF(data, v_bytes);
3122 3122 }
3123 3123 }
3124 3124 break;
3125 3125 case 4:
3126 3126 {
3127 3127 Word v = (Word)value;
3128 3128 uchar_t *v_bytes = (uchar_t *)&v;
3129 3129
3130 3130 if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3131 3131 UL_ASSIGN_BSWAP_WORD(data, v_bytes);
3132 3132 } else {
3133 3133 UL_ASSIGN_WORD(data, v_bytes);
3134 3134 }
3135 3135 }
3136 3136 break;
3137 3137 default:
3138 3138 {
3139 3139 Conv_inv_buf_t inv_buf;
3140 3140 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
3141 3141 conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
3142 3142 0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
3143 3143 ld_reloc_sym_name(rsp), (int)rep->re_fsize);
3144 3144 }
3145 3145 return (0);
3146 3146 }
3147 3147 return (1);
3148 3148 }
3149 3149
3150 3150
3151 3151 /*
3152 3152 * Because of the combinations of 32-bit lib providing 64-bit support, and
3153 3153 * visa-versa, the use of krtld's dorelocs can result in differing message
3154 3154 * requirements that make msg.c/msg.h creation and chkmsg "interesting".
3155 3155 * Thus the actual message files contain a couple of entries to satisfy
3156 3156 * each architectures build. Here we add dummy calls to quieten chkmsg.
3157 3157 *
3158 3158 * chkmsg: MSG_INTL(MSG_REL_NOFIT)
3159 3159 * chkmsg: MSG_INTL(MSG_REL_NONALIGN)
3160 3160 */
↓ open down ↓ |
186 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX