@B fix linking with baserel32 mode

This commit is contained in:
bebbo
2017-02-06 21:44:29 +01:00
parent 1d7d87ecf0
commit bc877e33c6
+72 -41
View File
@@ -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;