Link map file (-Map=) is one good way to get detailed information about complete ready-to-deploy binary product. Unfortunately, a map file doesn't include information about local (static in C-speak) symbols. Usage of static symbols is the best practice in contemporary C and other languages, and such situation means that a map file unfortunately is not suitable for many interesting analyses (like for example tracking detailed function sizes across application versions/optimization settings). So, please consider: 1. Adding a linker option to include local/static symbols in generated map file. 2. Alternatively, it may be argued that users whu are interested in map files are probably want to have information about all symbols anyway, so it can be just changed to include local/static symbols unconditionally, without growing number of command-line options. Thanks.
This would also be useful for when compiling with LTO, as currently gcc seems to convert globals to locals, so the map file ends up containing no information about what functions are included.
Created attachment 14853 [details] Proposed patch Hi Paul, Hi Jon, Would either of you like to try out this potential patch ? It adds local symbols to the linker map at the appropriate places, with a prefix of "(local) " so that they can be quickly identified. (Note local symbols are displayed after global symbols for a given section, rather than being mixed in with the global symbols). It is not complete yet. I think that I am going to have to add a command line option to control its use, as I expect that there are people out there who rely on the current format not changing. Plus I will need to add a testcase or two to the testsuite. I did find that *some* local symbols are already included in the linker map, eg _GLOBAL_OFFSET_TABLE_ and at the moment such symbols will appear twice. So I ought to try to find a way to stop that from happening as well. Cheers Nick
Thanks Nick, I see local data and functions now. Is there perhaps anyway to optionally filter out labels generated within functions (E.g. those normally declared beginning with L or .L that are the targets of branch instructions)?
(In reply to jon from comment #3) > Is there perhaps anyway to optionally filter out labels generated within > functions (E.g. those normally declared beginning with L or .L that are the > targets of branch instructions)? Actually yes. :-) There is a function is_local_label() in the BFD library which does exactly that. I will add it to my patch.
Created attachment 14855 [details] Proposed patch OK, here is a revised patch. Changes include: * Temporary local symbols (.Lxxx etc) are not displayed. * A new command line option enables the feature: --print-map-locals * The new option is documented. * A new testcase for the feature.
Not sure why, but with the new patch, the addition of the condition: && bfd_link_hash_lookup (link_info.hash, bfd_asymbol_name (sym), false, false, true) == NULL Seems to prevent the output of the symbols (functions / data when using -flto) that I'm interested in.
(In reply to jon from comment #6) > Not sure why, but with the new patch, the addition of the condition: > > && bfd_link_hash_lookup (link_info.hash, > bfd_asymbol_name (sym), false, > false, true) == NULL > > Seems to prevent the output of the symbols (functions / data when using > -flto) that I'm interested in. Hmmm. That test is designed to catch local symbols which have already been displayed by the normal linker-map-symbol-displaying code. (eg __GLOBAL_OFFSET_TABLE__). Can you give me a specific example of a symbol which is suppressed by this check, but which should not be ? (A small test case would be ideal...)
test.c: void func() { } int main() { func(); return 0; } Compile with: arm-eabi-gcc test.c -o test.exe -Xlinker -Map=arm.map -flto -Xlinker --print-map-locals With the bfd_link_hash_lookup condition, func doesn't appear in the map file.
(In reply to jon from comment #8) Hi Jon, > arm-eabi-gcc test.c -o test.exe -Xlinker -Map=arm.map -flto -Xlinker > --print-map-locals > > With the bfd_link_hash_lookup condition, func doesn't appear in the map file. Ah - but if you remove the "-flto" option it works... The problem is that the LTO compiler moves the func() code into its own section, which confuses the local printing code. I am looking to see if I can find a way around this problem... Cheers Nick
> Ah - but if you remove the "-flto" option it works... Without -flto, func is a global symbol. > The problem is that the LTO compiler moves the func() code into its own section, I guess that may be target/gcc version specific. I just see it being changed from a global to a local in .text.
Created attachment 14869 [details] Proposed patch OK, here is another version of the patch. This version detects symbols in LTO generated object files and treats them slightly differently. It works with the test case you gave me, and I think that it should work for all inputs, but please do give it a try with a real program and see if it works as you want.
Looks good, thanks Nick.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=496917ce466c703c1ae3bf1cbbe753de1c091445 commit 496917ce466c703c1ae3bf1cbbe753de1c091445 Author: Nick Clifton <nickc@redhat.com> Date: Wed May 10 10:29:52 2023 +0100 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.
Patch applied. (With a couple of mistakes corrected).