2
0
mirror of https://frontier.innolan.net/github/amigaos-binutils.git synced 2025-11-21 19:55:04 +00:00

Add support for relocation hunks with short (16bit) data.

* bfd/amigaos.c (write_words): Add protototype.
  (write_words): New function to write 16bit words.
  (amiga_write_section_contents): Use write_words to write 16bit relocs.
This commit is contained in:
Gunther Nikl
2015-05-15 19:35:50 +00:00
parent 0c09613c8f
commit 4e19233665

View File

@ -181,6 +181,8 @@ static bfd_boolean amiga_mkobject PARAMS ((bfd *));
static bfd_boolean amiga_mkarchive PARAMS ((bfd *)); static bfd_boolean amiga_mkarchive PARAMS ((bfd *));
static bfd_boolean write_longs PARAMS ((const unsigned long *, unsigned long, static bfd_boolean write_longs PARAMS ((const unsigned long *, unsigned long,
bfd *)); bfd *));
static bfd_boolean write_words PARAMS ((const unsigned long *, unsigned long,
bfd *));
static long determine_datadata_relocs PARAMS ((bfd *, sec_ptr)); static long determine_datadata_relocs PARAMS ((bfd *, sec_ptr));
static void remove_section_index PARAMS ((sec_ptr, int *)); static void remove_section_index PARAMS ((sec_ptr, int *));
static bfd_boolean amiga_write_object_contents PARAMS ((bfd *)); static bfd_boolean amiga_write_object_contents PARAMS ((bfd *));
@ -1327,6 +1329,26 @@ write_longs (in, nb, abfd)
return TRUE; return TRUE;
} }
static bfd_boolean
write_words (in, nb, abfd)
const unsigned long *in;
unsigned long nb;
bfd *abfd;
{
unsigned char out[10*2];
unsigned long i;
while (nb)
{
for (i=0; i<nb && i<10; in++,i++)
bfd_putb16 (in[0], &out[i*2]);
if (bfd_bwrite ((PTR)out, 2*i, abfd) != 2*i)
return FALSE;
nb -= i;
}
return TRUE;
}
static long static long
determine_datadata_relocs (abfd, section) determine_datadata_relocs (abfd, section)
bfd *abfd ATTRIBUTE_UNUSED; bfd *abfd ATTRIBUTE_UNUSED;
@ -2021,6 +2043,7 @@ amiga_write_section_contents (abfd, section, data_sec, datadata_relocs,
if (reloc_count > 0) { if (reloc_count > 0) {
/* Sample every reloc type */ /* Sample every reloc type */
for (i = 0; i < NB_RELOC_TYPES; i++) { for (i = 0; i < NB_RELOC_TYPES; i++) {
int rel32 = reloc_types[i] != HUNK_RELOC32SHORT && reloc_types[i] != HUNK_RELRELOC32 ? TRUE : FALSE;
int written = FALSE; int written = FALSE;
for (j = 0; j <= max_hunk; j++) { for (j = 0; j <= max_hunk; j++) {
long relocs; long relocs;
@ -2037,8 +2060,14 @@ amiga_write_section_contents (abfd, section, data_sec, datadata_relocs,
n[0] = relocs; n[0] = relocs;
n[1] = j; n[1] = j;
if (rel32) {
if (!write_longs (n, 2, abfd)) if (!write_longs (n, 2, abfd))
return FALSE; return FALSE;
}
else {
if (!write_words (n, 2, abfd))
return FALSE;
}
reloc_counts[i+(j*NB_RELOC_TYPES)] -= relocs; reloc_counts[i+(j*NB_RELOC_TYPES)] -= relocs;
reloc_count -= relocs; reloc_count -= relocs;
@ -2067,8 +2096,14 @@ amiga_write_section_contents (abfd, section, data_sec, datadata_relocs,
#endif #endif
if (jj == j && i == determine_type(r)) { if (jj == j && i == determine_type(r)) {
section->orelocation[k] = NULL; section->orelocation[k] = NULL;
if (rel32) {
if (!write_longs (&r->address, 1, abfd)) if (!write_longs (&r->address, 1, abfd))
return FALSE; return FALSE;
}
else {
if (!write_words (&r->address, 1, abfd))
return FALSE;
}
if (--relocs == 0) if (--relocs == 0)
break; break;
} }
@ -2076,9 +2111,17 @@ amiga_write_section_contents (abfd, section, data_sec, datadata_relocs,
} }
} }
/* write a zero to finish the relocs */ /* write a zero to finish the relocs */
if (written && !write_longs (&zero, 1, abfd)) if (written) {
if (rel32 || (bfd_tell (abfd) & 2) == 0) {
if (!write_longs (&zero, 1, abfd))
return FALSE; return FALSE;
} }
else {
if (!write_words (&zero, 1, abfd))
return FALSE;
}
}
}
} }
bfd_release (abfd, reloc_counts); bfd_release (abfd, reloc_counts);