From owner-p4-projects@FreeBSD.ORG Tue Jun 15 23:25:59 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6E87916A4D0; Tue, 15 Jun 2004 23:25:59 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C27816A4CE for ; Tue, 15 Jun 2004 23:25:59 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2760143D2D for ; Tue, 15 Jun 2004 23:25:59 +0000 (GMT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i5FNPwSp008659 for ; Tue, 15 Jun 2004 23:25:59 GMT (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i5FNPwet008656 for perforce@freebsd.org; Tue, 15 Jun 2004 23:25:58 GMT (envelope-from peter@freebsd.org) Date: Tue, 15 Jun 2004 23:25:58 GMT Message-Id: <200406152325.i5FNPwet008656@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Subject: PERFORCE change 55052 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jun 2004 23:26:00 -0000 http://perforce.freebsd.org/chv.cgi?CH=55052 Change 55052 by peter@peter_daintree on 2004/06/15 23:25:10 Use Ian Dowse's idea of adjusting the symbol table once at load time rather than constantly trying to figure out which section each symbol is in and finding its base address. Incidently, this makes the internal look/feel of the after-load state more consistent with the non-obj loader. Affected files ... .. //depot/projects/hammer/sys/kern/link_elf_obj.c#43 edit Differences ... ==== //depot/projects/hammer/sys/kern/link_elf_obj.c#43 (text+ko) ==== @@ -187,7 +187,8 @@ struct thread *td = curthread; /* XXX */ Elf_Ehdr *hdr; Elf_Shdr *shdr; - int nbytes, i; + Elf_Sym *es; + int nbytes, i, j; vm_offset_t mapbase; size_t mapsize; int error = 0; @@ -504,6 +505,14 @@ if (ef->shstrtab && shdr[i].sh_name != 0) ef->progtab[pb].name = ef->shstrtab + shdr[i].sh_name; + + /* Update all symbol values with the offset. */ + for (j = 0; j < ef->ddbsymcnt; j++) { + es = &ef->ddbsymtab[j]; + if (es->st_shndx != i) + continue; + es->st_value += (Elf_Addr)ef->progtab[pb].addr; + } mapbase += shdr[i].sh_size; pb++; break; @@ -643,11 +652,11 @@ Elf_Addr base = 0; for (i = 0; i < ef->nprogtab; i++) { - if (sec == ef->progtab[i].sec) + if (sec == ef->progtab[i].sec) { base = (Elf_Addr)ef->progtab[i].addr; + break; + } } - if (base == 0) - base = (Elf_Addr)ef->address; return base; } @@ -672,6 +681,8 @@ panic("lost a reltab!"); rellim = rel + ef->reltab[i].nrel; base = findbase(ef, ef->reltab[i].sec); + if (base == 0) + panic("lost base for reltab"); for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) @@ -697,6 +708,8 @@ panic("lost a relatab!"); relalim = rela + ef->relatab[i].nrela; base = findbase(ef, ef->relatab[i].sec); + if (base == 0) + panic("lost base for relatab"); for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt) @@ -726,20 +739,13 @@ const char *strp; int i; -/* XXX search for globals first */ 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; + if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { + *sym = (c_linker_sym_t) symp; + return 0; } } - return ENOENT; } @@ -747,16 +753,12 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t *symval) { - Elf_Addr base; elf_file_t ef = (elf_file_t) lf; const Elf_Sym *es = (const Elf_Sym*) sym; if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { - base = findbase(ef, es->st_shndx); - if (base == 0) - base = (Elf_Addr)ef->address; symval->name = ef->ddbstrtab + es->st_name; - symval->value = (caddr_t)base + es->st_value; + symval->value = (caddr_t)es->st_value; symval->size = es->st_size; return 0; } @@ -771,7 +773,6 @@ u_long off = (uintptr_t) (void *) value; u_long diff = off; u_long st_value; - Elf_Addr base; const Elf_Sym *es; const Elf_Sym *best = 0; int i; @@ -779,10 +780,7 @@ for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { if (es->st_name == 0) continue; - base = findbase(ef, es->st_shndx); - if (base == 0) - base = (Elf_Addr)ef->address; - st_value = es->st_value + base; + st_value = es->st_value; if (off >= st_value) { if (off - st_value < diff) { diff = off - st_value; @@ -868,7 +866,6 @@ const Elf_Sym *sym; const char *symbol; Elf_Addr ret; - int i; /* Don't even try to lookup the symbol if the index is bogus. */ if (symidx >= ef->ddbsymcnt) @@ -877,19 +874,8 @@ sym = ef->ddbsymtab + symidx; /* Quick answer if there is a definition included. */ - if (sym->st_shndx != SHN_UNDEF) { - ret = 0; - /* Relative to section number */ - for (i = 0; i < ef->nprogtab; i++) { - if (sym->st_shndx == ef->progtab[i].sec) { - ret = (Elf_Addr)ef->progtab[i].addr; - break; - } - } - if (ret == 0) - return (0); - return ret + sym->st_value; - } + if (sym->st_shndx != SHN_UNDEF) + return (sym->st_value); /* If we get here, then it is undefined and needs a lookup. */ switch (ELF_ST_BIND(sym->st_info)) { @@ -937,6 +923,8 @@ panic("lost a reltab!"); rellim = rel + ef->reltab[i].nrel; base = findbase(ef, ef->reltab[i].sec); + if (base == 0) + panic("lost base for reltab"); for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) @@ -957,6 +945,8 @@ panic("lost a relatab!"); relalim = rela + ef->relatab[i].nrela; base = findbase(ef, ef->relatab[i].sec); + if (base == 0) + panic("lost base for relatab"); for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt)