From c40439a219ba23c42dd614b78d2c1b5c9d4bc44e Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 3 Jul 1995 23:27:25 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 10 ++++ bfd/som.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++-- bfd/som.h | 10 +++- 3 files changed, 142 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cfb81a50437..a340b74834d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 * config.bfd (win32): New configuration. diff --git a/bfd/som.c b/bfd/som.c index f97a7fefbb8..e43e3946afd 100644 --- a/bfd/som.c +++ b/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 diff --git a/bfd/som.h b/bfd/som.h index 99b777d3ca8..32303446e5b 100644 --- a/bfd/som.h +++ b/bfd/som.h @@ -30,6 +30,12 @@ #include #include +/* 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 +#include +#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 */ -- 2.30.2