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