aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1994-12-19 21:23:20 +0000
committerJeff Law <law@redhat.com>1994-12-19 21:23:20 +0000
commit60937ce7c2522765fc431338adf2d0aefb8e7eab (patch)
tree9471cf9f695eacd1eabbdd292cc078823a8db362 /gas/config
parent88cc1324ff0fdb8983b39166516ace7afb07f7ed (diff)
downloadgdb-60937ce7c2522765fc431338adf2d0aefb8e7eab.zip
gdb-60937ce7c2522765fc431338adf2d0aefb8e7eab.tar.gz
gdb-60937ce7c2522765fc431338adf2d0aefb8e7eab.tar.bz2
* Reduce useless symbols for ELF in an attempt to make smaller
objects and speed up the linker. * config/tc-hppa.c (struct call_info): Replace end_symbol field with a size field. (hppa_elf_mark_end_function): Delete unneeded function. (pa_build_unwind_subspace): For the 2nd unwind relocation, use the function symbol + function size instead of a special symbol for the end of the function. (process_exit): Compute the function size here. Don't call hppa_elf_mark_end_of_function anymore. (pa_procend): Likewise. (hppa_fix_adjustable): Only reject 32bit relocations for SOM. (elf_hppa_final_processing): Simplify.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-hppa.c200
1 files changed, 99 insertions, 101 deletions
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
index c1ec189..4c5fd73 100644
--- a/gas/config/tc-hppa.c
+++ b/gas/config/tc-hppa.c
@@ -145,8 +145,8 @@ struct call_info
/* Name of this function. */
symbolS *start_symbol;
- /* (temporary) symbol used to mark the end of this function. */
- symbolS *end_symbol;
+ /* Size of the function in bytes. */
+ unsigned long function_size;
/* Next entry in the chain. */
struct call_info *ci_next;
@@ -451,6 +451,7 @@ struct selector_entry
/* Prototypes for functions local to tc-hppa.c. */
+static void pa_check_current_space_and_subspace PARAMS ((void));
static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
static void pa_cons PARAMS ((int));
static void pa_data PARAMS ((int));
@@ -539,7 +540,6 @@ static int log2 PARAMS ((int));
static int pa_next_subseg PARAMS ((sd_chain_struct *));
static unsigned int pa_stringer_aux PARAMS ((char *));
static void pa_spaces_begin PARAMS ((void));
-static void hppa_elf_mark_end_of_function PARAMS ((void));
/* File and gloally scoped variable declarations. */
@@ -1058,6 +1058,31 @@ static struct default_space_dict pa_def_spaces[] =
/* Actual functions to implement the PA specific code for the assembler. */
+/* Called before writing the object file. Make sure entry/exit and
+ proc/procend pairs match. */
+
+void
+pa_check_eof ()
+{
+ if (within_entry_exit)
+ as_fatal ("Missing .exit\n");
+
+ if (within_procedure)
+ as_fatal ("Missing .procend\n");
+}
+
+/* Check to make sure we have a valid space and subspace. */
+
+static void
+pa_check_current_space_and_subspace ()
+{
+ if (current_space == NULL)
+ as_fatal ("Not in a space.\n");
+
+ if (current_subspace == NULL)
+ as_fatal ("Not in a subspace.\n");
+}
+
/* Returns a pointer to the label_symbol_struct for the current space.
or NULL if no label_symbol_struct exists for the current space. */
@@ -1367,6 +1392,9 @@ pa_ip (str)
unsigned long opcode;
struct pa_opcode *insn;
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
/* Skip to something interesting. */
for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
;
@@ -2568,15 +2596,7 @@ tc_gen_reloc (section, fixp)
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
- /* Ugh. Yet another case where the generic ELF code's
- handling of section vmas makes life a living hell.
-
- The generic ELF code will subtract out section->vma from
- the relocation offset before the relocs are written. So
- we have to add section->vma into the offset here so the
- net sum is zero. */
- reloc->address = (fixp->fx_frag->fr_address + fixp->fx_where
- + section->vma);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->addend = 0; /* default */
assert (reloc->howto && code == reloc->howto->type);
@@ -3856,6 +3876,9 @@ pa_parse_neg_add_cmpltr (s, isbranch)
static void
pa_align (bytes)
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
/* Let the generic gas code do most of the work. */
s_align_bytes (bytes);
@@ -3876,6 +3899,9 @@ pa_block (z)
unsigned int temp_size;
int i;
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
temp_size = get_absolute_expression ();
/* Always fill with zeros, that's what the HP assembler does. */
@@ -3906,6 +3932,9 @@ static void
pa_call (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
pa_call_args (&last_call_desc);
demand_empty_rest_of_line ();
}
@@ -4025,7 +4054,8 @@ pa_build_unwind_subspace (call_info)
/* Relocation info. for end offset of the function. */
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
- call_info->end_symbol, (offsetT) 0,
+ call_info->start_symbol,
+ call_info->function_size,
(expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL);
/* Dump it. */
@@ -4054,6 +4084,9 @@ pa_callinfo (unused)
char *name, c, *p;
int temp;
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
/* .CALLINFO must appear within a procedure definition. */
if (!within_procedure)
as_bad (".callinfo is not within a procedure definition");
@@ -4189,24 +4222,11 @@ static void
pa_code (unused)
int unused;
{
- sd_chain_struct *sdchain;
-
- /* First time through it might be necessary to create the
- $TEXT$ space. */
- if ((sdchain = is_defined_space ("$TEXT$")) == NULL)
- {
- sdchain = create_new_space (pa_def_spaces[0].name,
- pa_def_spaces[0].spnum,
- pa_def_spaces[0].loadable,
- pa_def_spaces[0].defined,
- pa_def_spaces[0].private,
- pa_def_spaces[0].sort,
- pa_def_spaces[0].segment, 0);
- }
-
- SPACE_DEFINED (sdchain) = 1;
- subseg_set (text_section, SUBSEG_CODE);
- demand_empty_rest_of_line ();
+ current_space = is_defined_space ("$TEXT$");
+ current_subspace
+ = pa_subsegment_to_subspace (current_space->sd_seg, 0);
+ s_text (0);
+ pa_undefine_label ();
}
/* This is different than the standard GAS s_comm(). On HP9000/800 machines,
@@ -4279,6 +4299,9 @@ static void
pa_enter (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
abort ();
}
@@ -4288,6 +4311,9 @@ static void
pa_entry (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
if (!within_procedure)
as_bad ("Misplaced .entry. Ignored.");
else
@@ -4361,11 +4387,13 @@ process_exit ()
where = frag_more (0);
+ last_call_info->function_size
+ = where - frag_now->fr_literal - S_GET_VALUE (last_call_info->start_symbol);
+
#ifdef OBJ_ELF
/* Mark the end of the function, stuff away the location of the frag
for the end of the function, and finally call pa_build_unwind_subspace
to add an entry in the unwind table. */
- hppa_elf_mark_end_of_function ();
pa_build_unwind_subspace (last_call_info);
#else
/* SOM defers building of unwind descriptors until the link phase.
@@ -4390,6 +4418,9 @@ static void
pa_exit (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
if (!within_procedure)
as_bad (".EXIT must appear within a procedure");
else
@@ -4678,6 +4709,9 @@ static void
pa_leave (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
abort ();
}
@@ -4687,6 +4721,9 @@ static void
pa_origin (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
s_org (0);
pa_undefine_label ();
}
@@ -4734,6 +4771,10 @@ pa_proc (unused)
int unused;
{
struct call_info *call_info;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
if (within_procedure)
as_fatal ("Nested procedures");
@@ -4798,6 +4839,9 @@ pa_procend (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
/* If we are within a procedure definition, make sure we've
defined a label for the procedure; handle case where the
label was defined after the .PROC directive.
@@ -4845,12 +4889,8 @@ pa_procend (unused)
if (within_entry_exit)
as_bad ("Missing .EXIT for a .ENTRY");
-#ifdef OBJ_ELF
- /* ELF needs to mark the end of each function so that it can compute
- the size of the function (apparently its needed in the symbol table). */
- hppa_elf_mark_end_of_function ();
-#endif
-
+ last_call_info->function_size
+ = frag_more (0) - frag_now->fr_literal - S_GET_VALUE (last_call_info->start_symbol);
within_procedure = FALSE;
demand_empty_rest_of_line ();
pa_undefine_label ();
@@ -5159,6 +5199,9 @@ pa_subspace (unused)
ssd_chain_struct *ssd;
asection *section;
+ if (current_space == NULL)
+ as_fatal ("Must be in a space before changing or declaring subspaces.\n");
+
if (within_procedure)
{
as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
@@ -5861,6 +5904,10 @@ pa_stringer_aux (s)
char *s;
{
unsigned int c = *s & CHAR_MASK;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
switch (c)
{
case '\"':
@@ -6009,6 +6056,9 @@ static void
pa_fill (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
s_fill (0);
pa_undefine_label ();
}
@@ -6019,6 +6069,9 @@ static void
pa_lcomm (needs_align)
int needs_align;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
s_lcomm (needs_align);
pa_undefine_label ();
}
@@ -6029,6 +6082,9 @@ static void
pa_lsym (unused)
int unused;
{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
s_lsym (0);
pa_undefine_label ();
}
@@ -6082,9 +6138,11 @@ hppa_fix_adjustable (fixp)
hppa_fix = (struct hppa_fix_struct *) fixp->tc_fix_data;
- /* Reject reductions of symbols in 32bit plabel relocs. */
+#ifdef OBJ_SOM
+ /* Reject reductions of symbols in 32bit relocs. */
if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
return 0;
+#endif
/* Reject reductions of symbols in DLT relative relocs. */
if (hppa_fix->fx_r_field == e_tsel
@@ -6139,66 +6197,8 @@ hppa_force_relocation (fixp)
/* Now for some ELF specific code. FIXME. */
#ifdef OBJ_ELF
-/* Mark the end of a function so that it's possible to compute
- the size of the function in hppa_elf_final_processing. */
-
-static void
-hppa_elf_mark_end_of_function ()
-{
- /* ELF does not have EXIT relocations. All we do is create a
- temporary symbol marking the end of the function. */
- char *name = (char *)
- xmalloc (strlen ("L$\001end_") +
- strlen (S_GET_NAME (last_call_info->start_symbol)) + 1);
-
- if (name)
- {
- symbolS *symbolP;
-
- strcpy (name, "L$\001end_");
- strcat (name, S_GET_NAME (last_call_info->start_symbol));
-
- /* If we have a .exit followed by a .procend, then the
- symbol will have already been defined. */
- symbolP = symbol_find (name);
- if (symbolP)
- {
- /* The symbol has already been defined! This can
- happen if we have a .exit followed by a .procend.
-
- This is *not* an error. All we want to do is free
- the memory we just allocated for the name and continue. */
- xfree (name);
- }
- else
- {
- /* symbol value should be the offset of the
- last instruction of the function */
- symbolP = symbol_new (name, now_seg,
- (valueT) (obstack_next_free (&frags)
- - frag_now->fr_literal - 4),
- frag_now);
-
- assert (symbolP);
- symbolP->bsym->flags = BSF_LOCAL;
- symbol_table_insert (symbolP);
- }
-
- if (symbolP)
- last_call_info->end_symbol = symbolP;
- else
- as_bad ("Symbol '%s' could not be created.", name);
-
- }
- else
- as_bad ("No memory for symbol name.");
-
-}
-
/* For ELF, this function serves one purpose: to setup the st_size
- field of STT_FUNC symbols. To do this, we need to scan the
- call_info structure list, determining st_size in by taking the
- difference in the address of the beginning/end marker symbols. */
+ field of STT_FUNC symbols. */
void
elf_hppa_final_processing ()
@@ -6211,9 +6211,7 @@ elf_hppa_final_processing ()
{
elf_symbol_type *esym
= (elf_symbol_type *) call_info_pointer->start_symbol->bsym;
- esym->internal_elf_sym.st_size =
- S_GET_VALUE (call_info_pointer->end_symbol)
- - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
+ esym->internal_elf_sym.st_size = call_info_pointer->function_size;
}
}
#endif