/* Write resource file */ void write_res_file (const char *fn,const rc_res_directory *resdir) { asection *sec; rc_uint_type language; bfd *abfd; windres_bfd wrbfd; unsigned long sec_length = 0,sec_length_wrote; static const bfd_byte sign[] = {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; filename = fn; abfd = windres_open_as_binary (filename, 0); sec = bfd_make_section (abfd, ".data"); if (sec == NULL) bfd_fatal ("bfd_make_section"); if (! bfd_set_section_flags (abfd, sec, (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA))) bfd_fatal ("bfd_set_section_flags"); /* Requiring this is probably a bug in BFD. */ sec->output_section = sec; set_windres_bfd (&wrbfd, abfd, sec, (target_is_bigendian ? WR_KIND_BFD_BIN_B : WR_KIND_BFD_BIN_L)); language = -1; sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir, (const rc_res_id *) NULL, (const rc_res_id *) NULL, &language, 1); if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3)) bfd_fatal ("bfd_set_section_size"); if ((sec_length & 3) != 0) set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3)); set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign)); language = -1; sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir, (const rc_res_id *) NULL, (const rc_res_id *) NULL, &language, 1); if (sec_length != sec_length_wrote) fatal ("res write failed with different sizes (%lu/%lu).", (long) sec_length, (long) sec_length_wrote); bfd_close (abfd); return; }
static void do_sections_p1 (struct coff_ofile *head) { asection *section; int idx; struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1, sizeof (struct coff_section))); head->nsections = abfd->section_count + 1; head->sections = all; for (idx = 0, section = abfd->sections; section; section = section->next, idx++) { long relsize; int i = section->target_index; arelent **relpp; long relcount; relsize = bfd_get_reloc_upper_bound (abfd, section); if (relsize < 0) bfd_fatal (bfd_get_filename (abfd)); if (relsize == 0) continue; relpp = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); if (relcount < 0) bfd_fatal (bfd_get_filename (abfd)); head->sections[i].name = (char *) (section->name); head->sections[i].code = section->flags & SEC_CODE; head->sections[i].data = section->flags & SEC_DATA; if (strcmp (section->name, ".bss") == 0) head->sections[i].data = 1; head->sections[i].address = section->lma; head->sections[i].size = bfd_get_section_size (section); head->sections[i].number = idx; head->sections[i].nrelocs = section->reloc_count; head->sections[i].relocs = (struct coff_reloc *) (xcalloc (section->reloc_count, sizeof (struct coff_reloc))); head->sections[i].bfd_section = section; } head->sections[0].name = "ABSOLUTE"; head->sections[0].code = 0; head->sections[0].data = 0; head->sections[0].address = 0; head->sections[0].size = 0; head->sections[0].number = 0; }
/* Read resource file */ rc_res_directory * read_res_file (const char *fn) { rc_uint_type off, flen; windres_bfd wrbfd; bfd *abfd; asection *sec; filename = fn; flen = (rc_uint_type) get_file_size (filename); if (! flen) fatal ("can't open '%s' for input.", filename); abfd = windres_open_as_binary (filename, 1); sec = bfd_get_section_by_name (abfd, ".data"); if (sec == NULL) bfd_fatal ("bfd_get_section_by_name"); set_windres_bfd (&wrbfd, abfd, sec, (target_is_bigendian ? WR_KIND_BFD_BIN_B : WR_KIND_BFD_BIN_L)); off = 0; if (! probe_binary (&wrbfd, flen)) set_windres_bfd_endianess (&wrbfd, ! target_is_bigendian); skip_null_resource (&wrbfd, &off, flen); while (read_resource_entry (&wrbfd, &off, flen)) ; bfd_close (abfd); return resources; }
bfd_boolean ar_emul_default_create (bfd **abfd_out, char *archive_file_name, char *file_name) { char *target = NULL; /* Try to figure out the target to use for the archive from the first object on the list. */ if (file_name != NULL) { bfd *obj; obj = bfd_openr (file_name, NULL); if (obj != NULL) { if (bfd_check_format (obj, bfd_object)) target = bfd_get_target (obj); (void) bfd_close (obj); } } /* Create an empty archive. */ *abfd_out = bfd_openw (archive_file_name, target); if (*abfd_out == NULL || ! bfd_set_format (*abfd_out, bfd_archive) || ! bfd_close (*abfd_out)) bfd_fatal (archive_file_name); return TRUE; }
static void slurp_symtab(bfd * abfd) { long symcount; unsigned int size; if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) return; symcount = bfd_read_minisymbols(abfd, false, (PTR) & syms, &size); if (symcount == 0) symcount = bfd_read_minisymbols(abfd, true /* dynamic */, (PTR) & syms, &size); if (symcount < 0) bfd_fatal(bfd_get_filename(abfd)); }
int main(int ac, char **av) { bfd *abfd; struct coff_ofile *tree; char **matching; char *input_file = NULL; int opt; static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { NULL, no_argument, 0, 0 } }; #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) setlocale(LC_MESSAGES, ""); #endif /* HAVE_SETLOCALE && HAVE_LC_MESSAGES */ #if defined(HAVE_SETLOCALE) setlocale(LC_CTYPE, ""); #endif /* HAVE_SETLOCALE */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); program_name = av[0]; xmalloc_set_program_name (program_name); while ((opt = getopt_long(ac, av, "HhVv", long_options, (int *)NULL)) != EOF) { switch (opt) { case 'H': case 'h': show_usage(stdout, 0); break; case 'v': case 'V': print_version("coffdump"); xexit(0); case 0: break; default: show_usage(stderr, 1); break; } } if (optind < ac) { input_file = av[optind]; } if (!input_file) fatal(_("no input file specified")); abfd = bfd_openr(input_file, 0); if (!abfd) bfd_fatal(input_file); if (! bfd_check_format_matches(abfd, bfd_object, &matching)) { bfd_nonfatal(input_file); if (bfd_get_error() == bfd_error_file_ambiguously_recognized) { list_matching_formats(matching); free(matching); } xexit(1); } tree = coff_grok(abfd); coff_dump(tree); printf("\n"); return 0; }