X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-spu.c;h=17ff079c0cccdfcf3da6aae52b062d9d636453c9;hb=6bba1048d63e0476b94b9934527defd81c590a13;hp=89b3422768f81e4bd3df8e1c318fb35924e0c218;hpb=f3c29e8aeed9932d38c06065ea643f28e5e08701;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 89b3422768..17ff079c0c 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -819,7 +819,7 @@ needs_ovl_stub (struct elf_link_hash_entry *h, section needs a stub. */ if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != spu_elf_section_data (input_section->output_section)->u.o.ovl_index) - return ovl_stub; + ret = ovl_stub; /* If this insn isn't a branch then we are possibly taking the address of a function and passing it out somehow. */ @@ -2807,6 +2807,8 @@ mark_overlay_section (struct function_info *fun, fun->visit4 = TRUE; if (!fun->sec->linker_mark) { + unsigned int size; + fun->sec->linker_mark = 1; fun->sec->gc_mark = 1; fun->sec->segment_mark = 0; @@ -2814,10 +2816,10 @@ mark_overlay_section (struct function_info *fun, be!), and SEC_CODE is clear on rodata sections. We use this flag to differentiate the two overlay section types. */ fun->sec->flags |= SEC_CODE; + if (spu_hash_table (info)->auto_overlay & OVERLAY_RODATA) { char *name = NULL; - unsigned int size; /* Find the rodata section corresponding to this function's text section. */ @@ -2872,12 +2874,12 @@ mark_overlay_section (struct function_info *fun, } free (name); } - size = fun->sec->size; - if (fun->rodata) - size += fun->rodata->size; - if (mos_param->max_overlay_size < size) - mos_param->max_overlay_size = size; } + size = fun->sec->size; + if (fun->rodata) + size += fun->rodata->size; + if (mos_param->max_overlay_size < size) + mos_param->max_overlay_size = size; } for (count = 0, call = fun->call_list; call != NULL; call = call->next) @@ -3600,19 +3602,24 @@ spu_elf_auto_overlay (struct bfd_link_info *info, } if (fixed_size + mos_param.max_overlay_size > htab->local_store) - info->callbacks->einfo (_("non-overlay plus maximum overlay size " - "of 0x%x exceeds local store\n"), - fixed_size + mos_param.max_overlay_size); + info->callbacks->einfo (_("non-overlay size of 0x%v plus maximum overlay " + "size of 0x%v exceeds local store\n"), + (bfd_vma) fixed_size, + (bfd_vma) mos_param.max_overlay_size); /* Now see if we should put some functions in the non-overlay area. */ - if (fixed_size < htab->overlay_fixed - && htab->overlay_fixed + mos_param.max_overlay_size < htab->local_store) + else if (fixed_size < htab->overlay_fixed) { - unsigned int lib_size = htab->overlay_fixed - fixed_size; + unsigned int max_fixed, lib_size; + + max_fixed = htab->local_store - mos_param.max_overlay_size; + if (max_fixed > htab->overlay_fixed) + max_fixed = htab->overlay_fixed; + lib_size = max_fixed - fixed_size; lib_size = auto_ovl_lib_functions (info, lib_size); if (lib_size == (unsigned int) -1) goto err_exit; - fixed_size = htab->overlay_fixed - lib_size; + fixed_size = max_fixed - lib_size; } /* Build an array of sections, suitably sorted to place into @@ -3966,10 +3973,51 @@ spu_elf_relocate_section (bfd *output_bfd, } else { - RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, - r_symndx, symtab_hdr, sym_hashes, - h, sec, relocation, - unresolved_reloc, warned); + if (sym_hashes == NULL) + return FALSE; + + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + relocation = 0; + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + sec = h->root.u.def.section; + if (sec == NULL + || sec->output_section == NULL) + /* Set a flag that will be cleared later if we find a + relocation value for this symbol. output_section + is typically NULL for symbols satisfied by a shared + library. */ + unresolved_reloc = TRUE; + else + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); + } + else if (h->root.type == bfd_link_hash_undefweak) + ; + else if (info->unresolved_syms_in_objects == RM_IGNORE + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) + ; + else if (!info->relocatable + && !(r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)) + { + bfd_boolean err; + err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); + if (!info->callbacks->undefined_symbol (info, + h->root.root.string, + input_bfd, + input_section, + rel->r_offset, err)) + return FALSE; + warned = TRUE; + } sym_name = h->root.root.string; }