1 |
/* BFD back-end for HP PA-RISC ELF files. |
/* BFD back-end for HP PA-RISC ELF files. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, |
3 |
2002 Free Software Foundation, Inc. |
2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
4 |
|
|
5 |
Original code by |
Original code by |
6 |
Center for Software Science |
Center for Software Science |
8 |
University of Utah |
University of Utah |
9 |
Largely rewritten by Alan Modra <alan@linuxcare.com.au> |
Largely rewritten by Alan Modra <alan@linuxcare.com.au> |
10 |
|
|
11 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
12 |
|
|
13 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
14 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
15 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
16 |
(at your option) any later version. |
(at your option) any later version. |
17 |
|
|
18 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
19 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 |
GNU General Public License for more details. |
GNU General Public License for more details. |
22 |
|
|
23 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
24 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
25 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
26 |
|
|
27 |
#include "bfd.h" |
#include "bfd.h" |
28 |
#include "sysdep.h" |
#include "sysdep.h" |
111 |
: ldw -24(%sp),%rp ; restore the original rp |
: ldw -24(%sp),%rp ; restore the original rp |
112 |
: ldsid (%rp),%r1 |
: ldsid (%rp),%r1 |
113 |
: mtsp %r1,%sr0 |
: mtsp %r1,%sr0 |
114 |
: be,n 0(%sr0,%rp) ; inter-space return */ |
: be,n 0(%sr0,%rp) ; inter-space return. */ |
115 |
|
|
116 |
#define PLT_ENTRY_SIZE 8 |
#define PLT_ENTRY_SIZE 8 |
117 |
#define GOT_ENTRY_SIZE 4 |
#define GOT_ENTRY_SIZE 4 |
141 |
#define IS_ABSOLUTE_RELOC(r_type) 1 |
#define IS_ABSOLUTE_RELOC(r_type) 1 |
142 |
#endif |
#endif |
143 |
|
|
144 |
|
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid |
145 |
|
copying dynamic variables from a shared lib into an app's dynbss |
146 |
|
section, and instead use a dynamic relocation to point into the |
147 |
|
shared lib. */ |
148 |
|
#define ELIMINATE_COPY_RELOCS 1 |
149 |
|
|
150 |
enum elf32_hppa_stub_type { |
enum elf32_hppa_stub_type { |
151 |
hppa_stub_long_branch, |
hppa_stub_long_branch, |
152 |
hppa_stub_long_branch_shared, |
hppa_stub_long_branch_shared, |
209 |
#endif |
#endif |
210 |
} *dyn_relocs; |
} *dyn_relocs; |
211 |
|
|
|
/* Set if the only reason we need a .plt entry is for a non-PIC to |
|
|
PIC function call. */ |
|
|
unsigned int pic_call:1; |
|
|
|
|
212 |
/* Set if this symbol is used by a plabel reloc. */ |
/* Set if this symbol is used by a plabel reloc. */ |
213 |
unsigned int plabel:1; |
unsigned int plabel:1; |
214 |
}; |
}; |
225 |
bfd *stub_bfd; |
bfd *stub_bfd; |
226 |
|
|
227 |
/* Linker call-backs. */ |
/* Linker call-backs. */ |
228 |
asection * (*add_stub_section) PARAMS ((const char *, asection *)); |
asection * (*add_stub_section) (const char *, asection *); |
229 |
void (*layout_sections_again) PARAMS ((void)); |
void (*layout_sections_again) (void); |
230 |
|
|
231 |
/* Array to keep track of which stub sections have been created, and |
/* Array to keep track of which stub sections have been created, and |
232 |
information on stub grouping. */ |
information on stub grouping. */ |
281 |
((struct elf32_hppa_stub_hash_entry *) \ |
((struct elf32_hppa_stub_hash_entry *) \ |
282 |
bfd_hash_lookup ((table), (string), (create), (copy))) |
bfd_hash_lookup ((table), (string), (create), (copy))) |
283 |
|
|
|
static struct bfd_hash_entry *stub_hash_newfunc |
|
|
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
|
|
|
|
|
static struct bfd_hash_entry *hppa_link_hash_newfunc |
|
|
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
|
|
|
|
|
static struct bfd_link_hash_table *elf32_hppa_link_hash_table_create |
|
|
PARAMS ((bfd *)); |
|
|
|
|
|
static void elf32_hppa_link_hash_table_free |
|
|
PARAMS ((struct bfd_link_hash_table *)); |
|
|
|
|
|
/* Stub handling functions. */ |
|
|
static char *hppa_stub_name |
|
|
PARAMS ((const asection *, const asection *, |
|
|
const struct elf32_hppa_link_hash_entry *, |
|
|
const Elf_Internal_Rela *)); |
|
|
|
|
|
static struct elf32_hppa_stub_hash_entry *hppa_get_stub_entry |
|
|
PARAMS ((const asection *, const asection *, |
|
|
struct elf32_hppa_link_hash_entry *, |
|
|
const Elf_Internal_Rela *, |
|
|
struct elf32_hppa_link_hash_table *)); |
|
|
|
|
|
static struct elf32_hppa_stub_hash_entry *hppa_add_stub |
|
|
PARAMS ((const char *, asection *, struct elf32_hppa_link_hash_table *)); |
|
|
|
|
|
static enum elf32_hppa_stub_type hppa_type_of_stub |
|
|
PARAMS ((asection *, const Elf_Internal_Rela *, |
|
|
struct elf32_hppa_link_hash_entry *, bfd_vma)); |
|
|
|
|
|
static boolean hppa_build_one_stub |
|
|
PARAMS ((struct bfd_hash_entry *, PTR)); |
|
|
|
|
|
static boolean hppa_size_one_stub |
|
|
PARAMS ((struct bfd_hash_entry *, PTR)); |
|
|
|
|
|
/* BFD and elf backend functions. */ |
|
|
static boolean elf32_hppa_object_p PARAMS ((bfd *)); |
|
|
|
|
|
static boolean elf32_hppa_add_symbol_hook |
|
|
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, |
|
|
const char **, flagword *, asection **, bfd_vma *)); |
|
|
|
|
|
static boolean elf32_hppa_create_dynamic_sections |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static void elf32_hppa_copy_indirect_symbol |
|
|
PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *)); |
|
|
|
|
|
static boolean elf32_hppa_check_relocs |
|
|
PARAMS ((bfd *, struct bfd_link_info *, |
|
|
asection *, const Elf_Internal_Rela *)); |
|
|
|
|
|
static asection *elf32_hppa_gc_mark_hook |
|
|
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
|
|
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
|
|
|
|
|
static boolean elf32_hppa_gc_sweep_hook |
|
|
PARAMS ((bfd *, struct bfd_link_info *, |
|
|
asection *, const Elf_Internal_Rela *)); |
|
|
|
|
|
static void elf32_hppa_hide_symbol |
|
|
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean)); |
|
|
|
|
|
static boolean elf32_hppa_adjust_dynamic_symbol |
|
|
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); |
|
|
|
|
|
static boolean mark_PIC_calls |
|
|
PARAMS ((struct elf_link_hash_entry *, PTR)); |
|
|
|
|
|
static boolean allocate_plt_static |
|
|
PARAMS ((struct elf_link_hash_entry *, PTR)); |
|
|
|
|
|
static boolean allocate_dynrelocs |
|
|
PARAMS ((struct elf_link_hash_entry *, PTR)); |
|
|
|
|
|
static boolean readonly_dynrelocs |
|
|
PARAMS ((struct elf_link_hash_entry *, PTR)); |
|
|
|
|
|
static boolean clobber_millicode_symbols |
|
|
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *)); |
|
|
|
|
|
static boolean elf32_hppa_size_dynamic_sections |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static void group_sections |
|
|
PARAMS ((struct elf32_hppa_link_hash_table *, bfd_size_type, boolean)); |
|
|
|
|
|
static int get_local_syms |
|
|
PARAMS ((bfd *, bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static boolean elf32_hppa_final_link |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static void hppa_record_segment_addr |
|
|
PARAMS ((bfd *, asection *, PTR)); |
|
|
|
|
|
static bfd_reloc_status_type final_link_relocate |
|
|
PARAMS ((asection *, bfd_byte *, const Elf_Internal_Rela *, |
|
|
bfd_vma, struct elf32_hppa_link_hash_table *, asection *, |
|
|
struct elf32_hppa_link_hash_entry *)); |
|
|
|
|
|
static boolean elf32_hppa_relocate_section |
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, |
|
|
bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
|
|
|
|
|
static boolean elf32_hppa_finish_dynamic_symbol |
|
|
PARAMS ((bfd *, struct bfd_link_info *, |
|
|
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
|
|
|
|
|
static enum elf_reloc_type_class elf32_hppa_reloc_type_class |
|
|
PARAMS ((const Elf_Internal_Rela *)); |
|
|
|
|
|
static boolean elf32_hppa_finish_dynamic_sections |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static void elf32_hppa_post_process_headers |
|
|
PARAMS ((bfd *, struct bfd_link_info *)); |
|
|
|
|
|
static int elf32_hppa_elf_get_symbol_type |
|
|
PARAMS ((Elf_Internal_Sym *, int)); |
|
|
|
|
284 |
/* Assorted hash table functions. */ |
/* Assorted hash table functions. */ |
285 |
|
|
286 |
/* Initialize an entry in the stub hash table. */ |
/* Initialize an entry in the stub hash table. */ |
287 |
|
|
288 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
289 |
stub_hash_newfunc (entry, table, string) |
stub_hash_newfunc (struct bfd_hash_entry *entry, |
290 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, |
291 |
struct bfd_hash_table *table; |
const char *string) |
|
const char *string; |
|
292 |
{ |
{ |
293 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
294 |
subclass. */ |
subclass. */ |
323 |
/* Initialize an entry in the link hash table. */ |
/* Initialize an entry in the link hash table. */ |
324 |
|
|
325 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
326 |
hppa_link_hash_newfunc (entry, table, string) |
hppa_link_hash_newfunc (struct bfd_hash_entry *entry, |
327 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, |
328 |
struct bfd_hash_table *table; |
const char *string) |
|
const char *string; |
|
329 |
{ |
{ |
330 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
331 |
subclass. */ |
subclass. */ |
347 |
eh = (struct elf32_hppa_link_hash_entry *) entry; |
eh = (struct elf32_hppa_link_hash_entry *) entry; |
348 |
eh->stub_cache = NULL; |
eh->stub_cache = NULL; |
349 |
eh->dyn_relocs = NULL; |
eh->dyn_relocs = NULL; |
|
eh->pic_call = 0; |
|
350 |
eh->plabel = 0; |
eh->plabel = 0; |
351 |
} |
} |
352 |
|
|
358 |
using static variables). */ |
using static variables). */ |
359 |
|
|
360 |
static struct bfd_link_hash_table * |
static struct bfd_link_hash_table * |
361 |
elf32_hppa_link_hash_table_create (abfd) |
elf32_hppa_link_hash_table_create (bfd *abfd) |
|
bfd *abfd; |
|
362 |
{ |
{ |
363 |
struct elf32_hppa_link_hash_table *ret; |
struct elf32_hppa_link_hash_table *ret; |
364 |
bfd_size_type amt = sizeof (*ret); |
bfd_size_type amt = sizeof (*ret); |
365 |
|
|
366 |
ret = (struct elf32_hppa_link_hash_table *) bfd_malloc (amt); |
ret = bfd_malloc (amt); |
367 |
if (ret == NULL) |
if (ret == NULL) |
368 |
return NULL; |
return NULL; |
369 |
|
|
402 |
/* Free the derived linker hash table. */ |
/* Free the derived linker hash table. */ |
403 |
|
|
404 |
static void |
static void |
405 |
elf32_hppa_link_hash_table_free (hash) |
elf32_hppa_link_hash_table_free (struct bfd_link_hash_table *hash) |
|
struct bfd_link_hash_table *hash; |
|
406 |
{ |
{ |
407 |
struct elf32_hppa_link_hash_table *ret |
struct elf32_hppa_link_hash_table *ret |
408 |
= (struct elf32_hppa_link_hash_table *) hash; |
= (struct elf32_hppa_link_hash_table *) hash; |
414 |
/* Build a name for an entry in the stub hash table. */ |
/* Build a name for an entry in the stub hash table. */ |
415 |
|
|
416 |
static char * |
static char * |
417 |
hppa_stub_name (input_section, sym_sec, hash, rel) |
hppa_stub_name (const asection *input_section, |
418 |
const asection *input_section; |
const asection *sym_sec, |
419 |
const asection *sym_sec; |
const struct elf32_hppa_link_hash_entry *hash, |
420 |
const struct elf32_hppa_link_hash_entry *hash; |
const Elf_Internal_Rela *rel) |
|
const Elf_Internal_Rela *rel; |
|
421 |
{ |
{ |
422 |
char *stub_name; |
char *stub_name; |
423 |
bfd_size_type len; |
bfd_size_type len; |
454 |
creating the stub name takes a bit of time. */ |
creating the stub name takes a bit of time. */ |
455 |
|
|
456 |
static struct elf32_hppa_stub_hash_entry * |
static struct elf32_hppa_stub_hash_entry * |
457 |
hppa_get_stub_entry (input_section, sym_sec, hash, rel, htab) |
hppa_get_stub_entry (const asection *input_section, |
458 |
const asection *input_section; |
const asection *sym_sec, |
459 |
const asection *sym_sec; |
struct elf32_hppa_link_hash_entry *hash, |
460 |
struct elf32_hppa_link_hash_entry *hash; |
const Elf_Internal_Rela *rel, |
461 |
const Elf_Internal_Rela *rel; |
struct elf32_hppa_link_hash_table *htab) |
|
struct elf32_hppa_link_hash_table *htab; |
|
462 |
{ |
{ |
463 |
struct elf32_hppa_stub_hash_entry *stub_entry; |
struct elf32_hppa_stub_hash_entry *stub_entry; |
464 |
const asection *id_sec; |
const asection *id_sec; |
485 |
return NULL; |
return NULL; |
486 |
|
|
487 |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
488 |
stub_name, false, false); |
stub_name, FALSE, FALSE); |
489 |
if (hash != NULL) |
if (hash != NULL) |
490 |
hash->stub_cache = stub_entry; |
hash->stub_cache = stub_entry; |
491 |
|
|
499 |
stub entry are initialised. */ |
stub entry are initialised. */ |
500 |
|
|
501 |
static struct elf32_hppa_stub_hash_entry * |
static struct elf32_hppa_stub_hash_entry * |
502 |
hppa_add_stub (stub_name, section, htab) |
hppa_add_stub (const char *stub_name, |
503 |
const char *stub_name; |
asection *section, |
504 |
asection *section; |
struct elf32_hppa_link_hash_table *htab) |
|
struct elf32_hppa_link_hash_table *htab; |
|
505 |
{ |
{ |
506 |
asection *link_sec; |
asection *link_sec; |
507 |
asection *stub_sec; |
asection *stub_sec; |
536 |
|
|
537 |
/* Enter this entry into the linker stub hash table. */ |
/* Enter this entry into the linker stub hash table. */ |
538 |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, stub_name, |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, stub_name, |
539 |
true, false); |
TRUE, FALSE); |
540 |
if (stub_entry == NULL) |
if (stub_entry == NULL) |
541 |
{ |
{ |
542 |
(*_bfd_error_handler) (_("%s: cannot create stub entry %s"), |
(*_bfd_error_handler) (_("%B: cannot create stub entry %s"), |
543 |
bfd_archive_filename (section->owner), |
section->owner, |
544 |
stub_name); |
stub_name); |
545 |
return NULL; |
return NULL; |
546 |
} |
} |
554 |
/* Determine the type of stub needed, if any, for a call. */ |
/* Determine the type of stub needed, if any, for a call. */ |
555 |
|
|
556 |
static enum elf32_hppa_stub_type |
static enum elf32_hppa_stub_type |
557 |
hppa_type_of_stub (input_sec, rel, hash, destination) |
hppa_type_of_stub (asection *input_sec, |
558 |
asection *input_sec; |
const Elf_Internal_Rela *rel, |
559 |
const Elf_Internal_Rela *rel; |
struct elf32_hppa_link_hash_entry *hash, |
560 |
struct elf32_hppa_link_hash_entry *hash; |
bfd_vma destination, |
561 |
bfd_vma destination; |
struct bfd_link_info *info) |
562 |
{ |
{ |
563 |
bfd_vma location; |
bfd_vma location; |
564 |
bfd_vma branch_offset; |
bfd_vma branch_offset; |
567 |
|
|
568 |
if (hash != NULL |
if (hash != NULL |
569 |
&& hash->elf.plt.offset != (bfd_vma) -1 |
&& hash->elf.plt.offset != (bfd_vma) -1 |
570 |
&& (hash->elf.dynindx != -1 || hash->pic_call) |
&& hash->elf.dynindx != -1 |
571 |
&& !hash->plabel) |
&& !hash->plabel |
572 |
|
&& (info->shared |
573 |
|
|| !hash->elf.def_regular |
574 |
|
|| hash->elf.root.type == bfd_link_hash_defweak)) |
575 |
{ |
{ |
576 |
/* We need an import stub. Decide between hppa_stub_import |
/* We need an import stub. Decide between hppa_stub_import |
577 |
and hppa_stub_import_shared later. */ |
and hppa_stub_import_shared later. */ |
649 |
#define LDW_R1_DLT LDW_R1_DP |
#define LDW_R1_DLT LDW_R1_DP |
650 |
#endif |
#endif |
651 |
|
|
652 |
static boolean |
static bfd_boolean |
653 |
hppa_build_one_stub (gen_entry, in_arg) |
hppa_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) |
|
struct bfd_hash_entry *gen_entry; |
|
|
PTR in_arg; |
|
654 |
{ |
{ |
655 |
struct elf32_hppa_stub_hash_entry *stub_entry; |
struct elf32_hppa_stub_hash_entry *stub_entry; |
656 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
666 |
|
|
667 |
/* Massage our args to the form they really have. */ |
/* Massage our args to the form they really have. */ |
668 |
stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry; |
stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry; |
669 |
info = (struct bfd_link_info *) in_arg; |
info = in_arg; |
670 |
|
|
671 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
672 |
stub_sec = stub_entry->stub_sec; |
stub_sec = stub_entry->stub_sec; |
673 |
|
|
674 |
/* Make a note of the offset within the stubs for this entry. */ |
/* Make a note of the offset within the stubs for this entry. */ |
675 |
stub_entry->stub_offset = stub_sec->_raw_size; |
stub_entry->stub_offset = stub_sec->size; |
676 |
loc = stub_sec->contents + stub_entry->stub_offset; |
loc = stub_sec->contents + stub_entry->stub_offset; |
677 |
|
|
678 |
stub_bfd = stub_sec->owner; |
stub_bfd = stub_sec->owner; |
688 |
+ stub_entry->target_section->output_offset |
+ stub_entry->target_section->output_offset |
689 |
+ stub_entry->target_section->output_section->vma); |
+ stub_entry->target_section->output_section->vma); |
690 |
|
|
691 |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_lrsel); |
val = hppa_field_adjust (sym_value, 0, e_lrsel); |
692 |
insn = hppa_rebuild_insn ((int) LDIL_R1, val, 21); |
insn = hppa_rebuild_insn ((int) LDIL_R1, val, 21); |
693 |
bfd_put_32 (stub_bfd, insn, loc); |
bfd_put_32 (stub_bfd, insn, loc); |
694 |
|
|
695 |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_rrsel) >> 2; |
val = hppa_field_adjust (sym_value, 0, e_rrsel) >> 2; |
696 |
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17); |
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17); |
697 |
bfd_put_32 (stub_bfd, insn, loc + 4); |
bfd_put_32 (stub_bfd, insn, loc + 4); |
698 |
|
|
738 |
if (stub_entry->stub_type == hppa_stub_import_shared) |
if (stub_entry->stub_type == hppa_stub_import_shared) |
739 |
insn = ADDIL_R19; |
insn = ADDIL_R19; |
740 |
#endif |
#endif |
741 |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_lrsel), |
val = hppa_field_adjust (sym_value, 0, e_lrsel), |
742 |
insn = hppa_rebuild_insn ((int) insn, val, 21); |
insn = hppa_rebuild_insn ((int) insn, val, 21); |
743 |
bfd_put_32 (stub_bfd, insn, loc); |
bfd_put_32 (stub_bfd, insn, loc); |
744 |
|
|
747 |
lsel/rsel then with unfortunate sym_values we will round |
lsel/rsel then with unfortunate sym_values we will round |
748 |
sym_value+4 up to the next 2k block leading to a mis-match |
sym_value+4 up to the next 2k block leading to a mis-match |
749 |
between the lsel and rsel value. */ |
between the lsel and rsel value. */ |
750 |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_rrsel); |
val = hppa_field_adjust (sym_value, 0, e_rrsel); |
751 |
insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14); |
insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14); |
752 |
bfd_put_32 (stub_bfd, insn, loc + 4); |
bfd_put_32 (stub_bfd, insn, loc + 4); |
753 |
|
|
774 |
size = 16; |
size = 16; |
775 |
} |
} |
776 |
|
|
|
if (!info->shared |
|
|
&& stub_entry->h != NULL |
|
|
&& stub_entry->h->pic_call) |
|
|
{ |
|
|
/* Build the .plt entry needed to call a PIC function from |
|
|
statically linked code. We don't need any relocs. */ |
|
|
bfd *dynobj; |
|
|
struct elf32_hppa_link_hash_entry *eh; |
|
|
bfd_vma value; |
|
|
|
|
|
dynobj = htab->elf.dynobj; |
|
|
eh = (struct elf32_hppa_link_hash_entry *) stub_entry->h; |
|
|
|
|
|
if (eh->elf.root.type != bfd_link_hash_defined |
|
|
&& eh->elf.root.type != bfd_link_hash_defweak) |
|
|
abort (); |
|
|
|
|
|
value = (eh->elf.root.u.def.value |
|
|
+ eh->elf.root.u.def.section->output_offset |
|
|
+ eh->elf.root.u.def.section->output_section->vma); |
|
|
|
|
|
/* Fill in the entry in the procedure linkage table. |
|
|
|
|
|
The format of a plt entry is |
|
|
<funcaddr> |
|
|
<__gp>. */ |
|
|
|
|
|
bfd_put_32 (htab->splt->owner, value, |
|
|
htab->splt->contents + off); |
|
|
value = elf_gp (htab->splt->output_section->owner); |
|
|
bfd_put_32 (htab->splt->owner, value, |
|
|
htab->splt->contents + off + 4); |
|
|
} |
|
777 |
break; |
break; |
778 |
|
|
779 |
case hppa_stub_export: |
case hppa_stub_export: |
792 |
|| sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2)))) |
|| sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2)))) |
793 |
{ |
{ |
794 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
795 |
(_("%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"), |
(_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"), |
796 |
bfd_archive_filename (stub_entry->target_section->owner), |
stub_entry->target_section->owner, |
797 |
stub_sec->name, |
stub_sec, |
798 |
(long) stub_entry->stub_offset, |
(long) stub_entry->stub_offset, |
799 |
stub_entry->root.string); |
stub_entry->root.string); |
800 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
801 |
return false; |
return FALSE; |
802 |
} |
} |
803 |
|
|
804 |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2; |
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2; |
816 |
|
|
817 |
/* Point the function symbol at the stub. */ |
/* Point the function symbol at the stub. */ |
818 |
stub_entry->h->elf.root.u.def.section = stub_sec; |
stub_entry->h->elf.root.u.def.section = stub_sec; |
819 |
stub_entry->h->elf.root.u.def.value = stub_sec->_raw_size; |
stub_entry->h->elf.root.u.def.value = stub_sec->size; |
820 |
|
|
821 |
size = 24; |
size = 24; |
822 |
break; |
break; |
823 |
|
|
824 |
default: |
default: |
825 |
BFD_FAIL (); |
BFD_FAIL (); |
826 |
return false; |
return FALSE; |
827 |
} |
} |
828 |
|
|
829 |
stub_sec->_raw_size += size; |
stub_sec->size += size; |
830 |
return true; |
return TRUE; |
831 |
} |
} |
832 |
|
|
833 |
#undef LDIL_R1 |
#undef LDIL_R1 |
835 |
#undef BL_R1 |
#undef BL_R1 |
836 |
#undef ADDIL_R1 |
#undef ADDIL_R1 |
837 |
#undef DEPI_R1 |
#undef DEPI_R1 |
|
#undef ADDIL_DP |
|
838 |
#undef LDW_R1_R21 |
#undef LDW_R1_R21 |
839 |
#undef LDW_R1_DLT |
#undef LDW_R1_DLT |
840 |
#undef LDW_R1_R19 |
#undef LDW_R1_R19 |
854 |
/* As above, but don't actually build the stub. Just bump offset so |
/* As above, but don't actually build the stub. Just bump offset so |
855 |
we know stub section sizes. */ |
we know stub section sizes. */ |
856 |
|
|
857 |
static boolean |
static bfd_boolean |
858 |
hppa_size_one_stub (gen_entry, in_arg) |
hppa_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) |
|
struct bfd_hash_entry *gen_entry; |
|
|
PTR in_arg; |
|
859 |
{ |
{ |
860 |
struct elf32_hppa_stub_hash_entry *stub_entry; |
struct elf32_hppa_stub_hash_entry *stub_entry; |
861 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
863 |
|
|
864 |
/* Massage our args to the form they really have. */ |
/* Massage our args to the form they really have. */ |
865 |
stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry; |
stub_entry = (struct elf32_hppa_stub_hash_entry *) gen_entry; |
866 |
htab = (struct elf32_hppa_link_hash_table *) in_arg; |
htab = in_arg; |
867 |
|
|
868 |
if (stub_entry->stub_type == hppa_stub_long_branch) |
if (stub_entry->stub_type == hppa_stub_long_branch) |
869 |
size = 8; |
size = 8; |
879 |
size = 16; |
size = 16; |
880 |
} |
} |
881 |
|
|
882 |
stub_entry->stub_sec->_raw_size += size; |
stub_entry->stub_sec->size += size; |
883 |
return true; |
return TRUE; |
884 |
} |
} |
885 |
|
|
886 |
/* Return nonzero if ABFD represents an HPPA ELF32 file. |
/* Return nonzero if ABFD represents an HPPA ELF32 file. |
887 |
Additionally we set the default architecture and machine. */ |
Additionally we set the default architecture and machine. */ |
888 |
|
|
889 |
static boolean |
static bfd_boolean |
890 |
elf32_hppa_object_p (abfd) |
elf32_hppa_object_p (bfd *abfd) |
|
bfd *abfd; |
|
891 |
{ |
{ |
892 |
Elf_Internal_Ehdr * i_ehdrp; |
Elf_Internal_Ehdr * i_ehdrp; |
893 |
unsigned int flags; |
unsigned int flags; |
895 |
i_ehdrp = elf_elfheader (abfd); |
i_ehdrp = elf_elfheader (abfd); |
896 |
if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0) |
if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0) |
897 |
{ |
{ |
898 |
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX) |
/* GCC on hppa-linux produces binaries with OSABI=Linux, |
899 |
return false; |
but the kernel produces corefiles with OSABI=SysV. */ |
900 |
|
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX && |
901 |
|
i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ |
902 |
|
return FALSE; |
903 |
|
} |
904 |
|
else if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0) |
905 |
|
{ |
906 |
|
/* GCC on hppa-netbsd produces binaries with OSABI=NetBSD, |
907 |
|
but the kernel produces corefiles with OSABI=SysV. */ |
908 |
|
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NETBSD && |
909 |
|
i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ |
910 |
|
return FALSE; |
911 |
} |
} |
912 |
else |
else |
913 |
{ |
{ |
914 |
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX) |
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX) |
915 |
return false; |
return FALSE; |
916 |
} |
} |
917 |
|
|
918 |
flags = i_ehdrp->e_flags; |
flags = i_ehdrp->e_flags; |
927 |
case EFA_PARISC_2_0 | EF_PARISC_WIDE: |
case EFA_PARISC_2_0 | EF_PARISC_WIDE: |
928 |
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25); |
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25); |
929 |
} |
} |
930 |
return true; |
return TRUE; |
|
} |
|
|
|
|
|
/* Undo the generic ELF code's subtraction of section->vma from the |
|
|
value of each external symbol. */ |
|
|
|
|
|
static boolean |
|
|
elf32_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) |
|
|
bfd *abfd ATTRIBUTE_UNUSED; |
|
|
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
|
|
const Elf_Internal_Sym *sym ATTRIBUTE_UNUSED; |
|
|
const char **namep ATTRIBUTE_UNUSED; |
|
|
flagword *flagsp ATTRIBUTE_UNUSED; |
|
|
asection **secp; |
|
|
bfd_vma *valp; |
|
|
{ |
|
|
*valp += (*secp)->vma; |
|
|
return true; |
|
931 |
} |
} |
932 |
|
|
933 |
/* Create the .plt and .got sections, and set up our hash table |
/* Create the .plt and .got sections, and set up our hash table |
934 |
short-cuts to various dynamic sections. */ |
short-cuts to various dynamic sections. */ |
935 |
|
|
936 |
static boolean |
static bfd_boolean |
937 |
elf32_hppa_create_dynamic_sections (abfd, info) |
elf32_hppa_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
938 |
{ |
{ |
939 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
940 |
|
struct elf_link_hash_entry *h; |
941 |
|
|
942 |
/* Don't try to create the .plt and .got twice. */ |
/* Don't try to create the .plt and .got twice. */ |
943 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
944 |
if (htab->splt != NULL) |
if (htab->splt != NULL) |
945 |
return true; |
return TRUE; |
946 |
|
|
947 |
/* Call the generic code to do most of the work. */ |
/* Call the generic code to do most of the work. */ |
948 |
if (! _bfd_elf_create_dynamic_sections (abfd, info)) |
if (! _bfd_elf_create_dynamic_sections (abfd, info)) |
949 |
return false; |
return FALSE; |
950 |
|
|
951 |
htab->splt = bfd_get_section_by_name (abfd, ".plt"); |
htab->splt = bfd_get_section_by_name (abfd, ".plt"); |
952 |
htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt"); |
htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt"); |
962 |
| SEC_LINKER_CREATED |
| SEC_LINKER_CREATED |
963 |
| SEC_READONLY)) |
| SEC_READONLY)) |
964 |
|| ! bfd_set_section_alignment (abfd, htab->srelgot, 2)) |
|| ! bfd_set_section_alignment (abfd, htab->srelgot, 2)) |
965 |
return false; |
return FALSE; |
966 |
|
|
967 |
htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss"); |
htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss"); |
968 |
htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss"); |
htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss"); |
969 |
|
|
970 |
return true; |
/* hppa-linux needs _GLOBAL_OFFSET_TABLE_ to be visible from the main |
971 |
|
application, because __canonicalize_funcptr_for_compare needs it. */ |
972 |
|
h = elf_hash_table (info)->hgot; |
973 |
|
h->forced_local = 0; |
974 |
|
h->other = STV_DEFAULT; |
975 |
|
return bfd_elf_link_record_dynamic_symbol (info, h); |
976 |
} |
} |
977 |
|
|
978 |
/* Copy the extra info we tack onto an elf_link_hash_entry. */ |
/* Copy the extra info we tack onto an elf_link_hash_entry. */ |
979 |
|
|
980 |
static void |
static void |
981 |
elf32_hppa_copy_indirect_symbol (dir, ind) |
elf32_hppa_copy_indirect_symbol (const struct elf_backend_data *bed, |
982 |
struct elf_link_hash_entry *dir, *ind; |
struct elf_link_hash_entry *dir, |
983 |
|
struct elf_link_hash_entry *ind) |
984 |
{ |
{ |
985 |
struct elf32_hppa_link_hash_entry *edir, *eind; |
struct elf32_hppa_link_hash_entry *edir, *eind; |
986 |
|
|
1023 |
eind->dyn_relocs = NULL; |
eind->dyn_relocs = NULL; |
1024 |
} |
} |
1025 |
|
|
1026 |
_bfd_elf_link_hash_copy_indirect (dir, ind); |
if (ELIMINATE_COPY_RELOCS |
1027 |
|
&& ind->root.type != bfd_link_hash_indirect |
1028 |
|
&& dir->dynamic_adjusted) |
1029 |
|
{ |
1030 |
|
/* If called to transfer flags for a weakdef during processing |
1031 |
|
of elf_adjust_dynamic_symbol, don't copy non_got_ref. |
1032 |
|
We clear it ourselves for ELIMINATE_COPY_RELOCS. */ |
1033 |
|
dir->ref_dynamic |= ind->ref_dynamic; |
1034 |
|
dir->ref_regular |= ind->ref_regular; |
1035 |
|
dir->ref_regular_nonweak |= ind->ref_regular_nonweak; |
1036 |
|
dir->needs_plt |= ind->needs_plt; |
1037 |
|
} |
1038 |
|
else |
1039 |
|
_bfd_elf_link_hash_copy_indirect (bed, dir, ind); |
1040 |
} |
} |
1041 |
|
|
1042 |
/* Look through the relocs for a section during the first phase, and |
/* Look through the relocs for a section during the first phase, and |
1044 |
table, and dynamic reloc sections. At this point we haven't |
table, and dynamic reloc sections. At this point we haven't |
1045 |
necessarily read all the input files. */ |
necessarily read all the input files. */ |
1046 |
|
|
1047 |
static boolean |
static bfd_boolean |
1048 |
elf32_hppa_check_relocs (abfd, info, sec, relocs) |
elf32_hppa_check_relocs (bfd *abfd, |
1049 |
bfd *abfd; |
struct bfd_link_info *info, |
1050 |
struct bfd_link_info *info; |
asection *sec, |
1051 |
asection *sec; |
const Elf_Internal_Rela *relocs) |
|
const Elf_Internal_Rela *relocs; |
|
1052 |
{ |
{ |
1053 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
1054 |
struct elf_link_hash_entry **sym_hashes; |
struct elf_link_hash_entry **sym_hashes; |
1058 |
asection *sreloc; |
asection *sreloc; |
1059 |
asection *stubreloc; |
asection *stubreloc; |
1060 |
|
|
1061 |
if (info->relocateable) |
if (info->relocatable) |
1062 |
return true; |
return TRUE; |
1063 |
|
|
1064 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
1065 |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
1098 |
case R_PARISC_DLTIND21L: |
case R_PARISC_DLTIND21L: |
1099 |
/* This symbol requires a global offset table entry. */ |
/* This symbol requires a global offset table entry. */ |
1100 |
need_entry = NEED_GOT; |
need_entry = NEED_GOT; |
|
|
|
|
/* Mark this section as containing PIC code. */ |
|
|
sec->flags |= SEC_HAS_GOT_REF; |
|
1101 |
break; |
break; |
1102 |
|
|
1103 |
case R_PARISC_PLABEL14R: /* "Official" procedure labels. */ |
case R_PARISC_PLABEL14R: /* "Official" procedure labels. */ |
1162 |
} |
} |
1163 |
break; |
break; |
1164 |
|
|
1165 |
case R_PARISC_SEGBASE: /* Used to set segment base. */ |
case R_PARISC_SEGBASE: /* Used to set segment base. */ |
1166 |
case R_PARISC_SEGREL32: /* Relative reloc, used for unwind. */ |
case R_PARISC_SEGREL32: /* Relative reloc, used for unwind. */ |
1167 |
case R_PARISC_PCREL14F: /* PC relative load/store. */ |
case R_PARISC_PCREL14F: /* PC relative load/store. */ |
1168 |
case R_PARISC_PCREL14R: |
case R_PARISC_PCREL14R: |
1169 |
case R_PARISC_PCREL17R: /* External branches. */ |
case R_PARISC_PCREL17R: /* External branches. */ |
1170 |
case R_PARISC_PCREL21L: /* As above, and for load/store too. */ |
case R_PARISC_PCREL21L: /* As above, and for load/store too. */ |
1171 |
|
case R_PARISC_PCREL32: |
1172 |
/* We don't need to propagate the relocation if linking a |
/* We don't need to propagate the relocation if linking a |
1173 |
shared object since these are section relative. */ |
shared object since these are section relative. */ |
1174 |
continue; |
continue; |
1179 |
if (info->shared) |
if (info->shared) |
1180 |
{ |
{ |
1181 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1182 |
(_("%s: relocation %s can not be used when making a shared object; recompile with -fPIC"), |
(_("%B: relocation %s can not be used when making a shared object; recompile with -fPIC"), |
1183 |
bfd_archive_filename (abfd), |
abfd, |
1184 |
elf_hppa_howto_table[r_type].name); |
elf_hppa_howto_table[r_type].name); |
1185 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1186 |
return false; |
return FALSE; |
1187 |
} |
} |
1188 |
/* Fall through. */ |
/* Fall through. */ |
1189 |
|
|
1192 |
case R_PARISC_DIR14F: /* Used for load/store from absolute locn. */ |
case R_PARISC_DIR14F: /* Used for load/store from absolute locn. */ |
1193 |
case R_PARISC_DIR14R: |
case R_PARISC_DIR14R: |
1194 |
case R_PARISC_DIR21L: /* As above, and for ext branches too. */ |
case R_PARISC_DIR21L: /* As above, and for ext branches too. */ |
|
#if 0 |
|
|
/* Help debug shared library creation. Any of the above |
|
|
relocs can be used in shared libs, but they may cause |
|
|
pages to become unshared. */ |
|
|
if (info->shared) |
|
|
{ |
|
|
(*_bfd_error_handler) |
|
|
(_("%s: relocation %s should not be used when making a shared object; recompile with -fPIC"), |
|
|
bfd_archive_filename (abfd), |
|
|
elf_hppa_howto_table[r_type].name); |
|
|
} |
|
|
/* Fall through. */ |
|
|
#endif |
|
|
|
|
1195 |
case R_PARISC_DIR32: /* .word relocs. */ |
case R_PARISC_DIR32: /* .word relocs. */ |
1196 |
/* We may want to output a dynamic relocation later. */ |
/* We may want to output a dynamic relocation later. */ |
1197 |
need_entry = NEED_DYNREL; |
need_entry = NEED_DYNREL; |
1200 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
1201 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
1202 |
case R_PARISC_GNU_VTINHERIT: |
case R_PARISC_GNU_VTINHERIT: |
1203 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, &h->elf, rel->r_offset)) |
1204 |
&h->elf, rel->r_offset)) |
return FALSE; |
|
return false; |
|
1205 |
continue; |
continue; |
1206 |
|
|
1207 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
1208 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
1209 |
case R_PARISC_GNU_VTENTRY: |
case R_PARISC_GNU_VTENTRY: |
1210 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, |
if (!bfd_elf_gc_record_vtentry (abfd, sec, &h->elf, rel->r_addend)) |
1211 |
&h->elf, rel->r_addend)) |
return FALSE; |
|
return false; |
|
1212 |
continue; |
continue; |
1213 |
|
|
1214 |
default: |
default: |
1225 |
if (htab->elf.dynobj == NULL) |
if (htab->elf.dynobj == NULL) |
1226 |
htab->elf.dynobj = abfd; |
htab->elf.dynobj = abfd; |
1227 |
if (!elf32_hppa_create_dynamic_sections (htab->elf.dynobj, info)) |
if (!elf32_hppa_create_dynamic_sections (htab->elf.dynobj, info)) |
1228 |
return false; |
return FALSE; |
1229 |
} |
} |
1230 |
|
|
1231 |
if (h != NULL) |
if (h != NULL) |
1248 |
pointer. */ |
pointer. */ |
1249 |
size = symtab_hdr->sh_info; |
size = symtab_hdr->sh_info; |
1250 |
size *= 2 * sizeof (bfd_signed_vma); |
size *= 2 * sizeof (bfd_signed_vma); |
1251 |
local_got_refcounts = ((bfd_signed_vma *) |
local_got_refcounts = bfd_zalloc (abfd, size); |
|
bfd_zalloc (abfd, size)); |
|
1252 |
if (local_got_refcounts == NULL) |
if (local_got_refcounts == NULL) |
1253 |
return false; |
return FALSE; |
1254 |
elf_local_got_refcounts (abfd) = local_got_refcounts; |
elf_local_got_refcounts (abfd) = local_got_refcounts; |
1255 |
} |
} |
1256 |
local_got_refcounts[r_symndx] += 1; |
local_got_refcounts[r_symndx] += 1; |
1271 |
{ |
{ |
1272 |
if (h != NULL) |
if (h != NULL) |
1273 |
{ |
{ |
1274 |
h->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; |
h->elf.needs_plt = 1; |
1275 |
h->elf.plt.refcount += 1; |
h->elf.plt.refcount += 1; |
1276 |
|
|
1277 |
/* If this .plt entry is for a plabel, mark it so |
/* If this .plt entry is for a plabel, mark it so |
1294 |
plt offsets. */ |
plt offsets. */ |
1295 |
size = symtab_hdr->sh_info; |
size = symtab_hdr->sh_info; |
1296 |
size *= 2 * sizeof (bfd_signed_vma); |
size *= 2 * sizeof (bfd_signed_vma); |
1297 |
local_got_refcounts = ((bfd_signed_vma *) |
local_got_refcounts = bfd_zalloc (abfd, size); |
|
bfd_zalloc (abfd, size)); |
|
1298 |
if (local_got_refcounts == NULL) |
if (local_got_refcounts == NULL) |
1299 |
return false; |
return FALSE; |
1300 |
elf_local_got_refcounts (abfd) = local_got_refcounts; |
elf_local_got_refcounts (abfd) = local_got_refcounts; |
1301 |
} |
} |
1302 |
local_plt_refcounts = (local_got_refcounts |
local_plt_refcounts = (local_got_refcounts |
1312 |
so that we generate copy relocs if it turns out to be |
so that we generate copy relocs if it turns out to be |
1313 |
dynamic. */ |
dynamic. */ |
1314 |
if (h != NULL && !info->shared) |
if (h != NULL && !info->shared) |
1315 |
h->elf.elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; |
h->elf.non_got_ref = 1; |
1316 |
|
|
1317 |
/* If we are creating a shared library then we need to copy |
/* If we are creating a shared library then we need to copy |
1318 |
the reloc into the shared library. However, if we are |
the reloc into the shared library. However, if we are |
1348 |
|| (h != NULL |
|| (h != NULL |
1349 |
&& (!info->symbolic |
&& (!info->symbolic |
1350 |
|| h->elf.root.type == bfd_link_hash_defweak |
|| h->elf.root.type == bfd_link_hash_defweak |
1351 |
|| (h->elf.elf_link_hash_flags |
|| !h->elf.def_regular)))) |
1352 |
& ELF_LINK_HASH_DEF_REGULAR) == 0)))) |
|| (ELIMINATE_COPY_RELOCS |
1353 |
|| (!info->shared |
&& !info->shared |
1354 |
&& (sec->flags & SEC_ALLOC) != 0 |
&& (sec->flags & SEC_ALLOC) != 0 |
1355 |
&& h != NULL |
&& h != NULL |
1356 |
&& (h->elf.root.type == bfd_link_hash_defweak |
&& (h->elf.root.type == bfd_link_hash_defweak |
1357 |
|| (h->elf.elf_link_hash_flags |
|| !h->elf.def_regular))) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))) |
|
1358 |
{ |
{ |
1359 |
struct elf32_hppa_dyn_reloc_entry *p; |
struct elf32_hppa_dyn_reloc_entry *p; |
1360 |
struct elf32_hppa_dyn_reloc_entry **head; |
struct elf32_hppa_dyn_reloc_entry **head; |
1376 |
(_("Could not find relocation section for %s"), |
(_("Could not find relocation section for %s"), |
1377 |
sec->name); |
sec->name); |
1378 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1379 |
return false; |
return FALSE; |
1380 |
} |
} |
1381 |
|
|
1382 |
if (htab->elf.dynobj == NULL) |
if (htab->elf.dynobj == NULL) |
1396 |
if (sreloc == NULL |
if (sreloc == NULL |
1397 |
|| !bfd_set_section_flags (dynobj, sreloc, flags) |
|| !bfd_set_section_flags (dynobj, sreloc, flags) |
1398 |
|| !bfd_set_section_alignment (dynobj, sreloc, 2)) |
|| !bfd_set_section_alignment (dynobj, sreloc, 2)) |
1399 |
return false; |
return FALSE; |
1400 |
} |
} |
1401 |
|
|
1402 |
elf_section_data (sec)->sreloc = sreloc; |
elf_section_data (sec)->sreloc = sreloc; |
1418 |
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, |
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, |
1419 |
sec, r_symndx); |
sec, r_symndx); |
1420 |
if (s == NULL) |
if (s == NULL) |
1421 |
return false; |
return FALSE; |
1422 |
|
|
1423 |
head = ((struct elf32_hppa_dyn_reloc_entry **) |
head = ((struct elf32_hppa_dyn_reloc_entry **) |
1424 |
&elf_section_data (s)->local_dynrel); |
&elf_section_data (s)->local_dynrel); |
1427 |
p = *head; |
p = *head; |
1428 |
if (p == NULL || p->sec != sec) |
if (p == NULL || p->sec != sec) |
1429 |
{ |
{ |
1430 |
p = ((struct elf32_hppa_dyn_reloc_entry *) |
p = bfd_alloc (htab->elf.dynobj, sizeof *p); |
|
bfd_alloc (htab->elf.dynobj, |
|
|
(bfd_size_type) sizeof *p)); |
|
1431 |
if (p == NULL) |
if (p == NULL) |
1432 |
return false; |
return FALSE; |
1433 |
p->next = *head; |
p->next = *head; |
1434 |
*head = p; |
*head = p; |
1435 |
p->sec = sec; |
p->sec = sec; |
1448 |
} |
} |
1449 |
} |
} |
1450 |
|
|
1451 |
return true; |
return TRUE; |
1452 |
} |
} |
1453 |
|
|
1454 |
/* Return the section that should be marked against garbage collection |
/* Return the section that should be marked against garbage collection |
1455 |
for a given relocation. */ |
for a given relocation. */ |
1456 |
|
|
1457 |
static asection * |
static asection * |
1458 |
elf32_hppa_gc_mark_hook (sec, info, rel, h, sym) |
elf32_hppa_gc_mark_hook (asection *sec, |
1459 |
asection *sec; |
struct bfd_link_info *info ATTRIBUTE_UNUSED, |
1460 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
Elf_Internal_Rela *rel, |
1461 |
Elf_Internal_Rela *rel; |
struct elf_link_hash_entry *h, |
1462 |
struct elf_link_hash_entry *h; |
Elf_Internal_Sym *sym) |
|
Elf_Internal_Sym *sym; |
|
1463 |
{ |
{ |
1464 |
if (h != NULL) |
if (h != NULL) |
1465 |
{ |
{ |
1493 |
/* Update the got and plt entry reference counts for the section being |
/* Update the got and plt entry reference counts for the section being |
1494 |
removed. */ |
removed. */ |
1495 |
|
|
1496 |
static boolean |
static bfd_boolean |
1497 |
elf32_hppa_gc_sweep_hook (abfd, info, sec, relocs) |
elf32_hppa_gc_sweep_hook (bfd *abfd, |
1498 |
bfd *abfd; |
struct bfd_link_info *info ATTRIBUTE_UNUSED, |
1499 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
asection *sec, |
1500 |
asection *sec; |
const Elf_Internal_Rela *relocs) |
|
const Elf_Internal_Rela *relocs; |
|
1501 |
{ |
{ |
1502 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
1503 |
struct elf_link_hash_entry **sym_hashes; |
struct elf_link_hash_entry **sym_hashes; |
1504 |
bfd_signed_vma *local_got_refcounts; |
bfd_signed_vma *local_got_refcounts; |
1505 |
bfd_signed_vma *local_plt_refcounts; |
bfd_signed_vma *local_plt_refcounts; |
1506 |
const Elf_Internal_Rela *rel, *relend; |
const Elf_Internal_Rela *rel, *relend; |
|
unsigned long r_symndx; |
|
|
struct elf_link_hash_entry *h; |
|
|
struct elf32_hppa_link_hash_table *htab; |
|
|
bfd *dynobj; |
|
1507 |
|
|
1508 |
elf_section_data (sec)->local_dynrel = NULL; |
elf_section_data (sec)->local_dynrel = NULL; |
1509 |
|
|
1513 |
local_plt_refcounts = local_got_refcounts; |
local_plt_refcounts = local_got_refcounts; |
1514 |
if (local_plt_refcounts != NULL) |
if (local_plt_refcounts != NULL) |
1515 |
local_plt_refcounts += symtab_hdr->sh_info; |
local_plt_refcounts += symtab_hdr->sh_info; |
|
htab = hppa_link_hash_table (info); |
|
|
dynobj = htab->elf.dynobj; |
|
|
if (dynobj == NULL) |
|
|
return true; |
|
1516 |
|
|
1517 |
relend = relocs + sec->reloc_count; |
relend = relocs + sec->reloc_count; |
1518 |
for (rel = relocs; rel < relend; rel++) |
for (rel = relocs; rel < relend; rel++) |
1519 |
switch ((unsigned int) ELF32_R_TYPE (rel->r_info)) |
{ |
1520 |
{ |
unsigned long r_symndx; |
1521 |
case R_PARISC_DLTIND14F: |
unsigned int r_type; |
1522 |
case R_PARISC_DLTIND14R: |
struct elf_link_hash_entry *h = NULL; |
|
case R_PARISC_DLTIND21L: |
|
|
r_symndx = ELF32_R_SYM (rel->r_info); |
|
|
if (r_symndx >= symtab_hdr->sh_info) |
|
|
{ |
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
|
if (h->got.refcount > 0) |
|
|
h->got.refcount -= 1; |
|
|
} |
|
|
else if (local_got_refcounts != NULL) |
|
|
{ |
|
|
if (local_got_refcounts[r_symndx] > 0) |
|
|
local_got_refcounts[r_symndx] -= 1; |
|
|
} |
|
|
break; |
|
1523 |
|
|
1524 |
case R_PARISC_PCREL12F: |
r_symndx = ELF32_R_SYM (rel->r_info); |
1525 |
case R_PARISC_PCREL17C: |
if (r_symndx >= symtab_hdr->sh_info) |
1526 |
case R_PARISC_PCREL17F: |
{ |
1527 |
case R_PARISC_PCREL22F: |
struct elf32_hppa_link_hash_entry *eh; |
1528 |
r_symndx = ELF32_R_SYM (rel->r_info); |
struct elf32_hppa_dyn_reloc_entry **pp; |
1529 |
if (r_symndx >= symtab_hdr->sh_info) |
struct elf32_hppa_dyn_reloc_entry *p; |
|
{ |
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
|
if (h->plt.refcount > 0) |
|
|
h->plt.refcount -= 1; |
|
|
} |
|
|
break; |
|
1530 |
|
|
1531 |
case R_PARISC_PLABEL14R: |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
1532 |
case R_PARISC_PLABEL21L: |
while (h->root.type == bfd_link_hash_indirect |
1533 |
case R_PARISC_PLABEL32: |
|| h->root.type == bfd_link_hash_warning) |
1534 |
r_symndx = ELF32_R_SYM (rel->r_info); |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1535 |
if (r_symndx >= symtab_hdr->sh_info) |
eh = (struct elf32_hppa_link_hash_entry *) h; |
|
{ |
|
|
struct elf32_hppa_link_hash_entry *eh; |
|
|
struct elf32_hppa_dyn_reloc_entry **pp; |
|
|
struct elf32_hppa_dyn_reloc_entry *p; |
|
1536 |
|
|
1537 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
1538 |
|
if (p->sec == sec) |
1539 |
|
{ |
1540 |
|
/* Everything must go for SEC. */ |
1541 |
|
*pp = p->next; |
1542 |
|
break; |
1543 |
|
} |
1544 |
|
} |
1545 |
|
|
1546 |
if (h->plt.refcount > 0) |
r_type = ELF32_R_TYPE (rel->r_info); |
1547 |
h->plt.refcount -= 1; |
switch (r_type) |
1548 |
|
{ |
1549 |
|
case R_PARISC_DLTIND14F: |
1550 |
|
case R_PARISC_DLTIND14R: |
1551 |
|
case R_PARISC_DLTIND21L: |
1552 |
|
if (h != NULL) |
1553 |
|
{ |
1554 |
|
if (h->got.refcount > 0) |
1555 |
|
h->got.refcount -= 1; |
1556 |
|
} |
1557 |
|
else if (local_got_refcounts != NULL) |
1558 |
|
{ |
1559 |
|
if (local_got_refcounts[r_symndx] > 0) |
1560 |
|
local_got_refcounts[r_symndx] -= 1; |
1561 |
|
} |
1562 |
|
break; |
1563 |
|
|
1564 |
eh = (struct elf32_hppa_link_hash_entry *) h; |
case R_PARISC_PCREL12F: |
1565 |
|
case R_PARISC_PCREL17C: |
1566 |
|
case R_PARISC_PCREL17F: |
1567 |
|
case R_PARISC_PCREL22F: |
1568 |
|
if (h != NULL) |
1569 |
|
{ |
1570 |
|
if (h->plt.refcount > 0) |
1571 |
|
h->plt.refcount -= 1; |
1572 |
|
} |
1573 |
|
break; |
1574 |
|
|
1575 |
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
case R_PARISC_PLABEL14R: |
1576 |
if (p->sec == sec) |
case R_PARISC_PLABEL21L: |
1577 |
{ |
case R_PARISC_PLABEL32: |
1578 |
#if RELATIVE_DYNRELOCS |
if (h != NULL) |
1579 |
if (!IS_ABSOLUTE_RELOC (rtype)) |
{ |
1580 |
p->relative_count -= 1; |
if (h->plt.refcount > 0) |
1581 |
#endif |
h->plt.refcount -= 1; |
1582 |
p->count -= 1; |
} |
1583 |
if (p->count == 0) |
else if (local_plt_refcounts != NULL) |
1584 |
*pp = p->next; |
{ |
1585 |
break; |
if (local_plt_refcounts[r_symndx] > 0) |
1586 |
} |
local_plt_refcounts[r_symndx] -= 1; |
1587 |
} |
} |
1588 |
else if (local_plt_refcounts != NULL) |
break; |
|
{ |
|
|
if (local_plt_refcounts[r_symndx] > 0) |
|
|
local_plt_refcounts[r_symndx] -= 1; |
|
|
} |
|
|
break; |
|
1589 |
|
|
1590 |
case R_PARISC_DIR32: |
default: |
1591 |
r_symndx = ELF32_R_SYM (rel->r_info); |
break; |
1592 |
if (r_symndx >= symtab_hdr->sh_info) |
} |
1593 |
{ |
} |
|
struct elf32_hppa_link_hash_entry *eh; |
|
|
struct elf32_hppa_dyn_reloc_entry **pp; |
|
|
struct elf32_hppa_dyn_reloc_entry *p; |
|
1594 |
|
|
1595 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
return TRUE; |
1596 |
|
} |
1597 |
|
|
1598 |
eh = (struct elf32_hppa_link_hash_entry *) h; |
/* Support for core dump NOTE sections. */ |
1599 |
|
|
1600 |
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
static bfd_boolean |
1601 |
if (p->sec == sec) |
elf32_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
1602 |
{ |
{ |
1603 |
#if RELATIVE_DYNRELOCS |
int offset; |
1604 |
if (!IS_ABSOLUTE_RELOC (R_PARISC_DIR32)) |
size_t size; |
|
p->relative_count -= 1; |
|
|
#endif |
|
|
p->count -= 1; |
|
|
if (p->count == 0) |
|
|
*pp = p->next; |
|
|
break; |
|
|
} |
|
|
} |
|
|
break; |
|
1605 |
|
|
1606 |
|
switch (note->descsz) |
1607 |
|
{ |
1608 |
default: |
default: |
1609 |
|
return FALSE; |
1610 |
|
|
1611 |
|
case 396: /* Linux/hppa */ |
1612 |
|
/* pr_cursig */ |
1613 |
|
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); |
1614 |
|
|
1615 |
|
/* pr_pid */ |
1616 |
|
elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24); |
1617 |
|
|
1618 |
|
/* pr_reg */ |
1619 |
|
offset = 72; |
1620 |
|
size = 320; |
1621 |
|
|
1622 |
break; |
break; |
1623 |
} |
} |
1624 |
|
|
1625 |
return true; |
/* Make a ".reg/999" section. */ |
1626 |
|
return _bfd_elfcore_make_pseudosection (abfd, ".reg", |
1627 |
|
size, note->descpos + offset); |
1628 |
|
} |
1629 |
|
|
1630 |
|
static bfd_boolean |
1631 |
|
elf32_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) |
1632 |
|
{ |
1633 |
|
switch (note->descsz) |
1634 |
|
{ |
1635 |
|
default: |
1636 |
|
return FALSE; |
1637 |
|
|
1638 |
|
case 124: /* Linux/hppa elf_prpsinfo. */ |
1639 |
|
elf_tdata (abfd)->core_program |
1640 |
|
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); |
1641 |
|
elf_tdata (abfd)->core_command |
1642 |
|
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); |
1643 |
|
} |
1644 |
|
|
1645 |
|
/* Note that for some reason, a spurious space is tacked |
1646 |
|
onto the end of the args in some (at least one anyway) |
1647 |
|
implementations, so strip it off if it exists. */ |
1648 |
|
{ |
1649 |
|
char *command = elf_tdata (abfd)->core_command; |
1650 |
|
int n = strlen (command); |
1651 |
|
|
1652 |
|
if (0 < n && command[n - 1] == ' ') |
1653 |
|
command[n - 1] = '\0'; |
1654 |
|
} |
1655 |
|
|
1656 |
|
return TRUE; |
1657 |
} |
} |
1658 |
|
|
1659 |
/* Our own version of hide_symbol, so that we can keep plt entries for |
/* Our own version of hide_symbol, so that we can keep plt entries for |
1660 |
plabels. */ |
plabels. */ |
1661 |
|
|
1662 |
static void |
static void |
1663 |
elf32_hppa_hide_symbol (info, h, force_local) |
elf32_hppa_hide_symbol (struct bfd_link_info *info, |
1664 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *h, |
1665 |
struct elf_link_hash_entry *h; |
bfd_boolean force_local) |
|
boolean force_local; |
|
1666 |
{ |
{ |
1667 |
if (force_local) |
if (force_local) |
1668 |
{ |
{ |
1669 |
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL; |
h->forced_local = 1; |
1670 |
if (h->dynindx != -1) |
if (h->dynindx != -1) |
1671 |
{ |
{ |
1672 |
h->dynindx = -1; |
h->dynindx = -1; |
1677 |
|
|
1678 |
if (! ((struct elf32_hppa_link_hash_entry *) h)->plabel) |
if (! ((struct elf32_hppa_link_hash_entry *) h)->plabel) |
1679 |
{ |
{ |
1680 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1681 |
h->plt.offset = (bfd_vma) -1; |
h->plt = elf_hash_table (info)->init_refcount; |
1682 |
} |
} |
1683 |
} |
} |
1684 |
|
|
|
/* This is the condition under which elf32_hppa_finish_dynamic_symbol |
|
|
will be called from elflink.h. If elflink.h doesn't call our |
|
|
finish_dynamic_symbol routine, we'll need to do something about |
|
|
initializing any .plt and .got entries in elf32_hppa_relocate_section. */ |
|
|
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ |
|
|
((DYN) \ |
|
|
&& ((INFO)->shared \ |
|
|
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ |
|
|
&& ((H)->dynindx != -1 \ |
|
|
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) |
|
|
|
|
1685 |
/* Adjust a symbol defined by a dynamic object and referenced by a |
/* Adjust a symbol defined by a dynamic object and referenced by a |
1686 |
regular object. The current definition is in some section of the |
regular object. The current definition is in some section of the |
1687 |
dynamic object, but we're not including those sections. We have to |
dynamic object, but we're not including those sections. We have to |
1688 |
change the definition to something the rest of the link can |
change the definition to something the rest of the link can |
1689 |
understand. */ |
understand. */ |
1690 |
|
|
1691 |
static boolean |
static bfd_boolean |
1692 |
elf32_hppa_adjust_dynamic_symbol (info, h) |
elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, |
1693 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *h) |
|
struct elf_link_hash_entry *h; |
|
1694 |
{ |
{ |
1695 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
|
struct elf32_hppa_link_hash_entry *eh; |
|
|
struct elf32_hppa_dyn_reloc_entry *p; |
|
1696 |
asection *s; |
asection *s; |
1697 |
unsigned int power_of_two; |
unsigned int power_of_two; |
1698 |
|
|
1699 |
/* If this is a function, put it in the procedure linkage table. We |
/* If this is a function, put it in the procedure linkage table. We |
1700 |
will fill in the contents of the procedure linkage table later. */ |
will fill in the contents of the procedure linkage table later. */ |
1701 |
if (h->type == STT_FUNC |
if (h->type == STT_FUNC |
1702 |
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) |
|| h->needs_plt) |
1703 |
{ |
{ |
1704 |
if (h->plt.refcount <= 0 |
if (h->plt.refcount <= 0 |
1705 |
|| ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 |
|| (h->def_regular |
1706 |
&& h->root.type != bfd_link_hash_defweak |
&& h->root.type != bfd_link_hash_defweak |
1707 |
&& ! ((struct elf32_hppa_link_hash_entry *) h)->plabel |
&& ! ((struct elf32_hppa_link_hash_entry *) h)->plabel |
1708 |
&& (!info->shared || info->symbolic))) |
&& (!info->shared || info->symbolic))) |
1715 |
used by a plabel relocation. Either this object is the |
used by a plabel relocation. Either this object is the |
1716 |
application or we are doing a shared symbolic link. */ |
application or we are doing a shared symbolic link. */ |
1717 |
|
|
1718 |
/* As a special sop to the hppa ABI, we keep a .plt entry |
h->plt.offset = (bfd_vma) -1; |
1719 |
for functions in sections containing PIC code. */ |
h->needs_plt = 0; |
|
if (!info->shared |
|
|
&& h->plt.refcount > 0 |
|
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 |
|
|
&& (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0) |
|
|
((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1; |
|
|
else |
|
|
{ |
|
|
h->plt.offset = (bfd_vma) -1; |
|
|
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
|
|
} |
|
1720 |
} |
} |
1721 |
|
|
1722 |
return true; |
return TRUE; |
1723 |
} |
} |
1724 |
else |
else |
1725 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1727 |
/* If this is a weak symbol, and there is a real definition, the |
/* If this is a weak symbol, and there is a real definition, the |
1728 |
processor independent code will have arranged for us to see the |
processor independent code will have arranged for us to see the |
1729 |
real definition first, and we can just use the same value. */ |
real definition first, and we can just use the same value. */ |
1730 |
if (h->weakdef != NULL) |
if (h->u.weakdef != NULL) |
1731 |
{ |
{ |
1732 |
if (h->weakdef->root.type != bfd_link_hash_defined |
if (h->u.weakdef->root.type != bfd_link_hash_defined |
1733 |
&& h->weakdef->root.type != bfd_link_hash_defweak) |
&& h->u.weakdef->root.type != bfd_link_hash_defweak) |
1734 |
abort (); |
abort (); |
1735 |
h->root.u.def.section = h->weakdef->root.u.def.section; |
h->root.u.def.section = h->u.weakdef->root.u.def.section; |
1736 |
h->root.u.def.value = h->weakdef->root.u.def.value; |
h->root.u.def.value = h->u.weakdef->root.u.def.value; |
1737 |
return true; |
if (ELIMINATE_COPY_RELOCS) |
1738 |
|
h->non_got_ref = h->u.weakdef->non_got_ref; |
1739 |
|
return TRUE; |
1740 |
} |
} |
1741 |
|
|
1742 |
/* This is a reference to a symbol defined by a dynamic object which |
/* This is a reference to a symbol defined by a dynamic object which |
1747 |
For such cases we need not do anything here; the relocations will |
For such cases we need not do anything here; the relocations will |
1748 |
be handled correctly by relocate_section. */ |
be handled correctly by relocate_section. */ |
1749 |
if (info->shared) |
if (info->shared) |
1750 |
return true; |
return TRUE; |
1751 |
|
|
1752 |
/* If there are no references to this symbol that do not use the |
/* If there are no references to this symbol that do not use the |
1753 |
GOT, we don't need to generate a copy reloc. */ |
GOT, we don't need to generate a copy reloc. */ |
1754 |
if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) |
if (!h->non_got_ref) |
1755 |
return true; |
return TRUE; |
1756 |
|
|
1757 |
eh = (struct elf32_hppa_link_hash_entry *) h; |
if (ELIMINATE_COPY_RELOCS) |
|
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
|
1758 |
{ |
{ |
1759 |
s = p->sec->output_section; |
struct elf32_hppa_link_hash_entry *eh; |
1760 |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
struct elf32_hppa_dyn_reloc_entry *p; |
|
break; |
|
|
} |
|
1761 |
|
|
1762 |
/* If we didn't find any dynamic relocs in read-only sections, then |
eh = (struct elf32_hppa_link_hash_entry *) h; |
1763 |
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
1764 |
if (p == NULL) |
{ |
1765 |
{ |
s = p->sec->output_section; |
1766 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
1767 |
return true; |
break; |
1768 |
|
} |
1769 |
|
|
1770 |
|
/* If we didn't find any dynamic relocs in read-only sections, then |
1771 |
|
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ |
1772 |
|
if (p == NULL) |
1773 |
|
{ |
1774 |
|
h->non_got_ref = 0; |
1775 |
|
return TRUE; |
1776 |
|
} |
1777 |
} |
} |
1778 |
|
|
1779 |
/* We must allocate the symbol in our .dynbss section, which will |
/* We must allocate the symbol in our .dynbss section, which will |
1793 |
runtime process image. */ |
runtime process image. */ |
1794 |
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) |
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) |
1795 |
{ |
{ |
1796 |
htab->srelbss->_raw_size += sizeof (Elf32_External_Rela); |
htab->srelbss->size += sizeof (Elf32_External_Rela); |
1797 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; |
h->needs_copy = 1; |
1798 |
} |
} |
1799 |
|
|
1800 |
/* We need to figure out the alignment required for this symbol. I |
/* We need to figure out the alignment required for this symbol. I |
1806 |
|
|
1807 |
/* Apply the required alignment. */ |
/* Apply the required alignment. */ |
1808 |
s = htab->sdynbss; |
s = htab->sdynbss; |
1809 |
s->_raw_size = BFD_ALIGN (s->_raw_size, |
s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); |
|
(bfd_size_type) (1 << power_of_two)); |
|
1810 |
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) |
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) |
1811 |
{ |
{ |
1812 |
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) |
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) |
1813 |
return false; |
return FALSE; |
1814 |
} |
} |
1815 |
|
|
1816 |
/* Define the symbol as being at this point in the section. */ |
/* Define the symbol as being at this point in the section. */ |
1817 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
1818 |
h->root.u.def.value = s->_raw_size; |
h->root.u.def.value = s->size; |
1819 |
|
|
1820 |
/* Increment the section size to make room for the symbol. */ |
/* Increment the section size to make room for the symbol. */ |
1821 |
s->_raw_size += h->size; |
s->size += h->size; |
1822 |
|
|
1823 |
return true; |
return TRUE; |
|
} |
|
|
|
|
|
/* Called via elf_link_hash_traverse to create .plt entries for an |
|
|
application that uses statically linked PIC functions. Similar to |
|
|
the first part of elf32_hppa_adjust_dynamic_symbol. */ |
|
|
|
|
|
static boolean |
|
|
mark_PIC_calls (h, inf) |
|
|
struct elf_link_hash_entry *h; |
|
|
PTR inf ATTRIBUTE_UNUSED; |
|
|
{ |
|
|
if (h->root.type == bfd_link_hash_warning) |
|
|
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
|
|
|
|
|
if (! (h->plt.refcount > 0 |
|
|
&& (h->root.type == bfd_link_hash_defined |
|
|
|| h->root.type == bfd_link_hash_defweak) |
|
|
&& (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)) |
|
|
{ |
|
|
h->plt.offset = (bfd_vma) -1; |
|
|
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
|
|
return true; |
|
|
} |
|
|
|
|
|
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; |
|
|
((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1; |
|
|
|
|
|
return true; |
|
1824 |
} |
} |
1825 |
|
|
1826 |
/* Allocate space in the .plt for entries that won't have relocations. |
/* Allocate space in the .plt for entries that won't have relocations. |
1827 |
ie. pic_call and plabel entries. */ |
ie. plabel entries. */ |
1828 |
|
|
1829 |
static boolean |
static bfd_boolean |
1830 |
allocate_plt_static (h, inf) |
allocate_plt_static (struct elf_link_hash_entry *h, void *inf) |
|
struct elf_link_hash_entry *h; |
|
|
PTR inf; |
|
1831 |
{ |
{ |
1832 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1833 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
1834 |
asection *s; |
asection *s; |
1835 |
|
|
1836 |
if (h->root.type == bfd_link_hash_indirect) |
if (h->root.type == bfd_link_hash_indirect) |
1837 |
return true; |
return TRUE; |
1838 |
|
|
1839 |
if (h->root.type == bfd_link_hash_warning) |
if (h->root.type == bfd_link_hash_warning) |
1840 |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1841 |
|
|
1842 |
info = (struct bfd_link_info *) inf; |
info = inf; |
1843 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
1844 |
if (((struct elf32_hppa_link_hash_entry *) h)->pic_call) |
if (htab->elf.dynamic_sections_created |
1845 |
{ |
&& h->plt.refcount > 0) |
|
/* Make an entry in the .plt section for non-pic code that is |
|
|
calling pic code. */ |
|
|
((struct elf32_hppa_link_hash_entry *) h)->plabel = 0; |
|
|
s = htab->splt; |
|
|
h->plt.offset = s->_raw_size; |
|
|
s->_raw_size += PLT_ENTRY_SIZE; |
|
|
} |
|
|
else if (htab->elf.dynamic_sections_created |
|
|
&& h->plt.refcount > 0) |
|
1846 |
{ |
{ |
1847 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1848 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1849 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1850 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 |
&& !h->forced_local |
1851 |
&& h->type != STT_PARISC_MILLI) |
&& h->type != STT_PARISC_MILLI) |
1852 |
{ |
{ |
1853 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1854 |
return false; |
return FALSE; |
1855 |
} |
} |
1856 |
|
|
1857 |
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) |
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) |
1858 |
{ |
{ |
1859 |
/* Allocate these later. From this point on, h->plabel |
/* Allocate these later. From this point on, h->plabel |
1860 |
means that the plt entry is only used by a plabel. |
means that the plt entry is only used by a plabel. |
1867 |
/* Make an entry in the .plt section for plabel references |
/* Make an entry in the .plt section for plabel references |
1868 |
that won't have a .plt entry for other reasons. */ |
that won't have a .plt entry for other reasons. */ |
1869 |
s = htab->splt; |
s = htab->splt; |
1870 |
h->plt.offset = s->_raw_size; |
h->plt.offset = s->size; |
1871 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
1872 |
} |
} |
1873 |
else |
else |
1874 |
{ |
{ |
1875 |
/* No .plt entry needed. */ |
/* No .plt entry needed. */ |
1876 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1877 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1878 |
} |
} |
1879 |
} |
} |
1880 |
else |
else |
1881 |
{ |
{ |
1882 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1883 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1884 |
} |
} |
1885 |
|
|
1886 |
return true; |
return TRUE; |
1887 |
} |
} |
1888 |
|
|
1889 |
/* Allocate space in .plt, .got and associated reloc sections for |
/* Allocate space in .plt, .got and associated reloc sections for |
1890 |
global syms. */ |
global syms. */ |
1891 |
|
|
1892 |
static boolean |
static bfd_boolean |
1893 |
allocate_dynrelocs (h, inf) |
allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) |
|
struct elf_link_hash_entry *h; |
|
|
PTR inf; |
|
1894 |
{ |
{ |
1895 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1896 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
1899 |
struct elf32_hppa_dyn_reloc_entry *p; |
struct elf32_hppa_dyn_reloc_entry *p; |
1900 |
|
|
1901 |
if (h->root.type == bfd_link_hash_indirect) |
if (h->root.type == bfd_link_hash_indirect) |
1902 |
return true; |
return TRUE; |
1903 |
|
|
1904 |
if (h->root.type == bfd_link_hash_warning) |
if (h->root.type == bfd_link_hash_warning) |
1905 |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1906 |
|
|
1907 |
info = (struct bfd_link_info *) inf; |
info = inf; |
1908 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
1909 |
if (htab->elf.dynamic_sections_created |
if (htab->elf.dynamic_sections_created |
1910 |
&& h->plt.offset != (bfd_vma) -1 |
&& h->plt.offset != (bfd_vma) -1 |
|
&& !((struct elf32_hppa_link_hash_entry *) h)->pic_call |
|
1911 |
&& !((struct elf32_hppa_link_hash_entry *) h)->plabel) |
&& !((struct elf32_hppa_link_hash_entry *) h)->plabel) |
1912 |
{ |
{ |
1913 |
/* Make an entry in the .plt section. */ |
/* Make an entry in the .plt section. */ |
1914 |
s = htab->splt; |
s = htab->splt; |
1915 |
h->plt.offset = s->_raw_size; |
h->plt.offset = s->size; |
1916 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
1917 |
|
|
1918 |
/* We also need to make an entry in the .rela.plt section. */ |
/* We also need to make an entry in the .rela.plt section. */ |
1919 |
htab->srelplt->_raw_size += sizeof (Elf32_External_Rela); |
htab->srelplt->size += sizeof (Elf32_External_Rela); |
1920 |
htab->need_plt_stub = 1; |
htab->need_plt_stub = 1; |
1921 |
} |
} |
1922 |
|
|
1925 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1926 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1927 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1928 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 |
&& !h->forced_local |
1929 |
&& h->type != STT_PARISC_MILLI) |
&& h->type != STT_PARISC_MILLI) |
1930 |
{ |
{ |
1931 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1932 |
return false; |
return FALSE; |
1933 |
} |
} |
1934 |
|
|
1935 |
s = htab->sgot; |
s = htab->sgot; |
1936 |
h->got.offset = s->_raw_size; |
h->got.offset = s->size; |
1937 |
s->_raw_size += GOT_ENTRY_SIZE; |
s->size += GOT_ENTRY_SIZE; |
1938 |
if (htab->elf.dynamic_sections_created |
if (htab->elf.dynamic_sections_created |
1939 |
&& (info->shared |
&& (info->shared |
1940 |
|| (h->dynindx != -1 |
|| (h->dynindx != -1 |
1941 |
&& h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)) |
&& !h->forced_local))) |
1942 |
{ |
{ |
1943 |
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); |
htab->srelgot->size += sizeof (Elf32_External_Rela); |
1944 |
} |
} |
1945 |
} |
} |
1946 |
else |
else |
1948 |
|
|
1949 |
eh = (struct elf32_hppa_link_hash_entry *) h; |
eh = (struct elf32_hppa_link_hash_entry *) h; |
1950 |
if (eh->dyn_relocs == NULL) |
if (eh->dyn_relocs == NULL) |
1951 |
return true; |
return TRUE; |
1952 |
|
|
1953 |
/* If this is a -Bsymbolic shared link, then we need to discard all |
/* If this is a -Bsymbolic shared link, then we need to discard all |
1954 |
space allocated for dynamic pc-relative relocs against symbols |
space allocated for dynamic pc-relative relocs against symbols |
1958 |
if (info->shared) |
if (info->shared) |
1959 |
{ |
{ |
1960 |
#if RELATIVE_DYNRELOCS |
#if RELATIVE_DYNRELOCS |
1961 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 |
if (SYMBOL_CALLS_LOCAL (info, h)) |
|
&& ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 |
|
|
|| info->symbolic)) |
|
1962 |
{ |
{ |
1963 |
struct elf32_hppa_dyn_reloc_entry **pp; |
struct elf32_hppa_dyn_reloc_entry **pp; |
1964 |
|
|
1973 |
} |
} |
1974 |
} |
} |
1975 |
#endif |
#endif |
1976 |
|
|
1977 |
|
/* Also discard relocs on undefined weak syms with non-default |
1978 |
|
visibility. */ |
1979 |
|
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
1980 |
|
&& h->root.type == bfd_link_hash_undefweak) |
1981 |
|
eh->dyn_relocs = NULL; |
1982 |
} |
} |
1983 |
else |
else |
1984 |
{ |
{ |
1985 |
/* For the non-shared case, discard space for relocs against |
/* For the non-shared case, discard space for relocs against |
1986 |
symbols which turn out to need copy relocs or are not |
symbols which turn out to need copy relocs or are not |
1987 |
dynamic. */ |
dynamic. */ |
1988 |
if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 |
if (!h->non_got_ref |
1989 |
&& (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& ((ELIMINATE_COPY_RELOCS |
1990 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
&& h->def_dynamic |
1991 |
|
&& !h->def_regular) |
1992 |
|| (htab->elf.dynamic_sections_created |
|| (htab->elf.dynamic_sections_created |
1993 |
&& (h->root.type == bfd_link_hash_undefweak |
&& (h->root.type == bfd_link_hash_undefweak |
1994 |
|| h->root.type == bfd_link_hash_undefined)))) |
|| h->root.type == bfd_link_hash_undefined)))) |
1996 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1997 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1998 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1999 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 |
&& !h->forced_local |
2000 |
&& h->type != STT_PARISC_MILLI) |
&& h->type != STT_PARISC_MILLI) |
2001 |
{ |
{ |
2002 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
2003 |
return false; |
return FALSE; |
2004 |
} |
} |
2005 |
|
|
2006 |
/* If that succeeded, we know we'll be keeping all the |
/* If that succeeded, we know we'll be keeping all the |
2010 |
} |
} |
2011 |
|
|
2012 |
eh->dyn_relocs = NULL; |
eh->dyn_relocs = NULL; |
2013 |
return true; |
return TRUE; |
2014 |
|
|
2015 |
keep: ; |
keep: ; |
2016 |
} |
} |
2019 |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
2020 |
{ |
{ |
2021 |
asection *sreloc = elf_section_data (p->sec)->sreloc; |
asection *sreloc = elf_section_data (p->sec)->sreloc; |
2022 |
sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela); |
sreloc->size += p->count * sizeof (Elf32_External_Rela); |
2023 |
} |
} |
2024 |
|
|
2025 |
return true; |
return TRUE; |
2026 |
} |
} |
2027 |
|
|
2028 |
/* This function is called via elf_link_hash_traverse to force |
/* This function is called via elf_link_hash_traverse to force |
2032 |
for all dynamic symbols. Arguably, this is a bug in |
for all dynamic symbols. Arguably, this is a bug in |
2033 |
elf_adjust_dynamic_symbol. */ |
elf_adjust_dynamic_symbol. */ |
2034 |
|
|
2035 |
static boolean |
static bfd_boolean |
2036 |
clobber_millicode_symbols (h, info) |
clobber_millicode_symbols (struct elf_link_hash_entry *h, |
2037 |
struct elf_link_hash_entry *h; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
2038 |
{ |
{ |
2039 |
if (h->root.type == bfd_link_hash_warning) |
if (h->root.type == bfd_link_hash_warning) |
2040 |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
2041 |
|
|
2042 |
if (h->type == STT_PARISC_MILLI |
if (h->type == STT_PARISC_MILLI |
2043 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) |
&& !h->forced_local) |
2044 |
{ |
{ |
2045 |
elf32_hppa_hide_symbol (info, h, true); |
elf32_hppa_hide_symbol (info, h, TRUE); |
2046 |
} |
} |
2047 |
return true; |
return TRUE; |
2048 |
} |
} |
2049 |
|
|
2050 |
/* Find any dynamic relocs that apply to read-only sections. */ |
/* Find any dynamic relocs that apply to read-only sections. */ |
2051 |
|
|
2052 |
static boolean |
static bfd_boolean |
2053 |
readonly_dynrelocs (h, inf) |
readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) |
|
struct elf_link_hash_entry *h; |
|
|
PTR inf; |
|
2054 |
{ |
{ |
2055 |
struct elf32_hppa_link_hash_entry *eh; |
struct elf32_hppa_link_hash_entry *eh; |
2056 |
struct elf32_hppa_dyn_reloc_entry *p; |
struct elf32_hppa_dyn_reloc_entry *p; |
2065 |
|
|
2066 |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
2067 |
{ |
{ |
2068 |
struct bfd_link_info *info = (struct bfd_link_info *) inf; |
struct bfd_link_info *info = inf; |
2069 |
|
|
2070 |
info->flags |= DF_TEXTREL; |
info->flags |= DF_TEXTREL; |
2071 |
|
|
2072 |
/* Not an error, just cut short the traversal. */ |
/* Not an error, just cut short the traversal. */ |
2073 |
return false; |
return FALSE; |
2074 |
} |
} |
2075 |
} |
} |
2076 |
return true; |
return TRUE; |
2077 |
} |
} |
2078 |
|
|
2079 |
/* Set the sizes of the dynamic sections. */ |
/* Set the sizes of the dynamic sections. */ |
2080 |
|
|
2081 |
static boolean |
static bfd_boolean |
2082 |
elf32_hppa_size_dynamic_sections (output_bfd, info) |
elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, |
2083 |
bfd *output_bfd ATTRIBUTE_UNUSED; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
2084 |
{ |
{ |
2085 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
2086 |
bfd *dynobj; |
bfd *dynobj; |
2087 |
bfd *ibfd; |
bfd *ibfd; |
2088 |
asection *s; |
asection *s; |
2089 |
boolean relocs; |
bfd_boolean relocs; |
2090 |
|
|
2091 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
2092 |
dynobj = htab->elf.dynobj; |
dynobj = htab->elf.dynobj; |
2096 |
if (htab->elf.dynamic_sections_created) |
if (htab->elf.dynamic_sections_created) |
2097 |
{ |
{ |
2098 |
/* Set the contents of the .interp section to the interpreter. */ |
/* Set the contents of the .interp section to the interpreter. */ |
2099 |
if (! info->shared) |
if (info->executable) |
2100 |
{ |
{ |
2101 |
s = bfd_get_section_by_name (dynobj, ".interp"); |
s = bfd_get_section_by_name (dynobj, ".interp"); |
2102 |
if (s == NULL) |
if (s == NULL) |
2103 |
abort (); |
abort (); |
2104 |
s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; |
s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
2105 |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
2106 |
} |
} |
2107 |
|
|
2110 |
clobber_millicode_symbols, |
clobber_millicode_symbols, |
2111 |
info); |
info); |
2112 |
} |
} |
|
else |
|
|
{ |
|
|
/* Run through the function symbols, looking for any that are |
|
|
PIC, and mark them as needing .plt entries so that %r19 will |
|
|
be set up. */ |
|
|
if (! info->shared) |
|
|
elf_link_hash_traverse (&htab->elf, mark_PIC_calls, (PTR) info); |
|
|
} |
|
2113 |
|
|
2114 |
/* Set up .got and .plt offsets for local syms, and space for local |
/* Set up .got and .plt offsets for local syms, and space for local |
2115 |
dynamic relocs. */ |
dynamic relocs. */ |
2146 |
else if (p->count != 0) |
else if (p->count != 0) |
2147 |
{ |
{ |
2148 |
srel = elf_section_data (p->sec)->sreloc; |
srel = elf_section_data (p->sec)->sreloc; |
2149 |
srel->_raw_size += p->count * sizeof (Elf32_External_Rela); |
srel->size += p->count * sizeof (Elf32_External_Rela); |
2150 |
if ((p->sec->output_section->flags & SEC_READONLY) != 0) |
if ((p->sec->output_section->flags & SEC_READONLY) != 0) |
2151 |
info->flags |= DF_TEXTREL; |
info->flags |= DF_TEXTREL; |
2152 |
} |
} |
2166 |
{ |
{ |
2167 |
if (*local_got > 0) |
if (*local_got > 0) |
2168 |
{ |
{ |
2169 |
*local_got = s->_raw_size; |
*local_got = s->size; |
2170 |
s->_raw_size += GOT_ENTRY_SIZE; |
s->size += GOT_ENTRY_SIZE; |
2171 |
if (info->shared) |
if (info->shared) |
2172 |
srel->_raw_size += sizeof (Elf32_External_Rela); |
srel->size += sizeof (Elf32_External_Rela); |
2173 |
} |
} |
2174 |
else |
else |
2175 |
*local_got = (bfd_vma) -1; |
*local_got = (bfd_vma) -1; |
2191 |
{ |
{ |
2192 |
if (*local_plt > 0) |
if (*local_plt > 0) |
2193 |
{ |
{ |
2194 |
*local_plt = s->_raw_size; |
*local_plt = s->size; |
2195 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
2196 |
if (info->shared) |
if (info->shared) |
2197 |
srel->_raw_size += sizeof (Elf32_External_Rela); |
srel->size += sizeof (Elf32_External_Rela); |
2198 |
} |
} |
2199 |
else |
else |
2200 |
*local_plt = (bfd_vma) -1; |
*local_plt = (bfd_vma) -1; |
2205 |
/* Do all the .plt entries without relocs first. The dynamic linker |
/* Do all the .plt entries without relocs first. The dynamic linker |
2206 |
uses the last .plt reloc to find the end of the .plt (and hence |
uses the last .plt reloc to find the end of the .plt (and hence |
2207 |
the start of the .got) for lazy linking. */ |
the start of the .got) for lazy linking. */ |
2208 |
elf_link_hash_traverse (&htab->elf, allocate_plt_static, (PTR) info); |
elf_link_hash_traverse (&htab->elf, allocate_plt_static, info); |
2209 |
|
|
2210 |
/* Allocate global sym .plt and .got entries, and space for global |
/* Allocate global sym .plt and .got entries, and space for global |
2211 |
sym dynamic relocs. */ |
sym dynamic relocs. */ |
2212 |
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); |
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); |
2213 |
|
|
2214 |
/* The check_relocs and adjust_dynamic_symbol entry points have |
/* The check_relocs and adjust_dynamic_symbol entry points have |
2215 |
determined the sizes of the various dynamic sections. Allocate |
determined the sizes of the various dynamic sections. Allocate |
2216 |
memory for them. */ |
memory for them. */ |
2217 |
relocs = false; |
relocs = FALSE; |
2218 |
for (s = dynobj->sections; s != NULL; s = s->next) |
for (s = dynobj->sections; s != NULL; s = s->next) |
2219 |
{ |
{ |
2220 |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
2234 |
if (gotalign > pltalign) |
if (gotalign > pltalign) |
2235 |
bfd_set_section_alignment (dynobj, s, gotalign); |
bfd_set_section_alignment (dynobj, s, gotalign); |
2236 |
mask = ((bfd_size_type) 1 << gotalign) - 1; |
mask = ((bfd_size_type) 1 << gotalign) - 1; |
2237 |
s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask; |
s->size = (s->size + sizeof (plt_stub) + mask) & ~mask; |
2238 |
} |
} |
2239 |
} |
} |
2240 |
else if (s == htab->sgot) |
else if (s == htab->sgot) |
2241 |
; |
; |
2242 |
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) |
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) |
2243 |
{ |
{ |
2244 |
if (s->_raw_size != 0) |
if (s->size != 0) |
2245 |
{ |
{ |
2246 |
/* Remember whether there are any reloc sections other |
/* Remember whether there are any reloc sections other |
2247 |
than .rela.plt. */ |
than .rela.plt. */ |
2248 |
if (s != htab->srelplt) |
if (s != htab->srelplt) |
2249 |
relocs = true; |
relocs = TRUE; |
2250 |
|
|
2251 |
/* We use the reloc_count field as a counter if we need |
/* We use the reloc_count field as a counter if we need |
2252 |
to copy relocs into the output file. */ |
to copy relocs into the output file. */ |
2259 |
continue; |
continue; |
2260 |
} |
} |
2261 |
|
|
2262 |
if (s->_raw_size == 0) |
if (s->size == 0) |
2263 |
{ |
{ |
2264 |
/* If we don't need this section, strip it from the |
/* If we don't need this section, strip it from the |
2265 |
output file. This is mostly to handle .rela.bss and |
output file. This is mostly to handle .rela.bss and |
2276 |
|
|
2277 |
/* Allocate memory for the section contents. Zero it, because |
/* Allocate memory for the section contents. Zero it, because |
2278 |
we may not fill in all the reloc sections. */ |
we may not fill in all the reloc sections. */ |
2279 |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); |
s->contents = bfd_zalloc (dynobj, s->size); |
2280 |
if (s->contents == NULL && s->_raw_size != 0) |
if (s->contents == NULL && s->size != 0) |
2281 |
return false; |
return FALSE; |
2282 |
} |
} |
2283 |
|
|
2284 |
if (htab->elf.dynamic_sections_created) |
if (htab->elf.dynamic_sections_created) |
2288 |
communicate the LTP value of a load module to the dynamic |
communicate the LTP value of a load module to the dynamic |
2289 |
linker. */ |
linker. */ |
2290 |
#define add_dynamic_entry(TAG, VAL) \ |
#define add_dynamic_entry(TAG, VAL) \ |
2291 |
bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) |
_bfd_elf_add_dynamic_entry (info, TAG, VAL) |
2292 |
|
|
2293 |
if (!add_dynamic_entry (DT_PLTGOT, 0)) |
if (!add_dynamic_entry (DT_PLTGOT, 0)) |
2294 |
return false; |
return FALSE; |
2295 |
|
|
2296 |
/* Add some entries to the .dynamic section. We fill in the |
/* Add some entries to the .dynamic section. We fill in the |
2297 |
values later, in elf32_hppa_finish_dynamic_sections, but we |
values later, in elf32_hppa_finish_dynamic_sections, but we |
2301 |
if (!info->shared) |
if (!info->shared) |
2302 |
{ |
{ |
2303 |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
2304 |
return false; |
return FALSE; |
2305 |
} |
} |
2306 |
|
|
2307 |
if (htab->srelplt->_raw_size != 0) |
if (htab->srelplt->size != 0) |
2308 |
{ |
{ |
2309 |
if (!add_dynamic_entry (DT_PLTRELSZ, 0) |
if (!add_dynamic_entry (DT_PLTRELSZ, 0) |
2310 |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
2311 |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
2312 |
return false; |
return FALSE; |
2313 |
} |
} |
2314 |
|
|
2315 |
if (relocs) |
if (relocs) |
2317 |
if (!add_dynamic_entry (DT_RELA, 0) |
if (!add_dynamic_entry (DT_RELA, 0) |
2318 |
|| !add_dynamic_entry (DT_RELASZ, 0) |
|| !add_dynamic_entry (DT_RELASZ, 0) |
2319 |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
2320 |
return false; |
return FALSE; |
2321 |
|
|
2322 |
/* If any dynamic relocs apply to a read-only section, |
/* If any dynamic relocs apply to a read-only section, |
2323 |
then we need a DT_TEXTREL entry. */ |
then we need a DT_TEXTREL entry. */ |
2324 |
if ((info->flags & DF_TEXTREL) == 0) |
if ((info->flags & DF_TEXTREL) == 0) |
2325 |
elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, |
elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); |
|
(PTR) info); |
|
2326 |
|
|
2327 |
if ((info->flags & DF_TEXTREL) != 0) |
if ((info->flags & DF_TEXTREL) != 0) |
2328 |
{ |
{ |
2329 |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
2330 |
return false; |
return FALSE; |
2331 |
} |
} |
2332 |
} |
} |
2333 |
} |
} |
2334 |
#undef add_dynamic_entry |
#undef add_dynamic_entry |
2335 |
|
|
2336 |
return true; |
return TRUE; |
2337 |
} |
} |
2338 |
|
|
2339 |
/* External entry points for sizing and building linker stubs. */ |
/* External entry points for sizing and building linker stubs. */ |
2343 |
0 when no stubs will be needed, and 1 on success. */ |
0 when no stubs will be needed, and 1 on success. */ |
2344 |
|
|
2345 |
int |
int |
2346 |
elf32_hppa_setup_section_lists (output_bfd, info) |
elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) |
|
bfd *output_bfd; |
|
|
struct bfd_link_info *info; |
|
2347 |
{ |
{ |
2348 |
bfd *input_bfd; |
bfd *input_bfd; |
2349 |
unsigned int bfd_count; |
unsigned int bfd_count; |
2353 |
bfd_size_type amt; |
bfd_size_type amt; |
2354 |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
2355 |
|
|
|
if (htab->elf.root.creator->flavour != bfd_target_elf_flavour) |
|
|
return 0; |
|
|
|
|
2356 |
/* Count the number of input BFDs and find the top input section id. */ |
/* Count the number of input BFDs and find the top input section id. */ |
2357 |
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; |
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; |
2358 |
input_bfd != NULL; |
input_bfd != NULL; |
2370 |
htab->bfd_count = bfd_count; |
htab->bfd_count = bfd_count; |
2371 |
|
|
2372 |
amt = sizeof (struct map_stub) * (top_id + 1); |
amt = sizeof (struct map_stub) * (top_id + 1); |
2373 |
htab->stub_group = (struct map_stub *) bfd_zmalloc (amt); |
htab->stub_group = bfd_zmalloc (amt); |
2374 |
if (htab->stub_group == NULL) |
if (htab->stub_group == NULL) |
2375 |
return -1; |
return -1; |
2376 |
|
|
2387 |
|
|
2388 |
htab->top_index = top_index; |
htab->top_index = top_index; |
2389 |
amt = sizeof (asection *) * (top_index + 1); |
amt = sizeof (asection *) * (top_index + 1); |
2390 |
input_list = (asection **) bfd_malloc (amt); |
input_list = bfd_malloc (amt); |
2391 |
htab->input_list = input_list; |
htab->input_list = input_list; |
2392 |
if (input_list == NULL) |
if (input_list == NULL) |
2393 |
return -1; |
return -1; |
2416 |
we may insert linker stubs. */ |
we may insert linker stubs. */ |
2417 |
|
|
2418 |
void |
void |
2419 |
elf32_hppa_next_input_section (info, isec) |
elf32_hppa_next_input_section (struct bfd_link_info *info, asection *isec) |
|
struct bfd_link_info *info; |
|
|
asection *isec; |
|
2420 |
{ |
{ |
2421 |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
2422 |
|
|
2443 |
the middle of a function is not a good idea. */ |
the middle of a function is not a good idea. */ |
2444 |
|
|
2445 |
static void |
static void |
2446 |
group_sections (htab, stub_group_size, stubs_always_before_branch) |
group_sections (struct elf32_hppa_link_hash_table *htab, |
2447 |
struct elf32_hppa_link_hash_table *htab; |
bfd_size_type stub_group_size, |
2448 |
bfd_size_type stub_group_size; |
bfd_boolean stubs_always_before_branch) |
|
boolean stubs_always_before_branch; |
|
2449 |
{ |
{ |
2450 |
asection **list = htab->input_list + htab->top_index; |
asection **list = htab->input_list + htab->top_index; |
2451 |
do |
do |
2458 |
asection *curr; |
asection *curr; |
2459 |
asection *prev; |
asection *prev; |
2460 |
bfd_size_type total; |
bfd_size_type total; |
2461 |
|
bfd_boolean big_sec; |
2462 |
|
|
2463 |
curr = tail; |
curr = tail; |
2464 |
if (tail->_cooked_size) |
total = tail->size; |
2465 |
total = tail->_cooked_size; |
big_sec = total >= stub_group_size; |
2466 |
else |
|
|
total = tail->_raw_size; |
|
2467 |
while ((prev = PREV_SEC (curr)) != NULL |
while ((prev = PREV_SEC (curr)) != NULL |
2468 |
&& ((total += curr->output_offset - prev->output_offset) |
&& ((total += curr->output_offset - prev->output_offset) |
2469 |
< stub_group_size)) |
< stub_group_size)) |
2491 |
while (tail != curr && (tail = prev) != NULL); |
while (tail != curr && (tail = prev) != NULL); |
2492 |
|
|
2493 |
/* But wait, there's more! Input sections up to 240000 |
/* But wait, there's more! Input sections up to 240000 |
2494 |
bytes before the stub section can be handled by it too. */ |
bytes before the stub section can be handled by it too. |
2495 |
if (!stubs_always_before_branch) |
Don't do this if we have a really large section after the |
2496 |
|
stubs, as adding more stubs increases the chance that |
2497 |
|
branches may not reach into the stub section. */ |
2498 |
|
if (!stubs_always_before_branch && !big_sec) |
2499 |
{ |
{ |
2500 |
total = 0; |
total = 0; |
2501 |
while (prev != NULL |
while (prev != NULL |
2520 |
Returns -1 on error, 1 if export stubs created, 0 otherwise. */ |
Returns -1 on error, 1 if export stubs created, 0 otherwise. */ |
2521 |
|
|
2522 |
static int |
static int |
2523 |
get_local_syms (output_bfd, input_bfd, info) |
get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info) |
|
bfd *output_bfd; |
|
|
bfd *input_bfd; |
|
|
struct bfd_link_info *info; |
|
2524 |
{ |
{ |
2525 |
unsigned int bfd_indx; |
unsigned int bfd_indx; |
2526 |
Elf_Internal_Sym *local_syms, **all_local_syms; |
Elf_Internal_Sym *local_syms, **all_local_syms; |
2531 |
we need to read in the local symbols in parallel and save them for |
we need to read in the local symbols in parallel and save them for |
2532 |
later use; so hold pointers to the local symbols in an array. */ |
later use; so hold pointers to the local symbols in an array. */ |
2533 |
bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; |
bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; |
2534 |
all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt); |
all_local_syms = bfd_zmalloc (amt); |
2535 |
htab->all_local_syms = all_local_syms; |
htab->all_local_syms = all_local_syms; |
2536 |
if (all_local_syms == NULL) |
if (all_local_syms == NULL) |
2537 |
return -1; |
return -1; |
2599 |
&& (hash->elf.root.u.def.section->output_section->owner |
&& (hash->elf.root.u.def.section->output_section->owner |
2600 |
== output_bfd) |
== output_bfd) |
2601 |
&& hash->elf.root.u.def.section->owner == input_bfd |
&& hash->elf.root.u.def.section->owner == input_bfd |
2602 |
&& (hash->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) |
&& hash->elf.def_regular |
2603 |
&& !(hash->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) |
&& !hash->elf.forced_local |
2604 |
&& ELF_ST_VISIBILITY (hash->elf.other) == STV_DEFAULT) |
&& ELF_ST_VISIBILITY (hash->elf.other) == STV_DEFAULT) |
2605 |
{ |
{ |
2606 |
asection *sec; |
asection *sec; |
2611 |
stub_name = hash->elf.root.root.string; |
stub_name = hash->elf.root.root.string; |
2612 |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
2613 |
stub_name, |
stub_name, |
2614 |
false, false); |
FALSE, FALSE); |
2615 |
if (stub_entry == NULL) |
if (stub_entry == NULL) |
2616 |
{ |
{ |
2617 |
stub_entry = hppa_add_stub (stub_name, sec, htab); |
stub_entry = hppa_add_stub (stub_name, sec, htab); |
2626 |
} |
} |
2627 |
else |
else |
2628 |
{ |
{ |
2629 |
(*_bfd_error_handler) (_("%s: duplicate export stub %s"), |
(*_bfd_error_handler) (_("%B: duplicate export stub %s"), |
2630 |
bfd_archive_filename (input_bfd), |
input_bfd, |
2631 |
stub_name); |
stub_name); |
2632 |
} |
} |
2633 |
} |
} |
2644 |
PC-relative calls to a target that is unreachable with a "bl" |
PC-relative calls to a target that is unreachable with a "bl" |
2645 |
instruction. */ |
instruction. */ |
2646 |
|
|
2647 |
boolean |
bfd_boolean |
2648 |
elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, |
elf32_hppa_size_stubs |
2649 |
add_stub_section, layout_sections_again) |
(bfd *output_bfd, bfd *stub_bfd, struct bfd_link_info *info, |
2650 |
bfd *output_bfd; |
bfd_boolean multi_subspace, bfd_signed_vma group_size, |
2651 |
bfd *stub_bfd; |
asection * (*add_stub_section) (const char *, asection *), |
2652 |
struct bfd_link_info *info; |
void (*layout_sections_again) (void)) |
|
boolean multi_subspace; |
|
|
bfd_signed_vma group_size; |
|
|
asection * (*add_stub_section) PARAMS ((const char *, asection *)); |
|
|
void (*layout_sections_again) PARAMS ((void)); |
|
2653 |
{ |
{ |
2654 |
bfd_size_type stub_group_size; |
bfd_size_type stub_group_size; |
2655 |
boolean stubs_always_before_branch; |
bfd_boolean stubs_always_before_branch; |
2656 |
boolean stub_changed; |
bfd_boolean stub_changed; |
2657 |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); |
2658 |
|
|
2659 |
/* Stash our params away. */ |
/* Stash our params away. */ |
2669 |
if (stub_group_size == 1) |
if (stub_group_size == 1) |
2670 |
{ |
{ |
2671 |
/* Default values. */ |
/* Default values. */ |
2672 |
stub_group_size = 7680000; |
if (stubs_always_before_branch) |
2673 |
if (htab->has_17bit_branch || htab->multi_subspace) |
{ |
2674 |
stub_group_size = 240000; |
stub_group_size = 7680000; |
2675 |
if (htab->has_12bit_branch) |
if (htab->has_17bit_branch || htab->multi_subspace) |
2676 |
stub_group_size = 7500; |
stub_group_size = 240000; |
2677 |
|
if (htab->has_12bit_branch) |
2678 |
|
stub_group_size = 7500; |
2679 |
|
} |
2680 |
|
else |
2681 |
|
{ |
2682 |
|
stub_group_size = 6971392; |
2683 |
|
if (htab->has_17bit_branch || htab->multi_subspace) |
2684 |
|
stub_group_size = 217856; |
2685 |
|
if (htab->has_12bit_branch) |
2686 |
|
stub_group_size = 6808; |
2687 |
|
} |
2688 |
} |
} |
2689 |
|
|
2690 |
group_sections (htab, stub_group_size, stubs_always_before_branch); |
group_sections (htab, stub_group_size, stubs_always_before_branch); |
2694 |
default: |
default: |
2695 |
if (htab->all_local_syms) |
if (htab->all_local_syms) |
2696 |
goto error_ret_free_local; |
goto error_ret_free_local; |
2697 |
return false; |
return FALSE; |
2698 |
|
|
2699 |
case 0: |
case 0: |
2700 |
stub_changed = false; |
stub_changed = FALSE; |
2701 |
break; |
break; |
2702 |
|
|
2703 |
case 1: |
case 1: |
2704 |
stub_changed = true; |
stub_changed = TRUE; |
2705 |
break; |
break; |
2706 |
} |
} |
2707 |
|
|
2747 |
|
|
2748 |
/* Get the relocs. */ |
/* Get the relocs. */ |
2749 |
internal_relocs |
internal_relocs |
2750 |
= _bfd_elf32_link_read_relocs (input_bfd, section, NULL, |
= _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL, |
2751 |
(Elf_Internal_Rela *) NULL, |
info->keep_memory); |
|
info->keep_memory); |
|
2752 |
if (internal_relocs == NULL) |
if (internal_relocs == NULL) |
2753 |
goto error_ret_free_local; |
goto error_ret_free_local; |
2754 |
|
|
2837 |
} |
} |
2838 |
else if (hash->elf.root.type == bfd_link_hash_undefined) |
else if (hash->elf.root.type == bfd_link_hash_undefined) |
2839 |
{ |
{ |
2840 |
if (! (info->shared |
if (! (info->unresolved_syms_in_objects == RM_IGNORE |
|
&& !info->no_undefined |
|
2841 |
&& (ELF_ST_VISIBILITY (hash->elf.other) |
&& (ELF_ST_VISIBILITY (hash->elf.other) |
2842 |
== STV_DEFAULT) |
== STV_DEFAULT) |
2843 |
&& hash->elf.type != STT_PARISC_MILLI)) |
&& hash->elf.type != STT_PARISC_MILLI)) |
2852 |
|
|
2853 |
/* Determine what (if any) linker stub is needed. */ |
/* Determine what (if any) linker stub is needed. */ |
2854 |
stub_type = hppa_type_of_stub (section, irela, hash, |
stub_type = hppa_type_of_stub (section, irela, hash, |
2855 |
destination); |
destination, info); |
2856 |
if (stub_type == hppa_stub_none) |
if (stub_type == hppa_stub_none) |
2857 |
continue; |
continue; |
2858 |
|
|
2866 |
|
|
2867 |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, |
2868 |
stub_name, |
stub_name, |
2869 |
false, false); |
FALSE, FALSE); |
2870 |
if (stub_entry != NULL) |
if (stub_entry != NULL) |
2871 |
{ |
{ |
2872 |
/* The proper stub has already been created. */ |
/* The proper stub has already been created. */ |
2892 |
stub_entry->stub_type = hppa_stub_long_branch_shared; |
stub_entry->stub_type = hppa_stub_long_branch_shared; |
2893 |
} |
} |
2894 |
stub_entry->h = hash; |
stub_entry->h = hash; |
2895 |
stub_changed = true; |
stub_changed = TRUE; |
2896 |
} |
} |
2897 |
|
|
2898 |
/* We're done with the internal relocs, free them. */ |
/* We're done with the internal relocs, free them. */ |
2909 |
for (stub_sec = htab->stub_bfd->sections; |
for (stub_sec = htab->stub_bfd->sections; |
2910 |
stub_sec != NULL; |
stub_sec != NULL; |
2911 |
stub_sec = stub_sec->next) |
stub_sec = stub_sec->next) |
2912 |
{ |
stub_sec->size = 0; |
|
stub_sec->_raw_size = 0; |
|
|
stub_sec->_cooked_size = 0; |
|
|
} |
|
2913 |
|
|
2914 |
bfd_hash_traverse (&htab->stub_hash_table, hppa_size_one_stub, htab); |
bfd_hash_traverse (&htab->stub_hash_table, hppa_size_one_stub, htab); |
2915 |
|
|
2916 |
/* Ask the linker to do its stuff. */ |
/* Ask the linker to do its stuff. */ |
2917 |
(*htab->layout_sections_again) (); |
(*htab->layout_sections_again) (); |
2918 |
stub_changed = false; |
stub_changed = FALSE; |
2919 |
} |
} |
2920 |
|
|
2921 |
free (htab->all_local_syms); |
free (htab->all_local_syms); |
2922 |
return true; |
return TRUE; |
2923 |
|
|
2924 |
error_ret_free_local: |
error_ret_free_local: |
2925 |
free (htab->all_local_syms); |
free (htab->all_local_syms); |
2926 |
return false; |
return FALSE; |
2927 |
} |
} |
2928 |
|
|
2929 |
/* For a final link, this function is called after we have sized the |
/* For a final link, this function is called after we have sized the |
2930 |
stubs to provide a value for __gp. */ |
stubs to provide a value for __gp. */ |
2931 |
|
|
2932 |
boolean |
bfd_boolean |
2933 |
elf32_hppa_set_gp (abfd, info) |
elf32_hppa_set_gp (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
2934 |
{ |
{ |
2935 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
2936 |
asection *sec = NULL; |
asection *sec = NULL; |
2938 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
2939 |
|
|
2940 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
2941 |
h = bfd_link_hash_lookup (&htab->elf.root, "$global$", false, false, false); |
h = bfd_link_hash_lookup (&htab->elf.root, "$global$", FALSE, FALSE, FALSE); |
2942 |
|
|
2943 |
if (h != NULL |
if (h != NULL |
2944 |
&& (h->type == bfd_link_hash_defined |
&& (h->type == bfd_link_hash_defined |
2949 |
} |
} |
2950 |
else |
else |
2951 |
{ |
{ |
2952 |
asection *splt; |
asection *splt = bfd_get_section_by_name (abfd, ".plt"); |
2953 |
asection *sgot; |
asection *sgot = bfd_get_section_by_name (abfd, ".got"); |
|
|
|
|
if (htab->elf.root.creator->flavour == bfd_target_elf_flavour) |
|
|
{ |
|
|
splt = htab->splt; |
|
|
sgot = htab->sgot; |
|
|
} |
|
|
else |
|
|
{ |
|
|
/* If we're not elf, look up the output sections in the |
|
|
hope we may actually find them. */ |
|
|
splt = bfd_get_section_by_name (abfd, ".plt"); |
|
|
sgot = bfd_get_section_by_name (abfd, ".got"); |
|
|
} |
|
2954 |
|
|
2955 |
/* Choose to point our LTP at, in this order, one of .plt, .got, |
/* Choose to point our LTP at, in this order, one of .plt, .got, |
2956 |
or .data, if these sections exist. In the case of choosing |
or .data, if these sections exist. In the case of choosing |
2960 |
if either the .plt or .got is larger than 0x2000. If both |
if either the .plt or .got is larger than 0x2000. If both |
2961 |
the .plt and .got are smaller than 0x2000, choose the end of |
the .plt and .got are smaller than 0x2000, choose the end of |
2962 |
the .plt section. */ |
the .plt section. */ |
2963 |
sec = splt; |
sec = strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0 |
2964 |
|
? NULL : splt; |
2965 |
if (sec != NULL) |
if (sec != NULL) |
2966 |
{ |
{ |
2967 |
gp_val = sec->_raw_size; |
gp_val = sec->size; |
2968 |
if (gp_val > 0x2000 || (sgot && sgot->_raw_size > 0x2000)) |
if (gp_val > 0x2000 || (sgot && sgot->size > 0x2000)) |
2969 |
{ |
{ |
2970 |
gp_val = 0x2000; |
gp_val = 0x2000; |
2971 |
} |
} |
2975 |
sec = sgot; |
sec = sgot; |
2976 |
if (sec != NULL) |
if (sec != NULL) |
2977 |
{ |
{ |
2978 |
/* We know we don't have a .plt. If .got is large, |
if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") != 0) |
2979 |
offset our LTP. */ |
{ |
2980 |
if (sec->_raw_size > 0x2000) |
/* We know we don't have a .plt. If .got is large, |
2981 |
gp_val = 0x2000; |
offset our LTP. */ |
2982 |
|
if (sec->size > 0x2000) |
2983 |
|
gp_val = 0x2000; |
2984 |
|
} |
2985 |
} |
} |
2986 |
else |
else |
2987 |
{ |
{ |
3005 |
gp_val += sec->output_section->vma + sec->output_offset; |
gp_val += sec->output_section->vma + sec->output_offset; |
3006 |
|
|
3007 |
elf_gp (abfd) = gp_val; |
elf_gp (abfd) = gp_val; |
3008 |
return true; |
return TRUE; |
3009 |
} |
} |
3010 |
|
|
3011 |
/* Build all the stubs associated with the current output file. The |
/* Build all the stubs associated with the current output file. The |
3014 |
functions here. This function is called via hppaelf_finish in the |
functions here. This function is called via hppaelf_finish in the |
3015 |
linker. */ |
linker. */ |
3016 |
|
|
3017 |
boolean |
bfd_boolean |
3018 |
elf32_hppa_build_stubs (info) |
elf32_hppa_build_stubs (struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
3019 |
{ |
{ |
3020 |
asection *stub_sec; |
asection *stub_sec; |
3021 |
struct bfd_hash_table *table; |
struct bfd_hash_table *table; |
3030 |
bfd_size_type size; |
bfd_size_type size; |
3031 |
|
|
3032 |
/* Allocate memory to hold the linker stubs. */ |
/* Allocate memory to hold the linker stubs. */ |
3033 |
size = stub_sec->_raw_size; |
size = stub_sec->size; |
3034 |
stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size); |
stub_sec->contents = bfd_zalloc (htab->stub_bfd, size); |
3035 |
if (stub_sec->contents == NULL && size != 0) |
if (stub_sec->contents == NULL && size != 0) |
3036 |
return false; |
return FALSE; |
3037 |
stub_sec->_raw_size = 0; |
stub_sec->size = 0; |
3038 |
} |
} |
3039 |
|
|
3040 |
/* Build the stubs as directed by the stub hash table. */ |
/* Build the stubs as directed by the stub hash table. */ |
3041 |
table = &htab->stub_hash_table; |
table = &htab->stub_hash_table; |
3042 |
bfd_hash_traverse (table, hppa_build_one_stub, info); |
bfd_hash_traverse (table, hppa_build_one_stub, info); |
3043 |
|
|
3044 |
return true; |
return TRUE; |
3045 |
} |
} |
3046 |
|
|
3047 |
/* Perform a final link. */ |
/* Perform a final link. */ |
3048 |
|
|
3049 |
static boolean |
static bfd_boolean |
3050 |
elf32_hppa_final_link (abfd, info) |
elf32_hppa_final_link (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
3051 |
{ |
{ |
3052 |
/* Invoke the regular ELF linker to do all the work. */ |
/* Invoke the regular ELF linker to do all the work. */ |
3053 |
if (!bfd_elf32_bfd_final_link (abfd, info)) |
if (!bfd_elf_final_link (abfd, info)) |
3054 |
return false; |
return FALSE; |
3055 |
|
|
3056 |
/* If we're producing a final executable, sort the contents of the |
/* If we're producing a final executable, sort the contents of the |
3057 |
unwind section. */ |
unwind section. */ |
3061 |
/* Record the lowest address for the data and text segments. */ |
/* Record the lowest address for the data and text segments. */ |
3062 |
|
|
3063 |
static void |
static void |
3064 |
hppa_record_segment_addr (abfd, section, data) |
hppa_record_segment_addr (bfd *abfd ATTRIBUTE_UNUSED, |
3065 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *section, |
3066 |
asection *section; |
void *data) |
|
PTR data; |
|
3067 |
{ |
{ |
3068 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
3069 |
|
|
3089 |
/* Perform a relocation as part of a final link. */ |
/* Perform a relocation as part of a final link. */ |
3090 |
|
|
3091 |
static bfd_reloc_status_type |
static bfd_reloc_status_type |
3092 |
final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h) |
final_link_relocate (asection *input_section, |
3093 |
asection *input_section; |
bfd_byte *contents, |
3094 |
bfd_byte *contents; |
const Elf_Internal_Rela *rel, |
3095 |
const Elf_Internal_Rela *rel; |
bfd_vma value, |
3096 |
bfd_vma value; |
struct elf32_hppa_link_hash_table *htab, |
3097 |
struct elf32_hppa_link_hash_table *htab; |
asection *sym_sec, |
3098 |
asection *sym_sec; |
struct elf32_hppa_link_hash_entry *h, |
3099 |
struct elf32_hppa_link_hash_entry *h; |
struct bfd_link_info *info) |
3100 |
{ |
{ |
3101 |
int insn; |
int insn; |
3102 |
unsigned int r_type = ELF32_R_TYPE (rel->r_info); |
unsigned int r_type = ELF32_R_TYPE (rel->r_info); |
3103 |
|
unsigned int orig_r_type = r_type; |
3104 |
reloc_howto_type *howto = elf_hppa_howto_table + r_type; |
reloc_howto_type *howto = elf_hppa_howto_table + r_type; |
3105 |
int r_format = howto->bitsize; |
int r_format = howto->bitsize; |
3106 |
enum hppa_reloc_field_selector_type_alt r_field; |
enum hppa_reloc_field_selector_type_alt r_field; |
3123 |
input_section->output_offset + |
input_section->output_offset + |
3124 |
input_section->output_section->vma); |
input_section->output_section->vma); |
3125 |
|
|
3126 |
|
/* If we are not building a shared library, convert DLTIND relocs to |
3127 |
|
DPREL relocs. */ |
3128 |
|
if (!info->shared) |
3129 |
|
{ |
3130 |
|
switch (r_type) |
3131 |
|
{ |
3132 |
|
case R_PARISC_DLTIND21L: |
3133 |
|
r_type = R_PARISC_DPREL21L; |
3134 |
|
break; |
3135 |
|
|
3136 |
|
case R_PARISC_DLTIND14R: |
3137 |
|
r_type = R_PARISC_DPREL14R; |
3138 |
|
break; |
3139 |
|
|
3140 |
|
case R_PARISC_DLTIND14F: |
3141 |
|
r_type = R_PARISC_DPREL14F; |
3142 |
|
break; |
3143 |
|
} |
3144 |
|
} |
3145 |
|
|
3146 |
switch (r_type) |
switch (r_type) |
3147 |
{ |
{ |
3148 |
case R_PARISC_PCREL12F: |
case R_PARISC_PCREL12F: |
3154 |
|| sym_sec->output_section == NULL |
|| sym_sec->output_section == NULL |
3155 |
|| (h != NULL |
|| (h != NULL |
3156 |
&& h->elf.plt.offset != (bfd_vma) -1 |
&& h->elf.plt.offset != (bfd_vma) -1 |
3157 |
&& (h->elf.dynindx != -1 || h->pic_call) |
&& h->elf.dynindx != -1 |
3158 |
&& !h->plabel)) |
&& !h->plabel |
3159 |
|
&& (info->shared |
3160 |
|
|| !h->elf.def_regular |
3161 |
|
|| h->elf.root.type == bfd_link_hash_defweak))) |
3162 |
{ |
{ |
3163 |
stub_entry = hppa_get_stub_entry (input_section, sym_sec, |
stub_entry = hppa_get_stub_entry (input_section, sym_sec, |
3164 |
h, rel, htab); |
h, rel, htab); |
3190 |
case R_PARISC_PCREL17R: |
case R_PARISC_PCREL17R: |
3191 |
case R_PARISC_PCREL14R: |
case R_PARISC_PCREL14R: |
3192 |
case R_PARISC_PCREL14F: |
case R_PARISC_PCREL14F: |
3193 |
|
case R_PARISC_PCREL32: |
3194 |
/* Make it a pc relative offset. */ |
/* Make it a pc relative offset. */ |
3195 |
value -= location; |
value -= location; |
3196 |
addend -= 8; |
addend -= 8; |
3199 |
case R_PARISC_DPREL21L: |
case R_PARISC_DPREL21L: |
3200 |
case R_PARISC_DPREL14R: |
case R_PARISC_DPREL14R: |
3201 |
case R_PARISC_DPREL14F: |
case R_PARISC_DPREL14F: |
3202 |
|
/* Convert instructions that use the linkage table pointer (r19) to |
3203 |
|
instructions that use the global data pointer (dp). This is the |
3204 |
|
most efficient way of using PIC code in an incomplete executable, |
3205 |
|
but the user must follow the standard runtime conventions for |
3206 |
|
accessing data for this to work. */ |
3207 |
|
if (orig_r_type == R_PARISC_DLTIND21L) |
3208 |
|
{ |
3209 |
|
/* Convert addil instructions if the original reloc was a |
3210 |
|
DLTIND21L. GCC sometimes uses a register other than r19 for |
3211 |
|
the operation, so we must convert any addil instruction |
3212 |
|
that uses this relocation. */ |
3213 |
|
if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26)) |
3214 |
|
insn = ADDIL_DP; |
3215 |
|
else |
3216 |
|
/* We must have a ldil instruction. It's too hard to find |
3217 |
|
and convert the associated add instruction, so issue an |
3218 |
|
error. */ |
3219 |
|
(*_bfd_error_handler) |
3220 |
|
(_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"), |
3221 |
|
input_bfd, |
3222 |
|
input_section, |
3223 |
|
(long) rel->r_offset, |
3224 |
|
howto->name, |
3225 |
|
insn); |
3226 |
|
} |
3227 |
|
else if (orig_r_type == R_PARISC_DLTIND14F) |
3228 |
|
{ |
3229 |
|
/* This must be a format 1 load/store. Change the base |
3230 |
|
register to dp. */ |
3231 |
|
insn = (insn & 0xfc1ffff) | (27 << 21); |
3232 |
|
} |
3233 |
|
|
3234 |
/* For all the DP relative relocations, we need to examine the symbol's |
/* For all the DP relative relocations, we need to examine the symbol's |
3235 |
section. If it's a code section, then "data pointer relative" makes |
section. If it has no section or if it's a code section, then |
3236 |
no sense. In that case we don't adjust the "value", and for 21 bit |
"data pointer relative" makes no sense. In that case we don't |
3237 |
addil instructions, we change the source addend register from %dp to |
adjust the "value", and for 21 bit addil instructions, we change the |
3238 |
%r0. This situation commonly arises when a variable's "constness" |
source addend register from %dp to %r0. This situation commonly |
3239 |
|
arises for undefined weak symbols and when a variable's "constness" |
3240 |
is declared differently from the way the variable is defined. For |
is declared differently from the way the variable is defined. For |
3241 |
instance: "extern int foo" with foo defined as "const int foo". */ |
instance: "extern int foo" with foo defined as "const int foo". */ |
3242 |
if (sym_sec == NULL) |
if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0) |
|
break; |
|
|
if ((sym_sec->flags & SEC_CODE) != 0) |
|
3243 |
{ |
{ |
3244 |
if ((insn & ((0x3f << 26) | (0x1f << 21))) |
if ((insn & ((0x3f << 26) | (0x1f << 21))) |
3245 |
== (((int) OP_ADDIL << 26) | (27 << 21))) |
== (((int) OP_ADDIL << 26) | (27 << 21))) |
3246 |
{ |
{ |
3247 |
insn &= ~ (0x1f << 21); |
insn &= ~ (0x1f << 21); |
|
#if 0 /* debug them. */ |
|
|
(*_bfd_error_handler) |
|
|
(_("%s(%s+0x%lx): fixing %s"), |
|
|
bfd_archive_filename (input_bfd), |
|
|
input_section->name, |
|
|
(long) rel->r_offset, |
|
|
howto->name); |
|
|
#endif |
|
3248 |
} |
} |
3249 |
/* Now try to make things easy for the dynamic linker. */ |
/* Now try to make things easy for the dynamic linker. */ |
3250 |
|
|
3276 |
case R_PARISC_DIR17F: |
case R_PARISC_DIR17F: |
3277 |
case R_PARISC_PCREL17C: |
case R_PARISC_PCREL17C: |
3278 |
case R_PARISC_PCREL14F: |
case R_PARISC_PCREL14F: |
3279 |
|
case R_PARISC_PCREL32: |
3280 |
case R_PARISC_DPREL14F: |
case R_PARISC_DPREL14F: |
3281 |
case R_PARISC_PLABEL32: |
case R_PARISC_PLABEL32: |
3282 |
case R_PARISC_DLTIND14F: |
case R_PARISC_DLTIND14F: |
3362 |
&& value + addend + max_branch_offset >= 2*max_branch_offset) |
&& value + addend + max_branch_offset >= 2*max_branch_offset) |
3363 |
{ |
{ |
3364 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3365 |
(_("%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"), |
(_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"), |
3366 |
bfd_archive_filename (input_bfd), |
input_bfd, |
3367 |
input_section->name, |
input_section, |
3368 |
(long) rel->r_offset, |
(long) rel->r_offset, |
3369 |
stub_entry->root.string); |
stub_entry->root.string); |
3370 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3402 |
|
|
3403 |
/* Relocate an HPPA ELF section. */ |
/* Relocate an HPPA ELF section. */ |
3404 |
|
|
3405 |
static boolean |
static bfd_boolean |
3406 |
elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, |
elf32_hppa_relocate_section (bfd *output_bfd, |
3407 |
contents, relocs, local_syms, local_sections) |
struct bfd_link_info *info, |
3408 |
bfd *output_bfd; |
bfd *input_bfd, |
3409 |
struct bfd_link_info *info; |
asection *input_section, |
3410 |
bfd *input_bfd; |
bfd_byte *contents, |
3411 |
asection *input_section; |
Elf_Internal_Rela *relocs, |
3412 |
bfd_byte *contents; |
Elf_Internal_Sym *local_syms, |
3413 |
Elf_Internal_Rela *relocs; |
asection **local_sections) |
|
Elf_Internal_Sym *local_syms; |
|
|
asection **local_sections; |
|
3414 |
{ |
{ |
3415 |
bfd_vma *local_got_offsets; |
bfd_vma *local_got_offsets; |
3416 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
3418 |
Elf_Internal_Rela *rel; |
Elf_Internal_Rela *rel; |
3419 |
Elf_Internal_Rela *relend; |
Elf_Internal_Rela *relend; |
3420 |
|
|
3421 |
|
if (info->relocatable) |
3422 |
|
return TRUE; |
3423 |
|
|
3424 |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
3425 |
|
|
3426 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
3439 |
bfd_vma relocation; |
bfd_vma relocation; |
3440 |
bfd_reloc_status_type r; |
bfd_reloc_status_type r; |
3441 |
const char *sym_name; |
const char *sym_name; |
3442 |
boolean plabel; |
bfd_boolean plabel; |
3443 |
boolean warned_undef; |
bfd_boolean warned_undef; |
3444 |
|
|
3445 |
r_type = ELF32_R_TYPE (rel->r_info); |
r_type = ELF32_R_TYPE (rel->r_info); |
3446 |
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED) |
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED) |
3447 |
{ |
{ |
3448 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3449 |
return false; |
return FALSE; |
3450 |
} |
} |
3451 |
if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY |
if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY |
3452 |
|| r_type == (unsigned int) R_PARISC_GNU_VTINHERIT) |
|| r_type == (unsigned int) R_PARISC_GNU_VTINHERIT) |
3453 |
continue; |
continue; |
3454 |
|
|
|
r_symndx = ELF32_R_SYM (rel->r_info); |
|
|
|
|
|
if (info->relocateable) |
|
|
{ |
|
|
/* This is a relocatable link. We don't have to change |
|
|
anything, unless the reloc is against a section symbol, |
|
|
in which case we have to adjust according to where the |
|
|
section symbol winds up in the output section. */ |
|
|
if (r_symndx < symtab_hdr->sh_info) |
|
|
{ |
|
|
sym = local_syms + r_symndx; |
|
|
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) |
|
|
{ |
|
|
sym_sec = local_sections[r_symndx]; |
|
|
rel->r_addend += sym_sec->output_offset; |
|
|
} |
|
|
} |
|
|
continue; |
|
|
} |
|
|
|
|
3455 |
/* This is a final link. */ |
/* This is a final link. */ |
3456 |
|
r_symndx = ELF32_R_SYM (rel->r_info); |
3457 |
h = NULL; |
h = NULL; |
3458 |
sym = NULL; |
sym = NULL; |
3459 |
sym_sec = NULL; |
sym_sec = NULL; |
3460 |
warned_undef = false; |
warned_undef = FALSE; |
3461 |
if (r_symndx < symtab_hdr->sh_info) |
if (r_symndx < symtab_hdr->sh_info) |
3462 |
{ |
{ |
3463 |
/* This is a local symbol, h defaults to NULL. */ |
/* This is a local symbol, h defaults to NULL. */ |
3464 |
sym = local_syms + r_symndx; |
sym = local_syms + r_symndx; |
3465 |
sym_sec = local_sections[r_symndx]; |
sym_sec = local_sections[r_symndx]; |
3466 |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel); |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sym_sec, rel); |
3467 |
} |
} |
3468 |
else |
else |
3469 |
{ |
{ |
3470 |
int indx; |
struct elf_link_hash_entry *hh; |
3471 |
|
bfd_boolean unresolved_reloc; |
3472 |
/* It's a global; Find its entry in the link hash. */ |
struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); |
3473 |
indx = r_symndx - symtab_hdr->sh_info; |
|
3474 |
h = ((struct elf32_hppa_link_hash_entry *) |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
3475 |
elf_sym_hashes (input_bfd)[indx]); |
r_symndx, symtab_hdr, sym_hashes, |
3476 |
while (h->elf.root.type == bfd_link_hash_indirect |
hh, sym_sec, relocation, |
3477 |
|| h->elf.root.type == bfd_link_hash_warning) |
unresolved_reloc, warned_undef); |
3478 |
h = (struct elf32_hppa_link_hash_entry *) h->elf.root.u.i.link; |
|
3479 |
|
if (relocation == 0 |
3480 |
relocation = 0; |
&& hh->root.type != bfd_link_hash_defined |
3481 |
if (h->elf.root.type == bfd_link_hash_defined |
&& hh->root.type != bfd_link_hash_defweak |
3482 |
|| h->elf.root.type == bfd_link_hash_defweak) |
&& hh->root.type != bfd_link_hash_undefweak) |
3483 |
{ |
{ |
3484 |
sym_sec = h->elf.root.u.def.section; |
if (info->unresolved_syms_in_objects == RM_IGNORE |
3485 |
/* If sym_sec->output_section is NULL, then it's a |
&& ELF_ST_VISIBILITY (hh->other) == STV_DEFAULT |
3486 |
symbol defined in a shared library. */ |
&& hh->type == STT_PARISC_MILLI) |
|
if (sym_sec->output_section != NULL) |
|
|
relocation = (h->elf.root.u.def.value |
|
|
+ sym_sec->output_offset |
|
|
+ sym_sec->output_section->vma); |
|
|
} |
|
|
else if (h->elf.root.type == bfd_link_hash_undefweak) |
|
|
; |
|
|
else if (info->shared && !info->no_undefined |
|
|
&& ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT |
|
|
&& h->elf.type != STT_PARISC_MILLI) |
|
|
{ |
|
|
if (info->symbolic && !info->allow_shlib_undefined) |
|
3487 |
{ |
{ |
3488 |
if (!((*info->callbacks->undefined_symbol) |
if (! info->callbacks->undefined_symbol |
3489 |
(info, h->elf.root.root.string, input_bfd, |
(info, hh->root.root.string, input_bfd, |
3490 |
input_section, rel->r_offset, false))) |
input_section, rel->r_offset, FALSE)) |
3491 |
return false; |
return FALSE; |
3492 |
warned_undef = true; |
warned_undef = TRUE; |
3493 |
} |
} |
3494 |
} |
} |
3495 |
else |
h = (struct elf32_hppa_link_hash_entry *) hh; |
|
{ |
|
|
if (!((*info->callbacks->undefined_symbol) |
|
|
(info, h->elf.root.root.string, input_bfd, |
|
|
input_section, rel->r_offset, true))) |
|
|
return false; |
|
|
warned_undef = true; |
|
|
} |
|
3496 |
} |
} |
3497 |
|
|
3498 |
/* Do any required modifications to the relocation value, and |
/* Do any required modifications to the relocation value, and |
3506 |
case R_PARISC_DLTIND21L: |
case R_PARISC_DLTIND21L: |
3507 |
{ |
{ |
3508 |
bfd_vma off; |
bfd_vma off; |
3509 |
boolean do_got = 0; |
bfd_boolean do_got = 0; |
3510 |
|
|
3511 |
/* Relocation is to the entry for this symbol in the |
/* Relocation is to the entry for this symbol in the |
3512 |
global offset table. */ |
global offset table. */ |
3513 |
if (h != NULL) |
if (h != NULL) |
3514 |
{ |
{ |
3515 |
boolean dyn; |
bfd_boolean dyn; |
3516 |
|
|
3517 |
off = h->elf.got.offset; |
off = h->elf.got.offset; |
3518 |
dyn = htab->elf.dynamic_sections_created; |
dyn = htab->elf.dynamic_sections_created; |
3519 |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf)) |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, |
3520 |
|
&h->elf)) |
3521 |
{ |
{ |
3522 |
/* If we aren't going to call finish_dynamic_symbol, |
/* If we aren't going to call finish_dynamic_symbol, |
3523 |
then we need to handle initialisation of the .got |
then we need to handle initialisation of the .got |
3562 |
In this case it is relative to the base of the |
In this case it is relative to the base of the |
3563 |
object because the symbol index is zero. */ |
object because the symbol index is zero. */ |
3564 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
3565 |
asection *srelgot = htab->srelgot; |
bfd_byte *loc; |
3566 |
Elf32_External_Rela *loc; |
asection *s = htab->srelgot; |
3567 |
|
|
3568 |
outrel.r_offset = (off |
outrel.r_offset = (off |
3569 |
+ htab->sgot->output_offset |
+ htab->sgot->output_offset |
3570 |
+ htab->sgot->output_section->vma); |
+ htab->sgot->output_section->vma); |
3571 |
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32); |
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32); |
3572 |
outrel.r_addend = relocation; |
outrel.r_addend = relocation; |
3573 |
loc = (Elf32_External_Rela *) srelgot->contents; |
loc = s->contents; |
3574 |
loc += srelgot->reloc_count++; |
loc += s->reloc_count++ * sizeof (Elf32_External_Rela); |
3575 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
3576 |
} |
} |
3577 |
else |
else |
3602 |
if (htab->elf.dynamic_sections_created) |
if (htab->elf.dynamic_sections_created) |
3603 |
{ |
{ |
3604 |
bfd_vma off; |
bfd_vma off; |
3605 |
boolean do_plt = 0; |
bfd_boolean do_plt = 0; |
3606 |
|
|
3607 |
/* If we have a global symbol with a PLT slot, then |
/* If we have a global symbol with a PLT slot, then |
3608 |
redirect this relocation to it. */ |
redirect this relocation to it. */ |
3609 |
if (h != NULL) |
if (h != NULL) |
3610 |
{ |
{ |
3611 |
off = h->elf.plt.offset; |
off = h->elf.plt.offset; |
3612 |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, &h->elf)) |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, |
3613 |
|
&h->elf)) |
3614 |
{ |
{ |
3615 |
/* In a non-shared link, adjust_dynamic_symbols |
/* In a non-shared link, adjust_dynamic_symbols |
3616 |
isn't called for symbols forced local. We |
isn't called for symbols forced local. We |
3653 |
/* Output a dynamic IPLT relocation for this |
/* Output a dynamic IPLT relocation for this |
3654 |
PLT entry. */ |
PLT entry. */ |
3655 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
3656 |
asection *srelplt = htab->srelplt; |
bfd_byte *loc; |
3657 |
Elf32_External_Rela *loc; |
asection *s = htab->srelplt; |
3658 |
|
|
3659 |
outrel.r_offset = (off |
outrel.r_offset = (off |
3660 |
+ htab->splt->output_offset |
+ htab->splt->output_offset |
3661 |
+ htab->splt->output_section->vma); |
+ htab->splt->output_section->vma); |
3662 |
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT); |
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT); |
3663 |
outrel.r_addend = relocation; |
outrel.r_addend = relocation; |
3664 |
loc = (Elf32_External_Rela *) srelplt->contents; |
loc = s->contents; |
3665 |
loc += srelplt->reloc_count++; |
loc += s->reloc_count++ * sizeof (Elf32_External_Rela); |
3666 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
3667 |
} |
} |
3668 |
else |
else |
3727 |
Conversely, DEF_DYNAMIC can't be used in check_relocs as |
Conversely, DEF_DYNAMIC can't be used in check_relocs as |
3728 |
there all files have not been loaded. */ |
there all files have not been loaded. */ |
3729 |
if ((info->shared |
if ((info->shared |
3730 |
|
&& (h == NULL |
3731 |
|
|| ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT |
3732 |
|
|| h->elf.root.type != bfd_link_hash_undefweak) |
3733 |
&& (IS_ABSOLUTE_RELOC (r_type) |
&& (IS_ABSOLUTE_RELOC (r_type) |
3734 |
|| (h != NULL |
|| !SYMBOL_CALLS_LOCAL (info, &h->elf))) |
|
&& h->elf.dynindx != -1 |
|
|
&& (!info->symbolic |
|
|
|| (h->elf.elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)))) |
|
3735 |
|| (!info->shared |
|| (!info->shared |
3736 |
&& h != NULL |
&& h != NULL |
3737 |
&& h->elf.dynindx != -1 |
&& h->elf.dynindx != -1 |
3738 |
&& (h->elf.elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 |
&& !h->elf.non_got_ref |
3739 |
&& (((h->elf.elf_link_hash_flags |
&& ((ELIMINATE_COPY_RELOCS |
3740 |
& ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& h->elf.def_dynamic |
3741 |
&& (h->elf.elf_link_hash_flags |
&& !h->elf.def_regular) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0) |
|
3742 |
|| h->elf.root.type == bfd_link_hash_undefweak |
|| h->elf.root.type == bfd_link_hash_undefweak |
3743 |
|| h->elf.root.type == bfd_link_hash_undefined))) |
|| h->elf.root.type == bfd_link_hash_undefined))) |
3744 |
{ |
{ |
3745 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
3746 |
boolean skip; |
bfd_boolean skip; |
3747 |
asection *sreloc; |
asection *sreloc; |
3748 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
3749 |
|
|
3750 |
/* When generating a shared object, these relocations |
/* When generating a shared object, these relocations |
3751 |
are copied into the output file to be resolved at run |
are copied into the output file to be resolved at run |
3770 |
|| !IS_ABSOLUTE_RELOC (r_type) |
|| !IS_ABSOLUTE_RELOC (r_type) |
3771 |
|| !info->shared |
|| !info->shared |
3772 |
|| !info->symbolic |
|| !info->symbolic |
3773 |
|| (h->elf.elf_link_hash_flags |
|| !h->elf.def_regular)) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
|
3774 |
{ |
{ |
3775 |
outrel.r_info = ELF32_R_INFO (h->elf.dynindx, r_type); |
outrel.r_info = ELF32_R_INFO (h->elf.dynindx, r_type); |
3776 |
} |
} |
3792 |
&& sym_sec->output_section != NULL |
&& sym_sec->output_section != NULL |
3793 |
&& ! bfd_is_abs_section (sym_sec)) |
&& ! bfd_is_abs_section (sym_sec)) |
3794 |
{ |
{ |
3795 |
|
/* Skip this relocation if the output section has |
3796 |
|
been discarded. */ |
3797 |
|
if (bfd_is_abs_section (sym_sec->output_section)) |
3798 |
|
break; |
3799 |
|
|
3800 |
indx = elf_section_data (sym_sec->output_section)->dynindx; |
indx = elf_section_data (sym_sec->output_section)->dynindx; |
3801 |
/* We are turning this relocation into one |
/* We are turning this relocation into one |
3802 |
against a section symbol, so subtract out the |
against a section symbol, so subtract out the |
3807 |
|
|
3808 |
outrel.r_info = ELF32_R_INFO (indx, r_type); |
outrel.r_info = ELF32_R_INFO (indx, r_type); |
3809 |
} |
} |
|
#if 0 |
|
|
/* EH info can cause unaligned DIR32 relocs. |
|
|
Tweak the reloc type for the dynamic linker. */ |
|
|
if (r_type == R_PARISC_DIR32 && (outrel.r_offset & 3) != 0) |
|
|
outrel.r_info = ELF32_R_INFO (ELF32_R_SYM (outrel.r_info), |
|
|
R_PARISC_DIR32U); |
|
|
#endif |
|
3810 |
sreloc = elf_section_data (input_section)->sreloc; |
sreloc = elf_section_data (input_section)->sreloc; |
3811 |
if (sreloc == NULL) |
if (sreloc == NULL) |
3812 |
abort (); |
abort (); |
3813 |
|
|
3814 |
loc = (Elf32_External_Rela *) sreloc->contents; |
loc = sreloc->contents; |
3815 |
loc += sreloc->reloc_count++; |
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
3816 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
3817 |
} |
} |
3818 |
break; |
break; |
3822 |
} |
} |
3823 |
|
|
3824 |
r = final_link_relocate (input_section, contents, rel, relocation, |
r = final_link_relocate (input_section, contents, rel, relocation, |
3825 |
htab, sym_sec, h); |
htab, sym_sec, h, info); |
3826 |
|
|
3827 |
if (r == bfd_reloc_ok) |
if (r == bfd_reloc_ok) |
3828 |
continue; |
continue; |
3835 |
symtab_hdr->sh_link, |
symtab_hdr->sh_link, |
3836 |
sym->st_name); |
sym->st_name); |
3837 |
if (sym_name == NULL) |
if (sym_name == NULL) |
3838 |
return false; |
return FALSE; |
3839 |
if (*sym_name == '\0') |
if (*sym_name == '\0') |
3840 |
sym_name = bfd_section_name (input_bfd, sym_sec); |
sym_name = bfd_section_name (input_bfd, sym_sec); |
3841 |
} |
} |
3847 |
if (r == bfd_reloc_notsupported || !warned_undef) |
if (r == bfd_reloc_notsupported || !warned_undef) |
3848 |
{ |
{ |
3849 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3850 |
(_("%s(%s+0x%lx): cannot handle %s for %s"), |
(_("%B(%A+0x%lx): cannot handle %s for %s"), |
3851 |
bfd_archive_filename (input_bfd), |
input_bfd, |
3852 |
input_section->name, |
input_section, |
3853 |
(long) rel->r_offset, |
(long) rel->r_offset, |
3854 |
howto->name, |
howto->name, |
3855 |
sym_name); |
sym_name); |
3856 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
3857 |
return false; |
return FALSE; |
3858 |
} |
} |
3859 |
} |
} |
3860 |
else |
else |
3861 |
{ |
{ |
3862 |
if (!((*info->callbacks->reloc_overflow) |
if (!((*info->callbacks->reloc_overflow) |
3863 |
(info, sym_name, howto->name, (bfd_vma) 0, |
(info, (h ? &h->elf.root : NULL), sym_name, howto->name, |
3864 |
input_bfd, input_section, rel->r_offset))) |
(bfd_vma) 0, input_bfd, input_section, rel->r_offset))) |
3865 |
return false; |
return FALSE; |
3866 |
} |
} |
3867 |
} |
} |
3868 |
|
|
3869 |
return true; |
return TRUE; |
3870 |
} |
} |
3871 |
|
|
3872 |
/* Finish up dynamic symbol handling. We set the contents of various |
/* Finish up dynamic symbol handling. We set the contents of various |
3873 |
dynamic sections here. */ |
dynamic sections here. */ |
3874 |
|
|
3875 |
static boolean |
static bfd_boolean |
3876 |
elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) |
elf32_hppa_finish_dynamic_symbol (bfd *output_bfd, |
3877 |
bfd *output_bfd; |
struct bfd_link_info *info, |
3878 |
struct bfd_link_info *info; |
struct elf_link_hash_entry *h, |
3879 |
struct elf_link_hash_entry *h; |
Elf_Internal_Sym *sym) |
|
Elf_Internal_Sym *sym; |
|
3880 |
{ |
{ |
3881 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
3882 |
|
Elf_Internal_Rela rel; |
3883 |
|
bfd_byte *loc; |
3884 |
|
|
3885 |
htab = hppa_link_hash_table (info); |
htab = hppa_link_hash_table (info); |
3886 |
|
|
3908 |
+ h->root.u.def.section->output_section->vma); |
+ h->root.u.def.section->output_section->vma); |
3909 |
} |
} |
3910 |
|
|
3911 |
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call) |
/* Create a dynamic IPLT relocation for this entry. */ |
3912 |
|
rel.r_offset = (h->plt.offset |
3913 |
|
+ htab->splt->output_offset |
3914 |
|
+ htab->splt->output_section->vma); |
3915 |
|
if (h->dynindx != -1) |
3916 |
{ |
{ |
3917 |
Elf_Internal_Rela rel; |
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_IPLT); |
3918 |
Elf32_External_Rela *loc; |
rel.r_addend = 0; |
|
|
|
|
/* Create a dynamic IPLT relocation for this entry. */ |
|
|
rel.r_offset = (h->plt.offset |
|
|
+ htab->splt->output_offset |
|
|
+ htab->splt->output_section->vma); |
|
|
if (h->dynindx != -1) |
|
|
{ |
|
|
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_IPLT); |
|
|
rel.r_addend = 0; |
|
|
} |
|
|
else |
|
|
{ |
|
|
/* This symbol has been marked to become local, and is |
|
|
used by a plabel so must be kept in the .plt. */ |
|
|
rel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT); |
|
|
rel.r_addend = value; |
|
|
} |
|
|
|
|
|
loc = (Elf32_External_Rela *) htab->srelplt->contents; |
|
|
loc += htab->srelplt->reloc_count++; |
|
|
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, |
|
|
&rel, loc); |
|
3919 |
} |
} |
3920 |
else |
else |
3921 |
{ |
{ |
3922 |
bfd_put_32 (htab->splt->owner, |
/* This symbol has been marked to become local, and is |
3923 |
value, |
used by a plabel so must be kept in the .plt. */ |
3924 |
htab->splt->contents + h->plt.offset); |
rel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT); |
3925 |
bfd_put_32 (htab->splt->owner, |
rel.r_addend = value; |
|
elf_gp (htab->splt->output_section->owner), |
|
|
htab->splt->contents + h->plt.offset + 4); |
|
3926 |
} |
} |
3927 |
|
|
3928 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
loc = htab->srelplt->contents; |
3929 |
|
loc += htab->srelplt->reloc_count++ * sizeof (Elf32_External_Rela); |
3930 |
|
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, &rel, loc); |
3931 |
|
|
3932 |
|
if (!h->def_regular) |
3933 |
{ |
{ |
3934 |
/* Mark the symbol as undefined, rather than as defined in |
/* Mark the symbol as undefined, rather than as defined in |
3935 |
the .plt section. Leave the value alone. */ |
the .plt section. Leave the value alone. */ |
3939 |
|
|
3940 |
if (h->got.offset != (bfd_vma) -1) |
if (h->got.offset != (bfd_vma) -1) |
3941 |
{ |
{ |
|
Elf_Internal_Rela rel; |
|
|
Elf32_External_Rela *loc; |
|
|
|
|
3942 |
/* This symbol has an entry in the global offset table. Set it |
/* This symbol has an entry in the global offset table. Set it |
3943 |
up. */ |
up. */ |
3944 |
|
|
3953 |
relocate_section function. */ |
relocate_section function. */ |
3954 |
if (info->shared |
if (info->shared |
3955 |
&& (info->symbolic || h->dynindx == -1) |
&& (info->symbolic || h->dynindx == -1) |
3956 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) |
&& h->def_regular) |
3957 |
{ |
{ |
3958 |
rel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32); |
rel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32); |
3959 |
rel.r_addend = (h->root.u.def.value |
rel.r_addend = (h->root.u.def.value |
3964 |
{ |
{ |
3965 |
if ((h->got.offset & 1) != 0) |
if ((h->got.offset & 1) != 0) |
3966 |
abort (); |
abort (); |
3967 |
bfd_put_32 (output_bfd, (bfd_vma) 0, |
bfd_put_32 (output_bfd, 0, htab->sgot->contents + h->got.offset); |
|
htab->sgot->contents + h->got.offset); |
|
3968 |
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_DIR32); |
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_DIR32); |
3969 |
rel.r_addend = 0; |
rel.r_addend = 0; |
3970 |
} |
} |
3971 |
|
|
3972 |
loc = (Elf32_External_Rela *) htab->srelgot->contents; |
loc = htab->srelgot->contents; |
3973 |
loc += htab->srelgot->reloc_count++; |
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela); |
3974 |
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); |
3975 |
} |
} |
3976 |
|
|
3977 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) |
if (h->needs_copy) |
3978 |
{ |
{ |
3979 |
asection *s; |
asection *s; |
|
Elf_Internal_Rela rel; |
|
|
Elf32_External_Rela *loc; |
|
3980 |
|
|
3981 |
/* This symbol needs a copy reloc. Set it up. */ |
/* This symbol needs a copy reloc. Set it up. */ |
3982 |
|
|
3992 |
+ h->root.u.def.section->output_section->vma); |
+ h->root.u.def.section->output_section->vma); |
3993 |
rel.r_addend = 0; |
rel.r_addend = 0; |
3994 |
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY); |
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY); |
3995 |
loc = (Elf32_External_Rela *) s->contents + s->reloc_count++; |
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); |
3996 |
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); |
3997 |
} |
} |
3998 |
|
|
4004 |
sym->st_shndx = SHN_ABS; |
sym->st_shndx = SHN_ABS; |
4005 |
} |
} |
4006 |
|
|
4007 |
return true; |
return TRUE; |
4008 |
} |
} |
4009 |
|
|
4010 |
/* Used to decide how to sort relocs in an optimal manner for the |
/* Used to decide how to sort relocs in an optimal manner for the |
4011 |
dynamic linker, before writing them out. */ |
dynamic linker, before writing them out. */ |
4012 |
|
|
4013 |
static enum elf_reloc_type_class |
static enum elf_reloc_type_class |
4014 |
elf32_hppa_reloc_type_class (rela) |
elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela) |
|
const Elf_Internal_Rela *rela; |
|
4015 |
{ |
{ |
4016 |
if (ELF32_R_SYM (rela->r_info) == 0) |
if (ELF32_R_SYM (rela->r_info) == 0) |
4017 |
return reloc_class_relative; |
return reloc_class_relative; |
4029 |
|
|
4030 |
/* Finish up the dynamic sections. */ |
/* Finish up the dynamic sections. */ |
4031 |
|
|
4032 |
static boolean |
static bfd_boolean |
4033 |
elf32_hppa_finish_dynamic_sections (output_bfd, info) |
elf32_hppa_finish_dynamic_sections (bfd *output_bfd, |
4034 |
bfd *output_bfd; |
struct bfd_link_info *info) |
|
struct bfd_link_info *info; |
|
4035 |
{ |
{ |
4036 |
bfd *dynobj; |
bfd *dynobj; |
4037 |
struct elf32_hppa_link_hash_table *htab; |
struct elf32_hppa_link_hash_table *htab; |
4050 |
abort (); |
abort (); |
4051 |
|
|
4052 |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
4053 |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); |
4054 |
for (; dyncon < dynconend; dyncon++) |
for (; dyncon < dynconend; dyncon++) |
4055 |
{ |
{ |
4056 |
Elf_Internal_Dyn dyn; |
Elf_Internal_Dyn dyn; |
4075 |
|
|
4076 |
case DT_PLTRELSZ: |
case DT_PLTRELSZ: |
4077 |
s = htab->srelplt; |
s = htab->srelplt; |
4078 |
if (s->_cooked_size != 0) |
dyn.d_un.d_val = s->size; |
|
dyn.d_un.d_val = s->_cooked_size; |
|
|
else |
|
|
dyn.d_un.d_val = s->_raw_size; |
|
4079 |
break; |
break; |
4080 |
|
|
4081 |
case DT_RELASZ: |
case DT_RELASZ: |
4082 |
/* Don't count procedure linkage table relocs in the |
/* Don't count procedure linkage table relocs in the |
4083 |
overall reloc count. */ |
overall reloc count. */ |
4084 |
if (htab->srelplt != NULL) |
s = htab->srelplt; |
4085 |
{ |
if (s == NULL) |
4086 |
s = htab->srelplt->output_section; |
continue; |
4087 |
if (s->_cooked_size != 0) |
dyn.d_un.d_val -= s->size; |
4088 |
dyn.d_un.d_val -= s->_cooked_size; |
break; |
4089 |
else |
|
4090 |
dyn.d_un.d_val -= s->_raw_size; |
case DT_RELA: |
4091 |
} |
/* We may not be using the standard ELF linker script. |
4092 |
|
If .rela.plt is the first .rela section, we adjust |
4093 |
|
DT_RELA to not include it. */ |
4094 |
|
s = htab->srelplt; |
4095 |
|
if (s == NULL) |
4096 |
|
continue; |
4097 |
|
if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset) |
4098 |
|
continue; |
4099 |
|
dyn.d_un.d_ptr += s->size; |
4100 |
break; |
break; |
4101 |
} |
} |
4102 |
|
|
4104 |
} |
} |
4105 |
} |
} |
4106 |
|
|
4107 |
if (htab->sgot != NULL && htab->sgot->_raw_size != 0) |
if (htab->sgot != NULL && htab->sgot->size != 0) |
4108 |
{ |
{ |
4109 |
/* Fill in the first entry in the global offset table. |
/* Fill in the first entry in the global offset table. |
4110 |
We use it to point to our dynamic section, if we have one. */ |
We use it to point to our dynamic section, if we have one. */ |
4111 |
bfd_put_32 (output_bfd, |
bfd_put_32 (output_bfd, |
4112 |
(sdyn != NULL |
sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0, |
|
? sdyn->output_section->vma + sdyn->output_offset |
|
|
: (bfd_vma) 0), |
|
4113 |
htab->sgot->contents); |
htab->sgot->contents); |
4114 |
|
|
4115 |
/* The second entry is reserved for use by the dynamic linker. */ |
/* The second entry is reserved for use by the dynamic linker. */ |
4120 |
->this_hdr.sh_entsize = GOT_ENTRY_SIZE; |
->this_hdr.sh_entsize = GOT_ENTRY_SIZE; |
4121 |
} |
} |
4122 |
|
|
4123 |
if (htab->splt != NULL && htab->splt->_raw_size != 0) |
if (htab->splt != NULL && htab->splt->size != 0) |
4124 |
{ |
{ |
4125 |
/* Set plt entry size. */ |
/* Set plt entry size. */ |
4126 |
elf_section_data (htab->splt->output_section) |
elf_section_data (htab->splt->output_section) |
4130 |
{ |
{ |
4131 |
/* Set up the .plt stub. */ |
/* Set up the .plt stub. */ |
4132 |
memcpy (htab->splt->contents |
memcpy (htab->splt->contents |
4133 |
+ htab->splt->_raw_size - sizeof (plt_stub), |
+ htab->splt->size - sizeof (plt_stub), |
4134 |
plt_stub, sizeof (plt_stub)); |
plt_stub, sizeof (plt_stub)); |
4135 |
|
|
4136 |
if ((htab->splt->output_offset |
if ((htab->splt->output_offset |
4137 |
+ htab->splt->output_section->vma |
+ htab->splt->output_section->vma |
4138 |
+ htab->splt->_raw_size) |
+ htab->splt->size) |
4139 |
!= (htab->sgot->output_offset |
!= (htab->sgot->output_offset |
4140 |
+ htab->sgot->output_section->vma)) |
+ htab->sgot->output_section->vma)) |
4141 |
{ |
{ |
4142 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
4143 |
(_(".got section not immediately after .plt section")); |
(_(".got section not immediately after .plt section")); |
4144 |
return false; |
return FALSE; |
4145 |
} |
} |
4146 |
} |
} |
4147 |
} |
} |
4148 |
|
|
4149 |
return true; |
return TRUE; |
4150 |
} |
} |
4151 |
|
|
4152 |
/* Tweak the OSABI field of the elf header. */ |
/* Tweak the OSABI field of the elf header. */ |
4153 |
|
|
4154 |
static void |
static void |
4155 |
elf32_hppa_post_process_headers (abfd, link_info) |
elf32_hppa_post_process_headers (bfd *abfd, |
4156 |
bfd *abfd; |
struct bfd_link_info *info ATTRIBUTE_UNUSED) |
|
struct bfd_link_info *link_info ATTRIBUTE_UNUSED; |
|
4157 |
{ |
{ |
4158 |
Elf_Internal_Ehdr * i_ehdrp; |
Elf_Internal_Ehdr * i_ehdrp; |
4159 |
|
|
4163 |
{ |
{ |
4164 |
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX; |
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX; |
4165 |
} |
} |
4166 |
|
else if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0) |
4167 |
|
{ |
4168 |
|
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_NETBSD; |
4169 |
|
} |
4170 |
else |
else |
4171 |
{ |
{ |
4172 |
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX; |
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX; |
4176 |
/* Called when writing out an object file to decide the type of a |
/* Called when writing out an object file to decide the type of a |
4177 |
symbol. */ |
symbol. */ |
4178 |
static int |
static int |
4179 |
elf32_hppa_elf_get_symbol_type (elf_sym, type) |
elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type) |
|
Elf_Internal_Sym *elf_sym; |
|
|
int type; |
|
4180 |
{ |
{ |
4181 |
if (ELF_ST_TYPE (elf_sym->st_info) == STT_PARISC_MILLI) |
if (ELF_ST_TYPE (elf_sym->st_info) == STT_PARISC_MILLI) |
4182 |
return STT_PARISC_MILLI; |
return STT_PARISC_MILLI; |
4194 |
#define bfd_elf32_bfd_final_link elf32_hppa_final_link |
#define bfd_elf32_bfd_final_link elf32_hppa_final_link |
4195 |
#define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create |
#define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create |
4196 |
#define bfd_elf32_bfd_link_hash_table_free elf32_hppa_link_hash_table_free |
#define bfd_elf32_bfd_link_hash_table_free elf32_hppa_link_hash_table_free |
|
#define elf_backend_add_symbol_hook elf32_hppa_add_symbol_hook |
|
4197 |
#define elf_backend_adjust_dynamic_symbol elf32_hppa_adjust_dynamic_symbol |
#define elf_backend_adjust_dynamic_symbol elf32_hppa_adjust_dynamic_symbol |
4198 |
#define elf_backend_copy_indirect_symbol elf32_hppa_copy_indirect_symbol |
#define elf_backend_copy_indirect_symbol elf32_hppa_copy_indirect_symbol |
4199 |
#define elf_backend_check_relocs elf32_hppa_check_relocs |
#define elf_backend_check_relocs elf32_hppa_check_relocs |
4206 |
#define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections |
#define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections |
4207 |
#define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook |
#define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook |
4208 |
#define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook |
#define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook |
4209 |
|
#define elf_backend_grok_prstatus elf32_hppa_grok_prstatus |
4210 |
|
#define elf_backend_grok_psinfo elf32_hppa_grok_psinfo |
4211 |
#define elf_backend_object_p elf32_hppa_object_p |
#define elf_backend_object_p elf32_hppa_object_p |
4212 |
#define elf_backend_final_write_processing elf_hppa_final_write_processing |
#define elf_backend_final_write_processing elf_hppa_final_write_processing |
4213 |
#define elf_backend_post_process_headers elf32_hppa_post_process_headers |
#define elf_backend_post_process_headers elf32_hppa_post_process_headers |
4221 |
#define elf_backend_plt_readonly 0 |
#define elf_backend_plt_readonly 0 |
4222 |
#define elf_backend_want_plt_sym 0 |
#define elf_backend_want_plt_sym 0 |
4223 |
#define elf_backend_got_header_size 8 |
#define elf_backend_got_header_size 8 |
4224 |
|
#define elf_backend_rela_normal 1 |
4225 |
|
|
4226 |
#define TARGET_BIG_SYM bfd_elf32_hppa_vec |
#define TARGET_BIG_SYM bfd_elf32_hppa_vec |
4227 |
#define TARGET_BIG_NAME "elf32-hppa" |
#define TARGET_BIG_NAME "elf32-hppa" |
4238 |
|
|
4239 |
#define INCLUDED_TARGET_FILE 1 |
#define INCLUDED_TARGET_FILE 1 |
4240 |
#include "elf32-target.h" |
#include "elf32-target.h" |
4241 |
|
|
4242 |
|
#undef TARGET_BIG_SYM |
4243 |
|
#define TARGET_BIG_SYM bfd_elf32_hppa_nbsd_vec |
4244 |
|
#undef TARGET_BIG_NAME |
4245 |
|
#define TARGET_BIG_NAME "elf32-hppa-netbsd" |
4246 |
|
|
4247 |
|
#include "elf32-target.h" |