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 */ 63 const 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 */ 365 int 366 do_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*/ 370 int 371 do_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 375 int 376 do_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