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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [mmalloc/] [mmap-sup.c] - Blame information for rev 1767

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

Line No. Rev Author Line
1 106 markom
/* Support for an sbrk-like function that uses mmap.
2
   Copyright 1992, 2000 Free Software Foundation, Inc.
3
 
4
   Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com
5
 
6
This file is part of the GNU C Library.
7
 
8
The GNU C Library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Library General Public License as
10
published by the Free Software Foundation; either version 2 of the
11
License, or (at your option) any later version.
12
 
13
The GNU C Library 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 GNU
16
Library General Public License for more details.
17
 
18
You should have received a copy of the GNU Library General Public
19
License along with the GNU C Library; see the file COPYING.LIB.  If
20
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
Boston, MA 02111-1307, USA.  */
22
 
23
#if defined(HAVE_MMAP)
24
 
25
#ifdef HAVE_UNISTD_H
26
#include <unistd.h>     /* Prototypes for lseek */
27
#endif
28
#include <stdio.h>
29
#include <fcntl.h>
30
#include <sys/mman.h>
31
 
32
#ifndef SEEK_SET
33
#define SEEK_SET 0
34
#endif
35
 
36
#include "mmprivate.h"
37
 
38
/* Cache the pagesize for the current host machine.  Note that if the host
39
   does not readily provide a getpagesize() function, we need to emulate it
40
   elsewhere, not clutter up this file with lots of kluges to try to figure
41
   it out. */
42
 
43
static size_t pagesize;
44
#if NEED_DECLARATION_GETPAGESIZE
45
extern int getpagesize PARAMS ((void));
46
#endif
47
 
48
#define PAGE_ALIGN(addr) (caddr_t) (((long)(addr) + pagesize - 1) & \
49
                                    ~(pagesize - 1))
50
 
51
/*  Get core for the memory region specified by MDP, using SIZE as the
52
    amount to either add to or subtract from the existing region.  Works
53
    like sbrk(), but using mmap(). */
54
 
55
PTR
56
__mmalloc_mmap_morecore (mdp, size)
57
  struct mdesc *mdp;
58
  int size;
59
{
60
  PTR result = NULL;
61
  off_t foffset;        /* File offset at which new mapping will start */
62
  size_t mapbytes;      /* Number of bytes to map */
63
  caddr_t moveto;       /* Address where we wish to move "break value" to */
64
  caddr_t mapto;        /* Address we actually mapped to */
65
  char buf = 0;          /* Single byte to write to extend mapped file */
66
 
67
  if (pagesize == 0)
68
    {
69
      pagesize = getpagesize ();
70
    }
71
  if (size == 0)
72
    {
73
      /* Just return the current "break" value. */
74
      result = mdp -> breakval;
75
    }
76
  else if (size < 0)
77
    {
78
      /* We are deallocating memory.  If the amount requested would cause
79
         us to try to deallocate back past the base of the mmap'd region
80
         then do nothing, and return NULL.  Otherwise, deallocate the
81
         memory and return the old break value. */
82
      if (mdp -> breakval + size >= mdp -> base)
83
        {
84
          result = (PTR) mdp -> breakval;
85
          mdp -> breakval += size;
86
          moveto = PAGE_ALIGN (mdp -> breakval);
87
          munmap (moveto, (size_t) (mdp -> top - moveto));
88
          mdp -> top = moveto;
89
        }
90
    }
91
  else
92
    {
93
      /* We are allocating memory.  Make sure we have an open file
94
         descriptor and then go on to get the memory. */
95
      if (mdp -> fd < 0)
96
        {
97
          result = NULL;
98
        }
99
      else if (mdp -> breakval + size > mdp -> top)
100
        {
101
          /* The request would move us past the end of the currently
102
             mapped memory, so map in enough more memory to satisfy
103
             the request.  This means we also have to grow the mapped-to
104
             file by an appropriate amount, since mmap cannot be used
105
             to extend a file. */
106
          moveto = PAGE_ALIGN (mdp -> breakval + size);
107
          mapbytes = moveto - mdp -> top;
108
          foffset = mdp -> top - mdp -> base;
109
          /* FIXME:  Test results of lseek() and write() */
110
          lseek (mdp -> fd, foffset + mapbytes - 1, SEEK_SET);
111
          write (mdp -> fd, &buf, 1);
112
          if (mdp -> base == 0)
113
            {
114
              /* Let mmap pick the map start address */
115
              mapto = mmap (0, mapbytes, PROT_READ | PROT_WRITE,
116
                            MAP_SHARED, mdp -> fd, foffset);
117
              if (mapto != (caddr_t) -1)
118
                {
119
                  mdp -> base = mdp -> breakval = mapto;
120
                  mdp -> top = mdp -> base + mapbytes;
121
                  result = (PTR) mdp -> breakval;
122
                  mdp -> breakval += size;
123
                }
124
            }
125
          else
126
            {
127
              mapto = mmap (mdp -> top, mapbytes, PROT_READ | PROT_WRITE,
128
                            MAP_SHARED | MAP_FIXED, mdp -> fd, foffset);
129
              if (mapto == mdp -> top)
130
                {
131
                  mdp -> top = moveto;
132
                  result = (PTR) mdp -> breakval;
133
                  mdp -> breakval += size;
134
                }
135
            }
136
        }
137
      else
138
        {
139
          result = (PTR) mdp -> breakval;
140
          mdp -> breakval += size;
141
        }
142
    }
143
  return (result);
144
}
145
 
146
PTR
147
__mmalloc_remap_core (mdp)
148
  struct mdesc *mdp;
149
{
150
  caddr_t base;
151
 
152
  /* FIXME:  Quick hack, needs error checking and other attention. */
153
 
154
  base = mmap (mdp -> base, mdp -> top - mdp -> base,
155
               PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
156
               mdp -> fd, 0);
157
  return ((PTR) base);
158
}
159
 
160
PTR
161
mmalloc_findbase (size)
162
  int size;
163
{
164
  int fd;
165
  int flags;
166
  caddr_t base = NULL;
167
 
168
#ifdef MAP_ANONYMOUS
169
  flags = MAP_SHARED | MAP_ANONYMOUS;
170
  fd = -1;
171
#else
172
#ifdef MAP_FILE
173
  flags = MAP_SHARED | MAP_FILE;
174
#else
175
  flags = MAP_SHARED;
176
#endif
177
  fd = open ("/dev/zero", O_RDWR);
178
  if (fd != -1)
179
    {
180
      return ((PTR) NULL);
181
    }
182
#endif
183
  base = mmap (0, size, PROT_READ | PROT_WRITE, flags, fd, 0);
184
  if (base != (caddr_t) -1)
185
    {
186
      munmap (base, (size_t) size);
187
    }
188
  if (fd != -1)
189
    {
190
      close (fd);
191
    }
192
  if (base == 0)
193
    {
194
      /* Don't allow mapping at address zero.  We use that value
195
         to signal an error return, and besides, it is useful to
196
         catch NULL pointers if it is unmapped.  Instead start
197
         at the next page boundary. */
198
      base = (caddr_t) getpagesize ();
199
    }
200
  else if (base == (caddr_t) -1)
201
    {
202
      base = NULL;
203
    }
204
  return ((PTR) base);
205
}
206
 
207
#else   /* defined(HAVE_MMAP) */
208
/* Prevent "empty translation unit" warnings from the idiots at X3J11. */
209
static char ansi_c_idiots = 69;
210
#endif  /* defined(HAVE_MMAP) */

powered by: WebSVN 2.1.0

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