]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Handle as-needed options.
authorUlrich Drepper <drepper@redhat.com>
Wed, 31 May 2006 15:50:43 +0000 (15:50 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 31 May 2006 15:50:43 +0000 (15:50 +0000)
libdw/libdw.h
libelf/libelfP.h
src/ChangeLog
src/addr2line.c
src/ld.c
src/ld.h
src/ldgeneric.c
src/ldscript.y

index 0758a38d523eb290871e2db79d00e800ac2a4d22..424c354e12dee227d873a4e9fde08b4b42f978d5 100644 (file)
@@ -1,6 +1,7 @@
 /* Interfaces for libdw.
    Copyright (C) 2002, 2004, 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by the
index 54158aeb8d4bdfaf64ffe552be243514e84e6d42..ed6b5f7f303c6f0cd71c20386783156b745c7e2a 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal interfaces for libelf.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -546,8 +546,9 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
 
 
 /* We often have to update a flag iff a value changed.  Make this
-   convenient.  */
-#define update_if_changed(var, exp, flag) \
+   convenient.  None of the parameters must have a side effect.  */
+#ifdef __GNUC__
+# define update_if_changed(var, exp, flag) \
   do {                                                                       \
     __typeof__ (var) *_var = &(var);                                         \
     __typeof__ (exp) _exp = (exp);                                           \
@@ -557,5 +558,15 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
        (flag) |= ELF_F_DIRTY;                                                \
       }                                                                              \
   } while (0)
+#else
+# define update_if_changed(var, exp, flag) \
+  do {                                                                       \
+    if ((var) != (exp))                                                              \
+      {                                                                              \
+       (var) = (exp);                                                        \
+       (flag) |= ELF_F_DIRTY;                                                \
+      }                                                                              \
+  } while (0)
+#endif
 
 #endif  /* libelfP.h */
index 77f9867b83f6ef7d1d780d0cfca8206f01743904..dc068b4f3d4aa076e584cd89bdfb7e0993d72f69 100644 (file)
@@ -1,7 +1,13 @@
-2006-05-28  Ulrich Drepper  <drepper@redhat.com>
-
-       * addr2line.c (print_dwarf_function): Use unsigned type for lineno
-       and colno.
+2006-05-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * ld.c: Recognize --as-needed and --no-as-needed options.
+       * ld.h (struct usedfile): Add as_needed field.
+       (struct ld_state): Likewise.
+       * ldgeneric.c (ld_handle_filename_list): Copy as_needed flag from
+       the list.
+       * ldscript.y (filename_id_list): Split to correctly parse all
+       combinations.
+       (mark_as_needed): Fix loop.
 
 2006-05-27  Ulrich Drepper  <drepper@redhat.com>
 
index 1729058e1aa925742ab23303452a9126800feb01..bc0ea803acb2bf1959c8bf9e9630a5c726d5c286 100644 (file)
@@ -258,8 +258,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
                                               &attr_mem), &val) == 0)
                {
                  const char *file = dwarf_filesrc (files, val, NULL, NULL);
-                 unsigned int lineno = 0;
-                 unsigned int colno = 0;
+                 int lineno = 0, colno = 0;
                  if (dwarf_formudata (dwarf_attr (&scopes[i],
                                                   DW_AT_call_line,
                                                   &attr_mem), &val) == 0)
index 110072f909634cc65030f01c3e6c226186010a1d..99190df942ae7e80c3b27916ab6553566583956c 100644 (file)
--- a/src/ld.c
+++ b/src/ld.c
@@ -71,6 +71,8 @@ enum
     ARGP_no_gc_sections,
     ARGP_no_undefined,
     ARGP_conserve,
+    ARGP_as_needed,
+    ARGP_no_as_needed,
 #if YYDEBUG
     ARGP_yydebug,
 #endif
@@ -192,6 +194,11 @@ Default rules of extracting from archive; weak references are not enough."),
     N_("Add/suppress addition indentifying link-editor to .comment section"),
     0 },
 
+  { "as-needed", ARGP_as_needed, NULL, 0,
+    N_("Only set DT_NEEDED for following dynamic libs if actually used"), 0 },
+  { "no-as-needed", ARGP_no_as_needed, NULL, 0,
+    N_("Always set DT_NEEDED for following dynamic libs"), 0 },
+
 #if YYDEBUG
   { "yydebug", ARGP_yydebug, NULL, 0,
     N_("Select to get parser debug information"), 0 },
@@ -636,6 +643,8 @@ parse_opt_1st (int key, char *arg,
     case 'O':
     case ARGP_whole_archive:
     case ARGP_no_whole_archive:
+    case ARGP_as_needed:
+    case ARGP_no_as_needed:
     case 'L':
     case '(':
     case ')':
@@ -732,6 +741,13 @@ parse_opt_2nd (int key, char *arg,
       ld_state.extract_rule = defaultextract;
       break;
 
+    case ARGP_as_needed:
+      ld_state.as_needed = true;
+      break;
+    case ARGP_no_as_needed:
+      ld_state.as_needed = false;
+      break;
+
     case ARGP_static:
     case ARGP_dynamic:
       /* Enable/disable use for DSOs.  */
@@ -1107,6 +1123,7 @@ ld_new_inputfile (const char *fname, enum file_type type)
   newfile->soname = newfile->fname = newfile->rfname = fname;
   newfile->file_type = type;
   newfile->extract_rule = ld_state.extract_rule;
+  newfile->as_needed = ld_state.as_needed;
   newfile->lazyload = ld_state.lazyload;
   newfile->status = not_opened;
 
index 3de257ca24bcdaa591a88057e7a3d4acd8748061..47354cbea76950907395319d1e6ca821e1c8c785 100644 (file)
--- a/src/ld.h
+++ b/src/ld.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2005 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -115,6 +115,10 @@ struct usedfiles
      used in a reference.  */
   bool used;
 
+  /* True when file should be added to DT_NEEDED list only when
+     directly referenced.  */
+  bool as_needed;
+
   /* If nonzero this is the archive sequence number which can be used to
      determine whether back refernces from -( -) or GROUP statements
      have to be followed.  */
@@ -791,6 +795,10 @@ struct ld_state
   /* If true static linking is requested.  */
   bool statically;
 
+  /* If true, add DT_NEEDED entries for following files if they are
+     needed.  */
+  bool as_needed;
+
   /* How to extract elements from archives.  */
   enum extract_rule extract_rule;
 
index c4c18a960bf351486a2333f1ae6eaf40920e357c..e0621d01945675a5d0ae43a64b1955ee32b02a06 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -1534,8 +1534,11 @@ ld_handle_filename_list (struct filename_list *fnames)
       curp = runp->real = ld_new_inputfile (runp->name, relocatable_file_type);
 
       /* Set flags for group handling.  */
-      runp->real->group_start = runp->group_start;
-      runp->real->group_end = runp->group_end;
+      curp->group_start = runp->group_start;
+      curp->group_end = runp->group_end;
+
+      /* Set as-needed flag from the file, not the command line.  */
+      curp->as_needed = runp->as_needed;
 
       /* Read the file and everything else which comes up, including
         handling groups.  */
index 7311164c3e784ce53868987fb66a6c0692330e4a..764b41575053dc58b8fb0c59bfa50698c1ee1e2a 100644 (file)
@@ -1,6 +1,6 @@
 %{
 /* Parser for linker scripts.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -128,6 +128,7 @@ extern int yylex (void);
 %type <output_rule> outputsections
 %type <assignment> assignment
 %type <filename_list> filename_id_list
+%type <filename_list> filename_id_listelem
 %type <version> versionlist
 %type <version> version
 %type <version> version_stmt_list
@@ -358,7 +359,20 @@ expr:                kALIGN '(' expr ')'
                    { $$ = new_expr (exp_pagesize); }
                ;
 
-filename_id_list: kGROUP '(' filename_id_list ')'
+filename_id_list: filename_id_list comma_opt filename_id_listelem
+                   {
+                     $3->next = $1->next;
+                     $$ = $1->next = $3;
+                   }
+               | filename_id_listelem
+                   { $$ = $1; }
+               ;
+
+comma_opt:       ','
+               |
+               ;
+
+filename_id_listelem: kGROUP '(' filename_id_list ')'
                    {
                      /* First little optimization.  If there is only one
                         file in the group don't do anything.  */
@@ -371,19 +385,10 @@ filename_id_list: kGROUP '(' filename_id_list ')'
                    }
                | kAS_NEEDED '(' filename_id_list ')'
                    { $$ = mark_as_needed ($3); }
-               | filename_id_list comma_opt filename_id
-                   {
-                     struct filename_list *newp = new_filename_listelem ($3);
-                     newp->next = $1->next;
-                     $$ = $1->next = newp;
-                   }
                | filename_id
                    { $$ = new_filename_listelem ($1); }
                ;
 
-comma_opt:       ','
-               |
-               ;
 
 versionlist:     versionlist version
                    {
@@ -579,11 +584,12 @@ static struct filename_list *
 mark_as_needed (struct filename_list *listp)
 {
   struct filename_list *runp = listp;
-  while (runp != NULL)
+  do
     {
       runp->as_needed = true;
       runp = runp->next;
     }
+  while (runp != listp);
 
   return listp;
 }