From: Ulrich Drepper Date: Wed, 31 May 2006 15:50:43 +0000 (+0000) Subject: Handle as-needed options. X-Git-Tag: elfutils-0.121~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8c56fe3b2c753234beb6f58a81c8b96f008226ef;p=thirdparty%2Felfutils.git Handle as-needed options. --- diff --git a/libdw/libdw.h b/libdw/libdw.h index 0758a38d5..424c354e1 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -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 , 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 diff --git a/libelf/libelfP.h b/libelf/libelfP.h index 54158aeb8..ed6b5f7f3 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -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 , 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 */ diff --git a/src/ChangeLog b/src/ChangeLog index 77f9867b8..dc068b4f3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,7 +1,13 @@ -2006-05-28 Ulrich Drepper - - * addr2line.c (print_dwarf_function): Use unsigned type for lineno - and colno. +2006-05-31 Ulrich Drepper + + * 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 diff --git a/src/addr2line.c b/src/addr2line.c index 1729058e1..bc0ea803a 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 110072f90..99190df94 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 3de257ca2..47354cbea 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 , 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 c4c18a960..e0621d019 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 , 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 7311164c3..764b41575 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 , 2001. @@ -128,6 +128,7 @@ extern int yylex (void); %type outputsections %type assignment %type filename_id_list +%type filename_id_listelem %type versionlist %type version %type 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; }