From owner-freebsd-hackers@FreeBSD.ORG Wed Sep 17 15:31:56 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CC1C61065671 for ; Wed, 17 Sep 2008 15:31:56 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from server.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id 15F758FC28 for ; Wed, 17 Sep 2008 15:31:55 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from localhost.corp.yahoo.com (john@localhost [IPv6:::1]) (authenticated bits=0) by server.baldwin.cx (8.14.2/8.14.2) with ESMTP id m8HFVaKR006866; Wed, 17 Sep 2008 11:31:49 -0400 (EDT) (envelope-from jhb@freebsd.org) From: John Baldwin To: freebsd-hackers@freebsd.org Date: Wed, 17 Sep 2008 11:31:30 -0400 User-Agent: KMail/1.9.7 References: In-Reply-To: MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200809171131.30819.jhb@freebsd.org> Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [IPv6:::1]); Wed, 17 Sep 2008 11:31:49 -0400 (EDT) X-Virus-Scanned: ClamAV 0.93.1/8270/Wed Sep 17 09:15:56 2008 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-2.5 required=4.2 tests=AWL,BAYES_00,NO_RELAYS autolearn=ham version=3.1.3 X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on server.baldwin.cx Cc: Navdeep Parhar Subject: Re: kgdb's add-kld broken on amd64 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Sep 2008 15:31:57 -0000 On Tuesday 16 September 2008 04:07:46 pm Navdeep Parhar wrote: > Hello everyone, > > The add-kld command in kgdb does not work as expected on amd64 > (I'm using a recent HEAD, problem may affect others too). It uses > the same address for all sections: > > (kgdb) add-kld if_cxgb.ko > add symbol table from file "/boot/kernel/if_cxgb.ko" at > .text_addr = 0xffffffff81022000 > .rodata_addr = 0xffffffff81022000 > .rodata.str1.8_addr = 0xffffffff81022000 > .rodata.str1.1_addr = 0xffffffff81022000 > set_modmetadata_set_addr = 0xffffffff81022000 > set_sysctl_set_addr = 0xffffffff81022000 > set_sysinit_set_addr = 0xffffffff81022000 > set_sysuninit_set_addr = 0xffffffff81022000 > .data_addr = 0xffffffff81022000 > .bss_addr = 0xffffffff81022000 > (y or n) > > This is not correct. The .text section's address is OK but the > others are not. > > The problem seems to be that all amd64 kernel objects have VMA set > to 0 for all sections. add_section() in gnu/usr.bin/gdb/kgdb/kld.c > uses this VMA to adjust the address of the section: > > address = asi->base_addr + bfd_get_section_vma(bfd, sect); > > objdump -h shows that the userland objects on amd64 and all > objects (kernel + userland) on i386 set VMA. It is only the > kernel objects on amd64 that have VMA = 0. (sample output from > amd64 and i386 machines appended at the end) > > For the time being I've patched kgdb to consider the file offset > and not the VMA while calculating the section address. It seems > to work but is probably not the right way to fix the problem. > > Any thoughts? Hmm, I wonder if this is because on amd64 modules are .o's rather than .so's. It is. File offset isn't quite right. Instead, the way sys/kern/link_elf_obj.c works is that it just loads the PROGBITS (text, code, etc.) and NOBITS (bss) sections in the order they are in the file and concatenates them. So, the relocation logic in kgdb will need to be updated to recognize a .o vs .so and apply that algorithm for .o files. Actually, what I've done is to replace the home-rolled section relocation stuff with the gdb primitives that the solib code in gdb uses. It works here on i386, and hopefully this will fix this as this is how the sharedlibrary kld stuff is doing the relocations: --- //depot/vendor/freebsd/src/gnu/usr.bin/gdb/kgdb/kld.c 2008/04/29 20:41:02 +++ //depot/user/jhb/kgdb/gnu/usr.bin/gdb/kgdb/kld.c 2008/09/17 15:27:25 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -196,39 +197,14 @@ return (0); } -struct add_section_info { - struct section_addr_info *section_addrs; - int sect_index; - CORE_ADDR base_addr; -}; - -static void -add_section (bfd *bfd, asection *sect, void *arg) -{ - struct add_section_info *asi = arg; - CORE_ADDR address; - char *name; - - /* Ignore non-resident sections. */ - if ((bfd_get_section_flags(bfd, sect) & (SEC_ALLOC | SEC_LOAD)) == 0) - return; - - name = xstrdup(bfd_get_section_name(bfd, sect)); - make_cleanup(xfree, name); - address = asi->base_addr + bfd_get_section_vma(bfd, sect); - asi->section_addrs->other[asi->sect_index].name = name; - asi->section_addrs->other[asi->sect_index].addr = address; - asi->section_addrs->other[asi->sect_index].sectindex = sect->index; - printf_unfiltered("\t%s_addr = %s\n", name, local_hex_string(address)); - asi->sect_index++; -} - static void load_kld (char *path, CORE_ADDR base_addr, int from_tty) { - struct add_section_info asi; + struct section_addr_info *sap; + struct section_table *sections, *sections_end, *s; struct cleanup *cleanup; bfd *bfd; + int i; /* Open the kld. */ bfd = bfd_openr(path, gnutarget); @@ -244,19 +220,30 @@ if (bfd_get_section_by_name (bfd, ".text") == NULL) error("\"%s\": can't find text section", path); + /* Build a section table from the bfd and relocate the sections. */ + if (build_section_table (bfd, §ions, §ions_end)) + error("\"%s\": can't find file sections", path); + cleanup = make_cleanup(xfree, sections); + for (s = sections; s < sections_end; s++) { + s->addr += base_addr; + s->endaddr += base_addr; + } + + /* Build a section addr info to pass to symbol_file_add(). */ + sap = build_section_addr_info_from_section_table (sections, + sections_end); + cleanup = make_cleanup((make_cleanup_ftype *)free_section_addr_info, + sap); + printf_unfiltered("add symbol table from file \"%s\" at\n", path); - - /* Build a section table for symbol_file_add() from the bfd sections. */ - asi.section_addrs = alloc_section_addr_info(bfd_count_sections(bfd)); - cleanup = make_cleanup(xfree, asi.section_addrs); - asi.sect_index = 0; - asi.base_addr = base_addr; - bfd_map_over_sections(bfd, add_section, &asi); + for (i = 0; i < sap->num_sections; i++) + printf_unfiltered("\t%s_addr = %s\n", sap->other[i].name, + local_hex_string(sap->other[i].addr)); if (from_tty && (!query("%s", ""))) error("Not confirmed."); - symbol_file_add(path, from_tty, asi.section_addrs, 0, OBJF_USERLOADED); + symbol_file_add(path, from_tty, sap, 0, OBJF_USERLOADED); do_cleanups(cleanup); } -- John Baldwin