X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldlang.c;h=0d6419d91ddaadc7d5449bd7ddcb77f8fc35d7d3;hb=00e52e5376c7ec604a739e6242e6be36221162d7;hp=c96c21fd4ee0dd2e513408d3049560478bf1a632;hpb=0e5fabeb2c4b90857403995e14550210fe1cae71;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldlang.c b/ld/ldlang.c index c96c21fd4e..0d6419d91d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3413,6 +3413,55 @@ lang_place_undefineds (void) insert_undefined (ptr->name); } +/* Structure used to build the list of symbols that the user has required + be defined. */ + +struct require_defined_symbol +{ + const char *name; + struct require_defined_symbol *next; +}; + +/* The list of symbols that the user has required be defined. */ + +static struct require_defined_symbol *require_defined_symbol_list; + +/* Add a new symbol NAME to the list of symbols that are required to be + defined. */ + +void +ldlang_add_require_defined (const char * const name) +{ + struct require_defined_symbol *ptr; + + ldlang_add_undef (name, TRUE); + ptr = (struct require_defined_symbol *) stat_alloc (sizeof (*ptr)); + ptr->next = require_defined_symbol_list; + ptr->name = strdup (name); + require_defined_symbol_list = ptr; +} + +/* Check that all symbols the user required to be defined, are defined, + raise an error if we find a symbol that is not defined. */ + +static void +ldlang_check_require_defined_symbols (void) +{ + struct require_defined_symbol *ptr; + + for (ptr = require_defined_symbol_list; ptr != NULL; ptr = ptr->next) + { + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, ptr->name, + FALSE, FALSE, TRUE); + if (h == NULL + || (h->type != bfd_link_hash_defined + && h->type != bfd_link_hash_defweak)) + einfo(_("%P%X: required symbol `%s' not defined\n"), ptr->name); + } +} + /* Check for all readonly or some readwrite sections. */ static void @@ -6805,6 +6854,9 @@ lang_process (void) if (command_line.check_section_addresses) lang_check_section_addresses (); + /* Check any required symbols are known. */ + ldlang_check_require_defined_symbols (); + lang_end (); } @@ -8133,3 +8185,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 ("%10" BFD_VMA_FMT "u GB", sz >> 30); + else if ((sz & 0xfffff) == 0) + printf ("%10" BFD_VMA_FMT "u MB", sz >> 20); + else if ((sz & 0x3ff) == 0) + printf ("%10" BFD_VMA_FMT "u KB", sz >> 10); + else + printf (" %10" 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 Used Size Region Size %%age Used\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); + } +}