Warn for ar/nm/ranlib/ld on lto objects without plugin
[deliverable/binutils-gdb.git] / binutils / size.c
index 1e1dc39b419427ea1e8bde3bb02da3692c3cd22e..e727165f019ae0fa692b7a50ec337889cfed6c5a 100644 (file)
@@ -1,12 +1,11 @@
 /* size.c -- report size of various sections of an executable file.
 /* size.c -- report size of various sections of an executable file.
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1991-2014 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,7 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 \f
 /* Extensions/incompatibilities:
    o - BSD output has filenames at the end.
 \f
 /* Extensions/incompatibilities:
    o - BSD output has filenames at the end.
    If you write shell scripts which manipulate this info then you may be
    out of luck; there's no --compatibility or --pedantic option.  */
 
    If you write shell scripts which manipulate this info then you may be
    out of luck; there's no --compatibility or --pedantic option.  */
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "bfd.h"
-#include "bucomm.h"
 #include "libiberty.h"
 #include "getopt.h"
 #include "libiberty.h"
 #include "getopt.h"
+#include "bucomm.h"
 
 #ifndef BSD_DEFAULT
 #define BSD_DEFAULT 1
 
 #ifndef BSD_DEFAULT
 #define BSD_DEFAULT 1
@@ -39,7 +40,7 @@
 
 /* Program options.  */
 
 
 /* Program options.  */
 
-enum
+static enum
   {
     decimal, octal, hex
   }
   {
     decimal, octal, hex
   }
@@ -48,33 +49,26 @@ radix = decimal;
 /* 0 means use AT&T-style output.  */
 static int berkeley_format = BSD_DEFAULT;
 
 /* 0 means use AT&T-style output.  */
 static int berkeley_format = BSD_DEFAULT;
 
-int show_version = 0;
-int show_help = 0;
-int show_totals = 0;
+static int show_version = 0;
+static int show_help = 0;
+static int show_totals = 0;
+static int show_common = 0;
 
 
+static bfd_size_type common_size;
 static bfd_size_type total_bsssize;
 static bfd_size_type total_datasize;
 static bfd_size_type total_textsize;
 
 /* Program exit status.  */
 static bfd_size_type total_bsssize;
 static bfd_size_type total_datasize;
 static bfd_size_type total_textsize;
 
 /* Program exit status.  */
-int return_code = 0;
+static int return_code = 0;
 
 static char *target = NULL;
 
 
 static char *target = NULL;
 
-/* Static declarations.  */
+/* Forward declarations.  */
 
 
-static void usage (FILE *, int);
 static void display_file (char *);
 static void display_file (char *);
-static void display_bfd (bfd *);
-static void display_archive (bfd *);
-static int size_number (bfd_size_type);
 static void rprint_number (int, bfd_size_type);
 static void rprint_number (int, bfd_size_type);
-static void print_berkeley_format (bfd *);
-static void sysv_internal_sizer (bfd *, asection *, void *);
-static void sysv_internal_printer (bfd *, asection *, void *);
-static void print_sysv_format (bfd *);
 static void print_sizes (bfd * file);
 static void print_sizes (bfd * file);
-static void berkeley_sum (bfd *, sec_ptr, void *);
 \f
 static void
 usage (FILE *stream, int status)
 \f
 static void
 usage (FILE *stream, int status)
@@ -86,7 +80,9 @@ usage (FILE *stream, int status)
   -A|-B     --format={sysv|berkeley}  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\
   -A|-B     --format={sysv|berkeley}  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\
             --target=<bfdname>        Set the binary file format\n\
             --target=<bfdname>        Set the binary file format\n\
+            @<file>                   Read options from <file>\n\
   -h        --help                    Display this information\n\
   -v        --version                 Display the program's version\n\
 \n"),
   -h        --help                    Display this information\n\
   -v        --version                 Display the program's version\n\
 \n"),
@@ -97,16 +93,21 @@ usage (FILE *stream, int status)
 #endif
 );
   list_supported_targets (program_name, stream);
 #endif
 );
   list_supported_targets (program_name, stream);
-  if (status == 0)
+  if (REPORT_BUGS_TO[0] && status == 0)
     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
   exit (status);
 }
 
     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
   exit (status);
 }
 
+#define OPTION_FORMAT (200)
+#define OPTION_RADIX (OPTION_FORMAT + 1)
+#define OPTION_TARGET (OPTION_RADIX + 1)
+
 static struct option long_options[] =
 {
 static struct option long_options[] =
 {
-  {"format", required_argument, 0, 200},
-  {"radix", required_argument, 0, 201},
-  {"target", required_argument, 0, 202},
+  {"common", no_argument, &show_common, 1},
+  {"format", required_argument, 0, OPTION_FORMAT},
+  {"radix", required_argument, 0, OPTION_RADIX},
+  {"target", required_argument, 0, OPTION_TARGET},
   {"totals", no_argument, &show_totals, 1},
   {"version", no_argument, &show_version, 1},
   {"help", no_argument, &show_help, 1},
   {"totals", no_argument, &show_totals, 1},
   {"version", no_argument, &show_version, 1},
   {"help", no_argument, &show_help, 1},
@@ -133,6 +134,8 @@ main (int argc, char **argv)
   program_name = *argv;
   xmalloc_set_program_name (program_name);
 
   program_name = *argv;
   xmalloc_set_program_name (program_name);
 
+  expandargv (&argc, &argv);
+
   bfd_init ();
   set_default_bfd_target ();
 
   bfd_init ();
   set_default_bfd_target ();
 
@@ -140,7 +143,7 @@ main (int argc, char **argv)
                           (int *) 0)) != EOF)
     switch (c)
       {
                           (int *) 0)) != EOF)
     switch (c)
       {
-      case 200:                /* --format */
+      case OPTION_FORMAT:
        switch (*optarg)
          {
          case 'B':
        switch (*optarg)
          {
          case 'B':
@@ -157,11 +160,11 @@ main (int argc, char **argv)
          }
        break;
 
          }
        break;
 
-      case 202:                /* --target */
+      case OPTION_TARGET:
        target = optarg;
        break;
 
        target = optarg;
        break;
 
-      case 201:                /* --radix */
+      case OPTION_RADIX:
 #ifdef ANSI_LIBRARIES
        temp = strtol (optarg, NULL, 10);
 #else
 #ifdef ANSI_LIBRARIES
        temp = strtol (optarg, NULL, 10);
 #else
@@ -252,6 +255,39 @@ main (int argc, char **argv)
   return return_code;
 }
 \f
   return return_code;
 }
 \f
+/* Total size required for common symbols in ABFD.  */
+
+static void
+calculate_common_size (bfd *abfd)
+{
+  asymbol **syms = NULL;
+  long storage, symcount;
+
+  common_size = 0;
+  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC | HAS_SYMS)) != HAS_SYMS)
+    return;
+
+  storage = bfd_get_symtab_upper_bound (abfd);
+  if (storage < 0)
+    bfd_fatal (bfd_get_filename (abfd));
+  if (storage)
+    syms = (asymbol **) xmalloc (storage);
+
+  symcount = bfd_canonicalize_symtab (abfd, syms);
+  if (symcount < 0)
+    bfd_fatal (bfd_get_filename (abfd));
+
+  while (--symcount >= 0)
+    {
+      asymbol *sym = syms[symcount];
+
+      if (bfd_is_com_section (sym->section)
+         && (sym->flags & BSF_SECTION_SYM) == 0)
+       common_size += sym->value;
+    }
+  free (syms);
+}
+
 /* Display stats on file or archive member ABFD.  */
 
 static void
 /* Display stats on file or archive member ABFD.  */
 
 static void
@@ -343,7 +379,10 @@ display_file (char *filename)
   bfd *file;
 
   if (get_file_size (filename) < 1)
   bfd *file;
 
   if (get_file_size (filename) < 1)
-    return;
+    {
+      return_code = 1;
+      return;
+    }
 
   file = bfd_openr (filename, target);
   if (file == NULL)
 
   file = bfd_openr (filename, target);
   if (file == NULL)
@@ -366,17 +405,15 @@ display_file (char *filename)
     }
 }
 \f
     }
 }
 \f
-/* This is what lexical functions are for.  */
-
 static int
 size_number (bfd_size_type num)
 {
   char buffer[40];
 
   sprintf (buffer,
 static int
 size_number (bfd_size_type num)
 {
   char buffer[40];
 
   sprintf (buffer,
-          (radix == decimal ? "%lu" :
-          ((radix == octal) ? "0%lo" : "0x%lx")),
-          (unsigned long) num);
+          (radix == decimal ? "%" BFD_VMA_FMT "u" :
+          ((radix == octal) ? "0%" BFD_VMA_FMT "o" : "0x%" BFD_VMA_FMT "x")),
+          num);
 
   return strlen (buffer);
 }
 
   return strlen (buffer);
 }
@@ -387,9 +424,9 @@ rprint_number (int width, bfd_size_type num)
   char buffer[40];
 
   sprintf (buffer,
   char buffer[40];
 
   sprintf (buffer,
-          (radix == decimal ? "%lu" :
-          ((radix == octal) ? "0%lo" : "0x%lx")),
-          (unsigned long) num);
+          (radix == decimal ? "%" BFD_VMA_FMT "u" :
+          ((radix == octal) ? "0%" BFD_VMA_FMT "o" : "0x%" BFD_VMA_FMT "x")),
+          num);
 
   printf ("%*s", width, buffer);
 }
 
   printf ("%*s", width, buffer);
 }
@@ -430,6 +467,7 @@ print_berkeley_format (bfd *abfd)
 
   bfd_map_over_sections (abfd, berkeley_sum, NULL);
 
 
   bfd_map_over_sections (abfd, berkeley_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 (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");
@@ -486,6 +524,16 @@ sysv_internal_sizer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
     }
 }
 
     }
 }
 
+static void
+sysv_one_line (const char *name, bfd_size_type size, bfd_vma vma)
+{
+  printf ("%-*s   ", svi_namelen, name);
+  rprint_number (svi_sizelen, size);
+  printf ("   ");
+  rprint_number (svi_vmalen, vma);
+  printf ("\n");
+}
+
 static void
 sysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
                       void *ignore ATTRIBUTE_UNUSED)
 static void
 sysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
                       void *ignore ATTRIBUTE_UNUSED)
@@ -498,11 +546,9 @@ sysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
     {
       svi_total += size;
 
     {
       svi_total += size;
 
-      printf ("%-*s   ", svi_namelen, bfd_section_name (file, sec));
-      rprint_number (svi_sizelen, size);
-      printf ("   ");
-      rprint_number (svi_vmalen, bfd_section_vma (file, sec));
-      printf ("\n");
+      sysv_one_line (bfd_section_name (file, sec),
+                    size,
+                    bfd_section_vma (file, sec));
     }
 }
 
     }
 }
 
@@ -514,6 +560,13 @@ print_sysv_format (bfd *file)
   svi_maxvma = 0;
   svi_namelen = 0;
   bfd_map_over_sections (file, sysv_internal_sizer, NULL);
   svi_maxvma = 0;
   svi_namelen = 0;
   bfd_map_over_sections (file, sysv_internal_sizer, NULL);
+  if (show_common)
+    {
+      if (svi_namelen < (int) sizeof ("*COM*") - 1)
+       svi_namelen = sizeof ("*COM*") - 1;
+      svi_total += common_size;
+    }
+
   svi_vmalen = size_number ((bfd_size_type)svi_maxvma);
 
   if ((size_t) svi_vmalen < sizeof ("addr") - 1)
   svi_vmalen = size_number ((bfd_size_type)svi_maxvma);
 
   if ((size_t) svi_vmalen < sizeof ("addr") - 1)
@@ -533,6 +586,11 @@ print_sysv_format (bfd *file)
          svi_sizelen, "size", svi_vmalen, "addr");
 
   bfd_map_over_sections (file, sysv_internal_printer, NULL);
          svi_sizelen, "size", svi_vmalen, "addr");
 
   bfd_map_over_sections (file, sysv_internal_printer, NULL);
+  if (show_common)
+    {
+      svi_total += common_size;
+      sysv_one_line ("*COM*", common_size, 0);
+    }
 
   printf ("%-*s   ", svi_namelen, "Total");
   rprint_number (svi_sizelen, svi_total);
 
   printf ("%-*s   ", svi_namelen, "Total");
   rprint_number (svi_sizelen, svi_total);
@@ -542,6 +600,8 @@ print_sysv_format (bfd *file)
 static void
 print_sizes (bfd *file)
 {
 static void
 print_sizes (bfd *file)
 {
+  if (show_common)
+    calculate_common_size (file);
   if (berkeley_format)
     print_berkeley_format (file);
   else
   if (berkeley_format)
     print_berkeley_format (file);
   else
This page took 0.026793 seconds and 4 git commands to generate.