#include "as.h"
#include "sections.h"
#include "obstack.h"
#include "frags.h"
#include "fixes.h"
#include "symbols.h"
#include "input-scrub.h"
#include <mach-o/x86_64/reloc.h>
static fixS *
fix_new_internal (fragS *frag,
int where,
int size,
symbolS *add_symbol,
symbolS *sub_symbol,
signed_target_addr_t offset,
int pcrel,
int pcrel_reloc,
int r_type)
{
struct fix *fixP;
fixP = (struct fix *)obstack_alloc(¬es, sizeof(struct fix));
fixP->fx_frag = frag;
fixP->fx_where = where;
fixP->fx_size = size;
fixP->fx_addsy = add_symbol;
fixP->fx_subsy = sub_symbol;
fixP->fx_offset = offset;
fixP->fx_pcrel = pcrel;
fixP->fx_pcrel_reloc = pcrel_reloc;
fixP->fx_r_type = r_type;
fixP->fx_sectdiff_divide_by_two = 0;
#if defined(I386) && defined(ARCH64)
if(fixP->fx_r_type == X86_64_RELOC_SIGNED){
switch(offset){
case -1:
fixP->fx_r_type = X86_64_RELOC_SIGNED_1;
break;
case -2:
fixP->fx_r_type = X86_64_RELOC_SIGNED_2;
break;
case -4:
fixP->fx_r_type = X86_64_RELOC_SIGNED_4;
break;
default:
break;
}
}
if(fixP->fx_r_type == X86_64_RELOC_GOT ||
fixP->fx_r_type == X86_64_RELOC_GOT_LOAD){
fixP->fx_pcrel = TRUE;
fixP->fx_pcrel_reloc = TRUE;
}
fixP->fx_localsy = symbol_new("L0\002", N_SECT, frchain_now->frch_nsect,
0, where, frag);
symbol_assign_index(fixP->fx_localsy);
#endif
as_file_and_line (&fixP->file, &fixP->line);
fixP->fx_next = frchain_now->frch_fix_root;
frchain_now->frch_fix_root = fixP;
return fixP;
}
#include "expr.h"
fixS *
fix_new(
fragS *frag,
int where,
int size,
symbolS *add_symbol,
symbolS *sub_symbol,
signed_target_addr_t
offset,
int pcrel,
int pcrel_reloc,
int r_type)
{
return fix_new_internal (frag, where, size, add_symbol,
sub_symbol, offset, pcrel, pcrel_reloc, r_type);
}
typedef int RELOC_ENUM;
#define X_op X_seg
#define X_op_symbol X_add_symbol
fixS *
fix_new_exp (fragS *frag,
int where,
int size,
expressionS *exp,
int pcrel,
int pcrel_reloc,
RELOC_ENUM r_type )
{
symbolS *add = NULL;
symbolS *sub = NULL;
offsetT off = 0;
switch (exp->X_op)
{
#ifdef NOTYET
case O_absent:
break;
case O_register:
as_bad (_("register value used as expression"));
break;
case O_add:
{
symbolS *stmp = make_expr_symbol (exp);
exp->X_op = O_symbol;
exp->X_op_symbol = 0;
exp->X_add_symbol = stmp;
exp->X_add_number = 0;
return fix_new_exp (frag, where, size, exp, pcrel, r_type);
}
case O_symbol_rva:
add = exp->X_add_symbol;
off = exp->X_add_number;
#if defined(BFD_ASSEMBLER)
r_type = BFD_RELOC_RVA;
#else
#if defined(TC_RVA_RELOC)
r_type = TC_RVA_RELOC;
#else
as_fatal (_("rva not supported"));
#endif
#endif
break;
case O_uminus:
sub = exp->X_add_symbol;
off = exp->X_add_number;
break;
case O_subtract:
sub = exp->X_op_symbol;
#endif
case O_symbol:
add = exp->X_add_symbol;
case O_constant:
off = exp->X_add_number;
break;
default:
add = make_expr_symbol (exp);
break;
}
return fix_new_internal (frag, where, size, add, sub, off, pcrel, pcrel_reloc, r_type);
}