* som.c (struct som_misc_symbol_info): Add is_comdat, is_common and

dup_common fields.
	(setup_sections): Use som_subspace_dictionary_record struct instead
	subspace_dictionary_record.  Set SEC_LINK_ONCE if subspace is
	is_comdat, is_common or dup_common.
	(som_prep_headers): Use som_subspace_dictionary_record struct.  Set
	is_comdat, is_common and dup_common in section subspace_dict from
	copy_data.
	(som_begin_writing): Use som_subspace_dictionary_record struct.
	(som_finish_writing): Likewise.
	(som_bfd_derive_misc_symbol_info): Add support to set is_comdat,
	is_common and dup_common flags in info for symbol.  Add comment
	regarding linker support for these fields.  Slightly reorganize
	function.
	(som_build_and_write_symbol_table): Set is_comdat, is_common and
	dup_common fields in symbol table from symbol info.
	(bfd_som_set_subsection_attributes): Add comdat, common and dup_common
	arguments.  Set corresponding fields in copy_data.  Change all callers.
	(som_bfd_ar_write_symbol_stuff): Set dup_common flag in library
	symbol table.
	(som_vec): Add SEC_LINK_ONCE to applicable section flags.
	* som.h (som_subspace_dictionary_record): Define.
	(som_copyable_section_data_struct): Add is_comdat, is_common and
	dup_common fields.
	(som_section_data_struct): Use som_subspace_dictionary_record struct
	instead of subspace_dictionary_record.
	(bfd_boolean bfd_som_set_subsection_attributes): Adjust prototype.
	* config/obj-som.c (obj_som_init_stab_section): Add new arguments in
	call to obj_set_subsection_attributes.
	(obj_som_init_stab_section): Likewise.
	* config/tc-hppa.c (default_subspace_dict): Add comdat field.
	(pa_def_subspaces): Provide comdat default.
	(pa_subspace): Handle new "comdat" parameter.  Set SEC_LINK_ONCE and
	not SEC_IS_COMMON if section is comdat, common or dup_common.  Update
	calls to create_new_subspace and update_subspace to pass comdat flag.
	(create_new_subspace, update_subspace): Add new comdat argument.  Use
	it in calls to obj_set_subsection_attributes.
	* doc/c-hppa.texi (.subspa, .nsubspa): Document new comdat parameter
	and use of comdat, common and dup_comm parameters.
This commit is contained in:
Dave Anglin 2004-04-28 18:02:49 +00:00
parent 82c10df67c
commit 351e2b5aa7
7 changed files with 250 additions and 65 deletions

View file

@ -1,3 +1,33 @@
2004-04-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* som.c (struct som_misc_symbol_info): Add is_comdat, is_common and
dup_common fields.
(setup_sections): Use som_subspace_dictionary_record struct instead
subspace_dictionary_record. Set SEC_LINK_ONCE if subspace is
is_comdat, is_common or dup_common.
(som_prep_headers): Use som_subspace_dictionary_record struct. Set
is_comdat, is_common and dup_common in section subspace_dict from
copy_data.
(som_begin_writing): Use som_subspace_dictionary_record struct.
(som_finish_writing): Likewise.
(som_bfd_derive_misc_symbol_info): Add support to set is_comdat,
is_common and dup_common flags in info for symbol. Add comment
regarding linker support for these fields. Slightly reorganize
function.
(som_build_and_write_symbol_table): Set is_comdat, is_common and
dup_common fields in symbol table from symbol info.
(bfd_som_set_subsection_attributes): Add comdat, common and dup_common
arguments. Set corresponding fields in copy_data. Change all callers.
(som_bfd_ar_write_symbol_stuff): Set dup_common flag in library
symbol table.
(som_vec): Add SEC_LINK_ONCE to applicable section flags.
* som.h (som_subspace_dictionary_record): Define.
(som_copyable_section_data_struct): Add is_comdat, is_common and
dup_common fields.
(som_section_data_struct): Use som_subspace_dictionary_record struct
instead of subspace_dictionary_record.
(bfd_boolean bfd_som_set_subsection_attributes): Adjust prototype.
2004-04-27 Bob Wilson <bob.wilson@acm.org>
* elf32-xtensa.c (xtensa_read_table_entries): Use section _cooked_size

114
bfd/som.c
View file

@ -146,6 +146,9 @@ struct som_misc_symbol_info {
unsigned int symbol_value;
unsigned int priv_level;
unsigned int secondary_def;
unsigned int is_comdat;
unsigned int is_common;
unsigned int dup_common;
};
/* Forward declarations. */
@ -1905,7 +1908,7 @@ setup_sections (abfd, file_hdr, current_offset)
for (space_index = 0; space_index < file_hdr->space_total; space_index++)
{
struct space_dictionary_record space;
struct subspace_dictionary_record subspace, save_subspace;
struct som_subspace_dictionary_record subspace, save_subspace;
unsigned int subspace_index;
asection *space_asect;
char *newname;
@ -1973,7 +1976,7 @@ setup_sections (abfd, file_hdr, current_offset)
/* Initialize save_subspace so we can reliably determine if this
loop placed any useful values into it. */
memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record));
memset (&save_subspace, 0, sizeof (save_subspace));
/* Loop over the rest of the subspaces, building up more sections. */
for (subspace_index = 0; subspace_index < space.subspace_quantity;
@ -2004,7 +2007,10 @@ setup_sections (abfd, file_hdr, current_offset)
if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect,
subspace.access_control_bits,
subspace.sort_key,
subspace.quadrant))
subspace.quadrant,
subspace.is_comdat,
subspace.is_common,
subspace.dup_common))
goto error_return;
/* Keep an easy mapping between subspaces and sections.
@ -2050,9 +2056,10 @@ setup_sections (abfd, file_hdr, current_offset)
break;
}
if (subspace.dup_common || subspace.is_common)
subspace_asect->flags |= SEC_IS_COMMON;
else if (subspace.subspace_length > 0)
if (subspace.is_comdat || subspace.is_common || subspace.dup_common)
subspace_asect->flags |= SEC_LINK_ONCE;
if (subspace.subspace_length > 0)
subspace_asect->flags |= SEC_HAS_CONTENTS;
if (subspace.is_loadable)
@ -2402,21 +2409,15 @@ som_prep_headers (abfd)
else
{
/* Allocate space for the subspace dictionary. */
amt = sizeof (struct subspace_dictionary_record);
amt = sizeof (struct som_subspace_dictionary_record);
som_section_data (section)->subspace_dict =
(struct subspace_dictionary_record *) bfd_zalloc (abfd, amt);
(struct som_subspace_dictionary_record *) bfd_zalloc (abfd, amt);
if (som_section_data (section)->subspace_dict == NULL)
return FALSE;
/* Set subspace attributes. Basic stuff is done here, additional
attributes are filled in later as more information becomes
available. */
if (section->flags & SEC_IS_COMMON)
{
som_section_data (section)->subspace_dict->dup_common = 1;
som_section_data (section)->subspace_dict->is_common = 1;
}
if (section->flags & SEC_ALLOC)
som_section_data (section)->subspace_dict->is_loadable = 1;
@ -2439,6 +2440,12 @@ som_prep_headers (abfd)
som_section_data (section)->copy_data->access_control_bits;
som_section_data (section)->subspace_dict->quadrant =
som_section_data (section)->copy_data->quadrant;
som_section_data (section)->subspace_dict->is_comdat =
som_section_data (section)->copy_data->is_comdat;
som_section_data (section)->subspace_dict->is_common =
som_section_data (section)->copy_data->is_common;
som_section_data (section)->subspace_dict->dup_common =
som_section_data (section)->copy_data->dup_common;
}
}
return TRUE;
@ -3474,7 +3481,8 @@ som_begin_writing (abfd)
num_subspaces = som_count_subspaces (abfd);
obj_som_file_hdr (abfd)->subspace_location = current_offset;
obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
current_offset
+= num_subspaces * sizeof (struct som_subspace_dictionary_record);
/* Next is the string table for the space/subspace names. We will
build and write the string table on the fly. At the same time
@ -3849,7 +3857,7 @@ som_finish_writing (abfd)
som_section_data (subsection)->subspace_dict->space_index = i;
/* Dump the current subspace header. */
amt = sizeof (struct subspace_dictionary_record);
amt = sizeof (struct som_subspace_dictionary_record);
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict,
amt, abfd) != amt)
return FALSE;
@ -3905,7 +3913,7 @@ som_finish_writing (abfd)
som_section_data (subsection)->subspace_dict->space_index = i;
/* Dump this subspace header. */
amt = sizeof (struct subspace_dictionary_record);
amt = sizeof (struct som_subspace_dictionary_record);
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict,
amt, abfd) != amt)
return FALSE;
@ -4053,12 +4061,12 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
info->symbol_type = ST_DATA;
else
{
/* Common symbols must have scope SS_UNSAT and type
ST_STORAGE or the linker will choke. */
/* For BFD style common, the linker will choke unless we set the
type and scope to ST_STORAGE and SS_UNSAT, respectively. */
if (bfd_is_com_section (sym->section))
{
info->symbol_scope = SS_UNSAT;
info->symbol_type = ST_STORAGE;
info->symbol_scope = SS_UNSAT;
}
/* It is possible to have a symbol without an associated
@ -4097,9 +4105,6 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
info->symbol_type = ST_DATA;
}
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
info->symbol_type = ST_DATA;
/* From now on it's a very simple mapping. */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
info->symbol_type = ST_ABSOLUTE;
@ -4120,14 +4125,15 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
/* Now handle the symbol's scope. Exported data which is not
in the common section has scope SS_UNIVERSAL. Note scope
of common symbols was handled earlier! */
if (bfd_is_und_section (sym->section))
if (bfd_is_com_section (sym->section))
;
else if (bfd_is_und_section (sym->section))
info->symbol_scope = SS_UNSAT;
else if (sym->flags & (BSF_EXPORT | BSF_WEAK)
&& ! bfd_is_com_section (sym->section))
else if (sym->flags & (BSF_EXPORT | BSF_WEAK))
info->symbol_scope = SS_UNIVERSAL;
/* Anything else which is not in the common section has scope
SS_LOCAL. */
else if (! bfd_is_com_section (sym->section))
else
info->symbol_scope = SS_LOCAL;
/* Now set the symbol_info field. It has no real meaning
@ -4146,12 +4152,49 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
/* Set the symbol's value. */
info->symbol_value = sym->value + sym->section->vma;
/* The secondary_def field is for weak symbols. */
/* The secondary_def field is for "weak" symbols. */
if (sym->flags & BSF_WEAK)
info->secondary_def = TRUE;
else
info->secondary_def = FALSE;
/* The is_comdat, is_common and dup_common fields provide various
flavors of common.
For data symbols, setting IS_COMMON provides Fortran style common
(duplicate definitions and overlapped initialization). Setting both
IS_COMMON and DUP_COMMON provides Cobol style common (duplicate
definitions as long as they are all the same length). In a shared
link data symbols retain their IS_COMMON and DUP_COMMON flags.
An IS_COMDAT data symbol is similar to a IS_COMMON | DUP_COMMON
symbol except in that it loses its IS_COMDAT flag in a shared link.
For code symbols, IS_COMDAT and DUP_COMMON have effect. Universal
DUP_COMMON code symbols are not exported from shared libraries.
IS_COMDAT symbols are exported but they lose their IS_COMDAT flag.
We take a simplified approach to setting the is_comdat, is_common
and dup_common flags in symbols based on the flag settings of their
subspace. This avoids having to add directives like `.comdat' but
the linker behavior is probably undefined if there is more than one
universal symbol (comdat key sysmbol) in a subspace.
The behavior of these flags is not well documentmented, so there
may be bugs and some surprising interactions with other flags. */
if (som_section_data (sym->section)
&& som_section_data (sym->section)->subspace_dict
&& info->symbol_scope == SS_UNIVERSAL
&& (info->symbol_type == ST_ENTRY
|| info->symbol_type == ST_CODE
|| info->symbol_type == ST_DATA))
{
info->is_comdat
= som_section_data (sym->section)->subspace_dict->is_comdat;
info->is_common
= som_section_data (sym->section)->subspace_dict->is_common;
info->dup_common
= som_section_data (sym->section)->subspace_dict->dup_common;
}
}
/* Build and write, in one big chunk, the entire symbol table for
@ -4197,6 +4240,9 @@ som_build_and_write_symbol_table (abfd)
som_symtab[i].xleast = 3;
som_symtab[i].symbol_value = info.symbol_value | info.priv_level;
som_symtab[i].secondary_def = info.secondary_def;
som_symtab[i].is_comdat = info.is_comdat;
som_symtab[i].is_common = info.is_common;
som_symtab[i].dup_common = info.dup_common;
}
/* Everything is ready, seek to the right location and
@ -5220,12 +5266,13 @@ bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
bfd_boolean
bfd_som_set_subsection_attributes (section, container, access,
sort_key, quadrant)
sort_key, quadrant, comdat,
common, dup_common)
asection *section;
asection *container;
int access;
unsigned int sort_key;
int quadrant;
int quadrant, comdat, common, dup_common;
{
/* Allocate memory to hold the magic information. */
if (som_section_data (section)->copy_data == NULL)
@ -5241,6 +5288,9 @@ bfd_som_set_subsection_attributes (section, container, access,
som_section_data (section)->copy_data->access_control_bits = access;
som_section_data (section)->copy_data->quadrant = quadrant;
som_section_data (section)->copy_data->container = container;
som_section_data (section)->copy_data->is_comdat = comdat;
som_section_data (section)->copy_data->is_common = common;
som_section_data (section)->copy_data->dup_common = dup_common;
return TRUE;
}
@ -6044,7 +6094,7 @@ som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst, elength)
curr_lst_sym->initially_frozen = 0;
curr_lst_sym->memory_resident = 0;
curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
curr_lst_sym->dup_common = 0;
curr_lst_sym->dup_common = info.dup_common;
curr_lst_sym->xleast = 3;
curr_lst_sym->arg_reloc = info.arg_reloc;
curr_lst_sym->name.n_strx = p - strings + 4;
@ -6370,7 +6420,7 @@ const bfd_target som_vec = {
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE
| SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
/* leading_symbol_char: is the first char of a user symbol

View file

@ -27,7 +27,7 @@
#include "libhppa.h"
/* Enable PA2.0 if available */
/* We want reloc.h to provide PA 2.0 defines. */
#define PA_2_0
#include <a.out.h>
@ -143,6 +143,35 @@ struct som_data_struct
struct somdata a;
};
struct som_subspace_dictionary_record
{
int space_index;
unsigned int access_control_bits : 7;
unsigned int memory_resident : 1;
unsigned int dup_common : 1;
unsigned int is_common : 1;
unsigned int is_loadable : 1;
unsigned int quadrant : 2;
unsigned int initially_frozen : 1;
unsigned int is_first : 1;
unsigned int code_only : 1;
unsigned int sort_key : 8;
unsigned int replicate_init : 1;
unsigned int continuation : 1;
unsigned int is_tspecific : 1;
unsigned int is_comdat : 1;
unsigned int reserved : 4;
int file_loc_init_value;
unsigned int initialization_length;
unsigned int subspace_start;
unsigned int subspace_length;
unsigned int reserved2 : 5;
unsigned int alignment :27;
union name_pt name;
int fixup_request_index;
unsigned int fixup_request_quantity;
};
/* Substructure of som_section_data_struct used to hold information
which can't be represented by the generic BFD section structure,
but which must be copied during objcopy or strip. */
@ -155,6 +184,9 @@ struct som_copyable_section_data_struct
unsigned int is_defined : 1;
unsigned int is_private : 1;
unsigned int quadrant : 2;
unsigned int is_comdat : 1;
unsigned int is_common : 1;
unsigned int dup_common : 1;
/* For subspaces, this points to the section which represents the
space in which the subspace is contained. For spaces it points
@ -184,7 +216,7 @@ struct som_section_data_struct
unsigned int reloc_size;
char *reloc_stream;
struct space_dictionary_record *space_dict;
struct subspace_dictionary_record *subspace_dict;
struct som_subspace_dictionary_record *subspace_dict;
};
#define somdata(bfd) ((bfd)->tdata.som_data->a)
@ -231,7 +263,7 @@ struct som_section_data_struct
bfd_boolean bfd_som_set_section_attributes
PARAMS ((asection *, int, int, unsigned int, int));
bfd_boolean bfd_som_set_subsection_attributes
PARAMS ((asection *, asection *, int, unsigned int, int));
PARAMS ((asection *, asection *, int, unsigned int, int, int, int, int));
void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int));
bfd_boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *));
int ** hppa_som_gen_reloc_type

View file

@ -1,3 +1,18 @@
2004-04-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config/obj-som.c (obj_som_init_stab_section): Add new arguments in
call to obj_set_subsection_attributes.
(obj_som_init_stab_section): Likewise.
* config/tc-hppa.c (default_subspace_dict): Add comdat field.
(pa_def_subspaces): Provide comdat default.
(pa_subspace): Handle new "comdat" parameter. Set SEC_LINK_ONCE and
not SEC_IS_COMMON if section is comdat, common or dup_common. Update
calls to create_new_subspace and update_subspace to pass comdat flag.
(create_new_subspace, update_subspace): Add new comdat argument. Use
it in calls to obj_set_subsection_attributes.
* doc/c-hppa.texi (.subspa, .nsubspa): Document new comdat parameter
and use of comdat, common and dup_comm parameters.
2004-04-26 H.J. Lu <hongjiu.lu@intel.com>
* config/obj-elf.c (obj_elf_change_section): Check if the old

View file

@ -248,7 +248,7 @@ obj_som_init_stab_section (seg)
(just created above). Also set some attributes which BFD does
not understand. In particular, access bits, sort keys, and load
quadrant. */
obj_set_subsection_attributes (seg, space, 0x1f, 73, 0);
obj_set_subsection_attributes (seg, space, 0x1f, 73, 0, 0, 0, 0);
bfd_set_section_alignment (stdoutput, seg, 2);
/* Make some space for the first special stab entry and zero the memory.
@ -271,7 +271,7 @@ obj_som_init_stab_section (seg)
not understand. In particular, access bits, sort keys, and load
quadrant. */
seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
obj_set_subsection_attributes (seg, space, 0x1f, 72, 0);
obj_set_subsection_attributes (seg, space, 0x1f, 72, 0, 0, 0, 0);
bfd_set_section_alignment (stdoutput, seg, 2);
subseg_set (saved_seg, saved_subseg);

View file

@ -363,6 +363,9 @@ struct default_subspace_dict
/* Nonzero if this subspace contains only code. */
char code_only;
/* Nonzero if this is a comdat subspace. */
char comdat;
/* Nonzero if this is a common subspace. */
char common;
@ -555,13 +558,13 @@ static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
asection *, int));
static ssd_chain_struct *create_new_subspace PARAMS ((sd_chain_struct *,
char *, int, int,
int, int, int,
int, int, int, int,
int, int, int, int,
int, asection *));
static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
char *, int, int, int,
int, int, int, int,
int, int, int,
int, int, int, int,
asection *));
static sd_chain_struct *is_defined_space PARAMS ((char *));
static ssd_chain_struct *is_defined_subspace PARAMS ((char *));
@ -1117,12 +1120,12 @@ static const struct selector_entry selector_table[] =
static struct default_subspace_dict pa_def_subspaces[] =
{
{"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},
{"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},
{"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},
{"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},
{"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},
{NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
{"$CODE$", 1, 1, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},
{"$DATA$", 1, 1, 0, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},
{"$LIT$", 1, 1, 0, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},
{"$MILLICODE$", 1, 1, 0, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},
{"$BSS$", 1, 1, 0, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},
{NULL, 0, 1, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
};
static struct default_space_dict pa_def_spaces[] =
@ -7454,7 +7457,7 @@ pa_subspace (create_new)
int create_new;
{
char *name, *ss_name, c;
char loadable, code_only, common, dup_common, zero, sort;
char loadable, code_only, comdat, common, dup_common, zero, sort;
int i, access, space_index, alignment, quadrant, applicable, flags;
sd_chain_struct *space;
ssd_chain_struct *ssd;
@ -7480,6 +7483,7 @@ pa_subspace (create_new)
sort = 0;
access = 0x7f;
loadable = 1;
comdat = 0;
common = 0;
dup_common = 0;
code_only = 0;
@ -7514,6 +7518,7 @@ pa_subspace (create_new)
if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
{
loadable = pa_def_subspaces[i].loadable;
comdat = pa_def_subspaces[i].comdat;
common = pa_def_subspaces[i].common;
dup_common = pa_def_subspaces[i].dup_common;
code_only = pa_def_subspaces[i].code_only;
@ -7577,6 +7582,11 @@ pa_subspace (create_new)
*input_line_pointer = c;
loadable = 0;
}
else if ((strncasecmp (name, "comdat", 6) == 0))
{
*input_line_pointer = c;
comdat = 1;
}
else if ((strncasecmp (name, "common", 6) == 0))
{
*input_line_pointer = c;
@ -7609,8 +7619,17 @@ pa_subspace (create_new)
flags |= (SEC_ALLOC | SEC_LOAD);
if (code_only)
flags |= SEC_CODE;
if (common || dup_common)
flags |= SEC_IS_COMMON;
/* These flags are used to implement various flavors of initialized
common. The SOM linker discards duplicate subspaces when they
have the same "key" symbol name. This support is more like
GNU linkonce than BFD common. Further, pc-relative relocations
are converted to section relative relocations in BFD common
sections. This complicates the handling of relocations in
common sections containing text and isn't currently supported
correctly in the SOM BFD backend. */
if (comdat || common || dup_common)
flags |= SEC_LINK_ONCE;
flags |= SEC_RELOC | SEC_HAS_CONTENTS;
@ -7652,16 +7671,16 @@ pa_subspace (create_new)
if (ssd)
current_subspace = update_subspace (space, ss_name, loadable,
code_only, common, dup_common,
sort, zero, access, space_index,
alignment, quadrant,
code_only, comdat, common,
dup_common, sort, zero, access,
space_index, alignment, quadrant,
section);
else
current_subspace = create_new_subspace (space, ss_name, loadable,
code_only, common,
code_only, comdat, common,
dup_common, zero, sort,
access, space_index,
alignment, quadrant, section);
alignment, quadrant, section);
demand_empty_rest_of_line ();
current_subspace->ssd_seg = section;
@ -7782,6 +7801,7 @@ pa_spaces_begin ()
create_new_subspace (space, name,
pa_def_subspaces[i].loadable,
pa_def_subspaces[i].code_only,
pa_def_subspaces[i].comdat,
pa_def_subspaces[i].common,
pa_def_subspaces[i].dup_common,
pa_def_subspaces[i].zero,
@ -7883,12 +7903,12 @@ create_new_space (name, spnum, loadable, defined, private,
order as defined by the SORT entries. */
static ssd_chain_struct *
create_new_subspace (space, name, loadable, code_only, common,
create_new_subspace (space, name, loadable, code_only, comdat, common,
dup_common, is_zero, sort, access, space_index,
alignment, quadrant, seg)
sd_chain_struct *space;
char *name;
int loadable, code_only, common, dup_common, is_zero;
int loadable, code_only, comdat, common, dup_common, is_zero;
int sort;
int access;
int space_index;
@ -7945,8 +7965,8 @@ create_new_subspace (space, name, loadable, code_only, common,
}
#ifdef obj_set_subsection_attributes
obj_set_subsection_attributes (seg, space->sd_seg, access,
sort, quadrant);
obj_set_subsection_attributes (seg, space->sd_seg, access, sort,
quadrant, comdat, common, dup_common);
#endif
return chain_entry;
@ -7956,12 +7976,13 @@ create_new_subspace (space, name, loadable, code_only, common,
various arguments. Return the modified subspace chain entry. */
static ssd_chain_struct *
update_subspace (space, name, loadable, code_only, common, dup_common, sort,
zero, access, space_index, alignment, quadrant, section)
update_subspace (space, name, loadable, code_only, comdat, common, dup_common,
sort, zero, access, space_index, alignment, quadrant, section)
sd_chain_struct *space;
char *name;
int loadable;
int code_only;
int comdat;
int common;
int dup_common;
int zero;
@ -7977,8 +7998,8 @@ update_subspace (space, name, loadable, code_only, common, dup_common, sort,
chain_entry = is_defined_subspace (name);
#ifdef obj_set_subsection_attributes
obj_set_subsection_attributes (section, space->sd_seg, access,
sort, quadrant);
obj_set_subsection_attributes (section, space->sd_seg, access, sort,
quadrant, comdat, common, dup_common);
#endif
return chain_entry;

View file

@ -245,14 +245,51 @@ identified by keywords. The keywords recognized are @samp{quad=@var{expr}}
beginning of this subsection; a power of two), @samp{access=@var{expr}} (value
for ``access rights'' field), @samp{sort=@var{expr}} (sorting order for this
subspace in link), @samp{code_only} (subsection contains only code),
@samp{unloadable} (subsection cannot be loaded into memory), @samp{common}
(subsection is common block), @samp{dup_comm} (initialized data may have
duplicate names), or @samp{zero} (subsection is all zeros, do not write in
object file).
@samp{unloadable} (subsection cannot be loaded into memory), @samp{comdat}
(subsection is comdat), @samp{common} (subsection is common block),
@samp{dup_comm} (subsection may have duplicate names), or @samp{zero}
(subsection is all zeros, do not write in object file).
@code{.nsubspa} always creates a new subspace with the given name, even
if one with the same name already exists.
@samp{comdat}, @samp{common} and @samp{dup_comm} can be used to implement
various flavors of one-only support when using the SOM linker. The SOM
linker only supports specific combinations of these flags. The details
are not documented. A brief description is provided here.
@samp{comdat} provides a form of linkonce support. It is useful for
both code and data subspaces. A @samp{comdat} subspace has a key symbol
marked by the @samp{is_comdat} flag or @samp{ST_COMDAT}. Only the first
subspace for any given key is selected. The key symbol becomes universal
in shared links. This is similar to the behavior of @samp{secondary_def}
symbols.
@samp{common} provides Fortran named common support. It is only useful
for data subspaces. Symbols with the flag @samp{is_common} retain this
flag in shared links. Referencing a @samp{is_common} symbol in a shared
library from outside the library doesn't work. Thus, @samp{is_common}
symbols must be output whenever they are needed.
@samp{common} and @samp{dup_comm} together provide Cobol common support.
The subspaces in this case must all be the same length. Otherwise, this
support is similar to the Fortran common support.
@samp{dup_comm} by itself provides a type of one-only support for code.
Only the first @samp{dup_comm} subspace is selected. There is a rather
complex algorithm to compare subspaces. Code symbols marked with the
@samp{dup_common} flag are hidden. This support was intended for "C++
duplicate inlines".
A simplified technique is used to mark the flags of symbols based on
the flags of their subspace. A symbol with the scope SS_UNIVERSAL and
type ST_ENTRY, ST_CODE or ST_DATA is marked with the corresponding
settings of @samp{comdat}, @samp{common} and @samp{dup_comm} from the
subspace, respectively. This avoids having to introduce additional
directives to mark these symbols. The HP assembler sets @samp{is_common}
from @samp{common}. However, it doesn't set the @samp{dup_common} from
@samp{dup_comm}. It doesn't have @samp{comdat} support.
@item .version "@var{str}"
Write @var{str} as version identifier in object code.
@end table