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