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:
parent
5c2bae7507
commit
3b9a72c53c
1 changed files with 171 additions and 50 deletions
|
@ -55,6 +55,9 @@ typedef elf_symbol_type obj_symbol_type;
|
||||||
/* Who knows. */
|
/* Who knows. */
|
||||||
#define obj_version obj_elf_version
|
#define obj_version obj_elf_version
|
||||||
|
|
||||||
|
/* Use space aliases. */
|
||||||
|
#define USE_ALIASES 1
|
||||||
|
|
||||||
/* Some local functions only used by ELF. */
|
/* Some local functions only used by ELF. */
|
||||||
static void pa_build_symextn_section PARAMS ((void));
|
static void pa_build_symextn_section PARAMS ((void));
|
||||||
static void hppa_tc_make_symextn_section PARAMS ((void));
|
static void hppa_tc_make_symextn_section PARAMS ((void));
|
||||||
|
@ -73,6 +76,9 @@ typedef int reloc_type;
|
||||||
/* Who knows. */
|
/* Who knows. */
|
||||||
#define obj_version obj_som_version
|
#define obj_version obj_som_version
|
||||||
|
|
||||||
|
/* Do not use space aliases. */
|
||||||
|
#define USE_ALIASES 0
|
||||||
|
|
||||||
/* How to generate a relocation. */
|
/* How to generate a relocation. */
|
||||||
#define hppa_gen_reloc_type hppa_som_gen_reloc_type
|
#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, char, char,
|
||||||
char, int, int, int,
|
char, int, int, int,
|
||||||
int, asection *));
|
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,
|
char, char, char, int,
|
||||||
int, int, int, subsegT));
|
int, int, int, subsegT));
|
||||||
static sd_chain_struct *is_defined_space PARAMS ((char *));
|
static sd_chain_struct *is_defined_space PARAMS ((char *));
|
||||||
|
@ -1181,7 +1188,7 @@ static label_symbol_struct *
|
||||||
pa_get_label ()
|
pa_get_label ()
|
||||||
{
|
{
|
||||||
label_symbol_struct *label_chain;
|
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;
|
for (label_chain = label_symbols_rootp;
|
||||||
label_chain;
|
label_chain;
|
||||||
|
@ -1200,7 +1207,7 @@ pa_define_label (symbol)
|
||||||
symbolS *symbol;
|
symbolS *symbol;
|
||||||
{
|
{
|
||||||
label_symbol_struct *label_chain = pa_get_label ();
|
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)
|
if (label_chain)
|
||||||
label_chain->lss_label = symbol;
|
label_chain->lss_label = symbol;
|
||||||
|
@ -1228,7 +1235,7 @@ pa_undefine_label ()
|
||||||
{
|
{
|
||||||
label_symbol_struct *label_chain;
|
label_symbol_struct *label_chain;
|
||||||
label_symbol_struct *prev_label_chain = NULL;
|
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;
|
for (label_chain = label_symbols_rootp;
|
||||||
label_chain;
|
label_chain;
|
||||||
|
@ -1383,6 +1390,10 @@ md_begin ()
|
||||||
|
|
||||||
if (lose)
|
if (lose)
|
||||||
as_fatal ("Broken assembler. No assembly attempted.");
|
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
|
/* 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 *name, *ptemp, c;
|
||||||
char loadable, defined, private, sort;
|
char loadable, defined, private, sort;
|
||||||
int spnum;
|
int spnum;
|
||||||
asection *seg;
|
asection *seg = NULL;
|
||||||
sd_chain_struct *space;
|
sd_chain_struct *space;
|
||||||
|
|
||||||
/* load default values */
|
/* load default values */
|
||||||
spnum = 0;
|
spnum = 0;
|
||||||
|
sort = 0;
|
||||||
loadable = TRUE;
|
loadable = TRUE;
|
||||||
defined = TRUE;
|
defined = TRUE;
|
||||||
private = FALSE;
|
private = FALSE;
|
||||||
|
@ -5174,6 +5186,9 @@ pa_parse_space_stmt (space_name, create_flag)
|
||||||
print_errors = TRUE;
|
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
|
/* If create_flag is nonzero, then create the new space with
|
||||||
the attributes computed above. Else set the values in
|
the attributes computed above. Else set the values in
|
||||||
an already existing space -- this can only happen for
|
an already existing space -- this can only happen for
|
||||||
|
@ -5414,7 +5429,7 @@ log2 (value)
|
||||||
return shift;
|
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.
|
given subspace, creating the new subspace if necessary.
|
||||||
|
|
||||||
FIXME. Should mirror pa_space more closely, in particular how
|
FIXME. Should mirror pa_space more closely, in particular how
|
||||||
|
@ -5424,11 +5439,12 @@ static void
|
||||||
pa_subspace (unused)
|
pa_subspace (unused)
|
||||||
int unused;
|
int unused;
|
||||||
{
|
{
|
||||||
char *name, *ss_name, c;
|
char *name, *ss_name, *alias, c;
|
||||||
char loadable, code_only, common, dup_common, zero, sort;
|
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;
|
sd_chain_struct *space;
|
||||||
ssd_chain_struct *ssd;
|
ssd_chain_struct *ssd;
|
||||||
|
asection *section;
|
||||||
|
|
||||||
if (within_procedure)
|
if (within_procedure)
|
||||||
{
|
{
|
||||||
|
@ -5454,8 +5470,9 @@ pa_subspace (unused)
|
||||||
space_index = ~0;
|
space_index = ~0;
|
||||||
alignment = 0;
|
alignment = 0;
|
||||||
quadrant = 0;
|
quadrant = 0;
|
||||||
|
alias = NULL;
|
||||||
|
|
||||||
space = pa_segment_to_space (now_seg);
|
space = current_space;
|
||||||
ssd = is_defined_subspace (name, space->sd_last_subseg);
|
ssd = is_defined_subspace (name, space->sd_last_subseg);
|
||||||
if (ssd)
|
if (ssd)
|
||||||
{
|
{
|
||||||
|
@ -5467,7 +5484,8 @@ pa_subspace (unused)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* A new subspace. Load default values. */
|
/* A new subspace. Load default values if it matches one of
|
||||||
|
the builtin subspaces. */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pa_def_subspaces[i].name)
|
while (pa_def_subspaces[i].name)
|
||||||
{
|
{
|
||||||
|
@ -5483,6 +5501,8 @@ pa_subspace (unused)
|
||||||
quadrant = pa_def_subspaces[i].quadrant;
|
quadrant = pa_def_subspaces[i].quadrant;
|
||||||
access = pa_def_subspaces[i].access;
|
access = pa_def_subspaces[i].access;
|
||||||
sort = pa_def_subspaces[i].sort;
|
sort = pa_def_subspaces[i].sort;
|
||||||
|
if (USE_ALIASES && pa_def_subspaces[i].alias)
|
||||||
|
alias = pa_def_subspaces[i].alias;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -5561,25 +5581,73 @@ pa_subspace (unused)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that all the flags are set, update an existing subspace,
|
/* Compute a reasonable set of BFD flags based on the information
|
||||||
or create a new one with the given flags if the subspace does
|
in the .subspace directive. */
|
||||||
not currently exist. */
|
applicable = bfd_applicable_section_flags (stdoutput);
|
||||||
space = pa_segment_to_space (now_seg);
|
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)
|
if (ssd)
|
||||||
current_subspace = update_subspace (ss_name, loadable, code_only,
|
section = ssd->ssd_seg;
|
||||||
common, dup_common, sort, zero,
|
if (alias)
|
||||||
access, space_index, alignment,
|
section = subseg_new (alias, 0);
|
||||||
quadrant, ssd->ssd_subseg);
|
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
|
else
|
||||||
current_subspace = create_new_subspace (space, ss_name, loadable,
|
current_subspace = create_new_subspace (space, ss_name, loadable,
|
||||||
code_only, common,
|
code_only, common,
|
||||||
dup_common, zero, sort,
|
dup_common, zero, sort,
|
||||||
access, space_index,
|
access, space_index,
|
||||||
alignment, quadrant, now_seg);
|
alignment, quadrant, section);
|
||||||
SUBSPACE_SUBSPACE_START (current_subspace) = pa_subspace_start (space,
|
|
||||||
quadrant);
|
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
|
current_subspace->ssd_seg = section;
|
||||||
subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
|
subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -5591,7 +5659,6 @@ pa_subspace (unused)
|
||||||
static void
|
static void
|
||||||
pa_spaces_begin ()
|
pa_spaces_begin ()
|
||||||
{
|
{
|
||||||
sd_chain_struct *space;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
space_dict_root = NULL;
|
space_dict_root = NULL;
|
||||||
|
@ -5600,12 +5667,15 @@ pa_spaces_begin ()
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pa_def_spaces[i].name)
|
while (pa_def_spaces[i].name)
|
||||||
{
|
{
|
||||||
if (pa_def_spaces[i].alias)
|
char *name;
|
||||||
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);
|
|
||||||
|
|
||||||
|
/* 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,
|
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].loadable, pa_def_spaces[i].defined,
|
||||||
pa_def_spaces[i].private, pa_def_spaces[i].sort,
|
pa_def_spaces[i].private, pa_def_spaces[i].sort,
|
||||||
|
@ -5616,12 +5686,68 @@ pa_spaces_begin ()
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pa_def_subspaces[i].name)
|
while (pa_def_subspaces[i].name)
|
||||||
{
|
{
|
||||||
space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
|
char *name;
|
||||||
if (space)
|
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;
|
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,
|
create_new_subspace (space, name,
|
||||||
pa_def_subspaces[i].loadable,
|
pa_def_subspaces[i].loadable,
|
||||||
pa_def_subspaces[i].code_only,
|
pa_def_subspaces[i].code_only,
|
||||||
|
@ -5633,12 +5759,7 @@ pa_spaces_begin ()
|
||||||
pa_def_subspaces[i].space_index,
|
pa_def_subspaces[i].space_index,
|
||||||
pa_def_subspaces[i].alignment,
|
pa_def_subspaces[i].alignment,
|
||||||
pa_def_subspaces[i].quadrant,
|
pa_def_subspaces[i].quadrant,
|
||||||
pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
|
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);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5758,7 +5879,6 @@ create_new_subspace (space, name, loadable, code_only, common,
|
||||||
asection *seg;
|
asection *seg;
|
||||||
{
|
{
|
||||||
ssd_chain_struct *chain_entry;
|
ssd_chain_struct *chain_entry;
|
||||||
symbolS *start_symbol;
|
|
||||||
|
|
||||||
chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
|
chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
|
||||||
if (!chain_entry)
|
if (!chain_entry)
|
||||||
|
@ -5779,7 +5899,7 @@ create_new_subspace (space, name, loadable, code_only, common,
|
||||||
SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
|
SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
|
||||||
SUBSPACE_ZERO (chain_entry) = is_zero;
|
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_seg = seg;
|
||||||
chain_entry->ssd_last_align = 1;
|
chain_entry->ssd_last_align = 1;
|
||||||
chain_entry->ssd_next = NULL;
|
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. */
|
various arguments. Return the modified subspace chain entry. */
|
||||||
|
|
||||||
static ssd_chain_struct *
|
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)
|
zero, access, space_index, alignment, quadrant, subseg)
|
||||||
|
sd_chain_struct *space;
|
||||||
char *name;
|
char *name;
|
||||||
char loadable;
|
char loadable;
|
||||||
char code_only;
|
char code_only;
|
||||||
|
|
Loading…
Reference in a new issue