[PATCH 8/8] Cygwin: Consider DLL rebasing when computing dumper exclusions

Jon Turney jon.turney@dronecode.org.uk
Wed Jul 1 21:25:29 GMT 2020


I think this would always have been neeeded, but is essential on x86_64,
as kernel32.dll has an ImageBase of 00000001:80000000 (but is always
rebased when loaded), which is identical to the cygwin DLL, causing
duplicate or overlapping exclusions.
---
 winsup/utils/dumper.cc   |  2 +-
 winsup/utils/dumper.h    |  2 +-
 winsup/utils/parse_pe.cc | 28 ++++++++++++++++++++--------
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/winsup/utils/dumper.cc b/winsup/utils/dumper.cc
index c0b3fd8ff..fa3fe1fbc 100644
--- a/winsup/utils/dumper.cc
+++ b/winsup/utils/dumper.cc
@@ -284,7 +284,7 @@ dumper::add_module (LPVOID base_address)
   new_entity->u.module.base_address = base_address;
   new_entity->u.module.name = module_name;
 
-  parse_pe (module_name, excl_list);
+  parse_pe (module_name, excl_list, base_address);
 
   deb_printf ("added module %p %s\n", base_address, module_name);
   return 1;
diff --git a/winsup/utils/dumper.h b/winsup/utils/dumper.h
index 9367587bf..9c4b1f092 100644
--- a/winsup/utils/dumper.h
+++ b/winsup/utils/dumper.h
@@ -133,7 +133,7 @@ extern int deb_printf ( const char* format, ... );
 
 extern char* psapi_get_module_name ( HANDLE hProcess, LPVOID BaseAddress );
 
-extern int parse_pe ( const char* file_name, exclusion* excl_list );
+extern int parse_pe ( const char* file_name, exclusion* excl_list, LPVOID base_address );
 
 extern BOOL verbose;
 
diff --git a/winsup/utils/parse_pe.cc b/winsup/utils/parse_pe.cc
index 653c46dfe..0256ada53 100644
--- a/winsup/utils/parse_pe.cc
+++ b/winsup/utils/parse_pe.cc
@@ -70,21 +70,21 @@ exclusion::sort_and_check ()
 }
 
 static void
-select_data_section (bfd * abfd, asection * sect, PTR obj)
+select_data_section (bfd * abfd, asection * sect, exclusion *excl_list,
+		     SSIZE_T adj)
 {
-  exclusion *excl_list = (exclusion *) obj;
-
   if ((sect->flags & (SEC_CODE | SEC_DEBUGGING)) &&
       sect->vma && bfd_get_section_size (sect))
     {
-      excl_list->add ((LPBYTE) sect->vma, (SIZE_T) bfd_get_section_size (sect));
-      deb_printf ("excluding section: %20s %08lx\n", sect->name,
-		  bfd_get_section_size (sect));
+      bfd_vma vma = sect->vma + adj;
+      excl_list->add ((LPBYTE) vma, (SIZE_T) bfd_get_section_size (sect));
+      deb_printf ("excluding section: %20s %016lx %016lx %08lx\n", sect->name,
+		  sect->vma, vma, bfd_get_section_size (sect));
     }
 }
 
 int
-parse_pe (const char *file_name, exclusion * excl_list)
+parse_pe (const char *file_name, exclusion * excl_list, LPVOID base_address)
 {
   if (file_name == NULL || excl_list == NULL)
     return 0;
@@ -104,7 +104,19 @@ parse_pe (const char *file_name, exclusion * excl_list)
     }
 
   bfd_check_format (abfd, bfd_object);
-  bfd_map_over_sections (abfd, &select_data_section, (PTR) excl_list);
+
+  /* Compute the relocation offset for this DLL.  Unfortunately, we have to
+     guess at ImageBase (one page before vma of first section), since bfd
+     doesn't let us get at backend-private data */
+  bfd_vma imagebase = abfd->sections->vma - 0x1000;
+  SSIZE_T adj = (bfd_vma)base_address - imagebase;
+  deb_printf("imagebase relocated from %016lx to %016lx (%016lx)\n",
+	     imagebase, base_address, adj);
+
+  asection *p;
+  for (p = abfd->sections; p != NULL; p = p->next)
+    select_data_section(abfd, p, excl_list, adj);
+
   excl_list->sort_and_check ();
 
   bfd_close (abfd);
-- 
2.27.0



More information about the Cygwin-patches mailing list