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