From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24015 invoked by alias); 18 Dec 2002 00:28:22 -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 24004 invoked from network); 18 Dec 2002 00:28:21 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by 209.249.29.67 with SMTP; 18 Dec 2002 00:28:21 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id gBI01xg20752 for ; Tue, 17 Dec 2002 19:01:59 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id gBI0S9219356; Tue, 17 Dec 2002 19:28:09 -0500 Received: from localhost.localdomain (vpn50-3.rdu.redhat.com [172.16.50.3]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id gBI0S8L32397; Tue, 17 Dec 2002 19:28:08 -0500 Received: (from kev@localhost) by localhost.localdomain (8.11.6/8.11.6) id gBI0S2f04460; Tue, 17 Dec 2002 17:28:02 -0700 Date: Tue, 17 Dec 2002 16:28:00 -0000 From: Kevin Buettner Message-Id: <1021218002802.ZM4459@localhost.localdomain> In-Reply-To: "Kris Warkentin" "relocation of shared libs not based at 0" (Dec 17, 3:23pm) References: <032c01c2a60a$2368a6e0$0202040a@catdog> To: "Kris Warkentin" , Subject: Re: relocation of shared libs not based at 0 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-12/txt/msg00266.txt.bz2 On Dec 17, 3:23pm, Kris Warkentin wrote: > I recently came across a problem debugging a core file with some of our > older shared libs. Info shared showed the relocations of the shared libs to > be mangled (offset to 0x60... range rather than 0xb0... range). We had > recently changed our tools to always set the vaddr of shared libs to be zero > because of this but I was speaking to one of our architects and he says that > this shouldn't be. > > One of the future optimizations we're looking at is pre-relocating shared > libs so that they can be executed in place (on flash for instance) and the > fact that the SysV stuff seems to assume that everything is based at zero is > not particularily compatable with that. I've attached an ugly patch that > shows a fix. This is for illustration only since solib.c is the wrong place > to put this but it makes it clear what the issue is. > > Can anyone with more knowledge than I enlighten me as to a) whether it is > proper to allow shared objects to be non zero-based and b) a better way to > do this. I looked at putting it in solib-svr4.c but I don't have access to > the bfd in there, at least in svr4_relocate_section_addresses(). With regard to a), it's okay for shared objects to be non-zero based. We'll get to b) in a bit... Let's first take a look at the existing code in GDB's solib-svr4.c: static void 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)); } This code is adjusting the start and end addresses by LM_ADDR (so) which is simply the l_addr field obtained from struct link_map. On my i386 GNU/Linux system, the comment in link.h says that l_addr is the "base address shared object is loaded at." We must be very careful with the term "base address" because it's quite possible that it means something very different than what you think it does. (I certainly found it counter-intuitive.) Here is what chapter 5 of the "System V Application Binary Interface, Edition 4.1" says about the term "Base Address": As "Program Loading" in this chapter of the processor supplement describes, the virtual addresses in the program headers might not represent the actual virtual addresses of the program's memory image. Executable files typically contain absolute code. To let the process execute correctly, the segments must reside at the virtual addresses used to build the executable file. On the other hand, shared object segments typically contain position-independent code. This lets a segment's virtual address change from one process to another, without invalidating execu- tion behavior. Though the system chooses virtual addresses for individual processes, it maintains the segments' relative positions. Because position- independent code uses relative addressing between segments, the difference between virtual addresses in memory must match the difference between virtual addresses in the file. The difference between the virtual address of any segment in memory and the corresponding virtual address in the file is thus a single constant value for any one executable or shared object in a given process. This difference is the base address. One use of the base address is to relocate the memory image of the program during dynamic linking. An executable or shared object file's base address is calculated during execution from three values: the virtual memory load address, the maximum page size, and M the lowest virtual address of a program's loadable segment. To compute the base address, one determines the memory address associated with the lowest p_vaddr value for a PT_LOAD segment. This address is truncated to the nearest multiple of the maximum page size. The corresponding p_vaddr value itself is also truncated to the nearest multiple of the maximum page size. The base address is the difference between the truncated memory address and the truncated p_vaddr value. See this chapter in the processor supplement for more information and examples. "Operating System Interface" of Chapter 3 in the processor supplement contains more information about the virtual address space and page size. So, as I understand it, the "base address" is *not* an absolute location, but is actually the difference between where the segment ended up and the location assigned to it in the executable file. Thus the "base address" is the proper value to use to relocate the segment's start and end addresses. Now, it's possible that my understanding is flawed. If so, I await enlightenment. I think it's also possible that the shared library implementation that you're using might not conform to the above definition of "base address". If that's the case, then you can either attempt to get it fixed in the code which implements the dynamic loader, or, if that's not possible, create a new solib backend for gdb which implements support for your shared library machinery. I suspect it would be very similar to solib-svr4.c. With regard to the two patches that have been posted for fixing this problem, I don't think that either one is correct in light of the above definition of "base address". Kevin