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*12155SAli.Bahrami@Sun.COM * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _RELOC_DOT_H 270Sstevel@tonic-gate #define _RELOC_DOT_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #if defined(_KERNEL) 300Sstevel@tonic-gate #include <sys/bootconf.h> 310Sstevel@tonic-gate #include <sys/kobj.h> 320Sstevel@tonic-gate #include <sys/kobj_impl.h> 330Sstevel@tonic-gate #else 341618Srie #include <rtld.h> 351169Srie #include <conv.h> 360Sstevel@tonic-gate #endif /* _KERNEL */ 370Sstevel@tonic-gate 386206Sab196087 #include "reloc_defs.h" 390Sstevel@tonic-gate 400Sstevel@tonic-gate #ifdef __cplusplus 410Sstevel@tonic-gate extern "C" { 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * Global include file for relocation common code. 460Sstevel@tonic-gate */ 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 491618Srie * In user land, redefine the relocation table and relocation engine to be 506206Sab196087 * class/machine specific if necessary. This allows multiple engines to 516206Sab196087 * reside within a single instance of libld. 521618Srie */ 531618Srie #if !defined(_KERNEL) 546206Sab196087 556206Sab196087 #if defined(DO_RELOC_LIBLD) 566206Sab196087 #undef DO_RELOC_LIBLD 576206Sab196087 #endif 586206Sab196087 596206Sab196087 #if defined(DO_RELOC_LIBLD_X86) 606206Sab196087 616206Sab196087 #define DO_RELOC_LIBLD 621618Srie #if defined(_ELF64) 636206Sab196087 #define do_reloc_ld do64_reloc_ld_x86 646206Sab196087 #define reloc_table reloc64_table_x86 656206Sab196087 #else 666206Sab196087 #define do_reloc_ld do32_reloc_ld_x86 676206Sab196087 #define reloc_table reloc32_table_x86 686206Sab196087 #endif 696206Sab196087 706206Sab196087 #elif defined(DO_RELOC_LIBLD_SPARC) 716206Sab196087 726206Sab196087 #define DO_RELOC_LIBLD 736206Sab196087 #if defined(_ELF64) 746206Sab196087 #define do_reloc_ld do64_reloc_ld_sparc 756206Sab196087 #define reloc_table reloc64_table_sparc 766206Sab196087 #else 776206Sab196087 #define do_reloc_ld do32_reloc_ld_sparc 786206Sab196087 #define reloc_table reloc32_table_sparc 796206Sab196087 #endif 806206Sab196087 816206Sab196087 #else /* rtld */ 826206Sab196087 836206Sab196087 #if defined(_ELF64) 845189Sab196087 #define do_reloc_rtld do64_reloc_rtld 851618Srie #define reloc_table reloc64_table 861618Srie #else 875189Sab196087 #define do_reloc_rtld do32_reloc_rtld 881618Srie #define reloc_table reloc32_table 891618Srie #endif 906206Sab196087 911618Srie #endif 921618Srie 936206Sab196087 #endif /* !_KERNEL */ 946206Sab196087 951618Srie /* 961618Srie * Relocation table and macros for testing relocation table flags. 970Sstevel@tonic-gate */ 986206Sab196087 extern const Rel_entry reloc_table[]; 990Sstevel@tonic-gate 1006206Sab196087 #define IS_PLT(X) RELTAB_IS_PLT(X, reloc_table) 1016206Sab196087 #define IS_GOT_RELATIVE(X) RELTAB_IS_GOT_RELATIVE(X, reloc_table) 1026206Sab196087 #define IS_GOT_PC(X) RELTAB_IS_GOT_PC(X, reloc_table) 1036206Sab196087 #define IS_GOTPCREL(X) RELTAB_IS_GOTPCREL(X, reloc_table) 1046206Sab196087 #define IS_GOT_BASED(X) RELTAB_IS_GOT_BASED(X, reloc_table) 1056206Sab196087 #define IS_GOT_OPINS(X) RELTAB_IS_GOT_OPINS(X, reloc_table) 1066206Sab196087 #define IS_GOT_REQUIRED(X) RELTAB_IS_GOT_REQUIRED(X, reloc_table) 1076206Sab196087 #define IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, reloc_table) 1086206Sab196087 #define IS_ADD_RELATIVE(X) RELTAB_IS_ADD_RELATIVE(X, reloc_table) 1096206Sab196087 #define IS_REGISTER(X) RELTAB_IS_REGISTER(X, reloc_table) 1106206Sab196087 #define IS_NOTSUP(X) RELTAB_IS_NOTSUP(X, reloc_table) 1116206Sab196087 #define IS_SEG_RELATIVE(X) RELTAB_IS_SEG_RELATIVE(X, reloc_table) 1126206Sab196087 #define IS_EXTOFFSET(X) RELTAB_IS_EXTOFFSET(X, reloc_table) 1136206Sab196087 #define IS_SEC_RELATIVE(X) RELTAB_IS_SEC_RELATIVE(X, reloc_table) 1146206Sab196087 #define IS_TLS_INS(X) RELTAB_IS_TLS_INS(X, reloc_table) 1156206Sab196087 #define IS_TLS_GD(X) RELTAB_IS_TLS_GD(X, reloc_table) 1166206Sab196087 #define IS_TLS_LD(X) RELTAB_IS_TLS_LD(X, reloc_table) 1176206Sab196087 #define IS_TLS_IE(X) RELTAB_IS_TLS_IE(X, reloc_table) 1186206Sab196087 #define IS_TLS_LE(X) RELTAB_IS_TLS_LE(X, reloc_table) 1196206Sab196087 #define IS_LOCALBND(X) RELTAB_IS_LOCALBND(X, reloc_table) 1206206Sab196087 #define IS_SIZE(X) RELTAB_IS_SIZE(X, reloc_table) 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate /* 1231618Srie * Relocation engine. 1245189Sab196087 * 1255189Sab196087 * The do_reloc() code is used in three different places: The kernel, 126*12155SAli.Bahrami@Sun.COM * the link-editor, and the runtime linker. All three convey the same 127*12155SAli.Bahrami@Sun.COM * basic information with the first 5 arguments: 128*12155SAli.Bahrami@Sun.COM * 129*12155SAli.Bahrami@Sun.COM * 1) Relocation type. The kernel and runtime linker pass this as 130*12155SAli.Bahrami@Sun.COM * an integer value, while the link-editor passes it as a Rel_desc 131*12155SAli.Bahrami@Sun.COM * descriptor. The relocation engine only looks at the rel_rtype 132*12155SAli.Bahrami@Sun.COM * field of this descriptor, and does not examine the other fields, 133*12155SAli.Bahrami@Sun.COM * which are explicitly allowed to contain garbage. 134*12155SAli.Bahrami@Sun.COM * 2) Address of offset 135*12155SAli.Bahrami@Sun.COM * 3) Address of value 136*12155SAli.Bahrami@Sun.COM * 4) Name of symbol associated with the relocation, used if it is 137*12155SAli.Bahrami@Sun.COM * necessary to report an error. The kernel and runtime linker pass 138*12155SAli.Bahrami@Sun.COM * directly as a string pointer. The link-editor passes the address 139*12155SAli.Bahrami@Sun.COM * of a rel_desc_sname_func_t function, which can be called by do_reloc(), 140*12155SAli.Bahrami@Sun.COM * passing it the Rel_desc pointer (argument 1, above), to obtain the 141*12155SAli.Bahrami@Sun.COM * string pointer. 142*12155SAli.Bahrami@Sun.COM * 5) String giving the source file for the relocation. 143*12155SAli.Bahrami@Sun.COM * 144*12155SAli.Bahrami@Sun.COM * In addition: 1455189Sab196087 * - The linker and rtld want a link map pointer argument 1465189Sab196087 * - The linker wants to pass a byte swap argument that tells 1475189Sab196087 * the relocation engine that the data it is relocating 1485189Sab196087 * has the opposite byte order of the system running the 1495189Sab196087 * linker. 1506206Sab196087 * - The linker is a cross-linker, meaning that it can examine 1516206Sab196087 * relocation records for target hosts other than that of 1526206Sab196087 * the currently running system. This means that multiple 1536206Sab196087 * versions of the relocation code must be able to reside 1546206Sab196087 * in a single program, without namespace clashes. 1555189Sab196087 * 1565189Sab196087 * To ensure that there is never any confusion about which version is 1575189Sab196087 * being linked to, we give each variant a different name, even though 1585189Sab196087 * each one is generated from the same source code. 1595189Sab196087 * 1605189Sab196087 * do_reloc_krtld() 1615189Sab196087 * The kernel version is provided if the _KERNEL macro is defined. 1625189Sab196087 * 1635189Sab196087 * do_reloc_ld() 1646206Sab196087 * The ld version is provided if the DO_RELOC_LIBLD_ macro is defined. 1655189Sab196087 * 1665189Sab196087 * do_reloc_rtld() 1675189Sab196087 * The rtld version is provided if neither _KERNEL or DO_RELOC_LIBLD 1685189Sab196087 * are defined. 1695189Sab196087 * 1705189Sab196087 * Implementations of do_reloc() should use these same macros to 1715189Sab196087 * conditionalize any code not used by all three versions. 1720Sstevel@tonic-gate */ 1735189Sab196087 #if defined(_KERNEL) 1745189Sab196087 extern int do_reloc_krtld(uchar_t, uchar_t *, Xword *, const char *, 1755189Sab196087 const char *); 1765189Sab196087 #elif defined(DO_RELOC_LIBLD) 177*12155SAli.Bahrami@Sun.COM extern int do_reloc_ld(Rel_desc *, uchar_t *, Xword *, 178*12155SAli.Bahrami@Sun.COM rel_desc_sname_func_t, const char *, int, void *); 1795189Sab196087 #else 1805189Sab196087 extern int do_reloc_rtld(uchar_t, uchar_t *, Xword *, const char *, 1811618Srie const char *, void *); 1825189Sab196087 #endif 1831169Srie 1840Sstevel@tonic-gate #if defined(_KERNEL) 1850Sstevel@tonic-gate /* 1861169Srie * These are macro's that are only needed for krtld. Many of these are already 1871169Srie * defined in the sgs/include files referenced by ld and rtld 1880Sstevel@tonic-gate */ 1890Sstevel@tonic-gate #define S_MASK(n) ((1l << (n)) - 1l) 1900Sstevel@tonic-gate #define S_INRANGE(v, n) (((-(1l << (n)) - 1l) < (v)) && ((v) < (1l << (n)))) 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate /* 1931169Srie * Message strings used by doreloc(). 1940Sstevel@tonic-gate */ 1951169Srie #define MSG_STR_UNKNOWN "(unknown)" 1961169Srie 1971169Srie #define MSG_REL_PREGEN "relocation error: %s: " 1981169Srie #define MSG_REL_PREFIL "relocation error: file %s: " 1991169Srie #define MSG_REL_FILE "file %s: " 2001169Srie #define MSG_REL_SYM "symbol %s: " 2011169Srie #define MSG_REL_VALUE "value 0x%llx " 2021169Srie #define MSG_REL_LOSEBITS "loses %d bits at " 2031169Srie 2041169Srie #define MSG_REL_UNIMPL "unimplemented relocation type: %d" 2051169Srie #define MSG_REL_UNSUPSZ "offset size (%d bytes) is not supported" 2061169Srie #define MSG_REL_NONALIGN "offset 0x%llx is non-aligned" 2071169Srie #define MSG_REL_UNNOBITS "unsupported number of bits: %d" 2081169Srie #define MSG_REL_OFFSET "offset 0x%llx" 2091169Srie #define MSG_REL_NOFIT "value 0x%llx does not fit" 2101169Srie 2111618Srie /* 2121618Srie * Provide a macro to select the appropriate conversion routine for this 2131618Srie * architecture. 2141618Srie */ 2151618Srie #if defined(__amd64) 2161618Srie 2171618Srie extern const char *conv_reloc_amd64_type(Word); 2181618Srie #define CONV_RELOC_TYPE conv_reloc_amd64_type 2191618Srie 2201618Srie #elif defined(__i386) 2211618Srie 2221618Srie extern const char *conv_reloc_386_type(Word); 2231618Srie #define CONV_RELOC_TYPE conv_reloc_386_type 2241618Srie 2251618Srie #elif defined(__sparc) 2261618Srie 2271618Srie extern const char *conv_reloc_SPARC_type(Word); 2281618Srie #define CONV_RELOC_TYPE conv_reloc_SPARC_type 2291618Srie 2301618Srie #else 2311618Srie #error platform not defined! 2321618Srie #endif 2330Sstevel@tonic-gate 2346206Sab196087 2350Sstevel@tonic-gate /* 2361618Srie * Note: dlerror() only keeps track of a single error string, and therefore 2371618Srie * must have errors reported through a single eprintf() call. The kernel's 2381618Srie * _kobj_printf is somewhat more limited, and must receive messages with only 2391618Srie * one argument to the format string. The following macros account for these 2405189Sab196087 * differences, as krtld and rtld share the same do_reloc() source. 2410Sstevel@tonic-gate */ 2421618Srie #define REL_ERR_UNIMPL(lml, file, sym, rtype) \ 2431169Srie _kobj_printf(ops, MSG_REL_PREFIL, (file)); \ 2441169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2451169Srie _kobj_printf(ops, MSG_REL_UNIMPL, (int)(rtype)) 2461169Srie 2471618Srie #define REL_ERR_UNSUPSZ(lml, file, sym, rtype, size) \ 2481169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2491169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2501169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2511169Srie _kobj_printf(ops, MSG_REL_UNSUPSZ, (int)(size)) 2520Sstevel@tonic-gate 2531618Srie #define REL_ERR_NONALIGN(lml, file, sym, rtype, off) \ 2541169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2551169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2561169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2571169Srie _kobj_printf(ops, MSG_REL_NONALIGN, EC_OFF((off))) 2580Sstevel@tonic-gate 2591618Srie #define REL_ERR_UNNOBITS(lml, file, sym, rtype, nbits) \ 2601169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2611169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2621169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2631169Srie _kobj_printf(ops, MSG_REL_UNNOBITS, (nbits)) 2640Sstevel@tonic-gate 2651618Srie #define REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, nbits, off) \ 2661169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2671169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2681169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2691169Srie _kobj_printf(ops, MSG_REL_VALUE, EC_XWORD((uvalue))); \ 2701169Srie _kobj_printf(ops, MSG_REL_LOSEBITS, (int)(nbits)); \ 2711618Srie _kobj_printf(ops, MSG_REL_OFFSET, EC_NATPTR((off))) 2720Sstevel@tonic-gate 2731618Srie #define REL_ERR_NOFIT(lml, file, sym, rtype, uvalue) \ 2741169Srie _kobj_printf(ops, MSG_REL_PREGEN, CONV_RELOC_TYPE((rtype))); \ 2751169Srie _kobj_printf(ops, MSG_REL_FILE, (file)); \ 2761169Srie _kobj_printf(ops, MSG_REL_SYM, ((sym) ? (sym) : MSG_STR_UNKNOWN)); \ 2771169Srie _kobj_printf(ops, MSG_REL_NOFIT, EC_XWORD((uvalue))) 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate #else /* !_KERNEL */ 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate extern const char *demangle(const char *); 2830Sstevel@tonic-gate 2841618Srie #define REL_ERR_UNIMPL(lml, file, sym, rtype) \ 2851618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNIMPL), (file), \ 2861169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (int)(rtype))) 2871169Srie 2881618Srie #define REL_ERR_UNSUPSZ(lml, file, sym, rtype, size) \ 2891618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ), \ 2904734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2911169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (int)(size))) 2920Sstevel@tonic-gate 2931618Srie #define REL_ERR_NONALIGN(lml, file, sym, rtype, off) \ 2941618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NONALIGN), \ 2954734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 2961169Srie ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), EC_OFF((off)))) 2970Sstevel@tonic-gate 2981618Srie #define REL_ERR_UNNOBITS(lml, file, sym, rtype, nbits) \ 2991618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNNOBITS), \ 3004734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 3010Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), (nbits))) 3020Sstevel@tonic-gate 3031618Srie #define REL_ERR_LOSEBITS(lml, file, sym, rtype, uvalue, nbits, off) \ 3041618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_LOSEBITS), \ 3054734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 3060Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), \ 3071618Srie EC_XWORD((uvalue)), (nbits), EC_NATPTR((off)))) 3080Sstevel@tonic-gate 3091618Srie #define REL_ERR_NOFIT(lml, file, sym, rtype, uvalue) \ 3101618Srie (eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOFIT), \ 3114734Sab196087 conv_reloc_type_static(M_MACH, (rtype), 0), (file), \ 3120Sstevel@tonic-gate ((sym) ? demangle(sym) : MSG_INTL(MSG_STR_UNKNOWN)), \ 3130Sstevel@tonic-gate EC_XWORD((uvalue)))) 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate #endif /* _KERNEL */ 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate #ifdef __cplusplus 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate #endif 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate #endif /* _RELOC_DOT_H */ 322