aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/som.c126
-rw-r--r--bfd/som.h10
3 files changed, 142 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cfb81a5..a340b74 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 <sac@slash.cygnus.com>
* config.bfd (win32): New configuration.
diff --git a/bfd/som.c b/bfd/som.c
index f97a7fe..e43e394 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 99b777d..3230344 100644
--- a/bfd/som.h
+++ b/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 */