diff options
-rw-r--r-- | ld/ChangeLog | 10 | ||||
-rw-r--r-- | ld/deffile.h | 2 | ||||
-rw-r--r-- | ld/pe-dll.c | 79 |
3 files changed, 74 insertions, 17 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index a139b18..e5e5355 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2006-01-31 Filip Navara <navaraf@reactos.com> + + * deffile.h (struct def_file_export): Add field flag_forward. + * pe-dll.c (process_def_file): Check for forward exports. + (generate_edata): Generate forward export symbols. + (fill_edata): Emit them. + + * pe-dll.c (process_def_file): Don't crash on malformed + fastcall symbol names in .def file. + 2006-01-30 Nick Clifton <nickc@redhat.com> * po/vi.po: Updated Vietnamese translation. diff --git a/ld/deffile.h b/ld/deffile.h index 699f190..6db8bf7 100644 --- a/ld/deffile.h +++ b/ld/deffile.h @@ -36,7 +36,7 @@ typedef struct def_file_export { char *internal_name; /* always set, may == name */ int ordinal; /* -1 if not specified */ int hint; - char flag_private, flag_constant, flag_noname, flag_data; + char flag_private, flag_constant, flag_noname, flag_data, flag_forward; } def_file_export; typedef struct def_file_module { diff --git a/ld/pe-dll.c b/ld/pe-dll.c index a11f9e1..d4d42e4 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -596,8 +596,13 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) have. */ int lead_at = (*pe_def_file->exports[i].name == '@'); char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at); + char *tmp_at = strchr (tmp, '@'); - *(strchr (tmp, '@')) = 0; + if (tmp_at) + *tmp_at = 0; + else + einfo (_("%XCannot export %s: invalid export name\n"), + pe_def_file->exports[i].name); pe_def_file->exports[i].name = tmp; } } @@ -680,6 +685,27 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) { char *name; + /* Check for forward exports */ + if (strchr (pe_def_file->exports[i].internal_name, '.')) + { + count_exported++; + if (!pe_def_file->exports[i].flag_noname) + count_exported_byname++; + + pe_def_file->exports[i].flag_forward = 1; + + if (pe_def_file->exports[i].ordinal != -1) + { + if (max_ordinal < pe_def_file->exports[i].ordinal) + max_ordinal = pe_def_file->exports[i].ordinal; + if (min_ordinal > pe_def_file->exports[i].ordinal) + min_ordinal = pe_def_file->exports[i].ordinal; + count_with_ordinals++; + } + + continue; + } + name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2); if (pe_details->underscored && (*pe_def_file->exports[i].internal_name != '@')) @@ -837,7 +863,8 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) /* Now we need to assign ordinals to those that don't have them. */ for (i = 0; i < NE; i++) { - if (exported_symbol_sections[i]) + if (exported_symbol_sections[i] || + pe_def_file->exports[i].flag_forward) { if (pe_def_file->exports[i].ordinal != -1) { @@ -856,19 +883,26 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) } name_table_size += strlen (pe_def_file->exports[i].name) + 1; } + + /* Reserve space for the forward name. */ + if (pe_def_file->exports[i].flag_forward) + { + name_table_size += strlen (pe_def_file->exports[i].internal_name) + 1; + } } next_ordinal = min_ordinal; for (i = 0; i < NE; i++) - if (exported_symbol_sections[i]) - if (pe_def_file->exports[i].ordinal == -1) - { - while (exported_symbols[next_ordinal - min_ordinal] != -1) - next_ordinal++; + if ((exported_symbol_sections[i] || + pe_def_file->exports[i].flag_forward) && + pe_def_file->exports[i].ordinal == -1) + { + while (exported_symbols[next_ordinal - min_ordinal] != -1) + next_ordinal++; - exported_symbols[next_ordinal - min_ordinal] = i; - pe_def_file->exports[i].ordinal = next_ordinal; - } + exported_symbols[next_ordinal - min_ordinal] = i; + pe_def_file->exports[i].ordinal = next_ordinal; + } /* OK, now we can allocate some memory. */ edata_sz = (40 /* directory */ @@ -967,15 +1001,28 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) for (s = 0; s < NE; s++) { struct bfd_section *ssec = exported_symbol_sections[s]; - if (ssec && pe_def_file->exports[s].ordinal != -1) + if (pe_def_file->exports[s].ordinal != -1 && + (pe_def_file->exports[s].flag_forward || ssec != NULL)) { - unsigned long srva = (exported_symbol_offsets[s] - + ssec->output_section->vma - + ssec->output_offset); int ord = pe_def_file->exports[s].ordinal; - bfd_put_32 (abfd, srva - image_base, - eaddresses + 4 * (ord - min_ordinal)); + if (pe_def_file->exports[s].flag_forward) + { + bfd_put_32 (abfd, ERVA (enamestr), + eaddresses + 4 * (ord - min_ordinal)); + + strcpy (enamestr, pe_def_file->exports[s].internal_name); + enamestr += strlen (pe_def_file->exports[s].internal_name) + 1; + } + else + { + unsigned long srva = (exported_symbol_offsets[s] + + ssec->output_section->vma + + ssec->output_offset); + + bfd_put_32 (abfd, srva - image_base, + eaddresses + 4 * (ord - min_ordinal)); + } if (!pe_def_file->exports[s].flag_noname) { |