From 5e2b0d475efa4aa40e098f49074f3c2afd854f48 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 11 Nov 2005 11:06:34 +0000 Subject: [PATCH] PR 1150 * readelf.c (get_mips_symbol_other): New function. (get_symbol_other): New function. (process_symbol_table): Call get_symbol_other() to get a description of the st_other field if it contains more information than just the visibility. * elfxx-mips.c (mips_elf_calculate_relocation): Ignore an undefined symbol if it is optional. (_bfd_mips_elf_merge_symbol_attribute): Make sure that the optional flag is merged as well as the visibility. * elfxx-mips.h (_bfd_mips_elf_merge_symbol_attribute): Prototype. (elf_backend_merge_symbol_attribute): Define. * mips.h (STO_OPTIONAL): Define. (ELF_MIPS_IS_OPTIONAL): Define. --- bfd/ChangeLog | 10 ++++++++++ bfd/elfxx-mips.c | 27 +++++++++++++++++++++++++-- bfd/elfxx-mips.h | 3 +++ binutils/ChangeLog | 9 +++++++++ binutils/readelf.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/elf/ChangeLog | 6 ++++++ include/elf/mips.h | 7 +++++++ 7 files changed, 105 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d74978e..fdc81a2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2005-11-11 Nick Clifton + + PR 1150 + * elfxx-mips.c (mips_elf_calculate_relocation): Ignore an + undefined symbol if it is optional. + (_bfd_mips_elf_merge_symbol_attribute): Make sure that the + optional flag is merged as well as the visibility. + * elfxx-mips.h (_bfd_mips_elf_merge_symbol_attribute): Prototype. + (elf_backend_merge_symbol_attribute): Define. + 2005-11-08 Nathan Sidwell Add ms2 support diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index a344849..d4b90de 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -3792,6 +3792,17 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, BFD_ASSERT (bfd_get_section_by_name (abfd, ".dynamic") == NULL); symbol = 0; } + else if (ELF_MIPS_IS_OPTIONAL (h->root.other)) + { + /* This is an optional symbol - an Irix specific extension to the + ELF spec. Ignore it for now. + XXX - FIXME - there is more to the spec for OPTIONAL symbols + than simply ignoring them, but we do not handle this for now. + For information see the "64-bit ELF Object File Specification" + which is available from here: + http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf */ + symbol = 0; + } else { if (! ((*info->callbacks->undefined_symbol) @@ -8867,8 +8878,7 @@ _bfd_elf_mips_get_relocated_section_contents case bfd_reloc_undefined: if (!((*link_info->callbacks->undefined_symbol) (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address, - TRUE))) + input_bfd, input_section, (*parent)->address, TRUE))) goto error_return; break; case bfd_reloc_dangerous: @@ -9994,3 +10004,16 @@ const struct bfd_elf_special_section _bfd_mips_elf_special_sections[] = { ".ucode", 6, 0, SHT_MIPS_UCODE, 0 }, { NULL, 0, 0, 0, 0 } }; + +/* Ensure that the STO_OPTIONAL flag is copied into h->other, + even if this is not a defintion of the symbol. */ +void +_bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic ATTRIBUTE_UNUSED) +{ + if (! definition + && ELF_MIPS_IS_OPTIONAL (isym->st_other)) + h->other |= STO_OPTIONAL; +} diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index d419435..3af342a 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -127,6 +127,8 @@ extern bfd_boolean _bfd_mips_relax_section (bfd *, asection *, struct bfd_link_info *, bfd_boolean *); extern bfd_vma _bfd_mips_elf_sign_extend (bfd_vma, int); +extern void _bfd_mips_elf_merge_symbol_attribute + (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, bfd_boolean); extern const struct bfd_elf_special_section _bfd_mips_elf_special_sections []; @@ -134,3 +136,4 @@ extern const struct bfd_elf_special_section _bfd_mips_elf_special_sections []; _bfd_mips_elf_name_local_section_symbols #define elf_backend_special_sections _bfd_mips_elf_special_sections #define elf_backend_eh_frame_address_size _bfd_mips_elf_eh_frame_address_size +#define elf_backend_merge_symbol_attribute _bfd_mips_elf_merge_symbol_attribute diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e9217a0..54a7c0f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,12 @@ +2005-11-11 Nick Clifton + + PR 1150 + * readelf.c (get_mips_symbol_other): New function. + (get_symbol_other): New function. + (process_symbol_table): Call get_symbol_other() to get a + description of the st_other field if it contains more information + than just the visibility. + 2005-11-07 Steve Ellcey * configure: Regenerate after modifying bfd/warning.m4. diff --git a/binutils/readelf.c b/binutils/readelf.c index d076a65..3e8eb20 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -6690,6 +6690,41 @@ get_symbol_visibility (unsigned int visibility) } static const char * +get_mips_symbol_other (unsigned int other) +{ + switch (other) + { + case STO_OPTIONAL: return "OPTIONAL"; + case STO_MIPS16: return "MIPS16"; + default: return NULL; + } +} + +static const char * +get_symbol_other (unsigned int other) +{ + const char * result = NULL; + static char buff [32]; + + if (other == 0) + return ""; + + switch (elf_header.e_machine) + { + case EM_MIPS: + result = get_mips_symbol_other (other); + default: + break; + } + + if (result) + return result; + + snprintf (buff, sizeof buff, _(": %x"), other); + return buff; +} + +static const char * get_symbol_index_type (unsigned int type) { static char buff[32]; @@ -6851,6 +6886,11 @@ process_symbol_table (FILE *file) printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); + /* Check to see if any other bits in the st_other field are set. + Note - displaying this information disrupts the layout of the + table being generated, but for the moment this case is very rare. */ + if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) + printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); printf (" %3.3s ", get_symbol_index_type (psym->st_shndx)); if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); @@ -6918,6 +6958,11 @@ process_symbol_table (FILE *file) printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); + /* Check to see if any other bits in the st_other field are set. + Note - displaying this information disrupts the layout of the + table being generated, but for the moment this case is very rare. */ + if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) + printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); printf (" %4s ", get_symbol_index_type (psym->st_shndx)); print_symbol (25, psym->st_name < strtab_size ? strtab + psym->st_name : ""); diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 485a78e..af4947c 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,9 @@ +2005-11-11 Nick Clifton + + PR 1150 + * mips.h (STO_OPTIONAL): Define. + (ELF_MIPS_IS_OPTIONAL): Define. + 2005-09-30 Catherine Moore * bfin.h: New file. diff --git a/include/elf/mips.h b/include/elf/mips.h index 540815b..6afc12f 100644 --- a/include/elf/mips.h +++ b/include/elf/mips.h @@ -718,6 +718,13 @@ extern void bfd_mips_elf32_swap_reginfo_out /* This value is used for a mips16 .text symbol. */ #define STO_MIPS16 0xf0 + +/* This bit is used on Irix to indicate a symbol whose definition + is optional - if, at final link time, it cannot be found, no + error message should be produced. */ +#define STO_OPTIONAL (1 << 2) +/* A macro to examine the STO_OPTIONAL bit. */ +#define ELF_MIPS_IS_OPTIONAL(other) ((other) & STO_OPTIONAL) /* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each relocation entry specifies up to three actual relocations, all at -- 2.7.4