OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gold/] [testsuite/] [relro_test.cc] - Blame information for rev 373

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
// relro_test.cc -- test -z relro for gold
2
 
3
// Copyright 2008 Free Software Foundation, Inc.
4
// Written by Ian Lance Taylor <iant@google.com>.
5
 
6
// This file is part of gold.
7
 
8
// This program is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 3 of the License, or
11
// (at your option) any later version.
12
 
13
// This program is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
 
18
// You should have received a copy of the GNU General Public License
19
// along with this program; if not, write to the Free Software
20
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
// MA 02110-1301, USA.
22
 
23
#include <cassert>
24
#include <csignal>
25
#include <cstdio>
26
#include <cstdlib>
27
#include <exception>
28
#include <stdint.h>
29
#include <unistd.h>
30
 
31
// This tests we were linked with a script.  If we were linked with a
32
// script, relro currently does not work.
33
 
34
extern char using_script[] __attribute__ ((weak));
35
 
36
// This code is put into a shared library linked with -z relro.
37
 
38
// i1 and i2 are not relro variables.
39
int i1 = 1;
40
static int i2 = 2;
41
 
42
// P1 is a global relro variable.
43
int* const p1 = &i1;
44
 
45
// P2 is a local relro variable.
46
int* const p2 = &i2;
47
 
48
// Test symbol addresses.
49
 
50
bool
51
t1()
52
{
53
  if (using_script)
54
    return true;
55
 
56
  void* i1addr = static_cast<void*>(&i1);
57
  void* i2addr = static_cast<void*>(&i2);
58
  const void* p1addr = static_cast<const void*>(&p1);
59
  const void* p2addr = static_cast<const void*>(&p2);
60
 
61
  // The relro variables should precede the non-relro variables in the
62
  // memory image.
63
  assert(i1addr > p1addr);
64
  assert(i1addr > p2addr);
65
  assert(i2addr > p1addr);
66
  assert(i2addr > p2addr);
67
 
68
  // The relro variables should not be on the same page as the
69
  // non-relro variables.
70
  const size_t page_size = getpagesize();
71
  uintptr_t i1page = reinterpret_cast<uintptr_t>(i1addr) & ~ (page_size - 1);
72
  uintptr_t i2page = reinterpret_cast<uintptr_t>(i2addr) & ~ (page_size - 1);
73
  uintptr_t p1page = reinterpret_cast<uintptr_t>(p1addr) & ~ (page_size - 1);
74
  uintptr_t p2page = reinterpret_cast<uintptr_t>(p2addr) & ~ (page_size - 1);
75
  assert(i1page != p1page);
76
  assert(i1page != p2page);
77
  assert(i2page != p1page);
78
  assert(i2page != p2page);
79
 
80
  return true;
81
}
82
 
83
// Tell terminate handler that we are throwing from a signal handler.
84
 
85
static bool throwing;
86
 
87
// A signal handler for SIGSEGV.
88
 
89
extern "C"
90
void
91
sigsegv_handler(int)
92
{
93
  throwing = true;
94
  throw 0;
95
}
96
 
97
// The original terminate handler.
98
 
99
std::terminate_handler orig_terminate;
100
 
101
// Throwing an exception out of a signal handler doesn't always work
102
// reliably.  When that happens the program will call terminate.  We
103
// set a terminate handler to indicate that the test probably passed.
104
 
105
void
106
terminate_handler()
107
{
108
  if (!throwing)
109
    {
110
      orig_terminate();
111
      ::exit(EXIT_FAILURE);
112
    }
113
  fprintf(stderr,
114
          "relro_test: terminate called due to failure to throw through signal handler\n");
115
  fprintf(stderr, "relro_test: assuming test succeeded\n");
116
  ::exit(EXIT_SUCCESS);
117
}
118
 
119
// Use a separate function to throw the exception, so that we don't
120
// need to use -fnon-call-exceptions.
121
 
122
void f2() __attribute__ ((noinline));
123
void
124
f2()
125
{
126
  int** pp1 = const_cast<int**>(&p1);
127
  *pp1 = &i2;
128
 
129
  // We shouldn't get here--the assignment to *pp1 should write to
130
  // memory which the dynamic linker marked as read-only, giving us a
131
  // SIGSEGV, causing sigsegv_handler to be invoked, to throw past us.
132
  assert(0);
133
}
134
 
135
// Changing a relro variable should give us a SIGSEGV.
136
 
137
bool
138
t2()
139
{
140
  if (using_script)
141
    return true;
142
 
143
  signal(SIGSEGV, sigsegv_handler);
144
  orig_terminate = std::set_terminate(terminate_handler);
145
 
146
  try
147
    {
148
      f2();
149
      return false;
150
    }
151
  catch (int i)
152
    {
153
      assert(i == 0);
154
      return true;
155
    }
156
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.