diff options
author | Ian Lance Taylor <iant@google.com> | 2007-11-09 07:00:15 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-11-09 07:00:15 +0000 |
commit | 730cdc88f70c0804b5daf2259d3bd8ad29b6411b (patch) | |
tree | bdc5f06993a5579fea47d658ecb900c9586727f2 /gold/target-reloc.h | |
parent | 0abe36f50df0f2475fec735f5c907bb7af584ab0 (diff) | |
download | gdb-730cdc88f70c0804b5daf2259d3bd8ad29b6411b.zip gdb-730cdc88f70c0804b5daf2259d3bd8ad29b6411b.tar.gz gdb-730cdc88f70c0804b5daf2259d3bd8ad29b6411b.tar.bz2 |
Generate a complete exception frame header. Discard duplicate
exception frame information.
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r-- | gold/target-reloc.h | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h index c38d5f6..0498e9a 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -24,7 +24,6 @@ #define GOLD_TARGET_RELOC_H #include "elfcpp.h" -#include "object.h" #include "symtab.h" #include "reloc-types.h" @@ -49,9 +48,10 @@ scan_relocs( unsigned int data_shndx, const unsigned char* prelocs, size_t reloc_count, + Output_section* output_section, + bool needs_special_offset_handling, size_t local_count, - const unsigned char* plocal_syms, - Symbol** global_syms) + const unsigned char* plocal_syms) { typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; @@ -62,6 +62,11 @@ scan_relocs( { Reltype reloc(prelocs); + if (needs_special_offset_handling + && !output_section->is_input_address_mapped(object, data_shndx, + reloc.get_r_offset())) + continue; + typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info(); unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); unsigned int r_type = elfcpp::elf_r_type<size>(r_info); @@ -99,7 +104,7 @@ scan_relocs( } else { - Symbol* gsym = global_syms[r_sym - local_count]; + Symbol* gsym = object->global_symbol(r_sym); gold_assert(gsym != NULL); if (gsym->is_forwarder()) gsym = symtab->resolve_forwards(gsym); @@ -122,8 +127,14 @@ scan_relocs( // RELOCATE implements operator() to do a relocation. // PRELOCS points to the relocation data. RELOC_COUNT is the number -// of relocs. VIEW is the section data, VIEW_ADDRESS is its memory -// address, and VIEW_SIZE is the size. +// of relocs. OUTPUT_SECTION is the output section. +// NEEDS_SPECIAL_OFFSET_HANDLING is true if input offsets need to be +// mapped to output offsets. + +// VIEW is the section data, VIEW_ADDRESS is its memory address, and +// VIEW_SIZE is the size. These refer to the input section, unless +// NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to +// the output section. template<int size, bool big_endian, typename Target_type, int sh_type, typename Relocate> @@ -133,6 +144,8 @@ relocate_section( Target_type* target, const unsigned char* prelocs, size_t reloc_count, + Output_section* output_section, + bool needs_special_offset_handling, unsigned char* view, typename elfcpp::Elf_types<size>::Elf_Addr view_address, off_t view_size) @@ -141,10 +154,8 @@ relocate_section( const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; Relocate relocate; - unsigned int local_count = relinfo->local_symbol_count; - const typename Sized_relobj<size, big_endian>::Local_values* local_values = - relinfo->local_values; - const Symbol* const * global_syms = relinfo->symbols; + Sized_relobj<size, big_endian>* object = relinfo->object; + unsigned int local_count = object->local_symbol_count(); for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) { @@ -152,6 +163,15 @@ relocate_section( off_t offset = reloc.get_r_offset(); + if (needs_special_offset_handling) + { + offset = output_section->output_offset(relinfo->object, + relinfo->data_shndx, + offset); + if (offset == -1) + continue; + } + typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info(); unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); unsigned int r_type = elfcpp::elf_r_type<size>(r_info); @@ -163,11 +183,11 @@ relocate_section( if (r_sym < local_count) { sym = NULL; - psymval = &(*local_values)[r_sym]; + psymval = object->local_symbol(r_sym); } else { - const Symbol* gsym = global_syms[r_sym - local_count]; + const Symbol* gsym = object->global_symbol(r_sym); gold_assert(gsym != NULL); if (gsym->is_forwarder()) gsym = relinfo->symtab->resolve_forwards(gsym); |