* som.c (som_object_setup): More heruistics to detect the
braindamaged HP OSF1 linker. (setup_sections): Don't forget to free subspace_sections if we get an error. (som_slurp_string_table): Allocate strings on this bfd's obstack rather than directly out of the heap. (som_slurp_symbol_table): Likewise for the saved copy of the canonical symbols. (som_slurp_reloc_table): Likewise for the saved copy of the canonical relocations. Free the native relocations when we're done with them.
This commit is contained in:
parent
ef6fb95dea
commit
9ea5de84ab
|
@ -1,3 +1,17 @@
|
||||||
|
Wed Feb 1 01:32:14 1995 Jeff Law (law@snake.cs.utah.edu)
|
||||||
|
|
||||||
|
* som.c (som_object_setup): More heruistics to detect the
|
||||||
|
braindamaged HP OSF1 linker.
|
||||||
|
(setup_sections): Don't forget to free subspace_sections if we get
|
||||||
|
an error.
|
||||||
|
(som_slurp_string_table): Allocate strings on this bfd's obstack
|
||||||
|
rather than directly out of the heap.
|
||||||
|
(som_slurp_symbol_table): Likewise for the saved copy of the
|
||||||
|
canonical symbols.
|
||||||
|
(som_slurp_reloc_table): Likewise for the saved copy of the
|
||||||
|
canonical relocations. Free the native relocations when we're
|
||||||
|
done with them.
|
||||||
|
|
||||||
Tue Jan 31 21:53:28 1995 Doug Evans <dje@canuck.cygnus.com>
|
Tue Jan 31 21:53:28 1995 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
* libelf.h (struct elf_obj_tdata): New member program_header_size.
|
* libelf.h (struct elf_obj_tdata): New member program_header_size.
|
||||||
|
|
246
bfd/som.c
246
bfd/som.c
|
@ -213,10 +213,11 @@ static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *,
|
||||||
static unsigned long som_count_spaces PARAMS ((bfd *));
|
static unsigned long som_count_spaces PARAMS ((bfd *));
|
||||||
static unsigned long som_count_subspaces PARAMS ((bfd *));
|
static unsigned long som_count_subspaces PARAMS ((bfd *));
|
||||||
static int compare_syms PARAMS ((const void *, const void *));
|
static int compare_syms PARAMS ((const void *, const void *));
|
||||||
|
static int compare_subspaces PARAMS ((const void *, const void *));
|
||||||
static unsigned long som_compute_checksum PARAMS ((bfd *));
|
static unsigned long som_compute_checksum PARAMS ((bfd *));
|
||||||
static boolean som_prep_headers PARAMS ((bfd *));
|
static boolean som_prep_headers PARAMS ((bfd *));
|
||||||
static int som_sizeof_headers PARAMS ((bfd *, boolean));
|
static int som_sizeof_headers PARAMS ((bfd *, boolean));
|
||||||
static boolean som_write_headers PARAMS ((bfd *));
|
static boolean som_finish_writing PARAMS ((bfd *));
|
||||||
static boolean som_build_and_write_symbol_table PARAMS ((bfd *));
|
static boolean som_build_and_write_symbol_table PARAMS ((bfd *));
|
||||||
static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long));
|
static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long));
|
||||||
static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *));
|
static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *));
|
||||||
|
@ -1571,6 +1572,9 @@ som_object_setup (abfd, file_hdrp, aux_hdrp)
|
||||||
struct header *file_hdrp;
|
struct header *file_hdrp;
|
||||||
struct som_exec_auxhdr *aux_hdrp;
|
struct som_exec_auxhdr *aux_hdrp;
|
||||||
{
|
{
|
||||||
|
asection *section;
|
||||||
|
int found;
|
||||||
|
|
||||||
/* som_mkobject will set bfd_error if som_mkobject fails. */
|
/* som_mkobject will set bfd_error if som_mkobject fails. */
|
||||||
if (som_mkobject (abfd) != true)
|
if (som_mkobject (abfd) != true)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1627,7 +1631,18 @@ som_object_setup (abfd, file_hdrp, aux_hdrp)
|
||||||
The new approach examines the entry field. If it's zero or not 4
|
The new approach examines the entry field. If it's zero or not 4
|
||||||
byte aligned then it's not a proper code address and we guess it's
|
byte aligned then it's not a proper code address and we guess it's
|
||||||
really the executable flags. */
|
really the executable flags. */
|
||||||
if (aux_hdrp->exec_entry == 0 || (aux_hdrp->exec_entry & 0x3) != 0)
|
found = 0;
|
||||||
|
for (section = abfd->sections; section; section = section->next)
|
||||||
|
{
|
||||||
|
if ((section->flags & SEC_CODE) == 0)
|
||||||
|
continue;
|
||||||
|
if (aux_hdrp->exec_entry >= section->vma
|
||||||
|
&& aux_hdrp->exec_entry < section->vma + section->_cooked_size)
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
if (aux_hdrp->exec_entry == 0
|
||||||
|
|| (aux_hdrp->exec_entry & 0x3) != 0
|
||||||
|
|| ! found)
|
||||||
{
|
{
|
||||||
bfd_get_start_address (abfd) = aux_hdrp->exec_flags;
|
bfd_get_start_address (abfd) = aux_hdrp->exec_flags;
|
||||||
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry;
|
obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry;
|
||||||
|
@ -1668,8 +1683,9 @@ setup_sections (abfd, file_hdr)
|
||||||
struct header *file_hdr;
|
struct header *file_hdr;
|
||||||
{
|
{
|
||||||
char *space_strings;
|
char *space_strings;
|
||||||
int space_index;
|
unsigned int space_index, i;
|
||||||
unsigned int total_subspaces = 0;
|
unsigned int total_subspaces = 0;
|
||||||
|
asection **subspace_sections, *section;
|
||||||
|
|
||||||
/* First, read in space names */
|
/* First, read in space names */
|
||||||
|
|
||||||
|
@ -1779,8 +1795,17 @@ setup_sections (abfd, file_hdr)
|
||||||
subspace.quadrant) == false)
|
subspace.quadrant) == false)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
/* Keep an easy mapping between subspaces and sections. */
|
/* Keep an easy mapping between subspaces and sections.
|
||||||
subspace_asect->target_index = total_subspaces++;
|
Note we do not necessarily read the subspaces in the
|
||||||
|
same order in which they appear in the object file.
|
||||||
|
|
||||||
|
So to make the target index come out correctly, we
|
||||||
|
store the location of the subspace header in target
|
||||||
|
index, then sort using the location of the subspace
|
||||||
|
header as the key. Then we can assign correct
|
||||||
|
subspace indices. */
|
||||||
|
total_subspaces++;
|
||||||
|
subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace);
|
||||||
|
|
||||||
/* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
|
/* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
|
||||||
by the access_control_bits in the subspace header. */
|
by the access_control_bits in the subspace header. */
|
||||||
|
@ -1873,13 +1898,43 @@ setup_sections (abfd, file_hdr)
|
||||||
space_asect->_raw_size = save_subspace.file_loc_init_value
|
space_asect->_raw_size = save_subspace.file_loc_init_value
|
||||||
- space_asect->filepos + save_subspace.initialization_length;
|
- space_asect->filepos + save_subspace.initialization_length;
|
||||||
}
|
}
|
||||||
|
/* Now that we've read in all the subspace records, we need to assign
|
||||||
|
a target index to each subspace. */
|
||||||
|
subspace_sections = (asection **) malloc (total_subspaces
|
||||||
|
* sizeof (asection *));
|
||||||
|
if (subspace_sections == NULL)
|
||||||
|
goto error_return;
|
||||||
|
|
||||||
|
for (i = 0, section = abfd->sections; section; section = section->next)
|
||||||
|
{
|
||||||
|
if (!som_is_subspace (section))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subspace_sections[i] = section;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
qsort (subspace_sections, total_subspaces,
|
||||||
|
sizeof (asection *), compare_subspaces);
|
||||||
|
|
||||||
|
/* subspace_sections is now sorted in the order in which the subspaces
|
||||||
|
appear in the object file. Assign an index to each one now. */
|
||||||
|
for (i = 0; i < total_subspaces; i++)
|
||||||
|
subspace_sections[i]->target_index = i;
|
||||||
|
|
||||||
if (space_strings != NULL)
|
if (space_strings != NULL)
|
||||||
free (space_strings);
|
free (space_strings);
|
||||||
|
|
||||||
|
if (subspace_sections != NULL)
|
||||||
|
free (subspace_sections);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
if (space_strings != NULL)
|
if (space_strings != NULL)
|
||||||
free (space_strings);
|
free (space_strings);
|
||||||
|
|
||||||
|
if (subspace_sections != NULL)
|
||||||
|
free (subspace_sections);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2136,7 +2191,9 @@ som_is_space (section)
|
||||||
|
|
||||||
/* If the containing space isn't the same as the given section,
|
/* If the containing space isn't the same as the given section,
|
||||||
then this isn't a space. */
|
then this isn't a space. */
|
||||||
if (som_section_data (section)->copy_data->container != section)
|
if (som_section_data (section)->copy_data->container != section
|
||||||
|
&& (som_section_data (section)->copy_data->container->output_section
|
||||||
|
!= section))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* OK. Must be a space. */
|
/* OK. Must be a space. */
|
||||||
|
@ -2156,7 +2213,9 @@ som_is_subspace (section)
|
||||||
|
|
||||||
/* If the containing space is the same as the given section,
|
/* If the containing space is the same as the given section,
|
||||||
then this isn't a subspace. */
|
then this isn't a subspace. */
|
||||||
if (som_section_data (section)->copy_data->container == section)
|
if (som_section_data (section)->copy_data->container == section
|
||||||
|
|| (som_section_data (section)->copy_data->container->output_section
|
||||||
|
== section))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* OK. Must be a subspace. */
|
/* OK. Must be a subspace. */
|
||||||
|
@ -2171,7 +2230,9 @@ static boolean
|
||||||
som_is_container (space, subspace)
|
som_is_container (space, subspace)
|
||||||
asection *space, *subspace;
|
asection *space, *subspace;
|
||||||
{
|
{
|
||||||
return som_section_data (subspace)->copy_data->container == space;
|
return (som_section_data (subspace)->copy_data->container == space
|
||||||
|
|| (som_section_data (subspace)->copy_data->container->output_section
|
||||||
|
== space));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count and return the number of spaces attached to the given BFD. */
|
/* Count and return the number of spaces attached to the given BFD. */
|
||||||
|
@ -2240,6 +2301,27 @@ compare_syms (arg1, arg2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return -1, 0, 1 indicating the relative ordering of subspace1
|
||||||
|
and subspace. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_subspaces (arg1, arg2)
|
||||||
|
const PTR arg1;
|
||||||
|
const PTR arg2;
|
||||||
|
|
||||||
|
{
|
||||||
|
asection **subspace1 = (asection **) arg1;
|
||||||
|
asection **subspace2 = (asection **) arg2;
|
||||||
|
unsigned int count1, count2;
|
||||||
|
|
||||||
|
if ((*subspace1)->target_index < (*subspace2)->target_index)
|
||||||
|
return -1;
|
||||||
|
else if ((*subspace2)->target_index < (*subspace1)->target_index)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform various work in preparation for emitting the fixup stream. */
|
/* Perform various work in preparation for emitting the fixup stream. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2953,23 +3035,6 @@ som_begin_writing (abfd)
|
||||||
obj_som_file_hdr (abfd)->symbol_total = num_syms;
|
obj_som_file_hdr (abfd)->symbol_total = num_syms;
|
||||||
current_offset += num_syms * sizeof (struct symbol_dictionary_record);
|
current_offset += num_syms * sizeof (struct symbol_dictionary_record);
|
||||||
|
|
||||||
/* Do prep work before handling fixups. */
|
|
||||||
som_prep_for_fixups (abfd, syms, num_syms);
|
|
||||||
|
|
||||||
/* Next comes the fixup stream which starts on a word boundary. */
|
|
||||||
if (current_offset % 4)
|
|
||||||
current_offset += (4 - (current_offset % 4));
|
|
||||||
obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
|
|
||||||
|
|
||||||
/* Write the fixups and update fields in subspace headers which
|
|
||||||
relate to the fixup stream. */
|
|
||||||
if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Record the total size of the fixup stream in the file header. */
|
|
||||||
obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
|
|
||||||
current_offset += total_reloc_size;
|
|
||||||
|
|
||||||
/* Next are the symbol strings.
|
/* Next are the symbol strings.
|
||||||
Align them to a word boundary. */
|
Align them to a word boundary. */
|
||||||
if (current_offset % 4)
|
if (current_offset % 4)
|
||||||
|
@ -2977,8 +3042,7 @@ som_begin_writing (abfd)
|
||||||
obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
|
obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
|
||||||
|
|
||||||
/* Scribble out the symbol strings. */
|
/* Scribble out the symbol strings. */
|
||||||
if (som_write_symbol_strings (abfd, current_offset,
|
if (som_write_symbol_strings (abfd, current_offset, syms,
|
||||||
obj_som_sorted_syms (abfd),
|
|
||||||
num_syms, &strings_size)
|
num_syms, &strings_size)
|
||||||
== false)
|
== false)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3185,7 +3249,7 @@ som_begin_writing (abfd)
|
||||||
obj_som_file_hdr (abfd)->loader_fixup_location = 0;
|
obj_som_file_hdr (abfd)->loader_fixup_location = 0;
|
||||||
obj_som_file_hdr (abfd)->loader_fixup_total = 0;
|
obj_som_file_hdr (abfd)->loader_fixup_total = 0;
|
||||||
|
|
||||||
/* Done. Store the total size of the SOM. */
|
/* Done. Store the total size of the SOM so far. */
|
||||||
obj_som_file_hdr (abfd)->som_length = current_offset;
|
obj_som_file_hdr (abfd)->som_length = current_offset;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3194,7 +3258,7 @@ som_begin_writing (abfd)
|
||||||
/* Finally, scribble out the various headers to the disk. */
|
/* Finally, scribble out the various headers to the disk. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
som_write_headers (abfd)
|
som_finish_writing (abfd)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
{
|
{
|
||||||
int num_spaces = som_count_spaces (abfd);
|
int num_spaces = som_count_spaces (abfd);
|
||||||
|
@ -3202,6 +3266,36 @@ som_write_headers (abfd)
|
||||||
int subspace_index = 0;
|
int subspace_index = 0;
|
||||||
file_ptr location;
|
file_ptr location;
|
||||||
asection *section;
|
asection *section;
|
||||||
|
unsigned long current_offset;
|
||||||
|
unsigned int total_reloc_size;
|
||||||
|
|
||||||
|
/* Do prep work before handling fixups. */
|
||||||
|
som_prep_for_fixups (abfd,
|
||||||
|
bfd_get_outsymbols (abfd),
|
||||||
|
bfd_get_symcount (abfd));
|
||||||
|
|
||||||
|
current_offset = obj_som_file_hdr (abfd)->som_length;
|
||||||
|
|
||||||
|
/* At the end of the file is the fixup stream which starts on a
|
||||||
|
word boundary. */
|
||||||
|
if (current_offset % 4)
|
||||||
|
current_offset += (4 - (current_offset % 4));
|
||||||
|
obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
|
||||||
|
|
||||||
|
/* Write the fixups and update fields in subspace headers which
|
||||||
|
relate to the fixup stream. */
|
||||||
|
if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Record the total size of the fixup stream in the file header. */
|
||||||
|
obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
|
||||||
|
|
||||||
|
obj_som_file_hdr (abfd)->som_length += total_reloc_size;
|
||||||
|
|
||||||
|
/* Now that the symbol table information is complete, build and
|
||||||
|
write the symbol table. */
|
||||||
|
if (som_build_and_write_symbol_table (abfd) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Subspaces are written first so that we can set up information
|
/* Subspaces are written first so that we can set up information
|
||||||
about them in their containing spaces as the subspace is written. */
|
about them in their containing spaces as the subspace is written. */
|
||||||
|
@ -3503,11 +3597,10 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
|
||||||
/* Now handle the symbol's scope. Exported data which is not
|
/* Now handle the symbol's scope. Exported data which is not
|
||||||
in the common section has scope SS_UNIVERSAL. Note scope
|
in the common section has scope SS_UNIVERSAL. Note scope
|
||||||
of common symbols was handled earlier! */
|
of common symbols was handled earlier! */
|
||||||
if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section))
|
if (bfd_is_und_section (sym->section))
|
||||||
info->symbol_scope = SS_UNIVERSAL;
|
|
||||||
/* Any undefined symbol at this point has a scope SS_UNSAT. */
|
|
||||||
else if (bfd_is_und_section (sym->section))
|
|
||||||
info->symbol_scope = SS_UNSAT;
|
info->symbol_scope = SS_UNSAT;
|
||||||
|
else if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section))
|
||||||
|
info->symbol_scope = SS_UNIVERSAL;
|
||||||
/* Anything else which is not in the common section has scope
|
/* Anything else which is not in the common section has scope
|
||||||
SS_LOCAL. */
|
SS_LOCAL. */
|
||||||
else if (! bfd_is_com_section (sym->section))
|
else if (! bfd_is_com_section (sym->section))
|
||||||
|
@ -3609,12 +3702,7 @@ som_write_object_contents (abfd)
|
||||||
som_begin_writing (abfd);
|
som_begin_writing (abfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that the symbol table information is complete, build and
|
return (som_finish_writing (abfd));
|
||||||
write the symbol table. */
|
|
||||||
if (som_build_and_write_symbol_table (abfd) == false)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (som_write_headers (abfd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3640,7 +3728,7 @@ som_slurp_string_table (abfd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate and read in the string table. */
|
/* Allocate and read in the string table. */
|
||||||
stringtab = malloc (obj_som_stringtab_size (abfd));
|
stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
|
||||||
if (stringtab == NULL)
|
if (stringtab == NULL)
|
||||||
{
|
{
|
||||||
bfd_set_error (bfd_error_no_memory);
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
@ -3747,7 +3835,7 @@ som_slurp_symbol_table (abfd)
|
||||||
stringtab = obj_som_stringtab (abfd);
|
stringtab = obj_som_stringtab (abfd);
|
||||||
|
|
||||||
symbase = (som_symbol_type *)
|
symbase = (som_symbol_type *)
|
||||||
malloc (symbol_count * sizeof (som_symbol_type));
|
bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
|
||||||
if (symbase == NULL)
|
if (symbase == NULL)
|
||||||
{
|
{
|
||||||
bfd_set_error (bfd_error_no_memory);
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
@ -4158,6 +4246,73 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
|
||||||
if (! just_count)
|
if (! just_count)
|
||||||
rptr->sym_ptr_ptr = &symbols[c];
|
rptr->sym_ptr_ptr = &symbols[c];
|
||||||
break;
|
break;
|
||||||
|
/* Argument relocation bits for a function call. */
|
||||||
|
case 'R':
|
||||||
|
if (! just_count)
|
||||||
|
{
|
||||||
|
unsigned int tmp = var ('R');
|
||||||
|
rptr->addend = 0;
|
||||||
|
|
||||||
|
if ((som_hppa_howto_table[op].type == R_PCREL_CALL
|
||||||
|
&& R_PCREL_CALL + 10 > op)
|
||||||
|
|| (som_hppa_howto_table[op].type == R_ABS_CALL
|
||||||
|
&& R_ABS_CALL + 10 > op))
|
||||||
|
{
|
||||||
|
/* Simple encoding. */
|
||||||
|
if (tmp > 4)
|
||||||
|
{
|
||||||
|
tmp -= 5;
|
||||||
|
rptr->addend |= 1;
|
||||||
|
}
|
||||||
|
if (tmp == 4)
|
||||||
|
rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2;
|
||||||
|
else if (tmp == 3)
|
||||||
|
rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4;
|
||||||
|
else if (tmp == 2)
|
||||||
|
rptr->addend |= 1 << 8 | 1 << 6;
|
||||||
|
else if (tmp == 1)
|
||||||
|
rptr->addend |= 1 << 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int tmp1, tmp2;
|
||||||
|
|
||||||
|
/* First part is easy -- low order two bits are
|
||||||
|
directly copied, then shifted away. */
|
||||||
|
rptr->addend = tmp & 0x3;
|
||||||
|
tmp >>= 2;
|
||||||
|
|
||||||
|
/* Diving the result by 10 gives us the second
|
||||||
|
part. If it is 9, then the first two words
|
||||||
|
are a double precision paramater, else it is
|
||||||
|
3 * the first arg bits + the 2nd arg bits. */
|
||||||
|
tmp1 = tmp / 10;
|
||||||
|
tmp -= tmp1 * 10;
|
||||||
|
if (tmp1 == 9)
|
||||||
|
rptr->addend += (0xe << 6);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get the two pieces. */
|
||||||
|
tmp2 = tmp1 / 3;
|
||||||
|
tmp1 -= tmp2 * 3;
|
||||||
|
/* Put them in the addend. */
|
||||||
|
rptr->addend += (tmp2 << 8) + (tmp1 << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* What's left is the third part. It's unpacked
|
||||||
|
just like the second. */
|
||||||
|
if (tmp == 9)
|
||||||
|
rptr->addend += (0xe << 2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp2 = tmp / 3;
|
||||||
|
tmp -= tmp2 * 3;
|
||||||
|
rptr->addend += (tmp2 << 4) + (tmp << 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rptr->addend = HPPA_R_ADDEND (rptr->addend, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
/* Handle the linker expression stack. */
|
/* Handle the linker expression stack. */
|
||||||
case 'O':
|
case 'O':
|
||||||
switch (op)
|
switch (op)
|
||||||
|
@ -4210,6 +4365,9 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
|
||||||
rptr->addend = var ('T');
|
rptr->addend = var ('T');
|
||||||
else if (som_hppa_howto_table[op].type == R_EXIT)
|
else if (som_hppa_howto_table[op].type == R_EXIT)
|
||||||
rptr->addend = var ('U');
|
rptr->addend = var ('U');
|
||||||
|
else if (som_hppa_howto_table[op].type == R_PCREL_CALL
|
||||||
|
|| som_hppa_howto_table[op].type == R_ABS_CALL)
|
||||||
|
;
|
||||||
else
|
else
|
||||||
rptr->addend = var ('V');
|
rptr->addend = var ('V');
|
||||||
rptr++;
|
rptr++;
|
||||||
|
@ -4292,7 +4450,8 @@ som_slurp_reloc_table (abfd, section, symbols, just_count)
|
||||||
if (section->relocation != (arelent *) NULL)
|
if (section->relocation != (arelent *) NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
internal_relocs = (arelent *) malloc (num_relocs * sizeof (arelent));
|
internal_relocs = (arelent *)
|
||||||
|
bfd_zalloc (abfd, (num_relocs * sizeof (arelent)));
|
||||||
if (internal_relocs == (arelent *) NULL)
|
if (internal_relocs == (arelent *) NULL)
|
||||||
{
|
{
|
||||||
bfd_set_error (bfd_error_no_memory);
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
@ -4303,6 +4462,9 @@ som_slurp_reloc_table (abfd, section, symbols, just_count)
|
||||||
som_set_reloc_info (external_relocs, fixup_stream_size,
|
som_set_reloc_info (external_relocs, fixup_stream_size,
|
||||||
internal_relocs, section, symbols, false);
|
internal_relocs, section, symbols, false);
|
||||||
|
|
||||||
|
/* We're done with the external relocations. Free them. */
|
||||||
|
free (external_relocs);
|
||||||
|
|
||||||
/* Save our results and return success. */
|
/* Save our results and return success. */
|
||||||
section->relocation = internal_relocs;
|
section->relocation = internal_relocs;
|
||||||
return (true);
|
return (true);
|
||||||
|
|
Loading…
Reference in New Issue