View | Details | Return to bug 19300 | Differences between
and this patch

Collapse All | Expand All

(-)config/host-linux.c (+66 lines)
Lines 61-66 Link Here
61
#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
61
#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
62
#define HOST_HOOKS_GT_PCH_GET_ADDRESS linux_gt_pch_get_address
62
#define HOST_HOOKS_GT_PCH_GET_ADDRESS linux_gt_pch_get_address
63
63
64
#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
65
#define HOST_HOOKS_GT_PCH_USE_ADDRESS linux_gt_pch_use_address
66
64
/* For various ports, try to guess a fixed spot in the vm space
67
/* For various ports, try to guess a fixed spot in the vm space
65
   that's probably free.  */
68
   that's probably free.  */
66
#if defined(__alpha)
69
#if defined(__alpha)
Lines 143-147 linux_gt_pch_get_address (size_t size, i Link Here
143
  return addr;
154
  return addr;
144
}
155
}
145
156
157
/* Map SIZE bytes of FD+OFFSET at BASE.  Return 1 if we succeeded at
158
   mapping the data at BASE, -1 if we couldn't.
159
160
   It's not possibly to reliably mmap a file using MAP_PRIVATE to
161
   a specific START address on either hpux or linux.  First we see
162
   if mmap with MAP_PRIVATE works.  If it does, we are off to the
163
   races.  If it doesn't, we try an anonymous private mmap since the
164
   kernel is more likely to honor the BASE address in anonymous maps.
165
   We then copy the data to the anonymous private map.  This assumes
166
   of course that we don't need to change the data in the PCH file
167
   after it is created.
168
169
   This approach obviously causes a performance penalty but there is
170
   little else we can do given the current PCH implementation.  */
171
172
static int
173
linux_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
174
{
175
  void *addr;
176
177
  /* We're called with size == 0 if we're not planning to load a PCH
178
     file at all.  This allows the hook to free any static space that
179
     we might have allocated at link time.  */
180
  if (size == 0)
181
    return -1;
182
183
  /* Try to map the file with MAP_PRIVATE.  */
184
  addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset);
185
186
  if (addr == base)
187
    return 1;
188
189
  if (addr != (void *) MAP_FAILED)
190
    munmap (addr, size);
191
192
  /* Try to make an anonymous private mmap at the desired location.  */
193
  addr = mmap (base, size, PROT_READ | PROT_WRITE,
194
	       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
195
196
  if (addr != base)
197
    {
198
      if (addr != (void *) MAP_FAILED)
199
        munmap (addr, size);
200
      return -1;
201
    }
202
203
  if (lseek (fd, offset, SEEK_SET) == (off_t)-1)
204
    return -1;
205
206
  while (size)
207
    {
208
      ssize_t nbytes;
209
210
      nbytes = read (fd, base, MIN (size, SSIZE_MAX));
211
      if (nbytes <= 0)
212
        return -1;
213
      base = (char *) base + nbytes;
214
      size -= nbytes;
215
    }
216
217
  return 1;
218
}
219
146
220
147
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
221
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;

Return to bug 19300