First batch of changes needed to make gas.new work with PIC on the ns32k.

Todo: Modify tc_gen_reloc to frob the relocations correctly, add code for
missing relocation types to libbfd.
This commit is contained in:
matthias 1999-03-13 15:18:49 +00:00
parent f9b0eec83a
commit 00cd9c886f
2 changed files with 75 additions and 17 deletions

View File

@ -366,6 +366,16 @@ char disp_test[] =
char disp_size[] =
{4, 1, 2, 0, 4};
/* In pic-mode all external pc-relative references are jmpslot
references except references to __GLOBAL_OFFSET_TABLE_. */
static symbolS *got_symbol;
/* The size of got-offsets. */
static int got_offset_size = 2;
/* Non-zero if we are generating PIC code. */
static int ns32k_pic_code = 0;
static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
static void md_number_to_disp PARAMS ((char *buf, long val, int n));
@ -1230,6 +1240,14 @@ convert_iif ()
{
if (type = iif.iifP[i].type)
{ /* the object exist, so handle it */
unsigned int reloc_mode;
if ((i == 4 || i == 6)
&& aout_pic_flag
&& (iif.iifP[i].addr_mode == 18 || iif.iifP[i].addr_mode == 26))
reloc_mode = BFD_RELOC_NS32K_GLOB_DAT;
else
reloc_mode = NO_RELOC;
switch (size = iif.iifP[i].size)
{
case 42:
@ -1260,7 +1278,7 @@ convert_iif ()
iif.iifP[i].im_disp,
j,
iif.iifP[i].bsr, /* sequent hack */
inst_frag, inst_offset);
inst_frag, inst_offset, reloc_mode);
}
else
{ /* good, just put them bytes out */
@ -1350,7 +1368,7 @@ convert_iif ()
iif.iifP[i].im_disp,
j,
iif.iifP[i].bsr,
inst_frag, inst_offset);
inst_frag, inst_offset, reloc_mode);
}
else
{
@ -1383,9 +1401,18 @@ convert_iif ()
if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
!iif.iifP[i].pcrel)
{
/* Size is unknown until link time so have to
allow 4 bytes. */
size = 4;
if (reloc_mode == BFD_RELOC_NS32K_GLOB_DAT
&& got_offset_size == 2)
{
/* We are using 2 byte GOT offsets. */
size = 2;
}
else
{
/* Size is unknown until link time so have to
allow 4 bytes. */
size = 4;
}
memP = frag_more(size);
fix_new_ns32k_exp (frag_now,
(long) (memP - frag_now->fr_literal),
@ -1395,7 +1422,8 @@ convert_iif ()
1, /* always iif.iifP[i].im_disp */
(bit_fixS *) 0, 0,
inst_frag,
inst_offset);
inst_offset,
reloc_mode);
break; /* exit this absolute hack */
}
@ -2011,7 +2039,7 @@ md_estimate_size_before_relax (fragP, segment)
0,
frag_bsr(fragP), /*sequent hack */
frag_opcode_frag(fragP),
frag_opcode_offset(fragP));
frag_opcode_offset(fragP), NO_RELOC);
fragP->fr_fix += 4;
/* fragP->fr_opcode[1]=0xff; */
frag_wane (fragP);
@ -2089,6 +2117,16 @@ md_parse_option (c, arg)
}
break;
case 'K':
got_offset_size = 4;
/*FALLTHROUGH*/
case 'k':
#ifdef OBJ_AOUT
aout_pic_flag = 1;
#endif
ns32k_pic_code = 1;
break;
default:
return 0;
}
@ -2140,7 +2178,7 @@ bit_fix_new (size, offset, min, max, add, base_type, base_adj)
void
fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
im_disp, bit_fixP, bsr, opcode_frag, opcode_offset, reloc_mode)
fragS *frag; /* Which frag? */
int where; /* Where in that frag? */
int size; /* 1, 2 or 4 usually. */
@ -2155,12 +2193,13 @@ fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
a bsr */
fragS *opcode_frag;
unsigned int opcode_offset;
unsigned int reloc_mode;
{
fixS *fixP = fix_new (frag, where, size, add_symbol,
offset, pcrel,
#ifdef BFD_ASSEMBLER
bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
bit_fixP || reloc_mode != NO_RELOC? reloc_mode: reloc(size, pcrel, im_disp)
#else
NO_RELOC
#endif
@ -2175,7 +2214,7 @@ fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
void
fix_new_ns32k_exp (frag, where, size, exp, pcrel,
im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
im_disp, bit_fixP, bsr, opcode_frag, opcode_offset, reloc_mode)
fragS *frag; /* Which frag? */
int where; /* Where in that frag? */
int size; /* 1, 2 or 4 usually. */
@ -2189,10 +2228,12 @@ fix_new_ns32k_exp (frag, where, size, exp, pcrel,
a bsr */
fragS *opcode_frag;
unsigned int opcode_offset;
unsigned int reloc_mode;
{
fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
#ifdef BFD_ASSEMBLER
bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
bit_fixP || reloc_mode != NO_RELOC? reloc_mode: reloc(size, pcrel, im_disp)
#else
NO_RELOC
#endif
@ -2215,15 +2256,25 @@ cons_fix_new_ns32k (frag, where, size, exp)
expressionS *exp; /* Expression. */
{
fix_new_ns32k_exp (frag, where, size, exp,
0, 2, 0, 0, 0, 0);
0, 2, 0, 0, 0, 0, NO_RELOC);
}
/* We have no need to default values of symbols. */
symbolS *
md_undefined_symbol (name)
char *name;
{
if (*name == '_' && *(name+1) == '_' && *(name+2) == 'G'
&& strcmp(name, "__GLOBAL_OFFSET_TABLE_") == 0)
{
if (!got_symbol)
{
if (symbol_find(name))
as_bad("GOT already in symbol table");
got_symbol = symbol_new (name, undefined_section,
(valueT) 0, &zero_address_frag);
};
return got_symbol;
}
return 0;
}

View File

@ -28,10 +28,15 @@
#define NO_RELOC BFD_RELOC_NONE
#define TARGET_ARCH bfd_arch_ns32k
#ifdef OBJ_AOUT
#ifdef TE_NetBSD
#define TARGET_FORMAT "a.out-ns32k-netbsd"
#endif
#ifndef TARGET_FORMAT /* Maybe defined in te-*.h */
#define TARGET_FORMAT "a.out-pc532-mach"
#endif
#endif
#else
#define NO_RELOC 0
#endif
@ -76,8 +81,9 @@ extern void fix_new_ns32k_exp PARAMS((fragS *frag,
int im_disp,
bit_fixS *bit_fixP, /* really bit_fixS */
int bsr,
fragS *opcode_frag,
unsigned int opcode_offset));
fragS *opcode_frag,
unsigned int opcode_offset,
unsigned int reloc_mode));
extern void fix_new_ns32k PARAMS ((fragS *frag,
@ -90,7 +96,8 @@ extern void fix_new_ns32k PARAMS ((fragS *frag,
bit_fixS *bit_fixP, /* really bit_fixS */
int bsr,
fragS *opcode_frag,
unsigned int opcode_offset));
unsigned int opcode_offset,
unsigned int reloc_mode));
extern void cons_fix_new_ns32k PARAMS ((fragS *frag,
int where,