* elf32-mips.c (FN_STUB, CALL_STUB, CALL_FP_STUB): Define.
(struct mips_elf_link_hash_entry): Add new fields fn_stub, need_fn_sub, call_stub, and call_fp_stub. (struct mips_elf_link_hash_table): Add field mips16_stubs_seen. (mips_elf_link_hash_newfunc): Initialize new fields. (mips_elf_link_hash_table_create): Likewise. (mips_elf_relocate_section): Redirect relocations to use mips16 stubs when appropriate. (mips_elf_check_relocs): Attach stub sections to the appropriate symbol. Set need_fn_stub when appropriate. (mips_elf_always_size_sections): New static function. (mips_elf_check_mips16_stubs): New static function. (elf_backend_always_size_sections): Define. * elf-bfd.h (struct elf_obj_tdata): Add local_stubs field.
This commit is contained in:
parent
258b1f5d18
commit
e900e695a2
|
@ -1,3 +1,23 @@
|
|||
Thu Feb 6 16:55:43 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* elf32-mips.c (FN_STUB, CALL_STUB, CALL_FP_STUB): Define.
|
||||
(struct mips_elf_link_hash_entry): Add new fields fn_stub,
|
||||
need_fn_sub, call_stub, and call_fp_stub.
|
||||
(struct mips_elf_link_hash_table): Add field mips16_stubs_seen.
|
||||
(mips_elf_link_hash_newfunc): Initialize new fields.
|
||||
(mips_elf_link_hash_table_create): Likewise.
|
||||
(mips_elf_relocate_section): Redirect relocations to use mips16
|
||||
stubs when appropriate.
|
||||
(mips_elf_check_relocs): Attach stub sections to the appropriate
|
||||
symbol. Set need_fn_stub when appropriate.
|
||||
(mips_elf_always_size_sections): New static function.
|
||||
(mips_elf_check_mips16_stubs): New static function.
|
||||
(elf_backend_always_size_sections): Define.
|
||||
* elf-bfd.h (struct elf_obj_tdata): Add local_stubs field.
|
||||
|
||||
* elflink.h (elf_link_input_bfd): Discard local symbols that are
|
||||
attached to sections which are not being included in the link.
|
||||
|
||||
Wed Feb 5 13:20:17 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* cofflink.c (_bfd_coff_generic_relocate_section): Ignore the
|
||||
|
|
417
bfd/elf32-mips.c
417
bfd/elf32-mips.c
|
@ -101,6 +101,8 @@ static boolean mips_elf_check_relocs
|
|||
const Elf_Internal_Rela *));
|
||||
static boolean mips_elf_adjust_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean mips_elf_always_size_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean mips_elf_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean mips_elf_finish_dynamic_symbol
|
||||
|
@ -2948,6 +2950,44 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
|
|||
line_ptr);
|
||||
}
|
||||
|
||||
/* The mips16 compiler uses a couple of special sections to handle
|
||||
floating point arguments.
|
||||
|
||||
Section names that look like .mips16.fn.FNNAME contain stubs that
|
||||
copy floating point arguments from the fp regs to the gp regs and
|
||||
then jump to FNNAME. If any 32 bit function calls FNNAME, the
|
||||
call should be redirected to the stub instead. If no 32 bit
|
||||
function calls FNNAME, the stub should be discarded. We need to
|
||||
consider any reference to the function, not just a call, because
|
||||
if the address of the function is taken we will need the stub,
|
||||
since the address might be passed to a 32 bit function.
|
||||
|
||||
Section names that look like .mips16.call.FNNAME contain stubs
|
||||
that copy floating point arguments from the gp regs to the fp
|
||||
regs and then jump to FNNAME. If FNNAME is a 32 bit function,
|
||||
then any 16 bit function that calls FNNAME should be redirected
|
||||
to the stub instead. If FNNAME is not a 32 bit function, the
|
||||
stub should be discarded.
|
||||
|
||||
.mips16.call.fp.FNNAME sections are similar, but contain stubs
|
||||
which call FNNAME and then copy the return value from the fp regs
|
||||
to the gp regs. These stubs store the return value in $18 while
|
||||
calling FNNAME; any function which might call one of these stubs
|
||||
must arrange to save $18 around the call. (This case is not
|
||||
needed for 32 bit functions that call 16 bit functions, because
|
||||
16 bit functions always return floating point values in both
|
||||
$f0/$f1 and $2/$3.)
|
||||
|
||||
Note that in all cases FNNAME might be defined statically.
|
||||
Therefore, FNNAME is not used literally. Instead, the relocation
|
||||
information will indicate which symbol the section is for.
|
||||
|
||||
We record any stubs that we find in the symbol table. */
|
||||
|
||||
#define FN_STUB ".mips16.fn."
|
||||
#define CALL_STUB ".mips16.call."
|
||||
#define CALL_FP_STUB ".mips16.call.fp."
|
||||
|
||||
/* The MIPS ELF linker needs additional information for each symbol in
|
||||
the global hash table. */
|
||||
|
||||
|
@ -2960,6 +3000,22 @@ struct mips_elf_link_hash_entry
|
|||
|
||||
/* Number of MIPS_32 or MIPS_REL32 relocs against this symbol. */
|
||||
unsigned int mips_32_relocs;
|
||||
|
||||
/* If there is a stub that 32 bit functions should use to call this
|
||||
16 bit function, this points to the section containing the stub. */
|
||||
asection *fn_stub;
|
||||
|
||||
/* Whether we need the fn_stub; this is set if this symbol appears
|
||||
in any relocs other than a 16 bit call. */
|
||||
boolean need_fn_stub;
|
||||
|
||||
/* If there is a stub that 16 bit functions should use to call this
|
||||
32 bit function, this points to the section containing the stub. */
|
||||
asection *call_stub;
|
||||
|
||||
/* This is like the call_stub field, but it is used if the function
|
||||
being called returns a floating point value. */
|
||||
asection *call_fp_stub;
|
||||
};
|
||||
|
||||
/* MIPS ELF linker hash table. */
|
||||
|
@ -2978,6 +3034,8 @@ struct mips_elf_link_hash_table
|
|||
boolean use_rld_obj_head;
|
||||
/* This is the value of the __rld_map or __rld_obj_head symbol. */
|
||||
bfd_vma rld_value;
|
||||
/* This is set if we see any mips16 stub sections. */
|
||||
boolean mips16_stubs_seen;
|
||||
};
|
||||
|
||||
/* Look up an entry in a MIPS ELF linker hash table. */
|
||||
|
@ -3035,6 +3093,10 @@ mips_elf_link_hash_newfunc (entry, table, string)
|
|||
not been set. -1 means there is no associated ifd. */
|
||||
ret->esym.ifd = -2;
|
||||
ret->mips_32_relocs = 0;
|
||||
ret->fn_stub = NULL;
|
||||
ret->need_fn_stub = false;
|
||||
ret->call_stub = NULL;
|
||||
ret->call_fp_stub = NULL;
|
||||
}
|
||||
|
||||
return (struct bfd_hash_entry *) ret;
|
||||
|
@ -3067,6 +3129,7 @@ mips_elf_link_hash_table_create (abfd)
|
|||
ret->compact_rel_size = 0;
|
||||
ret->use_rld_obj_head = false;
|
||||
ret->rld_value = 0;
|
||||
ret->mips16_stubs_seen = false;
|
||||
|
||||
return &ret->root.root;
|
||||
}
|
||||
|
@ -4378,6 +4441,8 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
struct elf_link_hash_entry *h;
|
||||
asection *sec;
|
||||
Elf_Internal_Sym *sym;
|
||||
struct mips_elf_link_hash_entry *mh;
|
||||
int other;
|
||||
bfd_reloc_status_type r;
|
||||
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
|
@ -4639,6 +4704,98 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
}
|
||||
}
|
||||
|
||||
mh = (struct mips_elf_link_hash_entry *) h;
|
||||
if (h != NULL)
|
||||
other = h->other;
|
||||
else if (sym != NULL)
|
||||
other = sym->st_other;
|
||||
else
|
||||
other = 0;
|
||||
|
||||
/* If this function has an fn_stub, then it is a mips16
|
||||
function which needs a stub if it is called by a 32 bit
|
||||
function. If this reloc is anything other than a 16 bit
|
||||
call, redirect the reloc to the stub. We don't redirect
|
||||
relocs from other stub functions. */
|
||||
if (r_type != R_MIPS16_26
|
||||
&& ((mh != NULL
|
||||
&& mh->fn_stub != NULL)
|
||||
|| (mh == NULL
|
||||
&& elf_tdata (input_bfd)->local_stubs != NULL
|
||||
&& elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
|
||||
&& strncmp (bfd_get_section_name (input_bfd, input_section),
|
||||
FN_STUB, sizeof FN_STUB - 1) != 0
|
||||
&& strncmp (bfd_get_section_name (input_bfd, input_section),
|
||||
CALL_STUB, sizeof CALL_STUB - 1) != 0
|
||||
&& strncmp (bfd_get_section_name (input_bfd, input_section),
|
||||
CALL_FP_STUB, sizeof CALL_FP_STUB - 1) != 0)
|
||||
{
|
||||
if (mh != NULL)
|
||||
{
|
||||
BFD_ASSERT (mh->need_fn_stub);
|
||||
relocation = (mh->fn_stub->output_section->vma
|
||||
+ mh->fn_stub->output_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
asection *fn_stub;
|
||||
|
||||
fn_stub = elf_tdata (input_bfd)->local_stubs[r_symndx];
|
||||
relocation = (fn_stub->output_section->vma
|
||||
+ fn_stub->output_offset);
|
||||
}
|
||||
|
||||
/* RELOCATION now points to 32 bit code. */
|
||||
other = 0;
|
||||
}
|
||||
|
||||
/* If this function has a call_stub, then it is called by a
|
||||
mips16 function; the call needs to go through a stub if
|
||||
this function is a 32 bit function. If this reloc is a
|
||||
16 bit call, and the symbol is not a 16 bit function,
|
||||
then redirect the reloc to the stub. Note that we don't
|
||||
need to worry about calling the function through a
|
||||
function pointer; such calls are handled by routing
|
||||
through a special mips16 routine. We don't have to check
|
||||
whether this call is from a stub; it can't be, because a
|
||||
stub contains 32 bit code, and hence can not have a 16
|
||||
bit reloc. */
|
||||
if (r_type == R_MIPS16_26
|
||||
&& mh != NULL
|
||||
&& (mh->call_stub != NULL || mh->call_fp_stub != NULL)
|
||||
&& other != STO_MIPS16)
|
||||
{
|
||||
asection *stub;
|
||||
|
||||
/* If both call_stub and call_fp_stub are defined, we
|
||||
can figure out which one to use by seeing which one
|
||||
appears in the input file. */
|
||||
if (mh->call_stub != NULL && mh->call_fp_stub != NULL)
|
||||
{
|
||||
asection *o;
|
||||
|
||||
stub = NULL;
|
||||
for (o = input_bfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
if (strncmp (bfd_get_section_name (input_bfd, o),
|
||||
CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
|
||||
{
|
||||
stub = mh->call_fp_stub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stub == NULL)
|
||||
stub = mh->call_stub;
|
||||
}
|
||||
else if (mh->call_stub != NULL)
|
||||
stub = mh->call_stub;
|
||||
else
|
||||
stub = mh->call_fp_stub;
|
||||
|
||||
BFD_ASSERT (stub->_raw_size > 0);
|
||||
relocation = stub->output_section->vma + stub->output_offset;
|
||||
}
|
||||
|
||||
if (r_type == R_MIPS_HI16)
|
||||
{
|
||||
Elf_Internal_Rela *lorel;
|
||||
|
@ -4867,9 +5024,7 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
addr += 4;
|
||||
bfd_put_32 (input_bfd, val, contents + addr);
|
||||
}
|
||||
else if (r_type == R_MIPS_26
|
||||
&& ((h != NULL && h->other == STO_MIPS16)
|
||||
|| (sym != NULL && sym->st_other == STO_MIPS16)))
|
||||
else if (r_type == R_MIPS_26 && other == STO_MIPS16)
|
||||
{
|
||||
unsigned long insn;
|
||||
|
||||
|
@ -4911,8 +5066,7 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
| ((insn & 0x3e0) >> 5));
|
||||
/* If this is a jump to a 32 bit routine, then make
|
||||
it jalx. */
|
||||
if ((h != NULL && h->other != STO_MIPS16)
|
||||
|| (sym != NULL && sym->st_other != STO_MIPS16))
|
||||
if (other != STO_MIPS16)
|
||||
insn |= 0x400;
|
||||
bfd_put_16 (input_bfd, insn, contents + rel->r_offset);
|
||||
}
|
||||
|
@ -5264,6 +5418,7 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
|||
asection *sec;
|
||||
const Elf_Internal_Rela *relocs;
|
||||
{
|
||||
const char *name;
|
||||
bfd *dynobj;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
|
@ -5282,6 +5437,164 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
|||
sym_hashes = elf_sym_hashes (abfd);
|
||||
extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
|
||||
|
||||
/* Check for the mips16 stub sections. */
|
||||
|
||||
name = bfd_get_section_name (abfd, sec);
|
||||
if (strncmp (name, FN_STUB, sizeof FN_STUB - 1) == 0)
|
||||
{
|
||||
unsigned long r_symndx;
|
||||
|
||||
/* Look at the relocation information to figure out which symbol
|
||||
this is for. */
|
||||
|
||||
r_symndx = ELF32_R_SYM (relocs->r_info);
|
||||
|
||||
if (r_symndx < extsymoff
|
||||
|| sym_hashes[r_symndx - extsymoff] == NULL)
|
||||
{
|
||||
asection *o;
|
||||
|
||||
/* This stub is for a local symbol. This stub will only be
|
||||
needed if there is some relocation in this BFD, other
|
||||
than a 16 bit function call, which refers to this symbol. */
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
Elf_Internal_Rela *sec_relocs;
|
||||
const Elf_Internal_Rela *r, *rend;
|
||||
|
||||
/* We can ignore stub sections when looking for relocs. */
|
||||
if ((o->flags & SEC_RELOC) == 0
|
||||
|| o->reloc_count == 0
|
||||
|| strncmp (bfd_get_section_name (abfd, o), FN_STUB,
|
||||
sizeof FN_STUB - 1) == 0
|
||||
|| strncmp (bfd_get_section_name (abfd, o), CALL_STUB,
|
||||
sizeof CALL_STUB - 1) == 0
|
||||
|| strncmp (bfd_get_section_name (abfd, o), CALL_FP_STUB,
|
||||
sizeof CALL_FP_STUB - 1) == 0)
|
||||
continue;
|
||||
|
||||
sec_relocs = (_bfd_elf32_link_read_relocs
|
||||
(abfd, o, (PTR) NULL,
|
||||
(Elf_Internal_Rela *) NULL,
|
||||
info->keep_memory));
|
||||
if (sec_relocs == NULL)
|
||||
return false;
|
||||
|
||||
rend = sec_relocs + o->reloc_count;
|
||||
for (r = sec_relocs; r < rend; r++)
|
||||
if (ELF32_R_SYM (r->r_info) == r_symndx
|
||||
&& ELF32_R_TYPE (r->r_info) != R_MIPS16_26)
|
||||
break;
|
||||
|
||||
if (! info->keep_memory)
|
||||
free (sec_relocs);
|
||||
|
||||
if (r < rend)
|
||||
break;
|
||||
}
|
||||
|
||||
if (o == NULL)
|
||||
{
|
||||
/* There is no non-call reloc for this stub, so we do
|
||||
not need it. Since this function is called before
|
||||
the linker maps input sections to output sections, we
|
||||
can easily discard it by setting the SEC_EXCLUDE
|
||||
flag. */
|
||||
sec->flags |= SEC_EXCLUDE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Record this stub in an array of local symbol stubs for
|
||||
this BFD. */
|
||||
if (elf_tdata (abfd)->local_stubs == NULL)
|
||||
{
|
||||
unsigned long symcount;
|
||||
asection **n;
|
||||
|
||||
if (elf_bad_symtab (abfd))
|
||||
symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
|
||||
else
|
||||
symcount = symtab_hdr->sh_info;
|
||||
n = (asection **) bfd_zalloc (abfd,
|
||||
symcount * sizeof (asection *));
|
||||
if (n == NULL)
|
||||
return false;
|
||||
elf_tdata (abfd)->local_stubs = n;
|
||||
}
|
||||
|
||||
elf_tdata (abfd)->local_stubs[r_symndx] = sec;
|
||||
|
||||
/* We don't need to set mips16_stubs_seen in this case.
|
||||
That flag is used to see whether we need to look through
|
||||
the global symbol table for stubs. We don't need to set
|
||||
it here, because we just have a local stub. */
|
||||
}
|
||||
else
|
||||
{
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
|
||||
h = ((struct mips_elf_link_hash_entry *)
|
||||
sym_hashes[r_symndx - extsymoff]);
|
||||
|
||||
/* H is the symbol this stub is for. */
|
||||
|
||||
h->fn_stub = sec;
|
||||
mips_elf_hash_table (info)->mips16_stubs_seen = true;
|
||||
}
|
||||
}
|
||||
else if (strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0
|
||||
|| strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
|
||||
{
|
||||
unsigned long r_symndx;
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
asection **loc;
|
||||
|
||||
/* Look at the relocation information to figure out which symbol
|
||||
this is for. */
|
||||
|
||||
r_symndx = ELF32_R_SYM (relocs->r_info);
|
||||
|
||||
if (r_symndx < extsymoff
|
||||
|| sym_hashes[r_symndx - extsymoff] == NULL)
|
||||
{
|
||||
/* This stub was actually built for a static symbol defined
|
||||
in the same file. We assume that all static symbols in
|
||||
mips16 code are themselves mips16, so we can simply
|
||||
discard this stub. Since this function is called before
|
||||
the linker maps input sections to output sections, we can
|
||||
easily discard it by setting the SEC_EXCLUDE flag. */
|
||||
sec->flags |= SEC_EXCLUDE;
|
||||
return true;
|
||||
}
|
||||
|
||||
h = ((struct mips_elf_link_hash_entry *)
|
||||
sym_hashes[r_symndx - extsymoff]);
|
||||
|
||||
/* H is the symbol this stub is for. */
|
||||
|
||||
if (strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
|
||||
loc = &h->call_fp_stub;
|
||||
else
|
||||
loc = &h->call_stub;
|
||||
|
||||
/* If we already have an appropriate stub for this function, we
|
||||
don't need another one, so we can discard this one. Since
|
||||
this function is called before the linker maps input sections
|
||||
to output sections, we can easily discard it by setting the
|
||||
SEC_EXCLUDE flag. We can also discard this section if we
|
||||
happen to already know that this is a mips16 function; it is
|
||||
not necessary to check this here, as it is checked later, but
|
||||
it is slightly faster to check now. */
|
||||
if (*loc != NULL || h->root.other == STO_MIPS16)
|
||||
{
|
||||
sec->flags |= SEC_EXCLUDE;
|
||||
return true;
|
||||
}
|
||||
|
||||
*loc = sec;
|
||||
mips_elf_hash_table (info)->mips16_stubs_seen = true;
|
||||
}
|
||||
|
||||
if (dynobj == NULL)
|
||||
{
|
||||
sgot = NULL;
|
||||
|
@ -5488,6 +5801,24 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If this reloc is not a 16 bit call, and it has a global
|
||||
symbol, then we will need the fn_stub if there is one.
|
||||
References from a stub section do not count. */
|
||||
if (h != NULL
|
||||
&& ELF32_R_TYPE (rel->r_info) != R_MIPS16_26
|
||||
&& strncmp (bfd_get_section_name (abfd, sec), FN_STUB,
|
||||
sizeof FN_STUB - 1) != 0
|
||||
&& strncmp (bfd_get_section_name (abfd, sec), CALL_STUB,
|
||||
sizeof CALL_STUB - 1) != 0
|
||||
&& strncmp (bfd_get_section_name (abfd, sec), CALL_FP_STUB,
|
||||
sizeof CALL_FP_STUB - 1) != 0)
|
||||
{
|
||||
struct mips_elf_link_hash_entry *mh;
|
||||
|
||||
mh = (struct mips_elf_link_hash_entry *) h;
|
||||
mh->need_fn_stub = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -5591,6 +5922,80 @@ mips_elf_adjust_dynamic_symbol (info, h)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* This function is called after all the input files have been read,
|
||||
and the input sections have been assigned to output sections. We
|
||||
check for any mips16 stub sections that we can discard. */
|
||||
|
||||
static boolean mips_elf_check_mips16_stubs
|
||||
PARAMS ((struct mips_elf_link_hash_entry *, PTR));
|
||||
|
||||
static boolean
|
||||
mips_elf_always_size_sections (output_bfd, info)
|
||||
bfd *output_bfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
if (info->relocateable
|
||||
|| ! mips_elf_hash_table (info)->mips16_stubs_seen)
|
||||
return true;
|
||||
|
||||
mips_elf_link_hash_traverse (mips_elf_hash_table (info),
|
||||
mips_elf_check_mips16_stubs,
|
||||
(PTR) NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check the mips16 stubs for a particular symbol, and see if we can
|
||||
discard them. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
mips_elf_check_mips16_stubs (h, data)
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
PTR data;
|
||||
{
|
||||
if (h->fn_stub != NULL
|
||||
&& ! h->need_fn_stub)
|
||||
{
|
||||
/* We don't need the fn_stub; the only references to this symbol
|
||||
are 16 bit calls. Clobber the size to 0 to prevent it from
|
||||
being included in the link. */
|
||||
h->fn_stub->_raw_size = 0;
|
||||
h->fn_stub->_cooked_size = 0;
|
||||
h->fn_stub->flags &= ~ SEC_RELOC;
|
||||
h->fn_stub->reloc_count = 0;
|
||||
h->fn_stub->flags |= SEC_EXCLUDE;
|
||||
}
|
||||
|
||||
if (h->call_stub != NULL
|
||||
&& h->root.other == STO_MIPS16)
|
||||
{
|
||||
/* We don't need the call_stub; this is a 16 bit function, so
|
||||
calls from other 16 bit functions are OK. Clobber the size
|
||||
to 0 to prevent it from being included in the link. */
|
||||
h->call_stub->_raw_size = 0;
|
||||
h->call_stub->_cooked_size = 0;
|
||||
h->call_stub->flags &= ~ SEC_RELOC;
|
||||
h->call_stub->reloc_count = 0;
|
||||
h->call_stub->flags |= SEC_EXCLUDE;
|
||||
}
|
||||
|
||||
if (h->call_fp_stub != NULL
|
||||
&& h->root.other == STO_MIPS16)
|
||||
{
|
||||
/* We don't need the call_stub; this is a 16 bit function, so
|
||||
calls from other 16 bit functions are OK. Clobber the size
|
||||
to 0 to prevent it from being included in the link. */
|
||||
h->call_fp_stub->_raw_size = 0;
|
||||
h->call_fp_stub->_cooked_size = 0;
|
||||
h->call_fp_stub->flags &= ~ SEC_RELOC;
|
||||
h->call_fp_stub->reloc_count = 0;
|
||||
h->call_fp_stub->flags |= SEC_EXCLUDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set the sizes of the dynamic sections. */
|
||||
|
||||
static boolean
|
||||
|
@ -6706,6 +7111,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap =
|
|||
#define elf_backend_check_relocs mips_elf_check_relocs
|
||||
#define elf_backend_adjust_dynamic_symbol \
|
||||
mips_elf_adjust_dynamic_symbol
|
||||
#define elf_backend_always_size_sections \
|
||||
mips_elf_always_size_sections
|
||||
#define elf_backend_size_dynamic_sections \
|
||||
mips_elf_size_dynamic_sections
|
||||
#define elf_backend_relocate_section mips_elf_relocate_section
|
||||
|
|
Loading…
Reference in New Issue