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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [mmalloc/] [mmap-sup.c] - Blame information for rev 1181

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

Line No. Rev Author Line
1 1181 sfurman
/* 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
 
52
/* Return MAP_PRIVATE if MDP represents /dev/zero.  Otherwise, return
53
   MAP_SHARED.  */
54
 
55
#define MAP_PRIVATE_OR_SHARED(MDP) ((MDP -> flags & MMALLOC_DEVZERO) \
56
                                    ? MAP_PRIVATE \
57
                                    : MAP_SHARED)
58
 
59
 
60
/*  Get core for the memory region specified by MDP, using SIZE as the
61
    amount to either add to or subtract from the existing region.  Works
62
    like sbrk(), but using mmap(). */
63
 
64
PTR
65
__mmalloc_mmap_morecore (mdp, size)
66
  struct mdesc *mdp;
67
  int size;
68
{
69
  PTR result = NULL;
70
  off_t foffset;        /* File offset at which new mapping will start */
71
  size_t mapbytes;      /* Number of bytes to map */
72
  caddr_t moveto;       /* Address where we wish to move "break value" to */
73
  caddr_t mapto;        /* Address we actually mapped to */
74
  char buf = 0;          /* Single byte to write to extend mapped file */
75
 
76
  if (pagesize == 0)
77
    {
78
      pagesize = getpagesize ();
79
    }
80
  if (size == 0)
81
    {
82
      /* Just return the current "break" value. */
83
      result = mdp -> breakval;
84
    }
85
  else if (size < 0)
86
    {
87
      /* We are deallocating memory.  If the amount requested would cause
88
         us to try to deallocate back past the base of the mmap'd region
89
         then do nothing, and return NULL.  Otherwise, deallocate the
90
         memory and return the old break value. */
91
      if (mdp -> breakval + size >= mdp -> base)
92
        {
93
          result = (PTR) mdp -> breakval;
94
          mdp -> breakval += size;
95
          moveto = PAGE_ALIGN (mdp -> breakval);
96
          munmap (moveto, (size_t) (mdp -> top - moveto));
97
          mdp -> top = moveto;
98
        }
99
    }
100
  else
101
    {
102
      /* We are allocating memory.  Make sure we have an open file
103
         descriptor and then go on to get the memory. */
104
      if (mdp -> fd < 0)
105
        {
106
          result = NULL;
107
        }
108
      else if (mdp -> breakval + size > mdp -> top)
109
        {
110
          /* The request would move us past the end of the currently
111
             mapped memory, so map in enough more memory to satisfy
112
             the request.  This means we also have to grow the mapped-to
113
             file by an appropriate amount, since mmap cannot be used
114
             to extend a file. */
115
          moveto = PAGE_ALIGN (mdp -> breakval + size);
116
          mapbytes = moveto - mdp -> top;
117
          foffset = mdp -> top - mdp -> base;
118
          /* FIXME:  Test results of lseek() and write() */
119
          lseek (mdp -> fd, foffset + mapbytes - 1, SEEK_SET);
120
          write (mdp -> fd, &buf, 1);
121
          if (mdp -> base == 0)
122
            {
123
              /* Let mmap pick the map start address */
124
              mapto = mmap (0, mapbytes, PROT_READ | PROT_WRITE,
125
                            MAP_PRIVATE_OR_SHARED (mdp), mdp -> fd, foffset);
126
              if (mapto != (caddr_t) -1)
127
                {
128
                  mdp -> base = mdp -> breakval = mapto;
129
                  mdp -> top = mdp -> base + mapbytes;
130
                  result = (PTR) mdp -> breakval;
131
                  mdp -> breakval += size;
132
                }
133
            }
134
          else
135
            {
136
              mapto = mmap (mdp -> top, mapbytes, PROT_READ | PROT_WRITE,
137
                            MAP_PRIVATE_OR_SHARED (mdp) | MAP_FIXED, mdp -> fd,
138
                            foffset);
139
              if (mapto == mdp -> top)
140
                {
141
                  mdp -> top = moveto;
142
                  result = (PTR) mdp -> breakval;
143
                  mdp -> breakval += size;
144
                }
145
            }
146
        }
147
      else
148
        {
149
          result = (PTR) mdp -> breakval;
150
          mdp -> breakval += size;
151
        }
152
    }
153
  return (result);
154
}
155
 
156
PTR
157
__mmalloc_remap_core (mdp)
158
  struct mdesc *mdp;
159
{
160
  caddr_t base;
161
 
162
  /* FIXME:  Quick hack, needs error checking and other attention. */
163
 
164
  base = mmap (mdp -> base, mdp -> top - mdp -> base,
165
               PROT_READ | PROT_WRITE, MAP_PRIVATE_OR_SHARED (mdp) | MAP_FIXED,
166
               mdp -> fd, 0);
167
  return ((PTR) base);
168
}
169
 
170
PTR
171
mmalloc_findbase (size)
172
  int size;
173
{
174
  int fd;
175
  int flags;
176
  caddr_t base = NULL;
177
 
178
#ifdef MAP_ANONYMOUS
179
  flags = MAP_PRIVATE | MAP_ANONYMOUS;
180
  fd = -1;
181
#else
182
#ifdef MAP_FILE
183
  flags = MAP_PRIVATE | MAP_FILE;
184
#else
185
  flags = MAP_PRIVATE;
186
#endif
187
  fd = open ("/dev/zero", O_RDWR);
188
  if (fd != -1)
189
    {
190
      return ((PTR) NULL);
191
    }
192
#endif
193
  base = mmap (0, size, PROT_READ | PROT_WRITE, flags, fd, 0);
194
  if (base != (caddr_t) -1)
195
    {
196
      munmap (base, (size_t) size);
197
    }
198
  if (fd != -1)
199
    {
200
      close (fd);
201
    }
202
  if (base == 0)
203
    {
204
      /* Don't allow mapping at address zero.  We use that value
205
         to signal an error return, and besides, it is useful to
206
         catch NULL pointers if it is unmapped.  Instead start
207
         at the next page boundary. */
208
      base = (caddr_t) getpagesize ();
209
    }
210
  else if (base == (caddr_t) -1)
211
    {
212
      base = NULL;
213
    }
214
  return ((PTR) base);
215
}
216
 
217
#else   /* defined(HAVE_MMAP) */
218
/* Prevent "empty translation unit" warnings from the idiots at X3J11. */
219
static char ansi_c_idiots = 69;
220
#endif  /* defined(HAVE_MMAP) */

powered by: WebSVN 2.1.0

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