public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH/RFC: ld add -p/-P options
@ 2009-08-28 21:41 Matt Rice
  2009-08-30  2:30 ` Matt Rice
  0 siblings, 1 reply; 10+ messages in thread
From: Matt Rice @ 2009-08-28 21:41 UTC (permalink / raw)
  To: Binutils

[-- Attachment #1: Type: text/plain, Size: 1238 bytes --]

this patch attempts to add the -P and -p options from the solaris ld
described here:
http://docs.sun.com/app/docs/doc/816-5165/ld-1?a=view
and in the sun linkers and libraries guide here:
http://docs.sun.com/app/docs/doc/817-1984/chapter6-1238?a=view

readelf already recognizes the options, so no patches needed for that.

there are some issues with the patch for instance
the tests currently fail because _bfd_elf_strtab_delref isn't being called,
i'm just not exactly sure how to make this get called.

and hopefully i did the readelf stuff in the testsuite right (i didn't
see it show up in the ld.log stuff)

now i guess that I am probably abusing some existing code paths in ways
which they weren't exactly intended, but it appears to work ignoring
that pesky assertion failure.

some other issues are that this is limited to elf binaries, so should
this be limited to using
the emultempl _parse_args() mechanism?

the glibc ld.so.2 doesn't yet handle these yet afaik, and I don't have
a solaris machine to test their implementation against.
so if somebody felt like doing that, it would also be appreciated.

since its not really in an applyable form yet I hope you don't mind if
i just do a changelog entry on the next iteration.

[-- Attachment #2: audit.diff --]
[-- Type: application/octet-stream, Size: 16556 bytes --]

Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.145
diff -u -p -r1.145 bfd-in.h
--- bfd/bfd-in.h	26 May 2009 14:12:02 -0000	1.145
+++ bfd/bfd-in.h	28 Aug 2009 19:21:38 -0000
@@ -618,7 +618,9 @@ enum dynamic_lib_link_class {
   DYN_AS_NEEDED = 1,
   DYN_DT_NEEDED = 2,
   DYN_NO_ADD_NEEDED = 4,
-  DYN_NO_NEEDED = 8
+  DYN_NO_NEEDED = 8,
+  DYN_DT_AUDIT = 16,
+  DYN_DT_DEPAUDIT = 32
 };
 
 enum notice_asneeded_action {
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.491
diff -u -p -r1.491 bfd-in2.h
--- bfd/bfd-in2.h	6 Aug 2009 17:37:59 -0000	1.491
+++ bfd/bfd-in2.h	28 Aug 2009 19:21:38 -0000
@@ -625,7 +625,9 @@ enum dynamic_lib_link_class {
   DYN_AS_NEEDED = 1,
   DYN_DT_NEEDED = 2,
   DYN_NO_ADD_NEEDED = 4,
-  DYN_NO_NEEDED = 8
+  DYN_NO_NEEDED = 8,
+  DYN_DT_AUDIT = 16,
+  DYN_DT_DEPAUDIT = 32
 };
 
 enum notice_asneeded_action {
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.352
diff -u -p -r1.352 elflink.c
--- bfd/elflink.c	11 Aug 2009 02:21:34 -0000	1.352
+++ bfd/elflink.c	28 Aug 2009 19:21:38 -0000
@@ -3086,7 +3086,8 @@ _bfd_elf_add_dynamic_entry (struct bfd_l
    1 if a DT_NEEDED tag already exists, and 0 on success.  */
 
 static int
-elf_add_dt_needed_tag (bfd *abfd,
+elf_add_dt_needed_like_tag (bfd *abfd,
+		       unsigned int needed_type,
 		       struct bfd_link_info *info,
 		       const char *soname,
 		       bfd_boolean do_it)
@@ -3120,7 +3121,7 @@ elf_add_dt_needed_tag (bfd *abfd,
 	    Elf_Internal_Dyn dyn;
 
 	    bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
-	    if (dyn.d_tag == DT_NEEDED
+	    if (dyn.d_tag == needed_type 
 		&& dyn.d_un.d_val == strindex)
 	      {
 		_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
@@ -3134,7 +3135,8 @@ elf_add_dt_needed_tag (bfd *abfd,
       if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
 	return -1;
 
-      if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+     
+      if (!_bfd_elf_add_dynamic_entry (info, needed_type, strindex))
 	return -1;
     }
   else
@@ -3388,6 +3390,12 @@ elf_link_add_object_symbols (bfd *abfd, 
   long old_dynsymcount = 0;
   size_t tabsize = 0;
   size_t hashsize = 0;
+  unsigned int needed_type = DT_NEEDED;
+
+  if (elf_dyn_lib_class(abfd) & DYN_DT_AUDIT)
+    needed_type = DT_AUDIT;
+  else if (elf_dyn_lib_class(abfd) & DYN_DT_DEPAUDIT)
+    needed_type = DT_DEPAUDIT;
 
   htab = elf_hash_table (info);
   bed = get_elf_backend_data (abfd);
@@ -3695,7 +3703,9 @@ error_free_dyn:
 	 will need to know it.  */
       elf_dt_name (abfd) = soname;
 
-      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+
+      ret = elf_add_dt_needed_like_tag (abfd, needed_type, info, soname,
+					add_needed);
       if (ret < 0)
 	goto error_return;
 
@@ -4444,7 +4454,9 @@ error_free_dyn:
 	      elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
 
 	      add_needed = TRUE;
-	      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+
+	      ret = elf_add_dt_needed_like_tag (abfd, needed_type, info, soname,
+						add_needed);
 	      if (ret < 0)
 		goto error_free_vers;
 
Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.52
diff -u -p -r1.52 ldfile.c
--- ld/ldfile.c	14 Apr 2009 03:17:21 -0000	1.52
+++ ld/ldfile.c	28 Aug 2009 19:21:39 -0000
@@ -371,7 +371,12 @@ ldfile_open_file (lang_input_statement_t
   if (entry->the_bfd != NULL)
     return;
 
-  if (! entry->search_dirs_flag)
+  if (entry->is_audit || entry->is_depaudit)
+    {
+      ldemul_open_dynamic_archive(entry->filename, NULL, entry);
+      return; 
+    }
+  else if (! entry->search_dirs_flag)
     {
       if (ldfile_try_open_bfd (entry->filename, entry))
 	return;
Index: ld/ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.59
diff -u -p -r1.59 ldgram.y
--- ld/ldgram.y	2 Mar 2009 17:27:35 -0000	1.59
+++ ld/ldgram.y	28 Aug 2009 19:21:39 -0000
@@ -97,7 +97,7 @@ static int error_index;
 %type <cname> wildcard_name
 %type <wildcard> wildcard_spec
 %token <bigint> INT
-%token <name> NAME LNAME
+%token <name> NAME LNAME AUDIT_NAME DEPAUDIT_NAME
 %type <integer> length
 %type <phdr> phdr_qualifiers
 %type <nocrossref> nocrossref_list
@@ -376,6 +376,24 @@ input_list:
 	|	input_list LNAME
 		{ lang_add_input_file($2,lang_input_file_is_l_enum,
 				 (char *)NULL); }
+	|	AUDIT_NAME
+		{ lang_add_input_file($1,lang_input_file_is_audit_enum,
+				 (char *)NULL); }
+	|	input_list ',' AUDIT_NAME
+		{ lang_add_input_file($3,lang_input_file_is_audit_enum,
+				 (char *)NULL); }
+	|	input_list AUDIT_NAME
+		{ lang_add_input_file($2,lang_input_file_is_audit_enum,
+				 (char *)NULL); }
+	|	DEPAUDIT_NAME
+		{ lang_add_input_file($1,lang_input_file_is_depaudit_enum,
+				 (char *)NULL); }
+	|	input_list ',' DEPAUDIT_NAME
+		{ lang_add_input_file($3,lang_input_file_is_depaudit_enum,
+				 (char *)NULL); }
+	|	input_list DEPAUDIT_NAME
+		{ lang_add_input_file($2,lang_input_file_is_depaudit_enum,
+				 (char *)NULL); }
 	|	AS_NEEDED '('
 		  { $<integer>$ = as_needed; as_needed = TRUE; }
 		     input_list ')'
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.315
diff -u -p -r1.315 ldlang.c
--- ld/ldlang.c	12 Aug 2009 12:40:55 -0000	1.315
+++ ld/ldlang.c	28 Aug 2009 19:21:39 -0000
@@ -1004,6 +1004,9 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->just_syms_flag = TRUE;
       p->search_dirs_flag = FALSE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
       break;
     case lang_input_file_is_fake_enum:
       p->filename = name;
@@ -1012,6 +1015,9 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->just_syms_flag = FALSE;
       p->search_dirs_flag = FALSE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
       break;
     case lang_input_file_is_l_enum:
       p->is_archive = TRUE;
@@ -1020,6 +1026,9 @@ new_afile (const char *name,
       p->local_sym_name = concat ("-l", name, (const char *) NULL);
       p->just_syms_flag = FALSE;
       p->search_dirs_flag = TRUE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
       break;
     case lang_input_file_is_marker_enum:
       p->filename = name;
@@ -1028,6 +1037,9 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->just_syms_flag = FALSE;
       p->search_dirs_flag = TRUE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
       break;
     case lang_input_file_is_search_file_enum:
       p->sysrooted = ldlang_sysrooted_script;
@@ -1037,6 +1049,9 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->just_syms_flag = FALSE;
       p->search_dirs_flag = TRUE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
       break;
     case lang_input_file_is_file_enum:
       p->filename = name;
@@ -1045,6 +1060,31 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->just_syms_flag = FALSE;
       p->search_dirs_flag = FALSE;
+      p->is_audit = FALSE;
+      p->is_depaudit = FALSE;
+      p->add_needed = add_needed;
+      break;
+    case lang_input_file_is_audit_enum:
+      p->is_archive = TRUE;
+      p->filename = name;
+      p->real = TRUE;
+      p->local_sym_name = concat ("-p", name, (const char *) NULL);
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = FALSE;
+      p->is_audit = TRUE;
+      p->is_depaudit = FALSE;
+      p->add_needed = FALSE;
+      break;
+    case lang_input_file_is_depaudit_enum:
+      p->is_archive = TRUE;
+      p->filename = name;
+      p->real = TRUE;
+      p->local_sym_name = concat ("-p", name, (const char *) NULL);
+      p->just_syms_flag = FALSE;
+      p->search_dirs_flag = FALSE;
+      p->is_audit = FALSE;
+      p->is_depaudit = TRUE;
+      p->add_needed = FALSE;
       break;
     default:
       FAIL ();
@@ -1053,7 +1093,6 @@ new_afile (const char *name,
   p->next_real_file = NULL;
   p->next = NULL;
   p->dynamic = config.dynamic_link;
-  p->add_needed = add_needed;
   p->as_needed = as_needed;
   p->whole_archive = whole_archive;
   p->loaded = FALSE;
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.84
diff -u -p -r1.84 ldlang.h
--- ld/ldlang.h	10 Aug 2009 07:50:56 -0000	1.84
+++ ld/ldlang.h	28 Aug 2009 19:21:39 -0000
@@ -32,7 +32,9 @@ typedef enum
   lang_input_file_is_marker_enum,
   lang_input_file_is_fake_enum,
   lang_input_file_is_search_file_enum,
-  lang_input_file_is_file_enum
+  lang_input_file_is_file_enum,
+  lang_input_file_is_audit_enum,
+  lang_input_file_is_depaudit_enum,
 } lang_input_file_enum_type;
 
 struct _fill_type
@@ -280,6 +282,13 @@ typedef struct lang_input_statement_stru
   unsigned int loaded : 1;
 
   unsigned int real : 1;
+
+  /* Whether this entry represents a DT_AUDIT entry */
+  unsigned int is_audit : 1;
+
+  /* Whether this entry represents a DT_DEPAUDIT entry */
+  unsigned int is_depaudit : 1;
+
 } lang_input_statement_type;
 
 typedef struct
Index: ld/ldlex.l
===================================================================
RCS file: /cvs/src/src/ld/ldlex.l,v
retrieving revision 1.42
diff -u -p -r1.42 ldlex.l
--- ld/ldlex.l	2 Mar 2009 17:27:35 -0000	1.42
+++ ld/ldlex.l	28 Aug 2009 19:21:39 -0000
@@ -372,6 +372,14 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 				  yylval.name = xstrdup (yytext + 2);
 				  return LNAME;
 				}
+<BOTH>"-p"{FILENAMECHAR}+ {
+				  yylval.name = xstrdup (yytext + 2);
+				  return AUDIT_NAME;
+				}
+<BOTH>"-P"{FILENAMECHAR}+ {
+				  yylval.name = xstrdup (yytext + 2);
+				  return DEPAUDIT_NAME;
+				}
 <EXPRESSION>{FILENAMECHAR1}{NOCFILENAMECHAR}*	{
 				 yylval.name = xstrdup (yytext);
 				  return NAME;
@@ -380,6 +388,14 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
 				  yylval.name = xstrdup (yytext + 2);
 				  return LNAME;
 				}
+<EXPRESSION>"-p"{NOCFILENAMECHAR}+ {
+				  yylval.name = xstrdup (yytext + 2);
+				  return AUDIT_NAME;
+				}
+<EXPRESSION>"-P"{NOCFILENAMECHAR}+ {
+				  yylval.name = xstrdup (yytext + 2);
+				  return DEPAUDIT_NAME;
+				}
 <SCRIPT>{WILDCHAR}* {
 		/* Annoyingly, this pattern can match comments, and we have
 		   longest match issues to consider.  So if the first two
Index: ld/lexsup.c
===================================================================
RCS file: /cvs/src/src/ld/lexsup.c,v
retrieving revision 1.112
diff -u -p -r1.112 lexsup.c
--- ld/lexsup.c	29 Apr 2009 17:24:26 -0000	1.112
+++ ld/lexsup.c	28 Aug 2009 19:21:39 -0000
@@ -268,6 +268,10 @@ static const struct ld_option ld_options
     'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES },
   { {NULL, required_argument, NULL, '\0'},
     'O', NULL, N_("Optimize output file"), ONE_DASH },
+  { {"audit", required_argument, NULL, 'p'},
+    'p', N_("AUDITLIB"), N_("Use AUDITLIB for rtld auditing."), TWO_DASHES },
+  { {"depaudit", required_argument, NULL, 'P'},
+    'P', N_("AUDITLIB"), N_("Use AUDITLIB for rtld dependency auditing."), TWO_DASHES },
   { {"Qy", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
   { {"emit-relocs", no_argument, NULL, 'q'},
@@ -885,6 +889,12 @@ parse_args (unsigned argc, char **argv)
 	case 'l':
 	  lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL);
 	  break;
+	case 'p':
+	  lang_add_input_file (optarg, lang_input_file_is_audit_enum, NULL);
+	  break;
+	case 'P':
+	  lang_add_input_file (optarg, lang_input_file_is_depaudit_enum, NULL);
+	  break;
 	case 'M':
 	  config.map_filename = "-";
 	  break;
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.199
diff -u -p -r1.199 elf32.em
--- ld/emultempl/elf32.em	26 Aug 2009 13:08:07 -0000	1.199
+++ ld/emultempl/elf32.em	28 Aug 2009 19:21:39 -0000
@@ -127,6 +127,12 @@ gld${EMULATION_NAME}_load_symbols (lang_
   if (!entry->add_needed)
     class |= DYN_NO_ADD_NEEDED;
 
+  if (entry->is_audit)
+    class |= DYN_DT_AUDIT;
+  
+  if (entry->is_depaudit)
+    class |= DYN_DT_DEPAUDIT;
+
   if (entry->just_syms_flag
       && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
     einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
@@ -1510,6 +1516,21 @@ gld${EMULATION_NAME}_open_dynamic_archiv
 
   filename = entry->filename;
 
+  if (entry->is_audit || entry->is_depaudit)
+    {
+
+      if (ldfile_try_open_bfd (entry->filename, entry)
+      	  && bfd_check_format (entry->the_bfd, bfd_object)
+          && (entry->the_bfd->flags & DYNAMIC) != 0)
+	{
+	  return TRUE;
+	}
+      return FALSE;
+    }
+
+  if (search == NULL)
+    return FALSE; /* assertion? */
+
   /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION
      is defined, but it does not seem worth the headache to optimize
      away those two bytes of space.  */
Index: ld/testsuite/ld-elf/audit.exp
===================================================================
RCS file: ld/testsuite/ld-elf/audit.exp
diff -N ld/testsuite/ld-elf/audit.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/audit.exp	28 Aug 2009 19:21:39 -0000
@@ -0,0 +1,51 @@
+# Expect script for various ELF tests.
+#   Copyright 2009 Free Software Foundation, Inc.
+#
+# 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.
+#
+
+# Exclude non-ELF targets.
+
+if ![is_elf_format] {
+    return
+}
+
+# The following tests require running the executable generated by ld.
+if ![isnative] {
+    return
+}
+
+# Check if compiler works
+if { [which $CC] == 0 } {
+    return
+}
+
+set build_tests {
+  {"Build audit.so"
+   "-shared" "-fPIC"
+   {auditlib.c} {} "audit.so"}
+  {"Run with -paudit.so"
+     "-Wl,-ptmpdir/audit.so" ""
+     {main.c} {{"readelf" {"-d"} "audit.rd"}} "audit.out"}
+  {"Run with -Paudit.so"
+     "-Wl,-Ptmpdir/audit.so" ""
+     {main.c} {{"readelf" {-d} "depaudit.rd"}} "depaudit.out"}
+}
+
+run_cc_link_tests $build_tests
+
Index: ld/testsuite/ld-elf/audit.rd
===================================================================
RCS file: ld/testsuite/ld-elf/audit.rd
diff -N ld/testsuite/ld-elf/audit.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/audit.rd	28 Aug 2009 19:21:39 -0000
@@ -0,0 +1 @@
+.*Audit library: \[tmpdir/audit.so\].*
Index: ld/testsuite/ld-elf/auditlib.c
===================================================================
RCS file: ld/testsuite/ld-elf/auditlib.c
diff -N ld/testsuite/ld-elf/auditlib.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/auditlib.c	28 Aug 2009 19:21:39 -0000
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <link.h>
+
+unsigned int la_version(unsigned int version)
+{
+  return version;
+}
+
+char *
+la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
+{
+  return (char *)name;
+}
+
Index: ld/testsuite/ld-elf/depaudit.rd
===================================================================
RCS file: ld/testsuite/ld-elf/depaudit.rd
diff -N ld/testsuite/ld-elf/depaudit.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/depaudit.rd	28 Aug 2009 19:21:39 -0000
@@ -0,0 +1 @@
+.*Dependency audit library: \[tmpdir/audit.so\].*

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-09-23 13:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-28 21:41 PATCH/RFC: ld add -p/-P options Matt Rice
2009-08-30  2:30 ` Matt Rice
2009-08-31 17:43   ` Ian Lance Taylor
2009-09-12 15:21     ` Matt Rice
2009-09-12 16:56       ` Matt Rice
2009-09-14  0:42         ` Alan Modra
2009-09-14  0:39       ` Alan Modra
2009-09-14 11:59         ` Matt Rice
2009-09-22 20:50           ` Matt Rice
2009-09-23 13:56             ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).