From owner-freebsd-sparc Wed Jan 8 8: 0: 8 2003 Delivered-To: freebsd-sparc@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DE28D37B401 for ; Wed, 8 Jan 2003 08:00:02 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id DF34A43EA9 for ; Wed, 8 Jan 2003 08:00:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id h08G01NS052533 for ; Wed, 8 Jan 2003 08:00:01 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id h08G01c5052532; Wed, 8 Jan 2003 08:00:01 -0800 (PST) Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4E3EA37B401 for ; Wed, 8 Jan 2003 07:56:39 -0800 (PST) Received: from mailhub.fokus.gmd.de (mailhub.fokus.gmd.de [193.174.154.14]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2F9BC43EB2 for ; Wed, 8 Jan 2003 07:56:38 -0800 (PST) (envelope-from hbb@catssrv.fokus.gmd.de) Received: from catssrv.fokus.gmd.de (catssrv [192.168.229.23]) by mailhub.fokus.gmd.de (8.11.6/8.11.6) with ESMTP id h08FuVM12956 for ; Wed, 8 Jan 2003 16:56:31 +0100 (MET) Received: from catssrv.fokus.gmd.de (localhost [127.0.0.1]) by catssrv.fokus.gmd.de (8.12.6/8.12.6) with ESMTP id h08FuVus000696 for ; Wed, 8 Jan 2003 16:56:31 +0100 (CET) (envelope-from hbb@catssrv.fokus.gmd.de) Received: (from hbb@localhost) by catssrv.fokus.gmd.de (8.12.6/8.12.6/Submit) id h08FuUGE000695; Wed, 8 Jan 2003 16:56:30 +0100 (CET) (envelope-from hbb) Message-Id: <200301081556.h08FuUGE000695@catssrv.fokus.gmd.de> Date: Wed, 8 Jan 2003 16:56:30 +0100 (CET) From: Hartmut Brandt Reply-To: Hartmut Brandt To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: sparc64/46870: loader does not resolve module dependencies Sender: owner-freebsd-sparc@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 46870 >Category: sparc64 >Synopsis: loader does not resolve module dependencies >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-sparc >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Jan 08 08:00:00 PST 2003 >Closed-Date: >Last-Modified: >Originator: Hartmut Brandt >Release: FreeBSD 5.0-CURRENT sparc64 >Organization: FhI Fokus >Environment: System: FreeBSD catssrv.fokus.gmd.de 5.0-CURRENT FreeBSD 5.0-CURRENT #3: Tue Jan 7 18:15:41 CET 2003 root@catssrv.fokus.gmd.de:/opt/obj/usr/src/sys/CATSSRV sparc64 >Description: The boot loader does not resolve module dependencies and does not load modules upon which a given module depends. >How-To-Repeat: Build if_hme.ko and insert the following line into /boot/loader.conf: if_hme_load="YES" Reboot and observe the loader to load if_hme.ko but not miibus.ko. Observe further that the kernel later on reports a missing dependency of hme on miibus. >Fix: The problem is the same as with kldxref and the kernel linker: the loader fails to process relocation correctly by assuming that only REL records exist. The correct fix is to have machine dependent relocation routines call from load_elf.c. This is somewhat complicated by the fact, that load_elf itself is called via a machine dependent function pointer. The attached patch is a hack rather than a fix. Based on the precedent of an #ifdef __i386__ in load_elf.c, MD processing is done for __sparc__ in load_elf.c to do just enough relocation processing to correctly access dependency information. Note, that this does not really relocate the loaded image - this is done later in the kernel linker. Instead local copies of the pointers are relocated. Index: load_elf.c =================================================================== RCS file: /usr/ncvs/src/sys/boot/common/load_elf.c,v retrieving revision 1.24 diff -c -r1.24 load_elf.c *** load_elf.c 10 May 2002 01:20:37 -0000 1.24 --- load_elf.c 8 Jan 2003 15:47:10 -0000 *************** *** 52,57 **** --- 52,61 ---- Elf_Hashelt nchains; Elf_Hashelt *buckets; Elf_Hashelt *chains; + #ifdef __sparc__ + Elf_Rela *rela; + size_t relasz; + #endif char *strtab; size_t strsz; int fd; *************** *** 63,68 **** --- 67,76 ---- static int elf_loadimage(struct preloaded_file *mp, elf_file_t ef, vm_offset_t loadaddr); static int elf_lookup_symbol(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym); + #ifdef __sparc__ + static void elf_reloc_ptr(struct preloaded_file *mp, elf_file_t ef, + void *p, void *val, size_t len); + #endif static int elf_parse_modmetadata(struct preloaded_file *mp, elf_file_t ef); static char *fake_modname(const char *name); *************** *** 491,496 **** --- 499,512 ---- case DT_SYMTAB: ef->symtab = (Elf_Sym*)(dp[i].d_un.d_ptr + off); break; + #ifdef __sparc__ + case DT_RELA: + ef->rela = (Elf_Rela *)(dp[i].d_un.d_ptr + off); + break; + case DT_RELASZ: + ef->relasz = dp[i].d_un.d_val; + break; + #endif default: break; } *************** *** 566,591 **** --- 582,628 ---- modcnt = 0; while (p < p_stop) { + #ifdef __sparc__ + COPYOUT(p, &v, sizeof(v)); + elf_reloc_ptr(fp, ef, p, &v, sizeof(v)); + COPYOUT(v, &md, sizeof(md)); + elf_reloc_ptr(fp, ef, v, &md, sizeof(md)); + p++; + #else COPYOUT(p++, &v, sizeof(v)); COPYOUT(v + ef->off, &md, sizeof(md)); + #endif switch(md.md_type) { case MDT_DEPEND: if (ef->kernel) /* kernel must not depend on anything */ break; + #ifdef __sparc__ + s = strdupout((vm_offset_t)md.md_cval); + #else s = strdupout((vm_offset_t)(md.md_cval + ef->off)); + #endif minfolen = sizeof(*mdepend) + strlen(s) + 1; mdepend = malloc(minfolen); if (mdepend == NULL) return ENOMEM; + #ifdef __sparc__ + COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof(*mdepend)); + #else COPYOUT((vm_offset_t)(md.md_data + ef->off), mdepend, sizeof(*mdepend)); + #endif strcpy((char*)(mdepend + 1), s); free(s); file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend); free(mdepend); break; case MDT_VERSION: + #ifdef __sparc__ + s = strdupout((vm_offset_t)md.md_cval); + COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); + #else s = strdupout((vm_offset_t)(md.md_cval + ef->off)); COPYOUT((vm_offset_t)(md.md_data + ef->off), &mver, sizeof(mver)); + #endif file_addmodule(fp, s, mver.mv_version, NULL); free(s); modcnt++; *************** *** 657,659 **** --- 694,723 ---- } return ENOENT; } + + #ifdef __sparc__ + /* + * Apply any intra-module relocations to the value. *p is the load address + * of the value and val/len is the value to be modified. This does NOT modify + * the image in-place, because this is done by kern_linker later on. + */ + static void + elf_reloc_ptr(struct preloaded_file *mp, elf_file_t ef, + void *p, void *val, size_t len) + { + Elf_Addr off = (Elf_Addr)p - ef->off, word; + size_t n; + Elf_Rela r; + + for (n = 0; n < ef->relasz / sizeof(r); n++) { + COPYOUT(ef->rela + n, &r, sizeof(r)); + + if (r.r_offset >= off && r.r_offset < off + len && + ELF_R_TYPE(r.r_info) == R_SPARC_RELATIVE) { + word = ef->off + r.r_addend; + bcopy(&word, (char *)val + (r.r_offset - off), + sizeof(word)); + } + } + } + #endif >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-sparc" in the body of the message