From 06e77878ef2b6a57ef92c1691b3aeb668dc248ba Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 24 Oct 2005 17:51:42 +0000 Subject: gas/ChangeLog: * read.c (potable): Add weakref. (s_weakref): New. * read.h (s_weakref): Declare. * struc-symbol.h (struct symbol): Add sy_weakrefr and sy_weakrefd. * symbols.c (colon): Clear weakrefr. (symbol_find_exact): Rename to, and reimplement in terms of... (symbol_find_exact_noref): ... new function. (symbol_find): Likewise... (symbol_find_noref): ... ditto. (resolve_symbol_value): Resolve weakrefr without setting their values. (S_SET_WEAK): Call hook. (S_GET_VALUE): Follow weakref link. (S_SET_VALUE): Clear weakrefr. (S_IS_WEAK): Follow weakref link. (S_IS_WEAKREFR, S_SET_WEAKREFR, S_CLEAR_WEAKREFR): New. (S_IS_WEAKREFD, S_SET_WEAKREFD, S_CLEAR_WEAKREFD): New. (symbol_set_value_expression, symbol_set_frag): Clear weakrefr. (symbol_mark_used): Follow weakref link. (print_symbol_value_1): Print weak, weakrefr and weakrefd. * symbols.h (symbol_find_noref, symbol_find_exact_noref): Declare. (S_IS_WEAKREFR, S_SET_WEAKREFR, S_CLEAR_WEAKREFR): Declare. (S_IS_WEAKREFD, S_SET_WEAKREFD, S_CLEAR_WEAKREFD): Declare. * write.c (adust_reloc_syms): Follow weakref link. Do not complain if target is undefined. (write_object_file): Likewise. Remove weakrefr symbols. Drop unreferenced weakrefd symbols. * config/obj-coff.c (obj_frob_symbol): Do not force WEAKREFD symbols EXTERNAL. (pecoff_obj_set_weak_hook, pecoff_obj_clear_weak_hook): New. * config/obj-coff.h (obj_set_weak_hook, obj_clear_weak_hook): Define. * doc/as.texinfo: Document weakref. * doc/internals.texi: Document new struct members, internal functions and hooks. gas/testsuite/ChangeLog: * gas/all/weakref1.s, gas/all/weakref1.d: New test. * gas/all/weakref1g.d, gas/all/weakref1l.d: New tests. * gas/all/weakref1u.d, gas/all/weakref1w.d: New tests. * gas/all/weakref2.s, gas/all/weakref3.s: New tests. * gas/all/gas.exp: Run new tests. --- gas/config/obj-coff.c | 71 ++++++++++++++++++++++++++++++++++----------------- gas/config/obj-coff.h | 7 +++++ 2 files changed, 54 insertions(+), 24 deletions(-) (limited to 'gas/config') diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 4ea65be..f1446c0 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1055,6 +1055,39 @@ weak_uniquify (const char * name) return ret; } +void +pecoff_obj_set_weak_hook (symbolS *symbolP) +{ + symbolS *alternateP; + + /* See _Microsoft Portable Executable and Common Object + File Format Specification_, section 5.5.3. + Create a symbol representing the alternate value. + coff_frob_symbol will set the value of this symbol from + the value of the weak symbol itself. */ + S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); + S_SET_NUMBER_AUXILIARY (symbolP, 1); + SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY); + + alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP))); + S_SET_EXTERNAL (alternateP); + S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK); + + SA_SET_SYM_TAGNDX (symbolP, alternateP); +} + +void +pecoff_obj_clear_weak_hook (symbolS *symbolP) +{ + symbolS *alternateP; + + S_SET_STORAGE_CLASS (symbolP, 0); + SA_SET_SYM_FSIZE (symbolP, 0); + + alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP))); + S_CLEAR_EXTERNAL (alternateP); +} + #endif /* TE_PE */ /* Handle .weak. This is a GNU extension in formats other than PE. */ @@ -1065,9 +1098,6 @@ obj_coff_weak (int ignore ATTRIBUTE_UNUSED) char *name; int c; symbolS *symbolP; -#ifdef TE_PE - symbolS *alternateP; -#endif do { @@ -1085,23 +1115,6 @@ obj_coff_weak (int ignore ATTRIBUTE_UNUSED) SKIP_WHITESPACE (); S_SET_WEAK (symbolP); -#ifdef TE_PE - /* See _Microsoft Portable Executable and Common Object - File Format Specification_, section 5.5.3. - Create a symbol representing the alternate value. - coff_frob_symbol will set the value of this symbol from - the value of the weak symbol itself. */ - S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); - S_SET_NUMBER_AUXILIARY (symbolP, 1); - SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY); - - alternateP = symbol_find_or_make (weak_name2altname (name)); - S_SET_EXTERNAL (alternateP); - S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK); - - SA_SET_SYM_TAGNDX (symbolP, alternateP); -#endif - if (c == ',') { input_line_pointer++; @@ -1157,12 +1170,19 @@ coff_frob_symbol (symbolS *symp, int *punt) { /* This is a weak alternate symbol. All processing of PECOFFweak symbols is done here, through the alternate. */ - symbolS *weakp = symbol_find (weak_altname2name (S_GET_NAME (symp))); + symbolS *weakp = symbol_find_noref (weak_altname2name + (S_GET_NAME (symp)), 1); assert (weakp); assert (S_GET_NUMBER_AUXILIARY (weakp) == 1); - if (symbol_equated_p (weakp)) + if (! S_IS_WEAK (weakp)) + { + /* The symbol was turned from weak to strong. Discard altname. */ + *punt = 1; + return; + } + else if (symbol_equated_p (weakp)) { /* The weak symbol has an alternate specified; symp is unneeded. */ S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); @@ -1225,7 +1245,7 @@ coff_frob_symbol (symbolS *symp, int *punt) && !SF_GET_STATICS (symp) && S_GET_STORAGE_CLASS (symp) != C_LABEL && symbol_constant_p (symp) - && (real = symbol_find (S_GET_NAME (symp))) + && (real = symbol_find_noref (S_GET_NAME (symp), 1)) && S_GET_STORAGE_CLASS (real) == C_NULL && real != symp) { @@ -1237,7 +1257,10 @@ coff_frob_symbol (symbolS *symp, int *punt) if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp)) { assert (S_GET_VALUE (symp) == 0); - S_SET_EXTERNAL (symp); + if (S_IS_WEAKREFD (symp)) + *punt = 1; + else + S_SET_EXTERNAL (symp); } else if (S_GET_STORAGE_CLASS (symp) == C_NULL) { diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index c6b4e63..81577c8 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -157,6 +157,9 @@ #ifdef TE_PE /* PE weak symbols need USE_UNIQUE. */ #define USE_UNIQUE 1 + +#define obj_set_weak_hook pecoff_obj_set_weak_hook +#define obj_clear_weak_hook pecoff_obj_clear_weak_hook #endif #ifndef OBJ_COFF_MAX_AUXENTRIES @@ -384,6 +387,10 @@ extern void coff_adjust_section_syms (bfd *, asection *, void *); extern void coff_frob_file_after_relocs (void); extern void coff_obj_symbol_new_hook (symbolS *); extern void coff_obj_read_begin_hook (void); +#ifdef TE_PE +extern void pecoff_obj_set_weak_hook (symbolS *); +extern void pecoff_obj_clear_weak_hook (symbolS *); +#endif extern void obj_coff_section (int); extern segT obj_coff_add_segment (const char *); extern void obj_coff_section (int); -- cgit v1.1