aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1993-10-31 01:53:01 +0000
committerJeff Law <law@redhat.com>1993-10-31 01:53:01 +0000
commit3b9a72c53c9325d1649895a43637c52ec203ce3e (patch)
treeb3d05dbaea0274a4af0f4e7dd78b685ef997b49e /gas
parent5c2bae7507c54d272e3527b33e8b26480f3c520b (diff)
downloadgdb-3b9a72c53c9325d1649895a43637c52ec203ce3e.zip
gdb-3b9a72c53c9325d1649895a43637c52ec203ce3e.tar.gz
gdb-3b9a72c53c9325d1649895a43637c52ec203ce3e.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-hppa.c217
1 files changed, 169 insertions, 48 deletions
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
index 7b63241..93a7fea 100644
--- a/gas/config/tc-hppa.c
+++ b/gas/config/tc-hppa.c
@@ -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)
}
}
+ /* 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)
+ 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 with the given flags if the subspace does
- not currently exist. */
- space = pa_segment_to_space (now_seg);
+ or create a new one. */
if (ssd)
- current_subspace = update_subspace (ss_name, loadable, code_only,
- common, dup_common, sort, zero,
- access, space_index, alignment,
- quadrant, ssd->ssd_subseg);
+
+ 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);
+ 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
- pa_def_spaces[i].segment
- = bfd_make_section_old_way (stdoutput, pa_def_spaces[i].name);
+ 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,29 +5686,80 @@ 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)
{
- char *name = pa_def_subspaces[i].alias;
- if (!name)
- name = pa_def_subspaces[i].name;
- create_new_subspace (space, name,
- pa_def_subspaces[i].loadable,
- pa_def_subspaces[i].code_only,
- pa_def_subspaces[i].common,
- pa_def_subspaces[i].dup_common,
- pa_def_subspaces[i].zero,
- pa_def_subspaces[i].sort,
- pa_def_subspaces[i].access,
- 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);
+ name = pa_def_subspaces[i].alias;
+ subsegment = pa_def_subspaces[i].subsegment;
}
else
- as_fatal ("Internal error: space missing for subspace \"%s\"\n",
- 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,
+ pa_def_subspaces[i].loadable,
+ pa_def_subspaces[i].code_only,
+ pa_def_subspaces[i].common,
+ pa_def_subspaces[i].dup_common,
+ pa_def_subspaces[i].zero,
+ pa_def_subspaces[i].sort,
+ pa_def_subspaces[i].access,
+ pa_def_subspaces[i].space_index,
+ pa_def_subspaces[i].alignment,
+ pa_def_subspaces[i].quadrant,
+ 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;