From 238d258f720ac6df748b9cc6c98646b3e4ddcd7e Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 18 Mar 2005 17:20:33 +0000 Subject: [PATCH] Add support for generating PLT lookups for the ColdFire. --- bfd/ChangeLog | 6 ++++ bfd/elf32-m68k.c | 94 ++++++++++++++++++++++++++++++++++++++++++--------- gas/ChangeLog | 5 +++ gas/config/tc-m68k.c | 2 ++ include/elf/ChangeLog | 4 +++ include/elf/m68k.h | 3 +- 6 files changed, 97 insertions(+), 17 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 75b8b61..10cf060 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2005-03-18 C Jaiprakash + + * elf32-m68k.c (elf_cfv4e_plt0_entry): plt entry for coldfire v4e. + (elf_m68k_adjust_dynamic_symbol,elf_m68k_finish_dynamic_symbol, + elf_m68k_finish_dynamic_sections): Use it. + 2005-03-17 Paul Brook Dan Jacobowitz Mark Mitchell diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index c98674d..99d97a5 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -217,6 +217,37 @@ static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] = 0, 0, 0, 0 /* replaced with offset to start of .plt. */ }; + +#define CFV4E_PLT_ENTRY_SIZE 24 + +#define CFV4E_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_CFV4E) + +static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] = +{ + 0x20, 0x3c, + 0, 0, 0, 0, /* Replaced with offset to .got + 4. */ + 0x2f, 0x3b, 0x08, 0xfa, /* move.l (%pc,addr),-(%sp) */ + 0x20, 0x3c, + 0, 0, 0, 0, /* Replaced with offset to .got + 8. */ + 0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */ + 0x4e, 0xd0, /* jmp (%a0) */ + 0x4e, 0x71 /* nop */ +}; + +/* Subsequent entries in a procedure linkage table look like this. */ + +static const bfd_byte elf_cfv4e_plt_entry[CFV4E_PLT_ENTRY_SIZE] = +{ + 0x20, 0x3c, + 0, 0, 0, 0, /* Replaced with offset to symbol's .got entry. */ + 0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */ + 0x4e, 0xd0, /* jmp (%a0) */ + 0x2f, 0x3c, /* move.l #offset,-(%sp) */ + 0, 0, 0, 0, /* Replaced with offset into relocation table. */ + 0x60, 0xff, /* bra.l .plt */ + 0, 0, 0, 0 /* Replaced with offset to start of .plt. */ +}; + #define CPU32_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_CPU32) #define PLT_CPU32_ENTRY_SIZE 24 @@ -977,6 +1008,8 @@ elf_m68k_adjust_dynamic_symbol (info, h) { if (CPU32_FLAG (dynobj)) s->size += PLT_CPU32_ENTRY_SIZE; + else if (CFV4E_FLAG (dynobj)) + s->size += CFV4E_PLT_ENTRY_SIZE; else s->size += PLT_ENTRY_SIZE; } @@ -998,6 +1031,8 @@ elf_m68k_adjust_dynamic_symbol (info, h) /* Make room for this entry. */ if (CPU32_FLAG (dynobj)) s->size += PLT_CPU32_ENTRY_SIZE; + else if (CFV4E_FLAG (dynobj)) + s->size += CFV4E_PLT_ENTRY_SIZE; else s->size += PLT_ENTRY_SIZE; @@ -1787,17 +1822,19 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) corresponds to this symbol. This is the index of this symbol in all the symbols for which we are making plt entries. The first entry in the procedure linkage table is reserved. */ - if ( CPU32_FLAG (output_bfd)) - plt_index = h->plt.offset / PLT_CPU32_ENTRY_SIZE - 1; + if (CPU32_FLAG (output_bfd)) + plt_index = (h->plt.offset / PLT_CPU32_ENTRY_SIZE) - 1; + else if (CFV4E_FLAG (output_bfd)) + plt_index = (h->plt.offset / CFV4E_PLT_ENTRY_SIZE) - 1; else - plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; + plt_index = (h->plt.offset / PLT_ENTRY_SIZE) - 1; /* Get the offset into the .got table of the entry that corresponds to this function. Each .got entry is 4 bytes. The first three are reserved. */ got_offset = (plt_index + 3) * 4; - if ( CPU32_FLAG (output_bfd)) + if (CPU32_FLAG (output_bfd)) { /* Fill in the entry in the procedure linkage table. */ memcpy (splt->contents + h->plt.offset, elf_cpu32_plt_entry, @@ -1806,6 +1843,14 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) plt_off2 = 12; plt_off3 = 18; } + else if (CFV4E_FLAG (output_bfd)) + { + memcpy (splt->contents + h->plt.offset, elf_cfv4e_plt_entry, + CFV4E_PLT_ENTRY_SIZE); + plt_off1 = 2; + plt_off2 = 14; + plt_off3 = 20; + } else { /* Fill in the entry in the procedure linkage table. */ @@ -1818,11 +1863,12 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) /* The offset is relative to the first extension word. */ bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset - - (splt->output_section->vma - + h->plt.offset + 2)), + sgot->output_section->vma + + sgot->output_offset + + got_offset + - (splt->output_section->vma + + h->plt.offset + + CFV4E_FLAG (output_bfd) ? 8 : 2), splt->contents + h->plt.offset + plt_off1); bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), @@ -1835,7 +1881,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) (splt->output_section->vma + splt->output_offset + h->plt.offset - + 8), + + CFV4E_FLAG (output_bfd) ? 12 : 8), sgot->contents + got_offset); /* Fill in the entry in the .rela.plt section. */ @@ -2013,9 +2059,25 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) /* Fill in the first entry in the procedure linkage table. */ if (splt->size > 0) { - if (!CPU32_FLAG (output_bfd)) + if (CFV4E_FLAG (output_bfd)) + { + memcpy (splt->contents, elf_cfv4e_plt0_entry, CFV4E_PLT_ENTRY_SIZE); + bfd_put_32 (output_bfd, + (sgot->output_section->vma + + sgot->output_offset + 4 + - (splt->output_section->vma + 2)), + splt->contents + 2); + bfd_put_32 (output_bfd, + (sgot->output_section->vma + + sgot->output_offset + 8 + - (splt->output_section->vma + 10) - 8), + splt->contents + 12); + elf_section_data (splt->output_section)->this_hdr.sh_entsize + = CFV4E_PLT_ENTRY_SIZE; + } + else if (CPU32_FLAG (output_bfd)) { - memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE); + memcpy (splt->contents, elf_cpu32_plt0_entry, PLT_CPU32_ENTRY_SIZE); bfd_put_32 (output_bfd, (sgot->output_section->vma + sgot->output_offset + 4 @@ -2027,11 +2089,11 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) - (splt->output_section->vma + 10)), splt->contents + 12); elf_section_data (splt->output_section)->this_hdr.sh_entsize - = PLT_ENTRY_SIZE; + = PLT_CPU32_ENTRY_SIZE; } - else /* cpu32 */ + else { - memcpy (splt->contents, elf_cpu32_plt0_entry, PLT_CPU32_ENTRY_SIZE); + memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE); bfd_put_32 (output_bfd, (sgot->output_section->vma + sgot->output_offset + 4 @@ -2043,7 +2105,7 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) - (splt->output_section->vma + 10)), splt->contents + 12); elf_section_data (splt->output_section)->this_hdr.sh_entsize - = PLT_CPU32_ENTRY_SIZE; + = PLT_ENTRY_SIZE; } } } diff --git a/gas/ChangeLog b/gas/ChangeLog index 46ef21c..268209e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2005-03-18 C Jaiprakash + + * config/tc-m68k.c (m68k_elf_final_processing): Set file specific + flag for coldfire v4e. + 2005-03-17 Bob Wilson * config/tc-xtensa.c (xg_apply_tentative_value): Rename to diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 8d0ed5c..db67d5e 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -7447,6 +7447,8 @@ void m68k_elf_final_processing (void) { /* Set file-specific flags if this is a cpu32 processor. */ + if (arch_coldfire_fpu (current_architecture)) + elf_elfheader (stdoutput)->e_flags |= EF_CFV4E; if (cpu_of_arch (current_architecture) & cpu32) elf_elfheader (stdoutput)->e_flags |= EF_CPU32; else if ((cpu_of_arch (current_architecture) & m68000up) diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 46df13d..e023f49 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2005-03-18 C Jaipraash + + * m68k.h (EF_CFV4E): Define. + 2005-03-17 Paul Brook Dan Jacobowitz Mark Mitchell diff --git a/include/elf/m68k.h b/include/elf/m68k.h index fe66c55..d6bc54f 100644 --- a/include/elf/m68k.h +++ b/include/elf/m68k.h @@ -1,5 +1,5 @@ /* MC68k ELF support for BFD. - Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -54,5 +54,6 @@ END_RELOC_NUMBERS (R_68K_max) #define EF_CPU32 0x00810000 #define EF_M68000 0x01000000 +#define EF_CFV4E 0x00008000 #endif -- 2.7.4