Add linker option to include local symbols in the linker map.
PR 16566 * ldlang.c (ld_is_local_symbol): New function. (print_input_section): Add code to display local symbols in the section. * ldlex.h (enum option_values): Add OPTION_PRINT_MAP_LOCALS and OPTION_PRINT_MAP_LOCALS. * lexsup.c (ld_options[]): Add entries for --print-map-locals and --no-print-map-locals. * NEWS: Mention the new feature. * ld.h (struct ld_config_type): Add print_map_locals field. * ld.texi: Document the new command line option. * testsuite/ld-scripts/sizeof.s: Add a local symbol. * testsuite/ld-scripts/map-locals.d: New test control file. * testsuite/ld-scripts/map-address.exp: Run the new test.
This commit is contained in:
parent
2093c2af3c
commit
496917ce46
17
ld/ChangeLog
17
ld/ChangeLog
@ -1,3 +1,20 @@
|
||||
2023-05-10 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 16566
|
||||
* ldlang.c (ld_is_local_symbol): New function.
|
||||
(print_input_section): Add code to display local symbols in the
|
||||
section.
|
||||
* ldlex.h (enum option_values): Add OPTION_PRINT_MAP_LOCALS and
|
||||
OPTION_PRINT_MAP_LOCALS.
|
||||
* lexsup.c (ld_options[]): Add entries for --print-map-locals
|
||||
and --no-print-map-locals.
|
||||
* NEWS: Mention the new feature.
|
||||
* ld.h (struct ld_config_type): Add print_map_locals field.
|
||||
* ld.texi: Document the new command line option.
|
||||
* testsuite/ld-scripts/sizeof.s: Add a local symbol.
|
||||
* testsuite/ld-scripts/map-locals.d: New test control file.
|
||||
* testsuite/ld-scripts/map-address.exp: Run the new test.
|
||||
|
||||
2023-05-04 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 30300
|
||||
|
3
ld/NEWS
3
ld/NEWS
@ -1,5 +1,8 @@
|
||||
-*- text -*-
|
||||
|
||||
* The linker command line option --print-map-locals can be used to include
|
||||
local symbols in a linker map. (ELF targets only).
|
||||
|
||||
* For most ELF based targets, if the --enable-linker-version option is used
|
||||
then the version of the linker will be inserted as a string into the .comment
|
||||
section.
|
||||
|
3
ld/ld.h
3
ld/ld.h
@ -297,6 +297,9 @@ typedef struct
|
||||
/* If set, print discarded sections in map file output. */
|
||||
bool print_map_discarded;
|
||||
|
||||
/* If set, print local symbols in map file output. */
|
||||
bool print_map_locals;
|
||||
|
||||
/* If set, emit the names and types of statically-linked variables
|
||||
into the CTF. */
|
||||
bool ctf_variables;
|
||||
|
10
ld/ld.texi
10
ld/ld.texi
@ -870,6 +870,16 @@ is 0x1, and @file{bar.o}, whose 0xc0010001 property value is 0x1.
|
||||
Print (or do not print) the list of discarded and garbage collected sections
|
||||
in the link map. Enabled by default.
|
||||
|
||||
@kindex --print-map-locals
|
||||
@kindex --no-print-map-locals
|
||||
@item --print-map-locals
|
||||
@itemx --no-print-map-locals
|
||||
Print (or do not print) local symbols in the link map. Local symbols
|
||||
will have the text @samp{(local)} printed before their name, and will
|
||||
be listed after all of the global symbols in a given section.
|
||||
Temporary local symbols (typically those that start with @samp{.L})
|
||||
will not be included in the output. Disabled by default.
|
||||
|
||||
@kindex -n
|
||||
@cindex read-only text
|
||||
@cindex NMAGIC
|
||||
|
88
ld/ldlang.c
88
ld/ldlang.c
@ -2296,13 +2296,15 @@ lang_map (void)
|
||||
{
|
||||
if (! dis_header_printed)
|
||||
{
|
||||
fprintf (config.map_file, _("\nDiscarded input sections\n\n"));
|
||||
minfo (_("\nDiscarded input sections\n\n"));
|
||||
dis_header_printed = true;
|
||||
}
|
||||
|
||||
print_input_section (s, true);
|
||||
}
|
||||
}
|
||||
if (config.print_map_discarded && ! dis_header_printed)
|
||||
minfo (_("\nThere are no discarded input sections\n"));
|
||||
|
||||
minfo (_("\nMemory Configuration\n\n"));
|
||||
fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
|
||||
@ -2330,7 +2332,7 @@ lang_map (void)
|
||||
print_nl ();
|
||||
}
|
||||
|
||||
fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
|
||||
minfo (_("\nLinker script and memory map\n\n"));
|
||||
|
||||
if (!link_info.reduce_memory_overheads)
|
||||
{
|
||||
@ -4797,6 +4799,50 @@ print_all_symbols (asection *sec)
|
||||
obstack_free (&map_obstack, entries);
|
||||
}
|
||||
|
||||
/* Returns TRUE if SYM is a symbol suitable for printing
|
||||
in a linker map as a local symbol. */
|
||||
|
||||
static bool
|
||||
ld_is_local_symbol (asymbol * sym)
|
||||
{
|
||||
const char * name = bfd_asymbol_name (sym);
|
||||
|
||||
if (name == NULL || *name == 0)
|
||||
return false;
|
||||
|
||||
if (strcmp (name, "(null)") == 0)
|
||||
return false;
|
||||
|
||||
/* Skip .Lxxx and such like. */
|
||||
if (bfd_is_local_label (link_info.output_bfd, sym))
|
||||
return false;
|
||||
|
||||
/* FIXME: This is intended to skip ARM mapping symbols,
|
||||
which for some reason are not excluded by bfd_is_local_label,
|
||||
but maybe it is wrong for other architectures.
|
||||
It would be better to fix bfd_is_local_label. */
|
||||
if (*name == '$')
|
||||
return false;
|
||||
|
||||
/* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
|
||||
in the hash table, so do not print duplicates here. */
|
||||
struct bfd_link_hash_entry * h;
|
||||
h = bfd_link_hash_lookup (link_info.hash, name, false /* create */,
|
||||
false /* copy */, true /* follow */);
|
||||
if (h == NULL)
|
||||
return true;
|
||||
|
||||
/* Symbols from the plugin owned BFD will not get their own
|
||||
iteration of this function, but can be on the link_info
|
||||
list. So include them here. */
|
||||
if (h->u.def.section->owner != NULL
|
||||
&& ((bfd_get_file_flags (h->u.def.section->owner) & (BFD_LINKER_CREATED | BFD_PLUGIN))
|
||||
== (BFD_LINKER_CREATED | BFD_PLUGIN)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Print information about an input section to the map file. */
|
||||
|
||||
static void
|
||||
@ -4852,6 +4898,44 @@ print_input_section (asection *i, bool is_discarded)
|
||||
later overlay is shorter than an earier one. */
|
||||
if (addr + TO_ADDR (size) > print_dot)
|
||||
print_dot = addr + TO_ADDR (size);
|
||||
|
||||
if (config.print_map_locals)
|
||||
{
|
||||
long storage_needed;
|
||||
|
||||
/* FIXME: It would be better to cache this table, rather
|
||||
than recreating it for each output section. */
|
||||
/* FIXME: This call is not working for non-ELF based targets.
|
||||
Find out why. */
|
||||
storage_needed = bfd_get_symtab_upper_bound (link_info.output_bfd);
|
||||
if (storage_needed > 0)
|
||||
{
|
||||
asymbol ** symbol_table;
|
||||
long number_of_symbols;
|
||||
long j;
|
||||
|
||||
symbol_table = xmalloc (storage_needed);
|
||||
number_of_symbols = bfd_canonicalize_symtab (link_info.output_bfd, symbol_table);
|
||||
|
||||
for (j = 0; j < number_of_symbols; j++)
|
||||
{
|
||||
asymbol * sym = symbol_table[j];
|
||||
bfd_vma sym_addr = sym->value + i->output_section->vma;
|
||||
|
||||
if (sym->section == i->output_section
|
||||
&& (sym->flags & BSF_LOCAL) != 0
|
||||
&& sym_addr >= addr
|
||||
&& sym_addr < print_dot
|
||||
&& ld_is_local_symbol (sym))
|
||||
{
|
||||
print_spaces (SECTION_NAME_MAP_LENGTH);
|
||||
minfo ("0x%V (local) %s\n", sym_addr, bfd_asymbol_name (sym));
|
||||
}
|
||||
}
|
||||
|
||||
free (symbol_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,8 @@ enum option_values
|
||||
OPTION_FORCE_GROUP_ALLOCATION,
|
||||
OPTION_PRINT_MAP_DISCARDED,
|
||||
OPTION_NO_PRINT_MAP_DISCARDED,
|
||||
OPTION_PRINT_MAP_LOCALS,
|
||||
OPTION_NO_PRINT_MAP_LOCALS,
|
||||
OPTION_NON_CONTIGUOUS_REGIONS,
|
||||
OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS,
|
||||
OPTION_DEPENDENCY_FILE,
|
||||
|
14
ld/lexsup.c
14
ld/lexsup.c
@ -605,6 +605,12 @@ static const struct ld_option ld_options[] =
|
||||
{ {"no-print-map-discarded", no_argument, NULL, OPTION_NO_PRINT_MAP_DISCARDED},
|
||||
'\0', NULL, N_("Do not show discarded sections in map file output"),
|
||||
TWO_DASHES },
|
||||
{ {"print-map-locals", no_argument, NULL, OPTION_PRINT_MAP_LOCALS},
|
||||
'\0', NULL, N_("Show local symbols in map file output"),
|
||||
TWO_DASHES },
|
||||
{ {"no-print-map-locals", no_argument, NULL, OPTION_NO_PRINT_MAP_LOCALS},
|
||||
'\0', NULL, N_("Do not show local symbols in map file output (default)"),
|
||||
TWO_DASHES },
|
||||
{ {"ctf-variables", no_argument, NULL, OPTION_CTF_VARIABLES},
|
||||
'\0', NULL, N_("Emit names and types of static variables in CTF"),
|
||||
TWO_DASHES },
|
||||
@ -1748,6 +1754,14 @@ parse_args (unsigned argc, char **argv)
|
||||
config.print_map_discarded = true;
|
||||
break;
|
||||
|
||||
case OPTION_NO_PRINT_MAP_LOCALS:
|
||||
config.print_map_locals = false;
|
||||
break;
|
||||
|
||||
case OPTION_PRINT_MAP_LOCALS:
|
||||
config.print_map_locals = true;
|
||||
break;
|
||||
|
||||
case OPTION_DEPENDENCY_FILE:
|
||||
config.dependency_file = optarg;
|
||||
break;
|
||||
|
@ -120,3 +120,30 @@ if {[regexp_diff \
|
||||
} else {
|
||||
pass $testname
|
||||
}
|
||||
|
||||
if { [is_elf_format] } {
|
||||
set testname "map with locals"
|
||||
|
||||
if {![ld_link $ld tmpdir/map-address \
|
||||
"$LDFLAGS -T $srcdir/$subdir/map-address.t \
|
||||
$IMAGE_BASE tmpdir/map-address.o \
|
||||
-Map=tmpdir/map-locals.map --print-map-locals"]} {
|
||||
fail $testname
|
||||
return
|
||||
}
|
||||
|
||||
if [is_remote host] then {
|
||||
remote_upload host "tmpdir/map-locals.map"
|
||||
}
|
||||
|
||||
# Some ELF targets do not preserve their local symbols.
|
||||
setup_xfail "d30v-*-*" "dlx-*-*" "pj-*-*" "s12z-*-*" "xgate-*-*"
|
||||
|
||||
if {[regexp_diff \
|
||||
"tmpdir/map-locals.map" \
|
||||
"$srcdir/$subdir/map-locals.d"]} {
|
||||
fail $testname
|
||||
} else {
|
||||
pass $testname
|
||||
}
|
||||
}
|
||||
|
5
ld/testsuite/ld-scripts/map-locals.d
Normal file
5
ld/testsuite/ld-scripts/map-locals.d
Normal file
@ -0,0 +1,5 @@
|
||||
#...
|
||||
Linker script and memory map
|
||||
#...
|
||||
.*\(local\)[ ]+local_sym
|
||||
#pass
|
@ -1 +1,2 @@
|
||||
local_sym:
|
||||
.space 16
|
||||
|
Loading…
x
Reference in New Issue
Block a user