* Removed sy_forward and replaced it with an undefined expression

as the value of a symbol.
	* struc-symbol.h (struct symbol): Removed sy_forward field.  Added
	sy_resolved and sy_resolving single bit fields.
	* symbols.c (symbol_new): Don't initialize sy_forward field.
	(resolve_symbol_value): New function to adjust symbol value by
	fragment address, using recursion to resolve forward symbols.
	* symbols.h: Added prototype for new function.
	* read.c (pseudo_set): Set symbolP->sy_value to an undefined
	expression rather than setting symbolP->sy_forward.
	* write.c (write_object_file): Use resolve_symbol_value on
	symbols, keeping the common case (the old behaviour) inline.
	* config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
	handling (subsumed by write.c change).
	* config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
	sy_value rather than sy_forward.
	* config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
	expression segment rather than sy_forward.
	(yank_symbols): Use resolve_symbol_value.
	(crawl_symbols): Removed extra pass over symbols.
	* config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
	config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
	symbols which handled sy_forward; use resolve_symbol_value
	instead.
	* config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
	Define.
	* config/obj-elf.c (obj_elf_stab_generic): Check expression
	segment rather than sy_forward.
	* config/obj-vms.c (VMS_Check_For_Main): Don't initialize
	sy_forward; do initialize sy_resolved and sy_resolving.
	* config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.
This commit is contained in:
Ian Lance Taylor 1993-07-14 22:21:25 +00:00
parent bf5b632df7
commit 5868b1fe68
12 changed files with 654 additions and 111 deletions

View File

@ -1,5 +1,37 @@
Wed Jul 14 15:09:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* Removed sy_forward and replaced it with an undefined expression
as the value of a symbol.
* struc-symbol.h (struct symbol): Removed sy_forward field. Added
sy_resolved and sy_resolving single bit fields.
* symbols.c (symbol_new): Don't initialize sy_forward field.
(resolve_symbol_value): New function to adjust symbol value by
fragment address, using recursion to resolve forward symbols.
* symbols.h: Added prototype for new function.
* read.c (pseudo_set): Set symbolP->sy_value to an undefined
expression rather than setting symbolP->sy_forward.
* write.c (write_object_file): Use resolve_symbol_value on
symbols, keeping the common case (the old behaviour) inline.
* config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
handling (subsumed by write.c change).
* config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
sy_value rather than sy_forward.
* config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
expression segment rather than sy_forward.
(yank_symbols): Use resolve_symbol_value.
(crawl_symbols): Removed extra pass over symbols.
* config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
symbols which handled sy_forward; use resolve_symbol_value
instead.
* config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
Define.
* config/obj-elf.c (obj_elf_stab_generic): Check expression
segment rather than sy_forward.
* config/obj-vms.c (VMS_Check_For_Main): Don't initialize
sy_forward; do initialize sy_resolved and sy_resolving.
* config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.
* Changes to keep a full expression as the value of a symbol, not
just a longword:
* struc-symbol.h: New field sy_value.

View File

@ -110,17 +110,6 @@ obj_aout_frob_symbol (sym, punt)
asection *sec;
int desc, type, other;
/* Is this part format-dependent? */
if (sym->sy_forward)
{
S_SET_VALUE (sym,
S_GET_VALUE (sym)
+ S_GET_VALUE (sym->sy_forward)
+ sym->sy_forward->sy_frag->fr_address
);
sym->sy_forward = 0;
}
flags = sym->bsym->flags;
desc = S_GET_DESC (sym);
type = S_GET_TYPE (sym);
@ -450,19 +439,6 @@ obj_crawl_symbol_chain (headers)
symbolS **symbolPP;
int symbol_number = 0;
/* JF deal with forward references first... */
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
if (symbolP->sy_forward)
{
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
+ S_GET_VALUE (symbolP->sy_forward)
+ symbolP->sy_forward->sy_frag->fr_address);
symbolP->sy_forward = 0;
} /* if it has a forward reference */
} /* walk the symbol chain */
tc_crawl_symbol_chain (headers);
symbolPP = &symbol_rootP; /*->last symbol chain link. */
@ -473,7 +449,7 @@ obj_crawl_symbol_chain (headers)
S_SET_SEGMENT (symbolP, SEG_TEXT);
} /* if pusing data into text */
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
resolve_symbol_value (symbolP);
/* OK, here is how we decide which symbols go out into the brave
new symtab. Symbols that do are:

View File

@ -433,19 +433,6 @@ obj_crawl_symbol_chain (headers)
symbolS *symbolP;
int symbol_number = 0;
/* JF deal with forward references first... */
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
if (symbolP->sy_forward)
{
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
+ S_GET_VALUE (symbolP->sy_forward)
+ symbolP->sy_forward->sy_frag->fr_address);
symbolP->sy_forward = 0;
} /* if it has a forward reference */
} /* walk the symbol chain */
tc_crawl_symbol_chain (headers);
symbolPP = &symbol_rootP; /*->last symbol chain link. */
@ -456,7 +443,7 @@ obj_crawl_symbol_chain (headers)
S_SET_SEGMENT (symbolP, SEG_TEXT);
} /* if pusing data into text */
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
resolve_symbol_value (symbolP);
/* OK, here is how we decide which symbols go out into the
brave new symtab. Symbols that do are:

View File

@ -1620,11 +1620,15 @@ obj_coff_val ()
}
else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
{
def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
def_symbol_in_progress->sy_value.X_add_symbol =
symbol_find_or_make (symbol_name);
def_symbol_in_progress->sy_value.X_subtract_symbol = NULL;
def_symbol_in_progress->sy_value.X_add_number = 0;
def_symbol_in_progress->sy_value.X_seg = undefined_section;
/* If the segment is undefined when the forward
reference is solved, then copy the segment id
from the forward symbol. */
/* If the segment is undefined when the forward reference is
resolved, then copy the segment id from the forward
symbol. */
SF_SET_GET_SEGMENT (def_symbol_in_progress);
}
/* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
@ -1720,32 +1724,6 @@ obj_crawl_symbol_chain (headers)
/* Initialize the stack used to keep track of the matching .bb .be */
stack *block_stack = stack_init (512, sizeof (symbolS *));
/* JF deal with forward references first... */
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
if (symbolP->sy_forward)
{
S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
+ S_GET_VALUE (symbolP->sy_forward)
+ symbolP->sy_forward->sy_frag->fr_address));
if (
#ifndef TE_I386AIX
SF_GET_GET_SEGMENT (symbolP)
#else
SF_GET_GET_SEGMENT (symbolP)
&& S_GET_SEGMENT (symbolP) == SEG_UNKNOWN
#endif /* TE_I386AIX */
)
{
S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
} /* forward segment also */
symbolP->sy_forward = 0;
} /* if it has a forward reference */
} /* walk the symbol chain */
tc_crawl_symbol_chain (headers);
/* The symbol list should be ordered according to the following sequence
@ -1864,7 +1842,7 @@ obj_crawl_symbol_chain (headers)
S_SET_SEGMENT (symbolP, SEG_TEXT);
} /* push data into text */
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
resolve_symbol_value (symbolP);
if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
{

View File

@ -990,7 +990,7 @@ DEFUN_VOID (obj_coff_endef)
|| (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
&& !SF_GET_TAG (def_symbol_in_progress))
|| S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
|| def_symbol_in_progress->sy_forward != NULL
|| def_symbol_in_progress->sy_value.X_seg != absolute_section
|| (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
|| (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
{
@ -1238,11 +1238,15 @@ obj_coff_val ()
}
else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
{
def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
def_symbol_in_progress->sy_value.X_add_symbol =
symbol_find_or_make (symbol_name);
def_symbol_in_progress->sy_value.X_subtract_symbol = NULL;
def_symbol_in_progress->sy_value.X_add_number = 0;
def_symbol_in_progress->sy_value.X_seg = undefined_section;
/* If the segment is undefined when the forward
reference is solved, then copy the segment id
from the forward symbol. */
/* If the segment is undefined when the forward reference is
resolved, then copy the segment id from the forward
symbol. */
SF_SET_GET_SEGMENT (def_symbol_in_progress);
/* FIXME: gcc can generate address expressions
@ -1369,7 +1373,7 @@ DEFUN_VOID (yank_symbols)
/* L* and C_EFCN symbols never merge. */
if (!SF_GET_LOCAL (symbolP)
&& S_GET_STORAGE_CLASS (symbolP) != C_LABEL
&& symbolP->sy_forward == NULL
&& symbolP->sy_value.X_seg == absolute_section
&& (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
&& real_symbolP != symbolP)
{
@ -1396,8 +1400,7 @@ DEFUN_VOID (yank_symbols)
S_SET_SEGMENT (symbolP, SEG_E0);
} /* push data into text */
S_SET_VALUE (symbolP,
S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
resolve_symbol_value (symbolP);
if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
{
@ -1612,16 +1615,6 @@ DEFUN (crawl_symbols, (h, abfd),
/* Initialize the stack used to keep track of the matching .bb .be */
block_stack = stack_init (512, sizeof (symbolS *));
/* JF deal with forward references first... */
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
if (symbolP->sy_forward)
{
S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
+ S_GET_VALUE (symbolP->sy_forward)
+ symbolP->sy_forward->sy_frag->fr_address));
if (SF_GET_GET_SEGMENT (symbolP))
S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
}
/* The symbol list should be ordered according to the following sequence
* order :

View File

@ -518,4 +518,10 @@ extern SCNHDR text_section_header;
#endif
#endif
/* Forward the segment of a forwarded symbol. */
#define obj_frob_forward_symbol(symp) \
(SF_GET_GET_SEGMENT (symp) \
? (S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol)), 0) \
: 0)
/* end of obj-coffbfd.h */

View File

@ -486,7 +486,7 @@ obj_elf_stab_generic (what, secname)
subseg_new ((char *) saved_seg->name, subseg);
if ((what == 's' || what == 'n')
&& symbolP->sy_forward == NULL)
&& symbolP->sy_value.X_seg == absolute_section)
{
/* symbol is not needed in the regular symbol table */
symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);

View File

@ -546,18 +546,6 @@ obj_crawl_symbol_chain (headers)
symbolS **symbolPP;
int symbol_number = 0;
/* JF deal with forward references first... */
for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
{
if (symbolP->sy_forward)
{
S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
+ S_GET_VALUE (symbolP->sy_forward)
+ symbolP->sy_forward->sy_frag->fr_address);
symbolP->sy_forward = 0;
} /* if it has a forward reference */
} /* walk the symbol chain */
{ /* crawl symbol table */
register int symbol_number = 0;
@ -565,8 +553,7 @@ obj_crawl_symbol_chain (headers)
symbolPP = &symbol_rootP; /* -> last symbol chain link. */
while ((symbolP = *symbolPP) != NULL)
{
S_SET_VALUE (symbolP,
S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
resolve_symbol_value (symbolP);
/* OK, here is how we decide which symbols go out into the
brave new symtab. Symbols that do are:
@ -4548,7 +4535,8 @@ VMS_Check_For_Main ()
symbolP->sy_name_offset = 0;
symbolP->sy_number = 0;
symbolP->sy_frag = New_Frag;
symbolP->sy_forward = 0;
symbolP->sy_resolved = 0;
symbolP->sy_resolving = 0;
/* this actually inserts at the beginning of the list */
symbol_append (symbol_rootP, symbolP, &symbol_rootP, &symbol_lastP);

519
gas/config/tc-hppa.h Normal file
View File

@ -0,0 +1,519 @@
/* tc-hppa.h -- Header file for the PA */
/* Copyright (C) 1989 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
HP PA-RISC support was contributed by the Center for Software Science
at the University of Utah.
*/
#ifndef _TC_HPPA_H
#define _TC_HPPA_H
#ifndef TC_HPPA
#define TC_HPPA 1
#endif
#define TARGET_ARCH bfd_arch_hppa
#define TARGET_FORMAT "elf32-hppa"
#define ASEC_NULL (asection *)0
/* We can do sym1 - sym2 as long as sym2 is $global$ */
#define SEG_DIFF_ALLOWED
typedef enum FPOF
{
SGL, DBL, ILLEGAL_FMT, QUAD
} FP_Operand_Format;
extern char *expr_end;
extern void s_globl (), s_long (), s_short (), s_space (), cons ();
extern void stringer ();
extern unsigned int next_char_of_string ();
extern void pa_big_cons ();
extern void pa_cons ();
extern void pa_data ();
extern void pa_desc ();
extern void pa_float_cons ();
extern void pa_fill ();
extern void pa_lcomm ();
extern void pa_lsym ();
extern void pa_stringer ();
extern void pa_text ();
extern void pa_version ();
int pa_parse_number ();
int pa_parse_fp_cmp_cond ();
FP_Operand_Format pa_parse_fp_format ();
#ifdef __STDC__
int getExpression (char *str);
#else
int getExpression ();
#endif
int getAbsoluteExpression ();
int evaluateAbsolute ();
int pa_build_arg_reloc ();
unsigned int pa_align_arg_reloc ();
void pa_skip ();
int pa_parse_nullif ();
int pa_parse_nonneg_cmpsub_cmpltr ();
int pa_parse_neg_cmpsub_cmpltr ();
int pa_parse_nonneg_add_cmpltr ();
int pa_parse_neg_add_cmpltr ();
int pa_build_arg_reloc ();
void s_seg (), s_proc (), s_data1 ();
void pa_block (), pa_call (), pa_call_args (), pa_callinfo ();
void pa_code (), pa_comm (), pa_copyright (), pa_end ();
void pa_enter ();
void pa_entry (), pa_equ (), pa_exit (), pa_export ();
void pa_export_args (), pa_import (), pa_label (), pa_leave ();
void pa_origin (), pa_proc (), pa_procend (), pa_space ();
void pa_spnum (), pa_subspace (), pa_version ();
extern const pseudo_typeS md_pseudo_table[];
/*
PA-89 floating point registers are arranged like this:
+--------------+--------------+
| 0 or 16L | 16 or 16R |
+--------------+--------------+
| 1 or 17L | 17 or 17R |
+--------------+--------------+
| | |
. . .
. . .
. . .
| | |
+--------------+--------------+
| 14 or 30L | 30 or 30R |
+--------------+--------------+
| 15 or 31L | 31 or 31R |
+--------------+--------------+
The following is a version of pa_parse_number that
handles the L/R notation and returns the correct
value to put into the instruction register field.
The correct value to put into the instruction is
encoded in the structure 'pa_89_fp_reg_struct'.
*/
struct pa_89_fp_reg_struct
{
char number_part;
char L_R_select;
};
int need_89_opcode ();
int pa_89_parse_number ();
/* pa-ctrl-func.h -- Control Structures and Functions for the PA */
extern unsigned int assemble_3 ( /* unsigned int x; */ );
extern void dis_assemble_3 ( /* unsigned int x, *r; */ );
extern unsigned int assemble_12 ( /* unsigned int x,y; */ );
extern void dis_assemble_12 ( /* unsigned int as12, *x,*y */ );
extern unsigned long assemble_17 ( /* unsigned int x,y,z */ );
extern void dis_assemble_17 ( /* unsigned int as17, *x,*y,*z */ );
extern unsigned long assemble_21 ( /* unsigned int x; */ );
extern void dis_assemble_21 ( /* unsigned int as21,*x; */ );
extern void sign_unext ( /* unsigned int x,len; unsigned int *result */ );
extern void low_sign_unext ( /* unsigned int x,len; unsigned int *result */ );
struct call_desc
{
unsigned int arg_reloc;
unsigned int arg_count;
};
typedef struct call_desc call_descS;
extern call_descS last_call_desc;
/* GDB debug support */
#if defined(OBJ_SOME)
#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
#else
#define GDB_DEBUG_SPACE_NAME ".stab"
#define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
#define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
#endif
/* pre-defined subsegments (subspaces) for the HP 9000 Series 800 */
#define SUBSEG_CODE 0
#define SUBSEG_DATA 0
#define SUBSEG_LIT 1
#define SUBSEG_BSS 2
#define SUBSEG_UNWIND 3
#define SUBSEG_GDB_STRINGS 0
#define SUBSEG_GDB_SYMBOLS 1
#define UNWIND_SECTION_NAME ".hppa_unwind"
/* subspace dictionary chain entry structure */
struct subspace_dictionary_chain
{
#if defined(OBJ_OSFROSE) | defined(OBJ_ELF)
#ifdef OBJ_OSFROSE
region_command_t *ssd_entry;/* XXX: not sure this is what we need here */
#else
Elf_Internal_Shdr *ssd_entry;
unsigned long ssd_vm_addr;
#endif
char *ssd_name; /* used until time of writing object file */
/* then we use ssd_entry->regc_region_name */
unsigned char ssd_quadrant;
unsigned char ssd_sort_key;
unsigned char ssd_common;
unsigned char ssd_dup_common;
unsigned char ssd_loadable;
unsigned char ssd_code_only;
#else
subspace_dictS *ssd_entry; /* this dictionary */
#endif
int ssd_defined; /* this subspace has been used */
int ssd_space_number; /* space # this subspace is in */
asection *ssd_seg; /* this subspace = this seg */
int ssd_subseg; /* and subseg */
int ssd_zero;
int object_file_index; /* index of this entry within
the subspace dictionary of
the object file (not used until
the object file is written */
int ssd_last_align; /* the size of the last alignment
request for this subspace */
symbolS *ssd_start_sym; /* a symbol whose value is the
start of this subspace */
struct subspace_dictionary_chain *ssd_next; /* next subspace dict. entry */
};
typedef struct subspace_dictionary_chain subspace_dict_chainS;
/* space dictionary chain entry structure */
struct space_dictionary_chain
{
#ifdef OBJ_OSFROSE
region_command_t *sd_entry; /* XXX: not sure this is what we need here */
char *sd_name; /* used until time of writing object file */
/* then we use sd_entry->regc_region_name */
unsigned int sd_loadable;
unsigned int sd_private;
unsigned int sd_spnum;
unsigned char sd_sort_key;
#else
#ifdef OBJ_ELF
Elf_Internal_Shdr *sd_entry;
char *sd_name; /* used until time of writing object file */
/* then we use sd_entry->sh_name */
unsigned int sd_loadable;
unsigned int sd_private;
unsigned int sd_spnum;
unsigned char sd_sort_key;
#else
space_dictS *sd_entry; /* this dictionary */
#endif
#endif
int sd_defined; /* this space has been used */
asection *sd_seg; /* GAS segment to which this space corresponds */
int sd_last_subseg; /* current subsegment number we are using */
subspace_dict_chainS *sd_subspaces; /* all subspaces in this space */
struct space_dictionary_chain *sd_next; /* the next space dict. entry */
};
typedef struct space_dictionary_chain space_dict_chainS;
/*
Macros to maintain spaces and subspaces
*/
#ifdef OBJ_OSFROSE
#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
#define SPACE_PRIVATE(space_chain) (space_chain)->sd_private
#define SPACE_LOADABLE(space_chain) (space_chain)->sd_loadable
#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
#define SPACE_SORT(space_chain) (space_chain)->sd_sort_key
#define SPACE_NAME(space_chain) (space_chain)->sd_name
#define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_quadrant
#define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->regc_addralign
#define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->regc_initprot
#define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_sort_key
#define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_common
#define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
#define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_dup_common
#define SUBSPACE_CODE_ONLY(ssch) ((ssch)->ssd_entry->regc_flags & REG_TEXT_T)
#define SET_SUBSPACE_CODE_ONLY(ssch,val) (ssch)->ssd_entry->regc_flags |= ((val) ? REG_TEXT_T : 0)
#define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_loadable
#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->regc_addr.vm_addr
#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->regc_vm_size
#define SUBSPACE_REGION_NAME(ss_chain) (ss_chain)->ssd_entry->regc_region_name
#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
#endif
#ifdef OBJ_ELF
#define RELOC_EXPANSION_POSSIBLE
#define MAX_RELOC_EXPANSION 5
#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
#define SPACE_PRIVATE(space_chain) (space_chain)->sd_private
#define SPACE_LOADABLE(space_chain) (space_chain)->sd_loadable
#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
#define SPACE_SORT(space_chain) (space_chain)->sd_sort_key
#define SPACE_NAME(space_chain) (space_chain)->sd_name
#define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_quadrant
#define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->sh_addralign
#define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->sh_flags
#define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_sort_key
#define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_common
#define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
#define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_dup_common
#define SUBSPACE_CODE_ONLY(ssch) \
(((ssch)->ssd_entry->sh_flags & (SHF_ALLOC | SHF_EXECINSTR | SHF_WRITE)) \
== (SHF_ALLOC | SHF_EXECINSTR))
#define SET_SUBSPACE_CODE_ONLY(ssch,val) \
(ssch)->ssd_entry->sh_flags &= ((val) ? ~SHF_WRITE : 0xffffffff)
#define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_loadable
#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_vm_addr
#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->sh_size
#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
#define STAB_FIXUP(frag,toptr,symP,stab_type) \
if ( (stab_type == 's' || stab_type == 'n') \
&& symP->sy_value.X_seg == undefined_section) \
{ \
int i = S_GET_TYPE(symP) & N_TYPE; \
fix_new_hppa(frag, \
toptr-frag->fr_literal, /* where */ \
4, /* size */ \
symP->sy_value.X_add_symbol, /* addr of sym for this stab */ \
(asymbol *)NULL, \
0, \
i == N_UNDF || i == N_ABS, /* 1 if internal reloc */ \
R_HPPA, /* type */ \
e_fsel, /* fixup fld = F% */ \
32, \
0, /* arg_reloc */ \
(char *)0 \
); \
} \
else if ( stab_type == 'd' ) \
{ \
fix_new_hppa (frag, \
toptr-frag->fr_literal, /* where */ \
4, /* size */ \
symP, /* addr of sym for this stab */ \
(asymbol *)NULL, \
0, \
0, \
R_HPPA, /* type */ \
e_fsel, /* fixup fld = F% */ \
32, \
0, /* arg_reloc */ \
(char *)0 \
); \
}
#endif
#ifdef OBJ_SOM
#define SPACE_DEFINED(space_chain) (space_chain)->sd_entry->is_defined
#define SPACE_PRIVATE(space_chain) (space_chain)->sd_entry->is_private
#define SPACE_LOADABLE(space_chain) (space_chain)->sd_entry->is_loadable
#define SPACE_SPNUM(space_chain) (space_chain)->sd_entry->space_number
#define SPACE_SORT(space_chain) (space_chain)->sd_entry->sort_key
#define SPACE_NAME(space_chain) (space_chain)->sd_entry->name
#define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_entry->quadrant
#define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->alignment
#define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->access_control_bits
#define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_entry->sort_key
#define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_entry->is_common
#define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
#define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_entry->dup_common
#define SUBSPACE_CODE_ONLY(ss_chain) (ss_chain)->ssd_entry->code_only
#define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_entry->is_loadable
#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->subspace_start
#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->subspace_length
#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_entry->name
#endif
extern space_dict_chainS *space_dict_root;
extern space_dict_chainS *space_dict_last;
extern space_dict_chainS *current_space;
extern subspace_dict_chainS *current_subspace;
extern space_dict_chainS *create_new_space ();
extern subspace_dict_chainS *create_new_subspace ();
extern subspace_dict_chainS *update_subspace ();
extern space_dict_chainS *is_defined_space ();
extern space_dict_chainS *pa_segment_to_space ();
extern subspace_dict_chainS *is_defined_subspace ();
extern subspace_dict_chainS *pa_subsegment_to_subspace ();
extern space_dict_chainS *pa_find_space_by_number ();
extern unsigned int pa_subspace_start ();
extern int is_last_defined_subspace ();
/* symbol support */
extern symbolS *pa_get_start_symbol ();
extern symbolS *pa_set_start_symbol ();
/* default space and subspace dictionaries */
struct default_subspace_dict
{
char *name;
char defined;
char loadable, code_only, common, dup_common, zero, sort;
int access, space_index, alignment, quadrant;
#ifdef OBJ_SOM
segT segment;
#else
int def_space_index; /* this is an index in the default spaces array */
char *alias; /* an alias for this section (or NULL if there isn't one) */
#endif
subsegT subsegment;
};
extern struct default_subspace_dict pa_def_subspaces[];
struct default_space_dict
{
char *name;
int spnum;
char loadable;
char defined;
char private;
char sort;
#ifdef OBJ_SOM
segT segment;
#else
asection *segment;
char *alias; /* an alias for this section (or NULL if there isn't one) */
#endif
};
extern struct default_space_dict pa_def_spaces[];
/*
Support for keeping track of the most recent label in each
space.
*/
typedef struct label_symbol_struct
{
symbolS *lss_label; /* the label symbol */
space_dict_chainS *lss_space; /* the space to which it applies*/
struct label_symbol_struct *lss_next; /* the next label symbol */
} label_symbolS;
extern label_symbolS *label_symbols_rootP;
label_symbolS *pa_get_label ();
int pa_label_is_defined ();
void pa_define_label ();
void pa_undefine_label ();
int pa_pseudo_op_moves_pc ();
/* end of label symbol support. */
#define is_DP_relative(exp) ( (exp).X_subtract_symbol \
&& strcmp((exp).X_subtract_symbol->bsym->name, \
"$global$") == 0 )
#define is_PC_relative(exp) ( (exp).X_subtract_symbol \
&& strcmp((exp).X_subtract_symbol->bsym->name, \
"$PIC_pcrel$0") == 0 )
#define is_complex(exp) ((exp).X_seg && (exp).X_seg == diff_section)
#define tc_crawl_symbol_chain(headers) {;} /* Not used. */
#define tc_headers_hook(headers) {;} /* Not used. */
#define elf_tc_symbol elf_hppa_tc_symbol
#define elf_tc_make_sections elf_hppa_tc_make_sections
extern void elf_hppa_final_processing ();
#define elf_tc_final_processing elf_hppa_final_processing
/* We need to parse field selectors in .byte, etc. */
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
parse_cons_expression_hppa (exp)
#define TC_CONS_FIX_NEW cons_fix_new_hppa
extern void parse_cons_expression_hppa PARAMS ((expressionS *exp));
extern void cons_fix_new_hppa PARAMS ((fragS *frag,
int where,
int size,
expressionS *exp));
#endif /* _TC_HPPA_H */

View File

@ -1499,13 +1499,19 @@ pseudo_set (symbolP)
}
else if (segment == pass1_section)
{
symbolP->sy_forward = exp.X_add_symbol;
symbolP->sy_value.X_add_symbol = exp.X_add_symbol;
symbolP->sy_value.X_subtract_symbol = NULL;
symbolP->sy_value.X_add_number = 0;
symbolP->sy_value.X_seg = undefined_section;
as_bad ("Unknown expression");
know (need_pass_2 == 1);
}
else if (segment == undefined_section)
{
symbolP->sy_forward = exp.X_add_symbol;
symbolP->sy_value.X_add_symbol = exp.X_add_symbol;
symbolP->sy_value.X_subtract_symbol = NULL;
symbolP->sy_value.X_add_number = 0;
symbolP->sy_value.X_seg = undefined_section;
}
else
{

View File

@ -118,7 +118,6 @@ symbol_new (name, segment, value, frag)
symbol_clear_list_pointers(symbolP);
symbolP->sy_frag = frag;
symbolP->sy_forward = NULL;
#ifndef BFD_ASSEMBLER
symbolP->sy_number = ~0;
symbolP->sy_name_offset = ~0;
@ -566,6 +565,53 @@ verify_symbol_chain_2 (sym)
verify_symbol_chain (p, n);
}
/* Resolve the value of a symbol. This is called during the final
pass over the symbol table to resolve any symbols with complex
values. */
void
resolve_symbol_value (symp)
symbolS *symp;
{
if (symp->sy_resolved)
return;
if (symp->sy_resolving)
{
as_bad ("Symbol definition loop encountered at %s",
S_GET_NAME (symp));
S_SET_VALUE (symp, (valueT) 0);
}
else
{
symp->sy_resolving = 1;
if (symp->sy_value.X_seg == absolute_section)
S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
else if (symp->sy_value.X_seg == undefined_section)
{
resolve_symbol_value (symp->sy_value.X_add_symbol);
#ifdef obj_frob_forward_symbol
/* Some object formats need to forward the segment. */
obj_frob_forward_symbol (symp);
#endif
S_SET_VALUE (symp,
(symp->sy_value.X_add_number
+ symp->sy_frag->fr_address
+ S_GET_VALUE (symp->sy_value.X_add_symbol)));
}
else
{
/* More cases need to be added here. */
abort ();
}
}
symp->sy_resolved = 1;
}
#ifdef LOCAL_LABELS_DOLLAR
/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
@ -953,7 +999,7 @@ S_GET_VALUE (s)
symbolS *s;
{
if (s->sy_value.X_seg != absolute_section)
as_bad ("Attempt to get value of unresolved symbol");
as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
return (valueT) s->sy_value.X_add_number;
}

View File

@ -1172,18 +1172,30 @@ write_object_file ()
{
int keep = 0;
S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
if (! symp->sy_resolved)
{
if (symp->sy_value.X_seg == absolute_section)
{
/* This is the normal case; skip the call. */
S_SET_VALUE (symp,
(S_GET_VALUE (symp)
+ symp->sy_frag->fr_address));
symp->sy_resolved = 1;
}
else
resolve_symbol_value (symp);
}
/* So far, common symbols have been treated like undefined symbols.
Put them in the common section now. */
if (S_IS_DEFINED (symp) == 0
&& S_GET_VALUE (symp) != 0)
S_SET_SEGMENT (symp, &bfd_com_section);
#if 0
printf ("symbol `%s'\n\t@%x: value=%d flags=%x forward=%x seg=%s\n",
printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
S_GET_NAME (symp), symp,
S_GET_VALUE (symp),
symp->bsym->flags,
symp->sy_forward,
segment_name (symp->bsym->section));
#endif
{