74 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <sys/cdefs.h>
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
 | 
						|
#include <err.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <libelf.h>
 | 
						|
#include <stdbool.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include "_libelf.h"
 | 
						|
#include "../libelf_compat.h"
 | 
						|
 | 
						|
void *
 | 
						|
libelf_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
 | 
						|
{
 | 
						|
    void *p; /* malloc'ed pointer */
 | 
						|
    size_t bufsize;
 | 
						|
 | 
						|
    if ((addr != NULL) || (flags != MAP_PRIVATE) || (prot != PROT_READ)) {
 | 
						|
	LIBELF_SET_ERROR(ARGUMENT, 0);
 | 
						|
	return (MAP_FAILED);
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Fall back to malloc+read.
 | 
						|
     */
 | 
						|
    p = NULL;
 | 
						|
    bufsize = 1024 * 1024;
 | 
						|
    while (/*CONSTCOND*/true) {
 | 
						|
	void *newp = realloc(p, bufsize);
 | 
						|
	ssize_t rsz;
 | 
						|
 | 
						|
	if (newp == NULL) {
 | 
						|
	    free(p);
 | 
						|
	    LIBELF_SET_ERROR(RESOURCE, 0);
 | 
						|
	    return (MAP_FAILED);
 | 
						|
	}
 | 
						|
	p = newp;
 | 
						|
	rsz = pread(fd, p, bufsize, 0);
 | 
						|
	if (rsz == -1) {
 | 
						|
	    free(p);
 | 
						|
	    LIBELF_SET_ERROR(IO, errno);
 | 
						|
	    return (MAP_FAILED);
 | 
						|
	} else if ((size_t) rsz > bufsize) {
 | 
						|
	    free(p);
 | 
						|
	    LIBELF_SET_ERROR(IO, EIO); /* XXX */
 | 
						|
	    return (MAP_FAILED);
 | 
						|
	} else if ((size_t) rsz < bufsize) {
 | 
						|
	    /*
 | 
						|
	     * try to shrink the buffer.
 | 
						|
	     */
 | 
						|
	    newp = realloc(p, (size_t) rsz);
 | 
						|
	    if (newp != NULL) {
 | 
						|
		p = newp;
 | 
						|
	    }
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
	bufsize *= 2;
 | 
						|
    }
 | 
						|
 | 
						|
    return p;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
libelf_munmap(void *addr, size_t len)
 | 
						|
{
 | 
						|
    free(addr);
 | 
						|
    return 0;
 | 
						|
}
 |