This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: libc/1818: pthread problem with dlcose()
- To: Ulrich Drepper <drepper at cygnus dot com>,Ian Lance Taylor <ian at zembu dot com>, binutils at sourceware dot cygnus dot com
- Subject: Re: libc/1818: pthread problem with dlcose()
- From: "H . J . Lu" <hjl at lucon dot org>
- Date: Tue, 18 Jul 2000 21:27:03 -0700
- Cc: Mark Kettenis <kettenis at wins dot uva dot nl>,libc-hacker at sourceware dot cygnus dot com
- References: <200007190007.e6J07gm14827@delius.kettenis.local> <m3r98r0y8e.fsf@otr.mynet.cygnus.com>
On Tue, Jul 18, 2000 at 05:17:53PM -0700, Ulrich Drepper wrote:
>
> Solaris solves the problem (they also don't allow unloading the thread
> library) is by having the flag DF_1_NODELETE set in the FLAGS_1 word
> of the thread library. This is a much more worthwhile way to handle
> this.
>
Here is the patch for binutils. Ian, any comments?
BTW, I will provide ChangeLog entries later.
H.J.
---
Index: bfd/bfd-in.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/bfd-in.h,v
retrieving revision 1.13
diff -u -p -r1.13 bfd-in.h
--- bfd/bfd-in.h 2000/07/19 00:30:54 1.13
+++ bfd/bfd-in.h 2000/07/19 03:27:43
@@ -610,6 +610,9 @@ struct bfd_link_needed_list
const char *name;
};
+extern boolean bfd_elf_set_dt_flags
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+
extern boolean bfd_elf32_record_link_assignment
PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
extern boolean bfd_elf64_record_link_assignment
Index: bfd/bfd-in2.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/bfd-in2.h,v
retrieving revision 1.37
diff -u -p -r1.37 bfd-in2.h
--- bfd/bfd-in2.h 2000/07/19 00:30:54 1.37
+++ bfd/bfd-in2.h 2000/07/19 03:28:33
@@ -610,6 +610,9 @@ struct bfd_link_needed_list
const char *name;
};
+extern boolean bfd_elf_set_dt_flags
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+
extern boolean bfd_elf32_record_link_assignment
PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
extern boolean bfd_elf64_record_link_assignment
Index: bfd/elf.c
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elf.c,v
retrieving revision 1.25
diff -u -p -r1.25 elf.c
--- bfd/elf.c 2000/07/19 00:30:54 1.25
+++ bfd/elf.c 2000/07/19 04:21:58
@@ -1046,6 +1046,41 @@ bfd_elf_get_needed_list (abfd, info)
return elf_hash_table (info)->needed;
}
+/* OR the flags and flag_1 fields for a link. This is a hook for the
+ linker ELF emulation code. */
+
+boolean
+bfd_elf_set_dt_flags (abfd, info, flag)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ struct bfd_link_info *info;
+ const char *flag;
+{
+ if (strcmp (flag, "initfirst") == 0)
+ info->flags_1 |= (bfd_vma) DF_1_INITFIRST;
+ else if (strcmp (flag, "loadfltr") == 0)
+ info->flags_1 |= (bfd_vma) DF_1_LOADFLTR;
+ else if (strcmp (flag, "now") == 0)
+ {
+ info->flags |= (bfd_vma) DF_BIND_NOW;
+ info->flags_1 |= (bfd_vma) DF_1_NOW;
+ }
+ else if (strcmp (flag, "nodlopen") == 0)
+ info->flags_1 |= (bfd_vma) DF_1_NOOPEN;
+ else if (strcmp (flag, "nodelete") == 0)
+ info->flags_1 |= (bfd_vma) DF_1_NODELETE;
+ else if (strcmp (flag, "origin") == 0)
+ {
+ info->flags |= (bfd_vma) DF_ORIGIN;
+ info->flags_1 |= (bfd_vma) DF_1_ORIGIN;
+ }
+ else if (strcmp (flag, "textoff") == 0)
+ info->flags |= (bfd_vma) DF_TEXTREL;
+ else
+ return false;
+
+ return true;
+}
+
/* Get the name actually used for a dynamic object for a link. This
is the SONAME entry if there is one. Otherwise, it is the string
passed to bfd_elf_set_dt_needed_name, or it is the filename. */
Index: bfd/elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.34
diff -u -p -r1.34 elflink.h
--- bfd/elflink.h 2000/07/19 00:30:54 1.34
+++ bfd/elflink.h 2000/07/19 04:03:03
@@ -2837,6 +2837,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
{
if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
return false;
+ info->flags |= DF_SYMBOLIC;
}
if (rpath != NULL)
@@ -3133,6 +3134,18 @@ NAME(bfd_elf,size_dynamic_sections) (out
return false;
elf_tdata (output_bfd)->cverdefs = cdefs;
+ }
+
+ if (info->flags)
+ {
+ if (! elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
+ return false;
+ }
+
+ if (info->flags_1)
+ {
+ if (! elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
+ return false;
}
/* Work out the size of the version reference section. */
Index: include/bfdlink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/include/bfdlink.h,v
retrieving revision 1.7
diff -u -p -r1.7 bfdlink.h
--- include/bfdlink.h 2000/05/18 22:10:35 1.7
+++ include/bfdlink.h 2000/07/19 03:19:57
@@ -246,6 +246,12 @@ struct bfd_link_info
/* The function to call when the executable or shared object is
unloaded. */
const char *fini_function;
+
+ /* May be used to set DT_FLAGS for ELF. */
+ bfd_vma flags;
+
+ /* May be used to set DT_FLAGS_1 for ELF. */
+ bfd_vma flags_1;
};
/* This structures holds a set of callback functions. These are
Index: ld/ldmain.c
===================================================================
RCS file: /work/cvs/gnu/binutils/ld/ldmain.c,v
retrieving revision 1.13
diff -u -p -r1.13 ldmain.c
--- ld/ldmain.c 2000/07/13 16:00:36 1.13
+++ ld/ldmain.c 2000/07/19 03:26:51
@@ -238,6 +238,8 @@ main (argc, argv)
and _fini symbols. We are compatible. */
link_info.init_function = "_init";
link_info.fini_function = "_fini";
+ link_info.flags = (bfd_vma) 0;
+ link_info.flags_1 = (bfd_vma) 0;
ldfile_add_arch ("");
Index: ld/lexsup.c
===================================================================
RCS file: /work/cvs/gnu/binutils/ld/lexsup.c,v
retrieving revision 1.17
diff -u -p -r1.17 lexsup.c
--- ld/lexsup.c 2000/07/09 23:42:05 1.17
+++ ld/lexsup.c 2000/07/19 01:48:46
@@ -241,8 +241,10 @@ static const struct ld_option ld_options
'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
{ {NULL, required_argument, NULL, '\0'},
'Y', N_("PATH"), N_("Default search path for Solaris compatibility"), ONE_DASH },
+#if 0
{ {NULL, required_argument, NULL, '\0'},
'z', N_("KEYWORD"), N_("Ignored for Solaris compatibility"), ONE_DASH },
+#endif
{ {"start-group", no_argument, NULL, '('},
'(', NULL, N_("Start a group"), TWO_DASHES },
{ {"end-group", no_argument, NULL, ')'},
@@ -1015,11 +1017,13 @@ the GNU General Public License. This pr
case 'y':
add_ysym (optarg);
break;
+#if 0
case 'z':
/* We accept and ignore this option for Solaris
compatibility. Actually, on Solaris, optarg is not
ignored. Someday we should handle it correctly. FIXME. */
break;
+#endif
case OPTION_SPLIT_BY_RELOC:
config.split_by_reloc = strtoul (optarg, NULL, 0);
break;
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /work/cvs/gnu/binutils/ld/emultempl/elf32.em,v
retrieving revision 1.18
diff -u -p -r1.18 elf32.em
--- ld/emultempl/elf32.em 2000/07/19 00:15:32 1.18
+++ ld/emultempl/elf32.em 2000/07/19 04:23:11
@@ -1188,20 +1188,80 @@ cat >>e${EMULATION_NAME}.c <<EOF
else
return "ldscripts/${EMULATION_NAME}.x";
}
-EOF
-if test -n "$PARSE_AND_LIST_ARGS" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE * file));
+EOF
+
+if test -n "$PARSE_AND_LIST_ARGS" ; then
+cat >>e${EMULATION_NAME}.c <<EOF
$PARSE_AND_LIST_ARGS
EOF
else
cat >>e${EMULATION_NAME}.c <<EOF
-#define gld_${EMULATION_NAME}_parse_args NULL
-#define gld_${EMULATION_NAME}_list_options NULL
+
+#include "getopt.h"
+
+static struct option longopts[] =
+{
+ {NULL, required_argument, NULL, 'z'},
+ {NULL, no_argument, NULL, 0}
+};
+
+static int
+gld_${EMULATION_NAME}_parse_args (argc, argv)
+ int argc;
+ char ** argv;
+{
+ int longind, optc;
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int wanterror;
+ static int lastoptind = -1;
+
+ if (lastoptind != optind)
+ opterr = 0;
+
+ wanterror = opterr;
+ optc = getopt_long_only (argc, argv, "-z:", longopts, &longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ default:
+ if (wanterror)
+ xexit (1);
+ optind = prevoptind;
+ return 0;
+
+ case 'z':
+ if (bfd_elf_set_dt_flags (output_bfd, &link_info, optarg)
+ == false)
+ {
+ fprintf (stderr, _("%s: Unknow -z option: \`%s'\n"),
+ program_name, optarg);
+ xexit (1);
+ }
+ break;
+ }
+
+ return 1;
+}
+
+static void
+gld_${EMULATION_NAME}_list_options (file)
+ FILE * file;
+{
+ fprintf (file, _(" -z initfirst\tMark DSO be initialized first at rutime\n"));
+ fprintf (file, _(" -z loadfltr\tMark object requiring immediate process\n"));
+ fprintf (file, _(" -z now\tMark object non-lazy runtime binding\n"));
+ fprintf (file, _(" -z nodlopen\tMark DSO not availale to dlopen\n"));
+ fprintf (file, _(" -z nodelete\tMark DSO as non-deletable at runtime\n"));
+ fprintf (file, _(" -z origin\tMark object as requiring immediate \$ORIGIN processing at runtime.\n"));
+ fprintf (file, _(" -z textoff\tMark object allow relocations against non-writablesectins\n"));
+}
EOF
fi