summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2023-05-10 10:29:52 +0100
committerNick Clifton <nickc@redhat.com>2023-05-10 10:29:52 +0100
commit496917ce466c703c1ae3bf1cbbe753de1c091445 (patch)
tree0c4992f98acf35f1965238bb7163a7d8cab0ee78 /ld
parent2093c2af3c58da1fe63807dfea07d56afc6e7a8a (diff)
downloadbinutils-gdb-496917ce466c703c1ae3bf1cbbe753de1c091445.tar.gz
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog17
-rw-r--r--ld/NEWS3
-rw-r--r--ld/ld.h3
-rw-r--r--ld/ld.texi10
-rw-r--r--ld/ldlang.c88
-rw-r--r--ld/ldlex.h2
-rw-r--r--ld/lexsup.c14
-rw-r--r--ld/testsuite/ld-scripts/map-address.exp27
-rw-r--r--ld/testsuite/ld-scripts/map-locals.d5
-rw-r--r--ld/testsuite/ld-scripts/sizeof.s1
10 files changed, 168 insertions, 2 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 121bdfd735f..dac58cd575b 100644
--- a/ld/ChangeLog
+++ b/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
diff --git a/ld/NEWS b/ld/NEWS
index 37041e7456f..9920d0209b8 100644
--- a/ld/NEWS
+++ b/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.
diff --git a/ld/ld.h b/ld/ld.h
index 05649ff61b8..1882a282020 100644
--- a/ld/ld.h
+++ b/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;
diff --git a/ld/ld.texi b/ld/ld.texi
index 1ea6874cbb0..012eec2e809 100644
--- a/ld/ld.texi
+++ b/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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index aa01c81e661..a9c4a4d5bd7 100644
--- a/ld/ldlang.c
+++ b/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);
+ }
+ }
}
}
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 48d323d0265..be942ec4327 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -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,
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 7dc2228a833..6090921bda4 100644
--- a/ld/lexsup.c
+++ b/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;
diff --git a/ld/testsuite/ld-scripts/map-address.exp b/ld/testsuite/ld-scripts/map-address.exp
index 0eeca10fdd8..fbea9064265 100644
--- a/ld/testsuite/ld-scripts/map-address.exp
+++ b/ld/testsuite/ld-scripts/map-address.exp
@@ -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
+ }
+}
diff --git a/ld/testsuite/ld-scripts/map-locals.d b/ld/testsuite/ld-scripts/map-locals.d
new file mode 100644
index 00000000000..f3137f13814
--- /dev/null
+++ b/ld/testsuite/ld-scripts/map-locals.d
@@ -0,0 +1,5 @@
+#...
+Linker script and memory map
+#...
+.*\(local\)[ ]+local_sym
+#pass
diff --git a/ld/testsuite/ld-scripts/sizeof.s b/ld/testsuite/ld-scripts/sizeof.s
index e221ca3c0b3..7cd1677bc85 100644
--- a/ld/testsuite/ld-scripts/sizeof.s
+++ b/ld/testsuite/ld-scripts/sizeof.s
@@ -1 +1,2 @@
+local_sym:
.space 16