This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH][RFC] Explicitly set ELF symbol size to zero for undefined symbols -- libbfd, gold
- From: simonb at google dot com (Simon Baldwin)
- To: binutils at sourceware dot org
- Date: Mon, 14 Jul 2008 11:48:25 +0100 (BST)
- Subject: [PATCH][RFC] Explicitly set ELF symbol size to zero for undefined symbols -- libbfd, gold
This patch explicitly sets the size of undefined ELF symbols to zero for
linker output.
Currently, the size of an undefined ELF symbol is copied out of the object
file or DSO that supplies the symbol, on linking. This size is unreliable,
for example in the case of two DSOs, one linking to the other. The lower-
level DSO could make an ABI-preserving change that alters the symbol size,
with no hard requirement to rebuild the higher-level DSO. And if the higher-
level DSO is rebuilt, tools that monitor file checksums will register a
change due to the altered size of the undefined symbol, even though nothing
else about the higher-level DSO has altered. This can lead to unnecessary
and undesirable rebuild and change cascades in checksum-based systems.
Confirmed test parity between pre- and post-patch source trees.
Any objections? Thanks.
*** binutils-2.18.50/bfd/elflink.c.orig Thu Jul 10 15:39:15 2008
--- binutils-2.18.50/bfd/elflink.c Thu Jul 10 15:41:12 2008
*************** elf_link_output_extsym (struct elf_link_
*** 8611,8630 ****
--- 8611,8637 ----
{
int bindtype;
if (h->ref_regular_nonweak)
bindtype = STB_GLOBAL;
else
bindtype = STB_WEAK;
sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
}
+ /* Reset size to zero for undefined symbols to indicate unknown size.
+ Undefined symbols may be picked up from shared libraries, and a shared
+ library can change between here and use with the dynamic loader,
+ making sizes other than zero invalid. */
+ if (sym.st_shndx == SHN_UNDEF)
+ sym.st_size = 0;
+
/* If a non-weak symbol with non-default visibility is not defined
locally, it is a fatal error. */
if (! finfo->info->relocatable
&& ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
&& h->root.type == bfd_link_hash_undefined
&& !h->def_regular)
{
(*_bfd_error_handler)
(_("%B: %s symbol `%s' isn't defined"),
*** binutils-2.18.50/gold/symtab.cc.orig Fri Jul 11 11:17:22 2008
--- binutils-2.18.50/gold/symtab.cc Fri Jul 11 10:26:25 2008
*************** void
*** 2292,2312 ****
Symbol_table::sized_write_symbol(
Sized_symbol<size>* sym,
typename elfcpp::Elf_types<size>::Elf_Addr value,
unsigned int shndx,
const Stringpool* pool,
unsigned char* p) const
{
elfcpp::Sym_write<size, big_endian> osym(p);
osym.put_st_name(pool->get_offset(sym->name()));
osym.put_st_value(value);
! osym.put_st_size(sym->symsize());
// A version script may have overridden the default binding.
if (sym->is_forced_local())
osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, sym->type()));
else
osym.put_st_info(elfcpp::elf_st_info(sym->binding(), sym->type()));
osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis()));
osym.put_st_shndx(shndx);
}
// Check for unresolved symbols in shared libraries. This is
--- 2292,2313 ----
Symbol_table::sized_write_symbol(
Sized_symbol<size>* sym,
typename elfcpp::Elf_types<size>::Elf_Addr value,
unsigned int shndx,
const Stringpool* pool,
unsigned char* p) const
{
elfcpp::Sym_write<size, big_endian> osym(p);
osym.put_st_name(pool->get_offset(sym->name()));
osym.put_st_value(value);
! // Use a symbol size of zero for undefined symbols.
! osym.put_st_size(shndx == elfcpp::SHN_UNDEF ? 0 : sym->symsize());
// A version script may have overridden the default binding.
if (sym->is_forced_local())
osym.put_st_info(elfcpp::elf_st_info(elfcpp::STB_LOCAL, sym->type()));
else
osym.put_st_info(elfcpp::elf_st_info(sym->binding(), sym->type()));
osym.put_st_other(elfcpp::elf_st_other(sym->visibility(), sym->nonvis()));
osym.put_st_shndx(shndx);
}
// Check for unresolved symbols in shared libraries. This is