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