Replaced fixed size array for hi16 relocations with a linked list.
This commit is contained in:
parent
5e424a1b6b
commit
45cac0cb84
@ -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>
|
||||
|
||||
* elf64-alpha.c (elf64_alpha_relax_section): Search for the proper
|
||||
|
356
bfd/elf32-v850.c
356
bfd/elf32-v850.c
@ -51,7 +51,7 @@ static bfd_reloc_status_type v850_elf_perform_relocation
|
||||
static boolean v850_elf_check_relocs
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
|
||||
static void remember_hi16s_reloc
|
||||
PARAMS ((bfd_vma, bfd_byte *));
|
||||
PARAMS ((bfd *, bfd_vma, bfd_byte *));
|
||||
static bfd_byte * find_remembered_hi16s_reloc
|
||||
PARAMS ((bfd_vma addend));
|
||||
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 */
|
||||
|
||||
/* 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. */
|
||||
@ -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_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
|
||||
/* 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 */
|
||||
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 */
|
||||
case R_V850_SDA_16_16_SPLIT_OFFSET:
|
||||
/* end-sanitize-v850e */
|
||||
@ -688,56 +735,46 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
typedef struct hi16s_location
|
||||
{
|
||||
bfd_vma addend;
|
||||
bfd_byte * address;
|
||||
unsigned long counter;
|
||||
struct hi16s_location * next;
|
||||
}
|
||||
hi16s_location;
|
||||
|
||||
static hi16s_location previous_hi16s[ 10 ]; /* XXX is this enough ? */
|
||||
static unsigned long hi16s_counter;
|
||||
static hi16s_location * previous_hi16s;
|
||||
static hi16s_location * free_hi16s;
|
||||
static unsigned long hi16s_counter;
|
||||
|
||||
static void
|
||||
remember_hi16s_reloc (addend, address)
|
||||
remember_hi16s_reloc (abfd, addend, address)
|
||||
bfd * abfd;
|
||||
bfd_vma addend;
|
||||
bfd_byte * address;
|
||||
{
|
||||
hi16s_location * oldest = NULL;
|
||||
int i;
|
||||
hi16s_location * entry = NULL;
|
||||
|
||||
/* Find a free slot. */
|
||||
for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
|
||||
{
|
||||
hi16s_location * entry = previous_hi16s + i;
|
||||
|
||||
if (entry->addend == 0 && entry->address == 0)
|
||||
{
|
||||
/* Use this entry. */
|
||||
oldest = entry;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Remember the least recently added entry. */
|
||||
if (oldest == NULL || oldest->counter > entry->counter)
|
||||
oldest = entry;
|
||||
}
|
||||
|
||||
oldest->addend = addend;
|
||||
oldest->address = address;
|
||||
oldest->counter = hi16s_counter ++;
|
||||
/* Find a free structure. */
|
||||
if (free_hi16s == NULL)
|
||||
free_hi16s = (hi16s_location *) bfd_zalloc (abfd, sizeof (* free_hi16s));
|
||||
|
||||
entry = free_hi16s;
|
||||
free_hi16s = free_hi16s->next;
|
||||
|
||||
entry->addend = addend;
|
||||
entry->address = address;
|
||||
entry->counter = hi16s_counter ++;
|
||||
entry->next = previous_hi16s;
|
||||
previous_hi16s = entry;
|
||||
|
||||
/* Cope with wrap around of our counter. */
|
||||
if (hi16s_counter == 0)
|
||||
{
|
||||
/* XXX - Assume that all counter entries differ only in their low 16 bits. */
|
||||
for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
|
||||
{
|
||||
hi16s_location * entry = previous_hi16s + i;
|
||||
|
||||
entry->counter &= 0xffff;
|
||||
}
|
||||
for (entry = previous_hi16s; entry != NULL; entry = entry->next)
|
||||
entry->counter &= 0xffff;
|
||||
|
||||
hi16s_counter = 0x10000;
|
||||
}
|
||||
@ -750,36 +787,50 @@ find_remembered_hi16s_reloc (addend)
|
||||
bfd_vma addend;
|
||||
{
|
||||
hi16s_location * match = NULL;
|
||||
hi16s_location * entry;
|
||||
hi16s_location * previous = NULL;
|
||||
hi16s_location * prev;
|
||||
int i;
|
||||
bfd_byte * addr;
|
||||
|
||||
/* 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 (match == NULL || match->counter < entry->counter)
|
||||
match = entry;
|
||||
{
|
||||
previous = prev;
|
||||
match = entry;
|
||||
}
|
||||
}
|
||||
|
||||
prev = entry;
|
||||
}
|
||||
|
||||
if (match != NULL)
|
||||
{
|
||||
bfd_byte * addr;
|
||||
if (match == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Empty the table entry. */
|
||||
match->addend = 0;
|
||||
|
||||
addr = match->address;
|
||||
match->address = NULL;
|
||||
|
||||
return addr;
|
||||
}
|
||||
/* Extract the address. */
|
||||
addr = match->address;
|
||||
|
||||
return NULL;
|
||||
/* Attach the entry to the free list. */
|
||||
if (previous)
|
||||
previous->next = match->next;
|
||||
else
|
||||
previous_hi16s = match->next;
|
||||
|
||||
match->next = free_hi16s->next;
|
||||
free_hi16s = match;
|
||||
|
||||
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
|
||||
v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
bfd * abfd;
|
||||
@ -788,6 +839,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
bfd_byte * address;
|
||||
{
|
||||
unsigned long insn;
|
||||
bfd_signed_vma saddend = (bfd_signed_vma) addend;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
@ -796,12 +848,11 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
return bfd_reloc_notsupported;
|
||||
|
||||
case R_V850_32:
|
||||
addend += bfd_get_32 (abfd, address);
|
||||
bfd_put_32 (abfd, addend, address);
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_V850_22_PCREL:
|
||||
if (addend > 0x1fffff || addend < -0x200000)
|
||||
if (saddend > 0x1fffff || saddend < -0x200000)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if ((addend % 2) != 0)
|
||||
@ -814,7 +865,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_V850_9_PCREL:
|
||||
if (addend > 0xff || addend < -0x100)
|
||||
if (saddend > 0xff || saddend < -0x100)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if ((addend % 2) != 0)
|
||||
@ -833,13 +884,13 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
|
||||
case R_V850_HI16_S:
|
||||
/* 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 = (addend >> 16) + ((addend & 0x8000) != 0);
|
||||
|
||||
/* This relocation cannot overflow. */
|
||||
if (addend > 0x7fff || addend < -0x8000)
|
||||
if (addend > 0x7fff)
|
||||
addend = 0;
|
||||
|
||||
insn = addend;
|
||||
@ -1025,7 +1076,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
case R_V850_8:
|
||||
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;
|
||||
|
||||
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:
|
||||
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;
|
||||
|
||||
insn = addend;
|
||||
@ -1050,7 +1105,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
case R_V850_TDA_16_16_OFFSET:
|
||||
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;
|
||||
|
||||
insn = addend;
|
||||
@ -1061,7 +1118,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += (insn & 0xfffe);
|
||||
|
||||
if (addend > 0x7ffe || addend < -0x8000)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0x7ffe || saddend < -0x8000)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if (addend & 1)
|
||||
@ -1074,7 +1133,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += ((insn & 0x7e) << 1);
|
||||
|
||||
if (addend > 0xfc || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0xfc || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if (addend & 3)
|
||||
@ -1088,7 +1149,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += ((insn & 0x7f) << 1);
|
||||
|
||||
if (addend > 0xfe || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0xfe || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if (addend & 1)
|
||||
@ -1102,7 +1165,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += insn & 0x7f;
|
||||
|
||||
if (addend > 0x7f || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0x7f || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
insn &= 0xff80;
|
||||
@ -1114,7 +1179,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += ((insn & 0xf) << 1);
|
||||
|
||||
if (addend > 0x1e || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0x1e || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if (addend & 1)
|
||||
@ -1128,7 +1195,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += insn & 0xf;
|
||||
|
||||
if (addend > 0xf || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0xf || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
insn &= 0xfff0;
|
||||
@ -1140,7 +1209,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_32 (abfd, address);
|
||||
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;
|
||||
|
||||
insn &= 0x0001ffdf;
|
||||
@ -1154,7 +1225,9 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn = bfd_get_16 (abfd, address);
|
||||
addend += ((insn & 0x3f) << 1);
|
||||
|
||||
if (addend > 0x7e || addend < 0)
|
||||
saddend = (bfd_signed_vma) addend;
|
||||
|
||||
if (saddend > 0x7e || saddend < 0)
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
if (addend & 1)
|
||||
@ -1164,6 +1237,11 @@ v850_elf_perform_relocation (abfd, r_type, addend, address)
|
||||
insn |= (addend >> 1);
|
||||
break;
|
||||
/* end-sanitize-v850e */
|
||||
|
||||
case R_V850_GNU_VTINHERIT:
|
||||
case R_V850_GNU_VTENTRY:
|
||||
return bfd_reloc_ok;
|
||||
|
||||
}
|
||||
|
||||
bfd_put_16 (abfd, insn, address);
|
||||
@ -1409,6 +1487,8 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
|
||||
/* end-sanitize-v850e */
|
||||
|
||||
case R_V850_NONE:
|
||||
case R_V850_GNU_VTINHERIT:
|
||||
case R_V850_GNU_VTENTRY:
|
||||
return bfd_reloc_ok;
|
||||
|
||||
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_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;
|
||||
|
||||
if (info->relocateable)
|
||||
@ -1620,6 +1705,57 @@ fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
|
||||
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. */
|
||||
static boolean
|
||||
v850_elf_object_p (abfd)
|
||||
@ -1804,21 +1940,15 @@ v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
|
||||
int * retval;
|
||||
{
|
||||
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
|
||||
{
|
||||
*retval = SHN_V850_SCOMMON;
|
||||
return true;
|
||||
}
|
||||
if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
|
||||
{
|
||||
*retval = SHN_V850_TCOMMON;
|
||||
return true;
|
||||
}
|
||||
if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
|
||||
{
|
||||
*retval = SHN_V850_ZCOMMON;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
*retval = SHN_V850_SCOMMON;
|
||||
else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
|
||||
*retval = SHN_V850_TCOMMON;
|
||||
else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
|
||||
*retval = SHN_V850_ZCOMMON;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Handle the special V850 section numbers that a symbol may use. */
|
||||
@ -1829,8 +1959,36 @@ v850_elf_symbol_processing (abfd, asym)
|
||||
asymbol * asym;
|
||||
{
|
||||
elf_symbol_type * elfsym = (elf_symbol_type *) asym;
|
||||
unsigned short index;
|
||||
|
||||
index = elfsym->internal_elf_sym.st_shndx;
|
||||
|
||||
switch (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:
|
||||
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
|
||||
file. We must handle the special MIPS section numbers here. */
|
||||
file. We must handle the special v850 section numbers here. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
@ -1902,7 +2060,34 @@ v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
|
||||
asection ** secp;
|
||||
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:
|
||||
*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_section_from_shdr v850_elf_section_from_shdr
|
||||
#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_reloc_type_lookup v850_elf_reloc_type_lookup
|
||||
|
Loading…
Reference in New Issue
Block a user