This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch]: ld - add --print-memory-usage option


Hello,

this patch adds a new linker option to display memory usage on the target.
This feature is useful for embedded targets when you need to monitor the
amount of free memory.  As far as I know there is no binutils tool for that:
the output of size is too rough, and the output of 'objdump -hâ is not clear
enough.  Here is an example of output:

Memory region           size  total size  Ratio
           FLASH:     1524 B        3 MB    0.05%
            SRAM:    22536 B      256 KB    8.60%
           SDRAM:        0 GB       8 MB    0.00%

The names of memory region directly comes from the linker script.

No regression on arm-elf.

Is it OK for trunk ?

Tristan.

ld/
2015-06-05  Tristan Gingold  <gingold@adacore.com>

	* NEWS: Mention new option.
	* lexsup.c (parse_args): Handle --print-memory-usage.
	(ld_options): Add --print-memory-usage.
	* ldmain.c (main): Call lang_print_memory_usage.
	* ldlex.h (enum option_values): Add OPTION_PRINT_MEMORY_USAGE.
	* ldlang.h: Add prototype of lang_print_memory_usage.
	* ldlang.c (lang_print_memory_size, lang_print_memory_usage): New
	functions.
	* ld.texinfo (Options): Document --print-memory-usage.
	* ld.h (args_type): Add print_memory_usage field.

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 84c268a..c5f1d1e 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,16 @@
+2015-06-05  Tristan Gingold  <gingold@adacore.com>
+
+	* NEWS: Mention new option.
+	* lexsup.c (parse_args): Handle --print-memory-usage.
+	(ld_options): Add --print-memory-usage.
+	* ldmain.c (main): Call lang_print_memory_usage.
+	* ldlex.h (enum option_values): Add OPTION_PRINT_MEMORY_USAGE.
+	* ldlang.h: Add prototype of lang_print_memory_usage.
+	* ldlang.c (lang_print_memory_size, lang_print_memory_usage): New
+	functions.
+	* ld.texinfo (Options): Document --print-memory-usage.
+	* ld.h (args_type): Add print_memory_usage field.
+
 2015-05-28  Catherine Moore  <clm@codesourcery.com>
 	    Paul Brook <paul@codesourcery.com>
 
diff --git a/ld/NEWS b/ld/NEWS
index 4e84d5a..140d3c9 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -7,6 +7,8 @@
 
 * Add support for LLVM plugin.
 
+* Add --print-memory-usage option to report memory blocks usage.
+
 Changes in 2.25:
 
 * PE binaries now once again contain real timestamps by default.  To disable
diff --git a/ld/ld.h b/ld/ld.h
index f804f9c..e6ebaae 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -161,6 +161,9 @@ typedef struct {
   /* If TRUE we'll just print the default output on stdout.  */
   bfd_boolean print_output_format;
 
+  /* If set, display the target memory usage (per memory region).  */
+  bfd_boolean print_memory_usage;
+
   /* Big or little endian as set on command line.  */
   enum endian_enum endian;
 
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 0c5f884..c925f81 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1472,6 +1472,13 @@ Print the name of the default output format (perhaps influenced by
 other command-line options).  This is the string that would appear
 in an @code{OUTPUT_FORMAT} linker script command (@pxref{File Commands}).
 
+@kindex --print-memory-usage
+@cindex memory usage
+@item --print-memory-usage
+Print used size, total size and used size of memory regions created with
+the @ref{MEMORY} command.  This is useful on embedded targets to have a
+quick view of amount of free memory.
+
 @cindex help
 @cindex usage
 @kindex --help
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c96c21f..e7414b1 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -8133,3 +8133,41 @@ lang_ld_feature (char *str)
       p = q;
     }
 }
+
+/* Pretty print memory amount.  */
+
+static void
+lang_print_memory_size (bfd_vma sz)
+{
+  if ((sz & 0x3fffffff) == 0)
+    printf ("%8" BFD_VMA_FMT "u GB", sz >> 30);
+  else if ((sz & 0xfffff) == 0)
+    printf ("%8" BFD_VMA_FMT "u MB", sz >> 20);
+  else if ((sz & 0x3ff) == 0)
+    printf ("%8" BFD_VMA_FMT "u KB", sz >> 10);
+  else
+    printf ("%8" BFD_VMA_FMT "u B ", sz);
+}
+
+/* Implement --print-memory-usage: disply per region memory usage.  */
+
+void
+lang_print_memory_usage (void)
+{
+  lang_memory_region_type *r;
+
+  printf ("Memory region           size  total size  Ratio\n");
+  for (r = lang_memory_region_list; r->next != NULL; r = r->next)
+    {
+      bfd_vma used_length = r->current - r->origin;
+      double percent;
+
+      printf ("%16s: ",r->name_list.name);
+      lang_print_memory_size (used_length);
+      lang_print_memory_size ((bfd_vma) r->length);
+
+      percent = used_length * 100.0 / r->length;
+
+      printf ("  %6.2f%%\n", percent);
+    }
+}
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 7cb7610..475cf71 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -688,4 +688,7 @@ ldlang_override_segment_assignment
 extern void
 lang_ld_feature (char *);
 
+extern void
+lang_print_memory_usage (void);
+
 #endif
diff --git a/ld/ldlex.h b/ld/ldlex.h
index f174c28..7885de0 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -142,6 +142,7 @@ enum option_values
   OPTION_IGNORE_UNRESOLVED_SYMBOL,
   OPTION_PUSH_STATE,
   OPTION_POP_STATE,
+  OPTION_PRINT_MEMORY_USAGE,
 };
 
 /* The initial parser states.  */
diff --git a/ld/ldmain.c b/ld/ldmain.c
index a7b72bd..0492034 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -440,6 +440,8 @@ main (int argc, char **argv)
     output_cref (config.map_file != NULL ? config.map_file : stdout);
   if (nocrossref_list != NULL)
     check_nocrossrefs ();
+  if (command_line.print_memory_usage)
+    lang_print_memory_usage ();
 #if 0
   {
     struct bfd_link_hash_entry * h;
diff --git a/ld/lexsup.c b/ld/lexsup.c
index b618241..b884d9a 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -523,6 +523,8 @@ static const struct ld_option ld_options[] =
   { {"pop-state", no_argument, NULL, OPTION_POP_STATE},
     '\0', NULL, N_("Pop state of flags governing input file handling"),
     TWO_DASHES },
+  { {"print-memory-usage", no_argument, NULL, OPTION_PRINT_MEMORY_USAGE},
+    '\0', NULL, N_("Report target memory usage"), TWO_DASHES },
 };
 
 #define OPTION_COUNT ARRAY_SIZE (ld_options)
@@ -1490,6 +1492,10 @@ parse_args (unsigned argc, char **argv)
 	      free (oldp);
 	    }
 	  break;
+
+	case OPTION_PRINT_MEMORY_USAGE:
+	  command_line.print_memory_usage = TRUE;
+	  break;
 	}
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]