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:
H.J. Lu 2006-09-07 17:16:34 +00:00
parent 7c94efc522
commit 55255daec3
40 changed files with 512 additions and 30 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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));

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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`

View File

@ -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`

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);
}

View File

@ -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

View File

@ -30,6 +30,7 @@ typedef enum input_enum {
input_script,
input_mri_script,
input_version_script,
input_dynamic_list,
input_defsym
} input_type;

View File

@ -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 ();
}

View File

@ -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;

View File

@ -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;

View File

@ -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.

10
ld/testsuite/ld-elf/dl1.c Normal file
View File

@ -0,0 +1,10 @@
#include <stdio.h>
extern int bar;
void
foo (void)
{
if (bar == -20)
printf ("OK\n");
}

View File

@ -0,0 +1,6 @@
{
extern "C"
{
bar;
};
};

View File

@ -0,0 +1 @@
OK

View File

@ -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;
}

16
ld/testsuite/ld-elf/dl2.c Normal file
View File

@ -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 ();
}

View File

@ -0,0 +1,3 @@
{
foo;
};

View File

@ -0,0 +1,3 @@
OK1
DSO
OK1

View File

@ -0,0 +1,3 @@
OK1
MAIN
OK1

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
#include <stdio.h>
void
xxx (void)
{
printf ("DSO\n");
}

View File

@ -0,0 +1,3 @@
{
xxx;
};

View File

@ -0,0 +1,7 @@
#include "dl3header.h"
void
f (void)
{
throw (A (42));
}

View File

@ -0,0 +1,6 @@
{
extern "C++"
{
typeinfo*;
};
};

View File

@ -0,0 +1 @@
OK

View File

@ -0,0 +1 @@
BAD2

View File

@ -0,0 +1,5 @@
struct A
{
int i;
A (int i): i(i) {}
};

View File

@ -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;
}

View File

@ -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

View File

@ -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