Fix segfault when .plt section does not exist
[binutils-gdb.git] / ld / pe-dll.c
index a2792e8f94919a39f33beade1063be8b9e1867f7..ac7c70ccf48d5c86159f4a3b9eacc79fcae1df8a 100644 (file)
@@ -1,5 +1,5 @@
 /* Routines to help build PEI-format DLLs (Win32 etc)
-   Copyright (C) 1998-2016 Free Software Foundation, Inc.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
    This file is part of the GNU Binutils.
     should run in parallel with addresses vector (FirstThunk), i.e. that they
     should have same number of elements and terminated with zero. We violate
     this, since FirstThunk points directly into machine code. But in practice,
-    OS loader implemented the sane way: it goes thru OriginalFirstThunk and
+    OS loader implemented the sane way: it goes through OriginalFirstThunk and
     puts addresses to FirstThunk, not something else. It once again should be
     noted that dll and symbol name structures are reused across fixup entries
     and should be there anyway to support standard import stuff, so sustained
@@ -897,11 +897,17 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
       char *int_name = pe_def_file->exports[i].internal_name;
       char *name;
 
+      /* PR 19803: Make sure that any exported symbol does not get garbage collected.  */
+      lang_add_gc_name (int_name);
+
       name = xmalloc (strlen (int_name) + 2);
       if (pe_details->underscored && int_name[0] != '@')
        {
          *name = '_';
          strcpy (name + 1, int_name);
+
+         /* PR 19803: The alias must be preserved as well.  */
+         lang_add_gc_name (xstrdup (name));
        }
       else
        strcpy (name, int_name);
@@ -2260,6 +2266,8 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
     }
   else
     {
+      int ord;
+
       /* { short, asciz }  */
       if (exp->its_name)
        len = 2 + strlen (exp->its_name) + 1;
@@ -2271,8 +2279,13 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
       d6 = xmalloc (len);
       id6->contents = d6;
       memset (d6, 0, len);
-      d6[0] = exp->hint & 0xff;
-      d6[1] = exp->hint >> 8;
+
+      /* PR 20880:  Use exp->hint as a backup, just in case exp->ordinal
+        contains an invalid value (-1).  */
+      ord = (exp->ordinal >= 0) ? exp->ordinal : exp->hint;
+      d6[0] = ord;
+      d6[1] = ord >> 8;
+
       if (exp->its_name)
        strcpy ((char*) d6 + 2, exp->its_name);
       else