📄 callahan.patch
字号:
+ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);+ }+}++static void+walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ asection *s;+ struct wildcard_list *sec0 = ptr->handler_data[0];+ struct wildcard_list *wildsec1 = ptr->handler_data[1];+ bfd_boolean multiple_sections_found;+ asection *s0 = find_section (file, sec0, &multiple_sections_found);++ if (multiple_sections_found)+ {+ walk_wild_section_general (ptr, file, callback, data);+ return;+ }++ /* Note that if the section was not found, s0 is NULL and+ we'll simply never succeed the s == s0 test below. */+ for (s = file->the_bfd->sections; s != NULL; s = s->next)+ {+ /* Recall that in this code path, a section cannot satisfy more+ than one spec, so if s == s0 then it cannot match+ wildspec1. */+ if (s == s0)+ walk_wild_consider_section (ptr, file, s, sec0, callback, data);+ else+ {+ const char *sname = bfd_get_section_name (file->the_bfd, s);+ bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);++ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec1, callback,+ data);+ }+ }+}++static void+walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ asection *s;+ struct wildcard_list *sec0 = ptr->handler_data[0];+ struct wildcard_list *wildsec1 = ptr->handler_data[1];+ struct wildcard_list *wildsec2 = ptr->handler_data[2];+ bfd_boolean multiple_sections_found;+ asection *s0 = find_section (file, sec0, &multiple_sections_found);++ if (multiple_sections_found)+ {+ walk_wild_section_general (ptr, file, callback, data);+ return;+ }++ for (s = file->the_bfd->sections; s != NULL; s = s->next)+ {+ if (s == s0)+ walk_wild_consider_section (ptr, file, s, sec0, callback, data);+ else+ {+ const char *sname = bfd_get_section_name (file->the_bfd, s);+ bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);++ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);+ else+ {+ skip = !match_simple_wild (wildsec2->spec.name, sname);+ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec2, callback,+ data);+ }+ }+ }+}++static void+walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ asection *s;+ struct wildcard_list *sec0 = ptr->handler_data[0];+ struct wildcard_list *sec1 = ptr->handler_data[1];+ struct wildcard_list *wildsec2 = ptr->handler_data[2];+ struct wildcard_list *wildsec3 = ptr->handler_data[3];+ bfd_boolean multiple_sections_found;+ asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;++ if (multiple_sections_found)+ {+ walk_wild_section_general (ptr, file, callback, data);+ return;+ }++ s1 = find_section (file, sec1, &multiple_sections_found);+ if (multiple_sections_found)+ {+ walk_wild_section_general (ptr, file, callback, data);+ return;+ }++ for (s = file->the_bfd->sections; s != NULL; s = s->next)+ {+ if (s == s0)+ walk_wild_consider_section (ptr, file, s, sec0, callback, data);+ else+ if (s == s1)+ walk_wild_consider_section (ptr, file, s, sec1, callback, data);+ else+ {+ const char *sname = bfd_get_section_name (file->the_bfd, s);+ bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,+ sname);++ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec2, callback,+ data);+ else+ {+ skip = !match_simple_wild (wildsec3->spec.name, sname);+ if (!skip)+ walk_wild_consider_section (ptr, file, s, wildsec3,+ callback, data);+ }+ }+ }+}++static void+walk_wild_section (lang_wild_statement_type *ptr,+ lang_input_statement_type *file,+ callback_t callback,+ void *data)+{+ if (file->just_syms_flag)+ return;++ (*ptr->walk_wild_section_handler) (ptr, file, callback, data);+}++/* Returns TRUE when name1 is a wildcard spec that might match+ something name2 can match. We're conservative: we return FALSE+ only if the prefixes of name1 and name2 are different up to the+ first wildcard character. */++static bfd_boolean+wild_spec_can_overlap (const char *name1, const char *name2)+{+ size_t prefix1_len = strcspn (name1, "?*[");+ size_t prefix2_len = strcspn (name2, "?*[");+ size_t min_prefix_len;++ /* Note that if there is no wildcard character, then we treat the+ terminating 0 as part of the prefix. Thus ".text" won't match+ ".text." or ".text.*", for example. */+ if (name1[prefix1_len] == '\0')+ prefix1_len++;+ if (name2[prefix2_len] == '\0')+ prefix2_len++;++ min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;++ return memcmp (name1, name2, min_prefix_len) == 0;+}++/* Select specialized code to handle various kinds of wildcard+ statements. */++static void+analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)+{+ int sec_count = 0;+ int wild_name_count = 0;+ struct wildcard_list *sec;+ int signature;+ int data_counter;++ ptr->walk_wild_section_handler = walk_wild_section_general;++ /* Count how many wildcard_specs there are, and how many of those+ actually use wildcards in the name. Also, bail out if any of the+ wildcard names are NULL. (Can this actually happen?+ walk_wild_section used to test for it.) And bail out if any+ of the wildcards are more complex than a simple string+ ending in a single '*'. */+ for (sec = ptr->section_list; sec != NULL; sec = sec->next)+ {+ ++sec_count;+ if (sec->spec.name == NULL)+ return;+ if (wildcardp (sec->spec.name))+ {+ ++wild_name_count;+ if (!is_simple_wild (sec->spec.name))+ return;+ }+ }++ /* The zero-spec case would be easy to optimize but it doesn't+ happen in practice. Likewise, more than 4 specs doesn't+ happen in practice. */+ if (sec_count == 0 || sec_count > 4)+ return;++ /* Check that no two specs can match the same section. */+ for (sec = ptr->section_list; sec != NULL; sec = sec->next)+ {+ struct wildcard_list *sec2;+ for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)+ {+ if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))+ return;+ }+ }++ signature = (sec_count << 8) + wild_name_count;+ switch (signature)+ {+ case 0x0100:+ ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;+ break;+ case 0x0101:+ ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;+ break;+ case 0x0201:+ ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;+ break;+ case 0x0302:+ ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;+ break;+ case 0x0402:+ ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;+ break;+ default:+ return;+ }++ /* Now fill the data array with pointers to the specs, first the+ specs with non-wildcard names, then the specs with wildcard+ names. It's OK to process the specs in different order from the+ given order, because we've already determined that no section+ will match more than one spec. */+ data_counter = 0;+ for (sec = ptr->section_list; sec != NULL; sec = sec->next)+ if (!wildcardp (sec->spec.name))+ ptr->handler_data[data_counter++] = sec;+ for (sec = ptr->section_list; sec != NULL; sec = sec->next)+ if (wildcardp (sec->spec.name))+ ptr->handler_data[data_counter++] = sec;+}+ /* Handle a wild statement for a single file F. */ static void@@ -1175,17 +1559,12 @@ static void init_os (lang_output_section_statement_type *s) {- lean_section_userdata_type *new;- if (s->bfd_section != NULL) return; if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME); - new = stat_alloc (SECTION_USERDATA_SIZE);- memset (new, 0, SECTION_USERDATA_SIZE);- s->bfd_section = bfd_get_section_by_name (output_bfd, s->name); if (s->bfd_section == NULL) s->bfd_section = bfd_make_section (output_bfd, s->name);@@ -1199,7 +1578,14 @@ /* We initialize an output sections output offset to minus its own vma to allow us to output a section through itself. */ s->bfd_section->output_offset = 0;- get_userdata (s->bfd_section) = new;+ if (!command_line.reduce_memory_overheads)+ {+ fat_section_userdata_type *new+ = stat_alloc (sizeof (fat_section_userdata_type));+ memset (new, 0, sizeof (fat_section_userdata_type));+ get_userdata (s->bfd_section) = new;+ }+ /* If there is a base address, make sure that any sections it might mention are initialized. */@@ -4939,6 +5325,7 @@ new->section_list = section_list; new->keep_sections = keep_sections; lang_list_init (&new->children);+ analyze_walk_wild_section_handler (new); } voidIndex: src/ld/ldlang.h===================================================================RCS file: /cvs/src/src/ld/ldlang.h,vretrieving revision 1.44retrieving revision 1.45diff -u -r1.44 -r1.45--- binutils/ld/ldlang.h.old 3 Mar 2005 11:51:58 -0000 1.44+++ binutils/ld/ldlang.h 6 Apr 2005 15:33:03 -0000 1.45@@ -298,7 +298,17 @@ union lang_statement_union *file; } lang_afile_asection_pair_statement_type; -typedef struct lang_wild_statement_struct+typedef struct lang_wild_statement_struct lang_wild_statement_type;++typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,+ asection *, lang_input_statement_type *, void *);++typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,+ lang_input_statement_type *,+ callback_t callback,+ void *data);++struct lang_wild_statement_struct { lang_statement_header_type header; const char *filename;@@ -306,7 +316,10 @@ struct wildcard_list *section_list; bfd_boolean keep_sections; lang_statement_list_type children;-} lang_wild_statement_type;++ walk_wild_section_handler_t walk_wild_section_handler;+ struct wildcard_list *handler_data[4];+}; typedef struct lang_address_statement_struct {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -