Replaced fixed size array for hi16 relocations with a linked list.
This commit is contained in:
parent
5e424a1b6b
commit
45cac0cb84
2 changed files with 278 additions and 83 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Mon Nov 16 10:57:06 1998 Nick Clifton <nickc@cygnus.com>
|
||||||
|
|
||||||
|
* elf32-v850.c (hi16s_location): Replaced fixed size array with
|
||||||
|
linked list.
|
||||||
|
|
||||||
Sun Nov 15 20:28:25 1998 Richard Henderson <rth@cygnus.com>
|
Sun Nov 15 20:28:25 1998 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
* elf64-alpha.c (elf64_alpha_relax_section): Search for the proper
|
* elf64-alpha.c (elf64_alpha_relax_section): Search for the proper
|
||||||
|
|
348
bfd/elf32-v850.c
348
bfd/elf32-v850.c
|
@ -51,7 +51,7 @@ static bfd_reloc_status_type v850_elf_perform_relocation
|
||||||
static boolean v850_elf_check_relocs
|
static boolean v850_elf_check_relocs
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
|
PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
|
||||||
static void remember_hi16s_reloc
|
static void remember_hi16s_reloc
|
||||||
PARAMS ((bfd_vma, bfd_byte *));
|
PARAMS ((bfd *, bfd_vma, bfd_byte *));
|
||||||
static bfd_byte * find_remembered_hi16s_reloc
|
static bfd_byte * find_remembered_hi16s_reloc
|
||||||
PARAMS ((bfd_vma addend));
|
PARAMS ((bfd_vma addend));
|
||||||
static bfd_reloc_status_type v850_elf_final_link_relocate
|
static bfd_reloc_status_type v850_elf_final_link_relocate
|
||||||
|
@ -436,6 +436,36 @@ static reloc_howto_type v850_elf_howto_table[] =
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
/* GNU extension to record C++ vtable hierarchy */
|
||||||
|
HOWTO (R_V850_GNU_VTINHERIT, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
NULL, /* special_function */
|
||||||
|
"R_V850_GNU_VTINHERIT", /* name */
|
||||||
|
false, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* GNU extension to record C++ vtable member usage */
|
||||||
|
HOWTO (R_V850_GNU_VTENTRY, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
0, /* bitsize */
|
||||||
|
false, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_dont, /* complain_on_overflow */
|
||||||
|
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
|
||||||
|
"R_V850_GNU_VTENTRY", /* name */
|
||||||
|
false, /* partial_inplace */
|
||||||
|
0, /* src_mask */
|
||||||
|
0, /* dst_mask */
|
||||||
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Map BFD reloc types to V850 ELF reloc types. */
|
/* Map BFD reloc types to V850 ELF reloc types. */
|
||||||
|
@ -473,6 +503,9 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
|
||||||
{ BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
|
{ BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
|
||||||
{ BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
|
{ BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
{ BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT },
|
||||||
|
{ BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -596,6 +629,20 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* This relocation describes the C++ object vtable hierarchy.
|
||||||
|
Reconstruct it for later use during GC. */
|
||||||
|
case R_V850_GNU_VTINHERIT:
|
||||||
|
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* This relocation describes which C++ vtable entries are actually
|
||||||
|
used. Record for later use during GC. */
|
||||||
|
case R_V850_GNU_VTENTRY:
|
||||||
|
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
case R_V850_SDA_16_16_SPLIT_OFFSET:
|
case R_V850_SDA_16_16_SPLIT_OFFSET:
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
@ -688,56 +735,46 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct hi16s_location
|
||||||
{
|
{
|
||||||
bfd_vma addend;
|
bfd_vma addend;
|
||||||
bfd_byte * address;
|
bfd_byte * address;
|
||||||
unsigned long counter;
|
unsigned long counter;
|
||||||
|
struct hi16s_location * next;
|
||||||
}
|
}
|
||||||
hi16s_location;
|
hi16s_location;
|
||||||
|
|
||||||
static hi16s_location previous_hi16s[ 10 ]; /* XXX is this enough ? */
|
static hi16s_location * previous_hi16s;
|
||||||
static unsigned long hi16s_counter;
|
static hi16s_location * free_hi16s;
|
||||||
|
static unsigned long hi16s_counter;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remember_hi16s_reloc (addend, address)
|
remember_hi16s_reloc (abfd, addend, address)
|
||||||
|
bfd * abfd;
|
||||||
bfd_vma addend;
|
bfd_vma addend;
|
||||||
bfd_byte * address;
|
bfd_byte * address;
|
||||||
{
|
{
|
||||||
hi16s_location * oldest = NULL;
|
hi16s_location * entry = NULL;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Find a free slot. */
|
/* Find a free structure. */
|
||||||
for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
|
if (free_hi16s == NULL)
|
||||||
{
|
free_hi16s = (hi16s_location *) bfd_zalloc (abfd, sizeof (* free_hi16s));
|
||||||
hi16s_location * entry = previous_hi16s + i;
|
|
||||||
|
|
||||||
if (entry->addend == 0 && entry->address == 0)
|
entry = free_hi16s;
|
||||||
{
|
free_hi16s = free_hi16s->next;
|
||||||
/* Use this entry. */
|
|
||||||
oldest = entry;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remember the least recently added entry. */
|
entry->addend = addend;
|
||||||
if (oldest == NULL || oldest->counter > entry->counter)
|
entry->address = address;
|
||||||
oldest = entry;
|
entry->counter = hi16s_counter ++;
|
||||||
}
|
entry->next = previous_hi16s;
|
||||||
|
previous_hi16s = entry;
|
||||||
oldest->addend = addend;
|
|
||||||
oldest->address = address;
|
|
||||||
oldest->counter = hi16s_counter ++;
|
|
||||||
|
|
||||||
/* Cope with wrap around of our counter. */
|
/* Cope with wrap around of our counter. */
|
||||||
if (hi16s_counter == 0)
|
if (hi16s_counter == 0)
|
||||||
{
|
{
|
||||||
/* XXX - Assume that all counter entries differ only in their low 16 bits. */
|
/* XXX - Assume that all counter entries differ only in their low 16 bits. */
|
||||||
for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
|
for (entry = previous_hi16s; entry != NULL; entry = entry->next)
|
||||||
{
|
entry->counter &= 0xffff;
|
||||||
hi16s_location * entry = previous_hi16s + i;
|
|
||||||
|
|
||||||
entry->counter &= 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
hi16s_counter = 0x10000;
|
hi16s_counter = 0x10000;
|
||||||
}
|
}
|
||||||
|
@ -750,36 +787,50 @@ find_remembered_hi16s_reloc (addend)
|
||||||
bfd_vma addend;
|
bfd_vma addend;
|
||||||
{
|
{
|
||||||
hi16s_location * match = NULL;
|
hi16s_location * match = NULL;
|
||||||
|
hi16s_location * entry;
|
||||||
|
hi16s_location * previous = NULL;
|
||||||
|
hi16s_location * prev;
|
||||||
int i;
|
int i;
|
||||||
|
bfd_byte * addr;
|
||||||
|
|
||||||
/* Search the table. Record the most recent entry that matches. */
|
/* Search the table. Record the most recent entry that matches. */
|
||||||
for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
|
for (entry = previous_hi16s; entry; entry = entry->next)
|
||||||
{
|
{
|
||||||
hi16s_location * entry = previous_hi16s + i;
|
|
||||||
|
|
||||||
if (entry->addend == addend)
|
if (entry->addend == addend)
|
||||||
{
|
{
|
||||||
if (match == NULL || match->counter < entry->counter)
|
if (match == NULL || match->counter < entry->counter)
|
||||||
match = entry;
|
{
|
||||||
|
previous = prev;
|
||||||
|
match = entry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match != NULL)
|
if (match == NULL)
|
||||||
{
|
return NULL;
|
||||||
bfd_byte * addr;
|
|
||||||
|
|
||||||
/* Empty the table entry. */
|
/* Extract the address. */
|
||||||
match->addend = 0;
|
addr = match->address;
|
||||||
|
|
||||||
addr = match->address;
|
/* Attach the entry to the free list. */
|
||||||
match->address = NULL;
|
if (previous)
|
||||||
|
previous->next = match->next;
|
||||||
|
else
|
||||||
|
previous_hi16s = match->next;
|
||||||
|
|
||||||
return addr;
|
match->next = free_hi16s->next;
|
||||||
}
|
free_hi16s = match;
|
||||||
|
|
||||||
return NULL;
|
match->addend = 0;
|
||||||
|
match->address = NULL;
|
||||||
|
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: The code here probably ought to be removed and the code in reloc.c
|
||||||
|
allowed to do its stuff instead. At least for most of the relocs, anwyay. */
|
||||||
static bfd_reloc_status_type
|
static bfd_reloc_status_type
|
||||||
v850_elf_perform_relocation (abfd, r_type, addend, address)
|
v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
bfd * abfd;
|
bfd * abfd;
|
||||||
|
@ -788,6 +839,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
bfd_byte * address;
|
bfd_byte * address;
|
||||||
{
|
{
|
||||||
unsigned long insn;
|
unsigned long insn;
|
||||||
|
bfd_signed_vma saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
|
@ -796,12 +848,11 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
return bfd_reloc_notsupported;
|
return bfd_reloc_notsupported;
|
||||||
|
|
||||||
case R_V850_32:
|
case R_V850_32:
|
||||||
addend += bfd_get_32 (abfd, address);
|
|
||||||
bfd_put_32 (abfd, addend, address);
|
bfd_put_32 (abfd, addend, address);
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
case R_V850_22_PCREL:
|
case R_V850_22_PCREL:
|
||||||
if (addend > 0x1fffff || addend < -0x200000)
|
if (saddend > 0x1fffff || saddend < -0x200000)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if ((addend % 2) != 0)
|
if ((addend % 2) != 0)
|
||||||
|
@ -814,7 +865,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
case R_V850_9_PCREL:
|
case R_V850_9_PCREL:
|
||||||
if (addend > 0xff || addend < -0x100)
|
if (saddend > 0xff || saddend < -0x100)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if ((addend % 2) != 0)
|
if ((addend % 2) != 0)
|
||||||
|
@ -833,13 +884,13 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
|
|
||||||
case R_V850_HI16_S:
|
case R_V850_HI16_S:
|
||||||
/* Remember where this relocation took place. */
|
/* Remember where this relocation took place. */
|
||||||
remember_hi16s_reloc (addend, address);
|
remember_hi16s_reloc (abfd, addend, address);
|
||||||
|
|
||||||
addend += (bfd_get_16 (abfd, address) << 16);
|
addend += (bfd_get_16 (abfd, address) << 16);
|
||||||
addend = (addend >> 16) + ((addend & 0x8000) != 0);
|
addend = (addend >> 16) + ((addend & 0x8000) != 0);
|
||||||
|
|
||||||
/* This relocation cannot overflow. */
|
/* This relocation cannot overflow. */
|
||||||
if (addend > 0x7fff || addend < -0x8000)
|
if (addend > 0x7fff)
|
||||||
addend = 0;
|
addend = 0;
|
||||||
|
|
||||||
insn = addend;
|
insn = addend;
|
||||||
|
@ -1025,7 +1076,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
case R_V850_8:
|
case R_V850_8:
|
||||||
addend += (char) bfd_get_8 (abfd, address);
|
addend += (char) bfd_get_8 (abfd, address);
|
||||||
|
|
||||||
if (addend > 0x7f || addend < -0x80)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7f || saddend < -0x80)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
bfd_put_8 (abfd, addend, address);
|
bfd_put_8 (abfd, addend, address);
|
||||||
|
@ -1035,7 +1088,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
case R_V850_CALLT_16_16_OFFSET:
|
case R_V850_CALLT_16_16_OFFSET:
|
||||||
addend += bfd_get_16 (abfd, address);
|
addend += bfd_get_16 (abfd, address);
|
||||||
|
|
||||||
if (addend > 0xffff || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0xffff || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
insn = addend;
|
insn = addend;
|
||||||
|
@ -1050,7 +1105,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
case R_V850_TDA_16_16_OFFSET:
|
case R_V850_TDA_16_16_OFFSET:
|
||||||
addend += bfd_get_16 (abfd, address);
|
addend += bfd_get_16 (abfd, address);
|
||||||
|
|
||||||
if (addend > 0x7fff || addend < -0x8000)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7fff || saddend < -0x8000)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
insn = addend;
|
insn = addend;
|
||||||
|
@ -1061,7 +1118,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += (insn & 0xfffe);
|
addend += (insn & 0xfffe);
|
||||||
|
|
||||||
if (addend > 0x7ffe || addend < -0x8000)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7ffe || saddend < -0x8000)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if (addend & 1)
|
if (addend & 1)
|
||||||
|
@ -1074,7 +1133,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += ((insn & 0x7e) << 1);
|
addend += ((insn & 0x7e) << 1);
|
||||||
|
|
||||||
if (addend > 0xfc || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0xfc || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if (addend & 3)
|
if (addend & 3)
|
||||||
|
@ -1088,7 +1149,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += ((insn & 0x7f) << 1);
|
addend += ((insn & 0x7f) << 1);
|
||||||
|
|
||||||
if (addend > 0xfe || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0xfe || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if (addend & 1)
|
if (addend & 1)
|
||||||
|
@ -1102,7 +1165,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += insn & 0x7f;
|
addend += insn & 0x7f;
|
||||||
|
|
||||||
if (addend > 0x7f || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7f || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
insn &= 0xff80;
|
insn &= 0xff80;
|
||||||
|
@ -1114,7 +1179,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += ((insn & 0xf) << 1);
|
addend += ((insn & 0xf) << 1);
|
||||||
|
|
||||||
if (addend > 0x1e || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x1e || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if (addend & 1)
|
if (addend & 1)
|
||||||
|
@ -1128,7 +1195,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += insn & 0xf;
|
addend += insn & 0xf;
|
||||||
|
|
||||||
if (addend > 0xf || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0xf || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
insn &= 0xfff0;
|
insn &= 0xfff0;
|
||||||
|
@ -1140,7 +1209,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_32 (abfd, address);
|
insn = bfd_get_32 (abfd, address);
|
||||||
addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
|
addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
|
||||||
|
|
||||||
if (addend > 0x7fff || addend < -0x8000)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7fff || saddend < -0x8000)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
insn &= 0x0001ffdf;
|
insn &= 0x0001ffdf;
|
||||||
|
@ -1154,7 +1225,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn = bfd_get_16 (abfd, address);
|
insn = bfd_get_16 (abfd, address);
|
||||||
addend += ((insn & 0x3f) << 1);
|
addend += ((insn & 0x3f) << 1);
|
||||||
|
|
||||||
if (addend > 0x7e || addend < 0)
|
saddend = (bfd_signed_vma) addend;
|
||||||
|
|
||||||
|
if (saddend > 0x7e || saddend < 0)
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
|
|
||||||
if (addend & 1)
|
if (addend & 1)
|
||||||
|
@ -1164,6 +1237,11 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||||
insn |= (addend >> 1);
|
insn |= (addend >> 1);
|
||||||
break;
|
break;
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
|
||||||
|
case R_V850_GNU_VTINHERIT:
|
||||||
|
case R_V850_GNU_VTENTRY:
|
||||||
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bfd_put_16 (abfd, insn, address);
|
bfd_put_16 (abfd, insn, address);
|
||||||
|
@ -1409,6 +1487,8 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
|
||||||
case R_V850_NONE:
|
case R_V850_NONE:
|
||||||
|
case R_V850_GNU_VTINHERIT:
|
||||||
|
case R_V850_GNU_VTENTRY:
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1456,6 +1536,11 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
|
|
||||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||||
r_type = ELF32_R_TYPE (rel->r_info);
|
r_type = ELF32_R_TYPE (rel->r_info);
|
||||||
|
|
||||||
|
if (r_type == R_V850_GNU_VTENTRY
|
||||||
|
|| r_type == R_V850_GNU_VTINHERIT)
|
||||||
|
continue;
|
||||||
|
|
||||||
howto = v850_elf_howto_table + r_type;
|
howto = v850_elf_howto_table + r_type;
|
||||||
|
|
||||||
if (info->relocateable)
|
if (info->relocateable)
|
||||||
|
@ -1620,6 +1705,57 @@ fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
|
||||||
|
bfd *abfd;
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
asection *sec;
|
||||||
|
const Elf_Internal_Rela *relocs;
|
||||||
|
{
|
||||||
|
/* No got and plt entries for v850-elf */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static asection *
|
||||||
|
v850_elf_gc_mark_hook (abfd, info, rel, h, sym)
|
||||||
|
bfd *abfd;
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
Elf_Internal_Rela *rel;
|
||||||
|
struct elf_link_hash_entry *h;
|
||||||
|
Elf_Internal_Sym *sym;
|
||||||
|
{
|
||||||
|
if (h != NULL)
|
||||||
|
{
|
||||||
|
switch (ELF32_R_TYPE (rel->r_info))
|
||||||
|
{
|
||||||
|
case R_V850_GNU_VTINHERIT:
|
||||||
|
case R_V850_GNU_VTENTRY:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (h->root.type)
|
||||||
|
{
|
||||||
|
case bfd_link_hash_defined:
|
||||||
|
case bfd_link_hash_defweak:
|
||||||
|
return h->root.u.def.section;
|
||||||
|
|
||||||
|
case bfd_link_hash_common:
|
||||||
|
return h->root.u.c.p->section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(elf_bad_symtab (abfd)
|
||||||
|
&& ELF_ST_BIND (sym->st_info) != STB_LOCAL)
|
||||||
|
&& ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
|
||||||
|
&& sym->st_shndx != SHN_COMMON))
|
||||||
|
{
|
||||||
|
return bfd_section_from_elf_index (abfd, sym->st_shndx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/* Set the right machine number. */
|
/* Set the right machine number. */
|
||||||
static boolean
|
static boolean
|
||||||
v850_elf_object_p (abfd)
|
v850_elf_object_p (abfd)
|
||||||
|
@ -1804,21 +1940,15 @@ v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
|
||||||
int * retval;
|
int * retval;
|
||||||
{
|
{
|
||||||
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
|
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
|
||||||
{
|
*retval = SHN_V850_SCOMMON;
|
||||||
*retval = SHN_V850_SCOMMON;
|
else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
|
||||||
return true;
|
*retval = SHN_V850_TCOMMON;
|
||||||
}
|
else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
|
||||||
if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
|
*retval = SHN_V850_ZCOMMON;
|
||||||
{
|
else
|
||||||
*retval = SHN_V850_TCOMMON;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
return true;
|
||||||
if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
|
|
||||||
{
|
|
||||||
*retval = SHN_V850_ZCOMMON;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the special V850 section numbers that a symbol may use. */
|
/* Handle the special V850 section numbers that a symbol may use. */
|
||||||
|
@ -1829,8 +1959,36 @@ v850_elf_symbol_processing (abfd, asym)
|
||||||
asymbol * asym;
|
asymbol * asym;
|
||||||
{
|
{
|
||||||
elf_symbol_type * elfsym = (elf_symbol_type *) asym;
|
elf_symbol_type * elfsym = (elf_symbol_type *) asym;
|
||||||
|
unsigned short index;
|
||||||
|
|
||||||
switch (elfsym->internal_elf_sym.st_shndx)
|
index = elfsym->internal_elf_sym.st_shndx;
|
||||||
|
|
||||||
|
/* If the section index is an "ordinary" index, then it may
|
||||||
|
refer to a v850 specific section created by the assembler.
|
||||||
|
Check the section's type and change the index it matches.
|
||||||
|
|
||||||
|
FIXME: Should we alter the st_shndx field as well ? */
|
||||||
|
|
||||||
|
if (index < elf_elfheader(abfd)[0].e_shnum)
|
||||||
|
switch (elf_elfsections(abfd)[index]->sh_type)
|
||||||
|
{
|
||||||
|
case SHT_V850_SCOMMON:
|
||||||
|
index = SHN_V850_SCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_V850_TCOMMON:
|
||||||
|
index = SHN_V850_TCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_V850_ZCOMMON:
|
||||||
|
index = SHN_V850_ZCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (index)
|
||||||
{
|
{
|
||||||
case SHN_V850_SCOMMON:
|
case SHN_V850_SCOMMON:
|
||||||
if (v850_elf_scom_section.name == NULL)
|
if (v850_elf_scom_section.name == NULL)
|
||||||
|
@ -1889,7 +2047,7 @@ v850_elf_symbol_processing (abfd, asym)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hook called by the linker routine which adds symbols from an object
|
/* Hook called by the linker routine which adds symbols from an object
|
||||||
file. We must handle the special MIPS section numbers here. */
|
file. We must handle the special v850 section numbers here. */
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static boolean
|
static boolean
|
||||||
|
@ -1902,7 +2060,34 @@ v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
|
||||||
asection ** secp;
|
asection ** secp;
|
||||||
bfd_vma * valp;
|
bfd_vma * valp;
|
||||||
{
|
{
|
||||||
switch (sym->st_shndx)
|
int index = sym->st_shndx;
|
||||||
|
|
||||||
|
/* If the section index is an "ordinary" index, then it may
|
||||||
|
refer to a v850 specific section created by the assembler.
|
||||||
|
Check the section's type and change the index it matches.
|
||||||
|
|
||||||
|
FIXME: Should we alter the st_shndx field as well ? */
|
||||||
|
|
||||||
|
if (index < elf_elfheader(abfd)[0].e_shnum)
|
||||||
|
switch (elf_elfsections(abfd)[index]->sh_type)
|
||||||
|
{
|
||||||
|
case SHT_V850_SCOMMON:
|
||||||
|
index = SHN_V850_SCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_V850_TCOMMON:
|
||||||
|
index = SHN_V850_TCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_V850_ZCOMMON:
|
||||||
|
index = SHN_V850_ZCOMMON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (index)
|
||||||
{
|
{
|
||||||
case SHN_V850_SCOMMON:
|
case SHN_V850_SCOMMON:
|
||||||
*secp = bfd_make_section_old_way (abfd, ".scommon");
|
*secp = bfd_make_section_old_way (abfd, ".scommon");
|
||||||
|
@ -2027,6 +2212,11 @@ v850_elf_fake_sections (abfd, hdr, sec)
|
||||||
#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
|
#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
|
||||||
#define elf_backend_section_from_shdr v850_elf_section_from_shdr
|
#define elf_backend_section_from_shdr v850_elf_section_from_shdr
|
||||||
#define elf_backend_fake_sections v850_elf_fake_sections
|
#define elf_backend_fake_sections v850_elf_fake_sections
|
||||||
|
#define elf_backend_gc_mark_hook v850_elf_gc_mark_hook
|
||||||
|
#define elf_backend_gc_sweep_hook v850_elf_gc_sweep_hook
|
||||||
|
|
||||||
|
#define elf_backend_can_gc_sections 1
|
||||||
|
|
||||||
|
|
||||||
#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
|
#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
|
||||||
#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
|
#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue