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