From 5cec694196c356cd13c79df6a278e1773f22cb2d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 2 Sep 2002 14:23:43 +0000 Subject: Use helpful names instead of cryptically overloaded bfd_reloc error codes. Replace caching of external symbols with caching of internal symbols obtained from calling bfd_elf_get_elf_syms(). Fixup problems with freeing cached allocated memory blocks. --- bfd/ChangeLog | 12 ++++ bfd/elf32-v850.c | 197 +++++++++++++++++++------------------------------------ 2 files changed, 78 insertions(+), 131 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 307bbcc..d597c4a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2002-09-02 Nick Clifton + + * elf32-v850.c (v850_elf_final_link_relocate): Use helpful + names instead of cryptically overloaded bfd_reloc error + codes. + (v850_elf_relocate_section): Likewise. + (v850_elf_relax_section): Replace caching of external symbols + with caching of internal symbols obtained from calling + bfd_elf_get_elf_syms(). + Fixup problems with freeing cached allocated memory blocks. + + 2002-09-02 Alan Modra * cpu-pj.c (scan_mach, compatible, arch_info_struct): Remove. diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 888a33a..57ed958 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -1331,10 +1331,6 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) reloc->address += isection->output_offset; return bfd_reloc_ok; } -#if 0 - else if (obfd != NULL) - return bfd_reloc_continue; -#endif /* Catch relocs involving undefined symbols. */ if (bfd_is_und_section (symbol->section) @@ -1422,6 +1418,11 @@ v850_elf_is_local_label_name (abfd, name) || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')); } +/* We overload some of the bfd_reloc error codes for own purposes. */ +#define bfd_reloc_gp_not_found bfd_reloc_other +#define bfd_reloc_ep_not_found bfd_reloc_continue +#define bfd_reloc_ctbp_not_found (bfd_reloc_dangerous + 1) + /* Perform a relocation as part of a final link. */ static bfd_reloc_status_type @@ -1496,7 +1497,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - return bfd_reloc_other; + return bfd_reloc_gp_not_found; gp = (h->u.def.value + h->u.def.section->output_section->vma @@ -1521,8 +1522,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - /* Actually this indicates that __ep could not be found. */ - return bfd_reloc_continue; + return bfd_reloc_ep_not_found; ep = (h->u.def.value + h->u.def.section->output_section->vma @@ -1541,8 +1541,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - /* Actually this indicates that __ctbp could not be found. */ - return bfd_reloc_dangerous + 1; + return bfd_reloc_ctbp_not_found; ctbp = (h->u.def.value + h->u.def.section->output_section->vma @@ -1563,7 +1562,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - return (bfd_reloc_dangerous + 1); + return bfd_reloc_ctbp_not_found; ctbp = (h->u.def.value + h->u.def.section->output_section->vma @@ -1762,15 +1761,15 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, msg = _("internal error: dangerous relocation"); goto common_error; - case bfd_reloc_other: + case bfd_reloc_gp_not_found: msg = _("could not locate special linker symbol __gp"); goto common_error; - case bfd_reloc_continue: + case bfd_reloc_ep_not_found: msg = _("could not locate special linker symbol __ep"); goto common_error; - case (bfd_reloc_dangerous + 1): + case bfd_reloc_ctbp_not_found: msg = _("could not locate special linker symbol __ctbp"); goto common_error; @@ -2485,20 +2484,16 @@ v850_elf_relax_section (abfd, sec, link_info, again) { Elf_Internal_Shdr * symtab_hdr; Elf_Internal_Rela * internal_relocs; - Elf_Internal_Rela * free_relocs = NULL; Elf_Internal_Rela * irel; Elf_Internal_Rela * irelend; Elf_Internal_Rela * irelalign = NULL; + Elf_Internal_Sym * isymbuf = NULL; bfd_byte * contents = NULL; - bfd_byte * free_contents = NULL; - Elf32_External_Sym * extsyms = NULL; - Elf32_External_Sym * free_extsyms = NULL; bfd_vma addr = 0; bfd_vma toaddr; int align_pad_size = 0; - Elf_Internal_Shdr * shndx_hdr = NULL; - Elf_External_Sym_Shndx * shndx_buf = NULL; - + boolean result = true; + * again = false; if (link_info->relocateable @@ -2518,8 +2513,6 @@ v850_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; irelend = internal_relocs + sec->reloc_count; @@ -2603,49 +2596,22 @@ v850_elf_relax_section (abfd, sec, link_info, again) 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) + /* 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; - } - - 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; - } + 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; } laddr = irel->r_offset; @@ -2737,27 +2703,12 @@ v850_elf_relax_section (abfd, sec, link_info, again) if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info) { - unsigned int r_index; - Elf_Internal_Sym isym; - asection * sym_sec; - Elf32_External_Sym * esym; - Elf_External_Sym_Shndx * shndx; + Elf_Internal_Sym * isym; /* A local symbol. */ - r_index = ELF32_R_SYM (irelcall->r_info); - esym = extsyms + r_index; - shndx = shndx_buf + (shndx_buf ? r_index : 0); - bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym); + isym = isymbuf + ELF32_R_SYM (irelcall->r_info); - if (isym.st_shndx == SHN_UNDEF) - sym_sec = bfd_und_section_ptr; - else if (isym.st_shndx == SHN_ABS) - sym_sec = bfd_abs_section_ptr; - 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; + symval = isym->st_value; } else { @@ -2791,27 +2742,21 @@ v850_elf_relax_section (abfd, sec, link_info, again) /* Get the value of the symbol referred to by the reloc. */ if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info) { - unsigned int r_index; - Elf_Internal_Sym isym; - asection * sym_sec; - Elf32_External_Sym * esym; - Elf_External_Sym_Shndx * shndx; + Elf_Internal_Sym * isym; + asection * sym_sec; /* A local symbol. */ - r_index = ELF32_R_SYM (irel->r_info); - esym = extsyms + r_index; - shndx = shndx_buf + (shndx_buf ? r_index : 0); - bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym); + isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info); - if (isym.st_shndx == SHN_UNDEF) + 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); } @@ -2821,7 +2766,7 @@ v850_elf_relax_section (abfd, sec, link_info, again) struct elf_link_hash_entry * h; /* An external symbol. */ - indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; + indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info; h = elf_sym_hashes (abfd)[indx]; BFD_ASSERT (h != NULL); @@ -2865,13 +2810,8 @@ v850_elf_relax_section (abfd, sec, link_info, again) that would be more work, but would require less memory when 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; - - symtab_hdr->contents = (bfd_byte *) extsyms; - free_extsyms = NULL; + symtab_hdr->contents = (bfd_byte *) isymbuf; /* Replace the long call with a jarl. */ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL); @@ -2972,38 +2912,33 @@ v850_elf_relax_section (abfd, sec, link_info, again) /* Get the value of the symbol referred to by the reloc. */ if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info) { - unsigned int r_index; - Elf_Internal_Sym isym; - asection * sym_sec; - Elf32_External_Sym * esym; - Elf_External_Sym_Shndx * shndx; + Elf_Internal_Sym * isym; + asection * sym_sec; /* A local symbol. */ - r_index = ELF32_R_SYM (irel->r_info); - esym = extsyms + r_index; - shndx = shndx_buf + (shndx_buf ? r_index : 0); - bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym); - - if (isym.st_shndx == SHN_UNDEF) + isym = isymbuf + ELF32_R_SYM (hi_irelfn->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); #ifdef DEBUG_RELAX { char * name = bfd_elf_string_from_elf_section - (abfd, symtab_hdr->sh_link, isym.st_name); + (abfd, symtab_hdr->sh_link, isym->st_name); fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n", - sym_sec->name, name, isym.st_name, - sym_sec->output_section->vma, sym_sec->output_offset, - isym.st_value, irel->r_addend); + sym_sec->name, name, isym->st_name, + sym_sec->output_section->vma, + sym_sec->output_offset, + isym->st_value, irel->r_addend); } #endif } @@ -3062,13 +2997,8 @@ v850_elf_relax_section (abfd, sec, link_info, again) that would be more work, but would require less memory when 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; - - symtab_hdr->contents = (bfd_byte *) extsyms; - free_extsyms = NULL; + symtab_hdr->contents = (bfd_byte *) isymbuf; if (foff < -0x100 || foff >= 0x100) { @@ -3166,19 +3096,24 @@ v850_elf_relax_section (abfd, sec, link_info, again) sec->_cooked_size -= align_pad_size; } - return true; + finish: + if (internal_relocs != NULL + && elf_section_data (sec)->relocs != internal_relocs) + free (internal_relocs); - error_return: - if (free_relocs != NULL) - free (free_relocs); + if (contents != NULL + && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents) + free (contents); - if (free_contents != NULL) - free (free_contents); + if (isymbuf != NULL + && symtab_hdr->contents != (bfd_byte *) isymbuf) + free (isymbuf); - if (free_extsyms != NULL) - free (free_extsyms); + return result; - return false; + error_return: + result = false; + goto finish; } #define TARGET_LITTLE_SYM bfd_elf32_v850_vec -- cgit v1.1