From 26475619ed15fdce4c7b6ad4ef91f3c76d283dc8 Mon Sep 17 00:00:00 2001 From: christos Date: Mon, 1 Mar 1999 16:40:07 +0000 Subject: [PATCH] KNF --- include/link_elf.h | 28 +- libexec/ld.elf_so/arch/powerpc/ppc_reloc.c | 10 +- libexec/ld.elf_so/arch/sparc/mdreloc.c | 22 +- libexec/ld.elf_so/debug.c | 33 +- libexec/ld.elf_so/debug.h | 32 +- libexec/ld.elf_so/headers.c | 358 +++++------ libexec/ld.elf_so/link.h | 28 +- libexec/ld.elf_so/load.c | 113 ++-- libexec/ld.elf_so/malloc.c | 3 +- libexec/ld.elf_so/map_object.c | 368 ++++++------ libexec/ld.elf_so/paths.c | 108 ++-- libexec/ld.elf_so/reloc.c | 137 ++--- libexec/ld.elf_so/rtld.c | 659 +++++++++++---------- libexec/ld.elf_so/rtld.h | 207 ++++--- libexec/ld.elf_so/rtldenv.h | 67 ++- libexec/ld.elf_so/search.c | 151 ++--- libexec/ld.elf_so/symbol.c | 161 ++--- libexec/ld.elf_so/xmalloc.c | 33 +- libexec/ld.elf_so/xprintf.c | 482 ++++++++------- 19 files changed, 1578 insertions(+), 1422 deletions(-) diff --git a/include/link_elf.h b/include/link_elf.h index 941f7fd61dbe..2ba6712f3a9a 100644 --- a/include/link_elf.h +++ b/include/link_elf.h @@ -1,4 +1,4 @@ -/* $NetBSD: link_elf.h,v 1.3 1998/10/30 05:43:40 jonathan Exp $ */ +/* $NetBSD: link_elf.h,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * This only exists for GDB. @@ -11,24 +11,26 @@ #include struct link_map { - caddr_t l_addr; /* Base Address of library */ + caddr_t l_addr; /* Base Address of library */ #ifdef __mips__ - caddr_t l_offs; /* Load Offset of library */ + caddr_t l_offs; /* Load Offset of library */ #endif - const char *l_name; /* Absolute Path to Library */ - void *l_ld; /* Pointer to .dynamic in memory */ - struct link_map *l_next, *l_prev; /* linked list of of mapped libs */ + const char *l_name; /* Absolute Path to Library */ + void *l_ld; /* Pointer to .dynamic in memory */ + struct link_map *l_next; /* linked list of of mapped libs */ + struct link_map *l_prev; }; struct r_debug { - int r_version; /* not used */ - struct link_map *r_map; /* list of loaded images */ - void (*r_brk)(void); /* pointer to break point */ + int r_version; /* not used */ + struct link_map *r_map; /* list of loaded images */ + void (*r_brk) __P((void)); /* pointer to break point */ enum { - RT_CONSISTENT, /* things are stable */ - RT_ADD, /* adding a shared library */ - RT_DELETE /* removing a shared library */ - } r_state; + RT_CONSISTENT, /* things are stable */ + RT_ADD, /* adding a shared library */ + RT_DELETE /* removing a shared library */ + } r_state; }; + #endif /* _LINK_H */ diff --git a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c index e1efee4739df..49b4f4da4515 100644 --- a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c +++ b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: ppc_reloc.c,v 1.1 1998/11/24 11:34:31 tsubai Exp $ */ +/* $NetBSD: ppc_reloc.c,v 1.2 1999/03/01 16:40:08 christos Exp $ */ /*- * Copyright (C) 1998 Tsubai Masanari @@ -37,11 +37,11 @@ #include "debug.h" #include "rtld.h" -extern caddr_t _rtld_bind_powerpc(const Obj_Entry *, Elf_Word); -extern void _rtld_powerpc_pltcall(Elf_Word); -extern void _rtld_powerpc_pltresolve(Elf_Word, Elf_Word); +caddr_t _rtld_bind_powerpc __P((const Obj_Entry *, Elf_Word)); +void _rtld_powerpc_pltcall __P((Elf_Word)); +void _rtld_powerpc_pltresolve __P((Elf_Word, Elf_Word)); -static Elf_Addr _rtld_bind_pltgot(const Obj_Entry *, const Elf_RelA *); +static Elf_Addr _rtld_bind_pltgot __P((const Obj_Entry *, const Elf_RelA *)); #define ha(x) ((((u_int32_t)(x) & 0x8000) ? \ ((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16) diff --git a/libexec/ld.elf_so/arch/sparc/mdreloc.c b/libexec/ld.elf_so/arch/sparc/mdreloc.c index 37d616d8c243..97f256314715 100644 --- a/libexec/ld.elf_so/arch/sparc/mdreloc.c +++ b/libexec/ld.elf_so/arch/sparc/mdreloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: mdreloc.c,v 1.6 1999/02/27 17:12:13 pk Exp $ */ +/* $NetBSD: mdreloc.c,v 1.7 1999/03/01 16:40:08 christos Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -160,10 +160,10 @@ static int reloc_target_bitmask[] = { #define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t]) int -_rtld_relocate_nonplt_object( - const Obj_Entry *obj, - const Elf_RelA *rela, - bool dodebug) +_rtld_relocate_nonplt_object(obj, rela, dodebug) + const Obj_Entry *obj; + const Elf_RelA *rela; + bool dodebug; { Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset); Elf_Word type, value, mask; @@ -262,12 +262,12 @@ _rtld_relocate_nonplt_object( } int -_rtld_relocate_plt_object( - const Obj_Entry *obj, - const Elf_RelA *rela, - caddr_t *addrp, - bool bind_now, - bool dodebug) +_rtld_relocate_plt_object(obj, rela, addrp, bind_now, dodebug) + const Obj_Entry *obj; + const Elf_RelA *rela; + caddr_t *addrp; + bool bind_now; + bool dodebug; { const Elf_Sym *def; const Obj_Entry *defobj; diff --git a/libexec/ld.elf_so/debug.c b/libexec/ld.elf_so/debug.c index c4e277238753..138148d08859 100644 --- a/libexec/ld.elf_so/debug.c +++ b/libexec/ld.elf_so/debug.c @@ -1,4 +1,4 @@ -/* $NetBSD: debug.c,v 1.1 1996/12/16 20:37:57 cgd Exp $ */ +/* $NetBSD: debug.c,v 1.2 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -35,7 +35,12 @@ * Support for printing debugging messages. */ +#include +#ifdef __STDC__ #include +#else +#include +#endif #include "debug.h" #include "rtldenv.h" @@ -44,16 +49,28 @@ int debug = 0; void +#ifdef __STDC__ debug_printf(const char *format, ...) +#else +debug_printf(va_alist) + va_dcl +#endif { - if(debug) { - va_list ap; - va_start(ap, format); + if(debug) { + va_list ap; +#ifdef __STDC__ + va_start(ap, format); +#else + const char *format; - xvprintf(format, ap); + va_start(ap); + format = va_arg(ap, const char *); +#endif - va_end(ap); - xprintf("\n"); - } + xvprintf(format, ap); + + va_end(ap); + xprintf("\n"); + } } #endif diff --git a/libexec/ld.elf_so/debug.h b/libexec/ld.elf_so/debug.h index 20d5d8a5a551..fd1f3adb5cfc 100644 --- a/libexec/ld.elf_so/debug.h +++ b/libexec/ld.elf_so/debug.h @@ -1,4 +1,4 @@ -/* $NetBSD: debug.h,v 1.3 1999/02/24 18:31:00 christos Exp $ */ +/* $NetBSD: debug.h,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -35,30 +35,24 @@ * Support for printing debugging messages. */ -#ifndef DEBUG_H /* { */ -#define DEBUG_H 1 +#ifndef DEBUG_H +#define DEBUG_H -#ifndef __GNUC__ /* { */ -#error "Sorry, this module relies on some GNU extensions" -#endif /* } */ -extern void xprintf(const char *fmt, ...) - __attribute__((__format__(__printf__, 1, 2))); -extern void xvprintf(const char *fmt, va_list ap) - __attribute__((__format__(__printf__, 1, 0))); -extern void debug_printf(const char *, ...) +#ifdef DEBUG + +extern void debug_printf __P((const char *, ...)) __attribute__((__format__(__printf__, 1, 2))); extern int debug; -#ifdef DEBUG /* { */ -#define dbg(format, args...) debug_printf(format, ## args) -#else /* } { */ -#define dbg(format, args...) ((void) 0) -#endif /* } */ +# define dbg(a) debug_printf a +#else +# define dbg(a) ((void) 0) +#endif #ifdef RTLD_DEBUG_RELOC -#define rdbg(f, format, args...) if (f) debug_printf(format, ## args) +# define rdbg(f, a) if (f) debug_printf a #else -#define rdbg(f, format, args...) ((void) 0) +# define rdbg(f, a) ((void) 0) #endif -#endif /* } */ +#endif diff --git a/libexec/ld.elf_so/headers.c b/libexec/ld.elf_so/headers.c index 878671fb1cc1..dd16d4e821e2 100644 --- a/libexec/ld.elf_so/headers.c +++ b/libexec/ld.elf_so/headers.c @@ -1,4 +1,4 @@ -/* $NetBSD: headers.c,v 1.3 1999/02/24 18:31:00 christos Exp $ */ +/* $NetBSD: headers.c,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -57,181 +57,193 @@ * information in its Obj_Entry structure. */ void -_rtld_digest_dynamic( - Obj_Entry *obj) +_rtld_digest_dynamic(obj) + Obj_Entry *obj; { - Elf_Dyn *dynp; - Needed_Entry **needed_tail = &obj->needed; - const Elf_Dyn *dyn_rpath = NULL; - enum Elf_e_dynamic_type plttype = Elf_edt_rel; - Elf_Word relsize = 0, relasize = 0, pltrelsize = 0, pltrelasize = 0; + Elf_Dyn *dynp; + Needed_Entry **needed_tail = &obj->needed; + const Elf_Dyn *dyn_rpath = NULL; + enum Elf_e_dynamic_type plttype = Elf_edt_rel; + Elf_Word relsz = 0, relasz = 0; + Elf_Word pltrelsz = 0, pltrelasz = 0; - for (dynp = obj->dynamic; dynp->d_tag != Elf_edt_null; ++dynp) { - switch(dynp->d_tag) { + for (dynp = obj->dynamic; dynp->d_tag != Elf_edt_null; ++dynp) { + switch (dynp->d_tag) { - case Elf_edt_rel: - obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_rel: + obj->rel = (const Elf_Rel *) + (obj->relocbase + dynp->d_un.d_ptr); + break; - case Elf_edt_relsz: - relsize = dynp->d_un.d_val; - break; + case Elf_edt_relsz: + relsz = dynp->d_un.d_val; + break; - case Elf_edt_relent: - assert(dynp->d_un.d_val == sizeof(Elf_Rel)); - break; + case Elf_edt_relent: + assert(dynp->d_un.d_val == sizeof(Elf_Rel)); + break; - case Elf_edt_jmprel: - if (plttype == Elf_edt_rel) { - obj->pltrel = (const Elf_Rel *) - (obj->relocbase + dynp->d_un.d_ptr); - } else { - obj->pltrela = (const Elf_RelA *) - (obj->relocbase + dynp->d_un.d_ptr); - } - break; + case Elf_edt_jmprel: + if (plttype == Elf_edt_rel) { + obj->pltrel = (const Elf_Rel *) + (obj->relocbase + dynp->d_un.d_ptr); + } else { + obj->pltrela = (const Elf_RelA *) + (obj->relocbase + dynp->d_un.d_ptr); + } + break; - case Elf_edt_pltrelsz: - if (plttype == Elf_edt_rel) { - pltrelsize = dynp->d_un.d_val; - } else { - pltrelasize = dynp->d_un.d_val; - } - break; + case Elf_edt_pltrelsz: + if (plttype == Elf_edt_rel) { + pltrelsz = dynp->d_un.d_val; + } else { + pltrelasz = dynp->d_un.d_val; + } + break; - case Elf_edt_rela: - obj->rela = (const Elf_RelA *) (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_rela: + obj->rela = (const Elf_RelA *) + (obj->relocbase + dynp->d_un.d_ptr); + break; - case Elf_edt_relasz: - relasize = dynp->d_un.d_val; - break; + case Elf_edt_relasz: + relasz = dynp->d_un.d_val; + break; - case Elf_edt_relaent: - assert(dynp->d_un.d_val == sizeof(Elf_RelA)); - break; + case Elf_edt_relaent: + assert(dynp->d_un.d_val == sizeof(Elf_RelA)); + break; - case Elf_edt_pltrel: - plttype = dynp->d_un.d_val; - assert(plttype == Elf_edt_rel || plttype == Elf_edt_rela); - if (plttype == Elf_edt_rela) { - obj->pltrela = (const Elf_RelA *) obj->pltrel; - obj->pltrel = NULL; - pltrelasize = pltrelsize; - pltrelsize = 0; - } - break; + case Elf_edt_pltrel: + plttype = dynp->d_un.d_val; + assert(plttype == Elf_edt_rel || + plttype == Elf_edt_rela); + if (plttype == Elf_edt_rela) { + obj->pltrela = (const Elf_RelA *) obj->pltrel; + obj->pltrel = NULL; + pltrelasz = pltrelsz; + pltrelsz = 0; + } + break; - case Elf_edt_symtab: - obj->symtab = (const Elf_Sym *) - (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_symtab: + obj->symtab = (const Elf_Sym *) + (obj->relocbase + dynp->d_un.d_ptr); + break; - case Elf_edt_syment: - assert(dynp->d_un.d_val == sizeof(Elf_Sym)); - break; + case Elf_edt_syment: + assert(dynp->d_un.d_val == sizeof(Elf_Sym)); + break; - case Elf_edt_strtab: - obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_strtab: + obj->strtab = (const char *) + (obj->relocbase + dynp->d_un.d_ptr); + break; - case Elf_edt_strsz: - obj->strsize = dynp->d_un.d_val; - break; + case Elf_edt_strsz: + obj->strsize = dynp->d_un.d_val; + break; - case Elf_edt_hash: - { - const Elf_Word *hashtab = (const Elf_Word *) - (obj->relocbase + dynp->d_un.d_ptr); - obj->nbuckets = hashtab[0]; - obj->nchains = hashtab[1]; - obj->buckets = hashtab + 2; - obj->chains = obj->buckets + obj->nbuckets; - } - break; + case Elf_edt_hash: + { + const Elf_Word *hashtab = (const Elf_Word *) + (obj->relocbase + dynp->d_un.d_ptr); - case Elf_edt_needed: - assert(!obj->rtld); - { - Needed_Entry *nep = NEW(Needed_Entry); - nep->name = dynp->d_un.d_val; - nep->obj = NULL; - nep->next = NULL; + obj->nbuckets = hashtab[0]; + obj->nchains = hashtab[1]; + obj->buckets = hashtab + 2; + obj->chains = obj->buckets + obj->nbuckets; + } + break; - *needed_tail = nep; - needed_tail = &nep->next; - } - break; + case Elf_edt_needed: + assert(!obj->rtld); + { + Needed_Entry *nep = NEW(Needed_Entry); - case Elf_edt_pltgot: - obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); - break; + nep->name = dynp->d_un.d_val; + nep->obj = NULL; + nep->next = NULL; - case Elf_edt_textrel: - obj->textrel = true; - break; + *needed_tail = nep; + needed_tail = &nep->next; + } + break; - case Elf_edt_symbolic: - obj->symbolic = true; - break; + case Elf_edt_pltgot: + obj->pltgot = (Elf_Addr *) + (obj->relocbase + dynp->d_un.d_ptr); + break; - case Elf_edt_rpath: - /* - * We have to wait until later to process this, because we - * might not have gotten the address of the string table yet. - */ - dyn_rpath = dynp; - break; + case Elf_edt_textrel: + obj->textrel = true; + break; - case Elf_edt_soname: - /* Not used by the dynamic linker. */ - break; + case Elf_edt_symbolic: + obj->symbolic = true; + break; - case Elf_edt_init: - obj->init = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_rpath: + /* + * We have to wait until later to process this, because + * we might not have gotten the address of the string + * table yet. + */ + dyn_rpath = dynp; + break; - case Elf_edt_fini: - obj->fini = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr); - break; + case Elf_edt_soname: + /* Not used by the dynamic linker. */ + break; - case Elf_edt_debug: + case Elf_edt_init: + obj->init = (void (*) __P((void))) + (obj->relocbase + dynp->d_un.d_ptr); + break; + + case Elf_edt_fini: + obj->fini = (void (*) __P((void))) + (obj->relocbase + dynp->d_un.d_ptr); + break; + + case Elf_edt_debug: #ifdef RTLD_LOADER - dynp->d_un.d_ptr = (Elf_Addr) &_rtld_debug; + dynp->d_un.d_ptr = (Elf_Addr)&_rtld_debug; #endif - break; + break; #if defined(__mips__) - case DT_MIPS_LOCAL_GOTNO: - obj->local_gotno = dynp->d_un.d_val; - break; + case DT_MIPS_LOCAL_GOTNO: + obj->local_gotno = dynp->d_un.d_val; + break; - case DT_MIPS_SYMTABNO: - obj->symtabno = dynp->d_un.d_val; - break; + case DT_MIPS_SYMTABNO: + obj->symtabno = dynp->d_un.d_val; + break; - case DT_MIPS_GOTSYM: - obj->gotsym = dynp->d_un.d_val; - break; + case DT_MIPS_GOTSYM: + obj->gotsym = dynp->d_un.d_val; + break; - case DT_MIPS_RLD_MAP: + case DT_MIPS_RLD_MAP: #ifdef RTLD_LOADER - *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) &_rtld_debug; + *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) + &_rtld_debug; #endif - break; + break; #endif + } } - } - obj->rellim = (const Elf_Rel *) ((caddr_t) obj->rel + relsize); - obj->relalim = (const Elf_RelA *) ((caddr_t) obj->rela + relasize); - obj->pltrellim = (const Elf_Rel *) ((caddr_t) obj->pltrel + pltrelsize); - obj->pltrelalim = (const Elf_RelA *) ((caddr_t) obj->pltrela + pltrelasize); + obj->rellim = (const Elf_Rel *)((caddr_t)obj->rel + relsz); + obj->relalim = (const Elf_RelA *)((caddr_t)obj->rela + relasz); + obj->pltrellim = (const Elf_Rel *)((caddr_t)obj->pltrel + pltrelsz); + obj->pltrelalim = (const Elf_RelA *)((caddr_t)obj->pltrela + pltrelasz); - if (dyn_rpath != NULL) { - _rtld_add_paths(&obj->rpaths, obj->strtab + dyn_rpath->d_un.d_val, - true); - } + if (dyn_rpath != NULL) { + _rtld_add_paths(&obj->rpaths, obj->strtab + + dyn_rpath->d_un.d_val, true); + } } /* @@ -241,47 +253,47 @@ _rtld_digest_dynamic( * returns an Obj_Entry structure. */ Obj_Entry * -_rtld_digest_phdr( - const Elf_Phdr *phdr, - int phnum, - caddr_t entry) +_rtld_digest_phdr(phdr, phnum, entry) + const Elf_Phdr *phdr; + int phnum; + caddr_t entry; { - Obj_Entry *obj = CNEW(Obj_Entry); - const Elf_Phdr *phlimit = phdr + phnum; - const Elf_Phdr *ph; - int nsegs = 0; + Obj_Entry *obj = CNEW(Obj_Entry); + const Elf_Phdr *phlimit = phdr + phnum; + const Elf_Phdr *ph; + int nsegs = 0; - for (ph = phdr; ph < phlimit; ++ph) { - switch(ph->p_type) { + for (ph = phdr; ph < phlimit; ++ph) { + switch (ph->p_type) { - case Elf_pt_phdr: - assert((const Elf_Phdr *) ph->p_vaddr == phdr); - obj->phdr = (const Elf_Phdr *) ph->p_vaddr; - obj->phsize = ph->p_memsz; - break; + case Elf_pt_phdr: + assert((const Elf_Phdr *) ph->p_vaddr == phdr); + obj->phdr = (const Elf_Phdr *) ph->p_vaddr; + obj->phsize = ph->p_memsz; + break; - case Elf_pt_load: - assert(nsegs < 2); - if (nsegs == 0) { /* First load segment */ - obj->vaddrbase = round_down(ph->p_vaddr); - obj->mapbase = (caddr_t) obj->vaddrbase; - obj->relocbase = obj->mapbase - obj->vaddrbase; - obj->textsize = round_up(ph->p_vaddr + ph->p_memsz) - - obj->vaddrbase; - } else { /* Last load segment */ - obj->mapsize = round_up(ph->p_vaddr + ph->p_memsz) - - obj->vaddrbase; - } - ++nsegs; - break; + case Elf_pt_load: + assert(nsegs < 2); + if (nsegs == 0) { /* First load segment */ + obj->vaddrbase = round_down(ph->p_vaddr); + obj->mapbase = (caddr_t) obj->vaddrbase; + obj->relocbase = obj->mapbase - obj->vaddrbase; + obj->textsize = round_up(ph->p_vaddr + + ph->p_memsz) - obj->vaddrbase; + } else { /* Last load segment */ + obj->mapsize = round_up(ph->p_vaddr + + ph->p_memsz) - obj->vaddrbase; + } + ++nsegs; + break; - case Elf_pt_dynamic: - obj->dynamic = (Elf_Dyn *) ph->p_vaddr; - break; + case Elf_pt_dynamic: + obj->dynamic = (Elf_Dyn *) ph->p_vaddr; + break; + } } - } - assert(nsegs == 2); + assert(nsegs == 2); - obj->entry = entry; - return obj; + obj->entry = entry; + return obj; } diff --git a/libexec/ld.elf_so/link.h b/libexec/ld.elf_so/link.h index 7d4a378c6754..e38c891f9257 100644 --- a/libexec/ld.elf_so/link.h +++ b/libexec/ld.elf_so/link.h @@ -1,4 +1,4 @@ -/* $NetBSD: link.h,v 1.3 1998/10/30 05:43:40 jonathan Exp $ */ +/* $NetBSD: link.h,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * This only exists for GDB. @@ -11,24 +11,26 @@ #include struct link_map { - caddr_t l_addr; /* Base Address of library */ + caddr_t l_addr; /* Base Address of library */ #ifdef __mips__ - caddr_t l_offs; /* Load Offset of library */ + caddr_t l_offs; /* Load Offset of library */ #endif - const char *l_name; /* Absolute Path to Library */ - void *l_ld; /* Pointer to .dynamic in memory */ - struct link_map *l_next, *l_prev; /* linked list of of mapped libs */ + const char *l_name; /* Absolute Path to Library */ + void *l_ld; /* Pointer to .dynamic in memory */ + struct link_map *l_next; /* linked list of of mapped libs */ + struct link_map *l_prev; }; struct r_debug { - int r_version; /* not used */ - struct link_map *r_map; /* list of loaded images */ - void (*r_brk)(void); /* pointer to break point */ + int r_version; /* not used */ + struct link_map *r_map; /* list of loaded images */ + void (*r_brk) __P((void)); /* pointer to break point */ enum { - RT_CONSISTENT, /* things are stable */ - RT_ADD, /* adding a shared library */ - RT_DELETE /* removing a shared library */ - } r_state; + RT_CONSISTENT, /* things are stable */ + RT_ADD, /* adding a shared library */ + RT_DELETE /* removing a shared library */ + } r_state; }; + #endif /* _LINK_H */ diff --git a/libexec/ld.elf_so/load.c b/libexec/ld.elf_so/load.c index b862a604f3b4..11ad4d4fae0b 100644 --- a/libexec/ld.elf_so/load.c +++ b/libexec/ld.elf_so/load.c @@ -1,4 +1,4 @@ -/* $NetBSD: load.c,v 1.2 1999/02/24 18:31:00 christos Exp $ */ +/* $NetBSD: load.c,v 1.3 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -61,49 +61,49 @@ * on failure. */ Obj_Entry * -_rtld_load_object( - char *filepath, - bool dodebug) +_rtld_load_object(filepath, dodebug) + char *filepath; + bool dodebug; { - Obj_Entry *obj; + Obj_Entry *obj; - for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) - if (strcmp(obj->path, filepath) == 0) - break; + for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) + if (strcmp(obj->path, filepath) == 0) + break; - if (obj == NULL) { /* First use of this object, so we must map it in */ - int fd; + if (obj == NULL) { /* First use of this object, so we must map it in */ + int fd; - if ((fd = open(filepath, O_RDONLY)) == -1) { - _rtld_error("Cannot open \"%s\"", filepath); - return NULL; - } - obj = _rtld_map_object(filepath, fd); - close(fd); - if (obj == NULL) { - free(filepath); - return NULL; - } + if ((fd = open(filepath, O_RDONLY)) == -1) { + _rtld_error("Cannot open \"%s\"", filepath); + return NULL; + } + obj = _rtld_map_object(filepath, fd); + (void)close(fd); + if (obj == NULL) { + free(filepath); + return NULL; + } + obj->path = filepath; + _rtld_digest_dynamic(obj); - obj->path = filepath; - _rtld_digest_dynamic(obj); - - *_rtld_objtail = obj; - _rtld_objtail = &obj->next; + *_rtld_objtail = obj; + _rtld_objtail = &obj->next; #ifdef RTLD_LOADER - _rtld_linkmap_add(obj); /* for GDB */ + _rtld_linkmap_add(obj); /* for GDB */ #endif - if (dodebug) { - dbg(" %p .. %p: %s", obj->mapbase, - obj->mapbase + obj->mapsize - 1, obj->path); - if (obj->textrel) - dbg(" WARNING: %s has impure text", obj->path); - } - } else - free(filepath); + if (dodebug) { + dbg((" %p .. %p: %s", obj->mapbase, + obj->mapbase + obj->mapsize - 1, obj->path)); + if (obj->textrel) + dbg((" WARNING: %s has impure text", + obj->path)); + } + } else + free(filepath); - ++obj->refcount; - return obj; + ++obj->refcount; + return obj; } /* @@ -112,32 +112,33 @@ _rtld_load_object( * returns -1 on failure. */ int -_rtld_load_needed_objects( - Obj_Entry *first) +_rtld_load_needed_objects(first) + Obj_Entry *first; { - Obj_Entry *obj; - int status = 0; + Obj_Entry *obj; + int status = 0; - for (obj = first; obj != NULL; obj = obj->next) { - Needed_Entry *needed; + for (obj = first; obj != NULL; obj = obj->next) { + Needed_Entry *needed; - for (needed = obj->needed; needed != NULL; needed = needed->next) { - const char *name = obj->strtab + needed->name; - char *libpath = _rtld_find_library(name, obj); + for (needed = obj->needed; needed != NULL; + needed = needed->next) { + const char *name = obj->strtab + needed->name; + char *libpath = _rtld_find_library(name, obj); - if (libpath == NULL) { - status = -1; - } else { - needed->obj = _rtld_load_object(libpath, true); - if (needed->obj == NULL) - status = -1; /* FIXME - cleanup */ - } + if (libpath == NULL) { + status = -1; + } else { + needed->obj = _rtld_load_object(libpath, true); + if (needed->obj == NULL) + status = -1; /* FIXME - cleanup */ + } #ifdef RTLD_LOADER - if (status == -1) - return status; + if (status == -1) + return status; #endif + } } - } - return status; + return status; } diff --git a/libexec/ld.elf_so/malloc.c b/libexec/ld.elf_so/malloc.c index 839c14444ba5..4c7918996720 100644 --- a/libexec/ld.elf_so/malloc.c +++ b/libexec/ld.elf_so/malloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: malloc.c,v 1.2 1997/10/08 08:55:35 mrg Exp $ */ +/* $NetBSD: malloc.c,v 1.3 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright (c) 1983 Regents of the University of California. @@ -48,6 +48,7 @@ * This is designed for use in a virtual memory environment. */ +#include #include "rtldenv.h" #include #include diff --git a/libexec/ld.elf_so/map_object.c b/libexec/ld.elf_so/map_object.c index 351889037f97..236750178cb6 100644 --- a/libexec/ld.elf_so/map_object.c +++ b/libexec/ld.elf_so/map_object.c @@ -1,4 +1,4 @@ -/* $NetBSD: map_object.c,v 1.3 1998/02/20 09:27:20 mycroft Exp $ */ +/* $NetBSD: map_object.c,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -46,7 +46,7 @@ #define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) #define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) -static int protflags(int); /* Elf flags -> mmap protection */ +static int protflags __P((int)); /* Elf flags -> mmap protection */ /* * Map a shared object into memory. The argument is a file descriptor, @@ -56,202 +56,202 @@ static int protflags(int); /* Elf flags -> mmap protection */ * for the shared object. Returns NULL on failure. */ Obj_Entry * -_rtld_map_object( - const char *path, - int fd) +_rtld_map_object(path, fd) + const char *path; + int fd; { - Obj_Entry *obj; - union { - Elf_Ehdr hdr; - char buf[PAGESIZE]; - } u; - int nbytes; - Elf_Phdr *phdr; - Elf_Phdr *phlimit; - Elf_Phdr *segs[2]; - int nsegs; - Elf_Phdr *phdyn; - Elf_Phdr *phphdr; - caddr_t mapbase; - size_t mapsize; - Elf_Off base_offset; - Elf_Addr base_vaddr; - Elf_Addr base_vlimit; - caddr_t base_addr; - Elf_Off data_offset; - Elf_Addr data_vaddr; - Elf_Addr data_vlimit; - caddr_t data_addr; + Obj_Entry *obj; + union { + Elf_Ehdr hdr; + char buf[PAGESIZE]; + } u; + int nbytes; + Elf_Phdr *phdr; + Elf_Phdr *phlimit; + Elf_Phdr *segs[2]; + int nsegs; + Elf_Phdr *phdyn; + Elf_Phdr *phphdr; + caddr_t mapbase; + size_t mapsize; + Elf_Off base_offset; + Elf_Addr base_vaddr; + Elf_Addr base_vlimit; + caddr_t base_addr; + Elf_Off data_offset; + Elf_Addr data_vaddr; + Elf_Addr data_vlimit; + caddr_t data_addr; #ifdef RTLD_LOADER - Elf_Addr clear_vaddr; - caddr_t clear_addr; - size_t nclear; - Elf_Addr bss_vaddr; - Elf_Addr bss_vlimit; - caddr_t bss_addr; + Elf_Addr clear_vaddr; + caddr_t clear_addr; + size_t nclear; + Elf_Addr bss_vaddr; + Elf_Addr bss_vlimit; + caddr_t bss_addr; #endif - if ((nbytes = read(fd, u.buf, PAGESIZE)) == -1) { - _rtld_error("%s: read error: %s", path, xstrerror(errno)); - return NULL; - } + if ((nbytes = read(fd, u.buf, PAGESIZE)) == -1) { + _rtld_error("%s: read error: %s", path, xstrerror(errno)); + return NULL; + } + /* Make sure the file is valid */ + if (nbytes < sizeof(Elf_Ehdr) || + memcmp(Elf_e_ident, u.hdr.e_ident, Elf_e_siz) != 0) { + _rtld_error("%s: unrecognized file format", path); + return NULL; + } + /* Elf_e_ident includes class */ + if (u.hdr.e_ident[Elf_ei_version] != Elf_ev_current || + u.hdr.e_version != Elf_ev_current || + u.hdr.e_ident[Elf_ei_data] != ELFDEFNNAME(MACHDEP_ENDIANNESS)) { + _rtld_error("%s: Unsupported file version", path); + return NULL; + } + if (u.hdr.e_type != Elf_et_exec && u.hdr.e_type != Elf_et_dyn) { + _rtld_error("%s: Unsupported file type", path); + return NULL; + } + switch (u.hdr.e_machine) { + ELFDEFNNAME(MACHDEP_ID_CASES) + default: + _rtld_error("%s: Unsupported machine", path); + return NULL; + } - /* Make sure the file is valid */ - if (nbytes < sizeof(Elf_Ehdr) - || memcmp(Elf_e_ident, u.hdr.e_ident, Elf_e_siz) != 0) { - _rtld_error("%s: unrecognized file format", path); - return NULL; - } - /* Elf_e_ident includes class */ - if (u.hdr.e_ident[Elf_ei_version] != Elf_ev_current - || u.hdr.e_version != Elf_ev_current - || u.hdr.e_ident[Elf_ei_data] != ELFDEFNNAME(MACHDEP_ENDIANNESS)) { - _rtld_error("%s: Unsupported file version", path); - return NULL; - } - if (u.hdr.e_type != Elf_et_exec && u.hdr.e_type != Elf_et_dyn) { - _rtld_error("%s: Unsupported file type", path); - return NULL; - } - switch (u.hdr.e_machine) { - ELFDEFNNAME(MACHDEP_ID_CASES) + /* + * We rely on the program header being in the first page. This is + * not strictly required by the ABI specification, but it seems to + * always true in practice. And, it simplifies things considerably. + */ + assert(u.hdr.e_phentsize == sizeof(Elf_Phdr)); + assert(u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) <= PAGESIZE); + assert(u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) <= nbytes); - default: - _rtld_error("%s: Unsupported machine", path); - return NULL; - } + /* + * Scan the program header entries, and save key information. + * + * We rely on there being exactly two load segments, text and data, + * in that order. + */ + phdr = (Elf_Phdr *) (u.buf + u.hdr.e_phoff); + phlimit = phdr + u.hdr.e_phnum; + nsegs = 0; + phdyn = NULL; + phphdr = NULL; + while (phdr < phlimit) { + switch (phdr->p_type) { - /* - * We rely on the program header being in the first page. This is - * not strictly required by the ABI specification, but it seems to - * always true in practice. And, it simplifies things considerably. - */ - assert(u.hdr.e_phentsize == sizeof(Elf_Phdr)); - assert(u.hdr.e_phoff + u.hdr.e_phnum*sizeof(Elf_Phdr) <= PAGESIZE); - assert(u.hdr.e_phoff + u.hdr.e_phnum*sizeof(Elf_Phdr) <= nbytes); - - /* - * Scan the program header entries, and save key information. - * - * We rely on there being exactly two load segments, text and data, - * in that order. - */ - phdr = (Elf_Phdr *) (u.buf + u.hdr.e_phoff); - phlimit = phdr + u.hdr.e_phnum; - nsegs = 0; - phdyn = NULL; - phphdr = NULL; - while(phdr < phlimit) { - switch(phdr->p_type) { - - case Elf_pt_load: + case Elf_pt_load: #ifdef __mips__ - /* NetBSD/pmax 1.1 elf toolchain peculiarity */ - if (nsegs >= 2) { - _rtld_error("%s: too many sections\n", path); - return NULL; - } + /* NetBSD/pmax 1.1 elf toolchain peculiarity */ + if (nsegs >= 2) { + _rtld_error("%s: too many sections\n", path); + return NULL; + } #endif - assert(nsegs < 2); - segs[nsegs] = phdr; - ++nsegs; - break; + assert(nsegs < 2); + segs[nsegs] = phdr; + ++nsegs; + break; - case Elf_pt_phdr: - phphdr = phdr; - break; + case Elf_pt_phdr: + phphdr = phdr; + break; - case Elf_pt_dynamic: - phdyn = phdr; - break; + case Elf_pt_dynamic: + phdyn = phdr; + break; + } + + ++phdr; } - - ++phdr; - } - if (phdyn == NULL) { - _rtld_error("%s: not dynamically-linked", path); - return NULL; - } - - assert(nsegs == 2); + if (phdyn == NULL) { + _rtld_error("%s: not dynamically-linked", path); + return NULL; + } + assert(nsegs == 2); #ifdef __i386__ - assert(segs[0]->p_align <= PAGESIZE); - assert(segs[1]->p_align <= PAGESIZE); + assert(segs[0]->p_align <= PAGESIZE); + assert(segs[1]->p_align <= PAGESIZE); #endif - /* - * Map the entire address space of the object, to stake out our - * contiguous region, and to establish the base address for relocation. - */ - base_offset = round_down(segs[0]->p_offset); - base_vaddr = round_down(segs[0]->p_vaddr); - base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz); - mapsize = base_vlimit - base_vaddr; + /* + * Map the entire address space of the object, to stake out our + * contiguous region, and to establish the base address for relocation. + */ + base_offset = round_down(segs[0]->p_offset); + base_vaddr = round_down(segs[0]->p_vaddr); + base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz); + mapsize = base_vlimit - base_vaddr; #ifdef RTLD_LOADER - base_addr = u.hdr.e_type == Elf_et_exec ? (caddr_t) base_vaddr : NULL; + base_addr = u.hdr.e_type == Elf_et_exec ? (caddr_t) base_vaddr : NULL; #else - base_addr = NULL; + base_addr = NULL; #endif - mapbase = mmap(base_addr, mapsize, protflags(segs[0]->p_flags), - MAP_FILE|MAP_PRIVATE, fd, base_offset); - if (mapbase == (caddr_t) -1) { - _rtld_error("mmap of entire address space failed: %s", xstrerror(errno)); - return NULL; - } - if (base_addr != NULL && mapbase != base_addr) { - _rtld_error("mmap returned wrong address: wanted %p, got %p", base_addr, - mapbase); - munmap(mapbase, mapsize); - return NULL; - } - - /* Overlay the data segment onto the proper region. */ - data_offset = round_down(segs[1]->p_offset); - data_vaddr = round_down(segs[1]->p_vaddr); - data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz); - data_addr = mapbase + (data_vaddr - base_vaddr); - if (mmap(data_addr, data_vlimit - data_vaddr, protflags(segs[1]->p_flags), - MAP_FILE|MAP_PRIVATE|MAP_FIXED, fd, data_offset) == (caddr_t) -1) { - _rtld_error("mmap of data failed: %s", xstrerror(errno)); - return NULL; - } - -#ifdef RTLD_LOADER - /* Clear any BSS in the last page of the data segment. */ - clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz; - clear_addr = mapbase + (clear_vaddr - base_vaddr); - if ((nclear = data_vlimit - clear_vaddr) > 0) - memset(clear_addr, 0, nclear); - - /* Overlay the BSS segment onto the proper region. */ - bss_vaddr = data_vlimit; - bss_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz); - bss_addr = mapbase + (bss_vaddr - base_vaddr); - if (bss_vlimit > bss_vaddr) { /* There is something to do */ - if (mmap(bss_addr, bss_vlimit - bss_vaddr, protflags(segs[1]->p_flags), - MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (caddr_t) -1) { - _rtld_error("mmap of bss failed: %s", xstrerror(errno)); - return NULL; + mapbase = mmap(base_addr, mapsize, protflags(segs[0]->p_flags), + MAP_FILE | MAP_PRIVATE, fd, base_offset); + if (mapbase == (caddr_t) - 1) { + _rtld_error("mmap of entire address space failed: %s", + xstrerror(errno)); + return NULL; + } + if (base_addr != NULL && mapbase != base_addr) { + _rtld_error("mmap returned wrong address: wanted %p, got %p", base_addr, + mapbase); + munmap(mapbase, mapsize); + return NULL; + } + /* Overlay the data segment onto the proper region. */ + data_offset = round_down(segs[1]->p_offset); + data_vaddr = round_down(segs[1]->p_vaddr); + data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz); + data_addr = mapbase + (data_vaddr - base_vaddr); + if (mmap(data_addr, data_vlimit - data_vaddr, + protflags(segs[1]->p_flags), MAP_FILE | MAP_PRIVATE | MAP_FIXED, + fd, data_offset) == (caddr_t)-1) { + _rtld_error("mmap of data failed: %s", xstrerror(errno)); + return NULL; + } +#ifdef RTLD_LOADER + /* Clear any BSS in the last page of the data segment. */ + clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz; + clear_addr = mapbase + (clear_vaddr - base_vaddr); + if ((nclear = data_vlimit - clear_vaddr) > 0) + memset(clear_addr, 0, nclear); + + /* Overlay the BSS segment onto the proper region. */ + bss_vaddr = data_vlimit; + bss_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz); + bss_addr = mapbase + (bss_vaddr - base_vaddr); + if (bss_vlimit > bss_vaddr) { /* There is something to do */ + if (mmap(bss_addr, bss_vlimit - bss_vaddr, + protflags(segs[1]->p_flags), + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, + 0) == (caddr_t)-1) { + _rtld_error("mmap of bss failed: %s", xstrerror(errno)); + return NULL; + } } - } #endif - obj = CNEW(Obj_Entry); - obj->mapbase = mapbase; - obj->mapsize = mapsize; - obj->textsize = round_up(segs[0]->p_vaddr + segs[0]->p_memsz) - base_vaddr; - obj->vaddrbase = base_vaddr; - obj->relocbase = mapbase - base_vaddr; - obj->dynamic = (Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); - if (u.hdr.e_entry != 0) - obj->entry = (caddr_t) (obj->relocbase + u.hdr.e_entry); - if (phphdr != NULL) { - obj->phdr = (const Elf_Phdr *) (obj->relocbase + phphdr->p_vaddr); - obj->phsize = phphdr->p_memsz; - } - - return obj; + obj = CNEW(Obj_Entry); + obj->mapbase = mapbase; + obj->mapsize = mapsize; + obj->textsize = round_up(segs[0]->p_vaddr + segs[0]->p_memsz) - + base_vaddr; + obj->vaddrbase = base_vaddr; + obj->relocbase = mapbase - base_vaddr; + obj->dynamic = (Elf_Dyn *)(obj->relocbase + phdyn->p_vaddr); + if (u.hdr.e_entry != 0) + obj->entry = (caddr_t)(obj->relocbase + u.hdr.e_entry); + if (phphdr != NULL) { + obj->phdr = (const Elf_Phdr *) + (obj->relocbase + phphdr->p_vaddr); + obj->phsize = phphdr->p_memsz; + } + return obj; } /* @@ -259,13 +259,17 @@ _rtld_map_object( * flags for MMAP. */ static int -protflags(int elfflags) +protflags(elfflags) + int elfflags; { - int prot = 0; - if (elfflags & Elf_pf_r) prot |= PROT_READ; + int prot = 0; + if (elfflags & Elf_pf_r) + prot |= PROT_READ; #ifdef RTLD_LOADER - if (elfflags & Elf_pf_w) prot |= PROT_WRITE; + if (elfflags & Elf_pf_w) + prot |= PROT_WRITE; #endif - if (elfflags & Elf_pf_x) prot |= PROT_EXEC; - return prot; + if (elfflags & Elf_pf_x) + prot |= PROT_EXEC; + return prot; } diff --git a/libexec/ld.elf_so/paths.c b/libexec/ld.elf_so/paths.c index 15f0f97a1143..854f974561fa 100644 --- a/libexec/ld.elf_so/paths.c +++ b/libexec/ld.elf_so/paths.c @@ -1,4 +1,4 @@ -/* $NetBSD: paths.c,v 1.3 1999/02/24 18:31:00 christos Exp $ */ +/* $NetBSD: paths.c,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 Matt Thomas @@ -43,68 +43,66 @@ #include "debug.h" #include "rtld.h" -Search_Path *_rtld_find_path(Search_Path *, const char *, size_t); +static Search_Path *_rtld_find_path __P((Search_Path *, const char *, size_t)); -Search_Path * -_rtld_find_path( - Search_Path *path, - const char *pathstr, - size_t pathlen) +static Search_Path * +_rtld_find_path(path, pathstr, pathlen) + Search_Path *path; + const char *pathstr; + size_t pathlen; { - for (; path != NULL; path = path->sp_next) { - if (pathlen == path->sp_pathlen - && memcmp(path->sp_path, pathstr, pathlen) == 0) - return path; - } - return NULL; + for (; path != NULL; path = path->sp_next) { + if (pathlen == path->sp_pathlen && + memcmp(path->sp_path, pathstr, pathlen) == 0) + return path; + } + return NULL; } void -_rtld_add_paths( - Search_Path **path_p, - const char *pathstr, - bool dodebug) +_rtld_add_paths(path_p, pathstr, dodebug) + Search_Path ** path_p; + const char *pathstr; + bool dodebug; { - Search_Path *path, **head_p = path_p; + Search_Path *path, **head_p = path_p; - if (pathstr == NULL) - return; + if (pathstr == NULL) + return; - if (pathstr[0] == ':') { - /* - * Leading colon means append to current path - */ - while ((*path_p) != NULL) - path_p = &(*path_p)->sp_next; - pathstr++; - } - - for (;;) { - const char *bp = pathstr; - const char *ep = strchr(bp, ':'); - if (ep == NULL) - ep = &pathstr[strlen(pathstr)]; - - if (bp < ep && (path = _rtld_find_path(*head_p, bp, ep - bp)) == NULL) { - char *cp; - path = CNEW(Search_Path); - path->sp_pathlen = ep - bp; - cp = xmalloc(path->sp_pathlen + 1); - strncpy(cp, bp, path->sp_pathlen); - cp[path->sp_pathlen] = '\0'; - path->sp_path = cp; - path->sp_next = (*path_p); - (*path_p) = path; - path_p = &path->sp_next; - - if (dodebug) - dbg(" added path \"%s\"", path->sp_path); + if (pathstr[0] == ':') { + /* + * Leading colon means append to current path + */ + while ((*path_p) != NULL) + path_p = &(*path_p)->sp_next; + pathstr++; } + for (;;) { + const char *bp = pathstr; + const char *ep = strchr(bp, ':'); + if (ep == NULL) + ep = &pathstr[strlen(pathstr)]; - if (ep[0] == '\0') - break; - pathstr = ep + 1; - } + if (bp < ep && + (path = _rtld_find_path(*head_p, bp, ep - bp)) == NULL) { + char *cp; + + path = CNEW(Search_Path); + path->sp_pathlen = ep - bp; + cp = xmalloc(path->sp_pathlen + 1); + strncpy(cp, bp, path->sp_pathlen); + cp[path->sp_pathlen] = '\0'; + path->sp_path = cp; + path->sp_next = (*path_p); + (*path_p) = path; + path_p = &path->sp_next; + + if (dodebug) + dbg((" added path \"%s\"", path->sp_path)); + } + if (ep[0] == '\0') + break; + pathstr = ep + 1; + } } - - diff --git a/libexec/ld.elf_so/reloc.c b/libexec/ld.elf_so/reloc.c index d450edf19adb..12d57c7c5912 100644 --- a/libexec/ld.elf_so/reloc.c +++ b/libexec/ld.elf_so/reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: reloc.c,v 1.15 1999/02/27 21:38:04 scottr Exp $ */ +/* $NetBSD: reloc.c,v 1.16 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -53,6 +53,9 @@ #include "rtld.h" #ifndef RTLD_INHIBIT_COPY_RELOCS +static int _rtld_do_copy_relocation __P((const Obj_Entry *, const Elf_RelA *, + bool)); + /* * XXX: These don't work for the alpha and i386; don't know about powerpc * The alpha and the i386 avoid the problem by compiling everything PIC. @@ -63,10 +66,10 @@ * not an indirect call. */ static int -_rtld_do_copy_relocation( - const Obj_Entry *dstobj, - const Elf_RelA *rela, - bool dodebug) +_rtld_do_copy_relocation(dstobj, rela, dodebug) + const Obj_Entry *dstobj; + const Elf_RelA *rela; + bool dodebug; { void *dstaddr = (void *)(dstobj->relocbase + rela->r_offset); const Elf_Sym *dstsym = dstobj->symtab + ELF_R_SYM(rela->r_info); @@ -89,9 +92,9 @@ _rtld_do_copy_relocation( } srcaddr = (const void *)(srcobj->relocbase + srcsym->st_value); (void)memcpy(dstaddr, srcaddr, size); - rdbg(dodebug, "COPY %s %s %s --> src=%p dst=%p *dst= %p size %d", + rdbg(dodebug, ("COPY %s %s %s --> src=%p dst=%p *dst= %p size %d", dstobj->path, srcobj->path, name, (void *)srcaddr, - (void *)dstaddr, (void *)*(long *)dstaddr, size); + (void *)dstaddr, (void *)*(long *)dstaddr, size)); return (0); } #endif /* RTLD_INHIBIT_COPY_RELOCS */ @@ -105,9 +108,9 @@ _rtld_do_copy_relocation( * Returns 0 on success, -1 on failure. */ int -_rtld_do_copy_relocations( - const Obj_Entry *dstobj, - bool dodebug) +_rtld_do_copy_relocations(dstobj, dodebug) + const Obj_Entry *dstobj; + bool dodebug; { #ifndef RTLD_INHIBIT_COPY_RELOCS @@ -146,10 +149,10 @@ _rtld_do_copy_relocations( #ifndef __sparc__ int -_rtld_relocate_nonplt_object( - const Obj_Entry * obj, - const Elf_RelA * rela, - bool dodebug) +_rtld_relocate_nonplt_object(obj, rela, dodebug) + const Obj_Entry *obj; + const Elf_RelA *rela; + bool dodebug; { Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); const Elf_Sym *def; @@ -176,9 +179,9 @@ _rtld_relocate_nonplt_object( tmp = (Elf_Addr)(defobj->relocbase + def->st_value); if (*where != tmp) *where = tmp; - rdbg(dodebug, "GOT32 %s in %s --> %p in %s", + rdbg(dodebug, ("GOT32 %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; case R_TYPE(PC32): @@ -195,9 +198,9 @@ _rtld_relocate_nonplt_object( *where += (Elf_Addr)(defobj->relocbase + def->st_value) - (Elf_Addr)where; - rdbg(dodebug, "PC32 %s in %s --> %p in %s", + rdbg(dodebug, ("PC32 %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; case R_TYPE(32): @@ -207,9 +210,9 @@ _rtld_relocate_nonplt_object( return -1; *where += (Elf_Addr)(defobj->relocbase + def->st_value); - rdbg(dodebug, "32 %s in %s --> %p in %s", + rdbg(dodebug, ("32 %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; #endif /* __i386__ */ @@ -224,9 +227,9 @@ _rtld_relocate_nonplt_object( *where + rela->r_addend; if (*where != tmp) *where = tmp; - rdbg(dodebug, "REFQUAD %s in %s --> %p in %s", + rdbg(dodebug, ("REFQUAD %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; #endif /* __alpha__ */ @@ -239,21 +242,21 @@ _rtld_relocate_nonplt_object( if (*where != (Elf_Addr)(defobj->relocbase + def->st_value)) *where = (Elf_Addr)(defobj->relocbase + def->st_value); - rdbg(dodebug, "GLOB_DAT %s in %s --> %p in %s", + rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; case R_TYPE(RELATIVE): if ((caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ || (caddr_t)where >= (caddr_t)&_DYNAMIC) { *where += (Elf_Addr)obj->relocbase; - rdbg(dodebug, "RELATIVE in %s --> %p", obj->path, - (void *)*where); + rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path, + (void *)*where)); } else - rdbg(dodebug, "RELATIVE in %s stays at %p", - obj->path, (void *)*where); + rdbg(dodebug, ("RELATIVE in %s stays at %p", + obj->path, (void *)*where)); break; case R_TYPE(COPY): @@ -269,7 +272,7 @@ _rtld_relocate_nonplt_object( obj->path); return -1; } - rdbg(dodebug, "COPY (avoid in main)"); + rdbg(dodebug, ("COPY (avoid in main)")); break; #endif /* __i386__ || __alpha__ */ @@ -282,8 +285,8 @@ _rtld_relocate_nonplt_object( (ELF_SYM_TYPE(def->st_info) == Elf_estt_section || ELF_SYM_TYPE(def->st_info) == Elf_estt_notype)) { *where += (Elf_Addr)obj->relocbase; - rdbg(dodebug, "REL32 in %s --> %p", obj->path, - (void *)*where); + rdbg(dodebug, ("REL32 in %s --> %p", obj->path, + (void *)*where)); } else { /* XXX maybe do something re: bootstrapping? */ def = _rtld_find_symdef(_rtld_objlist, rela->r_info, @@ -291,9 +294,9 @@ _rtld_relocate_nonplt_object( if (def == NULL) return -1; *where += (Elf_Addr)(defobj->relocbase + def->st_value); - rdbg(dodebug, "REL32 %s in %s --> %p in %s", + rdbg(dodebug, ("REL32 %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); } break; @@ -312,17 +315,17 @@ _rtld_relocate_nonplt_object( if (*where != tmp) *where = tmp; - rdbg(dodebug, "32/GLOB_DAT %s in %s --> %p in %s", + rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s", defobj->strtab + def->st_name, obj->path, - (void *)*where, defobj->path); + (void *)*where, defobj->path)); break; case R_TYPE(COPY): - rdbg(dodebug, "COPY"); + rdbg(dodebug, ("COPY")); break; case R_TYPE(JMP_SLOT): - rdbg(dodebug, "JMP_SLOT"); + rdbg(dodebug, ("JMP_SLOT")); break; case R_TYPE(RELATIVE): /* word32 B + A */ @@ -331,21 +334,21 @@ _rtld_relocate_nonplt_object( break; /* GOT - already done */ *where = tmp; - rdbg(dodebug, "RELATIVE in %s --> %p", obj->path, - (void *)*where); + rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path, + (void *)*where)); break; #endif /* __powerpc__ */ default: def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj, &defobj, true); - rdbg(dodebug, "sym = %lu, type = %lu, offset = %p, " + rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", (u_long)ELF_R_SYM(rela->r_info), (u_long)ELF_R_TYPE(rela->r_info), (void *)rela->r_offset, (void *)rela->r_addend, (void *)*where, - def ? defobj->strtab + def->st_name : "??"); + def ? defobj->strtab + def->st_name : "??")); _rtld_error("%s: Unsupported relocation type %d" "in non-PLT relocations\n", obj->path, ELF_R_TYPE(rela->r_info)); @@ -357,15 +360,15 @@ _rtld_relocate_nonplt_object( int -_rtld_relocate_plt_object( - const Obj_Entry * obj, - const Elf_RelA * rela, - caddr_t *addrp, - bool bind_now, - bool dodebug) +_rtld_relocate_plt_object(obj, rela, addrp, bind_now, dodebug) + const Obj_Entry *obj; + const Elf_RelA *rela; + caddr_t *addrp; + bool bind_now; + bool dodebug; { - Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - Elf_Addr new_value; + Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + Elf_Addr new_value; /* Fully resolve procedure addresses now */ @@ -386,17 +389,17 @@ _rtld_relocate_plt_object( return -1; new_value = (Elf_Addr)(defobj->relocbase + def->st_value); - rdbg(dodebug, "bind now %d/fixup in %s --> old=%p new=%p", + rdbg(dodebug, ("bind now %d/fixup in %s --> old=%p new=%p", (int)bind_now, defobj->strtab + def->st_name, - (void *)*where, (void *)new_value); + (void *)*where, (void *)new_value)); } else #endif /* __alpha__ || __i386__ */ if (!obj->mainprog) { /* Just relocate the GOT slots pointing into the PLT */ new_value = *where + (Elf_Addr)(obj->relocbase); - rdbg(dodebug, "fixup !main in %s --> %p", obj->path, - (void *)*where); + rdbg(dodebug, ("fixup !main in %s --> %p", obj->path, + (void *)*where)); } else { return 0; } @@ -413,9 +416,9 @@ _rtld_relocate_plt_object( #endif /* __sparc__ */ caddr_t -_rtld_bind( - const Obj_Entry *obj, - Elf_Word reloff) +_rtld_bind(obj, reloff) + const Obj_Entry *obj; + Elf_Word reloff; { const Elf_RelA *rela; Elf_RelA ourrela; @@ -445,29 +448,29 @@ _rtld_bind( * or -1 on failure. */ int -_rtld_relocate_objects( - Obj_Entry * first, - bool bind_now, - bool dodebug) +_rtld_relocate_objects(first, bind_now, dodebug) + Obj_Entry *first; + bool bind_now; + bool dodebug; { - Obj_Entry *obj; - int ok = 1; + Obj_Entry *obj; + int ok = 1; for (obj = first; obj != NULL; obj = obj->next) { - if (obj->nbuckets == 0 || obj->nchains == 0 - || obj->buckets == NULL || obj->symtab == NULL - || obj->strtab == NULL) { + if (obj->nbuckets == 0 || obj->nchains == 0 || + obj->buckets == NULL || obj->symtab == NULL || + obj->strtab == NULL) { _rtld_error("%s: Shared object has no run-time" " symbol table", obj->path); return -1; } - rdbg(dodebug, " relocating %s (%ld/%ld rel/rela, " + rdbg(dodebug, (" relocating %s (%ld/%ld rel/rela, " "%ld/%ld plt rel/rela)", obj->path, (long)(obj->rellim - obj->rel), (long)(obj->relalim - obj->rela), (long)(obj->pltrellim - obj->pltrel), - (long)(obj->pltrelalim - obj->pltrela)); + (long)(obj->pltrelalim - obj->pltrela))); if (obj->textrel) { /* diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index aee3fa95105e..78d0723d0268 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.14 1999/02/27 10:35:16 pk Exp $ */ +/* $NetBSD: rtld.c,v 1.15 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -61,55 +61,63 @@ * Debugging support. */ -typedef void (*funcptr)(void); +typedef void (*funcptr) __P((void)); /* * Function declarations. */ -static void _rtld_init(caddr_t); -static void _rtld_exit(void); +static void _rtld_init __P((caddr_t)); +static void _rtld_exit __P((void)); + +Elf_Addr _rtld __P((Elf_Word *)); + /* * Data declarations. */ -static char *error_message; /* Message for dlopen(), or NULL */ +static char *error_message; /* Message for dlopen(), or NULL */ -struct r_debug _rtld_debug; /* for GDB; */ -bool _rtld_trust; /* False for setuid and setgid programs */ -Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ -Obj_Entry **_rtld_objtail; /* Link field of last object in list */ -Obj_Entry *_rtld_objmain; /* The main program shared object */ -Obj_Entry _rtld_objself; /* The dynamic linker shared object */ -char _rtld_path[] = _PATH_RTLD; +struct r_debug _rtld_debug; /* for GDB; */ +bool _rtld_trust; /* False for setuid and setgid programs */ +Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ +Obj_Entry **_rtld_objtail; /* Link field of last object in list */ +Obj_Entry *_rtld_objmain; /* The main program shared object */ +Obj_Entry _rtld_objself; /* The dynamic linker shared object */ +char _rtld_path[] = _PATH_RTLD; -Search_Path *_rtld_paths; +Search_Path *_rtld_paths; /* * Global declarations normally provided by crt0. */ -char *__progname; -char **environ; +char *__progname; +char **environ; #ifdef OLD_GOT extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; #else extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; -extern Elf_Dyn _DYNAMIC; +extern Elf_Dyn _DYNAMIC; #endif +static void _rtld_call_fini_functions __P((Obj_Entry *)); +static void _rtld_call_init_functions __P((Obj_Entry *)); +static Obj_Entry *_rtld_dlcheck __P((void *)); +static void _rtld_unref_object_dag __P((Obj_Entry *)); + static void -_rtld_call_fini_functions( - Obj_Entry *first) +_rtld_call_fini_functions(first) + Obj_Entry *first; { Obj_Entry *obj; - for (obj = first; obj != NULL; obj = obj->next) + for (obj = first; obj != NULL; obj = obj->next) if (obj->fini != NULL) (*obj->fini)(); } static void -_rtld_call_init_functions( - Obj_Entry *first) +_rtld_call_init_functions(first) + Obj_Entry *first; { if (first != NULL) { _rtld_call_init_functions(first->next); @@ -124,10 +132,10 @@ _rtld_call_init_functions( * this function is to relocate the dynamic linker. */ static void -_rtld_init( - caddr_t mapbase) +_rtld_init(mapbase) + caddr_t mapbase; { - Obj_Entry objself; /* The dynamic linker shared object */ + Obj_Entry objself;/* The dynamic linker shared object */ #ifdef RTLD_RELOCATE_SELF int dodebug = false; #else @@ -154,16 +162,16 @@ _rtld_init( objself.pltgot = NULL; #ifdef OLD_GOT - objself.dynamic = (Elf_Dyn *)_GLOBAL_OFFSET_TABLE_[0]; + objself.dynamic = (Elf_Dyn *) _GLOBAL_OFFSET_TABLE_[0]; #else - objself.dynamic = (Elf_Dyn *)&_DYNAMIC; + objself.dynamic = (Elf_Dyn *) & _DYNAMIC; #endif #ifdef RTLD_RELOCATE_SELF /* We have not been relocated yet, so fix the dynamic address */ objself.dynamic = (Elf_Dyn *) - ((u_long)mapbase + (char *) objself.dynamic); -#endif /* RTLD_RELOCATE_SELF */ + ((u_long) mapbase + (char *) objself.dynamic); +#endif /* RTLD_RELOCATE_SELF */ _rtld_digest_dynamic(&objself); @@ -206,9 +214,9 @@ _rtld_init( * before the process exits. */ static void -_rtld_exit(void) +_rtld_exit() { - dbg("rtld_exit()"); + dbg(("rtld_exit()")); _rtld_call_fini_functions(_rtld_objlist->next); } @@ -229,336 +237,339 @@ _rtld_exit(void) * Such values are returned with their most-significant 32 bits in %edx, * and their least-significant 32 bits in %eax. */ -Elf_Addr _rtld(Elf_Word *); - Elf_Addr -_rtld( - Elf_Word *sp) +_rtld(sp) + Elf_Word *sp; { - const AuxInfo *pAUX_base, *pAUX_entry, *pAUX_execfd, - *pAUX_phdr, *pAUX_phent, *pAUX_phnum; - char **env; - const AuxInfo *aux; - const AuxInfo *auxp; - Elf_Word * const osp = sp; - bool bind_now = 0; - const char *ld_bind_now; - const char **argv; + const AuxInfo *pAUX_base, *pAUX_entry, *pAUX_execfd, *pAUX_phdr, + *pAUX_phent, *pAUX_phnum; + char **env; + const AuxInfo *aux; + const AuxInfo *auxp; + Elf_Word *const osp = sp; + bool bind_now = 0; + const char *ld_bind_now; + const char **argv; #if defined(RTLD_DEBUG) && !defined(RTLD_RELOCATE_SELF) - int i = 0; + int i = 0; #endif - /* - * On entry, the dynamic linker itself has not been relocated yet. - * Be very careful not to reference any global data until after - * _rtld_init has returned. It is OK to reference file-scope statics - * and string constants, and to call static and global functions. - */ - /* Find the auxiliary vector on the stack. */ - /* first Elf_Word reserved to address of exit routine */ + /* + * On entry, the dynamic linker itself has not been relocated yet. + * Be very careful not to reference any global data until after + * _rtld_init has returned. It is OK to reference file-scope statics + * and string constants, and to call static and global functions. + */ + /* Find the auxiliary vector on the stack. */ + /* first Elf_Word reserved to address of exit routine */ #if defined(RTLD_DEBUG) && !defined(RTLD_RELOCATE_SELF) - dbg("sp = %p, argc = %d, argv = %p <%s>\n", sp, sp[2], - &sp[3], (char *)sp[3]); - dbg("got is at %p, dynamic is at %p\n", _GLOBAL_OFFSET_TABLE_, &_DYNAMIC); - debug = 1; - dbg("_ctype_ is %p\n", _ctype_); + dbg(("sp = %p, argc = %d, argv = %p <%s>\n", sp, sp[2], + &sp[3], (char *) sp[3])); + dbg(("got is at %p, dynamic is at %p\n", + _GLOBAL_OFFSET_TABLE_, &_DYNAMIC)); + debug = 1; + dbg(("_ctype_ is %p\n", _ctype_)); #endif - sp += 2; /* skip over return argument space */ - argv = (const char **) &sp[1]; - sp += sp[0] + 2; /* Skip over argc, arguments, and NULL terminator */ - env = (char **) sp; - while (*sp++ != 0) { /* Skip over environment, and NULL terminator */ + sp += 2; /* skip over return argument space */ + argv = (const char **) &sp[1]; + sp += sp[0] + 2; /* Skip over argc, arguments, and NULL + * terminator */ + env = (char **) sp; + while (*sp++ != 0) { /* Skip over environment, and NULL terminator */ #if defined(RTLD_DEBUG) && !defined(RTLD_RELOCATE_SELF) - dbg("env[%d] = %p %s\n", i++, (void *)sp[-1], (char *)sp[-1]); + dbg(("env[%d] = %p %s\n", i++, (void *)sp[-1], (char *)sp[-1])); #endif - } - aux = (const AuxInfo *) sp; - - /* Digest the auxiliary vector. */ - pAUX_base = pAUX_entry = pAUX_execfd = - pAUX_phdr = pAUX_phent = pAUX_phnum = NULL; - for (auxp = aux; auxp->au_id != AUX_null; ++auxp) { - switch(auxp->au_id) { - case AUX_base: - pAUX_base = auxp; break; - case AUX_entry: - pAUX_entry = auxp; break; - case AUX_execfd: - pAUX_execfd = auxp; break; - case AUX_phdr: - pAUX_phdr = auxp; break; - case AUX_phent: - pAUX_phent = auxp; break; - case AUX_phnum: - pAUX_phnum = auxp; break; } - } + aux = (const AuxInfo *) sp; - /* Initialize and relocate ourselves. */ - assert(pAUX_base != NULL); - _rtld_init((caddr_t) pAUX_base->au_v); + /* Digest the auxiliary vector. */ + pAUX_base = pAUX_entry = pAUX_execfd = NULL; + pAUX_phdr = pAUX_phent = pAUX_phnum = NULL; + for (auxp = aux; auxp->au_id != AUX_null; ++auxp) { + switch (auxp->au_id) { + case AUX_base: + pAUX_base = auxp; + break; + case AUX_entry: + pAUX_entry = auxp; + break; + case AUX_execfd: + pAUX_execfd = auxp; + break; + case AUX_phdr: + pAUX_phdr = auxp; + break; + case AUX_phent: + pAUX_phent = auxp; + break; + case AUX_phnum: + pAUX_phnum = auxp; + break; + } + } + + /* Initialize and relocate ourselves. */ + assert(pAUX_base != NULL); + _rtld_init((caddr_t) pAUX_base->au_v); #ifdef RTLD_DEBUG - dbg("_ctype_ is %p\n", _ctype_); + dbg(("_ctype_ is %p\n", _ctype_)); #endif - __progname = _rtld_objself.path; - environ = env; + __progname = _rtld_objself.path; + environ = env; - _rtld_trust = geteuid() == getuid() && getegid() == getgid(); + _rtld_trust = geteuid() == getuid() && getegid() == getgid(); - ld_bind_now = getenv("LD_BIND_NOW"); - if (ld_bind_now != NULL && *ld_bind_now != '\0') - bind_now = true; - if (_rtld_trust) { + ld_bind_now = getenv("LD_BIND_NOW"); + if (ld_bind_now != NULL && *ld_bind_now != '\0') + bind_now = true; + if (_rtld_trust) { #ifdef DEBUG - const char *ld_debug = getenv("LD_DEBUG"); - if (ld_debug != NULL && *ld_debug != '\0') - debug = 1; + const char *ld_debug = getenv("LD_DEBUG"); + if (ld_debug != NULL && *ld_debug != '\0') + debug = 1; #endif - _rtld_add_paths(&_rtld_paths, getenv("LD_LIBRARY_PATH"), true); - } + _rtld_add_paths(&_rtld_paths, getenv("LD_LIBRARY_PATH"), true); + } + dbg(("%s is initialized, base address = %p", __progname, + (void *) pAUX_base->au_v)); - dbg("%s is initialized, base address = %p", __progname, - (void *)pAUX_base->au_v); + /* + * Load the main program, or process its program header if it is + * already loaded. + */ + if (pAUX_execfd != NULL) { /* Load the main program. */ + int fd = pAUX_execfd->au_v; + dbg(("loading main program")); + _rtld_objmain = _rtld_map_object(argv[0], fd); + close(fd); + if (_rtld_objmain == NULL) + _rtld_die(); + } else { /* Main program already loaded. */ + const Elf_Phdr *phdr; + int phnum; + caddr_t entry; - /* - * Load the main program, or process its program header if it is - * already loaded. - */ - if (pAUX_execfd != NULL) { /* Load the main program. */ - int fd = pAUX_execfd->au_v; - dbg("loading main program"); - _rtld_objmain = _rtld_map_object(argv[0], fd); - close(fd); - if (_rtld_objmain == NULL) - _rtld_die(); - } else { /* Main program already loaded. */ - const Elf_Phdr *phdr; - int phnum; - caddr_t entry; + dbg(("processing main program's program header")); + assert(pAUX_phdr != NULL); + phdr = (const Elf_Phdr *) pAUX_phdr->au_v; + assert(pAUX_phnum != NULL); + phnum = pAUX_phnum->au_v; + assert(pAUX_phent != NULL); + assert(pAUX_phent->au_v == sizeof(Elf_Phdr)); + assert(pAUX_entry != NULL); + entry = (caddr_t) pAUX_entry->au_v; + _rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry); + } - dbg("processing main program's program header"); - assert(pAUX_phdr != NULL); - phdr = (const Elf_Phdr *) pAUX_phdr->au_v; - assert(pAUX_phnum != NULL); - phnum = pAUX_phnum->au_v; - assert(pAUX_phent != NULL); - assert(pAUX_phent->au_v == sizeof(Elf_Phdr)); - assert(pAUX_entry != NULL); - entry = (caddr_t) pAUX_entry->au_v; - _rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry); - } + _rtld_objmain->path = xstrdup("main program"); + _rtld_objmain->mainprog = true; + _rtld_digest_dynamic(_rtld_objmain); - _rtld_objmain->path = xstrdup("main program"); - _rtld_objmain->mainprog = true; - _rtld_digest_dynamic(_rtld_objmain); + _rtld_linkmap_add(_rtld_objmain); + _rtld_linkmap_add(&_rtld_objself); - _rtld_linkmap_add(_rtld_objmain); - _rtld_linkmap_add(&_rtld_objself); + /* Link the main program into the list of objects. */ + *_rtld_objtail = _rtld_objmain; + _rtld_objtail = &_rtld_objmain->next; + ++_rtld_objmain->refcount; - /* Link the main program into the list of objects. */ - *_rtld_objtail = _rtld_objmain; - _rtld_objtail = &_rtld_objmain->next; - ++_rtld_objmain->refcount; + dbg(("loading needed objects")); + if (_rtld_load_needed_objects(_rtld_objmain) == -1) + _rtld_die(); - dbg("loading needed objects"); - if (_rtld_load_needed_objects(_rtld_objmain) == -1) - _rtld_die(); + dbg(("relocating objects")); + if (_rtld_relocate_objects(_rtld_objmain, bind_now, true) == -1) + _rtld_die(); - dbg("relocating objects"); - if (_rtld_relocate_objects(_rtld_objmain, bind_now, true) == -1) - _rtld_die(); + dbg(("doing copy relocations")); + if (_rtld_do_copy_relocations(_rtld_objmain, true) == -1) + _rtld_die(); - dbg("doing copy relocations"); - if (_rtld_do_copy_relocations(_rtld_objmain, true) == -1) - _rtld_die(); + dbg(("calling _init functions")); + _rtld_call_init_functions(_rtld_objmain->next); - dbg("calling _init functions"); - _rtld_call_init_functions(_rtld_objmain->next); + dbg(("control at program entry point = %p, obj = %p, exit = %p", + _rtld_objmain->entry, _rtld_objmain, _rtld_exit)); - dbg("control at program entry point = %p, obj = %p, exit = %p", - _rtld_objmain->entry, _rtld_objmain, _rtld_exit); + /* + * Return with the entry point and the exit procedure in at the top + * of stack. + */ - /* Return with the entry point and the exit procedure in at the top of - * stack. - */ + _rtld_debug_state(); /* say hello to gdb! */ - _rtld_debug_state(); /* say hello to gdb! */ - - ((void **) osp)[0] = _rtld_exit; - ((void **) osp)[1] = _rtld_objmain; - return (Elf_Addr) _rtld_objmain->entry; + ((void **) osp)[0] = _rtld_exit; + ((void **) osp)[1] = _rtld_objmain; + return (Elf_Addr) _rtld_objmain->entry; } void -_rtld_die( - void) +_rtld_die() { - const char *msg = _rtld_dlerror(); + const char *msg = _rtld_dlerror(); - if (msg == NULL) - msg = "Fatal error"; - xerrx(1, "%s\n", msg); + if (msg == NULL) + msg = "Fatal error"; + xerrx(1, "%s\n", msg); } static Obj_Entry * -_rtld_dlcheck( - void *handle) +_rtld_dlcheck(handle) + void *handle; { - Obj_Entry *obj; + Obj_Entry *obj; - for (obj = _rtld_objlist; obj != NULL; obj = obj->next) - if (obj == (Obj_Entry *) handle) - break; + for (obj = _rtld_objlist; obj != NULL; obj = obj->next) + if (obj == (Obj_Entry *) handle) + break; - if (obj == NULL || obj->dl_refcount == 0) { - xwarnx("Invalid shared object handle %p", handle); - return NULL; - } - return obj; + if (obj == NULL || obj->dl_refcount == 0) { + xwarnx("Invalid shared object handle %p", handle); + return NULL; + } + return obj; } static void -_rtld_unref_object_dag( - Obj_Entry *root) +_rtld_unref_object_dag(root) + Obj_Entry *root; { - assert(root->refcount != 0); - --root->refcount; - if (root->refcount == 0) { - const Needed_Entry *needed; + assert(root->refcount != 0); + --root->refcount; + if (root->refcount == 0) { + const Needed_Entry *needed; - for (needed = root->needed; needed != NULL; needed = needed->next) - _rtld_unref_object_dag(needed->obj); - } + for (needed = root->needed; needed != NULL; + needed = needed->next) + _rtld_unref_object_dag(needed->obj); + } } int -_rtld_dlclose( - void *handle) +_rtld_dlclose(handle) + void *handle; { - Obj_Entry *root = _rtld_dlcheck(handle); + Obj_Entry *root = _rtld_dlcheck(handle); - if (root == NULL) - return -1; + if (root == NULL) + return -1; - _rtld_debug.r_state = RT_DELETE; - _rtld_debug_state(); + _rtld_debug.r_state = RT_DELETE; + _rtld_debug_state(); - --root->dl_refcount; - _rtld_unref_object_dag(root); - if (root->refcount == 0) { /* We are finished with some objects. */ - Obj_Entry *obj; - Obj_Entry **linkp; + --root->dl_refcount; + _rtld_unref_object_dag(root); + if (root->refcount == 0) { /* We are finished with some objects. */ + Obj_Entry *obj; + Obj_Entry **linkp; - /* Finalize objects that are about to be unmapped. */ - for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) - if (obj->refcount == 0 && obj->fini != NULL) - (*obj->fini)(); + /* Finalize objects that are about to be unmapped. */ + for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) + if (obj->refcount == 0 && obj->fini != NULL) + (*obj->fini) (); - /* Unmap all objects that are no longer referenced. */ - linkp = &_rtld_objlist->next; - while((obj = *linkp) != NULL) { - if (obj->refcount == 0) { - munmap(obj->mapbase, obj->mapsize); - free(obj->path); - while(obj->needed != NULL) { - Needed_Entry *needed = obj->needed; - obj->needed = needed->next; - free(needed); + /* Unmap all objects that are no longer referenced. */ + linkp = &_rtld_objlist->next; + while ((obj = *linkp) != NULL) { + if (obj->refcount == 0) { + munmap(obj->mapbase, obj->mapsize); + free(obj->path); + while (obj->needed != NULL) { + Needed_Entry *needed = obj->needed; + obj->needed = needed->next; + free(needed); + } + _rtld_linkmap_delete(obj); + *linkp = obj->next; + if (obj->next == NULL) + _rtld_objtail = linkp; + free(obj); + } else + linkp = &obj->next; } - _rtld_linkmap_delete(obj); - *linkp = obj->next; - if (obj->next == NULL) - _rtld_objtail = linkp; - free(obj); - } else - linkp = &obj->next; } - } + _rtld_debug.r_state = RT_CONSISTENT; + _rtld_debug_state(); - _rtld_debug.r_state = RT_CONSISTENT; - _rtld_debug_state(); - - return 0; + return 0; } char * -_rtld_dlerror( - void) +_rtld_dlerror() { - char *msg = error_message; - error_message = NULL; - return msg; + char *msg = error_message; + error_message = NULL; + return msg; } void * -_rtld_dlopen( - const char *name, - int mode) +_rtld_dlopen(name, mode) + const char *name; + int mode; { - Obj_Entry **old_obj_tail = _rtld_objtail; - Obj_Entry *obj = NULL; + Obj_Entry **old_obj_tail = _rtld_objtail; + Obj_Entry *obj = NULL; - _rtld_debug.r_state = RT_ADD; - _rtld_debug_state(); + _rtld_debug.r_state = RT_ADD; + _rtld_debug_state(); - if (name == NULL) { - obj = _rtld_objmain; - } else { - char *path = _rtld_find_library(name, NULL); - if (path != NULL) - obj = _rtld_load_object(path, true); - } - - if (obj != NULL) { - ++obj->dl_refcount; - if (*old_obj_tail != NULL) { /* We loaded something new. */ - assert(*old_obj_tail == obj); - - /* FIXME - Clean up properly after an error. */ - if (_rtld_load_needed_objects(obj) == -1) { - --obj->dl_refcount; - obj = NULL; - } else if (_rtld_relocate_objects(obj, (mode & 3) == RTLD_NOW, - true) == -1) { - --obj->dl_refcount; - obj = NULL; - } else { - _rtld_call_init_functions(obj); - } + if (name == NULL) { + obj = _rtld_objmain; + } else { + char *path = _rtld_find_library(name, NULL); + if (path != NULL) + obj = _rtld_load_object(path, true); } - } - _rtld_debug.r_state = RT_CONSISTENT; - _rtld_debug_state(); + if (obj != NULL) { + ++obj->dl_refcount; + if (*old_obj_tail != NULL) { /* We loaded something new. */ + assert(*old_obj_tail == obj); - return obj; + /* FIXME - Clean up properly after an error. */ + if (_rtld_load_needed_objects(obj) == -1) { + --obj->dl_refcount; + obj = NULL; + } else if (_rtld_relocate_objects(obj, + (mode & 3) == RTLD_NOW, true) == -1) { + --obj->dl_refcount; + obj = NULL; + } else { + _rtld_call_init_functions(obj); + } + } + } + _rtld_debug.r_state = RT_CONSISTENT; + _rtld_debug_state(); + + return obj; } void * -_rtld_dlsym( - void *handle, - const char *name) +_rtld_dlsym(handle, name) + void *handle; + const char *name; { - const Obj_Entry *obj = _rtld_dlcheck(handle); - const Elf_Sym *def; - const Obj_Entry *defobj; + const Obj_Entry *obj = _rtld_dlcheck(handle); + const Elf_Sym *def; + const Obj_Entry *defobj; - if (obj == NULL) + if (obj == NULL) + return NULL; + + /* + * FIXME - This isn't correct. The search should include the whole + * DAG rooted at the given object. + */ + def = _rtld_find_symdef(_rtld_objlist, 0, name, obj, &defobj, false); + if (def != NULL) + return defobj->relocbase + def->st_value; + + _rtld_error("Undefined symbol \"%s\"", name); return NULL; - - /* - * FIXME - This isn't correct. The search should include the whole - * DAG rooted at the given object. - */ - def = _rtld_find_symdef(_rtld_objlist, 0, name, obj, &defobj, false); - if (def != NULL) - return defobj->relocbase + def->st_value; - - _rtld_error("Undefined symbol \"%s\"", name); - return NULL; } /* @@ -567,64 +578,70 @@ _rtld_dlsym( * will return the message. */ void -_rtld_error( - const char *fmt, ...) +#ifdef __STDC__ +_rtld_error(const char *fmt,...) +#else +_rtld_error(va_alist) + va_dcl +#endif { - static char buf[512]; - va_list ap; + static char buf[512]; + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + const char *fmt; - va_start(ap, fmt); - xvsnprintf(buf, sizeof buf, fmt, ap); - error_message = buf; - va_end(ap); + va_start(ap); + fmt = va_arg(ap, const char *); +#endif + xvsnprintf(buf, sizeof buf, fmt, ap); + error_message = buf; + va_end(ap); } void -_rtld_debug_state( - void) +_rtld_debug_state() { - /* do nothing */ + /* do nothing */ } void -_rtld_linkmap_add( - Obj_Entry *obj) +_rtld_linkmap_add(obj) + Obj_Entry *obj; { - struct link_map *l = &obj->linkmap; - struct link_map *prev; + struct link_map *l = &obj->linkmap; + struct link_map *prev; - obj->linkmap.l_name = obj->path; - obj->linkmap.l_addr = obj->mapbase; - obj->linkmap.l_ld = obj->dynamic; + obj->linkmap.l_name = obj->path; + obj->linkmap.l_addr = obj->mapbase; + obj->linkmap.l_ld = obj->dynamic; #ifdef __mips__ - /* GDB needs load offset on MIPS to use the symbols */ - obj->linkmap.l_offs = obj->relocbase; + /* GDB needs load offset on MIPS to use the symbols */ + obj->linkmap.l_offs = obj->relocbase; #endif - if (_rtld_debug.r_map == NULL) { - _rtld_debug.r_map = l; - return; - } - - for (prev = _rtld_debug.r_map; prev->l_next != NULL; prev = prev->l_next) - ; - l->l_prev = prev; - prev->l_next = l; - l->l_next = NULL; + if (_rtld_debug.r_map == NULL) { + _rtld_debug.r_map = l; + return; + } + for (prev = _rtld_debug.r_map; prev->l_next != NULL; prev = prev->l_next); + l->l_prev = prev; + prev->l_next = l; + l->l_next = NULL; } void -_rtld_linkmap_delete( - Obj_Entry *obj) +_rtld_linkmap_delete(obj) + Obj_Entry *obj; { - struct link_map *l = &obj->linkmap; + struct link_map *l = &obj->linkmap; - if (l->l_prev == NULL) { - if ((_rtld_debug.r_map = l->l_next) != NULL) - l->l_next->l_prev = NULL; - return; - } - - if ((l->l_prev->l_next = l->l_next) != NULL) - l->l_next->l_prev = l->l_prev; + if (l->l_prev == NULL) { + if ((_rtld_debug.r_map = l->l_next) != NULL) + l->l_next->l_prev = NULL; + return; + } + if ((l->l_prev->l_next = l->l_next) != NULL) + l->l_next->l_prev = l->l_prev; } diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h index 29f3903d2db8..25887702cce1 100644 --- a/libexec/ld.elf_so/rtld.h +++ b/libexec/ld.elf_so/rtld.h @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.7 1999/02/24 18:31:00 christos Exp $ */ +/* $NetBSD: rtld.h,v 1.8 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -31,8 +31,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RTLD_H /* { */ -#define RTLD_H 1 +#ifndef RTLD_H +#define RTLD_H #include #include @@ -57,6 +57,7 @@ # define PAGESIZE 8192 /* NPBG is not constant! */ # endif #endif + #define round_down(x) ((x) & ~(PAGESIZE-1)) #define round_up(x) round_down((x) + PAGESIZE - 1) @@ -74,16 +75,16 @@ typedef unsigned char bool; struct Struct_Obj_Entry; typedef struct Struct_Needed_Entry { - struct Struct_Needed_Entry *next; - struct Struct_Obj_Entry *obj; - unsigned long name; /* Offset of name in string table */ -} Needed_Entry; + struct Struct_Needed_Entry *next; + struct Struct_Obj_Entry *obj; + unsigned long name; /* Offset of name in string table */ +} Needed_Entry; typedef struct _rtld_search_path_t { - struct _rtld_search_path_t *sp_next; - const char *sp_path; - size_t sp_pathlen; -} Search_Path; + struct _rtld_search_path_t *sp_next; + const char *sp_path; + size_t sp_pathlen; +} Search_Path; /* * Shared object descriptor. @@ -96,68 +97,72 @@ typedef struct _rtld_search_path_t { #define RTLD_VERSION 1 typedef struct Struct_Obj_Entry { - Elf32_Word magic; /* Magic number (sanity check) */ - Elf32_Word version; /* Version number of struct format */ + Elf32_Word magic; /* Magic number (sanity check) */ + Elf32_Word version; /* Version number of struct format */ - struct Struct_Obj_Entry *next; - char *path; /* Pathname of underlying file (%) */ - int refcount; - int dl_refcount; /* Number of times loaded by dlopen */ + struct Struct_Obj_Entry *next; + char *path; /* Pathname of underlying file (%) */ + int refcount; + int dl_refcount; /* Number of times loaded by dlopen */ - /* These items are computed by map_object() or by digest_phdr(). */ - caddr_t mapbase; /* Base address of mapped region */ - size_t mapsize; /* Size of mapped region in bytes */ - size_t textsize; /* Size of text segment in bytes */ - Elf_Addr vaddrbase; /* Base address in shared object file */ - caddr_t relocbase; /* Relocation constant = mapbase - vaddrbase */ - Elf_Dyn *dynamic; /* Dynamic section */ - caddr_t entry; /* Entry point */ - const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ - size_t phsize; /* Size of program header in bytes */ + /* These items are computed by map_object() or by digest_phdr(). */ + caddr_t mapbase; /* Base address of mapped region */ + size_t mapsize; /* Size of mapped region in bytes */ + size_t textsize; /* Size of text segment in bytes */ + Elf_Addr vaddrbase; /* Base address in shared object file */ + caddr_t relocbase; /* Reloc const = mapbase - *vaddrbase */ + Elf_Dyn *dynamic; /* Dynamic section */ + caddr_t entry; /* Entry point */ + const Elf_Phdr *phdr; /* Program header if mapped, ow NULL */ + size_t phsize; /* Size of program header in bytes */ - /* Items from the dynamic section. */ - Elf_Addr *pltgot; /* PLTGOT table */ - const Elf_Rel *rel; /* Relocation entries */ - const Elf_Rel *rellim; /* Limit of Relocation entries */ - const Elf_RelA *rela; /* Relocation entries */ - const Elf_RelA *relalim; /* Limit of Relocation entries */ - const Elf_Rel *pltrel; /* PLT relocation entries */ - const Elf_Rel *pltrellim; /* Limit of PLT relocation entries */ - const Elf_RelA *pltrela; /* PLT relocation entries */ - const Elf_RelA *pltrelalim; /* Limit of PLT relocation entries */ - const Elf_Sym *symtab; /* Symbol table */ - const char *strtab; /* String table */ - unsigned long strsize; /* Size in bytes of string table */ + /* Items from the dynamic section. */ + Elf_Addr *pltgot; /* PLTGOT table */ + const Elf_Rel *rel; /* Relocation entries */ + const Elf_Rel *rellim; /* Limit of Relocation entries */ + const Elf_RelA *rela; /* Relocation entries */ + const Elf_RelA *relalim; /* Limit of Relocation entries */ + const Elf_Rel *pltrel; /* PLT relocation entries */ + const Elf_Rel *pltrellim; /* Limit of PLT relocation entries */ + const Elf_RelA *pltrela; /* PLT relocation entries */ + const Elf_RelA *pltrelalim; /* Limit of PLT relocation entries */ + const Elf_Sym *symtab; /* Symbol table */ + const char *strtab; /* String table */ + unsigned long strsize; /* Size in bytes of string table */ #if defined(__mips__) - Elf_Word local_gotno; /* Number of local GOT entries */ - Elf_Word symtabno; /* Number of dynamic symbols */ - Elf_Word gotsym; /* First dynamic symbol in GOT */ + Elf_Word local_gotno; /* Number of local GOT entries */ + Elf_Word symtabno; /* Number of dynamic symbols */ + Elf_Word gotsym; /* First dynamic symbol in GOT */ #endif - const Elf_Word *buckets; /* Hash table buckets array */ - unsigned long nbuckets; /* Number of buckets */ - const Elf_Word *chains; /* Hash table chain array */ - unsigned long nchains; /* Number of chains */ + const Elf_Word *buckets; /* Hash table buckets array */ + unsigned long nbuckets; /* Number of buckets */ + const Elf_Word *chains; /* Hash table chain array */ + unsigned long nchains; /* Number of chains */ - Search_Path *rpaths; /* Search path specified in object */ - Needed_Entry *needed; /* Shared objects needed by this one (%) */ + Search_Path *rpaths; /* Search path specified in object */ + Needed_Entry *needed; /* Shared objects needed by this (%) */ - void (*init)(void); /* Initialization function to call */ - void (*fini)(void); /* Termination function to call */ + void (*init) /* Initialization function to call */ + __P((void)); + void (*fini) /* Termination function to call */ + __P((void)); - /* Entry points for dlopen() and friends. */ - void *(*dlopen)(const char *, int); - void *(*dlsym)(void *, const char *); - char *(*dlerror)(void); - int (*dlclose)(void *); + /* Entry points for dlopen() and friends. */ + void *(*dlopen) __P((const char *, int)); + void *(*dlsym) __P((void *, const char *)); + char *(*dlerror) __P((void)); + int (*dlclose) __P((void *)); - int mainprog : 1; /* True if this is the main program */ - int rtld : 1; /* True if this is the dynamic linker */ - int textrel : 1; /* True if there are relocations to text seg */ - int symbolic : 1; /* True if generated with "-Bsymbolic" */ - int printed : 1; /* True if ldd has printed it */ + int mainprog:1; /* True if this is the main program */ + int rtld:1; /* True if this is the dynamic linker */ + int textrel:1; /* True if there are relocations to + * text seg */ + int symbolic:1; /* True if generated with + * "-Bsymbolic" */ + int printed:1; /* True if ldd has printed it */ - struct link_map linkmap; /* for GDB */ + struct link_map linkmap; /* for GDB */ } Obj_Entry; extern struct r_debug _rtld_debug; @@ -169,71 +174,63 @@ extern bool _rtld_trust; extern const char *_rtld_error_message; /* rtld_start.S */ -extern void _rtld_bind_start(void); +void _rtld_bind_start __P((void)); /* rtld.c */ - -extern void _rtld_error(const char *, ...); -extern void _rtld_die(void); - -extern char *_rtld_dlerror(void); -extern void *_rtld_dlopen(const char *, int); -extern void *_rtld_dlsym(void *, const char *); -extern int _rtld_dlclose(void *); - -extern void _rtld_debug_state(void); - -extern void _rtld_linkmap_add(Obj_Entry *); -extern void _rtld_linkmap_delete(Obj_Entry *); +void _rtld_error __P((const char *, ...)); +void _rtld_die __P((void)); +char *_rtld_dlerror __P((void)); +void *_rtld_dlopen __P((const char *, int)); +void *_rtld_dlsym __P((void *, const char *)); +int _rtld_dlclose __P((void *)); +void _rtld_debug_state __P((void)); +void _rtld_linkmap_add __P((Obj_Entry *)); +void _rtld_linkmap_delete __P((Obj_Entry *)); /* headers.c */ - -extern void _rtld_digest_dynamic(Obj_Entry *); -extern Obj_Entry *_rtld_digest_phdr(const Elf_Phdr *, int, caddr_t); +void _rtld_digest_dynamic __P((Obj_Entry *)); +Obj_Entry *_rtld_digest_phdr __P((const Elf_Phdr *, int, caddr_t)); /* load.c */ - -extern Obj_Entry *_rtld_load_object(char *path, bool); -extern int _rtld_load_needed_objects(Obj_Entry *); +Obj_Entry *_rtld_load_object __P((char *, bool)); +int _rtld_load_needed_objects __P((Obj_Entry *)); /* path.c */ - -extern void _rtld_add_paths(Search_Path **, const char *, bool); +void _rtld_add_paths __P((Search_Path **, const char *, bool)); /* reloc.c */ -extern int _rtld_do_copy_relocations(const Obj_Entry *, bool); -extern caddr_t _rtld_bind(const Obj_Entry *, Elf_Word); -extern int _rtld_relocate_objects(Obj_Entry *, bool, bool); -extern int _rtld_relocate_nonplt_object(const Obj_Entry *, const Elf_RelA *, - bool); -extern int _rtld_relocate_plt_object(const Obj_Entry *, const Elf_RelA *, - caddr_t *, bool, bool); +int _rtld_do_copy_relocations __P((const Obj_Entry *, bool)); +caddr_t _rtld_bind __P((const Obj_Entry *, Elf_Word)); +int _rtld_relocate_objects __P((Obj_Entry *, bool, bool)); +int _rtld_relocate_nonplt_object __P((const Obj_Entry *, + const Elf_RelA *, bool)); +int _rtld_relocate_plt_object __P((const Obj_Entry *, const Elf_RelA *, + caddr_t *, bool, bool)); /* search.c */ - -extern char *_rtld_find_library(const char *, const Obj_Entry *); +char *_rtld_find_library __P((const char *, const Obj_Entry *)); /* symbol.c */ -extern unsigned long _rtld_elf_hash(const char *); -extern const Elf_Sym *_rtld_symlook_obj(const char *, unsigned long, - const Obj_Entry *, bool); -extern const Elf_Sym *_rtld_find_symdef(const Obj_Entry *, Elf_Word, - const char *, const Obj_Entry *, const Obj_Entry **, bool); +unsigned long _rtld_elf_hash __P((const char *)); +const Elf_Sym *_rtld_symlook_obj __P((const char *, unsigned long, + const Obj_Entry *, bool)); +const Elf_Sym *_rtld_find_symdef __P((const Obj_Entry *, Elf_Word, + const char *, const Obj_Entry *, const Obj_Entry **, bool)); /* map_object.c */ -extern Obj_Entry *_rtld_map_object(const char *, int); +Obj_Entry *_rtld_map_object __P((const char *, int)); #if defined(__mips__) /* mips_reloc.c */ -extern void _rtld_relocate_mips_got(Obj_Entry *); -extern caddr_t _rtld_bind_mips (Elf_Word, Elf_Addr, Elf_Addr, Elf_Addr); +void _rtld_relocate_mips_got __P((Obj_Entry *)); +caddr_t _rtld_bind_mips __P((Elf_Word, Elf_Addr, Elf_Addr, Elf_Addr)); #endif #if defined(__powerpc__) /* ppc_reloc.c */ -extern caddr_t _rtld_bind_powerpc(const Obj_Entry *, Elf_Word); -extern int _rtld_reloc_powerpc_plt(const Obj_Entry *, const Elf_RelA *, bool); -extern void _rtld_setup_powerpc_plt(const Obj_Entry *); +caddr_t _rtld_bind_powerpc __P((const Obj_Entry *, Elf_Word)); +int _rtld_reloc_powerpc_plt __P((const Obj_Entry *, const Elf_RelA *, bool)); +void _rtld_setup_powerpc_plt __P((const Obj_Entry *)); #endif -#endif /* } */ +#endif diff --git a/libexec/ld.elf_so/rtldenv.h b/libexec/ld.elf_so/rtldenv.h index 2c157b0e7e30..d5bde740ad9d 100644 --- a/libexec/ld.elf_so/rtldenv.h +++ b/libexec/ld.elf_so/rtldenv.h @@ -1,4 +1,4 @@ -/* $NetBSD: rtldenv.h,v 1.2 1997/10/08 08:55:38 mrg Exp $ */ +/* $NetBSD: rtldenv.h,v 1.3 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 Matt Thomas @@ -33,40 +33,49 @@ #include #include -extern void *xcalloc(size_t); -extern void *xmalloc(size_t); -extern char *xstrdup(const char *); +void *xcalloc __P((size_t)); +void *xmalloc __P((size_t)); +char *xstrdup __P((const char *)); #ifdef RTLD_LOADER -extern void xprintf(const char *fmt, ...); -extern void xvprintf(const char *fmt, va_list ap); -extern void xsnprintf(char *buf, size_t buflen, const char *fmt, ...); -extern size_t xvsnprintf(char *buf, size_t buflen, const char *fmt, va_list ap); -extern void xwarn(const char *fmt, ...); -extern void xwarnx(const char *fmt, ...); -extern void xerr(int eval, const char *fmt, ...); -extern void xerrx(int eval, const char *fmt, ...); -extern void xassert(const char *file, int line, const char *failedexpr); -extern const char *xstrerror(int error); +void xprintf __P((const char *, ...)) + __attribute__((__format__(__printf__, 1, 2))); +void xvprintf __P((const char *, va_list)) + __attribute__((__format__(__printf__, 1, 0))); +void xsnprintf __P((char *, size_t, const char *, ...)) + __attribute__((__format__(__printf__, 3, 4))); +size_t xvsnprintf __P((char *, size_t, const char *, va_list)) + __attribute__((__format__(__printf__, 3, 0))); +void xwarn __P((const char *, ...)) + __attribute__((__format__(__printf__, 1, 2))); +void xwarnx __P((const char *, ...)) + __attribute__((__format__(__printf__, 1, 2))); +void xerr __P((int, const char *, ...)) + __attribute__((__format__(__printf__, 2, 3))); +void xerrx __P((int, const char *, ...)) + __attribute__((__format__(__printf__, 2, 3))); -#define assert(cond) ((cond) \ +void xassert __P((const char *, int, const char *)); +const char *xstrerror __P((int)); + +# define assert(cond) ((cond) \ ? (void) 0 :\ (xassert(__FILE__, __LINE__, #cond "\n"), abort())) #else -#include -#include -#include - -#define xprintf printf -#define xvprintf vprintf -#define xsnprintf snprintf -#define xvsnprintf vsnprintf -#define xwarn warn -#define xwarnx warnx -#define xerr err -#define xerrx errx -#define xassert assert -#define xstrerror strerror +# include +# include +# include + +# define xprintf printf +# define xvprintf vprintf +# define xsnprintf snprintf +# define xvsnprintf vsnprintf +# define xwarn warn +# define xwarnx warnx +# define xerr err +# define xerrx errx +# define xassert assert +# define xstrerror strerror #endif #endif /* _RTLDENV_H */ diff --git a/libexec/ld.elf_so/search.c b/libexec/ld.elf_so/search.c index 7c626c66edfe..5f41aee341dd 100644 --- a/libexec/ld.elf_so/search.c +++ b/libexec/ld.elf_so/search.c @@ -1,4 +1,4 @@ -/* $NetBSD: search.c,v 1.3 1997/02/17 19:32:05 cgd Exp $ */ +/* $NetBSD: search.c,v 1.4 1999/03/01 16:40:07 christos Exp $ */ /* * Copyright 1996 Matt Thomas @@ -61,66 +61,74 @@ /* * Data declarations. */ +static bool _rtld_check_library __P((const char *)); +static char *_rtld_search_library_path __P((const char *, size_t, const char *, + size_t)); static bool -_rtld_check_library( - const char *pathname) +_rtld_check_library(pathname) + const char *pathname; { - struct stat mystat; - Elf_Ehdr ehdr; - int fd; + struct stat mystat; + Elf_Ehdr ehdr; + int fd; - if (stat(pathname, &mystat) >= 0 && S_ISREG(mystat.st_mode)) { - if ((fd = open(pathname, O_RDONLY)) >= 0) { - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) + if (stat(pathname, &mystat) == -1 || !S_ISREG(mystat.st_mode)) + return false; + + if ((fd = open(pathname, O_RDONLY)) == -1) + return false; + + if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) goto lose; - /* Elf_e_ident includes class */ - if (memcmp(Elf_e_ident, ehdr.e_ident, Elf_e_siz) != 0) + /* Elf_e_ident includes class */ + if (memcmp(Elf_e_ident, ehdr.e_ident, Elf_e_siz) != 0) goto lose; - switch (ehdr.e_machine) { - ELFDEFNNAME(MACHDEP_ID_CASES) - - default: + switch (ehdr.e_machine) { + ELFDEFNNAME(MACHDEP_ID_CASES) + default: goto lose; - } + } - if (ehdr.e_ident[Elf_ei_version] != Elf_ev_current || - ehdr.e_version != Elf_ev_current || - ehdr.e_ident[Elf_ei_data] != ELFDEFNNAME(MACHDEP_ENDIANNESS) || - ehdr.e_type != Elf_et_dyn) + if (ehdr.e_ident[Elf_ei_version] != Elf_ev_current || + ehdr.e_version != Elf_ev_current || + ehdr.e_ident[Elf_ei_data] != ELFDEFNNAME(MACHDEP_ENDIANNESS) || + ehdr.e_type != Elf_et_dyn) goto lose; - close(fd); - return true; + close(fd); + return true; lose: - close(fd); - } - } - - return false; + close(fd); + return false; } static char * -_rtld_search_library_path(const char *name, int namelen, const char *dir, int dirlen) +_rtld_search_library_path(name, namelen, dir, dirlen) + const char *name; + size_t namelen; + const char *dir; + size_t dirlen; { char *pathname; pathname = xmalloc(dirlen + 1 + namelen + 1); - strncpy(pathname, dir, dirlen); + (void)strncpy(pathname, dir, dirlen); pathname[dirlen] = '/'; strcpy(pathname + dirlen + 1, name); - dbg(" Trying \"%s\"", pathname); - if(_rtld_check_library(pathname)) /* We found it */ + dbg((" Trying \"%s\"", pathname)); + if (_rtld_check_library(pathname)) /* We found it */ return pathname; free(pathname); return NULL; } + /* * Find the library with the given name, and return its full pathname. * The returned string is dynamically allocated. Generates an error @@ -130,42 +138,47 @@ _rtld_search_library_path(const char *name, int namelen, const char *dir, int di * loaded shared object, whose library search path will be searched. */ char * -_rtld_find_library( - const char *name, - const Obj_Entry *refobj) +_rtld_find_library(name, refobj) + const char *name; + const Obj_Entry *refobj; { - Search_Path *sp; - char *pathname; - int namelen; + Search_Path *sp; + char *pathname; + int namelen; - if (strchr(name, '/') != NULL) { /* Hard coded pathname */ - if (name[0] != '/' && !_rtld_trust) { - _rtld_error("Absolute pathname required for shared object \"%s\"", - name); - return NULL; - } + if (strchr(name, '/') != NULL) { /* Hard coded pathname */ + if (name[0] != '/' && !_rtld_trust) { + _rtld_error( + "Absolute pathname required for shared object \"%s\"", + name); + return NULL; + } #ifdef SVR4_LIBDIR - if (strncmp(name, SVR4_LIBDIR, SVR4_LIBDIRLEN) == 0 - && name[SVR4_LIBDIRLEN] == '/') { /* In "/usr/lib" */ - /* Map hard-coded "/usr/lib" onto our ELF library directory. */ - pathname = xmalloc(strlen(name) + LIBDIRLEN - SVR4_LIBDIRLEN + 1); - strcpy(pathname, LIBDIR); - strcpy(pathname + LIBDIRLEN, name + SVR4_LIBDIRLEN); - return pathname; - } + if (strncmp(name, SVR4_LIBDIR, SVR4_LIBDIRLEN) == 0 + && name[SVR4_LIBDIRLEN] == '/') { /* In "/usr/lib" */ + /* + * Map hard-coded "/usr/lib" onto our ELF library + * directory. + */ + pathname = xmalloc(strlen(name) + LIBDIRLEN - + SVR4_LIBDIRLEN + 1); + (void)strcpy(pathname, LIBDIR); + (void)strcpy(pathname + LIBDIRLEN, name + + SVR4_LIBDIRLEN); + return pathname; + } #endif /* SVR4_LIBDIR */ - return xstrdup(name); - } - - dbg(" Searching for \"%s\" (%p)", name, refobj); + return xstrdup(name); + } + dbg((" Searching for \"%s\" (%p)", name, refobj)); namelen = strlen(name); - if (refobj != NULL) - for (sp = refobj->rpaths; sp != NULL; sp = sp->sp_next) - if ((pathname = _rtld_search_library_path(name, namelen, - sp->sp_path, sp->sp_pathlen)) != NULL) - return (pathname); + if (refobj != NULL) + for (sp = refobj->rpaths; sp != NULL; sp = sp->sp_next) + if ((pathname = _rtld_search_library_path(name, namelen, + sp->sp_path, sp->sp_pathlen)) != NULL) + return (pathname); for (sp = _rtld_paths; sp != NULL; sp = sp->sp_next) if ((pathname = _rtld_search_library_path(name, namelen, @@ -173,17 +186,19 @@ _rtld_find_library( return (pathname); #if 0 - if((refobj != NULL && - (pathname = _rtld_search_library_path(name, refobj->rpath)) != NULL) || - (pathname = _rtld_search_library_path(name, ld_library_path)) != NULL + if ((refobj != NULL && + (pathname = _rtld_search_library_path(name, + refobj->rpath)) != NULL) || + (pathname = _rtld_search_library_path(name, + ld_library_path)) != NULL #ifdef SVR4_LIBDIR - LOSE! - || (pathname = _rtld_search_library_path(name, SVR4_LIBDIR)) != NULL + LOSE ! + ||(pathname = _rtld_search_library_path(name, SVR4_LIBDIR)) != NULL #endif - ) + ) return pathname; #endif - _rtld_error("Shared object \"%s\" not found", name); - return NULL; + _rtld_error("Shared object \"%s\" not found", name); + return NULL; } diff --git a/libexec/ld.elf_so/symbol.c b/libexec/ld.elf_so/symbol.c index adbcf583ff38..8ef4f0e32801 100644 --- a/libexec/ld.elf_so/symbol.c +++ b/libexec/ld.elf_so/symbol.c @@ -1,4 +1,4 @@ -/* $NetBSD: symbol.c,v 1.2 1998/03/25 04:13:02 mhitch Exp $ */ +/* $NetBSD: symbol.c,v 1.3 1999/03/01 16:40:08 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -57,20 +57,20 @@ * this. It is specified by the System V ABI. */ unsigned long -_rtld_elf_hash( - const char *name) +_rtld_elf_hash(name) + const char *name; { - const unsigned char *p = (const unsigned char *) name; - unsigned long h = 0; - unsigned long g; + const unsigned char *p = (const unsigned char *) name; + unsigned long h = 0; + unsigned long g; - while(*p != '\0') { - h = (h << 4) + *p++; - if ((g = h & 0xf0000000) != 0) - h ^= g >> 24; - h &= ~g; - } - return h; + while (*p != '\0') { + h = (h << 4) + *p++; + if ((g = h & 0xf0000000) != 0) + h ^= g >> 24; + h &= ~g; + } + return h; } /* @@ -82,40 +82,39 @@ _rtld_elf_hash( * eliminates many recomputations of the hash value. */ const Elf_Sym * -_rtld_symlook_obj( - const char *name, - unsigned long hash, - const Obj_Entry *obj, - bool in_plt) +_rtld_symlook_obj(name, hash, obj, in_plt) + const char *name; + unsigned long hash; + const Obj_Entry *obj; + bool in_plt; { - unsigned long symnum = obj->buckets[hash % obj->nbuckets]; + unsigned long symnum = obj->buckets[hash % obj->nbuckets]; - while (symnum != ELF_SYM_UNDEFINED) { - const Elf_Sym *symp; - const char *strp; + while (symnum != ELF_SYM_UNDEFINED) { + const Elf_Sym *symp; + const char *strp; - assert(symnum < obj->nchains); - symp = obj->symtab + symnum; - strp = obj->strtab + symp->st_name; + assert(symnum < obj->nchains); + symp = obj->symtab + symnum; + strp = obj->strtab + symp->st_name; #if 0 - assert(symp->st_name != 0); + assert(symp->st_name != 0); #endif - if (strcmp(name, strp) == 0) { - if (symp->st_shndx != Elf_eshn_undefined -#if !defined(__mips__) /* Following doesn't work on MIPS? mhitch */ - || (!in_plt && symp->st_value != 0 && - ELF_SYM_TYPE(symp->st_info) == Elf_estt_func)) { + if (strcmp(name, strp) == 0) { + if (symp->st_shndx != Elf_eshn_undefined +#if !defined(__mips__) /* Following doesn't work on MIPS? mhitch */ + || (!in_plt && symp->st_value != 0 && + ELF_SYM_TYPE(symp->st_info) == Elf_estt_func)) { #else - ) { + ) { #endif - return symp; - } + return symp; + } + } + symnum = obj->chains[symnum]; } - symnum = obj->chains[symnum]; - } - - return NULL; + return NULL; } /* @@ -125,51 +124,55 @@ _rtld_symlook_obj( * defining object via the reference parameter DEFOBJ_OUT. */ const Elf_Sym * -_rtld_find_symdef( - const Obj_Entry *obj_list, - Elf_Word r_info, - const char *name, - const Obj_Entry *refobj, - const Obj_Entry **defobj_out, - bool in_plt) +_rtld_find_symdef(obj_list, r_info, name, refobj, defobj_out, in_plt) + const Obj_Entry *obj_list; + Elf_Word r_info; + const char *name; + const Obj_Entry *refobj; + const Obj_Entry **defobj_out; + bool in_plt; { - Elf_Word symnum = ELF_R_SYM(r_info); - const Elf_Sym *ref; - const Obj_Entry *obj; - unsigned long hash; + Elf_Word symnum = ELF_R_SYM(r_info); + const Elf_Sym *ref; + const Obj_Entry *obj; + unsigned long hash; - if (name == NULL) { - ref = refobj->symtab + symnum; - name = refobj->strtab + ref->st_name; - } - hash = _rtld_elf_hash(name); - - if (refobj->symbolic) { /* Look first in the referencing object */ - const Elf_Sym *def = _rtld_symlook_obj(name, hash, refobj, in_plt); - if (def != NULL) { - *defobj_out = refobj; - return def; + if (name == NULL) { + ref = refobj->symtab + symnum; + name = refobj->strtab + ref->st_name; } - } + hash = _rtld_elf_hash(name); - /* - * Look in all loaded objects. Skip the referencing object, if - * we have already searched it. - */ - for (obj = obj_list; obj != NULL; obj = obj->next) { - if (obj != refobj || !refobj->symbolic) { - const Elf_Sym *def = _rtld_symlook_obj(name, hash, obj, in_plt); - if (def != NULL) { - *defobj_out = obj; - return def; - } + if (refobj->symbolic) { /* Look first in the referencing object */ + const Elf_Sym *def; + + def = _rtld_symlook_obj(name, hash, refobj, in_plt); + if (def != NULL) { + *defobj_out = refobj; + return def; + } } - } + /* + * Look in all loaded objects. Skip the referencing object, if + * we have already searched it. + */ + for (obj = obj_list; obj != NULL; obj = obj->next) { + if (obj != refobj || !refobj->symbolic) { + const Elf_Sym *def; - if (ELF_R_TYPE(r_info) != R_TYPE(NONE)) { - _rtld_error("%s: Undefined %ssymbol \"%s\" (reloc type = %d, symnum = %d)", - refobj->path, in_plt ? "PLT " : "", name, - ELF_R_TYPE(r_info), symnum); - } - return NULL; + def = _rtld_symlook_obj(name, hash, obj, in_plt); + if (def != NULL) { + *defobj_out = obj; + return def; + } + } + } + + if (ELF_R_TYPE(r_info) != R_TYPE(NONE)) { + _rtld_error( + "%s: Undefined %ssymbol \"%s\" (reloc type = %d, symnum = %d)", + refobj->path, in_plt ? "PLT " : "", name, + ELF_R_TYPE(r_info), symnum); + } + return NULL; } diff --git a/libexec/ld.elf_so/xmalloc.c b/libexec/ld.elf_so/xmalloc.c index 260312e353d3..d16a693da60f 100644 --- a/libexec/ld.elf_so/xmalloc.c +++ b/libexec/ld.elf_so/xmalloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: xmalloc.c,v 1.1 1996/12/16 20:38:07 cgd Exp $ */ +/* $NetBSD: xmalloc.c,v 1.2 1999/03/01 16:40:08 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -31,31 +31,36 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include "rtldenv.h" #include +#include #include #include void * -xcalloc(size_t size) +xcalloc(size) + size_t size; { - return memset(xmalloc(size), 0, size); + return memset(xmalloc(size), 0, size); } void * -xmalloc(size_t size) +xmalloc(size) + size_t size; { - void *p = malloc(size); - if(p == NULL) - xerr(1, "Out of memory"); - return p; + void *p = malloc(size); + if (p == NULL) + xerr(1, "%s", xstrerror(errno)); + return p; } -char * -xstrdup(const char *s) +char* +xstrdup(s) + const char *s; { - char *p = strdup(s); - if(p == NULL) - xerr(1, "Out of memory"); - return p; + char *p = strdup(s); + if (p == NULL) + xerr(1, "%s", xstrerror(errno)); + return p; } diff --git a/libexec/ld.elf_so/xprintf.c b/libexec/ld.elf_so/xprintf.c index 929c7061d162..2f18612f4fe2 100644 --- a/libexec/ld.elf_so/xprintf.c +++ b/libexec/ld.elf_so/xprintf.c @@ -1,4 +1,4 @@ -/* $NetBSD: xprintf.c,v 1.3 1999/02/27 21:52:23 scottr Exp $ */ +/* $NetBSD: xprintf.c,v 1.4 1999/03/01 16:40:08 christos Exp $ */ /* * Copyright 1996 Matt Thomas @@ -27,10 +27,16 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include "rtldenv.h" #include #include #include +#ifdef __STDC__ +#include +#else +#include +#endif #define SZ_SHORT 0x01 #define SZ_INT 0x02 @@ -46,263 +52,333 @@ * deals withs formats %x, %p, %s, and %d. */ size_t -xvsnprintf( - char *buf, - size_t buflen, - const char *fmt, - va_list ap) +xvsnprintf(buf, buflen, fmt, ap) + char *buf; + size_t buflen; + const char *fmt; + va_list ap; { - char *bp = buf; - char * const ep = buf + buflen - 4; - int size; + char *bp = buf; + char *const ep = buf + buflen - 4; + int size; - while (*fmt != NULL && bp < ep) { - switch (*fmt) { - case '\\': { - if (fmt[1] != '\0') - *bp++ = *++fmt; - continue; - } - case '%': { - size = SZ_INT; -rflag: switch (fmt[1]) { - case 'h': - size = (size & SZ_MASK) | SZ_SHORT; - fmt++; - goto rflag; - case 'l': - size = (size & SZ_MASK) | SZ_LONG; - fmt++; - if (fmt[1] == 'l') { - case 'q': - size = (size & SZ_MASK) | SZ_QUAD; - fmt++; + while (*fmt != NULL && bp < ep) { + switch (*fmt) { + case '\\':{ + if (fmt[1] != '\0') + *bp++ = *++fmt; + continue; } - goto rflag; - case 'u': - size |= SZ_UNSIGNED; - /* FALLTHROUGH*/ - case 'd': { - long long sval; - unsigned long long uval; - char digits[sizeof(int) * 3], *dp = digits; + case '%':{ + size = SZ_INT; + rflag: switch (fmt[1]) { + case 'h': + size = (size&SZ_MASK)|SZ_SHORT; + fmt++; + goto rflag; + case 'l': + size = (size&SZ_MASK)|SZ_LONG; + fmt++; + if (fmt[1] == 'l') { + case 'q': + size = (size&SZ_MASK)|SZ_QUAD; + fmt++; + } + goto rflag; + case 'u': + size |= SZ_UNSIGNED; + /* FALLTHROUGH */ + case 'd':{ + long long sval; + unsigned long long uval; + char digits[sizeof(int) * 3], *dp = digits; #define SARG() \ - (size & SZ_SHORT ? va_arg(ap, short) : \ - size & SZ_LONG ? va_arg(ap, long) : \ - size & SZ_QUAD ? va_arg(ap, long long) : \ - va_arg(ap, int)) +(size & SZ_SHORT ? va_arg(ap, short) : \ +size & SZ_LONG ? va_arg(ap, long) : \ +size & SZ_QUAD ? va_arg(ap, long long) : \ +va_arg(ap, int)) #define UARG() \ - (size & SZ_SHORT ? va_arg(ap, unsigned short) : \ - size & SZ_LONG ? va_arg(ap, unsigned long) : \ - size & SZ_QUAD ? va_arg(ap, unsigned long long) : \ - va_arg(ap, unsigned int)) +(size & SZ_SHORT ? va_arg(ap, unsigned short) : \ +size & SZ_LONG ? va_arg(ap, unsigned long) : \ +size & SZ_QUAD ? va_arg(ap, unsigned long long) : \ +va_arg(ap, unsigned int)) #define ARG() (size & SZ_UNSIGNED ? UARG() : SARG()) - if (fmt[1] == 'd') { - sval = ARG(); - if (sval < 0) { - if ((sval << 1) == 0) { - /* - * We can't flip the sign of this since - * it's can't represented as a postive - * number in two complement, handle the - * first digit. After that, it can be - * flipped since it is now not 2^(n-1). - */ - *dp++ = '0' - (sval % 10); - sval /= 10; + if (fmt[1] == 'd') { + sval = ARG(); + if (sval < 0) { + if ((sval << 1) == 0) { + /* + * We can't flip the + * sign of this since + * it can't be + * represented as a + * positive number in + * two complement, + * handle the first + * digit. After that, + * it can be flipped + * since it is now not + * 2^(n-1). + */ + *dp++ = '0'-(sval % 10); + sval /= 10; + } + *bp++ = '-'; + uval = -sval; + } else { + uval = sval; + } + } else { + uval = ARG(); + } + do { + *dp++ = '0' + (uval % 10); + uval /= 10; + } while (uval != 0); + do { + *bp++ = *--dp; + } while (dp != digits && bp < ep); + fmt += 2; + break; } - *bp++ = '-'; - uval = -sval; - } else { - uval = sval; - } - } else { - uval = ARG(); - } - do { - *dp++ = '0' + (uval % 10); - uval /= 10; - } while (uval != 0); - do { - *bp++ = *--dp; - } while (dp != digits && bp < ep); - fmt += 2; - break; - } - case 'x': case 'p': { - unsigned long val = va_arg(ap, unsigned long); - unsigned long mask = ~(~0UL >> 4); - int bits = sizeof(val) * 8 - 4; - const char hexdigits[] = "0123456789abcdef"; - if (fmt[1] == 'p') { - *bp++ = '0'; - *bp++ = 'x'; - } - /* handle the border case */ - if (val == 0) { - *bp++ = '0'; - fmt += 2; - break; - } - /* suppress 0s */ - while ((val & mask) == 0) - bits -= 4, mask >>= 4; + case 'x': + case 'p':{ + unsigned long val = va_arg(ap, unsigned long); + unsigned long mask = ~(~0UL >> 4); + int bits = sizeof(val) * 8 - 4; + const char hexdigits[] = "0123456789abcdef"; + if (fmt[1] == 'p') { + *bp++ = '0'; + *bp++ = 'x'; + } + /* handle the border case */ + if (val == 0) { + *bp++ = '0'; + fmt += 2; + break; + } + /* suppress 0s */ + while ((val & mask) == 0) + bits -= 4, mask >>= 4; - /* emit the hex digits */ - while (bits >= 0 && bp < ep) { - *bp++ = hexdigits[(val & mask) >> bits]; - bits -= 4, mask >>= 4; - } - fmt += 2; - break; - } - case 's': { - const char *str = va_arg(ap, const char *); - int len; - if (str == NULL) - str = "(null)"; + /* emit the hex digits */ + while (bits >= 0 && bp < ep) { + *bp++ = hexdigits[(val & mask) >> bits]; + bits -= 4, mask >>= 4; + } + fmt += 2; + break; + } + case 's':{ + const char *str = va_arg(ap, const char *); + int len; - len = strlen(str); - if (ep - bp < len) - len = ep - bp; - memcpy(bp, str, len); - bp += len; - fmt += 2; - break; - } - default: - *bp++ = *fmt; - break; - } - break; + if (str == NULL) + str = "(null)"; + + len = strlen(str); + if (ep - bp < len) + len = ep - bp; + memcpy(bp, str, len); + bp += len; + fmt += 2; + break; + } + default: + *bp++ = *fmt; + break; + } + break; + } + default: + *bp++ = *fmt++; + break; + } } - default: - *bp++ = *fmt++; - break; - } - } - - *bp = '\0'; - return bp - buf; + *bp = '\0'; + return bp - buf; } void -xvprintf( - const char *fmt, - va_list ap) +xvprintf(fmt, ap) + const char *fmt; + va_list ap; { - char buf[256]; - (void) write(2, buf, xvsnprintf(buf, sizeof(buf), fmt, ap)); + char buf[256]; + (void) write(2, buf, xvsnprintf(buf, sizeof(buf), fmt, ap)); } void -xprintf( - const char *fmt, - ...) +#ifdef __STDC__ +xprintf(const char *fmt, ...) +#else +xprintf(va_alist) + va_dcl +#endif { - va_list ap; - va_start(ap, fmt); + va_list ap; - xvprintf(fmt, ap); +#ifdef __STDC__ + va_start(ap, fmt); +#else + const char *fmt; - va_end(ap); + va_start(ap); + fmt = va_arg(ap, const char *); +#endif + + xvprintf(fmt, ap); + + va_end(ap); } void -xsnprintf( - char *buf, - size_t buflen, - const char *fmt, - ...) +#ifdef __STDC__ +xsnprintf(char *buf, size_t buflen, const char *fmt, ...) +#else +xsnprintf(va_alist) + va_dcl +#endif { - va_list ap; - va_start(ap, fmt); + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + char *buf; + size_t buflen; + const char *fmt; - xvprintf(fmt, ap); + va_start(ap); + buf = va_arg(ap, char *); + buflen = va_arg(ap, size_t); + fmt = va_arg(ap, const char *); +#endif + xvsnprintf(buf, buflen, fmt, ap); - va_end(ap); + va_end(ap); } const char * -xstrerror( - int error) +xstrerror(error) + int error; { - if (error >= sys_nerr) { - static char buf[128]; - xsnprintf(buf, sizeof(buf), "Unknown error: %d", error); - return buf; - } - return sys_errlist[error]; + if (error >= sys_nerr || error < 0) { + static char buf[128]; + xsnprintf(buf, sizeof(buf), "Unknown error: %d", error); + return buf; + } + return sys_errlist[error]; } void -xerrx( - int eval, - const char *fmt, - ...) +#ifdef __STDC__ +xerrx(int eval, const char *fmt, ...) +#else +xerrx(va_alist) + va_dcl +#endif { - va_list ap; - va_start(ap, fmt); - xvprintf(fmt, ap); - va_end(ap); + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + int eval; + const char *fmt; - exit(eval); + va_start(ap); + eval = va_arg(ap, int); + fmt = va_arg(ap, const char *); +#endif + + xvprintf(fmt, ap); + va_end(ap); + + exit(eval); } void -xerr( - int eval, - const char *fmt, - ...) +#ifdef __STDC__ +xerr(int eval, const char *fmt, ...) +#else +xerr(va_alist) + va_dcl +#endif { - int saved_errno = errno; + int saved_errno = errno; + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + int eval; + const char *fmt; - va_list ap; - va_start(ap, fmt); - xvprintf(fmt, ap); - va_end(ap); + va_start(ap); + eval = va_arg(ap, int); + fmt = va_arg(ap, const char *); +#endif + xvprintf(fmt, ap); + va_end(ap); - xprintf(": %s\n", xstrerror(saved_errno)); - exit(eval); + xprintf(": %s\n", xstrerror(saved_errno)); + exit(eval); } void -xwarn( - const char *fmt, - ...) +#ifdef __STDC__ +xwarn(const char *fmt, ...) +#else +xwarn(va_alist) + va_dcl +#endif { - int saved_errno = errno; + int saved_errno = errno; + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + const char *fmt; - va_list ap; - va_start(ap, fmt); - xvprintf(fmt, ap); - va_end(ap); + va_start(ap); + fmt = va_arg(ap, const char *); +#endif + xvprintf(fmt, ap); + va_end(ap); - xprintf(": %s\n", xstrerror(saved_errno)); - errno = saved_errno; + xprintf(": %s\n", xstrerror(saved_errno)); + errno = saved_errno; } void -xwarnx( - const char *fmt, - ...) +#ifdef __STDC__ +xwarnx(const char *fmt, ...) +#else +xwarnx(va_alist) + va_dcl +#endif { - va_list ap; - va_start(ap, fmt); - xvprintf(fmt, ap); - va_end(ap); + va_list ap; +#ifdef __STDC__ + va_start(ap, fmt); +#else + const char *fmt; + + va_start(ap); + fmt = va_arg(ap, const char *); +#endif + xvprintf(fmt, ap); + va_end(ap); } void -xassert( - const char *file, - int line, - const char *failedexpr) +xassert(file, line, failedexpr) + const char *file; + int line; + const char *failedexpr; { - xprintf("assertion \"%s\" failed: file \"%s\", line %d\n", - failedexpr, file, line); - abort(); - /* NOTREACHED */ + xprintf("assertion \"%s\" failed: file \"%s\", line %d\n", + failedexpr, file, line); + abort(); + /* NOTREACHED */ }