📄 callahan.patch
字号:
Signed-off-by: dank@kegel.comFixes ld speed issue. See http://weblogs.mozillazine.org/roc/archives/2005/02/optimizing_gnu.htmlSee thread "Re: optimizations for 3x speedup in ld",http://sources.redhat.com/ml/binutils/2005-03/msg00847.htmlWildcard section matching enhancement, backported from the binutils CVS tree.Here's the CVS log comment from the original change to ldlang.c:revision 1.177date: 2005/04/06 15:33:02; author: jakub; state: Exp; lines: +438 -512005-04-06 Jakub Jelinek <jakub@redhat.com> * ldlang.c: Formatting. (walk_wild_consider_section): Remember return value from wildcardp. (is_simple_wild): Use strcspn instead of 2 strpbrk calls and strlen. (wild_spec_can_overlap): Use strcspn instead of strpbrk and strlen.2005-04-06 Robert O'Callahan <rocallahan@novell.com> * ld.h (lean_section_userdata_type): Remove. (fat_section_userdata_type): Remove file field. (SECTION_USERDATA_SIZE): Remove. * ldlang.c (init_os): Eliminate initialization of unused lean_section_userdata_type. * ldlang.h (callback_t, walk_wild_section_handler_t): New typedefs. (struct lang_wild_statement_struct): Add walk_wild_section_handler and handler_data fields. * ldlang.c (callback_t): Removed. (walk_wild_consider_section, walk_wild_section_general, section_iterator_callback, find_section, is_simple_wild, match_simple_wild, walk_wild_section_specs1_wild0, walk_wild_section_specs1_wild1, walk_wild_section_specs2_wild1, walk_wild_section_specs3_wild2, walk_wild_section_specs4_wild2, wild_spec_can_overlap, analyze_walk_wild_section_handler): New functions. (lang_add_wild): Call analyze_walk_wild_section_handler. (walk_wild_section): Renamed to walk_wild_section_general and created a wrapper function. (section_iterator_callback_data): New typedef.Index: src/ld/ld.h===================================================================RCS file: /cvs/src/src/ld/ld.h,vretrieving revision 1.26retrieving revision 1.27diff -u -r1.26 -r1.27--- binutils/ld/ld.h.old 16 Mar 2005 21:52:42 -0000 1.26+++ binutils/ld/ld.h 6 Apr 2005 15:33:02 -0000 1.27@@ -1,6 +1,6 @@ /* ld.h -- general linker header file Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,- 2001, 2002, 2003, 2004+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker.@@ -89,28 +89,15 @@ struct map_symbol_def *next; }; -/* Extra information we hold on sections */-typedef struct lean_user_section_struct {- /* For output sections: pointer to the section where this data will go. */- struct lang_input_statement_struct *file;-} lean_section_userdata_type;- /* The initial part of fat_user_section_struct has to be idential with lean_user_section_struct. */ typedef struct fat_user_section_struct {- /* For output sections: pointer to the section where this data will go. */- struct lang_input_statement_struct *file; /* For input sections, when writing a map file: head / tail of a linked list of hash table entries for symbols defined in this section. */ struct map_symbol_def *map_symbol_def_head; struct map_symbol_def **map_symbol_def_tail; } fat_section_userdata_type; -#define SECTION_USERDATA_SIZE \- (command_line.reduce_memory_overheads \- ? sizeof (lean_section_userdata_type) \- : sizeof (fat_section_userdata_type))- #define get_userdata(x) ((x)->userdata) #define BYTE_SIZE (1)Index: src/ld/ldlang.c===================================================================RCS file: /cvs/src/src/ld/ldlang.c,vretrieving revision 1.176retrieving revision 1.177diff -u -r1.176 -r1.177--- binutils/ld/ldlang.c.old 18 Mar 2005 13:56:26 -0000 1.176+++ binutils/ld/ldlang.c 6 Apr 2005 15:33:02 -0000 1.177@@ -84,9 +84,6 @@ static void lang_record_phdrs (void); static void lang_do_version_exports_section (void); -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,- asection *, lang_input_statement_type *, void *);- /* Exported variables. */ lang_output_section_statement_type *abs_output_section; lang_statement_list_type lang_output_section_statement;@@ -155,21 +152,71 @@ /* Generic traversal routines for finding matching sections. */ +/* Try processing a section against a wildcard. This just calls+ the callback unless the filename exclusion list is present+ and excludes the file. It's hardly ever present so this+ function is very fast. */++static void+walk_wild_consider_section (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ asection *s,+ struct wildcard_list *sec,+ callback_t callback,+ void *data)+{+ bfd_boolean skip = FALSE;+ struct name_list *list_tmp;++ /* Don't process sections from files which were+ excluded. */+ for (list_tmp = sec->spec.exclude_name_list;+ list_tmp;+ list_tmp = list_tmp->next)+ {+ bfd_boolean is_wildcard = wildcardp (list_tmp->name);+ if (is_wildcard)+ skip = fnmatch (list_tmp->name, file->filename, 0) == 0;+ else+ skip = strcmp (list_tmp->name, file->filename) == 0;++ /* If this file is part of an archive, and the archive is+ excluded, exclude this file. */+ if (! skip && file->the_bfd != NULL+ && file->the_bfd->my_archive != NULL+ && file->the_bfd->my_archive->filename != NULL)+ {+ if (is_wildcard)+ skip = fnmatch (list_tmp->name,+ file->the_bfd->my_archive->filename,+ 0) == 0;+ else+ skip = strcmp (list_tmp->name,+ file->the_bfd->my_archive->filename) == 0;+ }++ if (skip)+ break;+ }++ if (!skip)+ (*callback) (ptr, sec, s, file, data);+}++/* Lowest common denominator routine that can handle everything correctly,+ but slowly. */+ static void-walk_wild_section (lang_wild_statement_type *ptr,- lang_input_statement_type *file,- callback_t callback,- void *data)+walk_wild_section_general (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data) { asection *s;-- if (file->just_syms_flag)- return;+ struct wildcard_list *sec; for (s = file->the_bfd->sections; s != NULL; s = s->next) {- struct wildcard_list *sec;- sec = ptr->section_list; if (sec == NULL) (*callback) (ptr, sec, s, file, data);@@ -177,39 +224,8 @@ while (sec != NULL) { bfd_boolean skip = FALSE;- struct name_list *list_tmp; - /* Don't process sections from files which were- excluded. */- for (list_tmp = sec->spec.exclude_name_list;- list_tmp;- list_tmp = list_tmp->next)- {- if (wildcardp (list_tmp->name))- skip = fnmatch (list_tmp->name, file->filename, 0) == 0;- else- skip = strcmp (list_tmp->name, file->filename) == 0;-- /* If this file is part of an archive, and the archive is- excluded, exclude this file. */- if (! skip && file->the_bfd != NULL- && file->the_bfd->my_archive != NULL- && file->the_bfd->my_archive->filename != NULL)- {- if (wildcardp (list_tmp->name))- skip = fnmatch (list_tmp->name,- file->the_bfd->my_archive->filename,- 0) == 0;- else- skip = strcmp (list_tmp->name,- file->the_bfd->my_archive->filename) == 0;- }-- if (skip)- break;- }-- if (!skip && sec->spec.name != NULL)+ if (sec->spec.name != NULL) { const char *sname = bfd_get_section_name (file->the_bfd, s); @@ -220,13 +236,381 @@ } if (!skip)- (*callback) (ptr, sec, s, file, data);+ walk_wild_consider_section (ptr, file, s, sec, callback, data); sec = sec->next; } } } +/* Routines to find a single section given its name. If there's more+ than one section with that name, we report that. */++typedef struct+{+ asection *found_section;+ bfd_boolean multiple_sections_found;+} section_iterator_callback_data;++static bfd_boolean+section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)+{+ section_iterator_callback_data *d = data;++ if (d->found_section != NULL)+ {+ d->multiple_sections_found = TRUE;+ return TRUE;+ }++ d->found_section = s;+ return FALSE;+}++static asection *+find_section (lang_input_statement_type *file,+ struct wildcard_list *sec,+ bfd_boolean *multiple_sections_found)+{+ section_iterator_callback_data cb_data = { NULL, FALSE };++ bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, + section_iterator_callback, &cb_data);+ *multiple_sections_found = cb_data.multiple_sections_found;+ return cb_data.found_section;+}++/* Code for handling simple wildcards without going through fnmatch,+ which can be expensive because of charset translations etc. */++/* A simple wild is a literal string followed by a single '*',+ where the literal part is at least 4 characters long. */++static bfd_boolean+is_simple_wild (const char *name)+{+ size_t len = strcspn (name, "*?[");+ return len >= 4 && name[len] == '*' && name[len + 1] == '\0';+}++static bfd_boolean+match_simple_wild (const char *pattern, const char *name)+{+ /* The first four characters of the pattern are guaranteed valid+ non-wildcard characters. So we can go faster. */+ if (pattern[0] != name[0] || pattern[1] != name[1]+ || pattern[2] != name[2] || pattern[3] != name[3])+ return FALSE;++ pattern += 4;+ name += 4;+ while (*pattern != '*')+ if (*name++ != *pattern++)+ return FALSE;++ return TRUE;+}++/* Specialized, optimized routines for handling different kinds of+ wildcards */++static void+walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ /* We can just do a hash lookup for the section with the right name.+ But if that lookup discovers more than one section with the name+ (should be rare), we fall back to the general algorithm because+ we would otherwise have to sort the sections to make sure they+ get processed in the bfd's order. */+ bfd_boolean multiple_sections_found;+ struct wildcard_list *sec0 = ptr->handler_data[0];+ asection *s0 = find_section (file, sec0, &multiple_sections_found);++ if (multiple_sections_found)+ walk_wild_section_general (ptr, file, callback, data);+ else if (s0)+ walk_wild_consider_section (ptr, file, s0, sec0, callback, data);+}++static void+walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ asection *s;+ struct wildcard_list *wildsec0 = ptr->handler_data[0];++ for (s = file->the_bfd->sections; s != NULL; s = s->next)+ {+ const char *sname = bfd_get_section_name (file->the_bfd, s);+ bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -