+
+ if (sorted_syms[thisplace]->section != sec
+ && (require_sec
+ || ((abfd->flags & HAS_RELOC) != 0
+ && vma >= bfd_get_section_vma (abfd, sec)
+ && vma < (bfd_get_section_vma (abfd, sec)
+ + bfd_section_size (abfd, sec)))))
+ {
+ /* There is no suitable symbol. */
+ return NULL;
+ }
+ }
+
+ if (place != NULL)
+ *place = thisplace;
+
+ return sorted_syms[thisplace];
+}
+
+/* Print an address to INFO symbolically. */
+
+static void
+objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
+ bfd *abfd;
+ asection *sec;
+ asymbol *sym;
+ bfd_vma vma;
+ struct disassemble_info *info;
+ boolean skip_zeroes;
+{
+ objdump_print_value (vma, info, skip_zeroes);
+
+ if (sym == NULL)
+ {
+ bfd_vma secaddr;
+
+ (*info->fprintf_func) (info->stream, " <%s",
+ bfd_get_section_name (abfd, sec));
+ secaddr = bfd_get_section_vma (abfd, sec);
+ if (vma < secaddr)
+ {
+ (*info->fprintf_func) (info->stream, "-0x");
+ objdump_print_value (secaddr - vma, info, true);
+ }
+ else if (vma > secaddr)
+ {
+ (*info->fprintf_func) (info->stream, "+0x");
+ objdump_print_value (vma - secaddr, info, true);
+ }
+ (*info->fprintf_func) (info->stream, ">");
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, " <");
+ objdump_print_symname (abfd, info, sym);
+ if (bfd_asymbol_value (sym) > vma)
+ {
+ (*info->fprintf_func) (info->stream, "-0x");
+ objdump_print_value (bfd_asymbol_value (sym) - vma, info, true);
+ }
+ else if (vma > bfd_asymbol_value (sym))
+ {
+ (*info->fprintf_func) (info->stream, "+0x");
+ objdump_print_value (vma - bfd_asymbol_value (sym), info, true);
+ }
+ (*info->fprintf_func) (info->stream, ">");
+
+ /* Notify the disassembler of the symbol being used: */
+ disasm_symaddr (sym, info);
+ }
+}
+
+/* Print VMA to INFO, symbolically if possible. If SKIP_ZEROES is
+ true, don't output leading zeroes. */
+
+static void
+objdump_print_addr (vma, info, skip_zeroes)
+ bfd_vma vma;
+ struct disassemble_info *info;
+ boolean skip_zeroes;
+{
+ struct objdump_disasm_info *aux;
+ asymbol *sym;
+
+ if (sorted_symcount < 1)
+ {
+ (*info->fprintf_func) (info->stream, "0x");
+ objdump_print_value (vma, info, skip_zeroes);
+ return;
+ }
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
+ (long *) NULL);
+ objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
+ skip_zeroes);
+}
+
+/* Print VMA to INFO. This function is passed to the disassembler
+ routine. */
+
+static void
+objdump_print_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info *info;
+{
+ objdump_print_addr (vma, info, ! prefix_addresses);
+}
+
+/* Determine of the given address has a symbol associated with it. */
+
+static int
+objdump_symbol_at_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info * info;
+{
+ struct objdump_disasm_info * aux;
+ asymbol * sym;
+
+ /* No symbols - do not bother checking. */
+ if (sorted_symcount < 1)
+ return 0;
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
+ (long *) NULL);
+
+ return (sym != NULL && (bfd_asymbol_value (sym) == vma));
+}
+
+/* Hold the last function name and the last line number we displayed
+ in a disassembly. */
+
+static char *prev_functionname;
+static unsigned int prev_line;
+
+/* We keep a list of all files that we have seen when doing a
+ dissassembly with source, so that we know how much of the file to
+ display. This can be important for inlined functions. */
+
+struct print_file_list
+{
+ struct print_file_list *next;
+ char *filename;
+ unsigned int line;
+ FILE *f;
+};
+
+static struct print_file_list *print_files;
+
+/* The number of preceding context lines to show when we start
+ displaying a file for the first time. */
+
+#define SHOW_PRECEDING_CONTEXT_LINES (5)
+
+/* Skip ahead to a given line in a file, optionally printing each
+ line. */
+
+static void
+skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
+
+static void
+skip_to_line (p, line, show)
+ struct print_file_list *p;
+ unsigned int line;
+ boolean show;
+{
+ while (p->line < line)
+ {
+ char buf[100];
+
+ if (fgets (buf, sizeof buf, p->f) == NULL)
+ {
+ fclose (p->f);
+ p->f = NULL;
+ break;
+ }
+
+ if (show)
+ printf ("%s", buf);
+
+ if (strchr (buf, '\n') != NULL)
+ ++p->line;
+ }
+}
+
+/* Show the line number, or the source line, in a dissassembly
+ listing. */
+
+static void
+show_line (abfd, section, off)
+ bfd *abfd;
+ asection *section;
+ bfd_vma off;
+{
+ CONST char *filename;
+ CONST char *functionname;
+ unsigned int line;
+
+ if (! with_line_numbers && ! with_source_code)
+ return;
+
+ if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
+ &functionname, &line))
+ return;
+
+ if (filename != NULL && *filename == '\0')
+ filename = NULL;
+ if (functionname != NULL && *functionname == '\0')
+ functionname = NULL;
+
+ if (with_line_numbers)
+ {
+ if (functionname != NULL
+ && (prev_functionname == NULL
+ || strcmp (functionname, prev_functionname) != 0))
+ printf ("%s():\n", functionname);
+ if (line > 0 && line != prev_line)
+ printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
+ }
+
+ if (with_source_code
+ && filename != NULL
+ && line > 0)
+ {
+ struct print_file_list **pp, *p;
+
+ for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
+ if (strcmp ((*pp)->filename, filename) == 0)
+ break;
+ p = *pp;
+
+ if (p != NULL)
+ {
+ if (p != print_files)