From 99e4ae17b92a887d5832d39f70ab865193cabb4f Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Sun, 26 Aug 2001 18:03:19 +0000 Subject: [PATCH] * elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf_cris_reloc_type_class): New. (elf_backend_reloc_type_class): Define. * elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf_backend_reloc_type_class): Define. (sh_elf_reloc_type_class): New. (sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. * elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the reloc is against read-only section. (elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of looking up section names for DT_TEXTREL. (elf32_arm_reloc_type_class): New. --- bfd/ChangeLog | 23 +++++++++++ bfd/elf32-arm.h | 102 ++++++++++++++++++++++++----------------------- bfd/elf32-cris.c | 59 ++++++++++++--------------- bfd/elf32-sh.c | 59 +++++++++++++-------------- 4 files changed, 130 insertions(+), 113 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cdab09608c3..2d21d8ad8e5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +2001-08-26 Andreas Jaeger + + * elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the + reloc is against read-only section. + (elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of + looking up section names for DT_TEXTREL. + (elf_cris_reloc_type_class): New. + (elf_backend_reloc_type_class): Define. + + * elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is + against read-only section. + (elf_backend_reloc_type_class): Define. + (sh_elf_reloc_type_class): New. + (sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of + looking up section names for DT_TEXTREL. + + * elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the + reloc is against read-only section. + (elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of + looking up section names for DT_TEXTREL. + (elf32_arm_reloc_type_class): New. + (elf_backend_reloc_type_class): Define. + 2001-08-25 Andreas Jaeger * oasys.c: Add missing prototypes. diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index af27354f400..fcde30ec84c 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -91,6 +91,9 @@ boolean bfd_elf32_arm_get_bfd_for_interworking PARAMS ((bfd *, struct bfd_link_info *)); boolean bfd_elf32_arm_process_before_allocation PARAMS ((bfd *, struct bfd_link_info *, int)); +static enum elf_reloc_type_class elf32_arm_reloc_type_class + PARAMS ((int)); + #define INTERWORK_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) /* The linker script knows the section names for placement. @@ -125,7 +128,7 @@ static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] = /* Subsequent entries in a procedure linkage table look like this. */ static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] = - { + { 0xe59fc004, /* ldr ip, [pc, #4] */ 0xe08fc00c, /* add ip, pc, ip */ 0xe59cf000, /* ldr pc, [ip] */ @@ -1058,7 +1061,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, /* If the start address has been set, then set the EF_ARM_HASENTRY flag. Setting this more than once is redundant, but the cost is not too high, and it keeps the code simple. - + The test is done here, rather than somewhere else, because the start address is only set just before the final link commences. @@ -1066,7 +1069,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, flag will not be set. */ if (bfd_get_start_address (output_bfd) != 0) elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY; - + globals = elf32_arm_hash_table (info); dynobj = elf_hash_table (info)->dynobj; @@ -1110,7 +1113,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, into the output file to be resolved at run time. */ if (info->shared && (r_type != R_ARM_PC24 - || (h != NULL + || (h != NULL && h->dynindx != -1 && (! info->symbolic || (h->elf_link_hash_flags @@ -1493,7 +1496,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, corresponding bit one in the target address will be set from bit one of the source address. */ lower_insn &= ~1; -#endif +#endif /* Put the relocated value back in the object file: */ bfd_put_16 (input_bfd, upper_insn, hit_data); bfd_put_16 (input_bfd, lower_insn, hit_data + 2); @@ -1533,8 +1536,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, calculation. */ value -= sgot->output_section->vma; return _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, value, - (bfd_vma) 0); + contents, rel->r_offset, value, + (bfd_vma) 0); case R_ARM_GOTPC: /* Use global offset table as symbol value. */ @@ -1545,8 +1548,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, value = sgot->output_section->vma; return _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, value, - (bfd_vma) 0); + contents, rel->r_offset, value, + (bfd_vma) 0); case R_ARM_GOT32: /* Relocation is to the entry for this symbol in the @@ -1629,8 +1632,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, } return _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, value, - (bfd_vma) 0); + contents, rel->r_offset, value, + (bfd_vma) 0); case R_ARM_PLT32: /* Relocation is to the entry for this symbol in the @@ -1640,8 +1643,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, without using the procedure linkage table. */ if (h == NULL) return _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, value, - (bfd_vma) 0); + contents, rel->r_offset, value, + (bfd_vma) 0); if (h->plt.offset == (bfd_vma) -1) /* We didn't make a PLT entry for this symbol. This @@ -1659,8 +1662,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, + splt->output_offset + h->plt.offset); return _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, value, - (bfd_vma) 0); + contents, rel->r_offset, value, + (bfd_vma) 0); case R_ARM_SBREL32: return bfd_reloc_notsupported; @@ -1872,7 +1875,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, case R_ARM_ABS32: if (info->shared && ( - (!info->symbolic && h->dynindx != -1) + (!info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 ) && ((input_section->flags & SEC_ALLOC) != 0 @@ -2310,7 +2313,7 @@ elf32_arm_print_private_bfd_data (abfd, ptr) if (flags & EF_ARM_MAPSYMSFIRST) fprintf (file, _(" [mapping symbols precede others]")); - flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX + flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX | EF_ARM_MAPSYMSFIRST); break; @@ -2506,7 +2509,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) srelgot = bfd_make_section (dynobj, ".rel.got"); if (srelgot == NULL || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC + (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY @@ -2534,7 +2537,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) } else { - /* This is a global offset table entry for a local + /* This is a global offset table entry for a local symbol. */ if (local_got_offsets == NULL) { @@ -2566,7 +2569,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) sgot->_raw_size += 4; break; - case R_ARM_PLT32: + case R_ARM_PLT32: /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, because this might be a case of linking PIC code which is @@ -2619,7 +2622,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) return false; BFD_ASSERT (strncmp (name, ".rel", 4) == 0 - && strcmp (bfd_get_section_name (abfd, sec), + && strcmp (bfd_get_section_name (abfd, sec), name + 4) == 0); sreloc = bfd_get_section_by_name (dynobj, name); @@ -2637,6 +2640,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) || ! bfd_set_section_alignment (dynobj, sreloc, 2)) return false; } + if (sec->flags & SEC_READONLY) + info->flags |= DF_TEXTREL; } sreloc->_raw_size += sizeof (Elf32_External_Rel); @@ -2951,14 +2956,13 @@ elf32_arm_adjust_dynamic_symbol (info, h) static boolean elf32_arm_size_dynamic_sections (output_bfd, info) - bfd * output_bfd; + bfd * output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info * info; { bfd * dynobj; asection * s; boolean plt; boolean relocs; - boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -3000,7 +3004,6 @@ elf32_arm_size_dynamic_sections (output_bfd, info) memory for them. */ plt = false; relocs = false; - reltext = false; for (s = dynobj->sections; s != NULL; s = s->next) { const char * name; @@ -3046,30 +3049,10 @@ elf32_arm_size_dynamic_sections (output_bfd, info) } else { - asection * target; - /* Remember whether there are any reloc sections other than .rel.plt. */ if (strcmp (name, ".rel.plt") != 0) - { - const char *outname; - - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rel.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - outname = bfd_get_section_name (output_bfd, - s->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 4); - - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = true; - } + relocs = true; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -3133,7 +3116,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info) return false; } - if (reltext) + if ((info->flags & DF_TEXTREL) != 0) { if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) return false; @@ -3457,29 +3440,48 @@ elf32_arm_post_process_headers (abfd, link_info) i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION; } +static enum elf_reloc_type_class +elf32_arm_reloc_type_class (type) + int type; +{ + switch (type) + { + case R_ARM_RELATIVE: + return reloc_class_relative; + case R_ARM_JUMP_SLOT: + return reloc_class_plt; + case R_ARM_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #define ELF_MAXPAGESIZE 0x8000 -#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data -#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data +#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data +#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data #define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags #define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create -#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup +#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line #define elf_backend_get_symbol_type elf32_arm_get_symbol_type #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook #define elf_backend_check_relocs elf32_arm_check_relocs -#define elf_backend_relocate_section elf32_arm_relocate_section +#define elf_backend_relocate_section elf32_arm_relocate_section #define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections #define elf_backend_finish_dynamic_symbol elf32_arm_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections #define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections #define elf_backend_post_process_headers elf32_arm_post_process_headers +#define elf_backend_reloc_type_class elf32_arm_reloc_type_class #define elf_backend_can_gc_sections 1 #define elf_backend_plt_readonly 1 diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index e57202b37dc..a4b5e09dc10 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -85,6 +85,8 @@ static boolean elf_cris_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); static void elf_cris_hide_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); +static enum elf_reloc_type_class elf_cris_reloc_type_class + PARAMS ((int)); static reloc_howto_type cris_elf_howto_table [] = { @@ -2575,6 +2577,8 @@ cris_elf_check_relocs (abfd, info, sec, relocs) || !bfd_set_section_alignment (dynobj, sreloc, 2)) return false; } + if (sec->flags & SEC_READONLY) + info->flags |= DF_TEXTREL; } sreloc->_raw_size += sizeof (Elf32_External_Rela); @@ -2642,14 +2646,13 @@ cris_elf_check_relocs (abfd, info, sec, relocs) static boolean elf_cris_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; + bfd *output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info *info; { bfd *dynobj; asection *s; boolean plt; boolean relocs; - boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -2703,7 +2706,6 @@ elf_cris_size_dynamic_sections (output_bfd, info) memory for them. */ plt = false; relocs = false; - reltext = false; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; @@ -2749,41 +2751,11 @@ elf_cris_size_dynamic_sections (output_bfd, info) } else { - asection *target; - /* Remember whether there are any reloc sections other than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) - { - const char *outname; - relocs = true; - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. - The entries in the .rela.plt section are actually - associated with .got.plt, which we created ourselves - and so know is not readonly. */ - outname = bfd_get_section_name (output_bfd, - s->output_section); - target - = bfd_get_section_by_name (output_bfd, - outname + strlen (".rela")); - - /* We have to test the .text section by name, becase for - some reason it does not have SEC_READONLY set at this - time. That flag is actually set in ldmain.c:main - specifically for ".text" at a time long after this - function is called. FIXME: This might be due to a - general bug. FIXME: Have testcase for this. */ - if (target != NULL - && (target->flags & SEC_ALLOC) != 0 - && ((target->flags & SEC_READONLY) != 0 - || strcmp (outname + strlen (".rela"), - ".text") == 0)) - reltext = true; - } - /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ s->reloc_count = 0; @@ -2842,7 +2814,7 @@ elf_cris_size_dynamic_sections (output_bfd, info) return false; } - if (reltext) + if ((info->flags & DF_TEXTREL) != 0) { if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) return false; @@ -3020,6 +2992,24 @@ cris_elf_merge_private_bfd_data (ibfd, obfd) return true; } + + +static enum elf_reloc_type_class +elf_cris_reloc_type_class (type) + int type; +{ + switch (type) + { + case R_CRIS_RELATIVE: + return reloc_class_relative; + case R_CRIS_JUMP_SLOT: + return reloc_class_plt; + case R_CRIS_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} #define ELF_ARCH bfd_arch_cris #define ELF_MACHINE_CODE EM_CRIS @@ -3063,6 +3053,7 @@ cris_elf_merge_private_bfd_data (ibfd, obfd) #define bfd_elf32_bfd_final_link \ _bfd_elf32_gc_common_final_link #define elf_backend_hide_symbol elf_cris_hide_symbol +#define elf_backend_reloc_type_class elf_cris_reloc_type_class #define elf_backend_want_got_plt 1 #define elf_backend_plt_readonly 1 diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 11ea3a5d4f4..6cf49749182 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -83,6 +83,8 @@ static asection * sh_elf_gc_mark_hook static boolean sh_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); +static enum elf_reloc_type_class sh_elf_reloc_type_class + PARAMS ((int)); /* The name of the dynamic interpreter. This is put in the .interp section. */ @@ -1111,11 +1113,11 @@ sh_elf_relax_section (abfd, sec, link_info, again) } /* Get the address from which the register is being loaded. The - displacement in the mov.l instruction is quadrupled. It is a - displacement from four bytes after the movl instruction, but, - before adding in the PC address, two least significant bits - of the PC are cleared. We assume that the section is aligned - on a four byte boundary. */ + displacement in the mov.l instruction is quadrupled. It is a + displacement from four bytes after the movl instruction, but, + before adding in the PC address, two least significant bits + of the PC are cleared. We assume that the section is aligned + on a four byte boundary. */ paddr = insn & 0xff; paddr *= 4; paddr += (laddr + 4) & ~3; @@ -2761,14 +2763,13 @@ sh_elf_adjust_dynamic_symbol (info, h) static boolean sh_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; + bfd *output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info *info; { bfd *dynobj; asection *s; boolean plt; boolean relocs; - boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -2810,7 +2811,6 @@ sh_elf_size_dynamic_sections (output_bfd, info) memory for them. */ plt = false; relocs = false; - reltext = false; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; @@ -2856,29 +2856,10 @@ sh_elf_size_dynamic_sections (output_bfd, info) } else { - asection *target; - /* Remember whether there are any reloc sections other than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) - { - const char *outname; - - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rela.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - outname = bfd_get_section_name (output_bfd, - s->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = true; - } + relocs = true; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -2934,7 +2915,7 @@ sh_elf_size_dynamic_sections (output_bfd, info) return false; } - if (reltext) + if ((info->flags & DF_TEXTREL) != 0) { if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) return false; @@ -3957,6 +3938,8 @@ sh_elf_check_relocs (abfd, info, sec, relocs) || ! bfd_set_section_alignment (dynobj, sreloc, 2)) return false; } + if (sec->flags & SEC_READONLY) + info->flags |= DF_TEXTREL; } sreloc->_raw_size += sizeof (Elf32_External_Rela); @@ -4441,6 +4424,23 @@ sh_elf_finish_dynamic_sections (output_bfd, info) return true; } +static enum elf_reloc_type_class +sh_elf_reloc_type_class (type) + int type; +{ + switch (type) + { + case R_SH_RELATIVE: + return reloc_class_relative; + case R_SH_JMP_SLOT: + return reloc_class_plt; + case R_SH_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + #ifndef ELF_ARCH #define TARGET_BIG_SYM bfd_elf32_sh_vec #define TARGET_BIG_NAME "elf32-sh" @@ -4484,6 +4484,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info) sh_elf_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ sh_elf_finish_dynamic_sections +#define elf_backend_reloc_type_class sh_elf_reloc_type_class #define elf_backend_want_got_plt 1 #define elf_backend_plt_readonly 1 -- 2.30.2