[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