Blame elf/vismain.c

Packit 6c4009
/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* This file must be compiled as PIE to avoid copy relocation when
Packit 6c4009
   accessing protected symbols defined in shared libaries since copy
Packit 6c4009
   relocation doesn't work with protected symbols and linker in
Packit 6c4009
   binutils 2.26 enforces this rule.  */
Packit 6c4009
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
Packit 6c4009
#include "vismod.h"
Packit 6c4009
Packit 6c4009
/* Prototype for our test function.  */
Packit 6c4009
extern int do_test (void);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* This defines the `main' function and some more.  */
Packit 6c4009
#include <support/test-driver.c>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Prototypes for local functions.  */
Packit 6c4009
extern int protlocal (void);
Packit 6c4009
Packit 6c4009
const char *protvarlocal = __FILE__;
Packit 6c4009
extern const char *protvarinmod;
Packit 6c4009
extern const char *protvaritcpt;
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
do_test (void)
Packit 6c4009
{
Packit 6c4009
  int res = 0;
Packit 6c4009
  int val;
Packit 6c4009
Packit 6c4009
  /* First test: check whether .protected is handled correctly by the
Packit 6c4009
     assembler/linker.  The uses of `protlocal' in the DSOs and in the
Packit 6c4009
     main program should all be resolved with the local definitions.  */
Packit 6c4009
  val = protlocal () + calllocal1 () + calllocal2 ();
Packit 6c4009
  if (val != 0x155)
Packit 6c4009
    {
Packit 6c4009
      puts ("\
Packit 6c4009
The handling of `.protected' seems to be implemented incorrectly: giving up");
Packit 6c4009
      abort ();
Packit 6c4009
    }
Packit 6c4009
  puts ("`.protected' seems to be handled correctly, good!");
Packit 6c4009
Packit 6c4009
  /* Function pointers: for functions which are marked local and for
Packit 6c4009
     which definitions are available all function pointers must be
Packit 6c4009
     distinct.  */
Packit 6c4009
  if (protlocal == getlocal1 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protlocal' in main and mod1 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (protlocal == getlocal2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protlocal' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getlocal1 () == getlocal2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protlocal' in mod1 and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getlocal1 () () + getlocal2 () () != 0x44)
Packit 6c4009
    {
Packit 6c4009
      puts ("pointers to `protlocal' in mod1 or mod2 incorrect");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Next test.  This is similar to the last one but the function we
Packit 6c4009
     are calling is not defined in the main object.  This means that
Packit 6c4009
     the invocation in the main object uses the definition in the
Packit 6c4009
     first DSO.  */
Packit 6c4009
  if (protinmod != getinmod1 ())
Packit 6c4009
    {
Packit 6c4009
      printf ("&protinmod in main (%p) != &protinmod in mod1 (%p)\n",
Packit 6c4009
	      protinmod, getinmod1 ());
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (protinmod == getinmod2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protinmod' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getinmod1 () == getinmod2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protinmod' in mod1 and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (protinmod () + getinmod1 () () + getinmod2 () () != 0x4800)
Packit 6c4009
    {
Packit 6c4009
      puts ("pointers to `protinmod' in mod1 or mod2 incorrect");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  val = protinmod () + callinmod1 () + callinmod2 ();
Packit 6c4009
  if (val != 0x15800)
Packit 6c4009
    {
Packit 6c4009
      printf ("calling of `protinmod' leads to wrong result (%#x)\n", val);
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* A very similar text.  Same setup for the main object and the modules
Packit 6c4009
     but this time we have another definition in a preloaded module. This
Packit 6c4009
     one intercepts the references from the main object.  */
Packit 6c4009
  if (protitcpt != getitcpt3 ())
Packit 6c4009
    {
Packit 6c4009
      printf ("&protitcpt in main (%p) != &protitcpt in mod3 (%p)\n",
Packit 6c4009
	      &protitcpt, getitcpt3 ());
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (protitcpt == getitcpt1 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protitcpt' in main and mod1 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (protitcpt == getitcpt2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protitcpt' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getitcpt1 () == getitcpt2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protitcpt' in mod1 and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  val = protitcpt () + getitcpt1 () () + getitcpt2 () () + getitcpt3 () ();
Packit 6c4009
  if (val != 0x8440000)
Packit 6c4009
    {
Packit 6c4009
      printf ("\
Packit 6c4009
pointers to `protitcpt' in mod1 or mod2 or mod3 incorrect (%#x)\n", val);
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  val = protitcpt () + callitcpt1 () + callitcpt2 () + callitcpt3 ();
Packit 6c4009
  if (val != 0x19540000)
Packit 6c4009
    {
Packit 6c4009
      printf ("calling of `protitcpt' leads to wrong result (%#x)\n", val);
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Now look at variables.  First a variable which is available
Packit 6c4009
     everywhere.  We must have three different addresses.  */
Packit 6c4009
  if (&protvarlocal == getvarlocal1 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvarlocal' in main and mod1 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (&protvarlocal == getvarlocal2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvarlocal' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getvarlocal1 () == getvarlocal2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvarlocal' in mod1 and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (protvarlocal, __FILE__) != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvarlocal in main has wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvarlocal1 (), "vismod1.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvarlocal1' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvarlocal2 (), "vismod2.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvarlocal2' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Now the case where there is no local definition.  */
Packit 6c4009
  if (&protvarinmod != getvarinmod1 ())
Packit 6c4009
    {
Packit 6c4009
      printf ("&protvarinmod in main (%p) != &protitcpt in mod1 (%p)\n",
Packit 6c4009
	      &protvarinmod, getvarinmod1 ());
Packit 6c4009
      // XXX Possibly enable once fixed.
Packit 6c4009
      // res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (&protvarinmod == getvarinmod2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvarinmod' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvarinmod1 (), "vismod1.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvarinmod1' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvarinmod2 (), "vismod2.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvarinmod2' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* And a test where a variable definition is intercepted.  */
Packit 6c4009
  if (&protvaritcpt == getvaritcpt1 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvaritcpt' in main and mod1 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (&protvaritcpt == getvaritcpt2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvaritcpt' in main and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (&protvaritcpt != getvaritcpt3 ())
Packit 6c4009
    {
Packit 6c4009
      printf ("&protvaritcpt in main (%p) != &protvaritcpt in mod3 (%p)\n",
Packit 6c4009
	      &protvaritcpt, getvaritcpt3 ());
Packit 6c4009
      // XXX Possibly enable once fixed.
Packit 6c4009
      // res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (getvaritcpt1 () == getvaritcpt2 ())
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvaritcpt' in mod1 and mod2 have same address");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (protvaritcpt, "vismod3.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`protvaritcpt in main has wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvaritcpt1 (), "vismod1.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvaritcpt1' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
  if (strcmp (*getvaritcpt2 (), "vismod2.c") != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("`getvaritcpt2' returns wrong value");
Packit 6c4009
      res = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return res;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
protlocal (void)
Packit 6c4009
{
Packit 6c4009
  return 0x1;
Packit 6c4009
}