/* 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,
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>
+/* This is the code recommended in the autoconf documentation, almost
+ verbatim. */
+
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+/* Indented so that pre-ansi C compilers will ignore it, rather than
+ choke on it. Some versions of AIX require this to be the first
+ thing in the file. */
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+extern char *alloca ();
+# else
+extern void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* _AIX */
+# endif /* HAVE_ALLOCA_H */
+#else
+extern void *alloca (size_t);
+#endif /* __GNUC__ */
+
static bfd_reloc_status_type hppa_som_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_boolean som_mkobject (bfd *);
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. */
&& 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
return -1;
return (asect->reloc_count + 1) * sizeof (arelent *);
}
- /* There are no relocations. */
- return 0;
+
+ /* There are no relocations. Return enough space to hold the
+ NULL pointer which will be installed if som_canonicalize_reloc
+ is called. */
+ return sizeof (arelent *);
}
/* Convert relocations from SOM (external) form into BFD internal
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
}
static bfd_boolean
-som_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED,
- asection *section ATTRIBUTE_UNUSED,
- asymbol **symbols ATTRIBUTE_UNUSED,
- bfd_vma offset ATTRIBUTE_UNUSED,
- const char **filename_ptr ATTRIBUTE_UNUSED,
- const char **functionname_ptr ATTRIBUTE_UNUSED,
- unsigned int *line_ptr ATTRIBUTE_UNUSED)
+som_find_nearest_line (bfd *abfd,
+ asection *section,
+ asymbol **symbols,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
{
- return FALSE;
+ bfd_boolean found;
+ asymbol *func;
+ bfd_vma low_func;
+ asymbol **p;
+
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ & found, filename_ptr,
+ functionname_ptr, line_ptr,
+ & somdata (abfd).line_info))
+ return FALSE;
+
+ if (found)
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ /* Fallback: find function name from symbols table. */
+ func = NULL;
+ low_func = 0;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ som_symbol_type *q = (som_symbol_type *) *p;
+
+ if (q->som_type == SYMBOL_TYPE_ENTRY
+ && q->symbol.section == section
+ && q->symbol.value >= low_func
+ && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ }
+
+ if (func == NULL)
+ return FALSE;
+
+ *filename_ptr = NULL;
+ *functionname_ptr = bfd_asymbol_name (func);
+ *line_ptr = 0;
+
+ return TRUE;
}
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_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 =
{