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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libmudflap/] [mf-heuristics.c] - Blame information for rev 744

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

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

powered by: WebSVN 2.1.0

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