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

* Re: PATCH/RFC: ld add -p/-P options
  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
  0 siblings, 1 reply; 10+ messages in thread
From: Matt Rice @ 2009-08-30  2:30 UTC (permalink / raw)
  To: Binutils

On Fri, Aug 28, 2009 at 1:13 PM, Matt Rice<ratmice@gmail.com> wrote:
>
> 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.
>

ok, so here is the list of questions I have regarding -P/-p i couldn't
glean from suns documentation

a) does it require that the shared library denoted as the argument
even exist, or does it just encode it as a shared library name which
is assumed to exist at runtime?
b) if the library does exist does it use the soname encoded into the audit lib?
c) in the testsuite i had to link to -ptmpdir/audit.so and
-Ptmpdir/audit.so are these basename'd or as is specified on the
command line?
d) does ld do any searching for the audit library in the /lib/secure,
/usr/lib/secure,/lib/secure/64 and /usr/lib/secure/64 directories or
anywhere, or is this only handled at runtime?
e) out of curiosity if 'a' is true does this mean an audit library
could potentially audit itself when also being linked to in a
DT_NEEDED?

anyhow i've tried to make the simple case provided in their docs work
(-plibaudit.so where libaudit.so exists), and i'm not sure how
important it is we hit all these corner cases correctly out of the
starting gate, though a) or some combination of a) and b) would impact
the implementation quite a bit.

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-08-30  2:30 ` Matt Rice
@ 2009-08-31 17:43   ` Ian Lance Taylor
  2009-09-12 15:21     ` Matt Rice
  0 siblings, 1 reply; 10+ messages in thread
From: Ian Lance Taylor @ 2009-08-31 17:43 UTC (permalink / raw)
  To: Matt Rice; +Cc: Binutils

Matt Rice <ratmice@gmail.com> writes:

> ok, so here is the list of questions I have regarding -P/-p i couldn't
> glean from suns documentation
>
> a) does it require that the shared library denoted as the argument
> even exist, or does it just encode it as a shared library name which
> is assumed to exist at runtime?

The best way to answer all of these questions is to see what Solaris ld
actually does.

That said, I don't see any reason that the libraries must exist at link
time.

> b) if the library does exist does it use the soname encoded into the audit lib?

I assume so.

> c) in the testsuite i had to link to -ptmpdir/audit.so and
> -Ptmpdir/audit.so are these basename'd or as is specified on the
> command line?

I assume as specific on the command line if there is no soname.

> d) does ld do any searching for the audit library in the /lib/secure,
> /usr/lib/secure,/lib/secure/64 and /usr/lib/secure/64 directories or
> anywhere, or is this only handled at runtime?

I doubt it ld would search those directories by default, but I really
don't know.

> e) out of curiosity if 'a' is true does this mean an audit library
> could potentially audit itself when also being linked to in a
> DT_NEEDED?

I don't see why not.

Ian

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

* Re: PATCH/RFC: ld add -p/-P options
  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:39       ` Alan Modra
  0 siblings, 2 replies; 10+ messages in thread
From: Matt Rice @ 2009-09-12 15:21 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Binutils

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

On Mon, Aug 31, 2009 at 10:27 AM, Ian Lance Taylor <iant@google.com> wrote:
> Matt Rice <ratmice@gmail.com> writes:
>
>> ok, so here is the list of questions I have regarding -P/-p i couldn't
>> glean from suns documentation
>
> The best way to answer all of these questions is to see what Solaris ld
> actually does.
>

Got this done, attached is a patch which implements my findings, and
documents the behaviour.
Solaris ld does not attempt to load the library or use the soname in it.
let me know if this is something I should do for the sake of
consistency with other ld behaviour,
or if documenting it is enough.

my copyright assignment should be arriving any day now.

2009-09-12  Matt Rice <ratmice@gmail.com>

	* bfd-in.h (bfd_elf_size_dynamic_sections): Add audit and depaudit
	arguments.
	* elflink.c (bfd_elf_size_dynamic_sections): Generate DT_AUDIT,
	DT_DEPAUDIT from audit/depaudit arguments.
	(elf_finalize_dynstr): finalize DT_AUDIT and DT_DEPAUDIT strtab entries.
	* bfd-in2.h: Regenerate.

2009-09-12  Matt Rice <ratmice@gmail.com>

	* emultempl/elf32.em:
	(gld${EMULATION_NAME}_add_options): Add -p and -P options.
	(gld${EULATION_NAME}_handle_options): Ditto.
	(gld${EULATION_NAME}_list_options): Ditto.
	(gld${EMULATION_NAME}_append_to_separated_string): New function for
	handling rpath-like colon separated strings.
	(gld${EMULATION_NAME}_before_allocation): Pass the audit and depaudit
	libs to bfd.
	ld.texinfo: Document -p and -P options.

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

? bfd/.ChangeLog.snip.swp
? bfd/ChangeLog.snip
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.146
diff -p -u -r1.146 bfd-in.h
--- bfd/bfd-in.h	2 Sep 2009 07:18:35 -0000	1.146
+++ bfd/bfd-in.h	12 Sep 2009 15:04:18 -0000
@@ -635,8 +635,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *,
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.493
diff -p -u -r1.493 bfd-in2.h
--- bfd/bfd-in2.h	9 Sep 2009 21:38:57 -0000	1.493
+++ bfd/bfd-in2.h	12 Sep 2009 15:04:18 -0000
@@ -642,8 +642,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *, 
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.353
diff -p -u -r1.353 elflink.c
--- bfd/elflink.c	9 Sep 2009 21:38:57 -0000	1.353
+++ bfd/elflink.c	12 Sep 2009 15:04:19 -0000
@@ -3234,6 +3234,8 @@ elf_finalize_dynstr (bfd *output_bfd, st
 	case DT_RUNPATH:
 	case DT_FILTER:
 	case DT_AUXILIARY:
+	case DT_AUDIT:
+	case DT_DEPAUDIT:
 	  dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
 	  break;
 	default:
@@ -5451,6 +5453,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
 			       const char *soname,
 			       const char *rpath,
 			       const char *filter_shlib,
+			       const char *audit,
+			       const char *depaudit,
 			       const char * const *auxiliary_filters,
 			       struct bfd_link_info *info,
 			       asection **sinterpptr,
@@ -5603,6 +5607,28 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	    }
 	}
 
+      if (audit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx))
+	    return FALSE;
+	}
+
+      if (depaudit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx))
+	    return FALSE;
+	}
+
       eif.info = info;
       eif.verdefs = verdefs;
       eif.failed = FALSE;
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.247
diff -p -u -r1.247 ld.texinfo
--- ld/ld.texinfo	6 Jul 2009 13:48:51 -0000	1.247
+++ ld/ld.texinfo	12 Sep 2009 15:04:19 -0000
@@ -802,6 +802,22 @@ the linker may make more use of this opt
 no difference in the linker's behaviour for different non-zero values
 of this option.  Again this may change with future releases.
 
+@kindex -p @var{AUDITLIB}
+@item -p @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_AUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_AUDIT}
+will contain a colon separated list of audit interfaces to use.  This
+option is only meaningful on ELF platforms supporting the rtld-audit interface.  
+
+@kindex -P @var{AUDITLIB}
+@item -P @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_DEPAUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_DEPAUDIT}
+will contain a colon separated list of audit interfaces to use.  This
+option is only meaningful on ELF platforms supporting the rtld-audit interface.  
+
 @kindex -q
 @kindex --emit-relocs
 @cindex retain relocations in final executable
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.203
diff -p -u -r1.203 elf32.em
--- ld/emultempl/elf32.em	11 Sep 2009 15:27:35 -0000	1.203
+++ ld/emultempl/elf32.em	12 Sep 2009 15:04:20 -0000
@@ -66,6 +66,7 @@ static void gld${EMULATION_NAME}_before_
 static void gld${EMULATION_NAME}_after_allocation (void);
 static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
   (asection *, const char *, int);
+static void gld${EMULATION_NAME}_append_to_separated_string(char **, char *);
 EOF
 
 if [ "x${USE_LIBPATH}" = xyes ] ; then
@@ -157,6 +158,10 @@ static lang_input_statement_type *global
 static struct bfd_link_needed_list *global_vercheck_needed;
 static bfd_boolean global_vercheck_failed;
 
+/* These variables are used to implement target options */
+
+static char *audit; /* colon (typically) separated list of libs */
+static char *depaudit; /* colon (typically) separated list of libs */
 
 /* On Linux, it's possible to have different versions of the same
    shared library linked against different versions of libc.  The
@@ -1420,7 +1425,7 @@ gld${EMULATION_NAME}_before_allocation (
     rpath = (const char *) getenv ("LD_RUN_PATH");
   if (! (bfd_elf_size_dynamic_sections
 	 (link_info.output_bfd, command_line.soname, rpath,
-	  command_line.filter_shlib,
+	  command_line.filter_shlib, audit, depaudit,
 	  (const char * const *) command_line.auxiliary_filters,
 	  &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
@@ -2013,7 +2018,7 @@ gld${EMULATION_NAME}_add_options
   (int ns, char **shortopts, int nl, struct option **longopts,
    int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
 {
-  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
+  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:p:P:";
   static const struct option xtra_long[] = {
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
 EOF
@@ -2048,6 +2053,45 @@ fragment <<EOF
 
 #define DEFAULT_BUILD_ID_STYLE	"sha1"
 
+static void 
+gld${EMULATION_NAME}_append_to_separated_string(char **to, char *optarg)
+{
+  if (*to == NULL)
+    *to = xstrdup (optarg);
+  else
+    {
+      size_t to_len = strlen (*to);
+      size_t optarg_len = strlen (optarg);
+      char *buf;
+      char *cp = *to;
+
+      /* First see whether OPTARG is already in the path.  */
+      do
+	{
+	  if (strncmp (optarg, cp, optarg_len) == 0
+	      && (cp[optarg_len] == 0
+		  || cp[optarg_len] == config.rpath_separator))
+	    /* We found it.  */
+	    break;
+
+	  /* Not yet found.  */
+	  cp = strchr (cp, config.rpath_separator);
+	  if (cp != NULL)
+	    ++cp;
+	}
+      while (cp != NULL);
+
+      if (cp == NULL)
+	{
+	  buf = xmalloc (to_len + optarg_len + 2);
+	  sprintf (buf, "%s%c%s", *to,
+		   config.rpath_separator, optarg);
+	  free (*to);
+	  *to = buf;
+	}
+    }
+}
+
 static bfd_boolean
 gld${EMULATION_NAME}_handle_option (int optc)
 {
@@ -2067,6 +2111,12 @@ gld${EMULATION_NAME}_handle_option (int 
       if (strcmp (optarg, "none"))
 	link_info.emit_note_gnu_build_id = xstrdup (optarg);
       break;
+    case 'p':
+	gld${EMULATION_NAME}_append_to_separated_string(&audit, optarg); 
+	break;
+    case 'P':
+	gld${EMULATION_NAME}_append_to_separated_string(&depaudit, optarg);
+	break;
 
 EOF
 
@@ -2218,6 +2268,10 @@ gld${EMULATION_NAME}_list_options (FILE 
 {
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
+  fprintf (file, _("\
+  -p AUDITLIB                 Specify a library to use for auditing\n"));
+  fprintf (file, _("\
+  -P AUDITLIB                 Specify a library to use for auditing dependencies\n"));
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then

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

* Re: PATCH/RFC: ld add -p/-P options
  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
  1 sibling, 1 reply; 10+ messages in thread
From: Matt Rice @ 2009-09-12 16:56 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Binutils

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

On Sat, Sep 12, 2009 at 8:21 AM, Matt Rice <ratmice@gmail.com> forgot
to attach the test suite patches:

I guess the *.rd files might be a bit fragile if it ever decides to be
something other than the 4th line.


2009-09-12  Matt Rice <ratmice@gmail.com>

	ld-elf/audit.exp: New.
	ld-elf/audit.rd: New.
	ld-elf/depaudit.rd: New.
	ld-elf/auditlib.c: New.

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

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	12 Sep 2009 16:34:32 -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	12 Sep 2009 16:34:32 -0000
@@ -0,0 +1,6 @@
+# ...
+.*
+.*
+.*
+.*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	12 Sep 2009 16:34:32 -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	12 Sep 2009 16:34:32 -0000
@@ -0,0 +1,6 @@
+# ...
+.*
+.*
+.*
+.*Dependency audit library: \[tmpdir/audit.so\].*
+#...

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-09-12 15:21     ` Matt Rice
  2009-09-12 16:56       ` Matt Rice
@ 2009-09-14  0:39       ` Alan Modra
  2009-09-14 11:59         ` Matt Rice
  1 sibling, 1 reply; 10+ messages in thread
From: Alan Modra @ 2009-09-14  0:39 UTC (permalink / raw)
  To: Matt Rice; +Cc: Binutils

On Sat, Sep 12, 2009 at 08:21:35AM -0700, Matt Rice wrote:
> 	(gld${EMULATION_NAME}_add_options): Add -p and -P options.

There's a small problem here.  See armelf.em:PARSE_AND_LIST_SHORTOPTS.
You'll need to get approval from one of the ARM maintainers to remove
that from armelf.em.

> @@ -66,6 +66,7 @@ static void gld${EMULATION_NAME}_before_
>  static void gld${EMULATION_NAME}_after_allocation (void);
>  static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
>    (asection *, const char *, int);
> +static void gld${EMULATION_NAME}_append_to_separated_string(char **, char *);

No need for a prototype.

> @@ -2048,6 +2053,45 @@ fragment <<EOF
>  
>  #define DEFAULT_BUILD_ID_STYLE	"sha1"
>  
> +static void 
> +gld${EMULATION_NAME}_append_to_separated_string(char **to, char *optarg)

Space before (.  Other than that the patch looks good.

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-09-12 16:56       ` Matt Rice
@ 2009-09-14  0:42         ` Alan Modra
  0 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2009-09-14  0:42 UTC (permalink / raw)
  To: Matt Rice; +Cc: Binutils

On Sat, Sep 12, 2009 at 09:56:15AM -0700, Matt Rice wrote:
> I guess the *.rd files might be a bit fragile if it ever decides to be
> something other than the 4th line.

Write it like this:

#...
.*Audit library: \[tmpdir/audit.so\].*
#pass

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-09-14  0:39       ` Alan Modra
@ 2009-09-14 11:59         ` Matt Rice
  2009-09-22 20:50           ` Matt Rice
  0 siblings, 1 reply; 10+ messages in thread
From: Matt Rice @ 2009-09-14 11:59 UTC (permalink / raw)
  To: Matt Rice, Binutils

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

On Sun, Sep 13, 2009 at 5:39 PM, Alan Modra <amodra@bigpond.net.au> wrote:
> On Sat, Sep 12, 2009 at 08:21:35AM -0700, Matt Rice wrote:
>>       (gld${EMULATION_NAME}_add_options): Add -p and -P options.
>
> There's a small problem here.  See armelf.em:PARSE_AND_LIST_SHORTOPTS.
> You'll need to get approval from one of the ARM maintainers to remove
> that from armelf.em.

doesn't look like this is going to be an option, this is still passed
to ld by the linux kernel

http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob;f=arch/arm/Makefile;h=54661125a8bfff2b69a1daee5d6de3ae5ebd1395;hb=HEAD

 13 LDFLAGS_vmlinux :=-p --no-undefined -X

http://sourceware.org/ml/binutils/2004-11/msg00401.html
is the thread where this option was turned into a nop.

a possible hack I hesitate to mention is to make -p on gnu-ld accept
an optional argument,
in that case '-pfoo.so' will work with both linkers, the -p in '-p
--other-option' will be a ignored, but '-p foo.so' will
fail to recognize 'foo.so' as an argument to -p though....  there is
probably some caveat i'm missing, but it
does seem to maintain compatibility with the existing -p in armelf,
and give the ability to use a command line which will also work under
solaris.

Personally, I prefer just adding --audit with no short option and
seeing if solaris won't add a long option for compatibilty with us.
then if the armelf guys feel like deprecating their -p and going
through that whole process we could add -p as a short option to
--audit.
that doesn't help in the interim, but i'm going to need configure
checks to see if ld supports the option anyways.

if the hack is wanted i can send a follow up patch.

>> +static void gld${EMULATION_NAME}_append_to_separated_string(char **, char *);
>
> No need for a prototype.

Fixed

>> +gld${EMULATION_NAME}_append_to_separated_string(char **to, char *optarg)
>
> Space before (.  Other than that the patch looks good.

And fixed.

>> I guess the *.rd files might be a bit fragile if it ever decides to be
>> something other than the 4th line.
>
>Write it like this:

>#...
>.*Audit library: \[tmpdir/audit.so\].*
>#pass

Thanks,
I also removed the auditlib.c from the tests since it was unused.


2009-09-12  Matt Rice <ratmice@gmail.com>

       * bfd-in.h (bfd_elf_size_dynamic_sections): Add audit and depaudit
       arguments.
       * elflink.c (bfd_elf_size_dynamic_sections): Generate DT_AUDIT,
       DT_DEPAUDIT from audit/depaudit arguments.
       (elf_finalize_dynstr): finalize DT_AUDIT and DT_DEPAUDIT strtab entries.
       * bfd-in2.h: Regenerate.

2009-09-12  Matt Rice <ratmice@gmail.com>

       * emultempl/elf32.em:
       (gld${EMULATION_NAME}_add_options): Add --audit, --depaudit,
and -P options.
       (gld${EULATION_NAME}_handle_options): Ditto.
       (gld${EULATION_NAME}_list_options): Ditto.
       (gld${EMULATION_NAME}_append_to_separated_string): New function for
       handling rpath-like colon separated strings.
       (gld${EMULATION_NAME}_before_allocation): Pass the audit and depaudit
       libs to bfd.
       ld.texinfo: Document new options.

2009-09-12  Matt Rice <ratmice@gmail.com>

       ld-elf/audit.exp: New.
       ld-elf/audit.rd: New.
       ld-elf/depaudit.rd: New.

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

? bfd/ChangeLog.snip
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.247
diff -u -p -r1.247 ld.texinfo
--- ld/ld.texinfo	6 Jul 2009 13:48:51 -0000	1.247
+++ ld/ld.texinfo	14 Sep 2009 11:22:35 -0000
@@ -364,6 +364,14 @@ argument must be one of the strings @sam
 @samp{-Bstatic}, and the other two keywords are functionally equivalent
 to @samp{-Bdynamic}.  This option may be used any number of times.
 
+@kindex --audit @var{AUDITLIB}
+@item --audit @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_AUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_AUDIT}
+will contain a colon separated list of audit interfaces to use.  This
+option is only meaningful on ELF platforms supporting the rtld-audit interface.  
+
 @ifset I960
 @cindex architectures
 @kindex -A @var{arch}
@@ -451,6 +459,17 @@ even if a relocatable output file is spe
 script command @code{FORCE_COMMON_ALLOCATION} has the same effect.
 @xref{Miscellaneous Commands}.
 
+@kindex --depaudit @var{AUDITLIB}
+@kindex -P @var{AUDITLIB}
+@item --depaudit @var{AUDITLIB}
+@itemx -P @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_DEPAUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_DEPAUDIT}
+will contain a colon separated list of audit interfaces to use.  This
+option is only meaningful on ELF platforms supporting the rtld-audit interface.
+The -P option is provided for Solaris compatibility.  
+
 @cindex entry point, from command line
 @kindex -e @var{entry}
 @kindex --entry=@var{entry}
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.203
diff -u -p -r1.203 elf32.em
--- ld/emultempl/elf32.em	11 Sep 2009 15:27:35 -0000	1.203
+++ ld/emultempl/elf32.em	14 Sep 2009 11:22:35 -0000
@@ -157,6 +157,10 @@ static lang_input_statement_type *global
 static struct bfd_link_needed_list *global_vercheck_needed;
 static bfd_boolean global_vercheck_failed;
 
+/* These variables are used to implement target options */
+
+static char *audit; /* colon (typically) separated list of libs */
+static char *depaudit; /* colon (typically) separated list of libs */
 
 /* On Linux, it's possible to have different versions of the same
    shared library linked against different versions of libc.  The
@@ -1420,7 +1424,7 @@ gld${EMULATION_NAME}_before_allocation (
     rpath = (const char *) getenv ("LD_RUN_PATH");
   if (! (bfd_elf_size_dynamic_sections
 	 (link_info.output_bfd, command_line.soname, rpath,
-	  command_line.filter_shlib,
+	  command_line.filter_shlib, audit, depaudit,
 	  (const char * const *) command_line.auxiliary_filters,
 	  &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
@@ -2007,15 +2011,19 @@ fragment <<EOF
 #define OPTION_EXCLUDE_LIBS		(OPTION_EH_FRAME_HDR + 1)
 #define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
 #define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
+#define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
+#define OPTION_DEPAUDIT			(OPTION_AUDIT + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
   (int ns, char **shortopts, int nl, struct option **longopts,
    int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
 {
-  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
+  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
   static const struct option xtra_long[] = {
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"audit", required_argument, NULL, OPTION_AUDIT},
+    {"depaudit", required_argument, NULL, OPTION_DEPAUDIT},
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
@@ -2048,6 +2056,45 @@ fragment <<EOF
 
 #define DEFAULT_BUILD_ID_STYLE	"sha1"
 
+static void 
+gld${EMULATION_NAME}_append_to_separated_string (char **to, char *optarg)
+{
+  if (*to == NULL)
+    *to = xstrdup (optarg);
+  else
+    {
+      size_t to_len = strlen (*to);
+      size_t optarg_len = strlen (optarg);
+      char *buf;
+      char *cp = *to;
+
+      /* First see whether OPTARG is already in the path.  */
+      do
+	{
+	  if (strncmp (optarg, cp, optarg_len) == 0
+	      && (cp[optarg_len] == 0
+		  || cp[optarg_len] == config.rpath_separator))
+	    /* We found it.  */
+	    break;
+
+	  /* Not yet found.  */
+	  cp = strchr (cp, config.rpath_separator);
+	  if (cp != NULL)
+	    ++cp;
+	}
+      while (cp != NULL);
+
+      if (cp == NULL)
+	{
+	  buf = xmalloc (to_len + optarg_len + 2);
+	  sprintf (buf, "%s%c%s", *to,
+		   config.rpath_separator, optarg);
+	  free (*to);
+	  *to = buf;
+	}
+    }
+}
+
 static bfd_boolean
 gld${EMULATION_NAME}_handle_option (int optc)
 {
@@ -2067,6 +2114,13 @@ gld${EMULATION_NAME}_handle_option (int 
       if (strcmp (optarg, "none"))
 	link_info.emit_note_gnu_build_id = xstrdup (optarg);
       break;
+    case OPTION_AUDIT:
+  	gld${EMULATION_NAME}_append_to_separated_string(&audit, optarg); 
+	break;
+    case OPTION_DEPAUDIT:
+    case 'P':
+	gld${EMULATION_NAME}_append_to_separated_string(&depaudit, optarg);
+	break;
 
 EOF
 
@@ -2218,6 +2272,11 @@ gld${EMULATION_NAME}_list_options (FILE 
 {
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
+  fprintf (file, _("\
+  --audit=AUDITLIB            Specify a library to use for auditing\n"));
+  fprintf (file, _("\
+  -P AUDITLIB, --depaudit=AUDITLIB\n" "\
+                              Specify a library to use for auditing dependencies\n"));
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
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	14 Sep 2009 11:22:35 -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 {
+  {"Run with -paudit.so"
+     "-Wl,--audit=tmpdir/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 with --depaudit=audit.so"
+     "-Wl,--depaudit=tmpdir/audit.so" ""
+     {main.c} {{"readelf" {-d} "depaudit.rd"}} "depaudit2.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	14 Sep 2009 11:22:35 -0000
@@ -0,0 +1,3 @@
+#...
+.*Audit library: \[tmpdir/audit.so\].*
+#pass
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	14 Sep 2009 11:22:35 -0000
@@ -0,0 +1,3 @@
+#...
+.*Dependency audit library: \[tmpdir/audit.so\].*
+#pass
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.146
diff -u -p -r1.146 bfd-in.h
--- bfd/bfd-in.h	2 Sep 2009 07:18:35 -0000	1.146
+++ bfd/bfd-in.h	14 Sep 2009 11:22:35 -0000
@@ -635,8 +635,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *,
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.493
diff -u -p -r1.493 bfd-in2.h
--- bfd/bfd-in2.h	9 Sep 2009 21:38:57 -0000	1.493
+++ bfd/bfd-in2.h	14 Sep 2009 11:22:35 -0000
@@ -642,8 +642,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *, 
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.353
diff -u -p -r1.353 elflink.c
--- bfd/elflink.c	9 Sep 2009 21:38:57 -0000	1.353
+++ bfd/elflink.c	14 Sep 2009 11:22:36 -0000
@@ -3234,6 +3234,8 @@ elf_finalize_dynstr (bfd *output_bfd, st
 	case DT_RUNPATH:
 	case DT_FILTER:
 	case DT_AUXILIARY:
+	case DT_AUDIT:
+	case DT_DEPAUDIT:
 	  dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
 	  break;
 	default:
@@ -5451,6 +5453,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
 			       const char *soname,
 			       const char *rpath,
 			       const char *filter_shlib,
+			       const char *audit,
+			       const char *depaudit,
 			       const char * const *auxiliary_filters,
 			       struct bfd_link_info *info,
 			       asection **sinterpptr,
@@ -5603,6 +5607,28 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	    }
 	}
 
+      if (audit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx))
+	    return FALSE;
+	}
+
+      if (depaudit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx))
+	    return FALSE;
+	}
+
       eif.info = info;
       eif.verdefs = verdefs;
       eif.failed = FALSE;

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-09-14 11:59         ` Matt Rice
@ 2009-09-22 20:50           ` Matt Rice
  2009-09-23 13:56             ` Alan Modra
  0 siblings, 1 reply; 10+ messages in thread
From: Matt Rice @ 2009-09-22 20:50 UTC (permalink / raw)
  To: Matt Rice, Binutils

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

My copyright assignment went through recently, so thats no longer an issue.
I discovered a feature missing from in my patch, when linking to an object
which has a DT_AUDIT, it needs to propagate into a DT_DEPAUDIT in the
output file,

I tried to avoid the iteration over the input_bfd's in before_allocation, by
doing it in the existing loop in _after_open, but this proved to be
quite difficult
due to it exiting the loop early, or skipping objects, etc, so i
finally gave up on that.
so hopefully this is ok.

2009-09-12  Matt Rice <ratmice@gmail.com>

       * bfd-in.h (bfd_elf_size_dynamic_sections): Add audit and depaudit
       arguments.
       * elflink.c (bfd_elf_size_dynamic_sections): Generate DT_AUDIT,
       DT_DEPAUDIT from audit/depaudit arguments.
       (elf_finalize_dynstr): finalize DT_AUDIT and DT_DEPAUDIT strtab entries.
       (elf_link_add_object_symbols): Set dt_audit target data when finding a
       DT_AUDIT.
       * bfd-in2.h: Regenerate.
       * bfd-elf.h: Add dt_audit to elf_obj_tdata, and elf_dt_audit macro.

2009-09-12  Matt Rice <ratmice@gmail.com>

       * emultempl/elf32.em:
       (gld${EMULATION_NAME}_add_options): Add --audit, --depaudit,
 and -P options.
       (gld${EULATION_NAME}_handle_options): Ditto.
       (gld${EULATION_NAME}_list_options): Ditto.
       (gld${EMULATION_NAME}_append_to_separated_string): New function for
       handling rpath-like colon separated strings.
       (gld${EMULATION_NAME}_before_allocation): Pass the audit and depaudit
       libs to bfd.  Propagate DT_AUDIT from needed libs to depaudit.
       ld.texinfo: Document new options.

2009-09-12  Matt Rice <ratmice@gmail.com>

      ld-elf/audit.exp: New.
      ld-elf/audit.rd: New.
      ld-elf/depaudit.rd: New.
      ld-elf/depaudit2.rd: New.

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

? bfd/ChangeLog.snip
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.247
diff -u -p -r1.247 ld.texinfo
--- ld/ld.texinfo	6 Jul 2009 13:48:51 -0000	1.247
+++ ld/ld.texinfo	22 Sep 2009 20:11:10 -0000
@@ -364,6 +364,17 @@ argument must be one of the strings @sam
 @samp{-Bstatic}, and the other two keywords are functionally equivalent
 to @samp{-Bdynamic}.  This option may be used any number of times.
 
+@kindex --audit @var{AUDITLIB}
+@item --audit @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_AUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_AUDIT}
+will contain a colon separated list of audit interfaces to use. If the linker
+finds an object with an audit entry while searching for shared libraries,
+it will add a corresponding @code{DT_DEPAUDIT} entry in the output file.  
+This option is only meaningful on ELF platforms supporting the rtld-audit
+interface.  
+
 @ifset I960
 @cindex architectures
 @kindex -A @var{arch}
@@ -451,6 +462,17 @@ even if a relocatable output file is spe
 script command @code{FORCE_COMMON_ALLOCATION} has the same effect.
 @xref{Miscellaneous Commands}.
 
+@kindex --depaudit @var{AUDITLIB}
+@kindex -P @var{AUDITLIB}
+@item --depaudit @var{AUDITLIB}
+@itemx -P @var{AUDITLIB}
+Adds @var{AUDITLIB} to the @code{DT_DEPAUDIT} entry of the dynamic section.
+@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME
+specified in the library.  If specified multiple times @code{DT_DEPAUDIT}
+will contain a colon separated list of audit interfaces to use.  This
+option is only meaningful on ELF platforms supporting the rtld-audit interface.
+The -P option is provided for Solaris compatibility.  
+
 @cindex entry point, from command line
 @kindex -e @var{entry}
 @kindex --entry=@var{entry}
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.203
diff -u -p -r1.203 elf32.em
--- ld/emultempl/elf32.em	11 Sep 2009 15:27:35 -0000	1.203
+++ ld/emultempl/elf32.em	22 Sep 2009 20:11:11 -0000
@@ -157,6 +157,10 @@ static lang_input_statement_type *global
 static struct bfd_link_needed_list *global_vercheck_needed;
 static bfd_boolean global_vercheck_failed;
 
+/* These variables are used to implement target options */
+
+static char *audit; /* colon (typically) separated list of libs */
+static char *depaudit; /* colon (typically) separated list of libs */
 
 /* On Linux, it's possible to have different versions of the same
    shared library linked against different versions of libc.  The
@@ -1396,6 +1400,46 @@ if test x"$LDEMUL_BEFORE_ALLOCATION" != 
   fi
 fragment <<EOF
 
+/* used by before_allocation and handle_option. */
+static void 
+gld${EMULATION_NAME}_append_to_separated_string (char **to, char *optarg)
+{
+  if (*to == NULL)
+    *to = xstrdup (optarg);
+  else
+    {
+      size_t to_len = strlen (*to);
+      size_t optarg_len = strlen (optarg);
+      char *buf;
+      char *cp = *to;
+
+      /* First see whether OPTARG is already in the path.  */
+      do
+	{
+	  if (strncmp (optarg, cp, optarg_len) == 0
+	      && (cp[optarg_len] == 0
+		  || cp[optarg_len] == config.rpath_separator))
+	    /* We found it.  */
+	    break;
+
+	  /* Not yet found.  */
+	  cp = strchr (cp, config.rpath_separator);
+	  if (cp != NULL)
+	    ++cp;
+	}
+      while (cp != NULL);
+
+      if (cp == NULL)
+	{
+	  buf = xmalloc (to_len + optarg_len + 2);
+	  sprintf (buf, "%s%c%s", *to,
+		   config.rpath_separator, optarg);
+	  free (*to);
+	  *to = buf;
+	}
+    }
+}
+
 /* This is called after the sections have been attached to output
    sections, but before any sizes or addresses have been set.  */
 
@@ -1404,6 +1448,7 @@ gld${EMULATION_NAME}_before_allocation (
 {
   const char *rpath;
   asection *sinterp;
+  bfd *abfd;
 
   if (link_info.hash->type == bfd_link_elf_hash_table)
     _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
@@ -1418,9 +1463,39 @@ gld${EMULATION_NAME}_before_allocation (
   rpath = command_line.rpath;
   if (rpath == NULL)
     rpath = (const char *) getenv ("LD_RUN_PATH");
+
+  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+    {
+      const char *audit_libs = elf_dt_audit (abfd);
+
+      /* If the input bfd contains an audit entry, we need to add it as 
+         a dep audit entry.  */
+      if (audit_libs && *audit_libs != '\0')
+	{
+	  char *cp = xstrdup (audit_libs);
+	  do
+	    {
+	      int more = 0;
+	      char *cp2 = strchr (cp, config.rpath_separator);
+
+	      if (cp2)
+		{
+	          *cp2 = '\0';
+		  more = 1;
+		}
+	      
+	      if (cp != NULL && *cp != '\0')
+	        gld${EMULATION_NAME}_append_to_separated_string (&depaudit, cp);
+
+	      cp = more ? ++cp2 : NULL;
+	    }
+	  while (cp != NULL);
+	}
+    }
+
   if (! (bfd_elf_size_dynamic_sections
 	 (link_info.output_bfd, command_line.soname, rpath,
-	  command_line.filter_shlib,
+	  command_line.filter_shlib, audit, depaudit,
 	  (const char * const *) command_line.auxiliary_filters,
 	  &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
@@ -2007,15 +2082,19 @@ fragment <<EOF
 #define OPTION_EXCLUDE_LIBS		(OPTION_EH_FRAME_HDR + 1)
 #define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
 #define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
+#define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
+#define OPTION_DEPAUDIT			(OPTION_AUDIT + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
   (int ns, char **shortopts, int nl, struct option **longopts,
    int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
 {
-  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
+  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
   static const struct option xtra_long[] = {
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"audit", required_argument, NULL, OPTION_AUDIT},
+    {"depaudit", required_argument, NULL, OPTION_DEPAUDIT},
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
@@ -2067,6 +2146,13 @@ gld${EMULATION_NAME}_handle_option (int 
       if (strcmp (optarg, "none"))
 	link_info.emit_note_gnu_build_id = xstrdup (optarg);
       break;
+    case OPTION_AUDIT:
+  	gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg); 
+	break;
+    case OPTION_DEPAUDIT:
+    case 'P':
+	gld${EMULATION_NAME}_append_to_separated_string (&depaudit, optarg);
+	break;
 
 EOF
 
@@ -2218,6 +2304,11 @@ gld${EMULATION_NAME}_list_options (FILE 
 {
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
+  fprintf (file, _("\
+  --audit=AUDITLIB            Specify a library to use for auditing\n"));
+  fprintf (file, _("\
+  -P AUDITLIB, --depaudit=AUDITLIB\n" "\
+                              Specify a library to use for auditing dependencies\n"));
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
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	22 Sep 2009 20:11:11 -0000
@@ -0,0 +1,65 @@
+# 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 {
+  {"Run with -paudit.so"
+     "-Wl,--audit=tmpdir/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 with --depaudit=audit.so"
+     "-Wl,--depaudit=tmpdir/audit.so" ""
+     {main.c} {{"readelf" {-d} "depaudit.rd"}} "depaudit2.out"}
+  {"Run with shared with --audit"
+     "-shared -Wl,--audit=tmpdir/audit.so" "-fPIC"
+     {main.c} {} "libusesaudit.so"}
+  {"Run with shared with --audit"
+     "-shared -Wl,--audit=tmpdir/audit.so -Wl,--audit=tmpdir/audit2.so \
+     -Wl,--audit=tmpdir/audit3.so"
+     "-fPIC"
+     {main.c} {} "libusesaudit2.so"}
+  {"Run with -lusesaudit"
+     "-Ltmpdir/ -lusesaudit" ""
+     {main.c} {{"readelf" {-d} "depaudit.rd"}} "useslibusesaudit.out"}
+  {"Run with -lusesaudit -lusesaudit2"
+     "-Ltmpdir/ -lusesaudit -lusesaudit2" ""
+     {main.c} {{"readelf" {-d} "depaudit2.rd"}} "useslibusesaudit2.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	22 Sep 2009 20:11:11 -0000
@@ -0,0 +1,3 @@
+#...
+.*Audit library: \[tmpdir/audit.so\].*
+#pass
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	22 Sep 2009 20:11:11 -0000
@@ -0,0 +1,3 @@
+#...
+.*Dependency audit library: \[tmpdir/audit.so\].*
+#pass
Index: ld/testsuite/ld-elf/depaudit2.rd
===================================================================
RCS file: ld/testsuite/ld-elf/depaudit2.rd
diff -N ld/testsuite/ld-elf/depaudit2.rd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/depaudit2.rd	22 Sep 2009 20:11:11 -0000
@@ -0,0 +1,3 @@
+#...
+.*Dependency audit library: \[tmpdir/audit.so:tmpdir/audit2.so:tmpdir/audit3.so\].*
+#pass
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.146
diff -u -p -r1.146 bfd-in.h
--- bfd/bfd-in.h	2 Sep 2009 07:18:35 -0000	1.146
+++ bfd/bfd-in.h	22 Sep 2009 20:11:11 -0000
@@ -635,8 +635,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *,
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.493
diff -u -p -r1.493 bfd-in2.h
--- bfd/bfd-in2.h	9 Sep 2009 21:38:57 -0000	1.493
+++ bfd/bfd-in2.h	22 Sep 2009 20:11:11 -0000
@@ -642,8 +642,8 @@ extern struct bfd_link_needed_list *bfd_
 extern bfd_boolean bfd_elf_get_bfd_needed_list
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
-  (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **,
+  (bfd *, const char *, const char *, const char *, const char *, const char *,
+   const char * const *, struct bfd_link_info *, struct bfd_section **,
    struct bfd_elf_version_tree *);
 extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
   (bfd *, struct bfd_link_info *);
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.295
diff -u -p -r1.295 elf-bfd.h
--- bfd/elf-bfd.h	19 Sep 2009 08:06:10 -0000	1.295
+++ bfd/elf-bfd.h	22 Sep 2009 20:11:11 -0000
@@ -1503,6 +1503,10 @@ struct elf_obj_tdata
      one.  */
   const char *dt_name;
 
+  /* The linker emulation needs to know what audit libs
+     are used by a dynamic object.  */ 
+  const char *dt_audit;
+
   /* Records the result of `get_program_header_size'.  */
   bfd_size_type program_header_size;
 
@@ -1632,6 +1636,7 @@ struct elf_obj_tdata
 #define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
 #define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
 #define elf_dt_name(bfd)	(elf_tdata(bfd) -> dt_name)
+#define elf_dt_audit(bfd)	(elf_tdata(bfd) -> dt_audit)
 #define elf_dyn_lib_class(bfd)	(elf_tdata(bfd) -> dyn_lib_class)
 #define elf_bad_symtab(bfd)	(elf_tdata(bfd) -> bad_symtab)
 #define elf_flags_init(bfd)	(elf_tdata(bfd) -> flags_init)
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.353
diff -u -p -r1.353 elflink.c
--- bfd/elflink.c	9 Sep 2009 21:38:57 -0000	1.353
+++ bfd/elflink.c	22 Sep 2009 20:11:11 -0000
@@ -3234,6 +3234,8 @@ elf_finalize_dynstr (bfd *output_bfd, st
 	case DT_RUNPATH:
 	case DT_FILTER:
 	case DT_AUXILIARY:
+	case DT_AUDIT:
+	case DT_DEPAUDIT:
 	  dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
 	  break;
 	default:
@@ -3525,6 +3527,7 @@ elf_link_add_object_symbols (bfd *abfd, 
     {
       asection *s;
       const char *soname = NULL;
+      char *audit = NULL;
       struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
       int ret;
 
@@ -3653,6 +3656,11 @@ error_free_dyn:
 		    ;
 		  *pn = n;
 		}
+	      if (dyn.d_tag == DT_AUDIT)
+		{
+		  unsigned int tagv = dyn.d_un.d_val;
+		  audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+		}
 	    }
 
 	  free (dynbuf);
@@ -3705,6 +3713,9 @@ error_free_dyn:
 	 particular dynamic object more than once.  */
       if (ret > 0)
 	return TRUE;
+
+      /* Save the DT_AUDIT entry for the linker emulation code. */
+      elf_dt_audit (abfd) = audit; 
     }
 
   /* If this is a dynamic object, we always link against the .dynsym
@@ -5451,6 +5462,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
 			       const char *soname,
 			       const char *rpath,
 			       const char *filter_shlib,
+			       const char *audit,
+			       const char *depaudit,
 			       const char * const *auxiliary_filters,
 			       struct bfd_link_info *info,
 			       asection **sinterpptr,
@@ -5603,6 +5616,28 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	    }
 	}
 
+      if (audit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx))
+	    return FALSE;
+	}
+
+      if (depaudit != NULL)
+	{
+	  bfd_size_type indx;
+
+	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit,
+				      TRUE);
+	  if (indx == (bfd_size_type) -1
+	      || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx))
+	    return FALSE;
+	}
+
       eif.info = info;
       eif.verdefs = verdefs;
       eif.failed = FALSE;

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

* Re: PATCH/RFC: ld add -p/-P options
  2009-09-22 20:50           ` Matt Rice
@ 2009-09-23 13:56             ` Alan Modra
  0 siblings, 0 replies; 10+ messages in thread
From: Alan Modra @ 2009-09-23 13:56 UTC (permalink / raw)
  To: Matt Rice; +Cc: Binutils

Patch applied with a minor tweak to elf32.em.

-- 
Alan Modra
Australia Development Lab, IBM

^ 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).