aboutsummaryrefslogtreecommitdiff
path: root/user/lib/ld-weenix/ldalloc.c
blob: c5e79e7a00b646186681354ed2c20706e89a788f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 *  File: ldalloc.c
 *  Date: 28 March 1998
 *  Acct: David Powell (dep)
 *  Desc: simple allocation routines
 */

#include "ldalloc.h"
#include "ldutil.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

static unsigned long start;
static unsigned long pos;
static unsigned long amount;

/* This function initializes the simple memory allocator.  We basically
 * allocate a specified number of pages to use as scratch memory for
 * the linker itself.  No deallocation functionality is provided; the
 * amount of memory used should be small, and is usually needed for the
 * duration of the program's execution, anyway.
 *
 * All this function does is mmap the specified number of pages of
 * /dev/zero to provide the memory for our little memory-wading-pool. */

void _ldainit(unsigned long pagesize, unsigned long pages)
{
    amount = pagesize * pages;
    pos = 0;

    start = (unsigned long)mmap(NULL, amount, PROT_READ | PROT_WRITE,
                                MAP_PRIVATE | MAP_ANON, -1, 0);
    if (start == (unsigned long)MAP_FAILED)
    {
        fprintf(stderr, "ld-weenix: panic - unable to map /dev/zero\n");
        exit(1);
    }
}

/* This function allocates a block of memory of the specified size from
 * our memory pool.  The memory is word-aligned, and cannot be freed. */

void *_ldalloc(unsigned long size)
{
    unsigned long next;

    if (size & 3)
    {
        size = (size & ~3) + 4;
    }

    if (pos + size > amount)
    {
        fprintf(stderr,
                "ld.so.1: panic - unable to allocate %lu bytes (_ldalloc)\n",
                size);
        exit(1);
    }

    next = start + pos;
    pos += size;

    return (void *)next;
}