* [Patch, tentative] Show output section size contribution from each input file in map file
@ 2015-05-20 12:46 Senthil Kumar Selvaraj
2015-05-27 1:12 ` Alan Modra
0 siblings, 1 reply; 4+ messages in thread
From: Senthil Kumar Selvaraj @ 2015-05-20 12:46 UTC (permalink / raw)
To: binutils; +Cc: nickc
Hi,
This very rough patch adds extra information to the map file to show
how much each input file contributed to output sections in the output
file. While this information can already by computed by
grepping/summing existing map file output, this patch makes that
unnecessary - it groups by input bfd.
The primary motivation is to help embedded developers (or anyone who is
paranoid about code size) quickly figure out where most of the code/data
is coming from.
This is how the output looks (for an AVR ELF).
<snip>
Input files and contributions to output file.
/home/saaadhu/avr/install/lib/gcc/avr/6.0.0/../../../../avr/lib/avr51/crtatmega1280.o
.text 0xf6
.note.gnu.avr.deviceinfo
0x40
.debug_info 0xbbc
.debug_abbrev 0xb1a
.debug_line 0x1d
.debug_str 0x3e9
/tmp/cclzAVJF.o
.text 0x12
.comment 0x29
_exit.o
.text 0x4
.debug_aranges 0x20
.debug_info 0x93
.debug_abbrev 0x14
.debug_line 0x70
_clear_bss.o
.text 0x10
.debug_aranges 0x20
.debug_info 0x93
.debug_abbrev 0x14
.debug_line 0x94
What do you guys think? Is there a better way to do this?
Regards
Senthil
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c96c21f..bf97f57 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2052,6 +2052,15 @@ lang_map_flags (flagword flag)
minfo ("l");
}
+
+static bfd_boolean
+is_section_discarded (asection *s)
+{
+ return ((s->output_section == NULL
+ || s->output_section->owner != link_info.output_bfd)
+ && (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0);
+}
+
void
lang_map (void)
{
@@ -2067,9 +2076,7 @@ lang_map (void)
continue;
for (s = file->the_bfd->sections; s != NULL; s = s->next)
- if ((s->output_section == NULL
- || s->output_section->owner != link_info.output_bfd)
- && (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0)
+ if (is_section_discarded (s))
{
if (! dis_header_printed)
{
@@ -2133,6 +2140,66 @@ lang_map (void)
lang_statement_iteration++;
print_statements ();
+ fprintf (config.map_file, _("\nInput files and contributions to "
+ "output file."));
+
+ LANG_FOR_EACH_INPUT_STATEMENT (f)
+ {
+ if ((f->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0
+ || f->flags.just_syms || f->the_bfd->filename == NULL)
+ continue;
+
+ bfd_boolean does_bfd_contribute = FALSE;
+
+ lang_output_section_statement_type *os;
+ for (os = &lang_output_section_statement.head->output_section_statement;
+ os != NULL;
+ os = os->next)
+ {
+ asection *output_section = os->bfd_section;
+ if (output_section == NULL)
+ continue;
+
+ asection *i;
+ bfd_size_type size_from_this_bfd = 0;
+
+ for (i = f->the_bfd->sections; i != NULL; i = i->next)
+ {
+ if (is_section_discarded (i))
+ continue;
+
+ if (i->output_section == output_section)
+ size_from_this_bfd += i->size;
+ }
+
+ if (size_from_this_bfd > 0)
+ {
+ int len;
+
+ if (does_bfd_contribute == FALSE)
+ {
+ does_bfd_contribute = TRUE;
+ fprintf (config.map_file, "\n\n%s\n", f->the_bfd->filename);
+ }
+
+ minfo ("\n%s", output_section->name);
+
+ len = strlen (output_section->name);
+ if (len >= SECTION_NAME_MAP_LENGTH - 1)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < SECTION_NAME_MAP_LENGTH)
+ {
+ print_space ();
+ ++len;
+ }
+ minfo ("%W", size_from_this_bfd);
+ }
+ }
+ }
+
ldemul_extra_map_file_text (link_info.output_bfd, &link_info, config.map_file);
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, tentative] Show output section size contribution from each input file in map file
2015-05-20 12:46 [Patch, tentative] Show output section size contribution from each input file in map file Senthil Kumar Selvaraj
@ 2015-05-27 1:12 ` Alan Modra
2015-05-27 3:29 ` Senthil Kumar Selvaraj
0 siblings, 1 reply; 4+ messages in thread
From: Alan Modra @ 2015-05-27 1:12 UTC (permalink / raw)
To: Senthil Kumar Selvaraj; +Cc: binutils, nickc
On Wed, May 20, 2015 at 06:14:46PM +0530, Senthil Kumar Selvaraj wrote:
> This very rough patch adds extra information to the map file to show
> how much each input file contributed to output sections in the output
> file. While this information can already by computed by
> grepping/summing existing map file output, this patch makes that
> unnecessary - it groups by input bfd.
>
> The primary motivation is to help embedded developers (or anyone who is
> paranoid about code size) quickly figure out where most of the code/data
> is coming from.
Sorry, I don't see this as useful at all. For people who don't want
the collected information, it is just clutter. Teach your users about
grep instead..
$ gcc -o hello hello.o -Wl,-Map,hello.map
$ grep hello.o hello.map
0x0000000000000000 0x0 hello.o
LOAD hello.o
.text 0x00000000004004d6 0x46 hello.o
.rodata 0x00000000004005a4 0x6 hello.o
.eh_frame 0x0000000000400658 0x40 hello.o
.data 0x0000000000600928 0x0 hello.o
.bss 0x0000000000600929 0x0 hello.o
.comment 0x000000000000001a 0x1b hello.o
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, tentative] Show output section size contribution from each input file in map file
2015-05-27 1:12 ` Alan Modra
@ 2015-05-27 3:29 ` Senthil Kumar Selvaraj
2015-06-08 6:00 ` Senthil Kumar Selvaraj
0 siblings, 1 reply; 4+ messages in thread
From: Senthil Kumar Selvaraj @ 2015-05-27 3:29 UTC (permalink / raw)
To: binutils, nickc
On Wed, May 27, 2015 at 10:42:22AM +0930, Alan Modra wrote:
> On Wed, May 20, 2015 at 06:14:46PM +0530, Senthil Kumar Selvaraj wrote:
> > This very rough patch adds extra information to the map file to show
> > how much each input file contributed to output sections in the output
> > file. While this information can already by computed by
> > grepping/summing existing map file output, this patch makes that
> > unnecessary - it groups by input bfd.
> >
> > The primary motivation is to help embedded developers (or anyone who is
> > paranoid about code size) quickly figure out where most of the code/data
> > is coming from.
>
> Sorry, I don't see this as useful at all. For people who don't want
> the collected information, it is just clutter. Teach your users about
> grep instead..
For trivial, straightforward compile-linkss, I agree it doesn't add value.
Where it gets interesting is when code is compiled and linked with
-ffunction-sections/-fdata-sections or with custom section names, which
are then grouped into appropriate output sections in the (perhaps custom)
linker script.
For example, for this source file
$ cat test.c
volatile int x;
int y;
void foo()
{
y++;
}
void bar()
{
x++;
}
int main()
{
bar();
return x;
}
When compiled with
$ ~/avr/install/bin/avr-gcc -o test.o -c test.c -ffunction-sections -fdata-sections -mmcu=atmega1280
$ ~/avr/install/bin/avr-gcc -o test test.o -Wl,--gc-sections -Wl,-Map=test.map -mmcu=atmega1280
Running grep 'test.o' test.map
.text 0x0000000000000000 0x0 test.o
.data 0x0000000000000000 0x0 test.o
.bss 0x0000000000000000 0x0 test.o
.text.foo 0x0000000000000000 0x22 test.o
LOAD test.o
.text.bar 0x000000000000010c 0x22 test.o
.text.main 0x000000000000012e 0x1a test.o
COMMON 0x0000000000800200 0x4 test.o
.comment 0x0000000000000000 0x29 test.o
whereas the map file (after my patch), has this
Input files and contributions to output file.
/home/saaadhu/avr/install/lib/gcc/avr/6.0.0/../../../../avr/lib/avr51/crtatmega1280.o
.text 0xfc
.note.gnu.avr.deviceinfo
0x40
.debug_info 0xbbc
.debug_abbrev 0xb1a
.debug_line 0x1d
.debug_str 0x3e9
test.o
.text 0x3c
.bss 0x4
.comment 0x29
_exit.o
.text 0x4
.debug_aranges 0x20
.debug_info 0x93
.debug_abbrev 0x14
.debug_line 0x70
_clear_bss.o
.text 0x10
.debug_aranges 0x20
.debug_info 0x93
.debug_abbrev 0x14
.debug_line 0x94
test.o
To arrive at that, you'd have to skip the initial few lines (from the discarded sections output), figure out
the input->output section mapping for .text.{bar,main} and then add up the sizes.
You'd also have to repeat this for *every* object file involved in the link, remembering to include crt/startup,
archive members etc..
I'm not saying it can't be done otherwise - just that the linker already has all this information that might
prove useful for code size analysis, so why not make it show that? Would making it optional via a command line flag work?
Regards
Senthil
>
> $ gcc -o hello hello.o -Wl,-Map,hello.map
> $ grep hello.o hello.map
> 0x0000000000000000 0x0 hello.o
> LOAD hello.o
> .text 0x00000000004004d6 0x46 hello.o
> .rodata 0x00000000004005a4 0x6 hello.o
> .eh_frame 0x0000000000400658 0x40 hello.o
> .data 0x0000000000600928 0x0 hello.o
> .bss 0x0000000000600929 0x0 hello.o
> .comment 0x000000000000001a 0x1b hello.o
>
> --
> Alan Modra
> Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, tentative] Show output section size contribution from each input file in map file
2015-05-27 3:29 ` Senthil Kumar Selvaraj
@ 2015-06-08 6:00 ` Senthil Kumar Selvaraj
0 siblings, 0 replies; 4+ messages in thread
From: Senthil Kumar Selvaraj @ 2015-06-08 6:00 UTC (permalink / raw)
To: binutils, nickc
Ping!
Regards
Senthil
On Wed, May 27, 2015 at 08:58:22AM +0530, Senthil Kumar Selvaraj wrote:
> On Wed, May 27, 2015 at 10:42:22AM +0930, Alan Modra wrote:
> > On Wed, May 20, 2015 at 06:14:46PM +0530, Senthil Kumar Selvaraj wrote:
> > > This very rough patch adds extra information to the map file to show
> > > how much each input file contributed to output sections in the output
> > > file. While this information can already by computed by
> > > grepping/summing existing map file output, this patch makes that
> > > unnecessary - it groups by input bfd.
> > >
> > > The primary motivation is to help embedded developers (or anyone who is
> > > paranoid about code size) quickly figure out where most of the code/data
> > > is coming from.
> >
> > Sorry, I don't see this as useful at all. For people who don't want
> > the collected information, it is just clutter. Teach your users about
> > grep instead..
>
> For trivial, straightforward compile-linkss, I agree it doesn't add value.
>
> Where it gets interesting is when code is compiled and linked with
> -ffunction-sections/-fdata-sections or with custom section names, which
> are then grouped into appropriate output sections in the (perhaps custom)
> linker script.
>
> For example, for this source file
>
> $ cat test.c
>
> volatile int x;
> int y;
> void foo()
> {
> y++;
> }
>
>
> void bar()
> {
> x++;
> }
>
> int main()
> {
> bar();
> return x;
> }
>
> When compiled with
> $ ~/avr/install/bin/avr-gcc -o test.o -c test.c -ffunction-sections -fdata-sections -mmcu=atmega1280
> $ ~/avr/install/bin/avr-gcc -o test test.o -Wl,--gc-sections -Wl,-Map=test.map -mmcu=atmega1280
>
> Running grep 'test.o' test.map
>
> .text 0x0000000000000000 0x0 test.o
> .data 0x0000000000000000 0x0 test.o
> .bss 0x0000000000000000 0x0 test.o
> .text.foo 0x0000000000000000 0x22 test.o
> LOAD test.o
> .text.bar 0x000000000000010c 0x22 test.o
> .text.main 0x000000000000012e 0x1a test.o
> COMMON 0x0000000000800200 0x4 test.o
> .comment 0x0000000000000000 0x29 test.o
>
> whereas the map file (after my patch), has this
>
> Input files and contributions to output file.
>
> /home/saaadhu/avr/install/lib/gcc/avr/6.0.0/../../../../avr/lib/avr51/crtatmega1280.o
>
> .text 0xfc
> .note.gnu.avr.deviceinfo
> 0x40
> .debug_info 0xbbc
> .debug_abbrev 0xb1a
> .debug_line 0x1d
> .debug_str 0x3e9
>
> test.o
>
> .text 0x3c
> .bss 0x4
> .comment 0x29
>
> _exit.o
>
> .text 0x4
> .debug_aranges 0x20
> .debug_info 0x93
> .debug_abbrev 0x14
> .debug_line 0x70
>
> _clear_bss.o
>
> .text 0x10
> .debug_aranges 0x20
> .debug_info 0x93
> .debug_abbrev 0x14
> .debug_line 0x94
> test.o
>
> To arrive at that, you'd have to skip the initial few lines (from the discarded sections output), figure out
> the input->output section mapping for .text.{bar,main} and then add up the sizes.
>
> You'd also have to repeat this for *every* object file involved in the link, remembering to include crt/startup,
> archive members etc..
>
> I'm not saying it can't be done otherwise - just that the linker already has all this information that might
> prove useful for code size analysis, so why not make it show that? Would making it optional via a command line flag work?
>
> Regards
> Senthil
>
> >
> > $ gcc -o hello hello.o -Wl,-Map,hello.map
> > $ grep hello.o hello.map
> > 0x0000000000000000 0x0 hello.o
> > LOAD hello.o
> > .text 0x00000000004004d6 0x46 hello.o
> > .rodata 0x00000000004005a4 0x6 hello.o
> > .eh_frame 0x0000000000400658 0x40 hello.o
> > .data 0x0000000000600928 0x0 hello.o
> > .bss 0x0000000000600929 0x0 hello.o
> > .comment 0x000000000000001a 0x1b hello.o
> >
> > --
> > Alan Modra
> > Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-06-08 6:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-20 12:46 [Patch, tentative] Show output section size contribution from each input file in map file Senthil Kumar Selvaraj
2015-05-27 1:12 ` Alan Modra
2015-05-27 3:29 ` Senthil Kumar Selvaraj
2015-06-08 6:00 ` Senthil Kumar Selvaraj
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).