bfd/
2006-09-07 H.J. Lu <hongjiu.lu@intel.com> * elf-bfd.h (elf_link_hash_entry): Add a dynamic field. (bfd_elf_link_mark_dynamic_symbol): New. (SYMBOLIC_BIND): New. * elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic with SYMBOLIC_BIND (info, h). (elf_i386_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise. (elf64_x86_64_relocate_section): Likewise. * elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise. * elflink.c (bfd_elf_link_mark_dynamic_symbol): New. (bfd_elf_record_link_assignment): Call bfd_elf_link_mark_dynamic_symbol on new entry. (_bfd_elf_merge_symbol): Likewise. (_bfd_elf_export_symbol): Return if the symbol isn't exported. (_bfd_elf_fix_symbol_flags): Replace info->symbolic with SYMBOLIC_BIND (info, h). (_bfd_elf_dynamic_symbol_p): Likewise. (_bfd_elf_symbol_refs_local_p): Likewise. (bfd_elf_size_dynamic_sections): Updated. include/ 2006-09-07 H.J. Lu <hongjiu.lu@intel.com> * bfdlink.h (bfd_elf_dynamic_list): New. (bfd_link_info): Add a dynamic field. ld/ 2006-09-07 H.J. Lu <hongjiu.lu@intel.com> * Makefile.am (CXX): Set to g++. (CXX_FOR_TARGET): Likewise. * Makefile.in: Regenerated. * NEWS: Mention --dynamic-list. * ld.texinfo: Document --dynamic-list. * ldgram.y: Support dynamic list. * ldlang.c (lang_process): Call lang_finalize_version_expr_head on link_info.dynamic if needed. (lang_append_dynamic_list): New. (lang_append_dynamic_list_cpp_typeinfo): New. * ldlang.h (lang_append_dynamic_list): Likewise. * ldlang.h (lang_append_dynamic_list_cpp_typeinfo): Likewise. * ldlex.h (input_enum): Add input_dynamic_list. * ldlex.l: Handle it. * ldmain.c (main): Initialize link_info.dynamic. * lexsup.c (option_values): Add OPTION_DYNAMIC_LIST and OPTION_DYNAMIC_LIST_CPP_TYPEINFO. (ld_options): Add entries for OPTION_DYNAMIC_LIST and OPTION_DYNAMIC_LIST_CPP_TYPEINFO. (parse_args): Handle OPTION_DYNAMIC_LIST and OPTION_DYNAMIC_LIST_CPP_TYPEINFO. ld/testsuite/ 2006-09-07 H.J. Lu <hongjiu.lu@intel.com> * ld-elf/dl1.c: New file. * ld-elf/dl1.list: Likewise. * ld-elf/dl1.out: Likewise. * ld-elf/dl1main.c: Likewise. * ld-elf/dl2.c: Likewise. * ld-elf/dl2.list: Likewise. * ld-elf/dl2a.out: Likewise. * ld-elf/dl2b.out: Likewise. * ld-elf/dl2main.c: Likewise. * ld-elf/dl2xxx.c: Likewise. * ld-elf/dl2xxx.list: Likewise. * ld-elf/dl3.cc: Likewise. * ld-elf/dl3.list: Likewise. * ld-elf/dl3a.out: Likewise. * ld-elf/dl3b.out: Likewise. * ld-elf/dl3header.h: Likewise. * ld-elf/dl3main.cc: Likewise. * ld-elf/shared.exp: Updated. * lib/ld-lib.exp (run_ld_link_exec_tests): Take an optional argument for source language. Use CC/CXX for link, depending on source language. (run_cc_link_tests): Likewise.
This commit is contained in:
parent
7c94efc522
commit
55255daec3
|
@ -1,3 +1,27 @@
|
|||
2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
|
||||
(bfd_elf_link_mark_dynamic_symbol): New.
|
||||
(SYMBOLIC_BIND): New.
|
||||
|
||||
* elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic
|
||||
with SYMBOLIC_BIND (info, h).
|
||||
(elf_i386_relocate_section): Likewise.
|
||||
* elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
|
||||
(elf64_x86_64_relocate_section): Likewise.
|
||||
* elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
|
||||
|
||||
* elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
|
||||
(bfd_elf_record_link_assignment): Call
|
||||
bfd_elf_link_mark_dynamic_symbol on new entry.
|
||||
(_bfd_elf_merge_symbol): Likewise.
|
||||
(_bfd_elf_export_symbol): Return if the symbol isn't exported.
|
||||
(_bfd_elf_fix_symbol_flags): Replace info->symbolic with
|
||||
SYMBOLIC_BIND (info, h).
|
||||
(_bfd_elf_dynamic_symbol_p): Likewise.
|
||||
(_bfd_elf_symbol_refs_local_p): Likewise.
|
||||
(bfd_elf_size_dynamic_sections): Updated.
|
||||
|
||||
2006-09-05 Bibo Mao <bibo.mao@intel.com>
|
||||
|
||||
PR binutils/3171
|
||||
|
|
|
@ -155,6 +155,8 @@ struct elf_link_hash_entry
|
|||
unsigned int hidden : 1;
|
||||
/* Symbol was forced to local scope due to a version script file. */
|
||||
unsigned int forced_local : 1;
|
||||
/* Symbol was forced to be dynamic due to a version script file. */
|
||||
unsigned int dynamic : 1;
|
||||
/* Symbol was marked during garbage collection. */
|
||||
unsigned int mark : 1;
|
||||
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
|
||||
|
@ -1828,6 +1830,9 @@ extern bfd_boolean bfd_elf_link_record_dynamic_symbol
|
|||
extern int bfd_elf_link_record_local_dynamic_symbol
|
||||
(struct bfd_link_info *, bfd *, long);
|
||||
|
||||
extern void bfd_elf_link_mark_dynamic_symbol
|
||||
(struct bfd_link_info *, struct elf_link_hash_entry *);
|
||||
|
||||
extern bfd_boolean _bfd_elf_close_and_cleanup
|
||||
(bfd *);
|
||||
|
||||
|
@ -1980,4 +1985,9 @@ extern bfd_boolean _sh_elf_set_mach_from_flags
|
|||
} \
|
||||
while (0)
|
||||
|
||||
/* Will a symbol be bound to the the definition within the shared
|
||||
library, if any. */
|
||||
#define SYMBOLIC_BIND(INFO, H) \
|
||||
((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))
|
||||
|
||||
#endif /* _LIBELF_H_ */
|
||||
|
|
|
@ -1150,7 +1150,7 @@ elf_i386_check_relocs (bfd *abfd,
|
|||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
&& (r_type != R_386_PC32
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
&& (! SYMBOLIC_BIND (info, h)
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
|| !h->def_regular))))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
|
@ -2629,7 +2629,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||
&& h->dynindx != -1
|
||||
&& (r_type == R_386_PC32
|
||||
|| !info->shared
|
||||
|| !info->symbolic
|
||||
|| !SYMBOLIC_BIND (info, h)
|
||||
|| !h->def_regular))
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
||||
else
|
||||
|
|
|
@ -997,7 +997,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
|
|||
&& (r_type != R_X86_64_PC32)
|
||||
&& (r_type != R_X86_64_PC64))
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
&& (! SYMBOLIC_BIND (info, h)
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
|| !h->def_regular))))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
|
@ -2445,7 +2445,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||
|| r_type == R_X86_64_PC32
|
||||
|| r_type == R_X86_64_PC64
|
||||
|| !info->shared
|
||||
|| !info->symbolic
|
||||
|| !SYMBOLIC_BIND (info, h)
|
||||
|| !h->def_regular))
|
||||
{
|
||||
outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
|
||||
|
|
|
@ -444,6 +444,21 @@ bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Mark a symbol dynamic. */
|
||||
|
||||
void
|
||||
bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
|
||||
struct elf_link_hash_entry *h)
|
||||
{
|
||||
struct bfd_elf_dynamic_list *d = info->dynamic;
|
||||
|
||||
if (d == NULL || info->relocatable)
|
||||
return;
|
||||
|
||||
if ((*d->match) (&d->head, NULL, h->root.root.string))
|
||||
h->dynamic = 1;
|
||||
}
|
||||
|
||||
/* Record an assignment to a symbol made by a linker script. We need
|
||||
this in case some dynamic object refers to this symbol. */
|
||||
|
||||
|
@ -477,7 +492,10 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
|
|||
}
|
||||
|
||||
if (h->root.type == bfd_link_hash_new)
|
||||
h->non_elf = 0;
|
||||
{
|
||||
bfd_elf_link_mark_dynamic_symbol (info, h);
|
||||
h->non_elf = 0;
|
||||
}
|
||||
|
||||
/* If this symbol is being provided by the linker script, and it is
|
||||
currently defined by a dynamic object, but not by a regular
|
||||
|
@ -840,6 +858,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
|
|||
|
||||
if (h->root.type == bfd_link_hash_new)
|
||||
{
|
||||
bfd_elf_link_mark_dynamic_symbol (info, h);
|
||||
h->non_elf = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1626,6 +1645,10 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
|
|||
{
|
||||
struct elf_info_failed *eif = data;
|
||||
|
||||
/* Ignore this if we won't export it. */
|
||||
if (!eif->info->export_dynamic && !h->dynamic)
|
||||
return TRUE;
|
||||
|
||||
/* Ignore indirect symbols. These are added by the versioning code. */
|
||||
if (h->root.type == bfd_link_hash_indirect)
|
||||
return TRUE;
|
||||
|
@ -2379,7 +2402,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
|
|||
if (h->needs_plt
|
||||
&& eif->info->shared
|
||||
&& is_elf_hash_table (eif->info->hash)
|
||||
&& (eif->info->symbolic
|
||||
&& (SYMBOLIC_BIND (eif->info, h)
|
||||
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|
||||
&& h->def_regular)
|
||||
{
|
||||
|
@ -2608,7 +2631,7 @@ _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
|
|||
|
||||
/* Identify the cases where name binding rules say that a
|
||||
visible symbol resolves locally. */
|
||||
binding_stays_local_p = info->executable || info->symbolic;
|
||||
binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
|
||||
|
||||
switch (ELF_ST_VISIBILITY (h->other))
|
||||
{
|
||||
|
@ -2671,7 +2694,7 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
|
|||
/* At this point, we know the symbol is defined and dynamic. In an
|
||||
executable it must resolve locally, likewise when building symbolic
|
||||
shared libraries. */
|
||||
if (info->executable || info->symbolic)
|
||||
if (info->executable || SYMBOLIC_BIND (info, h))
|
||||
return TRUE;
|
||||
|
||||
/* Now deal with defined dynamic symbols in shared libraries. Ones
|
||||
|
@ -5322,7 +5345,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
|||
|
||||
/* If we are supposed to export all symbols into the dynamic symbol
|
||||
table (this is not the normal case), then do so. */
|
||||
if (info->export_dynamic)
|
||||
if (info->export_dynamic
|
||||
|| (info->executable && info->dynamic))
|
||||
{
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
_bfd_elf_export_symbol,
|
||||
|
|
|
@ -2741,7 +2741,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
|
|||
have yet been processed. Do something with what we know, as
|
||||
this may help reduce memory usage and processing time later. */
|
||||
maybe_dynamic = (h && ((!info->executable
|
||||
&& (!info->symbolic
|
||||
&& (!SYMBOLIC_BIND (info, h)
|
||||
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|
||||
|| !h->def_regular
|
||||
|| h->root.type == bfd_link_hash_defweak));
|
||||
|
@ -2913,7 +2913,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
|
|||
have yet been processed. Do something with what we know, as
|
||||
this may help reduce memory usage and processing time later. */
|
||||
maybe_dynamic = (h && ((!info->executable
|
||||
&& (!info->symbolic
|
||||
&& (!SYMBOLIC_BIND (info, h)
|
||||
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|
||||
|| !h->def_regular
|
||||
|| h->root.type == bfd_link_hash_defweak));
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* bfdlink.h (bfd_elf_dynamic_list): New.
|
||||
(bfd_link_info): Add a dynamic field.
|
||||
|
||||
2006-08-04 Marcelo Tosatti <marcelo@kvack.org>
|
||||
|
||||
* bfdlink.h (struct bfd_link_info): New field: print_gc_sections.
|
||||
|
|
|
@ -221,6 +221,8 @@ enum report_method
|
|||
RM_GENERATE_ERROR
|
||||
};
|
||||
|
||||
struct bfd_elf_dynamic_list;
|
||||
|
||||
/* This structure holds all the information needed to communicate
|
||||
between BFD and the linker when doing a link. */
|
||||
|
||||
|
@ -431,6 +433,9 @@ struct bfd_link_info
|
|||
|
||||
/* Start and end of RELRO region. */
|
||||
bfd_vma relro_start, relro_end;
|
||||
|
||||
/* List of symbols should be dynamic. */
|
||||
struct bfd_elf_dynamic_list *dynamic;
|
||||
};
|
||||
|
||||
/* This structures holds a set of callback functions. These are
|
||||
|
@ -724,4 +729,12 @@ struct bfd_elf_version_tree
|
|||
struct bfd_elf_version_expr *prev, const char *sym);
|
||||
};
|
||||
|
||||
struct bfd_elf_dynamic_list
|
||||
{
|
||||
struct bfd_elf_version_expr_head head;
|
||||
struct bfd_elf_version_expr *(*match)
|
||||
(struct bfd_elf_version_expr_head *head,
|
||||
struct bfd_elf_version_expr *prev, const char *sym);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
31
ld/ChangeLog
31
ld/ChangeLog
|
@ -1,3 +1,34 @@
|
|||
2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* Makefile.am (CXX): Set to g++.
|
||||
(CXX_FOR_TARGET): Likewise.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
* NEWS: Mention --dynamic-list.
|
||||
|
||||
* ld.texinfo: Document --dynamic-list.
|
||||
|
||||
* ldgram.y: Support dynamic list.
|
||||
|
||||
* ldlang.c (lang_process): Call lang_finalize_version_expr_head
|
||||
on link_info.dynamic if needed.
|
||||
(lang_append_dynamic_list): New.
|
||||
(lang_append_dynamic_list_cpp_typeinfo): New.
|
||||
* ldlang.h (lang_append_dynamic_list): Likewise.
|
||||
* ldlang.h (lang_append_dynamic_list_cpp_typeinfo): Likewise.
|
||||
|
||||
* ldlex.h (input_enum): Add input_dynamic_list.
|
||||
* ldlex.l: Handle it.
|
||||
|
||||
* ldmain.c (main): Initialize link_info.dynamic.
|
||||
|
||||
* lexsup.c (option_values): Add OPTION_DYNAMIC_LIST and
|
||||
OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
|
||||
(ld_options): Add entries for OPTION_DYNAMIC_LIST and
|
||||
OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
|
||||
(parse_args): Handle OPTION_DYNAMIC_LIST and
|
||||
OPTION_DYNAMIC_LIST_CPP_TYPEINFO.
|
||||
|
||||
2006-09-07 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* emulparams/h8300elf.sh: _tinydata should not be placed in
|
||||
|
|
|
@ -73,19 +73,19 @@ CC_FOR_TARGET = ` \
|
|||
fi; \
|
||||
fi`
|
||||
|
||||
CXX = gcc
|
||||
CXX = g++
|
||||
CXX_FOR_TARGET = ` \
|
||||
if [ -f $$r/../gcc/xgcc ] ; then \
|
||||
if [ -f $$r/../gcc/g++ ] ; then \
|
||||
if [ -f $$r/../newlib/Makefile ] ; then \
|
||||
echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
|
||||
echo $$r/../gcc/g++ -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
|
||||
else \
|
||||
echo $$r/../gcc/xgcc -B$$r/../gcc/; \
|
||||
echo $$r/../gcc/g++ -B$$r/../gcc/; \
|
||||
fi; \
|
||||
else \
|
||||
if [ "@host@" = "@target@" ] ; then \
|
||||
echo $(CXX); \
|
||||
else \
|
||||
echo gcc | sed '$(transform)'; \
|
||||
echo g++ | sed '$(transform)'; \
|
||||
fi; \
|
||||
fi`
|
||||
|
||||
|
|
|
@ -302,19 +302,19 @@ CC_FOR_TARGET = ` \
|
|||
fi; \
|
||||
fi`
|
||||
|
||||
CXX = gcc
|
||||
CXX = g++
|
||||
CXX_FOR_TARGET = ` \
|
||||
if [ -f $$r/../gcc/xgcc ] ; then \
|
||||
if [ -f $$r/../gcc/g++ ] ; then \
|
||||
if [ -f $$r/../newlib/Makefile ] ; then \
|
||||
echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
|
||||
echo $$r/../gcc/g++ -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
|
||||
else \
|
||||
echo $$r/../gcc/xgcc -B$$r/../gcc/; \
|
||||
echo $$r/../gcc/g++ -B$$r/../gcc/; \
|
||||
fi; \
|
||||
else \
|
||||
if [ "@host@" = "@target@" ] ; then \
|
||||
echo $(CXX); \
|
||||
else \
|
||||
echo gcc | sed '$(transform)'; \
|
||||
echo g++ | sed '$(transform)'; \
|
||||
fi; \
|
||||
fi`
|
||||
|
||||
|
|
5
ld/NEWS
5
ld/NEWS
|
@ -1,4 +1,9 @@
|
|||
-*- text -*-
|
||||
* ELF: Add --dynamic-list option to specify a list of global symbols
|
||||
whose references shouldn't be bound to the definition within the
|
||||
shared library, or a list of symbols which should be added to the
|
||||
symbol table in the executable.
|
||||
|
||||
* The default output section LMA has changed for allocatable sections from
|
||||
being equal to VMA, to keeping the difference between LMA and VMA the same as
|
||||
the previous output section in the same region. This is a more useful
|
||||
|
|
|
@ -487,9 +487,9 @@ back to the symbols defined by the program, rather than some other
|
|||
dynamic object, then you will probably need to use this option when
|
||||
linking the program itself.
|
||||
|
||||
You can also use the version script to control what symbols should
|
||||
You can also use the dynamic list to control what symbols should
|
||||
be added to the dynamic symbol table if the output format supports it.
|
||||
See the description of @samp{--version-script} in @ref{VERSION}.
|
||||
See the description of @samp{--dynamic-list}.
|
||||
|
||||
@ifclear SingleFormat
|
||||
@cindex big-endian objects
|
||||
|
@ -1130,6 +1130,19 @@ for a program linked against a shared library to override the definition
|
|||
within the shared library. This option is only meaningful on ELF
|
||||
platforms which support shared libraries.
|
||||
|
||||
@kindex --dynamic-list=@var{dynamic-list-file}
|
||||
@item --dynamic-list=@var{dynamic-list-file}
|
||||
Specify the name of a dynamic list file to the linker. This is
|
||||
typically used when creating shared libraries to specify a list of
|
||||
global symbols whose references shouldn't be bound to the definition
|
||||
within the shared library, or creating dynamically linked executables
|
||||
to specify a list of symbols which should be added to the symbol table
|
||||
in the executable. This option is only meaningful on ELF platforms
|
||||
which support shared libraries.
|
||||
|
||||
The format of the dynamic list is the same as the version node without
|
||||
scope and node name. See @ref{VERSION} for more information.
|
||||
|
||||
@kindex --check-sections
|
||||
@kindex --no-check-sections
|
||||
@item --check-sections
|
||||
|
|
30
ld/ldgram.y
30
ld/ldgram.y
|
@ -156,6 +156,7 @@ static int error_index;
|
|||
%type <versyms> vers_defns
|
||||
%type <versnode> vers_tag
|
||||
%type <deflist> verdep
|
||||
%token INPUT_DYNAMIC_LIST
|
||||
|
||||
%%
|
||||
|
||||
|
@ -163,6 +164,7 @@ file:
|
|||
INPUT_SCRIPT script_file
|
||||
| INPUT_MRI_SCRIPT mri_script_file
|
||||
| INPUT_VERSION_SCRIPT version_script_file
|
||||
| INPUT_DYNAMIC_LIST dynamic_list_file
|
||||
| INPUT_DEFSYM defsym_expr
|
||||
;
|
||||
|
||||
|
@ -1139,6 +1141,34 @@ phdr_val:
|
|||
}
|
||||
;
|
||||
|
||||
dynamic_list_file:
|
||||
{
|
||||
ldlex_version_file ();
|
||||
PUSH_ERROR (_("dynamic list"));
|
||||
}
|
||||
dynamic_list_nodes
|
||||
{
|
||||
ldlex_popstate ();
|
||||
POP_ERROR ();
|
||||
}
|
||||
;
|
||||
|
||||
dynamic_list_nodes:
|
||||
dynamic_list_node
|
||||
| dynamic_list_nodes dynamic_list_node
|
||||
;
|
||||
|
||||
dynamic_list_node:
|
||||
'{' dynamic_list_tag '}' ';'
|
||||
;
|
||||
|
||||
dynamic_list_tag:
|
||||
vers_defns ';'
|
||||
{
|
||||
lang_append_dynamic_list ($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* This syntax is used within an external version script file. */
|
||||
|
||||
version_script_file:
|
||||
|
|
48
ld/ldlang.c
48
ld/ldlang.c
|
@ -83,6 +83,8 @@ static void print_input_section (asection *);
|
|||
static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
|
||||
static void lang_record_phdrs (void);
|
||||
static void lang_do_version_exports_section (void);
|
||||
static void lang_finalize_version_expr_head
|
||||
(struct bfd_elf_version_expr_head *);
|
||||
|
||||
/* Exported variables. */
|
||||
lang_output_section_statement_type *abs_output_section;
|
||||
|
@ -5624,6 +5626,10 @@ relax_sections (void)
|
|||
void
|
||||
lang_process (void)
|
||||
{
|
||||
/* Finalize dynamic list. */
|
||||
if (link_info.dynamic)
|
||||
lang_finalize_version_expr_head (&link_info.dynamic->head);
|
||||
|
||||
current_target = default_target;
|
||||
|
||||
/* Open the output file. */
|
||||
|
@ -6926,3 +6932,45 @@ lang_add_unique (const char *name)
|
|||
ent->next = unique_section_list;
|
||||
unique_section_list = ent;
|
||||
}
|
||||
|
||||
/* Append the list of dynamic symbols to the existing one. */
|
||||
|
||||
void
|
||||
lang_append_dynamic_list (struct bfd_elf_version_expr *dynamic)
|
||||
{
|
||||
if (link_info.dynamic)
|
||||
{
|
||||
dynamic->next = link_info.dynamic->head.list;
|
||||
link_info.dynamic->head.list = dynamic;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct bfd_elf_dynamic_list *d;
|
||||
|
||||
d = xcalloc (1, sizeof *d);
|
||||
d->head.list = dynamic;
|
||||
d->match = lang_vers_match;
|
||||
link_info.dynamic = d;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the list of C++ typeinfo dynamic symbols to the existing
|
||||
one. */
|
||||
|
||||
void
|
||||
lang_append_dynamic_list_cpp_typeinfo (void)
|
||||
{
|
||||
const char * symbols [] =
|
||||
{
|
||||
"typeinfo name for*",
|
||||
"typeinfo for*"
|
||||
};
|
||||
struct bfd_elf_version_expr *dynamic = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (symbols); i++)
|
||||
dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++",
|
||||
FALSE);
|
||||
|
||||
lang_append_dynamic_list (dynamic);
|
||||
}
|
||||
|
|
|
@ -602,6 +602,8 @@ extern struct bfd_elf_version_deps *lang_add_vers_depend
|
|||
(struct bfd_elf_version_deps *, const char *);
|
||||
extern void lang_register_vers_node
|
||||
(const char *, struct bfd_elf_version_tree *, struct bfd_elf_version_deps *);
|
||||
extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
|
||||
extern void lang_append_dynamic_list_cpp_typeinfo (void);
|
||||
bfd_boolean unique_section_p
|
||||
(const asection *);
|
||||
extern void lang_add_unique
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef enum input_enum {
|
|||
input_script,
|
||||
input_mri_script,
|
||||
input_version_script,
|
||||
input_dynamic_list,
|
||||
input_defsym
|
||||
} input_type;
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
|
|||
case input_script: return INPUT_SCRIPT; break;
|
||||
case input_mri_script: return INPUT_MRI_SCRIPT; break;
|
||||
case input_version_script: return INPUT_VERSION_SCRIPT; break;
|
||||
case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
|
||||
case input_defsym: return INPUT_DEFSYM; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
|
|
@ -319,6 +319,7 @@ main (int argc, char **argv)
|
|||
link_info.warn_shared_textrel = FALSE;
|
||||
link_info.gc_sections = FALSE;
|
||||
link_info.print_gc_sections = FALSE;
|
||||
link_info.dynamic = NULL;
|
||||
|
||||
config.maxpagesize = 0;
|
||||
config.commonpagesize = 0;
|
||||
|
|
23
ld/lexsup.c
23
ld/lexsup.c
|
@ -107,6 +107,8 @@ enum option_values
|
|||
OPTION_VERSION,
|
||||
OPTION_VERSION_SCRIPT,
|
||||
OPTION_VERSION_EXPORTS_SECTION,
|
||||
OPTION_DYNAMIC_LIST,
|
||||
OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
|
||||
OPTION_WARN_COMMON,
|
||||
OPTION_WARN_CONSTRUCTORS,
|
||||
OPTION_WARN_FATAL,
|
||||
|
@ -501,6 +503,10 @@ static const struct ld_option ld_options[] =
|
|||
OPTION_VERSION_EXPORTS_SECTION },
|
||||
'\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n"
|
||||
"\t\t\t\tSYMBOL as the version."), TWO_DASHES },
|
||||
{ {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO},
|
||||
'\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
|
||||
{ {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
|
||||
'\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
|
||||
{ {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
|
||||
'\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
|
||||
{ {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
|
||||
|
@ -1236,6 +1242,23 @@ parse_args (unsigned argc, char **argv)
|
|||
.exports sections. */
|
||||
command_line.version_exports_section = optarg;
|
||||
break;
|
||||
case OPTION_DYNAMIC_LIST_CPP_TYPEINFO:
|
||||
lang_append_dynamic_list_cpp_typeinfo ();
|
||||
break;
|
||||
case OPTION_DYNAMIC_LIST:
|
||||
/* This option indicates a small script that only specifies
|
||||
a dynamic list. Read it, but don't assume that we've
|
||||
seen a linker script. */
|
||||
{
|
||||
FILE *hold_script_handle;
|
||||
|
||||
hold_script_handle = saved_script_handle;
|
||||
ldfile_open_command_file (optarg);
|
||||
saved_script_handle = hold_script_handle;
|
||||
parser_input = input_dynamic_list;
|
||||
yyparse ();
|
||||
}
|
||||
break;
|
||||
case OPTION_WARN_COMMON:
|
||||
config.warn_common = TRUE;
|
||||
break;
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* ld-elf/dl1.c: New file.
|
||||
* ld-elf/dl1.list: Likewise.
|
||||
* ld-elf/dl1.out: Likewise.
|
||||
* ld-elf/dl1main.c: Likewise.
|
||||
* ld-elf/dl2.c: Likewise.
|
||||
* ld-elf/dl2.list: Likewise.
|
||||
* ld-elf/dl2a.out: Likewise.
|
||||
* ld-elf/dl2b.out: Likewise.
|
||||
* ld-elf/dl2main.c: Likewise.
|
||||
* ld-elf/dl2xxx.c: Likewise.
|
||||
* ld-elf/dl2xxx.list: Likewise.
|
||||
* ld-elf/dl3.cc: Likewise.
|
||||
* ld-elf/dl3.list: Likewise.
|
||||
* ld-elf/dl3a.out: Likewise.
|
||||
* ld-elf/dl3b.out: Likewise.
|
||||
* ld-elf/dl3header.h: Likewise.
|
||||
* ld-elf/dl3main.cc: Likewise.
|
||||
|
||||
* ld-elf/shared.exp: Updated.
|
||||
|
||||
* lib/ld-lib.exp (run_ld_link_exec_tests): Take an optional
|
||||
argument for source language. Use CC/CXX for link, depending
|
||||
on source language.
|
||||
(run_cc_link_tests): Likewise.
|
||||
|
||||
2006-08-29 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-elf/loadaddr3a.d: Adjust target test.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
|
||||
extern int bar;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
if (bar == -20)
|
||||
printf ("OK\n");
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
extern "C"
|
||||
{
|
||||
bar;
|
||||
};
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
OK
|
|
@ -0,0 +1,33 @@
|
|||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int bar = -20;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int ret = 0;
|
||||
void *handle;
|
||||
void (*fcn) (void);
|
||||
|
||||
handle = dlopen("./tmpdir/libdl1.so", RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (!handle)
|
||||
{
|
||||
printf("dlopen libfoo.so: %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
fcn = (void (*)(void)) dlsym(handle, "foo");
|
||||
if (!fcn)
|
||||
{
|
||||
printf("dlsym foo: %s\n", dlerror ());
|
||||
ret += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*fcn) ();
|
||||
}
|
||||
|
||||
dlclose (handle);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int foo;
|
||||
|
||||
extern void xxx (void);
|
||||
|
||||
void
|
||||
bar (int x)
|
||||
{
|
||||
if (foo == 1)
|
||||
printf ("OK1\n");
|
||||
else if (foo == 0)
|
||||
printf ("OK2\n");
|
||||
foo = -1;
|
||||
xxx ();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
foo;
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
OK1
|
||||
DSO
|
||||
OK1
|
|
@ -0,0 +1,3 @@
|
|||
OK1
|
||||
MAIN
|
||||
OK1
|
|
@ -0,0 +1,22 @@
|
|||
#include <stdio.h>
|
||||
|
||||
extern int foo;
|
||||
extern void bar (void);
|
||||
|
||||
void
|
||||
xxx (void)
|
||||
{
|
||||
printf ("MAIN\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
foo = 1;
|
||||
bar ();
|
||||
if (foo == -1)
|
||||
printf ("OK1\n");
|
||||
else if (foo == 1)
|
||||
printf ("OK2\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void
|
||||
xxx (void)
|
||||
{
|
||||
printf ("DSO\n");
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
xxx;
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
#include "dl3header.h"
|
||||
|
||||
void
|
||||
f (void)
|
||||
{
|
||||
throw (A (42));
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
extern "C++"
|
||||
{
|
||||
typeinfo*;
|
||||
};
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
OK
|
|
@ -0,0 +1 @@
|
|||
BAD2
|
|
@ -0,0 +1,5 @@
|
|||
struct A
|
||||
{
|
||||
int i;
|
||||
A (int i): i(i) {}
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
#include <stdio.h>
|
||||
#include "dl3header.h"
|
||||
|
||||
extern void f (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
}
|
||||
catch (A a)
|
||||
{
|
||||
if (a.i == 42)
|
||||
printf ("OK\n");
|
||||
else
|
||||
printf ("BAD1\n");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
printf ("BAD2\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -38,7 +38,7 @@ set build_tests {
|
|||
{foo.c} {} "libfoo.so"}
|
||||
{"Build versioned libfoo.so"
|
||||
"-shared -Wl,--version-script=foo.map" "-fPIC"
|
||||
{foo.c} {} "libfoov.so" "-fPIC"}
|
||||
{foo.c} {} "libfoov.so"}
|
||||
{"Build libbar.so"
|
||||
"-shared" "-fPIC"
|
||||
{begin.c end.c} {} "libbar.so"}
|
||||
|
@ -66,6 +66,15 @@ set build_tests {
|
|||
{"Build protected libbar.so with versioned libfoo.so"
|
||||
"-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
|
||||
{endprotected.c} {} "libbarpfoov.so"}
|
||||
{"Build libdl1.so"
|
||||
"-shared" "-fPIC"
|
||||
{dl1.c} {} "libdl1.so"}
|
||||
{"Build libdl2a.so with --dynamic-list=dl2.list"
|
||||
"-shared -Wl,--dynamic-list=dl2.list" "-fPIC"
|
||||
{dl2.c dl2xxx.c} {} "libdl2a.so"}
|
||||
{"Build libdl2b.so with --dynamic-list=dl2.list and dl2xxx.list"
|
||||
"-shared -Wl,--dynamic-list=dl2.list,--dynamic-list=dl2xxx.list" "-fPIC"
|
||||
{dl2.c dl2xxx.c} {} "libdl2b.so"}
|
||||
}
|
||||
|
||||
set run_tests {
|
||||
|
@ -105,8 +114,49 @@ set run_tests {
|
|||
{"Run hidden libbar.so with versioned libfoo.so"
|
||||
"tmpdir/libbarhfoov.so tmpdir/libfoov.so" ""
|
||||
{main.c} "hidden" "hidden.out"}
|
||||
{"Run with dlopen on libdl1.so"
|
||||
"--dynamic-list=dl1.list -ldl" ""
|
||||
{dl1main.c} "dl1" "dl1.out"}
|
||||
{"Run with libdl2a.so"
|
||||
"tmpdir/libdl2a.so" ""
|
||||
{dl2main.c} "dl2a" "dl2a.out"}
|
||||
{"Run with libdl2b.so"
|
||||
"tmpdir/libdl2b.so" ""
|
||||
{dl2main.c} "dl2b" "dl2b.out"}
|
||||
}
|
||||
|
||||
run_cc_link_tests $build_tests
|
||||
# NetBSD ELF systems do not currently support the .*_array sections.
|
||||
run_ld_link_exec_tests [list "*-*-netbsdelf*"] $run_tests
|
||||
|
||||
# Check if compiler works
|
||||
if { [which $CXX] == 0 } {
|
||||
return
|
||||
}
|
||||
|
||||
set build_cxx_tests {
|
||||
{"Build libdl3a.so with --dynamic-list=dl3.list"
|
||||
"-shared -Wl,--dynamic-list=dl3.list" "-fPIC"
|
||||
{dl3.cc} {} "libdl3a.so" "c++"}
|
||||
{"Build libdl3b.so with -Bsymbolic"
|
||||
"-shared -Wl,-Bsymbolic" "-fPIC"
|
||||
{dl3.cc} {} "libdl3b.so" "c++"}
|
||||
{"Build libdl3a.so with --dynamic-list-cpp-typeinfo"
|
||||
"-shared -Wl,--dynamic-list-cpp-typeinfo" "-fPIC"
|
||||
{dl3.cc} {} "libdl3c.so" "c++"}
|
||||
}
|
||||
|
||||
set run_cxx_tests {
|
||||
{"Run with libdl3a.so"
|
||||
"tmpdir/libdl3a.so" ""
|
||||
{dl3main.cc} "dl3a" "dl3a.out" "" "c++"}
|
||||
{"Run with libdl3b.so"
|
||||
"tmpdir/libdl3b.so" ""
|
||||
{dl3main.cc} "dl3b" "dl3b.out" "" "c++"}
|
||||
{"Run with libdl3c.so"
|
||||
"tmpdir/libdl3c.so" ""
|
||||
{dl3main.cc} "dl3c" "dl3a.out" "" "c++"}
|
||||
}
|
||||
|
||||
run_cc_link_tests $build_cxx_tests
|
||||
run_ld_link_exec_tests [] $run_cxx_tests
|
||||
|
|
|
@ -1246,14 +1246,15 @@ if ![string length [info proc prune_warnings]] {
|
|||
|
||||
# targets_to_xfail is a list of target triplets to be xfailed.
|
||||
# ldtests contains test-items with 3 items followed by 1 lists, 2 items
|
||||
# and one optional item:
|
||||
# and 2 optional items:
|
||||
# 0:name
|
||||
# 1:ld options
|
||||
# 2:assembler options
|
||||
# 3:filenames of assembler files
|
||||
# 3:filenames of source files
|
||||
# 4:name of output file
|
||||
# 5:expected output
|
||||
# 6:compiler flags (optional)
|
||||
# 7:language (optional)
|
||||
|
||||
proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
||||
global ld
|
||||
|
@ -1262,6 +1263,7 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
|||
global subdir
|
||||
global env
|
||||
global CC
|
||||
global CXX
|
||||
global CFLAGS
|
||||
global errcnt
|
||||
|
||||
|
@ -1276,6 +1278,7 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
|||
set binfile tmpdir/[lindex $testitem 4]
|
||||
set expfile [lindex $testitem 5]
|
||||
set cflags [lindex $testitem 6]
|
||||
set lang [lindex $testitem 7]
|
||||
set objfiles {}
|
||||
set failed 0
|
||||
|
||||
|
@ -1297,7 +1300,13 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
|||
ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
|
||||
|
||||
# We have to use $CC to build PIE and shared library.
|
||||
if { [ string match "-shared" $ld_options ] \
|
||||
if { [ string match "c" $lang ] } {
|
||||
set link_proc ld_simple_link
|
||||
set link_cmd $CC
|
||||
} elseif { [ string match "c++" $lang ] } {
|
||||
set link_proc ld_simple_link
|
||||
set link_cmd $CXX
|
||||
} elseif { [ string match "-shared" $ld_options ] \
|
||||
|| [ string match "-pie" $ld_options ] } {
|
||||
set link_proc ld_simple_link
|
||||
set link_cmd $CC
|
||||
|
@ -1344,8 +1353,13 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
|||
|
||||
# List contains test-items with 3 items followed by 2 lists, one item and
|
||||
# one optional item:
|
||||
# 0:name 1:link options 2:compile options
|
||||
# 3:filenames of assembler files 4: action and options. 5: name of output file
|
||||
# 0:name
|
||||
# 1:link options
|
||||
# 2:compile options
|
||||
# 3:filenames of source files
|
||||
# 4:action and options.
|
||||
# 5:name of output file
|
||||
# 6:language (optional)
|
||||
#
|
||||
# Actions:
|
||||
# objdump: Apply objdump options on result. Compare with regex (last arg).
|
||||
|
@ -1360,6 +1374,7 @@ proc run_cc_link_tests { ldtests } {
|
|||
global subdir
|
||||
global env
|
||||
global CC
|
||||
global CXX
|
||||
global CFLAGS
|
||||
|
||||
foreach testitem $ldtests {
|
||||
|
@ -1369,6 +1384,7 @@ proc run_cc_link_tests { ldtests } {
|
|||
set src_files [lindex $testitem 3]
|
||||
set actions [lindex $testitem 4]
|
||||
set binfile tmpdir/[lindex $testitem 5]
|
||||
set lang [lindex $testitem 6]
|
||||
set objfiles {}
|
||||
set is_unresolved 0
|
||||
set failed 0
|
||||
|
@ -1387,7 +1403,13 @@ proc run_cc_link_tests { ldtests } {
|
|||
# Clear error and warning counts.
|
||||
reset_vars
|
||||
|
||||
if ![ld_simple_link $CC $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
|
||||
if { [ string match "c++" $lang ] } {
|
||||
set cc_cmd $CXX
|
||||
} else {
|
||||
set cc_cmd $CC
|
||||
}
|
||||
|
||||
if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
|
||||
fail $testname
|
||||
} else {
|
||||
set failed 0
|
||||
|
|
Loading…
Reference in New Issue