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