diff options
Diffstat (limited to 'usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c')
| -rw-r--r-- | usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c deleted file mode 100644 index d56e79a209..0000000000 --- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 1988 AT&T - * All Rights Reserved - * - * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* - * SPARC machine dependent and a.out format file class dependent functions. - * Contains routines for performing function binding and symbol relocations. - */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <synch.h> -#include <dlfcn.h> -#include <debug.h> -#include "_a.out.h" -#include "_rtld.h" -#include "_audit.h" -#include "_inline_gen.h" -#include "msg.h" - -extern void iflush_range(caddr_t, size_t); - -/* - * Function binding routine - invoked on the first call to a function through - * the procedure linkage table; - * passes first through an assembly language interface. - * - * Takes the address of the PLT entry where the call originated, - * the offset into the relocation table of the associated - * relocation entry and the address of the link map (rt_private_map struct) - * for the entry. - * - * Returns the address of the function referenced after re-writing the PLT - * entry to invoke the function directly. - * - * On error, causes process to terminate with a signal. - */ -ulong_t -aout_bndr(caddr_t pc) -{ - Rt_map *lmp, *nlmp, *llmp; - struct relocation_info *rp; - struct nlist *sp; - Sym *sym; - char *name; - int rndx, entry; - ulong_t symval; - Slookup sl; - Sresult sr; - uint_t binfo; - Lm_list *lml; - - /* - * For compatibility with libthread (TI_VERSION 1) we track the entry - * value. A zero value indicates we have recursed into ld.so.1 to - * further process a locking request (see comments in completion()). - * Under this recursion we disable tsort and cleanup activities. - */ - entry = enter(0); - - for (lmp = lml_main.lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) { - if (THIS_IS_AOUT(lmp)) { - if (pc > (caddr_t)(LM2LP(lmp)->lp_plt) && - pc < (caddr_t)((int)LM2LP(lmp)->lp_plt + - AOUTDYN(lmp)->v2->ld_plt_sz)) { - break; - } - } - } - -#define LAST22BITS 0x3fffff - - /* LINTED */ - rndx = *(int *)(pc + (sizeof (ulong_t *) * 2)) & LAST22BITS; - rp = &LM2LP(lmp)->lp_rp[rndx]; - sp = &LM2LP(lmp)->lp_symtab[rp->r_symbolnum]; - name = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx]; - - /* - * Determine the last link-map of this list, this'll be the starting - * point for any tsort() processing. - */ - lml = LIST(lmp); - llmp = lml->lm_tail; - - /* - * Find definition for symbol. Initialize the symbol lookup data - * structure. - */ - SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0, 0, 0, 0, - LKUP_DEFT); - SRESULT_INIT(sr, name); - - if (aout_lookup_sym(&sl, &sr, &binfo, NULL) == 0) { - eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp), - demangle(name)); - rtldexit(lml, 1); - } - - name = (char *)sr.sr_name; - nlmp = sr.sr_dmap; - sym = sr.sr_sym; - - symval = sym->st_value; - - if (!(FLAGS(nlmp) & FLG_RT_FIXED) && - (sym->st_shndx != SHN_ABS)) - symval += (int)(ADDR(nlmp)); - if ((lmp != nlmp) && ((FLAGS1(nlmp) & FL1_RT_NOINIFIN) == 0)) { - /* - * Record that this new link map is now bound to the caller. - */ - if (bind_one(lmp, nlmp, BND_REFER) == 0) - rtldexit(lml, 1); - } - - /* - * Print binding information and rebuild PLT entry. - */ - DBG_CALL(Dbg_bind_global(lmp, (Addr)(ADDR(lmp) + rp->r_address), - (Off)rp->r_address, (Xword)(-1), PLT_T_NONE, nlmp, - (Addr)symval, sym->st_value, name, binfo)); - - if (!(rtld_flags & RT_FL_NOBIND)) - aout_plt_write((caddr_t)(ADDR(lmp) + rp->r_address), symval); - - /* - * Complete any processing for newly loaded objects. Note we don't - * know exactly where any new objects are loaded (we know the object - * that supplied the symbol, but others may have been loaded lazily as - * we searched for the symbol), so sorting starts from the last - * link-map know on entry to this routine. - */ - if (entry) - load_completion(llmp); - - /* - * Make sure the object to which we've bound has had it's .init fired. - * Cleanup before return to user code. - */ - if (entry) { - is_dep_init(nlmp, lmp); - leave(lml, 0); - } - - return (symval); -} - - -#define IS_PC_RELATIVE(X) (pc_rel_type[(X)] == 1) - -static const uchar_t pc_rel_type[] = { - 0, /* RELOC_8 */ - 0, /* RELOC_16 */ - 0, /* RELOC_32 */ - 1, /* RELOC_DISP8 */ - 1, /* RELOC_DISP16 */ - 1, /* RELOC_DISP32 */ - 1, /* RELOC_WDISP30 */ - 1, /* RELOC_WDISP22 */ - 0, /* RELOC_HI22 */ - 0, /* RELOC_22 */ - 0, /* RELOC_13 */ - 0, /* RELOC_LO10 */ - 0, /* RELOC_SFA_BASE */ - 0, /* RELOC_SFA_OFF13 */ - 0, /* RELOC_BASE10 */ - 0, /* RELOC_BASE13 */ - 0, /* RELOC_BASE22 */ - 0, /* RELOC_PC10 */ - 0, /* RELOC_PC22 */ - 0, /* RELOC_JMP_TBL */ - 0, /* RELOC_SEGOFF16 */ - 0, /* RELOC_GLOB_DAT */ - 0, /* RELOC_JMP_SLOT */ - 0 /* RELOC_RELATIVE */ -}; - -int -aout_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel) -{ - int k; /* loop temporary */ - int nr; /* number of relocations */ - char *name; /* symbol being searched for */ - long value; /* relocation temporary */ - long *ra; /* cached relocation address */ - struct relocation_info *rp; /* current relocation */ - struct nlist *sp; /* symbol table of "symbol" */ - Rt_map * _lmp; /* lm which holds symbol definition */ - Sym * sym; /* symbol definition */ - int ret = 1; - APlist *bound = NULL; - Lm_list *lml = LIST(lmp); - - DBG_CALL(Dbg_reloc_run(lmp, SHT_RELA, plt, DBG_REL_START)); - - /* - * If we've been called upon to promote an RTLD_LAZY object to an - * RTLD_NOW don't bother to do anything - a.out's are bound as if - * RTLD_NOW regardless. - */ - if (plt) - return (1); - - rp = LM2LP(lmp)->lp_rp; - nr = GETRELSZ(AOUTDYN(lmp)) / sizeof (struct relocation_info); - - /* - * Initialize _PLT_, if any. - */ - if (AOUTDYN(lmp)->v2->ld_plt_sz) - aout_plt_write((caddr_t)LM2LP(lmp)->lp_plt->jb_inst, - (ulong_t)aout_rtbndr); - - /* - * Loop through relocations. - */ - for (k = 0; k < nr; k++, rp++) { - mmapobj_result_t *mpp; - - /* LINTED */ - ra = (long *)&((char *)ADDR(lmp))[rp->r_address]; - - /* - * Make sure the segment is writable. - */ - if (((mpp = find_segment((caddr_t)ra, lmp)) != NULL) && - ((mpp->mr_prot & PROT_WRITE) == 0)) { - if ((set_prot(lmp, mpp, 1) == 0) || - (aplist_append(textrel, mpp, - AL_CNT_TEXTREL) == NULL)) { - ret = 0; - break; - } - } - - /* - * Perform the relocation. - */ - if (rp->r_extern == 0) { - name = NULL; - value = ADDR(lmp); - } else { - Slookup sl; - Sresult sr; - uint_t binfo; - - if (rp->r_type == RELOC_JMP_SLOT) - continue; - sp = &LM2LP(lmp)->lp_symtab[rp->r_symbolnum]; - name = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx]; - - /* - * Locate symbol. Initialize the symbol lookup data - * structure. - */ - SLOOKUP_INIT(sl, name, lmp, 0, ld_entry_cnt, - 0, 0, 0, 0, LKUP_STDRELOC); - SRESULT_INIT(sr, name); - - if (aout_lookup_sym(&sl, &sr, &binfo, in_nfavl) == 0) { - if (lml->lm_flags & LML_FLG_TRC_WARN) { - (void) - printf(MSG_INTL(MSG_LDD_SYM_NFOUND), - demangle(name), NAME(lmp)); - continue; - } else { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_REL_NOSYM), NAME(lmp), - demangle(name)); - ret = 0; - break; - } - } - - /* - * If symbol was found in an object other than the - * referencing object then record the binding. - */ - name = (char *)sr.sr_name; - _lmp = sr.sr_dmap; - sym = sr.sr_sym; - - if ((lmp != _lmp) && - ((FLAGS1(_lmp) & FL1_RT_NOINIFIN) == 0)) { - if (aplist_test(&bound, _lmp, - AL_CNT_RELBIND) == 0) { - ret = 0; - break; - } - } - - value = sym->st_value + rp->r_addend; - if (!(FLAGS(_lmp) & FLG_RT_FIXED) && - (sym->st_shndx != SHN_COMMON) && - (sym->st_shndx != SHN_ABS)) - value += ADDR(_lmp); - - if (IS_PC_RELATIVE(rp->r_type)) - value -= (long)ADDR(lmp); - - DBG_CALL(Dbg_bind_global(lmp, (Addr)ra, - (Off)(ra - ADDR(lmp)), (Xword)(-1), PLT_T_NONE, - _lmp, (Addr)value, sym->st_value, name, binfo)); - } - - /* - * Perform a specific relocation operation. - */ - switch (rp->r_type) { - case RELOC_RELATIVE: - value += *ra << (32-22); - *(long *)ra = (*(long *)ra & ~S_MASK(22)) | - ((value >> (32 - 22)) & S_MASK(22)); - ra++; - value += (*ra & S_MASK(10)); - *(long *)ra = (*(long *)ra & ~S_MASK(10)) | - (value & S_MASK(10)); - break; - case RELOC_8: - case RELOC_DISP8: - value += *ra & S_MASK(8); - if (!S_INRANGE(value, 8)) { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), - (name ? demangle(name) : - MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 8, - (uint_t)ra); - } - *ra = value; - break; - case RELOC_LO10: - case RELOC_BASE10: - value += *ra & S_MASK(10); - *(long *)ra = (*(long *)ra & ~S_MASK(10)) | - (value & S_MASK(10)); - break; - case RELOC_BASE13: - case RELOC_13: - value += *ra & S_MASK(13); - *(long *)ra = (*(long *)ra & ~S_MASK(13)) | - (value & S_MASK(13)); - break; - case RELOC_16: - case RELOC_DISP16: - value += *ra & S_MASK(16); - if (!S_INRANGE(value, 16)) { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), - (name ? demangle(name) : - MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 16, - (uint_t)ra); - } - *(short *)ra = value; - break; - case RELOC_22: - case RELOC_BASE22: - value += *ra & S_MASK(22); - if (!S_INRANGE(value, 22)) { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), - (name ? demangle(name) : - MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 22, - (uint_t)ra); - } - *(long *)ra = (*(long *)ra & ~S_MASK(22)) | - (value & S_MASK(22)); - break; - case RELOC_HI22: - value += (*ra & S_MASK(22)) << (32 - 22); - *(long *)ra = (*(long *)ra & ~S_MASK(22)) | - ((value >> (32 - 22)) & S_MASK(22)); - break; - case RELOC_WDISP22: - value += *ra & S_MASK(22); - value >>= 2; - if (!S_INRANGE(value, 22)) { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), - (name ? demangle(name) : - MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 22, - (uint_t)ra); - } - *(long *)ra = (*(long *)ra & ~S_MASK(22)) | - (value & S_MASK(22)); - break; - case RELOC_WDISP30: - value += *ra & S_MASK(30); - value >>= 2; - *(long *)ra = (*(long *)ra & ~S_MASK(30)) | - (value & S_MASK(30)); - break; - case RELOC_32: - case RELOC_GLOB_DAT: - case RELOC_DISP32: - value += *ra; - *(long *)ra = value; - break; - default: - eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNIMPL), - NAME(lmp), (name ? demangle(name) : - MSG_INTL(MSG_STR_UNKNOWN)), rp->r_type); - ret = 0; - break; - } - - /* - * If this relocation is against a text segment we must make - * sure that the instruction cache is flushed. - */ - if (textrel) { - if (rp->r_type == RELOC_RELATIVE) - iflush_range((caddr_t)(ra - 1), 0x8); - else - iflush_range((caddr_t)ra, 0x4); - } - } - - return (relocate_finish(lmp, bound, ret)); -} |
