17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 2175521904Sraf 227c478bd9Sstevel@tonic-gate /* 23*bf994817SAli Bahrami * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 2575521904Sraf 267c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 28986fd29aSsetje #include "krtld/reloc.h" 297c478bd9Sstevel@tonic-gate #else 30ba2be530Sab196087 #define ELF_TARGET_SPARC 31ba2be530Sab196087 #if defined(DO_RELOC_LIBLD) 32ba2be530Sab196087 #undef DO_RELOC_LIBLD 33ba2be530Sab196087 #define DO_RELOC_LIBLD_SPARC 34ba2be530Sab196087 #endif 357c478bd9Sstevel@tonic-gate #include <stdio.h> 367c478bd9Sstevel@tonic-gate #include "sgs.h" 377c478bd9Sstevel@tonic-gate #include "machdep.h" 387c478bd9Sstevel@tonic-gate #include "libld.h" 397c478bd9Sstevel@tonic-gate #include "reloc.h" 407c478bd9Sstevel@tonic-gate #include "conv.h" 417c478bd9Sstevel@tonic-gate #include "msg.h" 427c478bd9Sstevel@tonic-gate #endif 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 45ba2be530Sab196087 * We need to build this code differently when it is used for 46ba2be530Sab196087 * cross linking: 47ba2be530Sab196087 * - Data alignment requirements can differ from those 48ba2be530Sab196087 * of the running system, so we can't access data 49ba2be530Sab196087 * in units larger than a byte 50ba2be530Sab196087 * - We have to include code to do byte swapping when the 51ba2be530Sab196087 * target and linker host use different byte ordering, 52ba2be530Sab196087 * but such code is a waste when running natively. 53ba2be530Sab196087 */ 54ba2be530Sab196087 #if !defined(DO_RELOC_LIBLD) || defined(__sparc) 55ba2be530Sab196087 #define DORELOC_NATIVE 56ba2be530Sab196087 #endif 57ba2be530Sab196087 58ba2be530Sab196087 /* 597c478bd9Sstevel@tonic-gate * This table represents the current relocations that do_reloc() is able to 607c478bd9Sstevel@tonic-gate * process. The relocations below that are marked SPECIAL are relocations that 617c478bd9Sstevel@tonic-gate * take special processing and shouldn't actually ever be passed to do_reloc(). 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate const Rel_entry reloc_table[R_SPARC_NUM] = { 64552ff457Srie /* R_SPARC_NONE */ {0x0, FLG_RE_NOTREL, 0, 0, 0}, 65552ff457Srie /* R_SPARC_8 */ {0x0, FLG_RE_VERIFY, 1, 0, 0}, 66552ff457Srie /* R_SPARC_16 */ {0x0, FLG_RE_VERIFY, 2, 0, 0}, 67552ff457Srie /* R_SPARC_32 */ {0x0, FLG_RE_VERIFY, 4, 0, 0}, 687c478bd9Sstevel@tonic-gate /* R_SPARC_DISP8 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 697c478bd9Sstevel@tonic-gate 1, 0, 0}, 707c478bd9Sstevel@tonic-gate /* R_SPARC_DISP16 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 717c478bd9Sstevel@tonic-gate 2, 0, 0}, 727c478bd9Sstevel@tonic-gate /* R_SPARC_DISP32 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 737c478bd9Sstevel@tonic-gate 4, 0, 0}, 747c478bd9Sstevel@tonic-gate /* R_SPARC_WDISP30 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 757c478bd9Sstevel@tonic-gate 4, 2, 30}, 767c478bd9Sstevel@tonic-gate /* R_SPARC_WDISP22 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 777c478bd9Sstevel@tonic-gate 4, 2, 22}, 787c478bd9Sstevel@tonic-gate #if defined(_ELF64) 79552ff457Srie /* R_SPARC_HI22 */ {0x0, FLG_RE_VERIFY, 4, 10, 22}, 807c478bd9Sstevel@tonic-gate #else 817c478bd9Sstevel@tonic-gate /* R_SPARC_HI22 */ {0x0, FLG_RE_NOTREL, 4, 10, 22}, 827c478bd9Sstevel@tonic-gate #endif 83552ff457Srie /* R_SPARC_22 */ {0x0, FLG_RE_VERIFY, 4, 0, 22}, 84552ff457Srie /* R_SPARC_13 */ {0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 13}, 85552ff457Srie /* R_SPARC_LO10 */ {0x3ff, FLG_RE_SIGN, 4, 0, 13}, 867c478bd9Sstevel@tonic-gate /* R_SPARC_GOT10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_SIGN, 4, 0, 13}, 877c478bd9Sstevel@tonic-gate /* R_SPARC_GOT13 */ {0x0, FLG_RE_GOTADD | FLG_RE_VERIFY | FLG_RE_SIGN, 887c478bd9Sstevel@tonic-gate 4, 0, 13}, 897c478bd9Sstevel@tonic-gate /* R_SPARC_GOT22 */ {0x0, FLG_RE_GOTADD, 4, 10, 22}, 90141040e8Srie /* R_SPARC_PC10 */ {0x3ff, FLG_RE_PCREL | FLG_RE_SIGN | FLG_RE_LOCLBND, 91141040e8Srie 4, 0, 13}, 92141040e8Srie /* R_SPARC_PC22 */ {0x0, FLG_RE_PCREL | FLG_RE_SIGN | FLG_RE_VERIFY | 93141040e8Srie FLG_RE_LOCLBND, 4, 10, 22}, 947c478bd9Sstevel@tonic-gate /* R_SPARC_WPLT30 */ {0x0, FLG_RE_PCREL | FLG_RE_PLTREL | 957c478bd9Sstevel@tonic-gate FLG_RE_VERIFY | FLG_RE_SIGN, 967c478bd9Sstevel@tonic-gate 4, 2, 30}, 977c478bd9Sstevel@tonic-gate /* R_SPARC_COPY */ {0x0, 0, 0, 0, 0}, /* SPECIAL */ 987c478bd9Sstevel@tonic-gate #if defined(_ELF64) 997c478bd9Sstevel@tonic-gate /* R_SPARC_GLOB_DAT */ {0x0, FLG_RE_NOTREL, 8, 0, 0}, 1007c478bd9Sstevel@tonic-gate #else 1017c478bd9Sstevel@tonic-gate /* R_SPARC_GLOB_DAT */ {0x0, FLG_RE_NOTREL, 4, 0, 0}, 1027c478bd9Sstevel@tonic-gate #endif 1037c478bd9Sstevel@tonic-gate /* R_SPARC_JMP_SLOT */ {0x0, 0, 0, 0, 0}, /* SPECIAL */ 1047c478bd9Sstevel@tonic-gate #if defined(_ELF64) 1057c478bd9Sstevel@tonic-gate /* R_SPARC_RELATIVE */ {0x0, FLG_RE_NOTREL, 8, 0, 0}, 1067c478bd9Sstevel@tonic-gate #else 1077c478bd9Sstevel@tonic-gate /* R_SPARC_RELATIVE */ {0x0, FLG_RE_NOTREL, 4, 0, 0}, 1087c478bd9Sstevel@tonic-gate #endif 109552ff457Srie /* R_SPARC_UA32 */ {0x0, FLG_RE_UNALIGN, 4, 0, 0}, 1107c478bd9Sstevel@tonic-gate /* R_SPARC_PLT32 */ {0x0, FLG_RE_PLTREL | FLG_RE_VERIFY | 1117c478bd9Sstevel@tonic-gate FLG_RE_ADDRELATIVE, 4, 0, 0}, 1127c478bd9Sstevel@tonic-gate /* R_SPARC_HIPLT22 */ {0x0, FLG_RE_PLTREL, 4, 10, 22}, 1137c478bd9Sstevel@tonic-gate /* R_SPARC_LOPLT10 */ {0x3ff, FLG_RE_PLTREL, 4, 0, 13}, 1147c478bd9Sstevel@tonic-gate /* R_SPARC_PCPLT32 */ {0x0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY, 1157c478bd9Sstevel@tonic-gate 4, 0, 0}, 116552ff457Srie /* R_SPARC_PCPLT22 */ {0x0, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY, 1177c478bd9Sstevel@tonic-gate 4, 10, 22}, 118552ff457Srie /* R_SPARC_PCPLT10 */ {0x3ff, FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_VERIFY, 1197c478bd9Sstevel@tonic-gate 4, 0, 13}, 120552ff457Srie /* R_SPARC_10 */ {0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 10}, 121552ff457Srie /* R_SPARC_11 */ {0x0, FLG_RE_VERIFY | FLG_RE_SIGN, 4, 0, 11}, 122552ff457Srie /* R_SPARC_64 */ {0x0, FLG_RE_VERIFY, 8, 0, 0}, /* V9 */ 123552ff457Srie /* R_SPARC_OLO10 */ {0x3ff, FLG_RE_EXTOFFSET | FLG_RE_SIGN, 124552ff457Srie 4, 0, 13}, /* V9 */ 125552ff457Srie /* R_SPARC_HH22 */ {0x0, FLG_RE_VERIFY, 4, 42, 22}, /* V9 */ 126552ff457Srie /* R_SPARC_HM10 */ {0x3ff, FLG_RE_SIGN, 4, 32, 13}, /* V9 */ 127552ff457Srie /* R_SPARC_LM22 */ {0x0, FLG_RE_NOTREL, 4, 10, 22}, /* V9 */ 128141040e8Srie /* R_SPARC_PC_HH22 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY, 1297c478bd9Sstevel@tonic-gate 4, 42, 22}, /* V9 */ 130141040e8Srie /* R_SPARC_PC_HM10 */ {0x3ff, FLG_RE_PCREL | FLG_RE_SIGN, 1317c478bd9Sstevel@tonic-gate 4, 32, 13}, /* V9 */ 132141040e8Srie /* R_SPARC_PC_LM22 */ {0x0, FLG_RE_PCREL, 1337c478bd9Sstevel@tonic-gate 4, 10, 22}, /* V9 */ 1347c478bd9Sstevel@tonic-gate /* R_SPARC_WDISP16 */ {0x0, FLG_RE_PCREL | FLG_RE_WDISP16 | 1357c478bd9Sstevel@tonic-gate FLG_RE_VERIFY | FLG_RE_SIGN, 1367c478bd9Sstevel@tonic-gate 4, 2, 16}, 1377c478bd9Sstevel@tonic-gate /* R_SPARC_WDISP19 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 1387c478bd9Sstevel@tonic-gate 4, 2, 19}, 1397c478bd9Sstevel@tonic-gate /* R_SPARC_GLOB_JMP */ {0x0, 0, 0, 0, 0}, /* V9 - not implemented */ 1407c478bd9Sstevel@tonic-gate /* removed from v9 ABI */ 1417c478bd9Sstevel@tonic-gate /* R_SPARC_7 */ {0x0, FLG_RE_NOTREL, 4, 0, 7}, 1427c478bd9Sstevel@tonic-gate /* R_SPARC_5 */ {0x0, FLG_RE_NOTREL, 4, 0, 5}, 1437c478bd9Sstevel@tonic-gate /* R_SPARC_6 */ {0x0, FLG_RE_NOTREL, 4, 0, 6}, 1447c478bd9Sstevel@tonic-gate /* R_SPARC_DISP64 */ {0x0, FLG_RE_PCREL | FLG_RE_VERIFY | FLG_RE_SIGN, 1457c478bd9Sstevel@tonic-gate 8, 0, 0}, 1467c478bd9Sstevel@tonic-gate /* R_SPARC_PLT64 */ {0x0, FLG_RE_PLTREL | FLG_RE_VERIFY | 1477c478bd9Sstevel@tonic-gate FLG_RE_ADDRELATIVE, 8, 0, 0}, 1485aefb655Srie /* R_SPARC_HIX22 */ {(Xword)(-1LL), FLG_RE_VERIFY, 1497c478bd9Sstevel@tonic-gate 4, 10, 22}, /* V9 - HaL */ 150552ff457Srie /* R_SPARC_LOX10 */ {0x3ff, FLG_RE_SIGN, 4, 0, 13}, /* V9 - HaL */ 151552ff457Srie /* R_SPARC_H44 */ {0x0, FLG_RE_VERIFY, 4, 22, 22}, /* V9 */ 1527c478bd9Sstevel@tonic-gate /* R_SPARC_M44 */ {0x3ff, FLG_RE_NOTREL, 4, 12, 10}, /* V9 */ 1537c478bd9Sstevel@tonic-gate /* R_SPARC_L44 */ {0xfff, FLG_RE_NOTREL, 4, 0, 13}, /* V9 */ 154552ff457Srie /* R_SPARC_REGISTER */ {0x0, FLG_RE_REGISTER, 0, 0, 0}, /* SPECIAL */ 155552ff457Srie /* R_SPARC_UA64 */ {0x0, FLG_RE_VERIFY | FLG_RE_UNALIGN, 1567c478bd9Sstevel@tonic-gate 8, 0, 0}, /* V9 */ 157552ff457Srie /* R_SPARC_UA16 */ {0x0, FLG_RE_VERIFY | FLG_RE_UNALIGN, 1587c478bd9Sstevel@tonic-gate 2, 0, 0}, 159d326b23bSrie /* R_SPARC_TLS_GD_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSGD, 4, 10, 22}, 160d326b23bSrie /* R_SPARC_TLS_GD_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSGD | 161d326b23bSrie FLG_RE_SIGN, 4, 0, 13}, 162d326b23bSrie /* R_SPARC_TLS_GD_ADD */ {0x0, FLG_RE_TLSGD, 0, 0, 0}, 163d326b23bSrie /* R_SPARC_TLS_GD_CALL */ {0x0, FLG_RE_TLSGD, 0, 0, 0}, 164d326b23bSrie /* R_SPARC_TLS_LDM_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSLD, 4, 10, 22}, 165d326b23bSrie /* R_SPARC_TLS_LDM_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSLD | 166d326b23bSrie FLG_RE_SIGN, 4, 0, 13}, 167d326b23bSrie /* R_SPARC_TLS_LDM_ADD */ {0x0, FLG_RE_TLSLD, 0, 0, 0}, 168d326b23bSrie /* R_SPARC_TLS_LDM_CALL */ {0x0, FLG_RE_TLSLD, 0, 0, 0}, 169d326b23bSrie /* R_SPARC_TLS_LDO_HIX22 */ {0x0, FLG_RE_VERIFY | FLG_RE_TLSLD, 4, 10, 22}, 170d326b23bSrie /* R_SPARC_TLS_LDO_LOX10 */ {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLD, 4, 0, 13}, 171d326b23bSrie /* R_SPARC_TLS_LDO_ADD */ {0x0, FLG_RE_TLSLD, 0, 0, 0}, 172d326b23bSrie /* R_SPARC_TLS_IE_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSIE, 4, 10, 22}, 173d326b23bSrie /* R_SPARC_TLS_IE_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSIE | 174d326b23bSrie FLG_RE_SIGN, 4, 0, 13}, 175d326b23bSrie /* R_SPARC_TLS_IE_LD */ {0x0, FLG_RE_TLSIE, 0, 0, 0}, 176d326b23bSrie /* R_SPARC_TLS_IE_LDX */ {0x0, FLG_RE_TLSIE, 0, 0, 0}, 177d326b23bSrie /* R_SPARC_TLS_IE_ADD */ {0x0, FLG_RE_TLSIE, 0, 0, 0}, 178552ff457Srie /* R_SPARC_TLS_LE_HIX22 */ {(Xword)(-1LL), 179d326b23bSrie FLG_RE_VERIFY | FLG_RE_TLSLE, 4, 10, 22}, 180d326b23bSrie /* R_SPARC_TLS_LE_LOX10 */ {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLE, 4, 0, 13}, 1817c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_DTPMOD32 */ {0x0, FLG_RE_NOTREL, 4, 0, 0}, 1827c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_DTPMOD64 */ {0x0, FLG_RE_NOTREL, 8, 0, 0}, 1837c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_DTPOFF32 */ {0x0, FLG_RE_NOTREL, 4, 0, 0}, 1847c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_DTPOFF64 */ {0x0, FLG_RE_NOTREL, 8, 0, 0}, 1857c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_TPOFF32 */ {0x0, FLG_RE_NOTREL, 4, 0, 0}, 1867c478bd9Sstevel@tonic-gate /* R_SPARC_TLS_TPOFF64 */ {0x0, FLG_RE_NOTREL, 8, 0, 0}, 187051d39bbSrie /* R_SPARC_GOTDATA_HIX22 */ {0, FLG_RE_SIGN | FLG_RE_GOTREL | 188051d39bbSrie FLG_RE_VERIFY, 4, 10, 22}, 1897c478bd9Sstevel@tonic-gate /* R_SPARC_GOTDATA_LOX10 */ { 0x3ff, FLG_RE_GOTREL | FLG_RE_SIGN, 4, 0, 13}, 1907c478bd9Sstevel@tonic-gate /* R_SPARC_GOTDATA_OP_HIX22 */ { 0x0, FLG_RE_GOTOPINS | FLG_RE_GOTADD, 1917c478bd9Sstevel@tonic-gate 4, 10, 22}, 1927c478bd9Sstevel@tonic-gate /* R_SPARC_GOTDATA_OP_LOX10 */ { 0x3ff, FLG_RE_SIGN | FLG_RE_GOTOPINS | 1937c478bd9Sstevel@tonic-gate FLG_RE_GOTADD, 4, 0, 13}, 1947c478bd9Sstevel@tonic-gate /* R_SPARC_GOTDATA_OP */ { 0x0, FLG_RE_GOTOPINS, 0, 0, 0}, 1952926dd2eSrie /* R_SPARC_H34 */ {0x0, FLG_RE_VERIFY, 4, 12, 22}, /* V9 */ 1962926dd2eSrie /* R_SPARC_SIZE32 */ {0x0, FLG_RE_SIZE | FLG_RE_VERIFY, 4, 0, 0}, 1972926dd2eSrie /* R_SPARC_SIZE64 */ {0x0, FLG_RE_SIZE | FLG_RE_VERIFY, 8, 0, 0}, 1987c478bd9Sstevel@tonic-gate }; 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* 2027c478bd9Sstevel@tonic-gate * Write a single relocated value to its reference location. 2037c478bd9Sstevel@tonic-gate * We assume we wish to add the relocation amount, value, to the 204552ff457Srie * value of the address already present in the instruction. 2057c478bd9Sstevel@tonic-gate * 2067c478bd9Sstevel@tonic-gate * NAME VALUE FIELD CALCULATION 2077c478bd9Sstevel@tonic-gate * 2087c478bd9Sstevel@tonic-gate * R_SPARC_NONE 0 none none 2097c478bd9Sstevel@tonic-gate * R_SPARC_8 1 V-byte8 S + A 2107c478bd9Sstevel@tonic-gate * R_SPARC_16 2 V-half16 S + A 2117c478bd9Sstevel@tonic-gate * R_SPARC_32 3 V-word32 S + A 2127c478bd9Sstevel@tonic-gate * R_SPARC_DISP8 4 V-byte8 S + A - P 2137c478bd9Sstevel@tonic-gate * R_SPARC_DISP16 5 V-half16 S + A - P 2147c478bd9Sstevel@tonic-gate * R_SPARC_DISP32 6 V-word32 S + A - P 2157c478bd9Sstevel@tonic-gate * R_SPARC_WDISP30 7 V-disp30 (S + A - P) >> 2 2167c478bd9Sstevel@tonic-gate * R_SPARC_WDISP22 8 V-disp22 (S + A - P) >> 2 2177c478bd9Sstevel@tonic-gate * R_SPARC_HI22 9 T-imm22 (S + A) >> 10 2187c478bd9Sstevel@tonic-gate * R_SPARC_22 10 V-imm22 S + A 2197c478bd9Sstevel@tonic-gate * R_SPARC_13 11 V-simm13 S + A 2207c478bd9Sstevel@tonic-gate * R_SPARC_LO10 12 T-simm13 (S + A) & 0x3ff 2217c478bd9Sstevel@tonic-gate * R_SPARC_GOT10 13 T-simm13 G & 0x3ff 2227c478bd9Sstevel@tonic-gate * R_SPARC_GOT13 14 V-simm13 G 2237c478bd9Sstevel@tonic-gate * R_SPARC_GOT22 15 T-imm22 G >> 10 2247c478bd9Sstevel@tonic-gate * R_SPARC_PC10 16 T-simm13 (S + A - P) & 0x3ff 2257c478bd9Sstevel@tonic-gate * R_SPARC_PC22 17 V-disp22 (S + A - P) >> 10 2267c478bd9Sstevel@tonic-gate * R_SPARC_WPLT30 18 V-disp30 (L + A - P) >> 2 2277c478bd9Sstevel@tonic-gate * R_SPARC_COPY 19 none none 2287c478bd9Sstevel@tonic-gate * R_SPARC_GLOB_DAT 20 V-word32 S + A 2297c478bd9Sstevel@tonic-gate * R_SPARC_JMP_SLOT 21 V-plt22 S + A 2307c478bd9Sstevel@tonic-gate * R_SPARC_RELATIVE 22 V-word32 S + A 2317c478bd9Sstevel@tonic-gate * R_SPARC_UA32 23 V-word32 S + A 2327c478bd9Sstevel@tonic-gate * R_SPARC_PLT32 24 V-word32 L + A 2337c478bd9Sstevel@tonic-gate * R_SPARC_HIPLT22 25 T-imm22 (L + A) >> 10 2347c478bd9Sstevel@tonic-gate * R_SPARC_LOPLT10 26 T-simm13 (L + A) & 0x3ff 2357c478bd9Sstevel@tonic-gate * R_SPARC_PCPLT32 27 V-word32 L + A - P 2367c478bd9Sstevel@tonic-gate * R_SPARC_PCPLT22 28 V-disp22 (L + A - P) >> 10 2377c478bd9Sstevel@tonic-gate * R_SPARC_PCPLT10 29 V-simm13 (L + A - P) & 0x3ff 2387c478bd9Sstevel@tonic-gate * R_SPARC_10 30 V-simm10 S + A 2397c478bd9Sstevel@tonic-gate * R_SPARC_11 31 V-simm11 S + A 2407c478bd9Sstevel@tonic-gate * R_SPARC_64 32 V-xword64 S + A 2417c478bd9Sstevel@tonic-gate * R_SPARC_OLO10 33 V-simm13 ((S + A) & 0x3ff) + O 2427c478bd9Sstevel@tonic-gate * R_SPARC_HH22 34 V-imm22 (S + A) >> 42 2437c478bd9Sstevel@tonic-gate * R_SPARC_HM10 35 T-simm13 ((S + A) >> 32) & 0x3ff 2447c478bd9Sstevel@tonic-gate * R_SPARC_LM22 36 T-imm22 (S + A) >> 10 2457c478bd9Sstevel@tonic-gate * R_SPARC_PC_HH22 37 V-imm22 (S + A - P) >> 42 2467c478bd9Sstevel@tonic-gate * R_SPARC_PC_HM10 38 T-simm13 ((S + A - P) >> 32) & 0x3ff 2477c478bd9Sstevel@tonic-gate * R_SPARC_PC_LM22 39 T-imm22 (S + A - P) >> 10 2487c478bd9Sstevel@tonic-gate * R_SPARC_WDISP16 40 V-d2/disp14 (S + A - P) >> 2 2497c478bd9Sstevel@tonic-gate * R_SPARC_WDISP19 41 V-disp19 (S + A - P) >> 2 2507c478bd9Sstevel@tonic-gate * R_SPARC_GLOB_JMP 42 V-xword64 S + A 2517c478bd9Sstevel@tonic-gate * R_SPARC_7 43 V-imm7 S + A 2527c478bd9Sstevel@tonic-gate * R_SPARC_5 44 V-imm5 S + A 2537c478bd9Sstevel@tonic-gate * R_SPARC_6 45 V-imm6 S + A 2547c478bd9Sstevel@tonic-gate * R_SPARC_DISP64 46 V-xword64 S + A - P 2557c478bd9Sstevel@tonic-gate * R_SPARC_PLT64 47 V-xword64 L + A 256552ff457Srie * R_SPARC_HIX22 48 V-imm22 ((S + A) ^ 257552ff457Srie * 0xffffffffffffffff) >> 10 2587c478bd9Sstevel@tonic-gate * R_SPARC_LOX10 49 T-simm13 ((S + A) & 0x3ff) | 0x1c00 2597c478bd9Sstevel@tonic-gate * R_SPARC_H44 50 V-imm22 (S + A) >> 22 2607c478bd9Sstevel@tonic-gate * R_SPARC_M44 51 T-imm10 ((S + A) >> 12) & 0x3ff 2617c478bd9Sstevel@tonic-gate * R_SPARC_L44 52 T-imm13 (S + A) & 0xfff 2627c478bd9Sstevel@tonic-gate * R_SPARC_REGISTER 53 V-xword64 S + A 2637c478bd9Sstevel@tonic-gate * R_SPARC_UA64 54 V-xword64 S + A 2647c478bd9Sstevel@tonic-gate * R_SPARC_UA16 55 V-half16 S + A 2657c478bd9Sstevel@tonic-gate * R_SPARC_TLS_GD_HI22 56 T-simm22 @dtlndx(S + A) >> 10 2667c478bd9Sstevel@tonic-gate * R_SPARC_TLS_GD_LO10 57 T-simm13 @dtlndx(S + A) & 0x3ff 267552ff457Srie * R_SPARC_TLS_GD_ADD 58 none SPECIAL 268552ff457Srie * R_SPARC_TLS_GD_CALL 59 V-disp30 SPECIAL 2697c478bd9Sstevel@tonic-gate * R_SPARC_TLS_LDM_HI22 60 T-simm22 @tmndx(S + A) >> 10 2707c478bd9Sstevel@tonic-gate * R_SPARC_TLS_LDM_LO10 61 T-simm13 @tmndx(S + A) & 0x3ff 271552ff457Srie * R_SPARC_TLS_LDM_ADD 62 none SPECIAL 272552ff457Srie * R_SPARC_TLS_LDM_CALL 63 V-disp30 SPECIAL 2737c478bd9Sstevel@tonic-gate * R_SPARC_TLS_LDO_HIX22 64 V-simm22 @dtpoff(S + A) >> 10 2747c478bd9Sstevel@tonic-gate * R_SPARC_TLS_LDO_LOX10 65 T-simm13 @dtpoff(S + A) & 0x3ff 275552ff457Srie * R_SPARC_TLS_LDO_ADD 66 none SPECIAL 2767c478bd9Sstevel@tonic-gate * R_SPARC_TLS_IE_HI22 67 T-simm22 @got(@tpoff(S + A)) >> 10 2777c478bd9Sstevel@tonic-gate * R_SPARC_TLS_IE_LO10 68 T-simm13 @got(@tpoff(S + A)) & 0x3ff 278552ff457Srie * R_SPARC_TLS_IE_LD 69 none SPECIAL 279552ff457Srie * R_SPARC_TLS_IE_LDX 70 none SPECIAL 280552ff457Srie * R_SPARC_TLS_IE_ADD 71 none SPECIAL 281552ff457Srie * R_SPARC_TLS_LE_HIX22 72 V-simm22 (@tpoff(S + A) ^ 282552ff457Srie * 0xffffffff) >> 10 2837c478bd9Sstevel@tonic-gate * R_SPARC_TLS_LE_LOX10 73 T-simm13 (@tpoff(S + A) & 0x3ff) | 0x1c00 2847c478bd9Sstevel@tonic-gate * R_SPARC_TLS_DTPMOD32 74 V-word32 @dtmod(S + A) 2857c478bd9Sstevel@tonic-gate * R_SPARC_TLS_DTPMOD64 75 V-word64 @dtmod(S + A) 2867c478bd9Sstevel@tonic-gate * R_SPARC_TLS_DTPOFF32 76 V-word32 @dtpoff(S + A) 2877c478bd9Sstevel@tonic-gate * R_SPARC_TLS_DTPOFF64 77 V-word64 @dtpoff(S + A) 2887c478bd9Sstevel@tonic-gate * R_SPARC_TLS_TPOFF32 78 V-word32 @tpoff(S + A) 2897c478bd9Sstevel@tonic-gate * R_SPARC_TLS_TPOFF64 79 V-word64 @tpoff(S + A) 290051d39bbSrie * R_SPARC_GOTDATA_HIX22 80 V-imm22 ((S + A - GOT) >> 10) ^ 291552ff457Srie * ((S + A - GOT) >> 31) 292552ff457Srie * R_SPARC_GOTDATA_LOX10 81 T-simm13 ((S + A - GOT) & 0x3ff) | 293552ff457Srie * (((S + A - GOT) >> 31) & 294552ff457Srie * 0x1c00) 295552ff457Srie * R_SPARC_GOTDATA_OP_HIX22 82 T-imm22 (G >> 10) & (G >> 31) 296552ff457Srie * R_SPARC_GOTDATA_OP_LOX10 83 T-simm13 (G & 0x3ff) | 297552ff457Srie * ((G >> 31) & 0x1c00) 2982926dd2eSrie * R_SPARC_GOTDATA_OP 84 Word32 SPECIAL 2992926dd2eSrie * R_SPARC_H34 85 V-imm22 (S + A) >> 12 3002926dd2eSrie * R_SPARC_SIZE32 86 V-word32 Z + A 3012926dd2eSrie * R_SPARC_SIZE64 87 V-xword64 Z + A 3027c478bd9Sstevel@tonic-gate * 3037c478bd9Sstevel@tonic-gate * This is Figure 4-20: Relocation Types from the Draft Copy of 3047c478bd9Sstevel@tonic-gate * the ABI, Printed on 11/29/88. 3057c478bd9Sstevel@tonic-gate * 3067c478bd9Sstevel@tonic-gate * NOTE1: relocations 24->45 are newly registered relocations to support 3077c478bd9Sstevel@tonic-gate * C++ ABI & SPARC V8+ and SPARC V9 architectures (1/9/94), and 3087c478bd9Sstevel@tonic-gate * 64-bit relocations 46-55 were added for SPARC V9. 3097c478bd9Sstevel@tonic-gate * 3107c478bd9Sstevel@tonic-gate * NOTE2: relocations 56->79 are added to support Thread-Local storage 3117c478bd9Sstevel@tonic-gate * as recorded in PSARC/2001/509 3127c478bd9Sstevel@tonic-gate * 3137c478bd9Sstevel@tonic-gate * NOTE3: The value to be passed for relocations R_SPARC_HIX22 and 3147c478bd9Sstevel@tonic-gate * R_SPARC_TLS_HIX22 are negative values. So the upper 10 or 40 bits 3157c478bd9Sstevel@tonic-gate * are 1. (So when the exclusive OR is applied, the upper bits 3167c478bd9Sstevel@tonic-gate * will be 0.) 3177c478bd9Sstevel@tonic-gate * 3187c478bd9Sstevel@tonic-gate * Relocation calculations: 3197c478bd9Sstevel@tonic-gate * 3207c478bd9Sstevel@tonic-gate * The FIELD names indicate whether the relocation type checks for overflow. 3217c478bd9Sstevel@tonic-gate * A calculated relocation value may be larger than the intended field, and 3227c478bd9Sstevel@tonic-gate * the relocation type may verify (V) that the value fits, or truncate (T) 3237c478bd9Sstevel@tonic-gate * the result. 3247c478bd9Sstevel@tonic-gate * 3257c478bd9Sstevel@tonic-gate * CALCULATION uses the following notation: 3267c478bd9Sstevel@tonic-gate * A the addend used 3277c478bd9Sstevel@tonic-gate * B the base address of the shared object in memory 3287c478bd9Sstevel@tonic-gate * G the offset into the global offset table 3297c478bd9Sstevel@tonic-gate * L the procedure linkage entry 3307c478bd9Sstevel@tonic-gate * P the place of the storage unit being relocated 3317c478bd9Sstevel@tonic-gate * S the value of the symbol 3327c478bd9Sstevel@tonic-gate * O secondary addend (extra offset) in v9 r_info field 3332926dd2eSrie * Z the size of the symbol whose index resides in the relocation 3342926dd2eSrie * entry 3357c478bd9Sstevel@tonic-gate * 3367c478bd9Sstevel@tonic-gate * @dtlndx(x): Allocate two contiguous entries in the GOT table to hold 3377c478bd9Sstevel@tonic-gate * a Tls_index structure (for passing to __tls_get_addr()). The 3387c478bd9Sstevel@tonic-gate * instructions referencing this entry will be bound to the first 3397c478bd9Sstevel@tonic-gate * of the two GOT entries. 3407c478bd9Sstevel@tonic-gate * 3417c478bd9Sstevel@tonic-gate * @tmndx(x): Allocate two contiguous entries in the GOT table to hold 3427c478bd9Sstevel@tonic-gate * a Tls_index structure (for passing to __tls_get_addr()). The 3437c478bd9Sstevel@tonic-gate * ti_offset field of the Tls_index will be set to 0 (zero) and the 3447c478bd9Sstevel@tonic-gate * ti_module will be filled in at run-time. The call to 3457c478bd9Sstevel@tonic-gate * __tls_get_addr() will return the starting offset of the dynamic 3467c478bd9Sstevel@tonic-gate * TLS block. 3477c478bd9Sstevel@tonic-gate * 3487c478bd9Sstevel@tonic-gate * @dtpoff(x): calculate the tlsoffset relative to the TLS block. 3497c478bd9Sstevel@tonic-gate * 3507c478bd9Sstevel@tonic-gate * @tpoff(x): calculate the negative tlsoffset relative to the static 3517c478bd9Sstevel@tonic-gate * TLS block. This value can be added to the thread-pointer to 3527c478bd9Sstevel@tonic-gate * calculate the tls address. 3537c478bd9Sstevel@tonic-gate * 3547c478bd9Sstevel@tonic-gate * @dtpmod(x): calculate the module id of the object containing symbol x. 3557c478bd9Sstevel@tonic-gate * 3567c478bd9Sstevel@tonic-gate * The calculations in the CALCULATION column are assumed to have been performed 3577c478bd9Sstevel@tonic-gate * before calling this function except for the addition of the addresses in the 3587c478bd9Sstevel@tonic-gate * instructions. 3597c478bd9Sstevel@tonic-gate * 3607c478bd9Sstevel@tonic-gate * Upon successful completion of do_reloc() *value will be set to the 3617c478bd9Sstevel@tonic-gate * 'bit-shifted' value that will be or'ed into memory. 3627c478bd9Sstevel@tonic-gate */ 363f3324781Sab196087 #if defined(_KERNEL) 364f3324781Sab196087 #define lml 0 /* Needed by arglist of REL_ERR_* macros */ 3657c478bd9Sstevel@tonic-gate int 366f3324781Sab196087 do_reloc_krtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, 367f3324781Sab196087 const char *file) 368f3324781Sab196087 #elif defined(DO_RELOC_LIBLD) 369ba2be530Sab196087 /*ARGSUSED5*/ 370f3324781Sab196087 int 371*bf994817SAli Bahrami do_reloc_ld(Rel_desc *rdesc, uchar_t *off, Xword *value, 372*bf994817SAli Bahrami rel_desc_sname_func_t rel_desc_sname_func, 373f3324781Sab196087 const char *file, int bswap, void *lml) 374f3324781Sab196087 #else 375f3324781Sab196087 int 376f3324781Sab196087 do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym, 3775aefb655Srie const char *file, void *lml) 378f3324781Sab196087 #endif 3797c478bd9Sstevel@tonic-gate { 380*bf994817SAli Bahrami #ifdef DO_RELOC_LIBLD 381*bf994817SAli Bahrami #define sym (* rel_desc_sname_func)(rdesc) 382*bf994817SAli Bahrami uchar_t rtype = rdesc->rel_rtype; 383*bf994817SAli Bahrami #endif 3847c478bd9Sstevel@tonic-gate Xword uvalue = 0; 3857c478bd9Sstevel@tonic-gate Xword basevalue, sigbit_mask, sigfit_mask; 3867c478bd9Sstevel@tonic-gate Xword corevalue = *value; 387552ff457Srie uchar_t bshift; 3887c478bd9Sstevel@tonic-gate int field_size, re_flags; 3897c478bd9Sstevel@tonic-gate const Rel_entry *rep; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate rep = &reloc_table[rtype]; 3927c478bd9Sstevel@tonic-gate bshift = rep->re_bshift; 3937c478bd9Sstevel@tonic-gate field_size = rep->re_fsize; 3947c478bd9Sstevel@tonic-gate re_flags = rep->re_flags; 3957c478bd9Sstevel@tonic-gate sigbit_mask = S_MASK(rep->re_sigbits); 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate if ((re_flags & FLG_RE_SIGN) && sigbit_mask) { 3987c478bd9Sstevel@tonic-gate /* 3997c478bd9Sstevel@tonic-gate * sigfit_mask takes into account that a value 4007c478bd9Sstevel@tonic-gate * might be signed and discards the signbit for 4017c478bd9Sstevel@tonic-gate * comparison. 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate sigfit_mask = S_MASK(rep->re_sigbits - 1); 4047c478bd9Sstevel@tonic-gate } else 4057c478bd9Sstevel@tonic-gate sigfit_mask = sigbit_mask; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (field_size == 0) { 4085aefb655Srie REL_ERR_UNIMPL(lml, file, sym, rtype); 4097c478bd9Sstevel@tonic-gate return (0); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate 412ba2be530Sab196087 /* 413ba2be530Sab196087 * We have two ways to retrieve the base value, a general one 414ba2be530Sab196087 * that will work with data of any alignment, and another that is 415ba2be530Sab196087 * fast, but which requires the data to be aligned according to 416ba2be530Sab196087 * sparc alignment rules. 417ba2be530Sab196087 * 418ba2be530Sab196087 * For non-native linking, we always use the general path. For 419ba2be530Sab196087 * native linking, the FLG_RE_UNALIGN determines it. 420ba2be530Sab196087 */ 421ba2be530Sab196087 #if defined(DORELOC_NATIVE) 422ba2be530Sab196087 if (re_flags & FLG_RE_UNALIGN) 423ba2be530Sab196087 #endif 424ba2be530Sab196087 { 4257c478bd9Sstevel@tonic-gate int i; 426552ff457Srie uchar_t *dest = (uchar_t *)&basevalue; 4277c478bd9Sstevel@tonic-gate 428ba2be530Sab196087 basevalue = 0; 429ba2be530Sab196087 #if !defined(DORELOC_NATIVE) 430ba2be530Sab196087 if (bswap) { 431ba2be530Sab196087 int j = field_size - 1; 432ba2be530Sab196087 433ba2be530Sab196087 for (i = 0; i < field_size; i++, j--) 434ba2be530Sab196087 dest[i] = off[j]; 435ba2be530Sab196087 436ba2be530Sab196087 } else 437ba2be530Sab196087 #endif 438ba2be530Sab196087 { 4397c478bd9Sstevel@tonic-gate /* 440ba2be530Sab196087 * Adjust the offset 4417c478bd9Sstevel@tonic-gate */ 4427c478bd9Sstevel@tonic-gate /* LINTED */ 4437c478bd9Sstevel@tonic-gate i = (int)(sizeof (Xword) - field_size); 4447c478bd9Sstevel@tonic-gate if (i > 0) 4457c478bd9Sstevel@tonic-gate dest += i; 4467c478bd9Sstevel@tonic-gate for (i = field_size - 1; i >= 0; i--) 4477c478bd9Sstevel@tonic-gate dest[i] = off[i]; 448ba2be530Sab196087 } 449ba2be530Sab196087 } 450ba2be530Sab196087 451ba2be530Sab196087 /* 452ba2be530Sab196087 * Non-native linker: We have already fetched the value above, 453ba2be530Sab196087 * but if the relocation does not have the FLG_RE_UNALIGN 454ba2be530Sab196087 * flag set, we still need to do the same error checking we 455ba2be530Sab196087 * would do on a native linker. 456ba2be530Sab196087 * Native-linker: If this is an aligned relocation, we need to 457ba2be530Sab196087 * fetch the value and also do the error checking. 458ba2be530Sab196087 * 459ba2be530Sab196087 * The FETCH macro is used to conditionalize the fetching so that 460ba2be530Sab196087 * it only happens in the native case. 461ba2be530Sab196087 */ 462ba2be530Sab196087 #if defined(DORELOC_NATIVE) 463ba2be530Sab196087 #define FETCH(_type) basevalue = (Xword)*((_type *)off); 464ba2be530Sab196087 #else 465ba2be530Sab196087 #define FETCH(_type) 466ba2be530Sab196087 #endif 467ba2be530Sab196087 if ((re_flags & FLG_RE_UNALIGN) == 0) { 46875521904Sraf if (((field_size == 2) && ((uintptr_t)off & 0x1)) || 46975521904Sraf ((field_size == 4) && ((uintptr_t)off & 0x3)) || 47075521904Sraf ((field_size == 8) && ((uintptr_t)off & 0x7))) { 4715aefb655Srie REL_ERR_NONALIGN(lml, file, sym, rtype, (uintptr_t)off); 4727c478bd9Sstevel@tonic-gate return (0); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate switch (field_size) { 4757c478bd9Sstevel@tonic-gate case 1: 476ba2be530Sab196087 /* LINTED */ 477ba2be530Sab196087 FETCH(uchar_t); 4787c478bd9Sstevel@tonic-gate break; 4797c478bd9Sstevel@tonic-gate case 2: 4807c478bd9Sstevel@tonic-gate /* LINTED */ 481ba2be530Sab196087 FETCH(Half); 4827c478bd9Sstevel@tonic-gate break; 4837c478bd9Sstevel@tonic-gate case 4: 4847c478bd9Sstevel@tonic-gate /* LINTED */ 485ba2be530Sab196087 FETCH(Word); 4867c478bd9Sstevel@tonic-gate break; 4877c478bd9Sstevel@tonic-gate case 8: 4887c478bd9Sstevel@tonic-gate /* LINTED */ 489ba2be530Sab196087 FETCH(Xword); 4907c478bd9Sstevel@tonic-gate break; 4917c478bd9Sstevel@tonic-gate default: 4925aefb655Srie REL_ERR_UNNOBITS(lml, file, sym, rtype, 4935aefb655Srie (rep->re_fsize * 8)); 4947c478bd9Sstevel@tonic-gate return (0); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate } 497ba2be530Sab196087 #undef FETCH 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate if (sigbit_mask) { 5007c478bd9Sstevel@tonic-gate /* 5017c478bd9Sstevel@tonic-gate * The WDISP16 relocation is an unusual one in that it's bits 5027c478bd9Sstevel@tonic-gate * are not all contiguous. We have to selectivly pull them out. 5037c478bd9Sstevel@tonic-gate */ 5047c478bd9Sstevel@tonic-gate if (re_flags & FLG_RE_WDISP16) { 5057c478bd9Sstevel@tonic-gate uvalue = ((basevalue & 0x300000) >> 6) | 5067c478bd9Sstevel@tonic-gate (basevalue & 0x3fff); 5077c478bd9Sstevel@tonic-gate basevalue &= ~0x303fff; 5087c478bd9Sstevel@tonic-gate } else { 5097c478bd9Sstevel@tonic-gate uvalue = sigbit_mask & basevalue; 5107c478bd9Sstevel@tonic-gate basevalue &= ~sigbit_mask; 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate /* 5137c478bd9Sstevel@tonic-gate * If value is signed make sure that we signextend the uvalue. 5147c478bd9Sstevel@tonic-gate */ 5157c478bd9Sstevel@tonic-gate if (re_flags & FLG_RE_SIGN) { 5167c478bd9Sstevel@tonic-gate if (uvalue & (~sigbit_mask & sigfit_mask)) 5177c478bd9Sstevel@tonic-gate uvalue |= ~sigbit_mask; 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate } else 5207c478bd9Sstevel@tonic-gate uvalue = basevalue; 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if (bshift) 5237c478bd9Sstevel@tonic-gate uvalue <<= bshift; 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate uvalue += *value; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if (rep->re_mask && 5287c478bd9Sstevel@tonic-gate ((rtype == R_SPARC_HIX22) || (rtype == R_SPARC_TLS_LE_HIX22))) 5297c478bd9Sstevel@tonic-gate uvalue ^= rep->re_mask; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (bshift) { 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * This is to check that we are not attempting to 5347c478bd9Sstevel@tonic-gate * jump to a non-4 byte aligned address. 5357c478bd9Sstevel@tonic-gate */ 5367c478bd9Sstevel@tonic-gate if ((bshift == 2) && (uvalue & 0x3)) { 5375aefb655Srie REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, 2, off); 5387c478bd9Sstevel@tonic-gate return (0); 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (re_flags & FLG_RE_SIGN) { 5427c478bd9Sstevel@tonic-gate uvalue = (Sxword)uvalue >> bshift; 5437c478bd9Sstevel@tonic-gate } else { 5447c478bd9Sstevel@tonic-gate uvalue >>= bshift; 5457c478bd9Sstevel@tonic-gate } 5467c478bd9Sstevel@tonic-gate corevalue >>= bshift; 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate if ((rtype == R_SPARC_GOTDATA_HIX22) || 5507c478bd9Sstevel@tonic-gate (rtype == R_SPARC_GOTDATA_OP_HIX22)) { 5517c478bd9Sstevel@tonic-gate uvalue ^= ((Sxword)(*value) >> 31); 5527c478bd9Sstevel@tonic-gate corevalue ^= ((Sxword)(*value) >> 31); 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate if (rep->re_mask && 5567c478bd9Sstevel@tonic-gate (rtype != R_SPARC_HIX22) && (rtype != R_SPARC_TLS_LE_HIX22) && 5577c478bd9Sstevel@tonic-gate (rtype != R_SPARC_GOTDATA_HIX22)) 5587c478bd9Sstevel@tonic-gate uvalue &= rep->re_mask; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate if ((rtype == R_SPARC_LOX10) || (rtype == R_SPARC_TLS_LE_LOX10)) { 5617c478bd9Sstevel@tonic-gate uvalue |= 0x1c00; 5627c478bd9Sstevel@tonic-gate corevalue |= 0x1c00; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate if ((rtype == R_SPARC_GOTDATA_LOX10) || 5667c478bd9Sstevel@tonic-gate (rtype == R_SPARC_GOTDATA_OP_LOX10)) { 5677c478bd9Sstevel@tonic-gate uvalue |= ((Sxword)(*value) >> 31) & 0x1c00; 5687c478bd9Sstevel@tonic-gate corevalue |= ((Sxword)(*value) >> 31) & 0x1c00; 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate if ((re_flags & FLG_RE_VERIFY) && sigbit_mask) { 5737c478bd9Sstevel@tonic-gate if (((re_flags & FLG_RE_SIGN) && 5747c478bd9Sstevel@tonic-gate (S_INRANGE((Sxword)uvalue, rep->re_sigbits - 1) == 0)) || 5757c478bd9Sstevel@tonic-gate (!(re_flags & FLG_RE_SIGN) && 5767c478bd9Sstevel@tonic-gate ((sigbit_mask & uvalue) != uvalue))) { 5775aefb655Srie REL_ERR_NOFIT(lml, file, sym, rtype, uvalue); 5787c478bd9Sstevel@tonic-gate return (0); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate if (sigbit_mask) { 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * Again the R_SPARC_WDISP16 relocation takes special 5857c478bd9Sstevel@tonic-gate * processing because of its non-continguous bits. 5867c478bd9Sstevel@tonic-gate */ 5877c478bd9Sstevel@tonic-gate if (re_flags & FLG_RE_WDISP16) 5887c478bd9Sstevel@tonic-gate uvalue = ((uvalue & 0xc000) << 6) | 5897c478bd9Sstevel@tonic-gate (uvalue & 0x3fff); 5907c478bd9Sstevel@tonic-gate else 5917c478bd9Sstevel@tonic-gate uvalue &= sigbit_mask; 5927c478bd9Sstevel@tonic-gate /* 5937c478bd9Sstevel@tonic-gate * Combine value back with original word 5947c478bd9Sstevel@tonic-gate */ 5957c478bd9Sstevel@tonic-gate uvalue |= basevalue; 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate *value = corevalue; 5987c478bd9Sstevel@tonic-gate 599ba2be530Sab196087 /* 600ba2be530Sab196087 * Now, we store uvalue back at the location given by off. 601ba2be530Sab196087 * This is similar to the fetch case above: 602ba2be530Sab196087 * - We have general (unaligned) and fast (aligned) cases 603ba2be530Sab196087 * - Cross linkers need to use the unaligned case even 604ba2be530Sab196087 * when the relocation does not specify FLG_RE_UNALIGN. 605ba2be530Sab196087 * - A cross linker that processes a relocation that does not 606ba2be530Sab196087 * have FLG_RE_UNALIGN set has to do the same error 607ba2be530Sab196087 * checking that a native linker would do, while avoiding 608ba2be530Sab196087 * the aligned store (accomplished with the STORE macro). 609ba2be530Sab196087 */ 610ba2be530Sab196087 #if defined(DORELOC_NATIVE) 611ba2be530Sab196087 if (re_flags & FLG_RE_UNALIGN) 612ba2be530Sab196087 #endif 613ba2be530Sab196087 { 6147c478bd9Sstevel@tonic-gate int i; 615552ff457Srie uchar_t *src = (uchar_t *)&uvalue; 6167c478bd9Sstevel@tonic-gate 617ba2be530Sab196087 #if !defined(DORELOC_NATIVE) 618ba2be530Sab196087 if (bswap) { 619ba2be530Sab196087 int j = field_size - 1; 620ba2be530Sab196087 621ba2be530Sab196087 for (i = 0; i < field_size; i++, j--) 622ba2be530Sab196087 off[i] = src[j]; 623ba2be530Sab196087 624ba2be530Sab196087 } else 625ba2be530Sab196087 #endif 626ba2be530Sab196087 { 6277c478bd9Sstevel@tonic-gate /* 6287c478bd9Sstevel@tonic-gate * Adjust the offset. 6297c478bd9Sstevel@tonic-gate */ 6307c478bd9Sstevel@tonic-gate /* LINTED */ 6317c478bd9Sstevel@tonic-gate i = (int)(sizeof (Xword) - field_size); 6327c478bd9Sstevel@tonic-gate if (i > 0) 6337c478bd9Sstevel@tonic-gate src += i; 6347c478bd9Sstevel@tonic-gate for (i = field_size - 1; i >= 0; i--) 6357c478bd9Sstevel@tonic-gate off[i] = src[i]; 636ba2be530Sab196087 } 637ba2be530Sab196087 } 638ba2be530Sab196087 639ba2be530Sab196087 #if defined(DORELOC_NATIVE) 640ba2be530Sab196087 #define STORE(_type) *((_type *)off) = (_type)uvalue 641ba2be530Sab196087 #else 642ba2be530Sab196087 #define STORE(_type) 643ba2be530Sab196087 #endif 644ba2be530Sab196087 if ((re_flags & FLG_RE_UNALIGN) == 0) { 6457c478bd9Sstevel@tonic-gate switch (rep->re_fsize) { 6467c478bd9Sstevel@tonic-gate case 1: 647552ff457Srie /* LINTED */ 648ba2be530Sab196087 STORE(uchar_t); 6497c478bd9Sstevel@tonic-gate break; 6507c478bd9Sstevel@tonic-gate case 2: 6517c478bd9Sstevel@tonic-gate /* LINTED */ 652ba2be530Sab196087 STORE(Half); 6537c478bd9Sstevel@tonic-gate break; 6547c478bd9Sstevel@tonic-gate case 4: 6557c478bd9Sstevel@tonic-gate /* LINTED */ 656ba2be530Sab196087 STORE(Word); 6577c478bd9Sstevel@tonic-gate break; 6587c478bd9Sstevel@tonic-gate case 8: 6597c478bd9Sstevel@tonic-gate /* LINTED */ 660ba2be530Sab196087 STORE(Xword); 6617c478bd9Sstevel@tonic-gate break; 662552ff457Srie default: 663552ff457Srie /* 664552ff457Srie * To keep chkmsg() happy: MSG_INTL(MSG_REL_UNSUPSZ) 665552ff457Srie */ 6665aefb655Srie REL_ERR_UNSUPSZ(lml, file, sym, rtype, rep->re_fsize); 667552ff457Srie return (0); 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate } 670ba2be530Sab196087 #undef STORE 671ba2be530Sab196087 6727c478bd9Sstevel@tonic-gate return (1); 673*bf994817SAli Bahrami 674*bf994817SAli Bahrami #ifdef DO_RELOC_LIBLD 675*bf994817SAli Bahrami #undef sym 676*bf994817SAli Bahrami #endif 6777c478bd9Sstevel@tonic-gate } 678