x86-64: Test protected function pointers
[binutils-gdb.git] / ld / testplug.c
index 3be1ed4142d435c2089b045426fb37bd06b0c5b7..c1d7c22e6b4dd094f4b337d4bf9bdef0d66c0e0b 100644 (file)
@@ -1,5 +1,5 @@
 /* Test plugin for the GNU linker.
-   Copyright 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010-2021 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
 
 #include "sysdep.h"
 #include "bfd.h"
+#if BFD_SUPPORTS_PLUGINS
 #include "plugin-api.h"
 /* For ARRAY_SIZE macro only - we don't link the library itself.  */
 #include "libiberty.h"
 
+#include <ctype.h> /* For isdigit.  */
+
 extern enum ld_plugin_status onload (struct ld_plugin_tv *tv);
 static enum ld_plugin_status onclaim_file (const struct ld_plugin_input_file *file,
                                int *claimed);
@@ -38,7 +41,7 @@ typedef struct claim_file
 {
   struct claim_file *next;
   struct ld_plugin_input_file file;
-  bfd_boolean claimed;
+  bool claimed;
   struct ld_plugin_symbol *symbols;
   int n_syms_allocated;
   int n_syms_used;
@@ -87,6 +90,7 @@ static const tag_name_t tag_names[] =
   ADDENTRY(LDPT_ADD_INPUT_FILE),
   ADDENTRY(LDPT_MESSAGE),
   ADDENTRY(LDPT_GET_INPUT_FILE),
+  ADDENTRY(LDPT_GET_VIEW),
   ADDENTRY(LDPT_RELEASE_INPUT_FILE),
   ADDENTRY(LDPT_ADD_INPUT_LIBRARY),
   ADDENTRY(LDPT_OUTPUT_NAME),
@@ -104,6 +108,7 @@ static ld_plugin_get_symbols tv_get_symbols_v2 = 0;
 static ld_plugin_add_input_file tv_add_input_file = 0;
 static ld_plugin_message tv_message = 0;
 static ld_plugin_get_input_file tv_get_input_file = 0;
+static ld_plugin_get_view tv_get_view = 0;
 static ld_plugin_release_input_file tv_release_input_file = 0;
 static ld_plugin_add_input_library tv_add_input_library = 0;
 static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0;
@@ -117,10 +122,10 @@ static enum ld_plugin_status onload_ret = LDPS_OK;
 static enum ld_plugin_status claim_file_ret = LDPS_OK;
 static enum ld_plugin_status all_symbols_read_ret = LDPS_OK;
 static enum ld_plugin_status cleanup_ret = LDPS_OK;
-static bfd_boolean register_claimfile_hook = FALSE;
-static bfd_boolean register_allsymbolsread_hook = FALSE;
-static bfd_boolean register_cleanup_hook = FALSE;
-static bfd_boolean dumpresolutions = FALSE;
+static bool register_claimfile_hook = false;
+static bool register_allsymbolsread_hook = false;
+static bool register_cleanup_hook = false;
+static bool dumpresolutions = false;
 
 /* The master list of all claimable/claimed files.  */
 static claim_file_t *claimfiles_list = NULL;
@@ -137,6 +142,10 @@ static add_file_t *addfiles_list = NULL;
 /* We keep a tail pointer for easy linking on the end.  */
 static add_file_t **addfiles_tail_chain_ptr = &addfiles_list;
 
+/* Number of bytes read in claim file before deciding if the file can be
+   claimed.  */
+static int bytes_to_read_before_claim = 0;
+
 /* Add a new claimfile on the end of the chain.  */
 static enum ld_plugin_status
 record_claim_file (const char *file)
@@ -157,6 +166,22 @@ record_claim_file (const char *file)
   return LDPS_OK;
 }
 
+/* How many bytes to read before claiming (or not) an input file.  */
+static enum ld_plugin_status
+record_read_length (const char *length)
+{
+  const char *tmp;
+
+  tmp = length;
+  while (*tmp != '\0' && isdigit (*tmp))
+    ++tmp;
+  if (*tmp != '\0' || *length == '\0')
+    return LDPS_ERR;
+
+  bytes_to_read_before_claim = atoi (length);
+  return LDPS_OK;
+}
+
 /* Add a new addfile on the end of the chain.  */
 static enum ld_plugin_status
 record_add_file (const char *file, addfile_enum_t type)
@@ -168,7 +193,7 @@ record_add_file (const char *file, addfile_enum_t type)
     return LDPS_ERR;
   newfile->next = NULL;
   newfile->name = file;
-  newfile->type = type;;
+  newfile->type = type;
   /* Chain it on the end of the list.  */
   *addfiles_tail_chain_ptr = newfile;
   addfiles_tail_chain_ptr = &newfile->next;
@@ -212,12 +237,15 @@ parse_symdefstr (const char *str, struct ld_plugin_symbol *sym)
   /* Finally we'll use sscanf to parse the numeric fields, then
      we'll split out the strings which we need to allocate separate
      storage for anyway so that we can add nul termination.  */
-  n = sscanf (colon2 + 1, "%i:%i:%lli", &sym->def, &sym->visibility, &size);
+  n = sscanf (colon2 + 1, "%hhi:%i:%lli", &sym->def, &sym->visibility, &size);
   if (n != 3)
     return LDPS_ERR;
 
   /* Parsed successfully, so allocate strings and fill out fields.  */
   sym->size = size;
+  sym->unused = 0;
+  sym->section_kind = 0;
+  sym->symbol_type = 0;
   sym->resolution = LDPR_UNKNOWN;
   sym->name = malloc (colon1 - str + 1);
   if (!sym->name)
@@ -296,7 +324,7 @@ set_ret_val (const char *whichval, enum ld_plugin_status retval)
 
 /* Records hooks which should be registered.  */
 static enum ld_plugin_status
-set_register_hook (const char *whichhook, bfd_boolean yesno)
+set_register_hook (const char *whichhook, bool yesno)
 {
   if (!strcmp ("claimfile", whichhook))
     register_claimfile_hook = yesno;
@@ -318,11 +346,13 @@ parse_option (const char *opt)
   else if (!strncmp ("pass", opt, 4))
     return set_ret_val (opt + 4, LDPS_OK);
   else if (!strncmp ("register", opt, 8))
-    return set_register_hook (opt + 8, TRUE);
+    return set_register_hook (opt + 8, true);
   else if (!strncmp ("noregister", opt, 10))
-    return set_register_hook (opt + 10, FALSE);
+    return set_register_hook (opt + 10, false);
   else if (!strncmp ("claim:", opt, 6))
     return record_claim_file (opt + 6);
+  else if (!strncmp ("read:", opt, 5))
+    return record_read_length (opt + 5);
   else if (!strncmp ("sym:", opt, 4))
     return record_claimed_file_symbol (opt + 4);
   else if (!strncmp ("add:", opt, 4))
@@ -332,7 +362,7 @@ parse_option (const char *opt)
   else if (!strncmp ("dir:", opt, 4))
     return record_add_file (opt + 4, ADD_DIR);
   else if (!strcmp ("dumpresolutions", opt))
-    dumpresolutions = TRUE;
+    dumpresolutions = true;
   else
     return LDPS_ERR;
   return LDPS_OK;
@@ -367,6 +397,7 @@ dump_tv_tag (size_t n, struct ld_plugin_tv *tv)
       case LDPT_ADD_INPUT_FILE:
       case LDPT_MESSAGE:
       case LDPT_GET_INPUT_FILE:
+      case LDPT_GET_VIEW:
       case LDPT_RELEASE_INPUT_FILE:
       case LDPT_ADD_INPUT_LIBRARY:
       case LDPT_SET_EXTRA_LIBRARY_PATH:
@@ -433,6 +464,9 @@ parse_tv_tag (struct ld_plugin_tv *tv)
       case LDPT_GET_INPUT_FILE:
        SETVAR(tv_get_input_file);
        break;
+      case LDPT_GET_VIEW:
+       SETVAR(tv_get_view);
+       break;
       case LDPT_RELEASE_INPUT_FILE:
        SETVAR(tv_release_input_file);
        break;
@@ -521,6 +555,20 @@ onload (struct ld_plugin_tv *tv)
 static enum ld_plugin_status
 onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
 {
+  /* Possible read of some bytes out of the input file into a buffer.  This
+     simulates a plugin that reads some file content in order to decide if
+     the file should be claimed or not.  */
+  if (bytes_to_read_before_claim > 0)
+    {
+      char *buffer = malloc (bytes_to_read_before_claim);
+
+      if (buffer == NULL)
+        return LDPS_ERR;
+      if (read (file->fd, buffer, bytes_to_read_before_claim) < 0)
+        return LDPS_ERR;
+      free (buffer);
+    }
+
   /* Let's see if we want to claim this file.  */
   claim_file_t *claimfile = claimfiles_list;
   while (claimfile)
@@ -541,7 +589,7 @@ onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
   *claimed = (claimfile != 0);
   if (claimfile)
     {
-      claimfile->claimed = TRUE;
+      claimfile->claimed = true;
       claimfile->file = *file;
       if (claimfile->n_syms_used && !tv_add_symbols)
        return LDPS_ERR;
@@ -619,3 +667,4 @@ oncleanup (void)
   fflush (NULL);
   return cleanup_ret;
 }
+#endif /* BFD_SUPPORTS_PLUGINS */