* 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:
parent
3a6eecd42f
commit
c40439a219
3 changed files with 142 additions and 4 deletions
|
@ -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
126
bfd/som.c
|
@ -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
|
||||
|
|
10
bfd/som.h
10
bfd/som.h
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue