summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs/rtld/common/a.out.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/sgs/rtld/common/a.out.c')
-rw-r--r--usr/src/cmd/sgs/rtld/common/a.out.c768
1 files changed, 0 insertions, 768 deletions
diff --git a/usr/src/cmd/sgs/rtld/common/a.out.c b/usr/src/cmd/sgs/rtld/common/a.out.c
deleted file mode 100644
index 693b4f59bc..0000000000
--- a/usr/src/cmd/sgs/rtld/common/a.out.c
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * Object file dependent support for a.out format objects.
- */
-
-#include <a.out.h> /* Explicitly override M_SEGSIZE */
-#include <machdep.h> /* used in M_SROUND */
-
-#include <sys/types.h>
-#include <sys/procfs.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <stdio.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <debug.h>
-#include "_a.out.h"
-#include "cache_a.out.h"
-#include "msg.h"
-#include "_rtld.h"
-
-/*
- * Default and secure dependency search paths.
- */
-static Spath_defn _aout_def_dirs[] = {
- { MSG_ORIG(MSG_PTH_USRLIB), MSG_PTH_USRLIB_SIZE },
- { MSG_ORIG(MSG_PTH_USRLCLIB), MSG_PTH_USRLCLIB_SIZE },
- { 0, 0 }
-};
-
-static Spath_defn _aout_sec_dirs[] = {
- { MSG_ORIG(MSG_PTH_LIBSE), MSG_PTH_LIBSE_SIZE },
- { 0, 0 }
-};
-
-Alist *aout_def_dirs = NULL;
-Alist *aout_sec_dirs = NULL;
-
-/*
- * Defines for local functions.
- */
-static void aout_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int);
-static int aout_dlsym_handle(Grp_hdl *, Slookup *, Sresult *, uint_t *,
- int *);
-static Addr aout_entry_point(void);
-static int aout_find_sym(Slookup *, Sresult *, uint_t *, int *);
-static int aout_fix_name(const char *, Rt_map *, Alist **, Aliste, uint_t);
-static Alist **aout_get_def_dirs(void);
-static Alist **aout_get_sec_dirs(void);
-static char *aout_get_so(const char *, const char *, size_t, size_t);
-static int aout_needed(Lm_list *, Aliste, Rt_map *, int *);
-
-/*
- * Functions and data accessed through indirect pointers.
- */
-Fct aout_fct = {
- aout_verify,
- aout_new_lmp,
- aout_entry_point,
- aout_needed,
- aout_lookup_sym,
- aout_reloc,
- aout_get_def_dirs,
- aout_get_sec_dirs,
- aout_fix_name,
- aout_get_so,
- aout_dladdr,
- aout_dlsym_handle
-};
-
-/*
- * Default and secure dependency search paths.
- */
-static Alist **
-aout_get_def_dirs()
-{
- if (aout_def_dirs == NULL)
- set_dirs(&aout_def_dirs, _aout_def_dirs, LA_SER_DEFAULT);
- return (&aout_def_dirs);
-}
-
-static Alist **
-aout_get_sec_dirs()
-{
- if (aout_sec_dirs == NULL)
- set_dirs(&aout_sec_dirs, _aout_sec_dirs, LA_SER_SECURE);
- return (&aout_sec_dirs);
-}
-
-/*
- * In 4.x, a needed file or a dlopened file that was a simple file name implied
- * that the file be found in the present working directory. To simulate this
- * lookup within the ELF rules it is necessary to add a preceding `./' to the
- * filename.
- */
-/* ARGSUSED4 */
-static int
-aout_fix_name(const char *oname, Rt_map *clmp, Alist **alpp, Aliste alni,
- uint_t orig)
-{
- size_t len;
- Pdesc *pdp;
- const char *nname;
-
- /*
- * Check for slash in name, if none, prepend "./", otherwise just
- * return name given.
- */
- if (strchr(oname, '/')) {
- len = strlen(oname) + 1;
- if ((nname = stravl_insert(oname, 0, len, 0)) == NULL)
- return (0);
- } else {
- char buffer[PATH_MAX];
-
- len = strlen(oname) + 3;
- (void) snprintf(buffer, len, MSG_ORIG(MSG_FMT_4XPATH), oname);
- if ((nname = stravl_insert(buffer, 0, len, 0)) == NULL)
- return (0);
- }
-
- if ((pdp = alist_append(alpp, NULL, sizeof (Pdesc), alni)) == NULL)
- return (0);
-
- pdp->pd_pname = nname;
- pdp->pd_plen = len;
- pdp->pd_flags = PD_FLG_PNSLASH;
-
- DBG_CALL(Dbg_file_fixname(LIST(clmp), nname, oname));
- return (1);
-}
-
-/*
- * Determine if we have been given an A_OUT file. Returns 1 if true.
- */
-Fct *
-/* ARGSUSED1 */
-aout_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name,
- Rej_desc *rej)
-{
- /* LINTED */
- struct exec *exec = (struct exec *)addr;
-
- if (size < sizeof (exec) || (exec->a_machtype != M_SPARC) ||
- (N_BADMAG(*exec))) {
- return (NULL);
- }
- return (&aout_fct);
-}
-
-/*
- * Return the entry point of the A_OUT executable. Although the entry point
- * within an ELF file is flexible, the entry point of an A_OUT executable is
- * always zero.
- */
-static Addr
-aout_entry_point()
-{
- return (0);
-}
-
-/*
- * Search through the dynamic section for DT_NEEDED entries and perform one
- * of two functions. If only the first argument is specified then load the
- * defined shared object, otherwise add the link map representing the
- * defined link map the the dlopen list.
- */
-static int
-aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
-{
- Alist *palp = NULL;
- void *need;
-
- for (need = &TEXTBASE(clmp)[AOUTDYN(clmp)->v2->ld_need];
- need != &TEXTBASE(clmp)[0];
- need = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_next]) {
- Rt_map *nlmp;
- char *name;
-
- name = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_name];
-
- if (((Lnk_obj *)(need))->lo_library) {
- /*
- * If lo_library field is not NULL then this needed
- * library was linked in using the "-l" option.
- * Thus we need to rebuild the library name before
- * trying to load it.
- */
- char *file;
- size_t len;
-
- /*
- * Allocate name length plus 20 for full library name.
- * lib.so.. = 7 + (2 * short) + NULL = 7 + 12 + 1 = 20
- */
- len = strlen(name) + 20;
- if ((file = malloc(len)) == NULL)
- return (0);
- (void) snprintf(file, len, MSG_ORIG(MSG_FMT_4XLIB),
- name, ((Lnk_obj *)(need))->lo_major,
- ((Lnk_obj *)(need))->lo_minor);
-
- DBG_CALL(Dbg_libs_find(lml, file));
-
- /*
- * We need to determine what filename will match the
- * the filename specified (ie, a libc.so.1.2 may match
- * to a libc.so.1.3). It's the real pathname that is
- * recorded in the link maps. If we are presently
- * being traced, skip this pathname generation so
- * that we fall through into load_so() to print the
- * appropriate diagnostics. I don't like this at all.
- */
- if (lml->lm_flags & LML_FLG_TRC_ENABLE)
- name = file;
- else {
- Spath_desc sd = { search_rules, NULL, 0 };
- Pdesc *pdp;
- char *path = NULL;
-
- for (pdp = get_next_dir(&sd, clmp, 0); pdp;
- pdp = get_next_dir(&sd, clmp, 0)) {
- if (pdp->pd_pname == NULL)
- continue;
-
- if (path = aout_get_so(pdp->pd_pname,
- file, 0, 0))
- break;
- }
- if (path == NULL) {
- eprintf(lml, ERR_FATAL,
- MSG_INTL(MSG_SYS_OPEN), file,
- strerror(ENOENT));
- return (0);
- }
- name = path;
- }
- if (expand_paths(clmp, name, &palp,
- AL_CNT_NEEDED, 0, 0) == 0)
- return (0);
- } else {
- /*
- * If the library is specified as a pathname, see if
- * it must be fixed to specify the current working
- * directory (ie. libc.so.1.2 -> ./libc.so.1.2).
- */
- if (aout_fix_name(name, clmp, &palp,
- AL_CNT_NEEDED, 0) == 0)
- return (0);
- }
-
- DBG_CALL(Dbg_file_needed(clmp, name));
-
- nlmp = load_one(lml, lmco, palp, clmp, MODE(clmp), 0, 0,
- in_nfavl);
- remove_alist(&palp, 1);
- if (((nlmp == NULL) ||
- (bind_one(clmp, nlmp, BND_NEEDED) == 0)) &&
- ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
- return (0);
- }
-
- return (1);
-}
-
-static Sym *
-aout_symconvert(struct nlist *sp)
-{
- static Sym sym;
-
- sym.st_value = sp->n_value;
- sym.st_size = 0;
- sym.st_info = 0;
- sym.st_other = 0;
- switch (sp->n_type) {
- case N_EXT + N_ABS:
- sym.st_shndx = SHN_ABS;
- break;
- case N_COMM:
- sym.st_shndx = SHN_COMMON;
- break;
- case N_EXT + N_UNDF:
- sym.st_shndx = SHN_UNDEF;
- break;
- default:
- sym.st_shndx = 0;
- break;
- }
- return (&sym);
-}
-
-/*
- * Process a.out format commons.
- */
-static struct nlist *
-aout_find_com(struct nlist *sp, const char *name)
-{
- static struct rtc_symb *rtcp = NULL;
- struct rtc_symb *rs, *trs;
- const char *sl;
- char *cp;
-
- /*
- * See if common is already allocated.
- */
- trs = rtcp;
- while (trs) {
- sl = name;
- cp = trs->rtc_sp->n_un.n_name;
- while (*sl == *cp++)
- if (*sl++ == '\0')
- return (trs->rtc_sp);
- trs = trs->rtc_next;
- }
-
- /*
- * If we got here, common is not already allocated so allocate it.
- */
- if ((rs = malloc(sizeof (struct rtc_symb))) == NULL)
- return (NULL);
- if ((rs->rtc_sp = malloc(sizeof (struct nlist))) == NULL)
- return (NULL);
- trs = rtcp;
- rtcp = rs;
- rs->rtc_next = trs;
- *(rs->rtc_sp) = *sp;
- if ((rs->rtc_sp->n_un.n_name = malloc(strlen(name) + 1)) == NULL)
- return (NULL);
- (void) strcpy(rs->rtc_sp->n_un.n_name, name);
- rs->rtc_sp->n_type = N_COMM;
- if ((rs->rtc_sp->n_value =
- (long)calloc(rs->rtc_sp->n_value, 1)) == (long)NULL)
- return (NULL);
- return (rs->rtc_sp);
-}
-
-/*
- * Find a.out format symbol in the specified link map. Unlike the sister
- * elf routine we re-calculate the symbols hash value for each link map
- * we're looking at.
- */
-static struct nlist *
-aout_findsb(const char *aname, Rt_map *lmp, int flag)
-{
- const char *name = aname;
- char *cp;
- struct fshash *p;
- int i;
- struct nlist *sp;
- ulong_t hval = 0;
-
-#define HASHMASK 0x7fffffff
-#define RTHS 126
-
- /*
- * The name passed to us is in ELF format, thus it is necessary to
- * map this back to the A_OUT format to compute the hash value (see
- * mapping rules in aout_lookup_sym()). Basically the symbols are
- * mapped according to whether a leading `.' exists.
- *
- * elf symbol a.out symbol
- * i. .bar -> .bar (LKUP_LDOT)
- * ii. .nuts -> nuts
- * iii. foo -> _foo
- */
- if (*name == '.') {
- if (!(flag & LKUP_LDOT))
- name++;
- } else
- hval = '_';
-
- while (*name)
- hval = (hval << 1) + *name++;
- hval = hval & HASHMASK;
-
- i = hval % (AOUTDYN(lmp)->v2->ld_buckets == 0 ? RTHS :
- AOUTDYN(lmp)->v2->ld_buckets);
- p = LM2LP(lmp)->lp_hash + i;
-
- if (p->fssymbno != -1) {
- do {
- sp = &LM2LP(lmp)->lp_symtab[p->fssymbno];
- cp = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx];
- name = aname;
- if (*name == '.') {
- if (!(flag & LKUP_LDOT))
- name++;
- } else {
- cp++;
- }
- while (*name == *cp++) {
- if (*name++ == '\0')
- return (sp); /* found */
- }
- if (p->next == 0)
- return (NULL); /* not found */
- else
- continue;
- } while ((p = &LM2LP(lmp)->lp_hash[p->next]) != NULL);
- }
- return (NULL);
-}
-
-/*
- * The symbol name we have been asked to look up is in A_OUT format, this
- * symbol is mapped to the appropriate ELF format which is the standard by
- * which symbols are passed around ld.so.1. The symbols are mapped
- * according to whether a leading `_' or `.' exists.
- *
- * a.out symbol elf symbol
- * i. _foo -> foo
- * ii. .bar -> .bar (LKUP_LDOT)
- * iii. nuts -> .nuts
- */
-int
-aout_lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
-{
- char name[PATH_MAX];
- Slookup sl = *slp;
-
- DBG_CALL(Dbg_syms_lookup_aout(LIST(slp->sl_cmap), slp->sl_name));
-
- if (*sl.sl_name == '_')
- ++sl.sl_name;
- else if (*sl.sl_name == '.')
- sl.sl_flags |= LKUP_LDOT;
- else {
- name[0] = '.';
- (void) strcpy(&name[1], sl.sl_name);
- sl.sl_name = name;
- }
-
- /*
- * Call the generic lookup routine to cycle through the specified
- * link maps.
- */
- return (lookup_sym(&sl, srp, binfo, in_nfavl));
-}
-
-/*
- * Symbol lookup for an a.out format module.
- */
-/* ARGSUSED3 */
-static int
-aout_find_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
-{
- const char *name = slp->sl_name;
- Rt_map *ilmp = slp->sl_imap;
- struct nlist *sp;
-
- DBG_CALL(Dbg_syms_lookup(ilmp, name, MSG_ORIG(MSG_STR_AOUT)));
-
- if (sp = aout_findsb(name, ilmp, slp->sl_flags)) {
- if (sp->n_value != 0) {
- /*
- * is it a common?
- */
- if (sp->n_type == (N_EXT + N_UNDF)) {
- if ((sp = aout_find_com(sp, name)) == NULL)
- return (0);
- }
- srp->sr_dmap = ilmp;
- srp->sr_sym = aout_symconvert(sp);
- *binfo |= DBG_BINFO_FOUND;
- return (1);
- }
- }
- return (0);
-}
-
-/*
- * Create a new Rt_map structure for an a.out format object and
- * initializes all values.
- */
-/* ARGSUSED6 */
-Rt_map *
-aout_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize,
- void *odyn, Rt_map *clmp, int *in_nfavl)
-{
- const char *name = fdp->fd_nname;
- Rt_map *lmp;
- caddr_t base, caddr = (caddr_t)addr;
- Link_dynamic *ld = (Link_dynamic *)odyn;
- size_t lmsz, rtsz, prsz;
-
- DBG_CALL(Dbg_file_aout(lml, name, addr, msize, lml->lm_lmidstr, lmco));
-
- /*
- * Allocate space for the link-map and private a.out information. Once
- * these are allocated and initialized, we can use remove_so(0, lmp) to
- * tear down the link-map should any failures occur.
- */
- rtsz = S_DROUND(sizeof (Rt_map));
- prsz = S_DROUND(sizeof (Rt_aoutp));
- lmsz = rtsz + prsz + sizeof (struct ld_private);
- if ((lmp = calloc(lmsz, 1)) == NULL)
- return (NULL);
- AOUTPRV(lmp) = (void *)((uintptr_t)lmp + rtsz);
- ((Rt_aoutp *)AOUTPRV(lmp))->lm_lpd =
- (void *)((uintptr_t)lmp + rtsz + prsz);
- LMSIZE(lmp) = lmsz;
-
- /*
- * All fields not filled in were set to 0 by calloc.
- */
- NAME(lmp) = (char *)name;
- ADDR(lmp) = addr;
- MSIZE(lmp) = msize;
- SYMINTP(lmp) = aout_find_sym;
- FCT(lmp) = &aout_fct;
- LIST(lmp) = lml;
- OBJFLTRNDX(lmp) = FLTR_DISABLED;
- SORTVAL(lmp) = -1;
-
- /*
- * Specific settings for a.out format.
- */
- if (lml->lm_head == NULL) {
- base = (caddr_t)MAIN_BASE;
- FLAGS(lmp) |= FLG_RT_FIXED;
- } else
- base = caddr;
-
- /*
- * Fill in all AOUT information. Applications provide the Link_dynamic
- * offset via the boot block, but if this is a shared object that
- * ld.so.1 has mapped, then determine the Link_dynamic offset from the
- * mapped image.
- */
- if (ld == NULL) {
- /* LINTED */
- struct exec *exec = (struct exec *)caddr;
- struct nlist *nl;
-
- /* LINTED */
- nl = (struct nlist *)&caddr[N_SYMOFF(*exec)];
- /* LINTED */
- ld = (Link_dynamic *)&caddr[nl->n_value];
-
- ld->v2 = (struct link_dynamic_2 *)((int)ld->v2 + (int)caddr);
- }
- AOUTDYN(lmp) = ld;
-
- if ((RPATH(lmp) = (char *)&base[ld->v2->ld_rules]) == base)
- RPATH(lmp) = NULL;
- LM2LP(lmp)->lp_symbol_base = caddr;
- /* LINTED */
- LM2LP(lmp)->lp_plt = (struct jbind *)(&caddr[JMPOFF(ld)]);
- LM2LP(lmp)->lp_rp =
- /* LINTED */
- (struct relocation_info *)(&base[RELOCOFF(ld)]);
- /* LINTED */
- LM2LP(lmp)->lp_hash = (struct fshash *)(&base[HASHOFF(ld)]);
- /* LINTED */
- LM2LP(lmp)->lp_symtab = (struct nlist *)(&base[SYMOFF(ld)]);
- LM2LP(lmp)->lp_symstr = &base[STROFF(ld)];
- LM2LP(lmp)->lp_textbase = base;
- LM2LP(lmp)->lp_refcnt++;
- LM2LP(lmp)->lp_dlp = NULL;
-
- /*
- * Add the mapped object to the end of the link map list.
- */
- lm_append(lml, lmco, lmp);
- return (lmp);
-}
-
-/*
- * Build full pathname of shared object from the given directory name and
- * filename.
- */
-static char *
-/* ARGSUSED2 */
-aout_get_so(const char *dir, const char *file, size_t dlen, size_t flen)
-{
- struct db *dbp;
- char *path = NULL;
-
- if (dbp = lo_cache(dir)) {
- path = ask_db(dbp, file);
- }
- return (path);
-}
-
-/*
- * Determine the symbol location of an address within a link-map. Look for
- * the nearest symbol (whoes value is less than or equal to the required
- * address). This is the object specific part of dladdr().
- */
-static void
-aout_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info,
- int flags)
-{
- ulong_t ndx, cnt, base, _value;
- struct nlist *sym, *_sym;
-
- cnt = ((int)LM2LP(lmp)->lp_symstr - (int)LM2LP(lmp)->lp_symtab) /
- sizeof (struct nlist);
- sym = LM2LP(lmp)->lp_symtab;
-
- if (FLAGS(lmp) & FLG_RT_FIXED)
- base = 0;
- else
- base = ADDR(lmp);
-
- for (_sym = NULL, _value = 0, ndx = 0; ndx < cnt; ndx++, sym++) {
- ulong_t value;
-
- if (sym->n_type == (N_EXT + N_UNDF))
- continue;
-
- value = sym->n_value + base;
- if (value > addr)
- continue;
- if (value < _value)
- continue;
-
- _sym = sym;
- _value = value;
-
- if (value == addr)
- break;
- }
-
- if (_sym) {
- int _flags = flags & RTLD_DL_MASK;
-
- /*
- * The only way we can create a symbol entry is to use
- * aout_symconvert(), however this results in us pointing to
- * static data that could be overridden. In addition the AOUT
- * symbol format doesn't give us everything an ELF symbol does.
- * So, unless we get convinced otherwise, don't bother returning
- * a symbol entry for AOUT's.
- */
- if (_flags == RTLD_DL_SYMENT)
- *info = NULL;
- else if (_flags == RTLD_DL_LINKMAP)
- *info = (void *)lmp;
-
- dlip->dli_sname = &LM2LP(lmp)->lp_symstr[_sym->n_un.n_strx];
- dlip->dli_saddr = (void *)_value;
- }
-}
-
-/*
- * Continue processing a dlsym request. Lookup the required symbol in each
- * link-map specified by the handle. Note, that because this lookup is against
- * individual link-maps we don't need to supply a starting link-map to the
- * lookup routine (see lookup_sym():analyze.c).
- */
-static int
-aout_dlsym_handle(Grp_hdl *ghp, Slookup *slp, Sresult *srp, uint_t *binfo,
- int *in_nfavl)
-{
- char buffer[PATH_MAX];
- Slookup sl;
-
- if (dlsym_handle(ghp, slp, srp, binfo, in_nfavl))
- return (1);
-
- /*
- * Symbol not found as supplied. However, most of our symbols will
- * be in the "C" name space, where the implementation prepends a "_"
- * to the symbol as it emits it. Therefore, attempt to find the
- * symbol with the "_" prepend.
- */
- buffer[0] = '_';
- (void) strcpy(&buffer[1], slp->sl_name);
-
- sl = *slp;
- sl.sl_name = (const char *)buffer;
-
- return (dlsym_handle(ghp, &sl, srp, binfo, in_nfavl));
-}
-
-/*
- * The initial mapping of the a.out occurs through exec(2), and presently this
- * implementation doesn't provide a mmapobj_result_t array to ld.so.1. Thus,
- * aout_get_mmap() is called to create the mapping information. Unlike ELF,
- * the information that can be gathered from a mapped AOUT file, can be limited.
- * In some cases the AOUT header isn't available in the mapped image, and thus
- * this can't be inspected to determine the files size (the kernel always
- * returns a pointer to the AOUT dynamic structure, but this is only sufficient
- * to determine the size of the text segment).
- *
- * Therefore, the only generic mechanism of determining the AOUT's mapping is
- * to use /proc. Only two mappings are required, the text (to determine any
- * read-only region), and the data. The two mapping validate the range in
- * which any relocations will occur. Should there be an additional bss segment,
- * we don't care, as this can't be relocated, and we're never going to try
- * unmapping the a.out.
- */
-#define PROCSIZE 20
-
-int
-aout_get_mmap(Lm_list *lml, mmapobj_result_t *mpp)
-{
- prmap_t *maps;
- char proc[PROCSIZE];
- int num, err, fd;
-
- (void) snprintf(proc, PROCSIZE, MSG_ORIG(MSG_FMT_PROC),
- EC_SWORD(getpid()));
- if ((fd = open(proc, O_RDONLY)) == -1) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
- strerror(err));
- return (1);
- }
-
- if (ioctl(fd, PIOCNMAP, (void *)&num) == -1) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err));
- return (1);
- }
-
- if ((maps = malloc((num + 1) * sizeof (prmap_t))) == NULL)
- return (1);
-
- if (ioctl(fd, PIOCMAP, (void *)maps) == -1) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err));
- free(maps);
- return (1);
- }
-
- mpp->mr_addr = maps->pr_vaddr;
- mpp->mr_fsize = mpp->mr_msize = maps->pr_size;
- mpp->mr_prot = (PROT_READ | PROT_EXEC);
-
- mpp++, maps++;
-
- mpp->mr_addr = maps->pr_vaddr;
- mpp->mr_fsize = mpp->mr_msize = maps->pr_size;
- mpp->mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
-
- maps--;
- free(maps);
- return (0);
-}