diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2005-01-31 20:39:11 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2005-01-31 20:39:11 +0000 |
commit | 8c946ed5d5af555d95f39630fcb56bfc6b0ce93b (patch) | |
tree | 65cab0a41c020d51a982aef8b506199ec171ea51 /bfd/elfxx-mips.c | |
parent | 89fac5e3c33745a93c9b90538048505d46ca365c (diff) | |
download | gdb-8c946ed5d5af555d95f39630fcb56bfc6b0ce93b.zip gdb-8c946ed5d5af555d95f39630fcb56bfc6b0ce93b.tar.gz gdb-8c946ed5d5af555d95f39630fcb56bfc6b0ce93b.tar.bz2 |
* elf-bfd.h (elf_backend_data): Add elf_backend_eh_frame_address_size.
(_bfd_elf_eh_frame_address_size): Declare.
* elfxx-target.h (elf_backend_eh_frame_address_size): Define a default.
(elfNN_bed): Initialize elf_backend_eh_frame_address_size.
* elfxx-mips.h (_bfd_mips_elf_eh_frame_address_size): Declare.
(elf_backend_eh_frame_address_size): Define.
* elfxx-mips.c (_bfd_mips_elf_eh_frame_address_size): New function.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Get the address
size from the new backend hook.
(_bfd_elf_write_section_eh_frame): Likewise.
(_bfd_elf_eh_frame_address_size): New function.
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r-- | bfd/elfxx-mips.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 9ec9c86..595c9df 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -4248,6 +4248,72 @@ _bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym) } } +/* Implement elf_backend_eh_frame_address_size. This differs from + the default in the way it handles EABI64. + + EABI64 was originally specified as an LP64 ABI, and that is what + -mabi=eabi normally gives on a 64-bit target. However, gcc has + historically accepted the combination of -mabi=eabi and -mlong32, + and this ILP32 variation has become semi-official over time. + Both forms use elf32 and have pointer-sized FDE addresses. + + If an EABI object was generated by GCC 4.0 or above, it will have + an empty .gcc_compiled_longXX section, where XX is the size of longs + in bits. Unfortunately, ILP32 objects generated by earlier compilers + have no special marking to distinguish them from LP64 objects. + + We don't want users of the official LP64 ABI to be punished for the + existence of the ILP32 variant, but at the same time, we don't want + to mistakenly interpret pre-4.0 ILP32 objects as being LP64 objects. + We therefore take the following approach: + + - If ABFD contains a .gcc_compiled_longXX section, use it to + determine the pointer size. + + - Otherwise check the type of the first relocation. Assume that + the LP64 ABI is being used if the relocation is of type R_MIPS_64. + + - Otherwise punt. + + The second check is enough to detect LP64 objects generated by pre-4.0 + compilers because, in the kind of output generated by those compilers, + the first relocation will be associated with either a CIE personality + routine or an FDE start address. Furthermore, the compilers never + used a special (non-pointer) encoding for this ABI. + + Checking the relocation type should also be safe because there is no + reason to use R_MIPS_64 in an ILP32 object. Pre-4.0 compilers never + did so. */ + +unsigned int +_bfd_mips_elf_eh_frame_address_size (bfd *abfd, asection *sec) +{ + if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) + return 8; + if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64) + { + bfd_boolean long32_p, long64_p; + + long32_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long32") != 0; + long64_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long64") != 0; + if (long32_p && long64_p) + return 0; + if (long32_p) + return 4; + if (long64_p) + return 8; + + if (sec->reloc_count > 0 + && elf_section_data (sec)->relocs != NULL + && (ELF32_R_TYPE (elf_section_data (sec)->relocs[0].r_info) + == R_MIPS_64)) + return 8; + + return 0; + } + return 4; +} + /* There appears to be a bug in the MIPSpro linker that causes GOT_DISP relocations against two unnamed section symbols to resolve to the same address. For example, if we have code like: |