1 /* BFD back-end for HP PA-RISC ELF files.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
6 Center for Software Science
7 Department of Computer Science
10 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
32 /* ELF32/HPPA relocation support
34 This file contains ELF32/HPPA relocation support as specified
35 in the Stratus FTX/Golf Object File Format (SED-1762) dated
42 Center for Software Science
43 Department of Computer Science
47 #include "elf32-hppa.h"
49 #include "aout/aout64.h"
50 #include "hppa_stubs.h"
52 /* ELF/PA relocation howto entries */
54 static bfd_reloc_status_type
hppa_elf_reloc ();
56 static reloc_howto_type elf_hppa_howto_table
[ELF_HOWTO_TABLE_SIZE
] =
58 /* 'bitpos' and 'abs' are obsolete */
59 /* type rs sz bsz pcrel bpos abs ovrf sf name */
60 /* 9.3.4. Address relocation types */
61 {R_HPPA_NONE
, 0, 3, 19, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_NONE"},
62 {R_HPPA_32
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_32"},
63 {R_HPPA_11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_11"},
64 {R_HPPA_14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_14"},
65 {R_HPPA_17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_17"},
66 {R_HPPA_L21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_L21"},
67 {R_HPPA_R11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_R11"},
68 {R_HPPA_R14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_R14"},
69 {R_HPPA_R17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_R17"},
70 {R_HPPA_LS21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_LS21"},
71 {R_HPPA_RS11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RS11"},
72 {R_HPPA_RS14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RS14"},
73 {R_HPPA_RS17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RS17"},
74 {R_HPPA_LD21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_LD21"},
75 {R_HPPA_RD11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RD11"},
76 {R_HPPA_RD14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RD14"},
77 {R_HPPA_RD17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RD17"},
78 {R_HPPA_LR21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_LR21"},
79 {R_HPPA_RR14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RR14"},
80 {R_HPPA_RR17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_RR17"},
81 /* 9.3.5. GOTOFF address relocation types */
82 {R_HPPA_GOTOFF_11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_11"},
83 {R_HPPA_GOTOFF_14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_14"},
84 {R_HPPA_GOTOFF_L21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_L21"},
85 {R_HPPA_GOTOFF_R11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_R11"},
86 {R_HPPA_GOTOFF_R14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_R14"},
87 {R_HPPA_GOTOFF_LS21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_LS21"},
88 {R_HPPA_GOTOFF_RS11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_RS11"},
89 {R_HPPA_GOTOFF_RS14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_RS14"},
90 {R_HPPA_GOTOFF_LD21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_LD21"},
91 {R_HPPA_GOTOFF_RD11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_RD11"},
92 {R_HPPA_GOTOFF_RD14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_RD14"},
93 {R_HPPA_GOTOFF_LR21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_LR21"},
94 {R_HPPA_GOTOFF_RR14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_GOTOFF_RR14"},
95 /* 9.3.6. Absolute call relocation types */
96 {R_HPPA_ABS_CALL_11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_11"},
97 {R_HPPA_ABS_CALL_14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_14"},
98 {R_HPPA_ABS_CALL_17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_17"},
99 {R_HPPA_ABS_CALL_L21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_L21"},
100 {R_HPPA_ABS_CALL_R11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_R11"},
101 {R_HPPA_ABS_CALL_R14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_R14"},
102 {R_HPPA_ABS_CALL_R17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_R17"},
103 {R_HPPA_ABS_CALL_LS21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_LS21"},
104 {R_HPPA_ABS_CALL_RS11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RS11"},
105 {R_HPPA_ABS_CALL_RS14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RS14"},
106 {R_HPPA_ABS_CALL_RS17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RS17"},
107 {R_HPPA_ABS_CALL_LD21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_LD21"},
108 {R_HPPA_ABS_CALL_RD11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RD11"},
109 {R_HPPA_ABS_CALL_RD14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RD14"},
110 {R_HPPA_ABS_CALL_RD17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RD17"},
111 {R_HPPA_ABS_CALL_LR21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_LR21"},
112 {R_HPPA_ABS_CALL_RR14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RR14"},
113 {R_HPPA_ABS_CALL_RR17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ABS_CALL_RR17"},
114 /* 9.3.7. PC-relative call relocation types */
115 {R_HPPA_PCREL_CALL_11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_11"},
116 {R_HPPA_PCREL_CALL_14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_14"},
117 {R_HPPA_PCREL_CALL_17
, 0, 3, 17, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_17"},
118 {R_HPPA_PCREL_CALL_12
, 0, 3, 12, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_12"},
119 {R_HPPA_PCREL_CALL_L21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_L21"},
120 {R_HPPA_PCREL_CALL_R11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_R11"},
121 {R_HPPA_PCREL_CALL_R14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_R14"},
122 {R_HPPA_PCREL_CALL_R17
, 0, 3, 17, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_R17"},
123 {R_HPPA_PCREL_CALL_LS21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_LS21"},
124 {R_HPPA_PCREL_CALL_RS11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RS11"},
125 {R_HPPA_PCREL_CALL_RS14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RS14"},
126 {R_HPPA_PCREL_CALL_RS17
, 0, 3, 17, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RS17"},
127 {R_HPPA_PCREL_CALL_LD21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_LD21"},
128 {R_HPPA_PCREL_CALL_RD11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RD11"},
129 {R_HPPA_PCREL_CALL_RD14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RD14"},
130 {R_HPPA_PCREL_CALL_RD17
, 0, 3, 17, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RD17"},
131 {R_HPPA_PCREL_CALL_LR21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_LR21"},
132 {R_HPPA_PCREL_CALL_RR14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RR14"},
133 {R_HPPA_PCREL_CALL_RR17
, 0, 3, 17, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PCREL_CALL_RR17"},
135 /* 9.3.8. Plabel relocation types */
136 {R_HPPA_PLABEL_32
, 0, 3, 32, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_32"},
137 {R_HPPA_PLABEL_11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_11"},
138 {R_HPPA_PLABEL_14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_14"},
139 {R_HPPA_PLABEL_L21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_L21"},
140 {R_HPPA_PLABEL_R11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_R11"},
141 {R_HPPA_PLABEL_R14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_PLABEL_R14"},
143 /* 9.3.9. Data linkage table (DLT) relocation types */
144 {R_HPPA_DLT_32
, 0, 3, 32, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_32"},
145 {R_HPPA_DLT_11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_11"},
146 {R_HPPA_DLT_14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_14"},
147 {R_HPPA_DLT_L21
, 0, 3, 21, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_L21"},
148 {R_HPPA_DLT_R11
, 0, 3, 11, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_R11"},
149 {R_HPPA_DLT_R14
, 0, 3, 14, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_DLT_R14"},
151 /* 9.3.10. Relocations for unwinder tables */
152 {R_HPPA_UNWIND_ENTRY
, 0, 3, 32, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_UNWIND_ENTRY"},
153 {R_HPPA_UNWIND_ENTRIES
, 0, 3, 32, true, 0, complain_overflow_signed
, hppa_elf_reloc
, "R_HPPA_UNWIND_ENTRIES"},
155 /* 9.3.11. Relocation types for complex expressions */
156 {R_HPPA_PUSH_CONST
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_CONST"},
157 {R_HPPA_PUSH_PC
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_PC"},
158 {R_HPPA_PUSH_SYM
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_SYM"},
159 {R_HPPA_PUSH_GOTOFF
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_GOTOFF"},
160 {R_HPPA_PUSH_ABS_CALL
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_ABS_CALL"},
161 {R_HPPA_PUSH_PCREL_CALL
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_PCREL_CALL"},
162 {R_HPPA_PUSH_PLABEL
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_PUSH_PLABEL"},
163 {R_HPPA_MAX
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_MAX"},
164 {R_HPPA_MIN
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_MIN"},
165 {R_HPPA_ADD
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ADD"},
166 {R_HPPA_SUB
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_SUB"},
167 {R_HPPA_MULT
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_MULT"},
168 {R_HPPA_DIV
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_DIV"},
169 {R_HPPA_MOD
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_MOD"},
170 {R_HPPA_AND
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_AND"},
171 {R_HPPA_OR
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_OR"},
172 {R_HPPA_XOR
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_XOR"},
173 {R_HPPA_NOT
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_NOT"},
174 {R_HPPA_LSHIFT
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_LSHIFT"},
175 {R_HPPA_ARITH_RSHIFT
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_ARITH_RSHIFT"},
176 {R_HPPA_LOGIC_RSHIFT
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_LOGIC_RSHIFT"},
177 {R_HPPA_EXPR_F
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_L"},
178 {R_HPPA_EXPR_L
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_L"},
179 {R_HPPA_EXPR_R
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_R"},
180 {R_HPPA_EXPR_LS
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_LS"},
181 {R_HPPA_EXPR_RS
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_RS"},
182 {R_HPPA_EXPR_LD
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_LD"},
183 {R_HPPA_EXPR_RD
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_RD"},
184 {R_HPPA_EXPR_LR
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_LR"},
185 {R_HPPA_EXPR_RR
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_RR"},
187 {R_HPPA_EXPR_32
, 0, 3, 32, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_32"},
188 {R_HPPA_EXPR_21
, 0, 3, 21, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_21"},
189 {R_HPPA_EXPR_11
, 0, 3, 11, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_11"},
190 {R_HPPA_EXPR_14
, 0, 3, 14, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_14"},
191 {R_HPPA_EXPR_17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_17"},
192 {R_HPPA_EXPR_12
, 0, 3, 12, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_EXPR_12"},
193 {R_HPPA_STUB_CALL_17
, 0, 3, 17, false, 0, complain_overflow_bitfield
, hppa_elf_reloc
, "R_HPPA_STUB_CALL_17"},
194 {R_HPPA_UNIMPLEMENTED
, 0, 0, 0, false, 0, complain_overflow_dont
, NULL
, "R_HPPA_UNIMPLEMENTED"},
197 static symext_chainS
*symext_rootP
;
198 static symext_chainS
*symext_lastP
;
201 DEFUN (hppa_elf_rebuild_insn
, (abfd
, insn
, value
, r_type
, r_field
, r_format
),
203 unsigned long insn AND
204 unsigned long value AND
205 unsigned short r_type AND
206 unsigned short r_field AND
207 unsigned short r_format
)
209 unsigned long const_part
; /* part of the instruction that does not change */
210 unsigned long rebuilt_part
;
218 const_part
= insn
& 0xffffe002;
219 dis_assemble_12 (value
, &w1
, &w
);
220 rebuilt_part
= (w1
<< 2) | w
;
221 return const_part
| rebuilt_part
;
228 const_part
= insn
& 0xffffe002;
229 dis_assemble_12 (value
, &w1
, &w
);
230 rebuilt_part
= (w1
<< 2) | w
;
231 return const_part
| rebuilt_part
;
235 const_part
= insn
& 0xffffc000;
236 low_sign_unext (value
, 14, &rebuilt_part
);
237 return const_part
| rebuilt_part
;
243 const_part
= insn
& 0xffe0e002;
244 dis_assemble_17 (value
, &w1
, &w2
, &w
);
245 rebuilt_part
= (w2
<< 2) | (w1
<< 16) | w
;
246 return const_part
| rebuilt_part
;
250 const_part
= insn
& 0xffe00000;
251 dis_assemble_21 (value
, &rebuilt_part
);
252 return const_part
| rebuilt_part
;
259 fprintf (stderr
, "Relocation problem : ");
261 "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
262 r_type
, r_format
, r_field
, abfd
->filename
);
268 DEFUN (hppa_elf_relocate_insn
,
270 insn
, address
, symp
, sym_value
, r_addend
,
271 r_type
, r_format
, r_field
, pcrel
),
273 asection
* input_sect AND
274 unsigned long insn AND
275 unsigned long address AND
279 unsigned short r_type AND
280 unsigned short r_format AND
281 unsigned short r_field AND
284 unsigned char opcode
= get_opcode (insn
);
299 constant_value
= ELF32_HPPA_R_CONSTANT (r_addend
);
300 BFD_ASSERT (r_format
== 14);
303 sym_value
-= address
;
304 sym_value
= hppa_field_adjust (sym_value
, constant_value
, r_field
);
305 return hppa_elf_rebuild_insn (abfd
, insn
, sym_value
, r_type
, r_field
, r_format
);
308 case SUBI
: /* case SUBIO: */
309 case ADDIT
: /* case ADDITO: */
310 case ADDI
: /* case ADDIO: */
311 BFD_ASSERT (r_format
== 11);
313 constant_value
= ((insn
& 0x1) << 10) | ((insn
& 0xffe) >> 1);
314 sym_value
= hppa_field_adjust (sym_value
, constant_value
, r_field
);
315 return hppa_elf_rebuild_insn (abfd
, insn
, sym_value
, r_type
, r_field
, r_format
);
319 BFD_ASSERT (r_format
== 21);
321 constant_value
= assemble_21 (insn
);
322 constant_value
+= ELF32_HPPA_R_CONSTANT (r_addend
);
323 sym_value
= hppa_field_adjust (sym_value
, constant_value
, r_field
);
324 return hppa_elf_rebuild_insn (abfd
, insn
, sym_value
, r_type
, r_field
, r_format
);
329 arg_reloc
= ELF32_HPPA_R_ARG_RELOC (r_addend
);
331 BFD_ASSERT (r_format
== 17);
333 /* XXX computing constant_value is not needed??? */
334 constant_value
= assemble_17 ((insn
& 0x001f0000) >> 16,
335 (insn
& 0x00001ffc) >> 2,
337 /* @@ Assumes only 32 bits. */
338 constant_value
= (constant_value
<< 15) >> 15;
342 address
+ input_sect
->output_offset
343 + input_sect
->output_section
->vma
;
344 sym_value
= hppa_field_adjust (sym_value
, -8, r_field
);
347 sym_value
= hppa_field_adjust (sym_value
, constant_value
, r_field
);
349 return hppa_elf_rebuild_insn (abfd
, insn
, sym_value
>> 2, r_type
, r_field
, r_format
);
354 BFD_ASSERT (r_format
== 32);
355 constant_value
= insn
;
356 constant_value
+= ELF32_HPPA_R_CONSTANT (r_addend
);
358 return hppa_field_adjust (sym_value
, constant_value
, r_field
);
363 "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
364 opcode
, r_format
, r_field
);
371 DEFUN (hppa_elf_relocate_unwind_table
,
373 data
, address
, symp
, sym_value
, r_addend
,
374 r_type
, r_format
, r_field
, pcrel
),
376 asection
* input_sect AND
378 unsigned long address AND
382 unsigned short r_type AND
383 unsigned short r_format AND
384 unsigned short r_field AND
387 bfd_byte
*hit_data
= address
+ (bfd_byte
*) (data
);
390 long relocated_value
;
393 BFD_ASSERT (r_format
== 32);
394 BFD_ASSERT (r_field
== e_fsel
);
397 case R_HPPA_UNWIND_ENTRY
:
398 start_offset
= bfd_get_32 (abfd
, hit_data
);
399 relocated_value
= hppa_field_adjust (sym_value
, start_offset
, r_field
);
400 bfd_put_32 (abfd
, relocated_value
, hit_data
);
402 hit_data
+= sizeof (unsigned long);
403 end_offset
= bfd_get_32 (abfd
, hit_data
);
404 relocated_value
= hppa_field_adjust (sym_value
, end_offset
, r_field
);
405 bfd_put_32 (abfd
, relocated_value
, hit_data
);
408 case R_HPPA_UNWIND_ENTRIES
:
409 for (i
= 0; i
< r_addend
; i
++, hit_data
+= 3 * sizeof (unsigned long))
411 unsigned int adjustment
;
412 start_offset
= bfd_get_32 (abfd
, hit_data
);
413 /* Stuff the symbol value into the first word */
414 /* of the unwind descriptor */
415 bfd_put_32 (abfd
, sym_value
, hit_data
);
416 adjustment
= sym_value
- start_offset
;
418 hit_data
+= sizeof (unsigned long);
419 end_offset
= adjustment
+ bfd_get_32 (abfd
, hit_data
);
420 bfd_put_32 (abfd
, end_offset
, hit_data
);
422 /* If this is not the last unwind entry, */
423 /* adjust the symbol value. */
424 if (i
+ 1 < r_addend
)
426 start_offset
= bfd_get_32 (abfd
, hit_data
+ 3 * sizeof (unsigned long));
427 sym_value
= start_offset
+ adjustment
;
434 "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
435 r_type
, r_format
, r_field
);
439 /* Provided the symbol, returns the value reffed */
441 get_symbol_value (symbol
)
446 if (symbol
== (asymbol
*) NULL
)
448 else if (symbol
->section
== &bfd_com_section
)
454 relocation
= symbol
->value
+
455 symbol
->section
->output_section
->vma
+
456 symbol
->section
->output_offset
;
462 /* This function provides a pretty straight-forward mapping between a */
463 /* base relocation type, format and field into the relocation type */
464 /* that will be emitted in an object file. The only wrinkle in the */
465 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
466 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
467 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
468 /* (in the case of P, PR, and PL). */
470 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
474 hppa_elf_gen_reloc_error (base_type
, fmt
, field
)
475 elf32_hppa_reloc_type base_type
;
479 fprintf (stderr
, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
480 base_type
, fmt
, field
);
483 elf32_hppa_reloc_type
**
484 hppa_elf_gen_reloc_type (abfd
, base_type
, format
, field
)
486 elf32_hppa_reloc_type base_type
;
490 #define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field)
492 elf32_hppa_reloc_type
*finaltype
;
493 elf32_hppa_reloc_type
**final_types
;
496 final_types
= (elf32_hppa_reloc_type
**) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
*) * 2);
497 BFD_ASSERT (final_types
!= 0);
499 finaltype
= (elf32_hppa_reloc_type
*) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
));
500 BFD_ASSERT (finaltype
!= 0);
502 final_types
[0] = finaltype
;
503 final_types
[1] = NULL
;
505 #define final_type finaltype[0]
507 final_type
= base_type
;
518 final_type
= R_HPPA_11
;
521 final_type
= R_HPPA_R11
;
524 final_type
= R_HPPA_RS11
;
527 final_type
= R_HPPA_RD11
;
531 final_type
= R_HPPA_PLABEL_11
;
534 final_type
= R_HPPA_PLABEL_R11
;
547 final_type
= base_type
;
558 final_type
= R_HPPA_R14
;
561 final_type
= R_HPPA_RS14
;
564 final_type
= R_HPPA_RD14
;
567 final_type
= R_HPPA_RR14
;
571 final_type
= R_HPPA_PLABEL_14
;
574 final_type
= R_HPPA_PLABEL_R14
;
588 final_type
= base_type
;
596 final_type
= R_HPPA_17
;
599 final_type
= R_HPPA_R17
;
602 final_type
= R_HPPA_RS17
;
605 final_type
= R_HPPA_RD17
;
608 final_type
= R_HPPA_RR17
;
616 final_type
= base_type
;
624 final_type
= R_HPPA_L21
;
627 final_type
= R_HPPA_LS21
;
630 final_type
= R_HPPA_LD21
;
633 final_type
= R_HPPA_LR21
;
636 final_type
= R_HPPA_PLABEL_L21
;
645 final_type
= base_type
;
653 final_type
= R_HPPA_32
;
656 final_type
= R_HPPA_PLABEL_32
;
660 final_type
= base_type
;
666 final_type
= base_type
;
677 final_type
= R_HPPA_GOTOFF_R11
;
680 final_type
= R_HPPA_GOTOFF_RS11
;
683 final_type
= R_HPPA_GOTOFF_RD11
;
686 final_type
= R_HPPA_GOTOFF_11
;
694 final_type
= base_type
;
700 final_type
= base_type
;
706 final_type
= R_HPPA_GOTOFF_R14
;
709 final_type
= R_HPPA_GOTOFF_RS14
;
712 final_type
= R_HPPA_GOTOFF_RD14
;
715 final_type
= R_HPPA_GOTOFF_RR14
;
718 final_type
= R_HPPA_GOTOFF_14
;
726 final_type
= base_type
;
732 final_type
= base_type
;
738 final_type
= R_HPPA_GOTOFF_L21
;
741 final_type
= R_HPPA_GOTOFF_LS21
;
744 final_type
= R_HPPA_GOTOFF_LD21
;
747 final_type
= R_HPPA_GOTOFF_LR21
;
756 final_type
= base_type
;
762 final_type
= base_type
;
766 final_type
= base_type
;
770 case R_HPPA_PCREL_CALL
:
777 final_type
= R_HPPA_PCREL_CALL_R11
;
780 final_type
= R_HPPA_PCREL_CALL_RS11
;
783 final_type
= R_HPPA_PCREL_CALL_RD11
;
786 final_type
= R_HPPA_PCREL_CALL_11
;
794 final_type
= base_type
;
800 final_type
= base_type
;
806 final_type
= R_HPPA_PCREL_CALL_R14
;
809 final_type
= R_HPPA_PCREL_CALL_RS14
;
812 final_type
= R_HPPA_PCREL_CALL_RD14
;
815 final_type
= R_HPPA_PCREL_CALL_RR14
;
818 final_type
= R_HPPA_PCREL_CALL_14
;
826 final_type
= base_type
;
834 final_type
= R_HPPA_PCREL_CALL_R17
;
837 final_type
= R_HPPA_PCREL_CALL_RS17
;
840 final_type
= R_HPPA_PCREL_CALL_RD17
;
843 final_type
= R_HPPA_PCREL_CALL_RR17
;
846 final_type
= R_HPPA_PCREL_CALL_17
;
854 final_type
= base_type
;
862 final_type
= R_HPPA_PCREL_CALL_L21
;
865 final_type
= R_HPPA_PCREL_CALL_LS21
;
868 final_type
= R_HPPA_PCREL_CALL_LD21
;
871 final_type
= R_HPPA_PCREL_CALL_LR21
;
880 final_type
= base_type
;
886 final_type
= base_type
;
890 final_type
= base_type
;
901 final_type
= R_HPPA_PLABEL_11
;
904 final_type
= R_HPPA_PLABEL_R11
;
908 final_type
= base_type
;
916 final_type
= R_HPPA_PLABEL_14
;
919 final_type
= R_HPPA_PLABEL_R14
;
923 final_type
= base_type
;
931 final_type
= R_HPPA_PLABEL_L21
;
935 final_type
= base_type
;
943 final_type
= R_HPPA_PLABEL_32
;
947 final_type
= base_type
;
953 final_type
= base_type
;
956 case R_HPPA_ABS_CALL
:
963 final_type
= R_HPPA_ABS_CALL_R11
;
966 final_type
= R_HPPA_ABS_CALL_RS11
;
969 final_type
= R_HPPA_ABS_CALL_RD11
;
972 final_type
= R_HPPA_ABS_CALL_11
;
980 final_type
= base_type
;
986 final_type
= base_type
;
992 final_type
= R_HPPA_ABS_CALL_R14
;
995 final_type
= R_HPPA_ABS_CALL_RS14
;
998 final_type
= R_HPPA_ABS_CALL_RD14
;
1001 final_type
= R_HPPA_ABS_CALL_RR14
;
1004 final_type
= R_HPPA_ABS_CALL_14
;
1012 final_type
= base_type
;
1020 final_type
= R_HPPA_ABS_CALL_R17
;
1023 final_type
= R_HPPA_ABS_CALL_RS17
;
1026 final_type
= R_HPPA_ABS_CALL_RD17
;
1029 final_type
= R_HPPA_ABS_CALL_RR17
;
1032 final_type
= R_HPPA_ABS_CALL_17
;
1040 final_type
= base_type
;
1048 final_type
= R_HPPA_ABS_CALL_L21
;
1051 final_type
= R_HPPA_ABS_CALL_LS21
;
1054 final_type
= R_HPPA_ABS_CALL_LD21
;
1057 final_type
= R_HPPA_ABS_CALL_LR21
;
1066 final_type
= base_type
;
1072 final_type
= base_type
;
1076 final_type
= base_type
;
1081 final_type
= R_HPPA_UNWIND_ENTRY
;
1083 case R_HPPA_COMPLEX
:
1084 case R_HPPA_COMPLEX_PCREL_CALL
:
1085 case R_HPPA_COMPLEX_ABS_CALL
:
1086 final_types
= (elf32_hppa_reloc_type
**) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
*) * 6);
1087 BFD_ASSERT (final_types
!= 0);
1089 finaltype
= (elf32_hppa_reloc_type
*) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
) * 5);
1090 BFD_ASSERT (finaltype
!= 0);
1092 for (i
= 0; i
< 5; i
++)
1093 final_types
[i
] = &finaltype
[i
];
1095 final_types
[5] = NULL
;
1097 finaltype
[0] = R_HPPA_PUSH_SYM
;
1099 if (base_type
== R_HPPA_COMPLEX
)
1100 finaltype
[1] = R_HPPA_PUSH_SYM
;
1101 else if (base_type
== R_HPPA_COMPLEX_PCREL_CALL
)
1102 finaltype
[1] = R_HPPA_PUSH_PCREL_CALL
;
1103 else /* base_type == R_HPPA_COMPLEX_ABS_CALL */
1104 finaltype
[1] = R_HPPA_PUSH_ABS_CALL
;
1106 finaltype
[2] = R_HPPA_SUB
;
1111 finaltype
[3] = R_HPPA_EXPR_F
;
1114 finaltype
[3] = R_HPPA_EXPR_L
;
1117 finaltype
[3] = R_HPPA_EXPR_R
;
1120 finaltype
[3] = R_HPPA_EXPR_LS
;
1123 finaltype
[3] = R_HPPA_EXPR_RS
;
1126 finaltype
[3] = R_HPPA_EXPR_LD
;
1129 finaltype
[3] = R_HPPA_EXPR_RD
;
1132 finaltype
[3] = R_HPPA_EXPR_LR
;
1135 finaltype
[3] = R_HPPA_EXPR_RR
;
1142 finaltype
[4] = R_HPPA_EXPR_11
;
1145 finaltype
[4] = R_HPPA_EXPR_12
;
1148 finaltype
[4] = R_HPPA_EXPR_14
;
1151 finaltype
[4] = R_HPPA_EXPR_17
;
1154 finaltype
[4] = R_HPPA_EXPR_21
;
1157 finaltype
[4] = R_HPPA_EXPR_32
;
1164 final_type
= base_type
;
1173 /* 12.4.4. Derive format from instruction
1175 Given a machine instruction, this function determines its format.
1176 The format can be determined solely from looking at the first six
1177 bits (the major opcode) of the instruction. Several major opcodes
1178 map to the same format. Opcodes which do not map to a known format
1179 should probably be reported as an error. */
1182 hppa_elf_insn2fmt (type
, insn
)
1183 elf32_hppa_reloc_type type
;
1186 unsigned char fmt
= 0; /* XXX: is this a proper default? */
1187 unsigned char op
= get_opcode (insn
);
1189 if (type
== R_HPPA_NONE
)
1243 /* this function is in charge of performing all the HP PA relocations */
1244 static long global_value
;
1245 static long GOT_value
; /* XXX: need to calculate this! For HPUX, GOT == DP */
1246 static asymbol
*global_symbol
;
1247 static int global_sym_defined
;
1249 static bfd_reloc_status_type
1250 DEFUN (hppa_elf_reloc
, (abfd
, reloc_entry
, symbol_in
, data
, input_section
, output_bfd
),
1252 arelent
* reloc_entry AND
1253 asymbol
* symbol_in AND
1255 asection
* input_section AND
1261 unsigned long addr
= reloc_entry
->address
; /*+ input_section->vma*/
1262 bfd_byte
*hit_data
= addr
+ (bfd_byte
*) (data
);
1263 unsigned short r_type
= reloc_entry
->howto
->type
& 0xFF;
1264 unsigned short r_field
= e_fsel
;
1265 boolean r_pcrel
= reloc_entry
->howto
->pc_relative
;
1267 /* howto->bitsize contains the format (11, 14, 21, etc) information */
1268 unsigned r_format
= reloc_entry
->howto
->bitsize
;
1269 long r_addend
= reloc_entry
->addend
;
1274 /* Partial linking - do nothing */
1275 reloc_entry
->address
+= input_section
->output_offset
;
1276 return bfd_reloc_ok
;
1279 if (symbol_in
&& symbol_in
->section
== &bfd_und_section
)
1280 return bfd_reloc_undefined
;
1282 /* Check for stubs that might be required. */
1283 /* symbol_in = hppa_elf_stub_check (abfd, input_section->output_section->owner, reloc_entry); */
1285 sym_value
= get_symbol_value (symbol_in
);
1287 /* compute value of $global$ if it is there. */
1289 if (!global_sym_defined
)
1293 global_value
= (global_symbol
->value
1294 + global_symbol
->section
->output_section
->vma
1295 + global_symbol
->section
->output_offset
);
1296 GOT_value
= global_value
; /* XXX: For HP-UX, GOT==DP */
1297 global_sym_defined
++;
1301 /* get the instruction word */
1302 insn
= bfd_get_32 (abfd
, hit_data
);
1304 /* relocate the value based on the relocation type */
1306 /* basic_type_1: relocation is relative to $global$ */
1307 /* basic_type_2: relocation is relative to the current GOT */
1308 /* basic_type_3: relocation is an absolute call */
1309 /* basic_type_4: relocation is an PC-relative call */
1310 /* basic_type_5: relocation is plabel reference */
1311 /* basic_type_6: relocation is an unwind table relocation */
1312 /* extended_type: unimplemented */
1318 case R_HPPA_32
: /* Symbol + Addend 32 */
1320 goto do_basic_type_1
;
1321 case R_HPPA_11
: /* Symbol + Addend 11 */
1323 goto do_basic_type_1
;
1324 case R_HPPA_14
: /* Symbol + Addend 14 */
1326 goto do_basic_type_1
;
1327 case R_HPPA_17
: /* Symbol + Addend 17 */
1329 goto do_basic_type_1
;
1330 case R_HPPA_L21
: /* L (Symbol, Addend) 21 */
1332 goto do_basic_type_1
;
1333 case R_HPPA_R11
: /* R (Symbol, Addend) 11 */
1335 goto do_basic_type_1
;
1336 case R_HPPA_R14
: /* R (Symbol, Addend) 14 */
1338 goto do_basic_type_1
;
1339 case R_HPPA_R17
: /* R (Symbol, Addend) 17 */
1341 goto do_basic_type_1
;
1342 case R_HPPA_LS21
: /* LS(Symbol, Addend) 21 */
1344 goto do_basic_type_1
;
1345 case R_HPPA_RS11
: /* RS(Symbol, Addend) 11 */
1347 goto do_basic_type_1
;
1348 case R_HPPA_RS14
: /* RS(Symbol, Addend) 14 */
1350 goto do_basic_type_1
;
1351 case R_HPPA_RS17
: /* RS(Symbol, Addend) 17 */
1353 goto do_basic_type_1
;
1354 case R_HPPA_LD21
: /* LD(Symbol, Addend) 21 */
1356 goto do_basic_type_1
;
1357 case R_HPPA_RD11
: /* RD(Symbol, Addend) 11 */
1359 goto do_basic_type_1
;
1360 case R_HPPA_RD14
: /* RD(Symbol, Addend) 14 */
1362 goto do_basic_type_1
;
1363 case R_HPPA_RD17
: /* RD(Symbol, Addend) 17 */
1365 goto do_basic_type_1
;
1366 case R_HPPA_LR21
: /* LR(Symbol, Addend) 21 */
1368 goto do_basic_type_1
;
1369 case R_HPPA_RR14
: /* RR(Symbol, Addend) 14 */
1371 goto do_basic_type_1
;
1372 case R_HPPA_RR17
: /* RR(Symbol, Addend) 17 */
1376 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1377 symbol_in
, sym_value
, r_addend
,
1378 r_type
, r_format
, r_field
, r_pcrel
);
1381 case R_HPPA_GOTOFF_11
: /* Symbol - GOT + Addend 11 */
1383 goto do_basic_type_2
;
1384 case R_HPPA_GOTOFF_14
: /* Symbol - GOT + Addend 14 */
1386 goto do_basic_type_2
;
1387 case R_HPPA_GOTOFF_L21
: /* L (Sym - GOT, Addend) 21 */
1389 goto do_basic_type_2
;
1390 case R_HPPA_GOTOFF_R11
: /* R (Sym - GOT, Addend) 11 */
1392 goto do_basic_type_2
;
1393 case R_HPPA_GOTOFF_R14
: /* R (Sym - GOT, Addend) 14 */
1395 goto do_basic_type_2
;
1396 case R_HPPA_GOTOFF_LS21
: /* LS(Sym - GOT, Addend) 21 */
1398 goto do_basic_type_2
;
1399 case R_HPPA_GOTOFF_RS11
: /* RS(Sym - GOT, Addend) 11 */
1401 goto do_basic_type_2
;
1402 case R_HPPA_GOTOFF_RS14
: /* RS(Sym - GOT, Addend) 14 */
1404 goto do_basic_type_2
;
1405 case R_HPPA_GOTOFF_LD21
: /* LD(Sym - GOT, Addend) 21 */
1407 goto do_basic_type_2
;
1408 case R_HPPA_GOTOFF_RD11
: /* RD(Sym - GOT, Addend) 11 */
1410 goto do_basic_type_2
;
1411 case R_HPPA_GOTOFF_RD14
: /* RD(Sym - GOT, Addend) 14 */
1413 goto do_basic_type_2
;
1414 case R_HPPA_GOTOFF_LR21
: /* LR(Sym - GOT, Addend) 21 */
1416 goto do_basic_type_2
;
1417 case R_HPPA_GOTOFF_RR14
: /* RR(Sym - GOT, Addend) 14 */
1420 sym_value
-= GOT_value
;
1421 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1422 symbol_in
, sym_value
, r_addend
,
1423 r_type
, r_format
, r_field
, r_pcrel
);
1426 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
1428 goto do_basic_type_3
;
1429 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
1431 goto do_basic_type_3
;
1432 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
1434 goto do_basic_type_3
;
1435 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
1437 goto do_basic_type_3
;
1438 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
1440 goto do_basic_type_3
;
1441 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
1443 goto do_basic_type_3
;
1444 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
1446 goto do_basic_type_3
;
1447 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
1449 goto do_basic_type_3
;
1450 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
1452 goto do_basic_type_3
;
1453 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
1455 goto do_basic_type_3
;
1456 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
1458 goto do_basic_type_3
;
1459 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
1461 goto do_basic_type_3
;
1462 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
1464 goto do_basic_type_3
;
1465 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
1467 goto do_basic_type_3
;
1468 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
1470 goto do_basic_type_3
;
1471 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
1473 goto do_basic_type_3
;
1474 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
1476 goto do_basic_type_3
;
1477 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
1480 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1481 symbol_in
, sym_value
, r_addend
,
1482 r_type
, r_format
, r_field
, r_pcrel
);
1485 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
1487 goto do_basic_type_4
;
1488 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
1490 goto do_basic_type_4
;
1491 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
1493 goto do_basic_type_4
;
1494 case R_HPPA_PCREL_CALL_L21
:/* L (Symbol - PC, Addend) 21 */
1496 goto do_basic_type_4
;
1497 case R_HPPA_PCREL_CALL_R11
:/* R (Symbol - PC, Addend) 11 */
1499 goto do_basic_type_4
;
1500 case R_HPPA_PCREL_CALL_R14
:/* R (Symbol - PC, Addend) 14 */
1502 goto do_basic_type_4
;
1503 case R_HPPA_PCREL_CALL_R17
:/* R (Symbol - PC, Addend) 17 */
1505 goto do_basic_type_4
;
1506 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
1508 goto do_basic_type_4
;
1509 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
1511 goto do_basic_type_4
;
1512 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
1514 goto do_basic_type_4
;
1515 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
1517 goto do_basic_type_4
;
1518 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
1520 goto do_basic_type_4
;
1521 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
1523 goto do_basic_type_4
;
1524 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
1526 goto do_basic_type_4
;
1527 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
1529 goto do_basic_type_4
;
1530 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
1532 goto do_basic_type_4
;
1533 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
1535 goto do_basic_type_4
;
1536 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 *//* #69 */
1539 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1540 symbol_in
, sym_value
, r_addend
,
1541 r_type
, r_format
, r_field
, r_pcrel
);
1544 case R_HPPA_PLABEL_32
:
1545 case R_HPPA_PLABEL_11
:
1546 case R_HPPA_PLABEL_14
:
1548 goto do_basic_type_5
;
1549 case R_HPPA_PLABEL_L21
:
1551 goto do_basic_type_5
;
1552 case R_HPPA_PLABEL_R11
:
1553 case R_HPPA_PLABEL_R14
:
1556 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1557 symbol_in
, sym_value
, r_addend
,
1558 r_type
, r_format
, r_field
, r_pcrel
);
1561 case R_HPPA_UNWIND_ENTRY
:
1562 case R_HPPA_UNWIND_ENTRIES
:
1563 hppa_elf_relocate_unwind_table (abfd
, input_section
, data
, addr
,
1564 symbol_in
, sym_value
, r_addend
,
1565 r_type
, r_format
, r_field
, r_pcrel
);
1566 return (bfd_reloc_ok
);
1568 case R_HPPA_PUSH_CONST
: /* push Addend - - */
1569 case R_HPPA_PUSH_PC
: /* push PC + Addend - - */
1570 case R_HPPA_PUSH_SYM
: /* push Symbol + Addend - - */
1571 case R_HPPA_PUSH_GOTOFF
: /* push Symbol - GOT + Addend - - */
1572 case R_HPPA_PUSH_ABS_CALL
: /* push Symbol + Addend - - */
1573 case R_HPPA_PUSH_PCREL_CALL
: /* push Symbol - PC + Addend - - */
1574 case R_HPPA_PUSH_PLABEL
: /* [TBD] - - */
1575 case R_HPPA_MAX
: /* pop A and B, push max(B,A) - - */
1576 case R_HPPA_MIN
: /* pop A and B, push min(B,A) - - */
1577 case R_HPPA_ADD
: /* pop A and B, push B + A - - */
1578 case R_HPPA_SUB
: /* pop A and B, push B - A - - */
1579 case R_HPPA_MULT
: /* pop A and B, push B * A - - */
1580 case R_HPPA_DIV
: /* pop A and B, push B / A - - */
1581 case R_HPPA_MOD
: /* pop A and B, push B % A - - */
1582 case R_HPPA_AND
: /* pop A and B, push B & A - - */
1583 case R_HPPA_OR
: /* pop A and B, push B | A - - */
1584 case R_HPPA_XOR
: /* pop A and B, push B ^ A - - */
1585 case R_HPPA_NOT
: /* pop A, push ~A - - */
1586 case R_HPPA_LSHIFT
: /* pop A, push A << Addend - - */
1587 case R_HPPA_ARITH_RSHIFT
: /* pop A, push A >> Addend - - */
1588 case R_HPPA_LOGIC_RSHIFT
: /* pop A, push A >> Addend - - */
1589 case R_HPPA_EXPR_F
: /* pop A, push A + Addend L - */
1590 case R_HPPA_EXPR_L
: /* pop A, push L(A,Addend) L - */
1591 case R_HPPA_EXPR_R
: /* pop A, push R(A,Addend) R - */
1592 case R_HPPA_EXPR_LS
: /* pop A, push LS(A,Addend) LS - */
1593 case R_HPPA_EXPR_RS
: /* pop A, push RS(A,Addend) RS - */
1594 case R_HPPA_EXPR_LD
: /* pop A, push LD(A,Addend) LD - */
1595 case R_HPPA_EXPR_RD
: /* pop A, push RD(A,Addend) RD - */
1596 case R_HPPA_EXPR_LR
: /* pop A, push LR(A,Addend) LR - */
1597 case R_HPPA_EXPR_RR
: /* pop A, push RR(A,Addend) RR - */
1599 case R_HPPA_EXPR_32
: /* pop - 32 */
1600 case R_HPPA_EXPR_21
: /* pop - 21 */
1601 case R_HPPA_EXPR_11
: /* pop - 11 */
1602 case R_HPPA_EXPR_14
: /* pop - 14 */
1603 case R_HPPA_EXPR_17
: /* pop - 17 */
1604 case R_HPPA_EXPR_12
: /* pop - 12 */
1605 fprintf (stderr
, "Relocation problem: ");
1606 fprintf (stderr
, "Unimplemented reloc type %d, in module %s\n",
1607 r_type
, abfd
->filename
);
1608 return (bfd_reloc_notsupported
);
1609 case R_HPPA_STUB_CALL_17
:
1610 /* yes, a branch to a long branch stub. Change instruction to a BLE */
1612 if ( *(unsigned *)hit_data
& 2 )
1613 insn
= BLE_N_XXX_0_0
;
1616 bfd_put_32 (abfd
, insn
, hit_data
);
1617 r_type
= R_HPPA_ABS_CALL_17
;
1619 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1620 symbol_in
, sym_value
, r_addend
,
1621 r_type
, r_format
, r_field
, r_pcrel
);
1625 fprintf (stderr
, "Relocation problem : ");
1626 fprintf (stderr
, "Unrecognized reloc type %d, in module %s\n",
1627 r_type
, abfd
->filename
);
1628 return (bfd_reloc_dangerous
);
1631 /* update the instruction word */
1632 bfd_put_32 (abfd
, insn
, hit_data
);
1634 return (bfd_reloc_ok
);
1638 static reloc_howto_type
*
1639 elf_hppa_reloc_type_lookup (arch
, code
)
1640 bfd_arch_info_type
*arch
;
1641 bfd_reloc_code_real_type code
;
1643 if ((int) code
< (int) R_HPPA_UNIMPLEMENTED
)
1645 BFD_ASSERT ((int) elf_hppa_howto_table
[(int) code
].type
== (int) code
);
1646 return &elf_hppa_howto_table
[(int) code
];
1649 return (reloc_howto_type
*) 0;
1652 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1656 DEFUN (elf_hppa_tc_symbol
, (abfd
, symbolP
, sym_idx
),
1658 elf_symbol_type
* symbolP AND
1661 symext_chainS
*symextP
;
1662 unsigned int arg_reloc
;
1664 /* Only functions can have argument relocations. */
1665 if (!(symbolP
->symbol
.flags
& BSF_FUNCTION
))
1668 arg_reloc
= symbolP
->tc_data
.hppa_arg_reloc
;
1670 /* If there are no argument relocation bits, then no relocation is
1671 necessary. Do not add this to the symextn section. */
1675 symextP
= (symext_chainS
*) bfd_alloc (abfd
, sizeof (symext_chainS
) * 2);
1677 symextP
[0].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, sym_idx
);
1678 symextP
[0].next
= &symextP
[1];
1680 symextP
[1].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC
, arg_reloc
);
1681 symextP
[1].next
= NULL
;
1683 if (symext_rootP
== NULL
)
1685 symext_rootP
= &symextP
[0];
1686 symext_lastP
= &symextP
[1];
1690 symext_lastP
->next
= &symextP
[0];
1691 symext_lastP
= &symextP
[1];
1695 /* Accessor function for the list of symbol extension records. */
1696 symext_chainS
*elf32_hppa_get_symextn_chain()
1698 return symext_rootP
;
1701 static symext_entryS
*symextn_contents
;
1702 static unsigned int symextn_contents_real_size
;
1705 DEFUN (elf_hppa_tc_make_sections
, (abfd
, ignored
),
1709 symext_chainS
*symextP
;
1713 void hppa_elf_stub_finish (); /* forward declaration */
1714 asection
*symextn_sec
;
1716 hppa_elf_stub_finish (abfd
);
1718 if (symext_rootP
== NULL
)
1721 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
1724 size
= sizeof (symext_entryS
) * n
;
1725 symextn_sec
= bfd_get_section_by_name (abfd
, SYMEXTN_SECTION_NAME
);
1726 if (symextn_sec
== (asection
*) 0)
1728 symextn_sec
= bfd_make_section (abfd
, SYMEXTN_SECTION_NAME
);
1729 bfd_set_section_flags (abfd
,
1731 SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
| SEC_CODE
| SEC_READONLY
);
1732 symextn_sec
->output_section
= symextn_sec
;
1733 symextn_sec
->output_offset
= 0;
1734 bfd_set_section_alignment (abfd
, symextn_sec
, 2);
1736 symextn_contents
= (symext_entryS
*) bfd_alloc (abfd
, size
);
1738 for (i
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++i
)
1739 symextn_contents
[i
] = symextP
->entry
;
1740 symextn_contents_real_size
= size
;
1741 bfd_set_section_size (abfd
, symextn_sec
, symextn_contents_real_size
);
1746 /* Support for HP PA-RISC stub generation.
1750 Center for Software Science
1751 Department of Computer Science
1757 HP-PA calling conventions state:
1759 1. an argument relocation stub is required whenever the callee and
1760 caller argument relocation bits do not match exactly. The exception
1761 to this rule is if either the caller or callee argument relocation
1762 bit are 00 (do not relocate).
1764 2. The linker can optionally add a symbol record for the stub so that
1765 the stub can be reused. The symbol record will be the same as the
1766 original export symbol record, except that the relocation bits will
1767 reflect the input of the stub, the type would be STUB and the symbol
1768 value will be the location of the relocation stub.
1772 Stubs can be inserted *before* the section of the caller. The stubs
1773 can be treated as calls to code that manipulates the arguments.
1780 HPPA_STUB_ARG_RELOC
,
1781 HPPA_STUB_LONG_BRANCH
1785 elf32_hppa_get_sym_extn (abfd
, sym
, type
)
1790 /* This function finds the symbol extension record of the */
1791 /* specified type for the specified symbol. It returns the */
1792 /* value of the symbol extension record. */
1793 symext_entryS retval
;
1798 retval
= (symext_entryS
) 0;
1800 case HPPA_SXT_SYMNDX
:
1801 retval
= (symext_entryS
) 0; /* XXX: need to fix this */
1803 case HPPA_SXT_ARG_RELOC
:
1805 elf_symbol_type
*esymP
= (elf_symbol_type
*) sym
;
1807 retval
= (symext_entryS
) esymP
->tc_data
.hppa_arg_reloc
;
1810 /* This should never happen. */
1817 typedef struct elf32_hppa_stub_name_list_struct
1819 /* name of this stub */
1821 /* stub description for this stub */
1822 struct elf32_hppa_stub_description_struct
*stub_desc
;
1823 /* pointer into stub contents */
1825 /* size of this stub */
1827 /* next stub name entry */
1828 struct elf32_hppa_stub_name_list_struct
*next
;
1829 } elf32_hppa_stub_name_list
;
1831 typedef struct elf32_hppa_stub_description_struct
1833 struct elf32_hppa_stub_description_struct
*next
;
1834 bfd
*this_bfd
; /* bfd to which this stub applies */
1835 asection
*stub_sec
; /* stub section for this bfd */
1836 unsigned relocs_allocated_cnt
; /* count of relocations for this stub section */
1838 unsigned allocated_size
;
1839 int *stub_secp
; /* pointer to the next available location in the buffer */
1840 char *stub_contents
; /* contents of the stubs for this bfd */
1841 elf32_hppa_stub_name_list
*stub_listP
;
1843 elf32_hppa_stub_description
;
1845 static elf32_hppa_stub_description
*elf_hppa_stub_rootP
;
1847 /* Locate the stub section information for the given bfd. */
1848 static elf32_hppa_stub_description
*
1849 find_stubs (abfd
, stub_sec
)
1853 elf32_hppa_stub_description
*stubP
;
1855 for (stubP
= elf_hppa_stub_rootP
; stubP
; stubP
= stubP
->next
)
1857 if (stubP
->this_bfd
== abfd
1858 && stubP
->stub_sec
== stub_sec
)
1862 return (elf32_hppa_stub_description
*) NULL
;
1865 static elf32_hppa_stub_description
*
1866 new_stub (abfd
, stub_sec
)
1870 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1875 stub
= (elf32_hppa_stub_description
*) bfd_zalloc (abfd
, sizeof (elf32_hppa_stub_description
));
1878 stub
->this_bfd
= abfd
;
1879 stub
->stub_sec
= stub_sec
;
1880 stub
->real_size
= 0;
1881 stub
->allocated_size
= 0;
1882 stub
->stub_contents
= NULL
;
1883 stub
->stub_secp
= NULL
;
1885 stub
->next
= elf_hppa_stub_rootP
;
1886 elf_hppa_stub_rootP
= stub
;
1890 bfd_error
= no_memory
;
1891 bfd_perror ("new_stub");
1897 /* Locate the stub by the given name. */
1898 static elf32_hppa_stub_name_list
*
1899 find_stub_by_name (abfd
, stub_sec
, name
)
1904 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1908 elf32_hppa_stub_name_list
*name_listP
;
1910 for (name_listP
= stub
->stub_listP
; name_listP
; name_listP
= name_listP
->next
)
1912 if (!strcmp (name_listP
->sym
->name
, name
))
1920 /* Locate the stub by the given name. */
1921 static elf32_hppa_stub_name_list
*
1922 add_stub_by_name(abfd
, stub_sec
, sym
)
1927 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1928 elf32_hppa_stub_name_list
*stub_entry
;
1931 stub
= new_stub(abfd
, stub_sec
);
1935 stub_entry
= (elf32_hppa_stub_name_list
*)
1936 bfd_zalloc (abfd
, sizeof (elf32_hppa_stub_name_list
));
1940 stub_entry
->size
= 0;
1941 stub_entry
->sym
= sym
;
1942 stub_entry
->stub_desc
= stub
;
1943 /* First byte of this stub is the pointer to
1944 the next available location in the stub buffer. */
1945 stub_entry
->stub_secp
= stub
->stub_secp
;
1946 if (stub
->stub_listP
)
1947 stub_entry
->next
= stub
->stub_listP
;
1949 stub_entry
->next
= NULL
;
1950 stub
->stub_listP
= stub_entry
;
1955 bfd_error
= no_memory
;
1956 bfd_perror("add_stub_by_name");
1960 return (elf32_hppa_stub_name_list
*)NULL
;
1964 #define RETURN_VALUE 1
1966 #define NO_ARG_RELOC 0
1973 #define ARG_RELOC_ERR 7
1985 /* FP register in arg0/arg1. This value can only appear in the arg0 location. */
1987 /* FP register in arg2/arg3. This value can only appear in the arg2 location. */
1990 #define AR_WARN(type,loc) \
1991 fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
1992 reloc_type_strings[type],reloc_loc_strings[loc])
1994 static CONST
char *CONST reloc_type_strings
[] =
1996 "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
1999 static CONST
char *CONST reloc_loc_strings
[] =
2001 "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
2004 static CONST
char mismatches
[6][6] =
2005 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
2007 {NO_ARG_RELOC
, NO_ARG_RELOC
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, NO_ARG_RELOC
},
2009 {NO_ARG_RELOC
, NO_ARG_RELOC
, R_TO_FR
, ARG_RELOC_ERR
, R01_TO_FR
, ARG_RELOC_ERR
},
2011 {NO_ARG_RELOC
, FR_TO_R
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
2013 {ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
2015 {NO_ARG_RELOC
, FR_TO_R01
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, ARG_RELOC_ERR
},
2017 {NO_ARG_RELOC
, FR_TO_R23
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, NO_ARG_RELOC
},
2020 static CONST
char retval_mismatches
[6][6] =
2021 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
2023 {NO_ARG_RELOC
, NO_ARG_RELOC
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, NO_ARG_RELOC
},
2025 {NO_ARG_RELOC
, NO_ARG_RELOC
, FR_TO_R
, ARG_RELOC_ERR
, FR_TO_R01
, ARG_RELOC_ERR
},
2027 {NO_ARG_RELOC
, R_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
2029 {ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
2031 {NO_ARG_RELOC
, R01_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, ARG_RELOC_ERR
},
2033 {NO_ARG_RELOC
, R23_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, NO_ARG_RELOC
},
2037 type_of_mismatch (caller_bits
, callee_bits
, type
)
2045 return mismatches
[caller_bits
][callee_bits
];
2047 return retval_mismatches
[caller_bits
][callee_bits
];
2053 #define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
2055 #define NEW_INSTRUCTION(entry,insn) \
2056 *((entry)->stub_desc->stub_secp)++ = (insn); \
2057 (entry)->stub_desc->real_size += sizeof(int); \
2058 (entry)->size += sizeof(int); \
2059 bfd_set_section_size((entry)->stub_desc->this_bfd, \
2060 (entry)->stub_desc->stub_sec, \
2061 (entry)->stub_desc->real_size);
2063 #define CURRENT_STUB_OFFSET(entry) \
2064 ((int)(entry)->stub_desc->stub_secp - (int)(entry)->stub_desc->stub_contents - 4)
2066 static boolean stubs_finished
= false;
2069 hppa_elf_stub_finish (output_bfd
)
2072 extern bfd_error_vector_type bfd_error_vector
;
2073 elf32_hppa_stub_description
*stub_list
= elf_hppa_stub_rootP
;
2074 /* All the stubs have been built. Finish up building */
2075 /* stub section. Apply relocations to the section. */
2077 if ( stubs_finished
)
2080 for (; stub_list
; stub_list
= stub_list
->next
)
2082 if (stub_list
->real_size
)
2084 bfd
*stub_bfd
= stub_list
->this_bfd
;
2085 asection
*stub_sec
= bfd_get_section_by_name (stub_bfd
, ".hppa_linker_stubs");
2086 bfd_size_type reloc_size
;
2087 arelent
**reloc_vector
;
2089 BFD_ASSERT (stub_sec
== stub_list
->stub_sec
);
2090 reloc_size
= bfd_get_reloc_upper_bound (stub_bfd
, stub_sec
);
2091 reloc_vector
= (arelent
**) alloca (reloc_size
);
2093 BFD_ASSERT (stub_sec
);
2095 /* We are not relaxing the section, so just copy the size info */
2096 stub_sec
->_cooked_size
= stub_sec
->_raw_size
;
2097 stub_sec
->reloc_done
= true;
2100 if (bfd_canonicalize_reloc (stub_bfd
,
2103 output_bfd
->outsymbols
))
2106 for (parent
= reloc_vector
; *parent
!= (arelent
*) NULL
;
2109 bfd_reloc_status_type r
=
2110 bfd_perform_relocation (stub_bfd
,
2112 stub_list
->stub_contents
,
2116 if (r
!= bfd_reloc_ok
)
2120 case bfd_reloc_undefined
:
2121 bfd_error_vector
.undefined_symbol (*parent
, NULL
);
2123 case bfd_reloc_dangerous
:
2124 bfd_error_vector
.reloc_dangerous (*parent
, NULL
);
2126 case bfd_reloc_outofrange
:
2127 case bfd_reloc_overflow
:
2128 bfd_error_vector
.reloc_value_truncated (*parent
, NULL
);
2138 bfd_set_section_contents (output_bfd
,
2140 stub_list
->stub_contents
,
2142 stub_list
->real_size
);
2144 free (reloc_vector
);
2147 stubs_finished
= true;
2151 hppa_elf_stub_branch_reloc (stub_desc
, /* the bfd */
2152 output_bfd
, /* the output bfd */
2153 target_sym
, /* the target symbol */
2154 offset
) /* the offset within the stub buffer (pre-calculated) */
2155 elf32_hppa_stub_description
*stub_desc
;
2157 asymbol
*target_sym
;
2160 /* Allocate a new relocation entry. */
2164 if (stub_desc
->relocs_allocated_cnt
== stub_desc
->stub_sec
->reloc_count
)
2166 if (stub_desc
->stub_sec
->relocation
== NULL
)
2168 stub_desc
->relocs_allocated_cnt
= STUB_RELOC_INCR
;
2169 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2170 stub_desc
->stub_sec
->relocation
= (arelent
*) zalloc (size
);
2174 stub_desc
->relocs_allocated_cnt
+= STUB_RELOC_INCR
;
2175 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2176 stub_desc
->stub_sec
->relocation
= (arelent
*) realloc (stub_desc
->stub_sec
->relocation
,
2181 /* Fill in the details. */
2182 relent
.address
= offset
;
2184 relent
.sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2185 BFD_ASSERT (relent
.sym_ptr_ptr
);
2187 relent
.sym_ptr_ptr
[0] = target_sym
;
2188 relent
.howto
= bfd_reloc_type_lookup (stub_desc
->this_bfd
, R_HPPA_PCREL_CALL_17
);
2190 /* Save it in the array of relocations for the stub section. */
2192 memcpy (&stub_desc
->stub_sec
->relocation
[stub_desc
->stub_sec
->reloc_count
++],
2198 hppa_elf_stub_reloc (stub_desc
, /* the bfd */
2199 output_bfd
, /* the output bfd */
2200 target_sym
, /* the target symbol */
2201 offset
, /* the offset within the stub buffer (pre-calculated) */
2203 elf32_hppa_stub_description
*stub_desc
;
2205 asymbol
*target_sym
;
2207 elf32_hppa_reloc_type type
;
2209 /* Allocate a new relocation entry. */
2212 Elf_Internal_Shdr
*rela_hdr
;
2214 if (stub_desc
->relocs_allocated_cnt
== stub_desc
->stub_sec
->reloc_count
)
2216 if (stub_desc
->stub_sec
->relocation
== NULL
)
2218 stub_desc
->relocs_allocated_cnt
= STUB_RELOC_INCR
;
2219 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2220 stub_desc
->stub_sec
->relocation
= (arelent
*) zalloc (size
);
2224 stub_desc
->relocs_allocated_cnt
+= STUB_RELOC_INCR
;
2225 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2226 stub_desc
->stub_sec
->relocation
= (arelent
*) realloc (stub_desc
->stub_sec
->relocation
,
2231 rela_hdr
= &elf_section_data(stub_desc
->stub_sec
)->rel_hdr
;
2232 rela_hdr
->sh_size
+= sizeof(Elf32_External_Rela
);
2234 /* Fill in the details. */
2235 relent
.address
= offset
;
2237 relent
.sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2238 BFD_ASSERT (relent
.sym_ptr_ptr
);
2240 relent
.sym_ptr_ptr
[0] = target_sym
;
2241 relent
.howto
= bfd_reloc_type_lookup (stub_desc
->this_bfd
, type
);
2243 /* Save it in the array of relocations for the stub section. */
2245 memcpy (&stub_desc
->stub_sec
->relocation
[stub_desc
->stub_sec
->reloc_count
++],
2251 hppa_elf_build_arg_reloc_stub (abfd
, output_bfd
, reloc_entry
, stub_types
)
2254 arelent
*reloc_entry
;
2257 asection
*stub_sec
= bfd_get_section_by_name (abfd
, ".hppa_linker_stubs");
2258 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, stub_sec
);
2259 asymbol
*stub_sym
= NULL
;
2260 asymbol
*target_sym
= reloc_entry
->sym_ptr_ptr
[0];
2261 asection
*output_text_section
= bfd_get_section_by_name (output_bfd
, ".text");
2263 char stub_sym_name
[128];
2264 elf32_hppa_stub_name_list
*stub_entry
;
2268 BFD_ASSERT (stub_desc
== NULL
);
2269 stub_sec
= bfd_make_section (abfd
, ".hppa_linker_stubs");
2270 bfd_set_section_flags (abfd
,
2272 SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_CODE
| SEC_READONLY
);
2273 stub_sec
->output_section
= output_text_section
->output_section
;
2274 stub_sec
->output_offset
= 0;
2275 bfd_set_section_alignment (abfd
, stub_sec
, 2);
2276 stub_desc
= new_stub (abfd
, stub_sec
);
2279 /* make sure we have a stub descriptor structure */
2282 stub_desc
= new_stub (abfd
, stub_sec
);
2284 /* allocate some space to write the stub */
2286 if (!stub_desc
->stub_contents
)
2288 stub_desc
->allocated_size
= STUB_BUFFER_INCR
;
2289 stub_desc
->stub_contents
= (char *) xmalloc (STUB_BUFFER_INCR
);
2291 else if ((stub_desc
->allocated_size
- stub_desc
->real_size
) < STUB_MAX_SIZE
)
2293 stub_desc
->allocated_size
= stub_desc
->allocated_size
+ STUB_BUFFER_INCR
;
2294 stub_desc
->stub_contents
= (char *) xrealloc (stub_desc
->stub_contents
,
2295 stub_desc
->allocated_size
);
2298 stub_desc
->stub_secp
= (int *) (stub_desc
->stub_contents
+ stub_desc
->real_size
);
2300 sprintf (stub_sym_name
,
2301 "_stub_%s_%02d_%02d_%02d_%02d_%02d",
2302 reloc_entry
->sym_ptr_ptr
[0]->name
,
2303 stub_types
[0], stub_types
[1], stub_types
[2], stub_types
[3], stub_types
[4]);
2304 stub_entry
= find_stub_by_name(abfd
, stub_sec
, stub_sym_name
);
2308 stub_sym
= stub_entry
->sym
;
2309 /* redirect the original relocation from the old symbol (a function) */
2310 /* to the stub (the stub calls the function). */
2311 /* XXX do we need to change the relocation type? */
2312 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2313 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2317 /* Stub does not already exist. Create a new stub. */
2318 /* Create a new symbol to point to this stub */
2319 stub_sym
= bfd_make_empty_symbol (abfd
);
2320 stub_sym
->name
= bfd_zalloc (abfd
, strlen (stub_sym_name
) + 1);
2321 strcpy ((char *) stub_sym
->name
, stub_sym_name
);
2322 stub_sym
->value
= (int) stub_desc
->stub_secp
- (int) stub_desc
->stub_contents
;
2323 stub_sym
->section
= stub_sec
;
2324 stub_sym
->flags
= BSF_LOCAL
| BSF_FUNCTION
;
2325 stub_entry
= add_stub_by_name(abfd
, stub_sec
, stub_sym
);
2327 /* redirect the original relocation from the old symbol (a function) */
2328 /* to the stub (the stub calls the function). */
2329 /* XXX do we need to change the relocation type? */
2330 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2331 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2333 /* generate the beginning common section for all stubs */
2335 NEW_INSTRUCTION (stub_entry
, ADDI_8_SP
);
2337 /* generate the code to move the arguments around */
2338 for (i
= ARG0
; i
< ARG3
; i
++)
2340 if (stub_types
[i
] != NO_ARG_RELOC
)
2342 /* A stub is needed */
2343 switch (stub_types
[i
])
2349 NEW_INSTRUCTION (stub_entry
, STWS_ARG0_M8SP
);
2350 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG0
);
2353 NEW_INSTRUCTION (stub_entry
, STWS_ARG1_M8SP
);
2354 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG1
);
2357 NEW_INSTRUCTION (stub_entry
, STWS_ARG2_M8SP
);
2358 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG2
);
2361 NEW_INSTRUCTION (stub_entry
, STWS_ARG3_M8SP
);
2362 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG3
);
2371 NEW_INSTRUCTION(stub_entry
, STWS_ARG0_M4SP
);
2372 NEW_INSTRUCTION(stub_entry
, STWS_ARG1_M8SP
);
2373 NEW_INSTRUCTION(stub_entry
, FLDDS_M8SP_FARG1
);
2376 AR_WARN(stub_types
[i
],i
);
2385 NEW_INSTRUCTION(stub_entry
, STWS_ARG2_M4SP
);
2386 NEW_INSTRUCTION(stub_entry
, STWS_ARG3_M8SP
);
2387 NEW_INSTRUCTION(stub_entry
, FLDDS_M8SP_FARG3
);
2390 AR_WARN(stub_types
[i
],i
);
2399 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG0_M8SP
);
2400 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG0
);
2403 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG1_M8SP
);
2404 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG1
);
2407 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG2_M8SP
);
2408 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG2
);
2411 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG3_M8SP
);
2412 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG3
);
2421 NEW_INSTRUCTION(stub_entry
, FSTDS_FARG1_M8SP
);
2422 NEW_INSTRUCTION(stub_entry
, LDWS_M4SP_ARG0
);
2423 NEW_INSTRUCTION(stub_entry
, LDWS_M8SP_ARG1
);
2426 AR_WARN(stub_types
[i
],i
);
2435 NEW_INSTRUCTION(stub_entry
, FSTDS_FARG3_M8SP
);
2436 NEW_INSTRUCTION(stub_entry
, LDWS_M4SP_ARG2
);
2437 NEW_INSTRUCTION(stub_entry
, LDWS_M8SP_ARG3
);
2440 AR_WARN(stub_types
[i
],i
);
2449 NEW_INSTRUCTION (stub_entry
, ADDI_M8_SP
);
2451 /* generate the branch to the target routine */
2452 NEW_INSTRUCTION (stub_entry
, STW_RP_M8SP
); /* First, save the return address */
2454 /* Branch to the target function. */
2455 /* (Make it a long call, so we do not */
2456 /* have to worry about generating a */
2457 /* long call stub.) */
2458 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_31
);
2459 hppa_elf_stub_reloc (stub_entry
->stub_desc
,
2460 abfd
, /* the output bfd */
2461 target_sym
, /* the target symbol */
2462 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2464 NEW_INSTRUCTION(stub_entry
,BLE_XXX_0_31
);
2465 hppa_elf_stub_reloc (stub_entry
->stub_desc
,
2466 abfd
, /* the output bfd */
2467 target_sym
, /* the target symbol */
2468 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2469 R_HPPA_ABS_CALL_R17
);
2470 NEW_INSTRUCTION(stub_entry
,COPY_31_2
);
2472 /* generate the code to move the return value around */
2474 NEW_INSTRUCTION (stub_entry
, LDW_M8SP_RP
); /* restore return address */
2477 if (stub_types
[i
] != NO_ARG_RELOC
)
2479 /* A stub is needed */
2480 switch (stub_types
[i
])
2483 NEW_INSTRUCTION (stub_entry
, STWS_RET0_M8SP
);
2484 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FRET0
);
2488 NEW_INSTRUCTION (stub_entry
, FSTWS_FRET0_M8SP
);
2489 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_RET0
);
2494 /* generate the ending common section for all stubs */
2496 /* XXX: can we assume this is a save return? */
2497 NEW_INSTRUCTION (stub_entry
, BV_N_0RP
);
2504 hppa_elf_arg_reloc_needed_p (abfd
, reloc_entry
, stub_types
, caller_ar
)
2506 arelent
*reloc_entry
;
2508 symext_entryS caller_ar
;
2510 /* If the symbol is still undefined, there is */
2511 /* no way to know if a stub is required. */
2513 if (reloc_entry
->sym_ptr_ptr
[0] && reloc_entry
->sym_ptr_ptr
[0]->section
!= &bfd_und_section
)
2515 symext_entryS callee_ar
= elf32_hppa_get_sym_extn (abfd
,
2516 reloc_entry
->sym_ptr_ptr
[0],
2517 HPPA_SXT_ARG_RELOC
);
2519 /* Now, determine if a stub is */
2520 /* required. A stub is required if they the callee and caller */
2521 /* argument relocation bits are both nonzero and not equal. */
2523 if (caller_ar
&& callee_ar
)
2525 /* Both are non-zero, we need to do further checking. */
2526 /* First, check if there is a return value relocation to be done */
2530 callee_loc
[RETVAL
] = EXTRACT_ARBITS (callee_ar
, RETVAL
);
2531 caller_loc
[RETVAL
] = EXTRACT_ARBITS (caller_ar
, RETVAL
);
2532 callee_loc
[ARG0
] = EXTRACT_ARBITS (callee_ar
, ARG0
);
2533 caller_loc
[ARG0
] = EXTRACT_ARBITS (caller_ar
, ARG0
);
2534 callee_loc
[ARG1
] = EXTRACT_ARBITS (callee_ar
, ARG1
);
2535 caller_loc
[ARG1
] = EXTRACT_ARBITS (caller_ar
, ARG1
);
2536 callee_loc
[ARG2
] = EXTRACT_ARBITS (callee_ar
, ARG2
);
2537 caller_loc
[ARG2
] = EXTRACT_ARBITS (caller_ar
, ARG2
);
2538 callee_loc
[ARG3
] = EXTRACT_ARBITS (callee_ar
, ARG3
);
2539 caller_loc
[ARG3
] = EXTRACT_ARBITS (caller_ar
, ARG3
);
2541 /* Check some special combinations. For */
2542 /* example, if FU appears in ARG1 or ARG3, we */
2543 /* can move it to ARG0 or ARG2, respectively. */
2545 if (caller_loc
[ARG0
] == AR_FU
|| caller_loc
[ARG1
] == AR_FU
)
2547 caller_loc
[ARG0
] = AR_DBL01
;
2548 caller_loc
[ARG1
] = AR_NO
;
2550 if (caller_loc
[ARG2
] == AR_FU
|| caller_loc
[ARG3
] == AR_FU
)
2552 caller_loc
[ARG2
] = AR_DBL23
;
2553 caller_loc
[ARG3
] = AR_NO
;
2555 if (callee_loc
[ARG0
] == AR_FU
|| callee_loc
[ARG1
] == AR_FU
)
2557 callee_loc
[ARG0
] = AR_DBL01
;
2558 callee_loc
[ARG1
] = AR_NO
;
2560 if (callee_loc
[ARG2
] == AR_FU
|| callee_loc
[ARG3
] == AR_FU
)
2562 callee_loc
[ARG2
] = AR_DBL23
;
2563 callee_loc
[ARG3
] = AR_NO
;
2566 stub_types
[ARG0
] = type_of_mismatch (caller_loc
[ARG0
], callee_loc
[ARG0
], ARGUMENTS
);
2567 stub_types
[ARG1
] = type_of_mismatch (caller_loc
[ARG1
], callee_loc
[ARG1
], ARGUMENTS
);
2568 stub_types
[ARG2
] = type_of_mismatch (caller_loc
[ARG2
], callee_loc
[ARG2
], ARGUMENTS
);
2569 stub_types
[ARG3
] = type_of_mismatch (caller_loc
[ARG3
], callee_loc
[ARG3
], ARGUMENTS
);
2570 stub_types
[RETVAL
] = type_of_mismatch (caller_loc
[RETVAL
], callee_loc
[RETVAL
], RETURN_VALUE
);
2572 /* Steps involved in building stubs: */
2573 /* 1. Determine what argument registers need to relocated. This */
2574 /* step is already done here. */
2575 /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2576 /* This section should never appear in an object file. It is */
2577 /* only used internally. The output_section of the */
2578 /* .hppa_linker_stubs section is the .text section of the */
2580 /* 3. Build a symbol that is used (internally only) as the entry */
2581 /* point of the stub. */
2582 /* 4. Change the instruction of the original branch into a branch to */
2583 /* the stub routine. */
2584 /* 5. Build a relocation entry for the instruction of the original */
2585 /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
2597 fprintf (stderr
, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2598 reloc_entry
->sym_ptr_ptr
[0]->name
,
2599 abfd
->filename
, reloc_entry
->address
,
2600 callee_ar
, caller_ar
);
2601 for (i
= ARG0
; i
< RETVAL
; i
++)
2603 if (stub_types
[i
] != NO_ARG_RELOC
)
2605 fprintf (stderr
, "%s%d: %s ",
2606 i
== RETVAL
? "ret" : "arg",
2607 i
== RETVAL
? 0 : i
,
2608 reloc_type_strings
[stub_types
[i
]]);
2611 fprintf (stderr
, "\n");
2622 hppa_elf_build_long_branch_stub (abfd
, output_bfd
, reloc_entry
, symbol
, data
)
2625 arelent
*reloc_entry
;
2629 asection
*stub_sec
= bfd_get_section_by_name (abfd
, ".hppa_linker_stubs");
2630 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, stub_sec
);
2631 asymbol
*stub_sym
= NULL
;
2632 asymbol
*target_sym
= reloc_entry
->sym_ptr_ptr
[0];
2633 asection
*output_text_section
= bfd_get_section_by_name (output_bfd
, ".text");
2634 char stub_sym_name
[128];
2636 elf32_hppa_stub_name_list
*stub_entry
;
2640 BFD_ASSERT (stub_desc
== NULL
);
2641 stub_sec
= bfd_make_section (abfd
, ".hppa_linker_stubs");
2642 bfd_set_section_flags (abfd
,
2644 SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_CODE
| SEC_READONLY
);
2645 stub_sec
->output_section
= output_text_section
->output_section
;
2646 stub_sec
->output_offset
= 0;
2647 /* set up the ELF section header for this new section. */
2648 /* This is basically the same processing as elf_make_sections() */
2649 /* (elf_make_sections() is static so it is not accessible from */
2653 Elf_Internal_Shdr
*this_hdr
;
2654 this_hdr
= &elf_section_data (stub_sec
)->this_hdr
;
2656 this_hdr
->sh_addr
= stub_sec
->vma
;
2657 this_hdr
->sh_size
= stub_sec
->_raw_size
;
2658 /* contents already set by elf_set_section_contents */
2660 if (stub_sec
->flags
& SEC_RELOC
)
2662 /* emit a reloc section, and thus strtab and symtab... */
2663 Elf_Internal_Shdr
*rela_hdr
;
2664 int use_rela_p
= get_elf_backend_data (abfd
)->use_rela_p
;
2666 rela_hdr
= &elf_section_data (stub_sec
)->rel_hdr
;
2668 /* orelocation has the data, reloc_count has the count... */
2671 rela_hdr
->sh_type
= SHT_RELA
;
2672 rela_hdr
->sh_entsize
= sizeof (Elf32_External_Rela
);
2675 /* REL relocations */
2677 rela_hdr
->sh_type
= SHT_REL
;
2678 rela_hdr
->sh_entsize
= sizeof (Elf32_External_Rel
);
2680 rela_hdr
->sh_flags
= 0;
2681 rela_hdr
->sh_addr
= 0;
2682 rela_hdr
->sh_offset
= 0;
2683 rela_hdr
->sh_addralign
= 0;
2686 if (stub_sec
->flags
& SEC_ALLOC
)
2688 this_hdr
->sh_flags
|= SHF_ALLOC
;
2689 if (stub_sec
->flags
& SEC_LOAD
)
2691 /* @@ Do something with sh_type? */
2694 if (!(stub_sec
->flags
& SEC_READONLY
))
2695 this_hdr
->sh_flags
|= SHF_WRITE
;
2697 if (stub_sec
->flags
& SEC_CODE
)
2698 this_hdr
->sh_flags
|= SHF_EXECINSTR
;
2701 bfd_set_section_alignment (abfd
, stub_sec
, 2);
2702 stub_desc
= new_stub (abfd
, stub_sec
);
2706 stub_desc
= new_stub (abfd
, stub_sec
);
2708 /* allocate some space to write the stub */
2710 if (!stub_desc
->stub_contents
)
2712 stub_desc
->allocated_size
= STUB_BUFFER_INCR
;
2713 stub_desc
->stub_contents
= (char *) malloc (STUB_BUFFER_INCR
);
2715 else if ((stub_desc
->allocated_size
- stub_desc
->real_size
) < STUB_MAX_SIZE
)
2717 stub_desc
->allocated_size
= stub_desc
->allocated_size
+ STUB_BUFFER_INCR
;
2718 stub_desc
->stub_contents
= (char *) realloc (stub_desc
->stub_contents
,
2719 stub_desc
->allocated_size
);
2722 stub_desc
->stub_secp
= (int *) (stub_desc
->stub_contents
+ stub_desc
->real_size
);
2724 sprintf (stub_sym_name
,
2725 "_lb_stub_%s", reloc_entry
->sym_ptr_ptr
[0]->name
);
2726 stub_entry
= find_stub_by_name(abfd
, stub_sec
, stub_sym_name
);
2730 stub_sym
= stub_entry
->sym
;
2731 /* redirect the original relocation from the old symbol (a function) */
2732 /* to the stub (the stub calls the function). */
2733 /* XXX do we need to change the relocation type? */
2734 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2735 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2736 reloc_entry
->howto
= bfd_reloc_type_lookup (abfd
, R_HPPA_STUB_CALL_17
);
2740 /* Stub does not already exist. Create a new stub. */
2741 /* create a symbol to point to this stub */
2742 stub_sym
= bfd_make_empty_symbol (abfd
);
2743 stub_sym
->name
= bfd_zalloc (abfd
, strlen (stub_sym_name
) + 1);
2744 strcpy ((char *) stub_sym
->name
, stub_sym_name
);
2745 stub_sym
->value
= (int) stub_desc
->stub_secp
- (int) stub_desc
->stub_contents
;
2746 stub_sym
->section
= stub_sec
;
2747 stub_sym
->flags
= BSF_LOCAL
| BSF_FUNCTION
;
2748 stub_entry
= add_stub_by_name(abfd
, stub_sec
, stub_sym
);
2750 /* redirect the original relocation from the old symbol (a function) */
2751 /* to the stub (the stub calls the function). */
2752 /* XXX do we need to change the relocation type? */
2753 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2754 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2755 reloc_entry
->howto
= bfd_reloc_type_lookup (abfd
, R_HPPA_STUB_CALL_17
);
2757 /* Build the stub */
2759 /* A millicode call? */
2760 /* If so, the return address comes in on r31 rather than r2 (rp) so a */
2761 /* slightly different code sequence is needed. */
2762 if ( ((*data
& 0x03e00000) >> 21) == 31 )
2765 /* 1. initialization for the call. */
2767 NEW_INSTRUCTION(stub_entry
, LDSID_31_RP
);
2768 NEW_INSTRUCTION(stub_entry
, MTSP_RP_SR0
);
2771 NEW_INSTRUCTION(stub_entry
, COPY_31_2
);
2773 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_31
);
2774 hppa_elf_stub_reloc (stub_desc
,
2775 abfd
, /* the output bfd */
2776 target_sym
, /* the target symbol */
2777 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2780 /* 2. Make the call. */
2782 NEW_INSTRUCTION(stub_entry
,BE_N_XXX_0_31
);
2783 hppa_elf_stub_reloc (stub_desc
,
2784 abfd
, /* the output bfd */
2785 target_sym
, /* the target symbol */
2786 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2787 R_HPPA_ABS_CALL_R17
);
2788 /* 3. Branch back to the original location. */
2789 /* (accomplished with the COPY_31_2 instruction) */
2793 NEW_INSTRUCTION(stub_entry
, STW_31_M24SP
);
2794 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_RP
);
2795 hppa_elf_stub_reloc (stub_desc
,
2796 abfd
, /* the output bfd */
2797 target_sym
, /* the target symbol */
2798 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2801 /* 2. Make the call. */
2803 NEW_INSTRUCTION(stub_entry
,BLE_XXX_0_RP
);
2804 hppa_elf_stub_reloc (stub_desc
,
2805 abfd
, /* the output bfd */
2806 target_sym
, /* the target symbol */
2807 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2808 R_HPPA_ABS_CALL_R17
);
2809 NEW_INSTRUCTION(stub_entry
,COPY_31_2
);
2811 /* 3. Branch back to the original location. */
2812 NEW_INSTRUCTION(stub_entry
, LDW_M24SP_RP
);
2813 NEW_INSTRUCTION(stub_entry
, BV_N_0RP
);
2821 hppa_elf_long_branch_needed_p (abfd
, asec
, reloc_entry
, symbol
, insn
)
2824 arelent
*reloc_entry
;
2828 long sym_value
= get_symbol_value(symbol
);
2829 int fmt
= reloc_entry
->howto
->bitsize
;
2830 unsigned char op
= get_opcode(insn
);
2833 #define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
2835 BFD_ASSERT(fmt
== hppa_elf_insn2fmt(reloc_entry
->howto
->type
,insn
));
2841 reloc_entry
->address
+ asec
->output_offset
+ asec
->output_section
->vma
;
2842 if ( too_far(sym_value
- raddr
,fmt
+1) )
2845 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
);
2855 hppa_elf_stub_check (abfd
, output_bfd
, input_section
, reloc_entry
, symbol
, hit_data
)
2858 asection
*input_section
;
2859 arelent
*reloc_entry
;
2865 switch (reloc_entry
->howto
->type
)
2867 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
2868 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
2869 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
2870 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
2871 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
2872 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
2873 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
2874 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
2875 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
2876 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
2877 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
2878 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
2879 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
2880 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
2881 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
2882 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
2883 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
2884 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
2886 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
2887 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
2888 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
2889 case R_HPPA_PCREL_CALL_12
: /* Symbol - PC + Addend 12 */
2890 case R_HPPA_PCREL_CALL_L21
: /* L (Symbol - PC, Addend) 21 */
2891 case R_HPPA_PCREL_CALL_R11
: /* R (Symbol - PC, Addend) 11 */
2892 case R_HPPA_PCREL_CALL_R14
: /* R (Symbol - PC, Addend) 14 */
2893 case R_HPPA_PCREL_CALL_R17
: /* R (Symbol - PC, Addend) 17 */
2894 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
2895 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
2896 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
2897 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
2898 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
2899 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
2900 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
2901 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
2902 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
2903 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
2904 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 */
2906 symext_entryS caller_ar
= (symext_entryS
) ELF32_HGPPA_R_ARG_RELOC (reloc_entry
->addend
);
2907 if (hppa_elf_arg_reloc_needed_p (abfd
, reloc_entry
, stub_types
, caller_ar
))
2909 /* generate a stub */
2910 return hppa_elf_build_arg_reloc_stub (abfd
, output_bfd
,
2911 reloc_entry
, stub_types
);
2913 if (hppa_elf_long_branch_needed_p (abfd
, input_section
, reloc_entry
,
2914 symbol
, *(unsigned *)hit_data
))
2916 /* generate a stub */
2917 return hppa_elf_build_long_branch_stub (abfd
, output_bfd
,
2918 reloc_entry
, symbol
,
2919 (unsigned *)hit_data
);
2927 return reloc_entry
->sym_ptr_ptr
[0];
2930 #define STUB_SYM_BUFFER_INC 5
2933 hppa_look_for_stubs_in_section (stub_bfd
, abfd
, output_bfd
, asec
, syms
, new_sym_cnt
)
2943 asymbol
*new_syms
= (asymbol
*) NULL
;
2947 /* Relocations are in different places depending on whether this is
2948 an output section or an input section. Also, the relocations are
2949 in different forms. Sigh. Luckily, we have
2950 bfd_canonicalize_reloc() to straighten this out for us. */
2952 /* if ( asec->orelocation || asec->relocation ) { */
2953 if (asec
->reloc_count
> 0)
2955 arelent
**reloc_vector
= (arelent
**) alloca (asec
->reloc_count
* (sizeof (arelent
*) + 1));
2957 bfd_canonicalize_reloc (abfd
, asec
, reloc_vector
, syms
);
2958 for (i
= 0; i
< asec
->reloc_count
; i
++)
2963 if ( asec
->orelocation
)
2964 rle
= asec
->orelocation
[i
];
2966 rle
= asec
->relocation
+i
;
2969 arelent
*rle
= reloc_vector
[i
];
2971 switch (rle
->howto
->type
)
2973 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
2974 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
2975 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
2976 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
2977 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
2978 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
2979 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
2980 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
2981 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
2982 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
2983 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
2984 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
2985 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
2986 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
2987 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
2988 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
2989 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
2990 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
2992 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
2993 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
2994 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
2995 case R_HPPA_PCREL_CALL_12
: /* Symbol - PC + Addend 12 */
2996 case R_HPPA_PCREL_CALL_L21
: /* L (Symbol - PC, Addend) 21 */
2997 case R_HPPA_PCREL_CALL_R11
: /* R (Symbol - PC, Addend) 11 */
2998 case R_HPPA_PCREL_CALL_R14
: /* R (Symbol - PC, Addend) 14 */
2999 case R_HPPA_PCREL_CALL_R17
: /* R (Symbol - PC, Addend) 17 */
3000 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
3001 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
3002 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
3003 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
3004 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
3005 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
3006 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
3007 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
3008 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
3009 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
3010 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 */
3012 symext_entryS caller_ar
= (symext_entryS
) ELF32_HPPA_R_ARG_RELOC (rle
->addend
);
3013 if (hppa_elf_arg_reloc_needed_p (abfd
, rle
, stub_types
,
3016 /* generate a stub */
3017 /* keep track of the new symbol */
3020 if (new_cnt
== new_max
)
3022 new_max
+= STUB_SYM_BUFFER_INC
;
3023 new_syms
= (asymbol
*) realloc (new_syms
, new_max
* sizeof (asymbol
));
3025 r
= hppa_elf_build_arg_reloc_stub (stub_bfd
, output_bfd
,
3027 new_syms
[new_cnt
++] = *r
;
3029 /* We need to retrieve the section contents to check for
3034 bfd_get_section_contents (abfd
, asec
, &insn
, rle
->address
,
3036 if (hppa_elf_long_branch_needed_p (abfd
, asec
, rle
,
3037 rle
->sym_ptr_ptr
[0],
3040 /* generate a stub */
3041 /* keep track of the new symbol */
3044 if (new_cnt
== new_max
)
3046 new_max
+= STUB_SYM_BUFFER_INC
;
3047 new_syms
= (asymbol
*) realloc (new_syms
, (new_max
* sizeof (asymbol
)));
3049 r
= hppa_elf_build_long_branch_stub (stub_bfd
,
3052 rle
->sym_ptr_ptr
[0],
3054 new_syms
[new_cnt
++] = *r
;
3060 /* Plabels are designed to allow code pointers to be
3061 passed between spaces. These relocations correspond
3062 to the P%, LP%, and RP% field selectors. */
3064 case R_HPPA_PLABEL_32
: /* F(Plabel(Symbol,Addend),0) 32 */
3065 case R_HPPA_PLABEL_11
: /* F(Plabel(Symbol,Addend),0) 11 */
3066 case R_HPPA_PLABEL_14
: /* F(Plabel(Symbol,Addend),0) 14 */
3067 case R_HPPA_PLABEL_L21
: /* L(Plabel(Symbol,Addend),0) 21 */
3068 case R_HPPA_PLABEL_R11
: /* R(Plabel(Symbol,Addend),0) 11 */
3069 case R_HPPA_PLABEL_R14
: /* R(Plabel(Symbol,Addend),0) 14 */
3070 /* We need to retrieve the section contents to check for
3071 long branch stubs. */
3073 /* On a plabel relocation, assume the arguments of the
3074 caller are set up in general registers. */
3075 /* 0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
3076 symext_entryS caller_ar
= (symext_entryS
) 0x155;
3078 if (hppa_elf_arg_reloc_needed_p (abfd
, rle
, stub_types
,
3081 /* generate a plabel stub */
3082 /* keep track of the new symbol */
3085 if (new_cnt
== new_max
)
3087 new_max
+= STUB_SYM_BUFFER_INC
;
3088 new_syms
= (asymbol
*) realloc (new_syms
,
3090 * sizeof (asymbol
)));
3092 r
= hppa_elf_build_arg_reloc_stub (stub_bfd
,
3096 new_syms
[new_cnt
++] = *r
;
3107 *new_sym_cnt
= new_cnt
;
3112 char *linker_stubs
= NULL
;
3113 int linker_stubs_size
= 0;
3114 int linker_stubs_max_size
= 0;
3115 #define STUB_ALLOC_INCR 100
3118 DEFUN (hppa_elf_set_section_contents
, (abfd
, section
, location
, offset
, count
),
3123 bfd_size_type count
)
3125 if ( strcmp(section
->name
, ".hppa_linker_stubs") == 0 )
3127 if ( linker_stubs_max_size
< offset
+ count
)
3129 linker_stubs_max_size
= offset
+ count
+ STUB_ALLOC_INCR
;
3130 linker_stubs
= (char *)realloc(linker_stubs
, linker_stubs_max_size
);
3133 if ( offset
+ count
> linker_stubs_size
)
3134 linker_stubs_size
= offset
+ count
;
3136 memcpy(linker_stubs
+ offset
,location
,count
);
3140 return bfd_elf32_set_section_contents (abfd
, section
, location
,
3145 DEFUN (hppa_elf_get_section_contents
, (abfd
, section
, location
, offset
, count
),
3150 bfd_size_type count
)
3152 /* if this is the linker stub section, then we have the */
3153 /* section contents in memory rather than on disk. */
3154 if (strcmp (section
->name
, ".hppa_linker_stubs") == 0)
3156 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, section
);
3160 if ((bfd_size_type
) (offset
+ count
) > section
->_raw_size
)
3161 return (false); /* on error */
3162 if ((bfd_size_type
) (offset
+ count
) > stub_desc
->real_size
)
3163 return (false); /* on error */
3165 memcpy (location
, stub_desc
->stub_contents
+ offset
, count
);
3168 /* if this is the symbol extension section, then we have the */
3169 /* section contents in memory rather than on disk. */
3170 else if (strcmp (section
->name
, ".hppa_symextn") == 0)
3174 if ((bfd_size_type
) (offset
+ count
) > section
->_raw_size
)
3175 return (false); /* on error */
3176 if ((bfd_size_type
) (offset
+ count
) > symextn_contents_real_size
)
3177 return (false); /* on error */
3179 memcpy (location
, symextn_contents
+ offset
, count
);
3183 return bfd_generic_get_section_contents (abfd
, section
, location
, offset
,
3188 DEFUN (elf_info_to_howto
, (abfd
, cache_ptr
, dst
),
3190 arelent
* cache_ptr AND
3191 Elf32_Internal_Rela
* dst
)
3193 BFD_ASSERT (ELF32_R_TYPE(dst
->r_info
) < (unsigned int) R_HPPA_UNIMPLEMENTED
);
3194 cache_ptr
->howto
= &elf_hppa_howto_table
[ELF32_R_TYPE(dst
->r_info
)];
3198 DEFUN (elf32_hppa_backend_symbol_processing
, (abfd
, sym
),
3202 /* Is this a definition of $global$? If so, keep it because it will be
3203 needed if any relocations are performed. */
3205 if (!strcmp (sym
->name
, "$global$")
3206 && sym
->section
!= &bfd_und_section
)
3208 global_symbol
= sym
;
3212 #define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
3214 struct elf32_hppa_symextn_map_struct
3222 static struct elf32_hppa_symextn_map_struct
*elf32_hppa_symextn_map
;
3223 static int elf32_hppa_symextn_map_size
;
3226 DEFUN (elf32_hppa_backend_symbol_table_processing
, (abfd
, esyms
,symcnt
),
3228 elf_symbol_type
*esyms AND
3231 Elf32_Internal_Shdr
*symextn_hdr
= bfd_elf_find_section (abfd
, SYMEXTN_SECTION_NAME
);
3233 int current_sym_idx
= 0;
3235 /* If the symbol extension section does not exist, all the symbol */
3236 /* all the symbol extension information is assumed to be zero. */
3238 if ( symextn_hdr
== NULL
)
3240 for ( i
= 0; i
< symcnt
; i
++ )
3242 esyms
[i
].tc_data
.hppa_arg_reloc
= 0;
3247 /* allocate a buffer of the appropriate size for the symextn section */
3249 symextn_hdr
->contents
= bfd_zalloc(abfd
,symextn_hdr
->sh_size
);
3250 symextn_hdr
->size
= symextn_hdr
->sh_size
;
3252 /* read in the symextn section */
3254 if (bfd_seek (abfd
, symextn_hdr
->sh_offset
, SEEK_SET
) == -1)
3256 bfd_error
= system_call_error
;
3259 if (bfd_read ((PTR
) symextn_hdr
->contents
, 1, symextn_hdr
->size
, abfd
)
3260 != symextn_hdr
->size
)
3262 free ((PTR
)symextn_hdr
->contents
);
3263 bfd_error
= system_call_error
;
3267 /* parse the entries, updating the symtab entries as we go */
3269 for ( i
= 0; i
< symextn_hdr
->size
/ sizeof(symext_entryS
); i
++ )
3271 symext_entryS
*seP
= ((symext_entryS
*)symextn_hdr
->contents
) + i
;
3272 int se_value
= ELF32_HPPA_SX_VAL(*seP
);
3273 int se_type
= ELF32_HPPA_SX_TYPE(*seP
);
3280 case HPPA_SXT_SYMNDX
:
3281 if ( se_value
>= symcnt
)
3283 bfd_error
= bad_value
;
3284 bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3287 current_sym_idx
= se_value
- 1;
3290 case HPPA_SXT_ARG_RELOC
:
3291 esyms
[current_sym_idx
].tc_data
.hppa_arg_reloc
= se_value
;
3295 bfd_error
= bad_value
;
3296 bfd_perror("elf32_hppa_backend_symbol_table_processing");
3303 #define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
3306 DEFUN (elf32_hppa_backend_section_processing
, (abfd
, secthdr
),
3308 Elf32_Internal_Shdr
*secthdr
)
3312 if ( secthdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3314 for ( i
= 0; i
< secthdr
->size
/ sizeof(symext_entryS
); i
++ )
3316 symext_entryS
*seP
= ((symext_entryS
*)secthdr
->contents
) + i
;
3317 int se_value
= ELF32_HPPA_SX_VAL(*seP
);
3318 int se_type
= ELF32_HPPA_SX_TYPE(*seP
);
3325 case HPPA_SXT_SYMNDX
:
3326 for ( j
= 0; j
< abfd
->symcount
; j
++ )
3328 /* locate the map entry for this symbol, if there is one. */
3329 /* modify the symbol extension section symbol index entry */
3330 /* to reflect the new symbol table index */
3332 for ( k
= 0; k
< elf32_hppa_symextn_map_size
; k
++ )
3334 if ( elf32_hppa_symextn_map
[k
].old_index
== se_value
3335 && elf32_hppa_symextn_map
[k
].bfd
== abfd
->outsymbols
[j
]->the_bfd
3336 && elf32_hppa_symextn_map
[k
].sym
== abfd
->outsymbols
[j
] )
3339 ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, j
),
3346 case HPPA_SXT_ARG_RELOC
:
3350 bfd_error
= bad_value
;
3351 bfd_perror("elf32_hppa_backend_section_processing");
3359 #define elf_backend_section_processing elf32_hppa_backend_section_processing
3362 DEFUN (elf32_hppa_backend_section_from_shdr
, (abfd
, hdr
, name
),
3364 Elf32_Internal_Shdr
*hdr AND
3369 if ( hdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3371 BFD_ASSERT ( strcmp(name
,".hppa_symextn") == 0 );
3373 /* Bits that get saved. This one is real. */
3376 newsect
= bfd_make_section (abfd
, name
);
3377 if (newsect
!= NULL
)
3379 newsect
->vma
= hdr
->sh_addr
;
3380 newsect
->_raw_size
= hdr
->sh_size
;
3381 newsect
->filepos
= hdr
->sh_offset
; /* so we can read back the bits */
3382 newsect
->flags
|= SEC_HAS_CONTENTS
;
3383 newsect
->alignment_power
= hdr
->sh_addralign
;
3385 if (hdr
->sh_flags
& SHF_ALLOC
)
3387 newsect
->flags
|= SEC_ALLOC
;
3388 newsect
->flags
|= SEC_LOAD
;
3391 if (!(hdr
->sh_flags
& SHF_WRITE
))
3392 newsect
->flags
|= SEC_READONLY
;
3394 if (hdr
->sh_flags
& SHF_EXECINSTR
)
3395 newsect
->flags
|= SEC_CODE
; /* FIXME: may only contain SOME code */
3397 newsect
->flags
|= SEC_DATA
;
3399 hdr
->rawdata
= (void *) newsect
;
3407 #define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
3410 DEFUN (elf32_hppa_backend_fake_sections
, (abfd
, secthdr
, asect
),
3412 Elf_Internal_Shdr
*secthdr AND
3416 if ( strcmp(asect
->name
, ".hppa_symextn") == 0 )
3418 secthdr
->sh_type
= SHT_HPPA_SYMEXTN
;
3419 secthdr
->sh_flags
= 0;
3420 secthdr
->sh_info
= elf_section_data(asect
)->rel_hdr
.sh_link
;
3421 secthdr
->sh_link
= elf_onesymtab(abfd
);
3425 if (!strcmp (asect
->name
, ".hppa_unwind"))
3427 secthdr
->sh_type
= SHT_PROGBITS
;
3428 /* Unwind descriptors are not part of the program memory image. */
3429 secthdr
->sh_flags
= 0;
3430 secthdr
->sh_info
= 0;
3431 secthdr
->sh_link
= 0;
3432 secthdr
->sh_entsize
= 16;
3439 #define elf_backend_fake_sections elf32_hppa_backend_fake_sections
3442 DEFUN (elf32_hppa_backend_section_from_bfd_section
, (abfd
, hdr
, asect
),
3444 Elf32_Internal_Shdr
*hdr AND
3448 if ( hdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3452 if (((struct sec
*) (hdr
->rawdata
)) == asect
)
3454 BFD_ASSERT( strcmp(asect
->name
, ".hppa_symextn") == 0 );
3463 #define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
3465 #define bfd_generic_get_section_contents hppa_elf_get_section_contents
3466 #define bfd_elf32_set_section_contents hppa_elf_set_section_contents
3468 #define TARGET_BIG_SYM bfd_elf32_hppa_vec
3469 #define TARGET_BIG_NAME "elf32-hppa"
3470 #define ELF_ARCH bfd_arch_hppa
3471 #define ELF_MAXPAGESIZE 0x1000
3473 #include "elf32-target.h"