94 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| /* parse_pe.cc
 | |
| 
 | |
|    Copyright 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 | |
| 
 | |
|    Written by Egor Duda <deo@logos-m.ru>
 | |
| 
 | |
|    This file is part of Cygwin.
 | |
| 
 | |
|    This software is a copyrighted work licensed under the terms of the
 | |
|    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | |
|    details. */
 | |
| 
 | |
| #include <bfd.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include "dumper.h"
 | |
| 
 | |
| int
 | |
| exclusion::add (LPBYTE mem_base, DWORD mem_size)
 | |
| {
 | |
|   while (last >= size)
 | |
|     size += step;
 | |
|   region = (process_mem_region *) realloc (region, size * sizeof (process_mem_region));
 | |
|   if (region == NULL)
 | |
|     return 0;
 | |
|   region[last].base = mem_base;
 | |
|   region[last].size = mem_size;
 | |
|   last++;
 | |
|   return 1;
 | |
| };
 | |
| 
 | |
| int 
 | |
| cmp_regions (const void *r1, const void *r2)
 | |
| {
 | |
|   if (((process_mem_region *) r1)->base < ((process_mem_region *) r2)->base)
 | |
|     return -1;
 | |
|   if (((process_mem_region *) r1)->base > ((process_mem_region *) r2)->base)
 | |
|     return 1;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| exclusion::sort_and_check ()
 | |
| {
 | |
|   qsort (region, last, sizeof (process_mem_region), &cmp_regions);
 | |
|   for (process_mem_region * p = region; p < region + last - 1; p++)
 | |
|     {
 | |
|       process_mem_region *q = p + 1;
 | |
|       if (q == p + 1)
 | |
| 	continue;
 | |
|       if (p->base + size > q->base)
 | |
| 	{
 | |
| 	  fprintf (stderr, "region error @ (%8p + %d) > %8p\n", (unsigned) p->base, size, q->base);
 | |
| 	  return 0;
 | |
| 	}
 | |
|     }
 | |
|   return 1;
 | |
| }
 | |
| 
 | |
| static void
 | |
| select_data_section (bfd * abfd, asection * sect, PTR obj)
 | |
| {
 | |
|   exclusion *excl_list = (exclusion *) obj;
 | |
| 
 | |
|   if ((sect->flags & (SEC_CODE | SEC_DEBUGGING)) &&
 | |
|       sect->vma && sect->_raw_size)
 | |
|     {
 | |
|       excl_list->add ((LPBYTE) sect->vma, (DWORD) sect->_raw_size);
 | |
|       deb_printf ("excluding section: %20s %08lx\n", sect->name, sect->_raw_size);
 | |
|     }
 | |
| }
 | |
| 
 | |
| int
 | |
| parse_pe (const char *file_name, exclusion * excl_list)
 | |
| {
 | |
|   if (file_name == NULL || excl_list == NULL)
 | |
|     return 0;
 | |
| 
 | |
|   bfd *abfd = bfd_openr (file_name, "pei-i386");
 | |
|   if (abfd == NULL)
 | |
|     {
 | |
|       bfd_perror ("failed to open file");
 | |
|       return 0;
 | |
|     }
 | |
| 
 | |
|   bfd_check_format (abfd, bfd_object);
 | |
|   bfd_map_over_sections (abfd, &select_data_section, (PTR) excl_list);
 | |
|   excl_list->sort_and_check ();
 | |
| 
 | |
|   bfd_close (abfd);
 | |
|   return 1;
 | |
| }
 |