From ad660eb1642d6dd7e9105e3c6125eadddc9d9a19 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 14 Oct 1993 15:41:52 +0000 Subject: [PATCH] Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org) * config/tc-i386.c: (md_begin): Do not zero static arrays. Don't call strchr for each character to see if it is a special char, instead add a second loop over special_chars. Set alignment of text, data and bss sections to 4. (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be used again. (reloc): Don't return 8 and 16 bit non-PC relative relocations on ELF, since the ELF object format does not have these type of relocations. Change the abort into as as_bad and return BFD_RELOC_NONE to silence compiler warnings. (md_assemble): Keep track of the instruction size. Allow white space between the $ and the constant for compatibility with older gases and other assemblers. (i386_operand): Skip spaces between $ and expression. (tc_gen_reloc): Don't allow anything but 32 bit relocations on ELF. Convert abort into an as_bad and assert into as_fatal. --- gas/ChangeLog | 19 +++ gas/config/tc-i386.c | 281 +++++++++++++++++++++++++++---------------- 2 files changed, 196 insertions(+), 104 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index c25c2bd80be..18aefddc149 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org) + + * config/tc-i386.c: (md_begin): Do not zero static arrays. Don't + call strchr for each character to see if it is a special char, + instead add a second loop over special_chars. Set alignment + of text, data and bss sections to 4. + (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be + used again. + (reloc): Don't return 8 and 16 bit non-PC relative relocations on + ELF, since the ELF object format does not have these type of + relocations. Change the abort into as as_bad and return + BFD_RELOC_NONE to silence compiler warnings. + (md_assemble): Keep track of the instruction size. Allow white + space between the $ and the constant for compatibility with older + gases and other assemblers. + (i386_operand): Skip spaces between $ and expression. + (tc_gen_reloc): Don't allow anything but 32 bit relocations on + ELF. Convert abort into an as_bad and assert into as_fatal. + Wed Oct 13 16:50:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) * config/obj-coffbfd.c (fixup_segment) [DIFF_EXPR_OK]: If diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index f1d92ef6957..415e955f2d8 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -106,7 +106,7 @@ const char comment_chars[] = "#"; /* Also note that comments started like this one will always work if '/' isn't otherwise defined. */ #if defined (TE_I386AIX) || defined (OBJ_ELF) -const char line_comment_chars[]; +const char line_comment_chars[] = ""; #else const char line_comment_chars[] = "/"; #endif @@ -184,7 +184,8 @@ static int this_operand; /* current operand we are working on */ #endif #endif -#define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size)) +#define ENCODE_RELAX_STATE(type,size) \ + ((relax_substateT)((type<<2) | (size))) #define SIZE_FROM_RELAX_STATE(s) \ ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) ) @@ -227,7 +228,7 @@ static char *output_invalid PARAMS ((int c)); static int i386_operand PARAMS ((char *operand_string)); static reg_entry *parse_register PARAMS ((char *reg_string)); #ifndef I386COFF -static void s_bss PARAMS ((void)); +static void s_bss PARAMS ((int)); #endif static INLINE unsigned long @@ -237,6 +238,8 @@ mode_from_disp_size (t) return (t & Disp8) ? 1 : (t & Disp32) ? 2 : 0; } +#if 0 +/* Not used. */ /* convert opcode suffix ('b' 'w' 'l' typically) into type specifier */ static INLINE unsigned long @@ -247,6 +250,7 @@ opcode_suffix_to_type (s) ? Byte : (s == WORD_OPCODE_SUFFIX ? Word : DWord)); } /* opcode_suffix_to_type() */ +#endif static INLINE int fits_in_signed_byte (num) @@ -291,15 +295,6 @@ smallest_imm_type (num) : (Imm32)); } /* smallest_imm_type() */ -/* Ignore certain directives generated by gcc. This probably should - not be here. */ -void -dummy () -{ - while (*input_line_pointer && *input_line_pointer != '\n') - input_line_pointer++; -} - const pseudo_typeS md_pseudo_table[] = { #ifndef I386COFF @@ -339,7 +334,7 @@ static struct hash_control *prefix_hash = (struct hash_control *) 0; void md_begin () { - char *hash_err; + const char *hash_err; obstack_begin (&o, 4096); @@ -372,7 +367,7 @@ md_begin () core_optab->end = (template *) obstack_next_free (&o); core_optab->start = (template *) obstack_finish (&o); hash_err = hash_insert (op_hash, prev_name, (char *) core_optab); - if (hash_err && *hash_err) + if (hash_err) { hash_error: as_fatal ("Internal Error: Can't hash %s: %s", prev_name, @@ -392,8 +387,8 @@ md_begin () for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++) { - hash_err = hash_insert (reg_hash, regtab->reg_name, regtab); - if (hash_err && *hash_err) + hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab); + if (hash_err) goto hash_error; } } @@ -409,21 +404,17 @@ md_begin () for (prefixtab = i386_prefixtab; prefixtab < i386_prefixtab_end; prefixtab++) { - hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab); - if (hash_err && *hash_err) + hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, + (PTR) prefixtab); + if (hash_err) goto hash_error; } } /* fill in lexical tables: opcode_chars, operand_chars, space_chars */ { - register unsigned int c; - - memset (opcode_chars, '\0', sizeof (opcode_chars)); - memset (operand_chars, '\0', sizeof (operand_chars)); - memset (space_chars, '\0', sizeof (space_chars)); - memset (identifier_chars, '\0', sizeof (identifier_chars)); - memset (digit_chars, '\0', sizeof (digit_chars)); + register int c; + register char *p; for (c = 0; c < 256; c++) { @@ -448,8 +439,6 @@ md_begin () if (isupper (c) || islower (c) || isdigit (c)) operand_chars[c] = c; - else if (c && strchr (operand_special_chars, c)) - operand_chars[c] = c; if (isdigit (c) || c == '-') digit_chars[c] = c; @@ -460,7 +449,16 @@ md_begin () if (c == ' ' || c == '\t') space_chars[c] = c; } + + for (p = operand_special_chars; *p != '\0'; p++) + operand_chars[(unsigned char) *p] = *p; } + +#ifdef OBJ_ELF + record_alignment (text_section, 2); + record_alignment (data_section, 2); + record_alignment (bss_section, 2); +#endif } void @@ -472,7 +470,11 @@ md_end () #ifdef DEBUG386 /* debugging routines for md_assemble */ -/* static void pi (), pte (), pt (), pe (), ps (); */ +static void pi PARAMS ((char *, i386_insn *)); +static void pte PARAMS ((template *)); +static void pt PARAMS ((unsigned int)); +static void pe PARAMS ((expressionS *)); +static void ps PARAMS ((symbolS *)); static void pi (line, x) @@ -625,18 +627,25 @@ reloc (size, pcrel) if (pcrel) switch (size) { +#ifndef OBJ_ELF case 1: return BFD_RELOC_8_PCREL; case 2: return BFD_RELOC_16_PCREL; +#endif case 4: return BFD_RELOC_32_PCREL; } else switch (size) { +#ifndef OBJ_ELF case 1: return BFD_RELOC_8; case 2: return BFD_RELOC_16; +#endif case 4: return BFD_RELOC_32; } - abort (); + + as_bad ("Can not do %d byte %srelocation", size, + pcrel ? "pc-relative" : ""); + return BFD_RELOC_NONE; } #else #define reloc(SIZE,PCREL) 0 @@ -651,9 +660,12 @@ void md_assemble (line) char *line; { - /* Holds temlate once we've found it. */ + /* Holds template once we've found it. */ register template *t; + /* Count the size of the instruction generated. */ + int insn_size = 0; + /* Possible templates for current insn */ templates *current_templates = (templates *) 0; @@ -806,7 +818,7 @@ md_assemble (line) else break; /* we are done */ } - else if (!is_operand_char (*l)) + else if (!is_operand_char (*l) && !is_space_char (*l)) { as_bad ("invalid character %s in %s operand", output_invalid (*l), @@ -987,13 +999,13 @@ md_assemble (line) /* We take i.suffix from the LAST register operand specified. This assumes that the last register operands is the destination register operand. */ - int o; - for (o = 0; o < MAX_OPERANDS; o++) - if (i.types[o] & Reg) + int op; + for (op = 0; op < MAX_OPERANDS; op++) + if (i.types[op] & Reg) { - i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX : - (i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX : - DWORD_OPCODE_SUFFIX; + i.suffix = ((i.types[op] == Reg8) ? BYTE_OPCODE_SUFFIX : + (i.types[op] == Reg16) ? WORD_OPCODE_SUFFIX : + DWORD_OPCODE_SUFFIX); } } @@ -1113,9 +1125,9 @@ md_assemble (line) if (t->opcode_modifier & ShortForm) { /* The register or float register operand is in operand 0 or 1. */ - unsigned int o = (i.types[0] & (Reg | FloatReg)) ? 0 : 1; + unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1; /* Register goes in low 3 bits of opcode. */ - t->base_opcode |= i.regs[o]->reg_num; + t->base_opcode |= i.regs[op]->reg_num; } else if (t->opcode_modifier & ShortFormW) { @@ -1178,7 +1190,7 @@ md_assemble (line) if (i.mem_operands) { unsigned int fake_zero_displacement = 0; - unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2); + unsigned int op = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2); /* Encode memory operand into modrm byte and base index byte. */ @@ -1188,25 +1200,25 @@ md_assemble (line) /* (%esp) becomes two byte modrm with no index register. */ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.rm.mode = mode_from_disp_size (i.types[o]); + i.rm.mode = mode_from_disp_size (i.types[op]); i.bi.base = ESP_REG_NUM; i.bi.index = NO_INDEX_REGISTER; i.bi.scale = 0; /* Must be zero! */ } else if (i.base_reg == ebp && !i.index_reg) { - if (!(i.types[o] & Disp)) + if (!(i.types[op] & Disp)) { /* Must fake a zero byte displacement. There is no direct way to code '(%ebp)' directly. */ fake_zero_displacement = 1; /* fake_zero_displacement code does not set this. */ - i.types[o] |= Disp8; + i.types[op] |= Disp8; } - i.rm.mode = mode_from_disp_size (i.types[o]); + i.rm.mode = mode_from_disp_size (i.types[op]); i.rm.regmem = EBP_REG_NUM; } - else if (!i.base_reg && (i.types[o] & BaseIndex)) + else if (!i.base_reg && (i.types[op] & BaseIndex)) { /* There are three cases here. Case 1: '<32bit disp>(,1)' -- indirect absolute. @@ -1217,8 +1229,8 @@ md_assemble (line) i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; i.rm.mode = 0; /* 32bit mode */ i.bi.base = NO_BASE_REGISTER; - i.types[o] &= ~Disp; - i.types[o] |= Disp32; /* Must be 32bit! */ + i.types[op] &= ~Disp; + i.types[op] |= Disp32; /* Must be 32bit! */ if (i.index_reg) { /* case 2 or case 3 */ i.bi.index = i.index_reg->reg_num; @@ -1237,14 +1249,14 @@ md_assemble (line) /* Operand is just <32bit disp> */ i.rm.regmem = EBP_REG_NUM; i.rm.mode = 0; - i.types[o] &= ~Disp; - i.types[o] |= Disp32; + i.types[op] &= ~Disp; + i.types[op] |= Disp32; } else { /* It's not a special case; rev'em up. */ i.rm.regmem = i.base_reg->reg_num; - i.rm.mode = mode_from_disp_size (i.types[o]); + i.rm.mode = mode_from_disp_size (i.types[op]); if (i.index_reg) { i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; @@ -1254,17 +1266,17 @@ md_assemble (line) if (i.base_reg == ebp && i.disp_operands == 0) { /* pace */ fake_zero_displacement = 1; - i.types[o] |= Disp8; - i.rm.mode = mode_from_disp_size (i.types[o]); + i.types[op] |= Disp8; + i.rm.mode = mode_from_disp_size (i.types[op]); } } } if (fake_zero_displacement) { - /* Fakes a zero displacement assuming that i.types[o] + /* Fakes a zero displacement assuming that i.types[op] holds the correct displacement size. */ exp = &disp_expressions[i.disp_operands++]; - i.disps[o] = exp; + i.disps[op] = exp; exp->X_op = O_constant; exp->X_add_number = 0; exp->X_add_symbol = (symbolS *) 0; @@ -1308,15 +1320,15 @@ md_assemble (line) registers are coded into the i.rm.reg field. */ if (i.reg_operands) { - unsigned int o = + unsigned int op = (i.types[0] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 0 : (i.types[1] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 1 : 2; /* If there is an extension opcode to put here, the register number must be put into the regmem field. */ if (t->extension_opcode != None) - i.rm.regmem = i.regs[o]->reg_num; + i.rm.regmem = i.regs[op]->reg_num; else - i.rm.reg = i.regs[o]->reg_num; + i.rm.reg = i.regs[op]->reg_num; /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we must set it to 3 to indicate this is a register @@ -1347,13 +1359,14 @@ md_assemble (line) /* Output jumps. */ if (t->opcode_modifier & Jump) { - int n = i.disps[0]->X_add_number; + unsigned long n = i.disps[0]->X_add_number; if (i.disps[0]->X_op == O_constant) { if (fits_in_signed_byte (n)) { p = frag_more (2); + insn_size += 2; p[0] = t->base_opcode; p[1] = n; } @@ -1361,9 +1374,10 @@ md_assemble (line) else if (fits_in_signed_word (n)) { p = frag_more (4); + insn_size += 4; p[0] = WORD_PREFIX_OPCODE; p[1] = t->base_opcode; - md_number_to_chars (&p[2], n, 2); + md_number_to_chars (&p[2], (valueT) n, 2); } #endif else @@ -1372,16 +1386,18 @@ md_assemble (line) { /* pace */ /* unconditional jump */ p = frag_more (5); + insn_size += 5; p[0] = (char) 0xe9; - md_number_to_chars (&p[1], n, 4); + md_number_to_chars (&p[1], (valueT) n, 4); } else { /* conditional jump */ p = frag_more (6); + insn_size += 6; p[0] = TWO_BYTE_OPCODE_ESCAPE; p[1] = t->base_opcode + 0x10; - md_number_to_chars (&p[2], n, 4); + md_number_to_chars (&p[2], (valueT) n, 4); } } } @@ -1396,6 +1412,7 @@ md_assemble (line) frag_new (0); } p = frag_more (1); + insn_size += 1; p[0] = t->base_opcode; frag_var (rs_machine_dependent, 6, /* 2 opcode/prefix + 4 displacement */ @@ -1404,33 +1421,36 @@ md_assemble (line) ? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE) : ENCODE_RELAX_STATE (COND_JUMP, BYTE)), i.disps[0]->X_add_symbol, - n, p); + (long) n, p); } } else if (t->opcode_modifier & (JumpByte | JumpDword)) { int size = (t->opcode_modifier & JumpByte) ? 1 : 4; - int n = i.disps[0]->X_add_number; + unsigned long n = i.disps[0]->X_add_number; if (fits_in_unsigned_byte (t->base_opcode)) { FRAG_APPEND_1_CHAR (t->base_opcode); + insn_size += 1; } else { p = frag_more (2); /* opcode can be at most two bytes */ + insn_size += 2; /* put out high byte first: can't use md_number_to_chars! */ *p++ = (t->base_opcode >> 8) & 0xff; *p = t->base_opcode & 0xff; } p = frag_more (size); + insn_size += size; if (i.disps[0]->X_op == O_constant) { - md_number_to_chars (p, n, size); + md_number_to_chars (p, (valueT) n, size); if (size == 1 && !fits_in_signed_byte (n)) { - as_bad ("loop/jecx only takes byte displacement; %d shortened to %d", + as_bad ("loop/jecx only takes byte displacement; %lu shortened to %d", n, *p); } } @@ -1443,15 +1463,16 @@ md_assemble (line) else if (t->opcode_modifier & JumpInterSegment) { p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */ + insn_size += 1 + 2 + 4; p[0] = t->base_opcode; if (i.imms[1]->X_op == O_constant) - md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4); + md_number_to_chars (p + 1, (valueT) i.imms[1]->X_add_number, 4); else fix_new_exp (frag_now, p + 1 - frag_now->fr_literal, 4, i.imms[1], 0, BFD_RELOC_32); if (i.imms[0]->X_op != O_constant) as_bad ("can't handle non absolute segment in long call/jmp"); - md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2); + md_number_to_chars (p + 5, (valueT) i.imms[0]->X_add_number, 2); } else { @@ -1462,17 +1483,20 @@ md_assemble (line) for (q = i.prefix; q < i.prefix + i.prefixes; q++) { p = frag_more (1); - md_number_to_chars (p, (unsigned int) *q, 1); + insn_size += 1; + md_number_to_chars (p, (valueT) *q, 1); } /* Now the opcode; be careful about word order here! */ if (fits_in_unsigned_byte (t->base_opcode)) { FRAG_APPEND_1_CHAR (t->base_opcode); + insn_size += 1; } else if (fits_in_unsigned_word (t->base_opcode)) { p = frag_more (2); + insn_size += 2; /* put out high byte first: can't use md_number_to_chars! */ *p++ = (t->base_opcode >> 8) & 0xff; *p = t->base_opcode & 0xff; @@ -1482,10 +1506,14 @@ md_assemble (line) if (t->base_opcode & 0xff000000) { p = frag_more (4); + insn_size += 4; *p++ = (t->base_opcode >> 24) & 0xff; } else - p = frag_more (3); + { + p = frag_more (3); + insn_size += 3; + } *p++ = (t->base_opcode >> 16) & 0xff; *p++ = (t->base_opcode >> 8) & 0xff; *p = (t->base_opcode) & 0xff; @@ -1495,15 +1523,24 @@ md_assemble (line) if (t->opcode_modifier & Modrm) { p = frag_more (1); + insn_size += 1; /* md_number_to_chars (p, i.rm, 1); */ - md_number_to_chars (p, (i.rm.regmem << 0 | i.rm.reg << 3 | i.rm.mode << 6), 1); + md_number_to_chars (p, + (valueT) (i.rm.regmem << 0 + | i.rm.reg << 3 + | i.rm.mode << 6), + 1); /* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode) ==> need second modrm byte. */ if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3) { p = frag_more (1); + insn_size += 1; /* md_number_to_chars (p, i.bi, 1); */ - md_number_to_chars (p, (i.bi.base << 0 | i.bi.index << 3 | i.bi.scale << 6), 1); + md_number_to_chars (p, (valueT) (i.bi.base << 0 + | i.bi.index << 3 + | i.bi.scale << 6), + 1); } } @@ -1520,23 +1557,33 @@ md_assemble (line) if (i.types[n] & (Disp8 | Abs8)) { p = frag_more (1); - md_number_to_chars (p, i.disps[n]->X_add_number, 1); + insn_size += 1; + md_number_to_chars (p, + (valueT) i.disps[n]->X_add_number, + 1); } else if (i.types[n] & (Disp16 | Abs16)) { p = frag_more (2); - md_number_to_chars (p, i.disps[n]->X_add_number, 2); + insn_size += 2; + md_number_to_chars (p, + (valueT) i.disps[n]->X_add_number, + 2); } else { /* Disp32|Abs32 */ p = frag_more (4); - md_number_to_chars (p, i.disps[n]->X_add_number, 4); + insn_size += 4; + md_number_to_chars (p, + (valueT) i.disps[n]->X_add_number, + 4); } } else { /* not absolute_section */ /* need a 32-bit fixup (don't support 8bit non-absolute disps) */ p = frag_more (4); + insn_size += 4; fix_new_exp (frag_now, p - frag_now->fr_literal, 4, i.disps[n], 0, BFD_RELOC_32); } @@ -1558,17 +1605,26 @@ md_assemble (line) if (i.types[n] & (Imm8 | Imm8S)) { p = frag_more (1); - md_number_to_chars (p, i.imms[n]->X_add_number, 1); + insn_size += 1; + md_number_to_chars (p, + (valueT) i.imms[n]->X_add_number, + 1); } else if (i.types[n] & Imm16) { p = frag_more (2); - md_number_to_chars (p, i.imms[n]->X_add_number, 2); + insn_size += 2; + md_number_to_chars (p, + (valueT) i.imms[n]->X_add_number, + 2); } else { p = frag_more (4); - md_number_to_chars (p, i.imms[n]->X_add_number, 4); + insn_size += 4; + md_number_to_chars (p, + (valueT) i.imms[n]->X_add_number, + 4); } } else @@ -1583,6 +1639,7 @@ md_assemble (line) else size = 4; p = frag_more (size); + insn_size += size; fix_new_exp (frag_now, p - frag_now->fr_literal, size, i.imms[n], 0, reloc (size, 0)); } @@ -1696,6 +1753,7 @@ i386_operand (operand_string) i.imms[this_operand] = exp; save_input_line_pointer = input_line_pointer; input_line_pointer = ++op_string; /* must advance op_string! */ + SKIP_WHITESPACE (); exp_seg = expression (exp); input_line_pointer = save_input_line_pointer; @@ -1712,7 +1770,8 @@ i386_operand (operand_string) } else if (exp->X_op == O_constant) { - i.types[this_operand] |= smallest_imm_type (exp->X_add_number); + i.types[this_operand] |= + smallest_imm_type ((unsigned long) exp->X_add_number); } #ifdef OBJ_AOUT else if (exp_seg != text_section @@ -2152,7 +2211,7 @@ md_convert_frag (abfd, sec, fragP) } /* now put displacement after opcode */ md_number_to_chars ((char *) where_to_put_displacement, - displacement_from_opcode_start - extension, + (valueT) (displacement_from_opcode_start - extension), SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); fragP->fr_fix += extension; } @@ -2172,8 +2231,8 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) long offset; offset = to_addr - (from_addr + 2); - md_number_to_chars (ptr, (long) 0xeb, 1); /* opcode for byte-disp jump */ - md_number_to_chars (ptr + 1, offset, 1); + md_number_to_chars (ptr, (valueT) 0xeb, 1); /* opcode for byte-disp jump */ + md_number_to_chars (ptr + 1, (valueT) offset, 1); } void @@ -2188,16 +2247,16 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) if (flagseen['m']) { offset = to_addr - S_GET_VALUE (to_symbol); - md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ - md_number_to_chars (ptr + 1, offset, 4); + md_number_to_chars (ptr, (valueT) 0xe9, 1);/* opcode for long jmp */ + md_number_to_chars (ptr + 1, (valueT) offset, 4); fix_new (frag, (ptr + 1) - frag->fr_literal, 4, to_symbol, (offsetT) 0, 0, BFD_RELOC_32); } else { offset = to_addr - (from_addr + 5); - md_number_to_chars (ptr, (long) 0xe9, 1); - md_number_to_chars (ptr + 1, offset, 4); + md_number_to_chars (ptr, (valueT) 0xe9, 1); + md_number_to_chars (ptr + 1, (valueT) offset, 4); } } @@ -2294,6 +2353,8 @@ md_apply_fix (fixP, val) } #endif +#if 0 +/* This is never used. */ long /* Knows about the byte order in a word. */ md_chars_to_number (con, nbytes) unsigned char con[]; /* Low order byte 1st. */ @@ -2307,7 +2368,7 @@ md_chars_to_number (con, nbytes) } return retval; } - +#endif /* 0 */ #define MAX_LITTLENUMS 6 @@ -2356,7 +2417,7 @@ md_atof (type, litP, sizeP) the bigendian 386. */ for (wordP = words + prec - 1; prec--;) { - md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE)); + md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0; @@ -2439,16 +2500,13 @@ md_pcrel_from (fixP) #ifndef I386COFF static void -s_bss () +s_bss (ignore) + int ignore; { register int temp; temp = get_absolute_expression (); -#ifdef BFD_ASSEMBLER subseg_set (bss_section, (subsegT) temp); -#else - subseg_new (bss_section, (subsegT) temp); -#endif demand_empty_rest_of_line (); } @@ -2462,38 +2520,52 @@ tc_gen_reloc (section, fixp) asection *section; fixS *fixp; { - arelent *reloc; + arelent *rel; bfd_reloc_code_real_type code; #define F(SZ,PCREL) (((SZ) << 1) + (PCREL)) switch (F (fixp->fx_size, fixp->fx_pcrel)) { #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break +#ifndef OBJ_ELF MAP (1, 0, BFD_RELOC_8); MAP (2, 0, BFD_RELOC_16); +#endif MAP (4, 0, BFD_RELOC_32); +#ifndef OBJ_ELF MAP (1, 1, BFD_RELOC_8_PCREL); MAP (2, 1, BFD_RELOC_16_PCREL); +#endif MAP (4, 1, BFD_RELOC_32_PCREL); default: - abort (); + as_bad ("Can not do %d byte %srelocation", fixp->fx_size, + fixp->fx_pcrel ? "pc-relative" : ""); } #undef MAP #undef F - reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent)); - assert (reloc != 0); - reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym; - reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent)); + assert (rel != 0); + rel->sym_ptr_ptr = &fixp->fx_addsy->bsym; + rel->address = fixp->fx_frag->fr_address + fixp->fx_where; if (fixp->fx_pcrel) - reloc->addend = fixp->fx_addnumber; + rel->addend = fixp->fx_addnumber; else - reloc->addend = 0; + rel->addend = 0; - reloc->howto = bfd_reloc_type_lookup (stdoutput, code); - assert (reloc->howto != 0); + rel->howto = bfd_reloc_type_lookup (stdoutput, code); + if (!rel->howto) + { + const char *name; + + name = S_GET_NAME (fixp->fx_addsy); + if (name == NULL) + name = ""; + as_fatal ("Cannot find relocation type for symbol %s, code %d", + name, (int) code); + } - return reloc; + return rel; } #else /* ! BFD_ASSEMBLER */ @@ -2516,7 +2588,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) know (fixP->fx_addsy != NULL); md_number_to_chars (where, - fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, + (valueT) (fixP->fx_frag->fr_address + + fixP->fx_where - segment_address_in_file), 4); r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) -- 2.30.2