From 8977835cde2576229bb1ad01f32bb3e6279b5afe Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 26 Sep 2007 12:29:41 +0000 Subject: [PATCH] * elflink.c (set_symbol_value): Add isymbuf and locsymcount params. Change symidx to a size_t. Don't access past end of symbol buffer. (resolve_symbol): Add isymbuf param and use instead of finfo->internal_syms. (eval_symbol, evaluate_complex_relocation_symbols): Likewise. (elf_link_input_bfd): Don't read symbols specially for evaluate_complex_relocation_symbols. --- bfd/ChangeLog | 11 ++++++ bfd/elflink.c | 116 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 70 insertions(+), 57 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f93f756..afbd748e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2007-09-26 Alan Modra + + * elflink.c (set_symbol_value): Add isymbuf and locsymcount + params. Change symidx to a size_t. Don't access past end + of symbol buffer. + (resolve_symbol): Add isymbuf param and use instead of + finfo->internal_syms. + (eval_symbol, evaluate_complex_relocation_symbols): Likewise. + (elf_link_input_bfd): Don't read symbols specially for + evaluate_complex_relocation_symbols. + 2007-09-26 Tristan Gingold * som.c (som_get_reloc_upper_bound): If there are no relocs return diff --git a/bfd/elflink.c b/bfd/elflink.c index 8e17f89..ce59c3a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -7230,38 +7230,43 @@ struct elf_outext_info static void set_symbol_value (bfd * bfd_with_globals, - struct elf_final_link_info * finfo, - int symidx, + Elf_Internal_Sym * isymbuf, + size_t locsymcount, + size_t symidx, bfd_vma val) { - bfd_boolean is_local; - Elf_Internal_Sym * sym; - struct elf_link_hash_entry ** sym_hashes; - struct elf_link_hash_entry * h; + struct elf_link_hash_entry **sym_hashes; + struct elf_link_hash_entry *h; + size_t extsymoff = locsymcount; - sym_hashes = elf_sym_hashes (bfd_with_globals); - sym = finfo->internal_syms + symidx; - is_local = ELF_ST_BIND(sym->st_info) == STB_LOCAL; - - if (is_local) - { - /* It is a local symbol: move it to the - "absolute" section and give it a value. */ - sym->st_shndx = SHN_ABS; - sym->st_value = val; - } - else + if (symidx < locsymcount) { - /* It is a global symbol: set its link type - to "defined" and give it a value. */ - h = sym_hashes [symidx]; - 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; - h->root.type = bfd_link_hash_defined; - h->root.u.def.value = val; - h->root.u.def.section = bfd_abs_section_ptr; + Elf_Internal_Sym *sym; + + sym = isymbuf + symidx; + if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) + { + /* It is a local symbol: move it to the + "absolute" section and give it a value. */ + sym->st_shndx = SHN_ABS; + sym->st_value = val; + return; + } + BFD_ASSERT (elf_bad_symtab (bfd_with_globals)); + extsymoff = 0; } + + /* It is a global symbol: set its link type + to "defined" and give it a value. */ + + sym_hashes = elf_sym_hashes (bfd_with_globals); + h = sym_hashes [symidx - extsymoff]; + 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; + h->root.type = bfd_link_hash_defined; + h->root.u.def.value = val; + h->root.u.def.section = bfd_abs_section_ptr; } static bfd_boolean @@ -7269,6 +7274,7 @@ resolve_symbol (const char * name, bfd * input_bfd, struct elf_final_link_info * finfo, bfd_vma * result, + Elf_Internal_Sym * isymbuf, size_t locsymcount) { Elf_Internal_Sym * sym; @@ -7282,7 +7288,7 @@ resolve_symbol (const char * name, for (i = 0; i < locsymcount; ++ i) { - sym = finfo->internal_syms + i; + sym = isymbuf + i; sec = finfo->sections [i]; if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) @@ -7402,6 +7408,7 @@ eval_symbol (bfd_vma * result, struct elf_final_link_info * finfo, bfd_vma addr, bfd_vma section_offset, + Elf_Internal_Sym * isymbuf, size_t locsymcount, int signed_p) { @@ -7459,8 +7466,9 @@ eval_symbol (bfd_vma * result, if (symbol_is_section) { - if ((resolve_section (symbuf, finfo->output_bfd->sections, result) != TRUE) - && (resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE)) + if (!resolve_section (symbuf, finfo->output_bfd->sections, result) + && !resolve_symbol (symbuf, input_bfd, finfo, result, + isymbuf, locsymcount)) { undefined_reference ("section", symbuf); return FALSE; @@ -7468,9 +7476,10 @@ eval_symbol (bfd_vma * result, } else { - if ((resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE) - && (resolve_section (symbuf, finfo->output_bfd->sections, - result) != TRUE)) + if (!resolve_symbol (symbuf, input_bfd, finfo, result, + isymbuf, locsymcount) + && !resolve_section (symbuf, finfo->output_bfd->sections, + result)) { undefined_reference ("symbol", symbuf); return FALSE; @@ -7487,9 +7496,9 @@ eval_symbol (bfd_vma * result, sym += strlen (#op); \ if (* sym == ':') \ ++ sym; \ - if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ - section_offset, locsymcount, signed_p) \ - != TRUE) \ + if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \ + section_offset, isymbuf, locsymcount, \ + signed_p)) \ return FALSE; \ if (signed_p) \ * result = op ((signed)a); \ @@ -7505,14 +7514,14 @@ eval_symbol (bfd_vma * result, sym += strlen (#op); \ if (* sym == ':') \ ++ sym; \ - if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ - section_offset, locsymcount, signed_p) \ - != TRUE) \ + if (!eval_symbol (&a, sym, &sym, input_bfd, finfo, addr, \ + section_offset, isymbuf, locsymcount, \ + signed_p)) \ return FALSE; \ ++ sym; \ - if (eval_symbol (& b, sym, & sym, input_bfd, finfo, addr, \ - section_offset, locsymcount, signed_p) \ - != TRUE) \ + if (!eval_symbol (&b, sym, &sym, input_bfd, finfo, addr, \ + section_offset, isymbuf, locsymcount, \ + signed_p)) \ return FALSE; \ if (signed_p) \ * result = ((signed) a) op ((signed) b); \ @@ -7555,8 +7564,9 @@ eval_symbol (bfd_vma * result, /* Entry point to evaluator, called from elf_link_input_bfd. */ static bfd_boolean -evaluate_complex_relocation_symbols (bfd * input_bfd, - struct elf_final_link_info * finfo, +evaluate_complex_relocation_symbols (bfd *input_bfd, + struct elf_final_link_info *finfo, + Elf_Internal_Sym *isymbuf, size_t locsymcount) { const struct elf_backend_data * bed; @@ -7626,7 +7636,7 @@ evaluate_complex_relocation_symbols (bfd * input_bfd, if (index < locsymcount) { /* The symbol is local. */ - sym = finfo->internal_syms + index; + sym = isymbuf + index; /* We're only processing STT_RELC or STT_SRELC type symbols. */ if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) && @@ -7668,10 +7678,10 @@ evaluate_complex_relocation_symbols (bfd * input_bfd, printf (" Evaluating '%s' ...\n ", sym_name); #endif if (eval_symbol (& result, sym_name, & sym_name, input_bfd, - finfo, addr, section_offset, locsymcount, + finfo, addr, section_offset, isymbuf, locsymcount, signed_p)) /* Symbol evaluated OK. Update to absolute value. */ - set_symbol_value (input_bfd, finfo, index, result); + set_symbol_value (input_bfd, isymbuf, locsymcount, index, result); else result = FALSE; @@ -9066,15 +9076,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) if (isymbuf == NULL) return FALSE; } - /* evaluate_complex_relocation_symbols looks for symbols in - finfo->internal_syms. */ - else if (isymbuf != NULL && locsymcount != 0) - { - bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, - finfo->internal_syms, - finfo->external_syms, - finfo->locsym_shndx); - } /* Find local symbol sections and adjust values of symbols in SEC_MERGE sections. Write out those local symbols we know are @@ -9212,7 +9213,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) return FALSE; } - if (! evaluate_complex_relocation_symbols (input_bfd, finfo, locsymcount)) + if (! evaluate_complex_relocation_symbols (input_bfd, finfo, isymbuf, + locsymcount)) return FALSE; /* Relocate the contents of each section. */ -- 2.7.4