Rework space/subspace handling in PA code to fully support

SOM spaces/subspaces.
	* config/tc-hppa.c (USE_ALIASES): New object-format dependent define
	to control the use of space/subspace name aliases.
	(update_subspace): Accept space chain entry for containing space
	as a new parameter.  All callers changed.
	(pa_get_label): Use current_space rather than pa_segment_to_space.
	(pa_define_label): Likewise.
	(pa_undefine_label): Likewise.
	(md_begin): Change into the (possibly modified) text_section.
	(pa_parse_space_stmt): Create a new segment/space if create_flag
	is true, and the space name is not one of the two predefined spaces.
	(pa_subspace): Use current_space rather than a lookup via
	pa_segment_to_space.  Reset BFD section flags as required by
	the .subspace directive.  Likewise for the section alignment.
	Pass the current space to update_subspace and create_new_subspace.
	(pa_spaces_begin): Only use space/subspace aliases if USE_ALIASES
	is true.  When not using aliases, create a BFD section for each
	subspace encountered.  When not using aliases replace the default
	text, data, and bss segments with new ones.
	(create_new_subspace): When not using aliases each subspace has a
	section/segment and subsegments are not needed, so set the subsegment
	to zero.
This commit is contained in:
Jeff Law 1993-10-31 01:53:01 +00:00
parent 5c2bae7507
commit 3b9a72c53c

View File

@ -55,6 +55,9 @@ typedef elf_symbol_type obj_symbol_type;
/* Who knows. */
#define obj_version obj_elf_version
/* Use space aliases. */
#define USE_ALIASES 1
/* Some local functions only used by ELF. */
static void pa_build_symextn_section PARAMS ((void));
static void hppa_tc_make_symextn_section PARAMS ((void));
@ -73,6 +76,9 @@ typedef int reloc_type;
/* Who knows. */
#define obj_version obj_som_version
/* Do not use space aliases. */
#define USE_ALIASES 0
/* How to generate a relocation. */
#define hppa_gen_reloc_type hppa_som_gen_reloc_type
@ -569,7 +575,8 @@ static ssd_chain_struct * create_new_subspace PARAMS ((sd_chain_struct *,
char, char, char,
char, int, int, int,
int, asection *));
static ssd_chain_struct *update_subspace PARAMS ((char *, char, char, char,
static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
char *, char, char, char,
char, char, char, int,
int, int, int, subsegT));
static sd_chain_struct *is_defined_space PARAMS ((char *));
@ -1181,7 +1188,7 @@ static label_symbol_struct *
pa_get_label ()
{
label_symbol_struct *label_chain;
sd_chain_struct *space_chain = pa_segment_to_space (now_seg);
sd_chain_struct *space_chain = current_space;
for (label_chain = label_symbols_rootp;
label_chain;
@ -1200,7 +1207,7 @@ pa_define_label (symbol)
symbolS *symbol;
{
label_symbol_struct *label_chain = pa_get_label ();
sd_chain_struct *space_chain = pa_segment_to_space (now_seg);
sd_chain_struct *space_chain = current_space;
if (label_chain)
label_chain->lss_label = symbol;
@ -1228,7 +1235,7 @@ pa_undefine_label ()
{
label_symbol_struct *label_chain;
label_symbol_struct *prev_label_chain = NULL;
sd_chain_struct *space_chain = pa_segment_to_space (now_seg);
sd_chain_struct *space_chain = current_space;
for (label_chain = label_symbols_rootp;
label_chain;
@ -1383,6 +1390,10 @@ md_begin ()
if (lose)
as_fatal ("Broken assembler. No assembly attempted.");
/* SOM will change text_section. To make sure we never put
anything into the old one switch to the new one now. */
subseg_set (text_section, 0);
}
/* Called at the end of assembling a source file. Nothing to do
@ -5100,11 +5111,12 @@ pa_parse_space_stmt (space_name, create_flag)
char *name, *ptemp, c;
char loadable, defined, private, sort;
int spnum;
asection *seg;
asection *seg = NULL;
sd_chain_struct *space;
/* load default values */
spnum = 0;
sort = 0;
loadable = TRUE;
defined = TRUE;
private = FALSE;
@ -5174,6 +5186,9 @@ pa_parse_space_stmt (space_name, create_flag)
print_errors = TRUE;
}
if (create_flag && seg == NULL)
seg = subseg_new (space_name, 0);
/* If create_flag is nonzero, then create the new space with
the attributes computed above. Else set the values in
an already existing space -- this can only happen for
@ -5414,7 +5429,7 @@ log2 (value)
return shift;
}
/* Handle a .SPACE pseudo-op; this switches the current subspace to the
/* Handle a .SUBSPACE pseudo-op; this switches the current subspace to the
given subspace, creating the new subspace if necessary.
FIXME. Should mirror pa_space more closely, in particular how
@ -5424,11 +5439,12 @@ static void
pa_subspace (unused)
int unused;
{
char *name, *ss_name, c;
char *name, *ss_name, *alias, c;
char loadable, code_only, common, dup_common, zero, sort;
int i, access, space_index, alignment, quadrant;
int i, access, space_index, alignment, quadrant, applicable, flags;
sd_chain_struct *space;
ssd_chain_struct *ssd;
asection *section;
if (within_procedure)
{
@ -5454,8 +5470,9 @@ pa_subspace (unused)
space_index = ~0;
alignment = 0;
quadrant = 0;
alias = NULL;
space = pa_segment_to_space (now_seg);
space = current_space;
ssd = is_defined_subspace (name, space->sd_last_subseg);
if (ssd)
{
@ -5467,7 +5484,8 @@ pa_subspace (unused)
}
else
{
/* A new subspace. Load default values. */
/* A new subspace. Load default values if it matches one of
the builtin subspaces. */
i = 0;
while (pa_def_subspaces[i].name)
{
@ -5483,6 +5501,8 @@ pa_subspace (unused)
quadrant = pa_def_subspaces[i].quadrant;
access = pa_def_subspaces[i].access;
sort = pa_def_subspaces[i].sort;
if (USE_ALIASES && pa_def_subspaces[i].alias)
alias = pa_def_subspaces[i].alias;
break;
}
i++;
@ -5561,25 +5581,73 @@ pa_subspace (unused)
}
}
/* Now that all the flags are set, update an existing subspace,
or create a new one with the given flags if the subspace does
not currently exist. */
space = pa_segment_to_space (now_seg);
/* Compute a reasonable set of BFD flags based on the information
in the .subspace directive. */
applicable = bfd_applicable_section_flags (stdoutput);
flags = 0;
if (loadable)
flags |= (SEC_ALLOC | SEC_LOAD);
if (code_only)
flags |= SEC_CODE;
if (common || dup_common)
flags |= SEC_IS_COMMON;
/* This is a zero-filled subspace (eg BSS). */
if (zero)
flags &= ~SEC_LOAD;
flags |= SEC_RELOC | SEC_HAS_CONTENTS;
applicable &= flags;
/* If this is an existing subspace, then we want to use the
segment already associated with the subspace.
FIXME NOW! ELF BFD doesn't appear to be ready to deal with
lots of sections. It might be a problem in the PA ELF
code, I do not know yet. For now avoid creating anything
but the "standard" sections for ELF. */
if (ssd)
current_subspace = update_subspace (ss_name, loadable, code_only,
common, dup_common, sort, zero,
access, space_index, alignment,
quadrant, ssd->ssd_subseg);
section = ssd->ssd_seg;
if (alias)
section = subseg_new (alias, 0);
else if (! alias && USE_ALIASES)
{
as_warn ("Ignoring subspace decl due to ELF BFD bugs.");
demand_empty_rest_of_line ();
return;
}
else
section = subseg_new (ss_name, 0);
/* Now set the flags. */
bfd_set_section_flags (stdoutput, section, applicable);
/* Record any alignment request for this section. */
record_alignment (section, log2 (alignment));
/* Set the starting offset for this section. */
bfd_set_section_vma (stdoutput, section,
pa_subspace_start (space, quadrant));
/* Now that all the flags are set, update an existing subspace,
or create a new one. */
if (ssd)
current_subspace = update_subspace (space, ss_name, loadable,
code_only, common, dup_common,
sort, zero, access, space_index,
alignment, quadrant,
ssd->ssd_subseg);
else
current_subspace = create_new_subspace (space, ss_name, loadable,
code_only, common,
dup_common, zero, sort,
access, space_index,
alignment, quadrant, now_seg);
SUBSPACE_SUBSPACE_START (current_subspace) = pa_subspace_start (space,
quadrant);
alignment, quadrant, section);
demand_empty_rest_of_line ();
current_subspace->ssd_seg = section;
subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
}
return;
@ -5591,7 +5659,6 @@ pa_subspace (unused)
static void
pa_spaces_begin ()
{
sd_chain_struct *space;
int i;
space_dict_root = NULL;
@ -5600,12 +5667,15 @@ pa_spaces_begin ()
i = 0;
while (pa_def_spaces[i].name)
{
if (pa_def_spaces[i].alias)
pa_def_spaces[i].segment = subseg_new (pa_def_spaces[i].alias, 0);
else
pa_def_spaces[i].segment
= bfd_make_section_old_way (stdoutput, pa_def_spaces[i].name);
char *name;
/* Pick the right name to use for the new section. */
if (pa_def_spaces[i].alias && USE_ALIASES)
name = pa_def_spaces[i].alias;
else
name = pa_def_spaces[i].name;
pa_def_spaces[i].segment = subseg_new (name, 0);
create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum,
pa_def_spaces[i].loadable, pa_def_spaces[i].defined,
pa_def_spaces[i].private, pa_def_spaces[i].sort,
@ -5616,12 +5686,68 @@ pa_spaces_begin ()
i = 0;
while (pa_def_subspaces[i].name)
{
space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
if (space)
char *name;
int applicable, subsegment;
asection *segment = NULL;
sd_chain_struct *space;
/* Pick the right name for the new section and pick the right
subsegment number. */
if (pa_def_subspaces[i].alias && USE_ALIASES)
{
name = pa_def_subspaces[i].alias;
subsegment = pa_def_subspaces[i].subsegment;
}
else
{
char *name = pa_def_subspaces[i].alias;
if (!name)
name = pa_def_subspaces[i].name;
subsegment = 0;
}
/* Create the new section. */
segment = subseg_new (name, subsegment);
/* For SOM we want to replace the standard .text, .data, and .bss
sections with our own. */
if (! strcmp (pa_def_subspaces[i].name, "$CODE$") && ! USE_ALIASES)
{
text_section = segment;
applicable = bfd_applicable_section_flags (stdoutput);
bfd_set_section_flags (stdoutput, text_section,
applicable & (SEC_ALLOC | SEC_LOAD
| SEC_RELOC | SEC_CODE
| SEC_READONLY
| SEC_HAS_CONTENTS));
}
else if (! strcmp (pa_def_subspaces[i].name, "$DATA$") && ! USE_ALIASES)
{
data_section = segment;
applicable = bfd_applicable_section_flags (stdoutput);
bfd_set_section_flags (stdoutput, data_section,
applicable & (SEC_ALLOC | SEC_LOAD
| SEC_RELOC
| SEC_HAS_CONTENTS));
}
else if (! strcmp (pa_def_subspaces[i].name, "$BSS$") && ! USE_ALIASES)
{
bss_section = segment;
applicable = bfd_applicable_section_flags (stdoutput);
bfd_set_section_flags (stdoutput, bss_section,
applicable & SEC_ALLOC);
}
/* Find the space associated with this subspace. */
space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].
def_space_index].segment);
if (space == NULL)
{
as_fatal ("Internal error: Unable to find containing space for %s.",
pa_def_subspaces[i].name);
}
create_new_subspace (space, name,
pa_def_subspaces[i].loadable,
pa_def_subspaces[i].code_only,
@ -5633,12 +5759,7 @@ pa_spaces_begin ()
pa_def_subspaces[i].space_index,
pa_def_subspaces[i].alignment,
pa_def_subspaces[i].quadrant,
pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
subseg_new (name, pa_def_subspaces[i].subsegment);
}
else
as_fatal ("Internal error: space missing for subspace \"%s\"\n",
pa_def_subspaces[i].name);
segment);
i++;
}
}
@ -5758,7 +5879,6 @@ create_new_subspace (space, name, loadable, code_only, common,
asection *seg;
{
ssd_chain_struct *chain_entry;
symbolS *start_symbol;
chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
if (!chain_entry)
@ -5779,7 +5899,7 @@ create_new_subspace (space, name, loadable, code_only, common,
SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
SUBSPACE_ZERO (chain_entry) = is_zero;
chain_entry->ssd_subseg = pa_next_subseg (space);
chain_entry->ssd_subseg = USE_ALIASES ? pa_next_subseg (space) : 0;
chain_entry->ssd_seg = seg;
chain_entry->ssd_last_align = 1;
chain_entry->ssd_next = NULL;
@ -5834,8 +5954,9 @@ create_new_subspace (space, name, loadable, code_only, common,
various arguments. Return the modified subspace chain entry. */
static ssd_chain_struct *
update_subspace (name, loadable, code_only, common, dup_common, sort,
update_subspace (space, name, loadable, code_only, common, dup_common, sort,
zero, access, space_index, alignment, quadrant, subseg)
sd_chain_struct *space;
char *name;
char loadable;
char code_only;