Revision 5fafdf24 linux-user/mmap.c

b/linux-user/mmap.c
1 1
/*
2 2
 *  mmap support for qemu
3
 * 
3
 *
4 4
 *  Copyright (c) 2003 Fabrice Bellard
5 5
 *
6 6
 *  This program is free software; you can redistribute it and/or modify
......
52 52
        return -EINVAL;
53 53
    if (len == 0)
54 54
        return 0;
55
    
55
   
56 56
    host_start = start & qemu_host_page_mask;
57 57
    host_end = HOST_PAGE_ALIGN(end);
58 58
    if (start > host_start) {
......
77 77
        for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
78 78
            prot1 |= page_get_flags(addr);
79 79
        }
80
        ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size, 
80
        ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size,
81 81
                       prot1 & PAGE_BITS);
82 82
        if (ret != 0)
83 83
            return ret;
84 84
        host_end -= qemu_host_page_size;
85 85
    }
86
    
86
   
87 87
    /* handle the pages in the middle */
88 88
    if (host_start < host_end) {
89 89
        ret = mprotect(g2h(host_start), host_end - host_start, prot);
......
95 95
}
96 96

  
97 97
/* map an incomplete host page */
98
static int mmap_frag(target_ulong real_start, 
99
                     target_ulong start, target_ulong end, 
98
static int mmap_frag(target_ulong real_start,
99
                     target_ulong start, target_ulong end,
100 100
                     int prot, int flags, int fd, target_ulong offset)
101 101
{
102 102
    target_ulong real_end, ret, addr;
......
112 112
        if (addr < start || addr >= end)
113 113
            prot1 |= page_get_flags(addr);
114 114
    }
115
    
115
   
116 116
    if (prot1 == 0) {
117 117
        /* no page was there, so we allocate one */
118
        ret = (long)mmap(host_start, qemu_host_page_size, prot, 
118
        ret = (long)mmap(host_start, qemu_host_page_size, prot,
119 119
                         flags | MAP_ANONYMOUS, -1, 0);
120 120
        if (ret == -1)
121 121
            return ret;
......
134 134
        /* adjust protection to be able to read */
135 135
        if (!(prot1 & PROT_WRITE))
136 136
            mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
137
        
137
       
138 138
        /* read the corresponding file data */
139 139
        pread(fd, g2h(start), end - start, offset);
140
        
140
       
141 141
        /* put final protection */
142 142
        if (prot_new != (prot1 | PROT_WRITE))
143 143
            mprotect(host_start, qemu_host_page_size, prot_new);
......
151 151
}
152 152

  
153 153
/* NOTE: all the constants are the HOST ones */
154
long target_mmap(target_ulong start, target_ulong len, int prot, 
154
long target_mmap(target_ulong start, target_ulong len, int prot,
155 155
                 int flags, int fd, target_ulong offset)
156 156
{
157 157
    target_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
......
167 167
#ifdef DEBUG_MMAP
168 168
    {
169 169
        printf("mmap: start=0x%lx len=0x%lx prot=%c%c%c flags=",
170
               start, len, 
170
               start, len,
171 171
               prot & PROT_READ ? 'r' : '-',
172 172
               prot & PROT_WRITE ? 'w' : '-',
173 173
               prot & PROT_EXEC ? 'x' : '-');
......
216 216
            /* ??? This needs fixing for remapping.  */
217 217
abort();
218 218
            host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
219
            real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE, 
219
            real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
220 220
                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
221 221
            if (real_start == -1)
222 222
                return real_start;
......
238 238
            if (host_start == -1)
239 239
                return host_start;
240 240
            /* update start so that it points to the file position at 'offset' */
241
            if (!(flags & MAP_ANONYMOUS)) 
241
            if (!(flags & MAP_ANONYMOUS))
242 242
                host_start += offset - host_offset;
243 243
            start = h2g(host_start);
244 244
            goto the_end1;
245 245
        }
246 246
    }
247
    
247
   
248 248
    if (start & ~TARGET_PAGE_MASK) {
249 249
        errno = EINVAL;
250 250
        return -1;
......
263 263
            errno = EINVAL;
264 264
            return -1;
265 265
        }
266
        retaddr = target_mmap(start, len, prot | PROT_WRITE, 
267
                              MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 
266
        retaddr = target_mmap(start, len, prot | PROT_WRITE,
267
                              MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
268 268
                              -1, 0);
269 269
        if (retaddr == -1)
270 270
            return retaddr;
......
295 295
    }
296 296
    /* handle the end of the mapping */
297 297
    if (end < real_end) {
298
        ret = mmap_frag(real_end - qemu_host_page_size, 
298
        ret = mmap_frag(real_end - qemu_host_page_size,
299 299
                        real_end - qemu_host_page_size, real_end,
300
                        prot, flags, fd, 
300
                        prot, flags, fd,
301 301
                        offset + real_end - qemu_host_page_size - start);
302 302
        if (ret == -1)
303 303
            return ret;
304 304
        real_end -= qemu_host_page_size;
305 305
    }
306
    
306
   
307 307
    /* map the middle (easier) */
308 308
    if (real_start < real_end) {
309 309
        unsigned long offset1;
......
311 311
	  offset1 = 0;
312 312
	else
313 313
	  offset1 = offset + real_start - start;
314
        ret = (long)mmap(g2h(real_start), real_end - real_start, 
314
        ret = (long)mmap(g2h(real_start), real_end - real_start,
315 315
                         prot, flags, fd, offset1);
316 316
        if (ret == -1)
317 317
            return ret;
......
367 367
        if (prot != 0)
368 368
            real_end -= qemu_host_page_size;
369 369
    }
370
    
370
   
371 371
    /* unmap what we can */
372 372
    if (real_start < real_end) {
373 373
        ret = munmap((void *)real_start, real_end - real_start);
......
381 381

  
382 382
/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
383 383
   blocks which have been allocated starting on a host page */
384
long target_mremap(target_ulong old_addr, target_ulong old_size, 
384
long target_mremap(target_ulong old_addr, target_ulong old_size,
385 385
                   target_ulong new_size, unsigned long flags,
386 386
                   target_ulong new_addr)
387 387
{
......
410 410
        return -EINVAL;
411 411
    if (end == start)
412 412
        return 0;
413
    
413
   
414 414
    start &= qemu_host_page_mask;
415 415
    return msync(g2h(start), end - start, flags);
416 416
}

Also available in: Unified diff