/* bfd back-end for HP PA-RISC SOM objects.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Contributed by the Center for Software Science at the
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include "alloca-conf.h"
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) || defined(HOST_HPPAMPEIX)
#include <machine/reg.h>
#include <sys/file.h>
+static bfd_reloc_status_type hppa_som_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean som_mkobject (bfd *);
+static bfd_boolean som_is_space (asection *);
+static bfd_boolean som_is_subspace (asection *);
+static int compare_subspaces (const void *, const void *);
+static unsigned long som_compute_checksum (bfd *);
+static bfd_boolean som_build_and_write_symbol_table (bfd *);
+static unsigned int som_slurp_symbol_table (bfd *);
+
/* Magic not defined in standard HP-UX header files until 8.0. */
#ifndef CPU_PA_RISC1_0
static unsigned char *
try_prev_fixup (bfd *abfd ATTRIBUTE_UNUSED,
- int *subspace_reloc_sizep,
+ unsigned int *subspace_reloc_sizep,
unsigned char *p,
unsigned int size,
struct reloc_queue *queue)
hppa_som_reloc (bfd *abfd ATTRIBUTE_UNUSED,
arelent *reloc_entry,
asymbol *symbol_in ATTRIBUTE_UNUSED,
- void * data ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
asection *input_section,
bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
return NULL;
}
+static reloc_howto_type *
+som_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (som_hppa_howto_table) / sizeof (som_hppa_howto_table[0]);
+ i++)
+ if (som_hppa_howto_table[i].name != NULL
+ && strcasecmp (som_hppa_howto_table[i].name, r_name) == 0)
+ return &som_hppa_howto_table[i];
+
+ return NULL;
+}
+
/* Perform some initialization for an object. Save results of this
initialization in the BFD. */
count. Doing so compacts the relocation stream. */
static int
-compare_syms (const void * arg1, const void * arg2)
+compare_syms (const void *arg1, const void *arg2)
{
asymbol **sym1 = (asymbol **) arg1;
asymbol **sym2 = (asymbol **) arg2;
and subspace. */
static int
-compare_subspaces (const void * arg1, const void * arg2)
+compare_subspaces (const void *arg1, const void *arg2)
{
asection **subspace1 = (asection **) arg1;
asection **subspace2 = (asection **) arg2;
/* Chunk of memory that we can use as buffer space, then throw
away. */
size_t tmp_space_size = SOM_TMP_BUFSIZE;
- unsigned char *tmp_space = alloca (tmp_space_size);
- unsigned char *p = tmp_space;
+ char *tmp_space = alloca (tmp_space_size);
+ char *p = tmp_space;
unsigned int strings_size = 0;
asection *section;
bfd_size_type amt;
/* Chunk of memory that we can use as buffer space, then throw
away. */
size_t tmp_space_size = SOM_TMP_BUFSIZE;
- unsigned char *tmp_space = alloca (tmp_space_size);
- unsigned char *p = tmp_space;
+ char *tmp_space = alloca (tmp_space_size);
+ char *p = tmp_space;
unsigned int strings_size = 0;
- unsigned char *comp[4];
+ char *comp[4];
bfd_size_type amt;
/* This gets a bit gruesome because of the compilation unit. The
som_begin_writing (bfd *abfd)
{
unsigned long current_offset = 0;
- int strings_size = 0;
+ unsigned int strings_size = 0;
unsigned long num_spaces, num_subspaces, i;
asection *section;
unsigned int total_subspaces = 0;
{
int num_spaces = som_count_spaces (abfd);
asymbol **syms = bfd_get_outsymbols (abfd);
- int i, num_syms, strings_size;
+ int i, num_syms;
int subspace_index = 0;
file_ptr location;
asection *section;
unsigned long current_offset;
- unsigned int total_reloc_size;
+ unsigned int strings_size, total_reloc_size;
bfd_size_type amt;
/* We must set up the version identifier here as objcopy/strip copy
&& sym->symbol.name[strlen (sym->symbol.name) - 1] == '$'
&& !strcmp (sym->symbol.name, sym->symbol.section->name))
sym->symbol.flags |= BSF_SECTION_SYM;
- else if (!strncmp (sym->symbol.name, "L$0\002", 4))
+ else if (CONST_STRNEQ (sym->symbol.name, "L$0\002"))
{
sym->symbol.flags |= BSF_SECTION_SYM;
sym->symbol.name = sym->symbol.section->name;
}
- else if (!strncmp (sym->symbol.name, "L$0\001", 4))
+ else if (CONST_STRNEQ (sym->symbol.name, "L$0\001"))
sym->symbol.flags |= BSF_DEBUGGING;
/* Note increment at bottom of loop, since we skip some symbols
static void
som_print_symbol (bfd *abfd,
- void * afile,
+ void *afile,
asymbol *symbol,
bfd_print_symbol_type how)
{
asymbol **symbols,
bfd_boolean just_count)
{
- char *external_relocs;
+ unsigned char *external_relocs;
unsigned int fixup_stream_size;
arelent *internal_relocs;
unsigned int num_relocs;
static bfd_boolean
som_new_section_hook (bfd *abfd, asection *newsect)
{
- bfd_size_type amt = sizeof (struct som_section_data_struct);
-
- newsect->used_by_bfd = bfd_zalloc (abfd, amt);
if (!newsect->used_by_bfd)
- return FALSE;
+ {
+ bfd_size_type amt = sizeof (struct som_section_data_struct);
+
+ newsect->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (!newsect->used_by_bfd)
+ return FALSE;
+ }
newsect->alignment_power = 3;
/* We allow more than three sections internally. */
- return TRUE;
+ return _bfd_generic_new_section_hook (abfd, newsect);
}
/* Copy any private info we understand from the input symbol
fprintf (f, "\n");
fprintf (f, " type %#x\n", auxhdr->type);
fprintf (f, " length %#x\n", auxhdr->length);
- fprintf (f, " text size %#x\n", exec_header->exec_tsize);
- fprintf (f, " text memory offset %#x\n", exec_header->exec_tmem);
- fprintf (f, " text file offset %#x\n", exec_header->exec_tfile);
- fprintf (f, " data size %#x\n", exec_header->exec_dsize);
- fprintf (f, " data memory offset %#x\n", exec_header->exec_dmem);
- fprintf (f, " data file offset %#x\n", exec_header->exec_dfile);
- fprintf (f, " bss size %#x\n", exec_header->exec_bsize);
- fprintf (f, " entry point %#x\n", exec_header->exec_entry);
- fprintf (f, " loader flags %#x\n", exec_header->exec_flags);
- fprintf (f, " bss initializer %#x\n", exec_header->exec_bfill);
+
+ /* Note that, depending on the HP-UX version, the following fields can be
+ either ints, or longs. */
+
+ fprintf (f, " text size %#lx\n", (long) exec_header->exec_tsize);
+ fprintf (f, " text memory offset %#lx\n", (long) exec_header->exec_tmem);
+ fprintf (f, " text file offset %#lx\n", (long) exec_header->exec_tfile);
+ fprintf (f, " data size %#lx\n", (long) exec_header->exec_dsize);
+ fprintf (f, " data memory offset %#lx\n", (long) exec_header->exec_dmem);
+ fprintf (f, " data file offset %#lx\n", (long) exec_header->exec_dfile);
+ fprintf (f, " bss size %#lx\n", (long) exec_header->exec_bsize);
+ fprintf (f, " entry point %#lx\n", (long) exec_header->exec_entry);
+ fprintf (f, " loader flags %#lx\n", (long) exec_header->exec_flags);
+ fprintf (f, " bss initializer %#lx\n", (long) exec_header->exec_bfill);
}
return TRUE;
static bfd_boolean
som_get_section_contents (bfd *abfd,
sec_ptr section,
- void * location,
+ void *location,
file_ptr offset,
bfd_size_type count)
{
static bfd_boolean
som_set_section_contents (bfd *abfd,
sec_ptr section,
- const void * location,
+ const void *location,
file_ptr offset,
bfd_size_type count)
{
static int
som_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
- bfd_boolean reloc ATTRIBUTE_UNUSED)
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
(*_bfd_error_handler) (_("som_sizeof_headers unimplemented"));
fflush (stderr);
if (bfd_is_com_section (symbol->section))
return 'C';
if (bfd_is_und_section (symbol->section))
- return 'U';
+ {
+ if (symbol->flags & BSF_WEAK)
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'v';
+ else
+ return 'w';
+ }
+ else
+ return 'U';
+ }
if (bfd_is_ind_section (symbol->section))
return 'I';
if (symbol->flags & BSF_WEAK)
- return 'W';
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'V';
+ else
+ return 'W';
+ }
if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
return '?';
return FALSE;
/* For archives without .o files there is no symbol table. */
- if (strncmp (nextname, "/ ", 16))
+ if (! CONST_STRNEQ (nextname, "/ "))
{
bfd_has_map (abfd) = FALSE;
return TRUE;
if (curr_bfd->format != bfd_object
|| curr_bfd->xvec->flavour != bfd_target_som_flavour)
{
- curr_bfd = curr_bfd->next;
+ curr_bfd = curr_bfd->archive_next;
continue;
}
(*stringsize)++;
}
- curr_bfd = curr_bfd->next;
+ curr_bfd = curr_bfd->archive_next;
}
return TRUE;
}
if (curr_bfd->format != bfd_object
|| curr_bfd->xvec->flavour != bfd_target_som_flavour)
{
- curr_bfd = curr_bfd->next;
+ curr_bfd = curr_bfd->archive_next;
continue;
}
linker requires objects begin on an even boundary. So round
up the current offset as necessary. */
curr_som_offset = (curr_som_offset + 0x1) &~ (unsigned) 1;
- curr_bfd = curr_bfd->next;
+ curr_bfd = curr_bfd->archive_next;
som_index++;
}
if (curr_bfd->format == bfd_object
&& curr_bfd->xvec->flavour == bfd_target_som_flavour)
lst.module_count++;
- curr_bfd = curr_bfd->next;
+ curr_bfd = curr_bfd->archive_next;
}
lst.module_limit = lst.module_count;
lst.dir_loc = lst_size;
#define som_bfd_is_group_section bfd_generic_is_group_section
#define som_bfd_discard_group bfd_generic_discard_group
#define som_section_already_linked _bfd_generic_section_already_linked
+#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define som_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define som_find_inliner_info _bfd_nosymbols_find_inliner_info
const bfd_target som_vec =
{