From owner-svn-src-head@FreeBSD.ORG Sun Mar 10 00:43:02 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 62CE5FA7; Sun, 10 Mar 2013 00:43:02 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 3D2D12CE; Sun, 10 Mar 2013 00:43:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r2A0h2UO076957; Sun, 10 Mar 2013 00:43:02 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r2A0h1jC076955; Sun, 10 Mar 2013 00:43:01 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201303100043.r2A0h1jC076955@svn.freebsd.org> From: Ian Lepore Date: Sun, 10 Mar 2013 00:43:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r248121 - in head/sys/boot: common fdt X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Mar 2013 00:43:02 -0000 Author: ian Date: Sun Mar 10 00:43:01 2013 New Revision: 248121 URL: http://svnweb.freebsd.org/changeset/base/248121 Log: Attach the elf section headers to the loaded kernel as metadata, so they can easily be used by later post-processing. When searching for a compiled-in fdt blob, use the section headers to get the size and location of the .dynsym section to do a symbol search. This fixes a problem where the search could overshoot the symbol table and wander into the string table. Sometimes that was harmless and sometimes it lead to spurious panic messages about an offset bigger than the module size. Modified: head/sys/boot/common/load_elf.c head/sys/boot/fdt/fdt_loader_cmd.c Modified: head/sys/boot/common/load_elf.c ============================================================================== --- head/sys/boot/common/load_elf.c Sun Mar 10 00:36:28 2013 (r248120) +++ head/sys/boot/common/load_elf.c Sun Mar 10 00:43:01 2013 (r248121) @@ -397,6 +397,8 @@ __elfN(loadimage)(struct preloaded_file "_loadimage: failed to read section headers"); goto nosyms; } + file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); + symtabindex = -1; symstrindex = -1; for (i = 0; i < ehdr->e_shnum; i++) { Modified: head/sys/boot/fdt/fdt_loader_cmd.c ============================================================================== --- head/sys/boot/fdt/fdt_loader_cmd.c Sun Mar 10 00:36:28 2013 (r248120) +++ head/sys/boot/fdt/fdt_loader_cmd.c Sun Mar 10 00:43:01 2013 (r248121) @@ -118,16 +118,17 @@ static char cwd[FDT_CWD_LEN] = "/"; static vm_offset_t fdt_find_static_dtb() { - Elf_Dyn dyn; + Elf_Ehdr *ehdr; + Elf_Shdr *shdr; Elf_Sym sym; - vm_offset_t dyntab, esym, strtab, symtab, fdt_start; + vm_offset_t strtab, symtab, fdt_start; uint64_t offs; struct preloaded_file *kfp; struct file_metadata *md; char *strp; - int sym_count; + int i, sym_count; - symtab = strtab = dyntab = esym = 0; + symtab = strtab = 0; strp = NULL; offs = __elfN(relocation_offset); @@ -136,42 +137,26 @@ fdt_find_static_dtb() if (kfp == NULL) return (0); - md = file_findmetadata(kfp, MODINFOMD_ESYM); + /* Locate the dynamic symbols and strtab. */ + md = file_findmetadata(kfp, MODINFOMD_ELFHDR); if (md == NULL) return (0); - bcopy(md->md_data, &esym, sizeof(esym)); - /* esym is already offset */ + ehdr = (Elf_Ehdr *)md->md_data; - md = file_findmetadata(kfp, MODINFOMD_DYNAMIC); + md = file_findmetadata(kfp, MODINFOMD_SHDR); if (md == NULL) return (0); - bcopy(md->md_data, &dyntab, sizeof(dyntab)); - dyntab += offs; + shdr = (Elf_Shdr *)md->md_data; - /* Locate STRTAB and DYNTAB */ - for (;;) { - COPYOUT(dyntab, &dyn, sizeof(dyn)); - if (dyn.d_tag == DT_STRTAB) { - strtab = (vm_offset_t)(dyn.d_un.d_ptr) + offs; - } else if (dyn.d_tag == DT_SYMTAB) { - symtab = (vm_offset_t)(dyn.d_un.d_ptr) + offs; - } else if (dyn.d_tag == DT_NULL) { - break; + for (i = 0; i < ehdr->e_shnum; ++i) { + if (shdr[i].sh_type == SHT_DYNSYM && symtab == 0) { + symtab = shdr[i].sh_addr + offs; + sym_count = shdr[i].sh_size / sizeof(Elf_Sym); + } else if (shdr[i].sh_type == SHT_STRTAB && strtab == 0) { + strtab = shdr[i].sh_addr + offs; } - dyntab += sizeof(dyn); } - if (symtab == 0 || strtab == 0) { - /* - * No symtab? No strtab? That should not happen here, - * and should have been verified during __elfN(loadimage). - * This must be some kind of a bug. - */ - return (0); - } - - sym_count = (int)(esym - symtab) / sizeof(Elf_Sym); - /* * The most efficent way to find a symbol would be to calculate a * hash, find proper bucket and chain, and thus find a symbol.