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
;
199 static boolean symext_chain_built
;
202 DEFUN (hppa_elf_rebuild_insn
, (abfd
, insn
, value
, r_type
, r_field
, r_format
),
204 unsigned long insn AND
205 unsigned long value AND
206 unsigned short r_type AND
207 unsigned short r_field AND
208 unsigned short r_format
)
210 unsigned long const_part
; /* part of the instruction that does not change */
211 unsigned long rebuilt_part
;
219 const_part
= insn
& 0xffffe002;
220 dis_assemble_12 (value
, &w1
, &w
);
221 rebuilt_part
= (w1
<< 2) | w
;
222 return const_part
| rebuilt_part
;
229 const_part
= insn
& 0xffffe002;
230 dis_assemble_12 (value
, &w1
, &w
);
231 rebuilt_part
= (w1
<< 2) | w
;
232 return const_part
| rebuilt_part
;
236 const_part
= insn
& 0xffffc000;
237 low_sign_unext (value
, 14, &rebuilt_part
);
238 return const_part
| rebuilt_part
;
244 const_part
= insn
& 0xffe0e002;
245 dis_assemble_17 (value
, &w1
, &w2
, &w
);
246 rebuilt_part
= (w2
<< 2) | (w1
<< 16) | w
;
247 return const_part
| rebuilt_part
;
251 const_part
= insn
& 0xffe00000;
252 dis_assemble_21 (value
, &rebuilt_part
);
253 return const_part
| rebuilt_part
;
260 fprintf (stderr
, "Relocation problem : ");
262 "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
263 r_type
, r_format
, r_field
, abfd
->filename
);
269 DEFUN (hppa_elf_relocate_insn
,
271 insn
, address
, symp
, sym_value
, r_addend
,
272 r_type
, r_format
, r_field
, pcrel
),
274 asection
* input_sect AND
275 unsigned long insn AND
276 unsigned long address AND
280 unsigned short r_type AND
281 unsigned short r_format AND
282 unsigned short r_field AND
285 unsigned char opcode
= get_opcode (insn
);
300 constant_value
= HPPA_R_CONSTANT (r_addend
);
301 BFD_ASSERT (r_format
== 14);
304 sym_value
-= address
;
305 sym_value
= hppa_field_adjust (sym_value
, constant_value
, r_field
);
306 return hppa_elf_rebuild_insn (abfd
, insn
, sym_value
, r_type
, r_field
, r_format
);
309 case SUBI
: /* case SUBIO: */
310 case ADDIT
: /* case ADDITO: */
311 case ADDI
: /* case ADDIO: */
312 BFD_ASSERT (r_format
== 11);
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
);
320 BFD_ASSERT (r_format
== 21);
322 constant_value
= 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
= 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
= HPPA_R_CONSTANT (r_addend
);
357 return hppa_field_adjust (sym_value
, constant_value
, r_field
);
362 "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
363 opcode
, r_format
, r_field
);
370 DEFUN (hppa_elf_relocate_unwind_table
,
372 data
, address
, symp
, sym_value
, r_addend
,
373 r_type
, r_format
, r_field
, pcrel
),
375 asection
* input_sect AND
377 unsigned long address AND
381 unsigned short r_type AND
382 unsigned short r_format AND
383 unsigned short r_field AND
386 bfd_byte
*hit_data
= address
+ (bfd_byte
*) (data
);
389 long relocated_value
;
392 BFD_ASSERT (r_format
== 32);
393 BFD_ASSERT (r_field
== e_fsel
);
396 case R_HPPA_UNWIND_ENTRY
:
397 start_offset
= bfd_get_32 (abfd
, hit_data
);
398 relocated_value
= hppa_field_adjust (sym_value
, start_offset
, r_field
);
399 bfd_put_32 (abfd
, relocated_value
, hit_data
);
401 hit_data
+= sizeof (unsigned long);
402 end_offset
= bfd_get_32 (abfd
, hit_data
);
403 relocated_value
= hppa_field_adjust (sym_value
, end_offset
, r_field
);
404 bfd_put_32 (abfd
, relocated_value
, hit_data
);
407 case R_HPPA_UNWIND_ENTRIES
:
408 for (i
= 0; i
< r_addend
; i
++, hit_data
+= 3 * sizeof (unsigned long))
410 unsigned int adjustment
;
411 start_offset
= bfd_get_32 (abfd
, hit_data
);
412 /* Stuff the symbol value into the first word */
413 /* of the unwind descriptor */
414 bfd_put_32 (abfd
, sym_value
, hit_data
);
415 adjustment
= sym_value
- start_offset
;
417 hit_data
+= sizeof (unsigned long);
418 end_offset
= adjustment
+ bfd_get_32 (abfd
, hit_data
);
419 bfd_put_32 (abfd
, end_offset
, hit_data
);
421 /* If this is not the last unwind entry, */
422 /* adjust the symbol value. */
423 if (i
+ 1 < r_addend
)
425 start_offset
= bfd_get_32 (abfd
, hit_data
+ 3 * sizeof (unsigned long));
426 sym_value
= start_offset
+ adjustment
;
433 "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
434 r_type
, r_format
, r_field
);
438 /* Provided the symbol, returns the value reffed */
440 get_symbol_value (symbol
)
445 if (symbol
== (asymbol
*) NULL
)
447 else if (symbol
->section
== &bfd_com_section
)
453 relocation
= symbol
->value
+
454 symbol
->section
->output_section
->vma
+
455 symbol
->section
->output_offset
;
461 /* This function provides a pretty straight-forward mapping between a */
462 /* base relocation type, format and field into the relocation type */
463 /* that will be emitted in an object file. The only wrinkle in the */
464 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
465 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
466 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
467 /* (in the case of P, PR, and PL). */
469 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
473 hppa_elf_gen_reloc_error (base_type
, fmt
, field
)
474 elf32_hppa_reloc_type base_type
;
478 fprintf (stderr
, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
479 base_type
, fmt
, field
);
482 elf32_hppa_reloc_type
**
483 hppa_elf_gen_reloc_type (abfd
, base_type
, format
, field
)
485 elf32_hppa_reloc_type base_type
;
489 #define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field)
491 elf32_hppa_reloc_type
*finaltype
;
492 elf32_hppa_reloc_type
**final_types
;
495 final_types
= (elf32_hppa_reloc_type
**) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
*) * 2);
496 BFD_ASSERT (final_types
!= 0);
498 finaltype
= (elf32_hppa_reloc_type
*) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
));
499 BFD_ASSERT (finaltype
!= 0);
501 final_types
[0] = finaltype
;
502 final_types
[1] = NULL
;
504 #define final_type finaltype[0]
506 final_type
= base_type
;
517 final_type
= R_HPPA_11
;
520 final_type
= R_HPPA_R11
;
523 final_type
= R_HPPA_RS11
;
526 final_type
= R_HPPA_RD11
;
530 final_type
= R_HPPA_PLABEL_11
;
533 final_type
= R_HPPA_PLABEL_R11
;
546 final_type
= base_type
;
557 final_type
= R_HPPA_R14
;
560 final_type
= R_HPPA_RS14
;
563 final_type
= R_HPPA_RD14
;
566 final_type
= R_HPPA_RR14
;
570 final_type
= R_HPPA_PLABEL_14
;
573 final_type
= R_HPPA_PLABEL_R14
;
587 final_type
= base_type
;
595 final_type
= R_HPPA_17
;
598 final_type
= R_HPPA_R17
;
601 final_type
= R_HPPA_RS17
;
604 final_type
= R_HPPA_RD17
;
607 final_type
= R_HPPA_RR17
;
615 final_type
= base_type
;
623 final_type
= R_HPPA_L21
;
626 final_type
= R_HPPA_LS21
;
629 final_type
= R_HPPA_LD21
;
632 final_type
= R_HPPA_LR21
;
635 final_type
= R_HPPA_PLABEL_L21
;
644 final_type
= base_type
;
652 final_type
= R_HPPA_32
;
655 final_type
= R_HPPA_PLABEL_32
;
659 final_type
= base_type
;
665 final_type
= base_type
;
676 final_type
= R_HPPA_GOTOFF_R11
;
679 final_type
= R_HPPA_GOTOFF_RS11
;
682 final_type
= R_HPPA_GOTOFF_RD11
;
685 final_type
= R_HPPA_GOTOFF_11
;
693 final_type
= base_type
;
699 final_type
= base_type
;
705 final_type
= R_HPPA_GOTOFF_R14
;
708 final_type
= R_HPPA_GOTOFF_RS14
;
711 final_type
= R_HPPA_GOTOFF_RD14
;
714 final_type
= R_HPPA_GOTOFF_RR14
;
717 final_type
= R_HPPA_GOTOFF_14
;
725 final_type
= base_type
;
731 final_type
= base_type
;
737 final_type
= R_HPPA_GOTOFF_L21
;
740 final_type
= R_HPPA_GOTOFF_LS21
;
743 final_type
= R_HPPA_GOTOFF_LD21
;
746 final_type
= R_HPPA_GOTOFF_LR21
;
755 final_type
= base_type
;
761 final_type
= base_type
;
765 final_type
= base_type
;
769 case R_HPPA_PCREL_CALL
:
776 final_type
= R_HPPA_PCREL_CALL_R11
;
779 final_type
= R_HPPA_PCREL_CALL_RS11
;
782 final_type
= R_HPPA_PCREL_CALL_RD11
;
785 final_type
= R_HPPA_PCREL_CALL_11
;
793 final_type
= base_type
;
799 final_type
= base_type
;
805 final_type
= R_HPPA_PCREL_CALL_R14
;
808 final_type
= R_HPPA_PCREL_CALL_RS14
;
811 final_type
= R_HPPA_PCREL_CALL_RD14
;
814 final_type
= R_HPPA_PCREL_CALL_RR14
;
817 final_type
= R_HPPA_PCREL_CALL_14
;
825 final_type
= base_type
;
833 final_type
= R_HPPA_PCREL_CALL_R17
;
836 final_type
= R_HPPA_PCREL_CALL_RS17
;
839 final_type
= R_HPPA_PCREL_CALL_RD17
;
842 final_type
= R_HPPA_PCREL_CALL_RR17
;
845 final_type
= R_HPPA_PCREL_CALL_17
;
853 final_type
= base_type
;
861 final_type
= R_HPPA_PCREL_CALL_L21
;
864 final_type
= R_HPPA_PCREL_CALL_LS21
;
867 final_type
= R_HPPA_PCREL_CALL_LD21
;
870 final_type
= R_HPPA_PCREL_CALL_LR21
;
879 final_type
= base_type
;
885 final_type
= base_type
;
889 final_type
= base_type
;
900 final_type
= R_HPPA_PLABEL_11
;
903 final_type
= R_HPPA_PLABEL_R11
;
907 final_type
= base_type
;
915 final_type
= R_HPPA_PLABEL_14
;
918 final_type
= R_HPPA_PLABEL_R14
;
922 final_type
= base_type
;
930 final_type
= R_HPPA_PLABEL_L21
;
934 final_type
= base_type
;
942 final_type
= R_HPPA_PLABEL_32
;
946 final_type
= base_type
;
952 final_type
= base_type
;
955 case R_HPPA_ABS_CALL
:
962 final_type
= R_HPPA_ABS_CALL_R11
;
965 final_type
= R_HPPA_ABS_CALL_RS11
;
968 final_type
= R_HPPA_ABS_CALL_RD11
;
971 final_type
= R_HPPA_ABS_CALL_11
;
979 final_type
= base_type
;
985 final_type
= base_type
;
991 final_type
= R_HPPA_ABS_CALL_R14
;
994 final_type
= R_HPPA_ABS_CALL_RS14
;
997 final_type
= R_HPPA_ABS_CALL_RD14
;
1000 final_type
= R_HPPA_ABS_CALL_RR14
;
1003 final_type
= R_HPPA_ABS_CALL_14
;
1011 final_type
= base_type
;
1019 final_type
= R_HPPA_ABS_CALL_R17
;
1022 final_type
= R_HPPA_ABS_CALL_RS17
;
1025 final_type
= R_HPPA_ABS_CALL_RD17
;
1028 final_type
= R_HPPA_ABS_CALL_RR17
;
1031 final_type
= R_HPPA_ABS_CALL_17
;
1039 final_type
= base_type
;
1047 final_type
= R_HPPA_ABS_CALL_L21
;
1050 final_type
= R_HPPA_ABS_CALL_LS21
;
1053 final_type
= R_HPPA_ABS_CALL_LD21
;
1056 final_type
= R_HPPA_ABS_CALL_LR21
;
1065 final_type
= base_type
;
1071 final_type
= base_type
;
1075 final_type
= base_type
;
1080 final_type
= R_HPPA_UNWIND_ENTRY
;
1082 case R_HPPA_COMPLEX
:
1083 case R_HPPA_COMPLEX_PCREL_CALL
:
1084 case R_HPPA_COMPLEX_ABS_CALL
:
1085 final_types
= (elf32_hppa_reloc_type
**) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
*) * 6);
1086 BFD_ASSERT (final_types
!= 0);
1088 finaltype
= (elf32_hppa_reloc_type
*) bfd_alloc_by_size_t (abfd
, sizeof (elf32_hppa_reloc_type
) * 5);
1089 BFD_ASSERT (finaltype
!= 0);
1091 for (i
= 0; i
< 5; i
++)
1092 final_types
[i
] = &finaltype
[i
];
1094 final_types
[5] = NULL
;
1096 finaltype
[0] = R_HPPA_PUSH_SYM
;
1098 if (base_type
== R_HPPA_COMPLEX
)
1099 finaltype
[1] = R_HPPA_PUSH_SYM
;
1100 else if (base_type
== R_HPPA_COMPLEX_PCREL_CALL
)
1101 finaltype
[1] = R_HPPA_PUSH_PCREL_CALL
;
1102 else /* base_type == R_HPPA_COMPLEX_ABS_CALL */
1103 finaltype
[1] = R_HPPA_PUSH_ABS_CALL
;
1105 finaltype
[2] = R_HPPA_SUB
;
1110 finaltype
[3] = R_HPPA_EXPR_F
;
1113 finaltype
[3] = R_HPPA_EXPR_L
;
1116 finaltype
[3] = R_HPPA_EXPR_R
;
1119 finaltype
[3] = R_HPPA_EXPR_LS
;
1122 finaltype
[3] = R_HPPA_EXPR_RS
;
1125 finaltype
[3] = R_HPPA_EXPR_LD
;
1128 finaltype
[3] = R_HPPA_EXPR_RD
;
1131 finaltype
[3] = R_HPPA_EXPR_LR
;
1134 finaltype
[3] = R_HPPA_EXPR_RR
;
1141 finaltype
[4] = R_HPPA_EXPR_11
;
1144 finaltype
[4] = R_HPPA_EXPR_12
;
1147 finaltype
[4] = R_HPPA_EXPR_14
;
1150 finaltype
[4] = R_HPPA_EXPR_17
;
1153 finaltype
[4] = R_HPPA_EXPR_21
;
1156 finaltype
[4] = R_HPPA_EXPR_32
;
1163 final_type
= base_type
;
1173 /* this function is in charge of performing all the HP PA relocations */
1174 static long global_value
;
1175 static long GOT_value
; /* XXX: need to calculate this! For HPUX, GOT == DP */
1176 static asymbol
*global_symbol
;
1177 static int global_sym_defined
;
1179 static bfd_reloc_status_type
1180 DEFUN (hppa_elf_reloc
, (abfd
, reloc_entry
, symbol_in
, data
, input_section
, output_bfd
),
1182 arelent
* reloc_entry AND
1183 asymbol
* symbol_in AND
1185 asection
* input_section AND
1191 unsigned long addr
= reloc_entry
->address
; /*+ input_section->vma*/
1192 bfd_byte
*hit_data
= addr
+ (bfd_byte
*) (data
);
1193 unsigned short r_type
= reloc_entry
->howto
->type
& 0xFF;
1194 unsigned short r_field
= e_fsel
;
1195 boolean r_pcrel
= reloc_entry
->howto
->pc_relative
;
1197 /* howto->bitsize contains the format (11, 14, 21, etc) information */
1198 unsigned r_format
= reloc_entry
->howto
->bitsize
;
1199 long r_addend
= reloc_entry
->addend
;
1204 /* Partial linking - do nothing */
1205 reloc_entry
->address
+= input_section
->output_offset
;
1206 return bfd_reloc_ok
;
1209 if (symbol_in
&& symbol_in
->section
== &bfd_und_section
)
1210 return bfd_reloc_undefined
;
1212 /* Check for stubs that might be required. */
1213 /* symbol_in = hppa_elf_stub_check (abfd, input_section->output_section->owner, reloc_entry); */
1215 sym_value
= get_symbol_value (symbol_in
);
1217 /* compute value of $global$ if it is there. */
1219 if (!global_sym_defined
)
1223 global_value
= (global_symbol
->value
1224 + global_symbol
->section
->output_section
->vma
1225 + global_symbol
->section
->output_offset
);
1226 GOT_value
= global_value
; /* XXX: For HP-UX, GOT==DP */
1227 global_sym_defined
++;
1231 /* get the instruction word */
1232 insn
= bfd_get_32 (abfd
, hit_data
);
1234 /* relocate the value based on the relocation type */
1236 /* basic_type_1: relocation is relative to $global$ */
1237 /* basic_type_2: relocation is relative to the current GOT */
1238 /* basic_type_3: relocation is an absolute call */
1239 /* basic_type_4: relocation is an PC-relative call */
1240 /* basic_type_5: relocation is plabel reference */
1241 /* basic_type_6: relocation is an unwind table relocation */
1242 /* extended_type: unimplemented */
1248 case R_HPPA_32
: /* Symbol + Addend 32 */
1250 goto do_basic_type_1
;
1251 case R_HPPA_11
: /* Symbol + Addend 11 */
1253 goto do_basic_type_1
;
1254 case R_HPPA_14
: /* Symbol + Addend 14 */
1256 goto do_basic_type_1
;
1257 case R_HPPA_17
: /* Symbol + Addend 17 */
1259 goto do_basic_type_1
;
1260 case R_HPPA_L21
: /* L (Symbol, Addend) 21 */
1262 goto do_basic_type_1
;
1263 case R_HPPA_R11
: /* R (Symbol, Addend) 11 */
1265 goto do_basic_type_1
;
1266 case R_HPPA_R14
: /* R (Symbol, Addend) 14 */
1268 goto do_basic_type_1
;
1269 case R_HPPA_R17
: /* R (Symbol, Addend) 17 */
1271 goto do_basic_type_1
;
1272 case R_HPPA_LS21
: /* LS(Symbol, Addend) 21 */
1274 goto do_basic_type_1
;
1275 case R_HPPA_RS11
: /* RS(Symbol, Addend) 11 */
1277 goto do_basic_type_1
;
1278 case R_HPPA_RS14
: /* RS(Symbol, Addend) 14 */
1280 goto do_basic_type_1
;
1281 case R_HPPA_RS17
: /* RS(Symbol, Addend) 17 */
1283 goto do_basic_type_1
;
1284 case R_HPPA_LD21
: /* LD(Symbol, Addend) 21 */
1286 goto do_basic_type_1
;
1287 case R_HPPA_RD11
: /* RD(Symbol, Addend) 11 */
1289 goto do_basic_type_1
;
1290 case R_HPPA_RD14
: /* RD(Symbol, Addend) 14 */
1292 goto do_basic_type_1
;
1293 case R_HPPA_RD17
: /* RD(Symbol, Addend) 17 */
1295 goto do_basic_type_1
;
1296 case R_HPPA_LR21
: /* LR(Symbol, Addend) 21 */
1298 goto do_basic_type_1
;
1299 case R_HPPA_RR14
: /* RR(Symbol, Addend) 14 */
1301 goto do_basic_type_1
;
1302 case R_HPPA_RR17
: /* RR(Symbol, Addend) 17 */
1306 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1307 symbol_in
, sym_value
, r_addend
,
1308 r_type
, r_format
, r_field
, r_pcrel
);
1311 case R_HPPA_GOTOFF_11
: /* Symbol - GOT + Addend 11 */
1313 goto do_basic_type_2
;
1314 case R_HPPA_GOTOFF_14
: /* Symbol - GOT + Addend 14 */
1316 goto do_basic_type_2
;
1317 case R_HPPA_GOTOFF_L21
: /* L (Sym - GOT, Addend) 21 */
1319 goto do_basic_type_2
;
1320 case R_HPPA_GOTOFF_R11
: /* R (Sym - GOT, Addend) 11 */
1322 goto do_basic_type_2
;
1323 case R_HPPA_GOTOFF_R14
: /* R (Sym - GOT, Addend) 14 */
1325 goto do_basic_type_2
;
1326 case R_HPPA_GOTOFF_LS21
: /* LS(Sym - GOT, Addend) 21 */
1328 goto do_basic_type_2
;
1329 case R_HPPA_GOTOFF_RS11
: /* RS(Sym - GOT, Addend) 11 */
1331 goto do_basic_type_2
;
1332 case R_HPPA_GOTOFF_RS14
: /* RS(Sym - GOT, Addend) 14 */
1334 goto do_basic_type_2
;
1335 case R_HPPA_GOTOFF_LD21
: /* LD(Sym - GOT, Addend) 21 */
1337 goto do_basic_type_2
;
1338 case R_HPPA_GOTOFF_RD11
: /* RD(Sym - GOT, Addend) 11 */
1340 goto do_basic_type_2
;
1341 case R_HPPA_GOTOFF_RD14
: /* RD(Sym - GOT, Addend) 14 */
1343 goto do_basic_type_2
;
1344 case R_HPPA_GOTOFF_LR21
: /* LR(Sym - GOT, Addend) 21 */
1346 goto do_basic_type_2
;
1347 case R_HPPA_GOTOFF_RR14
: /* RR(Sym - GOT, Addend) 14 */
1350 sym_value
-= GOT_value
;
1351 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1352 symbol_in
, sym_value
, r_addend
,
1353 r_type
, r_format
, r_field
, r_pcrel
);
1356 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
1358 goto do_basic_type_3
;
1359 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
1361 goto do_basic_type_3
;
1362 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
1364 goto do_basic_type_3
;
1365 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
1367 goto do_basic_type_3
;
1368 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
1370 goto do_basic_type_3
;
1371 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
1373 goto do_basic_type_3
;
1374 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
1376 goto do_basic_type_3
;
1377 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
1379 goto do_basic_type_3
;
1380 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
1382 goto do_basic_type_3
;
1383 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
1385 goto do_basic_type_3
;
1386 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
1388 goto do_basic_type_3
;
1389 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
1391 goto do_basic_type_3
;
1392 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
1394 goto do_basic_type_3
;
1395 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
1397 goto do_basic_type_3
;
1398 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
1400 goto do_basic_type_3
;
1401 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
1403 goto do_basic_type_3
;
1404 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
1406 goto do_basic_type_3
;
1407 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
1410 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1411 symbol_in
, sym_value
, r_addend
,
1412 r_type
, r_format
, r_field
, r_pcrel
);
1415 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
1417 goto do_basic_type_4
;
1418 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
1420 goto do_basic_type_4
;
1421 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
1423 goto do_basic_type_4
;
1424 case R_HPPA_PCREL_CALL_L21
:/* L (Symbol - PC, Addend) 21 */
1426 goto do_basic_type_4
;
1427 case R_HPPA_PCREL_CALL_R11
:/* R (Symbol - PC, Addend) 11 */
1429 goto do_basic_type_4
;
1430 case R_HPPA_PCREL_CALL_R14
:/* R (Symbol - PC, Addend) 14 */
1432 goto do_basic_type_4
;
1433 case R_HPPA_PCREL_CALL_R17
:/* R (Symbol - PC, Addend) 17 */
1435 goto do_basic_type_4
;
1436 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
1438 goto do_basic_type_4
;
1439 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
1441 goto do_basic_type_4
;
1442 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
1444 goto do_basic_type_4
;
1445 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
1447 goto do_basic_type_4
;
1448 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
1450 goto do_basic_type_4
;
1451 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
1453 goto do_basic_type_4
;
1454 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
1456 goto do_basic_type_4
;
1457 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
1459 goto do_basic_type_4
;
1460 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
1462 goto do_basic_type_4
;
1463 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
1465 goto do_basic_type_4
;
1466 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 *//* #69 */
1469 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1470 symbol_in
, sym_value
, r_addend
,
1471 r_type
, r_format
, r_field
, r_pcrel
);
1474 case R_HPPA_PLABEL_32
:
1475 case R_HPPA_PLABEL_11
:
1476 case R_HPPA_PLABEL_14
:
1478 goto do_basic_type_5
;
1479 case R_HPPA_PLABEL_L21
:
1481 goto do_basic_type_5
;
1482 case R_HPPA_PLABEL_R11
:
1483 case R_HPPA_PLABEL_R14
:
1486 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1487 symbol_in
, sym_value
, r_addend
,
1488 r_type
, r_format
, r_field
, r_pcrel
);
1491 case R_HPPA_UNWIND_ENTRY
:
1492 case R_HPPA_UNWIND_ENTRIES
:
1493 hppa_elf_relocate_unwind_table (abfd
, input_section
, data
, addr
,
1494 symbol_in
, sym_value
, r_addend
,
1495 r_type
, r_format
, r_field
, r_pcrel
);
1496 return (bfd_reloc_ok
);
1498 case R_HPPA_PUSH_CONST
: /* push Addend - - */
1499 case R_HPPA_PUSH_PC
: /* push PC + Addend - - */
1500 case R_HPPA_PUSH_SYM
: /* push Symbol + Addend - - */
1501 case R_HPPA_PUSH_GOTOFF
: /* push Symbol - GOT + Addend - - */
1502 case R_HPPA_PUSH_ABS_CALL
: /* push Symbol + Addend - - */
1503 case R_HPPA_PUSH_PCREL_CALL
: /* push Symbol - PC + Addend - - */
1504 case R_HPPA_PUSH_PLABEL
: /* [TBD] - - */
1505 case R_HPPA_MAX
: /* pop A and B, push max(B,A) - - */
1506 case R_HPPA_MIN
: /* pop A and B, push min(B,A) - - */
1507 case R_HPPA_ADD
: /* pop A and B, push B + A - - */
1508 case R_HPPA_SUB
: /* pop A and B, push B - A - - */
1509 case R_HPPA_MULT
: /* pop A and B, push B * A - - */
1510 case R_HPPA_DIV
: /* pop A and B, push B / A - - */
1511 case R_HPPA_MOD
: /* pop A and B, push B % A - - */
1512 case R_HPPA_AND
: /* pop A and B, push B & A - - */
1513 case R_HPPA_OR
: /* pop A and B, push B | A - - */
1514 case R_HPPA_XOR
: /* pop A and B, push B ^ A - - */
1515 case R_HPPA_NOT
: /* pop A, push ~A - - */
1516 case R_HPPA_LSHIFT
: /* pop A, push A << Addend - - */
1517 case R_HPPA_ARITH_RSHIFT
: /* pop A, push A >> Addend - - */
1518 case R_HPPA_LOGIC_RSHIFT
: /* pop A, push A >> Addend - - */
1519 case R_HPPA_EXPR_F
: /* pop A, push A + Addend L - */
1520 case R_HPPA_EXPR_L
: /* pop A, push L(A,Addend) L - */
1521 case R_HPPA_EXPR_R
: /* pop A, push R(A,Addend) R - */
1522 case R_HPPA_EXPR_LS
: /* pop A, push LS(A,Addend) LS - */
1523 case R_HPPA_EXPR_RS
: /* pop A, push RS(A,Addend) RS - */
1524 case R_HPPA_EXPR_LD
: /* pop A, push LD(A,Addend) LD - */
1525 case R_HPPA_EXPR_RD
: /* pop A, push RD(A,Addend) RD - */
1526 case R_HPPA_EXPR_LR
: /* pop A, push LR(A,Addend) LR - */
1527 case R_HPPA_EXPR_RR
: /* pop A, push RR(A,Addend) RR - */
1529 case R_HPPA_EXPR_32
: /* pop - 32 */
1530 case R_HPPA_EXPR_21
: /* pop - 21 */
1531 case R_HPPA_EXPR_11
: /* pop - 11 */
1532 case R_HPPA_EXPR_14
: /* pop - 14 */
1533 case R_HPPA_EXPR_17
: /* pop - 17 */
1534 case R_HPPA_EXPR_12
: /* pop - 12 */
1535 fprintf (stderr
, "Relocation problem: ");
1536 fprintf (stderr
, "Unimplemented reloc type %d, in module %s\n",
1537 r_type
, abfd
->filename
);
1538 return (bfd_reloc_notsupported
);
1539 case R_HPPA_STUB_CALL_17
:
1540 /* yes, a branch to a long branch stub. Change instruction to a BLE */
1543 insn
= BLE_N_XXX_0_0
;
1546 unsigned long old_delay_slot_insn
= bfd_get_32 (abfd
, hit_data
+ 4);
1547 unsigned rtn_reg
= (insn
& 0x03e00000) >> 21;
1549 if (get_opcode(old_delay_slot_insn
) == LDO
)
1551 unsigned ldo_src_reg
= (old_delay_slot_insn
& 0x03e00000) >> 21;
1552 unsigned ldo_target_reg
= (old_delay_slot_insn
& 0x001f0000) >> 16;
1554 if (ldo_target_reg
== rtn_reg
)
1556 unsigned long new_delay_slot_insn
= old_delay_slot_insn
;
1558 BFD_ASSERT(ldo_src_reg
== ldo_target_reg
);
1559 new_delay_slot_insn
&= 0xfc00ffff;
1560 new_delay_slot_insn
|= ((31 << 21) | (31 << 16));
1561 bfd_put_32(abfd
, new_delay_slot_insn
, hit_data
+ 4);
1566 bfd_put_32 (abfd
, insn
, hit_data
);
1567 r_type
= R_HPPA_ABS_CALL_17
;
1569 insn
= hppa_elf_relocate_insn (abfd
, input_section
, insn
, addr
,
1570 symbol_in
, sym_value
, r_addend
,
1571 r_type
, r_format
, r_field
, r_pcrel
);
1575 fprintf (stderr
, "Relocation problem : ");
1576 fprintf (stderr
, "Unrecognized reloc type %d, in module %s\n",
1577 r_type
, abfd
->filename
);
1578 return (bfd_reloc_dangerous
);
1581 /* update the instruction word */
1582 bfd_put_32 (abfd
, insn
, hit_data
);
1584 return (bfd_reloc_ok
);
1588 static reloc_howto_type
*
1589 elf_hppa_reloc_type_lookup (arch
, code
)
1590 bfd_arch_info_type
*arch
;
1591 bfd_reloc_code_real_type code
;
1593 if ((int) code
< (int) R_HPPA_UNIMPLEMENTED
)
1595 BFD_ASSERT ((int) elf_hppa_howto_table
[(int) code
].type
== (int) code
);
1596 return &elf_hppa_howto_table
[(int) code
];
1599 return (reloc_howto_type
*) 0;
1602 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1606 DEFUN (elf_hppa_tc_symbol
, (abfd
, symbolP
, sym_idx
),
1608 elf_symbol_type
* symbolP AND
1611 symext_chainS
*symextP
;
1612 unsigned int arg_reloc
;
1614 /* Only functions can have argument relocations. */
1615 if (!(symbolP
->symbol
.flags
& BSF_FUNCTION
))
1618 arg_reloc
= symbolP
->tc_data
.hppa_arg_reloc
;
1620 /* If there are no argument relocation bits, then no relocation is
1621 necessary. Do not add this to the symextn section. */
1625 symextP
= (symext_chainS
*) bfd_alloc (abfd
, sizeof (symext_chainS
) * 2);
1627 symextP
[0].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, sym_idx
);
1628 symextP
[0].next
= &symextP
[1];
1630 symextP
[1].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC
, arg_reloc
);
1631 symextP
[1].next
= NULL
;
1633 if (symext_rootP
== NULL
)
1635 symext_rootP
= &symextP
[0];
1636 symext_lastP
= &symextP
[1];
1640 symext_lastP
->next
= &symextP
[0];
1641 symext_lastP
= &symextP
[1];
1645 /* Accessor function for the list of symbol extension records. */
1646 symext_chainS
*elf32_hppa_get_symextn_chain()
1648 return symext_rootP
;
1651 static symext_entryS
*symextn_contents
;
1652 static unsigned int symextn_contents_real_size
;
1655 DEFUN (elf_hppa_tc_make_sections
, (abfd
, ignored
),
1659 symext_chainS
*symextP
;
1663 void hppa_elf_stub_finish (); /* forward declaration */
1664 asection
*symextn_sec
;
1666 hppa_elf_stub_finish (abfd
);
1668 if (symext_rootP
== NULL
)
1671 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
1674 size
= sizeof (symext_entryS
) * n
;
1675 symextn_sec
= bfd_get_section_by_name (abfd
, SYMEXTN_SECTION_NAME
);
1676 if (symextn_sec
== (asection
*) 0)
1678 symextn_sec
= bfd_make_section (abfd
, SYMEXTN_SECTION_NAME
);
1679 bfd_set_section_flags (abfd
,
1681 SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
| SEC_CODE
| SEC_READONLY
);
1682 symextn_sec
->output_section
= symextn_sec
;
1683 symextn_sec
->output_offset
= 0;
1684 bfd_set_section_alignment (abfd
, symextn_sec
, 2);
1686 symextn_contents
= (symext_entryS
*) bfd_alloc (abfd
, size
);
1688 for (i
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++i
)
1689 symextn_contents
[i
] = symextP
->entry
;
1690 symextn_contents_real_size
= size
;
1691 bfd_set_section_size (abfd
, symextn_sec
, symextn_contents_real_size
);
1696 /* Support for HP PA-RISC stub generation.
1700 Center for Software Science
1701 Department of Computer Science
1707 HP-PA calling conventions state:
1709 1. an argument relocation stub is required whenever the callee and
1710 caller argument relocation bits do not match exactly. The exception
1711 to this rule is if either the caller or callee argument relocation
1712 bit are 00 (do not relocate).
1714 2. The linker can optionally add a symbol record for the stub so that
1715 the stub can be reused. The symbol record will be the same as the
1716 original export symbol record, except that the relocation bits will
1717 reflect the input of the stub, the type would be STUB and the symbol
1718 value will be the location of the relocation stub.
1722 Stubs can be inserted *before* the section of the caller. The stubs
1723 can be treated as calls to code that manipulates the arguments.
1730 HPPA_STUB_ARG_RELOC
,
1731 HPPA_STUB_LONG_BRANCH
1735 elf32_hppa_get_sym_extn (abfd
, sym
, type
)
1740 /* This function finds the symbol extension record of the */
1741 /* specified type for the specified symbol. It returns the */
1742 /* value of the symbol extension record. */
1743 symext_entryS retval
;
1748 retval
= (symext_entryS
) 0;
1750 case HPPA_SXT_SYMNDX
:
1751 retval
= (symext_entryS
) 0; /* XXX: need to fix this */
1753 case HPPA_SXT_ARG_RELOC
:
1755 elf_symbol_type
*esymP
= (elf_symbol_type
*) sym
;
1757 retval
= (symext_entryS
) esymP
->tc_data
.hppa_arg_reloc
;
1760 /* This should never happen. */
1767 typedef struct elf32_hppa_stub_name_list_struct
1769 /* name of this stub */
1771 /* stub description for this stub */
1772 struct elf32_hppa_stub_description_struct
*stub_desc
;
1773 /* pointer into stub contents */
1775 /* size of this stub */
1777 /* next stub name entry */
1778 struct elf32_hppa_stub_name_list_struct
*next
;
1779 } elf32_hppa_stub_name_list
;
1781 typedef struct elf32_hppa_stub_description_struct
1783 struct elf32_hppa_stub_description_struct
*next
;
1784 bfd
*this_bfd
; /* bfd to which this stub applies */
1785 asection
*stub_sec
; /* stub section for this bfd */
1786 unsigned relocs_allocated_cnt
; /* count of relocations for this stub section */
1788 unsigned allocated_size
;
1789 int *stub_secp
; /* pointer to the next available location in the buffer */
1790 char *stub_contents
; /* contents of the stubs for this bfd */
1791 elf32_hppa_stub_name_list
*stub_listP
;
1793 elf32_hppa_stub_description
;
1795 static elf32_hppa_stub_description
*elf_hppa_stub_rootP
;
1797 /* Locate the stub section information for the given bfd. */
1798 static elf32_hppa_stub_description
*
1799 find_stubs (abfd
, stub_sec
)
1803 elf32_hppa_stub_description
*stubP
;
1805 for (stubP
= elf_hppa_stub_rootP
; stubP
; stubP
= stubP
->next
)
1807 if (stubP
->this_bfd
== abfd
1808 && stubP
->stub_sec
== stub_sec
)
1812 return (elf32_hppa_stub_description
*) NULL
;
1815 static elf32_hppa_stub_description
*
1816 new_stub (abfd
, stub_sec
)
1820 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1825 stub
= (elf32_hppa_stub_description
*) bfd_zalloc (abfd
, sizeof (elf32_hppa_stub_description
));
1828 stub
->this_bfd
= abfd
;
1829 stub
->stub_sec
= stub_sec
;
1830 stub
->real_size
= 0;
1831 stub
->allocated_size
= 0;
1832 stub
->stub_contents
= NULL
;
1833 stub
->stub_secp
= NULL
;
1835 stub
->next
= elf_hppa_stub_rootP
;
1836 elf_hppa_stub_rootP
= stub
;
1840 bfd_error
= no_memory
;
1841 bfd_perror ("new_stub");
1847 /* Locate the stub by the given name. */
1848 static elf32_hppa_stub_name_list
*
1849 find_stub_by_name (abfd
, stub_sec
, name
)
1854 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1858 elf32_hppa_stub_name_list
*name_listP
;
1860 for (name_listP
= stub
->stub_listP
; name_listP
; name_listP
= name_listP
->next
)
1862 if (!strcmp (name_listP
->sym
->name
, name
))
1870 /* Locate the stub by the given name. */
1871 static elf32_hppa_stub_name_list
*
1872 add_stub_by_name(abfd
, stub_sec
, sym
)
1877 elf32_hppa_stub_description
*stub
= find_stubs (abfd
, stub_sec
);
1878 elf32_hppa_stub_name_list
*stub_entry
;
1881 stub
= new_stub(abfd
, stub_sec
);
1885 stub_entry
= (elf32_hppa_stub_name_list
*)
1886 bfd_zalloc (abfd
, sizeof (elf32_hppa_stub_name_list
));
1890 stub_entry
->size
= 0;
1891 stub_entry
->sym
= sym
;
1892 stub_entry
->stub_desc
= stub
;
1893 /* First byte of this stub is the pointer to
1894 the next available location in the stub buffer. */
1895 stub_entry
->stub_secp
= stub
->stub_secp
;
1896 if (stub
->stub_listP
)
1897 stub_entry
->next
= stub
->stub_listP
;
1899 stub_entry
->next
= NULL
;
1900 stub
->stub_listP
= stub_entry
;
1905 bfd_error
= no_memory
;
1906 bfd_perror("add_stub_by_name");
1910 return (elf32_hppa_stub_name_list
*)NULL
;
1914 #define RETURN_VALUE 1
1916 #define NO_ARG_RELOC 0
1923 #define ARG_RELOC_ERR 7
1935 /* FP register in arg0/arg1. This value can only appear in the arg0 location. */
1937 /* FP register in arg2/arg3. This value can only appear in the arg2 location. */
1940 #define AR_WARN(type,loc) \
1941 fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \
1942 reloc_type_strings[type],reloc_loc_strings[loc])
1944 static CONST
char *CONST reloc_type_strings
[] =
1946 "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
1949 static CONST
char *CONST reloc_loc_strings
[] =
1951 "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
1954 static CONST
char mismatches
[6][6] =
1955 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
1957 {NO_ARG_RELOC
, NO_ARG_RELOC
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, NO_ARG_RELOC
},
1959 {NO_ARG_RELOC
, NO_ARG_RELOC
, R_TO_FR
, ARG_RELOC_ERR
, R01_TO_FR
, ARG_RELOC_ERR
},
1961 {NO_ARG_RELOC
, FR_TO_R
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
1963 {ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
1965 {NO_ARG_RELOC
, FR_TO_R01
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, ARG_RELOC_ERR
},
1967 {NO_ARG_RELOC
, FR_TO_R23
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, NO_ARG_RELOC
},
1970 static CONST
char retval_mismatches
[6][6] =
1971 { /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */
1973 {NO_ARG_RELOC
, NO_ARG_RELOC
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, NO_ARG_RELOC
},
1975 {NO_ARG_RELOC
, NO_ARG_RELOC
, FR_TO_R
, ARG_RELOC_ERR
, FR_TO_R01
, ARG_RELOC_ERR
},
1977 {NO_ARG_RELOC
, R_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
1979 {ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, ARG_RELOC_ERR
},
1981 {NO_ARG_RELOC
, R01_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, NO_ARG_RELOC
, ARG_RELOC_ERR
},
1983 {NO_ARG_RELOC
, R23_TO_FR
, NO_ARG_RELOC
, ARG_RELOC_ERR
, ARG_RELOC_ERR
, NO_ARG_RELOC
},
1987 type_of_mismatch (caller_bits
, callee_bits
, type
)
1995 return mismatches
[caller_bits
][callee_bits
];
1997 return retval_mismatches
[caller_bits
][callee_bits
];
2003 #define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3
2005 #define NEW_INSTRUCTION(entry,insn) \
2006 *((entry)->stub_desc->stub_secp)++ = (insn); \
2007 (entry)->stub_desc->real_size += sizeof(int); \
2008 (entry)->size += sizeof(int); \
2009 bfd_set_section_size((entry)->stub_desc->this_bfd, \
2010 (entry)->stub_desc->stub_sec, \
2011 (entry)->stub_desc->real_size);
2013 #define CURRENT_STUB_OFFSET(entry) \
2014 ((int)(entry)->stub_desc->stub_secp - (int)(entry)->stub_desc->stub_contents - 4)
2016 static boolean stubs_finished
= false;
2019 hppa_elf_stub_finish (output_bfd
)
2022 extern bfd_error_vector_type bfd_error_vector
;
2023 elf32_hppa_stub_description
*stub_list
= elf_hppa_stub_rootP
;
2024 /* All the stubs have been built. Finish up building */
2025 /* stub section. Apply relocations to the section. */
2027 if ( stubs_finished
)
2030 for (; stub_list
; stub_list
= stub_list
->next
)
2032 if (stub_list
->real_size
)
2034 bfd
*stub_bfd
= stub_list
->this_bfd
;
2035 asection
*stub_sec
= bfd_get_section_by_name (stub_bfd
, ".hppa_linker_stubs");
2036 bfd_size_type reloc_size
;
2037 arelent
**reloc_vector
;
2039 BFD_ASSERT (stub_sec
== stub_list
->stub_sec
);
2040 reloc_size
= bfd_get_reloc_upper_bound (stub_bfd
, stub_sec
);
2041 reloc_vector
= (arelent
**) alloca (reloc_size
);
2043 BFD_ASSERT (stub_sec
);
2045 /* We are not relaxing the section, so just copy the size info */
2046 stub_sec
->_cooked_size
= stub_sec
->_raw_size
;
2047 stub_sec
->reloc_done
= true;
2050 if (bfd_canonicalize_reloc (stub_bfd
,
2053 output_bfd
->outsymbols
))
2056 for (parent
= reloc_vector
; *parent
!= (arelent
*) NULL
;
2059 bfd_reloc_status_type r
=
2060 bfd_perform_relocation (stub_bfd
,
2062 stub_list
->stub_contents
,
2066 if (r
!= bfd_reloc_ok
)
2070 case bfd_reloc_undefined
:
2071 bfd_error_vector
.undefined_symbol (*parent
, NULL
);
2073 case bfd_reloc_dangerous
:
2074 bfd_error_vector
.reloc_dangerous (*parent
, NULL
);
2076 case bfd_reloc_outofrange
:
2077 case bfd_reloc_overflow
:
2078 bfd_error_vector
.reloc_value_truncated (*parent
, NULL
);
2088 bfd_set_section_contents (output_bfd
,
2090 stub_list
->stub_contents
,
2092 stub_list
->real_size
);
2094 free (reloc_vector
);
2097 stubs_finished
= true;
2101 hppa_elf_stub_branch_reloc (stub_desc
, /* the bfd */
2102 output_bfd
, /* the output bfd */
2103 target_sym
, /* the target symbol */
2104 offset
) /* the offset within the stub buffer (pre-calculated) */
2105 elf32_hppa_stub_description
*stub_desc
;
2107 asymbol
*target_sym
;
2110 /* Allocate a new relocation entry. */
2114 if (stub_desc
->relocs_allocated_cnt
== stub_desc
->stub_sec
->reloc_count
)
2116 if (stub_desc
->stub_sec
->relocation
== NULL
)
2118 stub_desc
->relocs_allocated_cnt
= STUB_RELOC_INCR
;
2119 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2120 stub_desc
->stub_sec
->relocation
= (arelent
*) zalloc (size
);
2124 stub_desc
->relocs_allocated_cnt
+= STUB_RELOC_INCR
;
2125 size
= sizeof (arelent
) * stub_desc
->relocs_allocated_cnt
;
2126 stub_desc
->stub_sec
->relocation
= (arelent
*) realloc (stub_desc
->stub_sec
->relocation
,
2131 /* Fill in the details. */
2132 relent
.address
= offset
;
2134 relent
.sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2135 BFD_ASSERT (relent
.sym_ptr_ptr
);
2137 relent
.sym_ptr_ptr
[0] = target_sym
;
2138 relent
.howto
= bfd_reloc_type_lookup (stub_desc
->this_bfd
, R_HPPA_PCREL_CALL_17
);
2140 /* Save it in the array of relocations for the stub section. */
2142 memcpy (&stub_desc
->stub_sec
->relocation
[stub_desc
->stub_sec
->reloc_count
++],
2148 hppa_elf_stub_reloc (stub_desc
, /* the bfd */
2149 output_bfd
, /* the output bfd */
2150 target_sym
, /* the target symbol */
2151 offset
, /* the offset within the stub buffer (pre-calculated) */
2153 elf32_hppa_stub_description
*stub_desc
;
2155 asymbol
*target_sym
;
2157 elf32_hppa_reloc_type type
;
2159 /* Allocate a new relocation entry. */
2162 Elf_Internal_Shdr
*rela_hdr
;
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 rela_hdr
= &elf_section_data(stub_desc
->stub_sec
)->rel_hdr
;
2182 rela_hdr
->sh_size
+= sizeof(Elf32_External_Rela
);
2184 /* Fill in the details. */
2185 relent
.address
= offset
;
2187 relent
.sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2188 BFD_ASSERT (relent
.sym_ptr_ptr
);
2190 relent
.sym_ptr_ptr
[0] = target_sym
;
2191 relent
.howto
= bfd_reloc_type_lookup (stub_desc
->this_bfd
, type
);
2193 /* Save it in the array of relocations for the stub section. */
2195 memcpy (&stub_desc
->stub_sec
->relocation
[stub_desc
->stub_sec
->reloc_count
++],
2201 hppa_elf_build_arg_reloc_stub (abfd
, output_bfd
, reloc_entry
, stub_types
)
2204 arelent
*reloc_entry
;
2207 asection
*stub_sec
= bfd_get_section_by_name (abfd
, ".hppa_linker_stubs");
2208 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, stub_sec
);
2209 asymbol
*stub_sym
= NULL
;
2210 asymbol
*target_sym
= reloc_entry
->sym_ptr_ptr
[0];
2211 asection
*output_text_section
= bfd_get_section_by_name (output_bfd
, ".text");
2213 char stub_sym_name
[128];
2214 elf32_hppa_stub_name_list
*stub_entry
;
2218 BFD_ASSERT (stub_desc
== NULL
);
2219 stub_sec
= bfd_make_section (abfd
, ".hppa_linker_stubs");
2220 bfd_set_section_flags (abfd
,
2222 SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_CODE
| SEC_READONLY
);
2223 stub_sec
->output_section
= output_text_section
->output_section
;
2224 stub_sec
->output_offset
= 0;
2225 bfd_set_section_alignment (abfd
, stub_sec
, 2);
2226 stub_desc
= new_stub (abfd
, stub_sec
);
2229 /* make sure we have a stub descriptor structure */
2232 stub_desc
= new_stub (abfd
, stub_sec
);
2234 /* allocate some space to write the stub */
2236 if (!stub_desc
->stub_contents
)
2238 stub_desc
->allocated_size
= STUB_BUFFER_INCR
;
2239 stub_desc
->stub_contents
= (char *) xmalloc (STUB_BUFFER_INCR
);
2241 else if ((stub_desc
->allocated_size
- stub_desc
->real_size
) < STUB_MAX_SIZE
)
2243 stub_desc
->allocated_size
= stub_desc
->allocated_size
+ STUB_BUFFER_INCR
;
2244 stub_desc
->stub_contents
= (char *) xrealloc (stub_desc
->stub_contents
,
2245 stub_desc
->allocated_size
);
2248 stub_desc
->stub_secp
= (int *) (stub_desc
->stub_contents
+ stub_desc
->real_size
);
2250 sprintf (stub_sym_name
,
2251 "_stub_%s_%02d_%02d_%02d_%02d_%02d",
2252 reloc_entry
->sym_ptr_ptr
[0]->name
,
2253 stub_types
[0], stub_types
[1], stub_types
[2], stub_types
[3], stub_types
[4]);
2254 stub_entry
= find_stub_by_name(abfd
, stub_sec
, stub_sym_name
);
2258 stub_sym
= stub_entry
->sym
;
2259 /* redirect the original relocation from the old symbol (a function) */
2260 /* to the stub (the stub calls the function). */
2261 /* XXX do we need to change the relocation type? */
2262 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2263 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2267 /* Stub does not already exist. Create a new stub. */
2268 /* Create a new symbol to point to this stub */
2269 stub_sym
= bfd_make_empty_symbol (abfd
);
2270 stub_sym
->name
= bfd_zalloc (abfd
, strlen (stub_sym_name
) + 1);
2271 strcpy ((char *) stub_sym
->name
, stub_sym_name
);
2272 stub_sym
->value
= (int) stub_desc
->stub_secp
- (int) stub_desc
->stub_contents
;
2273 stub_sym
->section
= stub_sec
;
2274 stub_sym
->flags
= BSF_LOCAL
| BSF_FUNCTION
;
2275 stub_entry
= add_stub_by_name(abfd
, stub_sec
, stub_sym
);
2277 /* redirect the original relocation from the old symbol (a function) */
2278 /* to the stub (the stub calls the function). */
2279 /* XXX do we need to change the relocation type? */
2280 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2281 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2283 /* generate the beginning common section for all stubs */
2285 NEW_INSTRUCTION (stub_entry
, ADDI_8_SP
);
2287 /* generate the code to move the arguments around */
2288 for (i
= ARG0
; i
< ARG3
; i
++)
2290 if (stub_types
[i
] != NO_ARG_RELOC
)
2292 /* A stub is needed */
2293 switch (stub_types
[i
])
2299 NEW_INSTRUCTION (stub_entry
, STWS_ARG0_M8SP
);
2300 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG0
);
2303 NEW_INSTRUCTION (stub_entry
, STWS_ARG1_M8SP
);
2304 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG1
);
2307 NEW_INSTRUCTION (stub_entry
, STWS_ARG2_M8SP
);
2308 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG2
);
2311 NEW_INSTRUCTION (stub_entry
, STWS_ARG3_M8SP
);
2312 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FARG3
);
2321 NEW_INSTRUCTION(stub_entry
, STWS_ARG0_M4SP
);
2322 NEW_INSTRUCTION(stub_entry
, STWS_ARG1_M8SP
);
2323 NEW_INSTRUCTION(stub_entry
, FLDDS_M8SP_FARG1
);
2326 AR_WARN(stub_types
[i
],i
);
2335 NEW_INSTRUCTION(stub_entry
, STWS_ARG2_M4SP
);
2336 NEW_INSTRUCTION(stub_entry
, STWS_ARG3_M8SP
);
2337 NEW_INSTRUCTION(stub_entry
, FLDDS_M8SP_FARG3
);
2340 AR_WARN(stub_types
[i
],i
);
2349 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG0_M8SP
);
2350 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG0
);
2353 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG1_M8SP
);
2354 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG1
);
2357 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG2_M8SP
);
2358 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG2
);
2361 NEW_INSTRUCTION (stub_entry
, FSTWS_FARG3_M8SP
);
2362 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_ARG3
);
2371 NEW_INSTRUCTION(stub_entry
, FSTDS_FARG1_M8SP
);
2372 NEW_INSTRUCTION(stub_entry
, LDWS_M4SP_ARG0
);
2373 NEW_INSTRUCTION(stub_entry
, LDWS_M8SP_ARG1
);
2376 AR_WARN(stub_types
[i
],i
);
2385 NEW_INSTRUCTION(stub_entry
, FSTDS_FARG3_M8SP
);
2386 NEW_INSTRUCTION(stub_entry
, LDWS_M4SP_ARG2
);
2387 NEW_INSTRUCTION(stub_entry
, LDWS_M8SP_ARG3
);
2390 AR_WARN(stub_types
[i
],i
);
2399 NEW_INSTRUCTION (stub_entry
, ADDI_M8_SP
);
2401 /* generate the branch to the target routine */
2402 NEW_INSTRUCTION (stub_entry
, STW_RP_M8SP
); /* First, save the return address */
2404 /* Branch to the target function. */
2405 /* (Make it a long call, so we do not */
2406 /* have to worry about generating a */
2407 /* long call stub.) */
2408 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_31
);
2409 hppa_elf_stub_reloc (stub_entry
->stub_desc
,
2410 abfd
, /* the output bfd */
2411 target_sym
, /* the target symbol */
2412 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2414 NEW_INSTRUCTION(stub_entry
,BLE_XXX_0_31
);
2415 hppa_elf_stub_reloc (stub_entry
->stub_desc
,
2416 abfd
, /* the output bfd */
2417 target_sym
, /* the target symbol */
2418 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2419 R_HPPA_ABS_CALL_R17
);
2420 NEW_INSTRUCTION(stub_entry
,COPY_31_2
);
2422 /* generate the code to move the return value around */
2424 NEW_INSTRUCTION (stub_entry
, LDW_M8SP_RP
); /* restore return address */
2427 if (stub_types
[i
] != NO_ARG_RELOC
)
2429 /* A stub is needed */
2430 switch (stub_types
[i
])
2433 NEW_INSTRUCTION (stub_entry
, STWS_RET0_M8SP
);
2434 NEW_INSTRUCTION (stub_entry
, FLDWS_M8SP_FRET0
);
2438 NEW_INSTRUCTION (stub_entry
, FSTWS_FRET0_M8SP
);
2439 NEW_INSTRUCTION (stub_entry
, LDWS_M4SP_RET0
);
2444 /* generate the ending common section for all stubs */
2446 /* XXX: can we assume this is a save return? */
2447 NEW_INSTRUCTION (stub_entry
, BV_N_0_RP
);
2454 hppa_elf_arg_reloc_needed_p (abfd
, reloc_entry
, stub_types
, caller_ar
)
2456 arelent
*reloc_entry
;
2458 symext_entryS caller_ar
;
2460 /* If the symbol is still undefined, there is */
2461 /* no way to know if a stub is required. */
2463 if (reloc_entry
->sym_ptr_ptr
[0] && reloc_entry
->sym_ptr_ptr
[0]->section
!= &bfd_und_section
)
2465 symext_entryS callee_ar
= elf32_hppa_get_sym_extn (abfd
,
2466 reloc_entry
->sym_ptr_ptr
[0],
2467 HPPA_SXT_ARG_RELOC
);
2469 /* Now, determine if a stub is */
2470 /* required. A stub is required if they the callee and caller */
2471 /* argument relocation bits are both nonzero and not equal. */
2473 if (caller_ar
&& callee_ar
)
2475 /* Both are non-zero, we need to do further checking. */
2476 /* First, check if there is a return value relocation to be done */
2480 callee_loc
[RETVAL
] = EXTRACT_ARBITS (callee_ar
, RETVAL
);
2481 caller_loc
[RETVAL
] = EXTRACT_ARBITS (caller_ar
, RETVAL
);
2482 callee_loc
[ARG0
] = EXTRACT_ARBITS (callee_ar
, ARG0
);
2483 caller_loc
[ARG0
] = EXTRACT_ARBITS (caller_ar
, ARG0
);
2484 callee_loc
[ARG1
] = EXTRACT_ARBITS (callee_ar
, ARG1
);
2485 caller_loc
[ARG1
] = EXTRACT_ARBITS (caller_ar
, ARG1
);
2486 callee_loc
[ARG2
] = EXTRACT_ARBITS (callee_ar
, ARG2
);
2487 caller_loc
[ARG2
] = EXTRACT_ARBITS (caller_ar
, ARG2
);
2488 callee_loc
[ARG3
] = EXTRACT_ARBITS (callee_ar
, ARG3
);
2489 caller_loc
[ARG3
] = EXTRACT_ARBITS (caller_ar
, ARG3
);
2491 /* Check some special combinations. For */
2492 /* example, if FU appears in ARG1 or ARG3, we */
2493 /* can move it to ARG0 or ARG2, respectively. */
2495 if (caller_loc
[ARG0
] == AR_FU
|| caller_loc
[ARG1
] == AR_FU
)
2497 caller_loc
[ARG0
] = AR_DBL01
;
2498 caller_loc
[ARG1
] = AR_NO
;
2500 if (caller_loc
[ARG2
] == AR_FU
|| caller_loc
[ARG3
] == AR_FU
)
2502 caller_loc
[ARG2
] = AR_DBL23
;
2503 caller_loc
[ARG3
] = AR_NO
;
2505 if (callee_loc
[ARG0
] == AR_FU
|| callee_loc
[ARG1
] == AR_FU
)
2507 callee_loc
[ARG0
] = AR_DBL01
;
2508 callee_loc
[ARG1
] = AR_NO
;
2510 if (callee_loc
[ARG2
] == AR_FU
|| callee_loc
[ARG3
] == AR_FU
)
2512 callee_loc
[ARG2
] = AR_DBL23
;
2513 callee_loc
[ARG3
] = AR_NO
;
2516 stub_types
[ARG0
] = type_of_mismatch (caller_loc
[ARG0
], callee_loc
[ARG0
], ARGUMENTS
);
2517 stub_types
[ARG1
] = type_of_mismatch (caller_loc
[ARG1
], callee_loc
[ARG1
], ARGUMENTS
);
2518 stub_types
[ARG2
] = type_of_mismatch (caller_loc
[ARG2
], callee_loc
[ARG2
], ARGUMENTS
);
2519 stub_types
[ARG3
] = type_of_mismatch (caller_loc
[ARG3
], callee_loc
[ARG3
], ARGUMENTS
);
2520 stub_types
[RETVAL
] = type_of_mismatch (caller_loc
[RETVAL
], callee_loc
[RETVAL
], RETURN_VALUE
);
2522 /* Steps involved in building stubs: */
2523 /* 1. Determine what argument registers need to relocated. This */
2524 /* step is already done here. */
2525 /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2526 /* This section should never appear in an object file. It is */
2527 /* only used internally. The output_section of the */
2528 /* .hppa_linker_stubs section is the .text section of the */
2530 /* 3. Build a symbol that is used (internally only) as the entry */
2531 /* point of the stub. */
2532 /* 4. Change the instruction of the original branch into a branch to */
2533 /* the stub routine. */
2534 /* 5. Build a relocation entry for the instruction of the original */
2535 /* branch to be R_HPPA_PCREL_CALL to the stub routine. */
2547 fprintf (stderr
, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2548 reloc_entry
->sym_ptr_ptr
[0]->name
,
2549 abfd
->filename
, reloc_entry
->address
,
2550 callee_ar
, caller_ar
);
2551 for (i
= ARG0
; i
< RETVAL
; i
++)
2553 if (stub_types
[i
] != NO_ARG_RELOC
)
2555 fprintf (stderr
, "%s%d: %s ",
2556 i
== RETVAL
? "ret" : "arg",
2557 i
== RETVAL
? 0 : i
,
2558 reloc_type_strings
[stub_types
[i
]]);
2561 fprintf (stderr
, "\n");
2572 hppa_elf_build_long_branch_stub (abfd
, output_bfd
, reloc_entry
, symbol
, data
)
2575 arelent
*reloc_entry
;
2579 asection
*stub_sec
= bfd_get_section_by_name (abfd
, ".hppa_linker_stubs");
2580 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, stub_sec
);
2581 asymbol
*stub_sym
= NULL
;
2582 asymbol
*target_sym
= reloc_entry
->sym_ptr_ptr
[0];
2583 asection
*output_text_section
= bfd_get_section_by_name (output_bfd
, ".text");
2584 char stub_sym_name
[128];
2586 int dyncall
= false;
2587 elf32_hppa_stub_name_list
*stub_entry
;
2591 BFD_ASSERT (stub_desc
== NULL
);
2592 stub_sec
= bfd_make_section (abfd
, ".hppa_linker_stubs");
2593 bfd_set_section_flags (abfd
,
2595 SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_CODE
| SEC_READONLY
);
2596 stub_sec
->output_section
= output_text_section
->output_section
;
2597 stub_sec
->output_offset
= 0;
2598 /* set up the ELF section header for this new section. */
2599 /* This is basically the same processing as elf_make_sections() */
2600 /* (elf_make_sections() is static so it is not accessible from */
2604 Elf_Internal_Shdr
*this_hdr
;
2605 this_hdr
= &elf_section_data (stub_sec
)->this_hdr
;
2607 this_hdr
->sh_addr
= stub_sec
->vma
;
2608 this_hdr
->sh_size
= stub_sec
->_raw_size
;
2609 /* contents already set by elf_set_section_contents */
2611 if (stub_sec
->flags
& SEC_RELOC
)
2613 /* emit a reloc section, and thus strtab and symtab... */
2614 Elf_Internal_Shdr
*rela_hdr
;
2615 int use_rela_p
= get_elf_backend_data (abfd
)->use_rela_p
;
2617 rela_hdr
= &elf_section_data (stub_sec
)->rel_hdr
;
2619 /* orelocation has the data, reloc_count has the count... */
2622 rela_hdr
->sh_type
= SHT_RELA
;
2623 rela_hdr
->sh_entsize
= sizeof (Elf32_External_Rela
);
2626 /* REL relocations */
2628 rela_hdr
->sh_type
= SHT_REL
;
2629 rela_hdr
->sh_entsize
= sizeof (Elf32_External_Rel
);
2631 rela_hdr
->sh_flags
= 0;
2632 rela_hdr
->sh_addr
= 0;
2633 rela_hdr
->sh_offset
= 0;
2634 rela_hdr
->sh_addralign
= 0;
2637 if (stub_sec
->flags
& SEC_ALLOC
)
2639 this_hdr
->sh_flags
|= SHF_ALLOC
;
2640 if (stub_sec
->flags
& SEC_LOAD
)
2642 /* @@ Do something with sh_type? */
2645 if (!(stub_sec
->flags
& SEC_READONLY
))
2646 this_hdr
->sh_flags
|= SHF_WRITE
;
2648 if (stub_sec
->flags
& SEC_CODE
)
2649 this_hdr
->sh_flags
|= SHF_EXECINSTR
;
2652 bfd_set_section_alignment (abfd
, stub_sec
, 2);
2653 stub_desc
= new_stub (abfd
, stub_sec
);
2657 stub_desc
= new_stub (abfd
, stub_sec
);
2659 /* allocate some space to write the stub */
2661 if (!stub_desc
->stub_contents
)
2663 stub_desc
->allocated_size
= STUB_BUFFER_INCR
;
2664 stub_desc
->stub_contents
= (char *) malloc (STUB_BUFFER_INCR
);
2666 else if ((stub_desc
->allocated_size
- stub_desc
->real_size
) < STUB_MAX_SIZE
)
2668 stub_desc
->allocated_size
= stub_desc
->allocated_size
+ STUB_BUFFER_INCR
;
2669 stub_desc
->stub_contents
= (char *) realloc (stub_desc
->stub_contents
,
2670 stub_desc
->allocated_size
);
2673 stub_desc
->stub_secp
= (int *) (stub_desc
->stub_contents
+ stub_desc
->real_size
);
2675 sprintf (stub_sym_name
,
2676 "_lb_stub_%s", reloc_entry
->sym_ptr_ptr
[0]->name
);
2677 stub_entry
= find_stub_by_name(abfd
, stub_sec
, stub_sym_name
);
2681 stub_sym
= stub_entry
->sym
;
2682 /* redirect the original relocation from the old symbol (a function) */
2683 /* to the stub (the stub calls the function). */
2684 /* XXX do we need to change the relocation type? */
2685 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2686 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2687 reloc_entry
->howto
= bfd_reloc_type_lookup (abfd
, R_HPPA_STUB_CALL_17
);
2691 /* Stub does not already exist. Create a new stub. */
2692 /* create a symbol to point to this stub */
2693 stub_sym
= bfd_make_empty_symbol (abfd
);
2694 stub_sym
->name
= bfd_zalloc (abfd
, strlen (stub_sym_name
) + 1);
2695 strcpy ((char *) stub_sym
->name
, stub_sym_name
);
2696 stub_sym
->value
= (int) stub_desc
->stub_secp
- (int) stub_desc
->stub_contents
;
2697 stub_sym
->section
= stub_sec
;
2698 stub_sym
->flags
= BSF_LOCAL
| BSF_FUNCTION
;
2699 stub_entry
= add_stub_by_name(abfd
, stub_sec
, stub_sym
);
2701 /* redirect the original relocation from the old symbol (a function) */
2702 /* to the stub (the stub calls the function). */
2703 /* XXX do we need to change the relocation type? */
2704 reloc_entry
->sym_ptr_ptr
= (asymbol
**) bfd_zalloc (stub_desc
->this_bfd
, sizeof (asymbol
*));
2705 reloc_entry
->sym_ptr_ptr
[0] = stub_sym
;
2706 reloc_entry
->howto
= bfd_reloc_type_lookup (abfd
, R_HPPA_STUB_CALL_17
);
2708 /* Build the stub */
2710 /* A millicode call? */
2711 /* If so, the return address comes in on r31 rather than r2 (rp) so a */
2712 /* slightly different code sequence is needed. */
2713 if ( ((*data
& 0x03e00000) >> 21) == 31 )
2716 if ( strcmp(symbol
->name
,"$$dyncall") == 0 )
2719 /* 1. initialization for the call. */
2721 NEW_INSTRUCTION(stub_entry
, LDSID_31_1
);
2722 NEW_INSTRUCTION(stub_entry
, MTSP_1_SR0
);
2728 NEW_INSTRUCTION(stub_entry
, COPY_31_2
);
2732 NEW_INSTRUCTION(stub_entry
, COPY_31_1
);
2735 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_31
);
2736 hppa_elf_stub_reloc (stub_desc
,
2737 abfd
, /* the output bfd */
2738 target_sym
, /* the target symbol */
2739 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2742 /* 2. Make the call. */
2746 NEW_INSTRUCTION(stub_entry
,BE_N_XXX_0_31
);
2747 hppa_elf_stub_reloc (stub_desc
,
2748 abfd
, /* the output bfd */
2749 target_sym
, /* the target symbol */
2750 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2751 R_HPPA_ABS_CALL_R17
);
2755 NEW_INSTRUCTION(stub_entry
,BE_XXX_0_31
);
2756 hppa_elf_stub_reloc (stub_desc
,
2757 abfd
, /* the output bfd */
2758 target_sym
, /* the target symbol */
2759 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2760 R_HPPA_ABS_CALL_R17
);
2761 NEW_INSTRUCTION(stub_entry
, COPY_1_31
);
2763 /* 3. Branch back to the original location. */
2764 /* (for non-millicode calls, accomplished with the COPY_31_2 instruction) */
2765 /* (for millicode calls, return location is already in r2) */
2769 NEW_INSTRUCTION(stub_entry
, LDIL_XXX_31
);
2770 hppa_elf_stub_reloc (stub_desc
,
2771 abfd
, /* the output bfd */
2772 target_sym
, /* the target symbol */
2773 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2776 NEW_INSTRUCTION(stub_entry
,BE_N_XXX_0_31
);
2777 hppa_elf_stub_reloc (stub_desc
,
2778 abfd
, /* the output bfd */
2779 target_sym
, /* the target symbol */
2780 CURRENT_STUB_OFFSET(stub_entry
), /* offset in stub buffer */
2781 R_HPPA_ABS_CALL_R17
);
2789 hppa_elf_long_branch_needed_p (abfd
, asec
, reloc_entry
, symbol
, insn
)
2792 arelent
*reloc_entry
;
2796 long sym_value
= get_symbol_value(symbol
);
2797 int fmt
= reloc_entry
->howto
->bitsize
;
2798 unsigned char op
= get_opcode(insn
);
2801 #define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
2807 reloc_entry
->address
+ asec
->output_offset
+ asec
->output_section
->vma
;
2808 if ( too_far(sym_value
- raddr
,fmt
+1) )
2811 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
);
2821 hppa_elf_stub_check (abfd
, output_bfd
, input_section
, reloc_entry
, symbol
, hit_data
)
2824 asection
*input_section
;
2825 arelent
*reloc_entry
;
2831 switch (reloc_entry
->howto
->type
)
2833 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
2834 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
2835 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
2836 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
2837 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
2838 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
2839 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
2840 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
2841 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
2842 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
2843 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
2844 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
2845 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
2846 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
2847 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
2848 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
2849 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
2850 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
2852 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
2853 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
2854 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
2855 case R_HPPA_PCREL_CALL_12
: /* Symbol - PC + Addend 12 */
2856 case R_HPPA_PCREL_CALL_L21
: /* L (Symbol - PC, Addend) 21 */
2857 case R_HPPA_PCREL_CALL_R11
: /* R (Symbol - PC, Addend) 11 */
2858 case R_HPPA_PCREL_CALL_R14
: /* R (Symbol - PC, Addend) 14 */
2859 case R_HPPA_PCREL_CALL_R17
: /* R (Symbol - PC, Addend) 17 */
2860 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
2861 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
2862 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
2863 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
2864 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
2865 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
2866 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
2867 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
2868 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
2869 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
2870 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 */
2872 symext_entryS caller_ar
= (symext_entryS
) HPPA_R_ARG_RELOC (reloc_entry
->addend
);
2873 if (hppa_elf_arg_reloc_needed_p (abfd
, reloc_entry
, stub_types
, caller_ar
))
2875 /* generate a stub */
2876 return hppa_elf_build_arg_reloc_stub (abfd
, output_bfd
,
2877 reloc_entry
, stub_types
);
2879 if (hppa_elf_long_branch_needed_p (abfd
, input_section
, reloc_entry
,
2880 symbol
, *(unsigned *)hit_data
))
2882 /* generate a stub */
2883 return hppa_elf_build_long_branch_stub (abfd
, output_bfd
,
2884 reloc_entry
, symbol
,
2885 (unsigned *)hit_data
);
2893 return reloc_entry
->sym_ptr_ptr
[0];
2896 #define STUB_SYM_BUFFER_INC 5
2899 hppa_look_for_stubs_in_section (stub_bfd
, abfd
, output_bfd
, asec
, syms
, new_sym_cnt
)
2909 asymbol
*new_syms
= (asymbol
*) NULL
;
2913 /* Relocations are in different places depending on whether this is
2914 an output section or an input section. Also, the relocations are
2915 in different forms. Sigh. Luckily, we have
2916 bfd_canonicalize_reloc() to straighten this out for us. */
2918 /* if ( asec->orelocation || asec->relocation ) { */
2919 if (asec
->reloc_count
> 0)
2921 arelent
**reloc_vector
= (arelent
**) alloca (asec
->reloc_count
* (sizeof (arelent
*) + 1));
2923 bfd_canonicalize_reloc (abfd
, asec
, reloc_vector
, syms
);
2924 for (i
= 0; i
< asec
->reloc_count
; i
++)
2929 if ( asec
->orelocation
)
2930 rle
= asec
->orelocation
[i
];
2932 rle
= asec
->relocation
+i
;
2935 arelent
*rle
= reloc_vector
[i
];
2937 switch (rle
->howto
->type
)
2939 case R_HPPA_ABS_CALL_11
: /* Symbol + Addend 11 */
2940 case R_HPPA_ABS_CALL_14
: /* Symbol + Addend 14 */
2941 case R_HPPA_ABS_CALL_17
: /* Symbol + Addend 17 */
2942 case R_HPPA_ABS_CALL_L21
: /* L (Symbol, Addend) 21 */
2943 case R_HPPA_ABS_CALL_R11
: /* R (Symbol, Addend) 11 */
2944 case R_HPPA_ABS_CALL_R14
: /* R (Symbol, Addend) 14 */
2945 case R_HPPA_ABS_CALL_R17
: /* R (Symbol, Addend) 17 */
2946 case R_HPPA_ABS_CALL_LS21
: /* LS(Symbol, Addend) 21 */
2947 case R_HPPA_ABS_CALL_RS11
: /* RS(Symbol, Addend) 11 */
2948 case R_HPPA_ABS_CALL_RS14
: /* RS(Symbol, Addend) 14 */
2949 case R_HPPA_ABS_CALL_RS17
: /* RS(Symbol, Addend) 17 */
2950 case R_HPPA_ABS_CALL_LD21
: /* LD(Symbol, Addend) 21 */
2951 case R_HPPA_ABS_CALL_RD11
: /* RD(Symbol, Addend) 11 */
2952 case R_HPPA_ABS_CALL_RD14
: /* RD(Symbol, Addend) 14 */
2953 case R_HPPA_ABS_CALL_RD17
: /* RD(Symbol, Addend) 17 */
2954 case R_HPPA_ABS_CALL_LR21
: /* LR(Symbol, Addend) 21 */
2955 case R_HPPA_ABS_CALL_RR14
: /* RR(Symbol, Addend) 14 */
2956 case R_HPPA_ABS_CALL_RR17
: /* RR(Symbol, Addend) 17 */
2958 case R_HPPA_PCREL_CALL_11
: /* Symbol - PC + Addend 11 */
2959 case R_HPPA_PCREL_CALL_14
: /* Symbol - PC + Addend 14 */
2960 case R_HPPA_PCREL_CALL_17
: /* Symbol - PC + Addend 17 */
2961 case R_HPPA_PCREL_CALL_12
: /* Symbol - PC + Addend 12 */
2962 case R_HPPA_PCREL_CALL_L21
: /* L (Symbol - PC, Addend) 21 */
2963 case R_HPPA_PCREL_CALL_R11
: /* R (Symbol - PC, Addend) 11 */
2964 case R_HPPA_PCREL_CALL_R14
: /* R (Symbol - PC, Addend) 14 */
2965 case R_HPPA_PCREL_CALL_R17
: /* R (Symbol - PC, Addend) 17 */
2966 case R_HPPA_PCREL_CALL_LS21
: /* LS(Symbol - PC, Addend) 21 */
2967 case R_HPPA_PCREL_CALL_RS11
: /* RS(Symbol - PC, Addend) 11 */
2968 case R_HPPA_PCREL_CALL_RS14
: /* RS(Symbol - PC, Addend) 14 */
2969 case R_HPPA_PCREL_CALL_RS17
: /* RS(Symbol - PC, Addend) 17 */
2970 case R_HPPA_PCREL_CALL_LD21
: /* LD(Symbol - PC, Addend) 21 */
2971 case R_HPPA_PCREL_CALL_RD11
: /* RD(Symbol - PC, Addend) 11 */
2972 case R_HPPA_PCREL_CALL_RD14
: /* RD(Symbol - PC, Addend) 14 */
2973 case R_HPPA_PCREL_CALL_RD17
: /* RD(Symbol - PC, Addend) 17 */
2974 case R_HPPA_PCREL_CALL_LR21
: /* LR(Symbol - PC, Addend) 21 */
2975 case R_HPPA_PCREL_CALL_RR14
: /* RR(Symbol - PC, Addend) 14 */
2976 case R_HPPA_PCREL_CALL_RR17
: /* RR(Symbol - PC, Addend) 17 */
2978 symext_entryS caller_ar
= (symext_entryS
) HPPA_R_ARG_RELOC (rle
->addend
);
2979 if (hppa_elf_arg_reloc_needed_p (abfd
, rle
, stub_types
,
2982 /* generate a stub */
2983 /* keep track of the new symbol */
2986 if (new_cnt
== new_max
)
2988 new_max
+= STUB_SYM_BUFFER_INC
;
2989 new_syms
= (asymbol
*) realloc (new_syms
, new_max
* sizeof (asymbol
));
2991 r
= hppa_elf_build_arg_reloc_stub (stub_bfd
, output_bfd
,
2993 new_syms
[new_cnt
++] = *r
;
2995 /* We need to retrieve the section contents to check for
3000 bfd_get_section_contents (abfd
, asec
, &insn
, rle
->address
,
3002 if (hppa_elf_long_branch_needed_p (abfd
, asec
, rle
,
3003 rle
->sym_ptr_ptr
[0],
3006 /* generate a stub */
3007 /* keep track of the new symbol */
3010 if (new_cnt
== new_max
)
3012 new_max
+= STUB_SYM_BUFFER_INC
;
3013 new_syms
= (asymbol
*) realloc (new_syms
, (new_max
* sizeof (asymbol
)));
3015 r
= hppa_elf_build_long_branch_stub (stub_bfd
,
3018 rle
->sym_ptr_ptr
[0],
3020 new_syms
[new_cnt
++] = *r
;
3026 /* Plabels are designed to allow code pointers to be
3027 passed between spaces. These relocations correspond
3028 to the P%, LP%, and RP% field selectors. */
3030 case R_HPPA_PLABEL_32
: /* F(Plabel(Symbol,Addend),0) 32 */
3031 case R_HPPA_PLABEL_11
: /* F(Plabel(Symbol,Addend),0) 11 */
3032 case R_HPPA_PLABEL_14
: /* F(Plabel(Symbol,Addend),0) 14 */
3033 case R_HPPA_PLABEL_L21
: /* L(Plabel(Symbol,Addend),0) 21 */
3034 case R_HPPA_PLABEL_R11
: /* R(Plabel(Symbol,Addend),0) 11 */
3035 case R_HPPA_PLABEL_R14
: /* R(Plabel(Symbol,Addend),0) 14 */
3036 /* We need to retrieve the section contents to check for
3037 long branch stubs. */
3039 /* On a plabel relocation, assume the arguments of the
3040 caller are set up in general registers. */
3041 /* 0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
3042 symext_entryS caller_ar
= (symext_entryS
) 0x155;
3044 if (hppa_elf_arg_reloc_needed_p (abfd
, rle
, stub_types
,
3047 /* generate a plabel stub */
3048 /* keep track of the new symbol */
3051 if (new_cnt
== new_max
)
3053 new_max
+= STUB_SYM_BUFFER_INC
;
3054 new_syms
= (asymbol
*) realloc (new_syms
,
3056 * sizeof (asymbol
)));
3058 r
= hppa_elf_build_arg_reloc_stub (stub_bfd
,
3062 new_syms
[new_cnt
++] = *r
;
3073 *new_sym_cnt
= new_cnt
;
3078 char *linker_stubs
= NULL
;
3079 int linker_stubs_size
= 0;
3080 int linker_stubs_max_size
= 0;
3081 #define STUB_ALLOC_INCR 100
3084 DEFUN (hppa_elf_set_section_contents
, (abfd
, section
, location
, offset
, count
),
3089 bfd_size_type count
)
3091 if ( strcmp(section
->name
, ".hppa_linker_stubs") == 0 )
3093 if ( linker_stubs_max_size
< offset
+ count
)
3095 linker_stubs_max_size
= offset
+ count
+ STUB_ALLOC_INCR
;
3096 linker_stubs
= (char *)realloc(linker_stubs
, linker_stubs_max_size
);
3099 if ( offset
+ count
> linker_stubs_size
)
3100 linker_stubs_size
= offset
+ count
;
3102 memcpy(linker_stubs
+ offset
,location
,count
);
3106 return bfd_elf32_set_section_contents (abfd
, section
, location
,
3110 /* Get the contents of the given section.
3112 This is special for PA ELF because some sections (such as linker stubs)
3113 may reside in memory rather than on disk, or in the case of the symbol
3114 extension section, the contents may need to be generated from other
3115 information contained in the BFD. */
3118 hppa_elf_get_section_contents (abfd
, section
, location
, offset
, count
)
3123 bfd_size_type count
;
3125 /* If this is the linker stub section, then its contents are contained
3126 in memory rather than on disk. FIXME. Is that always right? What
3127 about the case where a final executable is read in and a user tries
3128 to get the contents of this section? In that case the contents would
3129 be on disk like everything else. */
3130 if (strcmp (section
->name
, ".hppa_linker_stubs") == 0)
3132 elf32_hppa_stub_description
*stub_desc
= find_stubs (abfd
, section
);
3137 /* Sanity check our arguments. */
3138 if ((bfd_size_type
) (offset
+ count
) > section
->_raw_size
3139 || (bfd_size_type
) (offset
+ count
) > stub_desc
->real_size
)
3142 memcpy (location
, stub_desc
->stub_contents
+ offset
, count
);
3146 /* The symbol extension section also needs special handling. Its
3147 contents might be on the disk, in memory, or still need to
3149 else if (strcmp (section
->name
, ".hppa_symextn") == 0)
3151 /* If this is the first time through and there are no output
3152 sections, then read the contents of the symbol extension section
3154 if (! symext_chain_built
3155 || ((section
->output_section
== NULL
)
3156 && (abfd
->direction
== read_direction
)))
3158 return bfd_generic_get_section_contents (abfd
, section
, location
,
3162 /* If this is the first time through, and there are output sections,
3163 then build the symbol extension section based on other information
3164 contained in the BFD. */
3165 else if (! symext_chain_built
)
3168 int *symtab_map
= elf_sym_extra(section
->output_section
->owner
);
3170 for (i
= 0; i
< section
->output_section
->owner
->symcount
; i
++ )
3172 elf_hppa_tc_symbol(section
->output_section
->owner
,
3173 section
->output_section
->owner
->outsymbols
[i
],
3176 symext_chain_built
++;
3177 elf_hppa_tc_make_sections (section
->output_section
->owner
, NULL
);
3182 /* Sanity check our arguments. */
3183 if ((bfd_size_type
) (offset
+ count
) > section
->_raw_size
3184 || (bfd_size_type
) (offset
+ count
) > symextn_contents_real_size
)
3188 ((char *)symextn_contents
+ section
->output_offset
+ offset
),
3193 return bfd_generic_get_section_contents (abfd
, section
, location
,
3198 DEFUN (elf_info_to_howto
, (abfd
, cache_ptr
, dst
),
3200 arelent
* cache_ptr AND
3201 Elf32_Internal_Rela
* dst
)
3203 BFD_ASSERT (ELF32_R_TYPE(dst
->r_info
) < (unsigned int) R_HPPA_UNIMPLEMENTED
);
3204 cache_ptr
->howto
= &elf_hppa_howto_table
[ELF32_R_TYPE(dst
->r_info
)];
3208 DEFUN (elf32_hppa_backend_symbol_processing
, (abfd
, sym
),
3212 /* Is this a definition of $global$? If so, keep it because it will be
3213 needed if any relocations are performed. */
3215 if (!strcmp (sym
->name
, "$global$")
3216 && sym
->section
!= &bfd_und_section
)
3218 global_symbol
= sym
;
3222 #define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing
3224 struct elf32_hppa_symextn_map_struct
3232 static struct elf32_hppa_symextn_map_struct
*elf32_hppa_symextn_map
;
3233 static int elf32_hppa_symextn_map_size
;
3236 DEFUN (elf32_hppa_backend_symbol_table_processing
, (abfd
, esyms
,symcnt
),
3238 elf_symbol_type
*esyms AND
3241 Elf32_Internal_Shdr
*symextn_hdr
= bfd_elf_find_section (abfd
, SYMEXTN_SECTION_NAME
);
3243 int current_sym_idx
= 0;
3245 /* If the symbol extension section does not exist, all the symbol */
3246 /* all the symbol extension information is assumed to be zero. */
3248 if ( symextn_hdr
== NULL
)
3250 for ( i
= 0; i
< symcnt
; i
++ )
3252 esyms
[i
].tc_data
.hppa_arg_reloc
= 0;
3257 /* allocate a buffer of the appropriate size for the symextn section */
3259 symextn_hdr
->contents
= bfd_zalloc(abfd
,symextn_hdr
->sh_size
);
3260 symextn_hdr
->size
= symextn_hdr
->sh_size
;
3262 /* read in the symextn section */
3264 if (bfd_seek (abfd
, symextn_hdr
->sh_offset
, SEEK_SET
) == -1)
3266 bfd_error
= system_call_error
;
3269 if (bfd_read ((PTR
) symextn_hdr
->contents
, 1, symextn_hdr
->size
, abfd
)
3270 != symextn_hdr
->size
)
3272 free ((PTR
)symextn_hdr
->contents
);
3273 bfd_error
= system_call_error
;
3277 /* parse the entries, updating the symtab entries as we go */
3279 for ( i
= 0; i
< symextn_hdr
->size
/ sizeof(symext_entryS
); i
++ )
3281 symext_entryS
*seP
= ((symext_entryS
*)symextn_hdr
->contents
) + i
;
3282 int se_value
= ELF32_HPPA_SX_VAL(*seP
);
3283 int se_type
= ELF32_HPPA_SX_TYPE(*seP
);
3290 case HPPA_SXT_SYMNDX
:
3291 if ( se_value
>= symcnt
)
3293 bfd_error
= bad_value
;
3294 bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3297 current_sym_idx
= se_value
- 1;
3300 case HPPA_SXT_ARG_RELOC
:
3301 esyms
[current_sym_idx
].tc_data
.hppa_arg_reloc
= se_value
;
3305 bfd_error
= bad_value
;
3306 bfd_perror("elf32_hppa_backend_symbol_table_processing");
3313 #define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing
3316 DEFUN (elf32_hppa_backend_section_processing
, (abfd
, secthdr
),
3318 Elf32_Internal_Shdr
*secthdr
)
3322 if ( secthdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3324 for ( i
= 0; i
< secthdr
->size
/ sizeof(symext_entryS
); i
++ )
3326 symext_entryS
*seP
= ((symext_entryS
*)secthdr
->contents
) + i
;
3327 int se_value
= ELF32_HPPA_SX_VAL(*seP
);
3328 int se_type
= ELF32_HPPA_SX_TYPE(*seP
);
3335 case HPPA_SXT_SYMNDX
:
3336 for ( j
= 0; j
< abfd
->symcount
; j
++ )
3338 /* locate the map entry for this symbol, if there is one. */
3339 /* modify the symbol extension section symbol index entry */
3340 /* to reflect the new symbol table index */
3342 for ( k
= 0; k
< elf32_hppa_symextn_map_size
; k
++ )
3344 if ( elf32_hppa_symextn_map
[k
].old_index
== se_value
3345 && elf32_hppa_symextn_map
[k
].bfd
== abfd
->outsymbols
[j
]->the_bfd
3346 && elf32_hppa_symextn_map
[k
].sym
== abfd
->outsymbols
[j
] )
3349 ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, j
),
3356 case HPPA_SXT_ARG_RELOC
:
3360 bfd_error
= bad_value
;
3361 bfd_perror("elf32_hppa_backend_section_processing");
3369 #define elf_backend_section_processing elf32_hppa_backend_section_processing
3372 DEFUN (elf32_hppa_backend_section_from_shdr
, (abfd
, hdr
, name
),
3374 Elf32_Internal_Shdr
*hdr AND
3379 if ( hdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3381 BFD_ASSERT ( strcmp(name
,".hppa_symextn") == 0 );
3383 /* Bits that get saved. This one is real. */
3386 newsect
= bfd_make_section (abfd
, name
);
3387 if (newsect
!= NULL
)
3389 newsect
->vma
= hdr
->sh_addr
;
3390 newsect
->_raw_size
= hdr
->sh_size
;
3391 newsect
->filepos
= hdr
->sh_offset
; /* so we can read back the bits */
3392 newsect
->flags
|= SEC_HAS_CONTENTS
;
3393 newsect
->alignment_power
= hdr
->sh_addralign
;
3395 if (hdr
->sh_flags
& SHF_ALLOC
)
3397 newsect
->flags
|= SEC_ALLOC
;
3398 newsect
->flags
|= SEC_LOAD
;
3401 if (!(hdr
->sh_flags
& SHF_WRITE
))
3402 newsect
->flags
|= SEC_READONLY
;
3404 if (hdr
->sh_flags
& SHF_EXECINSTR
)
3405 newsect
->flags
|= SEC_CODE
; /* FIXME: may only contain SOME code */
3407 newsect
->flags
|= SEC_DATA
;
3409 hdr
->rawdata
= (void *) newsect
;
3417 #define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr
3420 DEFUN (elf32_hppa_backend_fake_sections
, (abfd
, secthdr
, asect
),
3422 Elf_Internal_Shdr
*secthdr AND
3426 if ( strcmp(asect
->name
, ".hppa_symextn") == 0 )
3428 secthdr
->sh_type
= SHT_HPPA_SYMEXTN
;
3429 secthdr
->sh_flags
= 0;
3430 secthdr
->sh_info
= elf_section_data(asect
)->rel_hdr
.sh_link
;
3431 secthdr
->sh_link
= elf_onesymtab(abfd
);
3435 if (!strcmp (asect
->name
, ".hppa_unwind"))
3437 secthdr
->sh_type
= SHT_PROGBITS
;
3438 /* Unwind descriptors are not part of the program memory image. */
3439 secthdr
->sh_flags
= 0;
3440 secthdr
->sh_info
= 0;
3441 secthdr
->sh_link
= 0;
3442 secthdr
->sh_entsize
= 16;
3446 /* @@ Should this be CPU specific?? KR */
3447 if (!strcmp (asect
->name
, ".stabstr"))
3449 secthdr
->sh_type
= SHT_STRTAB
;
3450 secthdr
->sh_flags
= 0;
3451 secthdr
->sh_info
= 0;
3452 secthdr
->sh_link
= 0;
3453 secthdr
->sh_entsize
= 0;
3460 #define elf_backend_fake_sections elf32_hppa_backend_fake_sections
3463 DEFUN (elf32_hppa_backend_section_from_bfd_section
, (abfd
, hdr
, asect
, retval
),
3465 Elf32_Internal_Shdr
*hdr AND
3470 if ( hdr
->sh_type
== SHT_HPPA_SYMEXTN
)
3474 if (((struct sec
*) (hdr
->rawdata
)) == asect
)
3476 BFD_ASSERT( strcmp(asect
->name
, ".hppa_symextn") == 0 );
3481 else if ( hdr
->sh_type
== SHT_STRTAB
)
3485 if (((struct sec
*) (hdr
->rawdata
)) == asect
)
3487 BFD_ASSERT ( strcmp (asect
->name
, ".stabstr") == 0);
3496 #define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section
3498 #define bfd_generic_get_section_contents hppa_elf_get_section_contents
3499 #define bfd_elf32_set_section_contents hppa_elf_set_section_contents
3501 #define TARGET_BIG_SYM bfd_elf32_hppa_vec
3502 #define TARGET_BIG_NAME "elf32-hppa"
3503 #define ELF_ARCH bfd_arch_hppa
3504 #define ELF_MAXPAGESIZE 0x1000
3506 #include "elf32-target.h"