mirror of
https://frontier.innolan.net/github/amigaos-binutils.git
synced 2025-11-22 17:43:29 +00:00
(my_add_to): Replace boolean argument with a flags mask. Read addends as
requested in that mask either signed or unsigned. (amiga_perform_reloc): Test final relocation always signed. Request reading the addend of baserel relocations as unsigned value. Note that this is not always correct but should only be done for symbols that came from the same unit as the relocation. (aout_perform_reloc): Likewise.
This commit is contained in:
@ -111,7 +111,7 @@ bfd_boolean
|
|||||||
aout_amiga_final_link PARAMS ((bfd *, struct bfd_link_info *));
|
aout_amiga_final_link PARAMS ((bfd *, struct bfd_link_info *));
|
||||||
|
|
||||||
static bfd_reloc_status_type
|
static bfd_reloc_status_type
|
||||||
my_add_to PARAMS ((arelent *, PTR, int, bfd_boolean));
|
my_add_to PARAMS ((arelent *, PTR, int, int));
|
||||||
static bfd_reloc_status_type
|
static bfd_reloc_status_type
|
||||||
amiga_perform_reloc PARAMS ((bfd *, arelent *, PTR, sec_ptr, bfd *, char **));
|
amiga_perform_reloc PARAMS ((bfd *, arelent *, PTR, sec_ptr, bfd *, char **));
|
||||||
static bfd_reloc_status_type
|
static bfd_reloc_status_type
|
||||||
@ -120,6 +120,8 @@ static bfd_boolean
|
|||||||
amiga_reloc_link_order PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
amiga_reloc_link_order PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
||||||
struct bfd_link_order *));
|
struct bfd_link_order *));
|
||||||
|
|
||||||
|
enum { ADDEND_UNSIGNED=0x01, RELOC_SIGNED=0x02 };
|
||||||
|
|
||||||
|
|
||||||
/* This one is nearly identical to bfd_generic_get_relocated_section_contents
|
/* This one is nearly identical to bfd_generic_get_relocated_section_contents
|
||||||
in reloc.c */
|
in reloc.c */
|
||||||
@ -264,11 +266,10 @@ error_return:
|
|||||||
|
|
||||||
/* Add a value to a location */
|
/* Add a value to a location */
|
||||||
static bfd_reloc_status_type
|
static bfd_reloc_status_type
|
||||||
my_add_to (r, data, add, sign)
|
my_add_to (r, data, add, flags)
|
||||||
arelent *r;
|
arelent *r;
|
||||||
PTR data;
|
PTR data;
|
||||||
int add;
|
int add, flags;
|
||||||
bfd_boolean sign;
|
|
||||||
{
|
{
|
||||||
bfd_reloc_status_type ret=bfd_reloc_ok;
|
bfd_reloc_status_type ret=bfd_reloc_ok;
|
||||||
bfd_byte *p=((bfd_byte *)data)+r->address;
|
bfd_byte *p=((bfd_byte *)data)+r->address;
|
||||||
@ -279,9 +280,12 @@ my_add_to (r, data, add, sign)
|
|||||||
switch (r->howto->size)
|
switch (r->howto->size)
|
||||||
{
|
{
|
||||||
case 0: /* byte size */
|
case 0: /* byte size */
|
||||||
val = ((*p & 0xff) ^ 0x80) - 0x80 + add;
|
if ((flags & ADDEND_UNSIGNED) == 0)
|
||||||
|
val = ((*p & 0xff) ^ 0x80) - 0x80 + add;
|
||||||
|
else
|
||||||
|
val = (*p & 0xff) + add;
|
||||||
/* check for overflow */
|
/* check for overflow */
|
||||||
if (sign) {
|
if ((flags & RELOC_SIGNED) != 0) {
|
||||||
if (val<-0x80 || val>0x7f)
|
if (val<-0x80 || val>0x7f)
|
||||||
ret = bfd_reloc_overflow;
|
ret = bfd_reloc_overflow;
|
||||||
}
|
}
|
||||||
@ -294,9 +298,12 @@ my_add_to (r, data, add, sign)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* word size */
|
case 1: /* word size */
|
||||||
val = bfd_getb_signed_16 (p) + add;
|
if ((flags & ADDEND_UNSIGNED) == 0)
|
||||||
|
val = bfd_getb_signed_16 (p) + add;
|
||||||
|
else
|
||||||
|
val = bfd_getb16 (p) + add;
|
||||||
/* check for overflow */
|
/* check for overflow */
|
||||||
if (sign) {
|
if ((flags & RELOC_SIGNED) != 0) {
|
||||||
if (val<-0x8000 || val>0x7fff)
|
if (val<-0x8000 || val>0x7fff)
|
||||||
ret = bfd_reloc_overflow;
|
ret = bfd_reloc_overflow;
|
||||||
}
|
}
|
||||||
@ -350,8 +357,8 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
asymbol *sym; /* Reloc is relative to sym */
|
asymbol *sym; /* Reloc is relative to sym */
|
||||||
sec_ptr target_section; /* reloc is relative to this section */
|
sec_ptr target_section; /* reloc is relative to this section */
|
||||||
bfd_reloc_status_type ret;
|
bfd_reloc_status_type ret;
|
||||||
bfd_boolean copy,sign;
|
bfd_boolean copy;
|
||||||
int relocation;
|
int relocation,flags;
|
||||||
|
|
||||||
DPRINT(5,("Entering APR\nflavour is %d (amiga_flavour=%d, aout_flavour=%d)\n",
|
DPRINT(5,("Entering APR\nflavour is %d (amiga_flavour=%d, aout_flavour=%d)\n",
|
||||||
bfd_get_flavour (sec->owner), bfd_target_amiga_flavour,
|
bfd_get_flavour (sec->owner), bfd_target_amiga_flavour,
|
||||||
@ -384,7 +391,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
return bfd_reloc_undefined;
|
return bfd_reloc_undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation=0; sign=FALSE; copy=FALSE; ret=bfd_reloc_ok;
|
relocation=0; flags=RELOC_SIGNED; copy=FALSE; ret=bfd_reloc_ok;
|
||||||
|
|
||||||
DPRINT(5,("%s: size=%u\n",r->howto->name,bfd_get_reloc_size(r->howto)));
|
DPRINT(5,("%s: size=%u\n",r->howto->name,bfd_get_reloc_size(r->howto)));
|
||||||
switch (r->howto->type)
|
switch (r->howto->type)
|
||||||
@ -481,8 +488,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
relocation = sym->value + target_section->output_offset
|
relocation = sym->value + target_section->output_offset
|
||||||
- (AMIGA_DATA(target_section->output_section->owner))->a4init
|
- (AMIGA_DATA(target_section->output_section->owner))->a4init
|
||||||
+ r->addend;
|
+ r->addend;
|
||||||
copy=FALSE;
|
flags|=ADDEND_UNSIGNED;
|
||||||
sign=TRUE;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -494,7 +500,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
|
|
||||||
/* Add in relocation */
|
/* Add in relocation */
|
||||||
if (relocation!=0)
|
if (relocation!=0)
|
||||||
ret = my_add_to (r, data, relocation, sign);
|
ret = my_add_to (r, data, relocation, flags);
|
||||||
|
|
||||||
if (copy) /* Copy reloc to output section */
|
if (copy) /* Copy reloc to output section */
|
||||||
{
|
{
|
||||||
@ -522,8 +528,8 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
asymbol *sym; /* Reloc is relative to sym */
|
asymbol *sym; /* Reloc is relative to sym */
|
||||||
sec_ptr target_section; /* reloc is relative to this section */
|
sec_ptr target_section; /* reloc is relative to this section */
|
||||||
bfd_reloc_status_type ret;
|
bfd_reloc_status_type ret;
|
||||||
bfd_boolean copy,sign;
|
bfd_boolean copy;
|
||||||
int relocation;
|
int relocation,flags;
|
||||||
|
|
||||||
DPRINT(5,("Entering aout_perf_reloc\n"));
|
DPRINT(5,("Entering aout_perf_reloc\n"));
|
||||||
|
|
||||||
@ -552,7 +558,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
target_section=bfd_abs_section_ptr;
|
target_section=bfd_abs_section_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation=0; sign=FALSE; copy=FALSE; ret=bfd_reloc_ok;
|
relocation=0; flags=RELOC_SIGNED; copy=FALSE; ret=bfd_reloc_ok;
|
||||||
|
|
||||||
DPRINT(10,("RELOC: %s: size=%u\n",r->howto->name,bfd_get_reloc_size(r->howto)));
|
DPRINT(10,("RELOC: %s: size=%u\n",r->howto->name,bfd_get_reloc_size(r->howto)));
|
||||||
switch (r->howto->type)
|
switch (r->howto->type)
|
||||||
@ -637,7 +643,6 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
relocation = sym->value + target_section->output_offset
|
relocation = sym->value + target_section->output_offset
|
||||||
- sec->output_offset;
|
- sec->output_offset;
|
||||||
}
|
}
|
||||||
sign=TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case H_SD16: /* baserel */
|
case H_SD16: /* baserel */
|
||||||
@ -682,15 +687,12 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
into the opcode */
|
into the opcode */
|
||||||
if (target_section->index == 2)
|
if (target_section->index == 2)
|
||||||
relocation -= adata(abfd).datasec->_raw_size;
|
relocation -= adata(abfd).datasec->_raw_size;
|
||||||
|
|
||||||
copy = FALSE;
|
|
||||||
sign = TRUE;
|
|
||||||
|
|
||||||
DPRINT(20,("symbol=%s (0x%lx)\nsection %s (0x%lx; %s; output=0x%lx)"
|
DPRINT(20,("symbol=%s (0x%lx)\nsection %s (0x%lx; %s; output=0x%lx)"
|
||||||
"\nrelocation @0x%lx\n", sym->name, sym->value,
|
"\nrelocation @0x%lx\n", sym->name, sym->value,
|
||||||
target_section->name, target_section,
|
target_section->name, target_section,
|
||||||
target_section->owner->filename, target_section->output_offset,
|
target_section->owner->filename, target_section->output_offset,
|
||||||
r->address));
|
r->address));
|
||||||
|
flags|=ADDEND_UNSIGNED;
|
||||||
}
|
}
|
||||||
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||||
target_section->output_section->name,
|
target_section->output_section->name,
|
||||||
@ -706,7 +708,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
|||||||
|
|
||||||
/* Add in relocation */
|
/* Add in relocation */
|
||||||
if (relocation!=0)
|
if (relocation!=0)
|
||||||
ret = my_add_to (r, data, relocation, sign);
|
ret = my_add_to (r, data, relocation, flags);
|
||||||
|
|
||||||
if (copy) /* Copy reloc to output section */
|
if (copy) /* Copy reloc to output section */
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user