Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Mar 2004 10:49:53 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 48976 for review
Message-ID:  <200403141849.i2EInraP088119@repoman.freebsd.org>

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

Change 48976 by peter@peter_overcee on 2004/03/14 10:49:23

	cut out preload support for the time being and do a step 0 pass
	at converting this from a .so to a .o loader.  It isn't as hard
	as it looked.

Affected files ...

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

Differences ...

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

@@ -44,9 +44,6 @@
 #include <sys/linker.h>
 
 #include <machine/elf.h>
-#ifdef GPROF
-#include <machine/profile.h>
-#endif
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -64,21 +61,13 @@
 
 typedef struct elf_file {
     struct linker_file	lf;		/* Common fields */
-    int			preloaded;	/* Was file pre-loaded */
     caddr_t		address;	/* Relocation address */
 #ifdef SPARSE_MAPPING
     vm_object_t		object;		/* VM object to hold file pages */
 #endif
-    Elf_Dyn*		dynamic;	/* Symbol table etc. */
-    Elf_Hashelt		nbuckets;	/* DT_HASH info */
-    Elf_Hashelt		nchains;
-    const Elf_Hashelt*	buckets;
-    const Elf_Hashelt*	chains;
-    caddr_t		hash;
     caddr_t		strtab;		/* DT_STRTAB */
     int			strsz;		/* DT_STRSZ */
     const Elf_Sym*	symtab;		/* DT_SYMTAB */
-    Elf_Addr*		got;		/* DT_PLTGOT */
     const Elf_Rel*	pltrel;		/* DT_JMPREL */
     int			pltrelsize;	/* DT_PLTRELSZ */
     const Elf_Rela*	pltrela;	/* DT_JMPREL */
@@ -94,9 +83,6 @@
     long		ddbstrcnt;	/* number of bytes in string table */
     caddr_t		symbase;	/* malloc'ed symbold base */
     caddr_t		strbase;	/* malloc'ed string base */
-#ifdef DDB
-    struct link_map	gdb;		/* hooks for gdb */
-#endif
 } *elf_file_t;
 
 static int	link_elf_link_common_finish(linker_file_t);
@@ -111,7 +97,6 @@
 				       c_linker_sym_t* sym, long* diffp);
 
 static void	link_elf_unload_file(linker_file_t);
-static void	link_elf_unload_preload(linker_file_t);
 static int	link_elf_lookup_set(linker_file_t, const char *,
 				    void ***, void ***, int *);
 static int	link_elf_each_function_name(linker_file_t,
@@ -141,73 +126,7 @@
     link_elf_methods, sizeof(struct elf_file)
 };
 
-static int		parse_dynamic(elf_file_t ef);
 static int		relocate_file(elf_file_t ef);
-static int		link_elf_preload_parse_symbols(elf_file_t ef);
-
-#ifdef DDB
-static void		r_debug_state(struct r_debug *dummy_one,
-				      struct link_map *dummy_two);
-
-/*
- * A list of loaded modules for GDB to use for loading symbols.
- */
-struct r_debug r_debug;
-
-#define GDB_STATE(s)	r_debug.r_state = s; r_debug_state(NULL, NULL);
-
-/*
- * Function for the debugger to set a breakpoint on to gain control.
- */
-static void
-r_debug_state(struct r_debug *dummy_one __unused,
-	      struct link_map *dummy_two __unused)
-{
-}
-
-static void
-link_elf_add_gdb(struct link_map *l)
-{
-    struct link_map *prev;
-
-    l->l_next = NULL;
-
-    if (r_debug.r_map == NULL) {
-	/* Add first. */
-	l->l_prev = NULL;
-	r_debug.r_map = l;
-    } else {
-	/* Append to list. */
-	for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
-	    ;
-	l->l_prev = prev;
-	prev->l_next = l;
-    }
-}
-
-static void
-link_elf_delete_gdb(struct link_map *l)
-{
-    if (l->l_prev == NULL) {
-	/* Remove first. */
-	if ((r_debug.r_map = l->l_next) != NULL)
-	    l->l_next->l_prev = NULL;
-    } else {
-	/* Remove any but first. */
-	if ((l->l_prev->l_next = l->l_next) != NULL)
-	    l->l_next->l_prev = l->l_prev;
-    }
-}
-#endif /* DDB */
-
-#ifdef __ia64__
-Elf_Addr link_elf_get_gp(linker_file_t);
-#endif
-
-/*
- * The kernel symbol table starts here.
- */
-extern struct _dynamic _DYNAMIC;
 
 static void
 link_elf_error(const char *s)
@@ -217,15 +136,11 @@
 
 /*
  * Actions performed after linking/loading both the preloaded kernel and any
- * modules; whether preloaded or dynamicly loaded.
+ * modules;
  */
 static int
 link_elf_link_common_finish(linker_file_t lf)
 {
-#ifdef DDB
-    elf_file_t ef = (elf_file_t)lf;
-    char *newfilename;
-#endif
     int error;
 
     /* Notify MD code that a module is being loaded. */
@@ -233,295 +148,29 @@
     if (error)
 	return (error);
 
-#ifdef DDB
-    GDB_STATE(RT_ADD);
-    ef->gdb.l_addr = lf->address;
-    newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
-    strcpy(newfilename, lf->filename);
-    ef->gdb.l_name = newfilename;
-    ef->gdb.l_ld = ef->dynamic;
-    link_elf_add_gdb(&ef->gdb);
-    GDB_STATE(RT_CONSISTENT);
-#endif
-
     return (0);
 }
 
 static void
 link_elf_init(void* arg)
 {
-    Elf_Dyn	*dp;
-    caddr_t	modptr, baseptr, sizeptr;
-    elf_file_t	ef;
-    char	*modname;
 
-    linker_add_class(&link_elf_class);
-
-    dp = (Elf_Dyn*) &_DYNAMIC;
-    modname = NULL;
-    modptr = preload_search_by_type("elf" __XSTRING(__ELF_WORD_SIZE) " kernel");
-    if (modptr == NULL)
-	modptr = preload_search_by_type("elf kernel");
-    if (modptr)
-	modname = (char *)preload_search_info(modptr, MODINFO_NAME);
-    if (modname == NULL)
-	modname = "kernel";
-    linker_kernel_file = linker_make_file(modname, &link_elf_class);
-    if (linker_kernel_file == NULL)
-	panic("link_elf_init: Can't create linker structures for kernel");
-
-    ef = (elf_file_t) linker_kernel_file;
-    ef->preloaded = 1;
-    ef->address = 0;
-#ifdef SPARSE_MAPPING
-    ef->object = 0;
-#endif
-    ef->dynamic = dp;
-
-    if (dp)
-	parse_dynamic(ef);
-    linker_kernel_file->address = (caddr_t) KERNBASE;
-    linker_kernel_file->size = -(intptr_t)linker_kernel_file->address;
-
-    if (modptr) {
-	ef->modptr = modptr;
-	baseptr = preload_search_info(modptr, MODINFO_ADDR);
-	if (baseptr)
-	    linker_kernel_file->address = *(caddr_t *)baseptr;
-	sizeptr = preload_search_info(modptr, MODINFO_SIZE);
-	if (sizeptr)
-	    linker_kernel_file->size = *(size_t *)sizeptr;
-    }
-    (void)link_elf_preload_parse_symbols(ef);
-
-#ifdef DDB
-    r_debug.r_map = NULL;
-    r_debug.r_brk = r_debug_state;
-    r_debug.r_state = RT_CONSISTENT;
-#endif
-
-    (void)link_elf_link_common_finish(linker_kernel_file);
+	linker_add_class(&link_elf_class);
 }
 
 SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
 
 static int
-link_elf_preload_parse_symbols(elf_file_t ef)
-{
-    caddr_t	pointer;
-    caddr_t	ssym, esym, base;
-    caddr_t	strtab;
-    int		strcnt;
-    Elf_Sym*	symtab;
-    int		symcnt;
-
-    if (ef->modptr == NULL)
-	return 0;
-    pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_SSYM);
-    if (pointer == NULL)
-	return 0;
-    ssym = *(caddr_t *)pointer;
-    pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_ESYM);
-    if (pointer == NULL)
-	return 0;
-    esym = *(caddr_t *)pointer;
-
-    base = ssym;
-
-    symcnt = *(long *)base;
-    base += sizeof(long);
-    symtab = (Elf_Sym *)base;
-    base += roundup(symcnt, sizeof(long));
-
-    if (base > esym || base < ssym) {
-	printf("Symbols are corrupt!\n");
-	return EINVAL;
-    }
-
-    strcnt = *(long *)base;
-    base += sizeof(long);
-    strtab = base;
-    base += roundup(strcnt, sizeof(long));
-
-    if (base > esym || base < ssym) {
-	printf("Symbols are corrupt!\n");
-	return EINVAL;
-    }
-
-    ef->ddbsymtab = symtab;
-    ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
-    ef->ddbstrtab = strtab;
-    ef->ddbstrcnt = strcnt;
-
-    return 0;
-}
-
-static int
-parse_dynamic(elf_file_t ef)
-{
-    Elf_Dyn *dp;
-    int plttype = DT_REL;
-
-    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
-	switch (dp->d_tag) {
-	case DT_HASH:
-	{
-	    /* From src/libexec/rtld-elf/rtld.c */
-	    const Elf_Hashelt *hashtab = (const Elf_Hashelt *)
-		(ef->address + dp->d_un.d_ptr);
-	    ef->nbuckets = hashtab[0];
-	    ef->nchains = hashtab[1];
-	    ef->buckets = hashtab + 2;
-	    ef->chains = ef->buckets + ef->nbuckets;
-	    break;
-	}
-	case DT_STRTAB:
-	    ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_STRSZ:
-	    ef->strsz = dp->d_un.d_val;
-	    break;
-	case DT_SYMTAB:
-	    ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_SYMENT:
-	    if (dp->d_un.d_val != sizeof(Elf_Sym))
-		return ENOEXEC;
-	    break;
-	case DT_PLTGOT:
-	    ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_REL:
-	    ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_RELSZ:
-	    ef->relsize = dp->d_un.d_val;
-	    break;
-	case DT_RELENT:
-	    if (dp->d_un.d_val != sizeof(Elf_Rel))
-		return ENOEXEC;
-	    break;
-	case DT_JMPREL:
-	    ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_PLTRELSZ:
-	    ef->pltrelsize = dp->d_un.d_val;
-	    break;
-	case DT_RELA:
-	    ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr);
-	    break;
-	case DT_RELASZ:
-	    ef->relasize = dp->d_un.d_val;
-	    break;
-	case DT_RELAENT:
-	    if (dp->d_un.d_val != sizeof(Elf_Rela))
-		return ENOEXEC;
-	    break;
-	case DT_PLTREL:
-	    plttype = dp->d_un.d_val;
-	    if (plttype != DT_REL && plttype != DT_RELA)
-		return ENOEXEC;
-	    break;
-#ifdef DDB
-	case DT_DEBUG:
-	    dp->d_un.d_ptr = (Elf_Addr) &r_debug;
-	    break;
-#endif
-	}
-    }
-
-    if (plttype == DT_RELA) {
-	ef->pltrela = (const Elf_Rela *) ef->pltrel;
-	ef->pltrel = NULL;
-	ef->pltrelasize = ef->pltrelsize;
-	ef->pltrelsize = 0;
-    }
-
-    ef->ddbsymtab = ef->symtab;
-    ef->ddbsymcnt = ef->nchains;
-    ef->ddbstrtab = ef->strtab;
-    ef->ddbstrcnt = ef->strsz;
-
-    return 0;
-}
-
-static int
 link_elf_link_preload(linker_class_t cls,
 		      const char* filename, linker_file_t *result)
 {
-    caddr_t		modptr, baseptr, sizeptr, dynptr;
-    char		*type;
-    elf_file_t		ef;
-    linker_file_t	lf;
-    int			error;
-    vm_offset_t		dp;
-
-    /* Look to see if we have the file preloaded */
-    modptr = preload_search_by_name(filename);
-    if (modptr == NULL)
-	return ENOENT;
-
-    type = (char *)preload_search_info(modptr, MODINFO_TYPE);
-    baseptr = preload_search_info(modptr, MODINFO_ADDR);
-    sizeptr = preload_search_info(modptr, MODINFO_SIZE);
-    dynptr = preload_search_info(modptr, MODINFO_METADATA|MODINFOMD_DYNAMIC);
-    if (type == NULL ||
-	(strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) " module") != 0 &&
-	 strcmp(type, "elf module") != 0))
 	return (EFTYPE);
-    if (baseptr == NULL || sizeptr == NULL || dynptr == NULL)
-	return (EINVAL);
-
-    lf = linker_make_file(filename, &link_elf_class);
-    if (lf == NULL) {
-	return ENOMEM;
-    }
-
-    ef = (elf_file_t) lf;
-    ef->preloaded = 1;
-    ef->modptr = modptr;
-    ef->address = *(caddr_t *)baseptr;
-#ifdef SPARSE_MAPPING
-    ef->object = 0;
-#endif
-    dp = (vm_offset_t)ef->address + *(vm_offset_t *)dynptr;
-    ef->dynamic = (Elf_Dyn *)dp;
-    lf->address = ef->address;
-    lf->size = *(size_t *)sizeptr;
-
-    error = parse_dynamic(ef);
-    if (error) {
-	linker_file_unload(lf);
-	return error;
-    }
-    link_elf_reloc_local(lf);
-    *result = lf;
-    return (0);
 }
 
 static int
 link_elf_link_preload_finish(linker_file_t lf)
 {
-    elf_file_t		ef;
-    int error;
-
-    ef = (elf_file_t) lf;
-#if 0	/* this will be more trouble than it's worth for now */
-    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
-	if (dp->d_tag != DT_NEEDED)
-	    continue;
-	modname = ef->strtab + dp->d_un.d_val;
-	error = linker_load_module(modname, lf);
-	if (error)
-	    goto out;
-    }
-#endif
-    error = relocate_file(ef);
-    if (error)
-	return error;
-    (void)link_elf_preload_parse_symbols(ef);
-
-    return (link_elf_link_common_finish(lf));
+	return (EFTYPE);
 }
 
 static int
@@ -621,6 +270,8 @@
      * 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) &&
@@ -632,7 +283,14 @@
      *
      * 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;
@@ -680,7 +338,64 @@
 	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;
+
+    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;
+
+    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.
@@ -749,92 +464,20 @@
 #endif
     }
 
-#ifdef GPROF
-    /* Update profiling information with the new text segment. */
-    kmupetext((uintfptr_t)(mapbase + segs[0]->p_vaddr - base_vaddr +
-	segs[0]->p_memsz));
-#endif
-
-    ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr);
+    /* ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr); */
 
     lf->address = ef->address;
     lf->size = mapsize;
 
-    error = parse_dynamic(ef);
-    if (error)
-	goto out;
     link_elf_reloc_local(lf);
 
     error = linker_load_dependencies(lf);
     if (error)
 	goto out;
-#if 0	/* this will be more trouble than it's worth for now */
-    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
-	if (dp->d_tag != DT_NEEDED)
-	    continue;
-	modname = ef->strtab + dp->d_un.d_val;
-	error = linker_load_module(modname, lf);
-	if (error)
-	    goto out;
-    }
-#endif
     error = relocate_file(ef);
     if (error)
 	goto out;
 
-    /* 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;
-
-    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;
-
-    ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
-    ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
-    ef->ddbstrcnt = strcnt;
-    ef->ddbstrtab = ef->strbase;
-
     error = link_elf_link_common_finish(lf);
     if (error)
 	goto out;
@@ -861,23 +504,9 @@
 {
     elf_file_t ef = (elf_file_t) file;
 
-#ifdef DDB
-    if (ef->gdb.l_ld) {
-	GDB_STATE(RT_DELETE);
-	free((void *)(uintptr_t)ef->gdb.l_name, M_LINKER);
-	link_elf_delete_gdb(&ef->gdb);
-	GDB_STATE(RT_CONSISTENT);
-    }
-#endif
-
     /* Notify MD code that a module is being unloaded. */
     elf_cpu_unload_file(file);
 
-    if (ef->preloaded) {
-	link_elf_unload_preload(file);
-	return;
-    }
-
 #ifdef SPARSE_MAPPING
     if (ef->object) {
 	vm_map_remove(kernel_map, (vm_offset_t) ef->address,
@@ -895,13 +524,6 @@
 	free(ef->strbase, M_LINKER);
 }
 
-static void
-link_elf_unload_preload(linker_file_t file)
-{
-    if (file->filename)
-	preload_delete_name(file->filename);
-}
-
 static const char *
 symbol_name(elf_file_t ef, Elf_Word r_info)
 {
@@ -982,26 +604,6 @@
     return 0;
 }
 
-/*
- * Hash function for symbol table lookup.  Don't even think about changing
- * this.  It is specified by the System V ABI.
- */
-static unsigned long
-elf_hash(const char *name)
-{
-    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;
-}
-
 static int
 link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym)
 {
@@ -1009,44 +611,9 @@
     unsigned long symnum;
     const Elf_Sym* symp;
     const char *strp;
-    unsigned long hash;
     int i;
 
-    /* First, search hashed global symbols */
-    hash = elf_hash(name);
-    symnum = ef->buckets[hash % ef->nbuckets];
-
-    while (symnum != STN_UNDEF) {
-	if (symnum >= ef->nchains) {
-	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
-	    return ENOENT;
-	}
-
-	symp = ef->symtab + symnum;
-	if (symp->st_name == 0) {
-	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
-	    return ENOENT;
-	}
-
-	strp = ef->strtab + 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;
-	}
-
-	symnum = ef->chains[symnum];
-    }
-
-    /* If we have not found it, look at the full table (if loaded) */
-    if (ef->symtab == ef->ddbsymtab)
-	return ENOENT;
-
+/* XXX search for globals first */
     /* Exhaustive search */
     for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
 	strp = ef->ddbstrtab + symp->st_name;
@@ -1070,14 +637,6 @@
 	elf_file_t ef = (elf_file_t) lf;
 	const Elf_Sym* es = (const Elf_Sym*) sym;
 
-	if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
-	    symval->name = ef->strtab + es->st_name;
-	    symval->value = (caddr_t) ef->address + es->st_value;
-	    symval->size = es->st_size;
-	    return 0;
-	}
-	if (ef->symtab == ef->ddbsymtab)
-	    return ENOENT;
 	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;
@@ -1200,21 +759,6 @@
     return (0);
 }
 
-#ifdef __ia64__
-/*
- * Each KLD has its own GP. The GP value for each load module is given by
- * DT_PLTGOT on ia64. We need GP to construct function descriptors, but
- * don't have direct access to the ELF file structure. The link_elf_get_gp()
- * function returns the GP given a pointer to a generic linker file struct.
- */
-Elf_Addr
-link_elf_get_gp(linker_file_t lf)
-{
-	elf_file_t ef = (elf_file_t)lf;
-	return (Elf_Addr)ef->got;
-}
-#endif
-
 const Elf_Sym *
 elf_get_sym(linker_file_t lf, Elf_Word symidx)
 {



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