]>
Commit | Line | Data |
---|---|---|
252b5132 RH |
1 | /* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and |
2 | EVAX (openVMS/Alpha) files. | |
0c376465 TG |
3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, |
4 | 2008, 2009 Free Software Foundation, Inc. | |
252b5132 RH |
5 | |
6 | TIR record handling functions | |
7 | ETIR record handling functions | |
8 | ||
0c376465 | 9 | Go and read the openVMS linker manual (esp. appendix B) |
252b5132 RH |
10 | if you don't know what's going on here :-) |
11 | ||
12 | Written by Klaus K"ampf ([email protected]) | |
13 | ||
ca09e32b NC |
14 | This program is free software; you can redistribute it and/or modify |
15 | it under the terms of the GNU General Public License as published by | |
cd123cb7 | 16 | the Free Software Foundation; either version 3 of the License, or |
ca09e32b | 17 | (at your option) any later version. |
252b5132 | 18 | |
ca09e32b NC |
19 | This program is distributed in the hope that it will be useful, |
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | GNU General Public License for more details. | |
252b5132 | 23 | |
ca09e32b NC |
24 | You should have received a copy of the GNU General Public License |
25 | along with this program; if not, write to the Free Software | |
cd123cb7 NC |
26 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
27 | MA 02110-1301, USA. */ | |
28 | ||
252b5132 RH |
29 | /* The following type abbreviations are used: |
30 | ||
31 | cs counted string (ascii string with length byte) | |
32 | by byte (1 byte) | |
33 | sh short (2 byte, 16 bit) | |
34 | lw longword (4 byte, 32 bit) | |
35 | qw quadword (8 byte, 64 bit) | |
36 | da data stream */ | |
37 | ||
252b5132 | 38 | #include "sysdep.h" |
3db64b00 | 39 | #include "bfd.h" |
252b5132 RH |
40 | #include "bfdlink.h" |
41 | #include "libbfd.h" | |
252b5132 | 42 | #include "vms.h" |
0c376465 TG |
43 | |
44 | static int check_section (bfd *, int); | |
45 | static void image_set_ptr (bfd *abfd, int psect, uquad offset); | |
46 | static void image_inc_ptr (bfd *abfd, uquad offset); | |
47 | static void dst_define_location (bfd *abfd, uquad loc); | |
48 | static void dst_restore_location (bfd *abfd, uquad loc); | |
49 | static unsigned int dst_retrieve_location (bfd *abfd, uquad loc); | |
50 | static void dst_check_allocation (bfd *abfd, unsigned int size); | |
51 | static void image_dump (bfd *abfd, unsigned char *ptr, int size, int offset); | |
52 | static void image_write_b (bfd *abfd, unsigned int value); | |
53 | static void image_write_w (bfd *abfd, unsigned int value); | |
54 | static void image_write_l (bfd *abfd, unsigned long value); | |
55 | static void image_write_q (bfd *abfd, uquad value); | |
56 | static bfd_boolean etir_sta (bfd *, int, unsigned char *, int *); | |
57 | static bfd_boolean etir_sto (bfd *, int, unsigned char *, int *); | |
58 | static bfd_boolean etir_opr (bfd *, int, unsigned char *, int *); | |
59 | static bfd_boolean etir_ctl (bfd *, int, unsigned char *, int *); | |
60 | static bfd_boolean etir_stc (bfd *, int, unsigned char *, int *); | |
61 | static asection *new_section (bfd *, int); | |
62 | static int alloc_section (bfd *, unsigned int); | |
63 | static int etir_cmd (bfd *, int, unsigned char *, int *); | |
64 | static int analyze_tir (bfd *, unsigned char *, unsigned int); | |
65 | static int analyze_etir (bfd *, unsigned char *, unsigned int); | |
66 | static unsigned char *tir_opr (bfd *, unsigned char *); | |
67 | static const char *tir_cmd_name (int); | |
68 | static const char *cmd_name (int); | |
69 | ||
ca09e32b | 70 | \f |
252b5132 | 71 | static int |
7920ce38 | 72 | check_section (bfd * abfd, int size) |
252b5132 | 73 | { |
dc810e39 | 74 | bfd_size_type offset; |
252b5132 | 75 | |
dc810e39 | 76 | offset = PRIV (image_ptr) - PRIV (image_section)->contents; |
eea6121a | 77 | if (offset + size > PRIV (image_section)->size) |
252b5132 | 78 | { |
dc810e39 | 79 | PRIV (image_section)->contents |
515ef31d NC |
80 | = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size); |
81 | if (PRIV (image_section)->contents == NULL) | |
252b5132 RH |
82 | { |
83 | (*_bfd_error_handler) (_("No Mem !")); | |
84 | return -1; | |
85 | } | |
eea6121a | 86 | PRIV (image_section)->size = offset + size; |
dc810e39 | 87 | PRIV (image_ptr) = PRIV (image_section)->contents + offset; |
252b5132 RH |
88 | } |
89 | ||
90 | return 0; | |
91 | } | |
92 | ||
ca09e32b | 93 | /* Routines to fill sections contents during tir/etir read. */ |
252b5132 | 94 | |
ca09e32b | 95 | /* Initialize image buffer pointer to be filled. */ |
252b5132 RH |
96 | |
97 | static void | |
7920ce38 | 98 | image_set_ptr (bfd * abfd, int psect, uquad offset) |
252b5132 RH |
99 | { |
100 | #if VMS_DEBUG | |
101 | _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n", | |
dc810e39 | 102 | psect, PRIV (sections)[psect]->name, offset); |
252b5132 RH |
103 | #endif |
104 | ||
dc810e39 AM |
105 | PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset; |
106 | PRIV (image_section) = PRIV (sections)[psect]; | |
252b5132 RH |
107 | } |
108 | ||
ca09e32b | 109 | /* Increment image buffer pointer by offset. */ |
252b5132 RH |
110 | |
111 | static void | |
7920ce38 | 112 | image_inc_ptr (bfd * abfd, uquad offset) |
252b5132 RH |
113 | { |
114 | #if VMS_DEBUG | |
115 | _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset); | |
116 | #endif | |
117 | ||
dc810e39 | 118 | PRIV (image_ptr) += offset; |
252b5132 RH |
119 | } |
120 | ||
0c376465 TG |
121 | /* Save current DST location counter under specified index. */ |
122 | ||
123 | static void | |
124 | dst_define_location (bfd *abfd, uquad loc) | |
125 | { | |
126 | asection *dst_section = PRIV (dst_section); | |
127 | ||
128 | #if VMS_DEBUG | |
129 | _bfd_vms_debug (4, "dst_define_location (%d)\n", (int)loc); | |
130 | #endif | |
131 | ||
132 | /* Grow the ptr offset table if necessary. */ | |
133 | if (loc + 1 > PRIV (dst_ptr_offsets_count)) | |
134 | { | |
135 | PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets), | |
136 | (loc + 1) * sizeof (unsigned int)); | |
137 | PRIV (dst_ptr_offsets_count) = loc + 1; | |
138 | } | |
139 | ||
140 | PRIV (dst_ptr_offsets)[loc] = PRIV (image_ptr) - dst_section->contents; | |
141 | } | |
142 | ||
143 | /* Restore saved DST location counter from specified index. */ | |
144 | ||
145 | static void | |
146 | dst_restore_location (bfd *abfd, uquad loc) | |
147 | { | |
148 | asection *dst_section = PRIV (dst_section); | |
149 | ||
150 | #if VMS_DEBUG | |
151 | _bfd_vms_debug (4, "dst_restore_location (%d)\n", (int)loc); | |
152 | #endif | |
153 | ||
154 | PRIV (image_ptr) = dst_section->contents + PRIV (dst_ptr_offsets)[loc]; | |
155 | } | |
156 | ||
157 | /* Retrieve saved DST location counter from specified index. */ | |
158 | ||
159 | static unsigned int | |
160 | dst_retrieve_location (bfd *abfd, uquad loc) | |
161 | { | |
162 | #if VMS_DEBUG | |
163 | _bfd_vms_debug (4, "dst_retrieve_location (%d)\n", (int)loc); | |
164 | #endif | |
165 | ||
166 | return PRIV (dst_ptr_offsets)[loc]; | |
167 | } | |
168 | ||
169 | /* Check that the DST section is big enough for the specified | |
170 | amount of bytes. */ | |
171 | ||
172 | static void | |
173 | dst_check_allocation (bfd *abfd, unsigned int size) | |
174 | { | |
175 | asection *dst_section = PRIV (dst_section); | |
176 | ||
177 | bfd_size_type used = PRIV (image_ptr) - dst_section->contents; | |
178 | bfd_size_type left = dst_section->size - used; | |
179 | ||
180 | /* Grow the DST section as necessary */ | |
181 | if (size > left) | |
182 | { | |
183 | dst_section->size *= 2; | |
184 | dst_section->contents | |
185 | = bfd_realloc (dst_section->contents, dst_section->size); | |
186 | PRIV (image_ptr) = dst_section->contents + used; | |
187 | ||
188 | dst_check_allocation (abfd, size); | |
189 | } | |
190 | } | |
191 | ||
ca09e32b | 192 | /* Dump multiple bytes to section image. */ |
252b5132 RH |
193 | |
194 | static void | |
7920ce38 NC |
195 | image_dump (bfd * abfd, |
196 | unsigned char *ptr, | |
197 | int size, | |
198 | int offset ATTRIBUTE_UNUSED) | |
252b5132 RH |
199 | { |
200 | #if VMS_DEBUG | |
dc810e39 AM |
201 | _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size, |
202 | PRIV (image_ptr)); | |
252b5132 RH |
203 | _bfd_hexdump (9, ptr, size, offset); |
204 | #endif | |
205 | ||
dc810e39 | 206 | if (PRIV (is_vax) && check_section (abfd, size)) |
252b5132 RH |
207 | return; |
208 | ||
0c376465 TG |
209 | if (PRIV (dst_section)) |
210 | dst_check_allocation (abfd, size); | |
211 | ||
252b5132 | 212 | while (size-- > 0) |
dc810e39 | 213 | *PRIV (image_ptr)++ = *ptr++; |
252b5132 RH |
214 | } |
215 | ||
ca09e32b | 216 | /* Write byte to section image. */ |
252b5132 RH |
217 | |
218 | static void | |
7920ce38 | 219 | image_write_b (bfd * abfd, unsigned int value) |
252b5132 RH |
220 | { |
221 | #if VMS_DEBUG | |
7920ce38 | 222 | _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value); |
252b5132 RH |
223 | #endif |
224 | ||
dc810e39 | 225 | if (PRIV (is_vax) && check_section (abfd, 1)) |
252b5132 RH |
226 | return; |
227 | ||
0c376465 TG |
228 | if (PRIV (dst_section)) |
229 | dst_check_allocation (abfd, 1); | |
230 | ||
dc810e39 | 231 | *PRIV (image_ptr)++ = (value & 0xff); |
252b5132 RH |
232 | } |
233 | ||
ca09e32b | 234 | /* Write 2-byte word to image. */ |
252b5132 RH |
235 | |
236 | static void | |
7920ce38 | 237 | image_write_w (bfd * abfd, unsigned int value) |
252b5132 RH |
238 | { |
239 | #if VMS_DEBUG | |
7920ce38 | 240 | _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value); |
252b5132 RH |
241 | #endif |
242 | ||
dc810e39 | 243 | if (PRIV (is_vax) && check_section (abfd, 2)) |
252b5132 RH |
244 | return; |
245 | ||
0c376465 TG |
246 | if (PRIV (dst_section)) |
247 | dst_check_allocation (abfd, 2); | |
248 | ||
dc810e39 AM |
249 | bfd_putl16 ((bfd_vma) value, PRIV (image_ptr)); |
250 | PRIV (image_ptr) += 2; | |
252b5132 RH |
251 | } |
252 | ||
ca09e32b | 253 | /* Write 4-byte long to image. */ |
252b5132 RH |
254 | |
255 | static void | |
7920ce38 | 256 | image_write_l (bfd * abfd, unsigned long value) |
252b5132 RH |
257 | { |
258 | #if VMS_DEBUG | |
259 | _bfd_vms_debug (6, "image_write_l (%08lx)\n", value); | |
260 | #endif | |
261 | ||
dc810e39 | 262 | if (PRIV (is_vax) && check_section (abfd, 4)) |
252b5132 RH |
263 | return; |
264 | ||
0c376465 TG |
265 | if (PRIV (dst_section)) |
266 | dst_check_allocation (abfd, 4); | |
267 | ||
dc810e39 AM |
268 | bfd_putl32 ((bfd_vma) value, PRIV (image_ptr)); |
269 | PRIV (image_ptr) += 4; | |
252b5132 RH |
270 | } |
271 | ||
ca09e32b | 272 | /* Write 8-byte quad to image. */ |
252b5132 RH |
273 | |
274 | static void | |
7920ce38 | 275 | image_write_q (bfd * abfd, uquad value) |
252b5132 RH |
276 | { |
277 | #if VMS_DEBUG | |
278 | _bfd_vms_debug (6, "image_write_q (%016lx)\n", value); | |
279 | #endif | |
280 | ||
dc810e39 | 281 | if (PRIV (is_vax) && check_section (abfd, 8)) |
252b5132 RH |
282 | return; |
283 | ||
0c376465 TG |
284 | if (PRIV (dst_section)) |
285 | dst_check_allocation (abfd, 8); | |
286 | ||
dc810e39 AM |
287 | bfd_putl64 (value, PRIV (image_ptr)); |
288 | PRIV (image_ptr) += 8; | |
252b5132 RH |
289 | } |
290 | \f | |
ca09e32b | 291 | static const char * |
7920ce38 | 292 | cmd_name (int cmd) |
ca09e32b NC |
293 | { |
294 | switch (cmd) | |
295 | { | |
296 | case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL"; | |
0c376465 TG |
297 | case ETIR_S_C_STA_LW: return "ETIR_S_C_STA_LW"; |
298 | case ETIR_S_C_STA_QW: return "ETIR_S_C_STA_QW"; | |
ca09e32b NC |
299 | case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ"; |
300 | case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI"; | |
301 | case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD"; | |
302 | case ETIR_S_C_STA_CKARG: return "ETIR_S_C_STA_CKARG"; | |
303 | case ETIR_S_C_STO_B: return "ETIR_S_C_STO_B"; | |
304 | case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W"; | |
305 | case ETIR_S_C_STO_GBL: return "ETIR_S_C_STO_GBL"; | |
306 | case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA"; | |
307 | case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB"; | |
308 | case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB"; | |
0c376465 TG |
309 | case ETIR_S_C_STO_OFF: return "ETIR_S_C_STO_OFF"; |
310 | case ETIR_S_C_STO_IMM: return "ETIR_S_C_STO_IMM"; | |
311 | case ETIR_S_C_STO_IMMR: return "ETIR_S_C_STO_IMMR"; | |
312 | case ETIR_S_C_STO_LW: return "ETIR_S_C_STO_LW"; | |
313 | case ETIR_S_C_STO_QW: return "ETIR_S_C_STO_QW"; | |
ca09e32b NC |
314 | case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW"; |
315 | case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB"; | |
316 | case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL"; | |
317 | case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS"; | |
0c376465 | 318 | case ETIR_S_C_OPR_ADD: return "ETIR_S_C_OPR_ADD"; |
ca09e32b NC |
319 | case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV"; |
320 | case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH"; | |
321 | case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT"; | |
322 | case ETIR_S_C_OPR_REDEF: return "ETIR_S_C_OPR_REDEF"; | |
323 | case ETIR_S_C_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT"; | |
324 | case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP"; | |
325 | case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL"; | |
326 | case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA"; | |
327 | case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS"; | |
328 | case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS"; | |
329 | case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL"; | |
330 | case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS"; | |
331 | case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL"; | |
332 | case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS"; | |
333 | case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL"; | |
334 | case ETIR_S_C_STC_LDA_PS: return "ETIR_S_C_STC_LDA_PS"; | |
335 | case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL"; | |
336 | case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS"; | |
337 | case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL"; | |
0c376465 TG |
338 | case ETIR_S_C_CTL_SETRB: return "ETIR_S_C_CTL_SETRB"; |
339 | case ETIR_S_C_STC_LP_PSB: return "ETIR_S_C_STC_LP_PSB"; | |
340 | case ETIR_S_C_CTL_DFLOC: return "ETIR_S_C_CTL_DFLOC"; | |
341 | case ETIR_S_C_CTL_STLOC: return "ETIR_S_C_CTL_STLOC"; | |
342 | case ETIR_S_C_CTL_STKDL: return "ETIR_S_C_CTL_STKDL"; | |
252b5132 | 343 | |
ca09e32b NC |
344 | default: |
345 | /* These names have not yet been added to this switch statement. */ | |
0c376465 | 346 | (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd); |
ca09e32b | 347 | } |
0c376465 TG |
348 | |
349 | return NULL; | |
ca09e32b | 350 | } |
252b5132 RH |
351 | #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L) |
352 | ||
353 | /* etir_sta | |
672579e9 | 354 | |
0c376465 | 355 | Vms stack commands. |
672579e9 | 356 | |
0c376465 TG |
357 | Handle sta_xxx commands in etir section, |
358 | ptr points to data area in record. | |
672579e9 | 359 | |
0c376465 | 360 | See table B-8 of the openVMS linker manual. */ |
252b5132 | 361 | |
b34976b6 | 362 | static bfd_boolean |
0c376465 | 363 | etir_sta (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs) |
252b5132 | 364 | { |
252b5132 RH |
365 | #if VMS_DEBUG |
366 | _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd); | |
0c376465 | 367 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
368 | #endif |
369 | ||
370 | switch (cmd) | |
371 | { | |
0c376465 | 372 | /* Stack global |
dc810e39 | 373 | arg: cs symbol name |
252b5132 | 374 | |
7920ce38 | 375 | stack 32 bit value of symbol (high bits set to 0). */ |
dc810e39 AM |
376 | case ETIR_S_C_STA_GBL: |
377 | { | |
378 | char *name; | |
379 | vms_symbol_entry *entry; | |
252b5132 | 380 | |
dc810e39 AM |
381 | name = _bfd_vms_save_counted_string (ptr); |
382 | entry = (vms_symbol_entry *) | |
b34976b6 | 383 | bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE); |
7920ce38 | 384 | if (entry == NULL) |
dc810e39 | 385 | { |
252b5132 | 386 | #if VMS_DEBUG |
ca09e32b NC |
387 | _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", |
388 | cmd_name (cmd), name); | |
252b5132 | 389 | #endif |
dc810e39 AM |
390 | _bfd_vms_push (abfd, (uquad) 0, -1); |
391 | } | |
392 | else | |
7920ce38 | 393 | _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1); |
dc810e39 | 394 | } |
0c376465 | 395 | *quarter_relocs = 1; |
252b5132 RH |
396 | break; |
397 | ||
0c376465 | 398 | /* Stack longword |
dc810e39 | 399 | arg: lw value |
252b5132 | 400 | |
7920ce38 | 401 | stack 32 bit value, sign extend to 64 bit. */ |
dc810e39 AM |
402 | case ETIR_S_C_STA_LW: |
403 | _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1); | |
0c376465 TG |
404 | /* This one is special as it is both part of the section header |
405 | and of the ALPHA_R_REFLONG relocation. */ | |
406 | if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_DFLOC) | |
407 | *quarter_relocs = 0; | |
408 | else if (*quarter_relocs) | |
409 | *quarter_relocs += 1; | |
410 | else | |
411 | *quarter_relocs = 2; | |
252b5132 RH |
412 | break; |
413 | ||
0c376465 | 414 | /* Stack quadword |
dc810e39 | 415 | arg: qw value |
252b5132 | 416 | |
7920ce38 | 417 | stack 64 bit value of symbol. */ |
dc810e39 AM |
418 | case ETIR_S_C_STA_QW: |
419 | _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1); | |
0c376465 TG |
420 | if (*quarter_relocs) |
421 | *quarter_relocs += 1; | |
422 | else | |
423 | *quarter_relocs = 2; | |
252b5132 RH |
424 | break; |
425 | ||
0c376465 | 426 | /* Stack psect base plus quadword offset |
dc810e39 AM |
427 | arg: lw section index |
428 | qw signed quadword offset (low 32 bits) | |
252b5132 | 429 | |
0c376465 | 430 | Stack qw argument and section index |
7920ce38 | 431 | (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB). */ |
dc810e39 AM |
432 | case ETIR_S_C_STA_PQ: |
433 | { | |
434 | uquad dummy; | |
0c376465 | 435 | int psect; |
252b5132 | 436 | |
dc810e39 | 437 | psect = bfd_getl32 (ptr); |
0c376465 | 438 | if ((unsigned int) psect >= PRIV (section_count)) |
dc810e39 | 439 | { |
ca09e32b NC |
440 | (*_bfd_error_handler) (_("bad section index in %s"), |
441 | cmd_name (cmd)); | |
dc810e39 | 442 | bfd_set_error (bfd_error_bad_value); |
b34976b6 | 443 | return FALSE; |
dc810e39 | 444 | } |
7920ce38 | 445 | dummy = bfd_getl64 (ptr + 4); |
dc810e39 AM |
446 | _bfd_vms_push (abfd, dummy, (int) psect); |
447 | } | |
0c376465 TG |
448 | /* This one is special as it is both part of the section header |
449 | and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */ | |
450 | if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_SETRB) | |
451 | *quarter_relocs = 0; | |
452 | else | |
453 | *quarter_relocs = 2; | |
252b5132 RH |
454 | break; |
455 | ||
dc810e39 AM |
456 | case ETIR_S_C_STA_LI: |
457 | case ETIR_S_C_STA_MOD: | |
458 | case ETIR_S_C_STA_CKARG: | |
ca09e32b | 459 | (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd)); |
0c376465 | 460 | *quarter_relocs = 0; |
b34976b6 | 461 | return FALSE; |
252b5132 | 462 | |
dc810e39 | 463 | default: |
ca09e32b | 464 | (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd); |
0c376465 | 465 | *quarter_relocs = 0; |
b34976b6 | 466 | return FALSE; |
252b5132 | 467 | } |
0c376465 | 468 | |
252b5132 RH |
469 | #if VMS_DEBUG |
470 | _bfd_vms_debug (5, "etir_sta true\n"); | |
471 | #endif | |
0c376465 | 472 | |
b34976b6 | 473 | return TRUE; |
252b5132 RH |
474 | } |
475 | ||
7920ce38 | 476 | /* etir_sto |
672579e9 | 477 | |
252b5132 | 478 | vms store commands |
672579e9 | 479 | |
252b5132 RH |
480 | handle sto_xxx commands in etir section |
481 | ptr points to data area in record | |
672579e9 | 482 | |
ca09e32b | 483 | see table B-9 of the openVMS linker manual. */ |
252b5132 | 484 | |
b34976b6 | 485 | static bfd_boolean |
0c376465 | 486 | etir_sto (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs) |
252b5132 RH |
487 | { |
488 | uquad dummy; | |
489 | int psect; | |
490 | ||
491 | #if VMS_DEBUG | |
492 | _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd); | |
0c376465 | 493 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
494 | #endif |
495 | ||
496 | switch (cmd) | |
497 | { | |
7920ce38 NC |
498 | /* Store byte: pop stack, write byte |
499 | arg: -. */ | |
252b5132 RH |
500 | case ETIR_S_C_STO_B: |
501 | dummy = _bfd_vms_pop (abfd, &psect); | |
7920ce38 | 502 | /* FIXME: check top bits. */ |
dc810e39 | 503 | image_write_b (abfd, (unsigned int) dummy & 0xff); |
0c376465 | 504 | *quarter_relocs = 0; |
252b5132 RH |
505 | break; |
506 | ||
7920ce38 NC |
507 | /* Store word: pop stack, write word |
508 | arg: -. */ | |
252b5132 RH |
509 | case ETIR_S_C_STO_W: |
510 | dummy = _bfd_vms_pop (abfd, &psect); | |
dc810e39 AM |
511 | /* FIXME: check top bits */ |
512 | image_write_w (abfd, (unsigned int) dummy & 0xffff); | |
0c376465 | 513 | *quarter_relocs = 0; |
252b5132 RH |
514 | break; |
515 | ||
7920ce38 NC |
516 | /* Store longword: pop stack, write longword |
517 | arg: -. */ | |
252b5132 RH |
518 | case ETIR_S_C_STO_LW: |
519 | dummy = _bfd_vms_pop (abfd, &psect); | |
dc810e39 | 520 | dummy += (PRIV (sections)[psect])->vma; |
ca09e32b | 521 | /* FIXME: check top bits. */ |
dc810e39 | 522 | image_write_l (abfd, (unsigned int) dummy & 0xffffffff); |
0c376465 TG |
523 | if (*quarter_relocs == 2) |
524 | *quarter_relocs = 4; | |
525 | else | |
526 | *quarter_relocs += 1; | |
252b5132 RH |
527 | break; |
528 | ||
7920ce38 NC |
529 | /* Store quadword: pop stack, write quadword |
530 | arg: -. */ | |
252b5132 RH |
531 | case ETIR_S_C_STO_QW: |
532 | dummy = _bfd_vms_pop (abfd, &psect); | |
dc810e39 | 533 | dummy += (PRIV (sections)[psect])->vma; |
7920ce38 NC |
534 | /* FIXME: check top bits. */ |
535 | image_write_q (abfd, dummy); | |
0c376465 TG |
536 | if (*quarter_relocs == 2) |
537 | *quarter_relocs = 4; | |
538 | else | |
539 | *quarter_relocs += 1; | |
252b5132 RH |
540 | break; |
541 | ||
7920ce38 | 542 | /* Store immediate repeated: pop stack for repeat count |
252b5132 | 543 | arg: lw byte count |
7920ce38 | 544 | da data. */ |
252b5132 RH |
545 | case ETIR_S_C_STO_IMMR: |
546 | { | |
dc810e39 | 547 | int size; |
252b5132 RH |
548 | |
549 | size = bfd_getl32 (ptr); | |
dc810e39 AM |
550 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); |
551 | while (dummy-- > 0) | |
252b5132 RH |
552 | image_dump (abfd, ptr+4, size, 0); |
553 | } | |
0c376465 | 554 | *quarter_relocs = 0; |
252b5132 RH |
555 | break; |
556 | ||
7920ce38 | 557 | /* Store global: write symbol value |
ca09e32b | 558 | arg: cs global symbol name. */ |
252b5132 RH |
559 | case ETIR_S_C_STO_GBL: |
560 | { | |
561 | vms_symbol_entry *entry; | |
562 | char *name; | |
563 | ||
564 | name = _bfd_vms_save_counted_string (ptr); | |
dc810e39 | 565 | entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), |
b34976b6 | 566 | name, FALSE, FALSE); |
7920ce38 | 567 | if (entry == NULL) |
0c376465 TG |
568 | /* FIXME, reloc. */ |
569 | image_write_q (abfd, (uquad) (0)); | |
252b5132 | 570 | else |
ca09e32b NC |
571 | /* FIXME, reloc. */ |
572 | image_write_q (abfd, (uquad) (entry->symbol->value)); | |
252b5132 | 573 | } |
0c376465 | 574 | *quarter_relocs = 4; |
252b5132 RH |
575 | break; |
576 | ||
7920ce38 | 577 | /* Store code address: write address of entry point |
ca09e32b | 578 | arg: cs global symbol name (procedure). */ |
252b5132 RH |
579 | case ETIR_S_C_STO_CA: |
580 | { | |
581 | vms_symbol_entry *entry; | |
582 | char *name; | |
583 | ||
584 | name = _bfd_vms_save_counted_string (ptr); | |
dc810e39 | 585 | entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), |
b34976b6 | 586 | name, FALSE, FALSE); |
7920ce38 | 587 | if (entry == NULL) |
0c376465 TG |
588 | /* FIXME, reloc. */ |
589 | image_write_q (abfd, (uquad) (0)); | |
252b5132 | 590 | else |
7920ce38 NC |
591 | /* FIXME, reloc. */ |
592 | image_write_q (abfd, (uquad) (entry->symbol->value)); | |
252b5132 | 593 | } |
0c376465 | 594 | *quarter_relocs = 4; |
252b5132 RH |
595 | break; |
596 | ||
ca09e32b NC |
597 | /* Store offset to psect: pop stack, add low 32 bits to base of psect |
598 | arg: none. */ | |
252b5132 RH |
599 | case ETIR_S_C_STO_OFF: |
600 | { | |
601 | uquad q; | |
dc810e39 | 602 | int psect1; |
252b5132 | 603 | |
7920ce38 | 604 | q = _bfd_vms_pop (abfd, & psect1); |
dc810e39 | 605 | q += (PRIV (sections)[psect1])->vma; |
252b5132 RH |
606 | image_write_q (abfd, q); |
607 | } | |
0c376465 | 608 | *quarter_relocs += 2; |
252b5132 RH |
609 | break; |
610 | ||
ca09e32b | 611 | /* Store immediate |
252b5132 | 612 | arg: lw count of bytes |
ca09e32b | 613 | da data. */ |
252b5132 RH |
614 | case ETIR_S_C_STO_IMM: |
615 | { | |
616 | int size; | |
617 | ||
618 | size = bfd_getl32 (ptr); | |
619 | image_dump (abfd, ptr+4, size, 0); | |
620 | } | |
0c376465 | 621 | *quarter_relocs = 0; |
252b5132 RH |
622 | break; |
623 | ||
ca09e32b | 624 | /* This code is 'reserved to digital' according to the openVMS |
dc810e39 AM |
625 | linker manual, however it is generated by the DEC C compiler |
626 | and defined in the include file. | |
252b5132 RH |
627 | FIXME, since the following is just a guess |
628 | store global longword: store 32bit value of symbol | |
ca09e32b | 629 | arg: cs symbol name. */ |
252b5132 RH |
630 | case ETIR_S_C_STO_GBL_LW: |
631 | { | |
632 | vms_symbol_entry *entry; | |
633 | char *name; | |
634 | ||
635 | name = _bfd_vms_save_counted_string (ptr); | |
dc810e39 | 636 | entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), |
b34976b6 | 637 | name, FALSE, FALSE); |
7920ce38 | 638 | if (entry == NULL) |
252b5132 RH |
639 | { |
640 | #if VMS_DEBUG | |
ca09e32b | 641 | _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name); |
252b5132 | 642 | #endif |
dc810e39 | 643 | image_write_l (abfd, (unsigned long) 0); /* FIXME, reloc */ |
252b5132 RH |
644 | } |
645 | else | |
ca09e32b NC |
646 | /* FIXME, reloc. */ |
647 | image_write_l (abfd, (unsigned long) (entry->symbol->value)); | |
252b5132 | 648 | } |
0c376465 | 649 | *quarter_relocs = 4; |
252b5132 RH |
650 | break; |
651 | ||
ca09e32b NC |
652 | case ETIR_S_C_STO_RB: |
653 | case ETIR_S_C_STO_AB: | |
252b5132 | 654 | case ETIR_S_C_STO_LP_PSB: |
ca09e32b | 655 | (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd)); |
0c376465 TG |
656 | *quarter_relocs = 0; |
657 | return FALSE; | |
252b5132 | 658 | |
252b5132 | 659 | case ETIR_S_C_STO_HINT_GBL: |
252b5132 | 660 | case ETIR_S_C_STO_HINT_PS: |
ca09e32b | 661 | (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd)); |
0c376465 TG |
662 | *quarter_relocs = 0; |
663 | return FALSE; | |
252b5132 RH |
664 | |
665 | default: | |
ca09e32b | 666 | (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd); |
0c376465 TG |
667 | *quarter_relocs = 0; |
668 | return FALSE; | |
252b5132 RH |
669 | } |
670 | ||
b34976b6 | 671 | return TRUE; |
252b5132 RH |
672 | } |
673 | ||
ca09e32b | 674 | /* Stack operator commands |
252b5132 RH |
675 | all 32 bit signed arithmetic |
676 | all word just like a stack calculator | |
677 | arguments are popped from stack, results are pushed on stack | |
672579e9 | 678 | |
ca09e32b | 679 | see table B-10 of the openVMS linker manual. */ |
252b5132 | 680 | |
b34976b6 | 681 | static bfd_boolean |
0c376465 TG |
682 | etir_opr (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED, |
683 | int *quarter_relocs) | |
252b5132 RH |
684 | { |
685 | long op1, op2; | |
686 | ||
687 | #if VMS_DEBUG | |
688 | _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd); | |
0c376465 | 689 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
690 | #endif |
691 | ||
0c376465 TG |
692 | /* No relocation uses OPR commands except ETIR_S_C_OPR_ADD. */ |
693 | if (cmd == ETIR_S_C_OPR_ADD) | |
694 | *quarter_relocs += 1; | |
695 | else | |
696 | *quarter_relocs = 0; | |
697 | ||
252b5132 RH |
698 | switch (cmd) |
699 | { | |
7920ce38 | 700 | case ETIR_S_C_OPR_NOP: /* No-op. */ |
252b5132 RH |
701 | break; |
702 | ||
7920ce38 | 703 | case ETIR_S_C_OPR_ADD: /* Add. */ |
dc810e39 AM |
704 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
705 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 706 | _bfd_vms_push (abfd, (uquad) (op1 + op2), -1); |
252b5132 RH |
707 | break; |
708 | ||
7920ce38 | 709 | case ETIR_S_C_OPR_SUB: /* Subtract. */ |
dc810e39 AM |
710 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
711 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 712 | _bfd_vms_push (abfd, (uquad) (op2 - op1), -1); |
252b5132 RH |
713 | break; |
714 | ||
7920ce38 | 715 | case ETIR_S_C_OPR_MUL: /* Multiply. */ |
dc810e39 AM |
716 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
717 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 718 | _bfd_vms_push (abfd, (uquad) (op1 * op2), -1); |
252b5132 RH |
719 | break; |
720 | ||
7920ce38 | 721 | case ETIR_S_C_OPR_DIV: /* Divide. */ |
dc810e39 AM |
722 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
723 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
252b5132 | 724 | if (op2 == 0) |
dc810e39 | 725 | _bfd_vms_push (abfd, (uquad) 0, -1); |
252b5132 | 726 | else |
672579e9 | 727 | _bfd_vms_push (abfd, (uquad) (op2 / op1), -1); |
252b5132 RH |
728 | break; |
729 | ||
7920ce38 | 730 | case ETIR_S_C_OPR_AND: /* Logical AND. */ |
dc810e39 AM |
731 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
732 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 733 | _bfd_vms_push (abfd, (uquad) (op1 & op2), -1); |
252b5132 RH |
734 | break; |
735 | ||
7920ce38 | 736 | case ETIR_S_C_OPR_IOR: /* Logical inclusive OR. */ |
dc810e39 AM |
737 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
738 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 739 | _bfd_vms_push (abfd, (uquad) (op1 | op2), -1); |
252b5132 RH |
740 | break; |
741 | ||
7920ce38 | 742 | case ETIR_S_C_OPR_EOR: /* Logical exclusive OR. */ |
dc810e39 AM |
743 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
744 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
672579e9 | 745 | _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1); |
252b5132 RH |
746 | break; |
747 | ||
7920ce38 | 748 | case ETIR_S_C_OPR_NEG: /* Negate. */ |
dc810e39 | 749 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
672579e9 | 750 | _bfd_vms_push (abfd, (uquad) (-op1), -1); |
252b5132 RH |
751 | break; |
752 | ||
7920ce38 | 753 | case ETIR_S_C_OPR_COM: /* Complement. */ |
dc810e39 | 754 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
672579e9 | 755 | _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1); |
252b5132 RH |
756 | break; |
757 | ||
7920ce38 | 758 | case ETIR_S_C_OPR_ASH: /* Arithmetic shift. */ |
dc810e39 AM |
759 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
760 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
7920ce38 | 761 | if (op2 < 0) /* Shift right. */ |
252b5132 | 762 | op1 >>= -op2; |
7920ce38 | 763 | else /* Shift left. */ |
252b5132 | 764 | op1 <<= op2; |
dc810e39 | 765 | _bfd_vms_push (abfd, (uquad) op1, -1); |
252b5132 RH |
766 | break; |
767 | ||
7920ce38 | 768 | case ETIR_S_C_OPR_INSV: /* Insert field. */ |
ca09e32b | 769 | (void) _bfd_vms_pop (abfd, NULL); |
7920ce38 NC |
770 | case ETIR_S_C_OPR_USH: /* Unsigned shift. */ |
771 | case ETIR_S_C_OPR_ROT: /* Rotate. */ | |
ca09e32b NC |
772 | case ETIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */ |
773 | case ETIR_S_C_OPR_DFLIT: /* Define a literal. */ | |
774 | (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd)); | |
0c376465 | 775 | return FALSE; |
252b5132 | 776 | |
7920ce38 | 777 | case ETIR_S_C_OPR_SEL: /* Select. */ |
dc810e39 AM |
778 | if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L) |
779 | (void) _bfd_vms_pop (abfd, NULL); | |
252b5132 RH |
780 | else |
781 | { | |
dc810e39 AM |
782 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
783 | (void) _bfd_vms_pop (abfd, NULL); | |
784 | _bfd_vms_push (abfd, (uquad) op1, -1); | |
252b5132 RH |
785 | } |
786 | break; | |
787 | ||
252b5132 | 788 | default: |
ca09e32b | 789 | (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd); |
0c376465 | 790 | return FALSE; |
252b5132 RH |
791 | } |
792 | ||
b34976b6 | 793 | return TRUE; |
252b5132 RH |
794 | } |
795 | ||
ca09e32b | 796 | /* Control commands. |
672579e9 | 797 | |
ca09e32b | 798 | See table B-11 of the openVMS linker manual. */ |
252b5132 | 799 | |
b34976b6 | 800 | static bfd_boolean |
0c376465 | 801 | etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs) |
252b5132 | 802 | { |
0c376465 | 803 | uquad dummy; |
252b5132 RH |
804 | int psect; |
805 | ||
806 | #if VMS_DEBUG | |
807 | _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd); | |
0c376465 | 808 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
809 | #endif |
810 | ||
0c376465 TG |
811 | /* No relocation uses CTL commands. */ |
812 | *quarter_relocs = 0; | |
813 | ||
252b5132 RH |
814 | switch (cmd) |
815 | { | |
7920ce38 | 816 | /* Det relocation base: pop stack, set image location counter |
ca09e32b | 817 | arg: none. */ |
252b5132 RH |
818 | case ETIR_S_C_CTL_SETRB: |
819 | dummy = _bfd_vms_pop (abfd, &psect); | |
820 | image_set_ptr (abfd, psect, dummy); | |
821 | break; | |
822 | ||
7920ce38 NC |
823 | /* Augment relocation base: increment image location counter by offset |
824 | arg: lw offset value. */ | |
252b5132 RH |
825 | case ETIR_S_C_CTL_AUGRB: |
826 | dummy = bfd_getl32 (ptr); | |
827 | image_inc_ptr (abfd, dummy); | |
828 | break; | |
829 | ||
7920ce38 | 830 | /* Define location: pop index, save location counter under index |
ca09e32b | 831 | arg: none. */ |
252b5132 RH |
832 | case ETIR_S_C_CTL_DFLOC: |
833 | dummy = _bfd_vms_pop (abfd, NULL); | |
0c376465 | 834 | dst_define_location (abfd, dummy); |
252b5132 RH |
835 | break; |
836 | ||
7920ce38 | 837 | /* Set location: pop index, restore location counter from index |
ca09e32b | 838 | arg: none. */ |
252b5132 | 839 | case ETIR_S_C_CTL_STLOC: |
0c376465 TG |
840 | dummy = _bfd_vms_pop (abfd, NULL); |
841 | dst_restore_location (abfd, dummy); | |
252b5132 RH |
842 | break; |
843 | ||
7920ce38 | 844 | /* Stack defined location: pop index, push location counter from index |
ca09e32b | 845 | arg: none. */ |
252b5132 | 846 | case ETIR_S_C_CTL_STKDL: |
0c376465 TG |
847 | dummy = _bfd_vms_pop (abfd, NULL); |
848 | _bfd_vms_push (abfd, dst_retrieve_location (abfd, dummy), -1); | |
252b5132 RH |
849 | break; |
850 | ||
851 | default: | |
ca09e32b | 852 | (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd); |
0c376465 | 853 | return FALSE; |
252b5132 | 854 | } |
0c376465 | 855 | |
b34976b6 | 856 | return TRUE; |
252b5132 RH |
857 | } |
858 | ||
7920ce38 | 859 | /* Store conditional commands |
672579e9 | 860 | |
ca09e32b | 861 | See table B-12 and B-13 of the openVMS linker manual. */ |
252b5132 | 862 | |
b34976b6 | 863 | static bfd_boolean |
0c376465 TG |
864 | etir_stc (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED, |
865 | int *quarter_relocs) | |
252b5132 | 866 | { |
252b5132 RH |
867 | #if VMS_DEBUG |
868 | _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd); | |
0c376465 | 869 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
870 | #endif |
871 | ||
872 | switch (cmd) | |
873 | { | |
874 | /* 200 Store-conditional Linkage Pair | |
ca09e32b | 875 | arg: none. */ |
252b5132 | 876 | case ETIR_S_C_STC_LP: |
252b5132 RH |
877 | |
878 | /* 202 Store-conditional Address at global address | |
879 | arg: lw linkage index | |
b34976b6 | 880 | cs global name. */ |
252b5132 RH |
881 | |
882 | case ETIR_S_C_STC_GBL: | |
252b5132 RH |
883 | |
884 | /* 203 Store-conditional Code Address at global address | |
885 | arg: lw linkage index | |
b34976b6 | 886 | cs procedure name. */ |
252b5132 | 887 | case ETIR_S_C_STC_GCA: |
252b5132 RH |
888 | |
889 | /* 204 Store-conditional Address at psect + offset | |
890 | arg: lw linkage index | |
b34976b6 AM |
891 | lw psect index |
892 | qw offset. */ | |
252b5132 | 893 | case ETIR_S_C_STC_PS: |
ca09e32b | 894 | (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd)); |
0c376465 TG |
895 | *quarter_relocs = 0; |
896 | return FALSE; | |
897 | ||
898 | /* 201 Store-conditional Linkage Pair with Procedure Signature | |
899 | arg: lw linkage index | |
900 | cs procedure name | |
901 | by signature length | |
902 | da signature. */ | |
903 | ||
904 | case ETIR_S_C_STC_LP_PSB: | |
905 | image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */ | |
906 | *quarter_relocs = 4; | |
252b5132 RH |
907 | break; |
908 | ||
909 | /* 205 Store-conditional NOP at address of global | |
ca09e32b | 910 | arg: none. */ |
252b5132 | 911 | case ETIR_S_C_STC_NOP_GBL: |
0c376465 | 912 | /* ALPHA_R_NOP */ |
252b5132 RH |
913 | |
914 | /* 207 Store-conditional BSR at global address | |
ca09e32b | 915 | arg: none. */ |
252b5132 | 916 | |
0c376465 TG |
917 | case ETIR_S_C_STC_BSR_GBL: |
918 | /* ALPHA_R_BSR */ | |
252b5132 RH |
919 | |
920 | /* 209 Store-conditional LDA at global address | |
ca09e32b | 921 | arg: none. */ |
252b5132 | 922 | |
0c376465 TG |
923 | case ETIR_S_C_STC_LDA_GBL: |
924 | /* ALPHA_R_LDA */ | |
252b5132 RH |
925 | |
926 | /* 211 Store-conditional BSR or Hint at global address | |
ca09e32b | 927 | arg: none. */ |
252b5132 | 928 | |
0c376465 TG |
929 | case ETIR_S_C_STC_BOH_GBL: |
930 | *quarter_relocs = 4; | |
931 | break; | |
252b5132 RH |
932 | |
933 | /* 213 Store-conditional NOP,BSR or HINT at global address | |
ca09e32b | 934 | arg: none. */ |
0c376465 | 935 | |
252b5132 RH |
936 | case ETIR_S_C_STC_NBH_GBL: |
937 | ||
0c376465 TG |
938 | /* 206 Store-conditional NOP at pect + offset |
939 | arg: none. */ | |
940 | ||
941 | case ETIR_S_C_STC_NOP_PS: | |
942 | ||
943 | /* 208 Store-conditional BSR at pect + offset | |
944 | arg: none. */ | |
945 | ||
946 | case ETIR_S_C_STC_BSR_PS: | |
947 | ||
948 | /* 210 Store-conditional LDA at psect + offset | |
949 | arg: none. */ | |
950 | ||
951 | case ETIR_S_C_STC_LDA_PS: | |
952 | ||
953 | /* 212 Store-conditional BSR or Hint at pect + offset | |
954 | arg: none. */ | |
955 | ||
956 | case ETIR_S_C_STC_BOH_PS: | |
957 | ||
958 | /* 214 Store-conditional NOP, BSR or HINT at psect + offset | |
ca09e32b | 959 | arg: none. */ |
252b5132 | 960 | case ETIR_S_C_STC_NBH_PS: |
0c376465 TG |
961 | (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd)); |
962 | *quarter_relocs = 0; | |
963 | return FALSE; | |
252b5132 RH |
964 | |
965 | default: | |
0c376465 TG |
966 | (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd); |
967 | *quarter_relocs = 0; | |
968 | return FALSE; | |
252b5132 | 969 | } |
0c376465 | 970 | |
b34976b6 | 971 | return TRUE; |
252b5132 RH |
972 | } |
973 | ||
252b5132 | 974 | static asection * |
7920ce38 | 975 | new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx) |
252b5132 RH |
976 | { |
977 | asection *section; | |
978 | char sname[16]; | |
979 | char *name; | |
980 | ||
981 | #if VMS_DEBUG | |
ca09e32b | 982 | _bfd_vms_debug (5, "new_section %d\n", idx); |
252b5132 RH |
983 | #endif |
984 | sprintf (sname, SECTION_NAME_TEMPLATE, idx); | |
985 | ||
dc810e39 | 986 | name = bfd_malloc ((bfd_size_type) strlen (sname) + 1); |
252b5132 | 987 | if (name == 0) |
7920ce38 | 988 | return NULL; |
252b5132 RH |
989 | strcpy (name, sname); |
990 | ||
dc810e39 | 991 | section = bfd_malloc ((bfd_size_type) sizeof (asection)); |
252b5132 RH |
992 | if (section == 0) |
993 | { | |
994 | #if VMS_DEBUG | |
9b0ec667 | 995 | _bfd_vms_debug (6, "new_section (%s) failed", name); |
252b5132 | 996 | #endif |
7920ce38 | 997 | return NULL; |
252b5132 RH |
998 | } |
999 | ||
eea6121a | 1000 | section->size = 0; |
252b5132 RH |
1001 | section->vma = 0; |
1002 | section->contents = 0; | |
252b5132 RH |
1003 | section->name = name; |
1004 | section->index = idx; | |
1005 | ||
1006 | return section; | |
1007 | } | |
1008 | ||
252b5132 | 1009 | static int |
7920ce38 | 1010 | alloc_section (bfd * abfd, unsigned int idx) |
252b5132 | 1011 | { |
dc810e39 AM |
1012 | bfd_size_type amt; |
1013 | ||
252b5132 | 1014 | #if VMS_DEBUG |
ca09e32b | 1015 | _bfd_vms_debug (4, "alloc_section %d\n", idx); |
252b5132 RH |
1016 | #endif |
1017 | ||
dc810e39 AM |
1018 | amt = idx + 1; |
1019 | amt *= sizeof (asection *); | |
515ef31d NC |
1020 | PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt); |
1021 | if (PRIV (sections) == NULL) | |
252b5132 RH |
1022 | return -1; |
1023 | ||
dc810e39 | 1024 | while (PRIV (section_count) <= idx) |
252b5132 | 1025 | { |
dc810e39 AM |
1026 | PRIV (sections)[PRIV (section_count)] |
1027 | = new_section (abfd, (int) PRIV (section_count)); | |
1028 | if (PRIV (sections)[PRIV (section_count)] == 0) | |
252b5132 | 1029 | return -1; |
dc810e39 | 1030 | PRIV (section_count)++; |
252b5132 RH |
1031 | } |
1032 | ||
1033 | return 0; | |
1034 | } | |
1035 | ||
ca09e32b | 1036 | /* tir_sta |
b34976b6 | 1037 | |
0c376465 | 1038 | Vax stack commands. |
b34976b6 | 1039 | |
0c376465 TG |
1040 | Handle sta_xxx commands in tir section, |
1041 | ptr points to data area in record. | |
b34976b6 | 1042 | |
ca09e32b | 1043 | See table 7-3 of the VAX/VMS linker manual. */ |
252b5132 RH |
1044 | |
1045 | static unsigned char * | |
7920ce38 | 1046 | tir_sta (bfd * abfd, unsigned char *ptr) |
252b5132 RH |
1047 | { |
1048 | int cmd = *ptr++; | |
1049 | ||
1050 | #if VMS_DEBUG | |
1051 | _bfd_vms_debug (5, "tir_sta %d\n", cmd); | |
1052 | #endif | |
1053 | ||
1054 | switch (cmd) | |
1055 | { | |
dc810e39 AM |
1056 | /* stack */ |
1057 | case TIR_S_C_STA_GBL: | |
ca09e32b | 1058 | /* stack global |
b34976b6 AM |
1059 | arg: cs symbol name |
1060 | ||
1061 | stack 32 bit value of symbol (high bits set to 0). */ | |
dc810e39 AM |
1062 | { |
1063 | char *name; | |
1064 | vms_symbol_entry *entry; | |
252b5132 | 1065 | |
dc810e39 | 1066 | name = _bfd_vms_save_counted_string (ptr); |
252b5132 | 1067 | |
dc810e39 | 1068 | entry = _bfd_vms_enter_symbol (abfd, name); |
7920ce38 NC |
1069 | if (entry == NULL) |
1070 | return NULL; | |
252b5132 | 1071 | |
dc810e39 AM |
1072 | _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1); |
1073 | ptr += *ptr + 1; | |
1074 | } | |
252b5132 RH |
1075 | break; |
1076 | ||
dc810e39 | 1077 | case TIR_S_C_STA_SB: |
ca09e32b | 1078 | /* stack signed byte |
b34976b6 AM |
1079 | arg: by value |
1080 | ||
1081 | stack byte value, sign extend to 32 bit. */ | |
dc810e39 AM |
1082 | _bfd_vms_push (abfd, (uquad) *ptr++, -1); |
1083 | break; | |
1084 | ||
1085 | case TIR_S_C_STA_SW: | |
ca09e32b | 1086 | /* stack signed short word |
b34976b6 AM |
1087 | arg: sh value |
1088 | ||
1089 | stack 16 bit value, sign extend to 32 bit. */ | |
dc810e39 AM |
1090 | _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1); |
1091 | ptr += 2; | |
1092 | break; | |
1093 | ||
1094 | case TIR_S_C_STA_LW: | |
ca09e32b | 1095 | /* stack signed longword |
b34976b6 AM |
1096 | arg: lw value |
1097 | ||
1098 | stack 32 bit value. */ | |
dc810e39 AM |
1099 | _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1); |
1100 | ptr += 4; | |
1101 | break; | |
1102 | ||
1103 | case TIR_S_C_STA_PB: | |
1104 | case TIR_S_C_STA_WPB: | |
ca09e32b | 1105 | /* stack psect base plus byte offset (word index) |
b34976b6 AM |
1106 | arg: by section index |
1107 | (sh section index) | |
1108 | by signed byte offset. */ | |
dc810e39 AM |
1109 | { |
1110 | unsigned long dummy; | |
0c376465 | 1111 | int psect; |
dc810e39 AM |
1112 | |
1113 | if (cmd == TIR_S_C_STA_PB) | |
1114 | psect = *ptr++; | |
1115 | else | |
1116 | { | |
1117 | psect = bfd_getl16 (ptr); | |
1118 | ptr += 2; | |
1119 | } | |
1120 | ||
0c376465 | 1121 | if ((unsigned int) psect >= PRIV (section_count)) |
ca09e32b | 1122 | alloc_section (abfd, psect); |
dc810e39 AM |
1123 | |
1124 | dummy = (long) *ptr++; | |
1125 | dummy += (PRIV (sections)[psect])->vma; | |
0c376465 | 1126 | _bfd_vms_push (abfd, (uquad) dummy, psect); |
dc810e39 | 1127 | } |
252b5132 RH |
1128 | break; |
1129 | ||
dc810e39 AM |
1130 | case TIR_S_C_STA_PW: |
1131 | case TIR_S_C_STA_WPW: | |
ca09e32b | 1132 | /* stack psect base plus word offset (word index) |
b34976b6 AM |
1133 | arg: by section index |
1134 | (sh section index) | |
1135 | sh signed short offset. */ | |
dc810e39 AM |
1136 | { |
1137 | unsigned long dummy; | |
0c376465 | 1138 | int psect; |
252b5132 | 1139 | |
dc810e39 AM |
1140 | if (cmd == TIR_S_C_STA_PW) |
1141 | psect = *ptr++; | |
1142 | else | |
1143 | { | |
1144 | psect = bfd_getl16 (ptr); | |
1145 | ptr += 2; | |
1146 | } | |
252b5132 | 1147 | |
0c376465 | 1148 | if ((unsigned int) psect >= PRIV (section_count)) |
ca09e32b | 1149 | alloc_section (abfd, psect); |
252b5132 | 1150 | |
dc810e39 AM |
1151 | dummy = bfd_getl16 (ptr); ptr+=2; |
1152 | dummy += (PRIV (sections)[psect])->vma; | |
0c376465 | 1153 | _bfd_vms_push (abfd, (uquad) dummy, psect); |
dc810e39 AM |
1154 | } |
1155 | break; | |
252b5132 | 1156 | |
dc810e39 AM |
1157 | case TIR_S_C_STA_PL: |
1158 | case TIR_S_C_STA_WPL: | |
ca09e32b | 1159 | /* stack psect base plus long offset (word index) |
b34976b6 AM |
1160 | arg: by section index |
1161 | (sh section index) | |
1162 | lw signed longword offset. */ | |
dc810e39 AM |
1163 | { |
1164 | unsigned long dummy; | |
0c376465 | 1165 | int psect; |
252b5132 | 1166 | |
dc810e39 AM |
1167 | if (cmd == TIR_S_C_STA_PL) |
1168 | psect = *ptr++; | |
1169 | else | |
1170 | { | |
1171 | psect = bfd_getl16 (ptr); | |
1172 | ptr += 2; | |
1173 | } | |
252b5132 | 1174 | |
0c376465 | 1175 | if ((unsigned int) psect >= PRIV (section_count)) |
ca09e32b | 1176 | alloc_section (abfd, psect); |
dc810e39 AM |
1177 | |
1178 | dummy = bfd_getl32 (ptr); ptr += 4; | |
1179 | dummy += (PRIV (sections)[psect])->vma; | |
0c376465 | 1180 | _bfd_vms_push (abfd, (uquad) dummy, psect); |
dc810e39 | 1181 | } |
252b5132 RH |
1182 | break; |
1183 | ||
dc810e39 | 1184 | case TIR_S_C_STA_UB: |
ca09e32b | 1185 | /* stack unsigned byte |
b34976b6 AM |
1186 | arg: by value |
1187 | ||
1188 | stack byte value. */ | |
dc810e39 AM |
1189 | _bfd_vms_push (abfd, (uquad) *ptr++, -1); |
1190 | break; | |
1191 | ||
1192 | case TIR_S_C_STA_UW: | |
ca09e32b | 1193 | /* stack unsigned short word |
b34976b6 AM |
1194 | arg: sh value |
1195 | ||
1196 | stack 16 bit value. */ | |
dc810e39 AM |
1197 | _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1); |
1198 | ptr += 2; | |
1199 | break; | |
1200 | ||
1201 | case TIR_S_C_STA_BFI: | |
ca09e32b | 1202 | /* stack byte from image |
b34976b6 | 1203 | arg: none. */ |
ca09e32b | 1204 | /* FALLTHRU */ |
dc810e39 | 1205 | case TIR_S_C_STA_WFI: |
ca09e32b | 1206 | /* stack byte from image |
b34976b6 | 1207 | arg: none. */ |
ca09e32b | 1208 | /* FALLTHRU */ |
dc810e39 | 1209 | case TIR_S_C_STA_LFI: |
ca09e32b | 1210 | /* stack byte from image |
b34976b6 | 1211 | arg: none. */ |
ca09e32b | 1212 | (*_bfd_error_handler) (_("stack-from-image not implemented")); |
dc810e39 AM |
1213 | return NULL; |
1214 | ||
1215 | case TIR_S_C_STA_EPM: | |
ca09e32b | 1216 | /* stack entry point mask |
b34976b6 AM |
1217 | arg: cs symbol name |
1218 | ||
1219 | stack (unsigned) entry point mask of symbol | |
1220 | err if symbol is no entry point. */ | |
dc810e39 AM |
1221 | { |
1222 | char *name; | |
1223 | vms_symbol_entry *entry; | |
252b5132 | 1224 | |
dc810e39 AM |
1225 | name = _bfd_vms_save_counted_string (ptr); |
1226 | entry = _bfd_vms_enter_symbol (abfd, name); | |
7920ce38 NC |
1227 | if (entry == NULL) |
1228 | return NULL; | |
252b5132 | 1229 | |
ca09e32b | 1230 | (*_bfd_error_handler) (_("stack-entry-mask not fully implemented")); |
dc810e39 AM |
1231 | _bfd_vms_push (abfd, (uquad) 0, -1); |
1232 | ptr += *ptr + 1; | |
1233 | } | |
252b5132 RH |
1234 | break; |
1235 | ||
dc810e39 | 1236 | case TIR_S_C_STA_CKARG: |
ca09e32b | 1237 | /* compare procedure argument |
b34976b6 AM |
1238 | arg: cs symbol name |
1239 | by argument index | |
1240 | da argument descriptor | |
1241 | ||
1242 | compare argument descriptor with symbol argument (ARG$V_PASSMECH) | |
1243 | and stack TRUE (args match) or FALSE (args dont match) value. */ | |
dc810e39 AM |
1244 | (*_bfd_error_handler) (_("PASSMECH not fully implemented")); |
1245 | _bfd_vms_push (abfd, (uquad) 1, -1); | |
1246 | break; | |
1247 | ||
1248 | case TIR_S_C_STA_LSY: | |
ca09e32b | 1249 | /* stack local symbol value |
b34976b6 AM |
1250 | arg: sh environment index |
1251 | cs symbol name. */ | |
dc810e39 AM |
1252 | { |
1253 | int envidx; | |
1254 | char *name; | |
1255 | vms_symbol_entry *entry; | |
252b5132 | 1256 | |
dc810e39 AM |
1257 | envidx = bfd_getl16 (ptr); |
1258 | ptr += 2; | |
1259 | name = _bfd_vms_save_counted_string (ptr); | |
1260 | entry = _bfd_vms_enter_symbol (abfd, name); | |
7920ce38 NC |
1261 | if (entry == NULL) |
1262 | return NULL; | |
ca09e32b | 1263 | (*_bfd_error_handler) (_("stack-local-symbol not fully implemented")); |
dc810e39 AM |
1264 | _bfd_vms_push (abfd, (uquad) 0, -1); |
1265 | ptr += *ptr + 1; | |
1266 | } | |
252b5132 RH |
1267 | break; |
1268 | ||
dc810e39 | 1269 | case TIR_S_C_STA_LIT: |
ca09e32b | 1270 | /* stack literal |
b34976b6 AM |
1271 | arg: by literal index |
1272 | ||
1273 | stack literal. */ | |
dc810e39 AM |
1274 | ptr++; |
1275 | _bfd_vms_push (abfd, (uquad) 0, -1); | |
ca09e32b | 1276 | (*_bfd_error_handler) (_("stack-literal not fully implemented")); |
dc810e39 AM |
1277 | break; |
1278 | ||
1279 | case TIR_S_C_STA_LEPM: | |
ca09e32b | 1280 | /* stack local symbol entry point mask |
b34976b6 AM |
1281 | arg: sh environment index |
1282 | cs symbol name | |
1283 | ||
1284 | stack (unsigned) entry point mask of symbol | |
1285 | err if symbol is no entry point. */ | |
dc810e39 AM |
1286 | { |
1287 | int envidx; | |
1288 | char *name; | |
1289 | vms_symbol_entry *entry; | |
252b5132 | 1290 | |
dc810e39 AM |
1291 | envidx = bfd_getl16 (ptr); |
1292 | ptr += 2; | |
1293 | name = _bfd_vms_save_counted_string (ptr); | |
1294 | entry = _bfd_vms_enter_symbol (abfd, name); | |
7920ce38 NC |
1295 | if (entry == NULL) |
1296 | return NULL; | |
ca09e32b | 1297 | (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented")); |
dc810e39 AM |
1298 | _bfd_vms_push (abfd, (uquad) 0, -1); |
1299 | ptr += *ptr + 1; | |
1300 | } | |
252b5132 RH |
1301 | break; |
1302 | ||
dc810e39 | 1303 | default: |
ca09e32b | 1304 | (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]); |
dc810e39 | 1305 | return NULL; |
252b5132 | 1306 | break; |
dc810e39 | 1307 | } |
252b5132 RH |
1308 | |
1309 | return ptr; | |
1310 | } | |
1311 | ||
ca09e32b | 1312 | static const char * |
7920ce38 | 1313 | tir_cmd_name (int cmd) |
ca09e32b NC |
1314 | { |
1315 | switch (cmd) | |
1316 | { | |
1317 | case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB"; | |
1318 | case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW"; | |
1319 | case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL"; | |
1320 | case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS"; | |
1321 | case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB"; | |
1322 | case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW"; | |
1323 | case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB"; | |
1324 | case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW"; | |
1325 | case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR"; | |
1326 | case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV"; | |
1327 | case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT"; | |
1328 | case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF"; | |
1329 | case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT"; | |
1330 | case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH"; | |
1331 | case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH"; | |
1332 | case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC"; | |
1333 | case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC"; | |
1334 | case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL"; | |
1335 | ||
1336 | default: | |
1337 | /* These strings have not been added yet. */ | |
1338 | abort (); | |
1339 | } | |
1340 | } | |
1341 | ||
1342 | /* tir_sto | |
b34976b6 | 1343 | |
ca09e32b | 1344 | vax store commands |
b34976b6 | 1345 | |
ca09e32b NC |
1346 | handle sto_xxx commands in tir section |
1347 | ptr points to data area in record | |
b34976b6 | 1348 | |
ca09e32b | 1349 | See table 7-4 of the VAX/VMS linker manual. */ |
252b5132 RH |
1350 | |
1351 | static unsigned char * | |
7920ce38 | 1352 | tir_sto (bfd * abfd, unsigned char *ptr) |
252b5132 RH |
1353 | { |
1354 | unsigned long dummy; | |
1355 | int size; | |
1356 | int psect; | |
1357 | ||
1358 | #if VMS_DEBUG | |
1359 | _bfd_vms_debug (5, "tir_sto %d\n", *ptr); | |
1360 | #endif | |
1361 | ||
1362 | switch (*ptr++) | |
1363 | { | |
dc810e39 | 1364 | case TIR_S_C_STO_SB: |
7920ce38 | 1365 | /* Store signed byte: pop stack, write byte |
b34976b6 | 1366 | arg: none. */ |
dc810e39 AM |
1367 | dummy = _bfd_vms_pop (abfd, &psect); |
1368 | image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */ | |
1369 | break; | |
1370 | ||
1371 | case TIR_S_C_STO_SW: | |
7920ce38 | 1372 | /* Store signed word: pop stack, write word |
b34976b6 | 1373 | arg: none. */ |
dc810e39 AM |
1374 | dummy = _bfd_vms_pop (abfd, &psect); |
1375 | image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */ | |
1376 | break; | |
1377 | ||
1378 | case TIR_S_C_STO_LW: | |
7920ce38 | 1379 | /* Store longword: pop stack, write longword |
b34976b6 | 1380 | arg: none. */ |
dc810e39 AM |
1381 | dummy = _bfd_vms_pop (abfd, &psect); |
1382 | image_write_l (abfd, dummy & 0xffffffff); /* FIXME: check top bits */ | |
1383 | break; | |
1384 | ||
1385 | case TIR_S_C_STO_BD: | |
7920ce38 | 1386 | /* Store byte displaced: pop stack, sub lc+1, write byte |
b34976b6 | 1387 | arg: none. */ |
dc810e39 AM |
1388 | dummy = _bfd_vms_pop (abfd, &psect); |
1389 | dummy -= ((PRIV (sections)[psect])->vma + 1); | |
1390 | image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */ | |
1391 | break; | |
1392 | ||
1393 | case TIR_S_C_STO_WD: | |
7920ce38 | 1394 | /* Store word displaced: pop stack, sub lc+2, write word |
b34976b6 | 1395 | arg: none. */ |
dc810e39 AM |
1396 | dummy = _bfd_vms_pop (abfd, &psect); |
1397 | dummy -= ((PRIV (sections)[psect])->vma + 2); | |
1398 | image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */ | |
1399 | break; | |
ca09e32b | 1400 | |
dc810e39 | 1401 | case TIR_S_C_STO_LD: |
7920ce38 | 1402 | /* Store long displaced: pop stack, sub lc+4, write long |
b34976b6 | 1403 | arg: none. */ |
dc810e39 AM |
1404 | dummy = _bfd_vms_pop (abfd, &psect); |
1405 | dummy -= ((PRIV (sections)[psect])->vma + 4); | |
1406 | image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */ | |
1407 | break; | |
ca09e32b | 1408 | |
dc810e39 | 1409 | case TIR_S_C_STO_LI: |
7920ce38 | 1410 | /* Store short literal: pop stack, write byte |
b34976b6 | 1411 | arg: none. */ |
dc810e39 AM |
1412 | dummy = _bfd_vms_pop (abfd, &psect); |
1413 | image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */ | |
1414 | break; | |
ca09e32b | 1415 | |
dc810e39 | 1416 | case TIR_S_C_STO_PIDR: |
7920ce38 | 1417 | /* Store position independent data reference: pop stack, write longword |
b34976b6 | 1418 | arg: none. |
ca09e32b | 1419 | FIXME: incomplete ! */ |
dc810e39 AM |
1420 | dummy = _bfd_vms_pop (abfd, &psect); |
1421 | image_write_l (abfd, dummy & 0xffffffff); | |
1422 | break; | |
ca09e32b | 1423 | |
dc810e39 | 1424 | case TIR_S_C_STO_PICR: |
7920ce38 | 1425 | /* Store position independent code reference: pop stack, write longword |
b34976b6 AM |
1426 | arg: none. |
1427 | FIXME: incomplete ! */ | |
dc810e39 AM |
1428 | dummy = _bfd_vms_pop (abfd, &psect); |
1429 | image_write_b (abfd, 0x9f); | |
1430 | image_write_l (abfd, dummy & 0xffffffff); | |
1431 | break; | |
ca09e32b | 1432 | |
dc810e39 | 1433 | case TIR_S_C_STO_RIVB: |
7920ce38 | 1434 | /* Store repeated immediate variable bytes |
b34976b6 AM |
1435 | 1-byte count n field followed by n bytes of data |
1436 | pop stack, write n bytes <stack> times. */ | |
dc810e39 AM |
1437 | size = *ptr++; |
1438 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); | |
1439 | while (dummy-- > 0L) | |
1440 | image_dump (abfd, ptr, size, 0); | |
1441 | ptr += size; | |
1442 | break; | |
ca09e32b | 1443 | |
dc810e39 | 1444 | case TIR_S_C_STO_B: |
7920ce38 | 1445 | /* Store byte from top longword. */ |
dc810e39 AM |
1446 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); |
1447 | image_write_b (abfd, dummy & 0xff); | |
1448 | break; | |
ca09e32b | 1449 | |
dc810e39 | 1450 | case TIR_S_C_STO_W: |
7920ce38 | 1451 | /* Store word from top longword. */ |
dc810e39 AM |
1452 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); |
1453 | image_write_w (abfd, dummy & 0xffff); | |
1454 | break; | |
ca09e32b | 1455 | |
dc810e39 | 1456 | case TIR_S_C_STO_RB: |
7920ce38 | 1457 | /* Store repeated byte from top longword. */ |
dc810e39 AM |
1458 | size = (unsigned long) _bfd_vms_pop (abfd, NULL); |
1459 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); | |
1460 | while (size-- > 0) | |
252b5132 | 1461 | image_write_b (abfd, dummy & 0xff); |
dc810e39 | 1462 | break; |
ca09e32b | 1463 | |
dc810e39 | 1464 | case TIR_S_C_STO_RW: |
7920ce38 | 1465 | /* Store repeated word from top longword. */ |
dc810e39 AM |
1466 | size = (unsigned long) _bfd_vms_pop (abfd, NULL); |
1467 | dummy = (unsigned long) _bfd_vms_pop (abfd, NULL); | |
1468 | while (size-- > 0) | |
252b5132 | 1469 | image_write_w (abfd, dummy & 0xffff); |
dc810e39 | 1470 | break; |
252b5132 | 1471 | |
dc810e39 AM |
1472 | case TIR_S_C_STO_RSB: |
1473 | case TIR_S_C_STO_RSW: | |
1474 | case TIR_S_C_STO_RL: | |
1475 | case TIR_S_C_STO_VPS: | |
1476 | case TIR_S_C_STO_USB: | |
1477 | case TIR_S_C_STO_USW: | |
1478 | case TIR_S_C_STO_RUB: | |
1479 | case TIR_S_C_STO_RUW: | |
1480 | case TIR_S_C_STO_PIRR: | |
ca09e32b | 1481 | (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1])); |
252b5132 RH |
1482 | break; |
1483 | ||
dc810e39 | 1484 | default: |
ca09e32b | 1485 | (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]); |
252b5132 | 1486 | break; |
dc810e39 | 1487 | } |
252b5132 RH |
1488 | |
1489 | return ptr; | |
1490 | } | |
1491 | ||
7920ce38 NC |
1492 | /* Stack operator commands |
1493 | All 32 bit signed arithmetic | |
1494 | All word just like a stack calculator | |
1495 | Arguments are popped from stack, results are pushed on stack | |
b34976b6 | 1496 | |
ca09e32b | 1497 | See table 7-5 of the VAX/VMS linker manual. */ |
252b5132 RH |
1498 | |
1499 | static unsigned char * | |
7920ce38 | 1500 | tir_opr (bfd * abfd, unsigned char *ptr) |
252b5132 RH |
1501 | { |
1502 | long op1, op2; | |
1503 | ||
1504 | #if VMS_DEBUG | |
1505 | _bfd_vms_debug (5, "tir_opr %d\n", *ptr); | |
1506 | #endif | |
1507 | ||
7920ce38 | 1508 | /* Operation. */ |
252b5132 RH |
1509 | switch (*ptr++) |
1510 | { | |
7920ce38 | 1511 | case TIR_S_C_OPR_NOP: /* No-op. */ |
dc810e39 AM |
1512 | break; |
1513 | ||
7920ce38 | 1514 | case TIR_S_C_OPR_ADD: /* Add. */ |
dc810e39 AM |
1515 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1516 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1517 | _bfd_vms_push (abfd, (uquad) (op1 + op2), -1); | |
1518 | break; | |
1519 | ||
7920ce38 | 1520 | case TIR_S_C_OPR_SUB: /* Subtract. */ |
dc810e39 AM |
1521 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1522 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1523 | _bfd_vms_push (abfd, (uquad) (op2 - op1), -1); | |
1524 | break; | |
1525 | ||
7920ce38 | 1526 | case TIR_S_C_OPR_MUL: /* Multiply. */ |
dc810e39 AM |
1527 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1528 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1529 | _bfd_vms_push (abfd, (uquad) (op1 * op2), -1); | |
1530 | break; | |
1531 | ||
7920ce38 | 1532 | case TIR_S_C_OPR_DIV: /* Divide. */ |
dc810e39 AM |
1533 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1534 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1535 | if (op2 == 0) | |
1536 | _bfd_vms_push (abfd, (uquad) 0, -1); | |
1537 | else | |
1538 | _bfd_vms_push (abfd, (uquad) (op2 / op1), -1); | |
1539 | break; | |
1540 | ||
7920ce38 | 1541 | case TIR_S_C_OPR_AND: /* Logical AND. */ |
dc810e39 AM |
1542 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1543 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1544 | _bfd_vms_push (abfd, (uquad) (op1 & op2), -1); | |
1545 | break; | |
1546 | ||
7920ce38 | 1547 | case TIR_S_C_OPR_IOR: /* Logical inclusive OR. */ |
dc810e39 | 1548 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
dc810e39 AM |
1549 | op2 = (long) _bfd_vms_pop (abfd, NULL); |
1550 | _bfd_vms_push (abfd, (uquad) (op1 | op2), -1); | |
1551 | break; | |
1552 | ||
7920ce38 | 1553 | case TIR_S_C_OPR_EOR: /* Logical exclusive OR. */ |
dc810e39 AM |
1554 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1555 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
1556 | _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1); | |
1557 | break; | |
1558 | ||
7920ce38 | 1559 | case TIR_S_C_OPR_NEG: /* Negate. */ |
dc810e39 AM |
1560 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1561 | _bfd_vms_push (abfd, (uquad) (-op1), -1); | |
1562 | break; | |
1563 | ||
7920ce38 | 1564 | case TIR_S_C_OPR_COM: /* Complement. */ |
dc810e39 AM |
1565 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1566 | _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1); | |
252b5132 RH |
1567 | break; |
1568 | ||
7920ce38 | 1569 | case TIR_S_C_OPR_INSV: /* Insert field. */ |
dc810e39 | 1570 | (void) _bfd_vms_pop (abfd, NULL); |
ca09e32b NC |
1571 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1572 | tir_cmd_name (ptr[-1])); | |
252b5132 RH |
1573 | break; |
1574 | ||
7920ce38 | 1575 | case TIR_S_C_OPR_ASH: /* Arithmetic shift. */ |
dc810e39 AM |
1576 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1577 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
7920ce38 | 1578 | if (HIGHBIT (op1)) /* Shift right. */ |
dc810e39 | 1579 | op2 >>= op1; |
7920ce38 | 1580 | else /* Shift left. */ |
dc810e39 AM |
1581 | op2 <<= op1; |
1582 | _bfd_vms_push (abfd, (uquad) op2, -1); | |
ca09e32b NC |
1583 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1584 | tir_cmd_name (ptr[-1])); | |
dc810e39 AM |
1585 | break; |
1586 | ||
7920ce38 | 1587 | case TIR_S_C_OPR_USH: /* Unsigned shift. */ |
dc810e39 AM |
1588 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1589 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
7920ce38 | 1590 | if (HIGHBIT (op1)) /* Shift right. */ |
dc810e39 | 1591 | op2 >>= op1; |
7920ce38 | 1592 | else /* Shift left. */ |
dc810e39 AM |
1593 | op2 <<= op1; |
1594 | _bfd_vms_push (abfd, (uquad) op2, -1); | |
ca09e32b NC |
1595 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1596 | tir_cmd_name (ptr[-1])); | |
dc810e39 AM |
1597 | break; |
1598 | ||
7920ce38 | 1599 | case TIR_S_C_OPR_ROT: /* Rotate. */ |
dc810e39 AM |
1600 | op1 = (long) _bfd_vms_pop (abfd, NULL); |
1601 | op2 = (long) _bfd_vms_pop (abfd, NULL); | |
7920ce38 | 1602 | if (HIGHBIT (0)) /* Shift right. */ |
dc810e39 | 1603 | op2 >>= op1; |
7920ce38 | 1604 | else /* Shift left. */ |
dc810e39 AM |
1605 | op2 <<= op1; |
1606 | _bfd_vms_push (abfd, (uquad) op2, -1); | |
ca09e32b NC |
1607 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1608 | tir_cmd_name (ptr[-1])); | |
dc810e39 AM |
1609 | break; |
1610 | ||
7920ce38 | 1611 | case TIR_S_C_OPR_SEL: /* Select. */ |
dc810e39 AM |
1612 | if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L) |
1613 | (void) _bfd_vms_pop (abfd, NULL); | |
1614 | else | |
1615 | { | |
1616 | op1 = (long) _bfd_vms_pop (abfd, NULL); | |
1617 | (void) _bfd_vms_pop (abfd, NULL); | |
1618 | _bfd_vms_push (abfd, (uquad) op1, -1); | |
1619 | } | |
1620 | break; | |
1621 | ||
ca09e32b NC |
1622 | case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */ |
1623 | case TIR_S_C_OPR_DFLIT: /* Define a literal. */ | |
1624 | (*_bfd_error_handler) (_("%s: not supported"), | |
1625 | tir_cmd_name (ptr[-1])); | |
dc810e39 AM |
1626 | break; |
1627 | ||
1628 | default: | |
ca09e32b | 1629 | (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]); |
252b5132 RH |
1630 | break; |
1631 | } | |
1632 | ||
1633 | return ptr; | |
1634 | } | |
1635 | ||
7920ce38 | 1636 | /* Control commands |
b34976b6 | 1637 | |
ca09e32b NC |
1638 | See table 7-6 of the VAX/VMS linker manual. */ |
1639 | ||
252b5132 | 1640 | static unsigned char * |
7920ce38 | 1641 | tir_ctl (bfd * abfd, unsigned char *ptr) |
252b5132 RH |
1642 | { |
1643 | unsigned long dummy; | |
0c376465 | 1644 | int psect; |
252b5132 RH |
1645 | |
1646 | #if VMS_DEBUG | |
1647 | _bfd_vms_debug (5, "tir_ctl %d\n", *ptr); | |
1648 | #endif | |
1649 | ||
1650 | switch (*ptr++) | |
1651 | { | |
dc810e39 | 1652 | case TIR_S_C_CTL_SETRB: |
ca09e32b | 1653 | /* Set relocation base: pop stack, set image location counter |
b34976b6 | 1654 | arg: none. */ |
0c376465 TG |
1655 | dummy = _bfd_vms_pop (abfd, &psect); |
1656 | if ((unsigned int) psect >= PRIV (section_count)) | |
ca09e32b | 1657 | alloc_section (abfd, psect); |
0c376465 | 1658 | image_set_ptr (abfd, psect, (uquad) dummy); |
dc810e39 | 1659 | break; |
ca09e32b | 1660 | |
dc810e39 | 1661 | case TIR_S_C_CTL_AUGRB: |
ca09e32b | 1662 | /* Augment relocation base: increment image location counter by offset |
b34976b6 | 1663 | arg: lw offset value. */ |
dc810e39 AM |
1664 | dummy = bfd_getl32 (ptr); |
1665 | image_inc_ptr (abfd, (uquad) dummy); | |
1666 | break; | |
ca09e32b | 1667 | |
dc810e39 | 1668 | case TIR_S_C_CTL_DFLOC: |
ca09e32b | 1669 | /* Define location: pop index, save location counter under index |
b34976b6 | 1670 | arg: none. */ |
dc810e39 | 1671 | dummy = _bfd_vms_pop (abfd, NULL); |
ca09e32b NC |
1672 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1673 | tir_cmd_name (ptr[-1])); | |
dc810e39 | 1674 | break; |
ca09e32b | 1675 | |
dc810e39 | 1676 | case TIR_S_C_CTL_STLOC: |
ca09e32b | 1677 | /* Set location: pop index, restore location counter from index |
b34976b6 | 1678 | arg: none. */ |
0c376465 | 1679 | dummy = _bfd_vms_pop (abfd, &psect); |
ca09e32b NC |
1680 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1681 | tir_cmd_name (ptr[-1])); | |
252b5132 | 1682 | break; |
ca09e32b | 1683 | |
252b5132 | 1684 | case TIR_S_C_CTL_STKDL: |
ca09e32b | 1685 | /* Stack defined location: pop index, push location counter from index |
b34976b6 | 1686 | arg: none. */ |
0c376465 | 1687 | dummy = _bfd_vms_pop (abfd, &psect); |
ca09e32b NC |
1688 | (*_bfd_error_handler) (_("%s: not fully implemented"), |
1689 | tir_cmd_name (ptr[-1])); | |
252b5132 | 1690 | break; |
ca09e32b | 1691 | |
252b5132 | 1692 | default: |
ca09e32b | 1693 | (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]); |
dc810e39 AM |
1694 | break; |
1695 | } | |
252b5132 RH |
1696 | return ptr; |
1697 | } | |
1698 | ||
ca09e32b | 1699 | /* Handle command from TIR section. */ |
252b5132 RH |
1700 | |
1701 | static unsigned char * | |
7920ce38 | 1702 | tir_cmd (bfd * abfd, unsigned char *ptr) |
252b5132 | 1703 | { |
0c376465 | 1704 | static const struct |
dc810e39 | 1705 | { |
252b5132 RH |
1706 | int mincod; |
1707 | int maxcod; | |
672579e9 | 1708 | unsigned char * (*explain) (bfd *, unsigned char *); |
dc810e39 AM |
1709 | } |
1710 | tir_table[] = | |
1711 | { | |
b34976b6 | 1712 | { 0, TIR_S_C_MAXSTACOD, tir_sta }, |
dc810e39 AM |
1713 | { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto }, |
1714 | { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr }, | |
1715 | { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl }, | |
1716 | { -1, -1, NULL } | |
252b5132 RH |
1717 | }; |
1718 | int i = 0; | |
1719 | ||
1720 | #if VMS_DEBUG | |
1721 | _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr); | |
0c376465 | 1722 | _bfd_hexdump (8, ptr, 16, (long) ptr); |
252b5132 RH |
1723 | #endif |
1724 | ||
7920ce38 | 1725 | if (*ptr & 0x80) |
252b5132 | 1726 | { |
7920ce38 | 1727 | /* Store immediate. */ |
252b5132 RH |
1728 | i = 128 - (*ptr++ & 0x7f); |
1729 | image_dump (abfd, ptr, i, 0); | |
1730 | ptr += i; | |
1731 | } | |
1732 | else | |
1733 | { | |
1734 | while (tir_table[i].mincod >= 0) | |
1735 | { | |
672579e9 | 1736 | if ( (tir_table[i].mincod <= *ptr) |
dc810e39 | 1737 | && (*ptr <= tir_table[i].maxcod)) |
252b5132 RH |
1738 | { |
1739 | ptr = tir_table[i].explain (abfd, ptr); | |
1740 | break; | |
1741 | } | |
1742 | i++; | |
1743 | } | |
1744 | if (tir_table[i].mincod < 0) | |
1745 | { | |
ca09e32b | 1746 | (*_bfd_error_handler) (_("obj code %d not found"), *ptr); |
252b5132 RH |
1747 | ptr = 0; |
1748 | } | |
1749 | } | |
1750 | ||
1751 | return ptr; | |
1752 | } | |
1753 | ||
ca09e32b | 1754 | /* Handle command from ETIR section. */ |
252b5132 RH |
1755 | |
1756 | static int | |
0c376465 | 1757 | etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs) |
252b5132 | 1758 | { |
0c376465 | 1759 | static const struct |
dc810e39 | 1760 | { |
252b5132 RH |
1761 | int mincod; |
1762 | int maxcod; | |
0c376465 | 1763 | bfd_boolean (*explain) (bfd *, int, unsigned char *, int *); |
dc810e39 AM |
1764 | } |
1765 | etir_table[] = | |
1766 | { | |
252b5132 RH |
1767 | { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta }, |
1768 | { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto }, | |
1769 | { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr }, | |
1770 | { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl }, | |
1771 | { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc }, | |
1772 | { -1, -1, NULL } | |
1773 | }; | |
1774 | ||
1775 | int i = 0; | |
1776 | ||
1777 | #if VMS_DEBUG | |
0c376465 TG |
1778 | _bfd_vms_debug (4, "etir_cmd: %s(%d)\n", cmd_name (cmd), cmd); |
1779 | _bfd_hexdump (8, ptr, 16, (long) ptr); | |
252b5132 RH |
1780 | #endif |
1781 | ||
1782 | while (etir_table[i].mincod >= 0) | |
1783 | { | |
672579e9 | 1784 | if ( (etir_table[i].mincod <= cmd) |
dc810e39 | 1785 | && (cmd <= etir_table[i].maxcod)) |
252b5132 | 1786 | { |
0c376465 | 1787 | if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs)) |
252b5132 RH |
1788 | return -1; |
1789 | break; | |
1790 | } | |
1791 | i++; | |
1792 | } | |
1793 | ||
1794 | #if VMS_DEBUG | |
0c376465 | 1795 | _bfd_vms_debug (4, "etir_cmd: result = 0\n"); |
252b5132 RH |
1796 | #endif |
1797 | return 0; | |
1798 | } | |
1799 | ||
252b5132 | 1800 | /* Text Information and Relocation Records (OBJ$C_TIR) |
ca09e32b | 1801 | handle tir record. */ |
252b5132 RH |
1802 | |
1803 | static int | |
7920ce38 | 1804 | analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length) |
252b5132 RH |
1805 | { |
1806 | unsigned char *maxptr; | |
1807 | ||
1808 | #if VMS_DEBUG | |
1809 | _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length); | |
1810 | #endif | |
1811 | ||
1812 | maxptr = ptr + length; | |
1813 | ||
1814 | while (ptr < maxptr) | |
1815 | { | |
1816 | ptr = tir_cmd (abfd, ptr); | |
1817 | if (ptr == 0) | |
1818 | return -1; | |
1819 | } | |
1820 | ||
1821 | return 0; | |
1822 | } | |
1823 | ||
252b5132 | 1824 | /* Text Information and Relocation Records (EOBJ$C_ETIR) |
ca09e32b | 1825 | handle etir record. */ |
252b5132 RH |
1826 | |
1827 | static int | |
7920ce38 | 1828 | analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length) |
252b5132 | 1829 | { |
0c376465 TG |
1830 | unsigned char *maxptr = ptr + length; |
1831 | /* Relocations are made of 1, 2 or 4 ETIR commands. | |
1832 | We therefore count them using quarters. */ | |
1833 | int quarter_relocs = 0; | |
252b5132 RH |
1834 | int result = 0; |
1835 | ||
1836 | #if VMS_DEBUG | |
1837 | _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length); | |
1838 | #endif | |
1839 | ||
252b5132 RH |
1840 | while (ptr < maxptr) |
1841 | { | |
0c376465 TG |
1842 | int cmd = bfd_getl16 (ptr); |
1843 | int cmd_length = bfd_getl16 (ptr + 2); | |
1844 | result = etir_cmd (abfd, cmd, ptr + 4, &quarter_relocs); | |
252b5132 RH |
1845 | if (result != 0) |
1846 | break; | |
0c376465 TG |
1847 | |
1848 | /* If we have a relocation, we record its length to size | |
1849 | future buffers and bump the reloc count of the section. */ | |
1850 | if (quarter_relocs) | |
1851 | { | |
1852 | vms_section_data (PRIV (image_section))->reloc_size += cmd_length; | |
1853 | abfd->flags |= HAS_RELOC; | |
1854 | ||
1855 | if (quarter_relocs == 4) | |
1856 | { | |
1857 | PRIV (image_section)->reloc_count++; | |
1858 | ||
1859 | #if VMS_DEBUG | |
1860 | _bfd_vms_debug (4, "-> reloc %d at 0x%x\n", | |
1861 | PRIV (image_section)->reloc_count-1, | |
1862 | ptr - (maxptr - length)); | |
1863 | #endif | |
1864 | ||
1865 | quarter_relocs = 0; | |
1866 | } | |
1867 | else if (quarter_relocs > 4) | |
1868 | { | |
1869 | ||
1870 | #if VMS_DEBUG | |
1871 | _bfd_vms_debug (4, "Reloc count error (%d) in section %s\n", | |
1872 | PRIV (image_section)->reloc_count, | |
1873 | PRIV (image_section)->name); | |
1874 | #endif | |
1875 | ||
1876 | quarter_relocs = 0; | |
1877 | } | |
1878 | } | |
1879 | ||
1880 | /* If we have a Store Immediate, we reserve space for the | |
1881 | count argument. */ | |
1882 | else if (cmd == ETIR_S_C_STO_IMM) | |
1883 | vms_section_data (PRIV (image_section))->reloc_size | |
1884 | += ETIR_S_C_HEADER_SIZE + 4; | |
1885 | ||
1886 | ptr += cmd_length; | |
252b5132 RH |
1887 | } |
1888 | ||
1889 | #if VMS_DEBUG | |
0c376465 | 1890 | _bfd_vms_debug (3, "analyze_etir: result = %d\n", result); |
252b5132 RH |
1891 | #endif |
1892 | ||
1893 | return result; | |
1894 | } | |
1895 | ||
ca09e32b NC |
1896 | /* Process ETIR record |
1897 | Return 0 on success, -1 on error. */ | |
252b5132 RH |
1898 | |
1899 | int | |
7920ce38 | 1900 | _bfd_vms_slurp_tir (bfd * abfd, int objtype) |
252b5132 RH |
1901 | { |
1902 | int result; | |
1903 | ||
1904 | #if VMS_DEBUG | |
1905 | _bfd_vms_debug (2, "TIR/ETIR\n"); | |
1906 | #endif | |
1907 | ||
1908 | switch (objtype) | |
1909 | { | |
dc810e39 | 1910 | case EOBJ_S_C_ETIR: |
0c376465 TG |
1911 | PRIV (vms_rec) += ETIR_S_C_HEADER_SIZE; |
1912 | PRIV (rec_size) -= ETIR_S_C_HEADER_SIZE; | |
dc810e39 AM |
1913 | result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size)); |
1914 | break; | |
1915 | case OBJ_S_C_TIR: | |
7920ce38 | 1916 | PRIV (vms_rec) += 1; /* Skip type. */ |
dc810e39 AM |
1917 | PRIV (rec_size) -= 1; |
1918 | result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size)); | |
1919 | break; | |
1920 | default: | |
1921 | result = -1; | |
1922 | break; | |
252b5132 RH |
1923 | } |
1924 | ||
1925 | return result; | |
1926 | } | |
1927 | ||
0c376465 TG |
1928 | /* Slurp relocs from ETIR sections and (temporarily) save them |
1929 | in the per-section reloc buffer. */ | |
252b5132 RH |
1930 | |
1931 | int | |
0c376465 | 1932 | _bfd_vms_slurp_relocs (bfd *abfd) |
252b5132 | 1933 | { |
0c376465 TG |
1934 | struct vms_section_data_struct *vsd; |
1935 | unsigned char *begin = PRIV (vms_rec) + 4; | |
1936 | unsigned char *end = PRIV (vms_rec) + PRIV (rec_size); | |
1937 | unsigned char *ptr; | |
1938 | int cmd, length, slurped_length; | |
1939 | ||
252b5132 | 1940 | #if VMS_DEBUG |
0c376465 TG |
1941 | _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: %d bytes\n", PRIV (rec_size)); |
1942 | #endif | |
1943 | ||
1944 | for (ptr = begin; ptr < end; ptr += length) | |
1945 | { | |
1946 | cmd = bfd_getl16 (ptr); | |
1947 | length = bfd_getl16 (ptr + 2); | |
1948 | slurped_length = length; | |
1949 | ||
1950 | switch (cmd) | |
1951 | { | |
1952 | case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */ | |
1953 | /* This one is special as it is both part of the section header | |
1954 | and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */ | |
1955 | if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_SETRB) | |
1956 | { | |
1957 | int psect = bfd_getl32 (ptr + ETIR_S_C_HEADER_SIZE); | |
1958 | PRIV (image_section) = PRIV (sections)[psect]; | |
1959 | continue; | |
1960 | } | |
1961 | ||
1962 | case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */ | |
1963 | /* ALPHA_R_REFQUAD und_section, step 1 */ | |
1964 | break; | |
1965 | ||
1966 | case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG und_section, step 2 */ | |
1967 | /* ALPHA_R_REFLONG abs_section, step 1 */ | |
1968 | /* This one is special as it is both part of the section header | |
1969 | and of the ALPHA_R_REFLONG relocation. */ | |
1970 | if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_DFLOC) | |
1971 | { | |
1972 | PRIV (image_section) = PRIV (dst_section); | |
1973 | continue; | |
1974 | } | |
1975 | ||
1976 | case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD und_section, step 2 */ | |
1977 | /* ALPHA_R_REFQUAD abs_section, step 1 */ | |
1978 | ||
1979 | case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */ | |
1980 | /* ALPHA_R_REFLONG abs_section, step 2 */ | |
1981 | /* ALPHA_R_REFLONG others, step 2 */ | |
1982 | ||
1983 | case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */ | |
1984 | /* ALPHA_R_REFQUAD abs_section, step 2 */ | |
1985 | ||
1986 | case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */ | |
1987 | ||
1988 | case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */ | |
1989 | /* ALPHA_R_REFQUAD und_section, step 3 */ | |
1990 | ||
1991 | case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */ | |
1992 | case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */ | |
1993 | case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */ | |
1994 | case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */ | |
1995 | case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */ | |
1996 | case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */ | |
1997 | case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */ | |
1998 | case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */ | |
1999 | break; | |
2000 | ||
2001 | case ETIR_S_C_STO_IMM: | |
2002 | if (PRIV (image_section)->reloc_count == 0) | |
2003 | continue; | |
2004 | /* This is not a relocation, but we nevertheless slurp the | |
2005 | count argument. We'll use it to compute the addresses | |
2006 | of the relocations. */ | |
2007 | slurped_length = ETIR_S_C_HEADER_SIZE + 4; | |
2008 | break; | |
2009 | ||
2010 | default: | |
2011 | continue; | |
2012 | } | |
2013 | ||
2014 | vsd = vms_section_data (PRIV (image_section)); | |
2015 | memcpy (vsd->reloc_stream + vsd->reloc_offset, ptr, slurped_length); | |
2016 | vsd->reloc_offset += slurped_length; | |
2017 | if (vsd->reloc_offset > vsd->reloc_size) | |
2018 | { | |
2019 | (*_bfd_error_handler) (_("Reloc size error in section %s"), | |
2020 | PRIV (image_section)->name); | |
2021 | return -1; | |
2022 | } | |
2023 | } | |
2024 | ||
2025 | #if VMS_DEBUG | |
2026 | _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n"); | |
252b5132 RH |
2027 | #endif |
2028 | ||
252b5132 RH |
2029 | return 0; |
2030 | } | |
2031 | ||
0c376465 TG |
2032 | /* Decode relocs from the reloc buffer of the specified section |
2033 | and internalize them in the specified buffer. */ | |
252b5132 RH |
2034 | |
2035 | int | |
0c376465 TG |
2036 | _bfd_vms_decode_relocs (bfd *abfd, arelent *relocs, asection *section, |
2037 | asymbol **symbols ATTRIBUTE_UNUSED) | |
252b5132 | 2038 | { |
0c376465 TG |
2039 | int saved_cmd, saved_sym_offset, saved_sec_offset, saved_addend_offset; |
2040 | int cmd, sym_offset, sec_offset, address_offset, addend_offset; | |
2041 | struct vms_section_data_struct *vsd = vms_section_data (section); | |
2042 | bfd_reloc_code_real_type reloc_code; | |
2043 | vms_symbol_entry *entry; | |
2044 | bfd_vma vaddr = 0; | |
2045 | unsigned char *begin = vsd->reloc_stream; | |
2046 | unsigned char *end = vsd->reloc_stream + vsd->reloc_size; | |
2047 | unsigned char *ptr, *arg_ptr; | |
2048 | const char *name; | |
2049 | int length; | |
2050 | ||
252b5132 | 2051 | #if VMS_DEBUG |
0c376465 TG |
2052 | _bfd_vms_debug (3, "_bfd_vms_decode_relocs: %d bytes\n", vsd->reloc_size); |
2053 | #endif | |
2054 | ||
2055 | #define PUSH_CMD() \ | |
2056 | { \ | |
2057 | saved_cmd = cmd; \ | |
2058 | saved_sym_offset = sym_offset - length; \ | |
2059 | saved_sec_offset = sec_offset - length; \ | |
2060 | saved_addend_offset = addend_offset - length; \ | |
2061 | continue; \ | |
2062 | } | |
2063 | ||
2064 | #define POP_CMD() \ | |
2065 | { \ | |
2066 | cmd = saved_cmd; \ | |
2067 | saved_cmd = ETIR_S_C_MAXSTCCOD + 1; \ | |
2068 | sym_offset = saved_sym_offset; \ | |
2069 | sec_offset = saved_sec_offset; \ | |
2070 | addend_offset= saved_addend_offset; \ | |
2071 | } | |
2072 | ||
2073 | #define CMD_PUSHED (saved_cmd != ETIR_S_C_MAXSTCCOD + 1) | |
2074 | ||
2075 | #define NO_OFFSET -128 | |
2076 | ||
2077 | saved_cmd = ETIR_S_C_MAXSTCCOD + 1; | |
2078 | saved_sym_offset = NO_OFFSET; | |
2079 | saved_sec_offset = NO_OFFSET; | |
2080 | saved_addend_offset = NO_OFFSET; | |
2081 | ||
2082 | for (ptr = begin; ptr < end; ptr += length) | |
2083 | { | |
2084 | cmd = bfd_getl16 (ptr); | |
2085 | length = bfd_getl16 (ptr + 2); | |
2086 | ||
2087 | arg_ptr = ptr + ETIR_S_C_HEADER_SIZE; | |
2088 | sym_offset = NO_OFFSET; | |
2089 | sec_offset = NO_OFFSET; | |
2090 | address_offset = NO_OFFSET; | |
2091 | addend_offset = NO_OFFSET; | |
2092 | ||
2093 | switch (cmd) | |
2094 | { | |
2095 | case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */ | |
2096 | /* ALPHA_R_REFQUAD und_section, step 1 */ | |
2097 | sym_offset = 0; | |
2098 | PUSH_CMD () | |
2099 | ||
2100 | case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */ | |
2101 | sec_offset = 0; | |
2102 | addend_offset = 4; | |
2103 | PUSH_CMD () | |
2104 | ||
2105 | case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */ | |
2106 | /* ALPHA_R_REFLONG und_section, step 2 */ | |
2107 | if (CMD_PUSHED) | |
2108 | { | |
2109 | POP_CMD () | |
2110 | if (cmd != ETIR_S_C_STA_GBL) | |
2111 | { | |
2112 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2113 | cmd_name (cmd), | |
2114 | cmd_name (ETIR_S_C_STA_LW)); | |
2115 | return 0; | |
2116 | } | |
2117 | cmd = ETIR_S_C_STA_LW; | |
2118 | } | |
2119 | addend_offset = 0; | |
2120 | PUSH_CMD () | |
2121 | ||
2122 | case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */ | |
2123 | /* ALPHA_R_REFQUAD und_section, step 2 */ | |
2124 | if (CMD_PUSHED) | |
2125 | { | |
2126 | POP_CMD () | |
2127 | if (cmd != ETIR_S_C_STA_GBL) | |
2128 | { | |
2129 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2130 | cmd_name (cmd), | |
2131 | cmd_name (ETIR_S_C_STA_QW)); | |
2132 | return 0; | |
2133 | } | |
2134 | cmd = ETIR_S_C_STA_QW; | |
2135 | } | |
2136 | addend_offset = 0; | |
2137 | PUSH_CMD () | |
2138 | ||
2139 | case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */ | |
2140 | /* ALPHA_R_REFLONG abs_section, step 2 */ | |
2141 | /* ALPHA_R_REFLONG others, step 2 */ | |
2142 | POP_CMD () | |
2143 | if (cmd != ETIR_S_C_OPR_ADD | |
2144 | && cmd != ETIR_S_C_STA_LW | |
2145 | && cmd != ETIR_S_C_STA_PQ) | |
2146 | { | |
2147 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2148 | cmd_name (cmd), cmd_name (ETIR_S_C_STO_LW)); | |
2149 | return 0; | |
2150 | } | |
2151 | reloc_code = BFD_RELOC_32; | |
2152 | break; | |
2153 | ||
2154 | case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */ | |
2155 | /* ALPHA_R_REFQUAD abs_section, step 2 */ | |
2156 | POP_CMD () | |
2157 | if (cmd != ETIR_S_C_OPR_ADD && cmd != ETIR_S_C_STA_QW) | |
2158 | { | |
2159 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2160 | cmd_name (cmd), cmd_name (ETIR_S_C_STO_QW)); | |
2161 | return 0; | |
2162 | } | |
2163 | reloc_code = BFD_RELOC_64; | |
2164 | break; | |
2165 | ||
2166 | case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */ | |
2167 | POP_CMD () | |
2168 | if (cmd != ETIR_S_C_STA_PQ) | |
2169 | { | |
2170 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2171 | cmd_name (cmd), cmd_name (ETIR_S_C_STO_OFF)); | |
2172 | return 0; | |
2173 | } | |
2174 | reloc_code = BFD_RELOC_64; | |
2175 | break; | |
2176 | ||
2177 | case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */ | |
2178 | /* ALPHA_R_REFQUAD und_section, step 3 */ | |
2179 | POP_CMD () | |
2180 | if (cmd != ETIR_S_C_STA_LW && cmd != ETIR_S_C_STA_QW) | |
2181 | { | |
2182 | (*_bfd_error_handler) (_("Unknown reloc %s + %s"), | |
2183 | cmd_name (cmd), cmd_name (ETIR_S_C_OPR_ADD)); | |
2184 | return 0; | |
2185 | } | |
2186 | cmd = ETIR_S_C_OPR_ADD; | |
2187 | PUSH_CMD () | |
2188 | ||
2189 | case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */ | |
2190 | reloc_code = BFD_RELOC_ALPHA_CODEADDR; | |
2191 | sym_offset = 0; | |
2192 | break; | |
2193 | ||
2194 | case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */ | |
2195 | reloc_code = BFD_RELOC_64; | |
2196 | sym_offset = 0; | |
2197 | break; | |
2198 | ||
2199 | case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */ | |
2200 | reloc_code = BFD_RELOC_32; | |
2201 | sym_offset = 0; | |
2202 | break; | |
2203 | ||
2204 | case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */ | |
2205 | reloc_code = BFD_RELOC_ALPHA_LINKAGE; | |
2206 | sym_offset = 4; | |
2207 | break; | |
2208 | ||
2209 | case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */ | |
2210 | reloc_code = BFD_RELOC_ALPHA_NOP; | |
2211 | goto call_reloc; | |
2212 | ||
2213 | case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */ | |
2214 | reloc_code = BFD_RELOC_ALPHA_BSR; | |
2215 | goto call_reloc; | |
2216 | ||
2217 | case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */ | |
2218 | reloc_code = BFD_RELOC_ALPHA_LDA; | |
2219 | goto call_reloc; | |
2220 | ||
2221 | case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */ | |
2222 | reloc_code = BFD_RELOC_ALPHA_BOH; | |
2223 | goto call_reloc; | |
2224 | ||
2225 | call_reloc: | |
2226 | sym_offset = 32; | |
2227 | address_offset = 8; | |
2228 | addend_offset = 24; | |
2229 | break; | |
2230 | ||
2231 | case ETIR_S_C_STO_IMM: | |
2232 | vaddr += bfd_getl32 (arg_ptr); | |
2233 | length = ETIR_S_C_HEADER_SIZE + 4; | |
2234 | continue; | |
2235 | ||
2236 | default: | |
2237 | continue; | |
2238 | } | |
2239 | ||
2240 | relocs->howto = bfd_reloc_type_lookup (abfd, reloc_code); | |
2241 | ||
2242 | if (sym_offset > NO_OFFSET) | |
2243 | { | |
2244 | name = _bfd_vms_save_counted_string (arg_ptr + sym_offset); | |
2245 | entry = (vms_symbol_entry *) | |
2246 | bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE); | |
2247 | if (entry == NULL) | |
2248 | { | |
2249 | (*_bfd_error_handler) (_("Unknown symbol %s in command %s"), | |
2250 | name, cmd_name (cmd)); | |
2251 | relocs->sym_ptr_ptr = NULL; | |
2252 | } | |
2253 | else | |
2254 | /* ??? This is a hack. We should point in 'symbols'. */ | |
2255 | relocs->sym_ptr_ptr = &entry->symbol; | |
2256 | } | |
2257 | else if (sec_offset > NO_OFFSET) | |
2258 | relocs->sym_ptr_ptr | |
2259 | = PRIV (sections)[bfd_getl32 (arg_ptr + sec_offset)]->symbol_ptr_ptr; | |
2260 | else | |
2261 | relocs->sym_ptr_ptr = NULL; | |
2262 | ||
2263 | if (address_offset > NO_OFFSET) | |
2264 | relocs->address = bfd_getl64 (arg_ptr + address_offset); | |
2265 | else | |
2266 | relocs->address = vaddr; | |
2267 | ||
2268 | if (addend_offset > NO_OFFSET) | |
2269 | relocs->addend = bfd_getl64 (arg_ptr + addend_offset); | |
2270 | else | |
2271 | relocs->addend = 0; | |
2272 | ||
2273 | vaddr += bfd_get_reloc_size (relocs->howto); | |
2274 | relocs++; | |
2275 | } | |
2276 | ||
2277 | #undef PUSH_CMD | |
2278 | #undef POP_CMD | |
2279 | #undef NO_OFFSET | |
2280 | ||
2281 | #if VMS_DEBUG | |
2282 | _bfd_vms_debug (3, "_bfd_vms_decode_relocs: result = 0\n"); | |
252b5132 RH |
2283 | #endif |
2284 | ||
2285 | return 0; | |
2286 | } | |
2287 | ||
ca09e32b NC |
2288 | /* Process LNK record |
2289 | Return 0 on success, -1 on error | |
672579e9 | 2290 | |
ca09e32b | 2291 | Not implemented yet. */ |
252b5132 RH |
2292 | |
2293 | int | |
7920ce38 NC |
2294 | _bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED, |
2295 | int objtype ATTRIBUTE_UNUSED) | |
252b5132 RH |
2296 | { |
2297 | #if VMS_DEBUG | |
2298 | _bfd_vms_debug (2, "LNK\n"); | |
2299 | #endif | |
2300 | ||
2301 | return 0; | |
2302 | } | |
2303 | \f | |
0c376465 TG |
2304 | /* WRITE ETIR SECTION |
2305 | ||
2306 | This is still under construction and therefore not documented. */ | |
2307 | ||
2308 | static void start_etir_record (bfd *abfd, int index, uquad offset, | |
2309 | bfd_boolean justoffset); | |
2310 | static void start_first_etbt_record (bfd *abfd); | |
2311 | static void start_another_etbt_record (bfd *abfd); | |
2312 | static void sto_imm (bfd *abfd, bfd_size_type, unsigned char *, bfd_vma vaddr, | |
2313 | int index, const char *name); | |
2314 | static void end_etir_record (bfd *abfd); | |
2315 | static void etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, | |
2316 | int checklen); | |
2317 | ||
7920ce38 NC |
2318 | /* Start ETIR record for section #index at virtual addr offset. */ |
2319 | ||
2320 | static void | |
2321 | start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset) | |
2322 | { | |
2323 | if (!justoffset) | |
2324 | { | |
2325 | /* One ETIR per section. */ | |
2326 | _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1); | |
2327 | _bfd_vms_output_push (abfd); | |
2328 | } | |
2329 | ||
2330 | /* Push start offset. */ | |
2331 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1); | |
2332 | _bfd_vms_output_long (abfd, (unsigned long) index); | |
2333 | _bfd_vms_output_quad (abfd, (uquad) offset); | |
2334 | _bfd_vms_output_flush (abfd); | |
2335 | ||
2336 | /* Start = pop (). */ | |
2337 | _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); | |
2338 | _bfd_vms_output_flush (abfd); | |
2339 | } | |
2340 | ||
2341 | static void | |
2342 | end_etir_record (bfd * abfd) | |
2343 | { | |
2344 | _bfd_vms_output_pop (abfd); | |
2345 | _bfd_vms_output_end (abfd); | |
2346 | } | |
2347 | ||
0c376465 TG |
2348 | /* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual |
2349 | address VADDR in section specified by INDEX and NAME. */ | |
252b5132 | 2350 | |
252b5132 | 2351 | static void |
0c376465 TG |
2352 | sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr, |
2353 | int index, const char *name) | |
252b5132 | 2354 | { |
0c376465 | 2355 | bfd_size_type size; |
252b5132 RH |
2356 | |
2357 | #if VMS_DEBUG | |
0c376465 TG |
2358 | _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize); |
2359 | _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr); | |
252b5132 RH |
2360 | #endif |
2361 | ||
252b5132 RH |
2362 | while (ssize > 0) |
2363 | { | |
7920ce38 NC |
2364 | /* Try all the rest. */ |
2365 | size = ssize; | |
252b5132 RH |
2366 | |
2367 | if (_bfd_vms_output_check (abfd, size) < 0) | |
7920ce38 NC |
2368 | { |
2369 | /* Doesn't fit, split ! */ | |
252b5132 | 2370 | end_etir_record (abfd); |
0c376465 TG |
2371 | |
2372 | if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug")) | |
2373 | start_another_etbt_record (abfd); | |
2374 | else | |
2375 | start_etir_record (abfd, index, vaddr, FALSE); | |
2376 | ||
2377 | size = _bfd_vms_output_check (abfd, 0); /* get max size */ | |
2378 | if (size > ssize) /* more than what's left ? */ | |
252b5132 RH |
2379 | size = ssize; |
2380 | } | |
2381 | ||
2382 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1); | |
672579e9 | 2383 | _bfd_vms_output_long (abfd, (unsigned long) (size)); |
252b5132 RH |
2384 | _bfd_vms_output_dump (abfd, cptr, size); |
2385 | _bfd_vms_output_flush (abfd); | |
2386 | ||
2387 | #if VMS_DEBUG | |
2388 | _bfd_vms_debug (10, "dumped %d bytes\n", size); | |
dc810e39 | 2389 | _bfd_hexdump (10, cptr, (int) size, (int) vaddr); |
252b5132 RH |
2390 | #endif |
2391 | ||
2392 | vaddr += size; | |
252b5132 | 2393 | cptr += size; |
0c376465 TG |
2394 | ssize -= size; |
2395 | } | |
2396 | } | |
2397 | ||
2398 | /* Start ETBT record for section #index at virtual addr offset. */ | |
2399 | ||
2400 | static void | |
2401 | start_first_etbt_record (bfd *abfd) | |
2402 | { | |
2403 | _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1); | |
2404 | _bfd_vms_output_push (abfd); | |
2405 | ||
2406 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1); /* push start offset */ | |
2407 | _bfd_vms_output_long (abfd, (unsigned long) 0); | |
2408 | _bfd_vms_output_flush (abfd); | |
2409 | ||
2410 | _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_DFLOC, -1); /* start = pop() */ | |
2411 | _bfd_vms_output_flush (abfd); | |
2412 | } | |
2413 | ||
2414 | static void | |
2415 | start_another_etbt_record (bfd *abfd) | |
2416 | { | |
2417 | _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1); | |
2418 | _bfd_vms_output_push (abfd); | |
2419 | } | |
2420 | ||
2421 | static void | |
2422 | etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen) | |
2423 | { | |
2424 | if (_bfd_vms_output_check (abfd, checklen) < 0) | |
2425 | { | |
2426 | end_etir_record (abfd); | |
2427 | if (section->name[0] && section->name[1] == 'v' | |
2428 | && !strcmp (section->name, ".vmsdebug")) | |
2429 | start_another_etbt_record (abfd); | |
2430 | else | |
2431 | start_etir_record (abfd, section->index, vaddr, FALSE); | |
2432 | } | |
2433 | } | |
2434 | ||
2435 | /* Return whether RELOC must be deferred till the end. */ | |
2436 | ||
2437 | static int | |
2438 | defer_reloc_p (arelent *reloc) | |
2439 | { | |
2440 | switch (reloc->howto->type) | |
2441 | { | |
2442 | case ALPHA_R_NOP: | |
2443 | case ALPHA_R_LDA: | |
2444 | case ALPHA_R_BSR: | |
2445 | case ALPHA_R_BOH: | |
2446 | return 1; | |
2447 | ||
2448 | default: | |
2449 | return 0; | |
252b5132 | 2450 | } |
252b5132 RH |
2451 | } |
2452 | ||
ca09e32b | 2453 | /* Write section contents for bfd abfd. */ |
252b5132 RH |
2454 | |
2455 | int | |
7920ce38 | 2456 | _bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) |
252b5132 RH |
2457 | { |
2458 | asection *section; | |
252b5132 RH |
2459 | |
2460 | #if VMS_DEBUG | |
2461 | _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype); | |
2462 | #endif | |
2463 | ||
2464 | _bfd_vms_output_alignment (abfd, 4); | |
2465 | ||
dc810e39 | 2466 | PRIV (vms_linkage_index) = 1; |
252b5132 | 2467 | |
0c376465 | 2468 | for (section = abfd->sections; section; section = section->next) |
252b5132 | 2469 | { |
252b5132 | 2470 | #if VMS_DEBUG |
dc810e39 AM |
2471 | _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n", |
2472 | section->index, section->name, | |
eea6121a | 2473 | (int) (section->size)); |
252b5132 RH |
2474 | #endif |
2475 | ||
0c376465 TG |
2476 | if (!(section->flags & SEC_HAS_CONTENTS) |
2477 | || bfd_is_com_section (section)) | |
2478 | continue; | |
2479 | ||
2480 | if (!section->contents) | |
2481 | { | |
2482 | bfd_set_error (bfd_error_no_contents); | |
2483 | return -1; | |
2484 | } | |
2485 | ||
2486 | if (section->name[0] | |
2487 | && section->name[1] == 'v' | |
2488 | && !strcmp (section->name, ".vmsdebug")) | |
2489 | start_first_etbt_record (abfd); | |
2490 | else | |
2491 | start_etir_record (abfd, section->index, 0, FALSE); | |
2492 | ||
252b5132 RH |
2493 | if (section->flags & SEC_RELOC) |
2494 | { | |
0c376465 TG |
2495 | bfd_vma curr_addr = 0; |
2496 | unsigned char *curr_data = section->contents; | |
2497 | bfd_size_type size; | |
2498 | int pass2_needed = 0; | |
2499 | int pass2_in_progress = 0; | |
2500 | unsigned int irel; | |
2501 | ||
2502 | if (section->reloc_count <= 0) | |
2503 | (*_bfd_error_handler) | |
2504 | (_("SEC_RELOC with no relocs in section %s"), section->name); | |
252b5132 | 2505 | |
252b5132 RH |
2506 | #if VMS_DEBUG |
2507 | else | |
2508 | { | |
0c376465 TG |
2509 | int i = section->reloc_count; |
2510 | arelent **rptr = section->orelocation; | |
252b5132 | 2511 | _bfd_vms_debug (4, "%d relocations:\n", i); |
252b5132 RH |
2512 | while (i-- > 0) |
2513 | { | |
0c376465 TG |
2514 | _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, " |
2515 | "addr %08lx, off %08lx, len %d: %s\n", | |
dc810e39 AM |
2516 | (*(*rptr)->sym_ptr_ptr)->name, |
2517 | (*(*rptr)->sym_ptr_ptr)->section->name, | |
2518 | (long) (*(*rptr)->sym_ptr_ptr)->value, | |
2519 | (*rptr)->address, (*rptr)->addend, | |
2520 | bfd_get_reloc_size ((*rptr)->howto), | |
0c376465 | 2521 | ( *rptr)->howto->name); |
252b5132 RH |
2522 | rptr++; |
2523 | } | |
2524 | } | |
2525 | #endif | |
252b5132 | 2526 | |
0c376465 TG |
2527 | new_pass: |
2528 | for (irel = 0; irel < section->reloc_count; irel++) | |
252b5132 | 2529 | { |
0c376465 TG |
2530 | struct evax_private_udata_struct *udata; |
2531 | arelent *rptr = section->orelocation [irel]; | |
2532 | bfd_vma addr = rptr->address; | |
2533 | asymbol *sym = *rptr->sym_ptr_ptr; | |
2534 | asection *sec = sym->section; | |
2535 | int defer = defer_reloc_p (rptr); | |
2536 | unsigned int slen; | |
2537 | char *hash; | |
2538 | ||
2539 | if (pass2_in_progress) | |
2540 | { | |
2541 | /* Non-deferred relocs have already been output. */ | |
2542 | if (!defer) | |
2543 | continue; | |
2544 | } | |
2545 | else | |
2546 | { | |
2547 | /* Deferred relocs must be output at the very end. */ | |
2548 | if (defer) | |
2549 | { | |
2550 | pass2_needed = 1; | |
2551 | continue; | |
2552 | } | |
252b5132 | 2553 | |
0c376465 TG |
2554 | /* Regular relocs are intertwined with binary data. */ |
2555 | if (curr_addr > addr) | |
2556 | (*_bfd_error_handler) (_("Size error in section %s"), | |
2557 | section->name); | |
2558 | size = addr - curr_addr; | |
2559 | sto_imm (abfd, size, curr_data, curr_addr, | |
2560 | section->index, section->name); | |
2561 | curr_data += size; | |
2562 | curr_addr += size; | |
2563 | } | |
252b5132 | 2564 | |
0c376465 | 2565 | size = bfd_get_reloc_size (rptr->howto); |
252b5132 | 2566 | |
0c376465 TG |
2567 | switch (rptr->howto->type) |
2568 | { | |
2569 | case ALPHA_R_IGNORE: | |
2570 | break; | |
ca09e32b | 2571 | |
0c376465 TG |
2572 | case ALPHA_R_REFLONG: |
2573 | if (bfd_is_und_section (sym->section)) | |
252b5132 | 2574 | { |
0c376465 TG |
2575 | bfd_vma addend = rptr->addend; |
2576 | slen = strlen ((char *) sym->name); | |
2577 | hash = _bfd_vms_length_hash_symbol | |
2578 | (abfd, sym->name, EOBJ_S_C_SYMSIZ); | |
2579 | etir_output_check (abfd, section, curr_addr, slen); | |
2580 | if (addend) | |
252b5132 | 2581 | { |
0c376465 TG |
2582 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1); |
2583 | _bfd_vms_output_counted (abfd, hash); | |
2584 | _bfd_vms_output_flush (abfd); | |
2585 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1); | |
2586 | _bfd_vms_output_long (abfd, (unsigned long) addend); | |
2587 | _bfd_vms_output_flush (abfd); | |
2588 | _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1); | |
2589 | _bfd_vms_output_flush (abfd); | |
2590 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1); | |
2591 | _bfd_vms_output_flush (abfd); | |
252b5132 | 2592 | } |
7920ce38 | 2593 | else |
252b5132 | 2594 | { |
0c376465 TG |
2595 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1); |
2596 | _bfd_vms_output_counted (abfd, hash); | |
2597 | _bfd_vms_output_flush (abfd); | |
252b5132 | 2598 | } |
0c376465 TG |
2599 | } |
2600 | else if (bfd_is_abs_section (sym->section)) | |
2601 | { | |
2602 | etir_output_check (abfd, section, curr_addr, 16); | |
2603 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1); | |
2604 | _bfd_vms_output_long (abfd, (unsigned long) sym->value); | |
2605 | _bfd_vms_output_flush (abfd); | |
2606 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1); | |
2607 | _bfd_vms_output_flush (abfd); | |
2608 | } | |
2609 | else | |
2610 | { | |
2611 | etir_output_check (abfd, section, curr_addr, 32); | |
2612 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1); | |
2613 | _bfd_vms_output_long (abfd, (unsigned long) sec->index); | |
2614 | _bfd_vms_output_quad (abfd, (uquad) rptr->addend | |
2615 | + (uquad) sym->value); | |
2616 | _bfd_vms_output_flush (abfd); | |
2617 | /* ??? Table B-8 of the OpenVMS Linker Utilily Manual | |
2618 | says that we should have a ETIR_S_C_STO_OFF here. | |
2619 | But the relocation would not be BFD_RELOC_32 then. | |
2620 | This case is very likely unreachable. */ | |
2621 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1); | |
2622 | _bfd_vms_output_flush (abfd); | |
2623 | } | |
2624 | break; | |
252b5132 | 2625 | |
0c376465 TG |
2626 | case ALPHA_R_REFQUAD: |
2627 | if (bfd_is_und_section (sym->section)) | |
2628 | { | |
2629 | bfd_vma addend = rptr->addend; | |
2630 | slen = strlen ((char *) sym->name); | |
2631 | hash = _bfd_vms_length_hash_symbol | |
2632 | (abfd, sym->name, EOBJ_S_C_SYMSIZ); | |
2633 | etir_output_check (abfd, section, curr_addr, slen); | |
2634 | if (addend) | |
2635 | { | |
2636 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1); | |
2637 | _bfd_vms_output_counted (abfd, hash); | |
2638 | _bfd_vms_output_flush (abfd); | |
2639 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1); | |
2640 | _bfd_vms_output_quad (abfd, (uquad) addend); | |
2641 | _bfd_vms_output_flush (abfd); | |
2642 | _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1); | |
2643 | _bfd_vms_output_flush (abfd); | |
2644 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1); | |
2645 | _bfd_vms_output_flush (abfd); | |
2646 | } | |
2647 | else | |
252b5132 | 2648 | { |
0c376465 TG |
2649 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1); |
2650 | _bfd_vms_output_counted (abfd, hash); | |
2651 | _bfd_vms_output_flush (abfd); | |
252b5132 | 2652 | } |
7920ce38 | 2653 | } |
0c376465 TG |
2654 | else if (bfd_is_abs_section (sym->section)) |
2655 | { | |
2656 | etir_output_check (abfd, section, curr_addr, 16); | |
2657 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1); | |
2658 | _bfd_vms_output_quad (abfd, (uquad) sym->value); | |
2659 | _bfd_vms_output_flush (abfd); | |
2660 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1); | |
2661 | _bfd_vms_output_flush (abfd); | |
2662 | } | |
2663 | else | |
2664 | { | |
2665 | etir_output_check (abfd, section, curr_addr, 32); | |
2666 | _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1); | |
2667 | _bfd_vms_output_long (abfd, (unsigned long) sec->index); | |
2668 | _bfd_vms_output_quad (abfd, (uquad) rptr->addend | |
2669 | + (uquad) sym->value); | |
2670 | _bfd_vms_output_flush (abfd); | |
2671 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_OFF, -1); | |
2672 | _bfd_vms_output_flush (abfd); | |
2673 | } | |
2674 | break; | |
2675 | ||
2676 | case ALPHA_R_HINT: | |
2677 | sto_imm (abfd, size, curr_data, curr_addr, | |
2678 | section->index, section->name); | |
2679 | break; | |
2680 | ||
2681 | case ALPHA_R_LINKAGE: | |
2682 | etir_output_check (abfd, section, curr_addr, 64); | |
2683 | _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LP_PSB, -1); | |
2684 | _bfd_vms_output_long | |
2685 | (abfd, (unsigned long) PRIV (vms_linkage_index)); | |
2686 | PRIV (vms_linkage_index) += 2; | |
2687 | hash = _bfd_vms_length_hash_symbol | |
2688 | (abfd, sym->name, EOBJ_S_C_SYMSIZ); | |
2689 | _bfd_vms_output_counted (abfd, hash); | |
2690 | _bfd_vms_output_byte (abfd, 0); | |
2691 | _bfd_vms_output_flush (abfd); | |
2692 | break; | |
2693 | ||
2694 | case ALPHA_R_CODEADDR: | |
2695 | slen = strlen ((char *) sym->name); | |
2696 | hash = _bfd_vms_length_hash_symbol | |
2697 | (abfd, sym->name, EOBJ_S_C_SYMSIZ); | |
2698 | etir_output_check (abfd, section, curr_addr, slen); | |
2699 | _bfd_vms_output_begin (abfd, ETIR_S_C_STO_CA, -1); | |
2700 | _bfd_vms_output_counted (abfd, hash); | |
2701 | _bfd_vms_output_flush (abfd); | |
2702 | break; | |
2703 | ||
2704 | case ALPHA_R_NOP: | |
2705 | udata | |
2706 | = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; | |
2707 | etir_output_check (abfd, section, curr_addr, | |
2708 | 32 + 1 + strlen (udata->origname)); | |
2709 | _bfd_vms_output_begin (abfd, ETIR_S_C_STC_NOP_GBL, -1); | |
2710 | _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex); | |
2711 | _bfd_vms_output_long | |
2712 | (abfd, (unsigned long) udata->enbsym->section->index); | |
2713 | _bfd_vms_output_quad (abfd, (uquad) rptr->address); | |
2714 | _bfd_vms_output_long (abfd, (unsigned long) 0x47ff041f); | |
2715 | _bfd_vms_output_long | |
2716 | (abfd, (unsigned long) udata->enbsym->section->index); | |
2717 | _bfd_vms_output_quad (abfd, (uquad) rptr->addend); | |
2718 | _bfd_vms_output_counted | |
2719 | (abfd, _bfd_vms_length_hash_symbol | |
2720 | (abfd, udata->origname, EOBJ_S_C_SYMSIZ)); | |
2721 | _bfd_vms_output_flush (abfd); | |
2722 | break; | |
2723 | ||
2724 | case ALPHA_R_BSR: | |
2725 | (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc")); | |
2726 | break; | |
2727 | ||
2728 | case ALPHA_R_LDA: | |
2729 | udata | |
2730 | = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; | |
2731 | etir_output_check (abfd, section, curr_addr, | |
2732 | 32 + 1 + strlen (udata->origname)); | |
2733 | _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LDA_GBL, -1); | |
2734 | _bfd_vms_output_long | |
2735 | (abfd, (unsigned long) udata->lkindex + 1); | |
2736 | _bfd_vms_output_long | |
2737 | (abfd, (unsigned long) udata->enbsym->section->index); | |
2738 | _bfd_vms_output_quad (abfd, (uquad) rptr->address); | |
2739 | _bfd_vms_output_long (abfd, (unsigned long) 0x237B0000); | |
2740 | _bfd_vms_output_long | |
2741 | (abfd, (unsigned long) udata->bsym->section->index); | |
2742 | _bfd_vms_output_quad (abfd, (uquad) rptr->addend); | |
2743 | _bfd_vms_output_counted | |
2744 | (abfd, _bfd_vms_length_hash_symbol | |
2745 | (abfd, udata->origname, EOBJ_S_C_SYMSIZ)); | |
2746 | _bfd_vms_output_flush (abfd); | |
2747 | break; | |
2748 | ||
2749 | case ALPHA_R_BOH: | |
2750 | udata | |
2751 | = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr; | |
2752 | etir_output_check (abfd, section, curr_addr, | |
2753 | 32 + 1 + strlen (udata->origname)); | |
2754 | _bfd_vms_output_begin (abfd, ETIR_S_C_STC_BOH_GBL, -1); | |
2755 | _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex); | |
2756 | _bfd_vms_output_long | |
2757 | (abfd, (unsigned long) udata->enbsym->section->index); | |
2758 | _bfd_vms_output_quad (abfd, (uquad) rptr->address); | |
2759 | _bfd_vms_output_long (abfd, (unsigned long) 0xD3400000); | |
2760 | _bfd_vms_output_long | |
2761 | (abfd, (unsigned long) udata->enbsym->section->index); | |
2762 | _bfd_vms_output_quad (abfd, (uquad) rptr->addend); | |
2763 | _bfd_vms_output_counted | |
2764 | (abfd, _bfd_vms_length_hash_symbol | |
2765 | (abfd, udata->origname, EOBJ_S_C_SYMSIZ)); | |
2766 | _bfd_vms_output_flush (abfd); | |
2767 | break; | |
2768 | ||
2769 | default: | |
2770 | (*_bfd_error_handler) (_("Unhandled relocation %s"), | |
2771 | rptr->howto->name); | |
2772 | break; | |
7920ce38 | 2773 | } |
0c376465 TG |
2774 | |
2775 | curr_data += size; | |
2776 | curr_addr += size; | |
2777 | } /* End of relocs loop. */ | |
2778 | ||
2779 | if (!pass2_in_progress) | |
2780 | { | |
2781 | /* Output rest of section. */ | |
2782 | if (curr_addr > section->size) | |
2783 | (*_bfd_error_handler) (_("Size error in section %s"), | |
2784 | section->name); | |
2785 | size = section->size - curr_addr; | |
2786 | sto_imm (abfd, size, curr_data, curr_addr, | |
2787 | section->index, section->name); | |
2788 | curr_data += size; | |
2789 | curr_addr += size; | |
2790 | ||
2791 | if (pass2_needed) | |
252b5132 | 2792 | { |
0c376465 TG |
2793 | pass2_in_progress = 1; |
2794 | goto new_pass; | |
252b5132 | 2795 | } |
7920ce38 | 2796 | } |
7920ce38 | 2797 | } |
0c376465 TG |
2798 | |
2799 | else /* (section->flags & SEC_RELOC) */ | |
2800 | sto_imm (abfd, section->size, section->contents, 0, | |
2801 | section->index, section->name); | |
252b5132 | 2802 | |
0c376465 | 2803 | end_etir_record (abfd); |
252b5132 RH |
2804 | } |
2805 | ||
dc810e39 | 2806 | _bfd_vms_output_alignment (abfd, 2); |
252b5132 RH |
2807 | return 0; |
2808 | } |