Add ELF support for VAX; fix (from bjh) ARM ELF for NetBSD

This commit is contained in:
matt 2001-05-03 18:15:12 +00:00
parent 487447a9bf
commit bc6a8a09a0
6 changed files with 569 additions and 388 deletions

View File

@ -116,6 +116,7 @@ static boolean uses_apcs_26 = false;
static boolean atpcs = false;
static boolean support_interwork = false;
static boolean uses_apcs_float = false;
/*static boolean pic_code = false;*/
#endif
/* This array holds the chars that always start a comment. If the

View File

@ -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 */
@ -59,18 +64,23 @@ FLONUM_TYPE float_operand[VIT_MAX_OPERANDS];
/* Above is made to point into big_operand_bits by md_begin(). */
#ifndef OBJ_VMS
#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
#define PROCEDURE_LINKAGE_TABLE_NAME "__PROCEDURE_LINKAGE_TABLE_"
static int flag_want_pic;
symbolS *GOT_symbol; /* Pre-defined "__GLOBAL_OFFSET_TABLE_" */
symbolS *PLT_symbol; /* Pre-defined "__PROCEDURE_LINKAGE_TABLE_" */
#ifdef OBJ_AOUT
#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
#define PROCEDURE_LINKAGE_TABLE_NAME "__PROCEDURE_LINKAGE_TABLE_"
#endif
#ifdef OBJ_ELF
#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
#define PROCEDURE_LINKAGE_TABLE_NAME "_PROCEDURE_LINKAGE_TABLE_"
#endif
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 */
int flag_want_pic; /* -k */
/*
* For VAX, relative addresses of "just the right length" are easy.
@ -216,15 +226,6 @@ const relax_typeS md_relax_table[] =
{BF, BB, 1, C (5, 1)}, /* Xob___,,foo 5,0 */
{WF + 4, WB + 4, 6, C (5, 2)},/* Xob.+2,brb.+3,brw5,1 */
{0, 0, 9, 0}, /* Xob.+2,brb.+6,jmp5,2 */
{1, 1, 0, 0}, /* unused 5,3 */
{BF + 1, BB + 1, 2, C (6, 1)},/* B^"foo" 6,0 */
{WF + 1, WB + 1, 3, C (6, 2)},/* W^"foo" 6,1 */
{0, 0, 5, 0}, /* L^"foo" 6,2 */
{1, 1, 0, 0}, /* unused 6,3 */
{BF + 1, BB + 1, 2, C (7, 1)},/* B^"foo" 7,0 */
{WF + 1, WB + 1, 3, C (7, 2)},/* W^"foo" 7,1 */
{0, 0, 5, 0}, /* L^"foo" 7,2 */
{1, 1, 0, 0}, /* unused 7,3 */
};
#undef C
@ -241,7 +242,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)
@ -249,8 +250,6 @@ const pseudo_typeS md_pseudo_table[] =
#define STATE_ALWAYS_BRANCH (3) /* includes BSB... */
#define STATE_COMPLEX_BRANCH (4)
#define STATE_COMPLEX_HOP (5)
#define STATE_PC_RELATIVE_CALL (6)
#define STATE_PC_RELATIVE_JMP (7)
#define STATE_BYTE (0)
#define STATE_WORD (1)
@ -300,6 +299,32 @@ md_number_to_chars (con, value, nbytes)
/* Fix up some data or instructions after we find out the value of a symbol
that they reference. */
#ifdef BFD_ASSEMBLER
int /* Knows about order of bytes in address. */
md_apply_fix (fixP, valP)
fixS *fixP;
valueT *valP;
{
valueT val = *valP;
#ifdef OBJ_ELF
if (fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL || (fixP->fx_size == 4 && fixP->fx_pcrel))
{
#if 0
printf("info: %s:%d: fixup: symbol=%s: %#lx (off=%#lx)\n",
fixP->fx_frag->fr_file, fixP->fx_frag->fr_line,
S_GET_NAME(fixP->fx_frag->fr_symbol
? fixP->fx_frag->fr_symbol
: fixP->fx_addsy),
val, fixP->fx_offset);
#endif
val -= fixP->fx_offset;
}
#endif
number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
val, fixP->fx_size);
return 0;
}
#else
void /* Knows about order of bytes in address. */
md_apply_fix (fixP, value)
fixS *fixP;
@ -308,6 +333,7 @@ md_apply_fix (fixP, value)
number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
(valueT) value, fixP->fx_size);
}
#endif /* not BFD_ASSEMBLER */
long
md_chars_to_number (con, nbytes)
@ -331,6 +357,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;
@ -668,7 +696,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'
@ -737,16 +771,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
{
@ -822,15 +860,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
{
@ -921,7 +963,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)
{
@ -986,7 +1028,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; /* @#... */
@ -1009,17 +1051,9 @@ md_assemble (instruction_string)
* the instruction, permitting relaxation.
*/
p = frag_var (rs_machine_dependent, 5, 2,
#ifndef OBJ_VMS
(flag_want_pic && !at && (*(unsigned char *)opcode_low_byteP == 0xfa
|| *(unsigned char *)opcode_low_byteP == 0xfb))
? ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_UNDF) :
((flag_want_pic && !at && (*(unsigned char *)opcode_low_byteP == 0x16
|| *(unsigned char *)opcode_low_byteP == 0x17))
? ENCODE_RELAX (STATE_PC_RELATIVE_JMP, STATE_UNDF) :
#endif
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF)),
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
this_add_symbol, this_add_number,
0);
opcode_low_byteP);
p[0] = at << 4;
}
else
@ -1057,7 +1091,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)
{
@ -1069,8 +1103,6 @@ md_assemble (instruction_string)
}
else
{
int reloc_type = NO_RELOC;
int is_pcrel = 0;
/* I^#... */
know (nbytes);
p = frag_more (nbytes + 1);
@ -1079,16 +1111,11 @@ md_assemble (instruction_string)
if (flag_want_pic && operandP->vop_mode == 8
&& this_add_symbol != NULL)
{
as_warn ("Symbol used as immediate operand in PIC mode.");
#if 0
operandP->vop_mode = 0xf; /* deferred pc-rel */
reloc_type = RELOC_GLOB_DAT;
is_pcrel = 1;
#endif
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
@ -1132,7 +1159,7 @@ md_assemble (instruction_string)
{
fix_new (frag_now, p + 1 - frag_now->fr_literal,
nbytes, this_add_symbol,
this_add_number, is_pcrel, reloc_type);
this_add_number, 0, NO_RELOC);
}
}
}
@ -1143,7 +1170,7 @@ md_assemble (instruction_string)
|| (length > 0 && operandP->vop_short != ' '));
if (length == 0)
{
if (to_seg == SEG_ABSOLUTE)
if (is_absolute)
{
long test;
@ -1165,7 +1192,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);
}
@ -1221,71 +1248,68 @@ md_estimate_size_before_relax (fragP, segment)
* by the loader. We restrict ourselves to no offset due to
* a limitation in the NetBSD linker.
*/
#ifdef OBJ_AOUT
if ((p[0] & 0x10) == 0 && !fragP->fr_offset && !flag_want_pic)
{
reloc_type = NO_RELOC2;
}
#endif
if (GOT_symbol == NULL)
GOT_symbol = symbol_find(GLOBAL_OFFSET_TABLE_NAME);
GOT_symbol = symbol_find (GLOBAL_OFFSET_TABLE_NAME);
if (PLT_symbol == NULL)
PLT_symbol = symbol_find(PROCEDURE_LINKAGE_TABLE_NAME);
if (flag_want_pic
&& (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))
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_EXTERNAL (fragP->fr_symbol)))
{
if (p[0] & 0x10)
as_fatal("PIC reference to %s is already indirect.\n",
S_GET_NAME(fragP->fr_symbol));
p[0] |= 0x10; /* SET @ bit */
reloc_type = RELOC_GLOB_DAT;
{
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
|| S_IS_FUNCTION (fragP->fr_symbol))
{
#ifdef BFD_ASSEMBLER
reloc_type = BFD_RELOC_32_PLT_PCREL;
#else
reloc_type = RELOC_JMP_TBL;
#endif
}
else if (fragP->fr_opcode[0] == VAX_JSB
|| fragP->fr_opcode[0] == VAX_JMP)
{
#ifdef BFD_ASSEMBLER
reloc_type = BFD_RELOC_32_PLT_PCREL;
#else
reloc_type = RELOC_JMP_SLOT;
#endif
}
else
{
#ifdef OBJ_AOUT
if (fragP->fr_offset)
#endif
#ifdef BFD_ASSEMBLER
reloc_type = BFD_RELOC_32_GOT_PCREL;
#else
reloc_type = RELOC_GLOB_DAT;
#endif
}
}
}
#endif
p[0] |= VAX_PC_RELATIVE_MODE;
fragP->fr_fix += 1 + 4;
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, reloc_type);
frag_wane (fragP);
}
break;
case ENCODE_RELAX (STATE_PC_RELATIVE_JMP, STATE_UNDF):
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
{ /* A relaxable case. */
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE_JMP, STATE_BYTE);
}
else
{
p = fragP->fr_literal + old_fr_fix;
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,
#ifndef OBJ_VMS
flag_want_pic ? RELOC_JMP_SLOT :
#endif
NO_RELOC);
frag_wane (fragP);
}
break;
case ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_UNDF):
if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
{ /* A relaxable case. */
fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_BYTE);
}
else
{
p = fragP->fr_literal + old_fr_fix;
p[0] |= VAX_PC_RELATIVE_MODE; /* don't force @ bit */
fragP->fr_fix += 1 + 4;
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1,
#ifndef OBJ_VMS
flag_want_pic ? RELOC_JMP_TBL :
#endif
NO_RELOC);
fragP->fr_offset, 1, reloc_type);
frag_wane (fragP);
}
break;
@ -1362,11 +1386,7 @@ md_estimate_size_before_relax (fragP, segment)
p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
fragP->fr_fix += 1 + 4;
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1,
#ifndef OBJ_VMS
flag_want_pic ? RELOC_JMP_SLOT :
#endif
NO_RELOC);
fragP->fr_offset, 1, NO_RELOC);
frag_wane (fragP);
}
break;
@ -1388,11 +1408,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)
bfd *headers;
segT seg;
fragS *fragP;
#else
void
md_convert_frag (headers, seg, fragP)
object_headers *headers;
segT seg;
fragS *fragP;
#endif
{
char *addressP; /* -> _var to change. */
char *opcodeP; /* -> opcode char(s) to change. */
@ -1401,10 +1429,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);
length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */
@ -1414,49 +1438,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_JMP, STATE_BYTE):
case ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_BYTE):
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_JMP, STATE_WORD):
case ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_WORD):
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_JMP, STATE_LONG):
case ENCODE_RELAX (STATE_PC_RELATIVE_CALL, STATE_LONG):
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;
@ -1465,30 +1486,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;
@ -1499,12 +1525,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;
@ -1513,7 +1541,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;
@ -1523,7 +1552,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;
@ -1558,6 +1588,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;
@ -1570,7 +1602,7 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
*/
static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
long r_symbolnum;
int r_symbolnum;
int r_flags;
know (fixP->fx_addsy != NULL);
@ -1630,6 +1662,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
where[6] = (r_symbolnum >> 16) & 0xff;
where[7] = r_flags;
}
#endif /* !BFD_ASSEMBLER */
#endif /* OBJ_AOUT */
/*
* BUGS, GRIPES, APOLOGIA, etc.
@ -3268,7 +3302,7 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
#ifdef OBJ_VMS
CONST char *md_shortopts = "d:STt:V+1h:Hv::";
#else
CONST char *md_shortopts = "d:STt:Vk";
CONST char *md_shortopts = "d:STt:VkK";
#endif
struct option md_longopts[] = {
{NULL, no_argument, NULL, 0}
@ -3334,7 +3368,8 @@ md_parse_option (c, arg)
#endif
#ifndef OBJ_VMS
case 'k':
case 'K':
case 'k':
flag_want_pic = 1;
break; /* -pic, Position Independent Code */
#endif
@ -3398,12 +3433,134 @@ 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;
object_headers *headers;
{
N_SET_INFO(headers->header, OMAGIC, M_VAX, flag_want_pic ? 0x40 : 0);
headers->header.a_info = htonl(headers->header.a_info);
}
#endif
#endif
#ifdef BFD_ASSEMBLER
arelent *
tc_gen_reloc (section, fixp)
asection *section;
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 0
/* Since DIFF_EXPR_OK is defined in tc-m68k.h, it is possible
that fixup_segment converted a non-PC relative reloc into a
PC relative reloc. In such a case, we need to convert the
reloc code. */
#endif
if (fixp->fx_pcrel)
{
switch (code)
{
#if 0
case BFD_RELOC_8:
code = BFD_RELOC_8_PCREL;
break;
case BFD_RELOC_16:
code = BFD_RELOC_16_PCREL;
break;
case BFD_RELOC_32:
code = BFD_RELOC_32_PCREL;
break;
#endif
case BFD_RELOC_8_PCREL:
case BFD_RELOC_16_PCREL:
case BFD_RELOC_32_PCREL:
case BFD_RELOC_8_GOT_PCREL:
case BFD_RELOC_16_GOT_PCREL:
case BFD_RELOC_32_GOT_PCREL:
case BFD_RELOC_8_GOTOFF:
case BFD_RELOC_16_GOTOFF:
case BFD_RELOC_32_GOTOFF:
case BFD_RELOC_8_PLT_PCREL:
case BFD_RELOC_16_PLT_PCREL:
case BFD_RELOC_32_PLT_PCREL:
case BFD_RELOC_8_PLTOFF:
case BFD_RELOC_16_PLTOFF:
case BFD_RELOC_32_PLTOFF:
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
if (!fixp->fx_pcrel)
{
reloc->addend = fixp->fx_addnumber;
}
#ifdef OBJ_ELF
else if (code == BFD_RELOC_32_GOT_PCREL && fixp->fx_offset != 0)
{
code = BFD_RELOC_32_PCREL;
reloc->addend = 0;
}
else if (code == BFD_RELOC_32_GOT_PCREL || code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32_PLT_PCREL)
{
reloc->addend = fixp->fx_offset;
}
#endif
else
{
reloc->addend = 0;
}
#endif
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
assert (reloc->howto != 0);
return reloc;
}
#endif
/* end of tc-vax.c */

View File

@ -23,15 +23,28 @@
#define TARGET_BYTES_BIG_ENDIAN 0
#ifndef OBJ_VMS
#ifndef BFD_ASSEMBLER
enum reloc_type {
NO_RELOC, NO_RELOC2, RELOC_32, RELOC_GLOB_DAT, RELOC_JMP_TBL, RELOC_JMP_SLOT
};
#ifdef OBJ_AOUT
#ifdef TE_NetBSD
#define TARGET_FORMAT "a.out-vax-netbsd"
#endif
#ifndef TARGET_FORMAT
#define TARGET_FORMAT "a.out-vax-bsd"
#endif
#endif
#ifdef OBJ_VMS
#define TARGET_FORMAT "vms-vax"
#endif
#ifdef OBJ_ELF
#define TARGET_FORMAT "elf32-vax"
#endif
#define BFD_ARCH bfd_arch_vax /* for non-BFD_ASSEMBLER */
#define TARGET_ARCH bfd_arch_vax /* BFD_ASSEMBLER */
#define NO_RELOC BFD_RELOC_NONE
#define NOP_OPCODE 0x01
#define NEED_FX_R_TYPE 1
#define tc_aout_pre_write_hook(x) {;} /* not used */
#define tc_crawl_symbol_chain(a) {;} /* not used */
@ -42,6 +55,20 @@ long md_chars_to_number PARAMS ((unsigned char *, int));
extern const struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
/* This expression evaluates to false if the relocation is for a local object
for which we still want to do the relocation at runtime. True if we
are willing to perform this relocation while building the .o file. If
the reloc is against an externally visible symbol, then the assembler
should never do the relocation. */
#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
((FIX)->fx_addsy == NULL \
|| (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
&& ! S_IS_WEAK ((FIX)->fx_addsy) \
&& S_IS_DEFINED ((FIX)->fx_addsy) \
&& ! S_IS_COMMON ((FIX)->fx_addsy)))
/*
* Local Variables:
* comment-column: 0

View File

@ -54,6 +54,7 @@ typedef long vax_opcodeT; /* For initialising array of opcodes */
#define VAX_WIDTH_WORD_JUMP '!' /* and VIT_OPCODE_SYNTHETIC set. */
#define VAX_WIDTH_BYTE_JUMP ':' /* */
#define VAX_JSB (0x16) /* Jump to subroutine */
#define VAX_JMP (0x17) /* Useful for branch optimising. Jump instr*/
#define VAX_PC_RELATIVE_MODE (0xef) /* Use it after VAX_JMP */
#define VAX_ABSOLUTE_MODE (0x9F)/* Use as @#... */
@ -62,6 +63,8 @@ typedef long vax_opcodeT; /* For initialising array of opcodes */
#define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */
#define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/
/* Needs VAX_PC_RELATIVE_MODE byte after it*/
#define VAX_CALLS (0xFB) /* Call with arg list on stack */
#define VAX_CALLG (0xFA) /* Call with arg list in memory */
struct vit /* vax instruction tree */
{

File diff suppressed because it is too large Load Diff

View File

@ -186,6 +186,7 @@ changequote([,])dnl
arm-*-linux*aout*) fmt=aout em=linux ;;
arm*-*-linux-gnu* | arm*-*-uclinux*)
fmt=elf em=linux ;;
arm*-*-netbsdelf*) fmt=elf em=nbsd bfd_gas=yes ;;
arm-*-netbsd*) fmt=aout em=nbsd ;;
arm-*-oabi | thumb-*-oabi) fmt=elf ;;
arm-epoc-pe | thumb-epoc-pe) fmt=coff em=epoc-pe ;;
@ -426,6 +427,7 @@ changequote([,])dnl
v850e-*-*) fmt=elf bfd_gas=yes ;;
v850ea-*-*) fmt=elf bfd_gas=yes ;;
vax-*-netbsdelf*) fmt=elf em=nbsd bfd_gas=yes ;;
vax-*-netbsd*) fmt=aout em=nbsd ;;
vax-*-bsd* | vax-*-ultrix*)
fmt=aout ;;