+ free (data);
+
+ if (rel_ppstart != NULL)
+ free (rel_ppstart);
+}
+
+/* Disassemble the contents of an object file. */
+
+static void
+disassemble_data (bfd *abfd)
+{
+ struct disassemble_info disasm_info;
+ struct objdump_disasm_info aux;
+ long i;
+
+ print_files = NULL;
+ prev_functionname = NULL;
+ prev_line = -1;
+
+ /* We make a copy of syms to sort. We don't want to sort syms
+ because that will screw up the relocs. */
+ sorted_symcount = symcount ? symcount : dynsymcount;
+ sorted_syms = xmalloc ((sorted_symcount + synthcount) * sizeof (asymbol *));
+ memcpy (sorted_syms, symcount ? syms : dynsyms,
+ sorted_symcount * sizeof (asymbol *));
+
+ sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
+
+ for (i = 0; i < synthcount; ++i)
+ {
+ sorted_syms[sorted_symcount] = synthsyms + i;
+ ++sorted_symcount;
+ }
+
+ /* Sort the symbols into section and symbol order. */
+ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+
+ init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
+
+ disasm_info.application_data = (void *) &aux;
+ aux.abfd = abfd;
+ aux.require_sec = FALSE;
+ aux.dynrelbuf = NULL;
+ aux.dynrelcount = 0;
+ aux.reloc = NULL;
+
+ disasm_info.print_address_func = objdump_print_address;
+ disasm_info.symbol_at_address_func = objdump_symbol_at_address;
+
+ if (machine != NULL)
+ {
+ const bfd_arch_info_type *info = bfd_scan_arch (machine);
+
+ if (info == NULL)
+ fatal (_("Can't use supplied machine %s"), machine);
+
+ abfd->arch_info = info;
+ }
+
+ if (endian != BFD_ENDIAN_UNKNOWN)
+ {
+ struct bfd_target *xvec;
+
+ xvec = xmalloc (sizeof (struct bfd_target));
+ memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
+ xvec->byteorder = endian;
+ abfd->xvec = xvec;
+ }
+
+ /* Use libopcodes to locate a suitable disassembler. */
+ aux.disassemble_fn = disassembler (abfd);
+ if (!aux.disassemble_fn)
+ {
+ non_fatal (_("Can't disassemble for architecture %s\n"),
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
+ exit_status = 1;
+ return;
+ }
+
+ disasm_info.flavour = bfd_get_flavour (abfd);
+ disasm_info.arch = bfd_get_arch (abfd);
+ disasm_info.mach = bfd_get_mach (abfd);
+ disasm_info.disassembler_options = disassembler_options;
+ disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
+ disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
+ disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
+ disasm_info.disassembler_needs_relocs = FALSE;
+
+ if (bfd_big_endian (abfd))
+ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
+ else if (bfd_little_endian (abfd))
+ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
+ else
+ /* ??? Aborting here seems too drastic. We could default to big or little
+ instead. */
+ disasm_info.endian = BFD_ENDIAN_UNKNOWN;
+
+ /* Allow the target to customize the info structure. */
+ disassemble_init_for_target (& disasm_info);
+
+ /* Pre-load the dynamic relocs if we are going
+ to be dumping them along with the disassembly. */
+ if (dump_dynamic_reloc_info)
+ {
+ long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
+
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (relsize > 0)
+ {
+ aux.dynrelbuf = xmalloc (relsize);
+ aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
+ aux.dynrelbuf,
+ dynsyms);
+ if (aux.dynrelcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));