From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23170 invoked by alias); 12 Jun 2007 20:47:41 -0000 Received: (qmail 23162 invoked by uid 22791); 12 Jun 2007 20:47:40 -0000 X-Spam-Check-By: sourceware.org Received: from nile.gnat.com (HELO nile.gnat.com) (205.232.38.5) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 12 Jun 2007 20:47:35 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-nile.gnat.com (Postfix) with ESMTP id D5B9648CF67 for ; Tue, 12 Jun 2007 16:47:32 -0400 (EDT) Received: from nile.gnat.com ([127.0.0.1]) by localhost (nile.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 22262-01-6 for ; Tue, 12 Jun 2007 16:47:32 -0400 (EDT) Received: from joel.gnat.com (unknown [70.71.0.212]) by nile.gnat.com (Postfix) with ESMTP id 3B4B548D0DC for ; Tue, 12 Jun 2007 16:47:32 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 46A61E7B4F; Tue, 12 Jun 2007 13:49:00 -0700 (PDT) Date: Tue, 12 Jun 2007 20:47:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [win32] wrong solib from/to addresses Message-ID: <20070612204900.GA4435@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="2fHTh5uZTiUOsy+g" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-06/txt/msg00210.txt.bz2 --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1781 Hello, We are working on porting our product to Vista, and we have noticed an issue that this version of the MS OS makes more apparent: The from/to addresses printed in the "info shared" listing are correct only when the DLL was loaded at the prefered load address (which is in the ImageBase field of the COFF/PE header). I collegue of mine told me that, for security reasons, system DLLs on Vista are now always rebased, and thus, the information printed by info based is off by a certain offset. The core of the attached patch is to implement the target_so_ops method relocate_section_addresses. For that, I needed to compute the offset between the load address and the image_base, and store it for later use (during the call of our routine above). There were two challenges: 1. Compute this image base. Rather than dig into the COFF/PE data, I took a simpler route that I think has already been taken: Use the start address of the .text section. I think this is already used to do the symbol relocation. 2. Make that information available: I found that the lm_info field was not allocated, so I had to add its initialization. With all these changes, the address are correct again. 2007-06-12 Joel Brobecker * win32-nat.c (struct lm_info): Add new field image_base. (solib_symbols_add): Compute the prefered load address and save it in the lm_info. (register_loaded_dll): Initialize new field image_base. (win32_relocate_section_addresses): Implement this routine. (win32_current_sos): Allocate and set lm_info data. Tested on x86-windows, no regression. Dejagnu on Vista is not working at all for me, so I ran the testsuite on XP instead. OK to apply? Thanks, -- Joel --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="win32-solib-fsf.diff" Content-length: 3057 Index: gdb/win32-nat.c =================================================================== RCS file: /cvs/src/src/gdb/win32-nat.c,v retrieving revision 1.131 diff -u -p -r1.131 win32-nat.c --- gdb/win32-nat.c 31 May 2007 17:32:21 -0000 1.131 +++ gdb/win32-nat.c 12 Jun 2007 20:17:19 -0000 @@ -541,6 +541,9 @@ struct safe_symbol_file_add_args struct lm_info { DWORD load_addr; + + /* The ImageBase, aka the prefered load address. */ + CORE_ADDR image_base; }; static struct so_list solib_start, *solib_end; @@ -659,6 +662,7 @@ solib_symbols_add (struct so_list *so, C static struct objfile *result = NULL; char *name = so->so_name; bfd *abfd = NULL; + asection *text = NULL; char *p; /* The symbols in a dll are offset by 0x1000, which is the @@ -701,10 +705,19 @@ solib_symbols_add (struct so_list *so, C do_cleanups (my_cleanups); } + if (abfd != NULL) + text = bfd_get_section_by_name (abfd, ".text"); + + /* Compute the ImageBase of our DLL. For that, we assume that + it is identical to the VMA of the ".text" section. This is + an assumption that is being made in other places already, + so this should be ok. */ + if (text != NULL) + so->lm_info->image_base = bfd_section_vma (abfd, text); + p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) { - asection *text = bfd_get_section_by_name (abfd, ".text"); cygwin_load_start = bfd_section_vma (abfd, text); cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); } @@ -752,6 +765,7 @@ register_loaded_dll (const char *name, D so = XZALLOC (struct so_list); so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); so->lm_info->load_addr = load_addr; + so->lm_info->image_base = 0; /* Will be filled in later. */ cygwin_conv_to_posix_path (buf, so->so_name); strcpy (so->so_original_name, so->so_name); @@ -842,8 +856,18 @@ static void win32_relocate_section_addresses (struct so_list *so, struct section_table *sec) { - /* FIXME */ - return; + const DWORD load_addr = so->lm_info->load_addr; + const CORE_ADDR image_base = so->lm_info->image_base; + + /* If we couldn't determine the DLL prefered load address (image base), + then we can't adjust the section addresses. Assume that the DLL was + loaded at the prefered load address, which means that the second + addresses do not need to be adjusted. */ + if (image_base == 0) + return; + + sec->addr = sec->addr - image_base + load_addr; + sec->endaddr = sec->endaddr - image_base + load_addr; } static void @@ -2231,6 +2255,8 @@ win32_current_sos (void) struct so_list *new = XZALLOC (struct so_list); strcpy (new->so_name, sop->so_name); strcpy (new->so_original_name, sop->so_original_name); + new->lm_info = xmalloc (sizeof (struct lm_info)); + memcpy (new->lm_info, sop->lm_info, sizeof (struct lm_info)); if (!start) last = start = new; else --2fHTh5uZTiUOsy+g--