Make all callers of malloc or realloc (including via obstacks)
[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); /* FIXME */
489
490 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
491 BFD_ASSERT (finaltype != 0); /* FIXME */
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); /* FIXME */
1094
1095 finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
1096 BFD_ASSERT (finaltype != 0); /* FIXME */
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 if (!symextP)
1751 {
1752 bfd_error = no_memory;
1753 abort(); /* FIXME */
1754 }
1755
1756 symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
1757 symextP[0].next = &symextP[1];
1758
1759 symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
1760 symextP[1].next = NULL;
1761
1762 if (symext_rootP == NULL)
1763 {
1764 symext_rootP = &symextP[0];
1765 symext_lastP = &symextP[1];
1766 }
1767 else
1768 {
1769 symext_lastP->next = &symextP[0];
1770 symext_lastP = &symextP[1];
1771 }
1772 }
1773
1774 /* Accessor function for the list of symbol extension records. */
1775 symext_chainS *elf32_hppa_get_symextn_chain()
1776 {
1777 return symext_rootP;
1778 }
1779
1780 static symext_entryS *symextn_contents;
1781 static unsigned int symextn_contents_real_size;
1782
1783 void
1784 elf_hppa_tc_make_sections (abfd, ignored)
1785 bfd *abfd;
1786 PTR ignored;
1787 {
1788 symext_chainS *symextP;
1789 int size;
1790 int n;
1791 int i;
1792 void hppa_elf_stub_finish (); /* forward declaration */
1793 asection *symextn_sec;
1794
1795 hppa_elf_stub_finish (abfd);
1796
1797 if (symext_rootP == NULL)
1798 return;
1799
1800 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
1801 ;
1802
1803 size = sizeof (symext_entryS) * n;
1804 symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
1805 if (symextn_sec == (asection *) 0)
1806 {
1807 symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
1808 bfd_set_section_flags (abfd,
1809 symextn_sec,
1810 SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
1811 symextn_sec->output_section = symextn_sec;
1812 symextn_sec->output_offset = 0;
1813 bfd_set_section_alignment (abfd, symextn_sec, 2);
1814 }
1815 symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
1816 if (!symextn_contents)
1817 {
1818 bfd_error = no_memory;
1819 abort(); /* FIXME */
1820 }
1821
1822 for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
1823 symextn_contents[i] = symextP->entry;
1824 symextn_contents_real_size = size;
1825 bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
1826
1827 return;
1828 }
1829
1830 /* Support for HP PA-RISC stub generation.
1831
1832 Written by
1833
1834 Center for Software Science
1835 Department of Computer Science
1836 University of Utah
1837
1838 */
1839
1840 /*
1841 HP-PA calling conventions state:
1842
1843 1. an argument relocation stub is required whenever the callee and
1844 caller argument relocation bits do not match exactly. The exception
1845 to this rule is if either the caller or callee argument relocation
1846 bit are 00 (do not relocate).
1847
1848 2. The linker can optionally add a symbol record for the stub so that
1849 the stub can be reused. The symbol record will be the same as the
1850 original export symbol record, except that the relocation bits will
1851 reflect the input of the stub, the type would be STUB and the symbol
1852 value will be the location of the relocation stub.
1853
1854 Other notes:
1855
1856 Stubs can be inserted *before* the section of the caller. The stubs
1857 can be treated as calls to code that manipulates the arguments.
1858
1859 */
1860
1861 typedef enum
1862 {
1863 HPPA_STUB_ILLEGAL,
1864 HPPA_STUB_ARG_RELOC,
1865 HPPA_STUB_LONG_BRANCH
1866 } hppa_stub_type;
1867
1868 symext_entryS
1869 elf32_hppa_get_sym_extn (abfd, sym, type)
1870 bfd *abfd;
1871 asymbol *sym;
1872 int type;
1873 {
1874 /* This function finds the symbol extension record of the */
1875 /* specified type for the specified symbol. It returns the */
1876 /* value of the symbol extension record. */
1877 symext_entryS retval;
1878
1879 switch (type)
1880 {
1881 case HPPA_SXT_NULL:
1882 retval = (symext_entryS) 0;
1883 break;
1884 case HPPA_SXT_SYMNDX:
1885 retval = (symext_entryS) 0; /* XXX: need to fix this */
1886 break;
1887 case HPPA_SXT_ARG_RELOC:
1888 {
1889 elf_symbol_type *esymP = (elf_symbol_type *) sym;
1890
1891 retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
1892 break;
1893 }
1894 /* This should never happen. */
1895 default:
1896 abort();
1897 }
1898 return retval;
1899 }
1900
1901 typedef struct elf32_hppa_stub_name_list_struct
1902 {
1903 /* name of this stub */
1904 asymbol *sym;
1905 /* stub description for this stub */
1906 struct elf32_hppa_stub_description_struct *stub_desc;
1907 /* pointer into stub contents */
1908 int *stub_secp;
1909 /* size of this stub */
1910 unsigned size;
1911 /* next stub name entry */
1912 struct elf32_hppa_stub_name_list_struct *next;
1913 } elf32_hppa_stub_name_list;
1914
1915 typedef struct elf32_hppa_stub_description_struct
1916 {
1917 struct elf32_hppa_stub_description_struct *next;
1918 bfd *this_bfd; /* bfd to which this stub applies */
1919 asection *stub_sec; /* stub section for this bfd */
1920 unsigned relocs_allocated_cnt; /* count of relocations for this stub section */
1921 unsigned real_size;
1922 unsigned allocated_size;
1923 int *stub_secp; /* pointer to the next available location in the buffer */
1924 char *stub_contents; /* contents of the stubs for this bfd */
1925 elf32_hppa_stub_name_list *stub_listP;
1926 struct bfd_link_info *link_info;
1927 }
1928 elf32_hppa_stub_description;
1929
1930 static elf32_hppa_stub_description *elf_hppa_stub_rootP;
1931
1932 /* Locate the stub section information for the given bfd. */
1933 static elf32_hppa_stub_description *
1934 find_stubs (abfd, stub_sec)
1935 bfd *abfd;
1936 asection *stub_sec;
1937 {
1938 elf32_hppa_stub_description *stubP;
1939
1940 for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
1941 {
1942 if (stubP->this_bfd == abfd
1943 && stubP->stub_sec == stub_sec)
1944 return stubP;
1945 }
1946
1947 return (elf32_hppa_stub_description *) NULL;
1948 }
1949
1950 static elf32_hppa_stub_description *
1951 new_stub (abfd, stub_sec, link_info)
1952 bfd *abfd;
1953 asection *stub_sec;
1954 struct bfd_link_info *link_info;
1955 {
1956 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
1957
1958 if (stub)
1959 return stub;
1960
1961 stub = (elf32_hppa_stub_description *) bfd_zalloc (abfd, sizeof (elf32_hppa_stub_description));
1962 if (stub)
1963 {
1964 stub->this_bfd = abfd;
1965 stub->stub_sec = stub_sec;
1966 stub->real_size = 0;
1967 stub->allocated_size = 0;
1968 stub->stub_contents = NULL;
1969 stub->stub_secp = NULL;
1970 stub->link_info = link_info;
1971
1972 stub->next = elf_hppa_stub_rootP;
1973 elf_hppa_stub_rootP = stub;
1974 }
1975 else
1976 {
1977 bfd_error = no_memory;
1978 abort(); /* FIXME */
1979 }
1980
1981 return stub;
1982 }
1983
1984 /* Locate the stub by the given name. */
1985 static elf32_hppa_stub_name_list *
1986 find_stub_by_name (abfd, stub_sec, name)
1987 bfd *abfd;
1988 asection *stub_sec;
1989 char *name;
1990 {
1991 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
1992
1993 if (stub)
1994 {
1995 elf32_hppa_stub_name_list *name_listP;
1996
1997 for (name_listP = stub->stub_listP; name_listP; name_listP = name_listP->next)
1998 {
1999 if (!strcmp (name_listP->sym->name, name))
2000 return name_listP;
2001 }
2002 }
2003
2004 return 0;
2005 }
2006
2007 /* Locate the stub by the given name. */
2008 static elf32_hppa_stub_name_list *
2009 add_stub_by_name(abfd, stub_sec, sym, link_info)
2010 bfd *abfd;
2011 asection *stub_sec;
2012 asymbol *sym;
2013 struct bfd_link_info *link_info;
2014 {
2015 elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
2016 elf32_hppa_stub_name_list *stub_entry;
2017
2018 if (!stub)
2019 stub = new_stub(abfd, stub_sec, link_info);
2020
2021 if (stub)
2022 {
2023 stub_entry = (elf32_hppa_stub_name_list *)
2024 bfd_zalloc (abfd, sizeof (elf32_hppa_stub_name_list));
2025
2026 if (stub_entry)
2027 {
2028 stub_entry->size = 0;
2029 stub_entry->sym = sym;
2030 stub_entry->stub_desc = stub;
2031 /* First byte of this stub is the pointer to
2032 the next available location in the stub buffer. */
2033 stub_entry->stub_secp = stub->stub_secp;
2034 if (stub->stub_listP)
2035 stub_entry->next = stub->stub_listP;
2036 else
2037 stub_entry->next = NULL;
2038 stub->stub_listP = stub_entry;
2039 return stub_entry;
2040 }
2041 else
2042 {
2043 bfd_error = no_memory;
2044 abort(); /* FIXME */
2045 }
2046 }
2047
2048 return (elf32_hppa_stub_name_list *)NULL;
2049 }
2050
2051 #define ARGUMENTS 0
2052 #define RETURN_VALUE 1
2053
2054 #define NO_ARG_RELOC 0
2055 #define R_TO_FR 1
2056 #define R01_TO_FR 2
2057 #define R23_TO_FR 3
2058 #define FR_TO_R 4
2059 #define FR_TO_R01 5
2060 #define FR_TO_R23 6
2061 #define ARG_RELOC_ERR 7
2062
2063 #define ARG0 0
2064 #define ARG1 1
2065 #define ARG2 2
2066 #define ARG3 3
2067 #define RETVAL 4
2068
2069 #define AR_NO 0
2070 #define AR_GR 1
2071 #define AR_FR 2
2072 #define AR_FU 3
2073 /* FP register in arg0/arg1. This value can only appear in the arg0 location. */
2074 #define AR_DBL01 4
2075 /* FP register in arg2/arg3. This value can only appear in the arg2 location. */
2076 #define AR_DBL23 5
2077
2078 #define AR_WARN(type,loc) \
2079 fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
2080 reloc_type_strings[type],reloc_loc_strings[loc])
2081
2082 static CONST char *CONST reloc_type_strings[] =
2083 {
2084 "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
2085 };
2086
2087 static CONST char *CONST reloc_loc_strings[] =
2088 {
2089 "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
2090 };
2091
2092 static CONST char mismatches[6][6] =
2093 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
2094 /* CALLER NONE */
2095 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
2096 /* CALLER GR */
2097 {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
2098 /* CALLER FR */
2099 {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
2100 /* CALLER FU */
2101 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2102 /* CALLER DBL01 */
2103 {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
2104 /* CALLER DBL23 */
2105 {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
2106 };
2107
2108 static CONST char retval_mismatches[6][6] =
2109 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
2110 /* CALLER NONE */
2111 {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
2112 /* CALLER GR */
2113 {NO_ARG_RELOC, NO_ARG_RELOC, FR_TO_R, ARG_RELOC_ERR, FR_TO_R01, ARG_RELOC_ERR},
2114 /* CALLER FR */
2115 {NO_ARG_RELOC, R_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2116 /* CALLER FU */
2117 {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2118 /* CALLER DBL01 */
2119 {NO_ARG_RELOC, R01_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
2120 /* CALLER DBL23 */
2121 {NO_ARG_RELOC, R23_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
2122 };
2123
2124 static int
2125 type_of_mismatch (caller_bits, callee_bits, type)
2126 int caller_bits;
2127 int callee_bits;
2128 int type;
2129 {
2130 switch (type)
2131 {
2132 case ARGUMENTS:
2133 return mismatches[caller_bits][callee_bits];
2134 case RETURN_VALUE:
2135 return retval_mismatches[caller_bits][callee_bits];
2136 }
2137
2138 return 0;
2139 }
2140
2141 #define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
2142
2143 #define NEW_INSTRUCTION(entry,insn) \
2144 { \
2145 *((entry)->stub_desc->stub_secp)++ = (insn); \
2146 (entry)->stub_desc->real_size += sizeof(int); \
2147 (entry)->size += sizeof(int); \
2148 bfd_set_section_size((entry)->stub_desc->this_bfd, \
2149 (entry)->stub_desc->stub_sec, \
2150 (entry)->stub_desc->real_size); \
2151 }
2152
2153 #define CURRENT_STUB_OFFSET(entry) \
2154 ((char *)(entry)->stub_desc->stub_secp \
2155 - (char *)(entry)->stub_desc->stub_contents - 4)
2156
2157 static boolean stubs_finished = false;
2158
2159 void
2160 hppa_elf_stub_finish (output_bfd)
2161 bfd *output_bfd;
2162 {
2163 elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
2164 /* All the stubs have been built. Finish up building */
2165 /* stub section. Apply relocations to the section. */
2166
2167 if ( stubs_finished )
2168 return;
2169
2170 for (; stub_list; stub_list = stub_list->next)
2171 {
2172 if (stub_list->real_size)
2173 {
2174 bfd *stub_bfd = stub_list->this_bfd;
2175 asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
2176 bfd_size_type reloc_size;
2177 arelent **reloc_vector;
2178
2179 BFD_ASSERT (stub_sec == stub_list->stub_sec);
2180 reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
2181 reloc_vector = (arelent **) alloca (reloc_size);
2182
2183 BFD_ASSERT (stub_sec);
2184
2185 /* We are not relaxing the section, so just copy the size info */
2186 stub_sec->_cooked_size = stub_sec->_raw_size;
2187 stub_sec->reloc_done = true;
2188
2189
2190 if (bfd_canonicalize_reloc (stub_bfd,
2191 stub_sec,
2192 reloc_vector,
2193 output_bfd->outsymbols))
2194 {
2195 arelent **parent;
2196 for (parent = reloc_vector; *parent != (arelent *) NULL;
2197 parent++)
2198 {
2199 char *err = (char *) NULL;
2200 bfd_reloc_status_type r =
2201 bfd_perform_relocation (stub_bfd,
2202 *parent,
2203 stub_list->stub_contents,
2204 stub_sec, (bfd *) NULL, &err);
2205
2206
2207 if (r != bfd_reloc_ok)
2208 {
2209 struct bfd_link_info *link_info = stub_list->link_info;
2210
2211 switch (r)
2212 {
2213 case bfd_reloc_undefined:
2214 if (! ((*link_info->callbacks->undefined_symbol)
2215 (link_info,
2216 bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2217 stub_bfd, stub_sec, (*parent)->address)))
2218 abort ();
2219 break;
2220 case bfd_reloc_dangerous:
2221 if (! ((*link_info->callbacks->reloc_dangerous)
2222 (link_info, err, stub_bfd, stub_sec,
2223 (*parent)->address)))
2224 abort ();
2225 break;
2226 case bfd_reloc_overflow:
2227 {
2228 if (! ((*link_info->callbacks->reloc_overflow)
2229 (link_info,
2230 bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2231 (*parent)->howto->name,
2232 (*parent)->addend,
2233 stub_bfd, stub_sec,
2234 (*parent)->address)))
2235 abort ();
2236 }
2237 break;
2238 case bfd_reloc_outofrange:
2239 default:
2240 abort ();
2241 break;
2242 }
2243 }
2244 }
2245 }
2246
2247 bfd_set_section_contents (output_bfd,
2248 stub_sec,
2249 stub_list->stub_contents,
2250 0,
2251 stub_list->real_size);
2252
2253 free (reloc_vector);
2254 }
2255 }
2256 stubs_finished = true;
2257 }
2258
2259 void
2260 hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */
2261 output_bfd, /* the output bfd */
2262 target_sym, /* the target symbol */
2263 offset) /* the offset within the stub buffer (pre-calculated) */
2264 elf32_hppa_stub_description *stub_desc;
2265 bfd *output_bfd;
2266 asymbol *target_sym;
2267 int offset;
2268 {
2269 /* Allocate a new relocation entry. */
2270 arelent relent;
2271 int size;
2272
2273 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2274 {
2275 if (stub_desc->stub_sec->relocation == NULL)
2276 {
2277 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2278 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2279 stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
2280 }
2281 else
2282 {
2283 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2284 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2285 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2286 size);
2287 }
2288 if (!stub_desc->stub_sec->relocation)
2289 {
2290 bfd_error = no_memory;
2291 abort(); /* FIXME */
2292 }
2293 }
2294
2295 /* Fill in the details. */
2296 relent.address = offset;
2297 relent.addend = 0;
2298 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2299 BFD_ASSERT (relent.sym_ptr_ptr); /* FIXME */
2300
2301 relent.sym_ptr_ptr[0] = target_sym;
2302 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
2303
2304 /* Save it in the array of relocations for the stub section. */
2305
2306 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2307 &relent,
2308 sizeof (arelent));
2309 }
2310
2311 void
2312 hppa_elf_stub_reloc (stub_desc, /* the bfd */
2313 output_bfd, /* the output bfd */
2314 target_sym, /* the target symbol */
2315 offset, /* the offset within the stub buffer (pre-calculated) */
2316 type)
2317 elf32_hppa_stub_description *stub_desc;
2318 bfd *output_bfd;
2319 asymbol *target_sym;
2320 int offset;
2321 elf32_hppa_reloc_type type;
2322 {
2323 /* Allocate a new relocation entry. */
2324 arelent relent;
2325 int size;
2326 Elf_Internal_Shdr *rela_hdr;
2327
2328 if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2329 {
2330 if (stub_desc->stub_sec->relocation == NULL)
2331 {
2332 stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2333 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2334 stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
2335 }
2336 else
2337 {
2338 stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2339 size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2340 stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2341 size);
2342 }
2343 if (!stub_desc->stub_sec->relocation)
2344 {
2345 bfd_error = no_memory;
2346 abort(); /* FIXME */
2347 }
2348 }
2349
2350 rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
2351 rela_hdr->sh_size += sizeof(Elf32_External_Rela);
2352
2353 /* Fill in the details. */
2354 relent.address = offset;
2355 relent.addend = 0;
2356 relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2357 BFD_ASSERT (relent.sym_ptr_ptr); /* FIXME */
2358
2359 relent.sym_ptr_ptr[0] = target_sym;
2360 relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
2361
2362 /* Save it in the array of relocations for the stub section. */
2363
2364 memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2365 &relent,
2366 sizeof (arelent));
2367 }
2368
2369 asymbol *
2370 hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
2371 stub_types, rtn_adjust, data)
2372 bfd *abfd;
2373 bfd *output_bfd;
2374 struct bfd_link_info *link_info;
2375 arelent *reloc_entry;
2376 int stub_types[5];
2377 int rtn_adjust;
2378 unsigned *data;
2379 {
2380 asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2381 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
2382 asymbol *stub_sym = NULL;
2383 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2384 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2385 int i;
2386 char stub_sym_name[128];
2387 elf32_hppa_stub_name_list *stub_entry;
2388 unsigned insn = data[0];
2389
2390 /* Perform some additional checks on whether we should really do the
2391 return adjustment. For example, if the instruction is nullified
2392 or if the delay slot contains an instruction that modifies the return
2393 pointer, then the branch instructions should not be rearranged
2394 (rtn_adjust is false). */
2395 if (insn & 2 || insn == 0)
2396 rtn_adjust = false;
2397 else
2398 {
2399 unsigned delay_insn = data[1];
2400
2401 if (get_opcode (delay_insn) == LDO
2402 && (((insn & 0x03e00000) >> 21) == ((delay_insn & 0x001f0000) >> 16)))
2403 rtn_adjust = false;
2404 }
2405
2406 /* See if the proper stub entry has already been made. */
2407 if (!stub_sec)
2408 {
2409 BFD_ASSERT (stub_desc == NULL);
2410 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2411 bfd_set_section_flags (abfd,
2412 stub_sec,
2413 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2414 | SEC_RELOC | SEC_CODE | SEC_READONLY);
2415 stub_sec->output_section = output_text_section->output_section;
2416 stub_sec->output_offset = 0;
2417 bfd_set_section_alignment (abfd, stub_sec, 2);
2418 stub_desc = new_stub (abfd, stub_sec, link_info);
2419 }
2420
2421 /* Make the stub if we did not find one already. */
2422 if (!stub_desc)
2423 stub_desc = new_stub (abfd, stub_sec, link_info);
2424
2425 /* Allocate space to write the stub.
2426 FIXME. Why using realloc?!? */
2427 if (!stub_desc->stub_contents)
2428 {
2429 stub_desc->allocated_size = STUB_BUFFER_INCR;
2430 stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
2431 if (!stub_desc->stub_contents)
2432 {
2433 bfd_error = no_memory;
2434 return NULL;
2435 }
2436 }
2437 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2438 {
2439 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2440 stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2441 stub_desc->allocated_size);
2442 }
2443
2444 stub_desc->stub_secp
2445 = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2446
2447 sprintf (stub_sym_name,
2448 "_stub_%s_%02d_%02d_%02d_%02d_%02d_%s",
2449 reloc_entry->sym_ptr_ptr[0]->name,
2450 stub_types[0], stub_types[1], stub_types[2],
2451 stub_types[3], stub_types[4],
2452 rtn_adjust ? "RA" : "");
2453 stub_entry = find_stub_by_name (abfd, stub_sec, stub_sym_name);
2454
2455 if (stub_entry)
2456 {
2457 stub_sym = stub_entry->sym;
2458 /* Redirect the original relocation from the old symbol (a function)
2459 to the stub (the stub calls the function). Should we need to
2460 change the relocation type? */
2461 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2462 sizeof (asymbol *));
2463 if (!reloc_entry->sym_ptr_ptr)
2464 {
2465 bfd_error = no_memory;
2466 return NULL;
2467 }
2468 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2469 if (reloc_entry->howto->type != R_HPPA_PLABEL_32
2470 && (get_opcode(insn) == BLE
2471 || get_opcode (insn) == BE
2472 || get_opcode (insn) == BL))
2473 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2474 }
2475 else
2476 {
2477 /* Create a new symbol to point to this stub. */
2478 stub_sym = bfd_make_empty_symbol (abfd);
2479 if (!stub_sym)
2480 {
2481 bfd_error = no_memory;
2482 return NULL;
2483 }
2484 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2485 if (!stub_sym->name)
2486 {
2487 bfd_error = no_memory;
2488 return NULL;
2489 }
2490 strcpy ((char *) stub_sym->name, stub_sym_name);
2491 stub_sym->value
2492 = (char *) stub_desc->stub_secp - (char *) stub_desc->stub_contents;
2493 stub_sym->section = stub_sec;
2494 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2495 stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
2496
2497 /* Redirect the original relocation from the old symbol (a function)
2498 to the stub (the stub calls the function). Change the type of
2499 relocation to be the internal use only stub R_HPPA_STUB_CALL_17. */
2500 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2501 sizeof (asymbol *));
2502 if (!reloc_entry->sym_ptr_ptr)
2503 {
2504 bfd_error = no_memory;
2505 return NULL;
2506 }
2507 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2508 if (reloc_entry->howto->type != R_HPPA_PLABEL_32
2509 && (get_opcode (insn) == BLE
2510 || get_opcode (insn) == BE
2511 || get_opcode (insn) == BL))
2512 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2513
2514 /* Generate common code for all stubs. */
2515
2516 NEW_INSTRUCTION (stub_entry, LDSID_31_1);
2517 NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
2518 NEW_INSTRUCTION (stub_entry, ADDI_8_SP);
2519
2520 /* Generate code to move the arguments around. */
2521 for (i = ARG0; i < ARG3; i++)
2522 {
2523 if (stub_types[i] != NO_ARG_RELOC)
2524 {
2525 switch (stub_types[i])
2526 {
2527 case R_TO_FR:
2528 switch (i)
2529 {
2530 case ARG0:
2531 NEW_INSTRUCTION (stub_entry, STWS_ARG0_M8SP);
2532 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG0);
2533 break;
2534 case ARG1:
2535 NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2536 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG1);
2537 break;
2538 case ARG2:
2539 NEW_INSTRUCTION (stub_entry, STWS_ARG2_M8SP);
2540 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG2);
2541 break;
2542 case ARG3:
2543 NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2544 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG3);
2545 break;
2546 }
2547 continue;
2548
2549 case R01_TO_FR:
2550 switch (i)
2551 {
2552 case ARG0:
2553 NEW_INSTRUCTION (stub_entry, STWS_ARG0_M4SP);
2554 NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2555 NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG1);
2556 break;
2557 default:
2558 AR_WARN (stub_types[i],i);
2559 break;
2560 }
2561 continue;
2562
2563 case R23_TO_FR:
2564 switch (i)
2565 {
2566 case ARG2:
2567 NEW_INSTRUCTION (stub_entry, STWS_ARG2_M4SP);
2568 NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2569 NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG3);
2570 break;
2571 default:
2572 AR_WARN (stub_types[i],i);
2573 break;
2574 }
2575 continue;
2576
2577 case FR_TO_R:
2578 switch (i)
2579 {
2580 case ARG0:
2581 NEW_INSTRUCTION (stub_entry, FSTWS_FARG0_M8SP);
2582 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2583 break;
2584 case ARG1:
2585 NEW_INSTRUCTION (stub_entry, FSTWS_FARG1_M8SP);
2586 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG1);
2587 break;
2588 case ARG2:
2589 NEW_INSTRUCTION (stub_entry, FSTWS_FARG2_M8SP);
2590 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2591 break;
2592 case ARG3:
2593 NEW_INSTRUCTION (stub_entry, FSTWS_FARG3_M8SP);
2594 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG3);
2595 break;
2596 }
2597 continue;
2598
2599 case FR_TO_R01:
2600 switch (i)
2601 {
2602 case ARG0:
2603 NEW_INSTRUCTION (stub_entry, FSTDS_FARG1_M8SP);
2604 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2605 NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG1);
2606 break;
2607 default:
2608 AR_WARN (stub_types[i],i);
2609 break;
2610 }
2611 continue;
2612
2613 case FR_TO_R23:
2614 switch (i)
2615 {
2616 case ARG2:
2617 NEW_INSTRUCTION (stub_entry, FSTDS_FARG3_M8SP);
2618 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2619 NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG3);
2620 break;
2621 default:
2622 AR_WARN (stub_types[i],i);
2623 break;
2624 }
2625 continue;
2626
2627 }
2628 }
2629 }
2630
2631 NEW_INSTRUCTION (stub_entry, ADDI_M8_SP_SP);
2632
2633 /* Adjust the return address if necessary. */
2634 if (rtn_adjust)
2635 {
2636 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
2637 }
2638 else
2639 NEW_INSTRUCTION (stub_entry, COPY_31_2);
2640
2641 /* Save the return address. */
2642 NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
2643
2644 /* Long branch to the target function. */
2645 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
2646 hppa_elf_stub_reloc (stub_entry->stub_desc,
2647 abfd,
2648 target_sym,
2649 CURRENT_STUB_OFFSET (stub_entry),
2650 R_HPPA_L21);
2651 NEW_INSTRUCTION (stub_entry, BLE_XXX_0_31);
2652 hppa_elf_stub_reloc (stub_entry->stub_desc,
2653 abfd,
2654 target_sym,
2655 CURRENT_STUB_OFFSET (stub_entry),
2656 R_HPPA_ABS_CALL_R17);
2657 NEW_INSTRUCTION (stub_entry, COPY_31_2);
2658
2659
2660 /* Restore the return address. */
2661 NEW_INSTRUCTION (stub_entry, LDW_M8SP_RP);
2662
2663 /* Generate the code to move the return value around. */
2664 i = RETVAL;
2665 if (stub_types[i] != NO_ARG_RELOC)
2666 {
2667 switch (stub_types[i])
2668 {
2669 case R_TO_FR:
2670 NEW_INSTRUCTION (stub_entry, STWS_RET0_M8SP);
2671 NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FRET0);
2672 break;
2673
2674 case FR_TO_R:
2675 NEW_INSTRUCTION (stub_entry, FSTWS_FRET0_M8SP);
2676 NEW_INSTRUCTION (stub_entry, LDWS_M4SP_RET0);
2677 break;
2678 }
2679 }
2680 NEW_INSTRUCTION (stub_entry, BV_N_0_RP);
2681 }
2682
2683 return stub_sym;
2684 }
2685
2686 int
2687 hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
2688 bfd *abfd;
2689 arelent *reloc_entry;
2690 int stub_types[5];
2691 symext_entryS caller_ar;
2692 {
2693 /* If the symbol is still undefined, there is */
2694 /* no way to know if a stub is required. */
2695
2696 if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
2697 {
2698 symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
2699 reloc_entry->sym_ptr_ptr[0],
2700 HPPA_SXT_ARG_RELOC);
2701
2702 /* Now, determine if a stub is */
2703 /* required. A stub is required if they the callee and caller */
2704 /* argument relocation bits are both nonzero and not equal. */
2705
2706 if (caller_ar && callee_ar)
2707 {
2708 /* Both are non-zero, we need to do further checking. */
2709 /* First, check if there is a return value relocation to be done */
2710 int caller_loc[5];
2711 int callee_loc[5];
2712
2713 callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
2714 caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
2715 callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
2716 caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
2717 callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
2718 caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
2719 callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
2720 caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
2721 callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
2722 caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
2723
2724 /* Check some special combinations. For */
2725 /* example, if FU appears in ARG1 or ARG3, we */
2726 /* can move it to ARG0 or ARG2, respectively. */
2727
2728 if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
2729 {
2730 caller_loc[ARG0] = AR_DBL01;
2731 caller_loc[ARG1] = AR_NO;
2732 }
2733 if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
2734 {
2735 caller_loc[ARG2] = AR_DBL23;
2736 caller_loc[ARG3] = AR_NO;
2737 }
2738 if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
2739 {
2740 callee_loc[ARG0] = AR_DBL01;
2741 callee_loc[ARG1] = AR_NO;
2742 }
2743 if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
2744 {
2745 callee_loc[ARG2] = AR_DBL23;
2746 callee_loc[ARG3] = AR_NO;
2747 }
2748
2749 stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
2750 stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
2751 stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
2752 stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
2753 stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
2754
2755 /* Steps involved in building stubs: */
2756 /* 1. Determine what argument registers need to relocated. This */
2757 /* step is already done here. */
2758 /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2759 /* This section should never appear in an object file. It is */
2760 /* only used internally. The output_section of the */
2761 /* .hppa_linker_stubs section is the .text section of the */
2762 /* executable. */
2763 /* 3. Build a symbol that is used (internally only) as the entry */
2764 /* point of the stub. */
2765 /* 4. Change the instruction of the original branch into a branch to */
2766 /* the stub routine. */
2767 /* 5. Build a relocation entry for the instruction of the original */
2768 /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
2769
2770
2771 if (stub_types[0]
2772 || stub_types[1]
2773 || stub_types[2]
2774 || stub_types[3]
2775 || stub_types[4])
2776 {
2777 #ifdef DETECT_STUBS
2778 int i;
2779
2780 fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2781 reloc_entry->sym_ptr_ptr[0]->name,
2782 abfd->filename, reloc_entry->address,
2783 callee_ar, caller_ar);
2784 for (i = ARG0; i < RETVAL; i++)
2785 {
2786 if (stub_types[i] != NO_ARG_RELOC)
2787 {
2788 fprintf (stderr, "%s%d: %s ",
2789 i == RETVAL ? "ret" : "arg",
2790 i == RETVAL ? 0 : i,
2791 reloc_type_strings[stub_types[i]]);
2792 }
2793 }
2794 fprintf (stderr, "\n");
2795 #endif
2796 return 1;
2797 }
2798
2799 }
2800 }
2801 return 0;
2802 }
2803
2804 asymbol *
2805 hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
2806 symbol, data)
2807 bfd *abfd;
2808 bfd *output_bfd;
2809 struct bfd_link_info *link_info;
2810 arelent *reloc_entry;
2811 asymbol *symbol;
2812 unsigned *data;
2813 {
2814 asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2815 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
2816 asymbol *stub_sym = NULL;
2817 asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2818 asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2819 char stub_sym_name[128];
2820 int milli = false;
2821 int dyncall = false;
2822 elf32_hppa_stub_name_list *stub_entry;
2823 int rtn_adjust = true;
2824 int rtn_reg;
2825 unsigned insn;
2826
2827 /* Create the stub section if it does not already exist. */
2828 if (!stub_sec)
2829 {
2830 BFD_ASSERT (stub_desc == NULL);
2831 stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2832 bfd_set_section_flags (abfd,
2833 stub_sec,
2834 SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2835 | SEC_RELOC | SEC_CODE | SEC_READONLY);
2836 stub_sec->output_section = output_text_section->output_section;
2837 stub_sec->output_offset = 0;
2838
2839 /* Set up the ELF section header for this new section. This
2840 is basically the same processing as elf_make_sections().
2841 elf_make_sections is static and therefore not accessable
2842 here. */
2843 {
2844 Elf_Internal_Shdr *this_hdr;
2845 this_hdr = &elf_section_data (stub_sec)->this_hdr;
2846
2847 /* Set the sizes of this section. The contents have already
2848 been set up ?!? */
2849 this_hdr->sh_addr = stub_sec->vma;
2850 this_hdr->sh_size = stub_sec->_raw_size;
2851
2852 /* Set appropriate flags for sections with relocations. */
2853 if (stub_sec->flags & SEC_RELOC)
2854 {
2855 Elf_Internal_Shdr *rela_hdr;
2856 int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
2857
2858 rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
2859
2860 if (use_rela_p)
2861 {
2862 rela_hdr->sh_type = SHT_RELA;
2863 rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
2864 }
2865 else
2866 {
2867 rela_hdr->sh_type = SHT_REL;
2868 rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
2869 }
2870 rela_hdr->sh_flags = 0;
2871 rela_hdr->sh_addr = 0;
2872 rela_hdr->sh_offset = 0;
2873 rela_hdr->sh_addralign = 0;
2874 rela_hdr->size = 0;
2875 }
2876
2877 if (stub_sec->flags & SEC_ALLOC)
2878 {
2879 this_hdr->sh_flags |= SHF_ALLOC;
2880 /* FIXME. If SEC_LOAD is true should we do something with
2881 with sh_type? */
2882 }
2883
2884 if (!(stub_sec->flags & SEC_READONLY))
2885 this_hdr->sh_flags |= SHF_WRITE;
2886
2887 if (stub_sec->flags & SEC_CODE)
2888 this_hdr->sh_flags |= SHF_EXECINSTR;
2889 }
2890
2891 bfd_set_section_alignment (abfd, stub_sec, 2);
2892 stub_desc = new_stub (abfd, stub_sec, link_info);
2893 }
2894
2895 if (!stub_desc)
2896 stub_desc = new_stub (abfd, stub_sec, link_info);
2897
2898 /* Allocate memory to contain the stub. FIXME. Why isn't this using
2899 the BFD memory allocation routines? */
2900 if (!stub_desc->stub_contents)
2901 {
2902 stub_desc->allocated_size = STUB_BUFFER_INCR;
2903 stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
2904 }
2905 else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2906 {
2907 stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2908 stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2909 stub_desc->allocated_size);
2910 }
2911
2912 stub_desc->stub_secp
2913 = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2914
2915 /* Is this a millicode call? If so, the return address
2916 comes in on r31 rather than r2 (rp) so a slightly
2917 different code sequence is needed. */
2918
2919 insn = data[0];
2920 rtn_reg = (insn & 0x03e00000) >> 21;
2921 if (rtn_reg == 31)
2922 milli = true;
2923
2924 if (strcmp (symbol->name, "$$dyncall") == 0)
2925 dyncall = true;
2926
2927 /* If we are creating a call from a stub to another stub, then
2928 never do the instruction reordering. We can tell if we are
2929 going to be calling one stub from another by the fact that
2930 the symbol name has '_stub_' (arg. reloc. stub) or '_lb_stub_'
2931 prepended to the name. Alternatively, the section of the
2932 symbol will be '.hppa_linker_stubs'. */
2933
2934 if ((strncmp (symbol->name, "_stub_", 6) == 0)
2935 || (strncmp (symbol->name, "_lb_stub_", 9) == 0))
2936 {
2937 BFD_ASSERT (strcmp (symbol->section->name, ".hppa_linker_stubs") == 0);
2938 rtn_adjust = false;
2939 }
2940
2941 /* Check to see if we modify the return pointer
2942 in the delay slot of the branch. */
2943 {
2944 unsigned delay_insn = data[1];
2945
2946 /* If we nullify the delay slot, or if the delay slot contains an
2947 instruction that modifies the return pointer, then no additional
2948 modification of the return pointer is necessary. */
2949 if (insn & 2 || insn == 0)
2950 rtn_adjust = false;
2951 else
2952 {
2953 if (get_opcode (delay_insn) == LDO
2954 && (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
2955 rtn_adjust = false;
2956 if (milli)
2957 rtn_adjust = false;
2958 }
2959 }
2960
2961 sprintf (stub_sym_name,
2962 "_lb_stub_%s_%s", reloc_entry->sym_ptr_ptr[0]->name,
2963 rtn_adjust ? "RA" : "");
2964 stub_entry = find_stub_by_name(abfd, stub_sec, stub_sym_name);
2965
2966 /* If a copy of this stub already exists re-use it. */
2967 if (stub_entry)
2968 {
2969 stub_sym = stub_entry->sym;
2970
2971 /* Change symbol associated with the original relocation to point
2972 to the stub.
2973
2974 FIXME. Is there a need to change the relocation type too? */
2975 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2976 sizeof (asymbol *));
2977 if (!reloc_entry->sym_ptr_ptr)
2978 {
2979 bfd_error = no_memory;
2980 return NULL;
2981 }
2982 reloc_entry->sym_ptr_ptr[0] = stub_sym;
2983 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2984 }
2985 else
2986 {
2987 /* We will need to allocate a new stub. */
2988 stub_sym = bfd_make_empty_symbol (abfd);
2989 if (!stub_sym)
2990 {
2991 bfd_error = no_memory;
2992 return NULL;
2993 }
2994 stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2995 if (!stub_sym->name)
2996 {
2997 bfd_error = no_memory;
2998 return NULL;
2999 }
3000 strcpy ((char *) stub_sym->name, stub_sym_name);
3001 stub_sym->value
3002 = (char *) stub_desc->stub_secp - (char *) stub_desc->stub_contents;
3003 stub_sym->section = stub_sec;
3004 stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
3005 stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
3006
3007 /* Change symbol associated with the original relocation to point
3008 to the stub.
3009
3010 FIXME. Is there a need to change the relocation type too? */
3011 reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
3012 sizeof (asymbol *));
3013 if (!reloc_entry->sym_ptr_ptr)
3014 {
3015 bfd_error = no_memory;
3016 return NULL;
3017 }
3018 reloc_entry->sym_ptr_ptr[0] = stub_sym;
3019 reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
3020
3021 /* Build the stub. */
3022
3023 /* 1. initialization for the call. */
3024 NEW_INSTRUCTION (stub_entry, LDSID_31_1);
3025 NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
3026
3027 if (!dyncall)
3028 {
3029 if (!milli)
3030 {
3031 if (rtn_adjust)
3032 {
3033 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
3034 }
3035 else
3036 {
3037 NEW_INSTRUCTION (stub_entry, COPY_31_2);
3038 }
3039 }
3040 else
3041 {
3042 if (rtn_adjust)
3043 {
3044 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_1);
3045 }
3046 else
3047 {
3048 NEW_INSTRUCTION (stub_entry, COPY_31_1);
3049 }
3050 }
3051
3052 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3053 hppa_elf_stub_reloc (stub_desc,
3054 abfd,
3055 target_sym,
3056 CURRENT_STUB_OFFSET (stub_entry),
3057 R_HPPA_L21);
3058
3059 /* 2. Make the call. */
3060 if (!milli)
3061 {
3062 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3063 hppa_elf_stub_reloc (stub_desc,
3064 abfd,
3065 target_sym,
3066 CURRENT_STUB_OFFSET (stub_entry),
3067 R_HPPA_ABS_CALL_R17);
3068 NEW_INSTRUCTION (stub_entry, COPY_2_31);
3069 }
3070 else
3071 {
3072 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3073 hppa_elf_stub_reloc (stub_desc,
3074 abfd,
3075 target_sym,
3076 CURRENT_STUB_OFFSET (stub_entry),
3077 R_HPPA_ABS_CALL_R17);
3078 NEW_INSTRUCTION (stub_entry, COPY_1_31);
3079 }
3080 }
3081 else
3082 {
3083 /* 3. Branch back to the original location.
3084 (For non-millicode calls, this is accomplished with the
3085 COPY_31_2 instruction. For millicode calls, the return
3086 location is already in r2.) */
3087 if (rtn_adjust)
3088 {
3089 NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
3090 }
3091 NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3092 hppa_elf_stub_reloc (stub_desc,
3093 abfd,
3094 target_sym,
3095 CURRENT_STUB_OFFSET (stub_entry),
3096 R_HPPA_L21);
3097
3098 NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3099 hppa_elf_stub_reloc (stub_desc,
3100 abfd,
3101 target_sym,
3102 CURRENT_STUB_OFFSET (stub_entry),
3103 R_HPPA_ABS_CALL_R17);
3104 NEW_INSTRUCTION (stub_entry, COPY_2_31);
3105 }
3106 }
3107 return stub_sym;
3108 }
3109
3110 int
3111 hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
3112 bfd *abfd;
3113 asection *asec;
3114 arelent *reloc_entry;
3115 asymbol *symbol;
3116 unsigned insn;
3117 {
3118 long sym_value = get_symbol_value(symbol);
3119 int fmt = reloc_entry->howto->bitsize;
3120 unsigned char op = get_opcode(insn);
3121 unsigned raddr;
3122
3123 #define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
3124
3125 switch (op)
3126 {
3127 case BL:
3128 raddr =
3129 reloc_entry->address + asec->output_offset + asec->output_section->vma;
3130 if ( too_far(sym_value - raddr,fmt+1) )
3131 {
3132 #ifdef DETECT_STUBS
3133 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);
3134 #endif
3135 return 1;
3136 }
3137 break;
3138 }
3139 return 0;
3140 }
3141
3142 #define STUB_SYM_BUFFER_INC 5
3143
3144 asymbol *
3145 hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
3146 syms, new_sym_cnt, link_info)
3147 bfd *stub_bfd;
3148 bfd *abfd;
3149 bfd *output_bfd;
3150 asection *asec;
3151 asymbol **syms;
3152 int *new_sym_cnt;
3153 struct bfd_link_info *link_info;
3154 {
3155 int i;
3156 int stub_types[5];
3157 asymbol *new_syms = (asymbol *) NULL;
3158 int new_cnt = 0;
3159 int new_max = 0;
3160
3161 /* Relocations are in different places depending on whether this is
3162 an output section or an input section. Also, the relocations are
3163 in different forms. Sigh. Luckily, we have
3164 bfd_canonicalize_reloc() to straighten this out for us . */
3165
3166 if (asec->reloc_count > 0)
3167 {
3168 arelent **reloc_vector
3169 = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
3170
3171 bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
3172 for (i = 0; i < asec->reloc_count; i++)
3173 {
3174 arelent *rle = reloc_vector[i];
3175
3176 switch (rle->howto->type)
3177 {
3178 case R_HPPA_ABS_CALL_11:
3179 case R_HPPA_ABS_CALL_14:
3180 case R_HPPA_ABS_CALL_17:
3181 case R_HPPA_ABS_CALL_L21:
3182 case R_HPPA_ABS_CALL_R11:
3183 case R_HPPA_ABS_CALL_R14:
3184 case R_HPPA_ABS_CALL_R17:
3185 case R_HPPA_ABS_CALL_LS21:
3186 case R_HPPA_ABS_CALL_RS11:
3187 case R_HPPA_ABS_CALL_RS14:
3188 case R_HPPA_ABS_CALL_RS17:
3189 case R_HPPA_ABS_CALL_LD21:
3190 case R_HPPA_ABS_CALL_RD11:
3191 case R_HPPA_ABS_CALL_RD14:
3192 case R_HPPA_ABS_CALL_RD17:
3193 case R_HPPA_ABS_CALL_LR21:
3194 case R_HPPA_ABS_CALL_RR14:
3195 case R_HPPA_ABS_CALL_RR17:
3196 case R_HPPA_PCREL_CALL_11:
3197 case R_HPPA_PCREL_CALL_14:
3198 case R_HPPA_PCREL_CALL_17:
3199 case R_HPPA_PCREL_CALL_12:
3200 case R_HPPA_PCREL_CALL_L21:
3201 case R_HPPA_PCREL_CALL_R11:
3202 case R_HPPA_PCREL_CALL_R14:
3203 case R_HPPA_PCREL_CALL_R17:
3204 case R_HPPA_PCREL_CALL_LS21:
3205 case R_HPPA_PCREL_CALL_RS11:
3206 case R_HPPA_PCREL_CALL_RS14:
3207 case R_HPPA_PCREL_CALL_RS17:
3208 case R_HPPA_PCREL_CALL_LD21:
3209 case R_HPPA_PCREL_CALL_RD11:
3210 case R_HPPA_PCREL_CALL_RD14:
3211 case R_HPPA_PCREL_CALL_RD17:
3212 case R_HPPA_PCREL_CALL_LR21:
3213 case R_HPPA_PCREL_CALL_RR14:
3214 case R_HPPA_PCREL_CALL_RR17:
3215 {
3216 symext_entryS caller_ar
3217 = (symext_entryS) HPPA_R_ARG_RELOC (rle->addend);
3218 unsigned insn[2];
3219
3220 bfd_get_section_contents (abfd, asec, insn, rle->address,
3221 sizeof(insn));
3222 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3223 caller_ar))
3224 {
3225 /* Generate a stub and keep track of the new symbol. */
3226 asymbol *r;
3227
3228 if (new_cnt == new_max)
3229 {
3230 new_max += STUB_SYM_BUFFER_INC;
3231 new_syms = (asymbol *)
3232 realloc (new_syms, new_max * sizeof (asymbol));
3233 }
3234
3235 /* The rtn_adjust argument is true here because we
3236 know that we have a branch and (with a few exceptions
3237 detailed under the relocation code for relocation type
3238 R_HPPA_STUB_CALL_17) it will be possible to perform
3239 the code reorientation. */
3240 r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
3241 link_info, rle,
3242 stub_types,
3243 true, insn);
3244 new_syms[new_cnt++] = *r;
3245 }
3246
3247 /* We need to retrieve the section contents to check for
3248 long branch stubs. */
3249 if (hppa_elf_long_branch_needed_p (abfd, asec, rle,
3250 rle->sym_ptr_ptr[0],
3251 insn[0]))
3252 {
3253 /* Generate a stub and keep track of the new symbol. */
3254 asymbol *r;
3255
3256 if (new_cnt == new_max)
3257 {
3258 new_max += STUB_SYM_BUFFER_INC;
3259 new_syms = (asymbol *)
3260 realloc (new_syms, (new_max * sizeof (asymbol)));
3261 }
3262 r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
3263 link_info, rle,
3264 rle->sym_ptr_ptr[0],
3265 insn);
3266 new_syms[new_cnt++] = *r;
3267 }
3268 }
3269 break;
3270
3271 case R_HPPA_PLABEL_32:
3272 case R_HPPA_PLABEL_11:
3273 case R_HPPA_PLABEL_14:
3274 case R_HPPA_PLABEL_L21:
3275 case R_HPPA_PLABEL_R11:
3276 case R_HPPA_PLABEL_R14:
3277 {
3278 /* On a plabel relocation, assume the arguments of the
3279 caller are set up in general registers.
3280 NOTE: 0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
3281 symext_entryS caller_ar = (symext_entryS) 0x155;
3282 unsigned insn[2];
3283
3284 bfd_get_section_contents (abfd, asec, insn, rle->address,
3285 sizeof(insn));
3286
3287 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3288 caller_ar))
3289 {
3290 /* Generate a plabel stub and keep track of the
3291 new symbol. */
3292 asymbol *r;
3293 int rtn_adjust;
3294
3295 if (new_cnt == new_max)
3296 {
3297 new_max += STUB_SYM_BUFFER_INC;
3298 new_syms = (asymbol *) realloc (new_syms, new_max
3299 * sizeof (asymbol));
3300 }
3301
3302 /* Determine whether a return adjustment
3303 (see the relocation code for relocation type
3304 R_HPPA_STUB_CALL_17) is possible. Basically,
3305 determine whether we are looking at a branch or not. */
3306
3307 if (rle->howto->type == R_HPPA_PLABEL_32)
3308 rtn_adjust = false;
3309 else
3310 {
3311 switch (get_opcode(insn[0]))
3312 {
3313 case BLE:
3314 case BE:
3315 rtn_adjust = true;
3316 break;
3317 default:
3318 rtn_adjust = false;
3319 }
3320 }
3321 r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
3322 link_info, rle,
3323 stub_types,
3324 rtn_adjust, insn);
3325 new_syms[new_cnt++] = *r;
3326 }
3327 }
3328 break;
3329
3330 default:
3331 break;
3332
3333 }
3334 }
3335 }
3336 *new_sym_cnt = new_cnt;
3337 return new_syms;
3338 }
3339
3340
3341 char *linker_stubs = NULL;
3342 int linker_stubs_size = 0;
3343 int linker_stubs_max_size = 0;
3344 #define STUB_ALLOC_INCR 100
3345
3346 boolean
3347 hppa_elf_set_section_contents (abfd, section, location, offset, count)
3348 bfd *abfd;
3349 sec_ptr section;
3350 PTR location;
3351 file_ptr offset;
3352 bfd_size_type count;
3353 {
3354 if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
3355 {
3356 if ( linker_stubs_max_size < offset + count )
3357 {
3358 linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
3359 linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
3360 }
3361
3362 if ( offset + count > linker_stubs_size )
3363 linker_stubs_size = offset + count;
3364
3365 memcpy(linker_stubs + offset,location,count);
3366 return (true);
3367 }
3368 else
3369 return bfd_elf32_set_section_contents (abfd, section, location,
3370 offset, count);
3371 }
3372
3373 /* Get the contents of the given section.
3374
3375 This is special for PA ELF because some sections (such as linker stubs)
3376 may reside in memory rather than on disk, or in the case of the symbol
3377 extension section, the contents may need to be generated from other
3378 information contained in the BFD. */
3379
3380 boolean
3381 hppa_elf_get_section_contents (abfd, section, location, offset, count)
3382 bfd *abfd;
3383 sec_ptr section;
3384 PTR location;
3385 file_ptr offset;
3386 bfd_size_type count;
3387 {
3388 /* If this is the linker stub section, then its contents are contained
3389 in memory rather than on disk. FIXME. Is that always right? What
3390 about the case where a final executable is read in and a user tries
3391 to get the contents of this section? In that case the contents would
3392 be on disk like everything else. */
3393 if (strcmp (section->name, ".hppa_linker_stubs") == 0)
3394 {
3395 elf32_hppa_stub_description *stub_desc = find_stubs (abfd, section);
3396
3397 if (count == 0)
3398 return true;
3399
3400 /* Sanity check our arguments. */
3401 if ((bfd_size_type) (offset + count) > section->_raw_size
3402 || (bfd_size_type) (offset + count) > stub_desc->real_size)
3403 return (false);
3404
3405 memcpy (location, stub_desc->stub_contents + offset, count);
3406 return (true);
3407 }
3408
3409 /* The symbol extension section also needs special handling. Its
3410 contents might be on the disk, in memory, or still need to
3411 be generated. */
3412 else if (strcmp (section->name, ".hppa_symextn") == 0)
3413 {
3414 /* If there are no output sections, then read the contents of the
3415 symbol extension section from disk. */
3416 if (section->output_section == NULL
3417 && abfd->direction == read_direction)
3418 {
3419 return bfd_generic_get_section_contents (abfd, section, location,
3420 offset, count);
3421 }
3422
3423 /* If this is the first time through, and there are output sections,
3424 then build the symbol extension section based on other information
3425 contained in the BFD. */
3426 else if (! symext_chain_built)
3427 {
3428 int i;
3429 int *symtab_map =
3430 (int *) elf_sym_extra(section->output_section->owner);
3431
3432 for (i = 0; i < section->output_section->owner->symcount; i++ )
3433 {
3434 elf_hppa_tc_symbol(section->output_section->owner,
3435 ((elf_symbol_type *)
3436 section->output_section->owner->outsymbols[i]),
3437 symtab_map[i]);
3438 }
3439 symext_chain_built++;
3440 elf_hppa_tc_make_sections (section->output_section->owner, NULL);
3441 }
3442
3443 /* At this point we know that the symbol extension section has been
3444 built. We just need to copy it into the user's buffer. */
3445 if (count == 0)
3446 return true;
3447
3448 /* Sanity check our arguments. */
3449 if ((bfd_size_type) (offset + count) > section->_raw_size
3450 || (bfd_size_type) (offset + count) > symextn_contents_real_size)
3451 return (false);
3452
3453 memcpy (location,
3454 ((char *)symextn_contents + section->output_offset + offset),
3455 count);
3456 return (true);
3457 }
3458 else
3459 return bfd_generic_get_section_contents (abfd, section, location,
3460 offset, count);
3461 }
3462
3463 static void
3464 elf_info_to_howto (abfd, cache_ptr, dst)
3465 bfd *abfd;
3466 arelent *cache_ptr;
3467 Elf32_Internal_Rela *dst;
3468 {
3469 BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
3470 cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
3471 }
3472
3473 static void
3474 elf32_hppa_backend_symbol_processing (abfd, sym)
3475 bfd *abfd;
3476 asymbol *sym;
3477 {
3478 /* Is this a definition of $global$? If so, keep it because it will be
3479 needed if any relocations are performed. */
3480
3481 if (!strcmp (sym->name, "$global$")
3482 && sym->section != &bfd_und_section)
3483 {
3484 global_symbol = sym;
3485 }
3486 }
3487
3488 #define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
3489
3490 struct elf32_hppa_symextn_map_struct
3491 {
3492 int old_index;
3493 bfd *bfd;
3494 asymbol *sym;
3495 int new_index;
3496 };
3497
3498 static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
3499 static int elf32_hppa_symextn_map_size;
3500
3501 static boolean
3502 elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt)
3503 bfd *abfd;
3504 elf_symbol_type *esyms;
3505 int symcnt;
3506 {
3507 Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
3508 int i;
3509 int current_sym_idx = 0;
3510
3511 /* If the symbol extension section does not exist, all the symbol */
3512 /* all the symbol extension information is assumed to be zero. */
3513
3514 if ( symextn_hdr == NULL )
3515 {
3516 for ( i = 0; i < symcnt; i++ )
3517 {
3518 esyms[i].tc_data.hppa_arg_reloc = 0;
3519 }
3520 return (true);
3521 }
3522
3523 /* allocate a buffer of the appropriate size for the symextn section */
3524
3525 symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
3526 if (!symextn_hdr->contents)
3527 {
3528 bfd_error = no_memory;
3529 return false;
3530 }
3531 symextn_hdr->size = symextn_hdr->sh_size;
3532
3533 /* read in the symextn section */
3534
3535 if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
3536 {
3537 bfd_error = system_call_error;
3538 return (false);
3539 }
3540 if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd)
3541 != symextn_hdr->size)
3542 {
3543 free ((PTR)symextn_hdr->contents);
3544 bfd_error = system_call_error;
3545 return (false);
3546 }
3547
3548 /* parse the entries, updating the symtab entries as we go */
3549
3550 for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
3551 {
3552 symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
3553 int se_value = ELF32_HPPA_SX_VAL(*seP);
3554 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3555
3556 switch ( se_type )
3557 {
3558 case HPPA_SXT_NULL:
3559 break;
3560
3561 case HPPA_SXT_SYMNDX:
3562 if ( se_value >= symcnt )
3563 {
3564 bfd_error = bad_value;
3565 bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3566 return (false);
3567 }
3568 current_sym_idx = se_value - 1;
3569 break;
3570
3571 case HPPA_SXT_ARG_RELOC:
3572 esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
3573 break;
3574
3575 default:
3576 bfd_error = bad_value;
3577 bfd_perror("elf32_hppa_backend_symbol_table_processing");
3578 return (false);
3579 }
3580 }
3581 return (true);
3582 }
3583
3584 #define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
3585
3586 static boolean
3587 elf32_hppa_backend_section_processing (abfd, secthdr)
3588 bfd *abfd;
3589 Elf32_Internal_Shdr *secthdr;
3590 {
3591 int i,j,k;
3592
3593 if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
3594 {
3595 for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
3596 {
3597 symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
3598 int se_value = ELF32_HPPA_SX_VAL(*seP);
3599 int se_type = ELF32_HPPA_SX_TYPE(*seP);
3600
3601 switch ( se_type )
3602 {
3603 case HPPA_SXT_NULL:
3604 break;
3605
3606 case HPPA_SXT_SYMNDX:
3607 for ( j = 0; j < abfd->symcount; j++ )
3608 {
3609 /* locate the map entry for this symbol, if there is one. */
3610 /* modify the symbol extension section symbol index entry */
3611 /* to reflect the new symbol table index */
3612
3613 for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
3614 {
3615 if ( elf32_hppa_symextn_map[k].old_index == se_value
3616 && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
3617 && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
3618 {
3619 bfd_put_32(abfd,
3620 ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
3621 (char *)seP);
3622 }
3623 }
3624 }
3625 break;
3626
3627 case HPPA_SXT_ARG_RELOC:
3628 break;
3629
3630 default:
3631 bfd_error = bad_value;
3632 bfd_perror("elf32_hppa_backend_section_processing");
3633 return (false);
3634 }
3635 }
3636 }
3637 return true;
3638 }
3639
3640 #define elf_backend_section_processing elf32_hppa_backend_section_processing
3641
3642 static boolean
3643 elf32_hppa_backend_section_from_shdr (abfd, hdr, name)
3644 bfd *abfd;
3645 Elf32_Internal_Shdr *hdr;
3646 char *name;
3647 {
3648 asection *newsect;
3649
3650 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3651 {
3652 BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
3653
3654 /* Bits that get saved. This one is real. */
3655 if (!hdr->rawdata)
3656 {
3657 newsect = bfd_make_section (abfd, name);
3658 if (newsect != NULL)
3659 {
3660 newsect->vma = hdr->sh_addr;
3661 newsect->_raw_size = hdr->sh_size;
3662 newsect->filepos = hdr->sh_offset; /* so we can read back the bits */
3663 newsect->flags |= SEC_HAS_CONTENTS;
3664 newsect->alignment_power = hdr->sh_addralign;
3665
3666 if (hdr->sh_flags & SHF_ALLOC)
3667 {
3668 newsect->flags |= SEC_ALLOC;
3669 newsect->flags |= SEC_LOAD;
3670 }
3671
3672 if (!(hdr->sh_flags & SHF_WRITE))
3673 newsect->flags |= SEC_READONLY;
3674
3675 if (hdr->sh_flags & SHF_EXECINSTR)
3676 newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
3677 else
3678 newsect->flags |= SEC_DATA;
3679
3680 hdr->rawdata = (void *) newsect;
3681 }
3682 }
3683 return true;
3684 }
3685 return false;
3686 }
3687
3688 #define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
3689
3690 static boolean
3691 elf32_hppa_backend_fake_sections (abfd, secthdr, asect)
3692 bfd *abfd;
3693 Elf_Internal_Shdr *secthdr;
3694 asection *asect;
3695 {
3696
3697 if ( strcmp(asect->name, ".hppa_symextn") == 0 )
3698 {
3699 secthdr->sh_type = SHT_HPPA_SYMEXTN;
3700 secthdr->sh_flags = 0;
3701 secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
3702 secthdr->sh_link = elf_onesymtab(abfd);
3703 return true;
3704 }
3705
3706 if (!strcmp (asect->name, ".hppa_unwind"))
3707 {
3708 secthdr->sh_type = SHT_PROGBITS;
3709 /* Unwind descriptors are not part of the program memory image. */
3710 secthdr->sh_flags = 0;
3711 secthdr->sh_info = 0;
3712 secthdr->sh_link = 0;
3713 secthdr->sh_entsize = 16;
3714 return true;
3715 }
3716
3717 /* @@ Should this be CPU specific?? KR */
3718 if (!strcmp (asect->name, ".stabstr"))
3719 {
3720 secthdr->sh_type = SHT_STRTAB;
3721 secthdr->sh_flags = 0;
3722 secthdr->sh_info = 0;
3723 secthdr->sh_link = 0;
3724 secthdr->sh_entsize = 0;
3725 return true;
3726 }
3727
3728 return false;
3729 }
3730
3731 #define elf_backend_fake_sections elf32_hppa_backend_fake_sections
3732
3733 static boolean
3734 elf32_hppa_backend_section_from_bfd_section (abfd, hdr, asect, retval)
3735 bfd *abfd;
3736 Elf32_Internal_Shdr *hdr;
3737 asection *asect;
3738 int *retval;
3739 {
3740 if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3741 {
3742 if (hdr->rawdata)
3743 {
3744 if (((struct sec *) (hdr->rawdata)) == asect)
3745 {
3746 BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
3747 return true;
3748 }
3749 }
3750 }
3751 else if ( hdr->sh_type == SHT_STRTAB )
3752 {
3753 if (hdr->rawdata)
3754 {
3755 if (((struct sec *) (hdr->rawdata)) == asect)
3756 {
3757 BFD_ASSERT ( strcmp (asect->name, ".stabstr") == 0);
3758 return true;
3759 }
3760 }
3761 }
3762
3763 return false;
3764 }
3765
3766 #define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
3767
3768 #define bfd_generic_get_section_contents hppa_elf_get_section_contents
3769 #define bfd_elf32_set_section_contents hppa_elf_set_section_contents
3770
3771 #define TARGET_BIG_SYM bfd_elf32_hppa_vec
3772 #define TARGET_BIG_NAME "elf32-hppa"
3773 #define ELF_ARCH bfd_arch_hppa
3774 #define ELF_MACHINE_CODE EM_HPPA
3775 #define ELF_MAXPAGESIZE 0x1000
3776
3777 #include "elf32-target.h"