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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [libmudflap/] [mf-heuristics.c] - Blame information for rev 481

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

Line No. Rev Author Line
1 38 julius
/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2
   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3
   Contributed by Frank Ch. Eigler <fche@redhat.com>
4
   and Graydon Hoare <graydon@redhat.com>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 2, or (at your option) any later
11
version.
12
 
13
In addition to the permissions in the GNU General Public License, the
14
Free Software Foundation gives you unlimited permission to link the
15
compiled version of this file into combinations with other programs,
16
and to distribute those combinations without any restriction coming
17
from the use of this file.  (The General Public License restrictions
18
do apply in other respects; for example, they cover modification of
19
the file, and distribution when not linked into a combine
20
executable.)
21
 
22
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23
WARRANTY; without even the implied warranty of MERCHANTABILITY or
24
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
for more details.
26
 
27
You should have received a copy of the GNU General Public License
28
along with GCC; see the file COPYING.  If not, write to the Free
29
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
30
02110-1301, USA.  */
31
 
32
 
33
#include "config.h"
34
 
35
#include <stdio.h>
36
 
37
#include "mf-runtime.h"
38
#include "mf-impl.h"
39
 
40
#ifdef _MUDFLAP
41
#error "Do not compile this file with -fmudflap!"
42
#endif
43
 
44
 
45
extern char _end[];
46
extern char ENTRY_POINT[];
47
 
48
 
49
/* Run some quick validation of the given region.
50
   Return -1 / 0 / 1 if the access known-invalid, possibly-valid, or known-valid.
51
*/
52
int
53
__mf_heuristic_check (uintptr_t ptr, uintptr_t ptr_high)
54
{
55
  VERBOSE_TRACE ("mf: heuristic check\n");
56
 
57
  /* XXX: Disable the stack bounding check for libmudflapth.  We do
58
     actually have enough information to track stack bounds (see
59
     __mf_pthread_info in mf-hooks.c), so with a bit of future work,
60
     this heuristic can be turned on.  */
61
#ifndef LIBMUDFLAPTH
62
 
63
  /* The first heuristic is to check stack bounds.  This is a
64
     transient condition and quick to check. */
65
  if (__mf_opts.heur_stack_bound)
66
    {
67
      uintptr_t stack_top_guess = (uintptr_t)__builtin_frame_address(0);
68
#if defined(__i386__) && defined (__linux__)
69
      uintptr_t stack_segment_base = 0xC0000000; /* XXX: Bad assumption. */
70
#else
71
      /* Cause tests to fail. */
72
      uintptr_t stack_segment_base = 0;
73
#endif
74
 
75
      VERBOSE_TRACE ("mf: stack estimated as %p-%p\n",
76
                     (void *) stack_top_guess, (void *) stack_segment_base);
77
 
78
      if (ptr_high <= stack_segment_base &&
79
          ptr >= stack_top_guess &&
80
          ptr_high >= ptr)
81
        {
82
          return 1;
83
        }
84
    }
85
#endif
86
 
87
 
88
  /* The second heuristic is to scan the range of memory regions
89
     listed in /proc/self/maps, a special file provided by the Linux
90
     kernel.  Its results may be cached, and in fact, a GUESS object
91
     may as well be recorded for interesting matching sections.  */
92
  if (__mf_opts.heur_proc_map)
93
    {
94
      /* Keep a record of seen records from /proc/self/map.  */
95
      enum { max_entries = 500 };
96
      struct proc_self_map_entry
97
      {
98
        uintptr_t low;
99
        uintptr_t high;
100
      };
101
      static struct proc_self_map_entry entry [max_entries];
102
      static unsigned entry_used [max_entries];
103
 
104
      /* Look for a known proc_self_map entry that may cover this
105
         region.  If one exists, then this heuristic has already run,
106
         and should not be run again.  The check should be allowed to
107
         fail.  */
108
      unsigned i;
109
      unsigned deja_vu = 0;
110
      for (i=0; i<max_entries; i++)
111
        {
112
          if (entry_used[i] &&
113
              (entry[i].low <= ptr) &&
114
              (entry[i].high >= ptr_high))
115
            deja_vu = 1;
116
        }
117
 
118
      if (! deja_vu)
119
        {
120
          /* Time to run the heuristic.  Rescan /proc/self/maps; update the
121
             entry[] array; XXX: remove expired entries, add new ones.
122
             XXX: Consider entries that have grown (e.g., stack).  */
123
          char buf[512];
124
          char flags[4];
125
          void *low, *high;
126
          FILE *fp;
127
 
128
          fp = fopen ("/proc/self/maps", "r");
129
          if (fp)
130
            {
131
              while (fgets (buf, sizeof(buf), fp))
132
                {
133
                  if (sscanf (buf, "%p-%p %4c", &low, &high, flags) == 3)
134
                    {
135
                      if ((uintptr_t) low <= ptr &&
136
                          (uintptr_t) high >= ptr_high)
137
                        {
138
                          for (i=0; i<max_entries; i++)
139
                            {
140
                              if (! entry_used[i])
141
                                {
142
                                  entry[i].low = (uintptr_t) low;
143
                                  entry[i].high = (uintptr_t) high;
144
                                  entry_used[i] = 1;
145
                                  break;
146
                                }
147
                            }
148
 
149
                          VERBOSE_TRACE ("mf: registering region #%d "
150
                                         "%p-%p given %s",
151
                                         i, (void *) low, (void *) high, buf);
152
 
153
                          __mfu_register ((void *) low, (size_t) (high-low),
154
                                          __MF_TYPE_GUESS,
155
                                          "/proc/self/maps segment");
156
 
157
                          return 0; /* undecided (tending to cachable) */
158
                        }
159
                    }
160
                }
161
              fclose (fp);
162
            }
163
        }
164
    }
165
 
166
 
167
  /* The third heuristic is to approve all accesses between _start (or its
168
     equivalent for the given target) and _end, which should include all
169
     text and initialized data.  */
170
  if (__mf_opts.heur_start_end)
171
    if (ptr >= (uintptr_t) & ENTRY_POINT && ptr_high <= (uintptr_t) & _end)
172
      return 1; /* uncacheable */
173
 
174
  return 0; /* unknown */
175
}

powered by: WebSVN 2.1.0

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