diff options
Diffstat (limited to 'contrib/binutils/ld/pe-dll.c')
-rw-r--r-- | contrib/binutils/ld/pe-dll.c | 105 |
1 files changed, 63 insertions, 42 deletions
diff --git a/contrib/binutils/ld/pe-dll.c b/contrib/binutils/ld/pe-dll.c index 945564c..fd70c78 100644 --- a/contrib/binutils/ld/pe-dll.c +++ b/contrib/binutils/ld/pe-dll.c @@ -1,5 +1,5 @@ /* Routines to help build PEI-format DLLs (Win32 etc) - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by DJ Delorie <dj@cygnus.com> This file is part of GLD, the Gnu Linker. @@ -47,7 +47,7 @@ at the end of this file. This function is not re-entrant and is normally only called once, so static variables are used to reduce the number of parameters and return values required. - + See also: ld/emultempl/pe.em. */ /* Auto-import feature by Paul Sokolovsky @@ -231,6 +231,9 @@ static autofilter_entry_type autofilter_liblist[] = { "libgcc.", 7 }, { "libstdc++.", 10 }, { "libmingw32.", 11 }, + { "libg2c.", 7 }, + { "libsupc++.", 10 }, + { "libobjc.", 8 }, { NULL, 0 } }; @@ -243,7 +246,9 @@ static autofilter_entry_type autofilter_objlist[] = { "dllcrt2.o", 9 }, { "gcrt0.o", 7 }, { "gcrt1.o", 7 }, - { "gcrt2.o", 7 }, + { "gcrt2.o", 7 }, + { "crtbegin.o", 10 }, + { "crtend.o", 8 }, { NULL, 0 } }; @@ -317,7 +322,7 @@ pe_dll_id_target (target) exit (1); } -/* Helper functions for qsort. Relocs must be sorted so that we can write +/* Helper functions for qsort. Relocs must be sorted so that we can write them out by pages. */ typedef struct @@ -368,14 +373,16 @@ typedef struct exclude_list_struct { char *string; struct exclude_list_struct *next; + int type; } exclude_list_struct; static struct exclude_list_struct *excludes = 0; void -pe_dll_add_excludes (new_excludes) +pe_dll_add_excludes (new_excludes, type) const char *new_excludes; + const int type; { char *local_copy; char *exclude_string; @@ -391,6 +398,7 @@ pe_dll_add_excludes (new_excludes) xmalloc (sizeof (struct exclude_list_struct))); new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 1); strcpy (new_exclude->string, exclude_string); + new_exclude->type = type; new_exclude->next = excludes; excludes = new_exclude; } @@ -398,6 +406,7 @@ pe_dll_add_excludes (new_excludes) free (local_copy); } + /* abfd is a bfd containing n (or NULL) It can be used for contextual checks. */ @@ -410,6 +419,9 @@ auto_export (abfd, d, n) int i; struct exclude_list_struct *ex; autofilter_entry_type *afptr; + const char * libname = 0; + if (abfd && abfd->my_archive) + libname = lbasename (abfd->my_archive->filename); /* We should not re-export imported stuff. */ if (strncmp (n, "_imp__", 6) == 0) @@ -429,14 +441,14 @@ auto_export (abfd, d, n) n, abfd, abfd->my_archive); /* First of all, make context checks: - Don't export anything from libgcc. */ - if (abfd && abfd->my_archive) + Don't export anything from standard libs. */ + if (libname) { afptr = autofilter_liblist; while (afptr->name) { - if (strstr (abfd->my_archive->filename, afptr->name)) + if (strncmp (libname, afptr->name, afptr->len) == 0 ) return 0; afptr++; } @@ -446,11 +458,11 @@ auto_export (abfd, d, n) if (abfd && (p = lbasename (abfd->filename))) { - afptr = autofilter_objlist; - while (afptr->name) + afptr = autofilter_objlist; + while (afptr->name) { - if ( strcmp (p, afptr->name) == 0 ) - return 0; + if (strcmp (p, afptr->name) == 0) + return 0; afptr++; } } @@ -466,7 +478,7 @@ auto_export (abfd, d, n) if (strcmp (n, afptr->name) == 0) return 0; - afptr ++; + afptr++; } /* Next, exclude symbols starting with ... */ @@ -476,7 +488,7 @@ auto_export (abfd, d, n) if (strncmp (n, afptr->name, afptr->len) == 0) return 0; - afptr ++; + afptr++; } /* Finally, exclude symbols ending with ... */ @@ -484,19 +496,28 @@ auto_export (abfd, d, n) afptr = autofilter_symbolsuffixlist; while (afptr->name) { - if ((len >= afptr->len) && + if ((len >= afptr->len) /* Add 1 to insure match with trailing '\0'. */ - strncmp (n + len - afptr->len, afptr->name, - afptr->len + 1) == 0) + && strncmp (n + len - afptr->len, afptr->name, + afptr->len + 1) == 0) return 0; - afptr ++; + afptr++; } } for (ex = excludes; ex; ex = ex->next) - if (strcmp (n, ex->string) == 0) - return 0; + { + if (ex->type == 1) /* exclude-libs */ + { + if (libname + && ((strcmp (libname, ex->string) == 0) + || (strcasecmp ("ALL", ex->string) == 0))) + return 0; + } + else if (strcmp (n, ex->string) == 0) + return 0; + } return 1; } @@ -560,10 +581,10 @@ process_def_file (abfd, info) sprintf (name, "%s%s", U("_imp_"), sn); blhe = bfd_link_hash_lookup (info->hash, name, - false, false, false); + false, false, false); free (name); - if (blhe && blhe->type == bfd_link_hash_defined) + if (blhe && blhe->type == bfd_link_hash_defined) continue; } @@ -863,7 +884,7 @@ generate_edata (abfd, info) if (pe_def_file->exports[i].ordinal == -1) { while (exported_symbols[next_ordinal - min_ordinal] != -1) - next_ordinal ++; + next_ordinal++; exported_symbols[next_ordinal - min_ordinal] = i; pe_def_file->exports[i].ordinal = next_ordinal; @@ -1112,9 +1133,9 @@ generate_reloc (abfd, info) for (i = 0; i < nrelocs; i++) { if (pe_dll_extra_pe_debug) - { + { struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr; - printf("rel: %s\n",sym->name); + printf ("rel: %s\n", sym->name); } if (!relocs[i]->howto->pc_relative && relocs[i]->howto->type != pe_details->imagebase_reloc) @@ -1193,7 +1214,7 @@ generate_reloc (abfd, info) if (reloc_data[i].type == 4) reloc_sz += 2; } - + reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */ reloc_d = (unsigned char *) xmalloc (reloc_sz); sec_page = (unsigned long) (-1); @@ -1551,11 +1572,11 @@ save_relocs (asection *sec) .long 0 .rva __my_dll_iname .rva fthunk - + .section .idata$5 .long 0 fthunk: - + .section .idata$4 .long 0 hname: */ @@ -1695,10 +1716,10 @@ make_tail (parent) .global __imp__function _function: jmp *__imp__function: - + .section idata$7 .long __head_my_dll - + .section .idata$5 ___imp_function: __imp__function: @@ -1949,9 +1970,9 @@ make_import_fixup_mark (rel) static int counter; static char *fixup_name = NULL; static size_t buffer_len = 0; - + struct symbol_cache_entry *sym = *rel->sym_ptr_ptr; - + bfd *abfd = bfd_asymbol_bfd (sym); struct coff_link_hash_entry *myh = NULL; @@ -1962,7 +1983,7 @@ make_import_fixup_mark (rel) } if (strlen (sym->name) + 25 > buffer_len) - /* Assume 25 chars for "__fu" + counter + "_". If counter is + /* Assume 25 chars for "__fu" + counter + "_". If counter is bigger than 20 digits long, we've got worse problems than overflowing this buffer... */ { @@ -1972,17 +1993,17 @@ make_import_fixup_mark (rel) buffer_len = ((strlen (sym->name) + 25) + 127) & ~127; fixup_name = (char *) xmalloc (buffer_len); } - + sprintf (fixup_name, "__fu%d_%s", counter++, sym->name); - bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL, + bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL, current_sec, /* sym->section, */ rel->address, NULL, true, false, (struct bfd_link_hash_entry **) &myh); #if 0 - printf ("type:%d\n", myh->type); - printf ("%s\n", myh->root.u.def.section->name); + printf ("type:%d\n", myh->type); + printf ("%s\n", myh->root.u.def.section->name); #endif return fixup_name; } @@ -1995,7 +2016,7 @@ make_import_fixup_mark (rel) .rva __fuNN_SYM (pointer to reference (address) in text) */ static bfd * -make_import_fixup_entry (name, fixup_name, dll_symname,parent) +make_import_fixup_entry (name, fixup_name, dll_symname, parent) const char *name; const char *fixup_name; const char *dll_symname; @@ -2021,8 +2042,8 @@ make_import_fixup_entry (name, fixup_name, dll_symname,parent) symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *)); id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2); -#if 0 - quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0); +#if 0 + quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0); #endif quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0); @@ -2437,7 +2458,7 @@ pe_dll_fill_sections (abfd, info) /* Do the assignments again. */ lang_do_assignments (stat_ptr->head, abs_output_section, - (fill_type) 0, (bfd_vma) 0); + (fill_type *) 0, (bfd_vma) 0); } fill_edata (abfd, info); @@ -2471,7 +2492,7 @@ pe_exe_fill_sections (abfd, info) /* Do the assignments again. */ lang_do_assignments (stat_ptr->head, abs_output_section, - (fill_type) 0, (bfd_vma) 0); + (fill_type *) 0, (bfd_vma) 0); } reloc_s->contents = reloc_d; } |