Mail Archives: djgpp-workers/1999/08/25/18:16:24
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 <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}${EXE}")
*************** SECTIONS
*** 11,39 ****
{
.text ${RELOCATING+ ${TARGET_PAGE_SIZE}+SIZEOF_HEADERS} : {
*(.text)
*(.const*)
*(.ro*)
${RELOCATING+etext = . ; _etext = .};
${RELOCATING+. = ALIGN(${SEGMENT_SIZE});}
}
.data ${RELOCATING+ ${DATA_ALIGNMENT}} : {
${RELOCATING+djgpp_first_ctor = . ;
*(.ctor)
djgpp_last_ctor = . ;}
${RELOCATING+djgpp_first_dtor = . ;
*(.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});}
}
}
--- 25,63 ----
{
.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});}
}
.data ${RELOCATING+ ${DATA_ALIGNMENT}} : {
${RELOCATING+djgpp_first_ctor = . ;
+ *(SORT(.ctors.*))
*(.ctor)
djgpp_last_ctor = . ;}
${RELOCATING+djgpp_first_dtor = . ;
+ *(SORT(.dtors.*))
*(.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 -