diff options
author | Jason Thorpe <thorpej@netbsd.org> | 2002-06-09 00:45:42 +0000 |
---|---|---|
committer | Jason Thorpe <thorpej@netbsd.org> | 2002-06-09 00:45:42 +0000 |
commit | 7542c0f275dbb7217ddec0beea4985ba4a2f24b3 (patch) | |
tree | ff11d446c10f0144d8ff1c78ab38a251a48f11a1 /gas/config/tc-vax.c | |
parent | 05b65acb41e3fe35b45387e64a8f2f50b94935b6 (diff) | |
download | gdb-7542c0f275dbb7217ddec0beea4985ba4a2f24b3.zip gdb-7542c0f275dbb7217ddec0beea4985ba4a2f24b3.tar.gz gdb-7542c0f275dbb7217ddec0beea4985ba4a2f24b3.tar.bz2 |
2002-06-08 Matt Thomas <matt@3am-software.com>
* configure.in (vax-*-netbsdelf*, vax-*-netbsdaout*)
(vax-*-netbsd*): New targets.
* configure: Regenerate.
* config/aout_gnu.h (enum machine_type): Add M_VAX4K_NETBSD.
* config/tc-vax.c: Add support for ELF and PIC.
(flag_want_pic): New flag.
(float_cons): Fix prototype.
(md_apply_fix3): Adjust for BFD_ASSEMBLER.
(md_assemble): Introduce a new is_absolute local, and use it
rather than repeating the test. Make fatal errors actually
fatal by using as_fatal as appropriate. Adjust for BFD_ASSEMBLER.
Add support for ELF. Add support for PIC.
(md_convert_frag): Adjust for BFD_ASSEMBLER.
(tc_aout_fix_to_chars): Only include if OBJ_AOUT and not
BFD_ASSEMBLER.
(vax_reg_parse): Make the % register prefix mandatory for ELF,
optional for a.out, and not allowed for VMS. Adjust all callers.
(md_create_short_jump): Add ATTRIBUTE_UNUSED to unused arguments.
(md_create_long_jump): Likewise.
(md_undefined_symbol): Likewise.
(md_section_align): Likewise.
(md_shortopts): Allow -k and -K for ELF.
(md_parse_option): Set flag_want_pic if -k or -K.
(tc_headers_hook): New function if OBJ_AOUT and not BFD_ASSEMBLER.
(tc_gen_reloc): New function if BFD_ASSEMBLER.
* config/tc-vax.h (tc_headers_hook): Remove.
(TARGET_FORMAT): Set according to object format and target
environment.
(BFD_ARCH, TARGET_ARCH): Define.
(NO_RELOC): Adjust for BFD_ASSEMBLER.
(TC_RELOC_RTSYM_LOC_FIXUP, TC_FIX_ADJUSTABLE)
(tc_fix_adjustable): Define if BFD_ASSEMBLER.
* config/vax-inst.h (VAX_JSB, VAX_CALLS, VAX_CALLG): Define.
Diffstat (limited to 'gas/config/tc-vax.c')
-rw-r--r-- | gas/config/tc-vax.c | 404 |
1 files changed, 332 insertions, 72 deletions
diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 7c64723..a2bae67 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -23,6 +23,11 @@ #include "vax-inst.h" #include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */ +#include "subsegs.h" + +#ifdef OBJ_ELF +#include "elf/vax.h" +#endif /* These chars start a comment anywhere in a source file (except inside another comment */ @@ -58,10 +63,20 @@ LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER]; FLONUM_TYPE float_operand[VIT_MAX_OPERANDS]; /* Above is made to point into big_operand_bits by md_begin(). */ +#ifdef OBJ_ELF +#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" +#define PROCEDURE_LINKAGE_TABLE_NAME "_PROCEDURE_LINKAGE_TABLE_" +symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ +symbolS *PLT_symbol; /* Pre-defined "_PROCEDURE_LINKAGE_TABLE_" */ +#endif + int flag_hash_long_names; /* -+ */ int flag_one; /* -1 */ int flag_show_after_trunc; /* -H */ int flag_no_hash_mixed_case; /* -h NUM */ +#ifdef OBJ_ELF +int flag_want_pic; /* -k */ +#endif /* * For VAX, relative addresses of "just the right length" are easy. @@ -223,7 +238,7 @@ const relax_typeS md_relax_table[] = #undef WF #undef WB -void float_cons (); +void float_cons PARAMS ((int)); const pseudo_typeS md_pseudo_table[] = { @@ -231,7 +246,7 @@ const pseudo_typeS md_pseudo_table[] = {"ffloat", float_cons, 'f'}, {"gfloat", float_cons, 'g'}, {"hfloat", float_cons, 'h'}, - {0}, + {NULL, NULL, 0}, }; #define STATE_PC_RELATIVE (1) @@ -251,10 +266,13 @@ int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words)); static const char *vip_begin PARAMS ((int, const char *, const char *, const char *)); +static void vip_op_1 PARAMS ((int, const char *)); static void vip_op_defaults PARAMS ((const char *, const char *, const char *)); static void vip_op PARAMS ((char *, struct vop *)); static void vip PARAMS ((struct vit *, char *)); +static int vax_reg_parse PARAMS ((char, char, char, char)); + void md_begin () { @@ -290,14 +308,19 @@ md_number_to_chars (con, value, nbytes) void /* Knows about order of bytes in address. */ md_apply_fix3 (fixP, valueP, seg) - fixS * fixP; - valueT * valueP; + fixS *fixP; + valueT *valueP; segT seg ATTRIBUTE_UNUSED; { valueT value = * valueP; - - number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal, - value, fixP->fx_size); +#ifdef BFD_ASSEMBLER + if (((fixP->fx_addsy == NULL && fixP->fx_subsy == NULL) + && fixP->fx_r_type != BFD_RELOC_32_PLT_PCREL + && fixP->fx_r_type != BFD_RELOC_32_GOT_PCREL) + || fixP->fx_r_type == NO_RELOC) +#endif + number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal, + value, fixP->fx_size); if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1; @@ -325,6 +348,8 @@ md_assemble (instruction_string) { /* Non-zero if operand expression's segment is not known yet. */ int is_undefined; + /* Non-zero if operand expression's segment is absolute. */ + int is_absolute; int length_code; char *p; @@ -375,7 +400,7 @@ md_assemble (instruction_string) */ if ((goofed = (*v.vit_error)) != 0) { - as_warn (_("Ignoring statement due to \"%s\""), v.vit_error); + as_fatal (_("Ignoring statement due to \"%s\""), v.vit_error); } /* * We need to use expression() and friends, which require us to diddle @@ -394,7 +419,7 @@ md_assemble (instruction_string) { /* for each operand */ if (operandP->vop_error) { - as_warn (_("Ignoring statement because \"%s\""), operandP->vop_error); + as_fatal (_("Aborting because statement has \"%s\""), operandP->vop_error); goofed = 1; } else @@ -441,7 +466,7 @@ md_assemble (instruction_string) * instruction operands. */ need_pass_2 = 1; - as_warn (_("Can't relocate expression")); + as_fatal (_("Can't relocate expression")); break; case O_big: @@ -619,7 +644,7 @@ md_assemble (instruction_string) } if (input_line_pointer != operandP->vop_expr_end + 1) { - as_warn ("Junk at end of expression \"%s\"", input_line_pointer); + as_fatal ("Junk at end of expression \"%s\"", input_line_pointer); goofed = 1; } operandP->vop_expr_end[1] = c_save; @@ -662,7 +687,13 @@ md_assemble (instruction_string) this_add_number = expP->X_add_number; this_add_symbol = expP->X_add_symbol; to_seg = *segP; +#ifdef BFD_ASSEMBLER + is_undefined = (to_seg == undefined_section); + is_absolute = (to_seg == absolute_section); +#else is_undefined = (to_seg == SEG_UNKNOWN); + is_absolute = (to_seg == SEG_ABSOLUTE); +#endif at = operandP->vop_mode & 1; length = (operandP->vop_short == 'b' ? 1 : (operandP->vop_short == 'w' @@ -731,16 +762,20 @@ md_assemble (instruction_string) /* * --- SEG FLOAT MAY APPEAR HERE ---- */ - if (to_seg == SEG_ABSOLUTE) + if (is_absolute) { if (nbytes) { know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); p = frag_more (nbytes); /* Conventional relocation. */ - fix_new (frag_now, p - frag_now->fr_literal, - nbytes, &abs_symbol, this_add_number, - 1, NO_RELOC); + fix_new (frag_now, p - frag_now->fr_literal, nbytes, +#ifdef BFD_ASSEMBLER + section_symbol (absolute_section), +#else + &abs_symbol, +#endif + this_add_number, 1, NO_RELOC); } else { @@ -816,15 +851,19 @@ md_assemble (instruction_string) } else { - /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */ + /* to_seg != now_seg && !is_undefinfed && !is_absolute */ if (nbytes > 0) { /* Pc-relative. Conventional relocation. */ know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC)); p = frag_more (nbytes); - fix_new (frag_now, p - frag_now->fr_literal, - nbytes, &abs_symbol, this_add_number, - 1, NO_RELOC); + fix_new (frag_now, p - frag_now->fr_literal, nbytes, +#ifdef BFD_ASSEMBLER + section_symbol (absolute_section), +#else + &abs_symbol, +#endif + this_add_number, 1, NO_RELOC); } else { @@ -915,7 +954,7 @@ md_assemble (instruction_string) || operandP->vop_access == 'w'); if (operandP->vop_short == 's') { - if (to_seg == SEG_ABSOLUTE) + if (is_absolute) { if (this_add_number >= 64) { @@ -954,8 +993,14 @@ md_assemble (instruction_string) if (length == 0) { know (operandP->vop_short == ' '); + length_code = STATE_BYTE; +#ifdef OBJ_ELF + if (S_IS_EXTERNAL (this_add_symbol) + || S_IS_WEAK (this_add_symbol)) + length_code = STATE_UNDF; +#endif p = frag_var (rs_machine_dependent, 10, 2, - ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE), + ENCODE_RELAX (STATE_PC_RELATIVE, length_code), this_add_symbol, this_add_number, opcode_low_byteP); know (operandP->vop_mode == 10 + at); @@ -980,7 +1025,7 @@ md_assemble (instruction_string) { /* to_seg != now_seg */ if (this_add_symbol == NULL) { - know (to_seg == SEG_ABSOLUTE); + know (is_absolute); /* Do @#foo: simpler relocation than foo-.(pc) anyway. */ p = frag_more (5); p[0] = VAX_ABSOLUTE_MODE; /* @#... */ @@ -995,17 +1040,29 @@ md_assemble (instruction_string) /* {@}{q^}other_seg */ know ((length == 0 && operandP->vop_short == ' ') || (length > 0 && operandP->vop_short != ' ')); - if (is_undefined) + if (is_undefined +#ifdef OBJ_ELF + || S_IS_WEAK(this_add_symbol) + || S_IS_EXTERNAL(this_add_symbol) +#endif + ) { + switch (length) + { + default: length_code = STATE_UNDF; break; + case 1: length_code = STATE_BYTE; break; + case 2: length_code = STATE_WORD; break; + case 4: length_code = STATE_LONG; break; + } /* * We have a SEG_UNKNOWN symbol. It might * turn out to be in the same segment as * the instruction, permitting relaxation. */ p = frag_var (rs_machine_dependent, 5, 2, - ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF), + ENCODE_RELAX (STATE_PC_RELATIVE, length_code), this_add_symbol, this_add_number, - 0); + opcode_low_byteP); p[0] = at << 4; } else @@ -1043,7 +1100,7 @@ md_assemble (instruction_string) one case. */ } if (length == 0 - && to_seg == SEG_ABSOLUTE && (expP->X_op != O_big) + && is_absolute && (expP->X_op != O_big) && operandP->vop_mode == 8 /* No '@'. */ && this_add_number < 64) { @@ -1059,8 +1116,15 @@ md_assemble (instruction_string) know (nbytes); p = frag_more (nbytes + 1); know (operandP->vop_reg == 0xF); +#ifdef OBJ_ELF + if (flag_want_pic && operandP->vop_mode == 8 + && this_add_symbol != NULL) + { + as_warn (_("Symbol used as immediate operand in PIC mode.")); + } +#endif p[0] = (operandP->vop_mode << 4) | 0xF; - if ((to_seg == SEG_ABSOLUTE) && (expP->X_op != O_big)) + if ((is_absolute) && (expP->X_op != O_big)) { /* * If nbytes > 4, then we are scrod. We @@ -1115,7 +1179,7 @@ md_assemble (instruction_string) || (length > 0 && operandP->vop_short != ' ')); if (length == 0) { - if (to_seg == SEG_ABSOLUTE) + if (is_absolute) { long test; @@ -1137,7 +1201,7 @@ md_assemble (instruction_string) know (operandP->vop_reg >= 0); p[0] = operandP->vop_reg | ((at | "?\12\14?\16"[length]) << 4); - if (to_seg == SEG_ABSOLUTE) + if (is_absolute) { md_number_to_chars (p + 1, this_add_number, length); } @@ -1165,21 +1229,65 @@ md_estimate_size_before_relax (fragP, segment) { if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF) { - if (S_GET_SEGMENT (fragP->fr_symbol) != segment) + if (S_GET_SEGMENT (fragP->fr_symbol) != segment +#ifdef OBJ_ELF + || S_IS_WEAK (fragP->fr_symbol) + || S_IS_EXTERNAL (fragP->fr_symbol) +#endif + ) { /* Non-relaxable cases. */ + int reloc_type = NO_RELOC; char *p; int old_fr_fix; old_fr_fix = fragP->fr_fix; p = fragP->fr_literal + old_fr_fix; +#ifdef OBJ_ELF + /* + * If this is to undefined symbol, then if it's an indirect + * reference indicate that is can mutated into a GLOB_DAT + * by the loader. We restrict ourselves to no offset due to + * a limitation in the NetBSD linker. + */ + if (GOT_symbol == NULL) + GOT_symbol = symbol_find (GLOBAL_OFFSET_TABLE_NAME); + if (PLT_symbol == NULL) + PLT_symbol = symbol_find (PROCEDURE_LINKAGE_TABLE_NAME); + if ((GOT_symbol == NULL || fragP->fr_symbol != GOT_symbol) + && (PLT_symbol == NULL || fragP->fr_symbol != PLT_symbol) + && fragP->fr_symbol != NULL + && (!S_IS_DEFINED (fragP->fr_symbol) + || S_IS_WEAK (fragP->fr_symbol) + || S_IS_EXTERNAL (fragP->fr_symbol))) + { + if (p[0] & 0x10) + { + if (flag_want_pic) + as_fatal ("PIC reference to %s is indirect.\n", + S_GET_NAME (fragP->fr_symbol)); + } + else + { + + if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB + || ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP + || S_IS_FUNCTION (fragP->fr_symbol)) + reloc_type = BFD_RELOC_32_PLT_PCREL; + else + reloc_type = BFD_RELOC_32_GOT_PCREL; + } + } +#endif switch (RELAX_STATE (fragP->fr_subtype)) { case STATE_PC_RELATIVE: p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */ fragP->fr_fix += 1 + 4; fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, - fragP->fr_offset, 1, NO_RELOC); + fragP->fr_offset, 1, reloc_type); break; case STATE_CONDITIONAL_BRANCH: @@ -1272,11 +1380,19 @@ md_estimate_size_before_relax (fragP, segment) * Out: Any fixSs and constants are set up. * Caller will turn frag into a ".space 0". */ +#ifdef BFD_ASSEMBLER void md_convert_frag (headers, seg, fragP) - object_headers *headers; - segT seg; + bfd *headers ATTRIBUTE_UNUSED; + segT seg ATTRIBUTE_UNUSED; + fragS *fragP; +#else +void +md_convert_frag (headers, seg, fragP) + object_headers *headers ATTRIBUTE_UNUSED; + segT seg ATTRIBUTE_UNUSED; fragS *fragP; +#endif { char *addressP; /* -> _var to change. */ char *opcodeP; /* -> opcode char(s) to change. */ @@ -1284,10 +1400,6 @@ md_convert_frag (headers, seg, fragP) /* Added to fr_fix: incl. ALL var chars. */ symbolS *symbolP; long where; - long address_of_var; - /* Where, in file space, is _var of *fragP? */ - long target_address = 0; - /* Where, in file space, does addr point? */ know (fragP->fr_type == rs_machine_dependent); where = fragP->fr_fix; @@ -1295,43 +1407,46 @@ md_convert_frag (headers, seg, fragP) opcodeP = fragP->fr_opcode; symbolP = fragP->fr_symbol; know (symbolP); - target_address = S_GET_VALUE (symbolP) + fragP->fr_offset; - address_of_var = fragP->fr_address + where; switch (fragP->fr_subtype) { case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE): know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xAF; /* Byte displacement. */ - addressP[1] = target_address - (address_of_var + 2); + addressP[0] |= 0xAF; /* Byte displacement. */ + fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 2; break; case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD): know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xCF; /* Word displacement. */ - md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2); + addressP[0] |= 0xCF; /* Word displacement. */ + fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 3; break; case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG): know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */ - addressP[0] |= 0xEF; /* Long word displacement. */ - md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); + addressP[0] |= 0xEF; /* Long word displacement. */ + fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 5; break; case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); + fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 1; break; case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD): opcodeP[0] ^= 1; /* Reverse sense of test. */ addressP[0] = 3; - addressP[1] = VAX_BRB + VAX_WIDEN_WORD; - md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2); + addressP[1] = VAX_BRW; + fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 4; break; @@ -1340,30 +1455,35 @@ md_convert_frag (headers, seg, fragP) addressP[0] = 6; addressP[1] = VAX_JMP; addressP[2] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 3, target_address - (address_of_var + 7), 4); + fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 7; break; case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); + fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 1; break; case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD): opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */ - md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); + fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset, + 1, NO_RELOC); extension = 2; break; case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG): opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */ addressP[0] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4); + fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 5; break; case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD): - md_number_to_chars (addressP, target_address - (address_of_var + 2), 2); + fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 2; break; @@ -1374,12 +1494,14 @@ md_convert_frag (headers, seg, fragP) addressP[3] = 6; addressP[4] = VAX_JMP; addressP[5] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 6, target_address - (address_of_var + 10), 4); + fix_new (fragP, fragP->fr_fix + 6, 4, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 10; break; case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE): - addressP[0] = target_address - (address_of_var + 1); + fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 1; break; @@ -1388,7 +1510,8 @@ md_convert_frag (headers, seg, fragP) addressP[1] = VAX_BRB; addressP[2] = 3; addressP[3] = VAX_BRW; - md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2); + fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 6; break; @@ -1398,7 +1521,8 @@ md_convert_frag (headers, seg, fragP) addressP[2] = 6; addressP[3] = VAX_JMP; addressP[4] = VAX_PC_RELATIVE_MODE; - md_number_to_chars (addressP + 5, target_address - (address_of_var + 9), 4); + fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol, + fragP->fr_offset, 1, NO_RELOC); extension = 9; break; @@ -1433,6 +1557,8 @@ md_ri_to_chars (the_bytes, ri) #endif /* comment */ +#ifdef OBJ_AOUT +#ifndef BFD_ASSEMBLER void tc_aout_fix_to_chars (where, fixP, segment_address_in_file) char *where; @@ -1464,6 +1590,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06) | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f)); } +#endif /* !BFD_ASSEMBLER */ +#endif /* OBJ_AOUT */ /* * BUGS, GRIPES, APOLOGIA, etc. @@ -1978,13 +2106,35 @@ main () #define PC (15) int /* return -1 or 0:15 */ -vax_reg_parse (c1, c2, c3) /* 3 chars of register name */ - char c1, c2, c3; /* c3 == 0 if 2-character reg name */ +vax_reg_parse (c1, c2, c3, c4) /* 3 chars of register name */ + char c1, c2, c3, c4; /* c3 == 0 if 2-character reg name */ { int retval; /* return -1:15 */ retval = -1; +#ifdef OBJ_ELF + if (c1 != '%') /* register prefixes are mandatory for ELF */ + return retval; + c1 = c2; + c2 = c3; + c3 = c4; +#endif +#ifdef OBJ_VMS + if (c4 != 0) /* register prefixes are not allowed under VMS */ + return retval; +#endif +#ifdef OBJ_AOUT + if (c1 == '%') /* register prefixes are optional under a.out */ + { + c1 = c2; + c2 = c3; + c3 = c4; + } + else if (c3 && c4) /* can't be 4 characters long. */ + return retval; +#endif + c1 = TOLOWER (c1); c2 = TOLOWER (c2); if (ISDIGIT (c2) && c1 == 'r') @@ -2388,9 +2538,11 @@ vip_op (optext, vopP) * name error. So again we don't need to check for early '\0'. */ if (q[3] == ']') - ndx = vax_reg_parse (q[1], q[2], 0); + ndx = vax_reg_parse (q[1], q[2], 0, 0); else if (q[4] == ']') - ndx = vax_reg_parse (q[1], q[2], q[3]); + ndx = vax_reg_parse (q[1], q[2], q[3], 0); + else if (q[5] == ']') + ndx = vax_reg_parse (q[1], q[2], q[3], q[4]); else ndx = -1; /* @@ -2443,9 +2595,11 @@ vip_op (optext, vopP) * name error. So again we don't need to check for early '\0'. */ if (q[3] == ')') - reg = vax_reg_parse (q[1], q[2], 0); + reg = vax_reg_parse (q[1], q[2], 0, 0); else if (q[4] == ')') - reg = vax_reg_parse (q[1], q[2], q[3]); + reg = vax_reg_parse (q[1], q[2], q[3], 0); + else if (q[5] == ')') + reg = vax_reg_parse (q[1], q[2], q[3], q[4]); else reg = -1; /* @@ -2515,8 +2669,11 @@ vip_op (optext, vopP) q--; /* reverse over whitespace, but don't */ /* run back over *p */ - if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */ - reg = vax_reg_parse (p[0], p[1], q < p + 2 ? 0 : p[2]); + /* room for Rn or Rnn (include prefix) exactly? */ + if (q > p && q < p + 4) + reg = vax_reg_parse (p[0], p[1], + q < p + 2 ? 0 : p[2], + q < p + 3 ? 0 : p[3]); else reg = -1; /* always comes here if no register at all */ /* @@ -3065,9 +3222,10 @@ const int md_reloc_size = 8; /* Size of relocation record */ void md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; - addressT from_addr, to_addr; - fragS *frag; - symbolS *to_symbol; + addressT from_addr; + addressT to_addr ATTRIBUTE_UNUSED; + fragS *frag ATTRIBUTE_UNUSED; + symbolS *to_symbol ATTRIBUTE_UNUSED; { valueT offset; @@ -3083,7 +3241,8 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) void md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) char *ptr; - addressT from_addr, to_addr; + addressT from_addr ATTRIBUTE_UNUSED; + addressT to_addr; fragS *frag; symbolS *to_symbol; { @@ -3098,6 +3257,8 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) #ifdef OBJ_VMS const char *md_shortopts = "d:STt:V+1h:Hv::"; +#elif defined(OBJ_ELC) +const char *md_shortopts = "d:STt:VkK"; #else const char *md_shortopts = "d:STt:V"; #endif @@ -3164,6 +3325,13 @@ md_parse_option (c, arg) break; #endif +#ifdef OBJ_ELF + case 'K': + case 'k': + flag_want_pic = 1; + break; /* -pic, Position Independent Code */ +#endif + default: return 0; } @@ -3199,7 +3367,7 @@ VMS options:\n\ symbolS * md_undefined_symbol (name) - char *name; + char *name ATTRIBUTE_UNUSED; { return 0; } @@ -3207,7 +3375,7 @@ md_undefined_symbol (name) /* Round up a section size to the appropriate boundary. */ valueT md_section_align (segment, size) - segT segment; + segT segment ATTRIBUTE_UNUSED; valueT size; { return size; /* Byte alignment is fine */ @@ -3215,7 +3383,7 @@ md_section_align (segment, size) /* Exactly what point is a PC-relative offset relative TO? On the vax, they're relative to the address of the offset, plus - its size. (??? Is this right? FIXME-SOON) */ + its size. */ long md_pcrel_from (fixP) fixS *fixP; @@ -3223,4 +3391,96 @@ md_pcrel_from (fixP) return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; } +#ifdef OBJ_AOUT +#ifndef BFD_ASSEMBLER +void +tc_headers_hook(headers) + object_headers *headers; +{ +#ifdef TE_NetBSD + N_SET_INFO(headers->header, OMAGIC, M_VAX4K_NETBSD, 0); + headers->header.a_info = htonl(headers->header.a_info); +#endif +} +#endif /* !BFD_ASSEMBLER */ +#endif /* OBJ_AOUT */ + +#ifdef BFD_ASSEMBLER +arelent * +tc_gen_reloc (section, fixp) + asection *section ATTRIBUTE_UNUSED; + fixS *fixp; +{ + arelent *reloc; + bfd_reloc_code_real_type code; + + if (fixp->fx_tcbit) + abort(); + + if (fixp->fx_r_type != BFD_RELOC_NONE) + { + code = fixp->fx_r_type; + + if (fixp->fx_pcrel) + { + switch (code) + { + case BFD_RELOC_8_PCREL: + case BFD_RELOC_16_PCREL: + case BFD_RELOC_32_PCREL: +#ifdef OBJ_ELF + case BFD_RELOC_8_GOT_PCREL: + case BFD_RELOC_16_GOT_PCREL: + case BFD_RELOC_32_GOT_PCREL: + case BFD_RELOC_8_PLT_PCREL: + case BFD_RELOC_16_PLT_PCREL: + case BFD_RELOC_32_PLT_PCREL: +#endif + break; + default: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("Cannot make %s relocation PC relative"), + bfd_get_reloc_code_name (code)); + } + } + } + else + { +#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 + MAP (1, 0, BFD_RELOC_8); + MAP (2, 0, BFD_RELOC_16); + MAP (4, 0, BFD_RELOC_32); + MAP (1, 1, BFD_RELOC_8_PCREL); + MAP (2, 1, BFD_RELOC_16_PCREL); + MAP (4, 1, BFD_RELOC_32_PCREL); + default: + abort (); + } + } +#undef F +#undef MAP + + reloc = (arelent *) xmalloc (sizeof (arelent)); + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; +#ifndef OBJ_ELF + if (fixp->fx_pcrel) + reloc->addend = fixp->fx_addnumber; + else + reloc->addend = 0; +#else + reloc->addend = fixp->fx_offset; +#endif + + reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + assert (reloc->howto != 0); + + return reloc; +} +#endif /* BFD_ASSEMBLER */ + /* end of tc-vax.c */ |