diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a734dfe398..25c2fde0e9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,37 @@ +2009-03-14 Richard Sandiford + + * coffcode.h (coff_pointerize_aux_hook): Update CSECT_SYM_P to + check whether a symbol has csect information. + (coff_print_aux): Likewise. + * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Handle auxillary csect + information for C_AIX_WEAKEXT too. + (_bfd_xcoff_swap_aux_out): Likewise. + (xcoff_reloc_type_br): Handle defweak symbols too. + * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Handle auxillary csect + information for C_AIX_WEAKEXT too. + (_bfd_xcoff64_swap_aux_out): Likewise. + (xcoff64_reloc_type_br): Handle defweak symbols too. + * coffgen.c (coff_print_symbol): Handle auxillary function + information for C_AIX_WEAKEXT too. + * xcofflink.c (_bfd_xcoff_canonicalize_dynamic_symtab): Set BSF_WEAK + instead of BSF_GLOBAL if the L_WEAK flag is set. + (xcoff_dynamic_definition_p): New function. + (xcoff_link_add_dynamic_symbols): Use it to decide whether ldsym + defines h. Don't change h if ldsym isn't the definition. Otherwise, + always take the symbol class from the ldsym. Use weak bfd symbol + types for weak ldsyms. + (xcoff_link_add_symbols): Use CSECT_SYM_P and EXTERN_SYM_P. + Fix the check for whether a definition is from a shared object. + Allow redefinitions of weak symbols. + (xcoff_link_check_ar_symbols): Use EXTERN_SYM_P. + (xcoff_keep_symbol_p): Likewise. + (bfd_xcoff_size_dynamic_sections): Use CSECT_SYM_P. + (xcoff_link_input_bfd): Use CSECT_SYM_P and EXTERN_SYM_P. + Add .loader entries for C_AIX_WEAKEXT as well as C_EXT symbols, + but mark them as L_WEAK. + (xcoff_write_global_symbol): Treat weak symbols as C_AIX_WEAKEXT + instead of C_EXT if C_AIX_WEAKEXT == C_WEAKEXT. + 2009-03-14 Richard Sandiford * xcofflink.c (xcoff_mark): When walking the relocations, diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 70024851ec..334353056f 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -422,6 +422,7 @@ _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) /* RS/6000 "csect" auxents */ case C_EXT: + case C_AIX_WEAKEXT: case C_HIDEXT: if (indx + 1 == numaux) { @@ -531,6 +532,7 @@ _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) /* RS/6000 "csect" auxents */ case C_EXT: + case C_AIX_WEAKEXT: case C_HIDEXT: if (indx + 1 == numaux) { @@ -2963,7 +2965,8 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, going to global linkage code, we can replace the load with a cror. */ if (NULL != h - && bfd_link_hash_defined == h->root.type + && (bfd_link_hash_defined == h->root.type + || bfd_link_hash_defweak == h->root.type) && section_offset + 8 <= input_section->size) { bfd_byte *pnext; @@ -3008,7 +3011,8 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, howto->dst_mask = howto->src_mask; if (h != NULL - && h->root.type == bfd_link_hash_defined + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) && bfd_is_abs_section (h->root.u.def.section) && section_offset + 4 <= input_section->size) { diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 6be1583a4b..1a0ff59713 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -381,6 +381,7 @@ _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) /* RS/6000 "csect" auxents */ case C_EXT: + case C_AIX_WEAKEXT: case C_HIDEXT: if (indx + 1 == numaux) { @@ -473,6 +474,7 @@ _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) /* RS/6000 "csect" auxents */ case C_EXT: + case C_AIX_WEAKEXT: case C_HIDEXT: if (indx + 1 == numaux) { @@ -1133,7 +1135,8 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, going to global linkage code, we can replace the load with a cror. */ if (NULL != h - && bfd_link_hash_defined == h->root.type + && (bfd_link_hash_defined == h->root.type + || bfd_link_hash_defweak == h->root.type) && section_offset + 8 <= input_section->size) { bfd_byte *pnext; @@ -1176,7 +1179,8 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto, howto->dst_mask = howto->src_mask; if (h != NULL - && h->root.type == bfd_link_hash_defined + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) && bfd_is_abs_section (h->root.u.def.section) && section_offset + 4 <= input_section->size) { diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 59bb223521..44ac08008d 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2416,7 +2416,7 @@ symname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym) #define FORCE_SYMNAMES_IN_STRINGS #endif -/* Handle the csect auxent of a C_EXT or C_HIDEXT symbol. */ +/* Handle the csect auxent of a C_EXT, C_AIX_WEAKEXT or C_HIDEXT symbol. */ static bfd_boolean coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, @@ -2427,7 +2427,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED, { int class = symbol->u.syment.n_sclass; - if ((class == C_EXT || class == C_HIDEXT) + if (CSECT_SYM_P (class) && indaux + 1 == symbol->u.syment.n_numaux) { if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) @@ -2485,8 +2485,7 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED, unsigned int indaux ATTRIBUTE_UNUSED) { #ifdef RS6000COFF_C - if ((symbol->u.syment.n_sclass == C_EXT - || symbol->u.syment.n_sclass == C_HIDEXT) + if (CSECT_SYM_P (symbol->u.syment.n_sclass) && indaux + 1 == symbol->u.syment.n_numaux) { /* This is a csect entry. */ diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 0a1c97c2fa..0faaede68f 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -2006,6 +2006,7 @@ coff_print_symbol (bfd *abfd, } /* Otherwise fall through. */ case C_EXT: + case C_AIX_WEAKEXT: if (ISFCN (combined->u.syment.n_type)) { long next, llnos; diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index cbc750c16d..d87940c395 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -258,7 +258,12 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms) symbuf->symbol.flags = BSF_NO_FLAGS; if ((ldsym.l_smtype & L_EXPORT) != 0) - symbuf->symbol.flags |= BSF_GLOBAL; + { + if ((ldsym.l_smtype & L_WEAK) != 0) + symbuf->symbol.flags |= BSF_WEAK; + else + symbuf->symbol.flags |= BSF_GLOBAL; + } /* FIXME: We have no way to record the other information stored with the loader symbol. */ @@ -540,6 +545,36 @@ xcoff_read_internal_relocs (bfd *abfd, require_internal, internal_relocs); } +/* H is the bfd symbol associated with exported .loader symbol LDSYM. + Return true if LDSYM defines H. */ + +static bfd_boolean +xcoff_dynamic_definition_p (struct xcoff_link_hash_entry *h, + struct internal_ldsym *ldsym) +{ + /* If we didn't know about H before processing LDSYM, LDSYM + definitely defines H. */ + if (h->root.type == bfd_link_hash_new) + return TRUE; + + /* If H is currently a weak dynamic symbol, and if LDSYM is a strong + dynamic symbol, LDSYM trumps the current definition of H. */ + if ((ldsym->l_smtype & L_WEAK) == 0 + && (h->flags & XCOFF_DEF_DYNAMIC) != 0 + && (h->flags & XCOFF_DEF_REGULAR) == 0 + && (h->root.type == bfd_link_hash_defweak + || h->root.type == bfd_link_hash_undefweak)) + return TRUE; + + /* If H is currently undefined, LDSYM defines it. */ + if ((h->flags & XCOFF_DEF_DYNAMIC) == 0 + && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak)) + return TRUE; + + return FALSE; +} + /* This function is used to add symbols from a dynamic object to the global symbol table. */ @@ -638,43 +673,33 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info) if (h == NULL) return FALSE; + if (!xcoff_dynamic_definition_p (h, &ldsym)) + continue; + h->flags |= XCOFF_DEF_DYNAMIC; - - /* If the symbol is undefined, and the BFD it was found in is - not a dynamic object, change the BFD to this dynamic object, - so that we can get the correct import file ID. */ - if ((h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && (h->root.u.undef.abfd == NULL - || (h->root.u.undef.abfd->flags & DYNAMIC) == 0)) - h->root.u.undef.abfd = abfd; - - if (h->root.type == bfd_link_hash_new) - { - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = abfd; - /* We do not want to add this to the undefined symbol list. */ - } - - if (h->smclas == XMC_UA - || h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - h->smclas = ldsym.l_smclas; - - /* Unless this is an XMC_XO symbol, we don't bother to actually - define it, since we don't have a section to put it in anyhow. - Instead, the relocation routines handle the DEF_DYNAMIC flag - correctly. */ - - if (h->smclas == XMC_XO - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) + h->smclas = ldsym.l_smclas; + if (h->smclas == XMC_XO) { /* This symbol has an absolute value. */ - h->root.type = bfd_link_hash_defined; + if ((ldsym.l_smtype & L_WEAK) != 0) + h->root.type = bfd_link_hash_defweak; + else + h->root.type = bfd_link_hash_defined; h->root.u.def.section = bfd_abs_section_ptr; h->root.u.def.value = ldsym.l_value; } + else + { + /* Otherwise, we don't bother to actually define the symbol, + since we don't have a section to put it in anyhow. + We assume instead that an undefined XCOFF_DEF_DYNAMIC symbol + should be imported from the symbol's undef.abfd. */ + if ((ldsym.l_smtype & L_WEAK) != 0) + h->root.type = bfd_link_hash_undefweak; + else + h->root.type = bfd_link_hash_undefined; + h->root.u.undef.abfd = abfd; + } /* If this symbol defines a function descriptor, then it implicitly defines the function code as well. */ @@ -701,33 +726,30 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info) if (hds == NULL) return FALSE; - if (hds->root.type == bfd_link_hash_new) - { - hds->root.type = bfd_link_hash_undefined; - hds->root.u.undef.abfd = abfd; - /* We do not want to add this to the undefined - symbol list. */ - } - hds->descriptor = h; h->descriptor = hds; } - hds->flags |= XCOFF_DEF_DYNAMIC; - if (hds->smclas == XMC_UA) - hds->smclas = XMC_PR; - - /* An absolute symbol appears to actually define code, not a - function descriptor. This is how some math functions are - implemented on AIX 4.1. */ - if (h->smclas == XMC_XO - && (hds->root.type == bfd_link_hash_undefined - || hds->root.type == bfd_link_hash_undefweak)) + if (xcoff_dynamic_definition_p (hds, &ldsym)) { - hds->smclas = XMC_XO; - hds->root.type = bfd_link_hash_defined; - hds->root.u.def.section = bfd_abs_section_ptr; - hds->root.u.def.value = ldsym.l_value; + hds->root.type = h->root.type; + hds->flags |= XCOFF_DEF_DYNAMIC; + if (h->smclas == XMC_XO) + { + /* An absolute symbol appears to actually define code, not a + function descriptor. This is how some math functions are + implemented on AIX 4.1. */ + hds->smclas = XMC_XO; + hds->root.u.def.section = bfd_abs_section_ptr; + hds->root.u.def.value = ldsym.l_value; + } + else + { + hds->smclas = XMC_PR; + hds->root.u.undef.abfd = abfd; + /* We do not want to add this to the undefined + symbol list. */ + } } } } @@ -1087,7 +1109,6 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) const char *name; char buf[SYMNMLEN + 1]; int smtyp; - flagword flags; asection *section; bfd_vma value; struct xcoff_link_hash_entry *set_toc; @@ -1096,7 +1117,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) /* In this pass we are only interested in symbols with csect information. */ - if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT) + if (!CSECT_SYM_P (sym.n_sclass)) { /* Set csect_cache, Normally csect is a .pr, .rw etc. created in the loop @@ -1216,7 +1237,6 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); - flags = BSF_GLOBAL; section = NULL; value = 0; set_toc = NULL; @@ -1327,7 +1347,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) erelsym = ((bfd_byte *) obj_coff_external_syms (abfd) + rel->r_symndx * symesz); bfd_coff_swap_sym_in (abfd, (void *) erelsym, (void *) &relsym); - if (relsym.n_sclass == C_EXT) + if (EXTERN_SYM_P (relsym.n_sclass)) { const char *relname; char relbuf[SYMNMLEN + 1]; @@ -1482,9 +1502,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) if (first_csect == NULL) first_csect = csect; - /* If this symbol is C_EXT, we treat it as starting at the + /* If this symbol is external, we treat it as starting at the beginning of the newly created section. */ - if (sym.n_sclass == C_EXT) + if (EXTERN_SYM_P (sym.n_sclass)) { section = csect; value = 0; @@ -1573,7 +1593,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) if (first_csect == NULL) first_csect = csect; - if (sym.n_sclass == C_EXT) + if (EXTERN_SYM_P (sym.n_sclass)) { csect->flags |= SEC_IS_COMMON; csect->size = 0; @@ -1614,9 +1634,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) /* Now we have enough information to add the symbol to the linker hash table. */ - if (sym.n_sclass == C_EXT) + if (EXTERN_SYM_P (sym.n_sclass)) { bfd_boolean copy; + flagword flags; BFD_ASSERT (section != NULL); @@ -1687,8 +1708,8 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) section = bfd_und_section_ptr; value = 0; } - else if (((*sym_hash)->root.u.def.section->owner->flags - & DYNAMIC) != 0) + else if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0 + && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0) { /* The existing symbol is from a shared library. Replace it. */ @@ -1704,6 +1725,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) section = bfd_und_section_ptr; value = 0; } + else if (sym.n_sclass == C_AIX_WEAKEXT + || (*sym_hash)->root.type == bfd_link_hash_defweak) + { + /* At least one of the definitions is weak. + Allow the normal rules to take effect. */ + } else if ((*sym_hash)->root.u.undef.next != NULL || info->hash->undefs_tail == &(*sym_hash)->root) { @@ -1723,8 +1750,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) } } else if (((*sym_hash)->flags & XCOFF_MULTIPLY_DEFINED) != 0 - && ((*sym_hash)->root.type == bfd_link_hash_defined - || (*sym_hash)->root.type == bfd_link_hash_defweak) + && (*sym_hash)->root.type == bfd_link_hash_defined && (bfd_is_und_section (section) || bfd_is_com_section (section))) { @@ -1759,6 +1785,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) a second time from the csects. */ BFD_ASSERT (last_real->next == first_csect); last_real->next = NULL; + flags = (sym.n_sclass == C_EXT ? BSF_GLOBAL : BSF_WEAK); if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, NULL, copy, TRUE, @@ -2073,7 +2100,7 @@ xcoff_link_check_ar_symbols (bfd *abfd, bfd_coff_swap_sym_in (abfd, (void *) esym, (void *) &sym); - if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF) + if (EXTERN_SYM_P (sym.n_sclass) && sym.n_scnum != N_UNDEF) { const char *name; char buf[SYMNMLEN + 1]; @@ -3070,7 +3097,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd, return 0; /* Discard symbols that are defined elsewhere. */ - if (isym->n_sclass == C_EXT) + if (EXTERN_SYM_P (isym->n_sclass)) { if ((h->flags & XCOFF_ALLOCATED) != 0) return 0; @@ -3081,7 +3108,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd, /* If we're discarding local symbols, check whether ISYM is local. */ smtyp = SMTYP_SMTYP (aux->x_csect.x_smtyp); if (info->discard == discard_all - && isym->n_sclass != C_EXT + && !EXTERN_SYM_P (isym->n_sclass) && (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD)) return 0; @@ -3109,7 +3136,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd, return 0; if (info->discard == discard_l - && isym->n_sclass != C_EXT + && !EXTERN_SYM_P (isym->n_sclass) && (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD) && bfd_is_local_label_name (input_bfd, name)) return 0; @@ -3495,9 +3522,8 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, bfd_coff_swap_sym_in (sub, esym, &sym); - /* If this is a C_EXT or C_HIDEXT symbol, we need the csect - information too. */ - if (sym.n_sclass == C_EXT || sym.n_sclass == C_HIDEXT) + /* Read in the csect information, if any. */ + if (CSECT_SYM_P (sym.n_sclass)) { BFD_ASSERT (sym.n_numaux > 0); bfd_coff_swap_aux_in (sub, esym + symesz * sym.n_numaux, @@ -3698,9 +3724,8 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, bfd_coff_swap_sym_in (input_bfd, (void *) esym, (void *) isymp); - /* If this is a C_EXT or C_HIDEXT symbol, we need the csect - information. */ - if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT) + /* Read in the csect information, if any. */ + if (CSECT_SYM_P (isymp->n_sclass)) { BFD_ASSERT (isymp->n_numaux > 0); bfd_coff_swap_aux_in (input_bfd, @@ -3716,7 +3741,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, .loader symbol information. If this is an external symbol reference to a defined symbol, though, then wait until we get to the definition. */ - if (isymp->n_sclass == C_EXT + if (EXTERN_SYM_P (isymp->n_sclass) && *sym_hash != NULL && (*sym_hash)->ldsym != NULL && xcoff_final_definition_p (input_bfd, *sym_hash, *csectpp)) @@ -3751,6 +3776,8 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, ldsym->l_smtype |= L_EXPORT; if ((h->flags & XCOFF_ENTRY) != 0) ldsym->l_smtype |= L_ENTRY; + if (isymp->n_sclass == C_AIX_WEAKEXT) + ldsym->l_smtype |= L_WEAK; ldsym->l_smclas = aux.x_csect.x_smclas; @@ -3812,7 +3839,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, /* Assign the next unused index to this symbol. */ *indexp = output_index; - if (isymp->n_sclass == C_EXT) + if (EXTERN_SYM_P (isymp->n_sclass)) { BFD_ASSERT (*sym_hash != NULL); (*sym_hash)->indx = output_index; @@ -4018,8 +4045,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; } } - else if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) + else if (CSECT_SYM_P (isymp->n_sclass) && i + 1 == isymp->n_numaux) { @@ -4098,8 +4124,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, /* Copy over the line numbers, unless we are stripping them. We do this on a symbol by symbol basis in order to more easily handle garbage collection. */ - if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) + if (CSECT_SYM_P (isymp->n_sclass) && i == 0 && isymp->n_numaux > 1 && ISFCN (isymp->n_type) @@ -5194,7 +5219,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf) { isym.n_value = 0; isym.n_scnum = N_UNDEF; - isym.n_sclass = C_EXT; + if (h->root.type == bfd_link_hash_undefweak + && C_WEAKEXT == C_AIX_WEAKEXT) + isym.n_sclass = C_WEAKEXT; + else + isym.n_sclass = C_EXT; aux.x_csect.x_smtyp = XTY_ER; } else if ((h->root.type == bfd_link_hash_defined @@ -5204,7 +5233,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf) BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section)); isym.n_value = h->root.u.def.value; isym.n_scnum = N_UNDEF; - isym.n_sclass = C_EXT; + if (h->root.type == bfd_link_hash_undefweak + && C_WEAKEXT == C_AIX_WEAKEXT) + isym.n_sclass = C_WEAKEXT; + else + isym.n_sclass = C_EXT; aux.x_csect.x_smtyp = XTY_ER; } else if (h->root.type == bfd_link_hash_defined @@ -5266,7 +5299,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf) /* We just output an SD symbol. Now output an LD symbol. */ h->indx += 2; - isym.n_sclass = C_EXT; + if (h->root.type == bfd_link_hash_undefweak + && C_WEAKEXT == C_AIX_WEAKEXT) + isym.n_sclass = C_WEAKEXT; + else + isym.n_sclass = C_EXT; bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) outsym); outsym += bfd_coff_symesz (output_bfd); diff --git a/gas/ChangeLog b/gas/ChangeLog index 5056d8dcc9..360dc0d289 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2009-03-14 Richard Sandiford + + * config/tc-ppc.c (ppc_frob_symbol): Add csect information for + C_AIX_WEAKEXT too. + 2009-03-14 Richard Sandiford * config/tc-ppc.c (md_apply_fix): On COFF targets, always reread diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index c3803b3fe1..537b676be7 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -5170,6 +5170,7 @@ ppc_frob_symbol (symbolS *sym) S_SET_STORAGE_CLASS (sym, C_HIDEXT); if (S_GET_STORAGE_CLASS (sym) == C_EXT + || S_GET_STORAGE_CLASS (sym) == C_AIX_WEAKEXT || S_GET_STORAGE_CLASS (sym) == C_HIDEXT) { int i; diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog index d96ae1ca14..09cd87322f 100644 --- a/include/coff/ChangeLog +++ b/include/coff/ChangeLog @@ -1,3 +1,13 @@ +2009-03-14 Richard Sandiford + + * internal.h (C_AIX_WEAKEXT): New macro. + (C_WEAKEXT): Use the GNU definition in the generic part of the file, + and conditionally reset it to C_AIX_WEAKEXT in the XCOFF part of + the file. + (CSECT_SYM_P): New macro. + * xcoff.h (L_WEAK): Define. + (EXTERN_SYM_P): New macro. + 2009-03-14 Richard Sandiford * xcoff.h (XCOFF_ALLOCATED): New flag. diff --git a/include/coff/internal.h b/include/coff/internal.h index 2c9ae46c55..c5d6cd1fcc 100644 --- a/include/coff/internal.h +++ b/include/coff/internal.h @@ -273,12 +273,7 @@ struct internal_aouthdr #define C_LINE 104 /* line # reformatted as symbol table entry */ #define C_ALIAS 105 /* duplicate tag */ #define C_HIDDEN 106 /* ext symbol in dmert public lib */ - -#if defined _AIX52 || defined AIX_WEAK_SUPPORT -#define C_WEAKEXT 111 /* weak symbol -- AIX standard. */ -#else #define C_WEAKEXT 127 /* weak symbol -- GNU extension. */ -#endif /* New storage classes for TI COFF */ #define C_UEXT 19 /* Tentative external definition */ @@ -311,6 +306,12 @@ struct internal_aouthdr #define C_HIDEXT 107 /* Un-named external symbol */ #define C_BINCL 108 /* Marks beginning of include file */ #define C_EINCL 109 /* Marks ending of include file */ +#define C_AIX_WEAKEXT 111 /* AIX definition of C_WEAKEXT. */ + +#if defined _AIX52 || defined AIX_WEAK_SUPPORT +#undef C_WEAKEXT +#define C_WEAKEXT C_AIX_WEAKEXT +#endif /* storage classes for stab symbols for RS/6000 */ #define C_GSYM (0x80) @@ -336,6 +337,10 @@ struct internal_aouthdr #define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ #define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ +/* True if XCOFF symbols of class CLASS have auxillary csect information. */ +#define CSECT_SYM_P(CLASS) \ + ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT || (CLASS) == C_HIDEXT) + /********************** SECTION HEADER **********************/ #define SCNNMLEN (8) diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h index 3c3c8e9ead..4f9f7edee7 100644 --- a/include/coff/xcoff.h +++ b/include/coff/xcoff.h @@ -214,6 +214,8 @@ struct internal_ldsym #define L_ENTRY (0x20) /* Exported symbol. */ #define L_EXPORT (0x10) +/* Weak symbol. */ +#define L_WEAK (0x08) /* The ldrel structure. This is used to represent a reloc in the .loader section. */ @@ -644,4 +646,8 @@ struct xcoff_ar_hdr_big #define arch_xhdr_big(bfd) \ ((struct xcoff_ar_hdr_big *) arch_eltdata (bfd)->arch_header) +/* True if symbols of class CLASS are external. */ +#define EXTERN_SYM_P(CLASS) \ + ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT) + #endif /* _INTERNAL_XCOFF_H */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 81a65990b8..18b8beceec 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,25 @@ +2009-03-14 Richard Sandiford + + * ld-powerpc/aix-glink-2a.s, ld-powerpc/aix-glink-2a.ex, + ld-powerpc/aix-glink-2b.s, ld-powerpc/aix-glink-2c.s, + ld-powerpc/aix-glink-2c.ex, ld-powerpc/aix-glink-2d.s, + ld-powerpc/aix-glink-2-32.dd, ld-powerpc/aix-glink-2-64.dd, + ld-powerpc/aix-weak-1a.s, ld-powerpc/aix-weak-1b.s, + ld-powerpc/aix-weak-1-rel.hd, ld-powerpc/aix-weak-1-rel.nd, + ld-powerpc/aix-weak-1-dso.hd, ld-powerpc/aix-weak-1-dso.nd, + ld-powerpc/aix-weak-1-dso.dnd, ld-powerpc/aix-weak-1.ex, + ld-powerpc/aix-weak-2a.s, ld-powerpc/aix-weak-2a.ex, + ld-powerpc/aix-weak-2a.nd, ld-powerpc/aix-weak-2b.s, + ld-powerpc/aix-weak-2b.nd, ld-powerpc/aix-weak-2c.s, + ld-powerpc/aix-weak-2c.ex, ld-powerpc/aix-weak-2c.nd, + ld-powerpc/aix-weak-2c.od, ld-powerpc/aix-weak-3a.s, + ld-powerpc/aix-weak-3a.ex, ld-powerpc/aix-weak-3b.s, + ld-powerpc/aix-weak-3b.ex, ld-powerpc/aix-weak-3-32.d, + ld-powerpc/aix-weak-3-32.dd, ld-powerpc/aix-weak-3-64.d, + ld-powerpc/aix-weak-3-64.dd: New tests. + * ld-powerpc/aix52.exp: Run them. Replace tmp/aix-* with + tmp/aix64-* in 64-bit ld options. + 2009-03-14 Richard Sandiford * ld-powerpc/aix-no-dup-syms-1a.s, ld-powerpc/aix-no-dup-syms-1b.s, diff --git a/ld/testsuite/ld-powerpc/aix-glink-2-32.dd b/ld/testsuite/ld-powerpc/aix-glink-2-32.dd new file mode 100644 index 0000000000..2c91d23379 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2-32.dd @@ -0,0 +1,69 @@ + +tmpdir/aix-glink-2: file format aixcoff-rs6000 + + +Disassembly of section \.text: + +10000000 <\.b1>: +10000000: 60 00 00 00 oril r0,r0,0 + +10000004 <\.b2>: +10000004: 60 00 00 00 oril r0,r0,0 + +10000008 <\.b3>: +10000008: 60 00 00 00 oril r0,r0,0 + +1000000c <\.main>: +1000000c: 48 00 f1 03 bla f100 <.*> +10000010: 48 00 00 21 bl 10000030 <\.a2> +10000014: 48 00 00 41 bl 10000054 <\.a3> +10000018: 4b ff ff e9 bl 10000000 <\.b1> +1000001c: 4b ff ff e9 bl 10000004 <\.b2> +10000020: 4b ff ff e9 bl 10000008 <\.b3> +10000024: 48 00 f5 03 bla f500 <.*> +10000028: 48 00 00 51 bl 10000078 <\.c2> +1000002c: 48 00 00 71 bl 1000009c <\.c3> + +10000030 <\.a2>: +10000030: 81 82 00 00 l r12,0\(r2\) +10000034: 90 41 00 14 st r2,20\(r1\) +10000038: 80 0c 00 00 l r0,0\(r12\) +1000003c: 80 4c 00 04 l r2,4\(r12\) +10000040: 7c 09 03 a6 mtctr r0 +10000044: 4e 80 04 20 bctr +10000048: 00 00 00 00 \.long 0x0 +1000004c: 00 0c 80 00 \.long 0xc8000 +10000050: 00 00 00 00 \.long 0x0 + +10000054 <\.a3>: +10000054: 81 82 00 04 l r12,4\(r2\) +10000058: 90 41 00 14 st r2,20\(r1\) +1000005c: 80 0c 00 00 l r0,0\(r12\) +10000060: 80 4c 00 04 l r2,4\(r12\) +10000064: 7c 09 03 a6 mtctr r0 +10000068: 4e 80 04 20 bctr +1000006c: 00 00 00 00 \.long 0x0 +10000070: 00 0c 80 00 \.long 0xc8000 +10000074: 00 00 00 00 \.long 0x0 + +10000078 <\.c2>: +10000078: 81 82 00 08 l r12,8\(r2\) +1000007c: 90 41 00 14 st r2,20\(r1\) +10000080: 80 0c 00 00 l r0,0\(r12\) +10000084: 80 4c 00 04 l r2,4\(r12\) +10000088: 7c 09 03 a6 mtctr r0 +1000008c: 4e 80 04 20 bctr +10000090: 00 00 00 00 \.long 0x0 +10000094: 00 0c 80 00 \.long 0xc8000 +10000098: 00 00 00 00 \.long 0x0 + +1000009c <\.c3>: +1000009c: 81 82 00 0c l r12,12\(r2\) +100000a0: 90 41 00 14 st r2,20\(r1\) +100000a4: 80 0c 00 00 l r0,0\(r12\) +100000a8: 80 4c 00 04 l r2,4\(r12\) +100000ac: 7c 09 03 a6 mtctr r0 +100000b0: 4e 80 04 20 bctr +100000b4: 00 00 00 00 \.long 0x0 +100000b8: 00 0c 80 00 \.long 0xc8000 +100000bc: 00 00 00 00 \.long 0x0 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2-64.dd b/ld/testsuite/ld-powerpc/aix-glink-2-64.dd new file mode 100644 index 0000000000..5a34f0a802 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2-64.dd @@ -0,0 +1,73 @@ + +tmpdir/aix64-glink-2: file format aix5coff64-rs6000 + + +Disassembly of section \.text: + +0000000010000000 <\.b1>: + 10000000: 60 00 00 00 nop + +0000000010000004 <\.b2>: + 10000004: 60 00 00 00 nop + +0000000010000008 <\.b3>: + 10000008: 60 00 00 00 nop + +000000001000000c <\.main>: + 1000000c: 48 00 f1 03 bla f100 <.*> + 10000010: 48 00 00 21 bl 10000030 <\.a2> + 10000014: 48 00 00 45 bl 10000058 <\.a3> + 10000018: 4b ff ff e9 bl 10000000 <\.b1> + 1000001c: 4b ff ff e9 bl 10000004 <\.b2> + 10000020: 4b ff ff e9 bl 10000008 <\.b3> + 10000024: 48 00 f5 03 bla f500 <.*> + 10000028: 48 00 00 59 bl 10000080 <\.c2> + 1000002c: 48 00 00 7d bl 100000a8 <\.c3> + +0000000010000030 <\.a2>: + 10000030: e9 82 00 00 ld r12,0\(r2\) + 10000034: f8 41 00 28 std r2,40\(r1\) + 10000038: e8 0c 00 00 ld r0,0\(r12\) + 1000003c: e8 4c 00 08 ld r2,8\(r12\) + 10000040: 7c 09 03 a6 mtctr r0 + 10000044: 4e 80 04 20 bctr + 10000048: 00 00 00 00 \.long 0x0 + 1000004c: 00 0c a0 00 \.long 0xca000 + 10000050: 00 00 00 00 \.long 0x0 + 10000054: 00 00 00 18 \.long 0x18 + +0000000010000058 <\.a3>: + 10000058: e9 82 00 08 ld r12,8\(r2\) + 1000005c: f8 41 00 28 std r2,40\(r1\) + 10000060: e8 0c 00 00 ld r0,0\(r12\) + 10000064: e8 4c 00 08 ld r2,8\(r12\) + 10000068: 7c 09 03 a6 mtctr r0 + 1000006c: 4e 80 04 20 bctr + 10000070: 00 00 00 00 \.long 0x0 + 10000074: 00 0c a0 00 \.long 0xca000 + 10000078: 00 00 00 00 \.long 0x0 + 1000007c: 00 00 00 18 \.long 0x18 + +0000000010000080 <\.c2>: + 10000080: e9 82 00 10 ld r12,16\(r2\) + 10000084: f8 41 00 28 std r2,40\(r1\) + 10000088: e8 0c 00 00 ld r0,0\(r12\) + 1000008c: e8 4c 00 08 ld r2,8\(r12\) + 10000090: 7c 09 03 a6 mtctr r0 + 10000094: 4e 80 04 20 bctr + 10000098: 00 00 00 00 \.long 0x0 + 1000009c: 00 0c a0 00 \.long 0xca000 + 100000a0: 00 00 00 00 \.long 0x0 + 100000a4: 00 00 00 18 \.long 0x18 + +00000000100000a8 <\.c3>: + 100000a8: e9 82 00 18 ld r12,24\(r2\) + 100000ac: f8 41 00 28 std r2,40\(r1\) + 100000b0: e8 0c 00 00 ld r0,0\(r12\) + 100000b4: e8 4c 00 08 ld r2,8\(r12\) + 100000b8: 7c 09 03 a6 mtctr r0 + 100000bc: 4e 80 04 20 bctr + 100000c0: 00 00 00 00 \.long 0x0 + 100000c4: 00 0c a0 00 \.long 0xca000 + 100000c8: 00 00 00 00 \.long 0x0 + 100000cc: 00 00 00 18 \.long 0x18 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2a.ex b/ld/testsuite/ld-powerpc/aix-glink-2a.ex new file mode 100644 index 0000000000..406cabb3c7 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2a.ex @@ -0,0 +1,9 @@ +a1 +a2 +a3 +b1 +b2 +b3 +c1 +c2 +c3 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2a.s b/ld/testsuite/ld-powerpc/aix-glink-2a.s new file mode 100644 index 0000000000..fafbe4329e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2a.s @@ -0,0 +1,41 @@ + .toc + + .macro defabs,type,name,value + \type \name + \name = \value + .endm + + .macro deffun,type,name,fn + \type \name + .csect \name\()[DS] +\name\(): + .if size == 32 + .long .\name\()[PR],TOC[TC0],0 + .else + .llong .\name\()[PR],TOC[TC0],0 + .endif + + .globl .\name + .csect .\name\()[PR] +.\name\(): + nop + .endm + + .macro defdata,type,name,contents + \type \name + .csect \name\()[RW] +\name\(): + .long \contents + .endm + + defabs .globl,a1,0xf100 + deffun .globl,a2 + defdata .globl,a3,0x1100 + + defabs .globl,b1,0xf200 + deffun .globl,b2 + defdata .globl,b3,0x2200 + + defabs .weak,c1,0xf300 + deffun .weak,c2 + defdata .weak,c3,0x3300 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2b.s b/ld/testsuite/ld-powerpc/aix-glink-2b.s new file mode 100644 index 0000000000..9c06d48918 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2b.s @@ -0,0 +1,12 @@ + .toc + + .macro deffun,type,name + .globl .\name + .csect .\name\()[PR] +.\name\(): + nop + .endm + + deffun .globl,b1 + deffun .globl,b2 + deffun .globl,b3 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2c.ex b/ld/testsuite/ld-powerpc/aix-glink-2c.ex new file mode 100644 index 0000000000..4e16c9b75e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2c.ex @@ -0,0 +1,6 @@ +a1 +a2 +a3 +c1 +c2 +c3 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2c.s b/ld/testsuite/ld-powerpc/aix-glink-2c.s new file mode 100644 index 0000000000..7dd6dadc3c --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2c.s @@ -0,0 +1,33 @@ + .toc + + .macro defabs,type,name,value + \type \name + \name = \value + .endm + + .macro deffun,type,name + \type \name + .csect \name\()[DS] +\name\(): + .long \name\()[PR],TOC[TC0],0 + + .globl .\name + .csect .\name\()[PR] +.\name\(): + nop + .endm + + .macro defdata,type,name,contents + \type \name + .csect \name\()[RW] +\name\(): + .long \contents + .endm + + defabs .globl,a1,0xf400 + deffun .globl,a2 + defdata .globl,a3,0x4400 + + defabs .globl,c1,0xf500 + deffun .globl,c2 + defdata .globl,c3,0x5500 diff --git a/ld/testsuite/ld-powerpc/aix-glink-2d.s b/ld/testsuite/ld-powerpc/aix-glink-2d.s new file mode 100644 index 0000000000..ba78609539 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-glink-2d.s @@ -0,0 +1,12 @@ + .globl .main + .csect .main[PR] +.main: + bl .a1 + bl .a2 + bl .a3 + bl .b1 + bl .b2 + bl .b3 + bl .c1 + bl .c2 + bl .c3 diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd new file mode 100644 index 0000000000..3105fa3286 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd @@ -0,0 +1,17 @@ +# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type) +# (strong common) loses to (strong data) +0*10000010 D a +# (strong common) wins over (weak data) +0*10000020 B b +# (strong data) wins over (strong common) +0*10000000 D c +# (weak data) loses to (strong common) +0*10000028 B d +# (weak common) loses to (strong data) +0*10000018 D e +# (weak common) wins over (weak data) +0*10000024 W f +# (strong data) wins over (weak common) +0*10000008 D g +# (weak data) wins over (weak common) +0*1000000c W h diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd new file mode 100644 index 0000000000..7368a5a2d9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd @@ -0,0 +1,12 @@ +.* + +Sections: +Idx Name * Size * VMA * LMA * File off *Algn + *0 \.text * 0+00 * 0*10000000 * 0*10000000 * [^ ]+ * 2\*\*2 + *ALLOC, LOAD, CODE + *1 \.data * 0+20 * 0*10000000 * 0*10000000 * [^ ]+ * 2\*\*3 + *CONTENTS, ALLOC, LOAD, DATA +# Should only have 3 three common symbols. + *2 \.bss * 0+0c * 0*10000020 * 0*10000020 * [^ ]+ * 2\*\*3 + *ALLOC +#pass diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd new file mode 100644 index 0000000000..3289e25781 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd @@ -0,0 +1,25 @@ +# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type) +# (strong common) loses to (strong data) +0*10000010 d a +0*10000010 D a +# (strong common) wins over (weak data) +0*10000020 B b +0*10000014 d b +# (strong data) wins over (strong common) +0*10000000 d c +0*10000000 D c +# (weak data) loses to (strong common) +0*10000004 d d +0*10000028 B d +# (weak common) loses to (strong data) +0*10000018 d e +0*10000018 D e +# (weak common) wins over (weak data) +0*10000024 W f +0*1000001c d f +# (strong data) wins over (weak common) +0*10000008 d g +0*10000008 D g +# (weak data) wins over (weak common) +0*1000000c d h +0*1000000c W h diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd b/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd new file mode 100644 index 0000000000..9ae4d4777f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd @@ -0,0 +1,12 @@ +.* + +Sections: +Idx Name * Size * VMA * LMA * File off *Algn + *0 \.text * 0+00 * 0+00 * 0+00 * [^ ]+ * 2\*\*2 + *ALLOC, LOAD, CODE + *1 \.data * 0+20 * 0+00 * 0+00 * [^ ]+ * 2\*\*3 + *CONTENTS, ALLOC, LOAD, DATA +# Should only have 3 three common symbols. + *2 \.bss * 0+0c * 0+20 * 0+20 * [^ ]+ * 2\*\*3 + *ALLOC +#pass diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd b/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd new file mode 100644 index 0000000000..73cfe90de6 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd @@ -0,0 +1,25 @@ +# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type) +# (strong common) loses to (strong data) +0+10 d a +0+10 D a +# (strong common) wins over (weak data) +0+20 B b +0+14 d b +# (strong data) wins over (strong common) +0+00 d c +0+00 D c +# (weak data) loses to (strong common) +0+04 d d +0+28 B d +# (weak common) loses to (strong data) +0+18 d e +0+18 D e +# (weak common) wins over (weak data) +0+24 W f +0+1c d f +# (strong data) wins over (weak common) +0+08 d g +0+08 D g +# (weak data) wins over (weak common) +0+0c d h +0+0c W h diff --git a/ld/testsuite/ld-powerpc/aix-weak-1.ex b/ld/testsuite/ld-powerpc/aix-weak-1.ex new file mode 100644 index 0000000000..71ac1b5791 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1.ex @@ -0,0 +1,8 @@ +a +b +c +d +e +f +g +h diff --git a/ld/testsuite/ld-powerpc/aix-weak-1a.s b/ld/testsuite/ld-powerpc/aix-weak-1a.s new file mode 100644 index 0000000000..da529caf6e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1a.s @@ -0,0 +1,24 @@ + .comm a,4 + .comm b,4 + .globl c + .csect c[RW],2 +c: + .long 0x11111111 + .weak d + .csect d[RW],2 +d: + .long 0x22222222 + + # Same again, with weak common symbols + .weak e + .comm e,4 + .weak f + .comm f,4 + .globl g + .csect g[RW],2 +g: + .long 0x33333333 + .weak h + .csect h[RW],2 +h: + .long 0x44444444 diff --git a/ld/testsuite/ld-powerpc/aix-weak-1b.s b/ld/testsuite/ld-powerpc/aix-weak-1b.s new file mode 100644 index 0000000000..e6c2429e43 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-1b.s @@ -0,0 +1,24 @@ + .globl a + .csect a[RW],2 +a: + .long 0x55555555 + .weak b + .csect b[RW],2 +b: + .long 0x66666666 + .comm c,4 + .comm d,4 + + # Same again, with weak common symbols + .globl e + .csect e[RW],2 +e: + .long 0x77777777 + .weak f + .csect f[RW],2 +f: + .long 0x88888888 + .weak g + .comm g,4 + .weak h + .comm h,4 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.ex b/ld/testsuite/ld-powerpc/aix-weak-2a.ex new file mode 100644 index 0000000000..0e65a8f1ad --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2a.ex @@ -0,0 +1,8 @@ +c1 +c2 +c3 +c4 +d1 +d2 +d3 +d4 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.nd b/ld/testsuite/ld-powerpc/aix-weak-2a.nd new file mode 100644 index 0000000000..2c2ea1c176 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2a.nd @@ -0,0 +1,8 @@ +0*cccc1111 W c1 +0*cccc2222 W c2 +0*cccc3333 A c3 +0*cccc4444 A c4 +0*ffff1111 W d1 +0*ffff2222 W d2 +0*10000000 D d3 +0*10000004 D d4 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.s b/ld/testsuite/ld-powerpc/aix-weak-2a.s new file mode 100644 index 0000000000..e4d8a0499f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2a.s @@ -0,0 +1,21 @@ + .weak c1 + c1 = 0xcccc1111 + .weak c2 + c2 = 0xcccc2222 + .globl c3 + c3 = 0xcccc3333 + .globl c4 + c4 = 0xcccc4444 + + .weak d1 + d1 = 0xffff1111 + .weak d2 + d2 = 0xffff2222 + .globl d3 + .csect d3[DS] +d3: + .long 0xffff3333 + .globl d4 + .csect d4[DS] +d4: + .long 0xffff4444 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2b.nd b/ld/testsuite/ld-powerpc/aix-weak-2b.nd new file mode 100644 index 0000000000..d54b35bcfe --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2b.nd @@ -0,0 +1,8 @@ +0*dddd1111 A c1 +0*dddd2222 W c2 +0*dddd3333 A c3 +0*dddd4444 W c4 +0*10000000 D d1 +0*eeee2222 W d2 +0*10000004 D d3 +0*eeee4444 W d4 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2b.s b/ld/testsuite/ld-powerpc/aix-weak-2b.s new file mode 100644 index 0000000000..84885ab7c9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2b.s @@ -0,0 +1,21 @@ + .globl c1 + c1 = 0xdddd1111 + .weak c2 + c2 = 0xdddd2222 + .globl c3 + c3 = 0xdddd3333 + .weak c4 + c4 = 0xdddd4444 + + .globl d1 + .csect d1[DS] +d1: + .long 0xeeee1111 + .weak d2 + d2 = 0xeeee2222 + .globl d3 + .csect d3[DS] +d3: + .long 0xeeee3333 + .weak d4 + d4 = 0xeeee4444 diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.ex b/ld/testsuite/ld-powerpc/aix-weak-2c.ex new file mode 100644 index 0000000000..257cc5642c --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2c.ex @@ -0,0 +1 @@ +foo diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.nd b/ld/testsuite/ld-powerpc/aix-weak-2c.nd new file mode 100644 index 0000000000..d42034b351 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2c.nd @@ -0,0 +1,10 @@ +0*dddd1111 C c1 +0*cccc2222 C c2 +0*cccc3333 C c3 +0*cccc4444 C c4 + * U d1 +0*ffff2222 C d2 + * U d3 + * U d4 +0*10000000 d foo +0*10000000 D foo diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.od b/ld/testsuite/ld-powerpc/aix-weak-2c.od new file mode 100644 index 0000000000..272c80e345 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2c.od @@ -0,0 +1,13 @@ + +.* + +DYNAMIC RELOCATION RECORDS +OFFSET * TYPE * VALUE +0*10000010 R_POS * d1 +0*10000018 R_POS * d3 +0*1000001c R_POS * d4 + + +Contents of section \.data: + 0*10000000 dddd1111 cccc2222 cccc3333 cccc4444 .* + 0*10000010 00000000 ffff2222 00000000 00000000 .* diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.s b/ld/testsuite/ld-powerpc/aix-weak-2c.s new file mode 100644 index 0000000000..5ca93d3e9e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-2c.s @@ -0,0 +1,11 @@ + .globl foo + .csect foo[DS] +foo: + .long c1 + .long c2 + .long c3 + .long c4 + .long d1 + .long d2 + .long d3 + .long d4 diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-32.d b/ld/testsuite/ld-powerpc/aix-weak-3-32.d new file mode 100644 index 0000000000..45976c9c99 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3-32.d @@ -0,0 +1,5 @@ +#name: Weak test 3 (main, static) (32-bit) +#source: aix-weak-3b.s +#as: -a32 --defsym size=32 +#ld: -b32 -e.main -bnoautoimp tmpdir/aix-weak-3a.so +#error: .*multiple definition of `x1'\n[^\n]*first defined here diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-32.dd b/ld/testsuite/ld-powerpc/aix-weak-3-32.dd new file mode 100644 index 0000000000..c52b735afe --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3-32.dd @@ -0,0 +1,24 @@ + +.* + + +Disassembly of section \.data: + +20000000 : +20000000: 00 00 01 02 .* + +20000004 : +20000004: 00 00 03 04 .* + +20000008 : +20000008: 20 00 00 00 .* + 20000008: R_POS x1\+.* + +2000000c : +2000000c: 20 00 00 04 .* + 2000000c: R_POS x2\+.* + +20000010 : +20000010: 00 00 00 00 .* + 20000010: R_POS x3 +20000014: 00 00 00 00 .* diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-64.d b/ld/testsuite/ld-powerpc/aix-weak-3-64.d new file mode 100644 index 0000000000..4673175dfc --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3-64.d @@ -0,0 +1,5 @@ +#name: Weak test 3 (main, static) (64-bit) +#source: aix-weak-3b.s +#as: -a64 --defsym size=64 +#ld: -b64 -e.main -bnoautoimp tmpdir/aix64-weak-3a.so +#error: .*multiple definition of `x1'\n[^\n]*first defined here diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-64.dd b/ld/testsuite/ld-powerpc/aix-weak-3-64.dd new file mode 100644 index 0000000000..7c10f6c76b --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3-64.dd @@ -0,0 +1,26 @@ + +.* + + +Disassembly of section \.data: + +0000000020000000 : + 20000000: 00 00 01 02 .* + +0000000020000004 : + 20000004: 00 00 03 04 .* + +0000000020000008 : + 20000008: 00 00 00 00 .* + 20000008: R_POS_64 x1\+.* + 2000000c: 20 00 00 00 .* + +0000000020000010 : + 20000010: 00 00 00 00 .* + 20000010: R_POS_64 x2\+.* + 20000014: 20 00 00 04 .* + +0000000020000018 : + 20000018: 00 00 00 00 .* + 20000018: R_POS_64 x3 + 2000001c: 00 00 00 00 .* diff --git a/ld/testsuite/ld-powerpc/aix-weak-3a.ex b/ld/testsuite/ld-powerpc/aix-weak-3a.ex new file mode 100644 index 0000000000..589f40bac9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3a.ex @@ -0,0 +1,3 @@ +x1 +x2 +x3 diff --git a/ld/testsuite/ld-powerpc/aix-weak-3a.s b/ld/testsuite/ld-powerpc/aix-weak-3a.s new file mode 100644 index 0000000000..e8b9d96559 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3a.s @@ -0,0 +1,8 @@ + .globl x1 + x1 = 0x11223344 + .globl x2 + x2 = 0x55667788 + .globl x3 + .csect x3[RW] +x3: + .long 42 diff --git a/ld/testsuite/ld-powerpc/aix-weak-3b.ex b/ld/testsuite/ld-powerpc/aix-weak-3b.ex new file mode 100644 index 0000000000..975fbec825 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3b.ex @@ -0,0 +1 @@ +y diff --git a/ld/testsuite/ld-powerpc/aix-weak-3b.s b/ld/testsuite/ld-powerpc/aix-weak-3b.s new file mode 100644 index 0000000000..4e69082e0f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-weak-3b.s @@ -0,0 +1,30 @@ + .globl x1 + .csect x1[RW] +x1: + .long 0x0102 + + .weak x2 + .csect x2[RW] +x2: + .long 0x0304 + + .toc +Tx1: + .tc x1[TC],x1 +Tx2: + .tc x2[TC],x2 +Tx3: + .tc x3[TC],x3 + + .globl .main + .csect .main[PR] +.main: + .if size == 32 + lwz 1,Tx1(2) + lwz 1,Tx2(2) + lwz 1,Tx3(2) + .else + ld 1,Tx1(2) + ld 1,Tx2(2) + ld 1,Tx3(2) + .endif diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index 6cd26fe8f5..98bbda3d7e 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -124,6 +124,64 @@ set aix52tests { {{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}} "aix-lineno-1b.exe"} + {"Glink test 2 (part a)" "-shared -bE:aix-glink-2a.ex" + "" {aix-glink-2a.s} + {} + "aix-glink-2a.so"} + + {"Glink test 2 (part b)" "-r" + "" {aix-glink-2b.s} + {} + "aix-glink-2b.ro"} + + {"Glink test 2 (part c)" "-shared -bE:aix-glink-2c.ex" + "" {aix-glink-2c.s} + {} + "aix-glink-2c.so"} + + {"Glink test 2" + "-e.main tmpdir/aix-glink-2a.so tmpdir/aix-glink-2b.ro tmpdir/aix-glink-2c.so" + "" {aix-glink-2d.s} + {{objdump -d aix-glink-2-SIZE.dd}} + "aix-glink-2"} + + {"Weak test 1 (rel)" "-r" + "" {aix-weak-1a.s aix-weak-1b.s} + {{nm {} aix-weak-1-rel.nd} {objdump -h aix-weak-1-rel.hd}} + "aix-weak-1.o"} + + {"Weak test 1 (shared, nogc)" "-shared -bE:aix-weak-1.ex -bnogc" + "" {aix-weak-1a.s aix-weak-1b.s} + {{nm {} aix-weak-1-dso.nd} {objdump -h aix-weak-1-dso.hd} + {nm -D aix-weak-1-dso.dnd}} + "aix-weak-1-nogc.so"} + + {"Weak test 2 (library 1)" "-shared -bE:aix-weak-2a.ex" + "" {aix-weak-2a.s} + {{nm -D aix-weak-2a.nd}} + "aix-weak-2a.so"} + + {"Weak test 2 (library 2)" "-shared -bE:aix-weak-2a.ex" + "" {aix-weak-2b.s} + {{nm -D aix-weak-2b.nd}} + "aix-weak-2b.so"} + + {"Weak test 2 (main library)" + "-shared -bE:aix-weak-2c.ex tmpdir/aix-weak-2a.so tmpdir/aix-weak-2b.so" + "" {aix-weak-2c.s} + {{nm {} aix-weak-2c.nd} {objdump {-sj.data -R} aix-weak-2c.od}} + "aix-weak-2c.so"} + + {"Weak test 3 (library)" "-shared -bE:aix-weak-3a.ex" + "" {aix-weak-3a.s} + {} + "aix-weak-3a.so"} + + {"Weak test 3 (main, dynamic)" "-e.main tmpdir/aix-weak-3a.so" + "" {aix-weak-3b.s} + {{objdump -Dzrj.data aix-weak-3-SIZE.dd}} + "aix-weak-3"} + {"TOC test 1" "-shared -bE:aix-toc-1.ex" "" {aix-toc-1a.s aix-toc-1b.s} {{objdump -dr aix-toc-1-SIZE.dd}} @@ -136,3 +194,6 @@ foreach test $aix52tests { run_aix_test 64 $name $ldopts $asopts $sources $tools $output } } + +run_dump_test "aix-weak-3-32" +run_dump_test "aix-weak-3-64"