diff options
-rw-r--r-- | gold/ChangeLog | 9 | ||||
-rw-r--r-- | gold/incremental.cc | 16 | ||||
-rw-r--r-- | gold/incremental.h | 5 | ||||
-rw-r--r-- | gold/layout.cc | 8 | ||||
-rw-r--r-- | gold/object.cc | 4 |
5 files changed, 35 insertions, 7 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index a44b8b5..6f72f92 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,12 @@ +2011-09-18 Cary Coutant <ccoutant@google.com> + + * incremental.cc (can_incremental_update): New function. + * incremental.h (can_incremental_update): New function. + * layout.cc (Layout::init_fixed_output_section): Call it. + (Layout::make_output_section): Don't allow patch space in .eh_frame. + * object.cc (Sized_relobj_file::do_layout): Call + can_incremental_update. + 2011-09-13 Cary Coutant <ccoutant@google.com> * configure.ac: Check for glibc support for gnu_indirect_function diff --git a/gold/incremental.cc b/gold/incremental.cc index 4c4483d..998c04d 100644 --- a/gold/incremental.cc +++ b/gold/incremental.cc @@ -161,6 +161,22 @@ Incremental_binary::error(const char* format, ...) const va_end(args); } +// Return TRUE if a section of type SH_TYPE will can be updated in place +// during an incremental update. We can update sections of type PROGBITS, +// NOBITS, INIT_ARRAY, FINI_ARRAY, PREINIT_ARRAY, and NOTE. All others +// will be regenerated. + +bool +can_incremental_update(unsigned int sh_type) +{ + return (sh_type == elfcpp::SHT_PROGBITS + || sh_type == elfcpp::SHT_NOBITS + || sh_type == elfcpp::SHT_INIT_ARRAY + || sh_type == elfcpp::SHT_FINI_ARRAY + || sh_type == elfcpp::SHT_PREINIT_ARRAY + || sh_type == elfcpp::SHT_NOTE); +} + // Find the .gnu_incremental_inputs section and related sections. template<int size, bool big_endian> diff --git a/gold/incremental.h b/gold/incremental.h index 1e4d9f5..5d1ebda 100644 --- a/gold/incremental.h +++ b/gold/incremental.h @@ -81,6 +81,11 @@ enum Incremental_shlib_symbol_flags static const int INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT = 30; +// Return TRUE if a section of type SH_TYPE will can be updated in place +// during an incremental update. +bool +can_incremental_update(unsigned int sh_type); + // Create an Incremental_binary object for FILE. Returns NULL is this is not // possible, e.g. FILE is not an ELF file or has an unsupported target. diff --git a/gold/layout.cc b/gold/layout.cc index afb5b6a..1c32bcf 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -898,11 +898,10 @@ Layout::init_fixed_output_section(const char* name, { unsigned int sh_type = shdr.get_sh_type(); - // We preserve the layout of PROGBITS, NOBITS, and NOTE sections. + // We preserve the layout of PROGBITS, NOBITS, INIT_ARRAY, FINI_ARRAY, + // PRE_INIT_ARRAY, and NOTE sections. // All others will be created from scratch and reallocated. - if (sh_type != elfcpp::SHT_PROGBITS - && sh_type != elfcpp::SHT_NOBITS - && sh_type != elfcpp::SHT_NOTE) + if (!can_incremental_update(sh_type)) return NULL; typename elfcpp::Elf_types<size>::Elf_Addr sh_addr = shdr.get_sh_addr(); @@ -1442,6 +1441,7 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type, && order != ORDER_FINI && order != ORDER_RELRO_LAST && order != ORDER_NON_RELRO_FIRST + && strcmp(name, ".eh_frame") != 0 && strcmp(name, ".ctors") != 0 && strcmp(name, ".dtors") != 0 && strcmp(name, ".jcr") != 0) diff --git a/gold/object.cc b/gold/object.cc index 99c2ca7..84a9646 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1344,9 +1344,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab, Incremental_inputs* incremental_inputs = layout->incremental_inputs(); if (incremental_inputs != NULL && !discard - && (shdr.get_sh_type() == elfcpp::SHT_PROGBITS - || shdr.get_sh_type() == elfcpp::SHT_NOBITS - || shdr.get_sh_type() == elfcpp::SHT_NOTE)) + && can_incremental_update(shdr.get_sh_type())) { off_t sh_size = shdr.get_sh_size(); section_size_type uncompressed_size; |