⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ld-2.15-callahan.patch

📁 linux下编译交叉工具链的工具源码
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
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.Note that bfd_get_section_by_name_if didn't exist in 2.15, so it was backportedas well.--- binutils-2.15/bfd/bfd-in2.h.old	2004-05-17 15:35:56.000000000 -0400+++ binutils-2.15/bfd/bfd-in2.h	2006-02-09 11:54:45.989940000 -0500@@ -1425,6 +1425,10 @@  asection *bfd_get_section_by_name (bfd *abfd, const char *name); +asection *bfd_get_section_by_name_if (bfd *abfd, const char *name,+   bfd_boolean (*operation) (bfd *, asection *, void *),+   void *user_storage);+ char *bfd_get_unique_section_name    (bfd *abfd, const char *templat, int *count); --- binutils-2.15/bfd/section.c.old	2003-12-01 01:33:01.000000000 -0500+++ binutils-2.15/bfd/section.c	2006-01-23 14:16:54.768993000 -0500@@ -801,6 +801,57 @@  /* FUNCTION+	bfd_get_section_by_name_if++SYNOPSIS+	asection *bfd_get_section_by_name_if+	  (bfd *abfd,+	   const char *name,+	   bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),+	   void *obj);++DESCRIPTION+	Call the provided function @var{func} for each section+	attached to the BFD @var{abfd} whose name matches @var{name},+	passing @var{obj} as an argument. The function will be called+	as if by++|	func (abfd, the_section, obj);++	It returns the first section for which @var{func} returns true,+	otherwise <<NULL>>.++*/++asection *+bfd_get_section_by_name_if (bfd *abfd, const char *name,+			    bfd_boolean (*operation) (bfd *,+						      asection *,+						      void *),+			    void *user_storage)+{+  struct section_hash_entry *sh;+  unsigned long hash;++  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);+  if (sh == NULL)+    return NULL;++  hash = sh->root.hash;+  do+    {+      if ((*operation) (abfd, &sh->section, user_storage))+	return &sh->section;+      sh = (struct section_hash_entry *) sh->root.next;+    }+  while (sh != NULL && sh->root.hash == hash+	 && strcmp (sh->root.string, name) == 0);++  return NULL;+}++/*+FUNCTION 	bfd_get_unique_section_name  SYNOPSIS--- binutils-2.15/ld/ldlang.c.old	2004-05-17 15:36:16.000000000 -0400+++ binutils-2.15/ld/ldlang.c	2006-01-23 13:40:12.745499000 -0500@@ -81,9 +81,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;@@ -138,21 +135,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);@@ -160,39 +207,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); @@ -203,13 +219,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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -