mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-23 20:19:49 +00:00
* 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:
parent
d8462f1281
commit
6cdc0ccc12
@ -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.
|
||||
|
@ -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 *));
|
||||
|
338
bfd/elf-m10200.c
338
bfd/elf-m10200.c
@ -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;
|
||||
}
|
||||
|
||||
|
665
bfd/elf-m10300.c
665
bfd/elf-m10300.c
File diff suppressed because it is too large
Load Diff
173
bfd/elf.c
173
bfd/elf.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
247
bfd/elf32-m32r.c
247
bfd/elf32-m32r.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
306
bfd/elf32-sh.c
306
bfd/elf32-sh.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
119
bfd/elf64-mmix.c
119
bfd/elf64-mmix.c
@ -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;
|
||||
}
|
||||
|
||||
|
230
bfd/elf64-ppc.c
230
bfd/elf64-ppc.c
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
137
bfd/elfcode.h
137
bfd/elfcode.h
@ -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;
|
||||
}
|
||||
|
||||
|
673
bfd/elflink.h
673
bfd/elflink.h
File diff suppressed because it is too large
Load Diff
137
bfd/elfxx-ia64.c
137
bfd/elfxx-ia64.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user