Message-Id: <199908252201.WAA107796@out4.ibm.net> From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Wed, 25 Aug 1999 18:01:05 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: backport patch for binutils 2.9.1 X-mailer: Pegasus Mail for Win32 (v3.12a) Reply-To: djgpp-workers AT delorie DOT com I've backported to binutils 2.9.1 the change to 16-byte alignment for .data and .text sections, long section names & .gnu.linkonce, the local label fix, and weak symbols, and the linker script template update for long section names, etc. Have fun, Mark *** 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/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 17:40:30 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: *************** const pseudo_typeS obj_pseudo_table[] = *** 4323,4328 **** --- 4368,4374 ---- /* 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 Tue Aug 24 12:00:16 1999 *************** *** 2,7 **** --- 2,21 ---- test -z "$ENTRY" && ENTRY=start EXE=${CONSTRUCTING+${RELOCATING+-exe}} + + # These are substituted in as variables in order to get '}' in a shell + # conditional expansion. + # Support the g++ attribute 'init_priority' from GCC 2.95 and above + # by sorting sections starting with '.ctors.' and '.dtors.' + CTOR='.ctor : { + *(SORT(.ctors.*)) + *(.ctor) + }' + DTOR='.dtor : { + *(SORT(.dtors.*)) + *(.dtor) + }' + cat <