* 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:
parent
82c10df67c
commit
351e2b5aa7
7 changed files with 250 additions and 65 deletions
|
@ -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
114
bfd/som.c
|
@ -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
|
||||
|
|
38
bfd/som.h
38
bfd/som.h
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,13 +7671,13 @@ 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);
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue