Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Mar 2004 15:38:08 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 49690 for review
Message-ID:  <200403252338.i2PNc81Y072749@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=49690

Change 49690 by peter@peter_daintree on 2004/03/25 15:37:13

	checkpoint.  note that I got fed up and reindented.  There are
	changes, but not that many.  Mostly preperation and validation.

Affected files ...

.. //depot/projects/hammer/sys/kern/link_elf_obj.c#3 edit

Differences ...

==== //depot/projects/hammer/sys/kern/link_elf_obj.c#3 (text+ko) ====

@@ -60,70 +60,69 @@
 #include "linker_if.h"
 
 typedef struct elf_file {
-    struct linker_file	lf;		/* Common fields */
-    caddr_t		address;	/* Relocation address */
+	struct linker_file lf;		/* Common fields */
+	caddr_t		address;	/* Relocation address */
 #ifdef SPARSE_MAPPING
-    vm_object_t		object;		/* VM object to hold file pages */
+	vm_object_t	object;		/* VM object to hold file pages */
 #endif
-    caddr_t		strtab;		/* DT_STRTAB */
-    int			strsz;		/* DT_STRSZ */
-    const Elf_Sym*	symtab;		/* DT_SYMTAB */
-    const Elf_Rel*	pltrel;		/* DT_JMPREL */
-    int			pltrelsize;	/* DT_PLTRELSZ */
-    const Elf_Rela*	pltrela;	/* DT_JMPREL */
-    int			pltrelasize;	/* DT_PLTRELSZ */
-    const Elf_Rel*	rel;		/* DT_REL */
-    int			relsize;	/* DT_RELSZ */
-    const Elf_Rela*	rela;		/* DT_RELA */
-    int			relasize;	/* DT_RELASZ */
-    caddr_t		modptr;
-    const Elf_Sym*	ddbsymtab;	/* The symbol table we are using */
-    long		ddbsymcnt;	/* Number of symbols */
-    caddr_t		ddbstrtab;	/* String table */
-    long		ddbstrcnt;	/* number of bytes in string table */
-    caddr_t		symbase;	/* malloc'ed symbold base */
-    caddr_t		strbase;	/* malloc'ed string base */
+	caddr_t		strtab;		/* DT_STRTAB */
+	int		strsz;		/* DT_STRSZ */
+	const Elf_Sym*	symtab;		/* DT_SYMTAB */
+	const Elf_Rel*	pltrel;		/* DT_JMPREL */
+	int		pltrelsize;	/* DT_PLTRELSZ */
+	const Elf_Rela*	pltrela;	/* DT_JMPREL */
+	int		pltrelasize;	/* DT_PLTRELSZ */
+	const Elf_Rel*	rel;		/* DT_REL */
+	int		relsize;	/* DT_RELSZ */
+	const Elf_Rela*	rela;		/* DT_RELA */
+	int		relasize;	/* DT_RELASZ */
+	caddr_t		modptr;
+	const Elf_Sym*	ddbsymtab;	/* The symbol table we are using */
+	long		ddbsymcnt;	/* Number of symbols */
+	caddr_t		ddbstrtab;	/* String table */
+	long		ddbstrcnt;	/* number of bytes in string table */
+	caddr_t		symbase;	/* malloc'ed symbold base */
+	caddr_t		strbase;	/* malloc'ed string base */
 } *elf_file_t;
 
 static int	link_elf_link_common_finish(linker_file_t);
 static int	link_elf_link_preload(linker_class_t cls,
-				      const char*, linker_file_t*);
+    const char*, linker_file_t*);
 static int	link_elf_link_preload_finish(linker_file_t);
 static int	link_elf_load_file(linker_class_t, const char*, linker_file_t*);
 static int	link_elf_lookup_symbol(linker_file_t, const char*,
-				       c_linker_sym_t*);
+    c_linker_sym_t*);
 static int	link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*);
 static int	link_elf_search_symbol(linker_file_t, caddr_t value,
-				       c_linker_sym_t* sym, long* diffp);
+    c_linker_sym_t* sym, long* diffp);
 
 static void	link_elf_unload_file(linker_file_t);
 static int	link_elf_lookup_set(linker_file_t, const char *,
-				    void ***, void ***, int *);
+    void ***, void ***, int *);
 static int	link_elf_each_function_name(linker_file_t,
-				int (*)(const char *, void *),
-				void *);
+    int (*)(const char *, void *), void *);
 static void	link_elf_reloc_local(linker_file_t);
 
 static kobj_method_t link_elf_methods[] = {
-    KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
-    KOBJMETHOD(linker_symbol_values,	link_elf_symbol_values),
-    KOBJMETHOD(linker_search_symbol,	link_elf_search_symbol),
-    KOBJMETHOD(linker_unload,		link_elf_unload_file),
-    KOBJMETHOD(linker_load_file,	link_elf_load_file),
-    KOBJMETHOD(linker_link_preload,	link_elf_link_preload),
-    KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
-    KOBJMETHOD(linker_lookup_set,	link_elf_lookup_set),
-    KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
-    { 0, 0 }
+	KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
+	KOBJMETHOD(linker_symbol_values,	link_elf_symbol_values),
+	KOBJMETHOD(linker_search_symbol,	link_elf_search_symbol),
+	KOBJMETHOD(linker_unload,		link_elf_unload_file),
+	KOBJMETHOD(linker_load_file,		link_elf_load_file),
+	KOBJMETHOD(linker_link_preload,		link_elf_link_preload),
+	KOBJMETHOD(linker_link_preload_finish,	link_elf_link_preload_finish),
+	KOBJMETHOD(linker_lookup_set,		link_elf_lookup_set),
+	KOBJMETHOD(linker_each_function_name,	link_elf_each_function_name),
+	{ 0, 0 }
 };
 
 static struct linker_class link_elf_class = {
 #if ELF_TARG_CLASS == ELFCLASS32
-    "elf32",
+	"elf32",
 #else
-    "elf64",
+	"elf64",
 #endif
-    link_elf_methods, sizeof(struct elf_file)
+	link_elf_methods, sizeof(struct elf_file)
 };
 
 static int		relocate_file(elf_file_t ef);
@@ -131,7 +130,7 @@
 static void
 link_elf_error(const char *s)
 {
-    printf("kldload: %s\n", s);
+	printf("kldload: %s\n", s);
 }
 
 /*
@@ -141,14 +140,14 @@
 static int
 link_elf_link_common_finish(linker_file_t lf)
 {
-    int error;
+	int error;
 
-    /* Notify MD code that a module is being loaded. */
-    error = elf_cpu_load_file(lf);
-    if (error)
-	return (error);
+	/* Notify MD code that a module is being loaded. */
+	error = elf_cpu_load_file(lf);
+	if (error)
+		return (error);
 
-    return (0);
+	return (0);
 }
 
 static void
@@ -161,8 +160,8 @@
 SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
 
 static int
-link_elf_link_preload(linker_class_t cls,
-		      const char* filename, linker_file_t *result)
+link_elf_link_preload(linker_class_t cls, const char* filename,
+    linker_file_t *result)
 {
 	return (EFTYPE);
 }
@@ -175,460 +174,455 @@
 
 static int
 link_elf_load_file(linker_class_t cls, const char* filename,
-	linker_file_t* result)
+    linker_file_t* result)
 {
-    struct nameidata nd;
-    struct thread* td = curthread;	/* XXX */
-    Elf_Ehdr *hdr;
-    caddr_t firstpage;
-    int nbytes, i;
-    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;
-    int error = 0;
-    int resid, flags;
-    elf_file_t ef;
-    linker_file_t lf;
-    Elf_Shdr *shdr;
-    int symtabindex;
-    int symstrindex;
-    int symcnt;
-    int strcnt;
+	struct nameidata nd;
+	struct thread* td = curthread;	/* XXX */
+	Elf_Ehdr *hdr;
+	caddr_t firstpage;
+	int nbytes, i;
+	Elf_Phdr *phdr;
+	Elf_Phdr *phlimit;
+	Elf_Phdr *segs[2];
+	int nsegs;
+	caddr_t mapbase;
+	size_t mapsize;
+	Elf_Off base_offset;
+	Elf_Addr base_vaddr;
+	Elf_Addr base_vlimit;
+	int error = 0;
+	int resid, flags;
+	elf_file_t ef;
+	linker_file_t lf;
+	Elf_Shdr *shdr;
+	int symtabindex;
+	int symstrindex;
+	int symcnt;
+	int strcnt;
 
-    GIANT_REQUIRED;
+	GIANT_REQUIRED;
 
-    shdr = NULL;
-    lf = NULL;
+	shdr = NULL;
+	lf = NULL;
 
-    NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
-    flags = FREAD;
-    error = vn_open(&nd, &flags, 0, -1);
-    if (error)
-	return error;
-    NDFREE(&nd, NDF_ONLY_PNBUF);
+	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
+	flags = FREAD;
+	error = vn_open(&nd, &flags, 0, -1);
+	if (error)
+		return error;
+	NDFREE(&nd, NDF_ONLY_PNBUF);
 #ifdef MAC
-    error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
-    if (error) {
-	firstpage = NULL;
-	goto out;
-    }
+	error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
+	if (error) {
+		firstpage = NULL;
+		goto out;
+	}
 #endif
 
-    /*
-     * Read the elf header from the file.
-     */
-    firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK);
-    if (firstpage == NULL) {
-	error = ENOMEM;
-	goto out;
-    }
-    hdr = (Elf_Ehdr *)firstpage;
-    error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-    nbytes = PAGE_SIZE - resid;
-    if (error)
-	goto out;
+	/*
+	 * Read the elf header from the file.
+	 */
+	firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK);
+	if (firstpage == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+	hdr = (Elf_Ehdr *)firstpage;
+	error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+	    &resid, td);
+	nbytes = PAGE_SIZE - resid;
+	if (error)
+		goto out;
+	if (nbytes < sizeof(Elf_Ehdr))
+		error = ENOEXEC;
+		goto out;
+	}
 
-    if (!IS_ELF(*hdr)) {
-	error = ENOEXEC;
-	goto out;
-    }
+	if (!IS_ELF(*hdr)) {
+		error = ENOEXEC;
+		goto out;
+	}
 
-    if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
-      || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
-	link_elf_error("Unsupported file layout");
-	error = ENOEXEC;
-	goto out;
-    }
-    if (hdr->e_ident[EI_VERSION] != EV_CURRENT
-      || hdr->e_version != EV_CURRENT) {
-	link_elf_error("Unsupported file version");
-	error = ENOEXEC;
-	goto out;
-    }
-    if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
-	link_elf_error("Unsupported file type");
-	error = ENOEXEC;
-	goto out;
-    }
-    if (hdr->e_machine != ELF_TARG_MACH) {
-	link_elf_error("Unsupported machine");
-	error = ENOEXEC;
-	goto out;
-    }
+	if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
+	    || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
+		link_elf_error("Unsupported file layout");
+		error = ENOEXEC;
+		goto out;
+	}
+	if (hdr->e_ident[EI_VERSION] != EV_CURRENT
+	    || hdr->e_version != EV_CURRENT) {
+		link_elf_error("Unsupported file version");
+		error = ENOEXEC;
+		goto out;
+	}
+	if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
+		link_elf_error("Unsupported file type");
+		error = ENOEXEC;
+		goto out;
+	}
+	if (hdr->e_machine != ELF_TARG_MACH) {
+		link_elf_error("Unsupported machine");
+		error = ENOEXEC;
+		goto out;
+	}
 
-    /*
-     * 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.
-     * XXX section table, not program header.  And we should not depend
-     * XXX on this because the section table is likely to be bigger.
-     */
-    if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) &&
-	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) &&
-	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes)))
-	link_elf_error("Unreadable program headers");
+	/* Read in the section header */
+	nbytes = hdr->e_shnum * hdr->e_shentsize;
+	if (nbytes == 0 || hdr->e_shoff == 0 ||
+	    hdr->e_shentsize != sizeof(Elf_Shdr)) {
+		error = ENOEXEC;
+		goto out;
+	}
+	shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
+	if (shdr == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+	error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);
+	if (error)
+		goto out;
+	if (resid) {
+		error = ENOEXEC;
+		goto out;
+	}
 
-    /*
-     * Scan the program header entries, and save key information.
-     *
-     * We rely on there being exactly two load segments, text and data,
-     * in that order.
-     *
-     * XXX do several passes of section table instead.
-     * XXX 1) count various things needed to size arrays
-     * XXX 2) grab info about things like PROGBITS/REL/RELA/STRTAB/SYMTAB
-     * XXX 3) read the string and symbol tables so we can do relocations etc
-     * XXX 4) (later on) load the rest of the entries.
-     */
+	/*
+	 * Scan the program header entries, and save key information.
+	 *
+	 * We rely on there being exactly two load segments, text and data,
+	 * in that order.
+	 *
+	 * XXX do several passes of section table instead.
+	 * XXX 1) count various things needed to size arrays
+	 * XXX 2) grab info about things like PROGBITS/REL/RELA/STRTAB/SYMTAB
+	 * XXX 3) read the string and symbol tables so we can do relocations etc
+	 * XXX 4) (later on) load the rest of the entries.
+	 */
 /* XXX *************** STEP 1 GOES HERE ************* XXX */
-    phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff);
-    phlimit = phdr + hdr->e_phnum;
-    nsegs = 0;
-    phdyn = NULL;
-    phphdr = NULL;
-    while (phdr < phlimit) {
-	switch (phdr->p_type) {
-
-	case PT_LOAD:
-	    if (nsegs == 2) {
-		link_elf_error("Too many sections");
+	shdr = (Elf_Shdr *)shtbuf;
+	shlimit = shdr + hdr->e_phnum;
+	nbits = 0;
+	nnobits = 0;
+	nsym = 0;
+	nrel = 0;
+	nrela = 0;
+	for (i = 0; i < hdr->e_shnum; i++) {
+		switch (shdr[i].sh_type) {
+		case SHT_PROGBITS:
+			nprogbits++;
+			break;
+		case SHT_NOBITS:
+			nnobits++;
+			break;
+		case SHT_SYMTAB:
+			nsym++;
+			symstrindex = shdr[i].sh_link;
+			break;
+		case SHT_REL:
+			nrel++;
+			break;
+		case SHT_RELA:
+			nrela++;
+			break;
+		}
+	}
+	if (nprogbits == 0 && nnobits == 0) {
+		link_elf_error("file has no contents");
+		error = ENOEXEC;
+		goto out;
+	}
+	if (nsym != 1) {
+		link_elf_error("file has no valid symbol table");
+		error = ENOEXEC;
+		goto out;
+	}
+	if (symstrindex < 0 || sysmstrindex > hdr->e_shnum ||
+	    shdr[symstrindex].sh_type != SHT_STRTAB) {
+		link_elf_error("file has invalid symbol strings");
 		error = ENOEXEC;
 		goto out;
-	    }
-	    /*
-	     * XXX: We just trust they come in right order ??
-	     */
-	    segs[nsegs] = phdr;
-	    ++nsegs;
-	    break;
+	}
 
-	case PT_PHDR:
-	    phphdr = phdr;
-	    break;
+/* XXX *************** STEP 2 GOES HERE ************* XXX */
+	symtabindex = -1;
+	symstrindex = -1;
+	for (i = 0; i < hdr->e_shnum; i++) {
+		switch (shdr[i].sh_type) {
 
-	case PT_DYNAMIC:
-	    phdyn = phdr;
-	    break;
-
-	case PT_INTERP:
-	    link_elf_error("Unsupported file type");
-	    error = ENOEXEC;
-	    goto out;
+		case SHT_SYMTAB:
+			symtabindex = i;
+			symstrindex = shdr[i].sh_link;
+			break;
+		}
 	}
-
-	++phdr;
-    }
-    if (phdyn == NULL) {
-	link_elf_error("Object is not dynamically-linked");
-	error = ENOEXEC;
-	goto out;
-    }
-    if (nsegs != 2) {
-	link_elf_error("Too few sections");
-	error = ENOEXEC;
-	goto out;
-    }
-/* XXX *************** STEP 2 GOES HERE ************* XXX */
 /* XXX *************** STEP 3 GOES HERE ************* XXX */
 
-    /* Try and load the symbol table if it's present.  (you can strip it!) */
-    nbytes = hdr->e_shnum * hdr->e_shentsize;
-    if (nbytes == 0 || hdr->e_shoff == 0)
-	goto nosyms;
-    shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
-    if (shdr == NULL) {
-	error = ENOMEM;
-	goto out;
-    }
-    error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    (caddr_t)shdr, nbytes, hdr->e_shoff,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-    if (error)
-	goto out;
-    symtabindex = -1;
-    symstrindex = -1;
-    for (i = 0; i < hdr->e_shnum; i++) {
-	if (shdr[i].sh_type == SHT_SYMTAB) {
-	    symtabindex = i;
-	    symstrindex = shdr[i].sh_link;
-	}
-    }
-    if (symtabindex < 0 || symstrindex < 0)
-	goto nosyms;
+	/* Load the symbol table. */
+	if (symtabindex < 0 || symstrindex < 0)
+		goto nosyms;
 
-    symcnt = shdr[symtabindex].sh_size;
-    ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
-    strcnt = shdr[symstrindex].sh_size;
-    ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
+	symcnt = shdr[symtabindex].sh_size;
+	ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
+	strcnt = shdr[symstrindex].sh_size;
+	ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
 
-    if (ef->symbase == NULL || ef->strbase == NULL) {
-	error = ENOMEM;
-	goto out;
-    }
-    error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    ef->symbase, symcnt, shdr[symtabindex].sh_offset,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-    if (error)
-	goto out;
-    error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    ef->strbase, strcnt, shdr[symstrindex].sh_offset,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-    if (error)
-	goto out;
+	if (ef->symbase == NULL || ef->strbase == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+	error = vn_rdwr(UIO_READ, nd.ni_vp,
+	    ef->symbase, symcnt, shdr[symtabindex].sh_offset,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+	    &resid, td);
+	if (error)
+		goto out;
+	error = vn_rdwr(UIO_READ, nd.ni_vp,
+	    ef->strbase, strcnt, shdr[symstrindex].sh_offset,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+	    &resid, td);
+	if (error)
+		goto out;
 
-    ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
-    ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
-    ef->ddbstrcnt = strcnt;
-    ef->ddbstrtab = ef->strbase;
+	ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
+	ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
+	ef->ddbstrcnt = strcnt;
+	ef->ddbstrtab = ef->strbase;
 
 /* XXX *************** STEP 4 GOES HERE ************* XXX */
 
-    /*
-     * Allocate the entire address space of the object, to stake out our
-     * contiguous region, and to establish the base address for relocation.
-     */
-    base_offset = trunc_page(segs[0]->p_offset);
-    base_vaddr = trunc_page(segs[0]->p_vaddr);
-    base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz);
-    mapsize = base_vlimit - base_vaddr;
+	/*
+	 * Allocate the entire address space of the object, to stake out our
+	 * contiguous region, and to establish the base address for relocation.
+	 */
+	base_offset = trunc_page(segs[0]->p_offset);
+	base_vaddr = trunc_page(segs[0]->p_vaddr);
+	base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz);
+	mapsize = base_vlimit - base_vaddr;
 
-    lf = linker_make_file(filename, &link_elf_class);
-    if (!lf) {
-	error = ENOMEM;
-	goto out;
-    }
+	lf = linker_make_file(filename, &link_elf_class);
+	if (!lf) {
+		error = ENOMEM;
+		goto out;
+	}
 
-    ef = (elf_file_t) lf;
+	ef = (elf_file_t) lf;
 #ifdef SPARSE_MAPPING
-    ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT);
-    if (ef->object == NULL) {
-	error = ENOMEM;
-	goto out;
-    }
-    vm_object_reference(ef->object);
-    ef->address = (caddr_t) vm_map_min(kernel_map);
-    error = vm_map_find(kernel_map, ef->object, 0,
-			(vm_offset_t *) &ef->address,
-			mapsize, 1,
-			VM_PROT_ALL, VM_PROT_ALL, 0);
-    if (error) {
-	vm_object_deallocate(ef->object);
-	ef->object = 0;
-	goto out;
-    }
+	ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT);
+	if (ef->object == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+	vm_object_reference(ef->object);
+	ef->address = (caddr_t) vm_map_min(kernel_map);
+	error = vm_map_find(kernel_map, ef->object, 0,
+	    (vm_offset_t *) &ef->address,
+	    mapsize, 1,
+	    VM_PROT_ALL, VM_PROT_ALL, 0);
+	if (error) {
+		vm_object_deallocate(ef->object);
+		ef->object = 0;
+		goto out;
+	}
 #else
-    ef->address = malloc(mapsize, M_LINKER, M_WAITOK);
-    if (!ef->address) {
-	error = ENOMEM;
-	goto out;
-    }
+	ef->address = malloc(mapsize, M_LINKER, M_WAITOK);
+	if (!ef->address) {
+		error = ENOMEM;
+		goto out;
+	}
 #endif
-    mapbase = ef->address;
+	mapbase = ef->address;
 
-    /*
-     * Read the text and data sections and zero the bss.
-     */
-    for (i = 0; i < 2; i++) {
-	caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
-	error = vn_rdwr(UIO_READ, nd.ni_vp,
-			segbase, segs[i]->p_filesz, segs[i]->p_offset,
-			UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-			&resid, td);
-	if (error) {
-	    goto out;
-	}
-	bzero(segbase + segs[i]->p_filesz,
-	      segs[i]->p_memsz - segs[i]->p_filesz);
+	/*
+	 * Read the text and data sections and zero the bss.
+	 */
+	for (i = 0; i < 2; i++) {
+		caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
+		error = vn_rdwr(UIO_READ, nd.ni_vp,
+		    segbase, segs[i]->p_filesz, segs[i]->p_offset,
+		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+		    &resid, td);
+		if (error) {
+			goto out;
+		}
+		bzero(segbase + segs[i]->p_filesz,
+		    segs[i]->p_memsz - segs[i]->p_filesz);
 
 #ifdef SPARSE_MAPPING
-	/*
-	 * Wire down the pages
-	 */
-	vm_map_wire(kernel_map,
+		/*
+		 * Wire down the pages
+		 */
+		vm_map_wire(kernel_map,
 		    (vm_offset_t) segbase,
 		    (vm_offset_t) segbase + segs[i]->p_memsz,
 		    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
 #endif
-    }
+	}
 
-    /* ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr); */
+	lf->address = ef->address;
+	lf->size = mapsize;
 
-    lf->address = ef->address;
-    lf->size = mapsize;
+	link_elf_reloc_local(lf);
 
-    link_elf_reloc_local(lf);
+	error = linker_load_dependencies(lf);
+	if (error)
+		goto out;
+	error = relocate_file(ef);
+	if (error)
+		goto out;
 
-    error = linker_load_dependencies(lf);
-    if (error)
-	goto out;
-    error = relocate_file(ef);
-    if (error)
-	goto out;
+	error = link_elf_link_common_finish(lf);
+	if (error)
+		goto out;
 
-    error = link_elf_link_common_finish(lf);
-    if (error)
-	goto out;
+ nosyms:
 
-nosyms:
+	*result = lf;
 
-    *result = lf;
+ out:
+	if (error && lf)
+		linker_file_unload(lf);
+	if (shdr)
+		free(shdr, M_LINKER);
+	if (firstpage)
+		free(firstpage, M_LINKER);
+	VOP_UNLOCK(nd.ni_vp, 0, td);
+	vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
 
-out:
-    if (error && lf)
-	linker_file_unload(lf);
-    if (shdr)
-	free(shdr, M_LINKER);
-    if (firstpage)
-	free(firstpage, M_LINKER);
-    VOP_UNLOCK(nd.ni_vp, 0, td);
-    vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
-
-    return error;
+	return error;
 }
 
 static void
 link_elf_unload_file(linker_file_t file)
 {
-    elf_file_t ef = (elf_file_t) file;
+	elf_file_t ef = (elf_file_t) file;
 
-    /* Notify MD code that a module is being unloaded. */
-    elf_cpu_unload_file(file);
+	/* Notify MD code that a module is being unloaded. */
+	elf_cpu_unload_file(file);
 
 #ifdef SPARSE_MAPPING
-    if (ef->object) {
-	vm_map_remove(kernel_map, (vm_offset_t) ef->address,
-		      (vm_offset_t) ef->address
-		      + (ef->object->size << PAGE_SHIFT));
-	vm_object_deallocate(ef->object);
-    }
+	if (ef->object) {
+		vm_map_remove(kernel_map, (vm_offset_t) ef->address,
+		    (vm_offset_t) ef->address
+		    + (ef->object->size << PAGE_SHIFT));
+		vm_object_deallocate(ef->object);
+	}
 #else
-    if (ef->address)
-	free(ef->address, M_LINKER);
+	if (ef->address)
+		free(ef->address, M_LINKER);
 #endif
-    if (ef->symbase)
-	free(ef->symbase, M_LINKER);
-    if (ef->strbase)
-	free(ef->strbase, M_LINKER);
+	if (ef->symbase)
+		free(ef->symbase, M_LINKER);
+	if (ef->strbase)
+		free(ef->strbase, M_LINKER);
 }
 
 static const char *
 symbol_name(elf_file_t ef, Elf_Word r_info)
 {
-    const Elf_Sym *ref;
+	const Elf_Sym *ref;
 
-    if (ELF_R_SYM(r_info)) {
-	ref = ef->symtab + ELF_R_SYM(r_info);
-	return ef->strtab + ref->st_name;
-    } else
-	return NULL;
+	if (ELF_R_SYM(r_info)) {
+		ref = ef->symtab + ELF_R_SYM(r_info);
+		return ef->strtab + ref->st_name;
+	} else
+		return NULL;
 }
 
 static int
 relocate_file(elf_file_t ef)
 {
-    const Elf_Rel *rellim;
-    const Elf_Rel *rel;
-    const Elf_Rela *relalim;
-    const Elf_Rela *rela;
-    const char *symname;
+	const Elf_Rel *rellim;
+	const Elf_Rel *rel;
+	const Elf_Rela *relalim;
+	const Elf_Rela *rela;
+	const char *symname;
 
-    /* Perform relocations without addend if there are any: */
-    rel = ef->rel;
-    if (rel) {
-	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
-	while (rel < rellim) {
-	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
-		symname = symbol_name(ef, rel->r_info);
-		printf("link_elf: symbol %s undefined\n", symname);
-		return ENOENT;
-	    }
-	    rel++;
+	/* Perform relocations without addend if there are any: */
+	rel = ef->rel;
+	if (rel) {
+		rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
+		while (rel < rellim) {
+			if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+				symname = symbol_name(ef, rel->r_info);
+				printf("link_elf: symbol %s undefined\n", symname);
+				return ENOENT;
+			}
+			rel++;
+		}
 	}
-    }
 
-    /* Perform relocations with addend if there are any: */
-    rela = ef->rela;
-    if (rela) {
-	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
-	while (rela < relalim) {
-	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
-		symname = symbol_name(ef, rela->r_info);
-		printf("link_elf: symbol %s undefined\n", symname);
-		return ENOENT;
-	    }
-	    rela++;
+	/* Perform relocations with addend if there are any: */
+	rela = ef->rela;
+	if (rela) {
+		relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
+		while (rela < relalim) {
+			if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+				symname = symbol_name(ef, rela->r_info);
+				printf("link_elf: symbol %s undefined\n", symname);
+				return ENOENT;
+			}
+			rela++;
+		}
 	}
-    }
 
-    /* Perform PLT relocations without addend if there are any: */
-    rel = ef->pltrel;
-    if (rel) {
-	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
-	while (rel < rellim) {
-	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
-		symname = symbol_name(ef, rel->r_info);
-		printf("link_elf: symbol %s undefined\n", symname);
-		return ENOENT;
-	    }
-	    rel++;
+	/* Perform PLT relocations without addend if there are any: */
+	rel = ef->pltrel;
+	if (rel) {
+		rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
+		while (rel < rellim) {
+			if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
+				symname = symbol_name(ef, rel->r_info);
+				printf("link_elf: symbol %s undefined\n", symname);
+				return ENOENT;
+			}
+			rel++;
+		}
 	}
-    }
 
-    /* Perform relocations with addend if there are any: */
-    rela = ef->pltrela;
-    if (rela) {
-	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
-	while (rela < relalim) {
-	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
-		symname = symbol_name(ef, rela->r_info);
-		printf("link_elf: symbol %s undefined\n", symname);
-		return ENOENT;
-	    }
-	    rela++;
+	/* Perform relocations with addend if there are any: */
+	rela = ef->pltrela;
+	if (rela) {
+		relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
+		while (rela < relalim) {
+			if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
+				symname = symbol_name(ef, rela->r_info);
+				printf("link_elf: symbol %s undefined\n", symname);
+				return ENOENT;
+			}
+			rela++;
+		}
 	}
-    }
 
-    return 0;
+	return 0;
 }
 
 static int
 link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym)
 {
-    elf_file_t ef = (elf_file_t) lf;
-    unsigned long symnum;
-    const Elf_Sym* symp;
-    const char *strp;
-    int i;
+	elf_file_t ef = (elf_file_t) lf;
+	unsigned long symnum;
+	const Elf_Sym* symp;
+	const char *strp;
+	int i;
 
 /* XXX search for globals first */
-    /* Exhaustive search */
-    for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
-	strp = ef->ddbstrtab + symp->st_name;
-	if (strcmp(name, strp) == 0) {
-	    if (symp->st_shndx != SHN_UNDEF ||
-		(symp->st_value != 0 &&
-		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
-		*sym = (c_linker_sym_t) symp;
-		return 0;
-	    } else
-		return ENOENT;
+	/* Exhaustive search */
+	for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
+		strp = ef->ddbstrtab + symp->st_name;
+		if (strcmp(name, strp) == 0) {
+			if (symp->st_shndx != SHN_UNDEF ||
+			    (symp->st_value != 0 &&
+				ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
+				*sym = (c_linker_sym_t) symp;
+				return 0;
+			} else
+				return ENOENT;
+		}
 	}
-    }
 
-    return ENOENT;
+	return ENOENT;
 }
 
 static int
@@ -638,17 +632,17 @@
 	const Elf_Sym* es = (const Elf_Sym*) sym;
 
 	if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
-	    symval->name = ef->ddbstrtab + es->st_name;
-	    symval->value = (caddr_t) ef->address + es->st_value;
-	    symval->size = es->st_size;
-	    return 0;
+		symval->name = ef->ddbstrtab + es->st_name;
+		symval->value = (caddr_t) ef->address + es->st_value;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403252338.i2PNc81Y072749>