mirror of
https://frontier.innolan.net/github/amigaos-binutils.git
synced 2026-09-12 12:41:34 +00:00
@B fix linking with baserel32 mode
This commit is contained in:
+72
-41
@@ -96,6 +96,8 @@ int amiga_attribute = 0;
|
||||
/* This one is used to indicate base-relative linking */
|
||||
int amiga_base_relative = 0;
|
||||
|
||||
static int amiga_base_relative32 = 0;
|
||||
|
||||
/* This one is used to indicate -resident linking */
|
||||
int amiga_resident = 0;
|
||||
|
||||
@@ -147,7 +149,7 @@ get_relocated_section_contents (abfd, link_info, link_order, data,
|
||||
bfd_reloc_status_type (*reloc_func)(bfd *, arelent *, PTR, sec_ptr,
|
||||
bfd *, char **);
|
||||
|
||||
DPRINT(5,("Entering get_rel_sec_cont\n"));
|
||||
DPRINT(5,("\n----\nEntering get_rel_sec_cont\n"));
|
||||
|
||||
if (reloc_size < 0)
|
||||
goto error_return;
|
||||
@@ -191,7 +193,7 @@ get_relocated_section_contents (abfd, link_info, link_order, data,
|
||||
{
|
||||
arelent **parent;
|
||||
|
||||
DPRINT(5,("reloc_count=%ld\n",reloc_count));
|
||||
DPRINT(5,("doing relocs section=%s at %p, output=%s reloc_count=%ld\n", input_section->name, reloc_vector, input_section->output_section->name, reloc_count));
|
||||
|
||||
for (parent = reloc_vector; *parent != (arelent *) NULL;
|
||||
parent++)
|
||||
@@ -199,8 +201,10 @@ get_relocated_section_contents (abfd, link_info, link_order, data,
|
||||
char *error_message = (char *) NULL;
|
||||
bfd_reloc_status_type r;
|
||||
|
||||
DPRINT(5,("Applying a reloc\nparent=%lx, reloc_vector=%lx, "
|
||||
"*parent=%lx\n",parent,reloc_vector,*parent));
|
||||
DPRINT(5,("apply reloc: %s in %s type=%d\n",
|
||||
(*((*parent)->sym_ptr_ptr))->name,
|
||||
(*((*parent)->sym_ptr_ptr))->section->name,
|
||||
(*parent)->howto->type));
|
||||
r=(*reloc_func) (input_bfd,
|
||||
*parent,
|
||||
(PTR) data,
|
||||
@@ -276,8 +280,9 @@ my_add_to (r, data, add, flags)
|
||||
bfd_reloc_status_type ret=bfd_reloc_ok;
|
||||
bfd_byte *p=((bfd_byte *)data)+r->address;
|
||||
int val;
|
||||
asymbol *sym=*(r->sym_ptr_ptr);
|
||||
|
||||
DPRINT(5,("Entering add_value\n"));
|
||||
DPRINT(5,("Entering add_value for %s with add: %x\n", sym->name, add));
|
||||
|
||||
switch (r->howto->size)
|
||||
{
|
||||
@@ -390,7 +395,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
bfd_boolean copy;
|
||||
int relocation,flags;
|
||||
|
||||
DPRINT(5,("Entering APR\nflavour is %d (amiga_flavour=%d, aout_flavour=%d)\n",
|
||||
DPRINT(5,("\nEntering APR\nflavour is %d (amiga_flavour=%d, aout_flavour=%d)\n",
|
||||
bfd_get_flavour (sec->owner), bfd_target_amiga_flavour,
|
||||
bfd_target_aout_flavour));
|
||||
|
||||
@@ -409,9 +414,9 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
sym=*(r->sym_ptr_ptr);
|
||||
|
||||
/* FIXME: XXX */
|
||||
if (0 && sym->udata.p)
|
||||
sym = ((struct generic_link_hash_entry *) sym->udata.p)->sym;
|
||||
// ?? /* FIXME: XXX */
|
||||
// if (0 && sym->udata.p)
|
||||
// sym = ((struct generic_link_hash_entry *) sym->udata.p)->sym;
|
||||
|
||||
target_section=sym->section;
|
||||
|
||||
@@ -423,7 +428,14 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
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,("amigaRELOC: %s: size=%u\n",r->howto->name,bfd_get_reloc_size(r->howto)));
|
||||
DPRINT(10,("target=%s, target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||
target_section->name,
|
||||
target_section->output_section->name,
|
||||
target_section->output_section,
|
||||
sec->output_section->name,
|
||||
sec->output_section,
|
||||
sym->name));
|
||||
switch (r->howto->type)
|
||||
{
|
||||
case H_ABS32:
|
||||
@@ -441,6 +453,8 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
relocation=0;
|
||||
copy=TRUE;
|
||||
}
|
||||
if (amiga_base_relative32 && 0 == strcmp("___a4_init", sym->name))
|
||||
relocation -= (AMIGA_DATA(target_section->output_section->owner))->a4init;
|
||||
break;
|
||||
|
||||
case H_PC8: /* pcrel */
|
||||
@@ -468,6 +482,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
case H_SD8: /* baserel */
|
||||
case H_SD16:
|
||||
case H_SD32:
|
||||
amiga_base_relative32 |= r->howto->type == H_SD32;
|
||||
/* Relocs are always relative to the symbol ___a4_init */
|
||||
/* Relocs to .bss section are converted to a reloc to .data section,
|
||||
since .bss section contains only COMMON sections...... and should
|
||||
@@ -489,12 +504,13 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
else
|
||||
{
|
||||
amiga_update_target_section (target_section);
|
||||
|
||||
relocation = sym->value + target_section->output_offset
|
||||
- (AMIGA_DATA(target_section->output_section->owner))->a4init
|
||||
+ r->addend;
|
||||
relocation = sym->value + target_section->output_offset + r->addend;
|
||||
flags|=ADDEND_UNSIGNED;
|
||||
}
|
||||
|
||||
if (amiga_base_relative && r->howto->type != H_SD32)
|
||||
relocation -= (AMIGA_DATA(target_section->output_section->owner))->a4init;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -509,7 +525,7 @@ amiga_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
if (copy) /* Copy reloc to output section */
|
||||
{
|
||||
DPRINT(5,("Copying reloc\n"));
|
||||
DPRINT(5,("Copying reloc to %s:%s at %d\n", sec->output_section->name, sym->name, r->address));
|
||||
target_section=sec->output_section;
|
||||
r->address+=sec->output_offset;
|
||||
target_section->orelocation[target_section->reloc_count++]=r;
|
||||
@@ -564,7 +580,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
bfd_boolean copy;
|
||||
int relocation,flags;
|
||||
|
||||
DPRINT(5,("Entering aout_perf_reloc\n"));
|
||||
DPRINT(5,("\nEntering aout_perf_reloc\n"));
|
||||
|
||||
/* If obfd==NULL: Apply the reloc, if possible. */
|
||||
/* Else: Modify it and return */
|
||||
@@ -579,6 +595,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
/* Try to apply the reloc */
|
||||
|
||||
sym=*(r->sym_ptr_ptr);
|
||||
|
||||
target_section=sym->section;
|
||||
|
||||
if (bfd_is_und_section(target_section)) /* Error */
|
||||
@@ -593,7 +610,13 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
relocation=0; flags=RELOC_SIGNED; copy=FALSE; ret=bfd_reloc_ok;
|
||||
|
||||
DPRINT(10,("RELOC: %s, %d: size=%u\n",r->howto->name,r->howto->type,bfd_get_reloc_size(r->howto)));
|
||||
DPRINT(10,("aoutRELOC: %s, %d: size=%u\n",r->howto->name,r->howto->type,bfd_get_reloc_size(r->howto)));
|
||||
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||
target_section->output_section->name,
|
||||
target_section->output_section,
|
||||
sec->output_section->name,
|
||||
sec->output_section,
|
||||
sym->name));
|
||||
switch (r->howto->type)
|
||||
{
|
||||
case H_ABS8: /* 8/16 bit reloc, pc relative or absolute */
|
||||
@@ -612,27 +635,24 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
// SBF: the if statement has been fixed, but the linker does no longer work.
|
||||
// if ((target_section->output_section->flags&SEC_DATA)!=0)
|
||||
// I replaced it with the old (obvious bogus) statement
|
||||
// TODO: a better fix
|
||||
if (target_section->output_section->flags & (SEC_DATA != 0))
|
||||
// TODO: a better fix?
|
||||
//if (target_section->output_section->flags & (SEC_DATA != 0))
|
||||
if (amiga_base_relative)
|
||||
goto baserel; /* Dirty, but no code duplication.. */
|
||||
bfd_msg ("pc relative relocation out-of-range in section %s. "
|
||||
"Relocation was to symbol %s",sec->name,sym->name);
|
||||
DPRINT(10,("Section %s, target %s: Reloc out-of-range...not same "
|
||||
"section, aout_perf\nsec->out=%s, target->out=%s, "
|
||||
"offset=%lx\n",sec->name,target_section->name,
|
||||
sec->output_section->name,
|
||||
target_section->output_section->name,r->address));
|
||||
ret=bfd_reloc_outofrange;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Same section, this is a pc relative hunk... */
|
||||
DPRINT(5,("Reloc to same section...\n"));
|
||||
relocation=-(r->address+sec->output_offset);
|
||||
relocation=-(long)(r->address+sec->output_offset);
|
||||
}
|
||||
break;
|
||||
|
||||
case H_ABS32: /* 32 bit reloc, pc relative or absolute */
|
||||
DPRINT(5, ("32 bit reloc, pc relative or absolute: %s=%d, target_sec_offset=%d, add=%d\n", sym->name, sym->value, target_section->output_offset, r->addend));
|
||||
if (bfd_is_abs_section(target_section)) /* Ref to absolute hunk */
|
||||
relocation=sym->value;
|
||||
else if (bfd_is_com_section(target_section)) /* ref to common */
|
||||
@@ -643,16 +663,29 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
else
|
||||
{
|
||||
if (amiga_base_relative)
|
||||
aout_update_target_section (target_section);
|
||||
{
|
||||
aout_update_target_section (target_section);
|
||||
}
|
||||
relocation=0;
|
||||
copy=TRUE;
|
||||
copy=!amiga_base_relative32;
|
||||
}
|
||||
if (amiga_base_relative32)
|
||||
{
|
||||
relocation = sym->value + target_section->output_offset;
|
||||
flags|=ADDEND_UNSIGNED;
|
||||
copy = sec->name == target_section->name; // .text->.text or .data->.data
|
||||
|
||||
if (copy)
|
||||
{
|
||||
relocation = 0;
|
||||
}
|
||||
else if(0 == strcmp("___a4_init", sym->name))
|
||||
{
|
||||
relocation = - (long)(AMIGA_DATA(target_section->output_section->owner))->a4init;
|
||||
copy=TRUE;
|
||||
}
|
||||
}
|
||||
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||
target_section->output_section->name,
|
||||
target_section->output_section,
|
||||
sec->output_section->name,
|
||||
sec->output_section,
|
||||
sym->name));
|
||||
break;
|
||||
|
||||
case H_PC8: /* pcrel */
|
||||
@@ -663,12 +696,6 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
relocation=sym->value;
|
||||
else if (sec->output_section!=target_section->output_section) /* Error */
|
||||
{
|
||||
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||
target_section->output_section->name,
|
||||
target_section->output_section,
|
||||
sec->output_section->name,
|
||||
sec->output_section,
|
||||
sym->name));
|
||||
DPRINT(5,("pc relative, but out-of-range\n"));
|
||||
ret=bfd_reloc_outofrange;
|
||||
}
|
||||
@@ -681,6 +708,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
case H_SD16: /* baserel */
|
||||
case H_SD32:
|
||||
amiga_base_relative32 |= r->howto->type == H_SD32;
|
||||
baserel:
|
||||
DPRINT(10,("baserel: %s\n", sym->name));
|
||||
/* We use the symbol ___a4_init as base */
|
||||
@@ -708,8 +736,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
{
|
||||
aout_update_target_section (target_section);
|
||||
|
||||
relocation = sym->value + target_section->output_offset
|
||||
- (AMIGA_DATA(target_section->output_section->owner))->a4init;
|
||||
relocation = sym->value + target_section->output_offset;
|
||||
/* if the symbol is in .bss, subtract the offset that gas has put
|
||||
into the opcode */
|
||||
if (target_section->index == 2)
|
||||
@@ -721,6 +748,10 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
r->address));
|
||||
flags|=ADDEND_UNSIGNED;
|
||||
}
|
||||
|
||||
if (amiga_base_relative && r->howto->type != H_SD32 && r->howto->type != H_ABS32)
|
||||
relocation -= (AMIGA_DATA(target_section->output_section->owner))->a4init;
|
||||
|
||||
DPRINT(10,("target->out=%s(%lx), sec->out=%s(%lx), symbol=%s\n",
|
||||
target_section->output_section->name,
|
||||
target_section->output_section,
|
||||
@@ -741,7 +772,7 @@ aout_perform_reloc (abfd, r, data, sec, obfd, error_message)
|
||||
|
||||
if (copy) /* Copy reloc to output section */
|
||||
{
|
||||
DPRINT(5,("Copying reloc\n"));
|
||||
DPRINT(5,("Copying reloc to %s:%s at %d\n", sec->output_section->name, sym->name, r->address));
|
||||
target_section=sec->output_section;
|
||||
r->address+=sec->output_offset;
|
||||
target_section->orelocation[target_section->reloc_count++]=r;
|
||||
|
||||
Reference in New Issue
Block a user