Message-Id: <199908261354.NAA97692@out5.ibm.net> From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Thu, 26 Aug 1999 09:54:15 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: backport patch for binutils 2.9.1 X-mailer: Pegasus Mail for Win32 (v3.12a) Reply-To: djgpp-workers AT delorie DOT com Below is the latest version of my 2.9.1 patch. I removed -finit_priority support from the linker script template because SORT is in 2.10 but not 2.9.1. I've added the EH section padding fix, a fix for preserving the link once flags, and handling of the .weak directive. If there are any other fixes already in binutils CVS that should be included too, speak up. *** include/coff/internal.h.orig Fri May 1 11:48:26 1998 --- include/coff/internal.h Wed Aug 25 12:35:24 1999 *************** struct internal_aouthdr *** 233,238 **** --- 233,240 ---- #define C_PRAGMA 111 /* Advice to compiler or linker */ #define C_SEGMENT 112 /* 80960 segment name */ + #define C_WEAKEXT 127 /* weak symbol -- GNU extension */ + /* Storage classes for m88k */ #define C_SHADOW 107 /* shadow symbol */ #define C_VERSION 108 /* coff version symbol */ *** bfd/coff-go32.c.orig Fri May 1 11:48:04 1998 --- bfd/coff-go32.c Wed Aug 25 17:51:08 1999 *************** *** 1,5 **** /* BFD back-end for Intel 386 COFF files (go32 variant). ! Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. Written by DJ Delorie. This file is part of BFD, the Binary File Descriptor library. --- 1,5 ---- /* BFD back-end for Intel 386 COFF files (go32 variant). ! Copyright 1990, 91, 92, 93, 94, 1999 Free Software Foundation, Inc. Written by DJ Delorie. This file is part of BFD, the Binary File Descriptor library. *************** Foundation, Inc., 59 Temple Place - Suit *** 21,25 **** --- 21,40 ---- #define TARGET_SYM go32coff_vec #define TARGET_NAME "coff-go32" #define TARGET_UNDERSCORE '_' + + #define COFF_LONG_SECTION_NAMES + #define COFF_SUPPORT_GNU_LINKONCE + + #define COFF_SECTION_ALIGNMENT_ENTRIES \ + { COFF_SECTION_NAME_EXACT_MATCH (".data"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ + { COFF_SECTION_NAME_EXACT_MATCH (".text"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ + { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ + { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ + { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 } #include "coff-i386.c" *** bfd/coff-stgo32.c.orig Fri May 1 11:48:04 1998 --- bfd/coff-stgo32.c Wed Aug 25 11:37:46 1999 *************** *** 40,45 **** --- 40,54 ---- #define TARGET_UNDERSCORE '_' #define COFF_GO32_EXE + #define COFF_LONG_SECTION_NAMES + #define COFF_SUPPORT_GNU_LINKONCE + + #define COFF_SECTION_ALIGNMENT_ENTRIES \ + { COFF_SECTION_NAME_EXACT_MATCH (".data"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ + { COFF_SECTION_NAME_EXACT_MATCH (".text"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 } + #include "bfd.h" /* At first the prototypes */ *** bfd/coffcode.h.orig Fri May 1 11:48:04 1998 --- bfd/coffcode.h Wed Aug 25 12:40:14 1999 *************** styp_to_sec_flags (abfd, hdr, name) *** 664,669 **** --- 664,680 ---- } #endif + #if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE) + /* As a GNU extension, if the name begins with .gnu.linkonce, we + only link a single copy of the section. This is used to support + g++. g++ will emit each template expansion in its own section. + The symbols will be defined as weak, so that multiple definitions + are permitted. The GNU linker extension is to actually discard + all but one of the sections. */ + if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0) + sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; + #endif + return (sec_flags); } *************** coff_slurp_symbol_table (abfd) *** 3463,3468 **** --- 3474,3480 ---- #endif case C_EXT: + case C_WEAKEXT: #if defined ARM case C_THUMBEXT: case C_THUMBEXTFUNC: *************** coff_slurp_symbol_table (abfd) *** 3529,3534 **** --- 3541,3549 ---- if (src->u.syment.n_sclass == C_NT_WEAK) dst->symbol.flags = BSF_WEAK; #endif + + if (src->u.syment.n_sclass == C_WEAKEXT) + dst->symbol.flags = BSF_WEAK; break; *** bfd/coffgen.c.orig Fri May 1 11:48:04 1998 --- bfd/coffgen.c Wed Aug 25 12:47:22 1999 *************** coff_renumber_symbols (bfd_ptr, first_un *** 658,673 **** if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) && !bfd_is_com_section (symbol_ptr_ptr[i]->section) ! && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION)) ! != BSF_GLOBAL))) *newsyms++ = symbol_ptr_ptr[i]; for (i = 0; i < symbol_count; i++) if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 && !bfd_is_und_section (symbol_ptr_ptr[i]->section) && (bfd_is_com_section (symbol_ptr_ptr[i]->section) ! || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION)) ! == BSF_GLOBAL))) *newsyms++ = symbol_ptr_ptr[i]; *first_undef = newsyms - bfd_ptr->outsymbols; --- 658,675 ---- if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) && !bfd_is_com_section (symbol_ptr_ptr[i]->section) ! && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0 ! || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) ! == 0)))) *newsyms++ = symbol_ptr_ptr[i]; for (i = 0; i < symbol_count; i++) if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 && !bfd_is_und_section (symbol_ptr_ptr[i]->section) && (bfd_is_com_section (symbol_ptr_ptr[i]->section) ! || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0 ! && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) ! != 0)))) *newsyms++ = symbol_ptr_ptr[i]; *first_undef = newsyms - bfd_ptr->outsymbols; *************** coff_write_alien_symbol (abfd, symbol, w *** 1032,1037 **** --- 1034,1041 ---- native->u.syment.n_type = 0; if (symbol->flags & BSF_LOCAL) native->u.syment.n_sclass = C_STAT; + else if (symbol->flags & BSF_WEAK) + native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; else native->u.syment.n_sclass = C_EXT; native->u.syment.n_numaux = 0; *** bfd/cofflink.c.orig Fri May 1 11:48:04 1998 --- bfd/cofflink.c Wed Aug 25 15:57:36 1999 *************** coff_link_check_ar_symbols (abfd, info, *** 244,249 **** --- 244,250 ---- bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); if ((sym.n_sclass == C_EXT + || sym.n_sclass == C_WEAKEXT #ifdef C_SYSTEM || sym.n_sclass == C_SYSTEM #endif *************** coff_link_add_symbols (abfd, info) *** 337,342 **** --- 338,344 ---- bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); if (sym.n_sclass == C_EXT + || sym.n_sclass == C_WEAKEXT #ifdef C_SYSTEM || sym.n_sclass == C_SYSTEM #endif *************** coff_link_add_symbols (abfd, info) *** 384,389 **** --- 386,395 ---- value -= section->vma; } + if (sym.n_sclass == C_WEAKEXT + || (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)) + flags = BSF_WEAK; + if (! (bfd_coff_link_add_one_symbol (info, abfd, name, flags, section, value, (const char *) NULL, copy, false, *************** coff_link_add_symbols (abfd, info) *** 403,409 **** && (*sym_hash)->type == T_NULL) || sym.n_scnum != 0 || (sym.n_value != 0 ! && (*sym_hash)->root.type != bfd_link_hash_defined)) { (*sym_hash)->class = sym.n_sclass; if (sym.n_type != T_NULL) --- 409,416 ---- && (*sym_hash)->type == T_NULL) || sym.n_scnum != 0 || (sym.n_value != 0 ! && (*sym_hash)->root.type != bfd_link_hash_defined ! && (*sym_hash)->root.type != bfd_link_hash_defweak)) { (*sym_hash)->class = sym.n_sclass; if (sym.n_type != T_NULL) *************** _bfd_coff_link_input_bfd (finfo, input_b *** 1329,1334 **** --- 1336,1342 ---- if (! skip) { if (isym.n_sclass == C_EXT + || isym.n_sclass == C_WEAKEXT #ifdef C_SYSTEM || isym.n_sclass == C_SYSTEM #endif *************** _bfd_coff_link_input_bfd (finfo, input_b *** 1648,1654 **** /* If doing task linking, convert normal global function symbols to static functions. */ ! if (finfo->info->task_link && isym.n_sclass == C_EXT) isym.n_sclass = C_STAT; /* Output the symbol. */ --- 1656,1665 ---- /* If doing task linking, convert normal global function symbols to static functions. */ ! if (finfo->info->task_link ! && (isym.n_sclass == C_EXT ! || isym.n_sclass == C_WEAKEXT ! || (obj_pe (input_bfd) && isym.n_sclass == C_NT_WEAK))) isym.n_sclass = C_STAT; /* Output the symbol. */ *************** _bfd_coff_write_global_sym (h, data) *** 2342,2348 **** just ignore it and it will be output during a later pass. */ if (finfo->global_to_static) { ! if (isym.n_sclass != C_EXT) { return true; } --- 2353,2361 ---- just ignore it and it will be output during a later pass. */ if (finfo->global_to_static) { ! if (isym.n_sclass != C_EXT ! && isym.n_sclass != C_WEAKEXT ! && (! obj_pe (output_bfd) || isym.n_sclass != C_NT_WEAK)) { return true; } *** bfd/libcoff-in.h.orig Fri May 1 11:48:12 1998 --- bfd/libcoff-in.h Wed Aug 25 11:41:06 1999 *************** struct coff_final_link_info *** 462,467 **** --- 462,502 ---- struct internal_reloc *internal_relocs; }; + /* Most COFF variants have no way to record the alignment of a + section. This struct is used to set a specific alignment based on + the name of the section. */ + + struct coff_section_alignment_entry + { + /* The section name. */ + const char *name; + + /* This is either (unsigned int) -1, indicating that the section + name must match exactly, or it is the number of letters which + must match at the start of the name. */ + unsigned int comparison_length; + + /* These macros may be used to fill in the first two fields in a + structure initialization. */ + #define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1) + #define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1) + + /* Only use this entry if the default section alignment for this + target is at least that much (as a power of two). If this field + is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ + unsigned int default_alignment_min; + + /* Only use this entry if the default section alignment for this + target is no greater than this (as a power of two). If this + field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ + unsigned int default_alignment_max; + + #define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1) + + /* The desired alignment for this section (as a power of two). */ + unsigned int alignment_power; + }; + extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); extern boolean _bfd_coff_link_hash_table_init *** bfd/libcoff.h.orig Fri May 1 11:48:12 1998 --- bfd/libcoff.h Wed Aug 25 11:41:40 1999 *************** struct coff_final_link_info *** 462,467 **** --- 462,502 ---- struct internal_reloc *internal_relocs; }; + /* Most COFF variants have no way to record the alignment of a + section. This struct is used to set a specific alignment based on + the name of the section. */ + + struct coff_section_alignment_entry + { + /* The section name. */ + const char *name; + + /* This is either (unsigned int) -1, indicating that the section + name must match exactly, or it is the number of letters which + must match at the start of the name. */ + unsigned int comparison_length; + + /* These macros may be used to fill in the first two fields in a + structure initialization. */ + #define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1) + #define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1) + + /* Only use this entry if the default section alignment for this + target is at least that much (as a power of two). If this field + is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ + unsigned int default_alignment_min; + + /* Only use this entry if the default section alignment for this + target is no greater than this (as a power of two). If this + field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ + unsigned int default_alignment_max; + + #define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1) + + /* The desired alignment for this section (as a power of two). */ + unsigned int alignment_power; + }; + extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); extern boolean _bfd_coff_link_hash_table_init *** gas/as.h.orig Fri May 1 11:45:04 1998 --- gas/as.h Thu Aug 26 00:16:52 1999 *************** void subseg_set PARAMS ((segT seg, subse *** 572,577 **** --- 572,578 ---- #ifdef BFD_ASSEMBLER segT subseg_get PARAMS ((const char *, int)); #endif + int subseg_text_p PARAMS ((segT)); void start_dependencies PARAMS ((char *)); void register_dependency PARAMS ((char *)); *** gas/ehopt.c.orig Fri May 1 11:45:08 1998 --- gas/ehopt.c Thu Aug 26 00:08:56 1999 *************** check_eh_frame (exp, pnbytes) *** 261,277 **** expressionS *exp; unsigned int *pnbytes; { static int saw_advance_loc4; static fragS *loc4_frag; static int loc4_fix; if (flag_traditional_format) { /* Don't optimize. */ } else if (strcmp (segment_name (now_seg), ".eh_frame") != 0) ! saw_advance_loc4 = 0; ! else if (*pnbytes == 1 && exp->X_op == O_constant && exp->X_add_number == DW_CFA_advance_loc4) { --- 261,312 ---- expressionS *exp; unsigned int *pnbytes; { + static int saw_size; + static symbolS *size_end_sym; static int saw_advance_loc4; static fragS *loc4_frag; static int loc4_fix; + if (saw_size + && S_IS_DEFINED (size_end_sym)) + { + /* We have come to the end of the CIE or FDE. See below where + we set saw_size. We must check this first because we may now + be looking at the next size. */ + saw_size = 0; + saw_advance_loc4 = 0; + } + if (flag_traditional_format) { /* Don't optimize. */ } else if (strcmp (segment_name (now_seg), ".eh_frame") != 0) ! { ! saw_size = 0; ! saw_advance_loc4 = 0; ! } ! else if (! saw_size ! && *pnbytes == 4) ! { ! /* This might be the size of the CIE or FDE. We want to know ! the size so that we don't accidentally optimize across an FDE ! boundary. We recognize the size in one of two forms: a ! symbol which will later be defined as a difference, or a ! subtraction of two symbols. Either way, we can tell when we ! are at the end of the FDE because the symbol becomes defined ! (in the case of a subtraction, the end symbol, from which the ! start symbol is being subtracted). Other ways of describing ! the size will not be optimized. */ ! if ((exp->X_op == O_symbol || exp->X_op == O_subtract) ! && ! S_IS_DEFINED (exp->X_add_symbol)) ! { ! saw_size = 1; ! size_end_sym = exp->X_add_symbol; ! } ! } ! else if (saw_size ! && *pnbytes == 1 && exp->X_op == O_constant && exp->X_add_number == DW_CFA_advance_loc4) { *** gas/subsegs.c.orig Fri May 1 11:45:16 1998 --- gas/subsegs.c Thu Aug 26 00:18:14 1999 *************** section_symbol (sec) *** 539,544 **** --- 539,589 ---- #endif /* BFD_ASSEMBLER */ + /* Return whether the specified segment is thought to hold text. */ + + #ifndef BFD_ASSEMBLER + const char * const nontext_section_names[] = + { + ".eh_frame", + ".gcc_except_table", + #ifdef OBJ_COFF + #ifndef COFF_LONG_SECTION_NAMES + ".eh_fram", + ".gcc_exc", + #endif + #endif + NULL + }; + #endif /* ! BFD_ASSEMBLER */ + + int + subseg_text_p (sec) + segT sec; + { + #ifdef BFD_ASSEMBLER + return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0; + #else /* ! BFD_ASSEMBLER */ + const char * const *p; + + if (sec == data_section || sec == bss_section) + return 0; + + for (p = nontext_section_names; *p != NULL; ++p) + { + if (strcmp (segment_name (sec), *p) == 0) + return 0; + + #ifdef obj_segment_name + if (strcmp (obj_segment_name (sec), *p) == 0) + return 0; + #endif + } + + return 1; + + #endif /* ! BFD_ASSEMBLER */ + } + void subsegs_print_statistics (file) FILE *file; *** gas/read.c.orig Fri May 1 11:45:16 1998 --- gas/read.c Thu Aug 26 00:21:18 1999 *************** do_align (n, fill, len, max) *** 1161,1181 **** if (fill == NULL) { ! int maybe_text; ! ! #ifdef BFD_ASSEMBLER ! if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) ! maybe_text = 1; ! else ! maybe_text = 0; ! #else ! if (now_seg != data_section && now_seg != bss_section) ! maybe_text = 1; ! else ! maybe_text = 0; ! #endif ! ! if (maybe_text) default_fill = NOP_OPCODE; else default_fill = 0; --- 1161,1167 ---- if (fill == NULL) { ! if (subseg_text_p (now_seg)) default_fill = NOP_OPCODE; else default_fill = 0; *** gas/write.c.orig Fri May 1 11:45:18 1998 --- gas/write.c Thu Aug 26 00:22:38 1999 *************** subsegs_finish () *** 1343,1349 **** for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) { subseg_set (frchainP->frch_seg, frchainP->frch_subseg); ! frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0); /* frag_align will have left a new frag. Use this last frag for an empty ".fill". --- 1343,1355 ---- for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) { subseg_set (frchainP->frch_seg, frchainP->frch_subseg); ! /* This now gets called even if we had errors. In that case, ! any alignment is meaningless, and, moreover, will look weird ! if we are generating a listing. */ ! frag_align (had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg), ! subseg_text_p (now_seg) ? NOP_OPCODE : 0, ! 0); ! /* frag_align will have left a new frag. Use this last frag for an empty ".fill". *** gas/config/tc-i386.h.orig Fri May 1 11:44:40 1998 --- gas/config/tc-i386.h Wed Aug 25 11:55:14 1999 *************** extern const char *i386_target_format PA *** 113,119 **** --- 113,133 ---- extern short tc_coff_fix2rtype PARAMS ((struct fix *)); #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag) extern int tc_coff_sizemachdep PARAMS ((fragS *frag)); + + #ifdef TE_GO32 + /* DJGPP now expects some sections to be 2**4 aligned. */ + #define SUB_SEGMENT_ALIGN(SEG) \ + ((strcmp (obj_segment_name (SEG), ".text") == 0 \ + || strcmp (obj_segment_name (SEG), ".data") == 0 \ + || strncmp (obj_segment_name (SEG), ".gnu.linkonce.t", 15) == 0 \ + || strncmp (obj_segment_name (SEG), ".gnu.linkonce.d", 15) == 0 \ + || strncmp (obj_segment_name (SEG), ".gnu.linkonce.r", 15) == 0) \ + ? 4 \ + : 2) + #else #define SUB_SEGMENT_ALIGN(SEG) 2 + #endif + #define TC_RVA_RELOC 7 /* Need this for PIC relocations */ #define NEED_FX_R_TYPE *************** extern int tc_coff_sizemachdep PARAMS (( *** 141,149 **** --- 155,165 ---- #ifndef BFD_ASSEMBLER #ifndef OBJ_AOUT #ifndef TE_PE + #ifndef TE_GO32 /* Local labels starts with .L */ #define LOCAL_LABEL(name) (name[0] == '.' \ && (name[1] == 'L' || name[1] == 'X' || name[1] == '.')) + #endif #endif #endif #endif *** gas/config/obj-coff.c.orig Fri May 1 11:44:34 1998 --- gas/config/obj-coff.c Wed Aug 25 23:59:52 1999 *************** *** 1,5 **** /* coff object file format ! Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. This file is part of GAS. --- 1,5 ---- /* coff object file format ! Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS. *************** obj_coff_bss (ignore) *** 179,184 **** --- 179,225 ---- s_lcomm (0); } + /* Handle .weak. This is a GNU extension. */ + + static void + obj_coff_weak (ignore) + int ignore; + { + char *name; + int c; + symbolS *symbolP; + + do + { + name = input_line_pointer; + c = get_symbol_end (); + symbolP = symbol_find_or_make (name); + *input_line_pointer = c; + SKIP_WHITESPACE (); + + #ifdef BFD_ASSEMLER + S_SET_WEAK (symbolP); + #endif + + #ifdef TE_PE + S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); + #else + S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT); + #endif + + if (c == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + if (*input_line_pointer == '\n') + c = '\n'; + } + } + while (c == ','); + + demand_empty_rest_of_line (); + } + #ifdef BFD_ASSEMBLER static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *)); *************** obj_coff_endef (ignore) *** 580,585 **** --- 621,630 ---- S_SET_SEGMENT (def_symbol_in_progress, absolute_section); break; + case C_WEAKEXT: + #ifdef TE_PE + case C_NT_WEAK: + #endif case C_EXT: case C_STAT: case C_LABEL: *************** obj_coff_section (ignore) *** 1217,1224 **** if (flags != SEC_NO_FLAGS) { if (! bfd_set_section_flags (stdoutput, sec, flags)) ! as_warn ("error setting flags for \"%s\": %s", bfd_section_name (stdoutput, sec), bfd_errmsg (bfd_get_error ())); } --- 1262,1275 ---- if (flags != SEC_NO_FLAGS) { + flagword oldflags; + + oldflags = bfd_get_section_flags (stdoutput, sec); + oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES; + flags |= oldflags; + if (! bfd_set_section_flags (stdoutput, sec, flags)) ! as_warn (_("error setting flags for \"%s\": %s"), bfd_section_name (stdoutput, sec), bfd_errmsg (bfd_get_error ())); } *************** const pseudo_typeS obj_pseudo_table[] = *** 4323,4328 **** --- 4374,4380 ---- /* We accept the .bss directive for backward compatibility with earlier versions of gas. */ {"bss", obj_coff_bss, 0}, + {"weak", obj_coff_weak, 0}, #ifndef BFD_ASSEMBLER {"use", obj_coff_section, 0}, {"text", obj_coff_text, 0}, *** ld/scripttempl/i386go32.sc.orig Fri May 1 11:48:56 1998 --- ld/scripttempl/i386go32.sc Thu Aug 26 09:47:04 1999 *************** *** 2,7 **** --- 2,17 ---- test -z "$ENTRY" && ENTRY=start EXE=${CONSTRUCTING+${RELOCATING+-exe}} + + # These are substituted in as variables in order to get '}' in a shell + # conditional expansion. + CTOR='.ctor : { + *(.ctor) + }' + DTOR='.dtor : { + *(.dtor) + }' + cat <