From mboxrd@z Thu Jan 1 00:00:00 1970 From: James Cownie To: Jakub Jelinek Cc: libc-alpha@sources.redhat.com, binutils@sources.redhat.com, gdb@sources.redhat.com Subject: Re: RFC: ELF prelinker - 0.1.1 Date: Thu, 05 Jul 2001 04:31:00 -0000 Message-id: <15I7Lu-0j2-00@etnus.com> References: <20010705125600.Q737@sunsite.ms.mff.cuni.cz> X-SW-Source: 2001-07/msg00039.html Jakub, > I have to. Debugger relocates them too, but debugger relocates them > by adding link_map->l_addr, which is load address, not base address. > Load address is the difference between actual virtual addresses in > library and virtual addresses stored in the library. Ahh, so the point is that l_addr is zero for a pre-linked library in the good case, or the offset of where you have to place the pre-linked library from where you pre-linked it to in the bad case. So you are right, the debugger won't do any relocation for you (well, it will, but adding zero doesn't achieve anything !). Previously (when shared libraries were all linked as though they would be loaded at zero), l_addr _was_ the base address of the library. After all, l_addr is declared like this :- ElfW(Addr) l_addr; /* Base address shared object is loaded at. */ It seems a pity to have to do so much work in the linker, though, especially since rewriting DWARF2 will be _very_ unpleasant and fragile. Since many of the things in DWARF2 are encoded in "LEB128" format, which basically means they're a byte-string of appropriate length, _and_ there are inter-object offsets to worry about when you change the lengths of things in the middle. DWARF2 is _not_ designed for rewriting. When other people (such as SGI) have encountered the need to rewrite DWARF2 they've chosen to do it by adding additional translation tables, rather than attempting the DWARF2 modification :-( Although it requires support in more tools, I would strongly suggest that the right solution here is to extend the struct link_map to include a new field for the debugger which is the offset to be applied to debug information. Something like this :- struct link_map { /* These first few members are part of the protocol with the debugger. This is the same format used in SVR4. */ ElfW(Addr) l_addr; /* Base address shared object is loaded at. */ char *l_name; /* Absolute file name object was found in. */ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ + ElfW(Addr) l_debug_relocation; /* Value to be added to debug entries */ ... etc ... the debugger would then add (l_addr + l_debug_relocation) to the debug entries. Somehow you'd need to get this information (which is basically the preferred base address of the pre-linked library) through to the dynamic linker. I assume that that's not too hard ? The advantage of an approach like this is that the pre-linker doesn't have to relocate the debug information. So It's faster It's independent of the debug formats Making the pre-linker dependent on debug formats is a very bad idea IMHO... -- Jim James Cownie Etnus, LLC. +44 117 9071438 http://www.etnus.com