diff options
author | Danny Smith <dannysmith@users.sourceforge.net> | 2006-01-31 22:08:14 +0000 |
---|---|---|
committer | Danny Smith <dannysmith@users.sourceforge.net> | 2006-01-31 22:08:14 +0000 |
commit | a8d701fd09ed1ce8afaf1a5892f3b37c078a6864 (patch) | |
tree | d12c757aed1e6d70b8ec87a05a71ea2a1f8471a5 /ld/pe-dll.c | |
parent | e7da6241844b3fd313859e6128bf5bddd3e22502 (diff) | |
download | gdb-a8d701fd09ed1ce8afaf1a5892f3b37c078a6864.zip gdb-a8d701fd09ed1ce8afaf1a5892f3b37c078a6864.tar.gz gdb-a8d701fd09ed1ce8afaf1a5892f3b37c078a6864.tar.bz2 |
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.
Diffstat (limited to 'ld/pe-dll.c')
-rw-r--r-- | ld/pe-dll.c | 79 |
1 files changed, 63 insertions, 16 deletions
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) { |