+
+ do_cleanups (cleanup_chain);
+}
+
+/* Given an address ADDR return all the elements needed to print the
+ address in a symbolic form. NAME can be mangled or not depending
+ on DO_DEMANGLE (and also on the asm_demangle global variable,
+ manipulated via ''set print asm-demangle''). Return 0 in case of
+ success, when all the info in the OUT paramters is valid. Return 1
+ otherwise. */
+int
+build_address_symbolic (CORE_ADDR addr, /* IN */
+ int do_demangle, /* IN */
+ char **name, /* OUT */
+ int *offset, /* OUT */
+ char **filename, /* OUT */
+ int *line, /* OUT */
+ int *unmapped) /* OUT */
+{
+ struct minimal_symbol *msymbol;
+ struct symbol *symbol;
+ struct symtab *symtab = 0;
+ CORE_ADDR name_location = 0;
+ asection *section = 0;
+ char *name_temp = "";
+
+ /* Let's say it is unmapped. */
+ *unmapped = 0;
+
+ /* Determine if the address is in an overlay, and whether it is
+ mapped. */
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (addr);
+ if (pc_in_unmapped_range (addr, section))
+ {
+ *unmapped = 1;
+ addr = overlay_mapped_address (addr, section);
+ }
+ }
+
+ /* On some targets, add in extra "flag" bits to PC for
+ disassembly. This should ensure that "rounding errors" in
+ symbol addresses that are masked for disassembly favour the
+ the correct symbol. */
+
+#ifdef GDB_TARGET_UNMASK_DISAS_PC
+ addr = GDB_TARGET_UNMASK_DISAS_PC (addr);
+#endif
+
+ /* First try to find the address in the symbol table, then
+ in the minsyms. Take the closest one. */
+
+ /* This is defective in the sense that it only finds text symbols. So
+ really this is kind of pointless--we should make sure that the
+ minimal symbols have everything we need (by changing that we could
+ save some memory, but for many debug format--ELF/DWARF or
+ anything/stabs--it would be inconvenient to eliminate those minimal
+ symbols anyway). */
+ msymbol = lookup_minimal_symbol_by_pc_section (addr, section);
+ symbol = find_pc_sect_function (addr, section);
+
+ if (symbol)
+ {
+ name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
+ if (do_demangle)
+ name_temp = SYMBOL_SOURCE_NAME (symbol);
+ else
+ name_temp = SYMBOL_LINKAGE_NAME (symbol);
+ }
+
+ if (msymbol != NULL)
+ {
+ if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
+ {
+ /* The msymbol is closer to the address than the symbol;
+ use the msymbol instead. */
+ symbol = 0;
+ symtab = 0;
+ name_location = SYMBOL_VALUE_ADDRESS (msymbol);
+ if (do_demangle)
+ name_temp = SYMBOL_SOURCE_NAME (msymbol);
+ else
+ name_temp = SYMBOL_LINKAGE_NAME (msymbol);
+ }
+ }
+ if (symbol == NULL && msymbol == NULL)
+ return 1;
+
+ /* On some targets, mask out extra "flag" bits from PC for handsome
+ disassembly. */
+
+#ifdef GDB_TARGET_MASK_DISAS_PC
+ name_location = GDB_TARGET_MASK_DISAS_PC (name_location);
+ addr = GDB_TARGET_MASK_DISAS_PC (addr);
+#endif
+
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
+
+ /* For when CORE_ADDR is larger than unsigned int, we do math in
+ CORE_ADDR. But when we detect unsigned wraparound in the
+ CORE_ADDR math, we ignore this test and print the offset,
+ because addr+max_symbolic_offset has wrapped through the end
+ of the address space back to the beginning, giving bogus comparison. */
+ if (addr > name_location + max_symbolic_offset
+ && name_location + max_symbolic_offset > name_location)
+ return 1;
+
+ *offset = addr - name_location;
+
+ *name = xstrdup (name_temp);
+
+ if (print_symbol_filename)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_sect_line (addr, section, 0);
+
+ if (sal.symtab)
+ {
+ *filename = xstrdup (sal.symtab->filename);
+ *line = sal.line;
+ }
+ else if (symtab && symbol && symbol->line)
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = symbol->line;
+ }
+ else if (symtab)
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = -1;
+ }
+ }
+ return 0;
+}
+
+/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for
+ print_longest. */
+void
+print_address_numeric (CORE_ADDR addr, int use_local, struct ui_file *stream)
+{
+ /* Truncate address to the size of a target address, avoiding shifts
+ larger or equal than the width of a CORE_ADDR. The local
+ variable ADDR_BIT stops the compiler reporting a shift overflow
+ when it won't occur. */
+ /* NOTE: This assumes that the significant address information is
+ kept in the least significant bits of ADDR - the upper bits were
+ either zero or sign extended. Should ADDRESS_TO_POINTER() or
+ some ADDRESS_TO_PRINTABLE() be used to do the conversion? */
+
+ int addr_bit = TARGET_ADDR_BIT;
+
+ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+ addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
+ print_longest (stream, 'x', use_local, (ULONGEST) addr);