diff options
| author | Richard Lowe <richlowe@richlowe.net> | 2022-06-30 21:34:13 -0400 |
|---|---|---|
| committer | Richard Lowe <richlowe@richlowe.net> | 2022-09-07 14:57:26 -0500 |
| commit | fec047081731fd77caf46ec0471c501b2cb33894 (patch) | |
| tree | e57b4a4ce742bb98bb952a861b6f3800bfdd7904 /usr/src/cmd/sgs/rtld | |
| parent | d0eff808627a496edc82505a80bac88afa61304e (diff) | |
| download | illumos-joyent-fec047081731fd77caf46ec0471c501b2cb33894.tar.gz | |
14901 remove remaining a.out support from sgs
Reviewed by: Dan McDonald <danmcd@mnx.io>
Reviewed by: Robert Mustacchi <rm+illumos@fingolfin.org>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/cmd/sgs/rtld')
26 files changed, 91 insertions, 2493 deletions
diff --git a/usr/src/cmd/sgs/rtld/Makefile.com b/usr/src/cmd/sgs/rtld/Makefile.com index 273081c28d..6ef3e7afbe 100644 --- a/usr/src/cmd/sgs/rtld/Makefile.com +++ b/usr/src/cmd/sgs/rtld/Makefile.com @@ -101,7 +101,6 @@ RTLDLIB = -L ../../librtld/$(MACH) CERRWARN += $(CNOWARN_UNINIT) CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-switch # not linted SMATCH=off diff --git a/usr/src/cmd/sgs/rtld/amd64/Makefile b/usr/src/cmd/sgs/rtld/amd64/Makefile index 244cb6ca0f..45b4727c3e 100644 --- a/usr/src/cmd/sgs/rtld/amd64/Makefile +++ b/usr/src/cmd/sgs/rtld/amd64/Makefile @@ -27,7 +27,7 @@ BASEPLAT = amd64 # Object lists are organized into primary (most frequently used code) and -# secondary lists (less frequently used code, ie. a.out support). +# secondary lists (less frequently used code). P_COMOBJS= debugdata.o \ analyze.o elf.o external.o globals.o \ diff --git a/usr/src/cmd/sgs/rtld/amd64/_setup.c b/usr/src/cmd/sgs/rtld/amd64/_setup.c index 2a92d72565..e48db1cc11 100644 --- a/usr/src/cmd/sgs/rtld/amd64/_setup.c +++ b/usr/src/cmd/sgs/rtld/amd64/_setup.c @@ -310,7 +310,7 @@ _setup(Boot *ebp, Dyn *ld_dyn) */ if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, _syspagsz, _rt_name, ld_base, interp_base, fd, phdr, - _execname, _argv, uid, euid, gid, egid, NULL, auxflags, + _execname, _argv, uid, euid, gid, egid, auxflags, hwcap)) == NULL) { rtldexit(&lml_main, 1); } diff --git a/usr/src/cmd/sgs/rtld/amd64/boot.s b/usr/src/cmd/sgs/rtld/amd64/boot.s index a440f7fc09..cfe6cbb63c 100644 --- a/usr/src/cmd/sgs/rtld/amd64/boot.s +++ b/usr/src/cmd/sgs/rtld/amd64/boot.s @@ -27,7 +27,6 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* * Bootstrap routine for run-time linker. @@ -69,7 +68,7 @@ * find the addr of the dynamic section of ld.so, of argv[0], and of * the process' environment pointers - and pass the thing to _setup * to handle. We then call _rtld - on return we jump to the entry - * point for the a.out. + * point for the executable. */ #if defined(lint) @@ -97,14 +96,14 @@ main() _rt_alias: / in case we were invoked from libc.so - jmp .get_got + jmp .get_got _rt_boot: / save for referencing args - movq %rsp,%rbp + movq %rsp,%rbp / make room for a max sized boot vector subq $EB_MAX_SIZE64,%rsp / use esi as a pointer to &eb[0] - movq %rsp,%rsi + movq %rsp,%rsi / set up tag for argv movq $EB_ARGV,0(%rsi) / get address of argv @@ -150,7 +149,7 @@ _rt_boot: movq %rbp,%rsp movq atexit_fini@GOTPCREL(%rip), %rdx - / transfer control to a.out + / transfer control to the executable jmp *%rax .size _rt_boot,.-_rt_boot #endif diff --git a/usr/src/cmd/sgs/rtld/common/_a.out.h b/usr/src/cmd/sgs/rtld/common/_a.out.h deleted file mode 100644 index 0924f01af0..0000000000 --- a/usr/src/cmd/sgs/rtld/common/_a.out.h +++ /dev/null @@ -1,361 +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) 1990, 2010, Oracle and/or its affiliates. All rights reserved. - */ -#ifndef _A_DOT_OUT_DOT_H -#define _A_DOT_OUT_DOT_H - -#include <sys/types.h> -#include <sys/null.h> -#include <sys/mman.h> -#include <a.out.h> -#include <_rtld.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define max(a, b) ((a) < (b) ? (b) : (a)) - -typedef struct link_dynamic Link_dynamic; - -/* - * Extern functions for a.out format file class. - */ -extern ulong_t aout_bndr(caddr_t); -extern int aout_get_mmap(Lm_list *, mmapobj_result_t *); -extern int aout_lookup_sym(Slookup *, Sresult *, uint_t *, int *); -extern Rt_map *aout_new_lmp(Lm_list *, Aliste, Fdesc *, Addr, size_t, void *, - Rt_map *, int *); -extern void aout_plt_write(caddr_t, ulong_t); -extern int aout_reloc(Rt_map *, uint_t, int *, APlist **); -extern void aout_rtbndr(caddr_t); -extern Fct *aout_verify(caddr_t, size_t, Fdesc *, const char *, - Rej_desc *); - -/* - * Private data for an a.out format file class. - */ -typedef struct _rt_aout_private { - struct link_dynamic *lm_ld; /* 4.x aout dynamic pointer */ - struct ld_private *lm_lpd; /* private aout object area */ -} Rt_aoutp; - -/* - * Special defines for a.out format file class. - */ -#define N_UNDF 0x0 /* undefined */ -#define N_ABS 0x2 /* absolute */ -#define N_COMM 0x12 /* common (internal to ld) */ -#define N_EXT 01 /* external bit, or'ed in */ - -/* - * Format of a symbol table entry. - */ -struct nlist { - union { - char *n_name; /* for use when in-core */ - long n_strx; /* index into file string table */ - } n_un; - uchar_t n_type; /* type flag (N_TEXT,..) */ - char n_other; /* unused */ - short n_desc; /* see <stab.h> */ - ulong_t n_value; /* value of symbol (or sdb offset) */ -}; - -/* - * Link editor public definitions. - */ - -#ifndef _link_h -#define _link_h - -/* - * Structure describing logical name and requirements on an object - * which is to be loaded dynamically. - */ -struct old_link_object { - char *lo_name; /* name of object */ - int lo_library : 1, /* searched for by library rules */ - lo_unused : 31; - short lo_major; /* major version number */ - short lo_minor; /* minor version number */ -}; - -struct link_object { - long lo_name; /* name (often relative) */ - int lo_library : 1, /* searched for by library rules */ - lo_unused : 31; - short lo_major; /* major version number */ - short lo_minor; /* minor version number */ - long lo_next; /* next one (often relative) */ -}; -typedef struct link_object Lnk_obj; - -/* - * Structure describing name and placement of dynamically loaded - * objects in a process' address space. - */ -typedef struct a_link_map A_link_map; - -struct a_link_map { - caddr_t lm_addr; /* address at which object mapped */ - char *lm_name; /* full name of loaded object */ - struct a_link_map *lm_next; /* next object in map */ - struct link_object *lm_lop; /* link object that got us here */ - caddr_t lm_lob; /* base address for said link object */ - int lm_rwt : 1; /* text is read/write */ - struct link_dynamic *lm_ld; /* dynamic structure */ - caddr_t lm_lpd; /* loader private data */ -}; - -/* - * Version 1 of dynamic linking information. With the exception of - * ld_loaded (determined at execution time) and ld_stab_hash (a special - * case of relocation handled at execution time), the values in this - * structure reflect offsets from the containing link_dynamic structure. - */ -struct link_dynamic_1 { - struct a_link_map *ld_loaded; /* list of loaded objects */ - long ld_need; /* list of needed objects */ - long ld_rules; /* search rules for library objects */ - long ld_got; /* global offset table */ - long ld_plt; /* procedure linkage table */ - long ld_rel; /* relocation table */ - long ld_hash; /* symbol hash table */ - long ld_stab; /* symbol table itself */ - long (*ld_stab_hash)(); /* "pointer" to symbol hash function */ - long ld_buckets; /* number of hash buckets */ - long ld_symbols; /* symbol strings */ - long ld_symb_size; /* size of symbol strings */ - long ld_text; /* size of text area */ -}; - -struct link_dynamic_2 { - struct a_link_map *ld_loaded; /* list of loaded objects */ - long ld_need; /* list of needed objects */ - long ld_rules; /* search rules for library objects */ - long ld_got; /* global offset table */ - long ld_plt; /* procedure linkage table */ - long ld_rel; /* relocation table */ - long ld_hash; /* symbol hash table */ - long ld_stab; /* symbol table itself */ - long (*ld_stab_hash)(); /* "pointer" to symbol hash function */ - long ld_buckets; /* number of hash buckets */ - long ld_symbols; /* symbol strings */ - long ld_symb_size; /* size of symbol strings */ - long ld_text; /* size of text area */ - long ld_plt_sz; /* size of procedure linkage table */ -}; - -/* - * Structure pointing to run time allocated common symbols and - * its string. - */ -struct rtc_symb { - struct nlist *rtc_sp; /* symbol for common */ - struct rtc_symb *rtc_next; /* next common */ -}; - -/* - * Debugger interface structure. - */ -struct ld_debug { - int ldd_version; /* version # of interface */ - int ldd_in_debugger; /* a debugger is running us */ - int ldd_sym_loaded; /* we loaded some symbols */ - char *ldd_bp_addr; /* place for ld-generated bpt */ - int ldd_bp_inst; /* instruction which was there */ - struct rtc_symb *ldd_cp; /* commons we built */ -}; - -/* - * Structure associated with each object which may be or which requires - * execution-time link editing. Used by the run-time linkage editor to - * identify needed objects and symbol definitions and references. - */ -struct old_link_dynamic { - int ld_version; /* version # of this structure */ - union { - struct link_dynamic_1 ld_1; - } ld_un; - - int in_debugging; - int sym_loaded; - char *bp_addr; - int bp_inst; - struct rtc_symb *cp; /* pointer to an array of runtime */ - /* allocated common symbols. */ -}; - -struct link_dynamic { - int ld_version; /* version # of this structure */ - struct ld_debug *ldd; - union { - struct link_dynamic_1 *ld_1; - struct link_dynamic_2 *ld_2; - } ld_un; -}; - - -/* - * Get size of relocations. - */ -#define GETGOTSZ(x) (x->ld_version < 2 ? \ - ((struct old_link_dynamic *)x)->v1.ld_plt - \ - ((struct old_link_dynamic *)x)->v1.ld_got : \ - (x)->v2->ld_plt - (x)->v2->ld_got) - -#define GETPLTSZ(x) (x->ld_version < 2 ? \ - ((struct old_link_dynamic *)x)->v1.ld_rel - \ - ((struct old_link_dynamic *)x)->v1.ld_plt : \ - (x)->v2->ld_rel - (x)->v2->ld_plt) - -#define GETRELSZ(x) (x->ld_version < 2 ? \ - ((struct old_link_dynamic *)x)->v1.ld_hash - \ - ((struct old_link_dynamic *)x)->v1.ld_rel : \ - (x)->v2->ld_hash - (x)->v2->ld_rel) - -#define GETHASHSZ(x) (x->ld_version < 2 ? \ - ((struct old_link_dynamic *)x)->v1.ld_stab - \ - ((struct old_link_dynamic *)x)->v1.ld_hash : \ - (x)->v2->ld_stab - (x)->v2->ld_hash) - -#define GETSTABSZ(x) (x->ld_version < 2 ? \ - ((struct old_link_dynamic *)x)->v1.ld_symbols -\ - ((struct old_link_dynamic *)x)->v1.ld_stab : \ - (x)->v2->ld_symbols - (x)->v2->ld_stab) - -#undef v2 -#undef v1 - -#endif /* !_link_h */ - -#define MAIN_BASE 0x2000 /* base address of a.out in 4.x system */ - -/* - * Macros for getting to linker a.out format private data. - */ -#define AOUTPRV(X) ((X)->rt_priv) -#define AOUTDYN(X) (((Rt_aoutp *)(X)->rt_priv)->lm_ld) -#define LM2LP(X) ((struct ld_private *)((Rt_aoutp *) \ - (X)->rt_priv)->lm_lpd) -#define TEXTBASE(X) (LM2LP(X)->lp_textbase) - -/* - * Most of the above macros are used from AOUT specific routines, however there - * are a couple of instances where we need to ensure the file being processed - * is AOUT before dereferencing the macro. - */ -#define THIS_IS_AOUT(X) (FCT(X) == &aout_fct) - -/* - * Code collapsing macros. - */ -#define v2 ld_un.ld_2 -#define v1 ld_un.ld_1 -#define JMPOFF(x) (x)->v2->ld_plt -#define RELOCOFF(x) (x)->v2->ld_rel -#define HASHOFF(x) (x)->v2->ld_hash -#define SYMOFF(x) (x)->v2->ld_stab -#define STROFF(x) (x)->v2->ld_symbols - -struct jbind { - int jb_inst[3]; /* need 4 instructions for jump slot */ -}; - -struct fshash { - int fssymbno; /* ordinal symbol number */ - int next; /* index to the hash array pointed by fs_hash */ -}; - -/* - * Sparc relocation types. - */ -enum reloc_type -{ - RELOC_8, RELOC_16, RELOC_32, /* simplest relocs */ - RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* Disp's (pc-rel) */ - RELOC_WDISP30, RELOC_WDISP22, /* SR word disp's */ - RELOC_HI22, RELOC_22, /* SR 22-bit relocs */ - RELOC_13, RELOC_LO10, /* SR 13&10-bit reloc */ - RELOC_SFA_BASE, RELOC_SFA_OFF13, /* SR S.F.A. relocs */ - RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* base_relative pic */ - RELOC_PC10, RELOC_PC22, /* special pc-rel pic */ - RELOC_JMP_TBL, /* jmp_tbl_rel in pic */ - RELOC_SEGOFF16, /* Shlib off-in-seg */ - RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE /* rtld relocs */ -}; - -/* - * Format of a relocation datum. - */ -#define r_symbolnum r_index - -struct relocation_info /* used when header.a_machtype == M_SPARC */ -{ - ulong_t r_address; /* relocation addr (offset in seg) */ - uint_t r_index :24; /* segment index or symbol index */ - uint_t r_extern : 1; /* if F, r_index==SEG#; if T, SYM idx */ - int : 2; /* <unused> */ - enum reloc_type r_type : 5; /* type of relocation to perform */ - long r_addend; /* addend for relocation value */ -}; - -struct ld_private { - struct jbind *lp_plt; /* procedure linkage table */ - struct relocation_info *lp_rp; /* relocation table */ - struct fshash *lp_hash; /* hash table */ - struct nlist *lp_symtab; /* symbol table */ - char *lp_symstr; /* symbol strings */ - caddr_t lp_textbase; /* base address for text addressing */ - struct nlist *(*lp_interp)(); /* link map interpreter */ - long lp_refcnt; /* reference count of link map */ - struct dl_object *lp_dlp; /* pointer to a dlopen object */ - caddr_t lp_symbol_base; /* base address for symbols */ -}; - - -/* - * Offsets of various sections of an object file. - */ -#define PAGSIZ 0x02000 -#define SEGSIZ PAGSIZ - -#define N_TXTOFF(x) \ - /* text segment */ \ - ((x).a_magic == ZMAGIC ? 0 : sizeof (struct exec)) - -#define N_SYMOFF(x) \ - /* symbol table */ \ - (N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) - -#define SIZE(x) \ - /* round to segment size */ \ - (M_SROUND((x).a_text) + (x).a_data + (x).a_bss) - -#ifdef __cplusplus -} -#endif - -#endif /* _A_DOT_OUT_DOT_H */ diff --git a/usr/src/cmd/sgs/rtld/common/_elf.h b/usr/src/cmd/sgs/rtld/common/_elf.h index 3c60474223..db417a4132 100644 --- a/usr/src/cmd/sgs/rtld/common/_elf.h +++ b/usr/src/cmd/sgs/rtld/common/_elf.h @@ -41,7 +41,7 @@ extern "C" { /* * Common extern functions for ELF file class. */ -extern int elf_config(Rt_map *, int); +extern int elf_config(Rt_map *); extern Rtc_obj *elf_config_ent(const char *, Word, int, const char **); extern void elf_config_flt(Lm_list *, const char *, const char *, Alist **, Aliste); @@ -118,7 +118,7 @@ typedef struct _rt_elf_private { int e_verneednum; /* their associated count */ Verdef *e_verdef; /* versions defined by this image and */ int e_verdefnum; /* their associated count */ - Versym *e_versym; /* Per-symbol versions */ + Versym *e_versym; /* Per-symbol versions */ ulong_t e_syminent; /* syminfo entry size */ void *e_pltpad; /* PLTpad table */ void *e_pltpadend; /* end of PLTpad table */ diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index ece14a855e..190483fa10 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -450,8 +450,8 @@ typedef struct { } Spath_desc; /* - * Define a path name definition descriptor. Used to maintain initial ELF and - * AOUT path name definitions. + * Define a path name definition descriptor. Used to maintain initial path + * name definitions. */ typedef struct { const char *sd_name; /* path name */ @@ -575,11 +575,6 @@ extern uchar_t search_rules[]; /* dependency search rules */ extern Fct elf_fct; /* ELF file class dependent data */ -#if defined(__sparc) && !defined(__sparcv9) -extern Fct aout_fct; /* a.out (4.x) file class dependent */ - /* data */ -#endif - extern Config *config; /* configuration structure */ extern const char *locale; /* locale environment setting */ @@ -599,8 +594,6 @@ extern const char *prm_preload; /* permanent LD_PRELOAD string */ extern Alist *elf_def_dirs; /* ELF default directory seach paths */ extern Alist *elf_sec_dirs; /* ELF secure directory seach paths */ -extern Alist *aout_def_dirs; /* AOUT default directory seach paths */ -extern Alist *aout_sec_dirs; /* AOUT secure directory seach paths */ extern uint_t env_info; /* information regarding environment */ /* variables */ @@ -675,7 +668,7 @@ extern void *calloc(size_t, size_t); extern int cap_alternative(void); extern int cap_check_fdesc(Fdesc *, Cap *, char *, Rej_desc *); extern int cap_check_lmp(Rt_map *, Rej_desc *); -extern int cap_filtees(Alist **, Aliste, const char *, Aliste, +extern int cap_filtees(Alist **, Aliste, const char *, Aliste, Rt_map *, Rt_map *, const char *, int, uint_t, int *); extern int cap_match(Sresult *, uint_t, Sym *, char *); @@ -729,7 +722,7 @@ extern void lm_append(Lm_list *, Aliste, Rt_map *); extern void lm_delete(Lm_list *, Rt_map *, Rt_map *); extern void lm_move(Lm_list *, Aliste, Aliste, Lm_cntl *, Lm_cntl *); -extern Rt_map *load_cap(Lm_list *, Aliste, const char *, Rt_map *, +extern Rt_map *load_cap(Lm_list *, Aliste, const char *, Rt_map *, uint_t, uint_t, Grp_hdl **, Rej_desc *, int *); extern void load_completion(Rt_map *); extern Rt_map *load_file(Lm_list *, Aliste, Rt_map *, Fdesc *, int *); @@ -750,10 +743,10 @@ extern int platcap_check(Syscapset *, const char *, Rej_desc *); extern void platform_name(Syscapset *); extern int pnavl_recorded(avl_tree_t **, const char *, uint_t, avl_index_t *); -extern int procenv_user(APlist *, Word *, Word *, int); +extern int procenv_user(APlist *, Word *, Word *); extern void rd_event(Lm_list *, rd_event_e, r_state_e); extern int readenv_user(const char **, APlist **); -extern int readenv_config(Rtc_env *, Addr, int); +extern int readenv_config(Rtc_env *, Addr); extern void rejection_inherit(Rej_desc *, Rej_desc *); extern int relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *, int *); @@ -781,14 +774,14 @@ extern int rtld_fstat(int, rtld_stat_t *restrict); extern int rtld_stat(const char *restrict, rtld_stat_t *restrict); #endif extern int rtld_getopt(char **, char ***, auxv_t **, Word *, - Word *, int); + Word *); extern void security(uid_t, uid_t, gid_t, gid_t, int); extern void set_environ(Lm_list *); extern void set_dirs(Alist **, Spath_defn *, uint_t); extern int set_prot(Rt_map *, mmapobj_result_t *, int); extern Rt_map *setup(char **, auxv_t *, Word, char *, int, char *, ulong_t, ulong_t, int fd, Phdr *, char *, char **, - uid_t, uid_t, gid_t, gid_t, void *, int, uint_t *); + uid_t, uid_t, gid_t, gid_t, int, uint_t *); extern const char *stravl_insert(const char *, uint_t, size_t, int); extern void spavl_insert(const char *); extern int sfcap1_check(Syscapset *, Xword, Rej_desc *); diff --git a/usr/src/cmd/sgs/rtld/common/a.out.c b/usr/src/cmd/sgs/rtld/common/a.out.c deleted file mode 100644 index 693b4f59bc..0000000000 --- a/usr/src/cmd/sgs/rtld/common/a.out.c +++ /dev/null @@ -1,768 +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) 1991, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* - * Object file dependent support for a.out format objects. - */ - -#include <a.out.h> /* Explicitly override M_SEGSIZE */ -#include <machdep.h> /* used in M_SROUND */ - -#include <sys/types.h> -#include <sys/procfs.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <limits.h> -#include <stdio.h> -#include <dlfcn.h> -#include <errno.h> -#include <debug.h> -#include "_a.out.h" -#include "cache_a.out.h" -#include "msg.h" -#include "_rtld.h" - -/* - * Default and secure dependency search paths. - */ -static Spath_defn _aout_def_dirs[] = { - { MSG_ORIG(MSG_PTH_USRLIB), MSG_PTH_USRLIB_SIZE }, - { MSG_ORIG(MSG_PTH_USRLCLIB), MSG_PTH_USRLCLIB_SIZE }, - { 0, 0 } -}; - -static Spath_defn _aout_sec_dirs[] = { - { MSG_ORIG(MSG_PTH_LIBSE), MSG_PTH_LIBSE_SIZE }, - { 0, 0 } -}; - -Alist *aout_def_dirs = NULL; -Alist *aout_sec_dirs = NULL; - -/* - * Defines for local functions. - */ -static void aout_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int); -static int aout_dlsym_handle(Grp_hdl *, Slookup *, Sresult *, uint_t *, - int *); -static Addr aout_entry_point(void); -static int aout_find_sym(Slookup *, Sresult *, uint_t *, int *); -static int aout_fix_name(const char *, Rt_map *, Alist **, Aliste, uint_t); -static Alist **aout_get_def_dirs(void); -static Alist **aout_get_sec_dirs(void); -static char *aout_get_so(const char *, const char *, size_t, size_t); -static int aout_needed(Lm_list *, Aliste, Rt_map *, int *); - -/* - * Functions and data accessed through indirect pointers. - */ -Fct aout_fct = { - aout_verify, - aout_new_lmp, - aout_entry_point, - aout_needed, - aout_lookup_sym, - aout_reloc, - aout_get_def_dirs, - aout_get_sec_dirs, - aout_fix_name, - aout_get_so, - aout_dladdr, - aout_dlsym_handle -}; - -/* - * Default and secure dependency search paths. - */ -static Alist ** -aout_get_def_dirs() -{ - if (aout_def_dirs == NULL) - set_dirs(&aout_def_dirs, _aout_def_dirs, LA_SER_DEFAULT); - return (&aout_def_dirs); -} - -static Alist ** -aout_get_sec_dirs() -{ - if (aout_sec_dirs == NULL) - set_dirs(&aout_sec_dirs, _aout_sec_dirs, LA_SER_SECURE); - return (&aout_sec_dirs); -} - -/* - * In 4.x, a needed file or a dlopened file that was a simple file name implied - * that the file be found in the present working directory. To simulate this - * lookup within the ELF rules it is necessary to add a preceding `./' to the - * filename. - */ -/* ARGSUSED4 */ -static int -aout_fix_name(const char *oname, Rt_map *clmp, Alist **alpp, Aliste alni, - uint_t orig) -{ - size_t len; - Pdesc *pdp; - const char *nname; - - /* - * Check for slash in name, if none, prepend "./", otherwise just - * return name given. - */ - if (strchr(oname, '/')) { - len = strlen(oname) + 1; - if ((nname = stravl_insert(oname, 0, len, 0)) == NULL) - return (0); - } else { - char buffer[PATH_MAX]; - - len = strlen(oname) + 3; - (void) snprintf(buffer, len, MSG_ORIG(MSG_FMT_4XPATH), oname); - if ((nname = stravl_insert(buffer, 0, len, 0)) == NULL) - return (0); - } - - if ((pdp = alist_append(alpp, NULL, sizeof (Pdesc), alni)) == NULL) - return (0); - - pdp->pd_pname = nname; - pdp->pd_plen = len; - pdp->pd_flags = PD_FLG_PNSLASH; - - DBG_CALL(Dbg_file_fixname(LIST(clmp), nname, oname)); - return (1); -} - -/* - * Determine if we have been given an A_OUT file. Returns 1 if true. - */ -Fct * -/* ARGSUSED1 */ -aout_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name, - Rej_desc *rej) -{ - /* LINTED */ - struct exec *exec = (struct exec *)addr; - - if (size < sizeof (exec) || (exec->a_machtype != M_SPARC) || - (N_BADMAG(*exec))) { - return (NULL); - } - return (&aout_fct); -} - -/* - * Return the entry point of the A_OUT executable. Although the entry point - * within an ELF file is flexible, the entry point of an A_OUT executable is - * always zero. - */ -static Addr -aout_entry_point() -{ - return (0); -} - -/* - * Search through the dynamic section for DT_NEEDED entries and perform one - * of two functions. If only the first argument is specified then load the - * defined shared object, otherwise add the link map representing the - * defined link map the the dlopen list. - */ -static int -aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl) -{ - Alist *palp = NULL; - void *need; - - for (need = &TEXTBASE(clmp)[AOUTDYN(clmp)->v2->ld_need]; - need != &TEXTBASE(clmp)[0]; - need = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_next]) { - Rt_map *nlmp; - char *name; - - name = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_name]; - - if (((Lnk_obj *)(need))->lo_library) { - /* - * If lo_library field is not NULL then this needed - * library was linked in using the "-l" option. - * Thus we need to rebuild the library name before - * trying to load it. - */ - char *file; - size_t len; - - /* - * Allocate name length plus 20 for full library name. - * lib.so.. = 7 + (2 * short) + NULL = 7 + 12 + 1 = 20 - */ - len = strlen(name) + 20; - if ((file = malloc(len)) == NULL) - return (0); - (void) snprintf(file, len, MSG_ORIG(MSG_FMT_4XLIB), - name, ((Lnk_obj *)(need))->lo_major, - ((Lnk_obj *)(need))->lo_minor); - - DBG_CALL(Dbg_libs_find(lml, file)); - - /* - * We need to determine what filename will match the - * the filename specified (ie, a libc.so.1.2 may match - * to a libc.so.1.3). It's the real pathname that is - * recorded in the link maps. If we are presently - * being traced, skip this pathname generation so - * that we fall through into load_so() to print the - * appropriate diagnostics. I don't like this at all. - */ - if (lml->lm_flags & LML_FLG_TRC_ENABLE) - name = file; - else { - Spath_desc sd = { search_rules, NULL, 0 }; - Pdesc *pdp; - char *path = NULL; - - for (pdp = get_next_dir(&sd, clmp, 0); pdp; - pdp = get_next_dir(&sd, clmp, 0)) { - if (pdp->pd_pname == NULL) - continue; - - if (path = aout_get_so(pdp->pd_pname, - file, 0, 0)) - break; - } - if (path == NULL) { - eprintf(lml, ERR_FATAL, - MSG_INTL(MSG_SYS_OPEN), file, - strerror(ENOENT)); - return (0); - } - name = path; - } - if (expand_paths(clmp, name, &palp, - AL_CNT_NEEDED, 0, 0) == 0) - return (0); - } else { - /* - * If the library is specified as a pathname, see if - * it must be fixed to specify the current working - * directory (ie. libc.so.1.2 -> ./libc.so.1.2). - */ - if (aout_fix_name(name, clmp, &palp, - AL_CNT_NEEDED, 0) == 0) - return (0); - } - - DBG_CALL(Dbg_file_needed(clmp, name)); - - nlmp = load_one(lml, lmco, palp, clmp, MODE(clmp), 0, 0, - in_nfavl); - remove_alist(&palp, 1); - if (((nlmp == NULL) || - (bind_one(clmp, nlmp, BND_NEEDED) == 0)) && - ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0)) - return (0); - } - - return (1); -} - -static Sym * -aout_symconvert(struct nlist *sp) -{ - static Sym sym; - - sym.st_value = sp->n_value; - sym.st_size = 0; - sym.st_info = 0; - sym.st_other = 0; - switch (sp->n_type) { - case N_EXT + N_ABS: - sym.st_shndx = SHN_ABS; - break; - case N_COMM: - sym.st_shndx = SHN_COMMON; - break; - case N_EXT + N_UNDF: - sym.st_shndx = SHN_UNDEF; - break; - default: - sym.st_shndx = 0; - break; - } - return (&sym); -} - -/* - * Process a.out format commons. - */ -static struct nlist * -aout_find_com(struct nlist *sp, const char *name) -{ - static struct rtc_symb *rtcp = NULL; - struct rtc_symb *rs, *trs; - const char *sl; - char *cp; - - /* - * See if common is already allocated. - */ - trs = rtcp; - while (trs) { - sl = name; - cp = trs->rtc_sp->n_un.n_name; - while (*sl == *cp++) - if (*sl++ == '\0') - return (trs->rtc_sp); - trs = trs->rtc_next; - } - - /* - * If we got here, common is not already allocated so allocate it. - */ - if ((rs = malloc(sizeof (struct rtc_symb))) == NULL) - return (NULL); - if ((rs->rtc_sp = malloc(sizeof (struct nlist))) == NULL) - return (NULL); - trs = rtcp; - rtcp = rs; - rs->rtc_next = trs; - *(rs->rtc_sp) = *sp; - if ((rs->rtc_sp->n_un.n_name = malloc(strlen(name) + 1)) == NULL) - return (NULL); - (void) strcpy(rs->rtc_sp->n_un.n_name, name); - rs->rtc_sp->n_type = N_COMM; - if ((rs->rtc_sp->n_value = - (long)calloc(rs->rtc_sp->n_value, 1)) == (long)NULL) - return (NULL); - return (rs->rtc_sp); -} - -/* - * Find a.out format symbol in the specified link map. Unlike the sister - * elf routine we re-calculate the symbols hash value for each link map - * we're looking at. - */ -static struct nlist * -aout_findsb(const char *aname, Rt_map *lmp, int flag) -{ - const char *name = aname; - char *cp; - struct fshash *p; - int i; - struct nlist *sp; - ulong_t hval = 0; - -#define HASHMASK 0x7fffffff -#define RTHS 126 - - /* - * The name passed to us is in ELF format, thus it is necessary to - * map this back to the A_OUT format to compute the hash value (see - * mapping rules in aout_lookup_sym()). Basically the symbols are - * mapped according to whether a leading `.' exists. - * - * elf symbol a.out symbol - * i. .bar -> .bar (LKUP_LDOT) - * ii. .nuts -> nuts - * iii. foo -> _foo - */ - if (*name == '.') { - if (!(flag & LKUP_LDOT)) - name++; - } else - hval = '_'; - - while (*name) - hval = (hval << 1) + *name++; - hval = hval & HASHMASK; - - i = hval % (AOUTDYN(lmp)->v2->ld_buckets == 0 ? RTHS : - AOUTDYN(lmp)->v2->ld_buckets); - p = LM2LP(lmp)->lp_hash + i; - - if (p->fssymbno != -1) { - do { - sp = &LM2LP(lmp)->lp_symtab[p->fssymbno]; - cp = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx]; - name = aname; - if (*name == '.') { - if (!(flag & LKUP_LDOT)) - name++; - } else { - cp++; - } - while (*name == *cp++) { - if (*name++ == '\0') - return (sp); /* found */ - } - if (p->next == 0) - return (NULL); /* not found */ - else - continue; - } while ((p = &LM2LP(lmp)->lp_hash[p->next]) != NULL); - } - return (NULL); -} - -/* - * The symbol name we have been asked to look up is in A_OUT format, this - * symbol is mapped to the appropriate ELF format which is the standard by - * which symbols are passed around ld.so.1. The symbols are mapped - * according to whether a leading `_' or `.' exists. - * - * a.out symbol elf symbol - * i. _foo -> foo - * ii. .bar -> .bar (LKUP_LDOT) - * iii. nuts -> .nuts - */ -int -aout_lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) -{ - char name[PATH_MAX]; - Slookup sl = *slp; - - DBG_CALL(Dbg_syms_lookup_aout(LIST(slp->sl_cmap), slp->sl_name)); - - if (*sl.sl_name == '_') - ++sl.sl_name; - else if (*sl.sl_name == '.') - sl.sl_flags |= LKUP_LDOT; - else { - name[0] = '.'; - (void) strcpy(&name[1], sl.sl_name); - sl.sl_name = name; - } - - /* - * Call the generic lookup routine to cycle through the specified - * link maps. - */ - return (lookup_sym(&sl, srp, binfo, in_nfavl)); -} - -/* - * Symbol lookup for an a.out format module. - */ -/* ARGSUSED3 */ -static int -aout_find_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) -{ - const char *name = slp->sl_name; - Rt_map *ilmp = slp->sl_imap; - struct nlist *sp; - - DBG_CALL(Dbg_syms_lookup(ilmp, name, MSG_ORIG(MSG_STR_AOUT))); - - if (sp = aout_findsb(name, ilmp, slp->sl_flags)) { - if (sp->n_value != 0) { - /* - * is it a common? - */ - if (sp->n_type == (N_EXT + N_UNDF)) { - if ((sp = aout_find_com(sp, name)) == NULL) - return (0); - } - srp->sr_dmap = ilmp; - srp->sr_sym = aout_symconvert(sp); - *binfo |= DBG_BINFO_FOUND; - return (1); - } - } - return (0); -} - -/* - * Create a new Rt_map structure for an a.out format object and - * initializes all values. - */ -/* ARGSUSED6 */ -Rt_map * -aout_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize, - void *odyn, Rt_map *clmp, int *in_nfavl) -{ - const char *name = fdp->fd_nname; - Rt_map *lmp; - caddr_t base, caddr = (caddr_t)addr; - Link_dynamic *ld = (Link_dynamic *)odyn; - size_t lmsz, rtsz, prsz; - - DBG_CALL(Dbg_file_aout(lml, name, addr, msize, lml->lm_lmidstr, lmco)); - - /* - * Allocate space for the link-map and private a.out information. Once - * these are allocated and initialized, we can use remove_so(0, lmp) to - * tear down the link-map should any failures occur. - */ - rtsz = S_DROUND(sizeof (Rt_map)); - prsz = S_DROUND(sizeof (Rt_aoutp)); - lmsz = rtsz + prsz + sizeof (struct ld_private); - if ((lmp = calloc(lmsz, 1)) == NULL) - return (NULL); - AOUTPRV(lmp) = (void *)((uintptr_t)lmp + rtsz); - ((Rt_aoutp *)AOUTPRV(lmp))->lm_lpd = - (void *)((uintptr_t)lmp + rtsz + prsz); - LMSIZE(lmp) = lmsz; - - /* - * All fields not filled in were set to 0 by calloc. - */ - NAME(lmp) = (char *)name; - ADDR(lmp) = addr; - MSIZE(lmp) = msize; - SYMINTP(lmp) = aout_find_sym; - FCT(lmp) = &aout_fct; - LIST(lmp) = lml; - OBJFLTRNDX(lmp) = FLTR_DISABLED; - SORTVAL(lmp) = -1; - - /* - * Specific settings for a.out format. - */ - if (lml->lm_head == NULL) { - base = (caddr_t)MAIN_BASE; - FLAGS(lmp) |= FLG_RT_FIXED; - } else - base = caddr; - - /* - * Fill in all AOUT information. Applications provide the Link_dynamic - * offset via the boot block, but if this is a shared object that - * ld.so.1 has mapped, then determine the Link_dynamic offset from the - * mapped image. - */ - if (ld == NULL) { - /* LINTED */ - struct exec *exec = (struct exec *)caddr; - struct nlist *nl; - - /* LINTED */ - nl = (struct nlist *)&caddr[N_SYMOFF(*exec)]; - /* LINTED */ - ld = (Link_dynamic *)&caddr[nl->n_value]; - - ld->v2 = (struct link_dynamic_2 *)((int)ld->v2 + (int)caddr); - } - AOUTDYN(lmp) = ld; - - if ((RPATH(lmp) = (char *)&base[ld->v2->ld_rules]) == base) - RPATH(lmp) = NULL; - LM2LP(lmp)->lp_symbol_base = caddr; - /* LINTED */ - LM2LP(lmp)->lp_plt = (struct jbind *)(&caddr[JMPOFF(ld)]); - LM2LP(lmp)->lp_rp = - /* LINTED */ - (struct relocation_info *)(&base[RELOCOFF(ld)]); - /* LINTED */ - LM2LP(lmp)->lp_hash = (struct fshash *)(&base[HASHOFF(ld)]); - /* LINTED */ - LM2LP(lmp)->lp_symtab = (struct nlist *)(&base[SYMOFF(ld)]); - LM2LP(lmp)->lp_symstr = &base[STROFF(ld)]; - LM2LP(lmp)->lp_textbase = base; - LM2LP(lmp)->lp_refcnt++; - LM2LP(lmp)->lp_dlp = NULL; - - /* - * Add the mapped object to the end of the link map list. - */ - lm_append(lml, lmco, lmp); - return (lmp); -} - -/* - * Build full pathname of shared object from the given directory name and - * filename. - */ -static char * -/* ARGSUSED2 */ -aout_get_so(const char *dir, const char *file, size_t dlen, size_t flen) -{ - struct db *dbp; - char *path = NULL; - - if (dbp = lo_cache(dir)) { - path = ask_db(dbp, file); - } - return (path); -} - -/* - * Determine the symbol location of an address within a link-map. Look for - * the nearest symbol (whoes value is less than or equal to the required - * address). This is the object specific part of dladdr(). - */ -static void -aout_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info, - int flags) -{ - ulong_t ndx, cnt, base, _value; - struct nlist *sym, *_sym; - - cnt = ((int)LM2LP(lmp)->lp_symstr - (int)LM2LP(lmp)->lp_symtab) / - sizeof (struct nlist); - sym = LM2LP(lmp)->lp_symtab; - - if (FLAGS(lmp) & FLG_RT_FIXED) - base = 0; - else - base = ADDR(lmp); - - for (_sym = NULL, _value = 0, ndx = 0; ndx < cnt; ndx++, sym++) { - ulong_t value; - - if (sym->n_type == (N_EXT + N_UNDF)) - continue; - - value = sym->n_value + base; - if (value > addr) - continue; - if (value < _value) - continue; - - _sym = sym; - _value = value; - - if (value == addr) - break; - } - - if (_sym) { - int _flags = flags & RTLD_DL_MASK; - - /* - * The only way we can create a symbol entry is to use - * aout_symconvert(), however this results in us pointing to - * static data that could be overridden. In addition the AOUT - * symbol format doesn't give us everything an ELF symbol does. - * So, unless we get convinced otherwise, don't bother returning - * a symbol entry for AOUT's. - */ - if (_flags == RTLD_DL_SYMENT) - *info = NULL; - else if (_flags == RTLD_DL_LINKMAP) - *info = (void *)lmp; - - dlip->dli_sname = &LM2LP(lmp)->lp_symstr[_sym->n_un.n_strx]; - dlip->dli_saddr = (void *)_value; - } -} - -/* - * Continue processing a dlsym request. Lookup the required symbol in each - * link-map specified by the handle. Note, that because this lookup is against - * individual link-maps we don't need to supply a starting link-map to the - * lookup routine (see lookup_sym():analyze.c). - */ -static int -aout_dlsym_handle(Grp_hdl *ghp, Slookup *slp, Sresult *srp, uint_t *binfo, - int *in_nfavl) -{ - char buffer[PATH_MAX]; - Slookup sl; - - if (dlsym_handle(ghp, slp, srp, binfo, in_nfavl)) - return (1); - - /* - * Symbol not found as supplied. However, most of our symbols will - * be in the "C" name space, where the implementation prepends a "_" - * to the symbol as it emits it. Therefore, attempt to find the - * symbol with the "_" prepend. - */ - buffer[0] = '_'; - (void) strcpy(&buffer[1], slp->sl_name); - - sl = *slp; - sl.sl_name = (const char *)buffer; - - return (dlsym_handle(ghp, &sl, srp, binfo, in_nfavl)); -} - -/* - * The initial mapping of the a.out occurs through exec(2), and presently this - * implementation doesn't provide a mmapobj_result_t array to ld.so.1. Thus, - * aout_get_mmap() is called to create the mapping information. Unlike ELF, - * the information that can be gathered from a mapped AOUT file, can be limited. - * In some cases the AOUT header isn't available in the mapped image, and thus - * this can't be inspected to determine the files size (the kernel always - * returns a pointer to the AOUT dynamic structure, but this is only sufficient - * to determine the size of the text segment). - * - * Therefore, the only generic mechanism of determining the AOUT's mapping is - * to use /proc. Only two mappings are required, the text (to determine any - * read-only region), and the data. The two mapping validate the range in - * which any relocations will occur. Should there be an additional bss segment, - * we don't care, as this can't be relocated, and we're never going to try - * unmapping the a.out. - */ -#define PROCSIZE 20 - -int -aout_get_mmap(Lm_list *lml, mmapobj_result_t *mpp) -{ - prmap_t *maps; - char proc[PROCSIZE]; - int num, err, fd; - - (void) snprintf(proc, PROCSIZE, MSG_ORIG(MSG_FMT_PROC), - EC_SWORD(getpid())); - if ((fd = open(proc, O_RDONLY)) == -1) { - err = errno; - eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc, - strerror(err)); - return (1); - } - - if (ioctl(fd, PIOCNMAP, (void *)&num) == -1) { - err = errno; - eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err)); - return (1); - } - - if ((maps = malloc((num + 1) * sizeof (prmap_t))) == NULL) - return (1); - - if (ioctl(fd, PIOCMAP, (void *)maps) == -1) { - err = errno; - eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err)); - free(maps); - return (1); - } - - mpp->mr_addr = maps->pr_vaddr; - mpp->mr_fsize = mpp->mr_msize = maps->pr_size; - mpp->mr_prot = (PROT_READ | PROT_EXEC); - - mpp++, maps++; - - mpp->mr_addr = maps->pr_vaddr; - mpp->mr_fsize = mpp->mr_msize = maps->pr_size; - mpp->mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC); - - maps--; - free(maps); - return (0); -} diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index 91a7546e85..06b78023bd 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -44,7 +44,6 @@ #include "_rtld.h" #include "_audit.h" #include "_elf.h" -#include "_a.out.h" #include "_inline_gen.h" #include "msg.h" @@ -1543,7 +1542,7 @@ find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej, if ((olen + pdp->pd_plen + 1) >= PATH_MAX) { eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), oname, strerror(ENAMETOOLONG)); - return (0); + return (0); } if ((fdp->fd_nname = (LM_GET_SO(clmp)(pdp->pd_pname, oname, pdp->pd_plen, olen))) == NULL) @@ -1554,9 +1553,6 @@ find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej, static Fct *Vector[] = { &elf_fct, -#ifdef A_OUT - &aout_fct, -#endif 0 }; @@ -1729,12 +1725,6 @@ map_obj(Lm_list *lml, Fdesc *fdp, size_t fsize, const char *name, int fd, fptr = elf_verify((mpp->mr_addr + mpp->mr_offset), mpp->mr_fsize, fdp, name, rej); } -#ifdef A_OUT - if (flags == MR_HDR_AOUT) { - fptr = aout_verify((mpp->mr_addr + mpp->mr_offset), - mpp->mr_fsize, fdp, name, rej); - } -#endif if (fptr) { fdp->fd_mapn = mapnum; fdp->fd_mapp = smpp; @@ -1798,8 +1788,7 @@ load_file(Lm_list *lml, Aliste lmco, Rt_map *clmp, Fdesc *fdp, int *in_nfavl) /* LINTED */ ehdr = (Ehdr *)(mpp->mr_addr + mpp->mr_offset); hmpp = mpp; - } else if (flags == MR_HDR_AOUT) - hmpp = mpp; + } } /* @@ -3160,10 +3149,6 @@ _lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) * search. If successful, return a pointer to the symbol table entry, a * pointer to the link map of the enclosing object, and information relating * to the type of binding. Else return a null pointer. - * - * To improve ELF performance, we first compute the ELF hash value and pass - * it to each _lookup_sym() routine. The ELF function will use this value to - * locate the symbol, the a.out function will simply ignore it. */ int lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) diff --git a/usr/src/cmd/sgs/rtld/common/cache_a.out.c b/usr/src/cmd/sgs/rtld/common/cache_a.out.c deleted file mode 100644 index 994edaa2fd..0000000000 --- a/usr/src/cmd/sgs/rtld/common/cache_a.out.c +++ /dev/null @@ -1,549 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * 4.x ld.so directory caching: run-time link-editor specific functions. - */ - -#include <dirent.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include "_a.out.h" -#include "cache_a.out.h" -#include "_rtld.h" -#include "msg.h" - -static int stol(char *, char, char **, int *); -static int rest_ok(char *); -static int verscmp(const char *, const char *); -static void fix_lo(struct db *); -static int extract_name(char **); -static int hash(char *, int, int); - -static struct link_object *get_lo(struct db *, char *, int, int, int); -static struct dbd *new_dbd(struct dbd **, struct db *); -static struct db *find_so(const char *); - -#define SKIP_DOT(str) ((*str == '.') ? ++str : str) -#define EMPTY(str) ((str == NULL) || (*str == '\0')) -#define isdigit(c) (((c) >= '0') && ((c) <= '9') ? 1:0) - -static struct dbd *dbd_head = NULL; /* head of data bases */ - - -/* - * Given a db - find the highest shared versioned object. The - * highest versioned object is the .so with a matching major number - * but the highest minor number - */ -char * -ask_db(struct db *dbp, const char *file) -{ - char *libname, *n; - char *mnp; - char *mjp; - int liblen; - int major = 0; - int to_min; - struct dbe *ep; - struct link_object *tlop; - int index; - - n = (char *)file; - if ((liblen = extract_name(&n)) == -1) - return (NULL); - if ((libname = malloc(liblen + 1)) == 0) - return (NULL); - (void) strncpy(libname, n, liblen); - libname[liblen] = '\0'; - - if (strncmp(MSG_ORIG(MSG_FIL_DOTSODOT), (n + liblen), - MSG_FIL_DOTSODOT_SIZE)) - return (NULL); - - mnp = mjp = ((char *)file + MSG_FIL_LIB_SIZE + liblen + - MSG_FIL_DOTSODOT_SIZE); - if (!(stol(mjp, '.', &mnp, &major) && (*mnp == '.') && - rest_ok(mnp + 1))) - return (NULL); - to_min = mnp - file + 1; - - /* - * Search appropriate hash bucket for a matching entry. - */ - index = hash(libname, liblen, major); - for (ep = (struct dbe *)&(dbp->db_hash[index]); (ep && ep->dbe_lop); - ep = ep->dbe_next == 0 ? NULL : - /* LINTED */ - (struct dbe *)&AP(dbp)[ep->dbe_next]) { - /* LINTED */ - tlop = (struct link_object *)&AP(dbp)[ep->dbe_lop]; - if (tlop->lo_major == major) - if (strcmp((char *)&AP(dbp)[tlop->lo_name], - libname) == 0) - break; - } - - /* - * If no entry was found, we've lost. - */ - if (!(ep && ep->dbe_lop)) - return (NULL); - if (verscmp(file + to_min, - &AP(dbp)[ep->dbe_name] + tlop->lo_minor) > 0) - eprintf(&lml_main, ERR_WARNING, MSG_INTL(MSG_GEN_OLDREV), - &AP(dbp)[ep->dbe_name], file + to_min); - return (&AP(dbp)[ep->dbe_name]); -} - -/* - * Given a directory name - give back a data base. The data base may have - * orginated from the mmapped file or temporarily created - */ -struct db * -lo_cache(const char *ds) -{ - struct db *dbp; /* database pointer */ - struct dbd *dbdp; /* working database descriptor */ - struct dbd **dbdpp; /* insertion pointer */ - - dbdpp = &dbd_head; - for (dbdp = dbd_head; dbdp; dbdp = dbdp->dbd_next) { - if (strcmp(ds, &AP(dbdp->dbd_db)[dbdp->dbd_db->db_name]) == 0) - return (dbdp->dbd_db); - dbdpp = &dbdp->dbd_next; - } - if (dbp = find_so(ds)) { - (void) new_dbd(dbdpp, dbp); - } - return (dbp); -} - -/* - * Build a database for the directory "ds". - */ -static struct db * -find_so(const char *ds) -{ - int fd; /* descriptor on directory */ - int n; /* bytes from getdents */ - char *cp; /* working char * */ - rtld_stat_t sb; /* buffer for stat'ing directory */ - struct db *dbp; /* database */ - static caddr_t buf = NULL; /* buffer for doing getdents */ - static long bs; /* cached blocksize for getdents */ - struct link_object *tlop; /* working link object ptr. */ - struct dirent *dp; /* directory entry ptr. */ - struct dbe *ep; /* working db_entry ptr. */ - char *mnp; /* where minor version begins */ - char *mjp; /* where major version begins */ - int m; /* the major number */ - int to_min; /* index into string of minor */ - int cplen; /* length of X */ - int index; /* the hash value */ - - /* - * Try to open directory. Failing that, just return silently. - */ - if ((fd = open(ds, O_RDONLY)) == -1) - return ((struct db *)NULL); - - /* - * If we have not yet gotten a buffer for reading directories, - * allocate it now. Size it according to the most efficient size - * for the first directory we open successfully. - */ - if (!buf) { - if (rtld_fstat(fd, &sb) == -1) { - (void) close(fd); - return ((struct db *)NULL); - } - bs = sb.st_blksize; - buf = calloc(bs, 1); - } - - /* - * Have a directory, have a buffer. Allocate up a database - * and initialize it. - */ - dbp = calloc(sizeof (struct db), 1); - dbp->db_name = RELPTR(dbp, calloc((strlen(ds) + 1), 1)); - (void) strcpy((char *)&AP(dbp)[dbp->db_name], ds); - - /* - * Scan the directory looking for shared libraries. getdents() - * failures are silently ignored and terminate the scan. - */ - /* LINTED */ - while ((n = getdents(fd, (struct dirent *)buf, bs)) > 0) - /* LINTED */ - for (dp = (struct dirent *)buf; - /* LINTED */ - dp && (dp < (struct dirent *)(buf + n)); - /* LINTED */ - dp = (struct dirent *)((dp->d_reclen == 0) ? - NULL : (char *)dp + dp->d_reclen)) { - - /* - * If file starts with a "lib", then extract the X - * from libX. - */ - cp = dp->d_name; - if ((cplen = extract_name(&cp)) == -1) - continue; - - /* - * Is the next component ".so."? - */ - if (strncmp(MSG_ORIG(MSG_FIL_DOTSODOT), (cp + cplen), - MSG_FIL_DOTSODOT_SIZE)) - continue; - - /* - * Check if next component is the major number and - * whether following components are legal. - */ - mnp = mjp = (dp->d_name + MSG_FIL_LIB_SIZE + cplen + - MSG_FIL_DOTSODOT_SIZE); - if (!(stol(mjp, '.', &mnp, &m) && (*mnp == '.') && - rest_ok(mnp + 1))) - continue; - to_min = mnp - dp->d_name + 1; - - /* - * Have libX.so.major.minor - attempt to add it to the - * cache. If there is another with the same major - * number then the chose the object with the highest - * minor number - */ - index = hash(cp, cplen, m); - ep = &(dbp->db_hash[index]); - if (ep->dbe_lop == 0) { - ep->dbe_lop = (long)get_lo(dbp, cp, - cplen, m, to_min); - /* LINTED */ - tlop = (struct link_object *) - &AP(dbp)[ep->dbe_lop]; - (void) strcpy(&AP(dbp)[tlop->lo_next], - dp->d_name); - continue; - } - for (ep = &(dbp->db_hash[index]); ep; - /* LINTED */ - ep = (struct dbe *)&AP(dbp)[ep->dbe_next]) { - /* LINTED */ - tlop = (struct link_object *) - &AP(dbp)[ep->dbe_lop]; - - /* - * Choose the highest minor version - */ - if ((tlop->lo_major == m) && - (strncmp(&AP(dbp)[tlop->lo_name], - cp, cplen) == 0) && - (*(&AP(dbp)[tlop->lo_name + - cplen]) == '\0')) { - if (verscmp(dp->d_name + to_min, - (char *)(&AP(dbp)[tlop->lo_next] - + to_min)) > 0) - (void) strcpy(&AP(dbp) - [tlop->lo_next], - dp->d_name); - break; - } - if (ep->dbe_next == 0) { - ep->dbe_next = RELPTR(dbp, - calloc(sizeof (struct dbe), 1)); - /* LINTED */ - ep = (struct dbe *) - &AP(dbp)[ep->dbe_next]; - ep->dbe_lop = (long)get_lo(dbp, - cp, cplen, m, to_min); - /* LINTED */ - tlop = (struct link_object *) - &AP(dbp)[ep->dbe_lop]; - (void) strcpy(&AP(dbp)[tlop->lo_next], - dp->d_name); - break; - } - } - } - fix_lo(dbp); - (void) close(fd); - return (dbp); -} - -/* - * Allocate and fill in the fields for a link_object - * Arguments: - * struct db *dbp; data base - * char *cp; ptr. to X of libX - * int cplen; length of X - * int m; major version - * int n; index to minor version - */ -static struct link_object * -get_lo(struct db *dbp, char *cp, int cplen, int m, int n) -{ - struct link_object *lop; /* link_object to be returned */ - struct link_object *tlop; /* working copy of the above */ - - /* - * Allocate a link object prototype in the database heap. - * Store the numeric major (interface) number, but the minor - * number is stored in the database as an index to the string - * representing the minor version. By keeping the minor version - * as a string, "subfields" (i.e., major.minor[.other.fields. etc.]) - * are permitted. Although not meaningful to the link editor, this - * permits run-time substitution of arbitrary customer revisions, - * although introducing the confusion of overloading the lo_minor - * field in the database (!) - */ - lop = (struct link_object *)RELPTR(dbp, - calloc(sizeof (struct link_object), 1)); - /* LINTED */ - tlop = (struct link_object *)&AP(dbp)[(long)lop]; - tlop->lo_major = m; - tlop->lo_minor = n; - - /* - * Allocate space for the complete path name on the host program's - * heap -- as we have to save it from the directory buffer which - * might otherwise get re-used on us. Note that this space - * is wasted -- we can not assume that it can be reclaimed. - */ - tlop->lo_next = (long)RELPTR(dbp, calloc(MAXNAMLEN, 1)); - - /* - * Store the prototype name in the link object in the database. - */ - tlop->lo_name = (long)RELPTR(dbp, calloc((cplen + 1), 1)); - (void) strncpy((char *)&AP(dbp)[tlop->lo_name], cp, cplen); - return (lop); -} - -/* - * Pull the "X" from libX, set name to X and return the - * length of X - */ -static int -extract_name(char **name) -{ - char *ls; /* string after LIB root */ - char *dp; /* string before first delimiter */ - - if (strncmp(*name, MSG_ORIG(MSG_FIL_LIB), MSG_FIL_LIB_SIZE) == 0) { - ls = *name + MSG_FIL_LIB_SIZE; - if ((dp = (char *)strchr(ls, '.')) != (char *)0) { - *name = ls; - return (dp - ls); - } - } - return (-1); -} - -/* - * Make a pass through the data base to set the dbe_name of a dbe. This - * is necessary because there may be several revisions of a library - * but only one will be chosen. - */ -static void -fix_lo(struct db *dbp) -{ - int i; /* loop temporary */ - int dirlen = strlen(&AP(dbp)[dbp->db_name]); - /* length of directory pathname */ - char *cp; /* working temporary */ - char *tp; /* working temporary */ - struct dbe *ep; /* working copy of dbe */ - struct link_object *lop; /* working copy of link_object */ - - for (i = 0; i < DB_HASH; i++) { - for (ep = &(dbp->db_hash[i]); ep && ep->dbe_lop; - (ep = ep->dbe_next == 0 ? NULL : - /* LINTED */ - (struct dbe *)&AP(dbp)[ep->dbe_next])) { - /* LINTED */ - lop = (struct link_object *)&AP(dbp)[ep->dbe_lop]; - tp = &AP(dbp)[lop->lo_next]; - ep->dbe_name = RELPTR(dbp, - calloc((dirlen + strlen(tp) + 2), 1)); - lop->lo_minor += dirlen + 1; - cp = strncpy(&AP(dbp)[ep->dbe_name], - &AP(dbp)[dbp->db_name], dirlen); - cp = strncpy(cp + dirlen, MSG_ORIG(MSG_STR_SLASH), - MSG_STR_SLASH_SIZE); - (void) strcpy(cp + 1, tp); - } - } -} - -/* - * Allocate a new dbd, append it after dbdpp and set the dbd_dbp to dbp. - * Arguments: - * struct dbd **dbdpp; insertion point - * struct db *dbp; db associated with this dbd - */ -static struct dbd * -new_dbd(struct dbd **dbdpp, struct db *dbp) -{ - struct dbd *dbdp; /* working dbd ptr. */ - - dbdp = malloc(sizeof (struct dbd)); - dbdp->dbd_db = dbp; - dbdp->dbd_next = NULL; - *dbdpp = dbdp; - return (dbdp); -} - -/* - * Calculate hash index for link object. - * This is based on X.major from libX.so.major.minor. - * Arguments: - * char *np; X of libX - * int nchrs; no of chrs. to hash on - * int m; the major version - */ -static int -hash(char *np, int nchrs, int m) -{ - int h; /* for loop counter */ - char *cp; /* working (char *) ptr */ - - for (h = 0, cp = np; h < nchrs; h++, cp++) - h = (h << 1) + *cp; - h += (h << 1) + m; - h = ((h & 0x7fffffff) % DB_HASH); - return (h); -} - -/* - * Test whether the string is of digit[.digit]* format - */ -static int -rest_ok(char *str) -{ - int dummy; /* integer place holder */ - int legal = 1; /* return flag */ - - while (!EMPTY(str)) { - if (!stol(str, '.', &str, &dummy)) { - legal = 0; - break; - } - if (EMPTY(str)) - break; - else - /* LINTED */ - (SKIP_DOT(str)); - } - return (legal); -} - -/* - * Compare 2 strings and test whether they are of the form digit[.digit]*. - * It will return -1, 0, or 1 depending on whether c1p is less, equal or - * greater than c2p - */ -static int -verscmp(const char *c1p, const char *c2p) -{ - char *l_c1p = (char *)c1p; /* working copy of c1p */ - char *l_c2p = (char *)c2p; /* working copy of c2p */ - int l_c1p_ok = 0; /* is c1p a legal string */ - int c2p_dig = 0; /* int that c1p currently */ - /* represents */ - int c1p_dig = 0; /* int that c2p currently */ - /* represents */ - - while (((l_c1p_ok = stol(l_c1p, '.', &l_c1p, &c1p_dig)) == 1) && - stol(l_c2p, '.', &l_c2p, &c2p_dig) && (c2p_dig == c1p_dig)) { - if (EMPTY(l_c1p) && EMPTY(l_c2p)) - return (0); - else if (EMPTY(l_c1p) && !EMPTY(l_c2p) && - rest_ok(SKIP_DOT(l_c2p))) - return (-1); - else if (EMPTY(l_c2p) && !EMPTY(l_c1p) && - rest_ok(SKIP_DOT(l_c1p))) - return (1); - l_c1p++; l_c2p++; - }; - if (!l_c1p_ok) - return (-1); - else if (c1p_dig < c2p_dig) - return (-1); - else if ((c1p_dig > c2p_dig) && rest_ok(SKIP_DOT(l_c1p))) - return (1); - else return (-1); -} - -/* - * "stol" attempts to interpret a collection of characters between delimiters - * as a decimal digit. It stops interpreting when it reaches a delimiter or - * when character does not represent a digit. In the first case it returns - * success and the latter failure. - * Arguments: - * char *cp; ptr to input string - * char delimit; delimiter - * char **ptr; left pointing to next del. or - * illegal character - * int *i; digit that the string represents - */ -static int -stol(char *cp, char delimit, char **ptr, int *i) -{ - int c = 0; /* current char */ - int n = 0; /* working copy of i */ - int neg = 0; /* is number negative */ - - if (ptr != (char **)0) - *ptr = cp; /* in case no number is formed */ - - if (EMPTY(cp)) - return (0); - - if (!isdigit(c = *cp) && (c == '-')) { - neg++; - c = *++cp; - }; - if (EMPTY(cp) || !isdigit(c)) - return (0); - - while (isdigit(c = *cp) && (*cp++ != '\0')) { - n *= 10; - n += c - '0'; - }; - if (ptr != (char **)0) - *ptr = cp; - - if ((*cp == '\0') || (*cp == delimit)) { - *i = neg ? -n : n; - return (1); - }; - return (0); -} diff --git a/usr/src/cmd/sgs/rtld/common/config_elf.c b/usr/src/cmd/sgs/rtld/common/config_elf.c index 54539e5924..14210cbc57 100644 --- a/usr/src/cmd/sgs/rtld/common/config_elf.c +++ b/usr/src/cmd/sgs/rtld/common/config_elf.c @@ -181,19 +181,20 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) * * A configuration file can be specified using the LD_CONFIG environment * variable, from a DT_CONFIG string recorded in the executable (see ld(1) -c), - * or in the case of a crle() dumped image, the file is "fabricated" to a + * or in the case of a crle(1) dumped image, the file is "fabricated" to a * configuration file that may have been associated with the dumped image. In * the absence of any of these techniques, a default configuration file is used. * - * The LD_CONFIG variable take precedence, unless the application is secure, in - * which case the environment variable is ignored (see ld_generic_env()). + * The LD_CONFIG variable takes precedence, unless the application is secure + * (see ld.so.1(1), issetugid(2)), in which case the environment variable is + * ignored (see ld_generic_env()). * * A DT_CONFIG string is honored, even if the application is secure. However, * the path name follows the same rules as RUNPATH's, which must be a full path * name with no use of $ORIGIN. */ int -elf_config(Rt_map *lmp, int aout) +elf_config(Rt_map *lmp) { Rtc_id *id; Rtc_head *head; @@ -349,20 +350,7 @@ elf_config(Rt_map *lmp, int aout) (LA_SER_SECURE | LA_SER_CONFIG), PD_TKN_CAP) != 0) features |= CONF_ESLIBPATH; } -#if defined(__sparc) && !defined(_ELF64) - if (head->ch_adlibpath) { - str = (const char *)(head->ch_adlibpath + addr); - if (expand_paths(lmp, str, &aout_def_dirs, AL_CNT_SEARCH, - (LA_SER_DEFAULT | LA_SER_CONFIG), PD_TKN_CAP) != 0) - features |= CONF_ADLIBPATH; - } - if (head->ch_aslibpath) { - str = (const char *)(head->ch_aslibpath + addr); - if (expand_paths(lmp, str, &aout_sec_dirs, AL_CNT_SEARCH, - (LA_SER_SECURE | LA_SER_CONFIG), PD_TKN_CAP) != 0) - features |= CONF_ASLIBPATH; - } -#endif + /* * Apply any environment variables. This attribute was added with * RTC_VER_THREE. @@ -370,7 +358,7 @@ elf_config(Rt_map *lmp, int aout) if ((head->ch_version >= RTC_VER_THREE) && head->ch_env && (!(rtld_flags & RT_FL_NOENVCFG))) { if (readenv_config((Rtc_env *)(head->ch_env + addr), - addr, aout) != 0) + addr) != 0) return (-1); features |= CONF_ENVS; } diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c index c8def82f61..d1d5ae3c59 100644 --- a/usr/src/cmd/sgs/rtld/common/elf.c +++ b/usr/src/cmd/sgs/rtld/common/elf.c @@ -126,8 +126,8 @@ elf_get_sec_dirs() } /* - * For a.out we have actual work to do here, on ELF we just perform path - * expansion. + * For ELF objects we only need perform path expansion. Latent support for + * other objects may require further work */ static int elf_fix_name(const char *name, Rt_map *clmp, Alist **alpp, Aliste alni, @@ -211,7 +211,7 @@ elf_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name, /* * Determine if we're an elf file. If not simply return, we don't set * any rejection information as this test allows use to scroll through - * the objects we support (ELF, AOUT). + * the objects we support (ELF). */ if (size < sizeof (Ehdr) || caddr[EI_MAG0] != ELFMAG0 || @@ -2289,8 +2289,8 @@ elf_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize, } else if ((cap = CAP(lmp)) != NULL) { /* - * Processing of the a.out and ld.so.1 does not involve a file - * descriptor as exec() did all the work, so capture the + * Processing of the executable and ld.so.1 does not involve a + * file descriptor as exec() did all the work, so capture the * capabilities for these cases. */ while (cap->c_tag != CA_SUNW_NULL) { diff --git a/usr/src/cmd/sgs/rtld/common/remove.c b/usr/src/cmd/sgs/rtld/common/remove.c index aa3e59d86d..d03ddb11a6 100644 --- a/usr/src/cmd/sgs/rtld/common/remove.c +++ b/usr/src/cmd/sgs/rtld/common/remove.c @@ -40,13 +40,13 @@ * necessary), but other than this all object removal is driven by inspecting * the components of a handle. * - * Things to note. The creation of a link-map, and its addition to the link-map - * list occurs in {elf|aout}_new_lm(), if this returns success the link-map is - * valid and added, otherwise any steps (allocations) in the process of creating - * the link-map would have been undone. If a failure occurs between creating - * the link-map and adding it to a handle, remove_so() is called to remove the - * link-map. If a failures occurs after a handle have been created, - * remove_hdl() is called to remove the handle and the link-map. + * Things to note. The creation of a link-map, and its addition to the + * link-map list occurs in elf_new_lm(), if this returns success the link-map + * is valid and added, otherwise any steps (allocations) in the process of + * creating the link-map would have been undone. If a failure occurs between + * creating the link-map and adding it to a handle, remove_so() is called to + * remove the link-map. If a failures occurs after a handle have been + * created, remove_hdl() is called to remove the handle and the link-map. */ #include <string.h> @@ -256,7 +256,7 @@ remove_so(Lm_list *lml, Rt_map *lmp, Rt_map *clmp) Aliste idx1; for (APLIST_TRAVERSE(dynlm_list, idx1, nlml)) { - Rt_map *hlmp = nlml->lm_head; + Rt_map *hlmp = nlml->lm_head; Audit_client *acp; Aliste idx2; @@ -1178,7 +1178,7 @@ remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed) continue; for (APLIST_TRAVERSE(DEPENDS(lmp), idx3, bdp)) { - Aliste idx4; + Aliste idx4; Grp_desc *gdp4; Rt_map *dlmp = bdp->b_depend; diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg index 94c5c5bf51..7d0f45c9e0 100644 --- a/usr/src/cmd/sgs/rtld/common/rtld.msg +++ b/usr/src/cmd/sgs/rtld/common/rtld.msg @@ -398,7 +398,6 @@ @ MSG_LD_SIGNAL "SIGNAL" @ MSG_LD_TRACE_OBJS "TRACE_LOADED_OBJECTS" @ MSG_LD_TRACE_OBJS_E "TRACE_LOADED_OBJECTS_E" -@ MSG_LD_TRACE_OBJS_A "TRACE_LOADED_OBJECTS_A" @ MSG_LD_TRACE_PTHS "TRACE_SEARCH_PATHS" @ MSG_LD_UNREF "UNREF" @ MSG_LD_UNUSED "UNUSED" diff --git a/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg b/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg index 99b623803d..a25bd1bcb6 100644 --- a/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg +++ b/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg @@ -28,28 +28,7 @@ # Message file for cmd/sgs/rtld (ld.so.1) - 32bit sparc specific. -# General error diagnostics (a.out) - -@ MSG_REL_OVERFLOW "relocation error: file %s: symbol %s: \ - value 0x%x overflows %d bits at offset 0x%x" - -@ MSG_GEN_OLDREV "%s: has older revision than expected %s" - -@ MSG_SYS_PROC "/proc error: %s" - @ _END_ -@ MSG_STR_AOUT "AOUT" - -@ MSG_FMT_4XPATH "./%s" -@ MSG_FMT_4XLIB "lib%s.so.%d.%d" - -@ MSG_FIL_DOTSODOT ".so." -@ MSG_FIL_LIB "lib" - -@ MSG_PTH_USRLCLIB "/usr/local/lib" - @ MSG_SYM_LAV8PLTENTER "la_sparcv8_pltenter" -@ MSG_FMT_PROC "/proc/%d" - diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c index 3bd4af5c5d..43a72fcd1e 100644 --- a/usr/src/cmd/sgs/rtld/common/setup.c +++ b/usr/src/cmd/sgs/rtld/common/setup.c @@ -53,7 +53,6 @@ #include "_rtld.h" #include "_audit.h" #include "_elf.h" -#include "_a.out.h" #include "msg.h" @@ -193,7 +192,7 @@ Rt_map * setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, char *_rtldname, ulong_t ld_base, ulong_t interp_base, int fd, Phdr *phdr, char *execname, char **argv, uid_t uid, uid_t euid, gid_t gid, gid_t egid, - void *aoutdyn, int auxflags, uint_t *hwcap) + int auxflags, uint_t *hwcap) { Rt_map *rlmp, *mlmp, *clmp, **tobj = NULL; Ehdr *ehdr; @@ -367,7 +366,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, * arguments. */ if (rtld_getopt(argv, &envp, &auxv, &(lml_main.lm_flags), - &(lml_main.lm_tflags), (aoutdyn != 0)) == 1) { + &(lml_main.lm_tflags)) == 1) { eprintf(&lml_main, ERR_NONE, MSG_INTL(MSG_USG_BADOPT)); return (0); } @@ -393,7 +392,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, if (ealp) { if (((rtld_flags & RT_FL_NOENVIRON) == 0) && (procenv_user(ealp, &(lml_main.lm_flags), - &(lml_main.lm_tflags), (aoutdyn != 0)) == 1)) + &(lml_main.lm_tflags)) == 1)) return (0); free(ealp); } @@ -524,67 +523,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, } } } else { - /* - * Set up function ptr and arguments according to the type - * of file class the executable is. (Currently only supported - * types are ELF and a.out format.) Then create a link map - * for the executable. - */ - if (aoutdyn) { -#ifdef A_OUT - mmapobj_result_t *mpp; - - /* - * Create a mapping structure sufficient to describe - * a single two segments. The ADDR() of the a.out is - * established as 0, which is required but the AOUT - * relocation code. - */ - if ((mpp = - calloc(sizeof (mmapobj_result_t), 2)) == NULL) - return (0); - - if ((fdm.fd_nname = - stravl_insert(execname, 0, 0, 0)) == NULL) - return (0); - if ((mlmp = aout_new_lmp(&lml_main, ALIST_OFF_DATA, - &fdm, 0, 0, aoutdyn, NULL, NULL)) == NULL) - return (0); - - /* - * Establish the true mapping information for the a.out. - */ - if (aout_get_mmap(&lml_main, mpp)) { - free(mpp); - return (0); - } - - MSIZE(mlmp) = - (size_t)(mpp[1].mr_addr + mpp[1].mr_msize) - - S_ALIGN((size_t)mpp[0].mr_addr, syspagsz); - MMAPS(mlmp) = mpp; - MMAPCNT(mlmp) = 2; - PADSTART(mlmp) = (ulong_t)mpp->mr_addr; - PADIMLEN(mlmp) = mpp->mr_msize; - - /* - * Disable any object configuration cache (BCP apps - * bring in sbcp which can benefit from any object - * cache, but both the app and sbcp can't use the same - * objects). - */ - rtld_flags |= RT_FL_NOOBJALT; - - /* - * Make sure no-direct bindings are in effect. - */ - lml_main.lm_tflags |= LML_TFLG_NODIRECT; -#else - eprintf(&lml_main, ERR_FATAL, - MSG_INTL(MSG_ERR_REJ_UNKFILE), argvname); - return (0); -#endif - } else if (phdr) { + if (phdr != NULL) { Phdr *pptr; Off i_offset = 0; Addr base = 0; @@ -802,7 +741,8 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, /* * Determine the dev/inode information for the executable to complete - * load_so() checking for those who might dlopen(a.out). + * load_so() checking for those who might call dlopen(3c) on the + * executable . */ if (rtld_stat(PATHNAME(mlmp), &status) == 0) { STDEV(mlmp) = status.st_dev; @@ -813,7 +753,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, * Initialize any configuration information. */ if (!(rtld_flags & RT_FL_NOCFG)) { - if ((features = elf_config(mlmp, (aoutdyn != 0))) == -1) + if ((features = elf_config(mlmp)) == -1) return (0); } @@ -928,10 +868,6 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, DBG_CALL(Dbg_file_elf(&lml_main, PATHNAME(mlmp), ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr, ALIST_OFF_DATA)); - } else { - DBG_CALL(Dbg_file_aout(&lml_main, PATHNAME(mlmp), - ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr, - ALIST_OFF_DATA)); } } diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index 7d3d193c4c..654b626aa0 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -1447,7 +1447,7 @@ static u_longlong_t cmdisa = 0; /* command line (-e) ISA */ */ static void ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, - Word *lmtflags, uint_t env_flags, int aout) + Word *lmtflags, uint_t env_flags) { u_longlong_t variable = 0; ushort_t select = 0; @@ -1510,9 +1510,11 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, } else if ((len == MSG_LD_BIND_NOT_SIZE) && (strncmp(s1, MSG_ORIG(MSG_LD_BIND_NOT), MSG_LD_BIND_NOT_SIZE) == 0)) { /* - * Another trick, enabled to help debug AOUT - * applications under BCP, but not documented for - * general use. + * Another trick, initially implemented to help debug + * a.out executables under SunOS 4 binary + * compatibility (now removed), not documented for + * general use, but still useful for debugging around + * the PLT, etc. */ select |= SEL_ACT_RT; val = RT_FL_NOBIND; @@ -1819,10 +1821,8 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, (strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS), MSG_LD_TRACE_OBJS_SIZE) == 0)) || ((len == MSG_LD_TRACE_OBJS_E_SIZE) && - (((strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS_E), - MSG_LD_TRACE_OBJS_E_SIZE) == 0) && !aout) || - ((strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS_A), - MSG_LD_TRACE_OBJS_A_SIZE) == 0) && aout)))) { + (strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS_E), + MSG_LD_TRACE_OBJS_E_SIZE) == 0))) { char *s0 = (char *)s1; select |= SEL_ACT_SPEC_2; @@ -2120,7 +2120,7 @@ ld_arch_env(const char *s1, size_t *len) */ static int ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, - uint_t env_flags, int aout) + uint_t env_flags) { char *nstr, *sstr, *estr = NULL; size_t nlen, len; @@ -2195,7 +2195,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, */ if ((flags |= ld_arch_env(nstr, &nlen)) != ENV_TYP_IGNORE) { ld_generic_env(nstr, nlen, estr, lmflags, - lmtflags, (env_flags | flags), aout); + lmtflags, (env_flags | flags)); } if (len == 0) break; @@ -2214,7 +2214,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, */ int rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, - Word *lmtflags, int aout) + Word *lmtflags) { int ndx; @@ -2251,7 +2251,7 @@ rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, (str[3] != '\0')) str += 3; if (ld_flags_env(str, lmflags, lmtflags, - ENV_TYP_CMDLINE, aout) == 1) + ENV_TYP_CMDLINE) == 1) return (1); } @@ -2274,8 +2274,7 @@ rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, * Process a single LD_XXXX string. */ static void -ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags, - int aout) +ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags) { const char *s2; size_t len; @@ -2317,7 +2316,7 @@ ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags, return; env_flags |= flags; - ld_generic_env(s1, len, s2, lmflags, lmtflags, env_flags, aout); + ld_generic_env(s1, len, s2, lmflags, lmtflags, env_flags); } /* @@ -2414,20 +2413,20 @@ readenv_user(const char **envp, APlist **ealpp) * Process any LD_XXXX environment variables collected by readenv_user(). */ int -procenv_user(APlist *ealp, Word *lmflags, Word *lmtflags, int aout) +procenv_user(APlist *ealp, Word *lmflags, Word *lmtflags) { Aliste idx; const char *s1; for (APLIST_TRAVERSE(ealp, idx, s1)) - ld_str_env(s1, lmflags, lmtflags, 0, aout); + ld_str_env(s1, lmflags, lmtflags, 0); /* * Having collected the best representation of any LD_FLAGS, process * these strings. */ if (rpl_ldflags) { - if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0, aout) == 1) + if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0) == 1) return (1); rpl_ldflags = NULL; } @@ -2460,11 +2459,11 @@ procenv_user(APlist *ealp, Word *lmflags, Word *lmtflags, int aout) } /* - * Configuration environment processing. Called after the a.out has been - * processed (as the a.out can specify its own configuration file). + * Configuration environment processing. Called after the executable has been + * processed (as the executable can specify its own configuration file). */ int -readenv_config(Rtc_env * envtbl, Addr addr, int aout) +readenv_config(Rtc_env * envtbl, Addr addr) { Word *lmflags = &(lml_main.lm_flags); Word *lmtflags = &(lml_main.lm_tflags); @@ -2481,7 +2480,7 @@ readenv_config(Rtc_env * envtbl, Addr addr, int aout) if ((*s1++ == 'L') && (*s1++ == 'D') && (*s1++ == '_') && (*s1 != '\0')) - ld_str_env(s1, lmflags, lmtflags, env_flags, 0); + ld_str_env(s1, lmflags, lmtflags, env_flags); envtbl++; } @@ -2490,10 +2489,10 @@ readenv_config(Rtc_env * envtbl, Addr addr, int aout) * Having collected the best representation of any LD_FLAGS, process * these strings. */ - if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0, aout) == 1) + if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0) == 1) return (1); - if (ld_flags_env(prm_ldflags, lmflags, lmtflags, ENV_TYP_CONFIG, - aout) == 1) + if (ld_flags_env(prm_ldflags, lmflags, lmtflags, + ENV_TYP_CONFIG) == 1) return (1); /* @@ -2931,14 +2930,17 @@ veprintf(Lm_list *lml, Error error, const char *format, va_list args) err_strs[ERR_GUIDANCE] = MSG_INTL(MSG_ERR_GUIDANCE); break; - case ERR_FATAL: - if (err_strs[ERR_FATAL] == NULL) - err_strs[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); - break; case ERR_ELF: if (err_strs[ERR_ELF] == NULL) err_strs[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); break; + /* If this API is mis-used, create a fatal error */ + case ERR_FATAL: + default: + if (err_strs[ERR_FATAL] == NULL) + err_strs[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); + break; + } if (procname) { if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR1), diff --git a/usr/src/cmd/sgs/rtld/i386/_setup.c b/usr/src/cmd/sgs/rtld/i386/_setup.c index 3dc934852f..da208c45cd 100644 --- a/usr/src/cmd/sgs/rtld/i386/_setup.c +++ b/usr/src/cmd/sgs/rtld/i386/_setup.c @@ -235,7 +235,7 @@ _setup(Boot *ebp, Dyn *ld_dyn) */ if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, _syspagsz, _rt_name, ld_base, interp_base, fd, phdr, - _execname, _argv, uid, euid, gid, egid, NULL, auxflags, + _execname, _argv, uid, euid, gid, egid, auxflags, hwcap)) == NULL) { rtldexit(&lml_main, 1); } diff --git a/usr/src/cmd/sgs/rtld/i386/boot.s b/usr/src/cmd/sgs/rtld/i386/boot.s index 3d2e8178d6..68bb9b42de 100644 --- a/usr/src/cmd/sgs/rtld/i386/boot.s +++ b/usr/src/cmd/sgs/rtld/i386/boot.s @@ -68,7 +68,7 @@ * find the addr of the dynamic section of ld.so, of argv[0], and of * the process' environment pointers - and pass the thing to _setup * to handle. We then call _rtld - on return we jump to the entry - * point for the a.out. + * point for the executable. */ #if defined(lint) @@ -132,7 +132,7 @@ _rt_boot: movl %ebp,%esp / release stack frame movl atexit_fini@GOT(%ebx), %edx - jmp *%eax / transfer control to a.out + jmp *%eax / transfer control to the executable .size _rt_boot,.-_rt_boot #endif diff --git a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg index 3db84efa8e..21389ddeec 100644 --- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg +++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg @@ -195,7 +195,7 @@ # Error messages # @ MSG_ERR_NAS "%s:: no address specified\n" -@ MSG_ERR_READ "%s:: failed to read from: 0x%p\n" +@ MSG_ERR_READ "%s:: failed to read from: 0x%p\n" @ MSG_ERR_SYMFAILED "rtmaps:: lookup of %s`%s failed\n" # @@ -448,7 +448,7 @@ \t lmco rtmap ADDR() NAME()\n\ \t ---------------------------------------------\n\ \t [0xc] 0xff3f7cc0 0xff3c0000 /lib/ld.so.1\n" - + # # Rt_map messages. @@ -580,7 +580,7 @@ \t Callers: 0xff3b08cc APlist[used 1: total 4]\n\ \t ----------------------------------------------\n\ \t Binding descriptor located at: 0xff3b0514\n\ - \t caller: 0xff3b0214 a.out\n\ + \t caller: 0xff3b0214 executable\n\ \t depend: 0xff3b0554 /lib/libc.so.1\n\ \t flags: 0x00000003 [ NEEDED,REFERENCED ]\n" diff --git a/usr/src/cmd/sgs/rtld/sparc/Makefile b/usr/src/cmd/sgs/rtld/sparc/Makefile index 2785c30fcf..dc1464285c 100644 --- a/usr/src/cmd/sgs/rtld/sparc/Makefile +++ b/usr/src/cmd/sgs/rtld/sparc/Makefile @@ -25,7 +25,7 @@ # # Object lists are organized into primary (most frequently used code) and -# secondary lists (less frequently used code, ie. a.out support). +# secondary lists (less frequently used code) P_COMOBJS= debugdata.o \ analyze.o elf.o external.o globals.o \ @@ -33,8 +33,7 @@ P_COMOBJS= debugdata.o \ dlfcns.o config_elf.o locale.o tsort.o \ remove.o move.o tls.o cap.o -S_COMOBJS= debug.o audit.o object.o cache_a.out.o \ - a.out.o +S_COMOBJS= debug.o audit.o object.o G_MACHOBJS= doreloc.o @@ -42,12 +41,8 @@ P_MACHOBJS= sparc_elf.o _setup.o CP_MACHOBJS= common_sparc.o -S_MACHOBJS= sparc_a.out.o - P_ASOBJS= boot.o boot_elf.o caller.o -S_ASOBJS= boot_a.out.o - CRTSRCS= ../../../../lib/crt/sparc CRTI= pics/crti.o CRTN= pics/crtn.o @@ -65,9 +60,9 @@ $(__GNUC)MAPFILE-ORDER = ../common/mapfile-order-gcc include $(SRC)/cmd/sgs/rtld/Makefile.com -# Add any a.out and machine specific flags. +# Add any machine specific flags. -CPPFLAGS += -I../../../../uts/sparc/krtld -DA_OUT +CPPFLAGS += -I../../../../uts/sparc/krtld CFLAGS += -xregs=no%appl ASFLAGS += $(AS_PICFLAGS) ADBGENCFLAGS += -erroff=%all diff --git a/usr/src/cmd/sgs/rtld/sparc/_setup.c b/usr/src/cmd/sgs/rtld/sparc/_setup.c index 0bd3e57944..9d57d580d0 100644 --- a/usr/src/cmd/sgs/rtld/sparc/_setup.c +++ b/usr/src/cmd/sgs/rtld/sparc/_setup.c @@ -53,9 +53,6 @@ #include "_rtld.h" #include "_audit.h" #include "msg.h" -#ifdef A_OUT -#include "_a.out.h" -#endif /* A_OUT */ /* VARARGS */ unsigned long @@ -76,9 +73,6 @@ _setup(Boot *ebp, Dyn *ld_dyn) gid_t gid = (gid_t)-1, egid = (gid_t)-1; char *_platform = NULL, *_execname = NULL, *_emulator = NULL; int auxflags = -1; -#ifdef A_OUT - void *aoutdyn = NULL; -#endif /* A_OUT */ /* * Scan the bootstrap structure to pick up the basics. @@ -86,9 +80,6 @@ _setup(Boot *ebp, Dyn *ld_dyn) for (; ebp->eb_tag != EB_NULL; ebp++) switch (ebp->eb_tag) { case EB_DYNAMIC: -#ifdef A_OUT - aoutdyn = (Link_dynamic *)ebp->eb_un.eb_val; -#endif /* A_OUT */ break; case EB_LDSO_BASE: ld_base = (unsigned long)ebp->eb_un.eb_val; @@ -240,12 +231,8 @@ _setup(Boot *ebp, Dyn *ld_dyn) if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, _syspagsz, _rt_name, ld_base, interp_base, fd, phdr, _execname, _argv, uid, euid, gid, egid, -#ifdef A_OUT - aoutdyn, auxflags, hwcap)) == NULL) { -#else /* CSTYLED */ NULL, auxflags, hwcap)) == NULL) { -#endif /* A_OUT */ rtldexit(&lml_main, 1); } /* END CSTYLED */ diff --git a/usr/src/cmd/sgs/rtld/sparc/boot.s b/usr/src/cmd/sgs/rtld/sparc/boot.s index ace70a813b..e1a52299e1 100644 --- a/usr/src/cmd/sgs/rtld/sparc/boot.s +++ b/usr/src/cmd/sgs/rtld/sparc/boot.s @@ -26,13 +26,11 @@ * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* * Bootstrap routine for ld.so. Control arrives here either directly from * exec() upon invocation of a dynamically linked program specifying ld.so - * as its interpreter, or from the "a.out compatibility ld.so". Entry - * vector at "_rt_boot" used to discriminate between the two. + * as its interpreter. * * On entry, the stack appears as: * @@ -68,13 +66,6 @@ * ! ! * ! Window save area ! * !_______________________! <- %sp - * - * In the case of being invoked from the a.out compatibility ld.so, the stack - * has the appearance above but also several frames pushed by the compatibility - * routine. An "elf_boot" structure is available in %o1 on entry, which - * has been "pre-evaluated" to hold much of the information needed from the - * original stack frame -- we pass this directly into the main portion of the - * ld.so bootstrap. */ #if defined(lint) @@ -103,7 +94,7 @@ main() ! Entry vector ! +0: normal start -! +4: compatibility start +! +4: compatibility start, now an error ! +8: alias start (frame exists) _rt_boot: diff --git a/usr/src/cmd/sgs/rtld/sparc/boot_a.out.s b/usr/src/cmd/sgs/rtld/sparc/boot_a.out.s deleted file mode 100644 index 1c89dea106..0000000000 --- a/usr/src/cmd/sgs/rtld/sparc/boot_a.out.s +++ /dev/null @@ -1,132 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (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) 1991,1992 by Sun Microsystems, Inc. - */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "machdep.h" -#if defined(lint) -#include <sys/types.h> -#include "sgs.h" -#include "_a.out.h" -#else - - .file "boot_a.out.s" - .seg ".text" -#endif - -/* - * We got here because the initial call to a function resolved to a procedure - * linkage table entry. That entry did a branch to the first PLT entry, which - * in turn did a call to aout_rtbndr (refer aout_plt_init()). - * - * the code sequence that got us here was: - * - * PLT entry for foo(): - * save %sp, -0x60, %sp ! patched first - * call .PLT0 ! patched second - * sethi %hi(XXXXXXX), %g0 ! unchanged - * - * Therefore on entry, %i7 has the address of the call, which will be added - * to the offset to the plt entry in %g1 to calculate the plt entry address - * we must also subtract 4 for because the address of PLT0 points to the - * save instruction before the call - * - * the plt entry is rewritten: - * - * PLT entry for foo(): - * sethi %hi(entry_pt), %g1 - * jmpl %g1 + %lo(entry_pt), %g0 - */ - -#if defined(lint) - -void -aout_rtbndr(caddr_t pc) -{ - (void) aout_bndr(pc); -} - -#else - .global aout_rtbndr - .type aout_rtbndr, #function - .align 4 - -aout_rtbndr: - save %sp, -80, %sp - call aout_bndr ! returns function address in %o0 - add %i7, -0x4, %o0 ! %o0 now has address of PLT0 - mov %o0, %g1 ! save address of routine binded - restore ! how many restores needed ? 2 - jmp %g1 ! jump to it - restore - nop - .size aout_rtbndr, . - aout_rtbndr - -#endif - - -/* - * After the first call to a plt, aout_bndr() will have determined the true - * address of the function being bound. The plt is now rewritten so that - * any subsequent calls go directly to the bound function. - * - * the new plt entry is: - * - * sethi %hi(function address), %g1 ! patched first - * jmpl %g1 + %lo(function address, %g0 ! patched second - */ - -#if defined(lint) - -void -aout_plt_write(caddr_t pc, unsigned long symval) -{ - /* LINTED */ - *(unsigned long *)(pc) = (M_SETHIG1 | (symval >> (32 - 22))); - /* LINTED */ - *(unsigned long *)(pc + 4) = (M_JMPL | (symval & S_MASK(10))); - -} - -#else - .global aout_plt_write - .type aout_plt_write, #function - .align 4 - -aout_plt_write: - srl %o1, 10, %o2 ! Get high part of function address - sethi %hi(M_SETHIG1), %o3 ! Get sethi instruction - or %o3, %o2, %o3 ! Add sethi and function address - st %o3, [%o0] ! Store instruction in plt[0] - iflush %o0 - stbar - sethi %hi(M_JMPL), %o3 ! Get jmpl instruction - and %o1, 0x3ff, %o2 ! Lower part of function address - or %o3, %o2, %o3 ! is or'ed into instruction - st %o3, [%o0 + 4] ! Store instruction in plt[1] - retl - iflush %o0 + 4 - .size aout_plt_write, . - aout_plt_write - -#endif 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)); -} diff --git a/usr/src/cmd/sgs/rtld/sparcv9/Makefile b/usr/src/cmd/sgs/rtld/sparcv9/Makefile index 32cdec91fa..c887d2ef16 100644 --- a/usr/src/cmd/sgs/rtld/sparcv9/Makefile +++ b/usr/src/cmd/sgs/rtld/sparcv9/Makefile @@ -25,7 +25,7 @@ # # Object lists are organized into primary (most frequently used code) and -# secondary lists (less frequently used code, ie. a.out support). +# secondary lists (less frequently used code). P_COMOBJS= debugdata.o \ analyze.o elf.o external.o globals.o \ |
