4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1988 AT&T
26 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
29 /* Get the sparc version of the relocation engine */
30 #define DO_RELOC_LIBLD_SPARC
34 #include <sys/elf_SPARC.h>
37 #include <sparc/machdep_sparc.h>
40 #include "machsym.sparc.h"
43 * Local Variable Definitions
45 static Sword neggotoffset
= 0; /* off. of GOT table from GOT symbol */
46 static Sword smlgotcnt
= M_GOT_XNumber
; /* no. of small GOT symbols */
47 static Sword mixgotcnt
= 0; /* # syms with both large/small GOT */
50 * Search the GOT index list for a GOT entry with a matching reference and the
54 ld_find_got_ndx(Alist
*alp
, Gotref gref
, Ofl_desc
*ofl
, Rel_desc
*rdesc
)
61 if ((gref
== GOT_REF_TLSLD
) && ofl
->ofl_tlsldgotndx
)
62 return (ofl
->ofl_tlsldgotndx
);
64 for (ALIST_TRAVERSE(alp
, idx
, gnp
)) {
65 if ((rdesc
->rel_raddend
== gnp
->gn_addend
) &&
66 (gref
== gnp
->gn_gotref
))
73 ld_calc_got_offset(Rel_desc
* rdesc
, Ofl_desc
* ofl
)
75 Os_desc
*osp
= ofl
->ofl_osgot
;
76 Sym_desc
*sdp
= rdesc
->rel_sym
;
81 if (rdesc
->rel_flags
& FLG_REL_DTLS
)
83 else if (rdesc
->rel_flags
& FLG_REL_MTLS
)
85 else if (rdesc
->rel_flags
& FLG_REL_STLS
)
88 gref
= GOT_REF_GENERIC
;
90 gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
, gref
, ofl
, rdesc
);
93 gotndx
= (Xword
)gnp
->gn_gotndx
;
95 if ((rdesc
->rel_flags
& FLG_REL_DTLS
) &&
96 (rdesc
->rel_rtype
== M_R_DTPOFF
))
99 return ((Xword
)((osp
->os_shdr
->sh_addr
) + (gotndx
* M_GOT_ENTSIZE
) +
100 (-neggotoffset
* M_GOT_ENTSIZE
)));
104 ld_init_rel(Rel_desc
*reld
, Word
*typedata
, void *reloc
)
106 Rela
*rela
= (Rela
*)reloc
;
109 reld
->rel_rtype
= (Word
)ELF_R_TYPE(rela
->r_info
, M_MACH
);
110 reld
->rel_roffset
= rela
->r_offset
;
111 reld
->rel_raddend
= rela
->r_addend
;
112 *typedata
= (Word
)ELF_R_TYPE_DATA(rela
->r_info
);
114 reld
->rel_flags
|= FLG_REL_RELA
;
116 return ((Word
)ELF_R_SYM(rela
->r_info
));
120 ld_mach_eflags(Ehdr
*ehdr
, Ofl_desc
*ofl
)
122 Word eflags
= ofl
->ofl_dehdr
->e_flags
;
123 Word memopt1
, memopt2
;
124 static int firstpass
;
127 * If a *PLUS relocatable is included, the output object is type *PLUS.
129 if ((ehdr
->e_machine
== EM_SPARC32PLUS
) &&
130 (ehdr
->e_flags
& EF_SPARC_32PLUS
))
131 ofl
->ofl_dehdr
->e_machine
= EM_SPARC32PLUS
;
134 * On the first pass, we don't yet have a memory model to compare
135 * against, therefore the initial file becomes our baseline. Subsequent
136 * passes will do the comparison described below.
138 if (firstpass
== 0) {
139 ofl
->ofl_dehdr
->e_flags
|= ehdr
->e_flags
;
145 * Determine which memory model to mark the binary with. The options
146 * are (most restrictive to least):
148 * EF_SPARCV9_TSO 0x0 Total Store Order
149 * EF_SPARCV9_PSO 0x1 Partial Store Order
150 * EF_SPARCV9_RMO 0x2 Relaxed Memory Order
152 * Mark the binary with the most restrictive option encountered from a
153 * relocatable object included in the link.
155 eflags
|= (ehdr
->e_flags
& ~EF_SPARCV9_MM
);
156 memopt1
= eflags
& EF_SPARCV9_MM
;
157 memopt2
= ehdr
->e_flags
& EF_SPARCV9_MM
;
158 eflags
&= ~EF_SPARCV9_MM
;
160 if ((memopt1
== EF_SPARCV9_TSO
) || (memopt2
== EF_SPARCV9_TSO
))
163 else if ((memopt1
== EF_SPARCV9_PSO
) || (memopt2
== EF_SPARCV9_PSO
))
164 eflags
|= EF_SPARCV9_PSO
;
166 eflags
|= EF_SPARCV9_RMO
;
168 ofl
->ofl_dehdr
->e_flags
= eflags
;
172 ld_mach_make_dynamic(Ofl_desc
*ofl
, size_t *cnt
)
174 if (!(ofl
->ofl_flags
& FLG_OF_RELOBJ
)) {
176 * Create this entry if we are going to create a PLT table.
179 (*cnt
)++; /* DT_PLTGOT */
184 ld_mach_update_odynamic(Ofl_desc
*ofl
, Dyn
**dyn
)
186 if (((ofl
->ofl_flags
& FLG_OF_RELOBJ
) == 0) && ofl
->ofl_pltcnt
) {
187 (*dyn
)->d_tag
= DT_PLTGOT
;
189 (*dyn
)->d_un
.d_ptr
= ofl
->ofl_osplt
->os_shdr
->sh_addr
;
191 (*dyn
)->d_un
.d_ptr
= 0;
199 ld_calc_plt_addr(Sym_desc
*sdp
, Ofl_desc
*ofl
)
201 Xword value
, pltndx
, farpltndx
;
203 pltndx
= sdp
->sd_aux
->sa_PLTndx
+ M_PLT_XNumber
- 1;
205 if ((pltndx
) < M64_PLT_NEARPLTS
) {
206 value
= (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
) +
207 (pltndx
* M_PLT_ENTSIZE
);
211 farpltndx
= pltndx
- M64_PLT_NEARPLTS
;
214 * pltoffset of a far plt is calculated by:
216 * <size of near plt table> +
217 * <size of preceding far plt blocks> +
218 * <blockndx * sizeof (far plt entsize)>
221 /* size of near plt table */
222 (M64_PLT_NEARPLTS
* M_PLT_ENTSIZE
) +
223 /* size of preceding far plt blocks */
224 ((farpltndx
/ M64_PLT_FBLKCNTS
) *
225 ((M64_PLT_FENTSIZE
+ sizeof (Addr
)) *
227 /* pltblockendx * fentsize */
228 ((farpltndx
% M64_PLT_FBLKCNTS
) * M64_PLT_FENTSIZE
);
230 value
+= (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
);
235 * Instructions required for Far PLT's
237 static uchar_t farplt_instrs
[24] = {
238 0x8a, 0x10, 0x00, 0x0f, /* mov %o7, %g5 */
239 0x40, 0x00, 0x00, 0x02, /* call . + 0x8 */
240 0x01, 0x00, 0x00, 0x00, /* nop */
241 0xc2, 0x5b, 0xe0, 0x00, /* ldx [%o7 + 0], %g1 */
242 0x83, 0xc3, 0xc0, 0x01, /* jmpl %o7 + %g1, %g1 */
243 0x9e, 0x10, 0x00, 0x05 /* mov %g5, %o7 */
249 * Far PLT's are established in blocks of '160' at a time. These
250 * PLT's consist of 6 instructions (24 bytes) and 1 pointer (8 bytes).
251 * The instructions are collected together in blocks of 160 entries
252 * followed by 160 pointers. The last group of entries and pointers
253 * may contain less then 160 items. No padding is required.
259 * ldx [%o7 + .PLTP32768 - (.PLT32768 + 4)], %g1
260 * jmpl %o7 + %g1, %g1
262 * ................................
267 * ldx [%o7 + .PLTP32927 - (.PLT32927 + 4)], %g1
268 * jmpl %o7 + %g1, %g1
271 * .xword .PLT0-(.PLT32768+4)
272 * ................................
274 * .xword .PLT0-(.PLT32927+4)
278 plt_far_entry(Ofl_desc
*ofl
, Xword pltndx
, Xword
*roffset
, Sxword
*raddend
)
280 uint_t blockndx
; /* # of far PLT blocks */
281 uint_t farblkcnt
; /* Index to far PLT block */
282 Xword farpltndx
; /* index of Far Plt */
283 Xword farpltblkndx
; /* index of PLT in BLOCK */
284 uint32_t *pltent
; /* ptr to plt instr. sequence */
285 uint64_t *pltentptr
; /* ptr to plt addr ptr */
286 Sxword pltblockoff
; /* offset to Far plt block */
287 Sxword pltoff
; /* offset to PLT instr. sequence */
288 Sxword pltptroff
; /* offset to PLT addr ptr */
289 uchar_t
*pltbuf
; /* ptr to PLT's in file */
292 farblkcnt
= ((ofl
->ofl_pltcnt
- 1 +
293 M_PLT_XNumber
- M64_PLT_NEARPLTS
) / M64_PLT_FBLKCNTS
);
296 * Determine the 'Far' PLT index.
298 farpltndx
= pltndx
- 1 + M_PLT_XNumber
- M64_PLT_NEARPLTS
;
299 farpltblkndx
= farpltndx
% M64_PLT_FBLKCNTS
;
302 * Determine what FPLT block this plt falls into.
304 blockndx
= (uint_t
)(farpltndx
/ M64_PLT_FBLKCNTS
);
307 * Calculate the starting offset of the Far PLT block
308 * that this PLT is a member of.
310 pltblockoff
= (M64_PLT_NEARPLTS
* M_PLT_ENTSIZE
) +
311 (blockndx
* M64_PLT_FBLOCKSZ
);
313 pltoff
= pltblockoff
+
314 (farpltblkndx
* M64_PLT_FENTSIZE
);
316 pltptroff
= pltblockoff
;
319 if (farblkcnt
> blockndx
) {
321 * If this is a full block - the 'pltptroffs' start
324 pltptroff
+= (M64_PLT_FBLKCNTS
* M64_PLT_FENTSIZE
) +
325 (farpltblkndx
* M64_PLT_PSIZE
);
329 * If this is the last block - the the pltptr's start
330 * after the last FPLT instruction sequence.
332 lastblkpltndx
= (ofl
->ofl_pltcnt
- 1 + M_PLT_XNumber
-
333 M64_PLT_NEARPLTS
) % M64_PLT_FBLKCNTS
;
334 pltptroff
+= ((lastblkpltndx
+ 1) * M64_PLT_FENTSIZE
) +
335 (farpltblkndx
* M64_PLT_PSIZE
);
337 pltbuf
= (uchar_t
*)ofl
->ofl_osplt
->os_outdata
->d_buf
;
340 * For far-plts, the Raddend and Roffset fields are defined
343 * roffset: address of .PLTP#
344 * raddend: -(.PLT#+4)
346 *roffset
= pltptroff
+ (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
);
347 *raddend
= -(pltoff
+ 4 + (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
));
350 pltent
= (uint32_t *)(pltbuf
+ pltoff
);
352 pltentptr
= (uint64_t *)(pltbuf
+ pltptroff
);
353 (void) memcpy(pltent
, farplt_instrs
, sizeof (farplt_instrs
));
359 * ldx [%o7 + .PLTP# - (.PLT# + 4)], %g1
362 pltent
[3] |= (uint32_t)(pltptroff
- (pltoff
+ 4));
367 * .xword .PLT0 - .PLT# + 4
369 *pltentptr
= -(pltoff
+ 4);
373 * Build a single V9 P.L.T. entry - code is:
375 * For Target Addresses +/- 4GB of the entry
376 * -----------------------------------------
377 * sethi (. - .PLT0), %g1
386 * For Target Addresses +/- 2GB of the entry
387 * -----------------------------------------
389 * .PLT0 is the address of the first entry in the P.L.T.
390 * This one is filled in by the run-time link editor. We just
391 * have to leave space for it.
394 plt_entry(Ofl_desc
*ofl
, Xword pltndx
, Xword
*roffset
, Sxword
*raddend
)
396 uchar_t
*pltent
; /* PLT entry being created. */
397 Sxword pltoff
; /* Offset of this entry from PLT top */
398 int bswap
= (ofl
->ofl_flags1
& FLG_OF1_ENCDIFF
) != 0;
401 * The second part of the V9 ABI (sec. 5.2.4)
402 * applies to plt entries greater than 0x8000 (32,768).
403 * This is handled in 'plt_far_entry()'
405 if ((pltndx
- 1 + M_PLT_XNumber
) >= M64_PLT_NEARPLTS
) {
406 plt_far_entry(ofl
, pltndx
, roffset
, raddend
);
410 pltoff
= M_PLT_RESERVSZ
+ (pltndx
- 1) * M_PLT_ENTSIZE
;
411 pltent
= (uchar_t
*)ofl
->ofl_osplt
->os_outdata
->d_buf
+ pltoff
;
413 *roffset
= pltoff
+ (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
);
417 * PLT[0]: sethi %hi(. - .L0), %g1
420 *(Word
*)pltent
= M_SETHIG1
| pltoff
;
423 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
426 * PLT[1]: ba,a %xcc, .PLT1 (.PLT1 accessed as a
427 * PC-relative index of longwords).
429 pltent
+= M_PLT_INSSIZE
;
430 pltoff
+= M_PLT_INSSIZE
;
433 *(Word
*)pltent
= M_BA_A_XCC
|
434 (((pltoff
+ M_PLT_ENTSIZE
) >> 2) & S_MASK(19));
437 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
440 * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI).
442 pltent
+= M_PLT_INSSIZE
;
444 *(Word
*)pltent
= M_NOP
;
447 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
450 * PLT[3]: sethi 0, %g0 (NOP for PLT padding).
452 pltent
+= M_PLT_INSSIZE
;
454 *(Word
*)pltent
= M_NOP
;
457 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
460 * PLT[4]: sethi 0, %g0 (NOP for PLT padding).
462 pltent
+= M_PLT_INSSIZE
;
464 *(Word
*)pltent
= M_NOP
;
467 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
470 * PLT[5]: sethi 0, %g0 (NOP for PLT padding).
472 pltent
+= M_PLT_INSSIZE
;
474 *(Word
*)pltent
= M_NOP
;
477 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
480 * PLT[6]: sethi 0, %g0 (NOP for PLT padding).
482 pltent
+= M_PLT_INSSIZE
;
484 *(Word
*)pltent
= M_NOP
;
487 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
490 * PLT[7]: sethi 0, %g0 (NOP for PLT padding).
492 pltent
+= M_PLT_INSSIZE
;
494 *(Word
*)pltent
= M_NOP
;
497 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
504 ld_calc_plt_addr(Sym_desc
*sdp
, Ofl_desc
*ofl
)
508 pltndx
= sdp
->sd_aux
->sa_PLTndx
+ M_PLT_XNumber
- 1;
509 value
= (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
) +
510 (pltndx
* M_PLT_ENTSIZE
);
516 * Build a single P.L.T. entry - code is:
518 * sethi (. - .L0), %g1
522 * .L0 is the address of the first entry in the P.L.T.
523 * This one is filled in by the run-time link editor. We just
524 * have to leave space for it.
527 plt_entry(Ofl_desc
* ofl
, Xword pltndx
, Xword
*roffset
, Sxword
*raddend
)
529 Byte
*pltent
; /* PLT entry being created. */
530 Sxword pltoff
; /* Offset of this entry from PLT top */
531 int bswap
= (ofl
->ofl_flags1
& FLG_OF1_ENCDIFF
) != 0;
533 pltoff
= M_PLT_RESERVSZ
+ (pltndx
- 1) * M_PLT_ENTSIZE
;
534 pltent
= (Byte
*)ofl
->ofl_osplt
->os_outdata
->d_buf
+ pltoff
;
536 *roffset
= pltoff
+ (Xword
)(ofl
->ofl_osplt
->os_shdr
->sh_addr
);
540 * PLT[0]: sethi %hi(. - .L0), %g1
543 *(Word
*)pltent
= M_SETHIG1
| pltoff
;
546 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
549 * PLT[1]: ba,a .L0 (.L0 accessed as a PC-relative index of longwords)
551 pltent
+= M_PLT_INSSIZE
;
552 pltoff
+= M_PLT_INSSIZE
;
555 *(Word
*)pltent
= M_BA_A
| ((pltoff
>> 2) & S_MASK(22));
558 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
561 * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI).
563 pltent
+= M_PLT_INSSIZE
;
565 *(Word
*)pltent
= M_SETHIG0
;
568 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
571 * PLT[3]: sethi 0, %g0 (NOP for PLT padding).
573 pltent
+= M_PLT_INSSIZE
;
575 *(Word
*)pltent
= M_SETHIG0
;
578 *(Word
*)pltent
= ld_bswap_Word(*(Word
*)pltent
);
584 ld_perform_outreloc(Rel_desc
*orsp
, Ofl_desc
*ofl
, Boolean
*remain_seen
)
586 Os_desc
*relosp
, *osp
= NULL
;
587 Xword ndx
, roffset
, value
;
589 const Rel_entry
*rep
;
592 Sym_desc
*sdp
, *psym
= NULL
;
594 Word dtflags1
= ofl
->ofl_dtflags_1
;
595 ofl_flag_t flags
= ofl
->ofl_flags
;
597 raddend
= orsp
->rel_raddend
;
601 * Special case, a regsiter symbol associated with symbol
602 * index 0 is initialized (i.e. relocated) to a constant
603 * in the r_addend field rather than to a symbol value.
605 if ((orsp
->rel_rtype
== M_R_REGISTER
) && !sdp
) {
606 relosp
= ofl
->ofl_osrel
;
607 relbits
= (char *)relosp
->os_outdata
->d_buf
;
609 rea
.r_info
= ELF_R_INFO(0,
610 ELF_R_TYPE_INFO(RELAUX_GET_TYPEDATA(orsp
),
612 rea
.r_offset
= orsp
->rel_roffset
;
613 rea
.r_addend
= raddend
;
614 DBG_CALL(Dbg_reloc_out(ofl
, ELF_DBG_LD
, SHT_RELA
, &rea
,
615 relosp
->os_name
, ld_reloc_sym_name(orsp
)));
617 assert(relosp
->os_szoutrels
<= relosp
->os_shdr
->sh_size
);
618 (void) memcpy((relbits
+ relosp
->os_szoutrels
),
619 (char *)&rea
, sizeof (Rela
));
620 relosp
->os_szoutrels
+= (Xword
)sizeof (Rela
);
626 * If the section this relocation is against has been discarded
627 * (-zignore), then also discard (skip) the relocation itself.
629 if (orsp
->rel_isdesc
&& ((orsp
->rel_flags
&
630 (FLG_REL_GOT
| FLG_REL_BSS
| FLG_REL_PLT
| FLG_REL_NOINFO
)) == 0) &&
631 (orsp
->rel_isdesc
->is_flags
& FLG_IS_DISCARD
)) {
632 DBG_CALL(Dbg_reloc_discard(ofl
->ofl_lml
, M_MACH
, orsp
));
637 * If this is a relocation against a move table, or expanded move
638 * table, adjust the relocation entries.
640 if (RELAUX_GET_MOVE(orsp
))
641 ld_adj_movereloc(ofl
, orsp
);
644 * If this is a relocation against a section then we need to adjust the
645 * raddend field to compensate for the new position of the input section
646 * within the new output section.
648 if (ELF_ST_TYPE(sdp
->sd_sym
->st_info
) == STT_SECTION
) {
649 if (ofl
->ofl_parsyms
&&
650 (sdp
->sd_isc
->is_flags
& FLG_IS_RELUPD
) &&
651 (psym
= ld_am_I_partial(orsp
, orsp
->rel_raddend
))) {
653 * If the symbol is moved, adjust the value
655 DBG_CALL(Dbg_move_outsctadj(ofl
->ofl_lml
, psym
));
657 if (ofl
->ofl_flags
& FLG_OF_RELOBJ
)
658 raddend
= psym
->sd_sym
->st_value
;
660 raddend
= psym
->sd_sym
->st_value
-
661 psym
->sd_isc
->is_osdesc
->os_shdr
->sh_addr
;
663 raddend
+= (Off
)_elf_getxoff(psym
->sd_isc
->is_indata
);
664 if (psym
->sd_isc
->is_shdr
->sh_flags
& SHF_ALLOC
)
666 psym
->sd_isc
->is_osdesc
->os_shdr
->sh_addr
;
669 raddend
+= (Off
)_elf_getxoff(sdp
->sd_isc
->is_indata
);
670 if (sdp
->sd_isc
->is_shdr
->sh_flags
& SHF_ALLOC
)
672 sdp
->sd_isc
->is_osdesc
->os_shdr
->sh_addr
;
676 value
= sdp
->sd_sym
->st_value
;
678 if (orsp
->rel_flags
& FLG_REL_GOT
) {
679 osp
= ofl
->ofl_osgot
;
680 roffset
= ld_calc_got_offset(orsp
, ofl
);
682 } else if (orsp
->rel_flags
& FLG_REL_PLT
) {
683 osp
= ofl
->ofl_osplt
;
684 plt_entry(ofl
, sdp
->sd_aux
->sa_PLTndx
, &roffset
, &raddend
);
685 } else if (orsp
->rel_flags
& FLG_REL_BSS
) {
687 * This must be a R_SPARC_COPY. For these set the roffset to
688 * point to the new symbols location.
690 osp
= ofl
->ofl_isbss
->is_osdesc
;
691 roffset
= (Xword
)value
;
694 * The raddend doesn't mean anything in an R_SPARC_COPY
695 * relocation. Null it out because it can confuse people.
698 } else if (orsp
->rel_flags
& FLG_REL_REG
) {
700 * The offsets of relocations against register symbols
701 * identifiy the register directly - so the offset
702 * does not need to be adjusted.
704 roffset
= orsp
->rel_roffset
;
706 osp
= RELAUX_GET_OSDESC(orsp
);
709 * Calculate virtual offset of reference point; equals offset
710 * into section + vaddr of section for loadable sections, or
711 * offset plus section displacement for nonloadable sections.
713 roffset
= orsp
->rel_roffset
+
714 (Off
)_elf_getxoff(orsp
->rel_isdesc
->is_indata
);
715 if (!(ofl
->ofl_flags
& FLG_OF_RELOBJ
))
716 roffset
+= orsp
->rel_isdesc
->is_osdesc
->
720 if ((osp
== 0) || ((relosp
= osp
->os_relosdesc
) == 0))
721 relosp
= ofl
->ofl_osrel
;
724 * Verify that the output relocations offset meets the
725 * alignment requirements of the relocation being processed.
727 rep
= &reloc_table
[orsp
->rel_rtype
];
728 if (((flags
& FLG_OF_RELOBJ
) || !(dtflags1
& DF_1_NORELOC
)) &&
729 !(rep
->re_flags
& FLG_RE_UNALIGN
)) {
730 if (((rep
->re_fsize
== 2) && (roffset
& 0x1)) ||
731 ((rep
->re_fsize
== 4) && (roffset
& 0x3)) ||
732 ((rep
->re_fsize
== 8) && (roffset
& 0x7))) {
733 Conv_inv_buf_t inv_buf
;
735 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_NONALIGN
),
736 conv_reloc_SPARC_type(orsp
->rel_rtype
, 0, &inv_buf
),
737 orsp
->rel_isdesc
->is_file
->ifl_name
,
738 ld_reloc_sym_name(orsp
), EC_XWORD(roffset
));
744 * Assign the symbols index for the output relocation. If the
745 * relocation refers to a SECTION symbol then it's index is based upon
746 * the output sections symbols index. Otherwise the index can be
747 * derived from the symbols index itself.
749 if (orsp
->rel_rtype
== R_SPARC_RELATIVE
)
751 else if ((orsp
->rel_flags
& FLG_REL_SCNNDX
) ||
752 (ELF_ST_TYPE(sdp
->sd_sym
->st_info
) == STT_SECTION
)) {
753 if (sectmoved
== 0) {
755 * Check for a null input section. This can
756 * occur if this relocation references a symbol
757 * generated by sym_add_sym().
759 if (sdp
->sd_isc
&& sdp
->sd_isc
->is_osdesc
)
760 ndx
= sdp
->sd_isc
->is_osdesc
->os_identndx
;
764 ndx
= ofl
->ofl_parexpnndx
;
766 ndx
= sdp
->sd_symndx
;
769 * Add the symbols 'value' to the addend field.
771 if (orsp
->rel_flags
& FLG_REL_ADVAL
)
775 * The addend field for R_SPARC_TLS_DTPMOD32 and R_SPARC_TLS_DTPMOD64
776 * mean nothing. The addend is propagated in the corresponding
777 * R_SPARC_TLS_DTPOFF* relocations.
779 if (orsp
->rel_rtype
== M_R_DTPMOD
)
782 relbits
= (char *)relosp
->os_outdata
->d_buf
;
784 rea
.r_info
= ELF_R_INFO(ndx
,
785 ELF_R_TYPE_INFO(RELAUX_GET_TYPEDATA(orsp
), orsp
->rel_rtype
));
786 rea
.r_offset
= roffset
;
787 rea
.r_addend
= raddend
;
788 DBG_CALL(Dbg_reloc_out(ofl
, ELF_DBG_LD
, SHT_RELA
, &rea
, relosp
->os_name
,
789 ld_reloc_sym_name(orsp
)));
792 * Assert we haven't walked off the end of our relocation table.
794 assert(relosp
->os_szoutrels
<= relosp
->os_shdr
->sh_size
);
796 (void) memcpy((relbits
+ relosp
->os_szoutrels
),
797 (char *)&rea
, sizeof (Rela
));
798 relosp
->os_szoutrels
+= (Xword
)sizeof (Rela
);
801 * Determine if this relocation is against a non-writable, allocatable
802 * section. If so we may need to provide a text relocation diagnostic.
804 ld_reloc_remain_entry(orsp
, osp
, ofl
, remain_seen
);
810 * Sparc Instructions for TLS processing
813 #define TLS_GD_IE_LD 0xd0580000 /* ldx [%g0 + %g0], %o0 */
815 #define TLS_GD_IE_LD 0xd0000000 /* ld [%g0 + %g0], %o0 */
817 #define TLS_GD_IE_ADD 0x9001c008 /* add %g7, %o0, %o0 */
819 #define TLS_GD_LE_XOR 0x80182000 /* xor %g0, 0, %g0 */
820 #define TLS_IE_LE_OR 0x80100000 /* or %g0, %o0, %o1 */
821 /* synthetic: mov %g0, %g0 */
823 #define TLS_LD_LE_CLRO0 0x90100000 /* clr %o0 */
825 #define FM3_REG_MSK_RD (0x1f << 25) /* Formate (3) rd register mask */
827 #define FM3_REG_MSK_RS1 (0x1f << 14) /* Formate (3) rs1 register mask */
829 #define FM3_REG_MSK_RS2 0x1f /* Formate (3) rs2 register mask */
832 #define REG_G7 7 /* %g7 register */
835 tls_fixups(Ofl_desc
*ofl
, Rel_desc
*arsp
)
837 Sym_desc
*sdp
= arsp
->rel_sym
;
838 Word rtype
= arsp
->rel_rtype
;
840 int bswap
= OFL_SWAP_RELOC_DATA(ofl
, arsp
);
843 offset
= (Word
*)((uintptr_t)arsp
->rel_roffset
+
844 (uintptr_t)_elf_getxoff(arsp
->rel_isdesc
->is_indata
) +
845 (uintptr_t)RELAUX_GET_OSDESC(arsp
)->os_outdata
->d_buf
);
847 if (sdp
->sd_ref
== REF_DYN_NEED
) {
852 case R_SPARC_TLS_GD_HI22
:
853 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
854 R_SPARC_TLS_IE_HI22
, arsp
,
856 arsp
->rel_rtype
= R_SPARC_TLS_IE_HI22
;
859 case R_SPARC_TLS_GD_LO10
:
860 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
861 R_SPARC_TLS_IE_LO10
, arsp
,
863 arsp
->rel_rtype
= R_SPARC_TLS_IE_LO10
;
866 case R_SPARC_TLS_GD_ADD
:
867 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
868 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
869 w
= bswap
? ld_bswap_Word(*offset
) : *offset
;
871 (w
& (FM3_REG_MSK_RS1
| FM3_REG_MSK_RS2
)));
872 *offset
= bswap
? ld_bswap_Word(w
) : w
;
875 case R_SPARC_TLS_GD_CALL
:
876 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
877 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
878 *offset
= TLS_GD_IE_ADD
;
880 *offset
= ld_bswap_Word(*offset
);
890 case R_SPARC_TLS_IE_HI22
:
891 case R_SPARC_TLS_GD_HI22
:
892 case R_SPARC_TLS_LDO_HIX22
:
893 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
894 R_SPARC_TLS_LE_HIX22
, arsp
, ld_reloc_sym_name
));
895 arsp
->rel_rtype
= R_SPARC_TLS_LE_HIX22
;
898 case R_SPARC_TLS_LDO_LOX10
:
899 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
900 R_SPARC_TLS_LE_LOX10
, arsp
, ld_reloc_sym_name
));
901 arsp
->rel_rtype
= R_SPARC_TLS_LE_LOX10
;
904 case R_SPARC_TLS_IE_LO10
:
905 case R_SPARC_TLS_GD_LO10
:
907 * Current instruction is:
913 * Need to udpate this to:
915 * xor r1, %lox(x), r2
917 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
918 R_SPARC_TLS_LE_LOX10
, arsp
, ld_reloc_sym_name
));
919 w
= bswap
? ld_bswap_Word(*offset
) : *offset
;
921 (w
& (FM3_REG_MSK_RS1
| FM3_REG_MSK_RD
));
922 *offset
= bswap
? ld_bswap_Word(w
) : w
;
923 arsp
->rel_rtype
= R_SPARC_TLS_LE_LOX10
;
926 case R_SPARC_TLS_IE_LD
:
927 case R_SPARC_TLS_IE_LDX
:
929 * Current instruction:
930 * ld{x} [r1 + r2], r3
932 * Need to update this to:
934 * mov r2, r3 (or %g0, r2, r3)
936 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
937 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
938 w
= bswap
? ld_bswap_Word(*offset
) : *offset
;
939 w
= (w
& (FM3_REG_MSK_RS2
| FM3_REG_MSK_RD
)) | TLS_IE_LE_OR
;
940 *offset
= bswap
? ld_bswap_Word(w
) : w
;
943 case R_SPARC_TLS_LDO_ADD
:
944 case R_SPARC_TLS_GD_ADD
:
946 * Current instruction is:
948 * add gptr_reg, r2, r3
950 * Need to updated this to:
954 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
955 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
956 w
= bswap
? ld_bswap_Word(*offset
) : *offset
;
957 w
= w
& (~FM3_REG_MSK_RS1
);
958 w
= w
| (REG_G7
<< 14);
959 *offset
= bswap
? ld_bswap_Word(w
) : w
;
962 case R_SPARC_TLS_LDM_CALL
:
963 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
964 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
965 *offset
= TLS_LD_LE_CLRO0
;
967 *offset
= ld_bswap_Word(*offset
);
970 case R_SPARC_TLS_LDM_HI22
:
971 case R_SPARC_TLS_LDM_LO10
:
972 case R_SPARC_TLS_LDM_ADD
:
973 case R_SPARC_TLS_IE_ADD
:
974 case R_SPARC_TLS_GD_CALL
:
975 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
976 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
979 *offset
= ld_bswap_Word(*offset
);
985 #define GOTOP_ADDINST 0x80000000 /* add %g0, %g0, %g0 */
988 gotop_fixups(Ofl_desc
*ofl
, Rel_desc
*arsp
)
990 Word rtype
= arsp
->rel_rtype
;
992 const char *ifl_name
;
993 Conv_inv_buf_t inv_buf
;
997 case R_SPARC_GOTDATA_OP_HIX22
:
998 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
999 R_SPARC_GOTDATA_HIX22
, arsp
, ld_reloc_sym_name
));
1000 arsp
->rel_rtype
= R_SPARC_GOTDATA_HIX22
;
1003 case R_SPARC_GOTDATA_OP_LOX10
:
1004 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
1005 R_SPARC_GOTDATA_LOX10
, arsp
, ld_reloc_sym_name
));
1006 arsp
->rel_rtype
= R_SPARC_GOTDATA_LOX10
;
1009 case R_SPARC_GOTDATA_OP
:
1011 * Current instruction:
1012 * ld{x} [r1 + r2], r3
1014 * Need to update this to:
1018 DBG_CALL(Dbg_reloc_transition(ofl
->ofl_lml
, M_MACH
,
1019 R_SPARC_NONE
, arsp
, ld_reloc_sym_name
));
1020 offset
= (Word
*)(uintptr_t)(arsp
->rel_roffset
+
1021 _elf_getxoff(arsp
->rel_isdesc
->is_indata
) +
1022 (uintptr_t)RELAUX_GET_OSDESC(arsp
)->os_outdata
->d_buf
);
1023 bswap
= OFL_SWAP_RELOC_DATA(ofl
, arsp
);
1024 w
= bswap
? ld_bswap_Word(*offset
) : *offset
;
1025 w
= (w
& (FM3_REG_MSK_RS1
|
1026 FM3_REG_MSK_RS2
| FM3_REG_MSK_RD
)) | GOTOP_ADDINST
;
1027 *offset
= bswap
? ld_bswap_Word(w
) : w
;
1031 * We should not get here
1033 if (arsp
->rel_isdesc
->is_file
)
1034 ifl_name
= arsp
->rel_isdesc
->is_file
->ifl_name
;
1036 ifl_name
= MSG_INTL(MSG_STR_NULL
);
1038 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_BADGOTFIX
),
1039 conv_reloc_SPARC_type(arsp
->rel_rtype
, 0, &inv_buf
),
1040 ifl_name
, ld_reloc_sym_name(arsp
));
1047 ld_do_activerelocs(Ofl_desc
*ofl
)
1052 uintptr_t return_code
= 1;
1053 ofl_flag_t flags
= ofl
->ofl_flags
;
1055 if (aplist_nitems(ofl
->ofl_actrels
.rc_list
) != 0)
1056 DBG_CALL(Dbg_reloc_doact_title(ofl
->ofl_lml
));
1059 * Process active relocations.
1061 REL_CACHE_TRAVERSE(&ofl
->ofl_actrels
, idx
, rcbp
, arsp
) {
1065 const char *ifl_name
;
1070 * If the section this relocation is against has been discarded
1071 * (-zignore), then discard (skip) the relocation itself.
1073 if ((arsp
->rel_isdesc
->is_flags
& FLG_IS_DISCARD
) &&
1074 ((arsp
->rel_flags
& (FLG_REL_GOT
| FLG_REL_BSS
|
1075 FLG_REL_PLT
| FLG_REL_NOINFO
)) == 0)) {
1076 DBG_CALL(Dbg_reloc_discard(ofl
->ofl_lml
, M_MACH
, arsp
));
1081 * Perform any required TLS fixups.
1083 if (arsp
->rel_flags
& FLG_REL_TLSFIX
) {
1086 if ((ret
= tls_fixups(ofl
, arsp
)) == FIX_ERROR
)
1088 if (ret
== FIX_DONE
)
1093 * Perform any required GOTOP fixups.
1095 if (arsp
->rel_flags
& FLG_REL_GOTFIX
) {
1098 if ((ret
= gotop_fixups(ofl
, arsp
)) == FIX_ERROR
)
1100 if (ret
== FIX_DONE
)
1105 * If this is a relocation against the move table, or
1106 * expanded move table, adjust the relocation entries.
1108 if (RELAUX_GET_MOVE(arsp
))
1109 ld_adj_movereloc(ofl
, arsp
);
1111 sdp
= arsp
->rel_sym
;
1112 refaddr
= arsp
->rel_roffset
+
1113 (Off
)_elf_getxoff(arsp
->rel_isdesc
->is_indata
);
1115 if ((arsp
->rel_flags
& FLG_REL_CLVAL
) ||
1116 (arsp
->rel_flags
& FLG_REL_GOTCL
))
1118 else if (ELF_ST_TYPE(sdp
->sd_sym
->st_info
) == STT_SECTION
) {
1122 * The value for a symbol pointing to a SECTION
1123 * is based off of that sections position.
1125 if ((sdp
->sd_isc
->is_flags
& FLG_IS_RELUPD
) &&
1126 (sym
= ld_am_I_partial(arsp
, arsp
->rel_raddend
))) {
1128 * The symbol was moved, so adjust the value
1129 * relative to the new section.
1131 value
= _elf_getxoff(sym
->sd_isc
->is_indata
);
1132 if (sym
->sd_isc
->is_shdr
->sh_flags
& SHF_ALLOC
)
1133 value
+= sym
->sd_isc
->
1134 is_osdesc
->os_shdr
->sh_addr
;
1137 * The original raddend covers the displacement
1138 * from the section start to the desired
1139 * address. The value computed above gets us
1140 * from the section start to the start of the
1141 * symbol range. Adjust the old raddend to
1142 * remove the offset from section start to
1143 * symbol start, leaving the displacement
1144 * within the range of the symbol.
1146 arsp
->rel_raddend
-= sym
->sd_osym
->st_value
;
1148 value
= _elf_getxoff(sdp
->sd_isc
->is_indata
);
1149 if (sdp
->sd_isc
->is_shdr
->sh_flags
& SHF_ALLOC
)
1150 value
+= sdp
->sd_isc
->
1151 is_osdesc
->os_shdr
->sh_addr
;
1154 if (sdp
->sd_isc
->is_shdr
->sh_flags
& SHF_TLS
)
1155 value
-= ofl
->ofl_tlsphdr
->p_vaddr
;
1157 } else if (IS_SIZE(arsp
->rel_rtype
)) {
1159 * Size relocations require the symbols size.
1161 value
= sdp
->sd_sym
->st_size
;
1163 } else if ((sdp
->sd_flags
& FLG_SY_CAP
) &&
1164 sdp
->sd_aux
&& sdp
->sd_aux
->sa_PLTndx
) {
1166 * If relocation is against a capabilities symbol, we
1167 * need to jump to an associated PLT, so that at runtime
1168 * ld.so.1 is involved to determine the best binding
1169 * choice. Otherwise, the value is the symbols value.
1171 value
= ld_calc_plt_addr(sdp
, ofl
);
1174 value
= sdp
->sd_sym
->st_value
;
1177 * Relocation against the GLOBAL_OFFSET_TABLE.
1179 if ((arsp
->rel_flags
& FLG_REL_GOT
) &&
1180 !ld_reloc_set_aux_osdesc(ofl
, arsp
, ofl
->ofl_osgot
))
1182 osp
= RELAUX_GET_OSDESC(arsp
);
1185 * If loadable and not producing a relocatable object add the
1186 * sections virtual address to the reference address.
1188 if ((arsp
->rel_flags
& FLG_REL_LOAD
) &&
1189 ((flags
& FLG_OF_RELOBJ
) == 0))
1191 arsp
->rel_isdesc
->is_osdesc
->os_shdr
->sh_addr
;
1194 * If this entry has a PLT assigned to it, its value is actually
1195 * the address of the PLT (and not the address of the function).
1197 if (IS_PLT(arsp
->rel_rtype
)) {
1198 if (sdp
->sd_aux
&& sdp
->sd_aux
->sa_PLTndx
)
1199 value
= ld_calc_plt_addr(sdp
, ofl
);
1203 * Add relocations addend to value. Add extra
1204 * relocation addend if needed.
1206 value
+= arsp
->rel_raddend
;
1207 if (IS_EXTOFFSET(arsp
->rel_rtype
))
1208 value
+= RELAUX_GET_TYPEDATA(arsp
);
1211 * Determine whether the value needs further adjustment. Filter
1212 * through the attributes of the relocation to determine what
1213 * adjustment is required. Note, many of the following cases
1214 * are only applicable when a .got is present. As a .got is
1215 * not generated when a relocatable object is being built,
1216 * any adjustments that require a .got need to be skipped.
1218 if ((arsp
->rel_flags
& FLG_REL_GOT
) &&
1219 ((flags
& FLG_OF_RELOBJ
) == 0)) {
1227 * Clear the GOT table entry, on SPARC we clear
1228 * the entry and the 'value' if needed is stored
1229 * in an output relocations addend.
1231 * Calculate offset into GOT at which to apply
1234 if (arsp
->rel_flags
& FLG_REL_DTLS
)
1235 gref
= GOT_REF_TLSGD
;
1236 else if (arsp
->rel_flags
& FLG_REL_MTLS
)
1237 gref
= GOT_REF_TLSLD
;
1238 else if (arsp
->rel_flags
& FLG_REL_STLS
)
1239 gref
= GOT_REF_TLSIE
;
1241 gref
= GOT_REF_GENERIC
;
1243 gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
, gref
, ofl
, arsp
);
1246 if (arsp
->rel_rtype
== M_R_DTPOFF
)
1247 gotndx
= gnp
->gn_gotndx
+ 1;
1249 gotndx
= gnp
->gn_gotndx
;
1252 R1addr
= (Xword
)((-neggotoffset
* M_GOT_ENTSIZE
) +
1253 (gotndx
* M_GOT_ENTSIZE
));
1256 * Add the GOTs data's offset.
1258 R2addr
= R1addr
+ (uintptr_t)osp
->os_outdata
->d_buf
;
1260 DBG_CALL(Dbg_reloc_doact(ofl
->ofl_lml
,
1261 ELF_DBG_LD_ACT
, M_MACH
, SHT_RELA
,
1262 arsp
, R1addr
, value
, ld_reloc_sym_name
));
1267 if (ofl
->ofl_flags1
& FLG_OF1_ENCDIFF
)
1268 *(Xword
*)R2addr
= ld_bswap_Xword(value
);
1270 *(Xword
*)R2addr
= value
;
1273 } else if (IS_GOT_BASED(arsp
->rel_rtype
) &&
1274 ((flags
& FLG_OF_RELOBJ
) == 0)) {
1275 value
-= (ofl
->ofl_osgot
->os_shdr
->sh_addr
+
1276 (-neggotoffset
* M_GOT_ENTSIZE
));
1278 } else if (IS_PC_RELATIVE(arsp
->rel_rtype
)) {
1281 } else if (IS_TLS_INS(arsp
->rel_rtype
) &&
1282 IS_GOT_RELATIVE(arsp
->rel_rtype
) &&
1283 ((flags
& FLG_OF_RELOBJ
) == 0)) {
1287 if (arsp
->rel_flags
& FLG_REL_STLS
)
1288 gref
= GOT_REF_TLSIE
;
1289 else if (arsp
->rel_flags
& FLG_REL_DTLS
)
1290 gref
= GOT_REF_TLSGD
;
1291 else if (arsp
->rel_flags
& FLG_REL_MTLS
)
1292 gref
= GOT_REF_TLSLD
;
1294 gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
, gref
, ofl
, arsp
);
1297 value
= gnp
->gn_gotndx
* M_GOT_ENTSIZE
;
1299 } else if (IS_GOT_RELATIVE(arsp
->rel_rtype
) &&
1300 ((flags
& FLG_OF_RELOBJ
) == 0)) {
1303 gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
,
1304 GOT_REF_GENERIC
, ofl
, arsp
);
1307 value
= gnp
->gn_gotndx
* M_GOT_ENTSIZE
;
1309 } else if ((arsp
->rel_flags
& FLG_REL_STLS
) &&
1310 ((flags
& FLG_OF_RELOBJ
) == 0)) {
1314 * This is the LE TLS reference model. Static offset is
1315 * hard-coded, and negated so that it can be added to
1316 * the thread pointer (%g7)
1319 S_ROUND(ofl
->ofl_tlsphdr
->p_memsz
, M_TLSSTATALIGN
);
1320 value
= -(tlsstatsize
- value
);
1323 if (arsp
->rel_isdesc
->is_file
)
1324 ifl_name
= arsp
->rel_isdesc
->is_file
->ifl_name
;
1326 ifl_name
= MSG_INTL(MSG_STR_NULL
);
1329 * Make sure we have data to relocate. Compiler and assembler
1330 * developers have been known to generate relocations against
1331 * invalid sections (normally .bss), so for their benefit give
1332 * them sufficient information to help analyze the problem.
1333 * End users should never see this.
1335 if (arsp
->rel_isdesc
->is_indata
->d_buf
== 0) {
1336 Conv_inv_buf_t inv_buf
;
1338 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_EMPTYSEC
),
1339 conv_reloc_SPARC_type(arsp
->rel_rtype
, 0, &inv_buf
),
1340 ifl_name
, ld_reloc_sym_name(arsp
),
1341 EC_WORD(arsp
->rel_isdesc
->is_scnndx
),
1342 arsp
->rel_isdesc
->is_name
);
1347 * Get the address of the data item we need to modify.
1349 addr
= (uchar_t
*)((uintptr_t)arsp
->rel_roffset
+
1350 (uintptr_t)_elf_getxoff(arsp
->rel_isdesc
->is_indata
));
1352 DBG_CALL(Dbg_reloc_doact(ofl
->ofl_lml
, ELF_DBG_LD_ACT
,
1353 M_MACH
, SHT_RELA
, arsp
, EC_NATPTR(addr
), value
,
1354 ld_reloc_sym_name
));
1355 addr
+= (uintptr_t)osp
->os_outdata
->d_buf
;
1357 if ((((uintptr_t)addr
- (uintptr_t)ofl
->ofl_nehdr
) >
1358 ofl
->ofl_size
) || (arsp
->rel_roffset
>
1359 osp
->os_shdr
->sh_size
)) {
1360 Conv_inv_buf_t inv_buf
;
1363 if (((uintptr_t)addr
- (uintptr_t)ofl
->ofl_nehdr
) >
1367 class = ERR_WARNING
;
1369 ld_eprintf(ofl
, class, MSG_INTL(MSG_REL_INVALOFFSET
),
1370 conv_reloc_SPARC_type(arsp
->rel_rtype
, 0, &inv_buf
),
1371 ifl_name
, EC_WORD(arsp
->rel_isdesc
->is_scnndx
),
1372 arsp
->rel_isdesc
->is_name
, ld_reloc_sym_name(arsp
),
1373 EC_ADDR((uintptr_t)addr
-
1374 (uintptr_t)ofl
->ofl_nehdr
));
1376 if (class == ERR_FATAL
) {
1377 return_code
= S_ERROR
;
1383 * If '-z noreloc' is specified - skip the do_reloc stage.
1385 if (OFL_DO_RELOC(ofl
)) {
1386 if (do_reloc_ld(arsp
, addr
, &value
, ld_reloc_sym_name
,
1387 ifl_name
, OFL_SWAP_RELOC_DATA(ofl
, arsp
),
1388 ofl
->ofl_lml
) == 0) {
1389 ofl
->ofl_flags
|= FLG_OF_FATAL
;
1390 return_code
= S_ERROR
;
1394 return (return_code
);
1398 ld_add_outrel(Word flags
, Rel_desc
*rsp
, Ofl_desc
*ofl
)
1401 Sym_desc
*sdp
= rsp
->rel_sym
;
1402 Conv_inv_buf_t inv_buf
;
1405 * Static executables *do not* want any relocations against them.
1406 * Since our engine still creates relocations against a WEAK UNDEFINED
1407 * symbol in a static executable, it's best to disable them here
1408 * instead of through out the relocation code.
1410 if (OFL_IS_STATIC_EXEC(ofl
))
1414 * Certain relocations do not make sense in a 64bit shared object,
1415 * if building a shared object do a sanity check on the output
1416 * relocations being created.
1418 if (ofl
->ofl_flags
& FLG_OF_SHAROBJ
) {
1419 Word rtype
= rsp
->rel_rtype
;
1421 * Because the R_SPARC_HIPLT22 & R_SPARC_LOPLT10 relocations
1422 * are not relative they make no sense to create in a shared
1423 * object - so emit the proper error message if that occurs.
1425 if ((rtype
== R_SPARC_HIPLT22
) || (rtype
== R_SPARC_LOPLT10
)) {
1426 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_UNRELREL
),
1427 conv_reloc_SPARC_type(rsp
->rel_rtype
, 0, &inv_buf
),
1428 rsp
->rel_isdesc
->is_file
->ifl_name
,
1429 ld_reloc_sym_name(rsp
));
1434 * Each of the following relocations requires that the
1435 * object being built be loaded in either the upper 32 or
1436 * 44 bit range of memory. Since shared libraries traditionally
1437 * are loaded in the lower range of memory - this isn't going
1440 if ((rtype
== R_SPARC_H44
) || (rtype
== R_SPARC_M44
) ||
1441 (rtype
== R_SPARC_L44
)) {
1442 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_SHOBJABS44
),
1443 conv_reloc_SPARC_type(rsp
->rel_rtype
, 0, &inv_buf
),
1444 rsp
->rel_isdesc
->is_file
->ifl_name
,
1445 ld_reloc_sym_name(rsp
));
1452 * If we are adding a output relocation against a section
1453 * symbol (non-RELATIVE) then mark that section. These sections
1454 * will be added to the .dynsym symbol table.
1456 if (sdp
&& (rsp
->rel_rtype
!= M_R_RELATIVE
) &&
1457 ((flags
& FLG_REL_SCNNDX
) ||
1458 (ELF_ST_TYPE(sdp
->sd_sym
->st_info
) == STT_SECTION
))) {
1461 * If this is a COMMON symbol - no output section
1462 * exists yet - (it's created as part of sym_validate()).
1463 * So - we mark here that when it's created it should
1464 * be tagged with the FLG_OS_OUTREL flag.
1466 if ((sdp
->sd_flags
& FLG_SY_SPECSEC
) &&
1467 (sdp
->sd_sym
->st_shndx
== SHN_COMMON
)) {
1468 if (ELF_ST_TYPE(sdp
->sd_sym
->st_info
) != STT_TLS
)
1469 ofl
->ofl_flags1
|= FLG_OF1_BSSOREL
;
1471 ofl
->ofl_flags1
|= FLG_OF1_TLSOREL
;
1474 Is_desc
*isp
= sdp
->sd_isc
;
1476 if (isp
&& ((osp
= isp
->is_osdesc
) != NULL
) &&
1477 ((osp
->os_flags
& FLG_OS_OUTREL
) == 0)) {
1478 ofl
->ofl_dynshdrcnt
++;
1479 osp
->os_flags
|= FLG_OS_OUTREL
;
1484 /* Enter it into the output relocation cache */
1485 if ((orsp
= ld_reloc_enter(ofl
, &ofl
->ofl_outrels
, rsp
, flags
)) == NULL
)
1488 if (flags
& FLG_REL_GOT
)
1489 ofl
->ofl_relocgotsz
+= (Xword
)sizeof (Rela
);
1490 else if (flags
& FLG_REL_PLT
)
1491 ofl
->ofl_relocpltsz
+= (Xword
)sizeof (Rela
);
1492 else if (flags
& FLG_REL_BSS
)
1493 ofl
->ofl_relocbsssz
+= (Xword
)sizeof (Rela
);
1494 else if (flags
& FLG_REL_NOINFO
)
1495 ofl
->ofl_relocrelsz
+= (Xword
)sizeof (Rela
);
1497 RELAUX_GET_OSDESC(orsp
)->os_szoutrels
+= (Xword
)sizeof (Rela
);
1499 if (orsp
->rel_rtype
== M_R_RELATIVE
)
1500 ofl
->ofl_relocrelcnt
++;
1504 * When building a 64-bit object any R_SPARC_WDISP30 relocation is given
1505 * a plt padding entry, unless we're building a relocatable object
1506 * (ld -r) or -b is in effect.
1508 if ((orsp
->rel_rtype
== R_SPARC_WDISP30
) &&
1509 ((ofl
->ofl_flags
& (FLG_OF_BFLAG
| FLG_OF_RELOBJ
)) == 0) &&
1510 ((orsp
->rel_sym
->sd_flags
& FLG_SY_PLTPAD
) == 0)) {
1512 orsp
->rel_sym
->sd_flags
|= FLG_SY_PLTPAD
;
1516 * We don't perform sorting on PLT relocations because
1517 * they have already been assigned a PLT index and if we
1518 * were to sort them we would have to re-assign the plt indexes.
1520 if (!(flags
& FLG_REL_PLT
))
1521 ofl
->ofl_reloccnt
++;
1524 * Insure a GLOBAL_OFFSET_TABLE is generated if required.
1526 if (IS_GOT_REQUIRED(orsp
->rel_rtype
))
1527 ofl
->ofl_flags
|= FLG_OF_BLDGOT
;
1530 * Identify and possibly warn of a displacement relocation.
1532 if (orsp
->rel_flags
& FLG_REL_DISP
) {
1533 ofl
->ofl_dtflags_1
|= DF_1_DISPRELPND
;
1535 if (ofl
->ofl_flags
& FLG_OF_VERBOSE
)
1536 ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL4
), orsp
, ofl
);
1538 DBG_CALL(Dbg_reloc_ors_entry(ofl
->ofl_lml
, ELF_DBG_LD
, SHT_RELA
,
1544 * Process relocation against a register symbol. Note, of -z muldefs is in
1545 * effect there may have been multiple register definitions, which would have
1546 * been processed as non-fatal, with the first definition winning. But, we
1547 * will also process multiple relocations for these multiple definitions. In
1548 * this case we must only preserve the relocation for the definition that was
1549 * kept. The sad part is that register relocations don't typically specify
1550 * the register symbol with which they are associated, so we might have to
1551 * search the input files global symbols to determine if this relocation is
1555 ld_reloc_register(Rel_desc
*rsp
, Is_desc
*isp
, Ofl_desc
*ofl
)
1557 if (ofl
->ofl_flags
& FLG_OF_MULDEFS
) {
1558 Ifl_desc
*ifl
= isp
->is_file
;
1559 Sym_desc
*sdp
= rsp
->rel_sym
;
1562 Xword offset
= rsp
->rel_roffset
;
1565 for (ndx
= ifl
->ifl_locscnt
;
1566 ndx
< ifl
->ifl_symscnt
; ndx
++) {
1567 if (((sdp
= ifl
->ifl_oldndx
[ndx
]) != 0) &&
1568 (sdp
->sd_flags
& FLG_SY_REGSYM
) &&
1569 (sdp
->sd_sym
->st_value
== offset
))
1573 if (sdp
&& (sdp
->sd_file
!= ifl
))
1576 return (ld_add_outrel((rsp
->rel_flags
| FLG_REL_REG
), rsp
, ofl
));
1580 * process relocation for a LOCAL symbol
1583 ld_reloc_local(Rel_desc
*rsp
, Ofl_desc
*ofl
)
1585 ofl_flag_t flags
= ofl
->ofl_flags
;
1586 Sym_desc
*sdp
= rsp
->rel_sym
;
1587 Word shndx
= sdp
->sd_sym
->st_shndx
;
1590 * if ((shared object) and (not pc relative relocation) and
1591 * (not against ABS symbol))
1593 * if (rtype != R_SPARC_32)
1595 * build relocation against section
1597 * build R_SPARC_RELATIVE
1601 if ((flags
& FLG_OF_SHAROBJ
) && (rsp
->rel_flags
& FLG_REL_LOAD
) &&
1602 !(IS_PC_RELATIVE(rsp
->rel_rtype
)) && !(IS_SIZE(rsp
->rel_rtype
)) &&
1603 !(IS_GOT_BASED(rsp
->rel_rtype
)) &&
1604 !(rsp
->rel_isdesc
!= NULL
&&
1605 (rsp
->rel_isdesc
->is_shdr
->sh_type
== SHT_SUNW_dof
)) &&
1606 (((sdp
->sd_flags
& FLG_SY_SPECSEC
) == 0) ||
1607 (shndx
!= SHN_ABS
) || (sdp
->sd_aux
&& sdp
->sd_aux
->sa_symspec
))) {
1608 Word ortype
= rsp
->rel_rtype
;
1610 if ((rsp
->rel_rtype
!= R_SPARC_32
) &&
1611 (rsp
->rel_rtype
!= R_SPARC_PLT32
) &&
1612 (rsp
->rel_rtype
!= R_SPARC_64
))
1613 return (ld_add_outrel((FLG_REL_SCNNDX
| FLG_REL_ADVAL
),
1616 rsp
->rel_rtype
= R_SPARC_RELATIVE
;
1617 if (ld_add_outrel(FLG_REL_ADVAL
, rsp
, ofl
) == S_ERROR
)
1619 rsp
->rel_rtype
= ortype
;
1624 * If the relocation is against a 'non-allocatable' section
1625 * and we can not resolve it now - then give a warning
1628 * We can not resolve the symbol if either:
1630 * b) it's defined in a shared library and a
1631 * COPY relocation hasn't moved it to the executable
1633 * Note: because we process all of the relocations against the
1634 * text segment before any others - we know whether
1635 * or not a copy relocation will be generated before
1636 * we get here (see reloc_init()->reloc_segments()).
1638 if (!(rsp
->rel_flags
& FLG_REL_LOAD
) &&
1639 ((shndx
== SHN_UNDEF
) ||
1640 ((sdp
->sd_ref
== REF_DYN_NEED
) &&
1641 ((sdp
->sd_flags
& FLG_SY_MVTOCOMM
) == 0)))) {
1642 Conv_inv_buf_t inv_buf
;
1643 Os_desc
*osp
= RELAUX_GET_OSDESC(rsp
);
1646 * If the relocation is against a SHT_SUNW_ANNOTATE
1647 * section - then silently ignore that the relocation
1648 * can not be resolved.
1650 if (osp
&& (osp
->os_shdr
->sh_type
== SHT_SUNW_ANNOTATE
))
1652 ld_eprintf(ofl
, ERR_WARNING
, MSG_INTL(MSG_REL_EXTERNSYM
),
1653 conv_reloc_SPARC_type(rsp
->rel_rtype
, 0, &inv_buf
),
1654 rsp
->rel_isdesc
->is_file
->ifl_name
,
1655 ld_reloc_sym_name(rsp
), osp
->os_name
);
1660 * Perform relocation.
1662 return (ld_add_actrel(NULL
, rsp
, ofl
));
1666 * Establish a relocation transition. Note, at this point of input relocation
1667 * processing, we have no idea of the relocation value that will be used in
1668 * the eventual relocation calculation. This value is only known after the
1669 * initial image has been constructed. Therefore, there is a small chance
1670 * that a value can exceed the capabilities of the transitioned relocation.
1671 * One example might be the offset from the GOT to a symbol.
1673 * The only instance of this failure discovered so far has been via the use of
1674 * ABS symbols to represent an external memory location. This situation is
1675 * rare, since ABS symbols aren't typically generated by the compilers.
1676 * Therefore, our solution is to excluded ABS symbols from the transition
1677 * relocation possibilities. As an additional safeguard, if an inappropriate
1678 * value is passed to the final relocation engine, a verification ("V")
1679 * relocation should trigger a fatal error condition.
1682 ld_reloc_GOTOP(Boolean local
, Rel_desc
*rsp
, Ofl_desc
*ofl
)
1684 Word rtype
= rsp
->rel_rtype
;
1686 if (!local
|| (rsp
->rel_sym
->sd_sym
->st_shndx
== SHN_ABS
)) {
1688 * When binding to a external symbol, no fixups are required
1689 * and the GOTDATA_OP relocation can be ignored.
1691 if (rtype
== R_SPARC_GOTDATA_OP
)
1693 return (ld_reloc_GOT_relative(local
, rsp
, ofl
));
1697 * When binding to a local symbol the relocations can be transitioned:
1699 * R_*_GOTDATA_OP_HIX22 -> R_*_GOTDATA_HIX22
1700 * R_*_GOTDATA_OP_LOX10 -> R_*_GOTDATA_LOX10
1701 * R_*_GOTDATA_OP -> instruction fixup
1703 return (ld_add_actrel(FLG_REL_GOTFIX
, rsp
, ofl
));
1707 ld_reloc_TLS(Boolean local
, Rel_desc
*rsp
, Ofl_desc
*ofl
)
1709 Word rtype
= rsp
->rel_rtype
;
1710 Sym_desc
*sdp
= rsp
->rel_sym
;
1711 ofl_flag_t flags
= ofl
->ofl_flags
;
1715 * If we're building an executable - use either the IE or LE access
1716 * model. If we're building a shared object process any IE model.
1718 if ((flags
& FLG_OF_EXEC
) || (IS_TLS_IE(rtype
))) {
1720 * Set the DF_STATIC_TLS flag.
1722 ofl
->ofl_dtflags
|= DF_STATIC_TLS
;
1724 if (!local
|| ((flags
& FLG_OF_EXEC
) == 0)) {
1726 * When processing static TLS - these relocations
1729 if ((rtype
== R_SPARC_TLS_IE_LD
) ||
1730 (rtype
== R_SPARC_TLS_IE_LDX
) ||
1731 (rtype
== R_SPARC_TLS_IE_ADD
))
1735 * Assign a GOT entry for IE static TLS references.
1737 if (((rtype
== R_SPARC_TLS_GD_HI22
) ||
1738 (rtype
== R_SPARC_TLS_GD_LO10
) ||
1739 (rtype
== R_SPARC_TLS_IE_HI22
) ||
1740 (rtype
== R_SPARC_TLS_IE_LO10
)) &&
1741 ((gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
,
1742 GOT_REF_TLSIE
, ofl
, rsp
)) == NULL
)) {
1744 if (ld_assign_got_TLS(local
, rsp
, ofl
, sdp
,
1745 gnp
, GOT_REF_TLSIE
, FLG_REL_STLS
,
1746 rtype
, M_R_TPOFF
, NULL
) == S_ERROR
)
1753 if (IS_TLS_IE(rtype
))
1754 return (ld_add_actrel(FLG_REL_STLS
, rsp
, ofl
));
1757 * Fixups are required for other executable models.
1759 return (ld_add_actrel((FLG_REL_TLSFIX
| FLG_REL_STLS
),
1766 if (IS_TLS_LE(rtype
))
1767 return (ld_add_actrel(FLG_REL_STLS
, rsp
, ofl
));
1770 * When processing static TLS - these relocations can be
1773 if (rtype
== R_SPARC_TLS_IE_ADD
)
1776 return (ld_add_actrel((FLG_REL_TLSFIX
| FLG_REL_STLS
),
1781 * Building a shared object.
1783 * For dynamic TLS references, ADD relocations are ignored.
1785 if ((rtype
== R_SPARC_TLS_GD_ADD
) || (rtype
== R_SPARC_TLS_LDM_ADD
) ||
1786 (rtype
== R_SPARC_TLS_LDO_ADD
))
1790 * Assign a GOT entry for a dynamic TLS reference.
1792 if (((rtype
== R_SPARC_TLS_LDM_HI22
) ||
1793 (rtype
== R_SPARC_TLS_LDM_LO10
)) &&
1794 ((gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
, GOT_REF_TLSLD
,
1795 ofl
, rsp
)) == NULL
)) {
1797 if (ld_assign_got_TLS(local
, rsp
, ofl
, sdp
, gnp
, GOT_REF_TLSLD
,
1798 FLG_REL_MTLS
, rtype
, M_R_DTPMOD
, 0) == S_ERROR
)
1801 } else if (((rtype
== R_SPARC_TLS_GD_HI22
) ||
1802 (rtype
== R_SPARC_TLS_GD_LO10
)) &&
1803 ((gnp
= ld_find_got_ndx(sdp
->sd_GOTndxs
, GOT_REF_TLSGD
,
1804 ofl
, rsp
)) == NULL
)) {
1806 if (ld_assign_got_TLS(local
, rsp
, ofl
, sdp
, gnp
, GOT_REF_TLSGD
,
1807 FLG_REL_DTLS
, rtype
, M_R_DTPMOD
, M_R_DTPOFF
) == S_ERROR
)
1812 * For GD/LD TLS reference - TLS_{GD,LD}_CALL, this will eventually
1813 * cause a call to __tls_get_addr(). Convert this relocation to that
1814 * symbol now, and prepare for the PLT magic.
1816 if ((rtype
== R_SPARC_TLS_GD_CALL
) || (rtype
== R_SPARC_TLS_LDM_CALL
)) {
1817 Sym_desc
*tlsgetsym
;
1819 if ((tlsgetsym
= ld_sym_add_u(MSG_ORIG(MSG_SYM_TLSGETADDR_U
),
1820 ofl
, MSG_STR_TLSREL
)) == (Sym_desc
*)S_ERROR
)
1823 rsp
->rel_sym
= tlsgetsym
;
1824 rsp
->rel_rtype
= R_SPARC_WPLT30
;
1826 if (ld_reloc_plt(rsp
, ofl
) == S_ERROR
)
1830 rsp
->rel_rtype
= rtype
;
1834 if (IS_TLS_LD(rtype
))
1835 return (ld_add_actrel(FLG_REL_MTLS
, rsp
, ofl
));
1837 return (ld_add_actrel(FLG_REL_DTLS
, rsp
, ofl
));
1841 * ld_allocate_got: if a GOT is to be made, after the section is built this
1842 * function is called to allocate all the GOT slots. The allocation is
1843 * deferred until after all GOTs have been counted and sorted according
1844 * to their size, for only then will we know how to allocate them on
1845 * a processor like SPARC which has different models for addressing the
1846 * GOT. SPARC has two: small and large, small uses a signed 13-bit offset
1847 * into the GOT, whereas large uses an unsigned 32-bit offset.
1849 static Sword small_index
; /* starting index for small GOT entries */
1850 static Sword mixed_index
; /* starting index for mixed GOT entries */
1851 static Sword large_index
; /* starting index for large GOT entries */
1854 ld_assign_got(Ofl_desc
*ofl
, Sym_desc
*sdp
)
1859 for (ALIST_TRAVERSE(sdp
->sd_GOTndxs
, idx
, gnp
)) {
1861 Gotref gref
= gnp
->gn_gotref
;
1863 if ((gref
== GOT_REF_TLSGD
) || (gref
== GOT_REF_TLSLD
))
1868 switch (gnp
->gn_gotndx
) {
1870 gnp
->gn_gotndx
= small_index
;
1871 small_index
+= gotents
;
1872 if (small_index
== 0)
1873 small_index
= M_GOT_XNumber
;
1876 gnp
->gn_gotndx
= mixed_index
;
1877 mixed_index
+= gotents
;
1880 gnp
->gn_gotndx
= large_index
;
1881 large_index
+= gotents
;
1884 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_ASSIGNGOT
),
1885 EC_XWORD(gnp
->gn_gotndx
), demangle(sdp
->sd_name
));
1893 ld_assign_got_ndx(Alist
**alpp
, Gotndx
*pgnp
, Gotref gref
, Ofl_desc
*ofl
,
1894 Rel_desc
*rsp
, Sym_desc
*sdp
)
1901 /* Some TLS requires two relocations with two GOT entries */
1902 if ((gref
== GOT_REF_TLSGD
) || (gref
== GOT_REF_TLSLD
))
1907 raddend
= rsp
->rel_raddend
;
1908 if (pgnp
&& (pgnp
->gn_addend
== raddend
) && (pgnp
->gn_gotref
== gref
)) {
1911 * If an entry for this addend already exists, determine if it
1912 * has mixed mode GOT access (both PIC and pic).
1914 * In order to be accessible by both large and small pic,
1915 * a mixed mode GOT must be located in the positive index
1916 * range above _GLOBAL_OFFSET_TABLE_, and in the range
1917 * reachable small pic. This is necessary because the large
1918 * PIC mode cannot use a negative offset. This implies that
1919 * there can be no more than (M_GOT_MAXSMALL/2 - M_GOT_XNumber)
1922 switch (pgnp
->gn_gotndx
) {
1925 * This one was previously identified as a small
1926 * GOT. If this access is large, then convert
1929 if (rsp
->rel_rtype
!= R_SPARC_GOT13
) {
1930 pgnp
->gn_gotndx
= M_GOT_MIXED
;
1931 mixgotcnt
+= gotents
;
1937 * This one was previously identified as a large
1938 * GOT. If this access is small, convert it to mixed.
1940 if (rsp
->rel_rtype
== R_SPARC_GOT13
) {
1941 smlgotcnt
+= gotents
;
1942 mixgotcnt
+= gotents
;
1943 pgnp
->gn_gotndx
= M_GOT_MIXED
;
1944 sdp
->sd_flags
|= FLG_SY_SMGOT
;
1951 gn
.gn_addend
= raddend
;
1952 gn
.gn_gotref
= gref
;
1954 if (rsp
->rel_rtype
== R_SPARC_GOT13
) {
1955 gn
.gn_gotndx
= M_GOT_SMALL
;
1956 smlgotcnt
+= gotents
;
1957 sdp
->sd_flags
|= FLG_SY_SMGOT
;
1959 gn
.gn_gotndx
= M_GOT_LARGE
;
1961 ofl
->ofl_gotcnt
+= gotents
;
1963 if (gref
== GOT_REF_TLSLD
) {
1964 if (ofl
->ofl_tlsldgotndx
== NULL
) {
1965 if ((gnp
= libld_malloc(sizeof (Gotndx
))) == NULL
)
1967 (void) memcpy(gnp
, &gn
, sizeof (Gotndx
));
1968 ofl
->ofl_tlsldgotndx
= gnp
;
1974 for (ALIST_TRAVERSE(*alpp
, idx
, gnp
)) {
1975 if (gnp
->gn_addend
> raddend
)
1980 * GOT indexes are maintained on an Alist, where there is typically
1981 * only one index. The usage of this list is to scan the list to find
1982 * an index, and then apply that index immediately to a relocation.
1983 * Thus there are no external references to these GOT index structures
1984 * that can be compromised by the Alist being reallocated.
1986 if (alist_insert(alpp
, &gn
, sizeof (Gotndx
),
1987 AL_CNT_SDP_GOT
, idx
) == NULL
)
1994 ld_assign_plt_ndx(Sym_desc
* sdp
, Ofl_desc
*ofl
)
1996 sdp
->sd_aux
->sa_PLTndx
= 1 + ofl
->ofl_pltcnt
++;
2001 ld_allocate_got(Ofl_desc
* ofl
)
2003 const Sword first_large_ndx
= M_GOT_MAXSMALL
/ 2;
2008 * Sanity check -- is this going to fit at all? There are two
2009 * limits to be concerned about:
2010 * 1) There is a limit on the number of small pic GOT indices,
2011 * given by M_GOT_MAXSMALL.
2012 * 2) If there are more than (M_GOT_MAXSMALL/2 - M_GOT_XNumber)
2013 * small GOT indices, there will be items at negative
2014 * offsets from _GLOBAL_OFFSET_TABLE_. Items that are
2015 * accessed via large (PIC) code cannot reach these
2016 * negative slots, so mixed mode items must be in the
2017 * non-negative range. This implies a limit of
2018 * (M_GOT_MAXSMALL/2 - M_GOT_XNumber) mixed mode indices.
2020 if (smlgotcnt
> M_GOT_MAXSMALL
) {
2021 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_SMALLGOT
),
2022 EC_WORD(smlgotcnt
), M_GOT_MAXSMALL
);
2025 if (mixgotcnt
> (first_large_ndx
- M_GOT_XNumber
)) {
2026 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_REL_MIXEDGOT
),
2027 EC_WORD(mixgotcnt
), first_large_ndx
- M_GOT_XNumber
);
2032 * Set starting offset to be either 0, or a negative index into
2033 * the GOT based on the number of small symbols we've got.
2035 neggotoffset
= ((smlgotcnt
>= first_large_ndx
) ?
2036 (first_large_ndx
- smlgotcnt
) : 0);
2039 * Initialize the got offsets used by assign_got() to
2041 * small - Starting index of items referenced only
2042 * by small offsets (-Kpic).
2043 * mixed - Starting index of items referenced
2044 * by both large (-KPIC) and small (-Kpic).
2045 * large - Indexes referenced only by large (-KPIC)
2047 * Small items can have negative indexes (i.e. lie below
2048 * _GLOBAL_OFFSET_TABLE_). Mixed and large items must have
2049 * non-negative offsets.
2051 small_index
= (neggotoffset
== 0) ? M_GOT_XNumber
: neggotoffset
;
2052 large_index
= neggotoffset
+ smlgotcnt
;
2053 mixed_index
= large_index
- mixgotcnt
;
2056 * Assign bias to GOT symbols.
2058 addr
= -neggotoffset
* M_GOT_ENTSIZE
;
2059 if ((sdp
= ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL
), SYM_NOHASH
,
2060 NULL
, ofl
)) != NULL
)
2061 sdp
->sd_sym
->st_value
= addr
;
2062 if ((sdp
= ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U
), SYM_NOHASH
,
2063 NULL
, ofl
)) != NULL
)
2064 sdp
->sd_sym
->st_value
= addr
;
2066 if (ofl
->ofl_tlsldgotndx
) {
2067 ofl
->ofl_tlsldgotndx
->gn_gotndx
= large_index
;
2074 * Initializes .got[0] with the _DYNAMIC symbol value.
2077 ld_fillin_gotplt(Ofl_desc
*ofl
)
2079 if (ofl
->ofl_osgot
) {
2082 if ((sdp
= ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U
),
2083 SYM_NOHASH
, NULL
, ofl
)) != NULL
) {
2086 genptr
= ((uchar_t
*)ofl
->ofl_osgot
->os_outdata
->d_buf
+
2087 (-neggotoffset
* M_GOT_ENTSIZE
) +
2088 (M_GOT_XDYNAMIC
* M_GOT_ENTSIZE
));
2090 *((Xword
*)genptr
) = sdp
->sd_sym
->st_value
;
2091 if (ofl
->ofl_flags1
& FLG_OF1_ENCDIFF
)
2093 *((Xword
*)genptr
) =
2095 ld_bswap_Xword(*((Xword
*)genptr
));
2104 * Template for generating "void (*)(void)" function
2106 static const uchar_t nullfunc_tmpl
[] = {
2107 /* 0x00 */ 0x81, 0xc3, 0xe0, 0x08, /* retl */
2108 /* 0x04 */ 0x01, 0x00, 0x00, 0x00 /* nop */
2114 * Return the ld_targ definition for this target.
2117 ld_targ_init_sparc(void)
2119 static const Target _ld_targ
= {
2121 M_MACH
, /* m_mach */
2122 M_MACHPLUS
, /* m_machplus */
2123 M_FLAGSPLUS
, /* m_flagsplus */
2124 M_CLASS
, /* m_class */
2125 M_DATA
, /* m_data */
2127 M_SEGM_ALIGN
, /* m_segm_align */
2128 M_SEGM_ORIGIN
, /* m_segm_origin */
2129 M_SEGM_AORIGIN
, /* m_segm_aorigin */
2130 M_DATASEG_PERM
, /* m_dataseg_perm */
2131 M_STACK_PERM
, /* m_stack_perm */
2132 M_WORD_ALIGN
, /* m_word_align */
2135 MSG_ORIG(MSG_PTH_RTLD_SPARCV9
),
2137 MSG_ORIG(MSG_PTH_RTLD
),
2140 /* Relocation type codes */
2141 M_R_ARRAYADDR
, /* m_r_arrayaddr */
2142 M_R_COPY
, /* m_r_copy */
2143 M_R_GLOB_DAT
, /* m_r_glob_dat */
2144 M_R_JMP_SLOT
, /* m_r_jmp_slot */
2145 M_R_NUM
, /* m_r_num */
2146 M_R_NONE
, /* m_r_none */
2147 M_R_RELATIVE
, /* m_r_relative */
2148 M_R_REGISTER
, /* m_r_register */
2150 /* Relocation related constants */
2151 M_REL_DT_COUNT
, /* m_rel_dt_count */
2152 M_REL_DT_ENT
, /* m_rel_dt_ent */
2153 M_REL_DT_SIZE
, /* m_rel_dt_size */
2154 M_REL_DT_TYPE
, /* m_rel_dt_type */
2155 M_REL_SHT_TYPE
, /* m_rel_sht_type */
2157 /* GOT related constants */
2158 M_GOT_ENTSIZE
, /* m_got_entsize */
2159 M_GOT_XNumber
, /* m_got_xnumber */
2161 /* PLT related constants */
2162 M_PLT_ALIGN
, /* m_plt_align */
2163 M_PLT_ENTSIZE
, /* m_plt_entsize */
2164 M_PLT_RESERVSZ
, /* m_plt_reservsz */
2165 M_PLT_SHF_FLAGS
, /* m_plt_shf_flags */
2167 /* Section type of .eh_frame/.eh_frame_hdr sections */
2168 SHT_PROGBITS
, /* m_sht_unwind */
2170 M_DT_REGISTER
, /* m_dt_register */
2172 { /* Target_machid */
2173 M_ID_ARRAY
, /* id_array */
2174 M_ID_BSS
, /* id_bss */
2175 M_ID_CAP
, /* id_cap */
2176 M_ID_CAPINFO
, /* id_capinfo */
2177 M_ID_CAPCHAIN
, /* id_capchain */
2178 M_ID_DATA
, /* id_data */
2179 M_ID_DYNAMIC
, /* id_dynamic */
2180 M_ID_DYNSORT
, /* id_dynsort */
2181 M_ID_DYNSTR
, /* id_dynstr */
2182 M_ID_DYNSYM
, /* id_dynsym */
2183 M_ID_DYNSYM_NDX
, /* id_dynsym_ndx */
2184 M_ID_GOT
, /* id_got */
2185 M_ID_GOTDATA
, /* id_gotdata */
2186 M_ID_HASH
, /* id_hash */
2187 M_ID_INTERP
, /* id_interp */
2188 M_ID_UNKNOWN
, /* id_lbss (unused) */
2189 M_ID_LDYNSYM
, /* id_ldynsym */
2190 M_ID_NOTE
, /* id_note */
2191 M_ID_NULL
, /* id_null */
2192 M_ID_PLT
, /* id_plt */
2193 M_ID_REL
, /* id_rel */
2194 M_ID_STRTAB
, /* id_strtab */
2195 M_ID_SYMINFO
, /* id_syminfo */
2196 M_ID_SYMTAB
, /* id_symtab */
2197 M_ID_SYMTAB_NDX
, /* id_symtab_ndx */
2198 M_ID_TEXT
, /* id_text */
2199 M_ID_TLS
, /* id_tls */
2200 M_ID_TLSBSS
, /* id_tlsbss */
2201 M_ID_UNKNOWN
, /* id_unknown */
2202 M_ID_UNWIND
, /* id_unwind */
2203 M_ID_UNWINDHDR
, /* id_unwindhdr */
2204 M_ID_USER
, /* id_user */
2205 M_ID_VERSION
, /* id_version */
2207 { /* Target_nullfunc */
2208 nullfunc_tmpl
, /* nf_template */
2209 sizeof (nullfunc_tmpl
), /* nf_size */
2211 { /* Target_fillfunc */
2213 * On sparc, special filling of executable sections
2214 * is undesirable, and the default 0 fill supplied
2215 * by libelf is preferred:
2217 * - 0 fill is interpreted as UNIMP instructions,
2218 * which cause an illegal_instruction_trap. These
2219 * serve as a sentinel against poorly written
2220 * code. The sparc architecture manual discusses
2221 * this as providing a measure of runtime safety.
2223 * - The one place where a hole should conceivably
2224 * be filled with NOP instructions is in the
2225 * .init/.fini sections. However, the sparc
2226 * assembler sizes the sections it generates
2227 * to a multiple of the section alignment, and as
2228 * such, takes the filling task out of our hands.
2229 * Furthermore, the sparc assembler uses 0-fill
2230 * for this, forcing the authors of sparc
2231 * assembler for .init/.fini sections to be aware
2232 * of this case and explicitly supply NOP fill.
2233 * Hence, there is no role for the link-editor.
2235 NULL
/* ff_execfill */
2237 { /* Target_machrel */
2240 ld_init_rel
, /* mr_init_rel */
2241 ld_mach_eflags
, /* mr_mach_eflags */
2242 ld_mach_make_dynamic
, /* mr_mach_make_dynamic */
2243 ld_mach_update_odynamic
, /* mr_mach_update_odynamic */
2244 ld_calc_plt_addr
, /* mr_calc_plt_addr */
2245 ld_perform_outreloc
, /* mr_perform_outreloc */
2246 ld_do_activerelocs
, /* mr_do_activerelocs */
2247 ld_add_outrel
, /* mr_add_outrel */
2248 ld_reloc_register
, /* mr_reloc_register */
2249 ld_reloc_local
, /* mr_reloc_local */
2250 ld_reloc_GOTOP
, /* mr_reloc_GOTOP */
2251 ld_reloc_TLS
, /* mr_reloc_TLS */
2252 ld_assign_got
, /* mr_assign_got */
2253 ld_find_got_ndx
, /* mr_find_got_ndx */
2254 ld_calc_got_offset
, /* mr_calc_got_offset */
2255 ld_assign_got_ndx
, /* mr_assign_got_ndx */
2256 ld_assign_plt_ndx
, /* mr_assign_plt_ndx */
2257 ld_allocate_got
, /* mr_allocate_got */
2258 ld_fillin_gotplt
, /* mr_fillin_gotplt */
2260 { /* Target_machsym */
2261 ld_reg_check_sparc
, /* ms_reg_check */
2262 ld_mach_sym_typecheck_sparc
, /* ms_mach_sym_typecheck */
2263 ld_is_regsym_sparc
, /* ms_is_regsym */
2264 ld_reg_find_sparc
, /* ms_reg_find */
2265 ld_reg_enter_sparc
/* ms_reg_enter */