newlib/winsup/utils/parse_pe.cc
Jon Turney ba2f251d43
Cygwin: Update dumper for bfd API changes
Update dumper for bfd API changes in binutils 2.34

libbfd doesn't guarantee API stability, so we've just been lucky this
hasn't broken more often.

See binutils commit fd361982.
2020-02-27 17:37:49 +00:00

108 lines
2.8 KiB
C++

/* parse_pe.cc
Written by Egor Duda <deo@logos-m.ru>
This file is part of Cygwin.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (file COPYING.dumper) for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#define PACKAGE
#include <bfd.h>
#include <stdio.h>
#include <stdlib.h>
#include "dumper.h"
#ifndef bfd_get_section_size
#define bfd_get_section_size(sect) bfd_section_size(sect)
#endif
int
exclusion::add (LPBYTE mem_base, SIZE_T 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 @ (%p + %zd) > %p\n", 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 && 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));
}
}
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;
}