aba6531bb3eb2bb843315466acf817dc4f8ef317
[deliverable/binutils-gdb.git] / bfd / som.c
1 /* bfd back-end for HP PA-RISC SOM objects.
2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25
26 #if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
27
28 #include "libbfd.h"
29 #include "som.h"
30 #include "libhppa.h"
31
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/dir.h>
36 #include <signal.h>
37 #include <machine/reg.h>
38 #include <sys/user.h> /* After a.out.h */
39 #include <sys/file.h>
40 #include <errno.h>
41
42 /* Magic not defined in standard HP-UX header files until 8.0 */
43
44 #ifndef CPU_PA_RISC1_0
45 #define CPU_PA_RISC1_0 0x20B
46 #endif /* CPU_PA_RISC1_0 */
47
48 #ifndef CPU_PA_RISC1_1
49 #define CPU_PA_RISC1_1 0x210
50 #endif /* CPU_PA_RISC1_1 */
51
52 #ifndef _PA_RISC1_0_ID
53 #define _PA_RISC1_0_ID CPU_PA_RISC1_0
54 #endif /* _PA_RISC1_0_ID */
55
56 #ifndef _PA_RISC1_1_ID
57 #define _PA_RISC1_1_ID CPU_PA_RISC1_1
58 #endif /* _PA_RISC1_1_ID */
59
60 #ifndef _PA_RISC_MAXID
61 #define _PA_RISC_MAXID 0x2FF
62 #endif /* _PA_RISC_MAXID */
63
64 #ifndef _PA_RISC_ID
65 #define _PA_RISC_ID(__m_num) \
66 (((__m_num) == _PA_RISC1_0_ID) || \
67 ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
68 #endif /* _PA_RISC_ID */
69
70 /* SOM allows any one of the four previous relocations to be reused
71 with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP
72 relocations are always a single byte, using a R_PREV_FIXUP instead
73 of some multi-byte relocation makes object files smaller.
74
75 Note one side effect of using a R_PREV_FIXUP is the relocation that
76 is being repeated moves to the front of the queue. */
77 struct reloc_queue
78 {
79 unsigned char *reloc;
80 unsigned int size;
81 } reloc_queue[4];
82
83 /* This fully describes the symbol types which may be attached to
84 an EXPORT or IMPORT directive. Only SOM uses this formation
85 (ELF has no need for it). */
86 typedef enum
87 {
88 SYMBOL_TYPE_UNKNOWN,
89 SYMBOL_TYPE_ABSOLUTE,
90 SYMBOL_TYPE_CODE,
91 SYMBOL_TYPE_DATA,
92 SYMBOL_TYPE_ENTRY,
93 SYMBOL_TYPE_MILLICODE,
94 SYMBOL_TYPE_PLABEL,
95 SYMBOL_TYPE_PRI_PROG,
96 SYMBOL_TYPE_SEC_PROG,
97 } pa_symbol_type;
98
99 /* Forward declarations */
100
101 static boolean som_mkobject PARAMS ((bfd *));
102 static bfd_target * som_object_setup PARAMS ((bfd *,
103 struct header *,
104 struct som_exec_auxhdr *));
105 static asection * make_unique_section PARAMS ((bfd *, CONST char *, int));
106 static boolean setup_sections PARAMS ((bfd *, struct header *));
107 static bfd_target * som_object_p PARAMS ((bfd *));
108 static boolean som_write_object_contents PARAMS ((bfd *));
109 static boolean som_slurp_string_table PARAMS ((bfd *));
110 static unsigned int som_slurp_symbol_table PARAMS ((bfd *));
111 static unsigned int som_get_symtab_upper_bound PARAMS ((bfd *));
112 static unsigned int som_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
113 arelent **, asymbol **));
114 static unsigned int som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
115 static unsigned int som_get_symtab PARAMS ((bfd *, asymbol **));
116 static asymbol * som_make_empty_symbol PARAMS ((bfd *));
117 static void som_print_symbol PARAMS ((bfd *, PTR,
118 asymbol *, bfd_print_symbol_type));
119 static boolean som_new_section_hook PARAMS ((bfd *, asection *));
120 static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
121 file_ptr, bfd_size_type));
122 static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
123 unsigned long));
124 static boolean som_find_nearest_line PARAMS ((bfd *, asection *,
125 asymbol **, bfd_vma,
126 CONST char **,
127 CONST char **,
128 unsigned int *));
129 static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
130 static asection * som_section_from_subspace_index PARAMS ((bfd *,
131 unsigned int));
132 static int log2 PARAMS ((unsigned int));
133 static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *,
134 asymbol *, PTR,
135 asection *, bfd *));
136
137 static reloc_howto_type som_hppa_howto_table[] =
138 {
139 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
140 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
141 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
142 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
143 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
144 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
145 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
146 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
147 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
148 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
149 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
150 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
151 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
152 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
153 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
154 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
155 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
156 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
157 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
158 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
159 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
160 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
161 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
162 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
163 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
164 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
165 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
166 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
167 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
168 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
169 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
170 {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
171 {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
172 {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
173 {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
174 {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
175 {R_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RELOCATION"},
176 {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
177 {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
178 {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
179 {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
180 {R_SPACE_REF, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SPACE_REF"},
181 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
182 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
183 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
184 {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
185 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
186 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
187 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
188 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
189 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
190 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
191 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
192 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
193 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
194 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
195 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
196 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
197 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
198 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
199 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
200 {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
201 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
202 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
203 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
204 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
205 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
206 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
207 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
208 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
209 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
210 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
211 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
212 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
213 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
214 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
215 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
216 {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
217 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
218 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
219 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
220 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
221 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
222 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
223 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
224 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
225 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
226 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
227 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
228 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
229 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
230 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
231 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
232 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
233 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
234 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
235 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
236 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
237 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
238 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
239 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
240 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
241 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
242 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
243 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
244 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
245 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
246 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
247 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
248 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
249 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
250 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
251 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
252 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
253 {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
254 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
255 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
256 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
257 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
258 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
259 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
260 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
261 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
262 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
263 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
264 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
265 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
266 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
267 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
268 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
269 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
270 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
271 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
272 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
273 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
274 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
275 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
276 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
277 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
278 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
279 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
280 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
281 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
282 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
283 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
284 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
285 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
286 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
287 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
288 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
289 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
290 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
291 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
292 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
293 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
294 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
295 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
296 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
297 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
298 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
299 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
300 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
301 {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
302 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
303 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
304 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
305 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
306 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
307 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
308 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
309 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
310 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
311 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
312 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
313 {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
314 {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
315 {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
316 {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
317 {R_BREAKPOINT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BREAKPOINT"},
318 {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
319 {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
320 {R_ALT_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ALT_ENTRY"},
321 {R_EXIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_EXIT"},
322 {R_BEGIN_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_TRY"},
323 {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
324 {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
325 {R_BEGIN_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_BRTAB"},
326 {R_END_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_BRTAB"},
327 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
328 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
329 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
330 {R_DATA_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_EXPR"},
331 {R_CODE_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_EXPR"},
332 {R_FSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_FSEL"},
333 {R_LSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LSEL"},
334 {R_RSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RSEL"},
335 {R_N_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N_MODE"},
336 {R_S_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_S_MODE"},
337 {R_D_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_D_MODE"},
338 {R_R_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_R_MODE"},
339 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
340 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
341 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
342 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
343 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
344 {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
345 {R_TRANSLATED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_TRANSLATED"},
346 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
347 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
348 {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
349 {R_COMP1, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP1"},
350 {R_COMP2, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP2"},
351 {R_COMP3, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP3"},
352 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
353 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
354 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
355 {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
356 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
357 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
358 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
359 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
360 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
361 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
362 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
363 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
364 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
365 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
366 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
367 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
368 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
369 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
370 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
371 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
372 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
373 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
374 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
375 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
376 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
377 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
378 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
379 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
380 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
381 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
382 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
383 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
384 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
385 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
386 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
387 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
388 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
389 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
390 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
391 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
392 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
393 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
394 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
395 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
396 {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}};
397
398 /* Return the logarithm of X, base 2, considering X unsigned.
399 Abort if X is not a power of two -- this should never happen (FIXME:
400 It will happen on corrupt executables. GDB should give an error, not
401 a coredump, in that case). */
402
403 static int
404 log2 (x)
405 unsigned int x;
406 {
407 int log = 0;
408
409 /* Test for 0 or a power of 2. */
410 if (x == 0 || x != (x & -x))
411 abort();
412
413 while ((x >>= 1) != 0)
414 log++;
415 return log;
416 }
417
418 static bfd_reloc_status_type
419 hppa_som_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
420 bfd *abfd;
421 arelent *reloc_entry;
422 asymbol *symbol_in;
423 PTR data;
424 asection *input_section;
425 bfd *output_bfd;
426 {
427 if (output_bfd)
428 {
429 reloc_entry->address += input_section->output_offset;
430 return bfd_reloc_ok;
431 }
432 return bfd_reloc_ok;
433 }
434
435 /* Perform some initialization for an object. Save results of this
436 initialization in the BFD. */
437
438 static bfd_target *
439 som_object_setup (abfd, file_hdrp, aux_hdrp)
440 bfd *abfd;
441 struct header *file_hdrp;
442 struct som_exec_auxhdr *aux_hdrp;
443 {
444 asection *text, *data, *bss;
445
446 /* som_mkobject will set bfd_error if som_mkobject fails. */
447 if (som_mkobject (abfd) != true)
448 return 0;
449
450 /* Make the standard .text, .data, and .bss sections so that tools
451 which assume those names work (size for example). They will have
452 no contents, but the sizes and such will reflect those of the
453 $CODE$, $DATA$, and $BSS$ subspaces respectively.
454
455 FIXME: Should check return status from bfd_make_section calls below. */
456
457 text = bfd_make_section (abfd, ".text");
458 data = bfd_make_section (abfd, ".data");
459 bss = bfd_make_section (abfd, ".bss");
460
461 text->_raw_size = aux_hdrp->exec_tsize;
462 data->_raw_size = aux_hdrp->exec_dsize;
463 bss->_raw_size = aux_hdrp->exec_bsize;
464
465 text->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_CODE);
466 data->flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS);
467 bss->flags = (SEC_ALLOC | SEC_IS_COMMON);
468
469 /* The virtual memory addresses of the sections */
470 text->vma = aux_hdrp->exec_tmem;
471 data->vma = aux_hdrp->exec_dmem;
472 bss->vma = aux_hdrp->exec_bfill;
473
474 /* The file offsets of the sections */
475 text->filepos = aux_hdrp->exec_tfile;
476 data->filepos = aux_hdrp->exec_dfile;
477
478 /* The file offsets of the relocation info */
479 text->rel_filepos = 0;
480 data->rel_filepos = 0;
481
482 /* Set BFD flags based on what information is available in the SOM. */
483 abfd->flags = NO_FLAGS;
484 if (! file_hdrp->entry_offset)
485 abfd->flags |= HAS_RELOC;
486 else
487 abfd->flags |= EXEC_P;
488 if (file_hdrp->symbol_total)
489 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
490
491 bfd_get_start_address (abfd) = aux_hdrp->exec_entry;
492 bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 0);
493 bfd_get_symcount (abfd) = file_hdrp->symbol_total;
494
495 /* Initialize the saved symbol table and string table to NULL.
496 Save important offsets and sizes from the SOM header into
497 the BFD. */
498 obj_som_stringtab (abfd) = (char *) NULL;
499 obj_som_symtab (abfd) = (som_symbol_type *) NULL;
500 obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
501 obj_som_sym_filepos (abfd) = file_hdrp->symbol_location;
502 obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location;
503 obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location;
504
505 return abfd->xvec;
506 }
507
508 /* Create a new BFD section for NAME. If NAME already exists, then create a
509 new unique name, with NAME as the prefix. This exists because SOM .o files
510 may have more than one $CODE$ subspace. */
511
512 static asection *
513 make_unique_section (abfd, name, num)
514 bfd *abfd;
515 CONST char *name;
516 int num;
517 {
518 asection *sect;
519 char *newname;
520 char altname[100];
521
522 sect = bfd_make_section (abfd, name);
523 while (!sect)
524 {
525 sprintf (altname, "%s-%d", name, num++);
526 sect = bfd_make_section (abfd, altname);
527 }
528
529 newname = bfd_alloc (abfd, strlen (sect->name) + 1);
530 strcpy (newname, sect->name);
531
532 sect->name = newname;
533 return sect;
534 }
535
536 /* Convert all of the space and subspace info into BFD sections. Each space
537 contains a number of subspaces, which in turn describe the mapping between
538 regions of the exec file, and the address space that the program runs in.
539 BFD sections which correspond to spaces will overlap the sections for the
540 associated subspaces. */
541
542 static boolean
543 setup_sections (abfd, file_hdr)
544 bfd *abfd;
545 struct header *file_hdr;
546 {
547 char *space_strings;
548 int space_index;
549 unsigned int total_subspaces = 0;
550
551 /* First, read in space names */
552
553 space_strings = alloca (file_hdr->space_strings_size);
554 if (!space_strings)
555 return false;
556
557 if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0)
558 return false;
559 if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
560 != file_hdr->space_strings_size)
561 return false;
562
563 /* Loop over all of the space dictionaries, building up sections */
564 for (space_index = 0; space_index < file_hdr->space_total; space_index++)
565 {
566 struct space_dictionary_record space;
567 struct subspace_dictionary_record subspace, save_subspace;
568 int subspace_index;
569 asection *space_asect;
570
571 /* Read the space dictionary element */
572 if (bfd_seek (abfd, file_hdr->space_location
573 + space_index * sizeof space, SEEK_SET) < 0)
574 return false;
575 if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
576 return false;
577
578 /* Setup the space name string */
579 space.name.n_name = space.name.n_strx + space_strings;
580
581 /* Make a section out of it */
582 space_asect = make_unique_section (abfd, space.name.n_name, space_index);
583 if (!space_asect)
584 return false;
585
586 /* Now, read in the first subspace for this space */
587 if (bfd_seek (abfd, file_hdr->subspace_location
588 + space.subspace_index * sizeof subspace,
589 SEEK_SET) < 0)
590 return false;
591 if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
592 return false;
593 /* Seek back to the start of the subspaces for loop below */
594 if (bfd_seek (abfd, file_hdr->subspace_location
595 + space.subspace_index * sizeof subspace,
596 SEEK_SET) < 0)
597 return false;
598
599 /* Setup the start address and file loc from the first subspace record */
600 space_asect->vma = subspace.subspace_start;
601 space_asect->filepos = subspace.file_loc_init_value;
602 space_asect->alignment_power = log2 (subspace.alignment);
603
604 /* Initialize save_subspace so we can reliably determine if this
605 loop placed any useful values into it. */
606 bzero (&save_subspace, sizeof (struct subspace_dictionary_record));
607
608 /* Loop over the rest of the subspaces, building up more sections */
609 for (subspace_index = 0; subspace_index < space.subspace_quantity;
610 subspace_index++)
611 {
612 asection *subspace_asect;
613
614 /* Read in the next subspace */
615 if (bfd_read (&subspace, 1, sizeof subspace, abfd)
616 != sizeof subspace)
617 return false;
618
619 /* Setup the subspace name string */
620 subspace.name.n_name = subspace.name.n_strx + space_strings;
621
622 /* Make a section out of this subspace */
623 subspace_asect = make_unique_section (abfd, subspace.name.n_name,
624 space.subspace_index + subspace_index);
625
626 if (!subspace_asect)
627 return false;
628
629 /* Keep an easy mapping between subspaces and sections. */
630 som_section_data (subspace_asect)->subspace_index
631 = total_subspaces++;
632
633 /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
634 by the access_control_bits in the subspace header. */
635 switch (subspace.access_control_bits >> 4)
636 {
637 /* Readonly data. */
638 case 0x0:
639 subspace_asect->flags |= SEC_DATA | SEC_READONLY;
640 break;
641
642 /* Normal data. */
643 case 0x1:
644 subspace_asect->flags |= SEC_DATA;
645 break;
646
647 /* Readonly code and the gateways.
648 Gateways have other attributes which do not map
649 into anything BFD knows about. */
650 case 0x2:
651 case 0x4:
652 case 0x5:
653 case 0x6:
654 case 0x7:
655 subspace_asect->flags |= SEC_CODE | SEC_READONLY;
656 break;
657
658 /* dynamic (writable) code. */
659 case 0x3:
660 subspace_asect->flags |= SEC_CODE;
661 break;
662 }
663
664 if (subspace.dup_common || subspace.is_common)
665 subspace_asect->flags |= SEC_IS_COMMON;
666 else
667 subspace_asect->flags |= SEC_HAS_CONTENTS;
668 if (subspace.is_loadable)
669 subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
670 if (subspace.code_only)
671 subspace_asect->flags |= SEC_CODE;
672
673 /* This subspace has relocations.
674 The fixup_request_quantity is a byte count for the number of
675 entries in the relocation stream; it is not the actual number
676 of relocations in the subspace. */
677 if (subspace.fixup_request_quantity != 0)
678 {
679 subspace_asect->flags |= SEC_RELOC;
680 subspace_asect->rel_filepos = subspace.fixup_request_index;
681 som_section_data (subspace_asect)->reloc_size
682 = subspace.fixup_request_quantity;
683 /* We can not determine this yet. When we read in the
684 relocation table the correct value will be filled in. */
685 subspace_asect->reloc_count = -1;
686 }
687
688 /* Update save_subspace if appropriate. */
689 if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
690 save_subspace = subspace;
691
692 subspace_asect->vma = subspace.subspace_start;
693 subspace_asect->_cooked_size = subspace.subspace_length;
694 subspace_asect->_raw_size = subspace.initialization_length;
695 subspace_asect->alignment_power = log2 (subspace.alignment);
696 subspace_asect->filepos = subspace.file_loc_init_value;
697 }
698
699 /* Yow! there is no subspace within the space which actually
700 has initialized information in it; this should never happen
701 as far as I know. */
702 if (!save_subspace.file_loc_init_value)
703 abort ();
704
705 /* Setup the sizes for the space section based upon the info in the
706 last subspace of the space. */
707 space_asect->_cooked_size = save_subspace.subspace_start
708 - space_asect->vma + save_subspace.subspace_length;
709 space_asect->_raw_size = save_subspace.file_loc_init_value
710 - space_asect->filepos + save_subspace.initialization_length;
711 }
712 return true;
713 }
714
715 /* Read in a SOM object and make it into a BFD. */
716
717 static bfd_target *
718 som_object_p (abfd)
719 bfd *abfd;
720 {
721 struct header file_hdr;
722 struct som_exec_auxhdr aux_hdr;
723
724 if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
725 {
726 bfd_error = system_call_error;
727 return 0;
728 }
729
730 if (!_PA_RISC_ID (file_hdr.system_id))
731 {
732 bfd_error = wrong_format;
733 return 0;
734 }
735
736 switch (file_hdr.a_magic)
737 {
738 case RELOC_MAGIC:
739 case EXEC_MAGIC:
740 case SHARE_MAGIC:
741 case DEMAND_MAGIC:
742 #ifdef DL_MAGIC
743 case DL_MAGIC:
744 #endif
745 #ifdef SHL_MAGIC
746 case SHL_MAGIC:
747 #endif
748 #ifdef EXECLIBMAGIC
749 case EXECLIBMAGIC:
750 #endif
751 break;
752 default:
753 bfd_error = wrong_format;
754 return 0;
755 }
756
757 if (file_hdr.version_id != VERSION_ID
758 && file_hdr.version_id != NEW_VERSION_ID)
759 {
760 bfd_error = wrong_format;
761 return 0;
762 }
763
764 /* If the aux_header_size field in the file header is zero, then this
765 object is an incomplete executable (a .o file). Do not try to read
766 a non-existant auxiliary header. */
767 bzero (&aux_hdr, sizeof (struct som_exec_auxhdr));
768 if (file_hdr.aux_header_size != 0)
769 {
770 if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
771 {
772 bfd_error = wrong_format;
773 return 0;
774 }
775 }
776
777 if (!setup_sections (abfd, &file_hdr))
778 {
779 /* setup_sections does not bubble up a bfd error code. */
780 bfd_error = bad_value;
781 return 0;
782 }
783
784 /* This appears to be a valid SOM object. Do some initialization. */
785 return som_object_setup (abfd, &file_hdr, &aux_hdr);
786 }
787
788 /* Create a SOM object. */
789
790 static boolean
791 som_mkobject (abfd)
792 bfd *abfd;
793 {
794 /* Allocate memory to hold backend information. */
795 abfd->tdata.som_data = (struct som_data_struct *)
796 bfd_zalloc (abfd, sizeof (struct som_data_struct));
797 if (abfd->tdata.som_data == NULL)
798 {
799 bfd_error = no_memory;
800 return false;
801 }
802 obj_som_file_hdr (abfd) = bfd_zalloc (abfd, sizeof (struct header));
803 if (obj_som_file_hdr (abfd) == NULL)
804
805 {
806 bfd_error = no_memory;
807 return false;
808 }
809 return true;
810 }
811
812 boolean
813 som_write_object_contents (abfd)
814 bfd *abfd;
815 {
816 fprintf (stderr, "som_write_object_contents unimplemented\n");
817 fflush (stderr);
818 abort ();
819 return (false);
820 }
821 /* Read and save the string table associated with the given BFD. */
822
823 static boolean
824 som_slurp_string_table (abfd)
825 bfd *abfd;
826 {
827 char *stringtab;
828
829 /* Use the saved version if its available. */
830 if (obj_som_stringtab (abfd) != NULL)
831 return true;
832
833 /* Allocate and read in the string table. */
834 stringtab = bfd_zalloc (abfd, obj_som_stringtab_size (abfd));
835 if (stringtab == NULL)
836 {
837 bfd_error = no_memory;
838 return false;
839 }
840
841 if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
842 {
843 bfd_error = system_call_error;
844 return false;
845 }
846
847 if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
848 != obj_som_stringtab_size (abfd))
849 {
850 bfd_error = system_call_error;
851 return false;
852 }
853
854 /* Save our results and return success. */
855 obj_som_stringtab (abfd) = stringtab;
856 return true;
857 }
858
859 /* Return the amount of data (in bytes) required to hold the symbol
860 table for this object. */
861
862 static unsigned int
863 som_get_symtab_upper_bound (abfd)
864 bfd *abfd;
865 {
866 if (!som_slurp_symbol_table (abfd))
867 return 0;
868
869 return (bfd_get_symcount (abfd) + 1) * (sizeof (som_symbol_type *));
870 }
871
872 /* Convert from a SOM subspace index to a BFD section. */
873
874 static asection *
875 som_section_from_subspace_index (abfd, index)
876 bfd *abfd;
877 unsigned int index;
878 {
879 asection *section;
880
881 for (section = abfd->sections; section != NULL; section = section->next)
882 if (som_section_data (section)->subspace_index == index)
883 return section;
884
885 /* Should never happen. */
886 abort();
887 }
888
889 /* Read and save the symbol table associated with the given BFD. */
890
891 static unsigned int
892 som_slurp_symbol_table (abfd)
893 bfd *abfd;
894 {
895 int symbol_count = bfd_get_symcount (abfd);
896 int symsize = sizeof (struct symbol_dictionary_record);
897 char *stringtab;
898 struct symbol_dictionary_record *buf, *bufp, *endbufp;
899 som_symbol_type *sym, *symbase;
900
901 /* Return saved value if it exists. */
902 if (obj_som_symtab (abfd) != NULL)
903 return true;
904
905 /* Sanity checking. Make sure there are some symbols and that
906 we can read the string table too. */
907 if (symbol_count == 0)
908 {
909 bfd_error = no_symbols;
910 return false;
911 }
912
913 if (!som_slurp_string_table (abfd))
914 return false;
915
916 stringtab = obj_som_stringtab (abfd);
917
918 symbase = (som_symbol_type *)
919 bfd_zalloc (abfd, symbol_count * sizeof (som_symbol_type));
920 if (symbase == NULL)
921 {
922 bfd_error = no_memory;
923 return false;
924 }
925
926 /* Read in the external SOM representation. */
927 buf = alloca (symbol_count * symsize);
928 if (buf == NULL)
929 {
930 bfd_error = no_memory;
931 return false;
932 }
933 if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
934 {
935 bfd_error = system_call_error;
936 return false;
937 }
938 if (bfd_read (buf, symbol_count * symsize, 1, abfd)
939 != symbol_count * symsize)
940 {
941 bfd_error = no_symbols;
942 return (false);
943 }
944
945 /* Iterate over all the symbols and internalize them. */
946 endbufp = buf + symbol_count;
947 for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
948 {
949
950 /* I don't think we care about these. */
951 if (bufp->symbol_type == ST_SYM_EXT
952 || bufp->symbol_type == ST_ARG_EXT)
953 continue;
954
955 /* Some reasonable defaults. */
956 sym->symbol.the_bfd = abfd;
957 sym->symbol.name = bufp->name.n_strx + stringtab;
958 sym->symbol.value = bufp->symbol_value;
959 sym->symbol.section = 0;
960 sym->symbol.flags = 0;
961
962 switch (bufp->symbol_type)
963 {
964 case ST_ENTRY:
965 sym->symbol.flags |= BSF_FUNCTION;
966 sym->symbol.value &= ~0x3;
967 break;
968
969 case ST_PRI_PROG:
970 case ST_SEC_PROG:
971 case ST_STUB:
972 case ST_MILLICODE:
973 case ST_CODE:
974 sym->symbol.value &= ~0x3;
975
976 default:
977 break;
978 }
979
980 /* Handle scoping and section information. */
981 switch (bufp->symbol_scope)
982 {
983 /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
984 so the section associated with this symbol can't be known. */
985 case SS_EXTERNAL:
986 case SS_UNSAT:
987 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
988 break;
989
990 case SS_UNIVERSAL:
991 sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
992 sym->symbol.section
993 = som_section_from_subspace_index (abfd, bufp->symbol_info);
994 sym->symbol.value -= sym->symbol.section->vma;
995 break;
996
997 #if 0
998 /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
999 Sound dumb? It is. */
1000 case SS_GLOBAL:
1001 #endif
1002 case SS_LOCAL:
1003 sym->symbol.flags |= BSF_LOCAL;
1004 sym->symbol.section
1005 = som_section_from_subspace_index (abfd, bufp->symbol_info);
1006 sym->symbol.value -= sym->symbol.section->vma;
1007 break;
1008 }
1009
1010 /* Mark symbols left around by the debugger. */
1011 if (strlen (sym->symbol.name) >= 3
1012 && sym->symbol.name[0] == 'L'
1013 && (sym->symbol.name[2] == '$' || sym->symbol.name[3] == '$'))
1014 sym->symbol.flags |= BSF_DEBUGGING;
1015
1016 /* Note increment at bottom of loop, since we skip some symbols
1017 we can not include it as part of the for statement. */
1018 sym++;
1019 }
1020
1021 /* Save our results and return success. */
1022 obj_som_symtab (abfd) = symbase;
1023 return (true);
1024 }
1025
1026 /* Canonicalize a SOM symbol table. Return the number of entries
1027 in the symbol table. */
1028
1029 static unsigned int
1030 som_get_symtab (abfd, location)
1031 bfd *abfd;
1032 asymbol **location;
1033 {
1034 int i;
1035 som_symbol_type *symbase;
1036
1037 if (!som_slurp_symbol_table (abfd))
1038 return 0;
1039
1040 i = bfd_get_symcount (abfd);
1041 symbase = obj_som_symtab (abfd);
1042
1043 for (; i > 0; i--, location++, symbase++)
1044 *location = &symbase->symbol;
1045
1046 /* Final null pointer. */
1047 *location = 0;
1048 return (bfd_get_symcount (abfd));
1049 }
1050
1051 /* Make a SOM symbol. There is nothing special to do here. */
1052
1053 static asymbol *
1054 som_make_empty_symbol (abfd)
1055 bfd *abfd;
1056 {
1057 som_symbol_type *new =
1058 (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
1059 if (new == NULL)
1060 {
1061 bfd_error = no_memory;
1062 return 0;
1063 }
1064 new->symbol.the_bfd = abfd;
1065
1066 return &new->symbol;
1067 }
1068
1069 /* Print symbol information. */
1070
1071 static void
1072 som_print_symbol (ignore_abfd, afile, symbol, how)
1073 bfd *ignore_abfd;
1074 PTR afile;
1075 asymbol *symbol;
1076 bfd_print_symbol_type how;
1077 {
1078 FILE *file = (FILE *) afile;
1079 switch (how)
1080 {
1081 case bfd_print_symbol_name:
1082 fprintf (file, "%s", symbol->name);
1083 break;
1084 case bfd_print_symbol_more:
1085 fprintf (file, "som ");
1086 fprintf_vma (file, symbol->value);
1087 fprintf (file, " %lx", (long) symbol->flags);
1088 break;
1089 case bfd_print_symbol_all:
1090 {
1091 CONST char *section_name;
1092 section_name = symbol->section ? symbol->section->name : "(*none*)";
1093 bfd_print_symbol_vandf ((PTR) file, symbol);
1094 fprintf (file, " %s\t%s", section_name, symbol->name);
1095 break;
1096 }
1097 }
1098 }
1099
1100 static unsigned int
1101 som_get_reloc_upper_bound (abfd, asect)
1102 bfd *abfd;
1103 sec_ptr asect;
1104 {
1105 fprintf (stderr, "som_get_reloc_upper_bound unimplemented\n");
1106 fflush (stderr);
1107 abort ();
1108 return (0);
1109 }
1110
1111 static unsigned int
1112 som_canonicalize_reloc (abfd, section, relptr, symbols)
1113 bfd *abfd;
1114 sec_ptr section;
1115 arelent **relptr;
1116 asymbol **symbols;
1117 {
1118 fprintf (stderr, "som_canonicalize_reloc unimplemented\n");
1119 fflush (stderr);
1120 abort ();
1121 }
1122
1123 extern bfd_target som_vec;
1124
1125 /* A hook to set up object file dependent section information. */
1126
1127 static boolean
1128 som_new_section_hook (abfd, newsect)
1129 bfd *abfd;
1130 asection *newsect;
1131 {
1132 newsect->used_by_bfd = (struct som_section_data_struct *)
1133 bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
1134 newsect->alignment_power = 3;
1135
1136 /* Initialize the subspace_index field to -1 so that it does
1137 not match a subspace with an index of 0. */
1138 som_section_data (newsect)->subspace_index = -1;
1139
1140 /* We allow more than three sections internally */
1141 return true;
1142 }
1143
1144 /* Set backend info for sections which can not be described
1145 in the BFD data structures. */
1146
1147 void
1148 bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
1149 asection *section;
1150 char defined;
1151 char private;
1152 unsigned char sort_key;
1153 int spnum;
1154 {
1155 struct space_dictionary_record *space_dict;
1156
1157 som_section_data (section)->is_space = 1;
1158 space_dict = &som_section_data (section)->space_dict;
1159 space_dict->is_defined = defined;
1160 space_dict->is_private = private;
1161 space_dict->sort_key = sort_key;
1162 space_dict->space_number = spnum;
1163 }
1164
1165 /* Set backend info for subsections which can not be described
1166 in the BFD data structures. */
1167
1168 void
1169 bfd_som_set_subsection_attributes (section, container, access,
1170 sort_key, quadrant)
1171 asection *section;
1172 asection *container;
1173 int access;
1174 unsigned char sort_key;
1175 int quadrant;
1176 {
1177 struct subspace_dictionary_record *subspace_dict;
1178 som_section_data (section)->is_subspace = 1;
1179 subspace_dict = &som_section_data (section)->subspace_dict;
1180 subspace_dict->access_control_bits = access;
1181 subspace_dict->sort_key = sort_key;
1182 subspace_dict->quadrant = quadrant;
1183 som_section_data (section)->containing_space = container;
1184 }
1185
1186 /* Set the full SOM symbol type. SOM needs far more symbol information
1187 than any other object file format I'm aware of. It is mandatory
1188 to be able to know if a symbol is an entry point, millicode, data,
1189 code, absolute, storage request, or procedure label. If you get
1190 the symbol type wrong your program will not link. */
1191
1192 void
1193 bfd_som_set_symbol_type (symbol, type)
1194 asymbol *symbol;
1195 unsigned int type;
1196 {
1197 (*som_symbol_data (symbol))->som_type = type;
1198 }
1199
1200 /* Attach 64bits of unwind information to a symbol (which hopefully
1201 is a function of some kind!). It would be better to keep this
1202 in the R_ENTRY relocation, but there is not enough space. */
1203
1204 void
1205 bfd_som_attach_unwind_info (symbol, unwind_desc)
1206 asymbol *symbol;
1207 char *unwind_desc;
1208 {
1209 (*som_symbol_data (symbol))->unwind = unwind_desc;
1210 }
1211
1212 static boolean
1213 som_set_section_contents (abfd, section, location, offset, count)
1214 bfd *abfd;
1215 sec_ptr section;
1216 PTR location;
1217 file_ptr offset;
1218 bfd_size_type count;
1219 {
1220 fprintf (stderr, "som_set_section_contents unimplimented\n");
1221 fflush (stderr);
1222 abort ();
1223 return false;
1224 }
1225
1226 static boolean
1227 som_set_arch_mach (abfd, arch, machine)
1228 bfd *abfd;
1229 enum bfd_architecture arch;
1230 unsigned long machine;
1231 {
1232 fprintf (stderr, "som_set_arch_mach unimplemented\n");
1233 fflush (stderr);
1234 /* Allow any architecture to be supported by the som backend */
1235 return bfd_default_set_arch_mach (abfd, arch, machine);
1236 }
1237
1238 static boolean
1239 som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
1240 functionname_ptr, line_ptr)
1241 bfd *abfd;
1242 asection *section;
1243 asymbol **symbols;
1244 bfd_vma offset;
1245 CONST char **filename_ptr;
1246 CONST char **functionname_ptr;
1247 unsigned int *line_ptr;
1248 {
1249 fprintf (stderr, "som_find_nearest_line unimplemented\n");
1250 fflush (stderr);
1251 abort ();
1252 return (false);
1253 }
1254
1255 static int
1256 som_sizeof_headers (abfd, reloc)
1257 bfd *abfd;
1258 boolean reloc;
1259 {
1260 fprintf (stderr, "som_sizeof_headers unimplemented\n");
1261 fflush (stderr);
1262 abort ();
1263 return (0);
1264 }
1265
1266 /* Return information about SOM symbol SYMBOL in RET. */
1267
1268 static void
1269 som_get_symbol_info (ignore_abfd, symbol, ret)
1270 bfd *ignore_abfd; /* Ignored. */
1271 asymbol *symbol;
1272 symbol_info *ret;
1273 {
1274 bfd_symbol_info (symbol, ret);
1275 }
1276
1277 /* End of miscellaneous support functions. */
1278
1279 #define som_bfd_debug_info_start bfd_void
1280 #define som_bfd_debug_info_end bfd_void
1281 #define som_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1282
1283 #define som_openr_next_archived_file bfd_generic_openr_next_archived_file
1284 #define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
1285 #define som_slurp_armap bfd_false
1286 #define som_slurp_extended_name_table _bfd_slurp_extended_name_table
1287 #define som_truncate_arname (void (*)())bfd_nullvoidptr
1288 #define som_write_armap 0
1289
1290 #define som_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1291 #define som_close_and_cleanup bfd_generic_close_and_cleanup
1292 #define som_get_section_contents bfd_generic_get_section_contents
1293
1294 #define som_bfd_get_relocated_section_contents \
1295 bfd_generic_get_relocated_section_contents
1296 #define som_bfd_relax_section bfd_generic_relax_section
1297 #define som_bfd_seclet_link bfd_generic_seclet_link
1298 #define som_bfd_reloc_type_lookup \
1299 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
1300 #define som_bfd_make_debug_symbol \
1301 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
1302
1303 /* Core file support is in the hpux-core backend. */
1304 #define som_core_file_failing_command _bfd_dummy_core_file_failing_command
1305 #define som_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1306 #define som_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
1307
1308 bfd_target som_vec =
1309 {
1310 "som", /* name */
1311 bfd_target_som_flavour,
1312 true, /* target byte order */
1313 true, /* target headers byte order */
1314 (HAS_RELOC | EXEC_P | /* object flags */
1315 HAS_LINENO | HAS_DEBUG |
1316 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1317 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
1318 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1319
1320 /* leading_symbol_char: is the first char of a user symbol
1321 predictable, and if so what is it */
1322 0,
1323 ' ', /* ar_pad_char */
1324 16, /* ar_max_namelen */
1325 3, /* minimum alignment */
1326 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1327 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1328 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
1329 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1330 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1331 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1332 {_bfd_dummy_target,
1333 som_object_p, /* bfd_check_format */
1334 bfd_generic_archive_p,
1335 _bfd_dummy_target
1336 },
1337 {
1338 bfd_false,
1339 som_mkobject,
1340 _bfd_generic_mkarchive,
1341 bfd_false
1342 },
1343 {
1344 bfd_false,
1345 som_write_object_contents,
1346 _bfd_write_archive_contents,
1347 bfd_false,
1348 },
1349 #undef som
1350 JUMP_TABLE (som),
1351 (PTR) 0
1352 };
1353
1354 #endif /* HOST_HPPAHPUX || HOST_HPPABSD */
This page took 0.067721 seconds and 4 git commands to generate.