+ else
+ {
+ FILE *f;
+
+ f = fopen (filename, "r");
+ if (f != NULL)
+ {
+ int l;
+
+ p = ((struct print_file_list *)
+ xmalloc (sizeof (struct print_file_list)));
+ p->filename = xmalloc (strlen (filename) + 1);
+ strcpy (p->filename, filename);
+ p->line = 0;
+ p->f = f;
+
+ if (print_files != NULL && print_files->f != NULL)
+ {
+ fclose (print_files->f);
+ print_files->f = NULL;
+ }
+ p->next = print_files;
+ print_files = p;
+
+ if (file_start_context)
+ l = 0;
+ else
+ l = line - SHOW_PRECEDING_CONTEXT_LINES;
+ if (l < 0)
+ l = 0;
+ skip_to_line (p, l, false);
+ if (p->f != NULL)
+ skip_to_line (p, line, true);
+ }
+ }
+ }
+
+ if (functionname != NULL
+ && (prev_functionname == NULL
+ || strcmp (functionname, prev_functionname) != 0))
+ {
+ if (prev_functionname != NULL)
+ free (prev_functionname);
+ prev_functionname = xmalloc (strlen (functionname) + 1);
+ strcpy (prev_functionname, functionname);
+ }
+
+ if (line > 0 && line != prev_line)
+ prev_line = line;
+}
+
+/* Pseudo FILE object for strings. */
+typedef struct
+{
+ char *buffer;
+ size_t size;
+ char *current;
+} SFILE;
+
+/* sprintf to a "stream" */
+
+static int
+#ifdef ANSI_PROTOTYPES
+objdump_sprintf (SFILE *f, const char *format, ...)
+#else
+objdump_sprintf (va_alist)
+ va_dcl
+#endif
+{
+#ifndef ANSI_PROTOTYPES
+ SFILE *f;
+ const char *format;
+#endif
+ char *buf;
+ va_list args;
+ size_t n;
+
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
+ va_start (args);
+ f = va_arg (args, SFILE *);
+ format = va_arg (args, const char *);
+#endif
+
+ vasprintf (&buf, format, args);
+
+ va_end (args);
+
+ if (buf == NULL)
+ {
+ fatal (_("Out of virtual memory"));
+ }
+
+ n = strlen (buf);
+
+ while ((size_t) ((f->buffer + f->size) - f->current) < n + 1)
+ {
+ size_t curroff;
+
+ curroff = f->current - f->buffer;
+ f->size *= 2;
+ f->buffer = xrealloc (f->buffer, f->size);
+ f->current = f->buffer + curroff;
+ }
+
+ memcpy (f->current, buf, n);
+ f->current += n;
+ f->current[0] = '\0';
+
+ free (buf);
+
+ return n;
+}
+
+/* The number of zeroes we want to see before we start skipping them.
+ The number is arbitrarily chosen. */
+
+#define SKIP_ZEROES (8)
+
+/* The number of zeroes to skip at the end of a section. If the
+ number of zeroes at the end is between SKIP_ZEROES_AT_END and
+ SKIP_ZEROES, they will be disassembled. If there are fewer than
+ SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
+ attempt to avoid disassembling zeroes inserted by section
+ alignment. */
+
+#define SKIP_ZEROES_AT_END (3)
+
+/* Disassemble some data in memory between given values. */
+
+static void
+disassemble_bytes (info, disassemble_fn, insns, data,
+ start_offset, stop_offset, relppp,
+ relppend)
+ struct disassemble_info *info;
+ disassembler_ftype disassemble_fn;
+ boolean insns;
+ bfd_byte *data;
+ bfd_vma start_offset;
+ bfd_vma stop_offset;
+ arelent ***relppp;
+ arelent **relppend;
+{
+ struct objdump_disasm_info *aux;
+ asection *section;
+ int octets_per_line;
+ boolean done_dot;
+ int skip_addr_chars;
+ bfd_vma addr_offset;
+ int opb = info->octets_per_byte;
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ section = aux->sec;
+
+ if (insns)
+ octets_per_line = 4;
+ else
+ octets_per_line = 16;
+
+ /* Figure out how many characters to skip at the start of an
+ address, to make the disassembly look nicer. We discard leading
+ zeroes in chunks of 4, ensuring that there is always a leading
+ zero remaining. */
+ skip_addr_chars = 0;
+ if (! prefix_addresses)
+ {
+ char buf[30];
+ char *s;
+
+ sprintf_vma (buf, section->vma +
+ bfd_section_size (section->owner, section) / opb);
+ s = buf;
+ while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
+ && s[4] == '0')
+ {
+ skip_addr_chars += 4;
+ s += 4;
+ }
+ }
+
+ info->insn_info_valid = 0;
+
+ done_dot = false;
+ addr_offset = start_offset;
+ while (addr_offset < stop_offset)
+ {
+ bfd_vma z;
+ int octets = 0;
+ boolean need_nl = false;
+
+ /* If we see more than SKIP_ZEROES octets of zeroes, we just
+ print `...'. */
+ for (z = addr_offset * opb; z < stop_offset * opb; z++)
+ if (data[z] != 0)
+ break;
+ if (! disassemble_zeroes
+ && (info->insn_info_valid == 0
+ || info->branch_delay_insns == 0)
+ && (z - addr_offset * opb >= SKIP_ZEROES
+ || (z == stop_offset * opb &&
+ z - addr_offset * opb < SKIP_ZEROES_AT_END)))
+ {
+ printf ("\t...\n");
+
+ /* If there are more nonzero octets to follow, we only skip
+ zeroes in multiples of 4, to try to avoid running over
+ the start of an instruction which happens to start with
+ zero. */
+ if (z != stop_offset * opb)
+ z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
+
+ octets = z - addr_offset * opb;
+ }
+ else
+ {
+ char buf[50];
+ SFILE sfile;
+ int bpc = 0;
+ int pb = 0;
+
+ done_dot = false;
+
+ if (with_line_numbers || with_source_code)
+ show_line (aux->abfd, section, addr_offset);
+
+ if (! prefix_addresses)
+ {
+ char *s;
+
+ sprintf_vma (buf, section->vma + addr_offset);
+ for (s = buf + skip_addr_chars; *s == '0'; s++)
+ *s = ' ';
+ if (*s == '\0')
+ *--s = '0';
+ printf ("%s:\t", buf + skip_addr_chars);
+ }
+ else
+ {
+ aux->require_sec = true;
+ objdump_print_address (section->vma + addr_offset, info);
+ aux->require_sec = false;
+ putchar (' ');
+ }
+
+ if (insns)
+ {
+ sfile.size = 120;
+ sfile.buffer = xmalloc (sfile.size);
+ sfile.current = sfile.buffer;
+ info->fprintf_func = (fprintf_ftype) objdump_sprintf;
+ info->stream = (FILE *) &sfile;
+ info->bytes_per_line = 0;
+ info->bytes_per_chunk = 0;
+
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+ /* FIXME: This is wrong. It tests the number of octets
+ in the last instruction, not the current one. */
+ if (*relppp < relppend
+ && (**relppp)->address >= addr_offset
+ && (**relppp)->address <= addr_offset + octets / opb)
+ info->flags = INSN_HAS_RELOC;
+ else
+#endif
+ info->flags = 0;
+
+ octets = (*disassemble_fn) (section->vma + addr_offset, info);
+ info->fprintf_func = (fprintf_ftype) fprintf;
+ info->stream = stdout;
+ if (info->bytes_per_line != 0)
+ octets_per_line = info->bytes_per_line;
+ if (octets < 0)
+ {
+ if (sfile.current != sfile.buffer)
+ printf ("%s\n", sfile.buffer);
+ free (sfile.buffer);
+ break;
+ }
+ }
+ else
+ {
+ bfd_vma j;
+
+ octets = octets_per_line;
+ if (addr_offset + octets / opb > stop_offset)
+ octets = (stop_offset - addr_offset) * opb;
+
+ for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
+ {
+ if (isprint (data[j]))
+ buf[j - addr_offset * opb] = data[j];
+ else
+ buf[j - addr_offset * opb] = '.';
+ }
+ buf[j - addr_offset * opb] = '\0';
+ }
+
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
+ {
+ bfd_vma j;
+
+ /* If ! prefix_addresses and ! wide_output, we print
+ octets_per_line octets per line. */
+ pb = octets;
+ if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
+ pb = octets_per_line;
+
+ if (info->bytes_per_chunk)
+ bpc = info->bytes_per_chunk;
+ else
+ bpc = 1;
+
+ for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
+ {
+ int k;
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ }
+
+ for (; pb < octets_per_line; pb += bpc)
+ {
+ int k;
+
+ for (k = 0; k < bpc; k++)
+ printf (" ");
+ putchar (' ');
+ }
+
+ /* Separate raw data from instruction by extra space. */
+ if (insns)
+ putchar ('\t');
+ else
+ printf (" ");
+ }
+
+ if (! insns)
+ printf ("%s", buf);
+ else
+ {
+ printf ("%s", sfile.buffer);
+ free (sfile.buffer);
+ }
+
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
+ {
+ while (pb < octets)
+ {
+ bfd_vma j;
+ char *s;
+
+ putchar ('\n');
+ j = addr_offset * opb + pb;
+
+ sprintf_vma (buf, section->vma + j / opb);
+ for (s = buf + skip_addr_chars; *s == '0'; s++)
+ *s = ' ';
+ if (*s == '\0')
+ *--s = '0';
+ printf ("%s:\t", buf + skip_addr_chars);
+
+ pb += octets_per_line;
+ if (pb > octets)
+ pb = octets;
+ for (; j < addr_offset * opb + pb; j += bpc)
+ {
+ int k;
+
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ }
+ }
+ }
+
+ if (!wide_output)
+ putchar ('\n');
+ else
+ need_nl = true;
+ }