* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,

change type of locsyms.
	(bfd_elf_get_elf_syms): Declare.
	* elf.c (bfd_elf_get_elf_syms): New function.
	(group_signature): Use bfd_elf_get_elf_syms.
	(bfd_section_from_r_symndx): Likewise.
	* elfcode.h (elf_slurp_symbol_table): Likewise.
	* elflink.h (elf_link_is_defined_archive_symbol): Likewise.
	(elf_link_add_object_symbols): Likewise.  Reorganise to increase
	locality of various data structures.  Properly free internal relocs.
	(elf_bfd_final_link): Properly free internal relocs.
	(elf_link_check_versioned_symbol): Use bfd_elf_get_elf_syms.
	(elf_link_input_bfd): Likewise.
	(elf_gc_mark): Likewise.  Properly free internal relocs.
	(elf_gc_sweep): Properly free internal relocs.
	(elf_reloc_symbol_deleted_p): No need to swap syms in.
	(elf_bfd_discard_info): Use bfd_elf_get_elf_syms.  Properly free
	internal relocs.
	* elf-m10200.c (mn10200_elf_relax_section): Use bfd_elf_get_elf_syms.
	Properly free possibly cached info.
	(mn10200_elf_relax_delete_bytes): Remove symbol swapping code.
	(mn10200_elf_symbol_address_p): Pass in internal syms.  Remove
	symbol swapping code.
	(mn10200_elf_get_relocated_section_contents): Use bfd_elf_get_elf_syms.
	Properly free possibly cached info.
	* elf-m10300.c (mn10300_elf_relax_section): As above for elf-m10200.c.
	(mn10300_elf_relax_delete_bytes): Likewise.
	(mn10300_elf_symbol_address_p): Likewise.
	(mn10300_elf_get_relocated_section_contents): Likewise.
	* elf32-h8300.c (elf32_h8_relax_section): As above for elf-m10200.c.
	(elf32_h8_relax_delete_bytes): Likewise.
	(elf32_h8_symbol_address_p): Likewise.
	(elf32_h8_get_relocated_section_contents): Likewise.
	* elf32-m32r.c (m32r_elf_relax_section): As above for elf-m10200.c.
	(m32r_elf_relax_delete_bytes): Likewise.
	(m32r_elf_get_relocated_section_contents): Likewise.
	* elf32-sh.c (sh_elf_reloc_loop): Free section contents using
	elf_section_data to determine whether cached.
	(sh_elf_relax_section): As above for elf-m10200.c.
	(sh_elf_relax_delete_bytes): Likewise.
	(sh_elf_get_relocated_section_contents): Likewise.
	* elf32-xstormy16.c (xstormy16_elf_relax_section): As above.
	* elf64-alpha.c (elf64_alpha_relax_section): As above.  Also delay
	reading of local syms.
	* elf64-mmix.c (mmix_elf_relax_section): Likewise.
	* elf64-sh64.c (sh_elf64_get_relocated_section_contents): As above.
	* elfxx-ia64.c (elfNN_ia64_relax_section): As above.
	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Properly free internal
	relocs.
	* elf32-arm.h (bfd_elf32_arm_process_before_allocation): Properly
	free internal relocs and section contents.  Don't read symbols.
	* elf32-hppa.c (get_local_syms): Use bfd_elf_get_elf_syms.
	(elf32_hppa_size_stubs): Don't free local syms.
	* elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Delay
	reading of local syms.  Use bfd_elf_get_elf_syms.  Properly free
	possibly cached info.
	* elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
	* elf64-hppa.c (elf64_hppa_check_relocs): Use bfd_elf_get_elf_syms.
	* elf64-ppc.c (struct ppc_link_hash_table): Delete bfd_count and
	all_local_syms.
	(get_local_syms): Delete function.
	(edit_opd): Use bfd_elf_get_elf_syms.  Free on error exit.  Cache
	on exit.
	(ppc64_elf_size_stubs): Use bfd_elf_get_elf_syms.  Free/cache on exit.
This commit is contained in:
Alan Modra 2002-07-07 09:10:41 +00:00
parent d8462f1281
commit 6cdc0ccc12
22 changed files with 1432 additions and 2704 deletions

View File

@ -1,3 +1,70 @@
2002-07-07 Alan Modra <amodra@bigpond.net.au>
* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
change type of locsyms.
(bfd_elf_get_elf_syms): Declare.
* elf.c (bfd_elf_get_elf_syms): New function.
(group_signature): Use bfd_elf_get_elf_syms.
(bfd_section_from_r_symndx): Likewise.
* elfcode.h (elf_slurp_symbol_table): Likewise.
* elflink.h (elf_link_is_defined_archive_symbol): Likewise.
(elf_link_add_object_symbols): Likewise. Reorganise to increase
locality of various data structures. Properly free internal relocs.
(elf_bfd_final_link): Properly free internal relocs.
(elf_link_check_versioned_symbol): Use bfd_elf_get_elf_syms.
(elf_link_input_bfd): Likewise.
(elf_gc_mark): Likewise. Properly free internal relocs.
(elf_gc_sweep): Properly free internal relocs.
(elf_reloc_symbol_deleted_p): No need to swap syms in.
(elf_bfd_discard_info): Use bfd_elf_get_elf_syms. Properly free
internal relocs.
* elf-m10200.c (mn10200_elf_relax_section): Use bfd_elf_get_elf_syms.
Properly free possibly cached info.
(mn10200_elf_relax_delete_bytes): Remove symbol swapping code.
(mn10200_elf_symbol_address_p): Pass in internal syms. Remove
symbol swapping code.
(mn10200_elf_get_relocated_section_contents): Use bfd_elf_get_elf_syms.
Properly free possibly cached info.
* elf-m10300.c (mn10300_elf_relax_section): As above for elf-m10200.c.
(mn10300_elf_relax_delete_bytes): Likewise.
(mn10300_elf_symbol_address_p): Likewise.
(mn10300_elf_get_relocated_section_contents): Likewise.
* elf32-h8300.c (elf32_h8_relax_section): As above for elf-m10200.c.
(elf32_h8_relax_delete_bytes): Likewise.
(elf32_h8_symbol_address_p): Likewise.
(elf32_h8_get_relocated_section_contents): Likewise.
* elf32-m32r.c (m32r_elf_relax_section): As above for elf-m10200.c.
(m32r_elf_relax_delete_bytes): Likewise.
(m32r_elf_get_relocated_section_contents): Likewise.
* elf32-sh.c (sh_elf_reloc_loop): Free section contents using
elf_section_data to determine whether cached.
(sh_elf_relax_section): As above for elf-m10200.c.
(sh_elf_relax_delete_bytes): Likewise.
(sh_elf_get_relocated_section_contents): Likewise.
* elf32-xstormy16.c (xstormy16_elf_relax_section): As above.
* elf64-alpha.c (elf64_alpha_relax_section): As above. Also delay
reading of local syms.
* elf64-mmix.c (mmix_elf_relax_section): Likewise.
* elf64-sh64.c (sh_elf64_get_relocated_section_contents): As above.
* elfxx-ia64.c (elfNN_ia64_relax_section): As above.
* elfxx-mips.c (_bfd_mips_elf_check_relocs): Properly free internal
relocs.
* elf32-arm.h (bfd_elf32_arm_process_before_allocation): Properly
free internal relocs and section contents. Don't read symbols.
* elf32-hppa.c (get_local_syms): Use bfd_elf_get_elf_syms.
(elf32_hppa_size_stubs): Don't free local syms.
* elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Delay
reading of local syms. Use bfd_elf_get_elf_syms. Properly free
possibly cached info.
* elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
* elf64-hppa.c (elf64_hppa_check_relocs): Use bfd_elf_get_elf_syms.
* elf64-ppc.c (struct ppc_link_hash_table): Delete bfd_count and
all_local_syms.
(get_local_syms): Delete function.
(edit_opd): Use bfd_elf_get_elf_syms. Free on error exit. Cache
on exit.
(ppc64_elf_size_stubs): Use bfd_elf_get_elf_syms. Free/cache on exit.
2002-07-05 Jim Wilson <wilson@redhat.com>
* syms.c (decode_section_type): New.

View File

@ -417,8 +417,7 @@ enum elf_reloc_type_class {
struct elf_reloc_cookie
{
Elf_Internal_Rela *rels, *rel, *relend;
PTR locsyms;
PTR locsym_shndx;
Elf_Internal_Sym *locsyms;
bfd *abfd;
size_t locsymcount;
size_t extsymoff;
@ -1216,6 +1215,9 @@ extern char *bfd_elf_string_from_elf_section
PARAMS ((bfd *, unsigned, unsigned));
extern char *bfd_elf_get_str_section
PARAMS ((bfd *, unsigned));
extern Elf_Internal_Sym *bfd_elf_get_elf_syms
PARAMS ((bfd *, Elf_Internal_Shdr *, size_t, size_t,
Elf_Internal_Sym *, PTR, Elf_External_Sym_Shndx *));
extern boolean _bfd_elf_copy_private_bfd_data
PARAMS ((bfd *, bfd *));

View File

@ -30,7 +30,7 @@ static void mn10200_info_to_howto
static boolean mn10200_elf_relax_delete_bytes
PARAMS ((bfd *, asection *, bfd_vma, int));
static boolean mn10200_elf_symbol_address_p
PARAMS ((bfd *, asection *, bfd_vma));
PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
static bfd_reloc_status_type mn10200_elf_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
@ -508,15 +508,10 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
bfd_byte *free_contents = NULL;
Elf32_External_Sym *extsyms = NULL;
Elf32_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* Assume nothing changes. */
*again = false;
@ -536,7 +531,6 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
sec->_cooked_size = sec->_raw_size;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf32_link_read_relocs
@ -544,8 +538,6 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
@ -572,7 +564,6 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@ -580,68 +571,35 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
}
}
/* Read this BFD's symbols if we haven't done so already. */
if (extsyms == NULL)
/* Read this BFD's local symbols if we haven't done so already. */
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
/* Get cached copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
/* Go get them off disk. */
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, abfd) != amt)
goto error_return;
symtab_hdr->contents = (bfd_byte *) extsyms;
}
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
shndx_hdr->contents = (bfd_byte *) shndx_buf;
}
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
/* A local symbol. */
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
Elf_Internal_Sym *isym;
asection *sym_sec;
esym = extsyms + ELF32_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == SHN_UNDEF)
isym = isymbuf + ELF32_R_SYM (irel->r_info);
if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
else if (isym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
symval = (isym.st_value
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
@ -702,12 +660,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
if (code == 0xe0)
@ -759,12 +713,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
@ -849,17 +799,14 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
/* We also have to be sure there is no symbol/label
at the unconditional branch. */
if (mn10200_elf_symbol_address_p (abfd, sec, irel->r_offset + 1))
if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
irel->r_offset + 1))
continue;
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Reverse the condition of the first branch. */
switch (code)
@ -977,12 +924,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xf8 + (code & 0x03),
@ -1020,12 +963,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
case 0xc8:
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
if ((code & 0xfc) == 0x74)
code = 0xdc + (code & 0x03);
@ -1107,12 +1046,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
@ -1170,12 +1105,8 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
case 0xc4:
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
bfd_put_8 (abfd, 0xcc + (code & 0x03),
contents + irel->r_offset - 2);
@ -1205,13 +1136,23 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
}
}
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
@ -1219,38 +1160,22 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
}
}
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
if (! link_info->keep_memory)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
}
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}
@ -1265,22 +1190,17 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
int count;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
Elf32_External_Sym *esym, *esymend;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
contents = elf_section_data (sec)->this_hdr.contents;
@ -1309,25 +1229,14 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
}
/* Adjust the local symbols defined in this section. */
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
esym = extsyms;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
Elf_External_Sym_Shndx dummy;
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == sec_shndx
&& isym.st_value > addr
&& isym.st_value < toaddr)
{
isym.st_value -= count;
bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) &dummy);
}
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
@ -1354,37 +1263,27 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
/* Return true if a symbol exists at the given address, else return
false. */
static boolean
mn10200_elf_symbol_address_p (abfd, sec, addr)
mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
bfd *abfd;
asection *sec;
Elf_Internal_Sym *isym;
bfd_vma addr;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
unsigned int sec_shndx;
Elf32_External_Sym *esym, *esymend;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
/* Examine all the symbols. */
/* Examine all the local symbols. */
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
esym = (Elf32_External_Sym *) symtab_hdr->contents;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == sec_shndx
&& isym.st_value == addr)
if (isym->st_shndx == sec_shndx
&& isym->st_value == addr)
return true;
}
@ -1419,15 +1318,11 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf32_External_Sym *external_syms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *internal_syms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@ -1439,7 +1334,6 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
(size_t) input_section->_raw_size);
@ -1447,48 +1341,27 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
{
Elf_Internal_Sym *isymp;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
asection **secpp;
Elf32_External_Sym *esym, *esymend;
bfd_size_type amt;
if (symtab_hdr->contents != NULL)
external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
else if (symtab_hdr->sh_info != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
if (external_syms == NULL)
goto error_return;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
goto error_return;
}
if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
goto error_return;
}
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_Internal_Sym);
internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
if (internal_syms == NULL && amt != 0)
goto error_return;
if (symtab_hdr->sh_info != 0)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@ -1496,59 +1369,48 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
if (sections == NULL && amt != 0)
goto error_return;
for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
esym = external_syms, esymend = esym + symtab_hdr->sh_info;
esym < esymend;
++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isymp);
if (isymp->st_shndx == SHN_UNDEF)
if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
else if (isymp->st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else
isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
internal_syms, sections))
isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
if (internal_syms != NULL)
free (internal_syms);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_relocs != elf_section_data (input_section)->relocs)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
}
return data;
error_return:
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_syms != NULL)
free (internal_syms);
if (sections != NULL)
free (sections);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return NULL;
}

File diff suppressed because it is too large Load Diff

173
bfd/elf.c
View File

@ -352,6 +352,107 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex)
return ((char *) hdr->contents) + strindex;
}
/* Read and convert symbols to internal format.
SYMCOUNT specifies the number of symbols to read, starting from
symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
are non-NULL, they are used to store the internal symbols, external
symbols, and symbol section index extensions, respectively. */
Elf_Internal_Sym *
bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset,
intsym_buf, extsym_buf, extshndx_buf)
bfd *ibfd;
Elf_Internal_Shdr *symtab_hdr;
size_t symcount;
size_t symoffset;
Elf_Internal_Sym *intsym_buf;
PTR extsym_buf;
Elf_External_Sym_Shndx *extshndx_buf;
{
Elf_Internal_Shdr *shndx_hdr;
PTR alloc_ext;
const PTR esym;
Elf_External_Sym_Shndx *alloc_extshndx;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
struct elf_backend_data *bed;
size_t extsym_size;
bfd_size_type amt;
file_ptr pos;
if (symcount == 0)
return intsym_buf;
/* Normal syms might have section extension entries. */
shndx_hdr = NULL;
if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
/* Read the symbols. */
alloc_ext = NULL;
alloc_extshndx = NULL;
bed = get_elf_backend_data (ibfd);
extsym_size = bed->s->sizeof_sym;
amt = symcount * extsym_size;
pos = symtab_hdr->sh_offset + symoffset * extsym_size;
if (extsym_buf == NULL)
{
alloc_ext = bfd_malloc (amt);
extsym_buf = alloc_ext;
}
if (extsym_buf == NULL
|| bfd_seek (ibfd, pos, SEEK_SET) != 0
|| bfd_bread (extsym_buf, amt, ibfd) != amt)
{
intsym_buf = NULL;
goto out;
}
if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
extshndx_buf = NULL;
else
{
amt = symcount * sizeof (Elf_External_Sym_Shndx);
pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
if (extshndx_buf == NULL)
{
alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
extshndx_buf = alloc_extshndx;
}
if (extshndx_buf == NULL
|| bfd_seek (ibfd, pos, SEEK_SET) != 0
|| bfd_bread (extshndx_buf, amt, ibfd) != amt)
{
intsym_buf = NULL;
goto out;
}
}
if (intsym_buf == NULL)
{
bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
intsym_buf = (Elf_Internal_Sym *) bfd_malloc (amt);
if (intsym_buf == NULL)
goto out;
}
/* Convert the symbols to internal form. */
isymend = intsym_buf + symcount;
for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
isym < isymend;
esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
(*bed->s->swap_symbol_in) (ibfd, esym, (const PTR) shndx, isym);
out:
if (alloc_ext != NULL)
free (alloc_ext);
if (alloc_extshndx != NULL)
free (alloc_extshndx);
return intsym_buf;
}
/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
sections. The first element is the flags, the rest are section
pointers. */
@ -369,11 +470,7 @@ group_signature (abfd, ghdr)
bfd *abfd;
Elf_Internal_Shdr *ghdr;
{
struct elf_backend_data *bed;
file_ptr pos;
bfd_size_type amt;
Elf_Internal_Shdr *hdr;
Elf_Internal_Shdr *shndx_hdr;
unsigned char esym[sizeof (Elf64_External_Sym)];
Elf_External_Sym_Shndx eshndx;
Elf_Internal_Sym isym;
@ -386,29 +483,10 @@ group_signature (abfd, ghdr)
/* Go read the symbol. */
hdr = &elf_tdata (abfd)->symtab_hdr;
bed = get_elf_backend_data (abfd);
amt = bed->s->sizeof_sym;
pos = hdr->sh_offset + ghdr->sh_info * amt;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread (esym, amt, abfd) != amt)
if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
&isym, esym, &eshndx) == NULL)
return NULL;
/* And possibly the symbol section index extension. */
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (elf_elfsections (abfd) != NULL
&& elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
{
amt = sizeof (Elf_External_Sym_Shndx);
pos = shndx_hdr->sh_offset + ghdr->sh_info * amt;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread ((PTR) &eshndx, amt, abfd) != amt)
return NULL;
}
/* Convert to internal format. */
(*bed->s->swap_symbol_in) (abfd, (const PTR *) &esym, (const PTR *) &eshndx,
&isym);
/* Look up the symbol name. */
iname = isym.st_name;
shindex = hdr->sh_link;
@ -1976,50 +2054,19 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
asection *sec;
unsigned long r_symndx;
{
unsigned char esym_shndx[4];
unsigned int isym_shndx;
Elf_Internal_Shdr *symtab_hdr;
file_ptr pos;
bfd_size_type amt;
unsigned char esym[sizeof (Elf64_External_Sym)];
Elf_External_Sym_Shndx eshndx;
Elf_Internal_Sym isym;
unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
return cache->sec[ent];
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
pos = symtab_hdr->sh_offset;
if (get_elf_backend_data (abfd)->s->sizeof_sym
== sizeof (Elf64_External_Sym))
{
pos += r_symndx * sizeof (Elf64_External_Sym);
pos += offsetof (Elf64_External_Sym, st_shndx);
amt = sizeof (((Elf64_External_Sym *) 0)->st_shndx);
}
else
{
pos += r_symndx * sizeof (Elf32_External_Sym);
pos += offsetof (Elf32_External_Sym, st_shndx);
amt = sizeof (((Elf32_External_Sym *) 0)->st_shndx);
}
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
&isym, esym, &eshndx) == NULL)
return NULL;
isym_shndx = H_GET_16 (abfd, esym_shndx);
if (isym_shndx == SHN_XINDEX)
{
Elf_Internal_Shdr *shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
pos = shndx_hdr->sh_offset;
pos += r_symndx * sizeof (Elf_External_Sym_Shndx);
amt = sizeof (Elf_External_Sym_Shndx);
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
return NULL;
isym_shndx = H_GET_32 (abfd, esym_shndx);
}
}
if (cache->abfd != abfd)
{
@ -2028,10 +2075,10 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
}
cache->indx[ent] = r_symndx;
cache->sec[ent] = sec;
if (isym_shndx < SHN_LORESERVE || isym_shndx > SHN_HIRESERVE)
if (isym.st_shndx < SHN_LORESERVE || isym.st_shndx > SHN_HIRESERVE)
{
asection *s;
s = bfd_section_from_elf_index (abfd, isym_shndx);
s = bfd_section_from_elf_index (abfd, isym.st_shndx);
if (s != NULL)
cache->sec[ent] = s;
}

View File

@ -639,12 +639,9 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
int no_pipeline_knowledge;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
bfd_byte *free_contents = NULL;
Elf32_External_Sym *extsyms = NULL;
Elf32_External_Sym *free_extsyms = NULL;
asection *sec;
struct elf32_arm_link_hash_table *globals;
@ -677,13 +674,15 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Load the relocs. */
irel = (_bfd_elf32_link_read_relocs (abfd, sec, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
internal_relocs
= _bfd_elf32_link_read_relocs (abfd, sec, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false);
BFD_ASSERT (irel != 0);
if (internal_relocs == NULL)
goto error_return;
irelend = irel + sec->reloc_count;
for (; irel < irelend; irel++)
irelend = internal_relocs + sec->reloc_count;
for (irel = internal_relocs; irel < irelend; irel++)
{
long r_type;
unsigned long r_index;
@ -711,37 +710,12 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
if (contents == NULL)
goto error_return;
free_contents = contents;
if (!bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
goto error_return;
}
}
/* Read this BFD's symbols if we haven't done so already. */
if (extsyms == NULL)
{
/* Get cached copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
/* Go get them off disk. */
extsyms = ((Elf32_External_Sym *)
bfd_malloc (symtab_hdr->sh_size));
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| (bfd_bread (extsyms, symtab_hdr->sh_size, abfd)
!= symtab_hdr->sh_size))
goto error_return;
}
}
/* If the relocation is not against a symbol it cannot concern us. */
h = NULL;
@ -781,17 +755,27 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
break;
}
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
contents = NULL;
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
internal_relocs = NULL;
}
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (free_extsyms != NULL)
free (free_extsyms);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}

View File

@ -688,15 +688,10 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
bfd_byte *free_contents = NULL;
Elf32_External_Sym *extsyms = NULL;
Elf32_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
static asection *last_input_section = NULL;
static Elf_Internal_Rela *last_reloc = NULL;
@ -718,7 +713,6 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
sec->_cooked_size = sec->_raw_size;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf32_link_read_relocs
@ -726,8 +720,6 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
if (sec != last_input_section)
last_reloc = NULL;
@ -764,7 +756,6 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@ -773,58 +764,27 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
}
/* Read this BFD's local symbols if we haven't done so already. */
if (extsyms == NULL)
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
/* Get cached copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
/* Go get them off disk. */
bfd_size_type amt;
amt = symtab_hdr->sh_info * sizeof (Elf32_External_Sym);
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, abfd) != amt)
goto error_return;
symtab_hdr->contents = (PTR) extsyms;
}
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
shndx_hdr->contents = (PTR) shndx_buf;
}
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
/* A local symbol. */
Elf_Internal_Sym *isym;
asection *sym_sec;
/* A local symbol. */
esym = extsyms + ELF32_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
symval = (isym.st_value
isym = isymbuf + ELF64_R_SYM (irel->r_info);
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
@ -884,12 +844,8 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* If the previous instruction conditionally jumped around
this instruction, we may be able to reverse the condition
@ -904,26 +860,17 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
&& ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
&& ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
{
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
bfd_vma last_value;
asection *last_sym_sec;
Elf_Internal_Sym last_symbol;
Elf_Internal_Sym *last_sym;
/* We will need to examine the symbol used by the
previous relocation. */
esym = extsyms + ELF32_R_SYM (last_reloc->r_info);
shndx = shndx_buf;
if (shndx != NULL)
shndx += ELF32_R_SYM (last_reloc->r_info);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym,
(const PTR) shndx,
&last_symbol);
last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
last_sym_sec
= bfd_section_from_elf_index (abfd, last_symbol.st_shndx);
last_value = (last_symbol.st_value
= bfd_section_from_elf_index (abfd, last_sym->st_shndx);
last_value = (last_sym->st_value
+ last_sym_sec->output_section->vma
+ last_sym_sec->output_offset);
@ -1015,12 +962,8 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Get the opcode. */
code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
@ -1076,12 +1019,8 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Get the opcode. */
code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
@ -1138,12 +1077,8 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Get the opcode. */
code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
@ -1194,12 +1129,8 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Get the opcode. */
code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
@ -1230,56 +1161,43 @@ elf32_h8_relax_section (abfd, sec, link_info, again)
}
}
if (free_relocs != NULL)
{
free (free_relocs);
free_relocs = NULL;
}
if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
free (isymbuf);
else
symtab_hdr->contents = (unsigned char *) isymbuf;
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
elf_section_data (sec)->this_hdr.contents = contents;
}
free_contents = NULL;
}
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
if (! link_info->keep_memory)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
}
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}
@ -1293,22 +1211,17 @@ elf32_h8_relax_delete_bytes (abfd, sec, addr, count)
int count;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
bfd_vma toaddr;
Elf32_External_Sym *esym, *esymend;
Elf_External_Sym_Shndx *shndx;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
contents = elf_section_data (sec)->this_hdr.contents;
@ -1337,25 +1250,15 @@ elf32_h8_relax_delete_bytes (abfd, sec, addr, count)
}
/* Adjust the local symbols defined in this section. */
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
esym = extsyms;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
isymend = isym + symtab_hdr->sh_info;
for (; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
Elf_External_Sym_Shndx dummy;
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == sec_shndx
&& isym.st_value > addr
&& isym.st_value < toaddr)
{
isym.st_value -= count;
bfd_elf32_swap_symbol_out (abfd, &isym, esym, &dummy);
}
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
@ -1388,10 +1291,9 @@ elf32_h8_symbol_address_p (abfd, sec, addr)
bfd_vma addr;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
unsigned int sec_shndx;
Elf32_External_Sym *esym, *esymend;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
@ -1400,19 +1302,12 @@ elf32_h8_symbol_address_p (abfd, sec, addr)
/* Examine all the symbols. */
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
esym = (Elf32_External_Sym *) symtab_hdr->contents;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
isymend = isym + symtab_hdr->sh_info;
for (; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == sec_shndx
&& isym.st_value == addr)
if (isym->st_shndx == sec_shndx
&& isym->st_value == addr)
return true;
}
@ -1447,15 +1342,11 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf32_External_Sym *external_syms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *internal_syms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@ -1467,7 +1358,6 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
(size_t) input_section->_raw_size);
@ -1475,48 +1365,26 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
{
Elf_Internal_Sym *isymp;
asection **secpp;
Elf32_External_Sym *esym, *esymend;
Elf_Internal_Sym *isym, *isymend;
bfd_size_type amt;
if (symtab_hdr->contents != NULL)
external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
else if (symtab_hdr->sh_info != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
if (external_syms == NULL)
goto error_return;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
goto error_return;
}
if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
goto error_return;
}
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_Internal_Sym);
internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
if (internal_syms == NULL && amt != 0)
goto error_return;
if (symtab_hdr->sh_info != 0)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@ -1524,59 +1392,48 @@ elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
if (sections == NULL && amt != 0)
goto error_return;
for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
esym = external_syms, esymend = esym + symtab_hdr->sh_info;
esym < esymend;
++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isymp);
if (isymp->st_shndx == SHN_UNDEF)
if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
else if (isymp->st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else
isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
internal_syms, sections))
isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
if (internal_syms != NULL)
free (internal_syms);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_relocs != elf_section_data (input_section)->relocs)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
}
return data;
error_return:
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_syms != NULL)
free (internal_syms);
if (sections != NULL)
free (sections);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return NULL;
}

View File

@ -2770,69 +2770,26 @@ get_local_syms (output_bfd, input_bfd, info)
input_bfd = input_bfd->link_next, bfd_indx++)
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Sym *isym;
Elf32_External_Sym *ext_syms, *esym, *end_sy;
Elf_External_Sym_Shndx *shndx_buf, *shndx;
bfd_size_type sec_size;
/* We'll need the symbol table in a second. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (symtab_hdr->sh_info == 0)
continue;
/* We need an array of the local symbols attached to the input bfd.
Unfortunately, we're going to have to read & swap them in. */
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf_Internal_Sym);
local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size);
/* We need an array of the local symbols attached to the input bfd. */
local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
if (local_syms == NULL)
{
local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
/* Cache them for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) local_syms;
}
if (local_syms == NULL)
return -1;
all_local_syms[bfd_indx] = local_syms;
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf32_External_Sym);
ext_syms = (Elf32_External_Sym *) bfd_malloc (sec_size);
if (ext_syms == NULL)
return -1;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) ext_syms, sec_size, input_bfd) != sec_size)
{
error_ret_free_ext_syms:
free (ext_syms);
return -1;
}
shndx_buf = NULL;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (sec_size);
if (shndx_buf == NULL)
goto error_ret_free_ext_syms;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, sec_size, input_bfd) != sec_size)
{
free (shndx_buf);
goto error_ret_free_ext_syms;
}
}
/* Swap the local symbols in. */
for (esym = ext_syms, end_sy = esym + symtab_hdr->sh_info,
isym = local_syms, shndx = shndx_buf;
esym < end_sy;
esym++, isym++, shndx = (shndx ? shndx + 1 : NULL))
bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isym);
/* Now we can free the external symbols. */
free (shndx_buf);
free (ext_syms);
if (info->shared && htab->multi_subspace)
{
@ -2927,7 +2884,6 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size,
bfd_size_type stub_group_size;
boolean stubs_always_before_branch;
boolean stub_changed;
boolean ret = 0;
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
/* Stash our params away. */
@ -3186,15 +3142,12 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size,
stub_changed = false;
}
ret = true;
free (htab->all_local_syms);
return true;
error_ret_free_local:
while (htab->bfd_count-- > 0)
if (htab->all_local_syms[htab->bfd_count])
free (htab->all_local_syms[htab->bfd_count]);
free (htab->all_local_syms);
return ret;
return false;
}
/* For a final link, this function is called after we have sized the

View File

@ -1337,13 +1337,10 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
/* The Rela structures are used here because that's what
_bfd_elf32_link_read_relocs uses [for convenience - it sets the addend
field to 0]. */
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
bfd_byte *free_contents = NULL;
Elf32_External_Sym *extsyms = NULL;
Elf32_External_Sym *free_extsyms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* Assume nothing changes. */
*again = false;
@ -1371,8 +1368,6 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
@ -1397,7 +1392,6 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@ -1405,39 +1399,28 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
}
}
/* Read this BFD's symbols if we haven't done so already. */
if (extsyms == NULL)
/* Read this BFD's local symbols if we haven't done so already. */
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
/* Get cached copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
bfd_size_type amt = symtab_hdr->sh_size;
/* Go get them off disk. */
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (extsyms, amt, abfd) != amt)
goto error_return;
}
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
Elf_Internal_Sym isym;
/* A local symbol. */
Elf_Internal_Sym *isym;
asection *sym_sec;
/* A local symbol. */
bfd_elf32_swap_symbol_in (abfd,
extsyms + ELF32_R_SYM (irel->r_info),
&isym);
sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
symval = (isym.st_value
isym = isymbuf + ELF32_R_SYM (irel->r_info),
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
@ -1599,13 +1582,8 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
symtab_hdr->contents = (bfd_byte *) extsyms;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Delete TO_DELETE bytes of data. */
if (!m32r_elf_relax_delete_bytes (abfd, sec,
@ -1633,45 +1611,47 @@ m32r_elf_relax_section (abfd, sec, link_info, again)
/* loop to try the next reloc */
}
if (free_relocs != NULL)
{
free (free_relocs);
free_relocs = NULL;
}
if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
elf_section_data (sec)->this_hdr.contents = contents;
}
free_contents = NULL;
}
if (free_extsyms != NULL)
{
if (! link_info->keep_memory)
free (free_extsyms);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = extsyms;
}
free_extsyms = NULL;
}
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (free_extsyms != NULL)
free (free_extsyms);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}
@ -1685,17 +1665,15 @@ m32r_elf_relax_delete_bytes (abfd, sec, addr, count)
int count;
{
Elf_Internal_Shdr *symtab_hdr;
Elf32_External_Sym *extsyms;
int shndx, index;
int shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
Elf32_External_Sym *esym, *esymend;
struct elf_link_hash_entry *sym_hash;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
Elf_Internal_Sym *isym, *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@ -1724,40 +1702,32 @@ m32r_elf_relax_delete_bytes (abfd, sec, addr, count)
}
/* Adjust the local symbols defined in this section. */
esym = extsyms;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
bfd_elf32_swap_symbol_in (abfd, esym, &isym);
if (isym.st_shndx == shndx
&& isym.st_value > addr
&& isym.st_value < toaddr)
{
isym.st_value -= count;
bfd_elf32_swap_symbol_out (abfd, &isym, esym);
}
if (isym->st_shndx == shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
esym = extsyms + symtab_hdr->sh_info;
esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
for (index = 0; esym < esymend; esym++, index++)
symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
- symtab_hdr->sh_info);
sym_hashes = elf_sym_hashes (abfd);
end_hashes = sym_hashes + symcount;
for (; sym_hashes < end_hashes; sym_hashes++)
{
Elf_Internal_Sym isym;
struct elf_link_hash_entry *sym_hash = *sym_hashes;
bfd_elf32_swap_symbol_in (abfd, esym, &isym);
sym_hash = elf_sym_hashes (abfd)[index];
if (isym.st_shndx == shndx
&& ((sym_hash)->root.type == bfd_link_hash_defined
|| (sym_hash)->root.type == bfd_link_hash_defweak)
&& (sym_hash)->root.u.def.section == sec
&& (sym_hash)->root.u.def.value > addr
&& (sym_hash)->root.u.def.value < toaddr)
if ((sym_hash->root.type == bfd_link_hash_defined
|| sym_hash->root.type == bfd_link_hash_defweak)
&& sym_hash->root.u.def.section == sec
&& sym_hash->root.u.def.value > addr
&& sym_hash->root.u.def.value < toaddr)
{
(sym_hash)->root.u.def.value -= count;
sym_hash->root.u.def.value -= count;
}
}
@ -1782,8 +1752,7 @@ m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf32_External_Sym *external_syms = NULL;
Elf_Internal_Sym *internal_syms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
bfd_size_type amt;
/* We only need to handle the case of relaxing, or of having a
@ -1807,31 +1776,22 @@ m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
asection **secpp;
Elf32_External_Sym *esym, *esymend;
if (symtab_hdr->contents != NULL)
external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
if (external_syms == NULL && symtab_hdr->sh_info > 0)
goto error_return;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (external_syms, amt, input_bfd) != amt)
goto error_return;
}
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_Internal_Sym);
internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
if (internal_syms == NULL && symtab_hdr->sh_info > 0)
goto error_return;
if (symtab_hdr->sh_info != 0)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@ -1839,61 +1799,50 @@ m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
if (sections == NULL && symtab_hdr->sh_info > 0)
goto error_return;
isymp = internal_syms;
secpp = sections;
esym = external_syms;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; ++esym, ++isymp, ++secpp)
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
if (isymp->st_shndx == SHN_UNDEF)
if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
else if (isymp->st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else if (isymp->st_shndx == SHN_M32R_SCOMMON)
else if (isym->st_shndx == SHN_M32R_SCOMMON)
isec = &m32r_elf_scom_section;
else
isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! m32r_elf_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
internal_syms, sections))
isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
sections = NULL;
if (internal_syms != NULL)
free (internal_syms);
internal_syms = NULL;
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
external_syms = NULL;
if (internal_relocs != elf_section_data (input_section)->relocs)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
internal_relocs = NULL;
}
return data;
error_return:
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_syms != NULL)
free (internal_syms);
if (sections != NULL)
free (sections);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return NULL;
}

View File

@ -2111,12 +2111,8 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
char **errmsg;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
Elf32_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Sym *isymbuf = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *p;
bfd_size_type amt;
@ -2129,40 +2125,6 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
return true;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Read this BFD's symbols if we haven't done so already, or get the cached
copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
/* Go get them off disk. */
amt = symtab_hdr->sh_info * sizeof (Elf32_External_Sym);
if (info->keep_memory)
extsyms = (Elf32_External_Sym *) bfd_alloc (abfd, amt);
else
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
if (! info->keep_memory)
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (extsyms, amt, abfd) != amt)
goto error_return;
if (info->keep_memory)
symtab_hdr->contents = (unsigned char *) extsyms;
}
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
}
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf32_link_read_relocs
@ -2170,8 +2132,6 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! info->keep_memory)
free_relocs = internal_relocs;
amt = (bfd_size_type) datasec->reloc_count * 12;
relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
@ -2202,17 +2162,23 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
/* Get the target section referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
/* A local symbol. */
esym = extsyms + ELF32_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
Elf_Internal_Sym *isym;
targetsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
/* Read this BFD's local symbols if we haven't done so already. */
if (isymbuf == NULL)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
isym = isymbuf + ELF32_R_SYM (irel->r_info);
targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
}
else
{
@ -2236,21 +2202,19 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
strncpy (p + 4, targetsec->output_section->name, 8);
}
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (free_relocs != NULL)
free (free_relocs);
if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (free_relocs != NULL)
free (free_relocs);
if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}

View File

@ -1786,15 +1786,10 @@ bfd_mips_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
char **errmsg;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
Elf32_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Sym *isymbuf = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *p;
bfd_size_type amt;
BFD_ASSERT (! info->relocateable);
@ -1803,41 +1798,17 @@ bfd_mips_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
if (datasec->reloc_count == 0)
return true;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Read this BFD's symbols if we haven't done so already, or get the cached
copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
if (symtab_hdr->sh_info != 0)
{
/* Go get them off disk. */
if (info->keep_memory)
extsyms = ((Elf32_External_Sym *)
bfd_alloc (abfd, symtab_hdr->sh_size));
else
extsyms = ((Elf32_External_Sym *)
bfd_malloc (symtab_hdr->sh_size));
if (extsyms == NULL)
goto error_return;
if (! info->keep_memory)
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| (bfd_bread (extsyms, symtab_hdr->sh_size, abfd)
!= symtab_hdr->sh_size))
goto error_return;
if (info->keep_memory)
symtab_hdr->contents = (unsigned char *) extsyms;
}
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
@ -1847,8 +1818,6 @@ bfd_mips_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! info->keep_memory)
free_relocs = internal_relocs;
relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12);
if (relsec->contents == NULL)
@ -1879,17 +1848,11 @@ bfd_mips_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
/* Get the target section referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
Elf_Internal_Sym *isym;
/* A local symbol. */
esym = extsyms + ELF32_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
targetsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
isym = isymbuf + ELF32_R_SYM (irel->r_info);
targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
}
else
{
@ -1926,21 +1889,21 @@ bfd_mips_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
strncpy (p + 4, targetsec->output_section->name, 8);
}
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (free_relocs != NULL)
free (free_relocs);
if (internal_relocs != NULL
&& elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return true;
error_return:
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (free_relocs != NULL)
free (free_relocs);
if (internal_relocs != NULL
&& elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return false;
}

View File

@ -1546,7 +1546,6 @@ sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
{
static bfd_vma last_addr;
static asection *last_symbol_section;
bfd_byte *free_contents = NULL;
bfd_byte *start_ptr, *ptr, *last_ptr;
int diff, cum_diff;
bfd_signed_vma x;
@ -1581,7 +1580,6 @@ sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
contents = (bfd_byte *) bfd_malloc (symbol_section->_raw_size);
if (contents == NULL)
return bfd_reloc_outofrange;
free_contents = contents;
if (! bfd_get_section_contents (input_bfd, symbol_section, contents,
(file_ptr) 0,
symbol_section->_raw_size))
@ -1621,8 +1619,9 @@ sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
end = start0;
}
if (free_contents)
free (free_contents);
if (contents != NULL
&& elf_section_data (symbol_section)->this_hdr.contents != contents)
free (contents);
insn = bfd_get_16 (input_bfd, contents + addr);
@ -1888,16 +1887,11 @@ sh_elf_relax_section (abfd, sec, link_info, again)
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
boolean have_code;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
bfd_byte *free_contents = NULL;
Elf32_External_Sym *extsyms = NULL;
Elf32_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
*again = false;
@ -1920,15 +1914,12 @@ sh_elf_relax_section (abfd, sec, link_info, again)
sec->_cooked_size = sec->_raw_size;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
internal_relocs = (_bfd_elf32_link_read_relocs
(abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
have_code = false;
@ -1956,7 +1947,6 @@ sh_elf_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@ -2021,56 +2011,25 @@ sh_elf_relax_section (abfd, sec, link_info, again)
}
/* Read this BFD's symbols if we haven't done so already. */
if (extsyms == NULL)
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, abfd) != amt)
goto error_return;
symtab_hdr->contents = (bfd_byte *) extsyms;
}
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
shndx_hdr->contents = (bfd_byte *) shndx_buf;
}
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
{
/* A local symbol. */
Elf32_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
Elf_Internal_Sym *isym;
esym = extsyms + ELF32_R_SYM (irelfn->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irelfn->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx
isym = isymbuf + ELF32_R_SYM (irelfn->r_info);
if (isym->st_shndx
!= (unsigned int) _bfd_elf_section_from_bfd_section (abfd, sec))
{
((*_bfd_error_handler)
@ -2079,7 +2038,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
continue;
}
symval = (isym.st_value
symval = (isym->st_value
+ sec->output_section->vma
+ sec->output_offset);
}
@ -2130,12 +2089,8 @@ sh_elf_relax_section (abfd, sec, link_info, again)
the linker is run. */
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
/* Replace the jsr with a bsr. */
@ -2240,7 +2195,6 @@ sh_elf_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@ -2255,22 +2209,28 @@ sh_elf_relax_section (abfd, sec, link_info, again)
if (swapped)
{
elf_section_data (sec)->relocs = internal_relocs;
free_relocs = NULL;
elf_section_data (sec)->this_hdr.contents = contents;
free_contents = NULL;
free_extsyms = NULL;
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
@ -2278,38 +2238,22 @@ sh_elf_relax_section (abfd, sec, link_info, again)
}
}
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
if (! link_info->keep_memory)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
}
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}
@ -2326,25 +2270,19 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
int count;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
Elf32_External_Sym *esym, *esymend;
Elf_External_Sym_Shndx *shndx_buf, *shndx;
Elf_Internal_Sym *isymbuf, *isym, *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
asection *o;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@ -2392,7 +2330,6 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
bfd_vma nraddr, stop;
bfd_vma start = 0;
int insn = 0;
Elf_Internal_Sym sym;
int off, adjust, oinsn;
bfd_signed_vma voff = 0;
boolean overflow;
@ -2446,19 +2383,15 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
range to be adjusted, and hence must be changed. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
esym = extsyms + ELF32_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym,
(const PTR) shndx, &sym);
if (sym.st_shndx == sec_shndx
&& (sym.st_value <= addr
|| sym.st_value >= toaddr))
isym = isymbuf + ELF32_R_SYM (irel->r_info);
if (isym->st_shndx == sec_shndx
&& (isym->st_value <= addr
|| isym->st_value >= toaddr))
{
bfd_vma val;
val = bfd_get_32 (abfd, contents + nraddr);
val += sym.st_value;
val += isym->st_value;
if (val > addr && val < toaddr)
bfd_put_32 (abfd, val - count, contents + nraddr);
}
@ -2651,8 +2584,6 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
irelscanend = internal_relocs + o->reloc_count;
for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
{
Elf_Internal_Sym sym;
/* Dwarf line numbers use R_SH_SWITCH32 relocs. */
if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_SWITCH32)
{
@ -2710,14 +2641,10 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
continue;
esym = extsyms + ELF32_R_SYM (irelscan->r_info);
shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irelscan->r_info) : 0);
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&sym);
if (sym.st_shndx == sec_shndx
&& (sym.st_value <= addr
|| sym.st_value >= toaddr))
isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
if (isym->st_shndx == sec_shndx
&& (isym->st_value <= addr
|| isym->st_value >= toaddr))
{
bfd_vma val;
@ -2743,7 +2670,7 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
}
val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
val += sym.st_value;
val += isym->st_value;
if (val > addr && val < toaddr)
bfd_put_32 (abfd, val - count,
ocontents + irelscan->r_offset);
@ -2752,24 +2679,13 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
}
/* Adjust the local symbols defined in this section. */
shndx = shndx_buf;
esym = extsyms;
esymend = esym + symtab_hdr->sh_info;
for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf; isym < isymend; isym++)
{
Elf_Internal_Sym isym;
Elf_External_Sym_Shndx dummy;
bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == sec_shndx
&& isym.st_value > addr
&& isym.st_value < toaddr)
{
isym.st_value -= count;
bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) &dummy);
}
if (isym->st_shndx == sec_shndx
&& isym->st_value > addr
&& isym->st_value < toaddr)
isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
@ -4844,15 +4760,11 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf32_External_Sym *external_syms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *internal_syms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@ -4864,7 +4776,6 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
(size_t) input_section->_raw_size);
@ -4872,48 +4783,26 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
{
Elf_Internal_Sym *isymp;
asection **secpp;
Elf32_External_Sym *esym, *esymend;
Elf_Internal_Sym *isym, *isymend;
bfd_size_type amt;
if (symtab_hdr->contents != NULL)
external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
else if (symtab_hdr->sh_info != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
if (external_syms == NULL)
goto error_return;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
goto error_return;
}
if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
goto error_return;
}
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_Internal_Sym);
internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
if (internal_syms == NULL && amt != 0)
goto error_return;
if (symtab_hdr->sh_info != 0)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@ -4921,59 +4810,48 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
if (sections == NULL && amt != 0)
goto error_return;
for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
esym = external_syms, esymend = esym + symtab_hdr->sh_info;
esym < esymend;
++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isymp);
if (isymp->st_shndx == SHN_UNDEF)
if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
else if (isymp->st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else
isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! sh_elf_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
internal_syms, sections))
isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
if (internal_syms != NULL)
free (internal_syms);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_relocs != elf_section_data (input_section)->relocs)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
}
return data;
error_return:
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
if (shndx_buf != NULL)
free (shndx_buf);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_syms != NULL)
free (internal_syms);
if (sections != NULL)
free (sections);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
return NULL;
}

View File

@ -586,88 +586,51 @@ xstormy16_elf_relax_section (dynobj, splt, info, again)
&relax_plt_data);
/* Likewise for local symbols, though that's somewhat less convenient
as we have walk the list of input bfds and swap in symbol data. */
as we have to walk the list of input bfds and swap in symbol data. */
for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
{
bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf32_External_Sym *extsyms;
Elf_External_Sym_Shndx *shndx_buf;
Elf_Internal_Sym *isymbuf = NULL;
unsigned int idx;
if (! local_plt_offsets)
continue;
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
if (symtab_hdr->contents != NULL)
extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
else
if (symtab_hdr->sh_info != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf32_External_Sym);
extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
return false;
if (bfd_seek (ibfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, ibfd) != amt)
{
error_ret_free_extsyms:
free (extsyms);
return false;
}
}
shndx_buf = NULL;
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_ret_free_extsyms;
if (bfd_seek (ibfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, ibfd) != amt)
{
free (shndx_buf);
goto error_ret_free_extsyms;
}
shndx_hdr->contents = (bfd_byte *) shndx_buf;
}
for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
{
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
Elf_Internal_Sym *isym;
asection *tsec;
bfd_vma address;
if (local_plt_offsets[idx] == (bfd_vma) -1)
continue;
shndx = shndx_buf;
if (shndx != NULL)
shndx += idx;
bfd_elf32_swap_symbol_in (ibfd, (const PTR) (extsyms + idx),
(const PTR) shndx, &isym);
if (isym.st_shndx == SHN_UNDEF)
isym = &isymbuf[idx];
if (isym->st_shndx == SHN_UNDEF)
continue;
else if (isym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
tsec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
tsec = bfd_com_section_ptr;
else
tsec = bfd_section_from_elf_index (ibfd, isym.st_shndx);
tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
address = (tsec->output_section->vma
+ tsec->output_offset
+ isym.st_value);
+ isym->st_value);
if (address <= 0xffff)
{
local_plt_offsets[idx] = -1;
@ -676,11 +639,17 @@ xstormy16_elf_relax_section (dynobj, splt, info, again)
}
}
if (shndx_buf != NULL)
free (shndx_buf);
if ((Elf32_External_Sym *) symtab_hdr->contents != extsyms)
free (extsyms);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! info->keep_memory)
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
}
/* If we changed anything, walk the symbols again to reallocate

View File

@ -2037,14 +2037,9 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *free_contents = NULL;
Elf64_External_Sym *extsyms;
Elf64_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
struct alpha_elf_got_entry **local_got_entries;
struct alpha_relax_info info;
struct elf_link_tls_segment tls_segment;
@ -2070,9 +2065,7 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
(abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
return false;
memset(&info, 0, sizeof (info));
info.abfd = abfd;
@ -2101,41 +2094,12 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (info.contents == NULL)
goto error_return;
free_contents = info.contents;
if (! bfd_get_section_contents (abfd, sec, info.contents,
(file_ptr) 0, sec->_raw_size))
goto error_return;
}
/* Read this BFD's symbols. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
else
{
bfd_size_type amt = symtab_hdr->sh_info * sizeof (Elf64_External_Sym);
extsyms = (Elf64_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, abfd) != amt)
goto error_return;
}
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
}
/* Compute the TLS segment information. The version normally found in
elf_hash_table (link_info)->tls_segment isn't built until final_link.
??? Probably should look into extracting this into a common function. */
@ -2144,7 +2108,6 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
for (irel = internal_relocs; irel < irelend; irel++)
{
bfd_vma symval;
Elf_Internal_Sym isym;
struct alpha_elf_got_entry *gotent;
unsigned long r_type = ELF64_R_TYPE (irel->r_info);
@ -2167,26 +2130,34 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
/* A local symbol. */
Elf64_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *isym;
esym = extsyms + ELF64_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELF64_R_SYM (irel->r_info) : 0);
bfd_elf64_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == SHN_UNDEF)
/* Read this BFD's local symbols. */
if (isymbuf == NULL)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
isym = isymbuf + ELF64_R_SYM (irel->r_info);
if (isym->st_shndx == SHN_UNDEF)
continue;
else if (isym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
info.tsec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
info.tsec = bfd_com_section_ptr;
else
info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
info.h = NULL;
info.other = isym.st_other;
info.other = isym->st_other;
info.first_gotent = &local_got_entries[ELF64_R_SYM(irel->r_info)];
symval = isym.st_value;
symval = isym->st_value;
}
else
{
@ -2281,17 +2252,23 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
if (!elf64_alpha_size_rela_got_section (link_info))
return false;
if (info.changed_relocs)
elf_section_data (sec)->relocs = internal_relocs;
else if (free_relocs != NULL)
free (free_relocs);
if (info.changed_contents)
elf_section_data (sec)->this_hdr.contents = info.contents;
else if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
if (!link_info->keep_memory)
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (info.contents != NULL
&& elf_section_data (sec)->this_hdr.contents != info.contents)
{
if (!info.changed_contents && !link_info->keep_memory)
free (info.contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
@ -2299,18 +2276,12 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
}
}
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
if (elf_section_data (sec)->relocs != internal_relocs)
{
if (! link_info->keep_memory)
free (free_extsyms);
if (!info.changed_relocs)
free (internal_relocs);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) extsyms;
}
elf_section_data (sec)->relocs = internal_relocs;
}
*again = info.changed_contents || info.changed_relocs;
@ -2318,14 +2289,15 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
if (info.contents != NULL
&& elf_section_data (sec)->this_hdr.contents != info.contents)
free (info.contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}

View File

@ -591,7 +591,6 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
struct elf64_hppa_link_hash_table *hppa_info;
const Elf_Internal_Rela *relend;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
const Elf_Internal_Rela *rel;
asection *dlt, *plt, *stubs;
char *buf;
@ -613,15 +612,14 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* If necessary, build a new table holding section symbols indices
for this BFD. This is disgusting. */
for this BFD. */
if (info->shared && hppa_info->section_syms_bfd != abfd)
{
unsigned long i;
unsigned int highest_shndx;
Elf_Internal_Sym *local_syms, *isym;
Elf64_External_Sym *ext_syms, *esym;
Elf_External_Sym_Shndx *shndx_buf, *shndx;
Elf_Internal_Sym *local_syms = NULL;
Elf_Internal_Sym *isym, *isymend;
bfd_size_type amt;
/* We're done with the old cache of section index to section symbol
@ -632,72 +630,27 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
if (hppa_info->section_syms)
free (hppa_info->section_syms);
/* Allocate memory for the internal and external symbols. */
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_Internal_Sym);
local_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
if (local_syms == NULL)
return false;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf64_External_Sym);
ext_syms = (Elf64_External_Sym *) bfd_malloc (amt);
if (ext_syms == NULL)
/* Read this BFD's local symbols. */
if (symtab_hdr->sh_info != 0)
{
free (local_syms);
return false;
local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
if (local_syms == NULL)
local_syms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (local_syms == NULL)
return false;
}
/* Read in the local symbols. */
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (ext_syms, amt, abfd) != amt)
{
free (ext_syms);
free (local_syms);
return false;
}
shndx_buf = NULL;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
{
free (ext_syms);
free (local_syms);
return false;
}
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (shndx_buf, amt, abfd) != amt)
{
free (shndx_buf);
free (ext_syms);
free (local_syms);
return false;
}
}
/* Swap in the local symbols, also record the highest section index
referenced by the local symbols. */
/* Record the highest section index referenced by the local symbols. */
highest_shndx = 0;
for (i = 0, isym = local_syms, esym = ext_syms, shndx = shndx_buf;
i < symtab_hdr->sh_info;
i++, esym++, isym++, shndx = (shndx != NULL ? shndx + 1 : NULL))
isymend = local_syms + symtab_hdr->sh_info;
for (isym = local_syms; isym < isymend; isym++)
{
bfd_elf64_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
isym);
if (isym->st_shndx > highest_shndx)
highest_shndx = isym->st_shndx;
}
/* Now we can free the external symbols. */
free (shndx_buf);
free (ext_syms);
/* Allocate an array to hold the section index to section symbol index
mapping. Bump by one since we start counting at zero. */
highest_shndx++;
@ -707,14 +660,24 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
/* Now walk the local symbols again. If we find a section symbol,
record the index of the symbol into the section_syms array. */
for (isym = local_syms, i = 0; i < symtab_hdr->sh_info; i++, isym++)
for (i = 0, isym = local_syms; isym < isymend; i++, isym++)
{
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
hppa_info->section_syms[isym->st_shndx] = i;
}
/* We are finished with the local symbols. Get rid of them. */
free (local_syms);
/* We are finished with the local symbols. */
if (local_syms != NULL
&& symtab_hdr->contents != (unsigned char *) local_syms)
{
if (! info->keep_memory)
free (local_syms);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) local_syms;
}
}
/* Record which BFD we built the section_syms mapping for. */
hppa_info->section_syms_bfd = abfd;

View File

@ -2305,9 +2305,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
asection *bpo_gregs_section = NULL;
struct bpo_greg_section_info *gregdata;
@ -2316,9 +2314,7 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
elf_section_data (sec)->tdata;
size_t bpono;
bfd *bpo_greg_owner;
Elf64_External_Sym *extsyms = NULL;
Elf64_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* Assume nothing changes. */
*again = false;
@ -2341,7 +2337,6 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
return true;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
bpo_greg_owner = (bfd *) link_info->base_file;
bpo_gregs_section = bpodata->bpo_greg_section;
@ -2357,8 +2352,6 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
link_info->keep_memory);
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
@ -2369,70 +2362,35 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
if (ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_BASE_PLUS_OFFSET)
continue;
/* Read this BFD's symbols if we haven't done so already. */
if (extsyms == NULL)
{
/* Get cached copy if it exists. */
if (symtab_hdr->contents != NULL)
extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
else
{
/* Go get them off disk. */
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf64_External_Sym);
extsyms = (Elf64_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) extsyms, amt, abfd) != amt)
goto error_return;
symtab_hdr->contents = (bfd_byte *) extsyms;
}
/* If >64k sections, this presumable happens. No test-case. */
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
goto error_return;
shndx_hdr->contents = (bfd_byte *) shndx_buf;
}
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
/* A local symbol. */
Elf64_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym isym;
Elf_Internal_Sym *isym;
asection *sym_sec;
esym = extsyms + ELF64_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf
? ELF64_R_SYM (irel->r_info) : 0);
bfd_elf64_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
/* Read this BFD's local symbols if we haven't already. */
if (isymbuf == NULL)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == 0)
goto error_return;
}
if (isym.st_shndx == SHN_UNDEF)
isym = isymbuf + ELF64_R_SYM (irel->r_info);
if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
else if (isym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
symval = (isym.st_value
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
@ -2529,40 +2487,29 @@ mmix_elf_relax_section (abfd, sec, link_info, again)
bpo_gregs_section->_cooked_size = (regindex + 1) * 8;
}
if (free_relocs != NULL)
free (free_relocs);
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
{
if (! link_info->keep_memory)
free (isymbuf);
else
{
symtab_hdr->contents = NULL;
free (free_extsyms);
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (shndx_buf != NULL)
{
shndx_hdr->contents = NULL;
free (shndx_buf);
}
if (free_extsyms != NULL)
{
symtab_hdr->contents = NULL;
free (free_extsyms);
}
if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
free (isymbuf);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}

View File

@ -2036,10 +2036,8 @@ struct ppc_link_hash_table
} *stub_group;
/* Assorted information used by ppc64_elf_size_stubs. */
unsigned int bfd_count;
int top_index;
asection **input_list;
Elf_Internal_Sym **all_local_syms;
/* Short-cuts to get to dynamic linker sections. */
asection *sgot;
@ -2134,8 +2132,6 @@ static boolean ppc_size_one_stub
PARAMS ((struct bfd_hash_entry *, PTR));
static void group_sections
PARAMS ((struct ppc_link_hash_table *, bfd_size_type, boolean));
static boolean get_local_syms
PARAMS ((bfd *, struct ppc_link_hash_table *));
static boolean ppc64_elf_fake_sections
PARAMS ((bfd *, Elf64_Internal_Shdr *, asection *));
static boolean ppc64_elf_relocate_section
@ -2295,7 +2291,6 @@ ppc64_elf_link_hash_table_create (abfd)
htab->add_stub_section = NULL;
htab->layout_sections_again = NULL;
htab->stub_group = NULL;
htab->all_local_syms = NULL;
htab->sgot = NULL;
htab->srelgot = NULL;
htab->splt = NULL;
@ -3689,7 +3684,6 @@ edit_opd (obfd, info)
{
bfd *ibfd;
unsigned int bfd_indx;
struct ppc_link_hash_table *htab = ppc_hash_table (info);
for (bfd_indx = 0, ibfd = info->input_bfds;
ibfd != NULL;
@ -3698,6 +3692,7 @@ edit_opd (obfd, info)
asection *sec;
Elf_Internal_Rela *relstart, *rel, *relend;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Sym *local_syms;
struct elf_link_hash_entry **sym_hashes;
bfd_vma offset;
long *adjust;
@ -3718,6 +3713,7 @@ edit_opd (obfd, info)
if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0)
continue;
local_syms = NULL;
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (ibfd);
@ -3793,7 +3789,17 @@ edit_opd (obfd, info)
}
else
{
sym = htab->all_local_syms[bfd_indx] + r_symndx;
if (local_syms == NULL)
{
local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
if (local_syms == NULL)
local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (local_syms == NULL)
goto error_free_rel;
}
sym = local_syms + r_symndx;
if ((sym->st_shndx != SHN_UNDEF
&& sym->st_shndx < SHN_LORESERVE)
|| sym->st_shndx > SHN_HIRESERVE)
@ -3833,11 +3839,18 @@ edit_opd (obfd, info)
if ((sec->flags & SEC_IN_MEMORY) == 0)
{
bfd_byte *loc = bfd_alloc (ibfd, sec->_raw_size);
if (loc == NULL)
return false;
if (! bfd_get_section_contents (ibfd, sec, loc, (bfd_vma) 0,
sec->_raw_size))
return false;
if (loc == NULL
|| !bfd_get_section_contents (ibfd, sec, loc, (bfd_vma) 0,
sec->_raw_size))
{
if (local_syms != NULL
&& symtab_hdr->contents != (unsigned char *) local_syms)
free (local_syms);
error_free_rel:
if (elf_section_data (sec)->relocs != relstart)
free (relstart);
return false;
}
sec->contents = loc;
sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
}
@ -3874,7 +3887,7 @@ edit_opd (obfd, info)
}
else
{
sym = htab->all_local_syms[bfd_indx] + r_symndx;
sym = local_syms + r_symndx;
if ((sym->st_shndx != SHN_UNDEF
&& sym->st_shndx < SHN_LORESERVE)
|| sym->st_shndx > SHN_HIRESERVE)
@ -3903,13 +3916,12 @@ edit_opd (obfd, info)
}
else
{
/* Local syms are a bit tricky. Other parts
of the linker re-read them so it's not
possible to tweak local sym values. In
any case, we'd need to look through the
local syms for the function descriptor
sym which we don't have at the moment.
So keep an array of adjustments. */
/* Local syms are a bit tricky. We could
tweak them as they can be cached, but
we'd need to look through the local syms
for the function descriptor sym which we
don't have at the moment. So keep an
array of adjustments. */
adjust[(rel->r_offset + wptr - rptr) / 24]
= wptr - rptr;
}
@ -3937,8 +3949,17 @@ edit_opd (obfd, info)
sec->_cooked_size = wptr - sec->contents;
sec->reloc_count = write_rel - relstart;
}
else if (elf_section_data (sec)->relocs == NULL)
else if (elf_section_data (sec)->relocs != relstart)
free (relstart);
if (local_syms != NULL
&& symtab_hdr->contents != (unsigned char *) local_syms)
{
if (!info->keep_memory)
free (local_syms);
else
symtab_hdr->contents = (unsigned char *) local_syms;
}
}
return true;
@ -4242,9 +4263,6 @@ ppc64_elf_size_dynamic_sections (output_bfd, info)
}
}
if (!get_local_syms (info->input_bfds, htab))
return false;
if (!edit_opd (output_bfd, info))
return false;
@ -4890,110 +4908,6 @@ group_sections (htab, stub_group_size, stubs_always_before_branch)
#undef PREV_SEC
}
/* Read in all local syms for all input bfds. */
static boolean
get_local_syms (input_bfd, htab)
bfd *input_bfd;
struct ppc_link_hash_table *htab;
{
unsigned int bfd_indx;
bfd *ibfd;
Elf_Internal_Sym *local_syms, **all_local_syms;
bfd_size_type amt;
if (htab->all_local_syms != NULL)
return true;
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for
later use; so hold pointers to the local symbols in an array. */
for (ibfd = input_bfd, bfd_indx = 0; ibfd != NULL; ibfd = ibfd->link_next)
bfd_indx += 1;
htab->bfd_count = bfd_indx;
amt = sizeof (Elf_Internal_Sym *) * bfd_indx;
all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
htab->all_local_syms = all_local_syms;
if (all_local_syms == NULL)
return false;
/* Walk over all the input BFDs, swapping in local symbols. */
for (bfd_indx = 0;
input_bfd != NULL;
input_bfd = input_bfd->link_next, bfd_indx++)
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Sym *isym;
Elf64_External_Sym *ext_syms, *esym, *end_sy;
Elf_External_Sym_Shndx *shndx_buf, *shndx;
bfd_size_type sec_size;
if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour)
continue;
/* We'll need the symbol table in a second. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (symtab_hdr->sh_info == 0)
continue;
/* We need an array of the local symbols attached to the input bfd.
Unfortunately, we're going to have to read & swap them in. */
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf_Internal_Sym);
local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size);
if (local_syms == NULL)
return false;
all_local_syms[bfd_indx] = local_syms;
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf64_External_Sym);
ext_syms = (Elf64_External_Sym *) bfd_malloc (sec_size);
if (ext_syms == NULL)
return false;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) ext_syms, sec_size, input_bfd) != sec_size)
{
error_ret_free_ext_syms:
free (ext_syms);
return false;
}
shndx_buf = NULL;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
sec_size = symtab_hdr->sh_info;
sec_size *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (sec_size);
if (shndx_buf == NULL)
goto error_ret_free_ext_syms;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, sec_size, input_bfd) != sec_size)
{
free (shndx_buf);
goto error_ret_free_ext_syms;
}
}
/* Swap the local symbols in. */
for (esym = ext_syms, end_sy = esym + symtab_hdr->sh_info,
isym = local_syms, shndx = shndx_buf;
esym < end_sy;
esym++, isym++, shndx = (shndx ? shndx + 1 : NULL))
bfd_elf64_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isym);
/* Now we can free the external symbols. */
free (shndx_buf);
free (ext_syms);
}
return true;
}
/* Determine and set the size of the stub section for a final link.
The basic idea here is to examine all the relocations looking for
@ -5012,7 +4926,6 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
{
bfd_size_type stub_group_size;
boolean stubs_always_before_branch;
boolean ret = false;
struct ppc_link_hash_table *htab = ppc_hash_table (info);
/* Stash our params away. */
@ -5034,13 +4947,6 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
group_sections (htab, stub_group_size, stubs_always_before_branch);
if (! get_local_syms (info->input_bfds, htab))
{
if (htab->all_local_syms)
goto error_ret_free_local;
return false;
}
while (1)
{
bfd *input_bfd;
@ -5057,15 +4963,13 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
{
Elf_Internal_Shdr *symtab_hdr;
asection *section;
Elf_Internal_Sym *local_syms;
Elf_Internal_Sym *local_syms = NULL;
/* We'll need the symbol table in a second. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (symtab_hdr->sh_info == 0)
continue;
local_syms = htab->all_local_syms[bfd_indx];
/* Walk over each section attached to the input bfd. */
for (section = input_bfd->sections;
section != NULL;
@ -5114,10 +5018,7 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
if (r_type >= (unsigned int) R_PPC_max)
{
bfd_set_error (bfd_error_bad_value);
error_ret_free_internal:
if (elf_section_data (section)->relocs == NULL)
free (internal_relocs);
goto error_ret_free_local;
goto error_ret_free_internal;
}
/* Only look for stubs on branch instructions. */
@ -5139,6 +5040,18 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
Elf_Internal_Sym *sym;
Elf_Internal_Shdr *hdr;
if (local_syms == NULL)
{
local_syms
= (Elf_Internal_Sym *) symtab_hdr->contents;
if (local_syms == NULL)
local_syms
= bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (local_syms == NULL)
goto error_ret_free_internal;
}
sym = local_syms + r_indx;
hdr = elf_elfsections (input_bfd)[sym->st_shndx];
sym_sec = hdr->bfd_section;
@ -5210,7 +5123,15 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
if (stub_entry == NULL)
{
free (stub_name);
goto error_ret_free_internal;
error_ret_free_internal:
if (elf_section_data (section)->relocs == NULL)
free (internal_relocs);
error_ret_free_local:
if (local_syms != NULL
&& (symtab_hdr->contents
!= (unsigned char *) local_syms))
free (local_syms);
return false;
}
stub_entry->target_value = sym_value;
@ -5221,9 +5142,18 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
}
/* We're done with the internal relocs, free them. */
if (elf_section_data (section)->relocs == NULL)
if (elf_section_data (section)->relocs != internal_relocs)
free (internal_relocs);
}
if (local_syms != NULL
&& symtab_hdr->contents != (unsigned char *) local_syms)
{
if (!info->keep_memory)
free (local_syms);
else
symtab_hdr->contents = (unsigned char *) local_syms;
}
}
if (!stub_changed)
@ -5252,15 +5182,7 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size,
the dynamic symbol table is corrupted since the section symbol
for the stripped section isn't written. */
ret = true;
error_ret_free_local:
while (htab->bfd_count-- > 0)
if (htab->all_local_syms[htab->bfd_count])
free (htab->all_local_syms[htab->bfd_count]);
free (htab->all_local_syms);
return ret;
return true;
}
/* Called after we have determined section placement. If sections

View File

@ -2144,15 +2144,11 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
Elf64_External_Sym *external_syms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_External_Sym_Shndx *shndx;
Elf_Internal_Sym *internal_syms = NULL;
Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@ -2164,7 +2160,6 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
input_section->_raw_size);
@ -2173,37 +2168,18 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
&& input_section->reloc_count > 0)
{
Elf_Internal_Sym *isymp;
Elf_Internal_Sym *isymend;
asection **secpp;
Elf64_External_Sym *esym, *esymend;
bfd_size_type amt;
if (symtab_hdr->contents != NULL)
external_syms = (Elf64_External_Sym *) symtab_hdr->contents;
else
/* Read this BFD's local symbols. */
if (symtab_hdr->sh_info != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf64_External_Sym);
external_syms = (Elf64_External_Sym *) bfd_malloc (amt);
if (external_syms == NULL && symtab_hdr->sh_info > 0)
goto error_return;
if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| (bfd_bread ((PTR) external_syms, amt, input_bfd) != amt))
goto error_return;
}
if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
{
amt = symtab_hdr->sh_info;
amt *= sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
goto error_return;
}
@ -2213,30 +2189,17 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
if (internal_relocs == NULL)
goto error_return;
internal_syms = ((Elf_Internal_Sym *)
bfd_malloc (symtab_hdr->sh_info
* sizeof (Elf_Internal_Sym)));
if (internal_syms == NULL && symtab_hdr->sh_info > 0)
goto error_return;
sections = (asection **) bfd_malloc (symtab_hdr->sh_info
* sizeof (asection *));
if (sections == NULL && symtab_hdr->sh_info > 0)
goto error_return;
isymp = internal_syms;
secpp = sections;
esym = external_syms;
esymend = esym + symtab_hdr->sh_info;
shndx = shndx_buf;
for (; esym < esymend;
++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
isymend = isymbuf + symtab_hdr->sh_info;
for (isymp = isymbuf; isymp < isymend; ++isymp, ++secpp)
{
asection *isec;
bfd_elf64_swap_symbol_in (input_bfd, (const PTR) esym,
(const PTR) shndx, isymp);
if (isymp->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
@ -2256,35 +2219,29 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
internal_syms, sections))
isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
sections = NULL;
if (internal_syms != NULL)
free (internal_syms);
internal_syms = NULL;
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
external_syms = NULL;
if (internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
internal_relocs = NULL;
if (isymbuf != NULL
&& (unsigned char *) isymbuf != symtab_hdr->contents)
free (isymbuf);
}
return data;
error_return:
if (sections != NULL)
free (sections);
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
if (external_syms != NULL && symtab_hdr->contents == NULL)
free (external_syms);
if (internal_syms != NULL)
free (internal_syms);
if (sections != NULL)
free (sections);
if (isymbuf != NULL
&& (unsigned char *) isymbuf != symtab_hdr->contents)
free (isymbuf);
return NULL;
}

View File

@ -1133,10 +1133,12 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
unsigned long symcount; /* Number of external ELF symbols */
elf_symbol_type *sym; /* Pointer to current bfd symbol */
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
Elf_Internal_Sym i_sym;
Elf_External_Sym *x_symp = NULL;
Elf_External_Sym_Shndx *x_shndx = NULL;
Elf_External_Versym *x_versymp = NULL;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
Elf_Internal_Sym *isymbuf = NULL;
Elf_External_Versym *xver;
Elf_External_Versym *xverbuf = NULL;
struct elf_backend_data *ebd;
bfd_size_type amt;
/* Read each raw ELF symbol, converting from external ELF form to
@ -1151,24 +1153,8 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
if (! dynamic)
{
Elf_Internal_Shdr *shndx_hdr;
hdr = &elf_tdata (abfd)->symtab_hdr;
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
verhdr = NULL;
/* If we have a SHT_SYMTAB_SHNDX section for the symbol table,
read the raw contents. */
if (elf_elfsections (abfd) != NULL
&& elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
{
amt = shndx_hdr->sh_size;
x_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (x_shndx == NULL
|| bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread ((PTR) x_shndx, amt, abfd) != amt)
goto error_return;
}
}
else
{
@ -1187,39 +1173,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
}
}
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
goto error_return;
ebd = get_elf_backend_data (abfd);
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
if (symcount == 0)
sym = symbase = NULL;
else
{
unsigned long i;
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
goto error_return;
isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
return -1;
amt = symcount;
amt *= sizeof (elf_symbol_type);
symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
if (symbase == (elf_symbol_type *) NULL)
goto error_return;
sym = symbase;
/* Temporarily allocate room for the raw ELF symbols. */
amt = symcount;
amt *= sizeof (Elf_External_Sym);
x_symp = (Elf_External_Sym *) bfd_malloc (amt);
if (x_symp == NULL)
goto error_return;
if (bfd_bread ((PTR) x_symp, amt, abfd) != amt)
goto error_return;
/* Read the raw ELF version symbol information. */
if (verhdr != NULL
&& verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
{
@ -1239,42 +1210,40 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
goto error_return;
x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
if (x_versymp == NULL && verhdr->sh_size != 0)
xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
if (xverbuf == NULL && verhdr->sh_size != 0)
goto error_return;
if (bfd_bread ((PTR) x_versymp, verhdr->sh_size, abfd)
if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd)
!= verhdr->sh_size)
goto error_return;
}
/* Skip first symbol, which is a null dummy. */
for (i = 1; i < symcount; i++)
xver = xverbuf;
if (xver != NULL)
++xver;
isymend = isymbuf + symcount;
for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
{
elf_swap_symbol_in (abfd, (const PTR) (x_symp + i),
(const PTR) (x_shndx + (x_shndx ? i : 0)),
&i_sym);
memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym));
#ifdef ELF_KEEP_EXTSYM
memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym));
#endif
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
sym->symbol.the_bfd = abfd;
sym->symbol.name = bfd_elf_string_from_elf_section (abfd,
hdr->sh_link,
i_sym.st_name);
isym->st_name);
sym->symbol.value = i_sym.st_value;
sym->symbol.value = isym->st_value;
if (i_sym.st_shndx == SHN_UNDEF)
if (isym->st_shndx == SHN_UNDEF)
{
sym->symbol.section = bfd_und_section_ptr;
}
else if (i_sym.st_shndx < SHN_LORESERVE
|| i_sym.st_shndx > SHN_HIRESERVE)
else if (isym->st_shndx < SHN_LORESERVE
|| isym->st_shndx > SHN_HIRESERVE)
{
sym->symbol.section = section_from_elf_index (abfd,
i_sym.st_shndx);
isym->st_shndx);
if (sym->symbol.section == NULL)
{
/* This symbol is in a section for which we did not
@ -1283,18 +1252,18 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
sym->symbol.section = bfd_abs_section_ptr;
}
}
else if (i_sym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
{
sym->symbol.section = bfd_abs_section_ptr;
}
else if (i_sym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
{
sym->symbol.section = bfd_com_section_ptr;
/* Elf puts the alignment into the `value' field, and
the size into the `size' field. BFD wants to see the
size in the value field, and doesn't care (at the
moment) about the alignment. */
sym->symbol.value = i_sym.st_size;
sym->symbol.value = isym->st_size;
}
else
sym->symbol.section = bfd_abs_section_ptr;
@ -1304,14 +1273,13 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
sym->symbol.value -= sym->symbol.section->vma;
switch (ELF_ST_BIND (i_sym.st_info))
switch (ELF_ST_BIND (isym->st_info))
{
case STB_LOCAL:
sym->symbol.flags |= BSF_LOCAL;
break;
case STB_GLOBAL:
if (i_sym.st_shndx != SHN_UNDEF
&& i_sym.st_shndx != SHN_COMMON)
if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
sym->symbol.flags |= BSF_GLOBAL;
break;
case STB_WEAK:
@ -1319,7 +1287,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
break;
}
switch (ELF_ST_TYPE (i_sym.st_info))
switch (ELF_ST_TYPE (isym->st_info))
{
case STT_SECTION:
sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
@ -1338,31 +1306,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
if (dynamic)
sym->symbol.flags |= BSF_DYNAMIC;
if (x_versymp != NULL)
if (xver != NULL)
{
Elf_Internal_Versym iversym;
_bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
_bfd_elf_swap_versym_in (abfd, xver, &iversym);
sym->version = iversym.vs_vers;
xver++;
}
/* Do some backend-specific processing on this symbol. */
{
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
if (ebd->elf_backend_symbol_processing)
(*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
}
sym++;
if (ebd->elf_backend_symbol_processing)
(*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
}
}
/* Do some backend-specific processing on this symbol table. */
{
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
if (ebd->elf_backend_symbol_table_processing)
(*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
}
if (ebd->elf_backend_symbol_table_processing)
(*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
/* We rely on the zalloc to clear out the final symbol entry. */
@ -1382,21 +1343,17 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
*symptrs = 0; /* Final null pointer */
}
if (x_shndx != NULL)
free (x_shndx);
if (x_versymp != NULL)
free (x_versymp);
if (x_symp != NULL)
free (x_symp);
if (xverbuf != NULL)
free (xverbuf);
if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return symcount;
error_return:
if (x_shndx != NULL)
free (x_shndx);
if (x_versymp != NULL)
free (x_versymp);
if (x_symp != NULL)
free (x_symp);
if (xverbuf != NULL)
free (xverbuf);
if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@ -691,15 +691,10 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
};
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents;
bfd_byte *free_contents = NULL;
ElfNN_External_Sym *extsyms;
ElfNN_External_Sym *free_extsyms = NULL;
Elf_External_Sym_Shndx *shndx_buf = NULL;
Elf_Internal_Sym *isymbuf = NULL;
struct elfNN_ia64_link_hash_table *ia64_info;
struct one_fixup *fixups = NULL;
boolean changed_contents = false;
@ -726,10 +721,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
(abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
if (! link_info->keep_memory)
free_relocs = internal_relocs;
return false;
ia64_info = elfNN_ia64_hash_table (link_info);
irelend = internal_relocs + sec->reloc_count;
@ -741,8 +733,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
/* No branch-type relocations. */
if (irel == irelend)
{
if (free_relocs != NULL)
free (free_relocs);
if (elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return true;
}
@ -754,48 +746,15 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
goto error_return;
}
/* Read this BFD's local symbols. */
if (symtab_hdr->contents != NULL)
extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
else
{
bfd_size_type amt;
amt = symtab_hdr->sh_info * sizeof (ElfNN_External_Sym);
extsyms = (ElfNN_External_Sym *) bfd_malloc (amt);
if (extsyms == NULL)
goto error_return;
free_extsyms = extsyms;
if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (extsyms, amt, abfd) != amt)
goto error_return;
}
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (shndx_hdr->sh_size != 0)
{
bfd_size_type amt;
amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL)
goto error_return;
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (shndx_buf, amt, abfd) != amt)
goto error_return;
}
for (; irel < irelend; irel++)
{
bfd_vma symaddr, reladdr, trampoff, toff, roff;
Elf_Internal_Sym isym;
asection *tsec;
struct one_fixup *f;
bfd_size_type amt;
@ -806,26 +765,34 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
/* Get the value of the symbol referred to by the reloc. */
if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
ElfNN_External_Sym *esym;
Elf_External_Sym_Shndx *shndx;
/* A local symbol. */
esym = extsyms + ELFNN_R_SYM (irel->r_info);
shndx = shndx_buf + (shndx_buf ? ELFNN_R_SYM (irel->r_info) : 0);
bfd_elfNN_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
&isym);
if (isym.st_shndx == SHN_UNDEF)
Elf_Internal_Sym *isym;
/* Read this BFD's local symbols. */
if (isymbuf == NULL)
{
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL)
isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
symtab_hdr->sh_info, 0,
NULL, NULL, NULL);
if (isymbuf == 0)
goto error_return;
}
isym = isymbuf + ELF64_R_SYM (irel->r_info);
if (isym->st_shndx == SHN_UNDEF)
continue; /* We can't do anthing with undefined symbols. */
else if (isym.st_shndx == SHN_ABS)
else if (isym->st_shndx == SHN_ABS)
tsec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
else if (isym->st_shndx == SHN_COMMON)
tsec = bfd_com_section_ptr;
else if (isym.st_shndx == SHN_IA_64_ANSI_COMMON)
else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
tsec = bfd_com_section_ptr;
else
tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
toff = isym.st_value;
toff = isym->st_value;
}
else
{
@ -973,17 +940,23 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
free (f);
}
if (changed_relocs)
elf_section_data (sec)->relocs = internal_relocs;
else if (free_relocs != NULL)
free (free_relocs);
if (changed_contents)
elf_section_data (sec)->this_hdr.contents = contents;
else if (free_contents != NULL)
if (isymbuf != NULL
&& symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
free (free_contents);
free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
{
if (!changed_contents && !link_info->keep_memory)
free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
@ -991,32 +964,26 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
}
}
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
if (elf_section_data (sec)->relocs != internal_relocs)
{
if (! link_info->keep_memory)
free (free_extsyms);
if (!changed_relocs)
free (internal_relocs);
else
{
/* Cache the symbols for elf_link_input_bfd. */
symtab_hdr->contents = (unsigned char *) extsyms;
}
elf_section_data (sec)->relocs = internal_relocs;
}
*again = changed_contents || changed_relocs;
return true;
error_return:
if (free_relocs != NULL)
free (free_relocs);
if (free_contents != NULL)
free (free_contents);
if (shndx_buf != NULL)
free (shndx_buf);
if (free_extsyms != NULL)
free (free_extsyms);
if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
free (isymbuf);
if (contents != NULL
&& elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
if (internal_relocs != NULL
&& elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return false;
}

View File

@ -4122,7 +4122,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
&& ELF_R_TYPE (abfd, r->r_info) != R_MIPS16_26)
break;
if (! info->keep_memory)
if (elf_section_data (o)->relocs != sec_relocs)
free (sec_relocs);
if (r < rend)