powerpc TLS in PIEs
[deliverable/binutils-gdb.git] / bfd / peicode.h
index a33e71bebef584df0fe362060d670c483b2a2ebb..e5cacbd2c106fbe7fc28340268479f905a9fccab 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright (C) 1995-2016 Free Software Foundation, Inc.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -771,11 +771,13 @@ pe_ILF_build_a_bfd (bfd *           abfd,
 
     case IMPORT_CONST:
       /* XXX code yet to be written.  */
+      /* xgettext:c-format */
       _bfd_error_handler (_("%B: Unhandled import type; %x"),
                          abfd, import_type);
       return FALSE;
 
     default:
+      /* xgettext:c-format */
       _bfd_error_handler (_("%B: Unrecognised import type; %x"),
                          abfd, import_type);
       return FALSE;
@@ -790,6 +792,7 @@ pe_ILF_build_a_bfd (bfd *           abfd,
       break;
 
     default:
+      /* xgettext:c-format */
       _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
                          abfd, import_name_type);
       return FALSE;
@@ -889,8 +892,8 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   if (import_name_type == IMPORT_ORDINAL)
     {
       if (ordinal == 0)
-       /* XXX - treat as IMPORT_NAME ??? */
-       abort ();
+       /* See PR 20907 for a reproducer.  */
+       goto error_return;
 
 #ifdef COFF_WITH_pex64
       ((unsigned int *) id4->contents)[0] = ordinal;
@@ -1210,6 +1213,7 @@ pe_ILF_object_p (bfd * abfd)
       /* We no longer support PowerPC.  */
     default:
       _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B: Unrecognised machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
@@ -1222,6 +1226,7 @@ pe_ILF_object_p (bfd * abfd)
   if (magic == 0)
     {
       _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B: Recognised but unhandled machine type (0x%x)"
           " in Import Library Format archive"),
         abfd, machine);
@@ -1264,7 +1269,8 @@ pe_ILF_object_p (bfd * abfd)
     }
 
   symbol_name = (char *) ptr;
-  source_dll  = symbol_name + strlen (symbol_name) + 1;
+  /* See PR 20905 for an example of where the strnlen is necessary.  */
+  source_dll  = symbol_name + strnlen (symbol_name, size - 1) + 1;
 
   /* Verify that the strings are null terminated.  */
   if (ptr[size - 1] != 0
@@ -1289,7 +1295,7 @@ pe_ILF_object_p (bfd * abfd)
 }
 
 static void
-pe_bfd_read_buildid(bfd *abfd)
+pe_bfd_read_buildid (bfd *abfd)
 {
   pe_data_type *pe = pe_data (abfd);
   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
@@ -1297,7 +1303,6 @@ pe_bfd_read_buildid(bfd *abfd)
   bfd_byte *data = 0;
   bfd_size_type dataoff;
   unsigned int i;
-
   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
 
@@ -1306,7 +1311,7 @@ pe_bfd_read_buildid(bfd *abfd)
 
   addr += extra->ImageBase;
 
-  /* Search for the section containing the DebugDirectory */
+  /* Search for the section containing the DebugDirectory */
   for (section = abfd->sections; section != NULL; section = section->next)
     {
       if ((addr >= section->vma) && (addr < (section->vma + section->size)))
@@ -1314,16 +1319,24 @@ pe_bfd_read_buildid(bfd *abfd)
     }
 
   if (section == NULL)
-    {
-      return;
-    }
-  else if (!(section->flags & SEC_HAS_CONTENTS))
-    {
-      return;
-    }
+    return;
+
+  if (!(section->flags & SEC_HAS_CONTENTS))
+    return;
 
   dataoff = addr - section->vma;
 
+  /* PR 20605 and 22373: Make sure that the data is really there.
+     Note - since we are dealing with unsigned quantities we have
+     to be careful to check for potential overflows.  */
+  if (dataoff >= section->size
+      || size > section->size - dataoff)
+    {
+      _bfd_error_handler (_("%B: Error: Debug Data ends beyond end of debug directory."),
+                         abfd);
+      return;
+    }
+  
   /* Read the whole section. */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
@@ -1354,8 +1367,8 @@ pe_bfd_read_buildid(bfd *abfd)
                                               (file_ptr) idd.PointerToRawData,
                                               idd.SizeOfData, cvinfo))
             {
-              struct bfd_build_id* build_id = bfd_alloc(abfd,
-                         sizeof(struct bfd_build_id) + cvinfo->SignatureLength);
+              struct bfd_build_id* build_id = bfd_alloc (abfd,
+                         sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
               if (build_id)
                 {
                   build_id->size = cvinfo->SignatureLength;
This page took 0.025148 seconds and 4 git commands to generate.