diff options
Diffstat (limited to 'ld/emultempl/lnk960.em')
-rw-r--r-- | ld/emultempl/lnk960.em | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/ld/emultempl/lnk960.em b/ld/emultempl/lnk960.em index 7120329..e556d43 100644 --- a/ld/emultempl/lnk960.em +++ b/ld/emultempl/lnk960.em @@ -130,15 +130,73 @@ lnk960_after_parse (void) add_on (syslib_list, lang_input_file_is_search_file_enum); } +/* Create a symbol with the given name with the value of the + address of first byte of the section named. + + If the symbol already exists, then do nothing. */ + +static void +symbol_at_beginning_of (const char *secname, const char *name) +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE); + if (h == NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + + if (h->type == bfd_link_hash_new + || h->type == bfd_link_hash_undefined) + { + asection *sec; + + h->type = bfd_link_hash_defined; + + sec = bfd_get_section_by_name (link_info.output_bfd, secname); + if (sec == NULL) + sec = bfd_abs_section_ptr; + h->u.def.value = 0; + h->u.def.section = sec; + } +} + +/* Create a symbol with the given name with the value of the + address of the first byte after the end of the section named. + + If the symbol already exists, then do nothing. */ + +static void +symbol_at_end_of (const char *secname, const char *name) +{ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (link_info.hash, name, TRUE, TRUE, TRUE); + if (h == NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + + if (h->type == bfd_link_hash_new + || h->type == bfd_link_hash_undefined) + { + asection *sec; + + h->type = bfd_link_hash_defined; + + sec = bfd_get_section_by_name (link_info.output_bfd, secname); + if (sec == NULL) + sec = bfd_abs_section_ptr; + h->u.def.value = sec->size; + h->u.def.section = sec; + } +} + static void lnk960_after_allocation (void) { if (!link_info.relocatable) { - lang_abs_symbol_at_end_of (".text", "_etext"); - lang_abs_symbol_at_end_of (".data", "_edata"); - lang_abs_symbol_at_beginning_of (".bss", "_bss_start"); - lang_abs_symbol_at_end_of (".bss", "_end"); + symbol_at_end_of (".text", "_etext"); + symbol_at_end_of (".data", "_edata"); + symbol_at_beginning_of (".bss", "_bss_start"); + symbol_at_end_of (".bss", "_end"); } } |