diff options
author | Cary Coutant <ccoutant@google.com> | 2008-05-01 01:23:21 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2008-05-01 01:23:21 +0000 |
commit | e94cf1277329c4eaba3b398b446e693550463c77 (patch) | |
tree | c3264396a84db5f5c415e8465cef5d21f58db7cf /gold/target-reloc.h | |
parent | 1af5d7ceb5960c714e55c2fdf80c22b52db84738 (diff) | |
download | gdb-e94cf1277329c4eaba3b398b446e693550463c77.zip gdb-e94cf1277329c4eaba3b398b446e693550463c77.tar.gz gdb-e94cf1277329c4eaba3b398b446e693550463c77.tar.bz2 |
* layout.cc (Layout::include_section): Refactored check for debug
info section.
(Layout::add_comdat): Add new parameters. Change type
of signature parameter. Add object and shndx to signatures table.
(Layout::find_kept_object): New function.
* layout.h: Include <cstring>.
(Layout::is_debug_info_section): New function.
(Layout::add_comdat): Add new parameters.
(Layout::find_kept_object): New function.
(Layout::Kept_section): New struct.
(Layout::Signatures): Change type of map range.
* object.cc (Relobj::output_section_address): New function.
(Sized_relobj::include_section_group): Add new parameters. Change
calls to Layout::add_comdat. Change to build table of kept comdat
groups and table mapping discarded sections to kept sections.
(Sized_relobj::include_linkonce_section): Likewise. Add new parameter.
(Sized_relobj::do_layout): Change calls to include_section_group and
include_linkonce_section.
(Sized_relobj::do_finalize_local_symbols): Do not set local symbol
value to zero when section is discarded.
(Sized_relobj::map_to_kept_section): New function.
* object.h (Relobj::output_section_address): New function.
(Relobj::Comdat_group): New type.
(Relobj::find_comdat_group): New function.
(Relobj::Comdat_group_table): New type.
(Relobj::Kept_comdat_section): New type.
(Relobj::Kept_comdat_section_table): New type.
(Relobj::add_comdat_group): New function.
(Relobj::set_kept_comdat_section): New function.
(Relobj::get_kept_comdat_section): New function.
(Relobj::comdat_groups_): New field.
(Relobj::kept_comdat_sections_): New field.
(Symbol_value::input_value): Update comment.
(Sized_relobj::map_to_kept_section) New function.
(Sized_relobj::include_linkonce_section): Add new parameter.
* target-reloc.h (Comdat_behavior): New type.
(get_comdat_behavior): New function.
(relocate_section): Add code to map a discarded section to the
corresponding kept section when applying a relocation.
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r-- | gold/target-reloc.h | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h index b0d71f5..e1c3cc3 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -119,6 +119,31 @@ scan_relocs( } } +// Behavior for relocations to discarded comdat sections. + +enum Comdat_behavior +{ + CB_UNDETERMINED, // Not yet determined -- need to look at section name. + CB_PRETEND, // Attempt to map to the corresponding kept section. + CB_IGNORE, // Ignore the relocation. + CB_WARNING // Print a warning. +}; + +// Decide what the linker should do for relocations that refer to discarded +// comdat sections. This decision is based on the name of the section being +// relocated. + +inline Comdat_behavior +get_comdat_behavior(const char* name) +{ + if (Layout::is_debug_info_section(name)) + return CB_PRETEND; + if (strcmp(name, ".eh_frame") == 0 + || strcmp(name, ".gcc_except_table") == 0) + return CB_IGNORE; + return CB_WARNING; +} + // This function implements the generic part of relocation processing. // The template parameter Relocate must be a class type which provides // a single function, relocate(), which implements the machine @@ -159,6 +184,8 @@ relocate_section( Sized_relobj<size, big_endian>* object = relinfo->object; unsigned int local_count = object->local_symbol_count(); + Comdat_behavior comdat_behavior = CB_UNDETERMINED; + for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) { Reltype reloc(prelocs); @@ -187,6 +214,44 @@ relocate_section( { sym = NULL; psymval = object->local_symbol(r_sym); + + // If the local symbol belongs to a section we are discarding, + // and that section is a debug section, try to find the + // corresponding kept section and map this symbol to its + // counterpart in the kept section. + bool is_ordinary; + unsigned int shndx = psymval->input_shndx(&is_ordinary); + if (is_ordinary + && shndx != elfcpp::SHN_UNDEF + && !object->is_section_included(shndx)) + { + if (comdat_behavior == CB_UNDETERMINED) + { + const char* name = + object->section_name(relinfo->data_shndx).c_str(); + comdat_behavior = get_comdat_behavior(name); + } + if (comdat_behavior == CB_PRETEND) + { + bool found; + typename elfcpp::Elf_types<size>::Elf_Addr value = + object->map_to_kept_section(shndx, &found); + if (found) + symval.set_output_value(value + psymval->input_value()); + else + symval.set_output_value(0); + } + else + { + if (comdat_behavior == CB_WARNING) + gold_warning_at_location(relinfo, i, offset, + _("Relocation refers to discarded " + "comdat section")); + symval.set_output_value(0); + } + symval.set_no_output_symtab_entry(); + psymval = &symval; + } } else { |