Mail Archives: djgpp-workers/1999/08/26/10:46:10
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 <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}${EXE}")
*************** SECTIONS
*** 11,18 ****
--- 21,30 ----
{
.text ${RELOCATING+ ${TARGET_PAGE_SIZE}+SIZEOF_HEADERS} : {
*(.text)
+ ${RELOCATING+*(.gnu.linkonce.t.*)}
*(.const*)
*(.ro*)
+ ${RELOCATING+*(.gnu.linkonce.r.*)}
${RELOCATING+etext = . ; _etext = .};
${RELOCATING+. = ALIGN(${SEGMENT_SIZE});}
}
*************** SECTIONS
*** 24,39 ****
*(.dtor)
djgpp_last_dtor = . ;}
*(.data)
! ${RELOCATING+ edata = . ; _edata = .};
! ${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});}
}
! ${CONSTRUCTING+${RELOCATING-.ctor : { *(.ctor) }}}
! ${CONSTRUCTING+${RELOCATING-.dtor : { *(.dtor) }}}
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
{
*(.bss)
*(COMMON)
! ${RELOCATING+ end = . ; _end = .};
${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});}
}
}
--- 36,57 ----
*(.dtor)
djgpp_last_dtor = . ;}
*(.data)
!
! ${RELOCATING+*(.gcc_exc*)}
! ${RELOCATING+*(.eh_fram*)}
! ${RELOCATING+LONG(0);}
!
! ${RELOCATING+*(.gnu.linkonce.d.*)}
! ${RELOCATING+edata = . ; _edata = . ;}
! ${RELOCATING+. = ALIGN(${SEGMENT_SIZE});}
}
! ${CONSTRUCTING+${RELOCATING-$CTOR}}
! ${CONSTRUCTING+${RELOCATING-$DTOR}}
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
{
*(.bss)
*(COMMON)
! ${RELOCATING+ end = . ; _end = . ;}
${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});}
}
}
---
Mark Elbrecht, snowball3 AT bigfoot DOT com
http://snowball.frogspace.net/
- Raw text -