10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51618Srie * Common Development and Distribution License (the "License"). 61618Srie * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 211169Srie 220Sstevel@tonic-gate /* 23*4734Sab196087 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #ifndef _RELOC_DOT_H 280Sstevel@tonic-gate #define _RELOC_DOT_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #if defined(_KERNEL) 330Sstevel@tonic-gate #include <sys/machelf.h> 340Sstevel@tonic-gate #include <sys/bootconf.h> 350Sstevel@tonic-gate #include <sys/kobj.h> 360Sstevel@tonic-gate #include <sys/kobj_impl.h> 370Sstevel@tonic-gate #else 380Sstevel@tonic-gate #include <machdep.h> 391618Srie #include <rtld.h> 401169Srie #include <conv.h> 410Sstevel@tonic-gate #endif /* _KERNEL */ 420Sstevel@tonic-gate 430Sstevel@tonic-gate #include <relmach.h> 440Sstevel@tonic-gate 450Sstevel@tonic-gate #ifdef __cplusplus 460Sstevel@tonic-gate extern "C" { 470Sstevel@tonic-gate #endif 480Sstevel@tonic-gate 490Sstevel@tonic-gate /* 500Sstevel@tonic-gate * Global include file for relocation common code. 510Sstevel@tonic-gate * 520Sstevel@tonic-gate * Flags for reloc_entry->re_flags 530Sstevel@tonic-gate */ 540Sstevel@tonic-gate #define FLG_RE_NOTREL 0x00000000 550Sstevel@tonic-gate #define FLG_RE_GOTADD 0x00000001 /* create a GOT entry */ 560Sstevel@tonic-gate #define FLG_RE_GOTREL 0x00000002 /* GOT based */ 570Sstevel@tonic-gate #define FLG_RE_GOTPC 0x00000004 /* GOT - P */ 580Sstevel@tonic-gate #define FLG_RE_GOTOPINS 0x00000008 /* GOTOP instruction */ 590Sstevel@tonic-gate #define FLG_RE_PCREL 0x00000010 600Sstevel@tonic-gate #define FLG_RE_PLTREL 0x00000020 610Sstevel@tonic-gate #define FLG_RE_VERIFY 0x00000040 /* verify value fits */ 620Sstevel@tonic-gate #define FLG_RE_UNALIGN 0x00000080 /* offset is not aligned */ 630Sstevel@tonic-gate #define FLG_RE_WDISP16 0x00000100 /* funky sparc DISP16 rel */ 640Sstevel@tonic-gate #define FLG_RE_SIGN 0x00000200 /* value is signed */ 650Sstevel@tonic-gate #define FLG_RE_ADDRELATIVE 0x00000400 /* RELATIVE relocation */ 662145Srie /* required for non- */ 672145Srie /* fixed objects */ 680Sstevel@tonic-gate #define FLG_RE_EXTOFFSET 0x00000800 /* extra offset required */ 690Sstevel@tonic-gate #define FLG_RE_REGISTER 0x00001000 /* relocation initializes */ 700Sstevel@tonic-gate /* a REGISTER by OLO10 */ 712850Srie #define FLG_RE_SIZE 0x00002000 /* symbol size required */ 722850Srie 730Sstevel@tonic-gate #define FLG_RE_NOTSUP 0x00010000 /* relocation not supported */ 740Sstevel@tonic-gate 751169Srie #define FLG_RE_SEGREL 0x00040000 /* segment relative */ 761169Srie #define FLG_RE_SECREL 0x00080000 /* section relative */ 772145Srie 780Sstevel@tonic-gate #define FLG_RE_TLSGD 0x00200000 /* TLS GD relocation */ 790Sstevel@tonic-gate #define FLG_RE_TLSLD 0x00400000 /* TLS LD relocation */ 800Sstevel@tonic-gate #define FLG_RE_TLSIE 0x00800000 /* TLS IE relocation */ 810Sstevel@tonic-gate #define FLG_RE_TLSLE 0x01000000 /* TLS LE relocation */ 820Sstevel@tonic-gate #define FLG_RE_LOCLBND 0x02000000 /* relocation must bind */ 831169Srie /* locally */ 840Sstevel@tonic-gate 850Sstevel@tonic-gate /* 861618Srie * In user land, redefine the relocation table and relocation engine to be 871618Srie * class specific if necessary. This allows both engines to reside in the 881618Srie * intel/amd version of libld. 891618Srie */ 901618Srie #if !defined(_KERNEL) 911618Srie #if defined(_ELF64) 921618Srie #define do_reloc do64_reloc 931618Srie #define reloc_table reloc64_table 941618Srie #else 951618Srie #define do_reloc do32_reloc 961618Srie #define reloc_table reloc32_table 971618Srie #endif 981618Srie #endif 991618Srie 1001618Srie /* 1011618Srie * Relocation table and macros for testing relocation table flags. 1020Sstevel@tonic-gate */ 1030Sstevel@tonic-gate extern const Rel_entry reloc_table[]; 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate #define IS_PLT(X) ((reloc_table[(X)].re_flags & \ 1060Sstevel@tonic-gate FLG_RE_PLTREL) != 0) 1070Sstevel@tonic-gate #define IS_GOT_RELATIVE(X) ((reloc_table[(X)].re_flags & \ 1080Sstevel@tonic-gate FLG_RE_GOTADD) != 0) 1090Sstevel@tonic-gate #define IS_GOT_PC(X) ((reloc_table[(X)].re_flags & \ 1100Sstevel@tonic-gate FLG_RE_GOTPC) != 0) 1110Sstevel@tonic-gate #define IS_GOTPCREL(X) ((reloc_table[(X)].re_flags & \ 1120Sstevel@tonic-gate (FLG_RE_GOTPC | FLG_RE_GOTADD)) == \ 1130Sstevel@tonic-gate (FLG_RE_GOTPC | FLG_RE_GOTADD)) 1140Sstevel@tonic-gate #define IS_GOT_BASED(X) ((reloc_table[(X)].re_flags & \ 1150Sstevel@tonic-gate FLG_RE_GOTREL) != 0) 1163304Srie #define IS_GOT_OPINS(X) ((reloc_table[(X)].re_flags & \ 1170Sstevel@tonic-gate FLG_RE_GOTOPINS) != 0) 1181324Srie #define IS_GOT_REQUIRED(X) ((reloc_table[(X)].re_flags & \ 1191324Srie (FLG_RE_GOTADD | FLG_RE_GOTREL | \ 1201324Srie FLG_RE_GOTPC | FLG_RE_GOTOPINS)) != 0) 1210Sstevel@tonic-gate #define IS_PC_RELATIVE(X) ((reloc_table[(X)].re_flags & \ 1220Sstevel@tonic-gate FLG_RE_PCREL) != 0) 1230Sstevel@tonic-gate #define IS_ADD_RELATIVE(X) ((reloc_table[(X)].re_flags & \ 1240Sstevel@tonic-gate FLG_RE_ADDRELATIVE) != 0) 1250Sstevel@tonic-gate #define IS_REGISTER(X) ((reloc_table[(X)].re_flags & \ 1260Sstevel@tonic-gate FLG_RE_REGISTER) != 0) 1271618Srie #define IS_NOTSUP(X) ((reloc_table[(X)].re_flags & \ 1280Sstevel@tonic-gate FLG_RE_NOTSUP) != 0) 1291618Srie #define IS_SEG_RELATIVE(X) ((reloc_table[(X)].re_flags & \ 1300Sstevel@tonic-gate FLG_RE_SEGREL) != 0) 1311618Srie #define IS_EXTOFFSET(X) ((reloc_table[(X)].re_flags & \ 1320Sstevel@tonic-gate FLG_RE_EXTOFFSET) != 0) 1331618Srie #define IS_SEC_RELATIVE(X) ((reloc_table[(X)].re_flags & \ 1340Sstevel@tonic-gate FLG_RE_SECREL) != 0) 1351618Srie #define IS_TLS_INS(X) ((reloc_table[(X)].re_flags & \ 1362145Srie (FLG_RE_TLSGD | FLG_RE_TLSLD | \ 1372145Srie FLG_RE_TLSIE | FLG_RE_TLSLE)) != 0) 1381618Srie #define IS_TLS_GD(X) ((reloc_table[(X)].re_flags & \ 1390Sstevel@tonic-gate FLG_RE_TLSGD) != 0) 1401618Srie #define IS_TLS_LD(X) ((reloc_table[(X)].re_flags & \ 1410Sstevel@tonic-gate FLG_RE_TLSLD) != 0) 1421618Srie #define IS_TLS_IE(X) ((reloc_table[(X)].re_flags & \ 1430Sstevel@tonic-gate FLG_RE_TLSIE) != 0) 1441618Srie #define IS_TLS_LE(X) ((reloc_table[(X)].re_flags & \ 1450Sstevel@tonic-gate FLG_RE_TLSLE) != 0) 1461618Srie #define IS_LOCALBND(X) ((reloc_table[(X)].re_flags & \ 1470Sstevel@tonic-gate FLG_RE_LOCLBND) != 0) 1482850Srie #define IS_SIZE(X) ((reloc_table[(X)].re_flags &\ 1492850Srie FLG_RE_SIZE) != 0) 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate /* 1521618Srie * Relocation engine. 1530Sstevel@tonic-gate */ 1541169Srie extern int do_reloc(uchar_t, uchar_t *, Xword *, const char *, 1551618Srie const char *, void *); 1561169Srie 1570Sstevel@tonic-gate #if defined(_KERNEL) 1580Sstevel@tonic-gate /* 1591169Srie * These are macro's that are only needed for krtld. Many of these are already 1601169Srie * defined in the sgs/include files referenced by ld and rtld 1610Sstevel@tonic-gate */ 1620Sstevel@tonic-gate #define S_MASK(n) ((1l << (n)) - 1l) 1630Sstevel@tonic-gate #define S_INRANGE(v, n) (((-(1l << (n)) - 1l) < (v)) && ((v) < (1l << (n)))) 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate /* 1661169Srie * Message strings used by doreloc(). 1670Sstevel@tonic-gate */ 1681169Srie #define MSG_STR_UNKNOWN "(unknown)" 1691169Srie 1701169Srie #define MSG_REL_PREGEN "relocation error: %s: " 1711169Srie #define MSG_REL_PREFIL "relocation error: file %s: " 1721169Srie #define MSG_REL_FILE "file %s: " 1731169Srie #define MSG_REL_SYM "symbol %s: " 1741169Srie #define MSG_REL_VALUE "value 0x%llx " 1751169Srie #define MSG_REL_LOSEBITS "loses %d bits at " 1761169Srie 1771169Srie #define MSG_REL_UNIMPL "unimplemented relocation type: %d" 1781169Srie #define MSG_REL_UNSUPSZ "offset size (%d bytes) is not supported" 1791169Srie #define MSG_REL_NONALIGN "offset 0x%llx is non-aligned" 1801169Srie #define MSG_REL_UNNOBITS "unsupported number of bits: %d" 1811169Srie #define MSG_REL_OFFSET "offset 0x%llx" 1821169Srie #define MSG_REL_NOFIT "value 0x%llx does not fit" 1831169Srie 1841618Srie /* 1851618Srie * Provide a macro to select the appropriate conversion routine for this 1861618Srie * architecture. 1871618Srie */ 1881618Srie #if defined(__amd64) 1891618Srie 1901618Srie extern const char *conv_reloc_amd64_type(Word); 1911618Srie #define CONV_RELOC_TYPE conv_reloc_amd64_type 1921618Srie 1931618Srie #elif defined(__i386) 1941618Srie 1951618Srie extern const char *conv_reloc_386_type(Word); 1961618Srie #define CONV_RELOC_TYPE conv_reloc_386_type 1971618Srie 1981618Srie #elif defined(__sparc) 1991618Srie 2001618Srie extern const char *conv_reloc_SPARC_type(Word); 2011618Srie #define CONV_RELOC_TYPE conv_reloc_SPARC_type 2021618Srie 2031618Srie #else 2041618Srie #error platform not defined! 2051618Srie #endif 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate /* 2081618Srie * Note: dlerror() only keeps track of a single error string, and therefore 2091618Srie * must have errors reported through a single eprintf() call. The kernel's 2101618Srie * _kobj_printf is somewhat more limited, and must receive messages with only 2111618Srie * one argument to the format string. The following macros account for these 2121618Srie * differences, as krtld and rtld share do_reloc(). 2130Sstevel@tonic-gate */ 2141618Srie #define REL_ERR_UNIMPL(lml, file, sym, rtype) \ 2151169Srie _kobj_printf(ops, MSG_REL_PREFIL, (file)); \ 2161169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2171169Srie _kobj_printf(ops, MSG_REL_UNIMPL, (int)(rtype)) 2181169Srie 2191618Srie #define REL_ERR_UNSUPSZ(lml, file, sym, rtype, size) \ 2201169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2211169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2221169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2231169Srie _kobj_printf(ops, MSG_REL_UNSUPSZ, (int)(size)) 2240Sstevel@tonic-gate 2251618Srie #define REL_ERR_NONALIGN(lml, file, sym, rtype, off) \ 2261169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2271169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2281169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2291169Srie _kobj_printf(ops, MSG_REL_NONALIGN, EC_OFF((off))) 2300Sstevel@tonic-gate 2311618Srie #define REL_ERR_UNNOBITS(lml, file, sym, rtype, nbits) \ 2321169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2331169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2341169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2351169Srie _kobj_printf(ops, MSG_REL_UNNOBITS, (nbits)) 2360Sstevel@tonic-gate 2371618Srie #define REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, nbits, off) \ 2381169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2391169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2401169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2411169Srie _kobj_printf(ops, MSG_REL_VALUE, EC_XWORD((uvalue))); \ 2421169Srie _kobj_printf(ops, MSG_REL_LOSEBITS, (int)(nbits)); \ 2431618Srie _kobj_printf(ops, MSG_REL_OFFSET, EC_NATPTR((off))) 2440Sstevel@tonic-gate 2451618Srie #define REL_ERR_NOFIT(lml, file, sym, rtype, uvalue) \ 2461169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2471169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2481169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2491169Srie _kobj_printf(ops, MSG_REL_NOFIT, EC_XWORD((uvalue))) 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate #else /* !_KERNEL */ 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate extern const char *demangle(const char *); 2550Sstevel@tonic-gate 2561618Srie #define REL_ERR_UNIMPL(lml, file, sym, rtype) \ 2571618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNIMPL), (file), \ 2581169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (int)(rtype))) 2591169Srie 2601618Srie #define REL_ERR_UNSUPSZ(lml, file, sym, rtype, size) \ 2611618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ), \ 262*4734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2631169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (int)(size))) 2640Sstevel@tonic-gate 2651618Srie #define REL_ERR_NONALIGN(lml, file, sym, rtype, off) \ 2661618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NONALIGN), \ 267*4734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2681169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), EC_OFF((off)))) 2690Sstevel@tonic-gate 2701618Srie #define REL_ERR_UNNOBITS(lml, file, sym, rtype, nbits) \ 2711618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNNOBITS), \ 272*4734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2730Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (nbits))) 2740Sstevel@tonic-gate 2751618Srie #define REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, nbits, off) \ 2761618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_LOSEBITS), \ 277*4734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2780Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), \ 2791618Srie EC_XWORD((uvalue)), (nbits), EC_NATPTR((off)))) 2800Sstevel@tonic-gate 2811618Srie #define REL_ERR_NOFIT(lml, file, sym, rtype, uvalue) \ 2821618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOFIT), \ 283*4734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2840Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), \ 2850Sstevel@tonic-gate EC_XWORD((uvalue)))) 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate #endif /* _KERNEL */ 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate #ifdef __cplusplus 2900Sstevel@tonic-gate } 2910Sstevel@tonic-gate #endif 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate #endif /* _RELOC_DOT_H */ 294