]> Git Repo - binutils.git/blame - bfd/elf32-hppa.c
* sparc-nat.c (fetch_inferior_registers, store_inferior_registers):
[binutils.git] / bfd / elf32-hppa.c
CommitLineData
4c85cbfa 1/* BFD back-end for HP PA-RISC ELF files.
4991ebb9 2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4c85cbfa
KR
3
4 Written by
e8f2240a 5
4c85cbfa
KR
6 Center for Software Science
7 Department of Computer Science
8 University of Utah
9
10This file is part of BFD, the Binary File Descriptor library.
11
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26#include "bfd.h"
27#include "sysdep.h"
28#include "libbfd.h"
29#include "obstack.h"
4991ebb9 30#include "bfdlink.h"
4c85cbfa
KR
31#include "libelf.h"
32
4c85cbfa
KR
33/* ELF32/HPPA relocation support
34
35 This file contains ELF32/HPPA relocation support as specified
36 in the Stratus FTX/Golf Object File Format (SED-1762) dated
37 November 19, 1992.
38*/
39
4c85cbfa 40#include "elf32-hppa.h"
d9ad93bc 41#include "libhppa.h"
e8f2240a 42#include "aout/aout64.h"
d9ad93bc 43#include "hppa_stubs.h"
4c85cbfa
KR
44
45/* ELF/PA relocation howto entries */
46
4991ebb9
ILT
47static bfd_reloc_status_type hppa_elf_reloc
48 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
4c85cbfa 49
d9ad93bc 50static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
4c85cbfa 51{
e8f2240a
KR
52/* 'bitpos' and 'abs' are obsolete */
53/* type rs sz bsz pcrel bpos abs ovrf sf name */
54/* 9.3.4. Address relocation types */
d9ad93bc
KR
55 {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"},
56 {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"},
57 {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"},
58 {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"},
59 {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"},
60{R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"},
61{R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"},
62{R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"},
63{R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"},
64 {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"},
65 {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"},
66 {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"},
67 {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"},
68 {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"},
69 {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"},
70 {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"},
71 {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"},
72 {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"},
73 {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"},
74 {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"},
e8f2240a 75/* 9.3.5. GOTOFF address relocation types */
d9ad93bc
KR
76 {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
77 {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
78 {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
79 {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
80 {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
81 {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
82 {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
83 {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
84 {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
85 {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
86 {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
87 {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
88 {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
e8f2240a 89/* 9.3.6. Absolute call relocation types */
d9ad93bc
KR
90 {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
91 {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
92 {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
93 {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
94 {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
95 {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
96 {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
97 {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
98 {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
99 {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
100 {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
101 {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
102 {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
103 {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
104 {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
105 {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
106 {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
107 {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
e8f2240a 108/* 9.3.7. PC-relative call relocation types */
d9ad93bc
KR
109 {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
110 {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
111 {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
112 {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
113 {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
114 {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
115 {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
116 {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
117 {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
118 {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
119 {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
120 {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
121 {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
122 {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
123 {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
124 {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
125 {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
126 {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
127 {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
e8f2240a
KR
128
129/* 9.3.8. Plabel relocation types */
4861ac76
JL
130 {R_HPPA_PLABEL_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
131 {R_HPPA_PLABEL_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
132 {R_HPPA_PLABEL_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
133 {R_HPPA_PLABEL_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
134 {R_HPPA_PLABEL_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
135 {R_HPPA_PLABEL_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
e8f2240a
KR
136
137/* 9.3.9. Data linkage table (DLT) relocation types */
4861ac76
JL
138 {R_HPPA_DLT_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"},
139 {R_HPPA_DLT_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"},
140 {R_HPPA_DLT_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"},
141 {R_HPPA_DLT_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"},
142 {R_HPPA_DLT_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"},
143 {R_HPPA_DLT_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"},
e8f2240a
KR
144
145/* 9.3.10. Relocations for unwinder tables */
d9ad93bc
KR
146 {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
147 {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
e8f2240a
KR
148
149/* 9.3.11. Relocation types for complex expressions */
d9ad93bc
KR
150 {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
151 {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
152 {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
153 {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
154 {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
155 {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
156 {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
157{R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"},
158{R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"},
159{R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"},
160{R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"},
161 {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"},
162{R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"},
163{R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"},
164{R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"},
165 {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"},
166{R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"},
167{R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"},
168 {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"},
169 {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
170 {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
171{R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"},
172 {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"},
173 {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"},
174 {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
175 {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
176 {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
177 {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
178 {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
179 {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
180
181 {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"},
182 {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"},
183 {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"},
184 {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"},
185 {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"},
186 {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"},
187 {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"},
188 {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"},
e8f2240a 189};
4c85cbfa 190
d9ad93bc
KR
191static symext_chainS *symext_rootP;
192static symext_chainS *symext_lastP;
7218bb04 193static boolean symext_chain_built;
4c85cbfa 194
e8f2240a
KR
195static unsigned long
196DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format),
197 bfd * abfd AND
198 unsigned long insn AND
199 unsigned long value AND
200 unsigned short r_type AND
201 unsigned short r_field AND
202 unsigned short r_format)
203{
204 unsigned long const_part; /* part of the instruction that does not change */
205 unsigned long rebuilt_part;
206
207 switch (r_format)
208 {
209 case 11:
210 {
211 unsigned w1, w;
212
213 const_part = insn & 0xffffe002;
214 dis_assemble_12 (value, &w1, &w);
215 rebuilt_part = (w1 << 2) | w;
216 return const_part | rebuilt_part;
217 }
218
219 case 12:
220 {
221 unsigned w1, w;
222
223 const_part = insn & 0xffffe002;
224 dis_assemble_12 (value, &w1, &w);
225 rebuilt_part = (w1 << 2) | w;
226 return const_part | rebuilt_part;
227 }
228
229 case 14:
230 const_part = insn & 0xffffc000;
231 low_sign_unext (value, 14, &rebuilt_part);
232 return const_part | rebuilt_part;
233
234 case 17:
235 {
236 unsigned w1, w2, w;
237
238 const_part = insn & 0xffe0e002;
239 dis_assemble_17 (value, &w1, &w2, &w);
240 rebuilt_part = (w2 << 2) | (w1 << 16) | w;
241 return const_part | rebuilt_part;
242 }
243
244 case 21:
245 const_part = insn & 0xffe00000;
246 dis_assemble_21 (value, &rebuilt_part);
247 return const_part | rebuilt_part;
248
249 case 32:
250 const_part = 0;
251 return value;
252
253 default:
254 fprintf (stderr, "Relocation problem : ");
255 fprintf (stderr,
256 "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
257 r_type, r_format, r_field, abfd->filename);
258 }
259 return insn;
4c85cbfa
KR
260}
261
262static unsigned long
e8f2240a
KR
263DEFUN (hppa_elf_relocate_insn,
264 (abfd, input_sect,
265 insn, address, symp, sym_value, r_addend,
266 r_type, r_format, r_field, pcrel),
267 bfd * abfd AND
268 asection * input_sect AND
269 unsigned long insn AND
270 unsigned long address AND
271 asymbol * symp AND
272 long sym_value AND
273 long r_addend AND
274 unsigned short r_type AND
275 unsigned short r_format AND
276 unsigned short r_field AND
277 unsigned char pcrel)
4c85cbfa 278{
e8f2240a
KR
279 unsigned char opcode = get_opcode (insn);
280 long constant_value;
281 unsigned arg_reloc;
282
283 switch (opcode)
284 {
285 case LDO:
286 case LDB:
287 case LDH:
288 case LDW:
289 case LDWM:
290 case STB:
291 case STH:
292 case STW:
293 case STWM:
7218bb04 294 constant_value = HPPA_R_CONSTANT (r_addend);
e8f2240a
KR
295 BFD_ASSERT (r_format == 14);
296
297 if (pcrel)
298 sym_value -= address;
299 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
d9ad93bc 300 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
e8f2240a
KR
301
302 case COMICLR:
303 case SUBI: /* case SUBIO: */
304 case ADDIT: /* case ADDITO: */
305 case ADDI: /* case ADDIO: */
306 BFD_ASSERT (r_format == 11);
307
7218bb04 308 constant_value = HPPA_R_CONSTANT(r_addend);
e8f2240a
KR
309 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
310 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
311
312 case LDIL:
313 case ADDIL:
314 BFD_ASSERT (r_format == 21);
315
7218bb04 316 constant_value = HPPA_R_CONSTANT (r_addend);
e8f2240a
KR
317 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
318 return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
319
320 case BL:
321 case BE:
322 case BLE:
7218bb04 323 arg_reloc = HPPA_R_ARG_RELOC (r_addend);
e8f2240a
KR
324
325 BFD_ASSERT (r_format == 17);
326
327 /* XXX computing constant_value is not needed??? */
328 constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
329 (insn & 0x00001ffc) >> 2,
330 insn & 1);
331 /* @@ Assumes only 32 bits. */
332 constant_value = (constant_value << 15) >> 15;
333 if (pcrel)
334 {
335 sym_value -=
336 address + input_sect->output_offset
337 + input_sect->output_section->vma;
338 sym_value = hppa_field_adjust (sym_value, -8, r_field);
339 }
340 else
341 sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
4c85cbfa 342
e8f2240a 343 return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
4c85cbfa 344
e8f2240a
KR
345 default:
346 if (opcode == 0)
347 {
348 BFD_ASSERT (r_format == 32);
7218bb04 349 constant_value = HPPA_R_CONSTANT (r_addend);
e8f2240a
KR
350
351 return hppa_field_adjust (sym_value, constant_value, r_field);
352 }
353 else
354 {
355 fprintf (stderr,
356 "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
357 opcode, r_format, r_field);
358 return insn;
4c85cbfa 359 }
e8f2240a 360 }
4c85cbfa
KR
361}
362
363static void
e8f2240a
KR
364DEFUN (hppa_elf_relocate_unwind_table,
365 (abfd, input_sect,
366 data, address, symp, sym_value, r_addend,
367 r_type, r_format, r_field, pcrel),
368 bfd * abfd AND
369 asection * input_sect AND
370 PTR data AND
371 unsigned long address AND
372 asymbol * symp AND
373 long sym_value AND
374 long r_addend AND
375 unsigned short r_type AND
376 unsigned short r_format AND
377 unsigned short r_field AND
378 unsigned char pcrel)
4c85cbfa 379{
e8f2240a
KR
380 bfd_byte *hit_data = address + (bfd_byte *) (data);
381 long start_offset;
382 long end_offset;
383 long relocated_value;
384 int i;
385
386 BFD_ASSERT (r_format == 32);
387 BFD_ASSERT (r_field == e_fsel);
388 switch (r_type)
389 {
390 case R_HPPA_UNWIND_ENTRY:
391 start_offset = bfd_get_32 (abfd, hit_data);
392 relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
393 bfd_put_32 (abfd, relocated_value, hit_data);
394
395 hit_data += sizeof (unsigned long);
396 end_offset = bfd_get_32 (abfd, hit_data);
397 relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
398 bfd_put_32 (abfd, relocated_value, hit_data);
399 break;
400
401 case R_HPPA_UNWIND_ENTRIES:
402 for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
403 {
d9ad93bc 404 unsigned int adjustment;
e8f2240a
KR
405 start_offset = bfd_get_32 (abfd, hit_data);
406 /* Stuff the symbol value into the first word */
407 /* of the unwind descriptor */
408 bfd_put_32 (abfd, sym_value, hit_data);
d9ad93bc 409 adjustment = sym_value - start_offset;
e8f2240a
KR
410
411 hit_data += sizeof (unsigned long);
d9ad93bc
KR
412 end_offset = adjustment + bfd_get_32 (abfd, hit_data);
413 bfd_put_32 (abfd, end_offset, hit_data);
e8f2240a
KR
414
415 /* If this is not the last unwind entry, */
416 /* adjust the symbol value. */
417 if (i + 1 < r_addend)
418 {
419 start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
d9ad93bc 420 sym_value = start_offset + adjustment;
e8f2240a 421 }
4c85cbfa 422 }
e8f2240a
KR
423 break;
424
425 default:
426 fprintf (stderr,
427 "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
428 r_type, r_format, r_field);
429 }
4c85cbfa
KR
430}
431
432/* Provided the symbol, returns the value reffed */
e8f2240a
KR
433static long
434get_symbol_value (symbol)
435 asymbol *symbol;
436{
437 long relocation = 0;
438
439 if (symbol == (asymbol *) NULL)
440 relocation = 0;
441 else if (symbol->section == &bfd_com_section)
442 {
443 relocation = 0;
444 }
445 else
446 {
447 relocation = symbol->value +
448 symbol->section->output_section->vma +
449 symbol->section->output_offset;
450 }
451
452 return (relocation);
4c85cbfa
KR
453}
454
455/* This function provides a pretty straight-forward mapping between a */
456/* base relocation type, format and field into the relocation type */
457/* that will be emitted in an object file. The only wrinkle in the */
458/* mapping is that when the T, TR, TL, P, PR, or PL expression */
459/* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
460/* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
461/* (in the case of P, PR, and PL). */
462
463/* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
464/* handled yet. */
465
466static void
e8f2240a
KR
467hppa_elf_gen_reloc_error (base_type, fmt, field)
468 elf32_hppa_reloc_type base_type;
469 int fmt;
470 int field;
4c85cbfa 471{
e8f2240a
KR
472 fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
473 base_type, fmt, field);
4c85cbfa
KR
474}
475
e8f2240a
KR
476elf32_hppa_reloc_type **
477hppa_elf_gen_reloc_type (abfd, base_type, format, field)
478 bfd *abfd;
479 elf32_hppa_reloc_type base_type;
480 int format;
481 int field;
4c85cbfa 482{
d9ad93bc 483#define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field)
4c85cbfa 484
e8f2240a
KR
485 elf32_hppa_reloc_type *finaltype;
486 elf32_hppa_reloc_type **final_types;
487 int i;
488
489 final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
490 BFD_ASSERT (final_types != 0);
491
492 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
493 BFD_ASSERT (finaltype != 0);
494
495 final_types[0] = finaltype;
496 final_types[1] = NULL;
497
498#define final_type finaltype[0]
499
500 final_type = base_type;
501
502 switch (base_type)
503 {
504 case R_HPPA:
505 switch (format)
506 {
507 case 11:
508 switch (field)
509 {
510 case e_fsel:
511 final_type = R_HPPA_11;
512 break;
513 case e_rsel:
514 final_type = R_HPPA_R11;
515 break;
516 case e_rssel:
517 final_type = R_HPPA_RS11;
518 break;
519 case e_rdsel:
520 final_type = R_HPPA_RD11;
521 break;
522
523 case e_psel:
524 final_type = R_HPPA_PLABEL_11;
525 break;
526 case e_rpsel:
527 final_type = R_HPPA_PLABEL_R11;
528 break;
e8f2240a 529 case e_tsel:
a36b6f1d
JL
530 final_type = R_HPPA_DLT_11;
531 break;
e8f2240a 532 case e_rtsel:
a36b6f1d
JL
533 final_type = R_HPPA_DLT_R11;
534 break;
e8f2240a 535
a36b6f1d
JL
536 case e_lpsel:
537 case e_ltsel:
e8f2240a
KR
538 case e_lsel:
539 case e_lrsel:
540 case e_lssel:
541 case e_rrsel:
542 default:
543 UNDEFINED;
544 final_type = base_type;
545 break;
546 }
547 break;
548 case 12:
549 UNDEFINED;
550 break;
551 case 14:
552 switch (field)
553 {
554 case e_rsel:
555 final_type = R_HPPA_R14;
556 break;
557 case e_rssel:
558 final_type = R_HPPA_RS14;
559 break;
560 case e_rdsel:
561 final_type = R_HPPA_RD14;
562 break;
563 case e_rrsel:
564 final_type = R_HPPA_RR14;
565 break;
566
567 case e_psel:
568 final_type = R_HPPA_PLABEL_14;
569 break;
570 case e_rpsel:
571 final_type = R_HPPA_PLABEL_R14;
572 break;
e8f2240a 573 case e_tsel:
a36b6f1d
JL
574 final_type = R_HPPA_DLT_14;
575 break;
e8f2240a 576 case e_rtsel:
a36b6f1d
JL
577 final_type = R_HPPA_DLT_R14;
578 break;
579
580 case e_lpsel:
581 case e_ltsel:
e8f2240a
KR
582
583 case e_fsel:
584 case e_lsel:
585 case e_lssel:
586 case e_ldsel:
587 case e_lrsel:
588 default:
589 UNDEFINED;
590 final_type = base_type;
591 break;
592 }
593 break;
594 case 17:
595 switch (field)
596 {
597 case e_fsel:
598 final_type = R_HPPA_17;
599 break;
600 case e_rsel:
601 final_type = R_HPPA_R17;
602 break;
603 case e_rssel:
604 final_type = R_HPPA_RS17;
605 break;
606 case e_rdsel:
607 final_type = R_HPPA_RD17;
608 break;
609 case e_rrsel:
610 final_type = R_HPPA_RR17;
611 break;
612 case e_lsel:
613 case e_lssel:
614 case e_ldsel:
615 case e_lrsel:
616 default:
617 UNDEFINED;
618 final_type = base_type;
619 break;
620 }
621 break;
622 case 21:
623 switch (field)
624 {
625 case e_lsel:
626 final_type = R_HPPA_L21;
627 break;
628 case e_lssel:
629 final_type = R_HPPA_LS21;
630 break;
631 case e_ldsel:
632 final_type = R_HPPA_LD21;
633 break;
634 case e_lrsel:
635 final_type = R_HPPA_LR21;
636 break;
637 case e_lpsel:
638 final_type = R_HPPA_PLABEL_L21;
639 break;
a36b6f1d
JL
640 case e_ltsel:
641 final_type = R_HPPA_PLABEL_L21;
642 break;
e8f2240a
KR
643 case e_rsel:
644 case e_rssel:
645 case e_rdsel:
646 case e_rrsel:
647 case e_fsel:
648 default:
649 UNDEFINED;
650 final_type = base_type;
651 break;
652 }
653 break;
654 case 32:
655 switch (field)
656 {
657 case e_fsel:
658 final_type = R_HPPA_32;
659 break;
660 case e_psel:
661 final_type = R_HPPA_PLABEL_32;
662 break;
a36b6f1d 663 case e_tsel:
7a60ed8c 664 final_type = R_HPPA_DLT_32;
a36b6f1d 665 break;
e8f2240a
KR
666 default:
667 UNDEFINED;
668 final_type = base_type;
669 break;
670 }
671 break;
672 default:
673 UNDEFINED;
674 final_type = base_type;
675 break;
676 }
677 break;
678 case R_HPPA_GOTOFF:
679 switch (format)
680 {
681 case 11:
682 switch (field)
683 {
684 case e_rsel:
685 final_type = R_HPPA_GOTOFF_R11;
686 break;
687 case e_rssel:
688 final_type = R_HPPA_GOTOFF_RS11;
689 break;
690 case e_rdsel:
691 final_type = R_HPPA_GOTOFF_RD11;
692 break;
693 case e_fsel:
694 final_type = R_HPPA_GOTOFF_11;
695 break;
696 case e_lsel:
697 case e_lrsel:
698 case e_lssel:
699 case e_rrsel:
700 default:
701 UNDEFINED;
702 final_type = base_type;
703 break;
704 }
705 break;
706 case 12:
707 UNDEFINED;
708 final_type = base_type;
709 break;
710 case 14:
711 switch (field)
712 {
713 case e_rsel:
714 final_type = R_HPPA_GOTOFF_R14;
715 break;
716 case e_rssel:
717 final_type = R_HPPA_GOTOFF_RS14;
718 break;
719 case e_rdsel:
720 final_type = R_HPPA_GOTOFF_RD14;
721 break;
722 case e_rrsel:
723 final_type = R_HPPA_GOTOFF_RR14;
724 break;
725 case e_fsel:
726 final_type = R_HPPA_GOTOFF_14;
727 break;
728 case e_lsel:
729 case e_lssel:
730 case e_ldsel:
731 case e_lrsel:
732 default:
733 UNDEFINED;
734 final_type = base_type;
735 break;
736 }
737 break;
738 case 17:
739 UNDEFINED;
740 final_type = base_type;
741 break;
742 case 21:
743 switch (field)
744 {
745 case e_lsel:
746 final_type = R_HPPA_GOTOFF_L21;
747 break;
748 case e_lssel:
749 final_type = R_HPPA_GOTOFF_LS21;
750 break;
751 case e_ldsel:
752 final_type = R_HPPA_GOTOFF_LD21;
753 break;
754 case e_lrsel:
755 final_type = R_HPPA_GOTOFF_LR21;
756 break;
757 case e_rsel:
758 case e_rssel:
759 case e_rdsel:
760 case e_rrsel:
761 case e_fsel:
762 default:
763 UNDEFINED;
764 final_type = base_type;
765 break;
766 }
767 break;
768 case 32:
769 UNDEFINED;
770 final_type = base_type;
771 break;
772 default:
773 UNDEFINED;
774 final_type = base_type;
775 break;
776 }
777 break;
778 case R_HPPA_PCREL_CALL:
779 switch (format)
780 {
781 case 11:
782 switch (field)
783 {
784 case e_rsel:
785 final_type = R_HPPA_PCREL_CALL_R11;
786 break;
787 case e_rssel:
788 final_type = R_HPPA_PCREL_CALL_RS11;
789 break;
790 case e_rdsel:
791 final_type = R_HPPA_PCREL_CALL_RD11;
792 break;
793 case e_fsel:
794 final_type = R_HPPA_PCREL_CALL_11;
795 break;
796 case e_lsel:
797 case e_lrsel:
798 case e_lssel:
799 case e_rrsel:
800 default:
801 UNDEFINED;
802 final_type = base_type;
803 break;
804 }
805 break;
806 case 12:
807 UNDEFINED;
808 final_type = base_type;
809 break;
810 case 14:
811 switch (field)
812 {
813 case e_rsel:
814 final_type = R_HPPA_PCREL_CALL_R14;
815 break;
816 case e_rssel:
817 final_type = R_HPPA_PCREL_CALL_RS14;
818 break;
819 case e_rdsel:
820 final_type = R_HPPA_PCREL_CALL_RD14;
821 break;
822 case e_rrsel:
823 final_type = R_HPPA_PCREL_CALL_RR14;
824 break;
825 case e_fsel:
826 final_type = R_HPPA_PCREL_CALL_14;
827 break;
828 case e_lsel:
829 case e_lssel:
830 case e_ldsel:
831 case e_lrsel:
832 default:
833 UNDEFINED;
834 final_type = base_type;
835 break;
836 }
837 break;
838 case 17:
839 switch (field)
840 {
841 case e_rsel:
842 final_type = R_HPPA_PCREL_CALL_R17;
843 break;
844 case e_rssel:
845 final_type = R_HPPA_PCREL_CALL_RS17;
846 break;
847 case e_rdsel:
848 final_type = R_HPPA_PCREL_CALL_RD17;
849 break;
850 case e_rrsel:
851 final_type = R_HPPA_PCREL_CALL_RR17;
852 break;
853 case e_fsel:
854 final_type = R_HPPA_PCREL_CALL_17;
855 break;
856 case e_lsel:
857 case e_lssel:
858 case e_ldsel:
859 case e_lrsel:
860 default:
861 UNDEFINED;
862 final_type = base_type;
863 break;
864 }
865 break;
866 case 21:
867 switch (field)
868 {
869 case e_lsel:
870 final_type = R_HPPA_PCREL_CALL_L21;
871 break;
872 case e_lssel:
873 final_type = R_HPPA_PCREL_CALL_LS21;
874 break;
875 case e_ldsel:
876 final_type = R_HPPA_PCREL_CALL_LD21;
877 break;
878 case e_lrsel:
879 final_type = R_HPPA_PCREL_CALL_LR21;
880 break;
881 case e_rsel:
882 case e_rssel:
883 case e_rdsel:
884 case e_rrsel:
885 case e_fsel:
886 default:
887 UNDEFINED;
888 final_type = base_type;
889 break;
890 }
891 break;
892 case 32:
893 UNDEFINED;
894 final_type = base_type;
895 break;
896 default:
897 UNDEFINED;
898 final_type = base_type;
899 break;
900 }
901 break;
902 case R_HPPA_PLABEL:
903 switch (format)
904 {
905 case 11:
906 switch (field)
907 {
908 case e_fsel:
909 final_type = R_HPPA_PLABEL_11;
910 break;
911 case e_rsel:
912 final_type = R_HPPA_PLABEL_R11;
913 break;
914 default:
915 UNDEFINED;
916 final_type = base_type;
917 break;
918 }
919 break;
920 case 14:
921 switch (field)
922 {
923 case e_fsel:
924 final_type = R_HPPA_PLABEL_14;
925 break;
926 case e_rsel:
927 final_type = R_HPPA_PLABEL_R14;
928 break;
929 default:
930 UNDEFINED;
931 final_type = base_type;
932 break;
933 }
934 break;
935 case 21:
936 switch (field)
937 {
938 case e_lsel:
939 final_type = R_HPPA_PLABEL_L21;
940 break;
941 default:
942 UNDEFINED;
943 final_type = base_type;
944 break;
945 }
946 break;
947 case 32:
948 switch (field)
949 {
950 case e_fsel:
951 final_type = R_HPPA_PLABEL_32;
952 break;
953 default:
954 UNDEFINED;
955 final_type = base_type;
956 break;
957 }
958 break;
959 default:
960 UNDEFINED;
961 final_type = base_type;
962 break;
963 }
964 case R_HPPA_ABS_CALL:
965 switch (format)
966 {
967 case 11:
968 switch (field)
969 {
970 case e_rsel:
971 final_type = R_HPPA_ABS_CALL_R11;
972 break;
973 case e_rssel:
974 final_type = R_HPPA_ABS_CALL_RS11;
975 break;
976 case e_rdsel:
977 final_type = R_HPPA_ABS_CALL_RD11;
978 break;
979 case e_fsel:
980 final_type = R_HPPA_ABS_CALL_11;
981 break;
982 case e_lsel:
983 case e_lrsel:
984 case e_lssel:
985 case e_rrsel:
4c85cbfa 986 default:
e8f2240a
KR
987 UNDEFINED;
988 final_type = base_type;
989 break;
990 }
991 break;
992 case 12:
993 UNDEFINED;
994 final_type = base_type;
995 break;
996 case 14:
997 switch (field)
998 {
999 case e_rsel:
1000 final_type = R_HPPA_ABS_CALL_R14;
1001 break;
1002 case e_rssel:
1003 final_type = R_HPPA_ABS_CALL_RS14;
1004 break;
1005 case e_rdsel:
1006 final_type = R_HPPA_ABS_CALL_RD14;
1007 break;
1008 case e_rrsel:
1009 final_type = R_HPPA_ABS_CALL_RR14;
1010 break;
1011 case e_fsel:
1012 final_type = R_HPPA_ABS_CALL_14;
1013 break;
1014 case e_lsel:
1015 case e_lssel:
1016 case e_ldsel:
1017 case e_lrsel:
1018 default:
1019 UNDEFINED;
1020 final_type = base_type;
1021 break;
1022 }
1023 break;
1024 case 17:
1025 switch (field)
1026 {
1027 case e_rsel:
1028 final_type = R_HPPA_ABS_CALL_R17;
1029 break;
1030 case e_rssel:
1031 final_type = R_HPPA_ABS_CALL_RS17;
1032 break;
1033 case e_rdsel:
1034 final_type = R_HPPA_ABS_CALL_RD17;
1035 break;
1036 case e_rrsel:
1037 final_type = R_HPPA_ABS_CALL_RR17;
1038 break;
1039 case e_fsel:
1040 final_type = R_HPPA_ABS_CALL_17;
1041 break;
1042 case e_lsel:
1043 case e_lssel:
1044 case e_ldsel:
1045 case e_lrsel:
1046 default:
1047 UNDEFINED;
1048 final_type = base_type;
1049 break;
1050 }
1051 break;
1052 case 21:
1053 switch (field)
1054 {
1055 case e_lsel:
1056 final_type = R_HPPA_ABS_CALL_L21;
1057 break;
1058 case e_lssel:
1059 final_type = R_HPPA_ABS_CALL_LS21;
1060 break;
1061 case e_ldsel:
1062 final_type = R_HPPA_ABS_CALL_LD21;
1063 break;
1064 case e_lrsel:
1065 final_type = R_HPPA_ABS_CALL_LR21;
1066 break;
1067 case e_rsel:
1068 case e_rssel:
1069 case e_rdsel:
1070 case e_rrsel:
1071 case e_fsel:
1072 default:
1073 UNDEFINED;
1074 final_type = base_type;
1075 break;
1076 }
1077 break;
1078 case 32:
1079 UNDEFINED;
1080 final_type = base_type;
1081 break;
1082 default:
1083 UNDEFINED;
1084 final_type = base_type;
1085 break;
1086 }
1087 break;
1088 case R_HPPA_UNWIND:
1089 final_type = R_HPPA_UNWIND_ENTRY;
1090 break;
1091 case R_HPPA_COMPLEX:
1092 case R_HPPA_COMPLEX_PCREL_CALL:
1093 case R_HPPA_COMPLEX_ABS_CALL:
1094 final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 6);
1095 BFD_ASSERT (final_types != 0);
1096
1097 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
1098 BFD_ASSERT (finaltype != 0);
1099
1100 for (i = 0; i < 5; i++)
1101 final_types[i] = &finaltype[i];
1102
1103 final_types[5] = NULL;
1104
1105 finaltype[0] = R_HPPA_PUSH_SYM;
1106
1107 if (base_type == R_HPPA_COMPLEX)
1108 finaltype[1] = R_HPPA_PUSH_SYM;
1109 else if (base_type == R_HPPA_COMPLEX_PCREL_CALL)
1110 finaltype[1] = R_HPPA_PUSH_PCREL_CALL;
1111 else /* base_type == R_HPPA_COMPLEX_ABS_CALL */
1112 finaltype[1] = R_HPPA_PUSH_ABS_CALL;
1113
1114 finaltype[2] = R_HPPA_SUB;
1115
1116 switch (field)
1117 {
1118 case e_fsel:
1119 finaltype[3] = R_HPPA_EXPR_F;
1120 break;
1121 case e_lsel:
1122 finaltype[3] = R_HPPA_EXPR_L;
1123 break;
1124 case e_rsel:
1125 finaltype[3] = R_HPPA_EXPR_R;
1126 break;
1127 case e_lssel:
1128 finaltype[3] = R_HPPA_EXPR_LS;
1129 break;
1130 case e_rssel:
1131 finaltype[3] = R_HPPA_EXPR_RS;
1132 break;
1133 case e_ldsel:
1134 finaltype[3] = R_HPPA_EXPR_LD;
1135 break;
1136 case e_rdsel:
1137 finaltype[3] = R_HPPA_EXPR_RD;
1138 break;
1139 case e_lrsel:
1140 finaltype[3] = R_HPPA_EXPR_LR;
1141 break;
1142 case e_rrsel:
1143 finaltype[3] = R_HPPA_EXPR_RR;
1144 break;
4c85cbfa
KR
1145 }
1146
e8f2240a
KR
1147 switch (format)
1148 {
1149 case 11:
1150 finaltype[4] = R_HPPA_EXPR_11;
1151 break;
1152 case 12:
1153 finaltype[4] = R_HPPA_EXPR_12;
1154 break;
1155 case 14:
1156 finaltype[4] = R_HPPA_EXPR_14;
1157 break;
1158 case 17:
1159 finaltype[4] = R_HPPA_EXPR_17;
1160 break;
1161 case 21:
1162 finaltype[4] = R_HPPA_EXPR_21;
1163 break;
1164 case 32:
1165 finaltype[4] = R_HPPA_EXPR_32;
1166 break;
1167 }
1168
1169 break;
1170
1171 default:
1172 final_type = base_type;
1173 break;
1174 }
1175
1176 return final_types;
4c85cbfa
KR
1177}
1178
e8f2240a
KR
1179#undef final_type
1180
4c85cbfa
KR
1181
1182/* this function is in charge of performing all the HP PA relocations */
d9ad93bc
KR
1183static long global_value;
1184static long GOT_value; /* XXX: need to calculate this! For HPUX, GOT == DP */
1185static asymbol *global_symbol;
1186static int global_sym_defined;
4c85cbfa
KR
1187
1188static bfd_reloc_status_type
4991ebb9
ILT
1189hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
1190 error_message)
4861ac76
JL
1191 bfd *abfd;
1192 arelent *reloc_entry;
1193 asymbol *symbol_in;
1194 PTR data;
1195 asection *input_section;
1196 bfd *output_bfd;
4991ebb9 1197 char **error_message;
e8f2240a
KR
1198{
1199 unsigned long insn;
1200 long sym_value = 0;
4861ac76 1201 unsigned long addr = reloc_entry->address;
e8f2240a
KR
1202 bfd_byte *hit_data = addr + (bfd_byte *) (data);
1203 unsigned short r_type = reloc_entry->howto->type & 0xFF;
1204 unsigned short r_field = e_fsel;
1205 boolean r_pcrel = reloc_entry->howto->pc_relative;
e8f2240a
KR
1206 unsigned r_format = reloc_entry->howto->bitsize;
1207 long r_addend = reloc_entry->addend;
1208
e8f2240a
KR
1209 if (output_bfd)
1210 {
1211 /* Partial linking - do nothing */
1212 reloc_entry->address += input_section->output_offset;
1213 return bfd_reloc_ok;
1214 }
1215
4861ac76
JL
1216 /* If performing final link and the symbol we're relocating against
1217 is undefined, then return an error. */
e8f2240a
KR
1218 if (symbol_in && symbol_in->section == &bfd_und_section)
1219 return bfd_reloc_undefined;
1220
e8f2240a
KR
1221 sym_value = get_symbol_value (symbol_in);
1222
4861ac76 1223 /* Compute the value of $global$. */
d9ad93bc 1224 if (!global_sym_defined)
e8f2240a 1225 {
d9ad93bc 1226 if (global_symbol)
e8f2240a 1227 {
d9ad93bc
KR
1228 global_value = (global_symbol->value
1229 + global_symbol->section->output_section->vma
1230 + global_symbol->section->output_offset);
4861ac76 1231 GOT_value = global_value;
d9ad93bc 1232 global_sym_defined++;
e8f2240a
KR
1233 }
1234 }
1235
4861ac76 1236 /* Get the instruction word. */
e8f2240a
KR
1237 insn = bfd_get_32 (abfd, hit_data);
1238
4861ac76 1239 /* Relocate the value based on one of the basic relocation types
e8f2240a 1240
4861ac76
JL
1241 basic_type_1: relocation is relative to $global$
1242 basic_type_2: relocation is relative to the current GOT
1243 basic_type_3: relocation is an absolute call
1244 basic_type_4: relocation is an PC-relative call
1245 basic_type_5: relocation is plabel reference
1246 basic_type_6: relocation is an unwind table relocation
1247 extended_type: unimplemented */
e8f2240a
KR
1248
1249 switch (r_type)
1250 {
1251 case R_HPPA_NONE:
1252 break;
4861ac76
JL
1253
1254 /* Handle all the basic type 1 relocations. */
1255 case R_HPPA_32:
e8f2240a
KR
1256 r_field = e_fsel;
1257 goto do_basic_type_1;
4861ac76 1258 case R_HPPA_11:
e8f2240a
KR
1259 r_field = e_fsel;
1260 goto do_basic_type_1;
4861ac76 1261 case R_HPPA_14:
e8f2240a
KR
1262 r_field = e_fsel;
1263 goto do_basic_type_1;
4861ac76 1264 case R_HPPA_17:
e8f2240a
KR
1265 r_field = e_fsel;
1266 goto do_basic_type_1;
4861ac76 1267 case R_HPPA_L21:
e8f2240a
KR
1268 r_field = e_lsel;
1269 goto do_basic_type_1;
4861ac76 1270 case R_HPPA_R11:
e8f2240a
KR
1271 r_field = e_rsel;
1272 goto do_basic_type_1;
4861ac76 1273 case R_HPPA_R14:
e8f2240a
KR
1274 r_field = e_rsel;
1275 goto do_basic_type_1;
4861ac76 1276 case R_HPPA_R17:
e8f2240a
KR
1277 r_field = e_rsel;
1278 goto do_basic_type_1;
4861ac76 1279 case R_HPPA_LS21:
e8f2240a
KR
1280 r_field = e_lssel;
1281 goto do_basic_type_1;
4861ac76 1282 case R_HPPA_RS11:
e8f2240a
KR
1283 r_field = e_rssel;
1284 goto do_basic_type_1;
4861ac76 1285 case R_HPPA_RS14:
e8f2240a
KR
1286 r_field = e_rssel;
1287 goto do_basic_type_1;
4861ac76 1288 case R_HPPA_RS17:
e8f2240a
KR
1289 r_field = e_ldsel;
1290 goto do_basic_type_1;
4861ac76 1291 case R_HPPA_LD21:
e8f2240a
KR
1292 r_field = e_ldsel;
1293 goto do_basic_type_1;
4861ac76 1294 case R_HPPA_RD11:
e8f2240a
KR
1295 r_field = e_rdsel;
1296 goto do_basic_type_1;
4861ac76 1297 case R_HPPA_RD14:
e8f2240a
KR
1298 r_field = e_rdsel;
1299 goto do_basic_type_1;
4861ac76 1300 case R_HPPA_RD17:
e8f2240a
KR
1301 r_field = e_rdsel;
1302 goto do_basic_type_1;
4861ac76 1303 case R_HPPA_LR21:
e8f2240a
KR
1304 r_field = e_lrsel;
1305 goto do_basic_type_1;
4861ac76 1306 case R_HPPA_RR14:
e8f2240a
KR
1307 r_field = e_rrsel;
1308 goto do_basic_type_1;
4861ac76 1309 case R_HPPA_RR17:
e8f2240a
KR
1310 r_field = e_rrsel;
1311
1312 do_basic_type_1:
1313 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1314 symbol_in, sym_value, r_addend,
1315 r_type, r_format, r_field, r_pcrel);
1316 break;
1317
4861ac76
JL
1318 /* Handle all the basic type 2 relocations. */
1319 case R_HPPA_GOTOFF_11:
e8f2240a
KR
1320 r_field = e_fsel;
1321 goto do_basic_type_2;
4861ac76 1322 case R_HPPA_GOTOFF_14:
e8f2240a
KR
1323 r_field = e_fsel;
1324 goto do_basic_type_2;
4861ac76 1325 case R_HPPA_GOTOFF_L21:
e8f2240a
KR
1326 r_field = e_lsel;
1327 goto do_basic_type_2;
4861ac76 1328 case R_HPPA_GOTOFF_R11:
e8f2240a
KR
1329 r_field = e_rsel;
1330 goto do_basic_type_2;
4861ac76 1331 case R_HPPA_GOTOFF_R14:
e8f2240a
KR
1332 r_field = e_rsel;
1333 goto do_basic_type_2;
4861ac76 1334 case R_HPPA_GOTOFF_LS21:
e8f2240a
KR
1335 r_field = e_lssel;
1336 goto do_basic_type_2;
4861ac76 1337 case R_HPPA_GOTOFF_RS11:
e8f2240a
KR
1338 r_field = e_rssel;
1339 goto do_basic_type_2;
4861ac76 1340 case R_HPPA_GOTOFF_RS14:
e8f2240a
KR
1341 r_field = e_rssel;
1342 goto do_basic_type_2;
4861ac76 1343 case R_HPPA_GOTOFF_LD21:
e8f2240a
KR
1344 r_field = e_ldsel;
1345 goto do_basic_type_2;
4861ac76 1346 case R_HPPA_GOTOFF_RD11:
e8f2240a
KR
1347 r_field = e_rdsel;
1348 goto do_basic_type_2;
4861ac76 1349 case R_HPPA_GOTOFF_RD14:
e8f2240a
KR
1350 r_field = e_rdsel;
1351 goto do_basic_type_2;
4861ac76 1352 case R_HPPA_GOTOFF_LR21:
e8f2240a
KR
1353 r_field = e_lrsel;
1354 goto do_basic_type_2;
4861ac76 1355 case R_HPPA_GOTOFF_RR14:
e8f2240a 1356 r_field = e_rrsel;
4861ac76 1357
e8f2240a
KR
1358 do_basic_type_2:
1359 sym_value -= GOT_value;
1360 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1361 symbol_in, sym_value, r_addend,
1362 r_type, r_format, r_field, r_pcrel);
1363 break;
1364
4861ac76
JL
1365 /* Handle all the basic type 3 relocations. */
1366 case R_HPPA_ABS_CALL_11:
e8f2240a
KR
1367 r_field = e_fsel;
1368 goto do_basic_type_3;
4861ac76 1369 case R_HPPA_ABS_CALL_14:
e8f2240a
KR
1370 r_field = e_fsel;
1371 goto do_basic_type_3;
4861ac76 1372 case R_HPPA_ABS_CALL_17:
e8f2240a
KR
1373 r_field = e_fsel;
1374 goto do_basic_type_3;
4861ac76 1375 case R_HPPA_ABS_CALL_L21:
e8f2240a
KR
1376 r_field = e_lsel;
1377 goto do_basic_type_3;
4861ac76 1378 case R_HPPA_ABS_CALL_R11:
e8f2240a
KR
1379 r_field = e_rsel;
1380 goto do_basic_type_3;
4861ac76 1381 case R_HPPA_ABS_CALL_R14:
e8f2240a
KR
1382 r_field = e_rsel;
1383 goto do_basic_type_3;
4861ac76 1384 case R_HPPA_ABS_CALL_R17:
e8f2240a
KR
1385 r_field = e_rsel;
1386 goto do_basic_type_3;
4861ac76 1387 case R_HPPA_ABS_CALL_LS21:
e8f2240a
KR
1388 r_field = e_lssel;
1389 goto do_basic_type_3;
4861ac76 1390 case R_HPPA_ABS_CALL_RS11:
e8f2240a
KR
1391 r_field = e_lssel;
1392 goto do_basic_type_3;
4861ac76 1393 case R_HPPA_ABS_CALL_RS14:
e8f2240a
KR
1394 r_field = e_rssel;
1395 goto do_basic_type_3;
4861ac76 1396 case R_HPPA_ABS_CALL_RS17:
e8f2240a
KR
1397 r_field = e_rssel;
1398 goto do_basic_type_3;
4861ac76 1399 case R_HPPA_ABS_CALL_LD21:
e8f2240a
KR
1400 r_field = e_ldsel;
1401 goto do_basic_type_3;
4861ac76 1402 case R_HPPA_ABS_CALL_RD11:
e8f2240a
KR
1403 r_field = e_rdsel;
1404 goto do_basic_type_3;
4861ac76 1405 case R_HPPA_ABS_CALL_RD14:
e8f2240a
KR
1406 r_field = e_rdsel;
1407 goto do_basic_type_3;
4861ac76 1408 case R_HPPA_ABS_CALL_RD17:
e8f2240a
KR
1409 r_field = e_rdsel;
1410 goto do_basic_type_3;
4861ac76 1411 case R_HPPA_ABS_CALL_LR21:
e8f2240a
KR
1412 r_field = e_lrsel;
1413 goto do_basic_type_3;
4861ac76 1414 case R_HPPA_ABS_CALL_RR14:
e8f2240a
KR
1415 r_field = e_rrsel;
1416 goto do_basic_type_3;
4861ac76 1417 case R_HPPA_ABS_CALL_RR17:
e8f2240a 1418 r_field = e_rrsel;
4861ac76 1419
e8f2240a
KR
1420 do_basic_type_3:
1421 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1422 symbol_in, sym_value, r_addend,
1423 r_type, r_format, r_field, r_pcrel);
1424 break;
1425
4861ac76
JL
1426 /* Handle all the basic type 4 relocations. */
1427 case R_HPPA_PCREL_CALL_11:
e8f2240a
KR
1428 r_field = e_fsel;
1429 goto do_basic_type_4;
4861ac76 1430 case R_HPPA_PCREL_CALL_14:
e8f2240a
KR
1431 r_field = e_fsel;
1432 goto do_basic_type_4;
4861ac76 1433 case R_HPPA_PCREL_CALL_17:
e8f2240a
KR
1434 r_field = e_fsel;
1435 goto do_basic_type_4;
4861ac76 1436 case R_HPPA_PCREL_CALL_L21:
e8f2240a
KR
1437 r_field = e_lsel;
1438 goto do_basic_type_4;
4861ac76 1439 case R_HPPA_PCREL_CALL_R11:
e8f2240a
KR
1440 r_field = e_rsel;
1441 goto do_basic_type_4;
4861ac76 1442 case R_HPPA_PCREL_CALL_R14:
e8f2240a
KR
1443 r_field = e_rsel;
1444 goto do_basic_type_4;
4861ac76 1445 case R_HPPA_PCREL_CALL_R17:
e8f2240a
KR
1446 r_field = e_rsel;
1447 goto do_basic_type_4;
4861ac76 1448 case R_HPPA_PCREL_CALL_LS21:
e8f2240a
KR
1449 r_field = e_lssel;
1450 goto do_basic_type_4;
4861ac76 1451 case R_HPPA_PCREL_CALL_RS11:
e8f2240a
KR
1452 r_field = e_rssel;
1453 goto do_basic_type_4;
4861ac76 1454 case R_HPPA_PCREL_CALL_RS14:
e8f2240a
KR
1455 r_field = e_rssel;
1456 goto do_basic_type_4;
4861ac76 1457 case R_HPPA_PCREL_CALL_RS17:
e8f2240a
KR
1458 r_field = e_rssel;
1459 goto do_basic_type_4;
4861ac76 1460 case R_HPPA_PCREL_CALL_LD21:
e8f2240a
KR
1461 r_field = e_ldsel;
1462 goto do_basic_type_4;
4861ac76 1463 case R_HPPA_PCREL_CALL_RD11:
e8f2240a
KR
1464 r_field = e_rdsel;
1465 goto do_basic_type_4;
4861ac76 1466 case R_HPPA_PCREL_CALL_RD14:
e8f2240a
KR
1467 r_field = e_rdsel;
1468 goto do_basic_type_4;
4861ac76 1469 case R_HPPA_PCREL_CALL_RD17:
e8f2240a
KR
1470 r_field = e_rdsel;
1471 goto do_basic_type_4;
4861ac76 1472 case R_HPPA_PCREL_CALL_LR21:
e8f2240a
KR
1473 r_field = e_lrsel;
1474 goto do_basic_type_4;
4861ac76 1475 case R_HPPA_PCREL_CALL_RR14:
e8f2240a
KR
1476 r_field = e_rrsel;
1477 goto do_basic_type_4;
4861ac76 1478 case R_HPPA_PCREL_CALL_RR17:
e8f2240a 1479 r_field = e_rrsel;
4861ac76 1480
e8f2240a
KR
1481 do_basic_type_4:
1482 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1483 symbol_in, sym_value, r_addend,
1484 r_type, r_format, r_field, r_pcrel);
1485 break;
1486
4861ac76 1487 /* Handle all the basic type 5 relocations. */
e8f2240a
KR
1488 case R_HPPA_PLABEL_32:
1489 case R_HPPA_PLABEL_11:
1490 case R_HPPA_PLABEL_14:
1491 r_field = e_fsel;
1492 goto do_basic_type_5;
1493 case R_HPPA_PLABEL_L21:
1494 r_field = e_lsel;
1495 goto do_basic_type_5;
1496 case R_HPPA_PLABEL_R11:
1497 case R_HPPA_PLABEL_R14:
1498 r_field = e_rsel;
1499 do_basic_type_5:
1500 insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1501 symbol_in, sym_value, r_addend,
1502 r_type, r_format, r_field, r_pcrel);
1503 break;
1504
4861ac76 1505 /* Handle all basic type 6 relocations. */
e8f2240a
KR
1506 case R_HPPA_UNWIND_ENTRY:
1507 case R_HPPA_UNWIND_ENTRIES:
1508 hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
1509 symbol_in, sym_value, r_addend,
1510 r_type, r_format, r_field, r_pcrel);
4861ac76
JL
1511 return bfd_reloc_ok;
1512
1513 /* Handle the stack operations and similar braindamage. */
1514 case R_HPPA_PUSH_CONST:
1515 case R_HPPA_PUSH_PC:
1516 case R_HPPA_PUSH_SYM:
1517 case R_HPPA_PUSH_GOTOFF:
1518 case R_HPPA_PUSH_ABS_CALL:
1519 case R_HPPA_PUSH_PCREL_CALL:
1520 case R_HPPA_PUSH_PLABEL:
1521 case R_HPPA_MAX:
1522 case R_HPPA_MIN:
1523 case R_HPPA_ADD:
1524 case R_HPPA_SUB:
1525 case R_HPPA_MULT:
1526 case R_HPPA_DIV:
1527 case R_HPPA_MOD:
1528 case R_HPPA_AND:
1529 case R_HPPA_OR:
1530 case R_HPPA_XOR:
1531 case R_HPPA_NOT:
1532 case R_HPPA_LSHIFT:
1533 case R_HPPA_ARITH_RSHIFT:
1534 case R_HPPA_LOGIC_RSHIFT:
1535 case R_HPPA_EXPR_F:
1536 case R_HPPA_EXPR_L:
1537 case R_HPPA_EXPR_R:
1538 case R_HPPA_EXPR_LS:
1539 case R_HPPA_EXPR_RS:
1540 case R_HPPA_EXPR_LD:
1541 case R_HPPA_EXPR_RD:
1542 case R_HPPA_EXPR_LR:
1543 case R_HPPA_EXPR_RR:
1544 case R_HPPA_EXPR_32:
1545 case R_HPPA_EXPR_21:
1546 case R_HPPA_EXPR_11:
1547 case R_HPPA_EXPR_14:
1548 case R_HPPA_EXPR_17:
1549 case R_HPPA_EXPR_12:
e8f2240a
KR
1550 fprintf (stderr, "Relocation problem: ");
1551 fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
1552 r_type, abfd->filename);
4861ac76
JL
1553 return bfd_reloc_notsupported;
1554
1555 /* This is a linker internal relocation. */
d9ad93bc 1556 case R_HPPA_STUB_CALL_17:
4861ac76
JL
1557 /* This relocation is for a branch to a long branch stub.
1558 Change instruction to a BLE,N. It may also be necessary
1559 to change interchange the branch and its delay slot.
1560 The original instruction stream is
1561
1562 bl <foo>,r ; call foo using register r as
1563 ; the return pointer
1564 XXX ; delay slot instruction
1565
1566 The new instruction stream will be:
1567
1568 XXX ; delay slot instruction
1569 ble <foo_stub> ; call the long call stub for foo
1570 ; using r31 as the return pointer
1571
1572 This braindamage is necessary because the compiler may put
1573 an instruction which uses %r31 in the delay slot of the original
1574 call. By changing the call instruction from a "bl" to a "ble"
1575 %r31 gets clobbered before the delay slot executes.
1576
1577 We do not interchange the branch and delay slot if the delay
1578 slot was already nullified, or if the instruction in the delay
1579 slot modifies the return pointer to avoid an unconditional
1580 jump after the call returns (GCC optimization). */
1581
1582 if (insn & 2)
a36b6f1d
JL
1583 {
1584 insn = BLE_N_XXX_0_0;
1585 bfd_put_32 (abfd, insn, hit_data);
1586 r_type = R_HPPA_ABS_CALL_17;
1587 r_pcrel = 0;
1588 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1589 addr, symbol_in, sym_value,
1590 r_addend, r_type, r_format,
1591 r_field, r_pcrel);
1592 }
d9ad93bc 1593 else
7218bb04
KR
1594 {
1595 unsigned long old_delay_slot_insn = bfd_get_32 (abfd, hit_data + 4);
1596 unsigned rtn_reg = (insn & 0x03e00000) >> 21;
1597
4861ac76 1598 if (get_opcode (old_delay_slot_insn) == LDO)
7218bb04
KR
1599 {
1600 unsigned ldo_src_reg = (old_delay_slot_insn & 0x03e00000) >> 21;
1601 unsigned ldo_target_reg = (old_delay_slot_insn & 0x001f0000) >> 16;
1602
4861ac76
JL
1603 /* If the target of the LDO is the same as the return
1604 register then there is no reordering. We can leave the
1605 instuction as a non-nullified BLE in this case. */
7218bb04
KR
1606 if (ldo_target_reg == rtn_reg)
1607 {
1608 unsigned long new_delay_slot_insn = old_delay_slot_insn;
1609
1610 BFD_ASSERT(ldo_src_reg == ldo_target_reg);
1611 new_delay_slot_insn &= 0xfc00ffff;
1612 new_delay_slot_insn |= ((31 << 21) | (31 << 16));
4861ac76
JL
1613 bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
1614 insn = BLE_XXX_0_0;
4861ac76
JL
1615 r_type = R_HPPA_ABS_CALL_17;
1616 r_pcrel = 0;
1617 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1618 addr, symbol_in, sym_value,
1619 r_addend, r_type, r_format,
1620 r_field, r_pcrel);
a36b6f1d 1621 bfd_put_32 (abfd, insn, hit_data);
4861ac76 1622 return bfd_reloc_ok;
7218bb04 1623 }
a36b6f1d
JL
1624 else if (rtn_reg == 31)
1625 {
1626 /* The return register is r31, so this is a millicode
1627 call. Do not perform any instruction reordering. */
1628 insn = BLE_XXX_0_0;
1629 r_type = R_HPPA_ABS_CALL_17;
1630 r_pcrel = 0;
1631 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1632 addr, symbol_in, sym_value,
1633 r_addend, r_type, r_format,
1634 r_field, r_pcrel);
1635 bfd_put_32 (abfd, insn, hit_data);
1636 return bfd_reloc_ok;
1637 }
4861ac76
JL
1638 else
1639 {
1640 /* Check to see if the delay slot instruction has a
1641 relocation. If so, we need to change the address
1642 field of it, because the instruction it relocates
1643 is going to be moved. */
1644 arelent * next_reloc_entry = reloc_entry+1;
1645
1646 if (next_reloc_entry->address == reloc_entry->address + 4)
1647 next_reloc_entry->address -= 4;
1648
1649 insn = old_delay_slot_insn;
1650 bfd_put_32 (abfd, insn, hit_data);
1651 insn = BLE_N_XXX_0_0;
1652 bfd_put_32 (abfd, insn, hit_data + 4);
1653 r_type = R_HPPA_ABS_CALL_17;
1654 r_pcrel = 0;
1655 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1656 addr + 4, symbol_in,
1657 sym_value, r_addend, r_type,
1658 r_format, r_field, r_pcrel);
1659 bfd_put_32 (abfd, insn, hit_data + 4);
1660 return bfd_reloc_ok;
1661 }
1662 }
a36b6f1d
JL
1663 else if (rtn_reg == 31)
1664 {
1665 /* The return register is r31, so this is a millicode call.
1666 Perform no instruction reordering in this case. */
1667 insn = BLE_XXX_0_0;
1668 r_type = R_HPPA_ABS_CALL_17;
1669 r_pcrel = 0;
1670 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1671 addr, symbol_in, sym_value,
1672 r_addend, r_type, r_format,
1673 r_field, r_pcrel);
1674 bfd_put_32 (abfd, insn, hit_data);
1675 return bfd_reloc_ok;
1676 }
4861ac76
JL
1677 else
1678 {
1679 /* Check to see if the delay slot instruction has a
1680 relocation. If so, we need to change its address
1681 field because the instruction it relocates is going
1682 to be moved. */
1683 arelent * next_reloc_entry = reloc_entry+1;
1684
1685 if (next_reloc_entry->address == reloc_entry->address + 4)
1686 next_reloc_entry->address -= 4;
1687
1688 insn = old_delay_slot_insn;
1689 bfd_put_32 (abfd, insn, hit_data);
1690 insn = BLE_N_XXX_0_0;
1691 bfd_put_32 (abfd, insn, hit_data + 4);
1692 r_type = R_HPPA_ABS_CALL_17;
1693 r_pcrel = 0;
1694 insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1695 addr + 4, symbol_in, sym_value,
1696 r_addend, r_type, r_format,
1697 r_field, r_pcrel);
1698 bfd_put_32 (abfd, insn, hit_data + 4);
1699 return bfd_reloc_ok;
7218bb04 1700 }
7218bb04 1701 }
d9ad93bc
KR
1702 break;
1703
e8f2240a 1704 default:
4991ebb9 1705 *error_message = (char *) "Unrecognized reloc";
4861ac76 1706 return bfd_reloc_dangerous;
e8f2240a
KR
1707 }
1708
4861ac76 1709 /* Update the instruction word. */
e8f2240a 1710 bfd_put_32 (abfd, insn, hit_data);
e8f2240a 1711 return (bfd_reloc_ok);
e8f2240a
KR
1712}
1713
a5ccdad1 1714static const reloc_howto_type *
e8f2240a
KR
1715elf_hppa_reloc_type_lookup (arch, code)
1716 bfd_arch_info_type *arch;
1717 bfd_reloc_code_real_type code;
1718{
e8f2240a
KR
1719 if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
1720 {
1721 BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
1722 return &elf_hppa_howto_table[(int) code];
1723 }
1724
1725 return (reloc_howto_type *) 0;
1726}
1727
1728#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1729
1730
1731void
1732DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx),
1733 bfd * abfd AND
3a70b01d 1734 elf_symbol_type * symbolP AND
e8f2240a
KR
1735 int sym_idx)
1736{
1737 symext_chainS *symextP;
1738 unsigned int arg_reloc;
1739
3a70b01d 1740 /* Only functions can have argument relocations. */
e8f2240a
KR
1741 if (!(symbolP->symbol.flags & BSF_FUNCTION))
1742 return;
1743
e8f2240a
KR
1744 arg_reloc = symbolP->tc_data.hppa_arg_reloc;
1745
3a70b01d
KR
1746 /* If there are no argument relocation bits, then no relocation is
1747 necessary. Do not add this to the symextn section. */
1748 if (arg_reloc == 0)
1749 return;
1750
e8f2240a
KR
1751 symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
1752
1753 symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
1754 symextP[0].next = &symextP[1];
1755
1756 symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
1757 symextP[1].next = NULL;
1758
1759 if (symext_rootP == NULL)
1760 {
1761 symext_rootP = &symextP[0];
1762 symext_lastP = &symextP[1];
1763 }
1764 else
1765 {
1766 symext_lastP->next = &symextP[0];
1767 symext_lastP = &symextP[1];
1768 }
1769}
1770
d9ad93bc
KR
1771/* Accessor function for the list of symbol extension records. */
1772symext_chainS *elf32_hppa_get_symextn_chain()
1773{
1774 return symext_rootP;
1775}
1776
1777static symext_entryS *symextn_contents;
1778static unsigned int symextn_contents_real_size;
e8f2240a
KR
1779
1780void
1781DEFUN (elf_hppa_tc_make_sections, (abfd, ignored),
1782 bfd * abfd AND
1783 PTR ignored)
1784{
1785 symext_chainS *symextP;
e8f2240a
KR
1786 int size;
1787 int n;
1788 int i;
e8f2240a
KR
1789 void hppa_elf_stub_finish (); /* forward declaration */
1790 asection *symextn_sec;
1791
1792 hppa_elf_stub_finish (abfd);
1793
1794 if (symext_rootP == NULL)
1795 return;
1796
1797 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
1798 ;
1799
1800 size = sizeof (symext_entryS) * n;
1801 symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
1802 if (symextn_sec == (asection *) 0)
1803 {
1804 symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
1805 bfd_set_section_flags (abfd,
1806 symextn_sec,
1807 SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
1808 symextn_sec->output_section = symextn_sec;
1809 symextn_sec->output_offset = 0;
1810 bfd_set_section_alignment (abfd, symextn_sec, 2);
1811 }
1812 symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
1813
1814 for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
1815 symextn_contents[i] = symextP->entry;
1816 symextn_contents_real_size = size;
1817 bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
1818
1819 return;
1820}
1821
1822/* Support for HP PA-RISC stub generation.
1823
1824 Written by
1825
1826 Center for Software Science
1827 Department of Computer Science
1828 University of Utah
1829
1830 */
1831
1832/*
1833 HP-PA calling conventions state:
1834
1835 1. an argument relocation stub is required whenever the callee and
1836 caller argument relocation bits do not match exactly. The exception
1837 to this rule is if either the caller or callee argument relocation
1838 bit are 00 (do not relocate).
1839
1840 2. The linker can optionally add a symbol record for the stub so that
1841 the stub can be reused. The symbol record will be the same as the
1842 original export symbol record, except that the relocation bits will
1843 reflect the input of the stub, the type would be STUB and the symbol
1844 value will be the location of the relocation stub.
1845
1846 Other notes:
1847
1848 Stubs can be inserted *before* the section of the caller. The stubs
1849 can be treated as calls to code that manipulates the arguments.
1850
1851 */
1852
1853typedef enum
1854 {
1855 HPPA_STUB_ILLEGAL,
1856 HPPA_STUB_ARG_RELOC,
1857 HPPA_STUB_LONG_BRANCH
1858 } hppa_stub_type;
1859
1860symext_entryS
1861elf32_hppa_get_sym_extn (abfd, sym, type)
1862 bfd *abfd;
1863 asymbol *sym;
1864 int type;
1865{
1866 /* This function finds the symbol extension record of the */
1867 /* specified type for the specified symbol. It returns the */
1868 /* value of the symbol extension record. */
1869 symext_entryS retval;
1870
1871 switch (type)
1872 {
1873 case HPPA_SXT_NULL:
1874 retval = (symext_entryS) 0;
1875 break;
1876 case HPPA_SXT_SYMNDX:
1877 retval = (symext_entryS) 0; /* XXX: need to fix this */
1878 break;
1879 case HPPA_SXT_ARG_RELOC:
1880 {
3a70b01d 1881 elf_symbol_type *esymP = (elf_symbol_type *) sym;
e8f2240a
KR
1882
1883 retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
1884 break;
1885 }
d9ad93bc
KR
1886 /* This should never happen. */
1887 default:
1888 abort();
e8f2240a
KR
1889 }
1890 return retval;
1891}
1892
3a70b01d
KR
1893typedef struct elf32_hppa_stub_name_list_struct
1894{
1895 /* name of this stub */
1896 asymbol *sym;
1897 /* stub description for this stub */
1898 struct elf32_hppa_stub_description_struct *stub_desc;
1899 /* pointer into stub contents */
1900 int *stub_secp;
1901 /* size of this stub */
1902 unsigned size;
1903 /* next stub name entry */
1904 struct elf32_hppa_stub_name_list_struct *next;
1905} elf32_hppa_stub_name_list;
1906
1907typedef struct elf32_hppa_stub_description_struct
e8f2240a 1908 {
3a70b01d
KR
1909 struct elf32_hppa_stub_description_struct *next;
1910 bfd *this_bfd; /* bfd to which this stub applies */
e8f2240a 1911 asection *stub_sec; /* stub section for this bfd */
3a70b01d 1912 unsigned relocs_allocated_cnt; /* count of relocations for this stub section */
e8f2240a
KR
1913 unsigned real_size;
1914 unsigned allocated_size;
1915 int *stub_secp; /* pointer to the next available location in the buffer */
1916 char *stub_contents; /* contents of the stubs for this bfd */
3a70b01d 1917 elf32_hppa_stub_name_list *stub_listP;
4991ebb9 1918 struct bfd_link_info *link_info;
e8f2240a 1919 }
3a70b01d 1920elf32_hppa_stub_description;
e8f2240a 1921
3a70b01d 1922static elf32_hppa_stub_description *elf_hppa_stub_rootP;
e8f2240a
KR
1923
1924/* Locate the stub section information for the given bfd. */
3a70b01d 1925static elf32_hppa_stub_description *
e8f2240a
KR
1926find_stubs (abfd, stub_sec)
1927 bfd *abfd;
1928 asection *stub_sec;
1929{
3a70b01d 1930 elf32_hppa_stub_description *stubP;
e8f2240a
KR
1931
1932 for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
1933 {
3a70b01d
KR
1934 if (stubP->this_bfd == abfd
1935 && stubP->stub_sec == stub_sec)
1936 return stubP;
e8f2240a
KR
1937 }
1938
3a70b01d 1939 return (elf32_hppa_stub_description *) NULL;
e8f2240a
KR
1940}
1941
3a70b01d 1942static elf32_hppa_stub_description *
4991ebb9 1943new_stub (abfd, stub_sec, link_info)
e8f2240a
KR
1944 bfd *abfd;
1945 asection *stub_sec;
4991ebb9 1946 struct bfd_link_info *link_info;
e8f2240a 1947{
3a70b01d 1948 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
e8f2240a
KR
1949
1950 if (stub)
1951 return stub;
1952
3a70b01d
KR
1953 stub = (elf32_hppa_stub_description *) bfd_zalloc (abfd, sizeof (elf32_hppa_stub_description));
1954 if (stub)
1955 {
1956 stub->this_bfd = abfd;
1957 stub->stub_sec = stub_sec;
1958 stub->real_size = 0;
1959 stub->allocated_size = 0;
1960 stub->stub_contents = NULL;
1961 stub->stub_secp = NULL;
4991ebb9 1962 stub->link_info = link_info;
3a70b01d
KR
1963
1964 stub->next = elf_hppa_stub_rootP;
1965 elf_hppa_stub_rootP = stub;
1966 }
1967 else
1968 {
1969 bfd_error = no_memory;
1970 bfd_perror ("new_stub");
1971 }
e8f2240a
KR
1972
1973 return stub;
1974}
1975
3a70b01d
KR
1976/* Locate the stub by the given name. */
1977static elf32_hppa_stub_name_list *
1978find_stub_by_name (abfd, stub_sec, name)
1979 bfd *abfd;
1980 asection *stub_sec;
1981 char *name;
1982{
1983 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
1984
1985 if (stub)
1986 {
1987 elf32_hppa_stub_name_list *name_listP;
1988
1989 for (name_listP = stub->stub_listP; name_listP; name_listP = name_listP->next)
1990 {
1991 if (!strcmp (name_listP->sym->name, name))
1992 return name_listP;
1993 }
1994 }
1995
1996 return 0;
1997}
1998
1999/* Locate the stub by the given name. */
2000static elf32_hppa_stub_name_list *
4991ebb9 2001add_stub_by_name(abfd, stub_sec, sym, link_info)
3a70b01d
KR
2002 bfd *abfd;
2003 asection *stub_sec;
2004 asymbol *sym;
4991ebb9 2005 struct bfd_link_info *link_info;
e8f2240a 2006{
3a70b01d
KR
2007 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
2008 elf32_hppa_stub_name_list *stub_entry;
e8f2240a 2009
3a70b01d 2010 if (!stub)
4991ebb9 2011 stub = new_stub(abfd, stub_sec, link_info);
e8f2240a 2012
3a70b01d 2013 if (stub)
e8f2240a 2014 {
3a70b01d
KR
2015 stub_entry = (elf32_hppa_stub_name_list *)
2016 bfd_zalloc (abfd, sizeof (elf32_hppa_stub_name_list));
e8f2240a 2017
3a70b01d 2018 if (stub_entry)
e8f2240a 2019 {
3a70b01d
KR
2020 stub_entry->size = 0;
2021 stub_entry->sym = sym;
2022 stub_entry->stub_desc = stub;
2023 /* First byte of this stub is the pointer to
2024 the next available location in the stub buffer. */
2025 stub_entry->stub_secp = stub->stub_secp;
2026 if (stub->stub_listP)
2027 stub_entry->next = stub->stub_listP;
2028 else
2029 stub_entry->next = NULL;
2030 stub->stub_listP = stub_entry;
2031 return stub_entry;
4c85cbfa 2032 }
e8f2240a
KR
2033 else
2034 {
3a70b01d
KR
2035 bfd_error = no_memory;
2036 bfd_perror("add_stub_by_name");
e8f2240a
KR
2037 }
2038 }
3a70b01d
KR
2039
2040 return (elf32_hppa_stub_name_list *)NULL;
e8f2240a
KR
2041}
2042
2043#define ARGUMENTS 0
2044#define RETURN_VALUE 1
2045
2046#define NO_ARG_RELOC 0
2047#define R_TO_FR 1
d9ad93bc
KR
2048#define R01_TO_FR 2
2049#define R23_TO_FR 3
2050#define FR_TO_R 4
2051#define FR_TO_R01 5
2052#define FR_TO_R23 6
2053#define ARG_RELOC_ERR 7
4c85cbfa 2054
e8f2240a
KR
2055#define ARG0 0
2056#define ARG1 1
2057#define ARG2 2
2058#define ARG3 3
2059#define RETVAL 4
4c85cbfa 2060
e8f2240a
KR
2061#define AR_NO 0
2062#define AR_GR 1
2063#define AR_FR 2
2064#define AR_FU 3
d9ad93bc
KR
2065/* FP register in arg0/arg1. This value can only appear in the arg0 location. */
2066#define AR_DBL01 4
2067/* FP register in arg2/arg3. This value can only appear in the arg2 location. */
2068#define AR_DBL23 5
2069
2070#define AR_WARN(type,loc) \
2071 fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
2072 reloc_type_strings[type],reloc_loc_strings[loc])
4c85cbfa 2073
e8f2240a
KR
2074static CONST char *CONST reloc_type_strings[] =
2075{
d9ad93bc
KR
2076 "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
2077};
2078
2079static CONST char *CONST reloc_loc_strings[] =
2080{
2081 "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
e8f2240a 2082};
4c85cbfa 2083
d9ad93bc
KR
2084static CONST char mismatches[6][6] =
2085{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
e8f2240a 2086 /* CALLER NONE */
d9ad93bc 2087 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
e8f2240a 2088 /* CALLER GR */
d9ad93bc 2089 {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
e8f2240a 2090 /* CALLER FR */
d9ad93bc 2091 {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
e8f2240a 2092 /* CALLER FU */
d9ad93bc
KR
2093 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2094 /* CALLER DBL01 */
2095 {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
2096 /* CALLER DBL23 */
2097 {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
e8f2240a 2098};
4c85cbfa 2099
d9ad93bc 2100static CONST char retval_mismatches[6][6] =
3a70b01d 2101{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
e8f2240a 2102 /* CALLER NONE */
d9ad93bc 2103 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
e8f2240a 2104 /* CALLER GR */
3a70b01d 2105 {NO_ARG_RELOC, NO_ARG_RELOC, FR_TO_R, ARG_RELOC_ERR, FR_TO_R01, ARG_RELOC_ERR},
e8f2240a 2106 /* CALLER FR */
3a70b01d 2107 {NO_ARG_RELOC, R_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
e8f2240a 2108 /* CALLER FU */
d9ad93bc
KR
2109 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2110 /* CALLER DBL01 */
3a70b01d 2111 {NO_ARG_RELOC, R01_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
d9ad93bc 2112 /* CALLER DBL23 */
3a70b01d 2113 {NO_ARG_RELOC, R23_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
e8f2240a
KR
2114};
2115
2116static int
2117type_of_mismatch (caller_bits, callee_bits, type)
2118 int caller_bits;
2119 int callee_bits;
2120 int type;
2121{
2122 switch (type)
2123 {
2124 case ARGUMENTS:
2125 return mismatches[caller_bits][callee_bits];
2126 case RETURN_VALUE:
2127 return retval_mismatches[caller_bits][callee_bits];
2128 }
2129
2130 return 0;
2131}
2132
2133#define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
2134
3a70b01d 2135#define NEW_INSTRUCTION(entry,insn) \
4861ac76 2136{ \
3a70b01d
KR
2137 *((entry)->stub_desc->stub_secp)++ = (insn); \
2138 (entry)->stub_desc->real_size += sizeof(int); \
2139 (entry)->size += sizeof(int); \
2140 bfd_set_section_size((entry)->stub_desc->this_bfd, \
2141 (entry)->stub_desc->stub_sec, \
4861ac76
JL
2142 (entry)->stub_desc->real_size); \
2143}
e8f2240a 2144
3a70b01d 2145#define CURRENT_STUB_OFFSET(entry) \
4861ac76
JL
2146 ((int)(entry)->stub_desc->stub_secp \
2147 - (int)(entry)->stub_desc->stub_contents - 4)
d9ad93bc
KR
2148
2149static boolean stubs_finished = false;
2150
e8f2240a
KR
2151void
2152hppa_elf_stub_finish (output_bfd)
2153 bfd *output_bfd;
2154{
3a70b01d 2155 elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
e8f2240a
KR
2156 /* All the stubs have been built. Finish up building */
2157 /* stub section. Apply relocations to the section. */
2158
d9ad93bc
KR
2159 if ( stubs_finished )
2160 return;
2161
e8f2240a
KR
2162 for (; stub_list; stub_list = stub_list->next)
2163 {
3a70b01d 2164 if (stub_list->real_size)
e8f2240a 2165 {
3a70b01d 2166 bfd *stub_bfd = stub_list->this_bfd;
e8f2240a
KR
2167 asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
2168 bfd_size_type reloc_size;
2169 arelent **reloc_vector;
2170
3a70b01d 2171 BFD_ASSERT (stub_sec == stub_list->stub_sec);
e8f2240a
KR
2172 reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
2173 reloc_vector = (arelent **) alloca (reloc_size);
2174
2175 BFD_ASSERT (stub_sec);
2176
2177 /* We are not relaxing the section, so just copy the size info */
2178 stub_sec->_cooked_size = stub_sec->_raw_size;
2179 stub_sec->reloc_done = true;
2180
2181
2182 if (bfd_canonicalize_reloc (stub_bfd,
2183 stub_sec,
2184 reloc_vector,
2185 output_bfd->outsymbols))
2186 {
2187 arelent **parent;
2188 for (parent = reloc_vector; *parent != (arelent *) NULL;
2189 parent++)
2190 {
4991ebb9 2191 char *err = (char *) NULL;
e8f2240a 2192 bfd_reloc_status_type r =
4991ebb9
ILT
2193 bfd_perform_relocation (stub_bfd,
2194 *parent,
2195 stub_list->stub_contents,
2196 stub_sec, (bfd *) NULL, &err);
e8f2240a
KR
2197
2198
2199 if (r != bfd_reloc_ok)
2200 {
4991ebb9
ILT
2201 struct bfd_link_info *link_info = stub_list->link_info;
2202
e8f2240a
KR
2203 switch (r)
2204 {
2205 case bfd_reloc_undefined:
4991ebb9
ILT
2206 if (! ((*link_info->callbacks->undefined_symbol)
2207 (link_info,
2208 bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2209 stub_bfd, stub_sec, (*parent)->address)))
2210 abort ();
e8f2240a
KR
2211 break;
2212 case bfd_reloc_dangerous:
4991ebb9
ILT
2213 if (! ((*link_info->callbacks->reloc_dangerous)
2214 (link_info, err, stub_bfd, stub_sec,
2215 (*parent)->address)))
2216 abort ();
e8f2240a 2217 break;
e8f2240a 2218 case bfd_reloc_overflow:
4991ebb9
ILT
2219 {
2220 if (! ((*link_info->callbacks->reloc_overflow)
2221 (link_info,
2222 bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2223 (*parent)->howto->name,
2224 (*parent)->addend,
2225 stub_bfd, stub_sec,
2226 (*parent)->address)))
2227 abort ();
2228 }
e8f2240a 2229 break;
4991ebb9 2230 case bfd_reloc_outofrange:
e8f2240a
KR
2231 default:
2232 abort ();
2233 break;
2234 }
2235 }
2236 }
2237 }
2238
2239 bfd_set_section_contents (output_bfd,
2240 stub_sec,
3a70b01d 2241 stub_list->stub_contents,
e8f2240a 2242 0,
3a70b01d 2243 stub_list->real_size);
e8f2240a
KR
2244
2245 free (reloc_vector);
2246 }
2247 }
d9ad93bc 2248 stubs_finished = true;
e8f2240a
KR
2249}
2250
2251void
2252hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
2253 output_bfd, /* the output bfd */
d9ad93bc 2254 target_sym, /* the target symbol */
e8f2240a 2255 offset) /* the offset within the stub buffer (pre-calculated) */
3a70b01d 2256 elf32_hppa_stub_description *stub_desc;
e8f2240a 2257 bfd *output_bfd;
d9ad93bc 2258 asymbol *target_sym;
e8f2240a
KR
2259 int offset;
2260{
2261 /* Allocate a new relocation entry. */
2262 arelent relent;
2263 int size;
2264
2265 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2266 {
2267 if (stub_desc->stub_sec->relocation == NULL)
2268 {
2269 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2270 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2271 stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
2272 }
2273 else
2274 {
2275 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2276 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2277 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2278 size);
2279 }
2280 }
2281
2282 /* Fill in the details. */
2283 relent.address = offset;
2284 relent.addend = 0;
2285 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2286 BFD_ASSERT (relent.sym_ptr_ptr);
2287
d9ad93bc
KR
2288 relent.sym_ptr_ptr[0] = target_sym;
2289 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
2290
2291 /* Save it in the array of relocations for the stub section. */
2292
2293 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2294 &relent,
2295 sizeof (arelent));
2296}
2297
2298void
2299hppa_elf_stub_reloc (stub_desc, /* the bfd */
2300 output_bfd, /* the output bfd */
2301 target_sym, /* the target symbol */
2302 offset, /* the offset within the stub buffer (pre-calculated) */
2303 type)
3a70b01d 2304elf32_hppa_stub_description *stub_desc;
d9ad93bc
KR
2305bfd *output_bfd;
2306asymbol *target_sym;
2307int offset;
2308elf32_hppa_reloc_type type;
2309{
2310 /* Allocate a new relocation entry. */
2311 arelent relent;
2312 int size;
2313 Elf_Internal_Shdr *rela_hdr;
2314
2315 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2316 {
2317 if (stub_desc->stub_sec->relocation == NULL)
2318 {
2319 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2320 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2321 stub_desc->stub_sec->relocation = (arelent *) zalloc (size);
2322 }
2323 else
2324 {
2325 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2326 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2327 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2328 size);
2329 }
2330 }
2331
2332 rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
2333 rela_hdr->sh_size += sizeof(Elf32_External_Rela);
2334
2335 /* Fill in the details. */
2336 relent.address = offset;
2337 relent.addend = 0;
2338 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2339 BFD_ASSERT (relent.sym_ptr_ptr);
2340
2341 relent.sym_ptr_ptr[0] = target_sym;
2342 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
e8f2240a
KR
2343
2344 /* Save it in the array of relocations for the stub section. */
2345
2346 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2347 &relent,
2348 sizeof (arelent));
2349}
2350
2351asymbol *
4991ebb9 2352hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
4861ac76 2353 stub_types, rtn_adjust, data)
e8f2240a
KR
2354 bfd *abfd;
2355 bfd *output_bfd;
4991ebb9 2356 struct bfd_link_info *link_info;
e8f2240a
KR
2357 arelent *reloc_entry;
2358 int stub_types[5];
4861ac76
JL
2359 int rtn_adjust;
2360 unsigned *data;
e8f2240a
KR
2361{
2362 asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
3a70b01d 2363 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
e8f2240a 2364 asymbol *stub_sym = NULL;
d9ad93bc 2365 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
e8f2240a
KR
2366 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2367 int i;
2368 char stub_sym_name[128];
3a70b01d 2369 elf32_hppa_stub_name_list *stub_entry;
4861ac76
JL
2370 unsigned insn = data[0];
2371
2372 /* Perform some additional checks on whether we should really do the
2373 return adjustment. For example, if the instruction is nullified
2374 or if the delay slot contains an instruction that modifies the return
2375 pointer, then the branch instructions should not be rearranged
2376 (rtn_adjust is false). */
2377 if (insn & 2 || insn == 0)
2378 rtn_adjust = false;
2379 else
2380 {
2381 unsigned delay_insn = data[1];
e8f2240a 2382
4861ac76
JL
2383 if (get_opcode (delay_insn) == LDO
2384 && (((insn & 0x03e00000) >> 21) == ((delay_insn & 0x001f0000) >> 16)))
2385 rtn_adjust = false;
2386 }
2387
2388 /* See if the proper stub entry has already been made. */
e8f2240a
KR
2389 if (!stub_sec)
2390 {
2391 BFD_ASSERT (stub_desc == NULL);
2392 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
d9ad93bc 2393 bfd_set_section_flags (abfd,
e8f2240a 2394 stub_sec,
4861ac76
JL
2395 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2396 | SEC_RELOC | SEC_CODE | SEC_READONLY);
e8f2240a
KR
2397 stub_sec->output_section = output_text_section->output_section;
2398 stub_sec->output_offset = 0;
d9ad93bc 2399 bfd_set_section_alignment (abfd, stub_sec, 2);
4991ebb9 2400 stub_desc = new_stub (abfd, stub_sec, link_info);
e8f2240a
KR
2401 }
2402
4861ac76 2403 /* Make the stub if we did not find one already. */
e8f2240a 2404 if (!stub_desc)
4991ebb9 2405 stub_desc = new_stub (abfd, stub_sec, link_info);
e8f2240a 2406
4861ac76
JL
2407 /* Allocate space to write the stub.
2408 FIXME. Why using realloc?!? */
e8f2240a
KR
2409 if (!stub_desc->stub_contents)
2410 {
2411 stub_desc->allocated_size = STUB_BUFFER_INCR;
a5ccdad1 2412 stub_desc->stub_contents = (char *) bfd_xmalloc (STUB_BUFFER_INCR);
e8f2240a
KR
2413 }
2414 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2415 {
2416 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
a5ccdad1
ILT
2417 stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2418 stub_desc->allocated_size);
e8f2240a
KR
2419 }
2420
4861ac76
JL
2421 stub_desc->stub_secp
2422 = (int *) (stub_desc->stub_contents + stub_desc->real_size);
e8f2240a 2423
e8f2240a 2424 sprintf (stub_sym_name,
4861ac76 2425 "_stub_%s_%02d_%02d_%02d_%02d_%02d_%s",
e8f2240a 2426 reloc_entry->sym_ptr_ptr[0]->name,
4861ac76
JL
2427 stub_types[0], stub_types[1], stub_types[2],
2428 stub_types[3], stub_types[4],
2429 rtn_adjust ? "RA" : "");
2430 stub_entry = find_stub_by_name (abfd, stub_sec, stub_sym_name);
e8f2240a 2431
3a70b01d
KR
2432 if (stub_entry)
2433 {
2434 stub_sym = stub_entry->sym;
4861ac76
JL
2435 /* Redirect the original relocation from the old symbol (a function)
2436 to the stub (the stub calls the function). Should we need to
2437 change the relocation type? */
2438 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2439 sizeof (asymbol *));
3a70b01d 2440 reloc_entry->sym_ptr_ptr[0] = stub_sym;
4861ac76 2441 if (reloc_entry->howto->type != R_HPPA_PLABEL_32
a36b6f1d
JL
2442 && (get_opcode(insn) == BLE
2443 || get_opcode (insn) == BE
2444 || get_opcode (insn) == BL))
4861ac76 2445 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
3a70b01d
KR
2446 }
2447 else
2448 {
4861ac76 2449 /* Create a new symbol to point to this stub. */
3a70b01d
KR
2450 stub_sym = bfd_make_empty_symbol (abfd);
2451 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2452 strcpy ((char *) stub_sym->name, stub_sym_name);
4861ac76
JL
2453 stub_sym->value
2454 = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
3a70b01d
KR
2455 stub_sym->section = stub_sec;
2456 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
4991ebb9 2457 stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
3a70b01d 2458
4861ac76
JL
2459 /* Redirect the original relocation from the old symbol (a function)
2460 to the stub (the stub calls the function). Change the type of
2461 relocation to be the internal use only stub R_HPPA_STUB_CALL_17. */
2462 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2463 sizeof (asymbol *));
3a70b01d 2464 reloc_entry->sym_ptr_ptr[0] = stub_sym;
4861ac76 2465 if (reloc_entry->howto->type != R_HPPA_PLABEL_32
a36b6f1d
JL
2466 && (get_opcode (insn) == BLE
2467 || get_opcode (insn) == BE
2468 || get_opcode (insn) == BL))
4861ac76 2469 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
3a70b01d 2470
4861ac76 2471 /* Generate common code for all stubs. */
3a70b01d 2472
4861ac76
JL
2473 NEW_INSTRUCTION (stub_entry, LDSID_31_1);
2474 NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
3a70b01d
KR
2475 NEW_INSTRUCTION (stub_entry, ADDI_8_SP);
2476
4861ac76 2477 /* Generate code to move the arguments around. */
3a70b01d
KR
2478 for (i = ARG0; i < ARG3; i++)
2479 {
2480 if (stub_types[i] != NO_ARG_RELOC)
2481 {
3a70b01d
KR
2482 switch (stub_types[i])
2483 {
2484 case R_TO_FR:
2485 switch (i)
2486 {
2487 case ARG0:
2488 NEW_INSTRUCTION (stub_entry, STWS_ARG0_M8SP);
2489 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG0);
2490 break;
2491 case ARG1:
2492 NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2493 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG1);
2494 break;
2495 case ARG2:
2496 NEW_INSTRUCTION (stub_entry, STWS_ARG2_M8SP);
2497 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG2);
2498 break;
2499 case ARG3:
2500 NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2501 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG3);
2502 break;
2503 }
2504 continue;
2505
2506 case R01_TO_FR:
2507 switch (i)
2508 {
2509 case ARG0:
4861ac76
JL
2510 NEW_INSTRUCTION (stub_entry, STWS_ARG0_M4SP);
2511 NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2512 NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG1);
3a70b01d
KR
2513 break;
2514 default:
4861ac76 2515 AR_WARN (stub_types[i],i);
3a70b01d
KR
2516 break;
2517 }
2518 continue;
2519
2520 case R23_TO_FR:
2521 switch (i)
2522 {
2523 case ARG2:
4861ac76
JL
2524 NEW_INSTRUCTION (stub_entry, STWS_ARG2_M4SP);
2525 NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2526 NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG3);
3a70b01d
KR
2527 break;
2528 default:
4861ac76 2529 AR_WARN (stub_types[i],i);
3a70b01d
KR
2530 break;
2531 }
2532 continue;
2533
2534 case FR_TO_R:
2535 switch (i)
2536 {
2537 case ARG0:
2538 NEW_INSTRUCTION (stub_entry, FSTWS_FARG0_M8SP);
2539 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2540 break;
2541 case ARG1:
2542 NEW_INSTRUCTION (stub_entry, FSTWS_FARG1_M8SP);
2543 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG1);
2544 break;
2545 case ARG2:
2546 NEW_INSTRUCTION (stub_entry, FSTWS_FARG2_M8SP);
2547 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2548 break;
2549 case ARG3:
2550 NEW_INSTRUCTION (stub_entry, FSTWS_FARG3_M8SP);
2551 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG3);
2552 break;
2553 }
2554 continue;
2555
2556 case FR_TO_R01:
2557 switch (i)
2558 {
2559 case ARG0:
4861ac76
JL
2560 NEW_INSTRUCTION (stub_entry, FSTDS_FARG1_M8SP);
2561 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2562 NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG1);
3a70b01d
KR
2563 break;
2564 default:
4861ac76 2565 AR_WARN (stub_types[i],i);
3a70b01d
KR
2566 break;
2567 }
2568 continue;
2569
2570 case FR_TO_R23:
2571 switch (i)
2572 {
2573 case ARG2:
4861ac76
JL
2574 NEW_INSTRUCTION (stub_entry, FSTDS_FARG3_M8SP);
2575 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2576 NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG3);
3a70b01d
KR
2577 break;
2578 default:
4861ac76 2579 AR_WARN (stub_types[i],i);
3a70b01d
KR
2580 break;
2581 }
2582 continue;
2583
2584 }
2585 }
2586 }
e8f2240a 2587
4861ac76
JL
2588 NEW_INSTRUCTION (stub_entry, ADDI_M8_SP_SP);
2589
2590 /* Adjust the return address if necessary. */
2591 if (rtn_adjust)
2592 {
2593 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
2594 }
4991ebb9
ILT
2595 else
2596 NEW_INSTRUCTION (stub_entry, COPY_31_2);
e8f2240a 2597
4861ac76
JL
2598 /* Save the return address. */
2599 NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
e8f2240a 2600
4861ac76
JL
2601 /* Long branch to the target function. */
2602 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3a70b01d 2603 hppa_elf_stub_reloc (stub_entry->stub_desc,
4861ac76
JL
2604 abfd,
2605 target_sym,
2606 CURRENT_STUB_OFFSET (stub_entry),
3a70b01d 2607 R_HPPA_L21);
4861ac76 2608 NEW_INSTRUCTION (stub_entry, BLE_XXX_0_31);
3a70b01d 2609 hppa_elf_stub_reloc (stub_entry->stub_desc,
4861ac76
JL
2610 abfd,
2611 target_sym,
2612 CURRENT_STUB_OFFSET (stub_entry),
3a70b01d 2613 R_HPPA_ABS_CALL_R17);
4861ac76 2614 NEW_INSTRUCTION (stub_entry, COPY_31_2);
3a70b01d 2615
4861ac76
JL
2616
2617 /* Restore the return address. */
2618 NEW_INSTRUCTION (stub_entry, LDW_M8SP_RP);
3a70b01d 2619
4861ac76 2620 /* Generate the code to move the return value around. */
3a70b01d 2621 i = RETVAL;
e8f2240a
KR
2622 if (stub_types[i] != NO_ARG_RELOC)
2623 {
e8f2240a
KR
2624 switch (stub_types[i])
2625 {
2626 case R_TO_FR:
3a70b01d
KR
2627 NEW_INSTRUCTION (stub_entry, STWS_RET0_M8SP);
2628 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FRET0);
2629 break;
2630
e8f2240a 2631 case FR_TO_R:
3a70b01d
KR
2632 NEW_INSTRUCTION (stub_entry, FSTWS_FRET0_M8SP);
2633 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_RET0);
2634 break;
e8f2240a 2635 }
e8f2240a 2636 }
7218bb04 2637 NEW_INSTRUCTION (stub_entry, BV_N_0_RP);
e8f2240a
KR
2638 }
2639
e8f2240a
KR
2640 return stub_sym;
2641}
2642
2643int
3a70b01d 2644hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
e8f2240a
KR
2645 bfd *abfd;
2646 arelent *reloc_entry;
2647 int stub_types[5];
3a70b01d 2648 symext_entryS caller_ar;
e8f2240a 2649{
e8f2240a
KR
2650 /* If the symbol is still undefined, there is */
2651 /* no way to know if a stub is required. */
2652
2653 if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
2654 {
e8f2240a
KR
2655 symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
2656 reloc_entry->sym_ptr_ptr[0],
2657 HPPA_SXT_ARG_RELOC);
2658
2659 /* Now, determine if a stub is */
2660 /* required. A stub is required if they the callee and caller */
2661 /* argument relocation bits are both nonzero and not equal. */
2662
2663 if (caller_ar && callee_ar)
2664 {
2665 /* Both are non-zero, we need to do further checking. */
2666 /* First, check if there is a return value relocation to be done */
2667 int caller_loc[5];
2668 int callee_loc[5];
2669
2670 callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
2671 caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
2672 callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
2673 caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
2674 callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
2675 caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
2676 callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
2677 caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
2678 callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
2679 caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
2680
2681 /* Check some special combinations. For */
2682 /* example, if FU appears in ARG1 or ARG3, we */
2683 /* can move it to ARG0 or ARG2, respectively. */
2684
2685 if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
2686 {
d9ad93bc 2687 caller_loc[ARG0] = AR_DBL01;
e8f2240a
KR
2688 caller_loc[ARG1] = AR_NO;
2689 }
2690 if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
2691 {
d9ad93bc 2692 caller_loc[ARG2] = AR_DBL23;
e8f2240a
KR
2693 caller_loc[ARG3] = AR_NO;
2694 }
2695 if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
2696 {
d9ad93bc 2697 callee_loc[ARG0] = AR_DBL01;
e8f2240a
KR
2698 callee_loc[ARG1] = AR_NO;
2699 }
2700 if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
2701 {
d9ad93bc 2702 callee_loc[ARG2] = AR_DBL23;
e8f2240a
KR
2703 callee_loc[ARG3] = AR_NO;
2704 }
2705
2706 stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
2707 stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
2708 stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
2709 stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
2710 stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
2711
d9ad93bc 2712 /* Steps involved in building stubs: */
e8f2240a
KR
2713 /* 1. Determine what argument registers need to relocated. This */
2714 /* step is already done here. */
2715 /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2716 /* This section should never appear in an object file. It is */
2717 /* only used internally. The output_section of the */
2718 /* .hppa_linker_stubs section is the .text section of the */
2719 /* executable. */
2720 /* 3. Build a symbol that is used (internally only) as the entry */
2721 /* point of the stub. */
2722 /* 4. Change the instruction of the original branch into a branch to */
2723 /* the stub routine. */
2724 /* 5. Build a relocation entry for the instruction of the original */
d9ad93bc 2725 /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
e8f2240a
KR
2726
2727
2728 if (stub_types[0]
2729 || stub_types[1]
2730 || stub_types[2]
2731 || stub_types[3]
2732 || stub_types[4])
2733 {
2734#ifdef DETECT_STUBS
3a70b01d
KR
2735 int i;
2736
e8f2240a
KR
2737 fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2738 reloc_entry->sym_ptr_ptr[0]->name,
2739 abfd->filename, reloc_entry->address,
2740 callee_ar, caller_ar);
2741 for (i = ARG0; i < RETVAL; i++)
2742 {
2743 if (stub_types[i] != NO_ARG_RELOC)
2744 {
2745 fprintf (stderr, "%s%d: %s ",
2746 i == RETVAL ? "ret" : "arg",
2747 i == RETVAL ? 0 : i,
2748 reloc_type_strings[stub_types[i]]);
2749 }
4c85cbfa 2750 }
e8f2240a
KR
2751 fprintf (stderr, "\n");
2752#endif
2753 return 1;
2754 }
2755
2756 }
2757 }
2758 return 0;
2759}
2760
2761asymbol *
4991ebb9
ILT
2762hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
2763 symbol, data)
d9ad93bc
KR
2764 bfd *abfd;
2765 bfd *output_bfd;
4991ebb9 2766 struct bfd_link_info *link_info;
d9ad93bc
KR
2767 arelent *reloc_entry;
2768 asymbol *symbol;
2769 unsigned *data;
2770{
2771 asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
3a70b01d 2772 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
d9ad93bc
KR
2773 asymbol *stub_sym = NULL;
2774 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
d9ad93bc
KR
2775 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2776 char stub_sym_name[128];
2777 int milli = false;
7218bb04 2778 int dyncall = false;
3a70b01d 2779 elf32_hppa_stub_name_list *stub_entry;
4861ac76
JL
2780 int rtn_adjust = true;
2781 int rtn_reg;
2782 unsigned insn;
d9ad93bc 2783
4861ac76 2784 /* Create the stub section if it does not already exist. */
d9ad93bc
KR
2785 if (!stub_sec)
2786 {
2787 BFD_ASSERT (stub_desc == NULL);
2788 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2789 bfd_set_section_flags (abfd,
2790 stub_sec,
4861ac76
JL
2791 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2792 | SEC_RELOC | SEC_CODE | SEC_READONLY);
d9ad93bc
KR
2793 stub_sec->output_section = output_text_section->output_section;
2794 stub_sec->output_offset = 0;
d9ad93bc 2795
4861ac76
JL
2796 /* Set up the ELF section header for this new section. This
2797 is basically the same processing as elf_make_sections().
2798 elf_make_sections is static and therefore not accessable
2799 here. */
d9ad93bc
KR
2800 {
2801 Elf_Internal_Shdr *this_hdr;
2802 this_hdr = &elf_section_data (stub_sec)->this_hdr;
4861ac76
JL
2803
2804 /* Set the sizes of this section. The contents have already
2805 been set up ?!? */
d9ad93bc
KR
2806 this_hdr->sh_addr = stub_sec->vma;
2807 this_hdr->sh_size = stub_sec->_raw_size;
4861ac76
JL
2808
2809 /* Set appropriate flags for sections with relocations. */
d9ad93bc
KR
2810 if (stub_sec->flags & SEC_RELOC)
2811 {
d9ad93bc
KR
2812 Elf_Internal_Shdr *rela_hdr;
2813 int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
4861ac76 2814
d9ad93bc 2815 rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
4861ac76 2816
d9ad93bc
KR
2817 if (use_rela_p)
2818 {
2819 rela_hdr->sh_type = SHT_RELA;
2820 rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
2821 }
2822 else
d9ad93bc
KR
2823 {
2824 rela_hdr->sh_type = SHT_REL;
2825 rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
2826 }
2827 rela_hdr->sh_flags = 0;
2828 rela_hdr->sh_addr = 0;
2829 rela_hdr->sh_offset = 0;
2830 rela_hdr->sh_addralign = 0;
2831 rela_hdr->size = 0;
2832 }
4861ac76 2833
d9ad93bc
KR
2834 if (stub_sec->flags & SEC_ALLOC)
2835 {
2836 this_hdr->sh_flags |= SHF_ALLOC;
4861ac76
JL
2837 /* FIXME. If SEC_LOAD is true should we do something with
2838 with sh_type? */
d9ad93bc 2839 }
4861ac76 2840
d9ad93bc
KR
2841 if (!(stub_sec->flags & SEC_READONLY))
2842 this_hdr->sh_flags |= SHF_WRITE;
4861ac76 2843
d9ad93bc
KR
2844 if (stub_sec->flags & SEC_CODE)
2845 this_hdr->sh_flags |= SHF_EXECINSTR;
2846 }
4861ac76 2847
d9ad93bc 2848 bfd_set_section_alignment (abfd, stub_sec, 2);
4991ebb9 2849 stub_desc = new_stub (abfd, stub_sec, link_info);
d9ad93bc 2850 }
4861ac76 2851
d9ad93bc 2852 if (!stub_desc)
4991ebb9 2853 stub_desc = new_stub (abfd, stub_sec, link_info);
4861ac76
JL
2854
2855 /* Allocate memory to contain the stub. FIXME. Why isn't this using
2856 the BFD memory allocation routines? */
d9ad93bc
KR
2857 if (!stub_desc->stub_contents)
2858 {
2859 stub_desc->allocated_size = STUB_BUFFER_INCR;
2860 stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
2861 }
2862 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2863 {
2864 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2865 stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
4861ac76 2866 stub_desc->allocated_size);
d9ad93bc 2867 }
4861ac76
JL
2868
2869 stub_desc->stub_secp
2870 = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2871
2872 /* Is this a millicode call? If so, the return address
2873 comes in on r31 rather than r2 (rp) so a slightly
2874 different code sequence is needed. */
2875
2876 insn = data[0];
2877 rtn_reg = (insn & 0x03e00000) >> 21;
2878 if (rtn_reg == 31)
2879 milli = true;
2880
2881 if (strcmp (symbol->name, "$$dyncall") == 0)
2882 dyncall = true;
a36b6f1d
JL
2883
2884 /* If we are creating a call from a stub to another stub, then
2885 never do the instruction reordering. We can tell if we are
2886 going to be calling one stub from another by the fact that
2887 the symbol name has '_stub_' (arg. reloc. stub) or '_lb_stub_'
2888 prepended to the name. Alternatively, the section of the
2889 symbol will be '.hppa_linker_stubs'. */
2890
2891 if ((strncmp (symbol->name, "_stub_", 6) == 0)
2892 || (strncmp (symbol->name, "_lb_stub_", 9) == 0))
2893 {
2894 BFD_ASSERT (strcmp (symbol->section->name, ".hppa_linker_stubs") == 0);
2895 rtn_adjust = false;
2896 }
4861ac76
JL
2897
2898 /* Check to see if we modify the return pointer
2899 in the delay slot of the branch. */
2900 {
2901 unsigned delay_insn = data[1];
2902
2903 /* If we nullify the delay slot, or if the delay slot contains an
2904 instruction that modifies the return pointer, then no additional
2905 modification of the return pointer is necessary. */
2906 if (insn & 2 || insn == 0)
2907 rtn_adjust = false;
2908 else
2909 {
2910 if (get_opcode (delay_insn) == LDO
2911 && (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
2912 rtn_adjust = false;
a36b6f1d
JL
2913 if (milli)
2914 rtn_adjust = false;
4861ac76
JL
2915 }
2916 }
2917
d9ad93bc 2918 sprintf (stub_sym_name,
4861ac76
JL
2919 "_lb_stub_%s_%s", reloc_entry->sym_ptr_ptr[0]->name,
2920 rtn_adjust ? "RA" : "");
3a70b01d 2921 stub_entry = find_stub_by_name(abfd, stub_sec, stub_sym_name);
d9ad93bc 2922
4861ac76 2923 /* If a copy of this stub already exists re-use it. */
3a70b01d
KR
2924 if (stub_entry)
2925 {
2926 stub_sym = stub_entry->sym;
4861ac76
JL
2927
2928 /* Change symbol associated with the original relocation to point
2929 to the stub.
2930
2931 FIXME. Is there a need to change the relocation type too? */
2932 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2933 sizeof (asymbol *));
3a70b01d
KR
2934 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2935 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
d9ad93bc
KR
2936 }
2937 else
2938 {
4861ac76 2939 /* We will need to allocate a new stub. */
3a70b01d
KR
2940 stub_sym = bfd_make_empty_symbol (abfd);
2941 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2942 strcpy ((char *) stub_sym->name, stub_sym_name);
4861ac76
JL
2943 stub_sym->value
2944 = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
3a70b01d
KR
2945 stub_sym->section = stub_sec;
2946 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
4991ebb9 2947 stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
4861ac76
JL
2948
2949 /* Change symbol associated with the original relocation to point
2950 to the stub.
3a70b01d 2951
4861ac76
JL
2952 FIXME. Is there a need to change the relocation type too? */
2953 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2954 sizeof (asymbol *));
3a70b01d
KR
2955 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2956 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
4861ac76
JL
2957
2958 /* Build the stub. */
2959
3a70b01d 2960 /* 1. initialization for the call. */
4861ac76
JL
2961 NEW_INSTRUCTION (stub_entry, LDSID_31_1);
2962 NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
2963
2964 if (!dyncall)
3a70b01d 2965 {
4861ac76 2966 if (!milli)
7218bb04 2967 {
4861ac76
JL
2968 if (rtn_adjust)
2969 {
2970 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
2971 }
2972 else
2973 {
2974 NEW_INSTRUCTION (stub_entry, COPY_31_2);
2975 }
7218bb04
KR
2976 }
2977 else
2978 {
4861ac76
JL
2979 if (rtn_adjust)
2980 {
2981 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_1);
2982 }
2983 else
2984 {
2985 NEW_INSTRUCTION (stub_entry, COPY_31_1);
2986 }
7218bb04 2987 }
4861ac76
JL
2988
2989 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3a70b01d 2990 hppa_elf_stub_reloc (stub_desc,
4861ac76
JL
2991 abfd,
2992 target_sym,
2993 CURRENT_STUB_OFFSET (stub_entry),
3a70b01d
KR
2994 R_HPPA_L21);
2995
2996 /* 2. Make the call. */
4861ac76 2997 if (!milli)
7218bb04 2998 {
a36b6f1d 2999 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
7218bb04 3000 hppa_elf_stub_reloc (stub_desc,
4861ac76
JL
3001 abfd,
3002 target_sym,
3003 CURRENT_STUB_OFFSET (stub_entry),
7218bb04 3004 R_HPPA_ABS_CALL_R17);
a36b6f1d 3005 NEW_INSTRUCTION (stub_entry, COPY_2_31);
7218bb04
KR
3006 }
3007 else
3008 {
4861ac76 3009 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
7218bb04 3010 hppa_elf_stub_reloc (stub_desc,
4861ac76
JL
3011 abfd,
3012 target_sym,
3013 CURRENT_STUB_OFFSET (stub_entry),
7218bb04 3014 R_HPPA_ABS_CALL_R17);
4861ac76 3015 NEW_INSTRUCTION (stub_entry, COPY_1_31);
7218bb04 3016 }
3a70b01d
KR
3017 }
3018 else
3019 {
4861ac76
JL
3020 /* 3. Branch back to the original location.
3021 (For non-millicode calls, this is accomplished with the
3022 COPY_31_2 instruction. For millicode calls, the return
3023 location is already in r2.) */
3024 if (rtn_adjust)
3025 {
3026 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
3027 }
3028 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3a70b01d 3029 hppa_elf_stub_reloc (stub_desc,
4861ac76
JL
3030 abfd,
3031 target_sym,
3032 CURRENT_STUB_OFFSET (stub_entry),
3a70b01d 3033 R_HPPA_L21);
4861ac76 3034
a36b6f1d 3035 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3a70b01d 3036 hppa_elf_stub_reloc (stub_desc,
4861ac76
JL
3037 abfd,
3038 target_sym,
3039 CURRENT_STUB_OFFSET (stub_entry),
3a70b01d 3040 R_HPPA_ABS_CALL_R17);
a36b6f1d 3041 NEW_INSTRUCTION (stub_entry, COPY_2_31);
3a70b01d 3042 }
d9ad93bc 3043 }
d9ad93bc
KR
3044 return stub_sym;
3045}
3046
3047int
3048hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
3049 bfd *abfd;
3050 asection *asec;
3051 arelent *reloc_entry;
3052 asymbol *symbol;
3053 unsigned insn;
3054{
3055 long sym_value = get_symbol_value(symbol);
3056 int fmt = reloc_entry->howto->bitsize;
3057 unsigned char op = get_opcode(insn);
3058 unsigned raddr;
3059
3060#define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
3061
d9ad93bc
KR
3062 switch (op)
3063 {
3064 case BL:
3065 raddr =
3066 reloc_entry->address + asec->output_offset + asec->output_section->vma;
3067 if ( too_far(sym_value - raddr,fmt+1) )
3068 {
3069#ifdef DETECT_STUBS
3070 fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address);
3071#endif
3072 return 1;
3073 }
3074 break;
3075 }
3076 return 0;
3077}
3078
e8f2240a
KR
3079#define STUB_SYM_BUFFER_INC 5
3080
3081asymbol *
4861ac76 3082hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
4991ebb9 3083 syms, new_sym_cnt, link_info)
d9ad93bc 3084 bfd *stub_bfd;
e8f2240a
KR
3085 bfd *abfd;
3086 bfd *output_bfd;
3087 asection *asec;
3088 asymbol **syms;
3089 int *new_sym_cnt;
4991ebb9 3090 struct bfd_link_info *link_info;
e8f2240a
KR
3091{
3092 int i;
3093 int stub_types[5];
3094 asymbol *new_syms = (asymbol *) NULL;
3095 int new_cnt = 0;
3096 int new_max = 0;
3097
3a70b01d
KR
3098 /* Relocations are in different places depending on whether this is
3099 an output section or an input section. Also, the relocations are
3100 in different forms. Sigh. Luckily, we have
4861ac76 3101 bfd_canonicalize_reloc() to straighten this out for us . */
e8f2240a 3102
e8f2240a
KR
3103 if (asec->reloc_count > 0)
3104 {
4861ac76
JL
3105 arelent **reloc_vector
3106 = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
e8f2240a
KR
3107
3108 bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
3109 for (i = 0; i < asec->reloc_count; i++)
3110 {
e8f2240a
KR
3111 arelent *rle = reloc_vector[i];
3112
3113 switch (rle->howto->type)
3114 {
4861ac76
JL
3115 case R_HPPA_ABS_CALL_11:
3116 case R_HPPA_ABS_CALL_14:
3117 case R_HPPA_ABS_CALL_17:
3118 case R_HPPA_ABS_CALL_L21:
3119 case R_HPPA_ABS_CALL_R11:
3120 case R_HPPA_ABS_CALL_R14:
3121 case R_HPPA_ABS_CALL_R17:
3122 case R_HPPA_ABS_CALL_LS21:
3123 case R_HPPA_ABS_CALL_RS11:
3124 case R_HPPA_ABS_CALL_RS14:
3125 case R_HPPA_ABS_CALL_RS17:
3126 case R_HPPA_ABS_CALL_LD21:
3127 case R_HPPA_ABS_CALL_RD11:
3128 case R_HPPA_ABS_CALL_RD14:
3129 case R_HPPA_ABS_CALL_RD17:
3130 case R_HPPA_ABS_CALL_LR21:
3131 case R_HPPA_ABS_CALL_RR14:
3132 case R_HPPA_ABS_CALL_RR17:
3133 case R_HPPA_PCREL_CALL_11:
3134 case R_HPPA_PCREL_CALL_14:
3135 case R_HPPA_PCREL_CALL_17:
3136 case R_HPPA_PCREL_CALL_12:
3137 case R_HPPA_PCREL_CALL_L21:
3138 case R_HPPA_PCREL_CALL_R11:
3139 case R_HPPA_PCREL_CALL_R14:
3140 case R_HPPA_PCREL_CALL_R17:
3141 case R_HPPA_PCREL_CALL_LS21:
3142 case R_HPPA_PCREL_CALL_RS11:
3143 case R_HPPA_PCREL_CALL_RS14:
3144 case R_HPPA_PCREL_CALL_RS17:
3145 case R_HPPA_PCREL_CALL_LD21:
3146 case R_HPPA_PCREL_CALL_RD11:
3147 case R_HPPA_PCREL_CALL_RD14:
3148 case R_HPPA_PCREL_CALL_RD17:
3149 case R_HPPA_PCREL_CALL_LR21:
3150 case R_HPPA_PCREL_CALL_RR14:
3151 case R_HPPA_PCREL_CALL_RR17:
3a70b01d 3152 {
4861ac76
JL
3153 symext_entryS caller_ar
3154 = (symext_entryS) HPPA_R_ARG_RELOC (rle->addend);
3155 unsigned insn[2];
3156
3157 bfd_get_section_contents (abfd, asec, insn, rle->address,
3158 sizeof(insn));
3a70b01d
KR
3159 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3160 caller_ar))
3161 {
4861ac76 3162 /* Generate a stub and keep track of the new symbol. */
3a70b01d 3163 asymbol *r;
d9ad93bc 3164
3a70b01d
KR
3165 if (new_cnt == new_max)
3166 {
3167 new_max += STUB_SYM_BUFFER_INC;
4861ac76
JL
3168 new_syms = (asymbol *)
3169 realloc (new_syms, new_max * sizeof (asymbol));
3a70b01d 3170 }
4861ac76
JL
3171
3172 /* The rtn_adjust argument is true here because we
3173 know that we have a branch and (with a few exceptions
3174 detailed under the relocation code for relocation type
3175 R_HPPA_STUB_CALL_17) it will be possible to perform
3176 the code reorientation. */
3a70b01d 3177 r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
4991ebb9
ILT
3178 link_info, rle,
3179 stub_types,
4861ac76 3180 true, insn);
3a70b01d
KR
3181 new_syms[new_cnt++] = *r;
3182 }
d9ad93bc 3183
4861ac76
JL
3184 /* We need to retrieve the section contents to check for
3185 long branch stubs. */
3186 if (hppa_elf_long_branch_needed_p (abfd, asec, rle,
3187 rle->sym_ptr_ptr[0],
3188 insn[0]))
3189 {
3190 /* Generate a stub and keep track of the new symbol. */
3191 asymbol *r;
3a70b01d 3192
4861ac76
JL
3193 if (new_cnt == new_max)
3194 {
3195 new_max += STUB_SYM_BUFFER_INC;
3196 new_syms = (asymbol *)
3197 realloc (new_syms, (new_max * sizeof (asymbol)));
3198 }
3199 r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
4991ebb9 3200 link_info, rle,
4861ac76
JL
3201 rle->sym_ptr_ptr[0],
3202 insn);
3203 new_syms[new_cnt++] = *r;
3204 }
3a70b01d
KR
3205 }
3206 break;
3207
4861ac76
JL
3208 case R_HPPA_PLABEL_32:
3209 case R_HPPA_PLABEL_11:
3210 case R_HPPA_PLABEL_14:
3211 case R_HPPA_PLABEL_L21:
3212 case R_HPPA_PLABEL_R11:
3213 case R_HPPA_PLABEL_R14:
d9ad93bc 3214 {
3a70b01d 3215 /* On a plabel relocation, assume the arguments of the
4861ac76
JL
3216 caller are set up in general registers.
3217 NOTE: 0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
3a70b01d 3218 symext_entryS caller_ar = (symext_entryS) 0x155;
4861ac76
JL
3219 unsigned insn[2];
3220
3221 bfd_get_section_contents (abfd, asec, insn, rle->address,
3222 sizeof(insn));
d9ad93bc 3223
3a70b01d
KR
3224 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3225 caller_ar))
d9ad93bc 3226 {
4861ac76
JL
3227 /* Generate a plabel stub and keep track of the
3228 new symbol. */
d9ad93bc 3229 asymbol *r;
4861ac76 3230 int rtn_adjust;
d9ad93bc
KR
3231
3232 if (new_cnt == new_max)
3233 {
3234 new_max += STUB_SYM_BUFFER_INC;
4861ac76
JL
3235 new_syms = (asymbol *) realloc (new_syms, new_max
3236 * sizeof (asymbol));
d9ad93bc 3237 }
4861ac76
JL
3238
3239 /* Determine whether a return adjustment
3240 (see the relocation code for relocation type
3241 R_HPPA_STUB_CALL_17) is possible. Basically,
3242 determine whether we are looking at a branch or not. */
3243
3244 if (rle->howto->type == R_HPPA_PLABEL_32)
3245 rtn_adjust = false;
3246 else
3247 {
3248 switch (get_opcode(insn[0]))
3249 {
3250 case BLE:
3251 case BE:
3252 rtn_adjust = true;
3253 break;
3254 default:
3255 rtn_adjust = false;
3256 }
3257 }
3258 r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
4991ebb9
ILT
3259 link_info, rle,
3260 stub_types,
4861ac76 3261 rtn_adjust, insn);
d9ad93bc
KR
3262 new_syms[new_cnt++] = *r;
3263 }
3264 }
e8f2240a 3265 break;
4c85cbfa 3266
e8f2240a
KR
3267 default:
3268 break;
4c85cbfa 3269
e8f2240a
KR
3270 }
3271 }
3272 }
3273 *new_sym_cnt = new_cnt;
3274 return new_syms;
4c85cbfa
KR
3275}
3276
d9ad93bc
KR
3277
3278char *linker_stubs = NULL;
3279int linker_stubs_size = 0;
3280int linker_stubs_max_size = 0;
3281#define STUB_ALLOC_INCR 100
3282
3283boolean
3284DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count),
3285 bfd * abfd AND
3286 sec_ptr section AND
3287 PTR location AND
3288 file_ptr offset AND
3289 bfd_size_type count)
4c85cbfa 3290{
d9ad93bc
KR
3291 if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
3292 {
3293 if ( linker_stubs_max_size < offset + count )
3294 {
3295 linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
3296 linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
3297 }
3298
3299 if ( offset + count > linker_stubs_size )
3300 linker_stubs_size = offset + count;
3301
3302 memcpy(linker_stubs + offset,location,count);
3303 return (true);
3304 }
3305 else
3306 return bfd_elf32_set_section_contents (abfd, section, location,
3307 offset, count);
e8f2240a 3308}
4c85cbfa 3309
7218bb04
KR
3310/* Get the contents of the given section.
3311
3312 This is special for PA ELF because some sections (such as linker stubs)
3313 may reside in memory rather than on disk, or in the case of the symbol
3314 extension section, the contents may need to be generated from other
3315 information contained in the BFD. */
3316
e8f2240a 3317boolean
7218bb04
KR
3318hppa_elf_get_section_contents (abfd, section, location, offset, count)
3319 bfd *abfd;
3320 sec_ptr section;
3321 PTR location;
3322 file_ptr offset;
3323 bfd_size_type count;
e8f2240a 3324{
7218bb04
KR
3325 /* If this is the linker stub section, then its contents are contained
3326 in memory rather than on disk. FIXME. Is that always right? What
3327 about the case where a final executable is read in and a user tries
3328 to get the contents of this section? In that case the contents would
3329 be on disk like everything else. */
e8f2240a
KR
3330 if (strcmp (section->name, ".hppa_linker_stubs") == 0)
3331 {
3a70b01d 3332 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, section);
7218bb04 3333
e8f2240a
KR
3334 if (count == 0)
3335 return true;
7218bb04
KR
3336
3337 /* Sanity check our arguments. */
3338 if ((bfd_size_type) (offset + count) > section->_raw_size
3339 || (bfd_size_type) (offset + count) > stub_desc->real_size)
3340 return (false);
3341
e8f2240a
KR
3342 memcpy (location, stub_desc->stub_contents + offset, count);
3343 return (true);
3344 }
7218bb04
KR
3345
3346 /* The symbol extension section also needs special handling. Its
3347 contents might be on the disk, in memory, or still need to
3348 be generated. */
e8f2240a
KR
3349 else if (strcmp (section->name, ".hppa_symextn") == 0)
3350 {
4861ac76 3351 /* If there are no output sections, then read the contents of the
a5ccdad1
ILT
3352 symbol extension section from disk. */
3353 if (section->output_section == NULL
3354 && abfd->direction == read_direction)
7218bb04
KR
3355 {
3356 return bfd_generic_get_section_contents (abfd, section, location,
3357 offset, count);
3358 }
3359
3360 /* If this is the first time through, and there are output sections,
3361 then build the symbol extension section based on other information
3362 contained in the BFD. */
3363 else if (! symext_chain_built)
3364 {
3365 int i;
a5ccdad1
ILT
3366 int *symtab_map =
3367 (int *) elf_sym_extra(section->output_section->owner);
7218bb04
KR
3368
3369 for (i = 0; i < section->output_section->owner->symcount; i++ )
3370 {
3371 elf_hppa_tc_symbol(section->output_section->owner,
a5ccdad1
ILT
3372 ((elf_symbol_type *)
3373 section->output_section->owner->outsymbols[i]),
7218bb04
KR
3374 symtab_map[i]);
3375 }
3376 symext_chain_built++;
3377 elf_hppa_tc_make_sections (section->output_section->owner, NULL);
3378 }
a5ccdad1
ILT
3379
3380 /* At this point we know that the symbol extension section has been
3381 built. We just need to copy it into the user's buffer. */
e8f2240a
KR
3382 if (count == 0)
3383 return true;
7218bb04
KR
3384
3385 /* Sanity check our arguments. */
3386 if ((bfd_size_type) (offset + count) > section->_raw_size
3387 || (bfd_size_type) (offset + count) > symextn_contents_real_size)
3388 return (false);
3389
3390 memcpy (location,
3391 ((char *)symextn_contents + section->output_offset + offset),
3392 count);
e8f2240a
KR
3393 return (true);
3394 }
3395 else
7218bb04
KR
3396 return bfd_generic_get_section_contents (abfd, section, location,
3397 offset, count);
4c85cbfa
KR
3398}
3399
8ddd7ab3
KR
3400static void
3401DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst),
e8f2240a
KR
3402 bfd * abfd AND
3403 arelent * cache_ptr AND
3404 Elf32_Internal_Rela * dst)
4c85cbfa 3405{
d9ad93bc
KR
3406 BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
3407 cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
3408}
3409
3410static void
3411DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym),
3412 bfd * abfd AND
3413 asymbol * sym)
3414{
3415 /* Is this a definition of $global$? If so, keep it because it will be
3416 needed if any relocations are performed. */
3417
3418 if (!strcmp (sym->name, "$global$")
3419 && sym->section != &bfd_und_section)
3420 {
3421 global_symbol = sym;
3422 }
3423}
3424
3425#define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
3426
3427struct elf32_hppa_symextn_map_struct
3428{
3429 int old_index;
3430 bfd *bfd;
3431 asymbol *sym;
3432 int new_index;
3433};
3434
3435static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
3436static int elf32_hppa_symextn_map_size;
3437
3438static boolean
3439DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt),
3440 bfd * abfd AND
3a70b01d 3441 elf_symbol_type *esyms AND
d9ad93bc
KR
3442 int symcnt)
3443{
3444 Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
3445 int i;
3446 int current_sym_idx = 0;
3447
3448 /* If the symbol extension section does not exist, all the symbol */
3449 /* all the symbol extension information is assumed to be zero. */
3450
3451 if ( symextn_hdr == NULL )
3452 {
3453 for ( i = 0; i < symcnt; i++ )
3454 {
3455 esyms[i].tc_data.hppa_arg_reloc = 0;
3456 }
3457 return (true);
3458 }
3459
3460 /* allocate a buffer of the appropriate size for the symextn section */
3461
3462 symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
3463 symextn_hdr->size = symextn_hdr->sh_size;
3464
3465 /* read in the symextn section */
3466
3467 if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
3468 {
3469 bfd_error = system_call_error;
3470 return (false);
3471 }
3472 if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd)
3473 != symextn_hdr->size)
3474 {
3475 free ((PTR)symextn_hdr->contents);
3476 bfd_error = system_call_error;
3477 return (false);
3478 }
3479
3480 /* parse the entries, updating the symtab entries as we go */
3481
3482 for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
3483 {
3484 symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
3485 int se_value = ELF32_HPPA_SX_VAL(*seP);
3486 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3487
3488 switch ( se_type )
3489 {
3490 case HPPA_SXT_NULL:
3491 break;
3492
3493 case HPPA_SXT_SYMNDX:
3494 if ( se_value >= symcnt )
3495 {
3496 bfd_error = bad_value;
3497 bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3498 return (false);
3499 }
3500 current_sym_idx = se_value - 1;
3501 break;
3502
3503 case HPPA_SXT_ARG_RELOC:
3504 esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
3505 break;
3506
3507 default:
3508 bfd_error = bad_value;
3509 bfd_perror("elf32_hppa_backend_symbol_table_processing");
3510 return (false);
3511 }
3512 }
3513 return (true);
3514}
3515
3516#define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
3517
3518static boolean
3519DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr),
3520 bfd * abfd AND
3521 Elf32_Internal_Shdr *secthdr)
3522{
3523 int i,j,k;
3524
3525 if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
3526 {
3527 for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
3528 {
3529 symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
3530 int se_value = ELF32_HPPA_SX_VAL(*seP);
3531 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3532
3533 switch ( se_type )
3534 {
3535 case HPPA_SXT_NULL:
3536 break;
3537
3538 case HPPA_SXT_SYMNDX:
3539 for ( j = 0; j < abfd->symcount; j++ )
3540 {
3541 /* locate the map entry for this symbol, if there is one. */
3542 /* modify the symbol extension section symbol index entry */
3543 /* to reflect the new symbol table index */
3544
3545 for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
3546 {
3547 if ( elf32_hppa_symextn_map[k].old_index == se_value
3548 && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
3549 && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
3550 {
3551 bfd_put_32(abfd,
3552 ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
3553 (char *)seP);
3554 }
3555 }
3556 }
3557 break;
3558
3559 case HPPA_SXT_ARG_RELOC:
3560 break;
3561
3562 default:
3563 bfd_error = bad_value;
3564 bfd_perror("elf32_hppa_backend_section_processing");
3565 return (false);
3566 }
3567 }
3568 }
3569 return true;
3570}
3571
3572#define elf_backend_section_processing elf32_hppa_backend_section_processing
3573
3574static boolean
3575DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name),
3576 bfd * abfd AND
3577 Elf32_Internal_Shdr *hdr AND
3578 char * name)
3579{
3580 asection *newsect;
3581
3582 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3583 {
3584 BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
3585
3586 /* Bits that get saved. This one is real. */
3587 if (!hdr->rawdata)
3588 {
3589 newsect = bfd_make_section (abfd, name);
3590 if (newsect != NULL)
3591 {
3592 newsect->vma = hdr->sh_addr;
3593 newsect->_raw_size = hdr->sh_size;
3594 newsect->filepos = hdr->sh_offset; /* so we can read back the bits */
3595 newsect->flags |= SEC_HAS_CONTENTS;
3596 newsect->alignment_power = hdr->sh_addralign;
3597
3598 if (hdr->sh_flags & SHF_ALLOC)
3599 {
3600 newsect->flags |= SEC_ALLOC;
3601 newsect->flags |= SEC_LOAD;
3602 }
3603
3604 if (!(hdr->sh_flags & SHF_WRITE))
3605 newsect->flags |= SEC_READONLY;
3606
3607 if (hdr->sh_flags & SHF_EXECINSTR)
3608 newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
3609 else
3610 newsect->flags |= SEC_DATA;
3611
3612 hdr->rawdata = (void *) newsect;
3613 }
3614 }
3615 return true;
3616 }
3617 return false;
3618}
3619
3620#define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
3621
3622static boolean
3623DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect),
3624 bfd * abfd AND
3625 Elf_Internal_Shdr *secthdr AND
3626 asection *asect)
3627{
3628
3629 if ( strcmp(asect->name, ".hppa_symextn") == 0 )
3630 {
3631 secthdr->sh_type = SHT_HPPA_SYMEXTN;
3632 secthdr->sh_flags = 0;
3633 secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
3634 secthdr->sh_link = elf_onesymtab(abfd);
3635 return true;
3636 }
3637
3638 if (!strcmp (asect->name, ".hppa_unwind"))
3639 {
3640 secthdr->sh_type = SHT_PROGBITS;
3641 /* Unwind descriptors are not part of the program memory image. */
3642 secthdr->sh_flags = 0;
3643 secthdr->sh_info = 0;
3644 secthdr->sh_link = 0;
3645 secthdr->sh_entsize = 16;
3646 return true;
3647 }
3648
7218bb04
KR
3649 /* @@ Should this be CPU specific?? KR */
3650 if (!strcmp (asect->name, ".stabstr"))
3651 {
3652 secthdr->sh_type = SHT_STRTAB;
3653 secthdr->sh_flags = 0;
3654 secthdr->sh_info = 0;
3655 secthdr->sh_link = 0;
3656 secthdr->sh_entsize = 0;
3657 return true;
3658 }
3659
d9ad93bc
KR
3660 return false;
3661}
3662
3663#define elf_backend_fake_sections elf32_hppa_backend_fake_sections
3664
3665static boolean
7218bb04 3666DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect, retval),
d9ad93bc
KR
3667 bfd *abfd AND
3668 Elf32_Internal_Shdr *hdr AND
7218bb04
KR
3669 asection *asect AND
3670 int *retval)
d9ad93bc
KR
3671{
3672
3673 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3674 {
3675 if (hdr->rawdata)
3676 {
3677 if (((struct sec *) (hdr->rawdata)) == asect)
3678 {
3679 BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
3680 return true;
3681 }
3682 }
3683 }
7218bb04
KR
3684 else if ( hdr->sh_type == SHT_STRTAB )
3685 {
3686 if (hdr->rawdata)
3687 {
3688 if (((struct sec *) (hdr->rawdata)) == asect)
3689 {
3690 BFD_ASSERT ( strcmp (asect->name, ".stabstr") == 0);
3691 return true;
3692 }
3693 }
3694 }
d9ad93bc
KR
3695
3696 return false;
8ddd7ab3 3697}
4c85cbfa 3698
d9ad93bc
KR
3699#define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
3700
3701#define bfd_generic_get_section_contents hppa_elf_get_section_contents
3702#define bfd_elf32_set_section_contents hppa_elf_set_section_contents
3703
e8f2240a 3704#define TARGET_BIG_SYM bfd_elf32_hppa_vec
8ddd7ab3
KR
3705#define TARGET_BIG_NAME "elf32-hppa"
3706#define ELF_ARCH bfd_arch_hppa
a5ccdad1 3707#define ELF_MACHINE_CODE EM_HPPA
3a70b01d 3708#define ELF_MAXPAGESIZE 0x1000
8ddd7ab3
KR
3709
3710#include "elf32-target.h"
This page took 0.593009 seconds and 4 git commands to generate.