diff options
author | Sterling Augustine <saugustine@google.com> | 2010-05-28 18:10:45 +0000 |
---|---|---|
committer | Sterling Augustine <saugustine@google.com> | 2010-05-28 18:10:45 +0000 |
commit | 7aa091969e42137104101e96592fda46ffcd0e90 (patch) | |
tree | a0c2a1a3ca739106a23a61ef13c9c5a8d10fb513 /bfd/elf32-xtensa.c | |
parent | 1e225492405c82b0b7b9973d8f549e1411168e3d (diff) | |
download | gdb-7aa091969e42137104101e96592fda46ffcd0e90.zip gdb-7aa091969e42137104101e96592fda46ffcd0e90.tar.gz gdb-7aa091969e42137104101e96592fda46ffcd0e90.tar.bz2 |
2010-05-28 Sterling Augustine <sterling@tensilica.com>
* elf32-xtensa.c (elf_xtensa_relocate_section): Add a large amount
of code to change the bits in the instructions to match the changes
in the relocations. Declare dest_addr and sym_sec to help.
Diffstat (limited to 'bfd/elf32-xtensa.c')
-rw-r--r-- | bfd/elf32-xtensa.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 4d1b384..888a801 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -2672,6 +2672,9 @@ elf_xtensa_relocate_section (bfd *output_bfd, if (info->relocatable) { + bfd_vma dest_addr; + asection * sym_sec = get_elf_r_symndx_section (input_bfd, r_symndx); + /* This is a relocatable link. 1) If the reloc is against a section symbol, adjust according to the output section. @@ -2688,6 +2691,9 @@ elf_xtensa_relocate_section (bfd *output_bfd, return FALSE; } + dest_addr = sym_sec->output_section->vma + sym_sec->output_offset + + get_elf_r_symndx_offset (input_bfd, r_symndx) + rel->r_addend; + if (r_type == R_XTENSA_ASM_SIMPLIFY) { error_message = NULL; @@ -2724,25 +2730,41 @@ elf_xtensa_relocate_section (bfd *output_bfd, to work around problems with DWARF in relocatable links with some previous version of BFD. Now we can't easily get rid of the hack without breaking backward compatibility.... */ - if (rel->r_addend) + r = bfd_reloc_ok; + howto = &elf_howto_table[r_type]; + if (howto->partial_inplace && rel->r_addend) + { + r = elf_xtensa_do_reloc (howto, input_bfd, input_section, + rel->r_addend, contents, + rel->r_offset, FALSE, + &error_message); + rel->r_addend = 0; + } + else { - howto = &elf_howto_table[r_type]; - if (howto->partial_inplace) + /* Put the correct bits in the target instruction, even + though the relocation will still be present in the output + file. This makes disassembly clearer, as well as + allowing loadable kernel modules to work without needing + relocations on anything other than calls and l32r's. */ + + /* If it is not in the same section, there is nothing we can do. */ + if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP && + sym_sec->output_section == input_section->output_section) { r = elf_xtensa_do_reloc (howto, input_bfd, input_section, - rel->r_addend, contents, + dest_addr, contents, rel->r_offset, FALSE, &error_message); - if (r != bfd_reloc_ok) - { - if (!((*info->callbacks->reloc_dangerous) - (info, error_message, input_bfd, input_section, - rel->r_offset))) - return FALSE; - } - rel->r_addend = 0; } } + if (r != bfd_reloc_ok) + { + if (!((*info->callbacks->reloc_dangerous) + (info, error_message, input_bfd, input_section, + rel->r_offset))) + return FALSE; + } /* Done with work for relocatable link; continue with next reloc. */ continue; @@ -8848,6 +8870,9 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); + if (!internal_relocs && !relax_info->action_list.head) + return TRUE; + contents = retrieve_contents (abfd, sec, link_info->keep_memory); if (contents == NULL && sec_size != 0) { |