+2011-07-11 Catherine Moore <clm@codesourcery.com>
+
+ * 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 <hongjiu.lu@intel.com>
PR ld/12978
#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
#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
#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
/* 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;
/* 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, \
\
#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))
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. */
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, \
/* 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 *);
.#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))
.
#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
#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
#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
/* 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
_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,
_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,
_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,
_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,
#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
0, NULL, 0,
/* target_index, used_by_bfd, constructor_chain, owner, */
0, NULL, NULL, NULL,
+ /* flag_info, */
+ NULL,
/* symbol, */
NULL,
/* symbol_ptr_ptr, */
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 *);
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);
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;
#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)
#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
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,
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
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
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
#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
#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)
#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)
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 *);
#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
#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
#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
#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
#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
#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
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
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
. {* 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;
. {* 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, \
. \
_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
#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
.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. *}
. 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, \
. {* 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 *);
.
#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
#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
#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
#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
+2011-07-11 Catherine Moore <clm@codesourcery.com>
+
+ * bfdlink.h (flag_type): New enumeration.
+ (flag_info_list): New structure.
+ (flag_info): New structure.
+
2011-07-09 H.J. Lu <hongjiu.lu@intel.com>
PR ld/12942
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
#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 \
+2011-07-11 Catherine Moore <clm@codesourcery.com>
+
+ * 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 <hongjiu.lu@intel.com>
PR ld/12942
-*- 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
const char *name;
struct name_list *exclude_name_list;
sort_type sorted;
+ struct flag_info *section_flag_list;
};
struct wildcard_list {
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.
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
%type <fill> fill_opt fill_exp
%type <name_list> exclude_name_list
%type <wildcard_list> file_NAME_list
+%type <flag_info_list> sect_flag_list
+%type <flag_info> sect_flags
%type <name> memspec_opt casesymlist
%type <name> memspec_at_opt
%type <cname> wildcard_name
%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
%token <name> 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 <versyms> vers_defns
$$.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;
}
;
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:
{
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;
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;
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;
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;
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;
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
<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
+<EXPRESSION,BOTH,SCRIPT>"INPUT_SECTION_FLAGS" { RTOKEN(INPUT_SECTION_FLAGS); }
<EXPRESSION,BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);}
<BOTH,SCRIPT>"PHDRS" { RTOKEN (PHDRS); }
<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
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. */
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);
}
+2011-07-11 Catherine Moore <clm@cm00re.com>
+
+ * 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 <amodra@gmail.com>
* ld-powerpc/tocopt2.s, * ld-powerpc/tocopt2.out,
--- /dev/null
+ .text
+ .space 16
--- /dev/null
+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.*)
+ }
+}
--- /dev/null
+ .text
+ .space 16
--- /dev/null
+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
+}
--- /dev/null
+# 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