]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-hppa.c
checkpoint hppa-elf code from Utah (Sanitize out until it's cleaned up & working)
[thirdparty/binutils-gdb.git] / bfd / elf32-hppa.c
1 /* BFD back-end for HP PA-RISC ELF files.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3
4 Written by
5
6 Center for Software Science
7 Department of Computer Science
8 University of Utah
9
10 This file is part of BFD, the Binary File Descriptor library.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "libbfd.h"
29 #include "obstack.h"
30 #include "libelf.h"
31
32
33 static struct elf_backend_data elf_hppa_backend_data = {
34 NULL /* initially, $global$ is undefined */
35 };
36
37 /* ELF32/HPPA relocation support
38
39 This file contains ELF32/HPPA relocation support as specified
40 in the Stratus FTX/Golf Object File Format (SED-1762) dated
41 November 19, 1992.
42 */
43
44 /*
45 Written by:
46
47 Center for Software Science
48 Department of Computer Science
49 University of Utah
50 */
51
52 #include "elf32-hppa.h"
53
54 /* ELF/PA stab entries */
55
56 #ifdef hp800
57 #undef hp800
58 #include <a.out.h> /* we want the non-hp800 definition of 'struct nlist' */
59 #define hp800
60 #else
61 #include <a.out.h>
62 #endif
63
64 /* ELF/PA relocation howto entries */
65
66 static bfd_reloc_status_type hppa_elf_reloc();
67
68 reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = {
69 /* 'bitpos' and 'abs' are obsolete */
70 /* type rs sz bsz pcrel bpos abs ovrf sf name */
71 /* 9.3.4. Address relocation types */
72 { R_HPPA_NONE, 0, 3, 19, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NONE"},
73 { R_HPPA_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_32" },
74 { R_HPPA_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_11" },
75 { R_HPPA_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_14" },
76 { R_HPPA_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_17" },
77 { R_HPPA_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L21" },
78 { R_HPPA_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R11" },
79 { R_HPPA_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R14" },
80 { R_HPPA_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R17" },
81 { R_HPPA_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LS21" },
82 { R_HPPA_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS11" },
83 { R_HPPA_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS14" },
84 { R_HPPA_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS17" },
85 { R_HPPA_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LD21" },
86 { R_HPPA_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD11" },
87 { R_HPPA_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD14" },
88 { R_HPPA_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD17" },
89 { R_HPPA_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LR21" },
90 { R_HPPA_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR14" },
91 { R_HPPA_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR17" },
92 /* 9.3.5. GOTOFF address relocation types */
93 { R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_11" },
94 { R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_14" },
95 { R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_L21" },
96 { R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R11" },
97 { R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R14" },
98 { R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21" },
99 { R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11" },
100 { R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14" },
101 { R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21" },
102 { R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11" },
103 { R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14" },
104 { R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21" },
105 { R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14" },
106 /* 9.3.6. Absolute call relocation types */
107 { R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_11" },
108 { R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_14" },
109 { R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_17" },
110 { R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21" },
111 { R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11" },
112 { R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14" },
113 { R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17" },
114 { R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21" },
115 { R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11" },
116 { R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14" },
117 { R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17" },
118 { R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21" },
119 { R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11" },
120 { R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14" },
121 { R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17" },
122 { R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21" },
123 { R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14" },
124 { R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17" },
125 /* 9.3.7. PC-relative call relocation types */
126 { R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11" },
127 { R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14" },
128 { R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17" },
129 { R_HPPA_PCREL_CALL_L21,0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21" },
130 { R_HPPA_PCREL_CALL_R11,0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11" },
131 { R_HPPA_PCREL_CALL_R14,0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14" },
132 { R_HPPA_PCREL_CALL_R17,0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17" },
133 { R_HPPA_PCREL_CALL_LS21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21" },
134 { R_HPPA_PCREL_CALL_RS11,0,3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11" },
135 { R_HPPA_PCREL_CALL_RS14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14" },
136 { R_HPPA_PCREL_CALL_RS17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17" },
137 { R_HPPA_PCREL_CALL_LD21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21" },
138 { R_HPPA_PCREL_CALL_RD11,0,3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11" },
139 { R_HPPA_PCREL_CALL_RD14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14" },
140 { R_HPPA_PCREL_CALL_RD17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17" },
141 { R_HPPA_PCREL_CALL_LR21,0,3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21" },
142 { R_HPPA_PCREL_CALL_RR14,0,3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14" },
143 { R_HPPA_PCREL_CALL_RR17,0,3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17" }, /* #69 */
144
145 /* 9.3.8. Plabel relocation types */
146 { R_HPPA_PLABEL_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_32" },
147 { R_HPPA_PLABEL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_11" },
148 { R_HPPA_PLABEL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_14" },
149 { R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_L21" },
150 { R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R11" },
151 { R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R14" }, /* 75 */
152
153 /* 9.3.9. Data linkage table (DLT) relocation types */
154 { R_HPPA_DLT_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_32" },
155 { R_HPPA_DLT_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_11" },
156 { R_HPPA_DLT_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_14" },
157 { R_HPPA_DLT_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_L21" },
158 { R_HPPA_DLT_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R11" },
159 { R_HPPA_DLT_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R14" }, /* 81 */
160
161 /* 9.3.10. Relocations for unwinder tables */
162 { R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
163 { R_HPPA_UNWIND_ENTRIES,0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"}, /* 83 */
164
165 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 84-89 */
166 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 90-99 */
167 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 100-109 */
168 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 110-119 */
169 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, /* 120-127 */
170
171 /* 9.3.11. Relocation types for complex expressions */
172 { R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_CONST" },
173 { R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM" },
174 { R_HPPA_PUSH_GOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOT" },
175 { R_HPPA_PUSH_PC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC" },
176 { R_HPPA_PUSH_PROC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PROC" },
177 { R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL" },
178 { R_HPPA_MAX, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MAX" },
179 { R_HPPA_MIN, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MIN" },
180 { R_HPPA_ADD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ADD" },
181 { R_HPPA_SUB, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_SUB" },
182 { R_HPPA_MULT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MULT" },
183 { R_HPPA_DIV, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_DIV" },
184 { R_HPPA_MOD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MOD" },
185 { R_HPPA_AND, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_AND" },
186 { R_HPPA_OR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_OR" },
187 { R_HPPA_XOR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_XOR" },
188 { R_HPPA_NOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NOT" },
189 { R_HPPA_LSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LSHIFT" },
190 { R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT" },
191 { R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT" },
192 { R_HPPA_EXPR_F, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L" },
193 { R_HPPA_EXPR_L, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_L" },
194 { R_HPPA_EXPR_R, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_R" },
195 { R_HPPA_EXPR_LS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LS" },
196 { R_HPPA_EXPR_RS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RS" },
197 { R_HPPA_EXPR_LD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LD" },
198 { R_HPPA_EXPR_RD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RD" },
199 { R_HPPA_EXPR_LR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LR" },
200 { R_HPPA_EXPR_RR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RR" },
201
202 { R_HPPA_EXPR_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_32" },
203 { R_HPPA_EXPR_21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_21" },
204 { R_HPPA_EXPR_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_11" },
205 { R_HPPA_EXPR_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_14" },
206 { R_HPPA_EXPR_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_17" },
207 { R_HPPA_EXPR_12, 0, 3, 12, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_12" },
208 { R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, false, false,NULL, "R_HPPA_UNIMPLEMENTED"}, /* 163 */
209 };
210
211 static unsigned long
212 DEFUN(hppa_elf_rebuild_insn, (abfd,insn,value,r_type,r_field, r_format),
213 bfd *abfd AND
214 unsigned long insn AND
215 unsigned long value AND
216 unsigned short r_type AND
217 unsigned short r_field AND
218 unsigned short r_format)
219 {
220 unsigned long const_part; /* part of the instruction that does not change */
221 unsigned long rebuilt_part;
222
223 switch ( r_format ) {
224 case 11: {
225 unsigned w1, w;
226
227 const_part = insn & 0xffffe002;
228 dis_assemble_12(value,&w1,&w);
229 rebuilt_part = (w1 << 2) | w;
230 return const_part | rebuilt_part;
231 }
232
233 case 12: {
234 unsigned w1, w;
235
236 const_part = insn & 0xffffe002;
237 dis_assemble_12(value,&w1,&w);
238 rebuilt_part = (w1 << 2) | w;
239 return const_part | rebuilt_part;
240 }
241
242 case 14:
243 const_part = insn & 0xffffc000;
244 low_sign_unext(value,14,&rebuilt_part);
245 return const_part | rebuilt_part;
246
247 case 17: {
248 unsigned w1, w2, w;
249
250 const_part = insn & 0xffe0e002;
251 dis_assemble_17(value,&w1,&w2,&w);
252 rebuilt_part = (w2 << 2) | (w1 << 16) | w;
253 return const_part | rebuilt_part;
254 }
255
256 case 21:
257 const_part = insn & 0xffe00000;
258 dis_assemble_21(value,&rebuilt_part);
259 return const_part | rebuilt_part;
260
261 case 32:
262 const_part = 0;
263 return value;
264
265 default:
266 fprintf(stderr,"Relocation problem : ");
267 fprintf(stderr,"Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
268 r_type, r_format, r_field, abfd->filename);
269 }
270 return insn;
271 }
272
273 static unsigned long
274 DEFUN(hppa_elf_relocate_insn,
275 (abfd, input_sect,
276 insn, address, symp, sym_value, r_addend,
277 r_type, r_format, r_field, pcrel),
278 bfd *abfd AND
279 asection *input_sect AND
280 unsigned long insn AND
281 unsigned long address AND
282 asymbol *symp AND
283 long sym_value AND
284 long r_addend AND
285 unsigned short r_type AND
286 unsigned short r_format AND
287 unsigned short r_field AND
288 unsigned char pcrel)
289 {
290 unsigned char opcode = get_opcode(insn);
291 long constant_value;
292 unsigned arg_reloc;
293
294 switch ( opcode ) {
295 case LDO:
296 case LDB:
297 case LDH:
298 case LDW:
299 case LDWM:
300 case STB:
301 case STH:
302 case STW:
303 case STWM:
304 constant_value = ELF32_HPPA_R_CONSTANT(r_addend);
305 BFD_ASSERT(r_format == 14);
306
307 if ( pcrel )
308 sym_value -= address;
309 sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
310 return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_format, r_format);
311
312 case COMICLR:
313 case SUBI: /* case SUBIO: */
314 case ADDIT: /* case ADDITO: */
315 case ADDI: /* case ADDIO: */
316 BFD_ASSERT(r_format == 11);
317
318 constant_value = ((insn & 0x1) << 10) | ((insn & 0xffe) >> 1);
319 sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
320 return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format);
321
322 case LDIL:
323 case ADDIL:
324 BFD_ASSERT(r_format == 21);
325
326 constant_value = assemble_21(insn);
327 sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
328 return hppa_elf_rebuild_insn(abfd,insn,sym_value,r_type,r_field, r_format);
329
330 case BL:
331 case BE:
332 case BLE:
333 arg_reloc = ELF32_HPPA_R_ARG_RELOC(r_addend);
334
335 BFD_ASSERT(r_format == 17);
336
337 /* XXX computing constant_value is not needed??? */
338 constant_value = assemble_17((insn & 0x001f0000) >> 16,
339 (insn & 0x00001ffc) >> 2,
340 insn & 1);
341 constant_value = sign_ext(constant_value,17);
342 if ( pcrel ) {
343 sym_value -=
344 address + input_sect->output_offset
345 + input_sect->output_section->vma;
346 sym_value = hppa_field_adjust(sym_value,-8,r_field);
347 }
348 else
349 sym_value = hppa_field_adjust(sym_value, constant_value, r_field);
350
351 return hppa_elf_rebuild_insn(abfd,insn,sym_value >> 2,r_type,r_field, r_format);
352
353 default:
354 if ( opcode == 0 && r_format == 32 ) {
355 constant_value = insn;
356 sym_value = hppa_field_adjust(sym_value,constant_value,r_field);
357 return sym_value;
358 }
359 else {
360 fprintf(stderr,
361 "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
362 opcode, r_format, r_field);
363 return (insn);
364 }
365 }
366 }
367
368 static void
369 DEFUN(hppa_elf_relocate_unwind_table,
370 (abfd, input_sect,
371 data, address, symp, sym_value, r_addend,
372 r_type, r_format, r_field, pcrel),
373 bfd *abfd AND
374 asection *input_sect AND
375 PTR data AND
376 unsigned long address AND
377 asymbol *symp AND
378 long sym_value AND
379 long r_addend AND
380 unsigned short r_type AND
381 unsigned short r_format AND
382 unsigned short r_field AND
383 unsigned char pcrel)
384 {
385 bfd_byte *hit_data = address + (bfd_byte *)(data);
386 long constant_value;
387 long start_offset;
388 long end_offset;
389 long relocated_value;
390 int i;
391
392 BFD_ASSERT( r_format == 32 );
393 BFD_ASSERT( r_field == e_fsel );
394 switch ( r_type ) {
395 case R_HPPA_UNWIND_ENTRY:
396 start_offset = bfd_get_32(abfd, hit_data);
397 relocated_value = hppa_field_adjust(sym_value,start_offset,r_field);
398 bfd_put_32(abfd, relocated_value ,hit_data);
399
400 hit_data += sizeof(unsigned long);
401 end_offset = bfd_get_32(abfd, hit_data);
402 relocated_value = hppa_field_adjust(sym_value,end_offset,r_field);
403 bfd_put_32(abfd, relocated_value ,hit_data);
404 break;
405
406 case R_HPPA_UNWIND_ENTRIES:
407 for ( i = 0; i < r_addend; i++,hit_data += 3*sizeof(unsigned long) ) {
408 unsigned int fsize;
409 start_offset = bfd_get_32(abfd, hit_data);
410 /* Stuff the symbol value into the first word */
411 /* of the unwind descriptor */
412 bfd_put_32(abfd, sym_value ,hit_data);
413
414 hit_data += sizeof(unsigned long);
415 end_offset = bfd_get_32(abfd, hit_data);
416 /* We could also compute the ending offset for */
417 /* the 2nd word of the unwind entry by */
418 /* retrieving the st_size field of the Elf_Sym */
419 /* structure stored with this symbol. We can */
420 /* get it with: */
421 /* e = (elf_symbol_type *)symp */
422 /* fsize = e->internal_elf_sym.st_size */
423
424 fsize = end_offset - start_offset;
425 relocated_value = hppa_field_adjust(sym_value,fsize,r_field);
426 bfd_put_32(abfd, relocated_value ,hit_data);
427
428 /* If this is not the last unwind entry, */
429 /* adjust the symbol value. */
430 if ( i+1 < r_addend ) {
431 start_offset = bfd_get_32(abfd, hit_data+3*sizeof(unsigned long));
432 sym_value += fsize + start_offset - end_offset;
433 }
434 }
435 break;
436
437 default:
438 fprintf(stderr,
439 "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
440 r_type, r_format, r_field);
441 }
442 return;
443 }
444
445 /* Provided the symbol, returns the value reffed */
446 static long
447 get_symbol_value(symbol)
448 asymbol *symbol;
449 {
450 long relocation = 0;
451
452 if ( symbol == (asymbol *)NULL )
453 relocation = 0;
454 else if (symbol->section == &bfd_com_section) {
455 relocation = 0;
456 }
457 else {
458 relocation = symbol->value +
459 symbol->section->output_section->vma +
460 symbol->section->output_offset;
461 }
462
463 return(relocation);
464 }
465
466 /* This function provides a pretty straight-forward mapping between a */
467 /* base relocation type, format and field into the relocation type */
468 /* that will be emitted in an object file. The only wrinkle in the */
469 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
470 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
471 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
472 /* (in the case of P, PR, and PL). */
473
474 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
475 /* handled yet. */
476
477 static void
478 hppa_elf_gen_reloc_error(base_type,fmt,field)
479 elf32_hppa_reloc_type base_type;
480 int fmt;
481 int field;
482 {
483 fprintf(stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
484 base_type, fmt, field);
485 }
486
487 unsigned char
488 hppa_elf_gen_reloc_type(base_type, format, field)
489 elf32_hppa_reloc_type base_type;
490 int format;
491 int field;
492 {
493 #define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field);
494
495 elf32_hppa_reloc_type final_type = base_type;
496 switch ( base_type ) {
497 case R_HPPA:
498 switch (format) {
499 case 11:
500 switch ( field ) {
501 case e_rsel:
502 final_type = R_HPPA_R11;
503 break;
504 case e_rssel:
505 final_type = R_HPPA_RS11;
506 break;
507 case e_rdsel:
508 final_type = R_HPPA_RD11;
509 break;
510
511 case e_psel:
512 final_type = R_HPPA_PLABEL_11;
513 break;
514 case e_rpsel:
515 final_type = R_HPPA_PLABEL_R11;
516 break;
517 case e_lpsel:
518 case e_tsel:
519 case e_ltsel:
520 case e_rtsel:
521
522 case e_fsel:
523 case e_lsel:
524 case e_lrsel:
525 case e_lssel:
526 case e_rrsel:
527 default:
528 UNDEFINED;
529 final_type = base_type;
530 break;
531 }
532 break;
533 case 12:
534 UNDEFINED;
535 break;
536 case 14:
537 switch ( field ) {
538 case e_rsel:
539 final_type = R_HPPA_R14;
540 break;
541 case e_rssel:
542 final_type = R_HPPA_RS14;
543 break;
544 case e_rdsel:
545 final_type = R_HPPA_RD14;
546 break;
547 case e_rrsel:
548 final_type = R_HPPA_RR14;
549 break;
550
551 case e_psel:
552 final_type = R_HPPA_PLABEL_14;
553 break;
554 case e_rpsel:
555 final_type = R_HPPA_PLABEL_R14;
556 break;
557 case e_lpsel:
558 case e_tsel:
559 case e_ltsel:
560 case e_rtsel:
561
562 case e_fsel:
563 case e_lsel:
564 case e_lssel:
565 case e_ldsel:
566 case e_lrsel:
567 default:
568 UNDEFINED;
569 final_type = base_type;
570 break;
571 }
572 break;
573 case 17:
574 switch ( field ) {
575 case e_rsel:
576 final_type = R_HPPA_R17;
577 break;
578 case e_rssel:
579 final_type = R_HPPA_RS17;
580 break;
581 case e_rdsel:
582 final_type = R_HPPA_RD17;
583 break;
584 case e_rrsel:
585 final_type = R_HPPA_RR17;
586 break;
587 case e_fsel:
588 case e_lsel:
589 case e_lssel:
590 case e_ldsel:
591 case e_lrsel:
592 default:
593 UNDEFINED;
594 final_type = base_type;
595 break;
596 }
597 break;
598 case 21:
599 switch ( field ) {
600 case e_lsel:
601 final_type = R_HPPA_L21;
602 break;
603 case e_lssel:
604 final_type = R_HPPA_LS21;
605 break;
606 case e_ldsel:
607 final_type = R_HPPA_LD21;
608 break;
609 case e_lrsel:
610 final_type = R_HPPA_LR21;
611 break;
612 case e_lpsel:
613 final_type = R_HPPA_PLABEL_L21;
614 break;
615 case e_rsel:
616 case e_rssel:
617 case e_rdsel:
618 case e_rrsel:
619 case e_fsel:
620 default:
621 UNDEFINED;
622 final_type = base_type;
623 break;
624 }
625 break;
626 case 32:
627 switch ( field ) {
628 case e_fsel:
629 final_type = R_HPPA_32;
630 break;
631 case e_psel:
632 final_type = R_HPPA_PLABEL_32;
633 break;
634 default:
635 UNDEFINED;
636 final_type = base_type;
637 break;
638 }
639 break;
640 default:
641 UNDEFINED;
642 final_type = base_type;
643 break;
644 }
645 break;
646 case R_HPPA_GOTOFF:
647 switch (format) {
648 case 11:
649 switch ( field ) {
650 case e_rsel:
651 final_type = R_HPPA_GOTOFF_R11;
652 break;
653 case e_rssel:
654 final_type = R_HPPA_GOTOFF_RS11;
655 break;
656 case e_rdsel:
657 final_type = R_HPPA_GOTOFF_RD11;
658 break;
659 case e_fsel:
660 final_type = R_HPPA_GOTOFF_11;
661 break;
662 case e_lsel:
663 case e_lrsel:
664 case e_lssel:
665 case e_rrsel:
666 default:
667 UNDEFINED;
668 final_type = base_type;
669 break;
670 }
671 break;
672 case 12:
673 UNDEFINED;
674 final_type = base_type;
675 break;
676 case 14:
677 switch ( field ) {
678 case e_rsel:
679 final_type = R_HPPA_GOTOFF_R14;
680 break;
681 case e_rssel:
682 final_type = R_HPPA_GOTOFF_RS14;
683 break;
684 case e_rdsel:
685 final_type = R_HPPA_GOTOFF_RD14;
686 break;
687 case e_rrsel:
688 final_type = R_HPPA_GOTOFF_RR14;
689 break;
690 case e_fsel:
691 final_type = R_HPPA_GOTOFF_14;
692 break;
693 case e_lsel:
694 case e_lssel:
695 case e_ldsel:
696 case e_lrsel:
697 default:
698 UNDEFINED;
699 final_type = base_type;
700 break;
701 }
702 break;
703 case 17:
704 UNDEFINED;
705 final_type = base_type;
706 break;
707 case 21:
708 switch ( field ) {
709 case e_lsel:
710 final_type = R_HPPA_GOTOFF_L21;
711 break;
712 case e_lssel:
713 final_type = R_HPPA_GOTOFF_LS21;
714 break;
715 case e_ldsel:
716 final_type = R_HPPA_GOTOFF_LD21;
717 break;
718 case e_lrsel:
719 final_type = R_HPPA_GOTOFF_LR21;
720 break;
721 case e_rsel:
722 case e_rssel:
723 case e_rdsel:
724 case e_rrsel:
725 case e_fsel:
726 default:
727 UNDEFINED;
728 final_type = base_type;
729 break;
730 }
731 break;
732 case 32:
733 UNDEFINED;
734 final_type = base_type;
735 break;
736 default:
737 UNDEFINED;
738 final_type = base_type;
739 break;
740 }
741 break;
742 case R_HPPA_PCREL_CALL:
743 switch (format) {
744 case 11:
745 switch ( field ) {
746 case e_rsel:
747 final_type = R_HPPA_PCREL_CALL_R11;
748 break;
749 case e_rssel:
750 final_type = R_HPPA_PCREL_CALL_RS11;
751 break;
752 case e_rdsel:
753 final_type = R_HPPA_PCREL_CALL_RD11;
754 break;
755 case e_fsel:
756 final_type = R_HPPA_PCREL_CALL_11;
757 break;
758 case e_lsel:
759 case e_lrsel:
760 case e_lssel:
761 case e_rrsel:
762 default:
763 UNDEFINED;
764 final_type = base_type;
765 break;
766 }
767 break;
768 case 12:
769 UNDEFINED;
770 final_type = base_type;
771 break;
772 case 14:
773 switch ( field ) {
774 case e_rsel:
775 final_type = R_HPPA_PCREL_CALL_R14;
776 break;
777 case e_rssel:
778 final_type = R_HPPA_PCREL_CALL_RS14;
779 break;
780 case e_rdsel:
781 final_type = R_HPPA_PCREL_CALL_RD14;
782 break;
783 case e_rrsel:
784 final_type = R_HPPA_PCREL_CALL_RR14;
785 break;
786 case e_fsel:
787 final_type = R_HPPA_PCREL_CALL_14;
788 break;
789 case e_lsel:
790 case e_lssel:
791 case e_ldsel:
792 case e_lrsel:
793 default:
794 UNDEFINED;
795 final_type = base_type;
796 break;
797 }
798 break;
799 case 17:
800 switch ( field ) {
801 case e_rsel:
802 final_type = R_HPPA_PCREL_CALL_R17;
803 break;
804 case e_rssel:
805 final_type = R_HPPA_PCREL_CALL_RS17;
806 break;
807 case e_rdsel:
808 final_type = R_HPPA_PCREL_CALL_RD17;
809 break;
810 case e_rrsel:
811 final_type = R_HPPA_PCREL_CALL_RR17;
812 break;
813 case e_fsel:
814 final_type = R_HPPA_PCREL_CALL_17;
815 break;
816 case e_lsel:
817 case e_lssel:
818 case e_ldsel:
819 case e_lrsel:
820 default:
821 UNDEFINED;
822 final_type = base_type;
823 break;
824 }
825 break;
826 case 21:
827 switch ( field ) {
828 case e_lsel:
829 final_type = R_HPPA_PCREL_CALL_L21;
830 break;
831 case e_lssel:
832 final_type = R_HPPA_PCREL_CALL_LS21;
833 break;
834 case e_ldsel:
835 final_type = R_HPPA_PCREL_CALL_LD21;
836 break;
837 case e_lrsel:
838 final_type = R_HPPA_PCREL_CALL_LR21;
839 break;
840 case e_rsel:
841 case e_rssel:
842 case e_rdsel:
843 case e_rrsel:
844 case e_fsel:
845 default:
846 UNDEFINED;
847 final_type = base_type;
848 break;
849 }
850 break;
851 case 32:
852 UNDEFINED;
853 final_type = base_type;
854 break;
855 default:
856 UNDEFINED;
857 final_type = base_type;
858 break;
859 }
860 break;
861 case R_HPPA_PLABEL:
862 switch (format) {
863 case 11:
864 switch (field) {
865 case e_fsel:
866 final_type = R_HPPA_PLABEL_11;
867 break;
868 case e_rsel:
869 final_type = R_HPPA_PLABEL_R11;
870 break;
871 default:
872 UNDEFINED;
873 final_type = base_type;
874 break;
875 }
876 break;
877 case 14:
878 switch (field) {
879 case e_fsel:
880 final_type = R_HPPA_PLABEL_14;
881 break;
882 case e_rsel:
883 final_type = R_HPPA_PLABEL_R14;
884 break;
885 default:
886 UNDEFINED;
887 final_type = base_type;
888 break;
889 }
890 break;
891 case 21:
892 switch (field) {
893 case e_lsel:
894 final_type = R_HPPA_PLABEL_L21;
895 break;
896 default:
897 UNDEFINED;
898 final_type = base_type;
899 break;
900 }
901 break;
902 case 32:
903 switch (field) {
904 case e_fsel:
905 final_type = R_HPPA_PLABEL_32;
906 break;
907 default:
908 UNDEFINED;
909 final_type = base_type;
910 break;
911 }
912 break;
913 default:
914 UNDEFINED;
915 final_type = base_type;
916 break;
917 }
918 case R_HPPA_ABS_CALL:
919 switch (format) {
920 case 11:
921 switch ( field ) {
922 case e_rsel:
923 final_type = R_HPPA_ABS_CALL_R11;
924 break;
925 case e_rssel:
926 final_type = R_HPPA_ABS_CALL_RS11;
927 break;
928 case e_rdsel:
929 final_type = R_HPPA_ABS_CALL_RD11;
930 break;
931 case e_fsel:
932 final_type = R_HPPA_ABS_CALL_11;
933 break;
934 case e_lsel:
935 case e_lrsel:
936 case e_lssel:
937 case e_rrsel:
938 default:
939 UNDEFINED;
940 final_type = base_type;
941 break;
942 }
943 break;
944 case 12:
945 UNDEFINED;
946 final_type = base_type;
947 break;
948 case 14:
949 switch ( field ) {
950 case e_rsel:
951 final_type = R_HPPA_ABS_CALL_R14;
952 break;
953 case e_rssel:
954 final_type = R_HPPA_ABS_CALL_RS14;
955 break;
956 case e_rdsel:
957 final_type = R_HPPA_ABS_CALL_RD14;
958 break;
959 case e_rrsel:
960 final_type = R_HPPA_ABS_CALL_RR14;
961 break;
962 case e_fsel:
963 final_type = R_HPPA_ABS_CALL_14;
964 break;
965 case e_lsel:
966 case e_lssel:
967 case e_ldsel:
968 case e_lrsel:
969 default:
970 UNDEFINED;
971 final_type = base_type;
972 break;
973 }
974 break;
975 case 17:
976 switch ( field ) {
977 case e_rsel:
978 final_type = R_HPPA_ABS_CALL_R17;
979 break;
980 case e_rssel:
981 final_type = R_HPPA_ABS_CALL_RS17;
982 break;
983 case e_rdsel:
984 final_type = R_HPPA_ABS_CALL_RD17;
985 break;
986 case e_rrsel:
987 final_type = R_HPPA_ABS_CALL_RR17;
988 break;
989 case e_fsel:
990 final_type = R_HPPA_ABS_CALL_17;
991 break;
992 case e_lsel:
993 case e_lssel:
994 case e_ldsel:
995 case e_lrsel:
996 default:
997 UNDEFINED;
998 final_type = base_type;
999 break;
1000 }
1001 break;
1002 case 21:
1003 switch ( field ) {
1004 case e_lsel:
1005 final_type = R_HPPA_ABS_CALL_L21;
1006 break;
1007 case e_lssel:
1008 final_type = R_HPPA_ABS_CALL_LS21;
1009 break;
1010 case e_ldsel:
1011 final_type = R_HPPA_ABS_CALL_LD21;
1012 break;
1013 case e_lrsel:
1014 final_type = R_HPPA_ABS_CALL_LR21;
1015 break;
1016 case e_rsel:
1017 case e_rssel:
1018 case e_rdsel:
1019 case e_rrsel:
1020 case e_fsel:
1021 default:
1022 UNDEFINED;
1023 final_type = base_type;
1024 break;
1025 }
1026 break;
1027 case 32:
1028 UNDEFINED;
1029 final_type = base_type;
1030 break;
1031 default:
1032 UNDEFINED;
1033 final_type = base_type;
1034 break;
1035 }
1036 break;
1037 case R_HPPA_UNWIND:
1038 final_type = R_HPPA_UNWIND_ENTRY;
1039 break;
1040 default:
1041 final_type = base_type;
1042 break;
1043 }
1044
1045 return final_type;
1046 }
1047
1048 /* 12.4.4. Derive format from instruction */
1049
1050 /* Given a machine instruction, this function determines its format. */
1051 /* The format can be determined solely from looking at the first six */
1052 /* bits (the major opcode) of the instruction. Several major opcodes */
1053 /* map to the same format. Opcodes which do not map to a known format */
1054 /* should probably be reported as an error. */
1055
1056 unsigned char
1057 hppa_elf_insn2fmt(type, insn)
1058 elf32_hppa_reloc_type type;
1059 unsigned long insn;
1060 {
1061 unsigned char fmt = 0; /* XXX: is this a proper default? */
1062 unsigned char op = get_opcode(insn);
1063
1064 if ( type == R_HPPA_NONE )
1065 fmt = 0;
1066 else {
1067 switch ( op ) {
1068 case ADDI:
1069 case ADDIT:
1070 case SUBI:
1071 fmt = 11;
1072 break;
1073 case MOVB:
1074 case MOVIB:
1075 case COMBT:
1076 case COMBF:
1077 case COMIBT:
1078 case COMIBF:
1079 case ADDBT:
1080 case ADDBF:
1081 case ADDIBT:
1082 case ADDIBF:
1083 case BVB:
1084 case BB:
1085 fmt = 12;
1086 break;
1087 case LDO:
1088 case LDB:
1089 case LDH:
1090 case LDW:
1091 case LDWM:
1092 case STB:
1093 case STH:
1094 case STW:
1095 case STWM:
1096 fmt = 14;
1097 break;
1098 case BL:
1099 case BE:
1100 case BLE:
1101 fmt = 17;
1102 break;
1103 case LDIL:
1104 case ADDIL:
1105 fmt = 21;
1106 break;
1107 default:
1108 fmt = 32;
1109 break;
1110 }
1111
1112 }
1113 return fmt;
1114 }
1115
1116 /* this function is in charge of performing all the HP PA relocations */
1117 long global_value = 0;
1118 long GOT_value = 0; /* XXX: need to calculate this! For HPUX, GOT == DP */
1119 asymbol *global_symbol = (asymbol *)NULL;
1120
1121 static bfd_reloc_status_type
1122 DEFUN(hppa_elf_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
1123 bfd *abfd AND
1124 arelent *reloc_entry AND
1125 asymbol *symbol_in AND
1126 PTR data AND
1127 asection *input_section AND
1128 bfd *output_bfd)
1129 {
1130 unsigned long insn;
1131 long sym_value = 0;
1132 unsigned long unsigned_value;
1133 long signed_value;
1134
1135 unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
1136 bfd_byte *hit_data = addr + (bfd_byte *)(data);
1137 unsigned short r_type = reloc_entry->howto->type & 0xFF;
1138 unsigned short r_field = e_fsel;
1139 boolean r_pcrel = reloc_entry->howto->pc_relative;
1140
1141 /* howto->bitsize contains the format (11, 14, 21, etc) information */
1142 unsigned r_format = reloc_entry->howto->bitsize;
1143 long r_addend = reloc_entry->addend;
1144
1145
1146 if (output_bfd) {
1147 /* Partial linking - do nothing */
1148 reloc_entry->address += input_section->output_offset;
1149 return bfd_reloc_ok;
1150 }
1151
1152 if ( symbol_in && symbol_in->section == &bfd_und_section )
1153 return bfd_reloc_undefined;
1154
1155 sym_value = get_symbol_value(symbol_in);
1156
1157 /* compute value of $global$ if it is there. */
1158
1159 if ( global_symbol == (asymbol *)NULL ) {
1160 struct elf_backend_data * bed
1161 = (struct elf_backend_data *)abfd->xvec->backend_data;
1162
1163 if ( bed && bed->global_sym ) {
1164 asymbol *gsym = &bed->global_sym->symbol;
1165 global_value
1166 = gsym->value
1167 + gsym->section->output_section->vma
1168 + gsym->section->output_offset;
1169 GOT_value = global_value; /* XXX: For HP-UX, GOT==DP */
1170 global_symbol = gsym;
1171 }
1172 }
1173
1174 /* get the instruction word */
1175 insn = bfd_get_32(abfd, hit_data);
1176
1177 /* relocate the value based on the relocation type */
1178
1179 /* basic_type_1: relocation is relative to $global$ */
1180 /* basic_type_2: relocation is relative to the current GOT */
1181 /* basic_type_3: relocation is an absolute call */
1182 /* basic_type_4: relocation is an PC-relative call */
1183 /* basic_type_5: relocation is plabel reference */
1184 /* basic_type_6: relocation is an unwind table relocation */
1185 /* extended_type: unimplemented */
1186
1187 switch ( r_type ) {
1188 case R_HPPA_NONE:
1189 break;
1190 case R_HPPA_32: /* Symbol + Addend 32 */
1191
1192 r_field = e_fsel;
1193 goto do_basic_type_1;
1194 case R_HPPA_L21: /* L (Symbol, Addend) 21 */
1195 r_field = e_lsel;
1196 goto do_basic_type_1;
1197 case R_HPPA_R11: /* R (Symbol, Addend) 11 */
1198 r_field = e_rsel;
1199 goto do_basic_type_1;
1200 case R_HPPA_R14: /* R (Symbol, Addend) 14 */
1201 r_field = e_rsel;
1202 goto do_basic_type_1;
1203 case R_HPPA_R17: /* R (Symbol, Addend) 17 */
1204 r_field = e_rsel;
1205 goto do_basic_type_1;
1206 case R_HPPA_LS21: /* LS(Symbol, Addend) 21 */
1207 r_field = e_lssel;
1208 goto do_basic_type_1;
1209 case R_HPPA_RS11: /* RS(Symbol, Addend) 11 */
1210 r_field = e_rssel;
1211 goto do_basic_type_1;
1212 case R_HPPA_RS14: /* RS(Symbol, Addend) 14 */
1213 r_field = e_rssel;
1214 goto do_basic_type_1;
1215 case R_HPPA_RS17: /* RS(Symbol, Addend) 17 */
1216 r_field = e_ldsel;
1217 goto do_basic_type_1;
1218 case R_HPPA_LD21: /* LD(Symbol, Addend) 21 */
1219 r_field = e_ldsel;
1220 goto do_basic_type_1;
1221 case R_HPPA_RD11: /* RD(Symbol, Addend) 11 */
1222 r_field = e_rdsel;
1223 goto do_basic_type_1;
1224 case R_HPPA_RD14: /* RD(Symbol, Addend) 14 */
1225 r_field = e_rdsel;
1226 goto do_basic_type_1;
1227 case R_HPPA_RD17: /* RD(Symbol, Addend) 17 */
1228 r_field = e_rdsel;
1229 goto do_basic_type_1;
1230 case R_HPPA_LR21: /* LR(Symbol, Addend) 21 */
1231 r_field = e_lrsel;
1232 goto do_basic_type_1;
1233 case R_HPPA_RR14: /* RR(Symbol, Addend) 14 */
1234 r_field = e_rrsel;
1235 goto do_basic_type_1;
1236 case R_HPPA_RR17: /* RR(Symbol, Addend) 17 */
1237 r_field = e_rrsel;
1238
1239 do_basic_type_1:
1240 insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr,
1241 symbol_in, sym_value, r_addend,
1242 r_type, r_format, r_field, r_pcrel);
1243 break;
1244
1245 case R_HPPA_GOTOFF_11: /* Symbol - GOT + Addend 11 */
1246 r_field = e_fsel;
1247 goto do_basic_type_2;
1248 case R_HPPA_GOTOFF_14: /* Symbol - GOT + Addend 14 */
1249 r_field = e_fsel;
1250 goto do_basic_type_2;
1251 case R_HPPA_GOTOFF_L21: /* L (Sym - GOT, Addend) 21 */
1252 r_field = e_lsel;
1253 goto do_basic_type_2;
1254 case R_HPPA_GOTOFF_R11: /* R (Sym - GOT, Addend) 11 */
1255 r_field = e_rsel;
1256 goto do_basic_type_2;
1257 case R_HPPA_GOTOFF_R14: /* R (Sym - GOT, Addend) 14 */
1258 r_field = e_rsel;
1259 goto do_basic_type_2;
1260 case R_HPPA_GOTOFF_LS21: /* LS(Sym - GOT, Addend) 21 */
1261 r_field = e_lssel;
1262 goto do_basic_type_2;
1263 case R_HPPA_GOTOFF_RS11: /* RS(Sym - GOT, Addend) 11 */
1264 r_field = e_rssel;
1265 goto do_basic_type_2;
1266 case R_HPPA_GOTOFF_RS14: /* RS(Sym - GOT, Addend) 14 */
1267 r_field = e_rssel;
1268 goto do_basic_type_2;
1269 case R_HPPA_GOTOFF_LD21: /* LD(Sym - GOT, Addend) 21 */
1270 r_field = e_ldsel;
1271 goto do_basic_type_2;
1272 case R_HPPA_GOTOFF_RD11: /* RD(Sym - GOT, Addend) 11 */
1273 r_field = e_rdsel;
1274 goto do_basic_type_2;
1275 case R_HPPA_GOTOFF_RD14: /* RD(Sym - GOT, Addend) 14 */
1276 r_field = e_rdsel;
1277 goto do_basic_type_2;
1278 case R_HPPA_GOTOFF_LR21: /* LR(Sym - GOT, Addend) 21 */
1279 r_field = e_lrsel;
1280 goto do_basic_type_2;
1281 case R_HPPA_GOTOFF_RR14: /* RR(Sym - GOT, Addend) 14 */
1282 r_field = e_rrsel;
1283 do_basic_type_2:
1284 sym_value -= GOT_value;
1285 insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr,
1286 symbol_in, sym_value, r_addend,
1287 r_type, r_format, r_field, r_pcrel);
1288 break;
1289
1290 case R_HPPA_ABS_CALL_11: /* Symbol + Addend 11 */
1291 r_field = e_fsel;
1292 goto do_basic_type_3;
1293 case R_HPPA_ABS_CALL_14: /* Symbol + Addend 14 */
1294 r_field = e_fsel;
1295 goto do_basic_type_3;
1296 case R_HPPA_ABS_CALL_17: /* Symbol + Addend 17 */
1297 r_field = e_fsel;
1298 goto do_basic_type_3;
1299 case R_HPPA_ABS_CALL_L21: /* L (Symbol, Addend) 21 */
1300 r_field = e_lsel;
1301 goto do_basic_type_3;
1302 case R_HPPA_ABS_CALL_R11: /* R (Symbol, Addend) 11 */
1303 r_field = e_rsel;
1304 goto do_basic_type_3;
1305 case R_HPPA_ABS_CALL_R14: /* R (Symbol, Addend) 14 */
1306 r_field = e_rsel;
1307 goto do_basic_type_3;
1308 case R_HPPA_ABS_CALL_R17: /* R (Symbol, Addend) 17 */
1309 r_field = e_rsel;
1310 goto do_basic_type_3;
1311 case R_HPPA_ABS_CALL_LS21: /* LS(Symbol, Addend) 21 */
1312 r_field = e_lssel;
1313 goto do_basic_type_3;
1314 case R_HPPA_ABS_CALL_RS11: /* RS(Symbol, Addend) 11 */
1315 r_field = e_lssel;
1316 goto do_basic_type_3;
1317 case R_HPPA_ABS_CALL_RS14: /* RS(Symbol, Addend) 14 */
1318 r_field = e_rssel;
1319 goto do_basic_type_3;
1320 case R_HPPA_ABS_CALL_RS17: /* RS(Symbol, Addend) 17 */
1321 r_field = e_rssel;
1322 goto do_basic_type_3;
1323 case R_HPPA_ABS_CALL_LD21: /* LD(Symbol, Addend) 21 */
1324 r_field = e_ldsel;
1325 goto do_basic_type_3;
1326 case R_HPPA_ABS_CALL_RD11: /* RD(Symbol, Addend) 11 */
1327 r_field = e_rdsel;
1328 goto do_basic_type_3;
1329 case R_HPPA_ABS_CALL_RD14: /* RD(Symbol, Addend) 14 */
1330 r_field = e_rdsel;
1331 goto do_basic_type_3;
1332 case R_HPPA_ABS_CALL_RD17: /* RD(Symbol, Addend) 17 */
1333 r_field = e_rdsel;
1334 goto do_basic_type_3;
1335 case R_HPPA_ABS_CALL_LR21: /* LR(Symbol, Addend) 21 */
1336 r_field = e_lrsel;
1337 goto do_basic_type_3;
1338 case R_HPPA_ABS_CALL_RR14: /* RR(Symbol, Addend) 14 */
1339 r_field = e_rrsel;
1340 goto do_basic_type_3;
1341 case R_HPPA_ABS_CALL_RR17: /* RR(Symbol, Addend) 17 */
1342 r_field = e_rrsel;
1343 do_basic_type_3:
1344 insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr,
1345 symbol_in, sym_value, r_addend,
1346 r_type, r_format, r_field, r_pcrel);
1347 break;
1348
1349 case R_HPPA_PCREL_CALL_11: /* Symbol - PC + Addend 11 */
1350 r_field = e_fsel;
1351 goto do_basic_type_4;
1352 case R_HPPA_PCREL_CALL_14: /* Symbol - PC + Addend 14 */
1353 r_field = e_fsel;
1354 goto do_basic_type_4;
1355 case R_HPPA_PCREL_CALL_17: /* Symbol - PC + Addend 17 */
1356 r_field = e_fsel;
1357 goto do_basic_type_4;
1358 case R_HPPA_PCREL_CALL_L21: /* L (Symbol - PC, Addend) 21 */
1359 r_field = e_lsel;
1360 goto do_basic_type_4;
1361 case R_HPPA_PCREL_CALL_R11: /* R (Symbol - PC, Addend) 11 */
1362 r_field = e_rsel;
1363 goto do_basic_type_4;
1364 case R_HPPA_PCREL_CALL_R14: /* R (Symbol - PC, Addend) 14 */
1365 r_field = e_rsel;
1366 goto do_basic_type_4;
1367 case R_HPPA_PCREL_CALL_R17: /* R (Symbol - PC, Addend) 17 */
1368 r_field = e_rsel;
1369 goto do_basic_type_4;
1370 case R_HPPA_PCREL_CALL_LS21: /* LS(Symbol - PC, Addend) 21 */
1371 r_field = e_lssel;
1372 goto do_basic_type_4;
1373 case R_HPPA_PCREL_CALL_RS11: /* RS(Symbol - PC, Addend) 11 */
1374 r_field = e_rssel;
1375 goto do_basic_type_4;
1376 case R_HPPA_PCREL_CALL_RS14: /* RS(Symbol - PC, Addend) 14 */
1377 r_field = e_rssel;
1378 goto do_basic_type_4;
1379 case R_HPPA_PCREL_CALL_RS17: /* RS(Symbol - PC, Addend) 17 */
1380 r_field = e_rssel;
1381 goto do_basic_type_4;
1382 case R_HPPA_PCREL_CALL_LD21: /* LD(Symbol - PC, Addend) 21 */
1383 r_field = e_ldsel;
1384 goto do_basic_type_4;
1385 case R_HPPA_PCREL_CALL_RD11: /* RD(Symbol - PC, Addend) 11 */
1386 r_field = e_rdsel;
1387 goto do_basic_type_4;
1388 case R_HPPA_PCREL_CALL_RD14: /* RD(Symbol - PC, Addend) 14 */
1389 r_field = e_rdsel;
1390 goto do_basic_type_4;
1391 case R_HPPA_PCREL_CALL_RD17: /* RD(Symbol - PC, Addend) 17 */
1392 r_field = e_rdsel;
1393 goto do_basic_type_4;
1394 case R_HPPA_PCREL_CALL_LR21: /* LR(Symbol - PC, Addend) 21 */
1395 r_field = e_lrsel;
1396 goto do_basic_type_4;
1397 case R_HPPA_PCREL_CALL_RR14: /* RR(Symbol - PC, Addend) 14 */
1398 r_field = e_rrsel;
1399 goto do_basic_type_4;
1400 case R_HPPA_PCREL_CALL_RR17: /* RR(Symbol - PC, Addend) 17 */ /* #69 */
1401 r_field = e_rrsel;
1402 do_basic_type_4:
1403 insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr,
1404 symbol_in, sym_value, r_addend,
1405 r_type, r_format, r_field, r_pcrel);
1406 break;
1407
1408 case R_HPPA_PLABEL_32:
1409 case R_HPPA_PLABEL_11:
1410 case R_HPPA_PLABEL_14:
1411 r_field = e_fsel;
1412 goto do_basic_type_5;
1413 case R_HPPA_PLABEL_L21:
1414 r_field = e_lsel;
1415 goto do_basic_type_5;
1416 case R_HPPA_PLABEL_R11:
1417 case R_HPPA_PLABEL_R14:
1418 r_field = e_rsel;
1419 do_basic_type_5:
1420 insn = hppa_elf_relocate_insn(abfd, input_section, insn, addr,
1421 symbol_in, sym_value, r_addend,
1422 r_type, r_format, r_field, r_pcrel);
1423 break;
1424
1425 case R_HPPA_UNWIND_ENTRY:
1426 case R_HPPA_UNWIND_ENTRIES:
1427 hppa_elf_relocate_unwind_table(abfd, input_section, data, addr,
1428 symbol_in, sym_value, r_addend,
1429 r_type, r_format, r_field, r_pcrel);
1430 return (bfd_reloc_ok);
1431
1432 case R_HPPA_PUSH_CONST: /* push Addend - - */
1433 case R_HPPA_PUSH_SYM: /* push Symbol - - */
1434 case R_HPPA_PUSH_GOT: /* push GOT - - */
1435 case R_HPPA_PUSH_PC: /* push PC - - */
1436 case R_HPPA_PUSH_PROC: /* push Symbol - - */
1437 case R_HPPA_PUSH_PLABEL: /* [TBD] - - */
1438 case R_HPPA_MAX: /* pop A and B, push max(B,A) - - */
1439 case R_HPPA_MIN: /* pop A and B, push min(B,A) - - */
1440 case R_HPPA_ADD: /* pop A and B, push B + A - - */
1441 case R_HPPA_SUB: /* pop A and B, push B - A - - */
1442 case R_HPPA_MULT: /* pop A and B, push B * A - - */
1443 case R_HPPA_DIV: /* pop A and B, push B / A - - */
1444 case R_HPPA_MOD: /* pop A and B, push B % A - - */
1445 case R_HPPA_AND: /* pop A and B, push B & A - - */
1446 case R_HPPA_OR: /* pop A and B, push B | A - - */
1447 case R_HPPA_XOR: /* pop A and B, push B ^ A - - */
1448 case R_HPPA_NOT: /* pop A, push ~A - - */
1449 case R_HPPA_LSHIFT: /* pop A, push A << Addend - - */
1450 case R_HPPA_ARITH_RSHIFT: /* pop A, push A >> Addend - - */
1451 case R_HPPA_LOGIC_RSHIFT: /* pop A, push A >> Addend - - */
1452 case R_HPPA_EXPR_F: /* pop A, push A + Addend L - */
1453 case R_HPPA_EXPR_L: /* pop A, push L(A,Addend) L - */
1454 case R_HPPA_EXPR_R: /* pop A, push R(A,Addend) R - */
1455 case R_HPPA_EXPR_LS: /* pop A, push LS(A,Addend) LS - */
1456 case R_HPPA_EXPR_RS: /* pop A, push RS(A,Addend) RS - */
1457 case R_HPPA_EXPR_LD: /* pop A, push LD(A,Addend) LD - */
1458 case R_HPPA_EXPR_RD: /* pop A, push RD(A,Addend) RD - */
1459 case R_HPPA_EXPR_LR: /* pop A, push LR(A,Addend) LR - */
1460 case R_HPPA_EXPR_RR: /* pop A, push RR(A,Addend) RR - */
1461
1462 case R_HPPA_EXPR_32: /* pop - 32 */
1463 case R_HPPA_EXPR_21: /* pop - 21 */
1464 case R_HPPA_EXPR_11: /* pop - 11 */
1465 case R_HPPA_EXPR_14: /* pop - 14 */
1466 case R_HPPA_EXPR_17: /* pop - 17 */
1467 case R_HPPA_EXPR_12: /* pop - 12 */
1468 fprintf(stderr, "Relocation problem: ");
1469 fprintf(stderr,"Unimplemented reloc type %d, in module %s\n",
1470 r_type,abfd->filename);
1471 return(bfd_reloc_notsupported);
1472 default:
1473 fprintf(stderr,"Relocation problem : ");
1474 fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
1475 r_type,abfd->filename);
1476 return (bfd_reloc_dangerous);
1477 }
1478
1479 /* update the instruction word */
1480 bfd_put_32(abfd, insn ,hit_data);
1481
1482 return (bfd_reloc_ok);
1483
1484 }
1485
1486 static reloc_howto_type *
1487 elf_hppa_reloc_type_lookup (arch, code)
1488 bfd_arch_info_type *arch;
1489 bfd_reloc_code_real_type code;
1490 {
1491 if ( code < R_HPPA_UNIMPLEMENTED ) {
1492 return &elf_hppa_howto_table[code];
1493 }
1494
1495 return (reloc_howto_type *)0;
1496 }
1497
1498 #include "elfcode.h"
1499
1500 bfd_target elf_big_vec =
1501 {
1502 /* name: identify kind of target */
1503 "elf-big",
1504
1505 /* flavour: general indication about file */
1506 bfd_target_elf_flavour,
1507
1508 /* byteorder_big_p: data is big endian */
1509 true,
1510
1511 /* header_byteorder_big_p: header is also big endian */
1512 true,
1513
1514 /* object_flags: mask of all file flags */
1515 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
1516 DYNAMIC | WP_TEXT),
1517
1518 /* section_flags: mask of all section flags */
1519 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
1520 SEC_CODE | SEC_DATA),
1521
1522 /* ar_pad_char: pad character for filenames within an archive header
1523 FIXME: this really has nothing to do with ELF, this is a characteristic
1524 of the archiver and/or os and should be independently tunable */
1525 '/',
1526
1527 /* ar_max_namelen: maximum number of characters in an archive header
1528 FIXME: this really has nothing to do with ELF, this is a characteristic
1529 of the archiver and should be independently tunable. This value is
1530 a WAG (wild a** guess) */
1531 15,
1532
1533 /* align_power_min: minimum alignment restriction for any section
1534 FIXME: this value may be target machine dependent */
1535 3,
1536
1537 /* Routines to byte-swap various sized integers from the data sections */
1538 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,
1539
1540 /* Routines to byte-swap various sized integers from the file headers */
1541 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,
1542
1543 /* bfd_check_format: check the format of a file being read */
1544 { _bfd_dummy_target, /* unknown format */
1545 elf_object_p, /* assembler/linker output (object file) */
1546 bfd_generic_archive_p, /* an archive */
1547 elf_core_file_p /* a core file */
1548 },
1549
1550 /* bfd_set_format: set the format of a file being written */
1551 { bfd_false,
1552 elf_mkobject,
1553 _bfd_generic_mkarchive,
1554 bfd_false
1555 },
1556
1557 /* bfd_write_contents: write cached information into a file being written */
1558 { bfd_false,
1559 elf_write_object_contents,
1560 _bfd_write_archive_contents,
1561 bfd_false
1562 },
1563
1564 /* Initialize a jump table with the standard macro. All names start
1565 with "elf" */
1566 JUMP_TABLE(elf),
1567
1568 /* SWAP_TABLE */
1569 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1570 elf_hppa_reloc_type_lookup,
1571 NULL, /* _bfd_make_debug_symbol */
1572 (PTR)&elf_hppa_backend_data
1573 };
1574
1575 bfd_target elf_little_vec =
1576 {
1577 /* name: identify kind of target */
1578 "elf-little",
1579
1580 /* flavour: general indication about file */
1581 bfd_target_elf_flavour,
1582
1583 /* byteorder_big_p: data is big endian */
1584 false, /* Nope -- this one's little endian */
1585
1586 /* header_byteorder_big_p: header is also big endian */
1587 false, /* Nope -- this one's little endian */
1588
1589 /* object_flags: mask of all file flags */
1590 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
1591 DYNAMIC | WP_TEXT),
1592
1593 /* section_flags: mask of all section flags */
1594 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
1595 SEC_DATA),
1596
1597 /* ar_pad_char: pad character for filenames within an archive header
1598 FIXME: this really has nothing to do with ELF, this is a characteristic
1599 of the archiver and/or os and should be independently tunable */
1600 '/',
1601
1602 /* ar_max_namelen: maximum number of characters in an archive header
1603 FIXME: this really has nothing to do with ELF, this is a characteristic
1604 of the archiver and should be independently tunable. This value is
1605 a WAG (wild a** guess) */
1606 15,
1607
1608 /* align_power_min: minimum alignment restriction for any section
1609 FIXME: this value may be target machine dependent */
1610 3,
1611
1612 /* Routines to byte-swap various sized integers from the data sections */
1613 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16,
1614
1615 /* Routines to byte-swap various sized integers from the file headers */
1616 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16,
1617
1618 /* bfd_check_format: check the format of a file being read */
1619 { _bfd_dummy_target, /* unknown format */
1620 elf_object_p, /* assembler/linker output (object file) */
1621 bfd_generic_archive_p, /* an archive */
1622 elf_core_file_p /* a core file */
1623 },
1624
1625 /* bfd_set_format: set the format of a file being written */
1626 { bfd_false,
1627 elf_mkobject,
1628 _bfd_generic_mkarchive,
1629 bfd_false
1630 },
1631
1632 /* bfd_write_contents: write cached information into a file being written */
1633 { bfd_false,
1634 elf_write_object_contents,
1635 _bfd_write_archive_contents,
1636 bfd_false
1637 },
1638
1639 /* Initialize a jump table with the standard macro. All names start
1640 with "elf" */
1641 JUMP_TABLE(elf),
1642
1643 /* SWAP_TABLE */
1644 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1645 elf_hppa_reloc_type_lookup,
1646 NULL, /* _bfd_make_debug_symbol */
1647 (PTR)&elf_hppa_backend_data
1648 };