133965Sjdp/* size.c -- report size of various sections of an executable file.
2218822Sdim   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
433965Sjdp
589857Sobrien   This file is part of GNU Binutils.
633965Sjdp
789857Sobrien   This program is free software; you can redistribute it and/or modify
889857Sobrien   it under the terms of the GNU General Public License as published by
989857Sobrien   the Free Software Foundation; either version 2 of the License, or
1089857Sobrien   (at your option) any later version.
1133965Sjdp
1289857Sobrien   This program is distributed in the hope that it will be useful,
1389857Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1489857Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1589857Sobrien   GNU General Public License for more details.
1633965Sjdp
1789857Sobrien   You should have received a copy of the GNU General Public License
1889857Sobrien   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2033965Sjdp
2133965Sjdp/* Extensions/incompatibilities:
2233965Sjdp   o - BSD output has filenames at the end.
2333965Sjdp   o - BSD output can appear in different radicies.
2433965Sjdp   o - SysV output has less redundant whitespace.  Filename comes at end.
2533965Sjdp   o - SysV output doesn't show VMA which is always the same as the PMA.
2633965Sjdp   o - We also handle core files.
2733965Sjdp   o - We also handle archives.
2833965Sjdp   If you write shell scripts which manipulate this info then you may be
2989857Sobrien   out of luck; there's no --compatibility or --pedantic option.  */
3033965Sjdp
31218822Sdim#include "sysdep.h"
3233965Sjdp#include "bfd.h"
3333965Sjdp#include "libiberty.h"
3491041Sobrien#include "getopt.h"
35218822Sdim#include "bucomm.h"
3633965Sjdp
3733965Sjdp#ifndef BSD_DEFAULT
3833965Sjdp#define BSD_DEFAULT 1
3933965Sjdp#endif
4033965Sjdp
4133965Sjdp/* Program options.  */
4233965Sjdp
4333965Sjdpenum
4433965Sjdp  {
4533965Sjdp    decimal, octal, hex
4689857Sobrien  }
4789857Sobrienradix = decimal;
4889857Sobrien
49218822Sdim/* 0 means use AT&T-style output.  */
50218822Sdimstatic int berkeley_format = BSD_DEFAULT;
51218822Sdim
5233965Sjdpint show_version = 0;
5333965Sjdpint show_help = 0;
5489857Sobrienint show_totals = 0;
5533965Sjdp
5689857Sobrienstatic bfd_size_type total_bsssize;
5789857Sobrienstatic bfd_size_type total_datasize;
5889857Sobrienstatic bfd_size_type total_textsize;
5989857Sobrien
6033965Sjdp/* Program exit status.  */
6133965Sjdpint return_code = 0;
6233965Sjdp
6338889Sjdpstatic char *target = NULL;
6433965Sjdp
6589857Sobrien/* Static declarations.  */
6633965Sjdp
67130561Sobrienstatic void usage (FILE *, int);
68130561Sobrienstatic void display_file (char *);
69130561Sobrienstatic void display_bfd (bfd *);
70130561Sobrienstatic void display_archive (bfd *);
71130561Sobrienstatic int size_number (bfd_size_type);
72130561Sobrienstatic void rprint_number (int, bfd_size_type);
73130561Sobrienstatic void print_berkeley_format (bfd *);
74130561Sobrienstatic void sysv_internal_sizer (bfd *, asection *, void *);
75130561Sobrienstatic void sysv_internal_printer (bfd *, asection *, void *);
76130561Sobrienstatic void print_sysv_format (bfd *);
77130561Sobrienstatic void print_sizes (bfd * file);
78130561Sobrienstatic void berkeley_sum (bfd *, sec_ptr, void *);
7933965Sjdp
8033965Sjdpstatic void
81130561Sobrienusage (FILE *stream, int status)
8233965Sjdp{
8389857Sobrien  fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
8489857Sobrien  fprintf (stream, _(" Displays the sizes of sections inside binary files\n"));
85104834Sobrien  fprintf (stream, _(" If no input file(s) are specified, a.out is assumed\n"));
8689857Sobrien  fprintf (stream, _(" The options are:\n\
8789857Sobrien  -A|-B     --format={sysv|berkeley}  Select output style (default is %s)\n\
88130561Sobrien  -o|-d|-x  --radix={8|10|16}         Display numbers in octal, decimal or hex\n\
8989857Sobrien  -t        --totals                  Display the total sizes (Berkeley only)\n\
9089857Sobrien            --target=<bfdname>        Set the binary file format\n\
91218822Sdim            @<file>                   Read options from <file>\n\
9289857Sobrien  -h        --help                    Display this information\n\
9389857Sobrien  -v        --version                 Display the program's version\n\
9489857Sobrien\n"),
9533965Sjdp#if BSD_DEFAULT
9689857Sobrien  "berkeley"
9733965Sjdp#else
9889857Sobrien  "sysv"
9933965Sjdp#endif
10089857Sobrien);
10133965Sjdp  list_supported_targets (program_name, stream);
102218822Sdim  if (REPORT_BUGS_TO[0] && status == 0)
10360484Sobrien    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
10433965Sjdp  exit (status);
10533965Sjdp}
10633965Sjdp
107218822Sdimstatic struct option long_options[] =
10833965Sjdp{
10933965Sjdp  {"format", required_argument, 0, 200},
11033965Sjdp  {"radix", required_argument, 0, 201},
11133965Sjdp  {"target", required_argument, 0, 202},
11289857Sobrien  {"totals", no_argument, &show_totals, 1},
11333965Sjdp  {"version", no_argument, &show_version, 1},
11433965Sjdp  {"help", no_argument, &show_help, 1},
11533965Sjdp  {0, no_argument, 0, 0}
11633965Sjdp};
11733965Sjdp
118130561Sobrienint main (int, char **);
11989857Sobrien
12033965Sjdpint
121130561Sobrienmain (int argc, char **argv)
12233965Sjdp{
12333965Sjdp  int temp;
12433965Sjdp  int c;
12533965Sjdp
12660484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12760484Sobrien  setlocale (LC_MESSAGES, "");
12860484Sobrien#endif
12989857Sobrien#if defined (HAVE_SETLOCALE)
13089857Sobrien  setlocale (LC_CTYPE, "");
13189857Sobrien#endif
13260484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
13360484Sobrien  textdomain (PACKAGE);
13460484Sobrien
13533965Sjdp  program_name = *argv;
13633965Sjdp  xmalloc_set_program_name (program_name);
13733965Sjdp
138218822Sdim  expandargv (&argc, &argv);
139218822Sdim
14033965Sjdp  bfd_init ();
14133965Sjdp  set_default_bfd_target ();
14233965Sjdp
14389857Sobrien  while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options,
14433965Sjdp			   (int *) 0)) != EOF)
14533965Sjdp    switch (c)
14633965Sjdp      {
14733965Sjdp      case 200:		/* --format */
14833965Sjdp	switch (*optarg)
14933965Sjdp	  {
15033965Sjdp	  case 'B':
15133965Sjdp	  case 'b':
15233965Sjdp	    berkeley_format = 1;
15333965Sjdp	    break;
15433965Sjdp	  case 'S':
15533965Sjdp	  case 's':
15633965Sjdp	    berkeley_format = 0;
15733965Sjdp	    break;
15833965Sjdp	  default:
15960484Sobrien	    non_fatal (_("invalid argument to --format: %s"), optarg);
16033965Sjdp	    usage (stderr, 1);
16133965Sjdp	  }
16233965Sjdp	break;
16333965Sjdp
16433965Sjdp      case 202:		/* --target */
16533965Sjdp	target = optarg;
16633965Sjdp	break;
16733965Sjdp
16833965Sjdp      case 201:		/* --radix */
16933965Sjdp#ifdef ANSI_LIBRARIES
17033965Sjdp	temp = strtol (optarg, NULL, 10);
17133965Sjdp#else
17233965Sjdp	temp = atol (optarg);
17333965Sjdp#endif
17433965Sjdp	switch (temp)
17533965Sjdp	  {
17633965Sjdp	  case 10:
17733965Sjdp	    radix = decimal;
17833965Sjdp	    break;
17933965Sjdp	  case 8:
18033965Sjdp	    radix = octal;
18133965Sjdp	    break;
18233965Sjdp	  case 16:
18333965Sjdp	    radix = hex;
18433965Sjdp	    break;
18533965Sjdp	  default:
18660484Sobrien	    non_fatal (_("Invalid radix: %s\n"), optarg);
18733965Sjdp	    usage (stderr, 1);
18833965Sjdp	  }
18933965Sjdp	break;
19033965Sjdp
19133965Sjdp      case 'A':
19233965Sjdp	berkeley_format = 0;
19333965Sjdp	break;
19433965Sjdp      case 'B':
19533965Sjdp	berkeley_format = 1;
19633965Sjdp	break;
19789857Sobrien      case 'v':
19833965Sjdp      case 'V':
19933965Sjdp	show_version = 1;
20033965Sjdp	break;
20133965Sjdp      case 'd':
20233965Sjdp	radix = decimal;
20333965Sjdp	break;
20433965Sjdp      case 'x':
20533965Sjdp	radix = hex;
20633965Sjdp	break;
20733965Sjdp      case 'o':
20833965Sjdp	radix = octal;
20933965Sjdp	break;
21089857Sobrien      case 't':
21189857Sobrien	show_totals = 1;
21289857Sobrien	break;
21377298Sobrien      case 'f': /* FIXME : For sysv68, `-f' means `full format', i.e.
21477298Sobrien		   `[fname:] M(.text) + N(.data) + O(.bss) + P(.comment) = Q'
21577298Sobrien		   where `fname: ' appears only if there are >= 2 input files,
21677298Sobrien		   and M, N, O, P, Q are expressed in decimal by default,
21777298Sobrien		   hexa or octal if requested by `-x' or `-o'.
21877298Sobrien		   Just to make things interesting, Solaris also accepts -f,
21977298Sobrien		   which prints out the size of each allocatable section, the
22077298Sobrien		   name of the section, and the total of the section sizes.  */
22177298Sobrien		/* For the moment, accept `-f' silently, and ignore it.  */
22277298Sobrien	break;
22333965Sjdp      case 0:
22433965Sjdp	break;
22589857Sobrien      case 'h':
22689857Sobrien      case 'H':
22733965Sjdp      case '?':
22833965Sjdp	usage (stderr, 1);
22933965Sjdp      }
23033965Sjdp
23133965Sjdp  if (show_version)
23233965Sjdp    print_version ("size");
23333965Sjdp  if (show_help)
23433965Sjdp    usage (stdout, 0);
23533965Sjdp
23633965Sjdp  if (optind == argc)
23733965Sjdp    display_file ("a.out");
23833965Sjdp  else
23933965Sjdp    for (; optind < argc;)
24033965Sjdp      display_file (argv[optind++]);
24133965Sjdp
24289857Sobrien  if (show_totals && berkeley_format)
24389857Sobrien    {
24489857Sobrien      bfd_size_type total = total_textsize + total_datasize + total_bsssize;
24589857Sobrien
24689857Sobrien      rprint_number (7, total_textsize);
24789857Sobrien      putchar('\t');
24889857Sobrien      rprint_number (7, total_datasize);
24989857Sobrien      putchar('\t');
25089857Sobrien      rprint_number (7, total_bsssize);
25189857Sobrien      printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"),
25289857Sobrien	      (unsigned long) total, (unsigned long) total);
25389857Sobrien      fputs ("(TOTALS)\n", stdout);
25489857Sobrien    }
25589857Sobrien
25633965Sjdp  return return_code;
25733965Sjdp}
25833965Sjdp
25933965Sjdp/* Display stats on file or archive member ABFD.  */
26033965Sjdp
26133965Sjdpstatic void
262130561Sobriendisplay_bfd (bfd *abfd)
26333965Sjdp{
26433965Sjdp  char **matching;
26533965Sjdp
26633965Sjdp  if (bfd_check_format (abfd, bfd_archive))
26733965Sjdp    /* An archive within an archive.  */
26833965Sjdp    return;
26933965Sjdp
27033965Sjdp  if (bfd_check_format_matches (abfd, bfd_object, &matching))
27133965Sjdp    {
27233965Sjdp      print_sizes (abfd);
27333965Sjdp      printf ("\n");
27433965Sjdp      return;
27533965Sjdp    }
27633965Sjdp
27733965Sjdp  if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
27833965Sjdp    {
27933965Sjdp      bfd_nonfatal (bfd_get_filename (abfd));
28033965Sjdp      list_matching_formats (matching);
28133965Sjdp      free (matching);
28233965Sjdp      return_code = 3;
28333965Sjdp      return;
28433965Sjdp    }
28533965Sjdp
28633965Sjdp  if (bfd_check_format_matches (abfd, bfd_core, &matching))
28733965Sjdp    {
28889857Sobrien      const char *core_cmd;
28933965Sjdp
29033965Sjdp      print_sizes (abfd);
29133965Sjdp      fputs (" (core file", stdout);
29233965Sjdp
29333965Sjdp      core_cmd = bfd_core_file_failing_command (abfd);
29433965Sjdp      if (core_cmd)
29533965Sjdp	printf (" invoked as %s", core_cmd);
29633965Sjdp
29733965Sjdp      puts (")\n");
29833965Sjdp      return;
29933965Sjdp    }
30033965Sjdp
30133965Sjdp  bfd_nonfatal (bfd_get_filename (abfd));
30233965Sjdp
30333965Sjdp  if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
30433965Sjdp    {
30533965Sjdp      list_matching_formats (matching);
30633965Sjdp      free (matching);
30733965Sjdp    }
30833965Sjdp
30933965Sjdp  return_code = 3;
31033965Sjdp}
31133965Sjdp
31233965Sjdpstatic void
313130561Sobriendisplay_archive (bfd *file)
31433965Sjdp{
31533965Sjdp  bfd *arfile = (bfd *) NULL;
31699461Sobrien  bfd *last_arfile = (bfd *) NULL;
31733965Sjdp
31833965Sjdp  for (;;)
31933965Sjdp    {
32033965Sjdp      bfd_set_error (bfd_error_no_error);
32133965Sjdp
32233965Sjdp      arfile = bfd_openr_next_archived_file (file, arfile);
32333965Sjdp      if (arfile == NULL)
32433965Sjdp	{
32533965Sjdp	  if (bfd_get_error () != bfd_error_no_more_archived_files)
32633965Sjdp	    {
32733965Sjdp	      bfd_nonfatal (bfd_get_filename (file));
32833965Sjdp	      return_code = 2;
32933965Sjdp	    }
33033965Sjdp	  break;
33133965Sjdp	}
33233965Sjdp
33333965Sjdp      display_bfd (arfile);
33499461Sobrien
33599461Sobrien      if (last_arfile != NULL)
33699461Sobrien	bfd_close (last_arfile);
33799461Sobrien      last_arfile = arfile;
33833965Sjdp    }
33999461Sobrien
34099461Sobrien  if (last_arfile != NULL)
34199461Sobrien    bfd_close (last_arfile);
34233965Sjdp}
34333965Sjdp
34433965Sjdpstatic void
345130561Sobriendisplay_file (char *filename)
34633965Sjdp{
347130561Sobrien  bfd *file;
34889857Sobrien
349130561Sobrien  if (get_file_size (filename) < 1)
350218822Sdim    {
351218822Sdim      return_code = 1;
352218822Sdim      return;
353218822Sdim    }
354130561Sobrien
355130561Sobrien  file = bfd_openr (filename, target);
35633965Sjdp  if (file == NULL)
35733965Sjdp    {
35833965Sjdp      bfd_nonfatal (filename);
35933965Sjdp      return_code = 1;
36033965Sjdp      return;
36133965Sjdp    }
36233965Sjdp
363130561Sobrien  if (bfd_check_format (file, bfd_archive))
36433965Sjdp    display_archive (file);
36533965Sjdp  else
36633965Sjdp    display_bfd (file);
36733965Sjdp
368130561Sobrien  if (!bfd_close (file))
36933965Sjdp    {
37033965Sjdp      bfd_nonfatal (filename);
37133965Sjdp      return_code = 1;
37233965Sjdp      return;
37333965Sjdp    }
37433965Sjdp}
37533965Sjdp
37633965Sjdp/* This is what lexical functions are for.  */
37733965Sjdp
37838889Sjdpstatic int
379130561Sobriensize_number (bfd_size_type num)
38038889Sjdp{
38138889Sjdp  char buffer[40];
38289857Sobrien
38338889Sjdp  sprintf (buffer,
38438889Sjdp	   (radix == decimal ? "%lu" :
38538889Sjdp	   ((radix == octal) ? "0%lo" : "0x%lx")),
38638889Sjdp	   (unsigned long) num);
38738889Sjdp
38838889Sjdp  return strlen (buffer);
38938889Sjdp}
39038889Sjdp
39133965Sjdpstatic void
392130561Sobrienrprint_number (int width, bfd_size_type num)
39333965Sjdp{
39438889Sjdp  char buffer[40];
39589857Sobrien
39638889Sjdp  sprintf (buffer,
39738889Sjdp	   (radix == decimal ? "%lu" :
39838889Sjdp	   ((radix == octal) ? "0%lo" : "0x%lx")),
39938889Sjdp	   (unsigned long) num);
40038889Sjdp
40138889Sjdp  printf ("%*s", width, buffer);
40233965Sjdp}
40333965Sjdp
40433965Sjdpstatic bfd_size_type bsssize;
40533965Sjdpstatic bfd_size_type datasize;
40633965Sjdpstatic bfd_size_type textsize;
40733965Sjdp
40833965Sjdpstatic void
409130561Sobrienberkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
410130561Sobrien	      void *ignore ATTRIBUTE_UNUSED)
41133965Sjdp{
41233965Sjdp  flagword flags;
41333965Sjdp  bfd_size_type size;
41433965Sjdp
41533965Sjdp  flags = bfd_get_section_flags (abfd, sec);
41633965Sjdp  if ((flags & SEC_ALLOC) == 0)
41733965Sjdp    return;
41833965Sjdp
419218822Sdim  size = bfd_get_section_size (sec);
42033965Sjdp  if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0)
42133965Sjdp    textsize += size;
42233965Sjdp  else if ((flags & SEC_HAS_CONTENTS) != 0)
42333965Sjdp    datasize += size;
42433965Sjdp  else
42533965Sjdp    bsssize += size;
42633965Sjdp}
42733965Sjdp
428104834Sobrienstatic void
429130561Sobrienprint_berkeley_format (bfd *abfd)
43033965Sjdp{
43133965Sjdp  static int files_seen = 0;
43233965Sjdp  bfd_size_type total;
43333965Sjdp
43433965Sjdp  bsssize = 0;
43533965Sjdp  datasize = 0;
43633965Sjdp  textsize = 0;
43733965Sjdp
438130561Sobrien  bfd_map_over_sections (abfd, berkeley_sum, NULL);
43933965Sjdp
44033965Sjdp  if (files_seen++ == 0)
44138889Sjdp    puts ((radix == octal) ? "   text\t   data\t    bss\t    oct\t    hex\tfilename" :
44238889Sjdp	  "   text\t   data\t    bss\t    dec\t    hex\tfilename");
44333965Sjdp
44433965Sjdp  total = textsize + datasize + bsssize;
44533965Sjdp
44689857Sobrien  if (show_totals)
44789857Sobrien    {
44889857Sobrien      total_textsize += textsize;
44989857Sobrien      total_datasize += datasize;
45089857Sobrien      total_bsssize  += bsssize;
45189857Sobrien    }
45289857Sobrien
45338889Sjdp  rprint_number (7, textsize);
45438889Sjdp  putchar ('\t');
45538889Sjdp  rprint_number (7, datasize);
45638889Sjdp  putchar ('\t');
45738889Sjdp  rprint_number (7, bsssize);
45838889Sjdp  printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"),
45933965Sjdp	  (unsigned long) total, (unsigned long) total);
46033965Sjdp
46133965Sjdp  fputs (bfd_get_filename (abfd), stdout);
46289857Sobrien
46333965Sjdp  if (bfd_my_archive (abfd))
46433965Sjdp    printf (" (ex %s)", bfd_get_filename (bfd_my_archive (abfd)));
46533965Sjdp}
46633965Sjdp
46733965Sjdp/* I REALLY miss lexical functions! */
46833965Sjdpbfd_size_type svi_total = 0;
46938889Sjdpbfd_vma svi_maxvma = 0;
47038889Sjdpint svi_namelen = 0;
47138889Sjdpint svi_vmalen = 0;
47238889Sjdpint svi_sizelen = 0;
47333965Sjdp
47433965Sjdpstatic void
475130561Sobriensysv_internal_sizer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
476130561Sobrien		     void *ignore ATTRIBUTE_UNUSED)
47738889Sjdp{
47838889Sjdp  bfd_size_type size = bfd_section_size (file, sec);
47989857Sobrien
48089857Sobrien  if (   ! bfd_is_abs_section (sec)
48189857Sobrien      && ! bfd_is_com_section (sec)
48289857Sobrien      && ! bfd_is_und_section (sec))
48338889Sjdp    {
48438889Sjdp      int namelen = strlen (bfd_section_name (file, sec));
48589857Sobrien
48638889Sjdp      if (namelen > svi_namelen)
48738889Sjdp	svi_namelen = namelen;
48838889Sjdp
48938889Sjdp      svi_total += size;
49089857Sobrien
49138889Sjdp      if (bfd_section_vma (file, sec) > svi_maxvma)
49238889Sjdp	svi_maxvma = bfd_section_vma (file, sec);
49338889Sjdp    }
49438889Sjdp}
49538889Sjdp
49638889Sjdpstatic void
497130561Sobriensysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
498130561Sobrien		       void *ignore ATTRIBUTE_UNUSED)
49933965Sjdp{
50033965Sjdp  bfd_size_type size = bfd_section_size (file, sec);
50189857Sobrien
50289857Sobrien  if (   ! bfd_is_abs_section (sec)
50389857Sobrien      && ! bfd_is_com_section (sec)
50489857Sobrien      && ! bfd_is_und_section (sec))
50533965Sjdp    {
50633965Sjdp      svi_total += size;
50733965Sjdp
50838889Sjdp      printf ("%-*s   ", svi_namelen, bfd_section_name (file, sec));
50938889Sjdp      rprint_number (svi_sizelen, size);
51038889Sjdp      printf ("   ");
51138889Sjdp      rprint_number (svi_vmalen, bfd_section_vma (file, sec));
51233965Sjdp      printf ("\n");
51333965Sjdp    }
51433965Sjdp}
51533965Sjdp
51633965Sjdpstatic void
517130561Sobrienprint_sysv_format (bfd *file)
51833965Sjdp{
51989857Sobrien  /* Size all of the columns.  */
52033965Sjdp  svi_total = 0;
52138889Sjdp  svi_maxvma = 0;
52238889Sjdp  svi_namelen = 0;
523130561Sobrien  bfd_map_over_sections (file, sysv_internal_sizer, NULL);
52438889Sjdp  svi_vmalen = size_number ((bfd_size_type)svi_maxvma);
52589857Sobrien
52638889Sjdp  if ((size_t) svi_vmalen < sizeof ("addr") - 1)
52738889Sjdp    svi_vmalen = sizeof ("addr")-1;
52833965Sjdp
52938889Sjdp  svi_sizelen = size_number (svi_total);
53038889Sjdp  if ((size_t) svi_sizelen < sizeof ("size") - 1)
53138889Sjdp    svi_sizelen = sizeof ("size")-1;
53238889Sjdp
53338889Sjdp  svi_total = 0;
53433965Sjdp  printf ("%s  ", bfd_get_filename (file));
53589857Sobrien
53633965Sjdp  if (bfd_my_archive (file))
53733965Sjdp    printf (" (ex %s)", bfd_get_filename (bfd_my_archive (file)));
53833965Sjdp
53938889Sjdp  printf (":\n%-*s   %*s   %*s\n", svi_namelen, "section",
54038889Sjdp	  svi_sizelen, "size", svi_vmalen, "addr");
54189857Sobrien
542130561Sobrien  bfd_map_over_sections (file, sysv_internal_printer, NULL);
54333965Sjdp
54438889Sjdp  printf ("%-*s   ", svi_namelen, "Total");
54538889Sjdp  rprint_number (svi_sizelen, svi_total);
54633965Sjdp  printf ("\n\n");
54733965Sjdp}
54833965Sjdp
54933965Sjdpstatic void
550130561Sobrienprint_sizes (bfd *file)
55133965Sjdp{
55233965Sjdp  if (berkeley_format)
55333965Sjdp    print_berkeley_format (file);
55433965Sjdp  else
55533965Sjdp    print_sysv_format (file);
55633965Sjdp}
557