OSDN Git Service

* cygpath.cc (get_device_name): Fix path length test.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / parse_pe.cc
1 /* parse_pe.cc
2
3    Copyright 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
4
5    Written by Egor Duda <deo@logos-m.ru>
6
7    This file is part of Cygwin.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License (file COPYING.dumper) for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22
23 #include <bfd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include "dumper.h"
28
29 int
30 exclusion::add (LPBYTE mem_base, DWORD mem_size)
31 {
32   while (last >= size)
33     size += step;
34   region = (process_mem_region *) realloc (region, size * sizeof (process_mem_region));
35   if (region == NULL)
36     return 0;
37   region[last].base = mem_base;
38   region[last].size = mem_size;
39   last++;
40   return 1;
41 };
42
43 int
44 cmp_regions (const void *r1, const void *r2)
45 {
46   if (((process_mem_region *) r1)->base < ((process_mem_region *) r2)->base)
47     return -1;
48   if (((process_mem_region *) r1)->base > ((process_mem_region *) r2)->base)
49     return 1;
50   return 0;
51 }
52
53 int
54 exclusion::sort_and_check ()
55 {
56   qsort (region, last, sizeof (process_mem_region), &cmp_regions);
57   for (process_mem_region * p = region; p < region + last - 1; p++)
58     {
59       process_mem_region *q = p + 1;
60       if (q == p + 1)
61         continue;
62       if (p->base + size > q->base)
63         {
64           fprintf (stderr, "region error @ (%8p + %d) > %8p\n", p->base, size, q->base);
65           return 0;
66         }
67     }
68   return 1;
69 }
70
71 static void
72 select_data_section (bfd * abfd, asection * sect, PTR obj)
73 {
74   exclusion *excl_list = (exclusion *) obj;
75
76   if ((sect->flags & (SEC_CODE | SEC_DEBUGGING)) &&
77       sect->vma && bfd_get_section_size (sect))
78     {
79       excl_list->add ((LPBYTE) sect->vma, (DWORD) bfd_get_section_size (sect));
80       deb_printf ("excluding section: %20s %08lx\n", sect->name,
81                   bfd_get_section_size (sect));
82     }
83 }
84
85 int
86 parse_pe (const char *file_name, exclusion * excl_list)
87 {
88   if (file_name == NULL || excl_list == NULL)
89     return 0;
90
91   bfd *abfd = bfd_openr (file_name, "pei-i386");
92   if (abfd == NULL)
93     {
94       bfd_perror ("failed to open file");
95       return 0;
96     }
97
98   bfd_check_format (abfd, bfd_object);
99   bfd_map_over_sections (abfd, &select_data_section, (PTR) excl_list);
100   excl_list->sort_and_check ();
101
102   bfd_close (abfd);
103   return 1;
104 }