1/*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#if	defined(_KERNEL)
27#include	<sys/types.h>
28#include	"krtld/reloc.h"
29#else
30#define	ELF_TARGET_SPARC
31#if defined(DO_RELOC_LIBLD)
32#undef DO_RELOC_LIBLD
33#define	DO_RELOC_LIBLD_SPARC
34#endif
35#include	<stdio.h>
36#include	"sgs.h"
37#include	"machdep.h"
38#include	"libld.h"
39#include	"reloc.h"
40#include	"conv.h"
41#include	"msg.h"
42#endif
43
44/*
45 * We need to build this code differently when it is used for
46 * cross linking:
47 *	- Data alignment requirements can differ from those
48 *		of the running system, so we can't access data
49 *		in units larger than a byte
50 *	- We have to include code to do byte swapping when the
51 *		target and linker host use different byte ordering,
52 *		but such code is a waste when running natively.
53 */
54#if !defined(DO_RELOC_LIBLD) || defined(__sparc)
55#define	DORELOC_NATIVE
56#endif
57
58/*
59 * This table represents the current relocations that do_reloc() is able to
60 * process.  The relocations below that are marked SPECIAL are relocations that
61 * take special processing and shouldn't actually ever be passed to do_reloc().
62 */
63const Rel_entry reloc_table[R_SPARC_NUM] = {
64/* R_SPARC_NONE */	{0x0, FLG_RE_NOTREL, 0, 0, 0},
65/* R_SPARC_8 */		{0x0, FLG_RE_VERIFY, 1, 0, 0},
66/* R_SPARC_16 */	{0x0, FLG_RE_VERIFY, 2, 0, 0},
67/* R_SPARC_32 */	{0x0, FLG_RE_VERIFY, 4, 0, 0},
68/* R_SPARC_DISP8 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
69				1, 0, 0},
70/* R_SPARC_DISP16 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
71				2, 0, 0},
72/* R_SPARC_DISP32 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
73				4, 0, 0},
74/* R_SPARC_WDISP30 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
75				4, 2, 30},
76/* R_SPARC_WDISP22 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
77				4, 2, 22},
78#if	defined(_ELF64)
79/* R_SPARC_HI22 */	{0x0, FLG_RE_VERIFY, 4, 10, 22},
80#else
81/* R_SPARC_HI22 */	{0x0, FLG_RE_NOTREL, 4, 10, 22},
82#endif
83/* R_SPARC_22 */	{0x0, FLG_RE_VERIFY, 4, 0, 22},
84/* R_SPARC_13 */	{0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 13},
85/* R_SPARC_LO10 */	{0x3ff, FLG_RE_SIGN, 4, 0, 13},
86/* R_SPARC_GOT10 */	{0x3ff, FLG_RE_GOTADD | FLG_RE_SIGN, 4, 0, 13},
87/* R_SPARC_GOT13 */	{0x0, FLG_RE_GOTADD | FLG_RE_VERIFY | FLG_RE_SIGN,
88				4, 0, 13},
89/* R_SPARC_GOT22 */	{0x0, FLG_RE_GOTADD, 4, 10, 22},
90/* R_SPARC_PC10 */	{0x3ff, FLG_RE_PCREL | FLG_RE_SIGN | FLG_RE_LOCLBND,
91				4, 0, 13},
92/* R_SPARC_PC22 */	{0x0, FLG_RE_PCREL | FLG_RE_SIGN | FLG_RE_VERIFY |
93				FLG_RE_LOCLBND, 4, 10, 22},
94/* R_SPARC_WPLT30 */	{0x0, FLG_RE_PCREL | FLG_RE_PLTREL |
95				FLG_RE_VERIFY | FLG_RE_SIGN,
96				4, 2, 30},
97/* R_SPARC_COPY */	{0x0, 0, 0, 0, 0},		/* SPECIAL */
98#if	defined(_ELF64)
99/* R_SPARC_GLOB_DAT */	{0x0, FLG_RE_NOTREL, 8, 0, 0},
100#else
101/* R_SPARC_GLOB_DAT */	{0x0, FLG_RE_NOTREL, 4, 0, 0},
102#endif
103/* R_SPARC_JMP_SLOT */	{0x0, 0, 0, 0, 0},		/* SPECIAL */
104#if	defined(_ELF64)
105/* R_SPARC_RELATIVE */	{0x0, FLG_RE_NOTREL, 8, 0, 0},
106#else
107/* R_SPARC_RELATIVE */	{0x0, FLG_RE_NOTREL, 4, 0, 0},
108#endif
109/* R_SPARC_UA32 */	{0x0, FLG_RE_UNALIGN, 4, 0, 0},
110/* R_SPARC_PLT32 */	{0x0, FLG_RE_PLTREL | FLG_RE_VERIFY |
111				FLG_RE_ADDRELATIVE, 4, 0, 0},
112/* R_SPARC_HIPLT22 */	{0x0, FLG_RE_PLTREL, 4, 10, 22},
113/* R_SPARC_LOPLT10 */	{0x3ff, FLG_RE_PLTREL, 4, 0, 13},
114/* R_SPARC_PCPLT32 */	{0x0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY,
115				4, 0, 0},
116/* R_SPARC_PCPLT22 */	{0x0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY,
117				4, 10, 22},
118/* R_SPARC_PCPLT10 */	{0x3ff, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY,
119				4, 0, 13},
120/* R_SPARC_10 */	{0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 10},
121/* R_SPARC_11 */	{0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 11},
122/* R_SPARC_64 */	{0x0, FLG_RE_VERIFY, 8, 0, 0},		/* V9 */
123/* R_SPARC_OLO10 */	{0x3ff, FLG_RE_EXTOFFSET | FLG_RE_SIGN,
124				4, 0, 13},			/* V9 */
125/* R_SPARC_HH22 */	{0x0, FLG_RE_VERIFY, 4, 42, 22},	/* V9 */
126/* R_SPARC_HM10 */	{0x3ff, FLG_RE_SIGN, 4, 32, 13},	/* V9 */
127/* R_SPARC_LM22 */	{0x0, FLG_RE_NOTREL, 4, 10, 22},	/* V9 */
128/* R_SPARC_PC_HH22 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY,
129				4, 42, 22},			/* V9 */
130/* R_SPARC_PC_HM10 */	{0x3ff, FLG_RE_PCREL | FLG_RE_SIGN,
131				4, 32, 13},			/* V9 */
132/* R_SPARC_PC_LM22 */	{0x0, FLG_RE_PCREL,
133				4, 10, 22},			/* V9 */
134/* R_SPARC_WDISP16 */	{0x0, FLG_RE_PCREL | FLG_RE_WDISP16 |
135				FLG_RE_VERIFY | FLG_RE_SIGN,
136				4, 2, 16},
137/* R_SPARC_WDISP19 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
138				4, 2, 19},
139/* R_SPARC_GLOB_JMP */	{0x0, 0, 0, 0, 0},	/* V9 - not implemented */
140						/* removed from v9 ABI */
141/* R_SPARC_7 */		{0x0, FLG_RE_NOTREL, 4, 0, 7},
142/* R_SPARC_5 */		{0x0, FLG_RE_NOTREL, 4, 0, 5},
143/* R_SPARC_6 */		{0x0, FLG_RE_NOTREL, 4, 0, 6},
144/* R_SPARC_DISP64 */	{0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN,
145				8, 0, 0},
146/* R_SPARC_PLT64 */	{0x0, FLG_RE_PLTREL | FLG_RE_VERIFY |
147				FLG_RE_ADDRELATIVE, 8, 0, 0},
148/* R_SPARC_HIX22 */	{(Xword)(-1LL), FLG_RE_VERIFY,
149				4, 10, 22},			/* V9 - HaL */
150/* R_SPARC_LOX10 */	{0x3ff, FLG_RE_SIGN, 4, 0, 13},		/* V9 - HaL */
151/* R_SPARC_H44 */	{0x0, FLG_RE_VERIFY, 4, 22, 22},	/* V9 */
152/* R_SPARC_M44 */	{0x3ff, FLG_RE_NOTREL, 4, 12, 10},	/* V9 */
153/* R_SPARC_L44 */	{0xfff, FLG_RE_NOTREL, 4, 0, 13},	/* V9 */
154/* R_SPARC_REGISTER */	{0x0, FLG_RE_REGISTER, 0, 0, 0},	/* SPECIAL */
155/* R_SPARC_UA64 */	{0x0, FLG_RE_VERIFY | FLG_RE_UNALIGN,
156				8, 0, 0},			/* V9 */
157/* R_SPARC_UA16 */	{0x0, FLG_RE_VERIFY | FLG_RE_UNALIGN,
158				2, 0, 0},
159/* R_SPARC_TLS_GD_HI22 */   {0x0, FLG_RE_GOTADD | FLG_RE_TLSGD, 4, 10, 22},
160/* R_SPARC_TLS_GD_LO10 */   {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSGD |
161				FLG_RE_SIGN, 4, 0, 13},
162/* R_SPARC_TLS_GD_ADD */    {0x0, FLG_RE_TLSGD, 0, 0, 0},
163/* R_SPARC_TLS_GD_CALL */   {0x0, FLG_RE_TLSGD, 0, 0, 0},
164/* R_SPARC_TLS_LDM_HI22 */  {0x0, FLG_RE_GOTADD | FLG_RE_TLSLD, 4, 10, 22},
165/* R_SPARC_TLS_LDM_LO10 */  {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSLD |
166				FLG_RE_SIGN, 4, 0, 13},
167/* R_SPARC_TLS_LDM_ADD */   {0x0, FLG_RE_TLSLD, 0, 0, 0},
168/* R_SPARC_TLS_LDM_CALL */  {0x0, FLG_RE_TLSLD, 0, 0, 0},
169/* R_SPARC_TLS_LDO_HIX22 */ {0x0, FLG_RE_VERIFY | FLG_RE_TLSLD, 4, 10, 22},
170/* R_SPARC_TLS_LDO_LOX10 */ {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLD, 4, 0, 13},
171/* R_SPARC_TLS_LDO_ADD */   {0x0, FLG_RE_TLSLD, 0, 0, 0},
172/* R_SPARC_TLS_IE_HI22 */   {0x0, FLG_RE_GOTADD | FLG_RE_TLSIE, 4, 10, 22},
173/* R_SPARC_TLS_IE_LO10 */   {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSIE |
174				FLG_RE_SIGN, 4, 0, 13},
175/* R_SPARC_TLS_IE_LD */	    {0x0, FLG_RE_TLSIE, 0, 0, 0},
176/* R_SPARC_TLS_IE_LDX */    {0x0, FLG_RE_TLSIE, 0, 0, 0},
177/* R_SPARC_TLS_IE_ADD */    {0x0, FLG_RE_TLSIE, 0, 0, 0},
178/* R_SPARC_TLS_LE_HIX22 */  {(Xword)(-1LL),
179				FLG_RE_VERIFY | FLG_RE_TLSLE, 4, 10, 22},
180/* R_SPARC_TLS_LE_LOX10 */  {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLE, 4, 0, 13},
181/* R_SPARC_TLS_DTPMOD32 */  {0x0, FLG_RE_NOTREL, 4, 0, 0},
182/* R_SPARC_TLS_DTPMOD64 */  {0x0, FLG_RE_NOTREL, 8, 0, 0},
183/* R_SPARC_TLS_DTPOFF32 */  {0x0, FLG_RE_NOTREL, 4, 0, 0},
184/* R_SPARC_TLS_DTPOFF64 */  {0x0, FLG_RE_NOTREL, 8, 0, 0},
185/* R_SPARC_TLS_TPOFF32 */   {0x0, FLG_RE_NOTREL, 4, 0, 0},
186/* R_SPARC_TLS_TPOFF64 */   {0x0, FLG_RE_NOTREL, 8, 0, 0},
187/* R_SPARC_GOTDATA_HIX22 */	{0, FLG_RE_SIGN | FLG_RE_GOTREL |
188					FLG_RE_VERIFY, 4, 10, 22},
189/* R_SPARC_GOTDATA_LOX10 */	{ 0x3ff, FLG_RE_GOTREL | FLG_RE_SIGN, 4, 0, 13},
190/* R_SPARC_GOTDATA_OP_HIX22 */	{ 0x0, FLG_RE_GOTOPINS | FLG_RE_GOTADD,
191					4, 10, 22},
192/* R_SPARC_GOTDATA_OP_LOX10 */	{ 0x3ff, FLG_RE_SIGN | FLG_RE_GOTOPINS |
193					FLG_RE_GOTADD, 4, 0, 13},
194/* R_SPARC_GOTDATA_OP */	{ 0x0, FLG_RE_GOTOPINS, 0, 0, 0},
195/* R_SPARC_H34 */	{0x0, FLG_RE_VERIFY, 4, 12, 22},	/* V9 */
196/* R_SPARC_SIZE32 */	{0x0, FLG_RE_SIZE | FLG_RE_VERIFY, 4, 0, 0},
197/* R_SPARC_SIZE64 */	{0x0, FLG_RE_SIZE | FLG_RE_VERIFY, 8, 0, 0},
198};
199
200
201/*
202 * Write a single relocated value to its reference location.
203 * We assume we wish to add the relocation amount, value, to the
204 * value of the address already present in the instruction.
205 *
206 * NAME			 VALUE	FIELD		CALCULATION
207 *
208 * R_SPARC_NONE		     0	none		none
209 * R_SPARC_8		     1	V-byte8		S + A
210 * R_SPARC_16		     2	V-half16	S + A
211 * R_SPARC_32		     3	V-word32	S + A
212 * R_SPARC_DISP8	     4	V-byte8		S + A - P
213 * R_SPARC_DISP16	     5	V-half16	S + A - P
214 * R_SPARC_DISP32	     6	V-word32	S + A - P
215 * R_SPARC_WDISP30	     7	V-disp30	(S + A - P) >> 2
216 * R_SPARC_WDISP22	     8	V-disp22	(S + A - P) >> 2
217 * R_SPARC_HI22		     9	T-imm22		(S + A) >> 10
218 * R_SPARC_22		    10	V-imm22		S + A
219 * R_SPARC_13		    11	V-simm13	S + A
220 * R_SPARC_LO10		    12	T-simm13	(S + A) & 0x3ff
221 * R_SPARC_GOT10	    13	T-simm13	G & 0x3ff
222 * R_SPARC_GOT13	    14	V-simm13	G
223 * R_SPARC_GOT22	    15	T-imm22		G >> 10
224 * R_SPARC_PC10		    16	T-simm13	(S + A - P) & 0x3ff
225 * R_SPARC_PC22		    17	V-disp22	(S + A - P) >> 10
226 * R_SPARC_WPLT30	    18	V-disp30	(L + A - P) >> 2
227 * R_SPARC_COPY		    19	none		none
228 * R_SPARC_GLOB_DAT	    20	V-word32	S + A
229 * R_SPARC_JMP_SLOT	    21	V-plt22		S + A
230 * R_SPARC_RELATIVE	    22	V-word32	S + A
231 * R_SPARC_UA32		    23	V-word32	S + A
232 * R_SPARC_PLT32	    24	V-word32        L + A
233 * R_SPARC_HIPLT22	    25	T-imm22         (L + A) >> 10
234 * R_SPARC_LOPLT10	    26	T-simm13        (L + A) & 0x3ff
235 * R_SPARC_PCPLT32	    27	V-word32        L + A - P
236 * R_SPARC_PCPLT22	    28	V-disp22        (L + A - P) >> 10
237 * R_SPARC_PCPLT10	    29	V-simm13        (L + A - P) & 0x3ff
238 * R_SPARC_10		    30	V-simm10	S + A
239 * R_SPARC_11		    31	V-simm11	S + A
240 * R_SPARC_64		    32	V-xword64	S + A
241 * R_SPARC_OLO10	    33	V-simm13	((S + A) & 0x3ff) + O
242 * R_SPARC_HH22		    34	V-imm22		(S + A) >> 42
243 * R_SPARC_HM10		    35	T-simm13	((S + A) >> 32) & 0x3ff
244 * R_SPARC_LM22		    36	T-imm22		(S + A) >> 10
245 * R_SPARC_PC_HH22	    37	V-imm22		(S + A - P) >> 42
246 * R_SPARC_PC_HM10	    38	T-simm13	((S + A - P) >> 32) & 0x3ff
247 * R_SPARC_PC_LM22	    39	T-imm22		(S + A - P) >> 10
248 * R_SPARC_WDISP16	    40	V-d2/disp14	(S + A - P) >> 2
249 * R_SPARC_WDISP19	    41	V-disp19	(S + A - P) >> 2
250 * R_SPARC_GLOB_JMP	    42	V-xword64	S + A
251 * R_SPARC_7		    43	V-imm7		S + A
252 * R_SPARC_5		    44	V-imm5		S + A
253 * R_SPARC_6		    45	V-imm6		S + A
254 * R_SPARC_DISP64	    46	V-xword64	S + A - P
255 * R_SPARC_PLT64	    47	V-xword64	L + A
256 * R_SPARC_HIX22	    48	V-imm22		((S + A) ^
257 *						    0xffffffffffffffff) >> 10
258 * R_SPARC_LOX10	    49	T-simm13	((S + A) & 0x3ff) | 0x1c00
259 * R_SPARC_H44		    50	V-imm22		(S + A) >> 22
260 * R_SPARC_M44		    51	T-imm10		((S + A) >> 12) & 0x3ff
261 * R_SPARC_L44		    52	T-imm13		(S + A) & 0xfff
262 * R_SPARC_REGISTER	    53	V-xword64	S + A
263 * R_SPARC_UA64		    54	V-xword64	S + A
264 * R_SPARC_UA16		    55	V-half16	S + A
265 * R_SPARC_TLS_GD_HI22	    56	T-simm22	@dtlndx(S + A) >> 10
266 * R_SPARC_TLS_GD_LO10	    57	T-simm13	@dtlndx(S + A) & 0x3ff
267 * R_SPARC_TLS_GD_ADD	    58	none		SPECIAL
268 * R_SPARC_TLS_GD_CALL	    59	V-disp30	SPECIAL
269 * R_SPARC_TLS_LDM_HI22	    60	T-simm22	@tmndx(S + A) >> 10
270 * R_SPARC_TLS_LDM_LO10	    61	T-simm13	@tmndx(S + A) & 0x3ff
271 * R_SPARC_TLS_LDM_ADD	    62	none		SPECIAL
272 * R_SPARC_TLS_LDM_CALL	    63	V-disp30	SPECIAL
273 * R_SPARC_TLS_LDO_HIX22    64	V-simm22	@dtpoff(S + A) >> 10
274 * R_SPARC_TLS_LDO_LOX10    65	T-simm13	@dtpoff(S + A) & 0x3ff
275 * R_SPARC_TLS_LDO_ADD	    66	none		SPECIAL
276 * R_SPARC_TLS_IE_HI22	    67	T-simm22	@got(@tpoff(S + A)) >> 10
277 * R_SPARC_TLS_IE_LO10	    68	T-simm13	@got(@tpoff(S + A)) & 0x3ff
278 * R_SPARC_TLS_IE_LD	    69	none		SPECIAL
279 * R_SPARC_TLS_IE_LDX	    70	none		SPECIAL
280 * R_SPARC_TLS_IE_ADD	    71	none		SPECIAL
281 * R_SPARC_TLS_LE_HIX22	    72	V-simm22	(@tpoff(S + A) ^
282 *						    0xffffffff) >> 10
283 * R_SPARC_TLS_LE_LOX10	    73	T-simm13	(@tpoff(S + A) & 0x3ff) | 0x1c00
284 * R_SPARC_TLS_DTPMOD32	    74	V-word32	@dtmod(S + A)
285 * R_SPARC_TLS_DTPMOD64	    75	V-word64	@dtmod(S + A)
286 * R_SPARC_TLS_DTPOFF32	    76	V-word32	@dtpoff(S + A)
287 * R_SPARC_TLS_DTPOFF64	    77	V-word64	@dtpoff(S + A)
288 * R_SPARC_TLS_TPOFF32	    78	V-word32	@tpoff(S + A)
289 * R_SPARC_TLS_TPOFF64	    79	V-word64	@tpoff(S + A)
290 * R_SPARC_GOTDATA_HIX22    80	V-imm22		((S + A - GOT) >> 10) ^
291 *						  ((S + A - GOT) >> 31)
292 * R_SPARC_GOTDATA_LOX10    81	T-simm13	((S + A - GOT) & 0x3ff) |
293 *						  (((S + A - GOT) >> 31) &
294 *						  0x1c00)
295 * R_SPARC_GOTDATA_OP_HIX22 82	T-imm22		(G >> 10) & (G >> 31)
296 * R_SPARC_GOTDATA_OP_LOX10 83	T-simm13	(G & 0x3ff) |
297 *						  ((G >> 31) & 0x1c00)
298 * R_SPARC_GOTDATA_OP	    84  Word32		SPECIAL
299 * R_SPARC_H34		    85	V-imm22		(S + A) >> 12
300 * R_SPARC_SIZE32	    86	V-word32	Z + A
301 * R_SPARC_SIZE64	    87	V-xword64	Z + A
302 *
303 *	This is Figure 4-20: Relocation Types from the Draft Copy of
304 * the ABI, Printed on 11/29/88.
305 *
306 * NOTE1: relocations 24->45 are newly registered relocations to support
307 *	 C++ ABI & SPARC V8+ and SPARC V9 architectures (1/9/94), and
308 *	 64-bit relocations 46-55 were added for SPARC V9.
309 *
310 * NOTE2: relocations 56->79 are added to support Thread-Local storage
311 *	  as recorded in PSARC/2001/509
312 *
313 * NOTE3: The value to be passed for relocations R_SPARC_HIX22 and
314 *	  R_SPARC_TLS_HIX22 are negative values. So the upper 10 or 40 bits
315 *	  are 1. (So when the exclusive OR is applied, the upper bits
316 *	  will be 0.)
317 *
318 * Relocation calculations:
319 *
320 * The FIELD names indicate whether the relocation type checks for overflow.
321 * A calculated relocation value may be larger than the intended field, and
322 * the relocation type may verify (V) that the value fits, or truncate (T)
323 * the result.
324 *
325 * CALCULATION uses the following notation:
326 *      A       the addend used
327 *      B       the base address of the shared object in memory
328 *      G       the offset into the global offset table
329 *      L       the procedure linkage entry
330 *      P       the place of the storage unit being relocated
331 *      S       the value of the symbol
332 *	O	secondary addend (extra offset) in v9 r_info field
333 *	Z	the size of the symbol whose index resides in the relocation
334 *		entry
335 *
336 *	@dtlndx(x): Allocate two contiguous entries in the GOT table to hold
337 *	   a Tls_index structure (for passing to __tls_get_addr()). The
338 *	   instructions referencing this entry will be bound to the first
339 *	   of the two GOT entries.
340 *
341 *	@tmndx(x): Allocate two contiguous entries in the GOT table to hold
342 *	   a Tls_index structure (for passing to __tls_get_addr()). The
343 *	   ti_offset field of the Tls_index will be set to 0 (zero) and the
344 *	   ti_module will be filled in at run-time. The call to
345 *	   __tls_get_addr() will return the starting offset of the dynamic
346 *	   TLS block.
347 *
348 *	@dtpoff(x): calculate the tlsoffset relative to the TLS block.
349 *
350 *	@tpoff(x): calculate the negative tlsoffset relative to the static
351 *	   TLS block. This value can be added to the thread-pointer to
352 *	   calculate the tls address.
353 *
354 *	@dtpmod(x): calculate the module id of the object containing symbol x.
355 *
356 * The calculations in the CALCULATION column are assumed to have been performed
357 * before calling this function except for the addition of the addresses in the
358 * instructions.
359 *
360 * Upon successful completion of do_reloc() *value will be set to the
361 * 'bit-shifted' value that will be or'ed into memory.
362 */
363#if defined(_KERNEL)
364#define	lml	0		/* Needed by arglist of REL_ERR_* macros */
365int
366do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym,
367    const char *file)
368#elif defined(DO_RELOC_LIBLD)
369/*ARGSUSED5*/
370int
371do_reloc_ld(Rel_desc *rdesc, uchar_t *off, Xword *value,
372    rel_desc_sname_func_t rel_desc_sname_func,
373    const char *file, int bswap, void *lml)
374#else
375int
376do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym,
377    const char *file, void *lml)
378#endif
379{
380#ifdef DO_RELOC_LIBLD
381#define	sym (* rel_desc_sname_func)(rdesc)
382	uchar_t	rtype = rdesc->rel_rtype;
383#endif
384	Xword	uvalue = 0;
385	Xword	basevalue, sigbit_mask, sigfit_mask;
386	Xword	corevalue = *value;
387	uchar_t	bshift;
388	int	field_size, re_flags;
389	const	Rel_entry	*rep;
390
391	rep = &reloc_table[rtype];
392	bshift = rep->re_bshift;
393	field_size = rep->re_fsize;
394	re_flags = rep->re_flags;
395	sigbit_mask = S_MASK(rep->re_sigbits);
396
397	if ((re_flags & FLG_RE_SIGN) && sigbit_mask) {
398		/*
399		 * sigfit_mask takes into account that a value
400		 * might be signed and discards the signbit for
401		 * comparison.
402		 */
403		sigfit_mask = S_MASK(rep->re_sigbits - 1);
404	} else
405		sigfit_mask = sigbit_mask;
406
407	if (field_size == 0) {
408		REL_ERR_UNIMPL(lml, file, sym, rtype);
409		return (0);
410	}
411
412	/*
413	 * We have two ways to retrieve the base value, a general one
414	 * that will work with data of any alignment, and another that is
415	 * fast, but which requires the data to be aligned according to
416	 * sparc alignment rules.
417	 *
418	 * For non-native linking, we always use the general path. For
419	 * native linking, the FLG_RE_UNALIGN determines it.
420	 */
421#if defined(DORELOC_NATIVE)
422	if (re_flags & FLG_RE_UNALIGN)
423#endif
424	{
425		int	i;
426		uchar_t	*dest = (uchar_t *)&basevalue;
427
428		basevalue = 0;
429#if !defined(DORELOC_NATIVE)
430		if (bswap) {
431			int j = field_size - 1;
432
433			for (i = 0; i < field_size; i++, j--)
434				dest[i] = off[j];
435
436		} else
437#endif
438		{
439			/*
440			 * Adjust the offset
441			 */
442			/* LINTED */
443			i = (int)(sizeof (Xword) - field_size);
444			if (i > 0)
445				dest += i;
446			for (i = field_size - 1; i >= 0; i--)
447				dest[i] = off[i];
448		}
449	}
450
451	/*
452	 * Non-native linker: We have already fetched the value above,
453	 *	but if the relocation does not have the FLG_RE_UNALIGN
454	 *	flag set, we still need to do the same error checking we
455	 *	would do on a native linker.
456	 * Native-linker: If this is an aligned relocation, we need to
457	 *	fetch the value and also do the error checking.
458	 *
459	 * The FETCH macro is used to conditionalize the fetching so that
460	 * it only happens in the native case.
461	 */
462#if defined(DORELOC_NATIVE)
463#define	FETCH(_type) basevalue = (Xword)*((_type *)off);
464#else
465#define	FETCH(_type)
466#endif
467	if ((re_flags & FLG_RE_UNALIGN) == 0) {
468		if (((field_size == 2) && ((uintptr_t)off & 0x1)) ||
469		    ((field_size == 4) && ((uintptr_t)off & 0x3)) ||
470		    ((field_size == 8) && ((uintptr_t)off & 0x7))) {
471			REL_ERR_NONALIGN(lml, file, sym, rtype, (uintptr_t)off);
472			return (0);
473		}
474		switch (field_size) {
475		case 1:
476			/* LINTED */
477			FETCH(uchar_t);
478			break;
479		case 2:
480			/* LINTED */
481			FETCH(Half);
482			break;
483		case 4:
484			/* LINTED */
485			FETCH(Word);
486			break;
487		case 8:
488			/* LINTED */
489			FETCH(Xword);
490			break;
491		default:
492			REL_ERR_UNNOBITS(lml, file, sym, rtype,
493			    (rep->re_fsize * 8));
494			return (0);
495		}
496	}
497#undef FETCH
498
499	if (sigbit_mask) {
500		/*
501		 * The WDISP16 relocation is an unusual one in that it's bits
502		 * are not all contiguous.  We have to selectivly pull them out.
503		 */
504		if (re_flags & FLG_RE_WDISP16) {
505			uvalue = ((basevalue & 0x300000) >> 6) |
506			    (basevalue & 0x3fff);
507			basevalue &= ~0x303fff;
508		} else {
509			uvalue = sigbit_mask & basevalue;
510			basevalue &= ~sigbit_mask;
511		}
512		/*
513		 * If value is signed make sure that we signextend the uvalue.
514		 */
515		if (re_flags & FLG_RE_SIGN) {
516			if (uvalue & (~sigbit_mask & sigfit_mask))
517				uvalue |= ~sigbit_mask;
518		}
519	} else
520		uvalue = basevalue;
521
522	if (bshift)
523		uvalue <<= bshift;
524
525	uvalue += *value;
526
527	if (rep->re_mask &&
528	    ((rtype == R_SPARC_HIX22) || (rtype == R_SPARC_TLS_LE_HIX22)))
529		uvalue ^= rep->re_mask;
530
531	if (bshift) {
532		/*
533		 * This is to check that we are not attempting to
534		 * jump to a non-4 byte aligned address.
535		 */
536		if ((bshift == 2) && (uvalue & 0x3)) {
537			REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, 2, off);
538			return (0);
539		}
540
541		if (re_flags & FLG_RE_SIGN) {
542			uvalue = (Sxword)uvalue >> bshift;
543		} else {
544			uvalue >>= bshift;
545		}
546		corevalue >>= bshift;
547	}
548
549	if ((rtype == R_SPARC_GOTDATA_HIX22) ||
550	    (rtype == R_SPARC_GOTDATA_OP_HIX22)) {
551		uvalue ^= ((Sxword)(*value) >> 31);
552		corevalue ^= ((Sxword)(*value) >> 31);
553	}
554
555	if (rep->re_mask &&
556	    (rtype != R_SPARC_HIX22) && (rtype != R_SPARC_TLS_LE_HIX22) &&
557	    (rtype != R_SPARC_GOTDATA_HIX22))
558		uvalue &= rep->re_mask;
559
560	if ((rtype == R_SPARC_LOX10) || (rtype == R_SPARC_TLS_LE_LOX10)) {
561		uvalue |= 0x1c00;
562		corevalue |= 0x1c00;
563	}
564
565	if ((rtype == R_SPARC_GOTDATA_LOX10) ||
566	    (rtype == R_SPARC_GOTDATA_OP_LOX10)) {
567		uvalue |= ((Sxword)(*value) >> 31) & 0x1c00;
568		corevalue |= ((Sxword)(*value) >> 31) & 0x1c00;
569	}
570
571
572	if ((re_flags & FLG_RE_VERIFY) && sigbit_mask) {
573		if (((re_flags & FLG_RE_SIGN) &&
574		    (S_INRANGE((Sxword)uvalue, rep->re_sigbits - 1) == 0)) ||
575		    (!(re_flags & FLG_RE_SIGN) &&
576		    ((sigbit_mask & uvalue) != uvalue))) {
577			REL_ERR_NOFIT(lml, file, sym, rtype, uvalue);
578			return (0);
579		}
580	}
581
582	if (sigbit_mask) {
583		/*
584		 * Again the R_SPARC_WDISP16 relocation takes special
585		 * processing because of its non-continguous bits.
586		 */
587		if (re_flags & FLG_RE_WDISP16)
588			uvalue = ((uvalue & 0xc000) << 6) |
589			    (uvalue & 0x3fff);
590		else
591			uvalue &= sigbit_mask;
592		/*
593		 * Combine value back with original word
594		 */
595		uvalue |= basevalue;
596	}
597	*value = corevalue;
598
599	/*
600	 * Now, we store uvalue back at the location given by off.
601	 * This is similar to the fetch case above:
602	 *	- We have general (unaligned) and fast (aligned) cases
603	 *	- Cross linkers need to use the unaligned case even
604	 *		when the relocation does not specify FLG_RE_UNALIGN.
605	 *	- A cross linker that processes a relocation that does not
606	 *		have FLG_RE_UNALIGN set has to do the same error
607	 *		checking that a native linker would do, while avoiding
608	 *		the aligned store (accomplished with the STORE macro).
609	 */
610#if defined(DORELOC_NATIVE)
611	if (re_flags & FLG_RE_UNALIGN)
612#endif
613	{
614		int	i;
615		uchar_t	*src = (uchar_t *)&uvalue;
616
617#if !defined(DORELOC_NATIVE)
618		if (bswap) {
619			int j = field_size - 1;
620
621			for (i = 0; i < field_size; i++, j--)
622				off[i] = src[j];
623
624		} else
625#endif
626		{
627			/*
628			 * Adjust the offset.
629			 */
630			/* LINTED */
631			i = (int)(sizeof (Xword) - field_size);
632			if (i > 0)
633				src += i;
634			for (i = field_size - 1; i >= 0; i--)
635				off[i] = src[i];
636		}
637	}
638
639#if defined(DORELOC_NATIVE)
640#define	STORE(_type) *((_type *)off) = (_type)uvalue
641#else
642#define	STORE(_type)
643#endif
644	if ((re_flags & FLG_RE_UNALIGN) == 0) {
645		switch (rep->re_fsize) {
646		case 1:
647			/* LINTED */
648			STORE(uchar_t);
649			break;
650		case 2:
651			/* LINTED */
652			STORE(Half);
653			break;
654		case 4:
655			/* LINTED */
656			STORE(Word);
657			break;
658		case 8:
659			/* LINTED */
660			STORE(Xword);
661			break;
662		default:
663			/*
664			 * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ)
665			 */
666			REL_ERR_UNSUPSZ(lml, file, sym, rtype, rep->re_fsize);
667			return (0);
668		}
669	}
670#undef STORE
671
672	return (1);
673
674#ifdef DO_RELOC_LIBLD
675#undef sym
676#endif
677}
678