The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sparc64/sparc64/elf_machdep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001 Jake Burkholder.
    3  * Copyright (c) 2000 Eduardo Horvath.
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Paul Kranenburg.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  *      from: NetBSD: mdreloc.c,v 1.42 2008/04/28 20:23:04 martin Exp
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD$");
   36 
   37 #include <sys/param.h>
   38 #include <sys/kernel.h>
   39 #include <sys/systm.h>
   40 #include <sys/exec.h>
   41 #include <sys/imgact.h>
   42 #include <sys/linker.h>
   43 #include <sys/proc.h>
   44 #include <sys/sysent.h>
   45 #include <sys/imgact_elf.h>
   46 #include <sys/syscall.h>
   47 #include <sys/signalvar.h>
   48 #include <sys/vnode.h>
   49 
   50 #include <vm/vm.h>
   51 #include <vm/vm_param.h>
   52 
   53 #include <machine/elf.h>
   54 
   55 #include "linker_if.h"
   56 
   57 static struct sysentvec elf64_freebsd_sysvec = {
   58         .sv_size        = SYS_MAXSYSCALL,
   59         .sv_table       = sysent,
   60         .sv_mask        = 0,
   61         .sv_sigsize     = 0,
   62         .sv_sigtbl      = NULL,
   63         .sv_errsize     = 0,
   64         .sv_errtbl      = NULL,
   65         .sv_transtrap   = NULL,
   66         .sv_fixup       = __elfN(freebsd_fixup),
   67         .sv_sendsig     = sendsig,
   68         .sv_sigcode     = NULL,
   69         .sv_szsigcode   = NULL,
   70         .sv_prepsyscall = NULL,
   71         .sv_name        = "FreeBSD ELF64",
   72         .sv_coredump    = __elfN(coredump),
   73         .sv_imgact_try  = NULL,
   74         .sv_minsigstksz = MINSIGSTKSZ,
   75         .sv_pagesize    = PAGE_SIZE,
   76         .sv_minuser     = VM_MIN_ADDRESS,
   77         .sv_maxuser     = VM_MAXUSER_ADDRESS,
   78         .sv_usrstack    = USRSTACK,
   79         .sv_psstrings   = PS_STRINGS,
   80         .sv_stackprot   = VM_PROT_READ | VM_PROT_WRITE,
   81         .sv_copyout_strings = exec_copyout_strings,
   82         .sv_setregs     = exec_setregs,
   83         .sv_fixlimit    = NULL,
   84         .sv_maxssiz     = NULL,
   85         .sv_flags       = SV_ABI_FREEBSD | SV_LP64,
   86         .sv_set_syscall_retval = cpu_set_syscall_retval,
   87         .sv_fetch_syscall_args = cpu_fetch_syscall_args,
   88         .sv_syscallnames = syscallnames,
   89         .sv_schedtail   = NULL,
   90 };
   91 
   92 static Elf64_Brandinfo freebsd_brand_info = {
   93         .brand          = ELFOSABI_FREEBSD,
   94         .machine        = EM_SPARCV9,
   95         .compat_3_brand = "FreeBSD",
   96         .emul_path      = NULL,
   97         .interp_path    = "/libexec/ld-elf.so.1",
   98         .sysvec         = &elf64_freebsd_sysvec,
   99         .interp_newpath = NULL,
  100         .brand_note     = &elf64_freebsd_brandnote,
  101         .flags          = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
  102 };
  103 
  104 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_FIRST,
  105     (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info);
  106 
  107 static Elf64_Brandinfo freebsd_brand_oinfo = {
  108         .brand          = ELFOSABI_FREEBSD,
  109         .machine        = EM_SPARCV9,
  110         .compat_3_brand = "FreeBSD",
  111         .emul_path      = NULL,
  112         .interp_path    = "/usr/libexec/ld-elf.so.1",
  113         .sysvec         = &elf64_freebsd_sysvec,
  114         .interp_newpath = NULL,
  115         .brand_note     = &elf64_freebsd_brandnote,
  116         .flags          = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
  117 };
  118 
  119 SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
  120     (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_oinfo);
  121 
  122 void
  123 elf64_dump_thread(struct thread *td __unused, void *dst __unused,
  124     size_t *off __unused)
  125 {
  126 
  127 }
  128 
  129 /*
  130  * The following table holds for each relocation type:
  131  *      - the width in bits of the memory location the relocation
  132  *        applies to (not currently used)
  133  *      - the number of bits the relocation value must be shifted to the
  134  *        right (i.e. discard least significant bits) to fit into
  135  *        the appropriate field in the instruction word.
  136  *      - flags indicating whether
  137  *              * the relocation involves a symbol
  138  *              * the relocation is relative to the current position
  139  *              * the relocation is for a GOT entry
  140  *              * the relocation is relative to the load address
  141  *
  142  */
  143 #define _RF_S           0x80000000              /* Resolve symbol */
  144 #define _RF_A           0x40000000              /* Use addend */
  145 #define _RF_P           0x20000000              /* Location relative */
  146 #define _RF_G           0x10000000              /* GOT offset */
  147 #define _RF_B           0x08000000              /* Load address relative */
  148 #define _RF_U           0x04000000              /* Unaligned */
  149 #define _RF_X           0x02000000              /* Bare symbols, needs proc */
  150 #define _RF_D           0x01000000              /* Use dynamic TLS offset */
  151 #define _RF_O           0x00800000              /* Use static TLS offset */
  152 #define _RF_I           0x00400000              /* Use TLS object ID */
  153 #define _RF_SZ(s)       (((s) & 0xff) << 8)     /* memory target size */
  154 #define _RF_RS(s)       ( (s) & 0xff)           /* right shift */
  155 static const int reloc_target_flags[] = {
  156         0,                                                      /* NONE */
  157         _RF_S|_RF_A|            _RF_SZ(8)  | _RF_RS(0),         /* 8 */
  158         _RF_S|_RF_A|            _RF_SZ(16) | _RF_RS(0),         /* 16 */
  159         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* 32 */
  160         _RF_S|_RF_A|_RF_P|      _RF_SZ(8)  | _RF_RS(0),         /* DISP_8 */
  161         _RF_S|_RF_A|_RF_P|      _RF_SZ(16) | _RF_RS(0),         /* DISP_16 */
  162         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(0),         /* DISP_32 */
  163         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* WDISP_30 */
  164         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* WDISP_22 */
  165         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(10),        /* HI22 */
  166         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 22 */
  167         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 13 */
  168         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* LO10 */
  169         _RF_G|                  _RF_SZ(32) | _RF_RS(0),         /* GOT10 */
  170         _RF_G|                  _RF_SZ(32) | _RF_RS(0),         /* GOT13 */
  171         _RF_G|                  _RF_SZ(32) | _RF_RS(10),        /* GOT22 */
  172         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(0),         /* PC10 */
  173         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(10),        /* PC22 */
  174               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* WPLT30 */
  175                                 _RF_SZ(32) | _RF_RS(0),         /* COPY */
  176         _RF_S|_RF_A|            _RF_SZ(64) | _RF_RS(0),         /* GLOB_DAT */
  177                                 _RF_SZ(32) | _RF_RS(0),         /* JMP_SLOT */
  178               _RF_A|    _RF_B|  _RF_SZ(64) | _RF_RS(0),         /* RELATIVE */
  179         _RF_S|_RF_A|    _RF_U|  _RF_SZ(32) | _RF_RS(0),         /* UA_32 */
  180 
  181               _RF_A|            _RF_SZ(32) | _RF_RS(0),         /* PLT32 */
  182               _RF_A|            _RF_SZ(32) | _RF_RS(10),        /* HIPLT22 */
  183               _RF_A|            _RF_SZ(32) | _RF_RS(0),         /* LOPLT10 */
  184               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(0),         /* PCPLT32 */
  185               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(10),        /* PCPLT22 */
  186               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(0),         /* PCPLT10 */
  187         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 10 */
  188         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 11 */
  189         _RF_S|_RF_A|_RF_X|      _RF_SZ(64) | _RF_RS(0),         /* 64 */
  190         _RF_S|_RF_A|/*extra*/   _RF_SZ(32) | _RF_RS(0),         /* OLO10 */
  191         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(42),        /* HH22 */
  192         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(32),        /* HM10 */
  193         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(10),        /* LM22 */
  194         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(42),        /* PC_HH22 */
  195         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(32),        /* PC_HM10 */
  196         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(10),        /* PC_LM22 */
  197         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* WDISP16 */
  198         _RF_S|_RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* WDISP19 */
  199         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* GLOB_JMP */
  200         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 7 */
  201         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 5 */
  202         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* 6 */
  203         _RF_S|_RF_A|_RF_P|      _RF_SZ(64) | _RF_RS(0),         /* DISP64 */
  204               _RF_A|            _RF_SZ(64) | _RF_RS(0),         /* PLT64 */
  205         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(10),        /* HIX22 */
  206         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* LOX10 */
  207         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(22),        /* H44 */
  208         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(12),        /* M44 */
  209         _RF_S|_RF_A|_RF_X|      _RF_SZ(32) | _RF_RS(0),         /* L44 */
  210         _RF_S|_RF_A|            _RF_SZ(64) | _RF_RS(0),         /* REGISTER */
  211         _RF_S|_RF_A|    _RF_U|  _RF_SZ(64) | _RF_RS(0),         /* UA64 */
  212         _RF_S|_RF_A|    _RF_U|  _RF_SZ(16) | _RF_RS(0),         /* UA16 */
  213 
  214 #if 0
  215         /* TLS */
  216         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(10),        /* GD_HI22 */
  217         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* GD_LO10 */
  218         0,                                                      /* GD_ADD */
  219               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* GD_CALL */
  220         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(10),        /* LDM_HI22 */
  221         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* LDM_LO10 */
  222         0,                                                      /* LDM_ADD */
  223               _RF_A|_RF_P|      _RF_SZ(32) | _RF_RS(2),         /* LDM_CALL */
  224         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(10),        /* LDO_HIX22 */
  225         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* LDO_LOX10 */
  226         0,                                                      /* LDO_ADD */
  227         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(10),        /* IE_HI22 */
  228         _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* IE_LO10 */
  229         0,                                                      /* IE_LD */
  230         0,                                                      /* IE_LDX */
  231         0,                                                      /* IE_ADD */
  232         _RF_S|_RF_A|    _RF_O|  _RF_SZ(32) | _RF_RS(10),        /* LE_HIX22 */
  233         _RF_S|_RF_A|    _RF_O|  _RF_SZ(32) | _RF_RS(0),         /* LE_LOX10 */
  234         _RF_S|          _RF_I|  _RF_SZ(32) | _RF_RS(0),         /* DTPMOD32 */
  235         _RF_S|          _RF_I|  _RF_SZ(64) | _RF_RS(0),         /* DTPMOD64 */
  236         _RF_S|_RF_A|    _RF_D|  _RF_SZ(32) | _RF_RS(0),         /* DTPOFF32 */
  237         _RF_S|_RF_A|    _RF_D|  _RF_SZ(64) | _RF_RS(0),         /* DTPOFF64 */
  238         _RF_S|_RF_A|    _RF_O|  _RF_SZ(32) | _RF_RS(0),         /* TPOFF32 */
  239         _RF_S|_RF_A|    _RF_O|  _RF_SZ(64) | _RF_RS(0)          /* TPOFF64 */
  240 #endif
  241 };
  242 
  243 #if 0
  244 static const char *const reloc_names[] = {
  245         "NONE", "8", "16", "32", "DISP_8", "DISP_16", "DISP_32", "WDISP_30",
  246         "WDISP_22", "HI22", "22", "13", "LO10", "GOT10", "GOT13", "GOT22",
  247         "PC10", "PC22", "WPLT30", "COPY", "GLOB_DAT", "JMP_SLOT", "RELATIVE",
  248         "UA_32", "PLT32", "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22",
  249         "PCPLT32", "10", "11", "64", "OLO10", "HH22", "HM10", "LM22",
  250         "PC_HH22", "PC_HM10", "PC_LM22", "WDISP16", "WDISP19", "GLOB_JMP",
  251         "7", "5", "6", "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44",
  252         "L44", "REGISTER", "UA64", "UA16", "GD_HI22", "GD_LO10", "GD_ADD",
  253         "GD_CALL", "LDM_HI22", "LDMO10", "LDM_ADD", "LDM_CALL", "LDO_HIX22",
  254         "LDO_LOX10", "LDO_ADD", "IE_HI22", "IE_LO10", "IE_LD", "IE_LDX",
  255         "IE_ADD", "LE_HIX22", "LE_LOX10", "DTPMOD32", "DTPMOD64", "DTPOFF32",
  256         "DTPOFF64", "TPOFF32", "TPOFF64"
  257 };
  258 #endif
  259 
  260 #define RELOC_RESOLVE_SYMBOL(t)         ((reloc_target_flags[t] & _RF_S) != 0)
  261 #define RELOC_PC_RELATIVE(t)            ((reloc_target_flags[t] & _RF_P) != 0)
  262 #define RELOC_BASE_RELATIVE(t)          ((reloc_target_flags[t] & _RF_B) != 0)
  263 #define RELOC_UNALIGNED(t)              ((reloc_target_flags[t] & _RF_U) != 0)
  264 #define RELOC_USE_ADDEND(t)             ((reloc_target_flags[t] & _RF_A) != 0)
  265 #define RELOC_BARE_SYMBOL(t)            ((reloc_target_flags[t] & _RF_X) != 0)
  266 #define RELOC_USE_TLS_DOFF(t)           ((reloc_target_flags[t] & _RF_D) != 0)
  267 #define RELOC_USE_TLS_OFF(t)            ((reloc_target_flags[t] & _RF_O) != 0)
  268 #define RELOC_USE_TLS_ID(t)             ((reloc_target_flags[t] & _RF_I) != 0)
  269 #define RELOC_TARGET_SIZE(t)            ((reloc_target_flags[t] >> 8) & 0xff)
  270 #define RELOC_VALUE_RIGHTSHIFT(t)       (reloc_target_flags[t] & 0xff)
  271 
  272 static const long reloc_target_bitmask[] = {
  273 #define _BM(x)  (~(-(1ULL << (x))))
  274         0,                              /* NONE */
  275         _BM(8), _BM(16), _BM(32),       /* 8, 16, 32 */
  276         _BM(8), _BM(16), _BM(32),       /* DISP8, DISP16, DISP32 */
  277         _BM(30), _BM(22),               /* WDISP30, WDISP22 */
  278         _BM(22), _BM(22),               /* HI22, 22 */
  279         _BM(13), _BM(10),               /* 13, LO10 */
  280         _BM(10), _BM(13), _BM(22),      /* GOT10, GOT13, GOT22 */
  281         _BM(10), _BM(22),               /* PC10, PC22 */
  282         _BM(30), 0,                     /* WPLT30, COPY */
  283         _BM(32), _BM(32), _BM(32),      /* GLOB_DAT, JMP_SLOT, RELATIVE */
  284         _BM(32), _BM(32),               /* UA32, PLT32 */
  285         _BM(22), _BM(10),               /* HIPLT22, LOPLT10 */
  286         _BM(32), _BM(22), _BM(10),      /* PCPLT32, PCPLT22, PCPLT10 */
  287         _BM(10), _BM(11), -1,           /* 10, 11, 64 */
  288         _BM(13), _BM(22),               /* OLO10, HH22 */
  289         _BM(10), _BM(22),               /* HM10, LM22 */
  290         _BM(22), _BM(10), _BM(22),      /* PC_HH22, PC_HM10, PC_LM22 */
  291         _BM(16), _BM(19),               /* WDISP16, WDISP19 */
  292         -1,                             /* GLOB_JMP */
  293         _BM(7), _BM(5), _BM(6),         /* 7, 5, 6 */
  294         -1, -1,                         /* DISP64, PLT64 */
  295         _BM(22), _BM(13),               /* HIX22, LOX10 */
  296         _BM(22), _BM(10), _BM(13),      /* H44, M44, L44 */
  297         -1, -1, _BM(16),                /* REGISTER, UA64, UA16 */
  298 #if 0
  299         _BM(22), _BM(10), 0, _BM(30),   /* GD_HI22, GD_LO10, GD_ADD, GD_CALL */
  300         _BM(22), _BM(10), 0,            /* LDM_HI22, LDMO10, LDM_ADD */
  301         _BM(30),                        /* LDM_CALL */
  302         _BM(22), _BM(10), 0,            /* LDO_HIX22, LDO_LOX10, LDO_ADD */
  303         _BM(22), _BM(10), 0, 0,         /* IE_HI22, IE_LO10, IE_LD, IE_LDX */
  304         0,                              /* IE_ADD */
  305         _BM(22), _BM(13),               /* LE_HIX22, LE_LOX10 */
  306         _BM(32), -1,                    /* DTPMOD32, DTPMOD64 */
  307         _BM(32), -1,                    /* DTPOFF32, DTPOFF64 */
  308         _BM(32), -1                     /* TPOFF32, TPOFF64 */
  309 #endif
  310 #undef _BM
  311 };
  312 #define RELOC_VALUE_BITMASK(t)  (reloc_target_bitmask[t])
  313 
  314 int
  315 elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
  316     int type, elf_lookup_fn lookup __unused)
  317 {
  318         const Elf_Rela *rela;
  319         Elf_Addr *where;
  320 
  321         if (type != ELF_RELOC_RELA)
  322                 return (-1);
  323 
  324         rela = (const Elf_Rela *)data;
  325         if (ELF64_R_TYPE_ID(rela->r_info) != R_SPARC_RELATIVE)
  326                 return (-1);
  327 
  328         where = (Elf_Addr *)(relocbase + rela->r_offset);
  329         *where = elf_relocaddr(lf, rela->r_addend + relocbase);
  330 
  331         return (0);
  332 }
  333 
  334 /* Process one elf relocation with addend. */
  335 int
  336 elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
  337     elf_lookup_fn lookup)
  338 {
  339         const Elf_Rela *rela;
  340         Elf_Word *where32;
  341         Elf_Addr *where;
  342         Elf_Size rtype, symidx;
  343         Elf_Addr value;
  344         Elf_Addr mask;
  345         Elf_Addr addr;
  346 
  347         if (type != ELF_RELOC_RELA)
  348                 return (-1);
  349 
  350         rela = (const Elf_Rela *)data;
  351         where = (Elf_Addr *)(relocbase + rela->r_offset);
  352         where32 = (Elf_Word *)where;
  353         rtype = ELF64_R_TYPE_ID(rela->r_info);
  354         symidx = ELF_R_SYM(rela->r_info);
  355 
  356         if (rtype == R_SPARC_NONE || rtype == R_SPARC_RELATIVE)
  357                 return (0);
  358 
  359         if (rtype == R_SPARC_JMP_SLOT || rtype == R_SPARC_COPY ||
  360             rtype >= sizeof(reloc_target_bitmask) /
  361             sizeof(*reloc_target_bitmask)) {
  362                 printf("kldload: unexpected relocation type %ld\n", rtype);
  363                 return (-1);
  364         }
  365 
  366         if (RELOC_UNALIGNED(rtype)) {
  367                 printf("kldload: unaligned relocation type %ld\n", rtype);
  368                 return (-1);
  369         }
  370 
  371         value = rela->r_addend;
  372 
  373         if (RELOC_RESOLVE_SYMBOL(rtype)) {
  374                 addr = lookup(lf, symidx, 1);
  375                 if (addr == 0)
  376                         return (-1);
  377                 value += addr;
  378                 if (RELOC_BARE_SYMBOL(rtype))
  379                         value = elf_relocaddr(lf, value);
  380         }
  381 
  382         if (rtype == R_SPARC_OLO10)
  383                 value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
  384 
  385         if (rtype == R_SPARC_HIX22)
  386                 value ^= 0xffffffffffffffff;
  387 
  388         if (RELOC_PC_RELATIVE(rtype))
  389                 value -= (Elf_Addr)where;
  390 
  391         if (RELOC_BASE_RELATIVE(rtype))
  392                 value = elf_relocaddr(lf, value + relocbase);
  393 
  394         mask = RELOC_VALUE_BITMASK(rtype);
  395         value >>= RELOC_VALUE_RIGHTSHIFT(rtype);
  396         value &= mask;
  397 
  398         if (rtype == R_SPARC_LOX10)
  399                 value |= 0x1c00;
  400 
  401         if (RELOC_TARGET_SIZE(rtype) > 32) {
  402                 *where &= ~mask;
  403                 *where |= value;
  404         } else {
  405                 *where32 &= ~mask;
  406                 *where32 |= value;
  407         }
  408 
  409         return (0);
  410 }
  411 
  412 int
  413 elf_cpu_load_file(linker_file_t lf __unused)
  414 {
  415 
  416         return (0);
  417 }
  418 
  419 int
  420 elf_cpu_unload_file(linker_file_t lf __unused)
  421 {
  422 
  423         return (0);
  424 }

Cache object: c1feff6b011ce05f4c443660b92e3285


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.