summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/deffile.h2
-rw-r--r--ld/pe-dll.c79
3 files changed, 74 insertions, 17 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a139b187c8..e5e53559b6 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 699f190f38..6db8bf79d0 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 a11f9e171a..d4d42e4d36 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)
{