From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23100 invoked by alias); 5 Jan 2004 17:39:49 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 23093 invoked from network); 5 Jan 2004 17:39:48 -0000 Received: from unknown (HELO sadr.equallogic.com) (66.155.203.134) by sources.redhat.com with SMTP; 5 Jan 2004 17:39:48 -0000 Received: from sadr.equallogic.com (localhost.localdomain [127.0.0.1]) by sadr.equallogic.com (8.12.8/8.12.8) with ESMTP id i05Hdm6a014903 for ; Mon, 5 Jan 2004 12:39:48 -0500 Received: from deneb.dev.equallogic.com (deneb [172.16.1.99]) by sadr.equallogic.com (8.12.8/8.12.8) with ESMTP id i05HdmIg014898 for ; Mon, 5 Jan 2004 12:39:48 -0500 Received: from localhost.equallogic.com (localhost.localdomain [127.0.0.1]) by deneb.dev.equallogic.com (8.11.6/8.11.6) with ESMTP id i05Hdl216335 for ; Mon, 5 Jan 2004 12:39:48 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16377.41315.519376.660039@gargle.gargle.HOWL> Date: Mon, 05 Jan 2004 17:39:00 -0000 From: Paul Koning To: gdb@sources.redhat.com Subject: RE: relocation of shared libs not based at 0 X-SW-Source: 2004-01/txt/msg00039.txt.bz2 Continuing a thread from a long time ago... On NetBSD/MIPS I was having trouble with shared library references, which is caused by wrong relocation processing in solib-svr4.c. Back in February 2003, I proposed a patch for this, but the reaction wasn't really encouraging and I wasn't happy with the diagnosis I had made at that time, anyway. Recently I went back to this and analyzed the problem better. The issue is very simple: solib-svr4.c assumes that the LM_ADDR entries in the library file headers are offsets from the start VMA of the library to the start VMA of that section. In fact, they are not; they are the start VMA of the section before relocation. If the library VMA (as linked) is zero, as is the case on many targets such as x86, then these two interpretations are identical. On MIPS, the as-linked base VMA is 0x5ffe0000, so the existing code produces the wrong answer. At the end of the earlier discussion it was pointed out that the SysV ABI requires all sections of a library to be relocated by the same amount, and it seemed that NetBSD wasn't obeying that. It turns out that it is; I was confused about this and muddled the picture. And that's what was wrong with my earlier patch. So the real answer is simple: the LM_ADDR entries have to be adjusted by the as-linked start VMA of the library. The only problem I ran into is that I couldn't find a clean way to obtain that value in gdb. I did come up with something that worked; if there are better ways to do this I would be interested. My fix is in a modified 5.3, but the relevant source is unchanged from 5.3 to 6.0. So attached is a diff for 6.0 that shows the fix I described. paul --- gdb/solib-svr4.c.orig Fri Jun 13 17:56:27 2003 +++ gdb/solib-svr4.c Mon Jan 5 12:29:49 2004 @@ -1375,8 +1375,29 @@ svr4_relocate_section_addresses (struct so_list *so, struct section_table *sec) { - sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR (so)); - sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so)); + CORE_ADDR reloc; + + /* On NetBSD/MIPS at least, the library is mapped in two pieces. + The section headers describe this: each shows the unrelocated + virtual address of the section. To figure out the relocated + address, we have to adjust these by the base VMA of the library. + + There isn't a really clean way to figure out the offset of each + section. "filepos" doesn't do it, because that is the + file-relative offset, not the VMA offset. + + So what we do is this: + Pick up the VMA (given by the header) of the first section, + and subtract from that its filepos. That's the unrelocated VMA + of the library. Subtract that from the unrelocated VMA + of each section to get its relocation bias; add that to the + library load address to get the relocated address. + */ + reloc = so->sections->the_bfd_section->vma - + so->sections->the_bfd_section->filepos; + + sec->endaddr = svr4_truncate_ptr (sec->endaddr - reloc + LM_ADDR (so)); + sec->addr = svr4_truncate_ptr (sec->addr - reloc + LM_ADDR (so)); }