PowerPC relocations for prefix insns
[deliverable/binutils-gdb.git] / gas / config / tc-moxie.c
CommitLineData
20135e4c 1/* tc-moxie.c -- Assemble code for moxie
82704155 2 Copyright (C) 2009-2019 Free Software Foundation, Inc.
20135e4c
NC
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
20
21/* Contributed by Anthony Green <green@moxielogic.com>. */
22
23#include "as.h"
24#include "safe-ctype.h"
25#include "opcode/moxie.h"
26#include "elf/moxie.h"
27
28extern const moxie_opc_info_t moxie_opc_info[128];
29
30const char comment_chars[] = "#";
31const char line_separator_chars[] = ";";
32const char line_comment_chars[] = "#";
33
34static int pending_reloc;
35static struct hash_control *opcode_hash_control;
36
37const pseudo_typeS md_pseudo_table[] =
38{
39 {0, 0, 0}
40};
41
42const char FLT_CHARS[] = "rRsSfFdDxXpP";
43const char EXP_CHARS[] = "eE";
44
e202fa84
AG
45static valueT md_chars_to_number (char * buf, int n);
46
47/* Byte order. */
48extern int target_big_endian;
f865a31d 49
20135e4c
NC
50void
51md_operand (expressionS *op __attribute__((unused)))
52{
53 /* Empty for now. */
54}
55
56/* This function is called once, at assembler startup time. It sets
57 up the hash table with all the opcodes in it, and also initializes
58 some aliases for compatibility with other assemblers. */
59
60void
61md_begin (void)
62{
63 int count;
64 const moxie_opc_info_t *opcode;
65 opcode_hash_control = hash_new ();
66
67 /* Insert names into hash table. */
68 for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
69 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
70
71 for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
72 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
73
f865a31d 74 for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
20135e4c
NC
75 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
76
48494700
AG
77 target_big_endian = TARGET_BYTES_BIG_ENDIAN;
78
20135e4c
NC
79 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
80}
81
82/* Parse an expression and then restore the input line pointer. */
83
84static char *
85parse_exp_save_ilp (char *s, expressionS *op)
86{
87 char *save = input_line_pointer;
88
89 input_line_pointer = s;
90 expression (op);
91 s = input_line_pointer;
92 input_line_pointer = save;
93 return s;
94}
95
96static int
97parse_register_operand (char **ptr)
98{
99 int reg;
100 char *s = *ptr;
101
102 if (*s != '$')
103 {
20203fb9 104 as_bad (_("expecting register"));
20135e4c
NC
105 ignore_rest_of_line ();
106 return -1;
107 }
108 if (s[1] == 'f' && s[2] == 'p')
109 {
110 *ptr += 3;
111 return 0;
112 }
113 if (s[1] == 's' && s[2] == 'p')
114 {
115 *ptr += 3;
116 return 1;
117 }
118 if (s[1] == 'r')
119 {
120 reg = s[2] - '0';
121 if ((reg < 0) || (reg > 9))
122 {
20203fb9 123 as_bad (_("illegal register number"));
20135e4c
NC
124 ignore_rest_of_line ();
125 return -1;
126 }
127 if (reg == 1)
128 {
129 int r2 = s[3] - '0';
130 if ((r2 >= 0) && (r2 <= 3))
131 {
132 reg = 10 + r2;
133 *ptr += 1;
134 }
135 }
136 }
137 else
138 {
20203fb9 139 as_bad (_("illegal register number"));
20135e4c
NC
140 ignore_rest_of_line ();
141 return -1;
142 }
143
144 *ptr += 3;
145
146 return reg + 2;
147}
148
149/* This is the guts of the machine-dependent assembler. STR points to
150 a machine dependent instruction. This function is supposed to emit
151 the frags/bytes it assembles to. */
152
153void
154md_assemble (char *str)
155{
156 char *op_start;
157 char *op_end;
158
159 moxie_opc_info_t *opcode;
160 char *p;
161 char pend;
162
163 unsigned short iword = 0;
164
165 int nlen = 0;
166
167 /* Drop leading whitespace. */
168 while (*str == ' ')
169 str++;
170
171 /* Find the op code end. */
172 op_start = str;
173 for (op_end = str;
174 *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
175 op_end++)
176 nlen++;
177
178 pend = *op_end;
179 *op_end = 0;
180
181 if (nlen == 0)
182 as_bad (_("can't find opcode "));
183 opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
184 *op_end = pend;
185
186 if (opcode == NULL)
187 {
188 as_bad (_("unknown opcode %s"), op_start);
189 return;
190 }
191
192 p = frag_more (2);
193
194 switch (opcode->itype)
195 {
196 case MOXIE_F2_A8V:
197 iword = (1<<15) | (opcode->opcode << 12);
198 while (ISSPACE (*op_end))
199 op_end++;
200 {
201 expressionS arg;
202 int reg;
203 reg = parse_register_operand (&op_end);
204 iword += (reg << 8);
205 if (*op_end != ',')
2cbd2211 206 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
207 op_end++;
208 op_end = parse_exp_save_ilp (op_end, &arg);
209 fix_new_exp (frag_now,
e202fa84 210 ((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
20135e4c
NC
211 1,
212 &arg,
213 0,
214 BFD_RELOC_8);
215 }
216 break;
217 case MOXIE_F1_AB:
218 iword = opcode->opcode << 8;
219 while (ISSPACE (*op_end))
220 op_end++;
221 {
222 int dest, src;
223 dest = parse_register_operand (&op_end);
224 if (*op_end != ',')
2cbd2211 225 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
226 op_end++;
227 src = parse_register_operand (&op_end);
228 iword += (dest << 4) + src;
229 while (ISSPACE (*op_end))
230 op_end++;
231 if (*op_end != 0)
20203fb9 232 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
233 }
234 break;
235 case MOXIE_F1_A4:
236 iword = opcode->opcode << 8;
237 while (ISSPACE (*op_end))
238 op_end++;
239 {
240 expressionS arg;
241 char *where;
242 int regnum;
243
244 regnum = parse_register_operand (&op_end);
245 while (ISSPACE (*op_end))
246 op_end++;
247
248 iword += (regnum << 4);
249
250 if (*op_end != ',')
251 {
20203fb9 252 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
253 ignore_rest_of_line ();
254 return;
255 }
256 op_end++;
257
258 op_end = parse_exp_save_ilp (op_end, &arg);
259 where = frag_more (4);
260 fix_new_exp (frag_now,
261 (where - frag_now->fr_literal),
262 4,
263 &arg,
264 0,
265 BFD_RELOC_32);
266 }
267 break;
d7a5ed35 268 case MOXIE_F1_M:
20135e4c
NC
269 case MOXIE_F1_4:
270 iword = opcode->opcode << 8;
271 while (ISSPACE (*op_end))
272 op_end++;
273 {
274 expressionS arg;
275 char *where;
276
277 op_end = parse_exp_save_ilp (op_end, &arg);
278 where = frag_more (4);
279 fix_new_exp (frag_now,
280 (where - frag_now->fr_literal),
281 4,
282 &arg,
283 0,
284 BFD_RELOC_32);
285 }
286 break;
287 case MOXIE_F1_NARG:
288 iword = opcode->opcode << 8;
289 while (ISSPACE (*op_end))
290 op_end++;
291 if (*op_end != 0)
20203fb9 292 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
293 break;
294 case MOXIE_F1_A:
295 iword = opcode->opcode << 8;
296 while (ISSPACE (*op_end))
297 op_end++;
298 {
299 int reg;
300 reg = parse_register_operand (&op_end);
301 while (ISSPACE (*op_end))
302 op_end++;
303 if (*op_end != 0)
20203fb9 304 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
305 iword += (reg << 4);
306 }
307 break;
308 case MOXIE_F1_ABi:
309 iword = opcode->opcode << 8;
310 while (ISSPACE (*op_end))
311 op_end++;
312 {
313 int a, b;
314 a = parse_register_operand (&op_end);
315 if (*op_end != ',')
2cbd2211 316 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
317 op_end++;
318 if (*op_end != '(')
319 {
20203fb9 320 as_bad (_("expecting indirect register `($rA)'"));
20135e4c
NC
321 ignore_rest_of_line ();
322 return;
323 }
324 op_end++;
325 b = parse_register_operand (&op_end);
326 if (*op_end != ')')
327 {
20203fb9 328 as_bad (_("missing closing parenthesis"));
20135e4c
NC
329 ignore_rest_of_line ();
330 return;
331 }
332 op_end++;
333 iword += (a << 4) + b;
334 while (ISSPACE (*op_end))
335 op_end++;
336 if (*op_end != 0)
20203fb9 337 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
338 }
339 break;
340 case MOXIE_F1_AiB:
341 iword = opcode->opcode << 8;
342 while (ISSPACE (*op_end))
343 op_end++;
344 {
345 int a, b;
346 if (*op_end != '(')
347 {
20203fb9 348 as_bad (_("expecting indirect register `($rA)'"));
20135e4c
NC
349 ignore_rest_of_line ();
350 return;
351 }
352 op_end++;
353 a = parse_register_operand (&op_end);
354 if (*op_end != ')')
355 {
20203fb9 356 as_bad (_("missing closing parenthesis"));
20135e4c
NC
357 ignore_rest_of_line ();
358 return;
359 }
360 op_end++;
361 if (*op_end != ',')
2cbd2211 362 as_warn (_("expecting comma delimited register operands"));
20135e4c
NC
363 op_end++;
364 b = parse_register_operand (&op_end);
365 iword += (a << 4) + b;
366 while (ISSPACE (*op_end))
367 op_end++;
368 if (*op_end != 0)
20203fb9 369 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
370 }
371 break;
372 case MOXIE_F1_4A:
373 iword = opcode->opcode << 8;
374 while (ISSPACE (*op_end))
375 op_end++;
376 {
377 expressionS arg;
378 char *where;
379 int a;
380
381 op_end = parse_exp_save_ilp (op_end, &arg);
382 where = frag_more (4);
383 fix_new_exp (frag_now,
384 (where - frag_now->fr_literal),
385 4,
386 &arg,
387 0,
388 BFD_RELOC_32);
389
390 if (*op_end != ',')
391 {
20203fb9 392 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
393 ignore_rest_of_line ();
394 return;
395 }
396 op_end++;
397
398 a = parse_register_operand (&op_end);
399 while (ISSPACE (*op_end))
400 op_end++;
401 if (*op_end != 0)
20203fb9 402 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
403
404 iword += (a << 4);
405 }
406 break;
bffb6004 407 case MOXIE_F1_ABi2:
20135e4c
NC
408 iword = opcode->opcode << 8;
409 while (ISSPACE (*op_end))
410 op_end++;
411 {
412 expressionS arg;
413 char *offset;
414 int a, b;
415
416 a = parse_register_operand (&op_end);
417 while (ISSPACE (*op_end))
418 op_end++;
419
420 if (*op_end != ',')
421 {
20203fb9 422 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
423 ignore_rest_of_line ();
424 return;
425 }
426 op_end++;
427
428 op_end = parse_exp_save_ilp (op_end, &arg);
bffb6004 429 offset = frag_more (2);
20135e4c
NC
430 fix_new_exp (frag_now,
431 (offset - frag_now->fr_literal),
bffb6004 432 2,
20135e4c
NC
433 &arg,
434 0,
bffb6004 435 BFD_RELOC_16);
20135e4c
NC
436
437 if (*op_end != '(')
438 {
20203fb9 439 as_bad (_("expecting indirect register `($rX)'"));
20135e4c
NC
440 ignore_rest_of_line ();
441 return;
442 }
443 op_end++;
444 b = parse_register_operand (&op_end);
445 if (*op_end != ')')
446 {
20203fb9 447 as_bad (_("missing closing parenthesis"));
20135e4c
NC
448 ignore_rest_of_line ();
449 return;
450 }
451 op_end++;
452
453 while (ISSPACE (*op_end))
454 op_end++;
455 if (*op_end != 0)
20203fb9 456 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
457
458 iword += (a << 4) + b;
459 }
460 break;
bffb6004 461 case MOXIE_F1_AiB2:
20135e4c
NC
462 iword = opcode->opcode << 8;
463 while (ISSPACE (*op_end))
464 op_end++;
465 {
466 expressionS arg;
467 char *offset;
468 int a, b;
469
470 op_end = parse_exp_save_ilp (op_end, &arg);
bffb6004 471 offset = frag_more (2);
20135e4c
NC
472 fix_new_exp (frag_now,
473 (offset - frag_now->fr_literal),
bffb6004 474 2,
20135e4c
NC
475 &arg,
476 0,
bffb6004 477 BFD_RELOC_16);
20135e4c
NC
478
479 if (*op_end != '(')
480 {
20203fb9 481 as_bad (_("expecting indirect register `($rX)'"));
20135e4c
NC
482 ignore_rest_of_line ();
483 return;
484 }
485 op_end++;
486 a = parse_register_operand (&op_end);
487 if (*op_end != ')')
488 {
20203fb9 489 as_bad (_("missing closing parenthesis"));
20135e4c
NC
490 ignore_rest_of_line ();
491 return;
492 }
493 op_end++;
494
495 if (*op_end != ',')
496 {
20203fb9 497 as_bad (_("expecting comma delimited operands"));
20135e4c
NC
498 ignore_rest_of_line ();
499 return;
500 }
501 op_end++;
502
503 b = parse_register_operand (&op_end);
504 while (ISSPACE (*op_end))
505 op_end++;
506
507 while (ISSPACE (*op_end))
508 op_end++;
509 if (*op_end != 0)
20203fb9 510 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
511
512 iword += (a << 4) + b;
513 }
514 break;
515 case MOXIE_F2_NARG:
516 iword = opcode->opcode << 12;
517 while (ISSPACE (*op_end))
518 op_end++;
519 if (*op_end != 0)
20203fb9 520 as_warn (_("extra stuff on line ignored"));
20135e4c 521 break;
f865a31d
AG
522 case MOXIE_F3_PCREL:
523 iword = (3<<14) | (opcode->opcode << 10);
524 while (ISSPACE (*op_end))
525 op_end++;
526 {
527 expressionS arg;
528
529 op_end = parse_exp_save_ilp (op_end, &arg);
530 fix_new_exp (frag_now,
531 (p - frag_now->fr_literal),
532 2,
533 &arg,
534 TRUE,
535 BFD_RELOC_MOXIE_10_PCREL);
536 }
537 break;
3f47df7f
AG
538 case MOXIE_BAD:
539 iword = 0;
540 while (ISSPACE (*op_end))
541 op_end++;
542 if (*op_end != 0)
543 as_warn (_("extra stuff on line ignored"));
544 break;
20135e4c 545 default:
20203fb9 546 abort ();
20135e4c
NC
547 }
548
549 md_number_to_chars (p, iword, 2);
3ee6e4fb 550 dwarf2_emit_insn (2);
20135e4c
NC
551
552 while (ISSPACE (*op_end))
553 op_end++;
554
555 if (*op_end != 0)
20203fb9 556 as_warn (_("extra stuff on line ignored"));
20135e4c
NC
557
558 if (pending_reloc)
20203fb9 559 as_bad (_("Something forgot to clean up\n"));
20135e4c
NC
560}
561
562/* Turn a string in input_line_pointer into a floating point constant
563 of type type, and store the appropriate bytes in *LITP. The number
564 of LITTLENUMS emitted is stored in *SIZEP . An error message is
565 returned, or NULL on OK. */
566
6d4af3c2 567const char *
20135e4c
NC
568md_atof (int type, char *litP, int *sizeP)
569{
570 int prec;
571 LITTLENUM_TYPE words[4];
572 char *t;
573 int i;
574
575 switch (type)
576 {
577 case 'f':
578 prec = 2;
579 break;
580
581 case 'd':
582 prec = 4;
583 break;
584
585 default:
586 *sizeP = 0;
587 return _("bad call to md_atof");
588 }
589
590 t = atof_ieee (input_line_pointer, type, words);
591 if (t)
592 input_line_pointer = t;
593
594 *sizeP = prec * 2;
595
596 for (i = prec - 1; i >= 0; i--)
597 {
598 md_number_to_chars (litP, (valueT) words[i], 2);
599 litP += 2;
600 }
601
602 return NULL;
603}
e202fa84
AG
604
605enum options
606{
607 OPTION_EB = OPTION_MD_BASE,
608 OPTION_EL,
609};
20135e4c
NC
610
611struct option md_longopts[] =
612{
e202fa84
AG
613 { "EB", no_argument, NULL, OPTION_EB},
614 { "EL", no_argument, NULL, OPTION_EL},
615 { NULL, no_argument, NULL, 0}
20135e4c 616};
e202fa84 617
20135e4c 618size_t md_longopts_size = sizeof (md_longopts);
e202fa84
AG
619\f
620const char *md_shortopts = "";
20135e4c 621
20135e4c 622int
17b9d67d 623md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
20135e4c 624{
e202fa84
AG
625 switch (c)
626 {
3739860c
L
627 case OPTION_EB:
628 target_big_endian = 1;
e202fa84 629 break;
3739860c 630 case OPTION_EL:
e202fa84 631 target_big_endian = 0;
e202fa84 632 break;
3739860c 633 default:
e202fa84
AG
634 return 0;
635 }
636
637 return 1;
20135e4c
NC
638}
639
640void
641md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
642{
e202fa84
AG
643 fprintf (stream, _("\
644 -EB assemble for a big endian system (default)\n\
645 -EL assemble for a little endian system\n"));
20135e4c
NC
646}
647
648/* Apply a fixup to the object file. */
649
650void
3739860c 651md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
f865a31d 652 valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
20135e4c
NC
653{
654 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
655 long val = *valP;
f865a31d 656 long newval;
20135e4c 657 long max, min;
20135e4c
NC
658
659 max = min = 0;
20135e4c
NC
660 switch (fixP->fx_r_type)
661 {
662 case BFD_RELOC_32:
e202fa84
AG
663 if (target_big_endian)
664 {
665 buf[0] = val >> 24;
666 buf[1] = val >> 16;
667 buf[2] = val >> 8;
668 buf[3] = val >> 0;
669 }
670 else
671 {
672 buf[3] = val >> 24;
673 buf[2] = val >> 16;
674 buf[1] = val >> 8;
675 buf[0] = val >> 0;
676 }
677 buf += 4;
20135e4c
NC
678 break;
679
680 case BFD_RELOC_16:
e202fa84
AG
681 if (target_big_endian)
682 {
683 buf[0] = val >> 8;
684 buf[1] = val >> 0;
685 }
686 else
687 {
688 buf[1] = val >> 8;
689 buf[0] = val >> 0;
690 }
691 buf += 2;
20135e4c
NC
692 break;
693
694 case BFD_RELOC_8:
695 *buf++ = val;
696 break;
697
f865a31d
AG
698 case BFD_RELOC_MOXIE_10_PCREL:
699 if (!val)
700 break;
701 if (val < -1024 || val > 1022)
702 as_bad_where (fixP->fx_file, fixP->fx_line,
703 _("pcrel too far BFD_RELOC_MOXIE_10"));
704 /* 11 bit offset even numbered, so we remove right bit. */
705 val >>= 1;
706 newval = md_chars_to_number (buf, 2);
707 newval |= val & 0x03ff;
708 md_number_to_chars (buf, newval, 2);
709 break;
710
20135e4c
NC
711 default:
712 abort ();
713 }
714
715 if (max != 0 && (val < min || val > max))
716 as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
717
718 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
719 fixP->fx_done = 1;
720}
721
e202fa84 722/* Put number into target byte order. */
20135e4c
NC
723
724void
e202fa84 725md_number_to_chars (char * ptr, valueT use, int nbytes)
20135e4c 726{
e202fa84
AG
727 if (target_big_endian)
728 number_to_chars_bigendian (ptr, use, nbytes);
729 else
730 number_to_chars_littleendian (ptr, use, nbytes);
20135e4c
NC
731}
732
f865a31d
AG
733/* Convert from target byte order to host byte order. */
734
e202fa84
AG
735static valueT
736md_chars_to_number (char * buf, int n)
f865a31d 737{
e202fa84
AG
738 valueT result = 0;
739 unsigned char * where = (unsigned char *) buf;
f865a31d 740
e202fa84
AG
741 if (target_big_endian)
742 {
743 while (n--)
744 {
745 result <<= 8;
746 result |= (*where++ & 255);
747 }
748 }
749 else
f865a31d 750 {
e202fa84
AG
751 while (n--)
752 {
753 result <<= 8;
754 result |= (where[n] & 255);
755 }
f865a31d
AG
756 }
757
e202fa84 758 return result;
f865a31d
AG
759}
760
20135e4c
NC
761/* Generate a machine-dependent relocation. */
762arelent *
763tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
764{
765 arelent *relP;
766 bfd_reloc_code_real_type code;
767
768 switch (fixP->fx_r_type)
769 {
770 case BFD_RELOC_32:
771 code = fixP->fx_r_type;
772 break;
f865a31d
AG
773 case BFD_RELOC_MOXIE_10_PCREL:
774 code = fixP->fx_r_type;
775 break;
20135e4c
NC
776 default:
777 as_bad_where (fixP->fx_file, fixP->fx_line,
778 _("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
779 return 0;
780 }
781
325801bd
TS
782 relP = XNEW (arelent);
783 relP->sym_ptr_ptr = XNEW (asymbol *);
20135e4c
NC
784 *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
785 relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
786
787 relP->addend = fixP->fx_offset;
788
789 /* This is the standard place for KLUDGEs to work around bugs in
790 bfd_install_relocation (first such note in the documentation
791 appears with binutils-2.8).
792
793 That function bfd_install_relocation does the wrong thing with
794 putting stuff into the addend of a reloc (it should stay out) for a
795 weak symbol. The really bad thing is that it adds the
796 "segment-relative offset" of the symbol into the reloc. In this
797 case, the reloc should instead be relative to the symbol with no
798 other offset than the assembly code shows; and since the symbol is
799 weak, any local definition should be ignored until link time (or
800 thereafter).
801 To wit: weaksym+42 should be weaksym+42 in the reloc,
802 not weaksym+(offset_from_segment_of_local_weaksym_definition)
803
804 To "work around" this, we subtract the segment-relative offset of
805 "known" weak symbols. This evens out the extra offset.
806
807 That happens for a.out but not for ELF, since for ELF,
808 bfd_install_relocation uses the "special function" field of the
809 howto, and does not execute the code that needs to be undone. */
810
811 if (OUTPUT_FLAVOR == bfd_target_aout_flavour
812 && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
813 && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
814 {
815 relP->addend -= S_GET_VALUE (fixP->fx_addsy);
816 }
817
818 relP->howto = bfd_reloc_type_lookup (stdoutput, code);
819 if (! relP->howto)
820 {
821 const char *name;
822
823 name = S_GET_NAME (fixP->fx_addsy);
824 if (name == NULL)
825 name = _("<unknown>");
826 as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
827 name, bfd_get_reloc_code_name (code));
828 }
829
830 return relP;
831}
832
833/* Decide from what point a pc-relative relocation is relative to,
834 relative to the pc-relative fixup. Er, relatively speaking. */
835long
836md_pcrel_from (fixS *fixP)
837{
838 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
839
20135e4c
NC
840 switch (fixP->fx_r_type)
841 {
842 case BFD_RELOC_32:
843 return addr + 4;
f865a31d 844 case BFD_RELOC_MOXIE_10_PCREL:
7078b409
AG
845 /* Offset is from the end of the instruction. */
846 return addr + 2;
20135e4c
NC
847 default:
848 abort ();
849 return addr;
850 }
851}
This page took 0.516885 seconds and 4 git commands to generate.