PATCH: Force a hidden symbol global
H. J. Lu
hjl@lucon.org
Thu Apr 21 21:06:00 GMT 2005
More information about the Binutils mailing list
Thu Apr 21 21:06:00 GMT 2005
- Previous message (by thread): PATCH: z8k buffer overrun fix
- Next message (by thread): PATCH: Build failure on Debian testing (cross to arm-none-eabi)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, Mar 03, 2005 at 05:37:20PM -0800, H. J. Lu wrote: > On Fri, Mar 04, 2005 at 08:24:44AM +1030, Alan Modra wrote: > > On Thu, Mar 03, 2005 at 08:55:10AM -0800, H. J. Lu wrote: > > > On Thu, Mar 03, 2005 at 07:55:04AM -0800, H. J. Lu wrote: > > > > On Thu, Mar 03, 2005 at 11:19:13PM +1030, Alan Modra wrote: > > > > > On Wed, Mar 02, 2005 at 08:14:59PM -0800, H. J. Lu wrote: > > > > > > Protected visibility has almost everything, but requires > > > > > > special handling at run-time. > > > > > > > > > > > > I was wondering if we could allow version script to overwrite > > > > > > hidden symbols. That is if a symbol is global in version script, we > > > > > > export it even if it is marked hidden. It may improve run-time > > > > > > performance. > > > > > > > > > > How is this going to be different from using protected symbols? > > > > > > > > No run-time special handling accociated with protected symbols, which > > > > may take extra lookup. > > > > > > Also compiler/linker can't optimize protected function pointers. > > > > Which means that if you export hidden function symbols from shared > > libraries by means of a version script, you will break function pointer > > comparisons. > > Yes. If you don't do any function pointer comparisons on exported > functions in DSO, you should be OK. > This patch will allow forcing a hidden symbol as global. It can be used for performance and languange specific features. H.J. ---- 2005-04-21 H.J. Lu <hongjiu.lu@intel.com> * elf-bfd.h (elf_link_hash_entry): Add forced_global. * elflink.c (bfd_elf_link_record_dynamic_symbol): Don't check symbol visibilty when we force a forced local symbol to global. (_bfd_elf_link_renumber_dynsyms): Move forced local symbols just before global ones. (_bfd_elf_link_assign_sym_version): Set the forced_global field if a forced local symbol is marked as global explicitly. (elf_link_output_extsym): Handle forced_global. --- bfd/elf-bfd.h.global 2005-04-04 10:35:34.000000000 -0700 +++ bfd/elf-bfd.h 2005-04-21 10:00:36.000000000 -0700 @@ -155,6 +155,8 @@ struct elf_link_hash_entry unsigned int hidden : 1; /* Symbol was forced to local scope due to a version script file. */ unsigned int forced_local : 1; + /* Symbol was forced to global scope due to a version script file. */ + unsigned int forced_global : 1; /* Symbol was marked during garbage collection. */ unsigned int mark : 1; /* Symbol is referenced by a non-GOT/non-PLT relocation. This is --- bfd/elflink.c.global 2005-04-19 10:42:57.000000000 -0700 +++ bfd/elflink.c 2005-04-21 13:55:00.000000000 -0700 @@ -377,22 +377,24 @@ bfd_elf_link_record_dynamic_symbol (stru /* XXX: The ABI draft says the linker must turn hidden and internal symbols into STB_LOCAL symbols when producing the DSO. However, if ld.so honors st_other in the dynamic table, - this would not be necessary. */ - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - if (h->root.type != bfd_link_hash_undefined - && h->root.type != bfd_link_hash_undefweak) - { - h->forced_local = 1; - if (!elf_hash_table (info)->is_relocatable_executable) - return TRUE; - } + this would not be necessary. Don't check symbol visibilty + when we force a forced local symbol to global. */ + if (!h->forced_global) + switch (ELF_ST_VISIBILITY (h->other)) + { + case STV_INTERNAL: + case STV_HIDDEN: + if (h->root.type != bfd_link_hash_undefined + && h->root.type != bfd_link_hash_undefweak) + { + h->forced_local = 1; + if (!elf_hash_table (info)->is_relocatable_executable) + return TRUE; + } - default: - break; - } + default: + break; + } h->dynindx = elf_hash_table (info)->dynsymcount; ++elf_hash_table (info)->dynsymcount; @@ -702,9 +704,9 @@ _bfd_elf_link_omit_section_dynsym (bfd * } /* Assign dynsym indices. In a shared library we generate a section - symbol for each output section, which come first. Next come symbols - which have been forced to local binding. Then all of the back-end - allocated local dynamic syms, followed by the rest of the global + symbol for each output section, which come first. Next come all of + the back-end allocated local dynamic syms. Then symbols which have + been forced to local binding, followed by the rest of the global symbols. */ static unsigned long @@ -726,10 +728,6 @@ _bfd_elf_link_renumber_dynsyms (bfd *out } *section_sym_count = dynsymcount; - elf_link_hash_traverse (elf_hash_table (info), - elf_link_renumber_local_hash_table_dynsyms, - &dynsymcount); - if (elf_hash_table (info)->dynlocal) { struct elf_link_local_dynamic_entry *p; @@ -738,6 +736,10 @@ _bfd_elf_link_renumber_dynsyms (bfd *out } elf_link_hash_traverse (elf_hash_table (info), + elf_link_renumber_local_hash_table_dynsyms, + &dynsymcount); + + elf_link_hash_traverse (elf_hash_table (info), elf_link_renumber_hash_table_dynsyms, &dynsymcount); @@ -1694,6 +1696,7 @@ _bfd_elf_link_assign_sym_version (struct struct elf_info_failed eif; char *p; bfd_size_type amt; + bfd_boolean forced_global; sinfo = data; info = sinfo->info; @@ -1716,6 +1719,10 @@ _bfd_elf_link_assign_sym_version (struct if (!h->def_regular) return TRUE; + /* Check if a forced local symbol is marked as global explicitly in + version script. */ + forced_global = FALSE; + bed = get_elf_backend_data (sinfo->output_bfd); p = strchr (h->root.root.string, ELF_VER_CHR); if (p != NULL && h->verinfo.vertree == NULL) @@ -1778,6 +1785,8 @@ _bfd_elf_link_assign_sym_version (struct && ! info->export_dynamic) (*bed->elf_backend_hide_symbol) (info, h, TRUE); } + else if (d) + forced_global = TRUE; free (alc); break; @@ -1868,6 +1877,7 @@ _bfd_elf_link_assign_sym_version (struct h->verinfo.vertree = t; local_ver = NULL; d->script = 1; + forced_global = TRUE; break; } if (d != NULL) @@ -1904,11 +1914,20 @@ _bfd_elf_link_assign_sym_version (struct && info->shared && ! info->export_dynamic) { + forced_global = FALSE; (*bed->elf_backend_hide_symbol) (info, h, TRUE); } } } + if (h->forced_local && forced_global) + { + h->forced_global = 1; + + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + return TRUE; } @@ -6316,12 +6335,12 @@ elf_link_output_extsym (struct elf_link_ /* Decide whether to output this symbol in this pass. */ if (eoinfo->localsyms) { - if (!h->forced_local) + if (!h->forced_local || h->forced_global) return TRUE; } else { - if (h->forced_local) + if (h->forced_local && !h->forced_global) return TRUE; } @@ -6351,6 +6370,7 @@ elf_link_output_extsym (struct elf_link_ if (! finfo->info->relocatable && (! finfo->info->shared) && h->forced_local + && !h->forced_global && h->ref_dynamic && !h->dynamic_def && !h->dynamic_weak @@ -6404,7 +6424,14 @@ elf_link_output_extsym (struct elf_link_ sym.st_value = 0; sym.st_size = h->size; sym.st_other = h->other; - if (h->forced_local) + if (h->forced_global) + { + /* A forced global symbol has the default visibility. */ + sym.st_other + = STV_DEFAULT | (h->other & ~ ELF_ST_VISIBILITY (-1)); + sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); + } + else if (h->forced_local) sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); else if (h->root.type == bfd_link_hash_undefweak || h->root.type == bfd_link_hash_defweak)
- Previous message (by thread): PATCH: z8k buffer overrun fix
- Next message (by thread): PATCH: Build failure on Debian testing (cross to arm-none-eabi)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list