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