From ae17ab41b73246a07697e79a36ec28deb51576f2 Mon Sep 17 00:00:00 2001 From: Catherine Moore Date: Mon, 11 Jul 2011 15:03:09 +0000 Subject: [PATCH] include/ChangeLog 2011-07-11 Catherine Moore * bfdlink.h (flag_type): New enumeration. (flag_info_list): New structure. (flag_info): New structure. bfd/ChangeLog 2011-07-11 Catherine Moore * aout-adobe.c (aout_32_bfd_lookup_section_flags): New definition. * aout-target.h (MY_bfd_lookup_section_flags): New definition. * aout-tic30.c (MY_bfd_lookup_section_flags): New definition. * bfd-in2.h: Regenerated. * bfd.c (bfd_lookup_section_flags): New definition. * binary.c (binary_bfd_lookup_section_flags): New definition. * bout.c (b_out_bfd_lookup_section_flags): New definition. * coff-alpha.c (_bfd_ecoff_bfd_lookup_section_flags): New definition. * coff-mips.c (_bfd_ecoff_bfd_lookup_section_flags): New definition. * coff-rs6000.c (rs6000coff_vec): Include bfd_generic_lookup_section_flags. (pmac_xcoff_vec): Likewise. * coffcode.h (coff_bfd_lookup_section_flags): New definition. * coff64-rs6000.c (rs6000coff64_vec): Include bfd_generic_lookup_section_flags. (aix5coff64_vec): Likewise. * ecoff.c (bfd_debug_section): Initialize flag_info field. * elf-bfd.h (elf_backend_lookup_section_flags_hook): Declare. (bfd_elf_lookup_section_flags): Declare. * elflink.c (bfd_elf_lookup_section_flags): New function. * elfxx-target.h (bfd_elfNN_bfd_lookup_section_flags): Define. (elf_backend_lookup_section_flags_hook): Define. (elf_backend_data): Add elf_backend_lookup_section_flags_hook. * i386msdos.c (msdos_bfd_lookup_section_flags): New define. * i386os9k.c (os9k_bfd_lookup_section_flags): New define. * ieee.c (ieee_bfd_lookup_section_flags): New define. * ihex.c (ihex_bfd_lookup_section_flags): New define. * libbfd-in.h (_bfd_nolink_bfd_lookup_section_flags): Declare. (bfd_generic_lookup_section_flags): Declare. * libbfd.h: Regenerated. * mach-o-target.c (bfd_mach_o_bfd_lookup_section_flags): New. * mmo.c (mmo_bfd_lookup_section_flags): New definition. * nlm-target.h (nlm_bfd_lookup_section_flags): New definition. * oasys.c (oasys_bfd_lookup_section_flags): New definition. * pef.c (bfd_pef_bfd_lookup_section_flags): New definition. * plugin.c (bfd_plugin_bfd_lookup_section_flags): New definition. * ppcboot.c (ppcboot_bfd_lookup_section_flags): New definition. * reloc.c (bfd_generic_lookup_section_flags): New function. * som.c (som_bfd_lookup_section_flags): New definition. * srec.c (srec_bfd_lookup_section_flags): New definition. * targets.c (flag_info): Declare. (NAME##_bfd_lookup_section_flags): Add to LINK jump table. (_bfd_lookup_section_flags): New. * tekhex.c (tekhex_bfd_lookup_section_flags): New definition. * versados.c (versados_bfd_lookup_section_flags): New definition. * vms-alpha.c (alpha_vms_bfd_lookup_section_flag): New definition. * xsym.c (bfd_sym_bfd_lookup_section_flags): New definition. ld/ChangeLog 2011-07-11 Catherine Moore * ld.h (section_flag_list): Add field to struct wildcard_spec. * ld.texinfo (INPUT_SECTION_FLAGS): Document. * ldgram.y (flag_info_list, flag_info): Add to union. (INPUT_SECTION_FLAGS): New token. (wildcard_spec): Initialize section_flag_list to NULL for each alternative. (sect_flag_list, sect_flags): New rules. (input_section_spec_no_keep): Add alternatives to recognize sect_flags. * ldlang.c (walk_wild_consider_section): Initialize section_flag_info field of the section struct. (lang_add_section): Check input section flags. (lang_add_wild): Initialize section_flag_list field of the statement struct. * ldlang.h (lang_input_statement_struct): Add section_flag_list field. (lang_wild_statement_struct): Likewise. * ldlex.l (INPUT_SECTION_FLAGS): New token. * mri.c (mri_draw_tree): Initialize section_flag_list to NULL. * NEWS: Announce INPUT_SECTION_FLAGS enhancement. ld/testsuite/ChangeLog 2011-07-11 Catherine Moore * ld-scripts/section-flags-1.s: New. * ld-scripts/section-flags-1.t: New. * ld-scripts/section-flags-2.s: New. * ld-scripts/section-flags-2.t: New. * ld-scripts/section-flags.exp: New. --- bfd/ChangeLog | 50 +++++++++++++ bfd/aout-adobe.c | 1 + bfd/aout-target.h | 3 + bfd/aout-tic30.c | 3 + bfd/bfd-in2.h | 17 +++++ bfd/bfd.c | 3 + bfd/binary.c | 1 + bfd/bout.c | 1 + bfd/coff-alpha.c | 3 + bfd/coff-mips.c | 3 + bfd/coff-rs6000.c | 2 + bfd/coff64-rs6000.c | 2 + bfd/coffcode.h | 4 + bfd/ecoff.c | 2 + bfd/elf-bfd.h | 8 ++ bfd/elflink.c | 77 +++++++++++++++++++ bfd/elfxx-target.h | 8 ++ bfd/i386msdos.c | 1 + bfd/i386os9k.c | 1 + bfd/ieee.c | 1 + bfd/ihex.c | 1 + bfd/libbfd-in.h | 3 + bfd/libbfd.h | 6 ++ bfd/mach-o-target.c | 1 + bfd/mmo.c | 1 + bfd/nlm-target.h | 1 + bfd/oasys.c | 1 + bfd/pef.c | 1 + bfd/plugin.c | 1 + bfd/ppcboot.c | 1 + bfd/reloc.c | 24 ++++++ bfd/section.c | 6 ++ bfd/som.c | 1 + bfd/srec.c | 1 + bfd/targets.c | 8 ++ bfd/tekhex.c | 1 + bfd/versados.c | 1 + bfd/vms-alpha.c | 1 + bfd/xsym.c | 1 + include/ChangeLog | 6 ++ include/bfdlink.h | 20 +++++ include/elf/ppc.h | 4 + ld/ChangeLog | 22 ++++++ ld/NEWS | 3 + ld/ld.h | 1 + ld/ld.texinfo | 20 +++++ ld/ldgram.y | 91 ++++++++++++++++++++++- ld/ldlang.c | 30 ++++++++ ld/ldlang.h | 3 + ld/ldlex.l | 1 + ld/mri.c | 2 + ld/testsuite/ChangeLog | 8 ++ ld/testsuite/ld-scripts/section-flags-1.s | 2 + ld/testsuite/ld-scripts/section-flags-1.t | 21 ++++++ ld/testsuite/ld-scripts/section-flags-2.s | 2 + ld/testsuite/ld-scripts/section-flags-2.t | 12 +++ ld/testsuite/ld-scripts/section-flags.exp | 52 +++++++++++++ 57 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-scripts/section-flags-1.s create mode 100644 ld/testsuite/ld-scripts/section-flags-1.t create mode 100644 ld/testsuite/ld-scripts/section-flags-2.s create mode 100644 ld/testsuite/ld-scripts/section-flags-2.t create mode 100644 ld/testsuite/ld-scripts/section-flags.exp diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e469ef2875..e20d3db2d0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,53 @@ +2011-07-11 Catherine Moore + + * aout-adobe.c (aout_32_bfd_lookup_section_flags): New definition. + * aout-target.h (MY_bfd_lookup_section_flags): New definition. + * aout-tic30.c (MY_bfd_lookup_section_flags): New definition. + * bfd-in2.h: Regenerated. + * bfd.c (bfd_lookup_section_flags): New definition. + * binary.c (binary_bfd_lookup_section_flags): New definition. + * bout.c (b_out_bfd_lookup_section_flags): New definition. + * coff-alpha.c (_bfd_ecoff_bfd_lookup_section_flags): New definition. + * coff-mips.c (_bfd_ecoff_bfd_lookup_section_flags): New definition. + * coff-rs6000.c (rs6000coff_vec): Include + bfd_generic_lookup_section_flags. + (pmac_xcoff_vec): Likewise. + * coffcode.h (coff_bfd_lookup_section_flags): New definition. + * coff64-rs6000.c (rs6000coff64_vec): Include + bfd_generic_lookup_section_flags. + (aix5coff64_vec): Likewise. + * ecoff.c (bfd_debug_section): Initialize flag_info field. + * elf-bfd.h (elf_backend_lookup_section_flags_hook): Declare. + (bfd_elf_lookup_section_flags): Declare. + * elflink.c (bfd_elf_lookup_section_flags): New function. + * elfxx-target.h (bfd_elfNN_bfd_lookup_section_flags): Define. + (elf_backend_lookup_section_flags_hook): Define. + (elf_backend_data): Add elf_backend_lookup_section_flags_hook. + * i386msdos.c (msdos_bfd_lookup_section_flags): New define. + * i386os9k.c (os9k_bfd_lookup_section_flags): New define. + * ieee.c (ieee_bfd_lookup_section_flags): New define. + * ihex.c (ihex_bfd_lookup_section_flags): New define. + * libbfd-in.h (_bfd_nolink_bfd_lookup_section_flags): Declare. + (bfd_generic_lookup_section_flags): Declare. + * libbfd.h: Regenerated. + * mach-o-target.c (bfd_mach_o_bfd_lookup_section_flags): New. + * mmo.c (mmo_bfd_lookup_section_flags): New definition. + * nlm-target.h (nlm_bfd_lookup_section_flags): New definition. + * oasys.c (oasys_bfd_lookup_section_flags): New definition. + * pef.c (bfd_pef_bfd_lookup_section_flags): New definition. + * plugin.c (bfd_plugin_bfd_lookup_section_flags): New definition. + * ppcboot.c (ppcboot_bfd_lookup_section_flags): New definition. + * reloc.c (bfd_generic_lookup_section_flags): New function. + * som.c (som_bfd_lookup_section_flags): New definition. + * srec.c (srec_bfd_lookup_section_flags): New definition. + * targets.c (flag_info): Declare. + (NAME##_bfd_lookup_section_flags): Add to LINK jump table. + (_bfd_lookup_section_flags): New. + * tekhex.c (tekhex_bfd_lookup_section_flags): New definition. + * versados.c (versados_bfd_lookup_section_flags): New definition. + * vms-alpha.c (alpha_vms_bfd_lookup_section_flag): New definition. + * xsym.c (bfd_sym_bfd_lookup_section_flags): New definition. + 2011-07-11 H.J. Lu PR ld/12978 diff --git a/bfd/aout-adobe.c b/bfd/aout-adobe.c index bd38ea8390..c8331d8c5d 100644 --- a/bfd/aout-adobe.c +++ b/bfd/aout-adobe.c @@ -459,6 +459,7 @@ aout_adobe_sizeof_headers (bfd *ignore_abfd ATTRIBUTE_UNUSED, #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window #define aout_32_bfd_relax_section bfd_generic_relax_section #define aout_32_bfd_gc_sections bfd_generic_gc_sections +#define aout_32_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define aout_32_bfd_merge_sections bfd_generic_merge_sections #define aout_32_bfd_is_group_section bfd_generic_is_group_section #define aout_32_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/aout-target.h b/bfd/aout-target.h index 5c0d2ae355..f6e8bd2e2d 100644 --- a/bfd/aout-target.h +++ b/bfd/aout-target.h @@ -486,6 +486,9 @@ MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info) #ifndef MY_bfd_gc_sections #define MY_bfd_gc_sections bfd_generic_gc_sections #endif +#ifndef MY_bfd_lookup_section_flags +#define MY_bfd_lookup_section_flags bfd_generic_lookup_section_flags +#endif #ifndef MY_bfd_merge_sections #define MY_bfd_merge_sections bfd_generic_merge_sections #endif diff --git a/bfd/aout-tic30.c b/bfd/aout-tic30.c index 30900ba388..0b01177296 100644 --- a/bfd/aout-tic30.c +++ b/bfd/aout-tic30.c @@ -944,6 +944,9 @@ tic30_aout_set_arch_mach (bfd *abfd, #ifndef MY_bfd_gc_sections #define MY_bfd_gc_sections bfd_generic_gc_sections #endif +#ifndef MY_bfd_lookup_section_flags +#define MY_bfd_lookup_section_flags bfd_generic_lookup_section_flags +#endif #ifndef MY_bfd_merge_sections #define MY_bfd_merge_sections bfd_generic_merge_sections #endif diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index da4688c48f..867d052c78 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1514,6 +1514,9 @@ typedef struct bfd_section /* The BFD which owns the section. */ bfd *owner; + /* INPUT_SECTION_FLAGS if specified in the linker script. */ + struct flag_info *section_flag_info; + /* A symbol which points at this section only. */ struct bfd_symbol *symbol; struct bfd_symbol **symbol_ptr_ptr; @@ -1692,6 +1695,9 @@ extern asection bfd_ind_section; /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ \ + /* flag_info, */ \ + NULL, \ + \ /* symbol, symbol_ptr_ptr, */ \ (struct bfd_symbol *) SYM, &SEC.symbol, \ \ @@ -5571,6 +5577,9 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); #define bfd_gc_sections(abfd, link_info) \ BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) +#define bfd_lookup_section_flags(link_info, flag_info) \ + BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info)) + #define bfd_merge_sections(abfd, link_info) \ BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) @@ -5728,6 +5737,9 @@ enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; typedef struct bfd_link_info _bfd_link_info; struct already_linked; +/* Forward declaration. */ +typedef struct flag_info flag_info; + typedef struct bfd_target { /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ @@ -5997,6 +6009,7 @@ typedef struct bfd_target NAME##_bfd_final_link, \ NAME##_bfd_link_split_section, \ NAME##_bfd_gc_sections, \ + NAME##_bfd_lookup_section_flags, \ NAME##_bfd_merge_sections, \ NAME##_bfd_is_group_section, \ NAME##_bfd_discard_group, \ @@ -6041,6 +6054,10 @@ typedef struct bfd_target /* Remove sections that are not referenced from the output. */ bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); + /* Sets the bitmask of allowed and disallowed section flags. */ + void (*_bfd_lookup_section_flags) (struct bfd_link_info *, + struct flag_info *); + /* Attempt to merge SEC_MERGE sections. */ bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); diff --git a/bfd/bfd.c b/bfd/bfd.c index b3e2c47289..7c14c7a00a 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1374,6 +1374,9 @@ DESCRIPTION .#define bfd_gc_sections(abfd, link_info) \ . BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) . +.#define bfd_lookup_section_flags(link_info, flag_info) \ +. BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info)) +. .#define bfd_merge_sections(abfd, link_info) \ . BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) . diff --git a/bfd/binary.c b/bfd/binary.c index ad93354016..700c862f93 100644 --- a/bfd/binary.c +++ b/bfd/binary.c @@ -299,6 +299,7 @@ binary_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, #define binary_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define binary_bfd_relax_section bfd_generic_relax_section #define binary_bfd_gc_sections bfd_generic_gc_sections +#define binary_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define binary_bfd_merge_sections bfd_generic_merge_sections #define binary_bfd_is_group_section bfd_generic_is_group_section #define binary_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/bout.c b/bfd/bout.c index b76191b048..cfd4abb019 100644 --- a/bfd/bout.c +++ b/bfd/bout.c @@ -1387,6 +1387,7 @@ b_out_bfd_get_relocated_section_contents (bfd *output_bfd, #define b_out_bfd_final_link _bfd_generic_final_link #define b_out_bfd_link_split_section _bfd_generic_link_split_section #define b_out_bfd_gc_sections bfd_generic_gc_sections +#define b_out_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define b_out_bfd_merge_sections bfd_generic_merge_sections #define b_out_bfd_is_group_section bfd_generic_is_group_section #define b_out_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index c4dfd8f7fb..2233a335cb 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -2393,6 +2393,9 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data = #define _bfd_ecoff_get_section_contents_in_window \ _bfd_generic_get_section_contents_in_window +/* Input section flag lookup is generic. */ +#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags + /* Relaxing sections is generic. */ #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index cbc172f7c0..9f8b90dcef 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -1410,6 +1410,9 @@ static const struct ecoff_backend_data mips_ecoff_backend_data = /* GC of sections is not done. */ #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections +/* Input section flags is not implemented. */ +#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags + /* Merging of sections is not done. */ #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index c1b5c89cc8..5d9b5aeb53 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -4102,6 +4102,7 @@ const bfd_target rs6000coff_vec = _bfd_xcoff_bfd_final_link, _bfd_generic_link_split_section, bfd_generic_gc_sections, + bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, @@ -4356,6 +4357,7 @@ const bfd_target pmac_xcoff_vec = _bfd_xcoff_bfd_final_link, _bfd_generic_link_split_section, bfd_generic_gc_sections, + bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index ef4dfbae58..031385deee 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -2738,6 +2738,7 @@ const bfd_target rs6000coff64_vec = _bfd_xcoff_bfd_final_link, _bfd_generic_link_split_section, bfd_generic_gc_sections, + bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, @@ -2994,6 +2995,7 @@ const bfd_target aix5coff64_vec = _bfd_xcoff_bfd_final_link, _bfd_generic_link_split_section, bfd_generic_gc_sections, + bfd_generic_lookup_section_flags, bfd_generic_merge_sections, bfd_generic_is_group_section, bfd_generic_discard_group, diff --git a/bfd/coffcode.h b/bfd/coffcode.h index e71aadd304..2313dc50a2 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5652,6 +5652,10 @@ static bfd_coff_backend_data ticoff1_swap_table = #define coff_bfd_gc_sections bfd_generic_gc_sections #endif +#ifndef coff_bfd_lookup_section_flags +#define coff_bfd_lookup_section_flags bfd_generic_lookup_section_flags +#endif + #ifndef coff_bfd_merge_sections #define coff_bfd_merge_sections bfd_generic_merge_sections #endif diff --git a/bfd/ecoff.c b/bfd/ecoff.c index efcb9bf75c..b76266d26f 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -73,6 +73,8 @@ static asection bfd_debug_section = 0, NULL, 0, /* target_index, used_by_bfd, constructor_chain, owner, */ 0, NULL, NULL, NULL, + /* flag_info, */ + NULL, /* symbol, */ NULL, /* symbol_ptr_ptr, */ diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b2075a5677..08da2aeed8 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1112,6 +1112,11 @@ struct elf_backend_data char *(*elf_backend_write_core_note) (bfd *abfd, char *buf, int *bufsiz, int note_type, ...); + /* This function, if defined, is called to convert target-specific + section flag names into hex values. */ + flagword (*elf_backend_lookup_section_flags_hook) + (char *); + /* This function returns class of a reloc type. */ enum elf_reloc_type_class (*elf_backend_reloc_type_class) (const Elf_Internal_Rela *); @@ -2193,6 +2198,9 @@ extern bfd_boolean _bfd_elf_is_function_type (unsigned int); extern int bfd_elf_get_default_section_type (flagword); +extern void bfd_elf_lookup_section_flags + (struct bfd_link_info *, struct flag_info *); + extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section); diff --git a/bfd/elflink.c b/bfd/elflink.c index 238a4aab1a..e2cb28cc8e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12167,6 +12167,83 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, return TRUE; } +/* Map an ELF section header flag to its corresponding string. */ +typedef struct +{ + char *flag_name; + flagword flag_value; +} elf_flags_to_name_table; + +static elf_flags_to_name_table elf_flags_to_names [] = +{ + { "SHF_WRITE", SHF_WRITE }, + { "SHF_ALLOC", SHF_ALLOC }, + { "SHF_EXECINSTR", SHF_EXECINSTR }, + { "SHF_MERGE", SHF_MERGE }, + { "SHF_STRINGS", SHF_STRINGS }, + { "SHF_INFO_LINK", SHF_INFO_LINK}, + { "SHF_LINK_ORDER", SHF_LINK_ORDER}, + { "SHF_OS_NONCONFORMING", SHF_OS_NONCONFORMING}, + { "SHF_GROUP", SHF_GROUP }, + { "SHF_TLS", SHF_TLS }, + { "SHF_MASKOS", SHF_MASKOS }, + { "SHF_EXCLUDE", SHF_EXCLUDE }, +}; + +void +bfd_elf_lookup_section_flags (struct bfd_link_info *info, + struct flag_info *finfo) +{ + bfd *output_bfd = info->output_bfd; + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + struct flag_info_list *tf = finfo->flag_list; + int with_hex = 0; + int without_hex = 0; + + for (tf = finfo->flag_list; tf != NULL; tf = tf->next) + { + int i; + if (bed->elf_backend_lookup_section_flags_hook) + { + flagword hexval = + (*bed->elf_backend_lookup_section_flags_hook) ((char *) tf->name); + + if (hexval != 0) + { + if (tf->with == with_flags) + with_hex |= hexval; + else if (tf->with == without_flags) + without_hex |= hexval; + tf->valid = TRUE; + continue; + } + } + for (i = 0; i < 12; i++) + { + if (!strcmp (tf->name, elf_flags_to_names[i].flag_name)) + { + if (tf->with == with_flags) + with_hex |= elf_flags_to_names[i].flag_value; + else if (tf->with == without_flags) + without_hex |= elf_flags_to_names[i].flag_value; + tf->valid = TRUE; + continue; + } + } + if (tf->valid == FALSE) + { + info->callbacks->einfo + (_("Unrecognized INPUT_SECTION_FLAG %s\n"), tf->name); + return; + } + } + finfo->flags_initialized = TRUE; + finfo->only_with_flags |= with_hex; + finfo->not_with_flags |= without_hex; + + return; +} + struct alloc_got_off_arg { bfd_vma gotoff; struct bfd_link_info *info; diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index b033c17655..b51ac9fde6 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -174,6 +174,10 @@ #define bfd_elfNN_bfd_define_common_symbol bfd_generic_define_common_symbol #endif +#ifndef bfd_elfNN_bfd_lookup_section_flags +#define bfd_elfNN_bfd_lookup_section_flags bfd_elf_lookup_section_flags +#endif + #ifndef bfd_elfNN_bfd_make_debug_symbol #define bfd_elfNN_bfd_make_debug_symbol \ ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr) @@ -529,6 +533,9 @@ #ifndef elf_backend_write_core_note #define elf_backend_write_core_note NULL #endif +#ifndef elf_backend_lookup_section_flags_hook +#define elf_backend_lookup_section_flags_hook NULL +#endif #ifndef elf_backend_reloc_type_class #define elf_backend_reloc_type_class _bfd_elf_reloc_type_class #endif @@ -717,6 +724,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_grok_prstatus, elf_backend_grok_psinfo, elf_backend_write_core_note, + elf_backend_lookup_section_flags_hook, elf_backend_reloc_type_class, elf_backend_discard_info, elf_backend_ignore_discarded_relocs, diff --git a/bfd/i386msdos.c b/bfd/i386msdos.c index 9ff5fd379c..b67b13e229 100644 --- a/bfd/i386msdos.c +++ b/bfd/i386msdos.c @@ -143,6 +143,7 @@ msdos_set_section_contents (bfd *abfd, bfd_generic_get_relocated_section_contents #define msdos_bfd_relax_section bfd_generic_relax_section #define msdos_bfd_gc_sections bfd_generic_gc_sections +#define msdos_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define msdos_bfd_merge_sections bfd_generic_merge_sections #define msdos_bfd_is_group_section bfd_generic_is_group_section #define msdos_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/i386os9k.c b/bfd/i386os9k.c index 5cbf927103..3beb8a3c1e 100644 --- a/bfd/i386os9k.c +++ b/bfd/i386os9k.c @@ -167,6 +167,7 @@ os9k_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, bfd_generic_get_relocated_section_contents #define os9k_bfd_relax_section bfd_generic_relax_section #define os9k_bfd_gc_sections bfd_generic_gc_sections +#define os9k_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define os9k_bfd_merge_sections bfd_generic_merge_sections #define os9k_bfd_is_group_section bfd_generic_is_group_section #define os9k_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/ieee.c b/bfd/ieee.c index 9494b35b66..de1e926721 100644 --- a/bfd/ieee.c +++ b/bfd/ieee.c @@ -3772,6 +3772,7 @@ ieee_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, bfd_generic_get_relocated_section_contents #define ieee_bfd_relax_section bfd_generic_relax_section #define ieee_bfd_gc_sections bfd_generic_gc_sections +#define ieee_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define ieee_bfd_merge_sections bfd_generic_merge_sections #define ieee_bfd_is_group_section bfd_generic_is_group_section #define ieee_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/ihex.c b/bfd/ihex.c index a92baafc76..09f756a1c2 100644 --- a/bfd/ihex.c +++ b/bfd/ihex.c @@ -930,6 +930,7 @@ ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, #define ihex_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define ihex_bfd_relax_section bfd_generic_relax_section #define ihex_bfd_gc_sections bfd_generic_gc_sections +#define ihex_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define ihex_bfd_merge_sections bfd_generic_merge_sections #define ihex_bfd_is_group_section bfd_generic_is_group_section #define ihex_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index a80687e2f6..0c98b47cbc 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -453,6 +453,9 @@ extern bfd_boolean _bfd_generic_set_section_contents #define _bfd_nolink_bfd_gc_sections \ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ bfd_false) +#define _bfd_nolink_bfd_lookup_section_flags \ + ((void (*) (struct bfd_link_info *, struct flag_info *)) \ + bfd_0) #define _bfd_nolink_bfd_merge_sections \ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ bfd_false) diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c72ff16442..25eba0f128 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -458,6 +458,9 @@ extern bfd_boolean _bfd_generic_set_section_contents #define _bfd_nolink_bfd_gc_sections \ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ bfd_false) +#define _bfd_nolink_bfd_lookup_section_flags \ + ((void (*) (struct bfd_link_info *, struct flag_info *)) \ + bfd_0) #define _bfd_nolink_bfd_merge_sections \ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ bfd_false) @@ -2469,6 +2472,9 @@ bfd_boolean bfd_generic_relax_section bfd_boolean bfd_generic_gc_sections (bfd *, struct bfd_link_info *); +void bfd_generic_lookup_section_flags + (struct bfd_link_info *, struct flag_info *); + bfd_boolean bfd_generic_merge_sections (bfd *, struct bfd_link_info *); diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index 32dc335111..eb7cb53cd4 100644 --- a/bfd/mach-o-target.c +++ b/bfd/mach-o-target.c @@ -51,6 +51,7 @@ #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections +#define bfd_mach_o_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/mmo.c b/bfd/mmo.c index c22790dec2..dc45f31b70 100644 --- a/bfd/mmo.c +++ b/bfd/mmo.c @@ -3190,6 +3190,7 @@ mmo_write_object_contents (bfd *abfd) #define mmo_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents #define mmo_bfd_gc_sections bfd_generic_gc_sections +#define mmo_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define mmo_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols diff --git a/bfd/nlm-target.h b/bfd/nlm-target.h index f38b16ec8e..9a3b7bef09 100644 --- a/bfd/nlm-target.h +++ b/bfd/nlm-target.h @@ -45,6 +45,7 @@ #define nlm_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define nlm_bfd_relax_section bfd_generic_relax_section #define nlm_bfd_gc_sections bfd_generic_gc_sections +#define nlm_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define nlm_bfd_merge_sections bfd_generic_merge_sections #define nlm_bfd_is_group_section bfd_generic_is_group_section #define nlm_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/oasys.c b/bfd/oasys.c index e58f0d0d6a..11d24401fe 100644 --- a/bfd/oasys.c +++ b/bfd/oasys.c @@ -1196,6 +1196,7 @@ oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define oasys_bfd_relax_section bfd_generic_relax_section #define oasys_bfd_gc_sections bfd_generic_gc_sections +#define oasys_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define oasys_bfd_merge_sections bfd_generic_merge_sections #define oasys_bfd_is_group_section bfd_generic_is_group_section #define oasys_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/pef.c b/bfd/pef.c index 6db730132e..d4ad33ad37 100644 --- a/bfd/pef.c +++ b/bfd/pef.c @@ -48,6 +48,7 @@ #define bfd_pef_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define bfd_pef_bfd_relax_section bfd_generic_relax_section #define bfd_pef_bfd_gc_sections bfd_generic_gc_sections +#define bfd_pef_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define bfd_pef_bfd_merge_sections bfd_generic_merge_sections #define bfd_pef_bfd_is_group_section bfd_generic_is_group_section #define bfd_pef_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/plugin.c b/bfd/plugin.c index 5d34f859b7..064e273128 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -63,6 +63,7 @@ #define bfd_plugin_bfd_final_link _bfd_generic_final_link #define bfd_plugin_bfd_link_split_section _bfd_generic_link_split_section #define bfd_plugin_bfd_gc_sections bfd_generic_gc_sections +#define bfd_plugin_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define bfd_plugin_bfd_merge_sections bfd_generic_merge_sections #define bfd_plugin_bfd_is_group_section bfd_generic_is_group_section #define bfd_plugin_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/ppcboot.c b/bfd/ppcboot.c index a97043695e..c2b4c3be79 100644 --- a/bfd/ppcboot.c +++ b/bfd/ppcboot.c @@ -470,6 +470,7 @@ ppcboot_bfd_print_private_bfd_data (abfd, farg) bfd_generic_get_relocated_section_contents #define ppcboot_bfd_relax_section bfd_generic_relax_section #define ppcboot_bfd_gc_sections bfd_generic_gc_sections +#define ppcboot_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define ppcboot_bfd_merge_sections bfd_generic_merge_sections #define ppcboot_bfd_is_group_section bfd_generic_is_group_section #define ppcboot_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/reloc.c b/bfd/reloc.c index 664a62874b..f83dac2782 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -6042,6 +6042,30 @@ bfd_generic_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, return TRUE; } +/* +INTERNAL_FUNCTION + bfd_generic_lookup_section_flags + +SYNOPSIS + void bfd_generic_lookup_section_flags + (struct bfd_link_info *, struct flag_info *); + +DESCRIPTION + Provides default handling for section flags lookup + -- i.e., does nothing. +*/ + +void +bfd_generic_lookup_section_flags (struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct flag_info *finfo) +{ + if (finfo != NULL) + { + (*_bfd_error_handler) (_("INPUT_SECTION_FLAGS are not supported.\n")); + return; + } +} + /* INTERNAL_FUNCTION bfd_generic_merge_sections diff --git a/bfd/section.c b/bfd/section.c index 3cd7e658e7..7c1f750483 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -516,6 +516,9 @@ CODE_FRAGMENT . {* The BFD which owns the section. *} . bfd *owner; . +. {* INPUT_SECTION_FLAGS if specified in the linker script. *} +. struct flag_info *section_flag_info; +. . {* A symbol which points at this section only. *} . struct bfd_symbol *symbol; . struct bfd_symbol **symbol_ptr_ptr; @@ -694,6 +697,9 @@ CODE_FRAGMENT . {* target_index, used_by_bfd, constructor_chain, owner, *} \ . 0, NULL, NULL, NULL, \ . \ +. {* flag_info, *} \ +. NULL, \ +. \ . {* symbol, symbol_ptr_ptr, *} \ . (struct bfd_symbol *) SYM, &SEC.symbol, \ . \ diff --git a/bfd/som.c b/bfd/som.c index a642231a8f..0726f842e3 100644 --- a/bfd/som.c +++ b/bfd/som.c @@ -6741,6 +6741,7 @@ som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) _bfd_generic_copy_link_hash_symbol_type #define som_bfd_final_link _bfd_generic_final_link #define som_bfd_gc_sections bfd_generic_gc_sections +#define som_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define som_bfd_merge_sections bfd_generic_merge_sections #define som_bfd_is_group_section bfd_generic_is_group_section #define som_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/srec.c b/bfd/srec.c index 6d4de1af72..6226773387 100644 --- a/bfd/srec.c +++ b/bfd/srec.c @@ -1252,6 +1252,7 @@ srec_print_symbol (bfd *abfd, #define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define srec_bfd_relax_section bfd_generic_relax_section #define srec_bfd_gc_sections bfd_generic_gc_sections +#define srec_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define srec_bfd_merge_sections bfd_generic_merge_sections #define srec_bfd_is_group_section bfd_generic_is_group_section #define srec_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/targets.c b/bfd/targets.c index ac978a14fb..241ff9c7a2 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -178,6 +178,9 @@ DESCRIPTION .typedef struct bfd_link_info _bfd_link_info; .struct already_linked; . +.{* Forward declaration. *} +.typedef struct flag_info flag_info; +. .typedef struct bfd_target .{ . {* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. *} @@ -449,6 +452,7 @@ BFD_JUMP_TABLE macros. . NAME##_bfd_final_link, \ . NAME##_bfd_link_split_section, \ . NAME##_bfd_gc_sections, \ +. NAME##_bfd_lookup_section_flags, \ . NAME##_bfd_merge_sections, \ . NAME##_bfd_is_group_section, \ . NAME##_bfd_discard_group, \ @@ -493,6 +497,10 @@ BFD_JUMP_TABLE macros. . {* Remove sections that are not referenced from the output. *} . bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); . +. {* Sets the bitmask of allowed and disallowed section flags. *} +. void (*_bfd_lookup_section_flags) (struct bfd_link_info *, +. struct flag_info *); +. . {* Attempt to merge SEC_MERGE sections. *} . bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); . diff --git a/bfd/tekhex.c b/bfd/tekhex.c index 376569af84..0ed7b5032b 100644 --- a/bfd/tekhex.c +++ b/bfd/tekhex.c @@ -943,6 +943,7 @@ tekhex_print_symbol (bfd *abfd, #define tekhex_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define tekhex_bfd_relax_section bfd_generic_relax_section #define tekhex_bfd_gc_sections bfd_generic_gc_sections +#define tekhex_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define tekhex_bfd_merge_sections bfd_generic_merge_sections #define tekhex_bfd_is_group_section bfd_generic_is_group_section #define tekhex_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/versados.c b/bfd/versados.c index 84a816b69d..7f7766a525 100644 --- a/bfd/versados.c +++ b/bfd/versados.c @@ -806,6 +806,7 @@ versados_canonicalize_reloc (bfd *abfd, #define versados_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define versados_bfd_relax_section bfd_generic_relax_section #define versados_bfd_gc_sections bfd_generic_gc_sections +#define versados_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define versados_bfd_merge_sections bfd_generic_merge_sections #define versados_bfd_is_group_section bfd_generic_is_group_section #define versados_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index 87e35edf7a..31dc1fb615 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -9336,6 +9336,7 @@ bfd_vms_get_data (bfd *abfd) #define alpha_vms_bfd_relax_section bfd_generic_relax_section #define alpha_vms_bfd_gc_sections bfd_generic_gc_sections +#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define alpha_vms_bfd_merge_sections bfd_generic_merge_sections #define alpha_vms_bfd_is_group_section bfd_generic_is_group_section #define alpha_vms_bfd_discard_group bfd_generic_discard_group diff --git a/bfd/xsym.c b/bfd/xsym.c index a0900f1fda..01434e1b72 100644 --- a/bfd/xsym.c +++ b/bfd/xsym.c @@ -42,6 +42,7 @@ #define bfd_sym_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define bfd_sym_bfd_relax_section bfd_generic_relax_section #define bfd_sym_bfd_gc_sections bfd_generic_gc_sections +#define bfd_sym_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define bfd_sym_bfd_merge_sections bfd_generic_merge_sections #define bfd_sym_bfd_is_group_section bfd_generic_is_group_section #define bfd_sym_bfd_discard_group bfd_generic_discard_group diff --git a/include/ChangeLog b/include/ChangeLog index bf2c020fda..2a62d3f579 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2011-07-11 Catherine Moore + + * bfdlink.h (flag_type): New enumeration. + (flag_info_list): New structure. + (flag_info): New structure. + 2011-07-09 H.J. Lu PR ld/12942 diff --git a/include/bfdlink.h b/include/bfdlink.h index 193b855113..0e583be187 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -224,6 +224,26 @@ enum report_method RM_GENERATE_ERROR }; +typedef enum {with_flags, without_flags} flag_type; + +/* A section flag list. */ +struct flag_info_list +{ + flag_type with; + const char *name; + bfd_boolean valid; + struct flag_info_list *next; +}; + +/* Section flag info. */ +struct flag_info +{ + flagword only_with_flags; + flagword not_with_flags; + struct flag_info_list *flag_list; + bfd_boolean flags_initialized; +}; + struct bfd_elf_dynamic_list; /* This structure holds all the information needed to communicate diff --git a/include/elf/ppc.h b/include/elf/ppc.h index 688cb9b9d1..8e27855be0 100644 --- a/include/elf/ppc.h +++ b/include/elf/ppc.h @@ -166,6 +166,10 @@ END_RELOC_NUMBERS (R_PPC_max) #define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag. */ #define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib flag. */ +/* This bit is reserved by BFD for processor specific stuff. Name + it properly so that we can easily stay consistent elsewhere. */ +#define SEC_PPC_VLE SEC_TIC54X_BLOCK + /* Processor specific section headers, sh_type field. */ #define SHT_ORDERED SHT_HIPROC /* Link editor is to sort the \ diff --git a/ld/ChangeLog b/ld/ChangeLog index 7ce5d7abd6..fbbb5bdc23 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,25 @@ +2011-07-11 Catherine Moore + + * ld.h (section_flag_list): Add field to struct wildcard_spec. + * ld.texinfo (INPUT_SECTION_FLAGS): Document. + * ldgram.y (flag_info_list, flag_info): Add to union. + (INPUT_SECTION_FLAGS): New token. + (wildcard_spec): Initialize section_flag_list to NULL for + each alternative. + (sect_flag_list, sect_flags): New rules. + (input_section_spec_no_keep): Add alternatives to recognize + sect_flags. + * ldlang.c (walk_wild_consider_section): Initialize + section_flag_info field of the section struct. + (lang_add_section): Check input section flags. + (lang_add_wild): Initialize section_flag_list field of + the statement struct. + * ldlang.h (lang_input_statement_struct): Add section_flag_list field. + (lang_wild_statement_struct): Likewise. + * ldlex.l (INPUT_SECTION_FLAGS): New token. + * mri.c (mri_draw_tree): Initialize section_flag_list to NULL. + * NEWS: Announce INPUT_SECTION_FLAGS enhancement. + 2011-07-09 H.J. Lu PR ld/12942 diff --git a/ld/NEWS b/ld/NEWS index 40a6b9fd82..e3fa540385 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* INPUT_SECTION_FLAGS has been added to the linker script language +to allow selection of input sections by section header section flags. + * Add support for the Tilera TILEPRO and TILE-Gx architectures. * Added SORT_BY_INIT_PRIORITY to the linker script language to permit diff --git a/ld/ld.h b/ld/ld.h index 9391923b6c..996cdd22b1 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -96,6 +96,7 @@ struct wildcard_spec { const char *name; struct name_list *exclude_name_list; sort_type sorted; + struct flag_info *section_flag_list; }; struct wildcard_list { diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 5a8e190c24..4fb649aafd 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -3859,6 +3859,26 @@ needs to be at a particular location in memory. For example: data.o(.data) @end smallexample +To refine the sections that are included based on the section flags +of an input section, INPUT_SECTION_FLAGS may be used. + +Here is a simple example for using Section header flags for ELF sections: + +@smallexample +@group +SECTIONS @{ + .text : @{ INPUT_SECTION_FLAGS (SHF_MERGE & SHF_STRINGS) *(.text) @} + .text2 : @{ INPUT_SECTION_FLAGS (!SHF_WRITE) *(.text) @} +@} +@end group +@end smallexample + +In this example, the output section @samp{.text} will be comprised of any +input section matching the name *(.text) whose section header flags +@code{SHF_MERGE} and @code{SHF_STRINGS} are set. The output section +@samp{.text2} will be comprised of any input section matching the name *(.text) +whose section header flag @code{SHF_WRITE} is clear. + You can also specify files within archives by writing a pattern matching the archive, a colon, then the pattern matching the file, with no whitespace around the colon. diff --git a/ld/ldgram.y b/ld/ldgram.y index 3795ffeb8f..36ccb5b28b 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -72,6 +72,8 @@ static int error_index; struct wildcard_spec wildcard; struct wildcard_list *wildcard_list; struct name_list *name_list; + struct flag_info_list *flag_info_list; + struct flag_info *flag_info; int token; union etree_union *etree; struct phdr_info @@ -93,6 +95,8 @@ static int error_index; %type fill_opt fill_exp %type exclude_name_list %type file_NAME_list +%type sect_flag_list +%type sect_flags %type memspec_opt casesymlist %type memspec_at_opt %type wildcard_name @@ -150,7 +154,7 @@ static int error_index; %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START %token VERS_TAG VERS_IDENTIFIER %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT -%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL +%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS %token EXCLUDE_FILE %token CONSTANT %type vers_defns @@ -437,60 +441,121 @@ wildcard_spec: $$.name = $1; $$.sorted = none; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name { $$.name = $5; $$.sorted = none; $$.exclude_name_list = $3; + $$.section_flag_list = NULL; } | SORT_BY_NAME '(' wildcard_name ')' { $$.name = $3; $$.sorted = by_name; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_ALIGNMENT '(' wildcard_name ')' { $$.name = $3; $$.sorted = by_alignment; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' { $$.name = $5; $$.sorted = by_name_alignment; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')' { $$.name = $5; $$.sorted = by_name; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')' { $$.name = $5; $$.sorted = by_alignment_name; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' { $$.name = $5; $$.sorted = by_alignment; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; } | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' { $$.name = $7; $$.sorted = by_name; $$.exclude_name_list = $5; + $$.section_flag_list = NULL; } | SORT_BY_INIT_PRIORITY '(' wildcard_name ')' { $$.name = $3; $$.sorted = by_init_priority; $$.exclude_name_list = NULL; + $$.section_flag_list = NULL; + } + ; + +sect_flag_list: NAME + { + struct flag_info_list *n; + n = ((struct flag_info_list *) xmalloc (sizeof *n)); + if ($1[0] == '!') + { + n->with = without_flags; + n->name = &$1[1]; + } + else + { + n->with = with_flags; + n->name = $1; + } + n->valid = FALSE; + n->next = NULL; + $$ = n; + } + | sect_flag_list '&' NAME + { + struct flag_info_list *n; + n = ((struct flag_info_list *) xmalloc (sizeof *n)); + if ($3[0] == '!') + { + n->with = without_flags; + n->name = &$3[1]; + } + else + { + n->with = with_flags; + n->name = $3; + } + n->valid = FALSE; + n->next = $1; + $$ = n; + } + ; + +sect_flags: + INPUT_SECTION_FLAGS '(' sect_flag_list ')' + { + struct flag_info *n; + n = ((struct flag_info *) xmalloc (sizeof *n)); + n->flag_list = $3; + n->flags_initialized = FALSE; + n->not_with_flags = 0; + n->only_with_flags = 0; + $$ = n; } ; @@ -541,16 +606,40 @@ input_section_spec_no_keep: tmp.name = $1; tmp.exclude_name_list = NULL; tmp.sorted = none; + tmp.section_flag_list = NULL; + lang_add_wild (&tmp, NULL, ldgram_had_keep); + } + | sect_flags NAME + { + struct wildcard_spec tmp; + tmp.name = $2; + tmp.exclude_name_list = NULL; + tmp.sorted = none; + tmp.section_flag_list = $1; lang_add_wild (&tmp, NULL, ldgram_had_keep); } | '[' file_NAME_list ']' { lang_add_wild (NULL, $2, ldgram_had_keep); } + | sect_flags '[' file_NAME_list ']' + { + struct wildcard_spec tmp; + tmp.name = NULL; + tmp.exclude_name_list = NULL; + tmp.sorted = none; + tmp.section_flag_list = $1; + lang_add_wild (NULL, $3, ldgram_had_keep); + } | wildcard_spec '(' file_NAME_list ')' { lang_add_wild (&$1, $3, ldgram_had_keep); } + | sect_flags wildcard_spec '(' file_NAME_list ')' + { + $2.section_flag_list = $1; + lang_add_wild (&$2, $4, ldgram_had_keep); + } ; input_section_spec: diff --git a/ld/ldlang.c b/ld/ldlang.c index 860ce27b30..3e63eedd40 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -237,6 +237,9 @@ walk_wild_consider_section (lang_wild_statement_type *ptr, { struct name_list *list_tmp; + /* Propagate the section_flag_info from the wild statement to the section. */ + s->section_flag_info = ptr->section_flag_list; + /* Don't process sections from files which were excluded. */ for (list_tmp = sec->spec.exclude_name_list; list_tmp; @@ -2261,8 +2264,11 @@ lang_add_section (lang_statement_list_type *ptr, lang_output_section_statement_type *output) { flagword flags = section->flags; + struct flag_info *sflag_info = section->section_flag_info; + bfd_boolean discard; lang_input_section_type *new_section; + bfd *abfd = link_info.output_bfd; /* Discard sections marked with SEC_EXCLUDE. */ discard = (flags & SEC_EXCLUDE) != 0; @@ -2288,6 +2294,28 @@ lang_add_section (lang_statement_list_type *ptr, return; } + if (sflag_info) + { + if (sflag_info->flags_initialized == FALSE) + bfd_lookup_section_flags (&link_info, sflag_info); + + if (sflag_info->only_with_flags != 0 + && sflag_info->not_with_flags != 0 + && ((sflag_info->not_with_flags & flags) != 0 + || (sflag_info->only_with_flags & flags) + != sflag_info->only_with_flags)) + return; + + if (sflag_info->only_with_flags != 0 + && (sflag_info->only_with_flags & flags) + != sflag_info->only_with_flags) + return; + + if (sflag_info->not_with_flags != 0 + && (sflag_info->not_with_flags & flags) != 0) + return; + } + if (section->output_section != NULL) return; @@ -6719,10 +6747,12 @@ lang_add_wild (struct wildcard_spec *filespec, new_stmt = new_stat (lang_wild_statement, stat_ptr); new_stmt->filename = NULL; new_stmt->filenames_sorted = FALSE; + new_stmt->section_flag_list = NULL; if (filespec != NULL) { new_stmt->filename = filespec->name; new_stmt->filenames_sorted = filespec->sorted == by_name; + new_stmt->section_flag_list = filespec->section_flag_list; } new_stmt->section_list = section_list; new_stmt->keep_sections = keep_sections; diff --git a/ld/ldlang.h b/ld/ldlang.h index d172c34f9c..a6d22ce304 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -240,6 +240,8 @@ typedef struct lang_input_statement_struct bfd *the_bfd; + struct flag_info *section_flag_list; + /* Point to the next file - whatever it is, wanders up and down archives */ union lang_statement_union *next; @@ -337,6 +339,7 @@ struct lang_wild_statement_struct walk_wild_section_handler_t walk_wild_section_handler; struct wildcard_list *handler_data[4]; lang_section_bst_type *tree; + struct flag_info *section_flag_list; }; typedef struct lang_address_statement_struct diff --git a/ld/ldlex.l b/ld/ldlex.l index 013c07e473..4e859b0332 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -313,6 +313,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "org" { RTOKEN(ORIGIN);} "l" { RTOKEN( LENGTH);} "len" { RTOKEN( LENGTH);} +"INPUT_SECTION_FLAGS" { RTOKEN(INPUT_SECTION_FLAGS); } "INCLUDE" { RTOKEN(INCLUDE);} "PHDRS" { RTOKEN (PHDRS); } "AT" { RTOKEN(AT);} diff --git a/ld/mri.c b/ld/mri.c index ce1406af33..91b40dc779 100644 --- a/ld/mri.c +++ b/ld/mri.c @@ -215,6 +215,7 @@ mri_draw_tree (void) tmp->spec.name = p->name; tmp->spec.exclude_name_list = NULL; tmp->spec.sorted = none; + tmp->spec.section_flag_list = NULL; lang_add_wild (NULL, tmp, FALSE); /* If there is an alias for this section, add it too. */ @@ -226,6 +227,7 @@ mri_draw_tree (void) tmp->spec.name = aptr->name; tmp->spec.exclude_name_list = NULL; tmp->spec.sorted = none; + tmp->spec.section_flag_list = NULL; lang_add_wild (NULL, tmp, FALSE); } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4fe8d0c482..64c2d10124 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-07-11 Catherine Moore + + * ld-scripts/section-flags-1.s: New. + * ld-scripts/section-flags-1.t: New. + * ld-scripts/section-flags-2.s: New. + * ld-scripts/section-flags-2.t: New. + * ld-scripts/section-flags.exp: New. + 2011-07-11 Alan Modra * ld-powerpc/tocopt2.s, * ld-powerpc/tocopt2.out, diff --git a/ld/testsuite/ld-scripts/section-flags-1.s b/ld/testsuite/ld-scripts/section-flags-1.s new file mode 100644 index 0000000000..566e3c606e --- /dev/null +++ b/ld/testsuite/ld-scripts/section-flags-1.s @@ -0,0 +1,2 @@ + .text + .space 16 diff --git a/ld/testsuite/ld-scripts/section-flags-1.t b/ld/testsuite/ld-scripts/section-flags-1.t new file mode 100644 index 0000000000..33804891ad --- /dev/null +++ b/ld/testsuite/ld-scripts/section-flags-1.t @@ -0,0 +1,21 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x100000, LENGTH = 144M +} + +SECTIONS +{ + .text : + { + INPUT_SECTION_FLAGS (!SHF_TLS) *(.text .text.* .text_* .gnu.linkonce.t.*) + } >ram + + .text_vle : + { + INPUT_SECTION_FLAGS (SHF_MERGE & SHF_STRINGS & SHF_LINK_ORDER) *(.text .text.* .text_* .gnu.linkonce.t.*) + } >ram + .text_other : + { + INPUT_SECTION_FLAGS (SHF_MERGE & !SHF_STRINGS) *(.text .text.* .text_* .gnu.linkonce.t.*) + } +} diff --git a/ld/testsuite/ld-scripts/section-flags-2.s b/ld/testsuite/ld-scripts/section-flags-2.s new file mode 100644 index 0000000000..566e3c606e --- /dev/null +++ b/ld/testsuite/ld-scripts/section-flags-2.s @@ -0,0 +1,2 @@ + .text + .space 16 diff --git a/ld/testsuite/ld-scripts/section-flags-2.t b/ld/testsuite/ld-scripts/section-flags-2.t new file mode 100644 index 0000000000..ca5ae63668 --- /dev/null +++ b/ld/testsuite/ld-scripts/section-flags-2.t @@ -0,0 +1,12 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x100000, LENGTH = 144M +} + +SECTIONS +{ + .text : + { + INPUT_SECTION_FLAGS (!SHF_TLS) *(EXCLUDE_FILE (section-flags-1.o) .text .text.* .text_* .gnu.linkonce.t.*) + } >ram +} diff --git a/ld/testsuite/ld-scripts/section-flags.exp b/ld/testsuite/ld-scripts/section-flags.exp new file mode 100644 index 0000000000..700c3d3343 --- /dev/null +++ b/ld/testsuite/ld-scripts/section-flags.exp @@ -0,0 +1,52 @@ +# Test SECTION_FLAGS in a linker script. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +set testname "SECTION_FLAGS-1" + + +# This test only works for ELF targets +if {! [is_elf_format]} { + unsupported $testname + return +} + +if ![ld_assemble $as $srcdir/$subdir/section-flags-1.s tmpdir/section-flags-1.o] { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/section-flags-1 "-T $srcdir/$subdir/section-flags-1.t tmpdir/section-flags-1.o"] { + fail $testname + return +} + +pass $testname + +set testname "SECTION_FLAGS-2" +if ![ld_assemble $as $srcdir/$subdir/section-flags-2.s tmpdir/section-flags-2.o] { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/section-flags-2 "-T $srcdir/$subdir/section-flags-2.t tmpdir/section-flags-1.o tmpdir/section-flags-2.o"] { + fail $testname + return +} + +pass $testname -- 2.34.1