1440a403fSchristos /* tc-pj.c -- Assemble code for Pico Java
2*b88e3e88Schristos Copyright (C) 1999-2020 Free Software Foundation, Inc.
3440a403fSchristos
4440a403fSchristos This file is part of GAS, the GNU Assembler.
5440a403fSchristos
6440a403fSchristos GAS is free software; you can redistribute it and/or modify
7440a403fSchristos it under the terms of the GNU General Public License as published by
8440a403fSchristos the Free Software Foundation; either version 3, or (at your option)
9440a403fSchristos any later version.
10440a403fSchristos
11440a403fSchristos GAS is distributed in the hope that it will be useful,
12440a403fSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
13440a403fSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14440a403fSchristos GNU General Public License for more details.
15440a403fSchristos
16440a403fSchristos You should have received a copy of the GNU General Public License
17440a403fSchristos along with GAS; see the file COPYING. If not, write to
18440a403fSchristos the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19440a403fSchristos Boston, MA 02110-1301, USA. */
20440a403fSchristos
21440a403fSchristos /* Contributed by Steve Chamberlain of Transmeta <sac@pobox.com>. */
22440a403fSchristos
23440a403fSchristos #include "as.h"
24440a403fSchristos #include "safe-ctype.h"
25440a403fSchristos #include "opcode/pj.h"
26440a403fSchristos
27440a403fSchristos extern const pj_opc_info_t pj_opc_info[512];
28440a403fSchristos
29440a403fSchristos const char comment_chars[] = "!/";
30440a403fSchristos const char line_separator_chars[] = ";";
31440a403fSchristos const char line_comment_chars[] = "/!#";
32440a403fSchristos
33440a403fSchristos static int pending_reloc;
34440a403fSchristos static struct hash_control *opcode_hash_control;
35440a403fSchristos
36440a403fSchristos static void
little(int ignore ATTRIBUTE_UNUSED)37440a403fSchristos little (int ignore ATTRIBUTE_UNUSED)
38440a403fSchristos {
39440a403fSchristos target_big_endian = 0;
40440a403fSchristos }
41440a403fSchristos
42440a403fSchristos static void
big(int ignore ATTRIBUTE_UNUSED)43440a403fSchristos big (int ignore ATTRIBUTE_UNUSED)
44440a403fSchristos {
45440a403fSchristos target_big_endian = 1;
46440a403fSchristos }
47440a403fSchristos
48440a403fSchristos const pseudo_typeS md_pseudo_table[] =
49440a403fSchristos {
50440a403fSchristos {"ml", little, 0},
51440a403fSchristos {"mb", big, 0},
52440a403fSchristos {0, 0, 0}
53440a403fSchristos };
54440a403fSchristos
55440a403fSchristos const char FLT_CHARS[] = "rRsSfFdDxXpP";
56440a403fSchristos const char EXP_CHARS[] = "eE";
57440a403fSchristos
58440a403fSchristos void
md_operand(expressionS * op)59440a403fSchristos md_operand (expressionS *op)
60440a403fSchristos {
61440a403fSchristos if (strncmp (input_line_pointer, "%hi16", 5) == 0)
62440a403fSchristos {
63440a403fSchristos if (pending_reloc)
64440a403fSchristos as_bad (_("confusing relocation expressions"));
65440a403fSchristos pending_reloc = BFD_RELOC_PJ_CODE_HI16;
66440a403fSchristos input_line_pointer += 5;
67440a403fSchristos expression (op);
68440a403fSchristos }
69440a403fSchristos
70440a403fSchristos if (strncmp (input_line_pointer, "%lo16", 5) == 0)
71440a403fSchristos {
72440a403fSchristos if (pending_reloc)
73440a403fSchristos as_bad (_("confusing relocation expressions"));
74440a403fSchristos pending_reloc = BFD_RELOC_PJ_CODE_LO16;
75440a403fSchristos input_line_pointer += 5;
76440a403fSchristos expression (op);
77440a403fSchristos }
78440a403fSchristos }
79440a403fSchristos
80440a403fSchristos /* Parse an expression and then restore the input line pointer. */
81440a403fSchristos
82440a403fSchristos static char *
parse_exp_save_ilp(char * s,expressionS * op)83440a403fSchristos parse_exp_save_ilp (char *s, expressionS *op)
84440a403fSchristos {
85440a403fSchristos char *save = input_line_pointer;
86440a403fSchristos
87440a403fSchristos input_line_pointer = s;
88440a403fSchristos expression (op);
89440a403fSchristos s = input_line_pointer;
90440a403fSchristos input_line_pointer = save;
91440a403fSchristos return s;
92440a403fSchristos }
93440a403fSchristos
94440a403fSchristos /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
95440a403fSchristos reloc for a cons. We could use the definition there, except that
96440a403fSchristos we want to handle magic pending reloc expressions specially. */
97440a403fSchristos
98440a403fSchristos void
pj_cons_fix_new_pj(fragS * frag,int where,int nbytes,expressionS * exp,bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)99440a403fSchristos pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp,
100440a403fSchristos bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
101440a403fSchristos {
102440a403fSchristos static int rv[5][2] =
103440a403fSchristos { { 0, 0 },
104440a403fSchristos { BFD_RELOC_8, BFD_RELOC_8 },
105440a403fSchristos { BFD_RELOC_PJ_CODE_DIR16, BFD_RELOC_16 },
106440a403fSchristos { 0, 0 },
107440a403fSchristos { BFD_RELOC_PJ_CODE_DIR32, BFD_RELOC_32 }};
108440a403fSchristos
109440a403fSchristos fix_new_exp (frag, where, nbytes, exp, 0,
110440a403fSchristos pending_reloc ? pending_reloc
111440a403fSchristos : rv[nbytes][(now_seg->flags & SEC_CODE) ? 0 : 1]);
112440a403fSchristos
113440a403fSchristos pending_reloc = 0;
114440a403fSchristos }
115440a403fSchristos
116440a403fSchristos /* Turn a reloc description character from the pj-opc.h table into
117440a403fSchristos code which BFD can handle. */
118440a403fSchristos
119440a403fSchristos static int
c_to_r(int x)120440a403fSchristos c_to_r (int x)
121440a403fSchristos {
122440a403fSchristos switch (x)
123440a403fSchristos {
124440a403fSchristos case O_R8:
125440a403fSchristos return BFD_RELOC_8_PCREL;
126440a403fSchristos case O_U8:
127440a403fSchristos case O_8:
128440a403fSchristos return BFD_RELOC_8;
129440a403fSchristos case O_R16:
130440a403fSchristos return BFD_RELOC_PJ_CODE_REL16;
131440a403fSchristos case O_U16:
132440a403fSchristos case O_16:
133440a403fSchristos return BFD_RELOC_PJ_CODE_DIR16;
134440a403fSchristos case O_R32:
135440a403fSchristos return BFD_RELOC_PJ_CODE_REL32;
136440a403fSchristos case O_32:
137440a403fSchristos return BFD_RELOC_PJ_CODE_DIR32;
138440a403fSchristos }
139440a403fSchristos abort ();
140440a403fSchristos return 0;
141440a403fSchristos }
142440a403fSchristos
143440a403fSchristos /* Handler for the ipush fake opcode,
144440a403fSchristos turns ipush <foo> into sipush lo16<foo>, sethi hi16<foo>. */
145440a403fSchristos
146440a403fSchristos static void
ipush_code(pj_opc_info_t * opcode ATTRIBUTE_UNUSED,char * str)147440a403fSchristos ipush_code (pj_opc_info_t *opcode ATTRIBUTE_UNUSED, char *str)
148440a403fSchristos {
149440a403fSchristos char *b = frag_more (6);
150440a403fSchristos expressionS arg;
151440a403fSchristos
152440a403fSchristos b[0] = 0x11;
153440a403fSchristos b[3] = 0xed;
154440a403fSchristos parse_exp_save_ilp (str + 1, &arg);
155440a403fSchristos if (pending_reloc)
156440a403fSchristos {
157440a403fSchristos as_bad (_("can't have relocation for ipush"));
158440a403fSchristos pending_reloc = 0;
159440a403fSchristos }
160440a403fSchristos
161440a403fSchristos fix_new_exp (frag_now, b - frag_now->fr_literal + 1, 2,
162440a403fSchristos &arg, 0, BFD_RELOC_PJ_CODE_DIR16);
163440a403fSchristos fix_new_exp (frag_now, b - frag_now->fr_literal + 4, 2,
164440a403fSchristos &arg, 0, BFD_RELOC_PJ_CODE_HI16);
165440a403fSchristos }
166440a403fSchristos
167440a403fSchristos /* Insert names into the opcode table which are really mini macros,
168440a403fSchristos not opcodes. The fakeness is indicated with an opcode of -1. */
169440a403fSchristos
170440a403fSchristos static void
fake_opcode(const char * name,void (* func)(struct pj_opc_info_t *,char *))171440a403fSchristos fake_opcode (const char *name,
172440a403fSchristos void (*func) (struct pj_opc_info_t *, char *))
173440a403fSchristos {
174440a403fSchristos pj_opc_info_t * fake = XNEW (pj_opc_info_t);
175440a403fSchristos
176440a403fSchristos fake->opcode = -1;
177440a403fSchristos fake->opcode_next = -1;
178440a403fSchristos fake->u.func = func;
179440a403fSchristos hash_insert (opcode_hash_control, name, (char *) fake);
180440a403fSchristos }
181440a403fSchristos
182440a403fSchristos /* Enter another entry into the opcode hash table so the same opcode
183440a403fSchristos can have another name. */
184440a403fSchristos
185440a403fSchristos static void
alias(const char * new_name,const char * old)186440a403fSchristos alias (const char *new_name, const char *old)
187440a403fSchristos {
188440a403fSchristos hash_insert (opcode_hash_control, new_name,
189440a403fSchristos (char *) hash_find (opcode_hash_control, old));
190440a403fSchristos }
191440a403fSchristos
192440a403fSchristos /* This function is called once, at assembler startup time. It sets
193440a403fSchristos up the hash table with all the opcodes in it, and also initializes
194440a403fSchristos some aliases for compatibility with other assemblers. */
195440a403fSchristos
196440a403fSchristos void
md_begin(void)197440a403fSchristos md_begin (void)
198440a403fSchristos {
199440a403fSchristos const pj_opc_info_t *opcode;
200440a403fSchristos opcode_hash_control = hash_new ();
201440a403fSchristos
202440a403fSchristos /* Insert names into hash table. */
203440a403fSchristos for (opcode = pj_opc_info; opcode->u.name; opcode++)
204440a403fSchristos hash_insert (opcode_hash_control, opcode->u.name, (char *) opcode);
205440a403fSchristos
206440a403fSchristos /* Insert the only fake opcode. */
207440a403fSchristos fake_opcode ("ipush", ipush_code);
208440a403fSchristos
209440a403fSchristos /* Add some aliases for opcode names. */
210440a403fSchristos alias ("ifeq_s", "ifeq");
211440a403fSchristos alias ("ifne_s", "ifne");
212440a403fSchristos alias ("if_icmpge_s", "if_icmpge");
213440a403fSchristos alias ("if_icmpne_s", "if_icmpne");
214440a403fSchristos alias ("if_icmpeq_s", "if_icmpeq");
215440a403fSchristos alias ("if_icmpgt_s", "if_icmpgt");
216440a403fSchristos alias ("goto_s", "goto");
217440a403fSchristos
218440a403fSchristos bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
219440a403fSchristos }
220440a403fSchristos
221440a403fSchristos /* This is the guts of the machine-dependent assembler. STR points to
222440a403fSchristos a machine dependent instruction. This function is supposed to emit
223440a403fSchristos the frags/bytes it assembles to. */
224440a403fSchristos
225440a403fSchristos void
md_assemble(char * str)226440a403fSchristos md_assemble (char *str)
227440a403fSchristos {
228440a403fSchristos char *op_start;
229440a403fSchristos char *op_end;
230440a403fSchristos
231440a403fSchristos pj_opc_info_t *opcode;
232440a403fSchristos char *output;
233440a403fSchristos int idx = 0;
234440a403fSchristos char pend;
235440a403fSchristos
236440a403fSchristos int nlen = 0;
237440a403fSchristos
238440a403fSchristos /* Drop leading whitespace. */
239440a403fSchristos while (*str == ' ')
240440a403fSchristos str++;
241440a403fSchristos
242440a403fSchristos /* Find the op code end. */
243440a403fSchristos op_start = str;
244440a403fSchristos for (op_end = str;
245440a403fSchristos *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
246440a403fSchristos op_end++)
247440a403fSchristos nlen++;
248440a403fSchristos
249440a403fSchristos pend = *op_end;
250440a403fSchristos *op_end = 0;
251440a403fSchristos
252440a403fSchristos if (nlen == 0)
253440a403fSchristos as_bad (_("can't find opcode "));
254440a403fSchristos
255440a403fSchristos opcode = (pj_opc_info_t *) hash_find (opcode_hash_control, op_start);
256440a403fSchristos *op_end = pend;
257440a403fSchristos
258440a403fSchristos if (opcode == NULL)
259440a403fSchristos {
260440a403fSchristos as_bad (_("unknown opcode %s"), op_start);
261440a403fSchristos return;
262440a403fSchristos }
263440a403fSchristos
264440a403fSchristos dwarf2_emit_insn (0);
265440a403fSchristos if (opcode->opcode == -1)
266440a403fSchristos {
267440a403fSchristos /* It's a fake opcode. Dig out the args and pretend that was
268440a403fSchristos what we were passed. */
269440a403fSchristos (*opcode->u.func) (opcode, op_end);
270440a403fSchristos }
271440a403fSchristos else
272440a403fSchristos {
273440a403fSchristos int an;
274440a403fSchristos
275440a403fSchristos output = frag_more (opcode->len);
276440a403fSchristos output[idx++] = opcode->opcode;
277440a403fSchristos
278440a403fSchristos if (opcode->opcode_next != -1)
279440a403fSchristos output[idx++] = opcode->opcode_next;
280440a403fSchristos
281440a403fSchristos for (an = 0; opcode->arg[an]; an++)
282440a403fSchristos {
283440a403fSchristos expressionS arg;
284440a403fSchristos
285440a403fSchristos if (*op_end == ',' && an != 0)
286440a403fSchristos op_end++;
287440a403fSchristos
288440a403fSchristos if (*op_end == 0)
289440a403fSchristos as_bad (_("expected expression"));
290440a403fSchristos
291440a403fSchristos op_end = parse_exp_save_ilp (op_end, &arg);
292440a403fSchristos
293440a403fSchristos fix_new_exp (frag_now,
294440a403fSchristos output - frag_now->fr_literal + idx,
295440a403fSchristos ASIZE (opcode->arg[an]),
296440a403fSchristos &arg,
297440a403fSchristos PCREL (opcode->arg[an]),
298440a403fSchristos pending_reloc ? pending_reloc : c_to_r (opcode->arg[an]));
299440a403fSchristos
300440a403fSchristos idx += ASIZE (opcode->arg[an]);
301440a403fSchristos pending_reloc = 0;
302440a403fSchristos }
303440a403fSchristos
304440a403fSchristos while (ISSPACE (*op_end))
305440a403fSchristos op_end++;
306440a403fSchristos
307440a403fSchristos if (*op_end != 0)
308440a403fSchristos as_warn (_("extra stuff on line ignored"));
309440a403fSchristos
310440a403fSchristos }
311440a403fSchristos
312440a403fSchristos if (pending_reloc)
313440a403fSchristos as_bad (_("Something forgot to clean up\n"));
314440a403fSchristos }
315440a403fSchristos
316440a403fSchristos const char *
md_atof(int type,char * litP,int * sizeP)317440a403fSchristos md_atof (int type, char *litP, int *sizeP)
318440a403fSchristos {
319440a403fSchristos return ieee_md_atof (type, litP, sizeP, target_big_endian);
320440a403fSchristos }
321440a403fSchristos
322440a403fSchristos const char *md_shortopts = "";
323440a403fSchristos
324440a403fSchristos struct option md_longopts[] =
325440a403fSchristos {
326440a403fSchristos #define OPTION_LITTLE (OPTION_MD_BASE)
327440a403fSchristos #define OPTION_BIG (OPTION_LITTLE + 1)
328440a403fSchristos
329440a403fSchristos {"little", no_argument, NULL, OPTION_LITTLE},
330440a403fSchristos {"big", no_argument, NULL, OPTION_BIG},
331440a403fSchristos {NULL, no_argument, NULL, 0}
332440a403fSchristos };
333440a403fSchristos size_t md_longopts_size = sizeof (md_longopts);
334440a403fSchristos
335440a403fSchristos int
md_parse_option(int c,const char * arg ATTRIBUTE_UNUSED)336440a403fSchristos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
337440a403fSchristos {
338440a403fSchristos switch (c)
339440a403fSchristos {
340440a403fSchristos case OPTION_LITTLE:
341440a403fSchristos little (0);
342440a403fSchristos break;
343440a403fSchristos case OPTION_BIG:
344440a403fSchristos big (0);
345440a403fSchristos break;
346440a403fSchristos default:
347440a403fSchristos return 0;
348440a403fSchristos }
349440a403fSchristos return 1;
350440a403fSchristos }
351440a403fSchristos
352440a403fSchristos void
md_show_usage(FILE * stream)353440a403fSchristos md_show_usage (FILE *stream)
354440a403fSchristos {
355440a403fSchristos fprintf (stream, _("\
356440a403fSchristos PJ options:\n\
357440a403fSchristos -little generate little endian code\n\
358440a403fSchristos -big generate big endian code\n"));
359440a403fSchristos }
360440a403fSchristos
361440a403fSchristos /* Apply a fixup to the object file. */
362440a403fSchristos
363440a403fSchristos void
md_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)364440a403fSchristos md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
365440a403fSchristos {
366440a403fSchristos char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
367440a403fSchristos long val = *valP;
368440a403fSchristos long max, min;
369440a403fSchristos
370440a403fSchristos max = min = 0;
371440a403fSchristos switch (fixP->fx_r_type)
372440a403fSchristos {
373440a403fSchristos case BFD_RELOC_VTABLE_INHERIT:
374440a403fSchristos case BFD_RELOC_VTABLE_ENTRY:
375440a403fSchristos fixP->fx_done = 0;
376440a403fSchristos return;
377440a403fSchristos
378440a403fSchristos case BFD_RELOC_PJ_CODE_REL16:
379440a403fSchristos if (val < -0x8000 || val >= 0x7fff)
380440a403fSchristos as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
381440a403fSchristos buf[0] |= (val >> 8) & 0xff;
382440a403fSchristos buf[1] = val & 0xff;
383440a403fSchristos break;
384440a403fSchristos
385440a403fSchristos case BFD_RELOC_PJ_CODE_HI16:
386440a403fSchristos *buf++ = val >> 24;
387440a403fSchristos *buf++ = val >> 16;
388440a403fSchristos fixP->fx_addnumber = val & 0xffff;
389440a403fSchristos break;
390440a403fSchristos
391440a403fSchristos case BFD_RELOC_PJ_CODE_DIR16:
392440a403fSchristos case BFD_RELOC_PJ_CODE_LO16:
393440a403fSchristos *buf++ = val >> 8;
394440a403fSchristos *buf++ = val >> 0;
395440a403fSchristos
396440a403fSchristos max = 0xffff;
397440a403fSchristos min = -0xffff;
398440a403fSchristos break;
399440a403fSchristos
400440a403fSchristos case BFD_RELOC_8:
401440a403fSchristos max = 0xff;
402440a403fSchristos min = -0xff;
403440a403fSchristos *buf++ = val;
404440a403fSchristos break;
405440a403fSchristos
406440a403fSchristos case BFD_RELOC_PJ_CODE_DIR32:
407440a403fSchristos *buf++ = val >> 24;
408440a403fSchristos *buf++ = val >> 16;
409440a403fSchristos *buf++ = val >> 8;
410440a403fSchristos *buf++ = val >> 0;
411440a403fSchristos break;
412440a403fSchristos
413440a403fSchristos case BFD_RELOC_32:
414440a403fSchristos if (target_big_endian)
415440a403fSchristos {
416440a403fSchristos *buf++ = val >> 24;
417440a403fSchristos *buf++ = val >> 16;
418440a403fSchristos *buf++ = val >> 8;
419440a403fSchristos *buf++ = val >> 0;
420440a403fSchristos }
421440a403fSchristos else
422440a403fSchristos {
423440a403fSchristos *buf++ = val >> 0;
424440a403fSchristos *buf++ = val >> 8;
425440a403fSchristos *buf++ = val >> 16;
426440a403fSchristos *buf++ = val >> 24;
427440a403fSchristos }
428440a403fSchristos break;
429440a403fSchristos
430440a403fSchristos case BFD_RELOC_16:
431440a403fSchristos if (target_big_endian)
432440a403fSchristos {
433440a403fSchristos *buf++ = val >> 8;
434440a403fSchristos *buf++ = val >> 0;
435440a403fSchristos }
436440a403fSchristos else
437440a403fSchristos {
438440a403fSchristos *buf++ = val >> 0;
439440a403fSchristos *buf++ = val >> 8;
440440a403fSchristos }
441440a403fSchristos break;
442440a403fSchristos
443440a403fSchristos case BFD_RELOC_PJ_CODE_REL32:
444440a403fSchristos fixP->fx_done = 0;
445440a403fSchristos return;
446440a403fSchristos
447440a403fSchristos default:
448440a403fSchristos abort ();
449440a403fSchristos }
450440a403fSchristos
451440a403fSchristos if (max != 0 && (val < min || val > max))
452440a403fSchristos as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
453440a403fSchristos
454440a403fSchristos if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
455440a403fSchristos fixP->fx_done = 1;
456440a403fSchristos }
457440a403fSchristos
458440a403fSchristos /* Put number into target byte order. Always put values in an
459440a403fSchristos executable section into big endian order. */
460440a403fSchristos
461440a403fSchristos void
md_number_to_chars(char * ptr,valueT use,int nbytes)462440a403fSchristos md_number_to_chars (char *ptr, valueT use, int nbytes)
463440a403fSchristos {
464440a403fSchristos if (target_big_endian || now_seg->flags & SEC_CODE)
465440a403fSchristos number_to_chars_bigendian (ptr, use, nbytes);
466440a403fSchristos else
467440a403fSchristos number_to_chars_littleendian (ptr, use, nbytes);
468440a403fSchristos }
469440a403fSchristos
470440a403fSchristos /* Translate internal representation of relocation info to BFD target
471440a403fSchristos format. */
472440a403fSchristos
473440a403fSchristos arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixp)474440a403fSchristos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
475440a403fSchristos {
476440a403fSchristos arelent *rel;
477440a403fSchristos bfd_reloc_code_real_type r_type;
478440a403fSchristos
479440a403fSchristos rel = XNEW (arelent);
480440a403fSchristos rel->sym_ptr_ptr = XNEW (asymbol *);
481440a403fSchristos *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
482440a403fSchristos rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
483440a403fSchristos
484440a403fSchristos r_type = fixp->fx_r_type;
485440a403fSchristos rel->addend = fixp->fx_addnumber;
486440a403fSchristos rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
487440a403fSchristos
488440a403fSchristos if (rel->howto == NULL)
489440a403fSchristos {
490440a403fSchristos as_bad_where (fixp->fx_file, fixp->fx_line,
491440a403fSchristos _("Cannot represent relocation type %s"),
492440a403fSchristos bfd_get_reloc_code_name (r_type));
493440a403fSchristos /* Set howto to a garbage value so that we can keep going. */
494440a403fSchristos rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
495440a403fSchristos gas_assert (rel->howto != NULL);
496440a403fSchristos }
497440a403fSchristos
498440a403fSchristos return rel;
499440a403fSchristos }
500