* som.c (hppa_som_gen_reloc_type): New argument "sym_diff",

nonzero when we're generating relocations for an expression
	using the difference of two symbols.  All callers changed.
	Handle difference of symbols for both R_HPPA and R_COMPLEX
	cases.
	(som_write_fixups): Handle R_COMP1, R_COMP2 and R_CODE_EXPR
	fixups.
This commit is contained in:
Jeff Law 1995-07-03 23:27:25 +00:00
parent 3a6eecd42f
commit c40439a219
3 changed files with 142 additions and 4 deletions

View File

@ -1,3 +1,13 @@
Mon Jul 3 17:03:52 1995 Jeff Law (law@snake.cs.utah.edu)
* som.c (hppa_som_gen_reloc_type): New argument "sym_diff",
nonzero when we're generating relocations for an expression
using the difference of two symbols. All callers changed.
Handle difference of symbols for both R_HPPA and R_COMPLEX
cases.
(som_write_fixups): Handle R_COMP1, R_COMP2 and R_CODE_EXPR
fixups.
Mon Jul 3 13:55:18 1995 Steve Chamberlain <sac@slash.cygnus.com>
* config.bfd (win32): New configuration.

126
bfd/som.c
View File

@ -167,6 +167,8 @@ static asymbol * som_make_empty_symbol PARAMS ((bfd *));
static void som_print_symbol PARAMS ((bfd *, PTR,
asymbol *, bfd_print_symbol_type));
static boolean som_new_section_hook PARAMS ((bfd *, asection *));
static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *,
bfd *, asymbol *));
static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *,
bfd *, asection *));
static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
@ -254,6 +256,7 @@ static boolean som_is_space PARAMS ((asection *));
static boolean som_is_subspace PARAMS ((asection *));
static boolean som_is_container PARAMS ((asection *, asection *));
static boolean som_bfd_free_cached_info PARAMS ((bfd *));
static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *));
/* Map SOM section names to POSIX/BSD single-character symbol types.
@ -1394,15 +1397,16 @@ hppa_som_reloc (abfd, reloc_entry, symbol_in, data,
and a field selector, return one or more appropriate SOM relocations. */
int **
hppa_som_gen_reloc_type (abfd, base_type, format, field)
hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff)
bfd *abfd;
int base_type;
int format;
enum hppa_reloc_field_selector_type_alt field;
int sym_diff;
{
int *final_type, **final_types;
final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 3);
final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 6);
final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
if (!final_types || !final_type)
{
@ -1507,8 +1511,29 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
switch (base_type)
{
case R_HPPA:
/* The difference of two symbols needs *very* special handling. */
if (sym_diff)
{
final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
if (!final_types[0] || !final_types[1] || !final_types[2])
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
*final_types[0] = R_FSEL;
*final_types[1] = R_COMP2;
*final_types[2] = R_COMP2;
*final_types[3] = R_COMP1;
final_types[4] = final_type;
*final_types[4] = R_CODE_EXPR;
final_types[5] = NULL;
break;
}
/* PLABELs get their own relocation type. */
if (field == e_psel
else if (field == e_psel
|| field == e_lpsel
|| field == e_rpsel)
{
@ -1538,6 +1563,31 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
*final_type = R_DATA_PLABEL;
break;
case R_HPPA_COMPLEX:
/* The difference of two symbols needs *very* special handling. */
if (sym_diff)
{
final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
if (!final_types[0] || !final_types[1] || !final_types[2])
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
*final_types[1] = R_FSEL;
*final_types[1] = R_COMP2;
*final_types[2] = R_COMP2;
*final_types[3] = R_COMP1;
final_types[4] = final_type;
*final_types[4] = R_CODE_EXPR;
final_types[5] = NULL;
break;
}
else
break;
case R_HPPA_NONE:
case R_HPPA_ABS_CALL:
case R_HPPA_PCREL_CALL:
@ -2556,6 +2606,8 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
case R_FSEL:
case R_LSEL:
case R_RSEL:
case R_COMP1:
case R_COMP2:
reloc_offset = bfd_reloc->address;
break;
@ -2690,6 +2742,37 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
p += 1;
break;
case R_COMP1:
/* The only time we generate R_COMP1, R_COMP2 and
R_CODE_EXPR relocs is for the difference of two
symbols. Hence we can cheat here. */
bfd_put_8 (abfd, bfd_reloc->howto->type, p);
bfd_put_8 (abfd, 0x44, p + 1);
p = try_prev_fixup (abfd, &subspace_reloc_size,
p, 2, reloc_queue);
break;
case R_COMP2:
/* The only time we generate R_COMP1, R_COMP2 and
R_CODE_EXPR relocs is for the difference of two
symbols. Hence we can cheat here. */
bfd_put_8 (abfd, bfd_reloc->howto->type, p);
bfd_put_8 (abfd, 0x80, p + 1);
bfd_put_8 (abfd, sym_num >> 16, p + 2);
bfd_put_16 (abfd, sym_num, p + 3);
p = try_prev_fixup (abfd, &subspace_reloc_size,
p, 5, reloc_queue);
break;
case R_CODE_EXPR:
/* The only time we generate R_COMP1, R_COMP2 and
R_CODE_EXPR relocs is for the difference of two
symbols. Hence we can cheat here. */
bfd_put_8 (abfd, bfd_reloc->howto->type, p);
subspace_reloc_size += 1;
p += 1;
break;
/* Put a "R_RESERVED" relocation in the stream if
we hit something we do not understand. The linker
will complain loudly if this ever happens. */
@ -4185,8 +4268,11 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
the stack. */
else if (islower (c))
{
int bits = (c - 'a') * 8;
for (v = 0; c > 'a'; --c)
v = (v << 8) | *fixup++;
if (varname == 'V')
v = sign_extend (v, bits);
push (v);
}
@ -4574,6 +4660,31 @@ som_new_section_hook (abfd, newsect)
return true;
}
/* Copy any private info we understand from the input symbol
to the output symbol. */
static boolean
som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
bfd *ibfd;
asymbol *isymbol;
bfd *obfd;
asymbol *osymbol;
{
struct som_symbol *input_symbol = isymbol;
struct som_symbol *output_symbol = osymbol;
/* One day we may try to grok other private data. */
if (ibfd->xvec->flavour != bfd_target_som_flavour
|| obfd->xvec->flavour != bfd_target_som_flavour)
return false;
/* The only private information we need to copy is the argument relocation
bits. */
output_symbol->tc_data.hppa_arg_reloc = input_symbol->tc_data.hppa_arg_reloc;
return true;
}
/* Copy any private info we understand from the input section
to the output section. */
static boolean
@ -5813,6 +5924,15 @@ som_bfd_free_cached_info (abfd)
/* End of miscellaneous support functions. */
/* Linker support functions. */
static boolean
som_bfd_link_split_section (abfd, sec)
bfd *abfd;
asection *sec;
{
return (som_is_subspace (sec) && sec->_raw_size > 240000);
}
#define som_close_and_cleanup som_bfd_free_cached_info
#define som_openr_next_archived_file bfd_generic_openr_next_archived_file

View File

@ -30,6 +30,12 @@
#include <lst.h>
#include <ar.h>
/* The SOM BFD backend doesn't currently use anything from these
two include files, but it's likely to need them in the future. */
#ifdef R_DLT_REL
#include <shl.h>
#include <dl.h>
#endif
#if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF)
/* BSD uses a completely different scheme for object file identification.
@ -107,6 +113,7 @@ struct somdata
need not be copied for objcopy or strip to work. */
som_symbol_type *symtab;
char *stringtab;
asymbol **sorted_syms;
/* We remember these offsets so that after check_file_format, we have
no dependencies on the particular format of the exec_hdr.
@ -179,6 +186,7 @@ struct som_section_data_struct
#define obj_som_str_filepos(bfd) (somdata(bfd).str_filepos)
#define obj_som_stringtab_size(bfd) (somdata(bfd).stringtab_size)
#define obj_som_reloc_filepos(bfd) (somdata(bfd).reloc_filepos)
#define obj_som_sorted_syms(bfd) (somdata(bfd).sorted_syms)
#define som_section_data(sec) \
((struct som_section_data_struct *)sec->used_by_bfd)
#define som_symbol_data(symbol) ((som_symbol_type *) symbol)
@ -210,5 +218,5 @@ boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *,
void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int));
boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *));
int ** hppa_som_gen_reloc_type
PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt));
PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int));
#endif /* _SOM_H */