diff --git a/binutils/ChangeLog b/binutils/ChangeLog index eccf84428a4..1ec886bb18a 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,22 @@ +2019-02-08 Andrew Burgess + + * size.c (berkeley_format): Delete. + (enum output_format): New enum. + (selected_output_format): New variable. + (usage): Update to mention GNU format. + (main): Update to extract options, and select format as needed. + Handle GNU format where needed. + (berkeley_sum): Renamed to... + (berkeley_or_gnu_sum): ...this, and updated to handle both formats. + (berkeley_format): Renamed to... + (berkeley_or_gnu_format): ...this, and updated to handle both + formats. + (print_sizes): Handle GNU format. + * doc/binutils.texi (size): Document new GNU format. + * testsuite/binutils-all/size.exp: Add test of extended + functionality. + * NEWS: Mention new functionality. + 2019-02-08 Andrew Burgess * doc/binutils.texi (size): Update example output for Berkeley diff --git a/binutils/NEWS b/binutils/NEWS index 9ea8297d65f..34fd9ec04a4 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -33,6 +33,11 @@ Changes in 2.32: 3A1000 processor, The -march=loongson3a is an alias of -march=gs464 for compatibility. +* The size tool now has a new output format '--format=GNU' or '-G'. The + results are displayed in a similar manor to the default berkeley layout, + except read-only data is counted in the data column, not the text column. + Additionally the total is only included once. + Changes in 2.31: * Add support for disassembling netronome Flow Processor (NFP) firmware files. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 1137dce94b8..01f1e5f56db 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2877,7 +2877,7 @@ ar(1), nm(1), and the Info entries for @file{binutils}. @smallexample @c man begin SYNOPSIS size -size [@option{-A}|@option{-B}|@option{--format=}@var{compatibility}] +size [@option{-A}|@option{-B}|@option{-G}|@option{--format=}@var{compatibility}] [@option{--help}] [@option{-d}|@option{-o}|@option{-x}|@option{--radix=}@var{number}] [@option{--common}] @@ -2906,13 +2906,16 @@ The command-line options have the following meanings: @table @env @item -A @itemx -B +@itemx -G @itemx --format=@var{compatibility} @cindex @command{size} display format Using one of these options, you can choose whether the output from @sc{gnu} @command{size} resembles output from System V @command{size} (using @option{-A}, or @option{--format=sysv}), or Berkeley @command{size} (using @option{-B}, or @option{--format=berkeley}). The default is the one-line format similar to -Berkeley's. +Berkeley's. Alternatively, you can choose the GNU format output +(using @option{-G}, or @option{--format=gnu}), this is similar to +Berkeley's output format, but sizes are counted differently. @c Bonus for doc-source readers: you can also say --format=strange (or @c anything else that starts with 's') for sysv, and --format=boring (or @c anything else that starts with 'b') for Berkeley. @@ -2926,6 +2929,24 @@ $ size --format=Berkeley ranlib size 294880 81920 11888 388688 5ee50 size @end smallexample +The Berkeley style output counts read only data in the @code{text} +column, not in the @code{data} column, the @code{dec} and @code{hex} +columns both display the sum of the @code{text}, @code{data}, and +@code{bss} columns in decimal and hexadecimal respectively. + +The GNU format counts read only data in the @code{data} column, not +the @code{text} column, and only displays the sum of the @code{text}, +@code{data}, and @code{bss} columns once, in the @code{total} column. +The @option{--radix} option can be used to change the number base for +all columns. Here is the same data displayed with GNU conventions: + +@smallexample +$ size --format=GNU ranlib size + text data bss total filename + 279880 96920 11592 388392 ranlib + 279880 96920 11888 388688 size +@end smallexample + @noindent This is the same data, but displayed closer to System V conventions: @@ -2966,11 +2987,11 @@ octal and hexadecimal if you're using @option{-o}. @item --common Print total size of common symbols in each file. When using Berkeley -format these are included in the bss size. +or GNU format these are included in the bss size. @item -t @itemx --totals -Show totals of all objects listed (Berkeley format listing mode only). +Show totals of all objects listed (Berkeley or GNU format mode only). @item --target=@var{bfdname} @cindex object code format diff --git a/binutils/size.c b/binutils/size.c index 93ec02691ea..479a4648877 100644 --- a/binutils/size.c +++ b/binutils/size.c @@ -46,8 +46,20 @@ static enum } radix = decimal; -/* 0 means use AT&T-style output. */ -static int berkeley_format = BSD_DEFAULT; +/* Select the desired output format. */ +enum output_format + { + FORMAT_BERKLEY, + FORMAT_SYSV, + FORMAT_GNU + }; +static enum output_format selected_output_format = +#if BSD_DEFAULT + FORMAT_BERKLEY +#else + FORMAT_SYSV +#endif + ; static int show_version = 0; static int show_help = 0; @@ -77,7 +89,7 @@ usage (FILE *stream, int status) fprintf (stream, _(" Displays the sizes of sections inside binary files\n")); fprintf (stream, _(" If no input file(s) are specified, a.out is assumed\n")); fprintf (stream, _(" The options are:\n\ - -A|-B --format={sysv|berkeley} Select output style (default is %s)\n\ + -A|-B|-G --format={sysv|berkeley|gnu} Select output style (default is %s)\n\ -o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex\n\ -t --totals Display the total sizes (Berkeley only)\n\ --common Display total size for *COM* syms\n\ @@ -141,7 +153,7 @@ main (int argc, char **argv) fatal (_("fatal error: libbfd ABI mismatch")); set_default_bfd_target (); - while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options, + while ((c = getopt_long (argc, argv, "ABGHhVvdfotx", long_options, (int *) 0)) != EOF) switch (c) { @@ -150,11 +162,15 @@ main (int argc, char **argv) { case 'B': case 'b': - berkeley_format = 1; + selected_output_format = FORMAT_BERKLEY; break; case 'S': case 's': - berkeley_format = 0; + selected_output_format = FORMAT_SYSV; + break; + case 'G': + case 'g': + selected_output_format = FORMAT_GNU; break; default: non_fatal (_("invalid argument to --format: %s"), optarg); @@ -190,10 +206,13 @@ main (int argc, char **argv) break; case 'A': - berkeley_format = 0; + selected_output_format = FORMAT_SYSV; break; case 'B': - berkeley_format = 1; + selected_output_format = FORMAT_BERKLEY; + break; + case 'G': + selected_output_format = FORMAT_GNU; break; case 'v': case 'V': @@ -240,17 +259,25 @@ main (int argc, char **argv) for (; optind < argc;) display_file (argv[optind++]); - if (show_totals && berkeley_format) + if (show_totals && (selected_output_format == FORMAT_BERKLEY + || selected_output_format == FORMAT_GNU)) { bfd_size_type total = total_textsize + total_datasize + total_bsssize; + int col_width = (selected_output_format == FORMAT_BERKLEY) ? 7 : 10; + char sep_char = (selected_output_format == FORMAT_BERKLEY) ? '\t' : ' '; - rprint_number (7, total_textsize); - putchar('\t'); - rprint_number (7, total_datasize); - putchar('\t'); - rprint_number (7, total_bsssize); - printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"), - (unsigned long) total, (unsigned long) total); + rprint_number (col_width, total_textsize); + putchar(sep_char); + rprint_number (col_width, total_datasize); + putchar(sep_char); + rprint_number (col_width, total_bsssize); + putchar(sep_char); + if (selected_output_format == FORMAT_BERKLEY) + printf (((radix == octal) ? "%7lo\t%7lx" : "%7lu\t%7lx"), + (unsigned long) total, (unsigned long) total); + else + rprint_number (col_width, total); + putchar(sep_char); fputs ("(TOTALS)\n", stdout); } @@ -445,8 +472,8 @@ static bfd_size_type datasize; static bfd_size_type textsize; static void -berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, - void *ignore ATTRIBUTE_UNUSED) +berkeley_or_gnu_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, + void *ignore ATTRIBUTE_UNUSED) { flagword flags; bfd_size_type size; @@ -456,7 +483,9 @@ berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, return; size = bfd_get_section_size (sec); - if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0) + if ((flags & SEC_CODE) != 0 + || (selected_output_format == FORMAT_BERKLEY + && (flags & SEC_READONLY) != 0)) textsize += size; else if ((flags & SEC_HAS_CONTENTS) != 0) datasize += size; @@ -465,21 +494,28 @@ berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, } static void -print_berkeley_format (bfd *abfd) +print_berkeley_or_gnu_format (bfd *abfd) { static int files_seen = 0; bfd_size_type total; + int col_width = (selected_output_format == FORMAT_BERKLEY) ? 7 : 10; + char sep_char = (selected_output_format == FORMAT_BERKLEY) ? '\t' : ' '; bsssize = 0; datasize = 0; textsize = 0; - bfd_map_over_sections (abfd, berkeley_sum, NULL); + bfd_map_over_sections (abfd, berkeley_or_gnu_sum, NULL); bsssize += common_size; if (files_seen++ == 0) - puts ((radix == octal) ? " text\t data\t bss\t oct\t hex\tfilename" : - " text\t data\t bss\t dec\t hex\tfilename"); + { + if (selected_output_format == FORMAT_BERKLEY) + puts ((radix == octal) ? " text\t data\t bss\t oct\t hex\tfilename" : + " text\t data\t bss\t dec\t hex\tfilename"); + else + puts (" text data bss total filename"); + } total = textsize + datasize + bsssize; @@ -490,14 +526,20 @@ print_berkeley_format (bfd *abfd) total_bsssize += bsssize; } - rprint_number (7, textsize); - putchar ('\t'); - rprint_number (7, datasize); - putchar ('\t'); - rprint_number (7, bsssize); - printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"), - (unsigned long) total, (unsigned long) total); + rprint_number (col_width, textsize); + putchar (sep_char); + rprint_number (col_width, datasize); + putchar (sep_char); + rprint_number (col_width, bsssize); + putchar (sep_char); + if (selected_output_format == FORMAT_BERKLEY) + printf (((radix == octal) ? "%7lo\t%7lx" : "%7lu\t%7lx"), + (unsigned long) total, (unsigned long) total); + else + rprint_number (col_width, total); + + putchar (sep_char); fputs (bfd_get_filename (abfd), stdout); if (abfd->my_archive) @@ -611,8 +653,8 @@ print_sizes (bfd *file) { if (show_common) calculate_common_size (file); - if (berkeley_format) - print_berkeley_format (file); - else + if (selected_output_format == FORMAT_SYSV) print_sysv_format (file); + else + print_berkeley_or_gnu_format (file); } diff --git a/binutils/testsuite/binutils-all/size.exp b/binutils/testsuite/binutils-all/size.exp index 3fa04052d27..a102e15c0de 100644 --- a/binutils/testsuite/binutils-all/size.exp +++ b/binutils/testsuite/binutils-all/size.exp @@ -79,4 +79,24 @@ if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then { pass "size -A" } } + + # Test size -G + + set got [binutils_run $SIZE "$SIZEFLAGS -G $testfile"] + + set want "($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+${testfile}" + + if ![regexp $want $got all text data bss dtot hextot] then { + fail "size -G" + } else { + if {$text < 8 || $data < 4} then { + # The z80-coff port defaults to a "binary" like output + # file format which does not include a data section. + setup_xfail "z80-*-coff" + fail "size -G" + } else { + pass "size -G" + } + } + }