summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2006-05-31 15:50:43 +0000
committerUlrich Drepper <[email protected]>2006-05-31 15:50:43 +0000
commit8c56fe3b2c753234beb6f58a81c8b96f008226ef (patch)
treed61ffb7018be1081e3bba89ba3e7c17338509259 /src
parentdf72c45805a859891ed0dcb854ee766f8ebef372 (diff)
Handle as-needed options.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/addr2line.c3
-rw-r--r--src/ld.c17
-rw-r--r--src/ld.h10
-rw-r--r--src/ldgeneric.c9
-rw-r--r--src/ldscript.y30
6 files changed, 61 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 77f9867b..dc068b4f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,7 +1,13 @@
-2006-05-28 Ulrich Drepper <[email protected]>
-
- * addr2line.c (print_dwarf_function): Use unsigned type for lineno
- and colno.
+2006-05-31 Ulrich Drepper <[email protected]>
+
+ * 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 <[email protected]>
diff --git a/src/addr2line.c b/src/addr2line.c
index 1729058e..bc0ea803 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -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)
diff --git a/src/ld.c b/src/ld.c
index 110072f9..99190df9 100644
--- 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;
diff --git a/src/ld.h b/src/ld.h
index 3de257ca..47354cbe 100644
--- 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 <[email protected]>, 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;
diff --git a/src/ldgeneric.c b/src/ldgeneric.c
index c4c18a96..e0621d01 100644
--- a/src/ldgeneric.c
+++ b/src/ldgeneric.c
@@ -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 <[email protected]>, 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. */
diff --git a/src/ldscript.y b/src/ldscript.y
index 7311164c..764b4157 100644
--- a/src/ldscript.y
+++ b/src/ldscript.y
@@ -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 <[email protected]>, 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;
}