* 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.
This commit is contained in:
Richard Sandiford 2005-01-31 20:39:11 +00:00
parent 89fac5e3c3
commit 8c946ed5d5
12 changed files with 616 additions and 5 deletions

View File

@ -1,3 +1,17 @@
2005-01-31 Richard Sandiford <rsandifo@redhat.com>
* 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.
2005-01-31 Andrew Cagney <cagney@gnu.org>
* configure: Regenerate to track ../gettext.m4.

View File

@ -906,6 +906,12 @@ struct elf_backend_data
bfd_boolean (*elf_backend_ignore_discarded_relocs)
(asection *);
/* This function returns the width of FDE pointers in bytes, or 0 if
that can't be determined for some reason. The default definition
goes by the bfd's EI_CLASS. */
unsigned int (*elf_backend_eh_frame_address_size)
(bfd *, asection *);
/* These functions tell elf-eh-frame whether to attempt to turn
absolute or lsda encodings into pc-relative ones. The default
definition enables these transformations. */
@ -1381,6 +1387,8 @@ extern void _bfd_elf_sprintf_vma
extern void _bfd_elf_fprintf_vma
(bfd *, void *, bfd_vma);
extern unsigned int _bfd_elf_eh_frame_address_size
(bfd *, asection *);
extern bfd_byte _bfd_elf_encode_eh_address
(bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset,
asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded);

View File

@ -418,8 +418,10 @@ _bfd_elf_discard_section_eh_frame
it (it would need to use 64-bit .eh_frame format anyway). */
REQUIRE (sec->size == (unsigned int) sec->size);
ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
== ELFCLASS64) ? 8 : 4;
ptr_size = (get_elf_backend_data (abfd)
->elf_backend_eh_frame_address_size (abfd, sec));
REQUIRE (ptr_size != 0);
buf = ehbuf;
last_cie = NULL;
last_cie_inf = NULL;
@ -987,12 +989,14 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
unsigned int ptr_size;
struct eh_cie_fde *ent;
ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
== ELFCLASS64) ? 8 : 4;
if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
return bfd_set_section_contents (abfd, sec->output_section, contents,
sec->output_offset, sec->size);
ptr_size = (get_elf_backend_data (abfd)
->elf_backend_eh_frame_address_size (abfd, sec));
BFD_ASSERT (ptr_size != 0);
sec_info = elf_section_data (sec)->sec_info;
htab = elf_hash_table (info);
hdr_info = &htab->eh_info;
@ -1407,6 +1411,14 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
return retval;
}
/* Return the width of FDE addresses. This is the default implementation. */
unsigned int
_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
{
return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
}
/* Decide whether we can use a PC-relative encoding within the given
EH frame section. This is the default implementation. */

View File

@ -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:

View File

@ -24,6 +24,8 @@ extern bfd_boolean _bfd_mips_elf_new_section_hook
(bfd *, asection *);
extern void _bfd_mips_elf_symbol_processing
(bfd *, asymbol *);
extern unsigned int _bfd_mips_elf_eh_frame_address_size
(bfd *, asection *);
extern bfd_boolean _bfd_mips_elf_name_local_section_symbols
(bfd *);
extern bfd_boolean _bfd_mips_elf_section_processing
@ -124,3 +126,4 @@ extern struct bfd_elf_special_section const _bfd_mips_elf_special_sections[];
#define elf_backend_name_local_section_symbols \
_bfd_mips_elf_name_local_section_symbols
#define elf_backend_special_sections _bfd_mips_elf_special_sections
#define elf_backend_eh_frame_address_size _bfd_mips_elf_eh_frame_address_size

View File

@ -442,6 +442,9 @@
#ifndef elf_backend_ignore_discarded_relocs
#define elf_backend_ignore_discarded_relocs NULL
#endif
#ifndef elf_backend_eh_frame_address_size
#define elf_backend_eh_frame_address_size _bfd_elf_eh_frame_address_size
#endif
#ifndef elf_backend_can_make_relative_eh_frame
#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
#endif
@ -573,6 +576,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_reloc_type_class,
elf_backend_discard_info,
elf_backend_ignore_discarded_relocs,
elf_backend_eh_frame_address_size,
elf_backend_can_make_relative_eh_frame,
elf_backend_can_make_lsda_relative_eh_frame,
elf_backend_encode_eh_address,

View File

@ -1,3 +1,11 @@
2005-01-31 Richard Sandiford <rsandifo@redhat.com>
* ld-mips-elf/eh-frame1.s: Create a .gcc_compiled_long32 if using
32-bit pointers.
* ld-mips-elf/eh-frame1.d: Link in .gcc_compiled_long32 sections.
* ld-mips-elf/eh-frame[34].d: New tests.
* ld-mips-elf/mips-elf.exp: Run them.
2005-01-28 Jan Beulich <jbeulich@novell.com>
* ld/ia64/tlsbin.[rt]d: Widen expected offset/size ranges.

View File

@ -13,6 +13,7 @@ SECTIONS
. = 0x30000;
.eh_frame : { *(.eh_frame) }
.got : { *(.got) }
.gcc_compiled_long32 : { *(.gcc_compiled_long32) }
/DISCARD/ : { *(*) }
}

View File

@ -146,3 +146,7 @@
cie_basic basic5
fde_basic basic5,.text,0x10
.if alignment == 2
.section .gcc_compiled_long32
.endif

View File

@ -0,0 +1,280 @@
# This test is for the official LP64 version of EABI64, which uses a
# combination of 32-bit objects and 64-bit FDE addresses.
#
#name: MIPS eh-frame 3
#source: eh-frame1.s
#source: eh-frame1.s
#as: -EB -mips3 -mabi=eabi --defsym alignment=3 --defsym fill=0 --defsym foo=0x1020304050607080
#readelf: -wf
#ld: -melf32ebmip -Teh-frame1.ld
The section \.eh_frame contains:
00000000 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000010 00000014 00000014 FDE cie=00000000 pc=00020000..00020010
00000028 00000014 0000002c FDE cie=00000000 pc=00020010..00020030
# basic2 removed
00000040 00000014 00000044 FDE cie=00000000 pc=00020030..00020060
# basic3 removed
00000058 00000014 0000005c FDE cie=00000000 pc=00020060..000200a0
# basic4 removed
00000070 00000014 00000074 FDE cie=00000000 pc=000200a0..000200f0
00000088 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 10 20 30 40 50 60 70 80
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000a8 0000001c 00000024 FDE cie=00000088 pc=000200f0..00020100
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000c8 0000001c 00000044 FDE cie=00000088 pc=00020100..00020120
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000e8 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00 10 20 30 40 50 60 70 80
00000108 0000001c 00000024 FDE cie=000000e8 pc=00020120..00020130
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000128 0000001c 00000044 FDE cie=000000e8 pc=00020130..00020150
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000148 0000001c 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 10 20 30 40 50 60 70 80 00
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000168 0000001c 00000024 FDE cie=00000148 pc=00020150..00020160
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# FDE for .discard removed
# zPR2 removed
00000188 0000001c 00000044 FDE cie=00000148 pc=00020160..00020190
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001a8 0000001c 00000064 FDE cie=00000148 pc=00020190..000201d0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001c8 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001d8 00000014 00000014 FDE cie=000001c8 pc=000201d0..000201e0
# basic1 removed, followed by repeat of above
000001f0 00000014 0000002c FDE cie=000001c8 pc=000201e0..000201f0
00000208 00000014 00000044 FDE cie=000001c8 pc=000201f0..00020210
00000220 00000014 0000005c FDE cie=000001c8 pc=00020210..00020240
00000238 00000014 00000074 FDE cie=000001c8 pc=00020240..00020280
00000250 00000014 0000008c FDE cie=000001c8 pc=00020280..000202d0
00000268 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 10 20 30 40 50 60 70 80
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000288 0000001c 00000024 FDE cie=00000268 pc=000202d0..000202e0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000002a8 0000001c 00000044 FDE cie=00000268 pc=000202e0..00020300
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000002c8 0000001c 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 00 00 00 00 10 20 30 40 50 60 70 80
000002e8 0000001c 00000024 FDE cie=000002c8 pc=00020300..00020310
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000308 0000001c 00000044 FDE cie=000002c8 pc=00020310..00020330
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000328 0000001c 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 10 20 30 40 50 60 70 80 00
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000348 0000001c 00000024 FDE cie=00000328 pc=00020330..00020340
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# FDE for .discard removed
# zPR2 removed
00000368 0000001c 00000044 FDE cie=00000328 pc=00020340..00020370
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000388 0000001c 00000064 FDE cie=00000328 pc=00020370..000203b0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000003a8 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000003b8 00000014 00000014 FDE cie=000003a8 pc=000203b0..000203c0

View File

@ -0,0 +1,207 @@
# This test is for the semi-official ILP32 variation of EABI64.
#
#name: MIPS eh-frame 4
#source: eh-frame1.s
#source: eh-frame1.s
#as: -EB -mips3 -mabi=eabi --defsym alignment=2 --defsym fill=0 --defsym foo=0x50607080
#readelf: -wf
#ld: -melf32ebmip -Teh-frame1.ld
The section \.eh_frame contains:
00000000 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000010 0000000c 00000014 FDE cie=00000000 pc=00020000..00020010
00000020 0000000c 00000024 FDE cie=00000000 pc=00020010..00020030
# basic2 removed
00000030 0000000c 00000034 FDE cie=00000000 pc=00020030..00020060
# basic3 removed
00000040 0000000c 00000044 FDE cie=00000000 pc=00020060..000200a0
# basic4 removed
00000050 0000000c 00000054 FDE cie=00000000 pc=000200a0..000200f0
00000060 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 50 60 70 80
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000078 00000010 0000001c FDE cie=00000060 pc=000200f0..00020100
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
0000008c 00000010 00000030 FDE cie=00000060 pc=00020100..00020120
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000a0 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 50 60 70 80
000000b8 00000010 0000001c FDE cie=000000a0 pc=00020120..00020130
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000cc 00000010 00000030 FDE cie=000000a0 pc=00020130..00020150
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000000e0 00000014 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 50 60 70 80 00
DW_CFA_nop
000000f8 00000010 0000001c FDE cie=000000e0 pc=00020150..00020160
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# FDE for .discard removed
# zPR2 removed
0000010c 00000010 00000030 FDE cie=000000e0 pc=00020160..00020190
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000120 00000010 00000044 FDE cie=000000e0 pc=00020190..000201d0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000134 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000144 0000000c 00000014 FDE cie=00000134 pc=000201d0..000201e0
# basic1 removed, followed by repeat of above
00000154 0000000c 00000024 FDE cie=00000134 pc=000201e0..000201f0
00000164 0000000c 00000034 FDE cie=00000134 pc=000201f0..00020210
00000174 0000000c 00000044 FDE cie=00000134 pc=00020210..00020240
00000184 0000000c 00000054 FDE cie=00000134 pc=00020240..00020280
00000194 0000000c 00000064 FDE cie=00000134 pc=00020280..000202d0
000001a4 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 50 60 70 80
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001bc 00000010 0000001c FDE cie=000001a4 pc=000202d0..000202e0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001d0 00000010 00000030 FDE cie=000001a4 pc=000202e0..00020300
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
000001e4 00000014 00000000 CIE
Version: 1
Augmentation: "zP"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 50 00 00 00 50 60 70 80
000001fc 00000010 0000001c FDE cie=000001e4 pc=00020300..00020310
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000210 00000010 00000030 FDE cie=000001e4 pc=00020310..00020330
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000224 00000014 00000000 CIE
Version: 1
Augmentation: "zPR"
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
Augmentation data: 00 50 60 70 80 00
DW_CFA_nop
0000023c 00000010 0000001c FDE cie=00000224 pc=00020330..00020340
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
# FDE for .discard removed
# zPR2 removed
00000250 00000010 00000030 FDE cie=00000224 pc=00020340..00020370
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000264 00000010 00000044 FDE cie=00000224 pc=00020370..000203b0
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000278 0000000c 00000000 CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: 4
Return address column: 31
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00000288 0000000c 00000014 FDE cie=00000278 pc=000203b0..000203c0

View File

@ -81,6 +81,10 @@ if {$has_newabi && $linux_gnu} {
run_dump_test "eh-frame2-n32"
run_dump_test "eh-frame2-n64"
}
if {$embedded_elf} {
run_dump_test "eh-frame3"
run_dump_test "eh-frame4"
}
run_dump_test "jaloverflow"
run_dump_test "jaloverflow-2"