This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On Apr 12, 2004, Alan Modra <amodra@bigpond.net.au> wrote: > On Sat, Apr 10, 2004 at 12:47:15AM -0300, Alexandre Oliva wrote: >> I suppose I could create a new bfd arch used for object files that >> have the EF_FRV_FDPIC bit set, but this would suck in terms of >> duplication of code :-( > grep will show you a number of other architectures that include > elf32-target two or more times. Doing that in elf32-frv.c, and making a > few tweaks here and there should let you do what you want without much > duplication. Ah, yes! Cool, I'd forgotten we could do that. It's exactly what I needed. This big patch implements your suggestion. While at that, I thought I'd rename all FDPIC-specific identifiers to make it clear that they're FDPIC-only, which made the patch huge. I attach a separate, smaller patch-lookalike that shows all non-mechanical changes contained in the patch. Having a separate BFD vector has enabled several simplifications. I also include a bug fix: when linking a shared library, we wouldn't relocate contents of debugging sections properly. I also noticed that the non-PCREL exception handling patch is missing from the 2.15 branch. This means FDPIC is pretty much broken, at least for C++, so there's little point in even trying to fix it in the branch. I attach a patch for the branch anyway, after the patch for mainline. They're equivalent except for the changes to the EH-related functions that didn't exist in the branch. I adjusted the testsuite to accept both bfd vector names, such that they'd pass in both frv-elf and frv-uclinux. The latter defaults to -mfdpic in the assembler now; previously, the linker used the elf32frvfd emulation but object files assembled directly from source didn't get the FDPIC bit set, which could be confusing. No regressions in mainline or branch, both frv-elf and frv-uclinux tested, the former with --enable-targets=all. Is the first bzip2ed attachment ok for mainline? Is the second ok for the branch?
--- bfd/elf32-frv.c +++ bfd/elf32-frv.c @@ -1,5 +1,5 @@ /* FRV-specific support for 32-bit ELF. - Copyright 2002, 2003 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -583,6 +583,8 @@ static const struct frv_reloc_map frv_re }; #endif +extern const bfd_target bfd_elf32_frv_vec; +#define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_frv_vec) /* An extension of the elf hash table data structure, containing some additional FRV-specific data. */ @@ -1871,19 +1897,19 @@ elf32_frv_relocate_section (output_bfd, isec_segment = _frv_osec_to_segment (output_bfd, input_section->output_section); - if (frv_got_section (info)) + if (IS_FDPIC (output_bfd) && frv_got_section (info)) got_segment = _frv_osec_to_segment (output_bfd, frv_got_section (info) ->output_section); else got_segment = -1; - if (frv_gotfixup_section (info)) + if (IS_FDPIC (output_bfd) && frv_gotfixup_section (info)) gprel_segment = _frv_osec_to_segment (output_bfd, frv_gotfixup_section (info) ->output_section); else gprel_segment = -1; - if (elf_hash_table (info)->dynamic_sections_created) + if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created) plt_segment = _frv_osec_to_segment (output_bfd, frv_plt_section (info) ->output_section); @@ -1977,6 +2003,9 @@ elf32_frv_relocate_section (output_bfd, { case R_FRV_LABEL24: case R_FRV_32: + if (! IS_FDPIC (output_bfd)) + goto non_fdpic; + case R_FRV_GOT12: case R_FRV_GOTHI: case R_FRV_GOTLO: return FALSE; if (!_frv_emit_got_relocs_plt_entries (picrel, output_bfd, info, - osec, sym, rel->r_addend)) + osec, sym, + rel->r_addend)) { - info->callbacks->warning - (info, _("Dynamic relocation references symbol with nonzero addend"), - name, input_bfd, input_section, rel->r_offset); + (*_bfd_error_handler) + (_("%s: relocation at `%s+0x%x' references symbol `%s' with nonzero addend"), + bfd_archive_filename (input_bfd), input_section->name, + rel->r_offset, name); return FALSE; } @@ -2018,6 +2049,7 @@ elf32_frv_relocate_section (output_bfd, break; default: + non_fdpic: picrel = NULL; if (h && ! FRV_SYM_LOCAL (info, h)) { @@ -2033,7 +2065,9 @@ elf32_frv_relocate_section (output_bfd, { case R_FRV_LABEL24: check_segment[0] = isec_segment; - if (picrel->plt) + if (! IS_FDPIC (output_bfd)) + check_segment[1] = isec_segment; + else if (picrel->plt) { relocation = frv_plt_section (info)->output_section->vma + frv_plt_section (info)->output_offset @@ -2181,14 +2219,18 @@ elf32_frv_relocate_section (output_bfd, + input_section->output_offset, r_type, dynindx, addend, picrel); } + else + addend += frv_got_section (info)->output_section->vma; } /* We want the addend in-place because dynamic @@ -2200,6 +2242,12 @@ elf32_frv_relocate_section (output_bfd, break; case R_FRV_32: + if (! IS_FDPIC (output_bfd)) + { + check_segment[0] = check_segment[1] = -1; + break; + } + /* Fall through. */ case R_FRV_FUNCDESC_VALUE: { int dynindx; @@ -2239,7 +2291,7 @@ elf32_frv_relocate_section (output_bfd, { if (osec) addend += osec->output_section->vma; - if ((elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC) + if (IS_FDPIC (input_bfd) && (bfd_get_section_flags (output_bfd, input_section->output_section) & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) @@ -2294,14 +2346,18 @@ elf32_frv_relocate_section (output_bfd, + input_section->output_offset, r_type, dynindx, addend, picrel); } + else if (osec) + addend += osec->output_section->vma; /* We want the addend in-place because dynamic relocations are REL. Setting relocation to it should arrange for it to be installed. */ @@ -2357,10 +2414,10 @@ elf32_frv_relocate_section (output_bfd, break; } - if (check_segment[0] != check_segment[1] - && (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC)) + if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd)) { -#if 1 +#if 1 /* If you take this out, remove the #error from fdpic-static-6.d + in the ld testsuite. */ /* This helps catch problems in GCC while we can't do more than static linking. The idea is to test whether the input file basename is crt0.o only once. */ @@ -2417,7 +2474,7 @@ elf32_frv_relocate_section (output_bfd, switch (r_type) { case R_FRV_LABEL24: - if (! picrel->plt) + if (! IS_FDPIC (output_bfd) || ! picrel->plt) break; /* Fall through. */ @@ -2614,6 +2671,7 @@ elf32_frv_add_symbol_hook (abfd, info, s return TRUE; } + /* Create a .got section, as well as its additional info field. This is almost entirely copied from elflink.c:_bfd_elf_create_got_section(). */ @@ -2627,6 +2685,7 @@ _frv_create_got_section (bfd *abfd, stru struct bfd_link_hash_entry *bh; const struct elf_backend_data *bed = get_elf_backend_data (abfd); int ptralign; + int offset; /* This function may be called more than once. */ s = bfd_get_section_by_name (abfd, ".got"); @@ -2686,6 +2745,8 @@ _frv_create_got_section (bfd *abfd, stru /* This is the machine-specific part. Create and initialize section data for the got. */ + if (IS_FDPIC (abfd)) + { frv_got_section (info) = s; frv_relocs_info (info) = htab_try_create (1, frv_pic_relocs_info_hash, frv_pic_relocs_info_eq, @@ -2709,13 +2770,21 @@ _frv_create_got_section (bfd *abfd, stru return FALSE; frv_gotfixup_section (info) = s; + offset = -2048; + flags = BSF_GLOBAL; + } + else + { + offset = 2048; + flags = BSF_GLOBAL | BSF_WEAK; + } - /* Define _gp in .rofixup, for FDPIC. If it turns out that - we're linking with a different linker script, the linker script - will override it. */ + /* Define _gp in .rofixup, for FDPIC, or .got otherwise. If it + turns out that we're linking with a different linker script, the + linker script will override it. */ bh = NULL; if (!(_bfd_generic_link_add_one_symbol - (info, abfd, "_gp", BSF_GLOBAL, s, -2048, (const char *) NULL, FALSE, + (info, abfd, "_gp", flags, s, offset, (const char *) NULL, FALSE, bed->collect, &bh))) return FALSE; h = (struct elf_link_hash_entry *) bh; @@ -2723,7 +2792,7 @@ _frv_create_got_section (bfd *abfd, stru h->type = STT_OBJECT; /* Machine-specific: we want the symbol for executables as well. */ - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (IS_FDPIC (abfd) && ! _bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; return TRUE; @@ -3454,8 +3534,7 @@ elf32_frvfdpic_size_dynamic_sections (bf return FALSE; } - if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC) - frvfdpic_gotfixup_section (info)->_raw_size = (gpinfo.g.fixups + 1) * 4; + frvfdpic_gotfixup_section (info)->_raw_size = (gpinfo.g.fixups + 1) * 4; if (frvfdpic_gotfixup_section (info)->_raw_size == 0) frvfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE; else @@ -3559,8 +3639,7 @@ static bfd_boolean elf32_frv_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { - if (!info->relocatable - && elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC) + if (!info->relocatable) { struct elf_link_hash_entry *h; asection *sec; @@ -3605,8 +3684,6 @@ static bfd_boolean elf32_frv_modify_segment_map (bfd *output_bfd, struct bfd_link_info *info) { - if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC) - { struct elf_segment_map *m; for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next) @@ -3642,7 +3719,6 @@ elf32_frv_modify_segment_map (bfd *outpu m->count++; } } - } return TRUE; } @@ -3650,6 +3726,14 @@ elf32_frv_modify_segment_map (bfd *outpu /* Fill in code and data in dynamic sections. */ static bfd_boolean +elf32_frv_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED) +{ + /* Nothing to be done for non-FDPIC. */ + return TRUE; +} + +static bfd_boolean elf32_frv_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { @@ -3666,8 +3750,6 @@ elf32_frv_finish_dynamic_sections (bfd * if (frv_gotfixup_section (info)) { - if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC) - { struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot; bfd_vma got_value = hgot->root.u.def.value + hgot->root.u.def.section->output_section->vma @@ -3675,29 +3757,14 @@ elf32_frv_finish_dynamic_sections (bfd * _frv_add_rofixup (output_bfd, frv_gotfixup_section (info), got_value, 0); - } if (frv_gotfixup_section (info)->_raw_size != (frv_gotfixup_section (info)->reloc_count * 4)) { - if (frv_gotfixup_section (info)->_raw_size - < frv_gotfixup_section (info)->reloc_count * 4) - { - info->callbacks->warning - (info, "LINKER BUG: .rofixup section size mismatch", - ".rofixup", NULL, NULL, 0); - abort (); - return FALSE; - } - else if (!elf_hash_table (info)->dynamic_sections_created) - { - info->callbacks->warning - (info, "no dynamic sections, missing -melf32frvfd?", - ".rofixup", NULL, NULL, 0); + (*_bfd_error_handler) + ("LINKER BUG: .rofixup section size mismatch"); return FALSE; } - BFD_ASSERT (0); - } } } if (elf_hash_table (info)->dynamic_sections_created) @@ -3807,14 +3877,11 @@ frv_elf_use_relative_eh_frame asection *eh_frame_section ATTRIBUTE_UNUSED) { /* We can't use PC-relative encodings in FDPIC binaries, in general. */ - if (elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC) - return FALSE; - - return TRUE; + return FALSE; } @@ -3829,11 +3896,6 @@ frv_elf_encode_eh_address (bfd *abfd, { struct elf_link_hash_entry *h; - /* Non-FDPIC binaries can use PC-relative encodings. */ - if (! (elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC)) - return _bfd_elf_encode_eh_address (abfd, info, osec, offset, - loc_sec, loc_offset, encoded); - h = elf_hash_table (info)->hgot; BFD_ASSERT (h && h->root.type == bfd_link_hash_defined); @@ -3996,8 +4058,6 @@ elf32_frv_check_relocs (abfd, info, sec, switch (ELF32_R_TYPE (rel->r_info)) { - case R_FRV_LABEL24: - case R_FRV_32: case R_FRV_GOT12: case R_FRV_GOTHI: case R_FRV_GOTLO: @@ -4012,12 +4072,26 @@ elf32_frv_check_relocs (abfd, info, sec, case R_FRV_FUNCDESC_GOTOFFLO: case R_FRV_FUNCDESC: case R_FRV_FUNCDESC_VALUE: + if (! IS_FDPIC (abfd)) + goto bad_reloc; + /* Fall through. */ + case R_FRV_GPREL12: + case R_FRV_GPRELU12: + case R_FRV_GPRELHI: + case R_FRV_GPRELLO: + case R_FRV_LABEL24: + case R_FRV_32: if (! dynobj) { elf_hash_table (info)->dynobj = dynobj = abfd; if (! _frv_create_got_section (abfd, info)) return FALSE; } + if (! IS_FDPIC (abfd)) + { + picrel = NULL; + break; + } if (h != NULL) { if (h->dynindx == -1) @@ -4051,6 +4125,7 @@ elf32_frv_check_relocs (abfd, info, sec, switch (ELF32_R_TYPE (rel->r_info)) { case R_FRV_LABEL24: + if (IS_FDPIC (abfd)) picrel->call = 1; break; @@ -4059,7 +4134,11 @@ elf32_frv_check_relocs (abfd, info, sec, if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) picrel->relocs32--; /* Fall through. */ + case R_FRV_32: + if (! IS_FDPIC (abfd)) + break; + picrel->sym = 1; if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) picrel->relocs32++; @@ -4116,6 +4195,23 @@ elf32_frv_check_relocs (abfd, info, sec, if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; + + case R_FRV_LABEL16: + case R_FRV_LO16: + case R_FRV_HI16: + case R_FRV_GPREL12: + case R_FRV_GPRELU12: + case R_FRV_GPREL32: + case R_FRV_GPRELHI: + case R_FRV_GPRELLO: + break; + + default: + bad_reloc: + (*_bfd_error_handler) + (_("%s: unsupported relocation type %i"), + bfd_archive_filename (abfd), ELF32_R_TYPE (rel->r_info)); + return FALSE; } } @@ -4152,7 +4248,8 @@ elf32_frv_object_p (abfd) bfd *abfd; { bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd)); - return TRUE; + return (((elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC) != 0) + == (IS_FDPIC (abfd))); } /* Function to set the ELF flag bits. */ @@ -4460,6 +4557,20 @@ frv_elf_merge_private_bfd_data (ibfd, ob if (old_partial != (old_flags & EF_FRV_CPU_MASK)) bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd)); + if (((new_flags & EF_FRV_FDPIC) == 0) + != (! IS_FDPIC (ibfd))) + { + error = TRUE; + if (IS_FDPIC (obfd)) + (*_bfd_error_handler) + (_("%s: cannot link non-fdpic object file into fdpic executable"), + bfd_get_filename (ibfd)); + else + (*_bfd_error_handler) + (_("%s: cannot link fdpic object file into non-fdpic executable"), + bfd_get_filename (ibfd)); + } + if (error) bfd_set_error (bfd_error_bad_value); @@ -4557,7 +4668,6 @@ frv_elf_print_private_bfd_data (abfd, pt #define TARGET_BIG_SYM bfd_elf32_frv_vec #define TARGET_BIG_NAME "elf32-frv" -#define elf_info_to_howto_rel frv_info_to_howto_rel #define elf_info_to_howto frv_info_to_howto_rela #define elf_backend_relocate_section elf32_frv_relocate_section #define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook @@ -4575,39 +4685,73 @@ frv_elf_print_private_bfd_data (abfd, pt #define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data #define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data -#define bfd_elf32_bfd_link_hash_table_create frv_elf_link_hash_table_create +#define elf_backend_want_got_sym 1 +#define elf_backend_got_header_size 0 +#define elf_backend_want_got_plt 0 +#define elf_backend_plt_readonly 1 +#define elf_backend_want_plt_sym 0 +#define elf_backend_plt_header_size 0 + +#define elf_backend_finish_dynamic_sections \ + elf32_frv_finish_dynamic_sections + +#include "elf32-target.h" + +#undef ELF_MAXPAGESIZE +#define ELF_MAXPAGESIZE 0x4000 + +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf32_frv_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf32-frv" +#undef elf32_bed +#define elf32_bed elf32_frv_bed + +#undef elf_info_to_howto_rel +#define elf_info_to_howto_rel frv_info_to_howto_rel + +#undef bfd_elf32_bfd_link_hash_table_create +#define bfd_elf32_bfd_link_hash_table_create \ + frv_elf_link_hash_table_create +#undef elf_backend_always_size_sections #define elf_backend_always_size_sections \ elf32_frv_always_size_sections +#undef elf_backend_modify_segment_map #define elf_backend_modify_segment_map \ elf32_frv_modify_segment_map +#undef elf_backend_create_dynamic_sections #define elf_backend_create_dynamic_sections \ elf32_frv_create_dynamic_sections +#undef elf_backend_adjust_dynamic_symbol #define elf_backend_adjust_dynamic_symbol \ elf32_frv_adjust_dynamic_symbol +#undef elf_backend_size_dynamic_sections #define elf_backend_size_dynamic_sections \ elf32_frv_size_dynamic_sections +#undef elf_backend_finish_dynamic_symbol #define elf_backend_finish_dynamic_symbol \ elf32_frv_finish_dynamic_symbol +#undef elf_backend_finish_dynamic_sections #define elf_backend_finish_dynamic_sections \ elf32_frv_finish_dynamic_sections -#define elf_backend_want_got_sym 1 -#define elf_backend_got_header_size 0 -#define elf_backend_want_got_plt 0 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 -#define elf_backend_plt_header_size 0 - +#undef elf_backend_can_make_relative_eh_frame #define elf_backend_can_make_relative_eh_frame \ frv_elf_use_relative_eh_frame +#undef elf_backend_can_make_lsda_relative_eh_frame #define elf_backend_can_make_lsda_relative_eh_frame \ frv_elf_use_relative_eh_frame -#define elf_backend_encode_eh_address frv_elf_encode_eh_address +#undef elf_backend_encode_eh_address +#define elf_backend_encode_eh_address \ + frv_elf_encode_eh_address +#undef elf_backend_may_use_rel_p #define elf_backend_may_use_rel_p 1 +#undef elf_backend_may_use_rela_p #define elf_backend_may_use_rela_p 1 /* We use REL for dynamic relocations only. */ +#undef elf_backend_default_use_rela_p #define elf_backend_default_use_rela_p 1 #include "elf32-target.h"
Attachment:
frvfdpic-bfdvec.patch.bz2
Description: BZip2 compressed data
Attachment:
frvfdpic-bfdvec.patch.bz2
Description: BZip2 compressed data
-- Alexandre Oliva http://www.ic.unicamp.br/~oliva/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |