哪个虚拟内存可用于进程? (linux mmap)

时间:2015-01-19 21:42:10

标签: c linux memory-management elf

在linux x64(3.16.0-29-generic)上,使用下面的代码我尝试使用mmap分配一些特定的内存地址。 我使用-m32和-m64进行了编译。 所以我发现内存地址(所有地址都是十六进制 - 3个最后的零是用于页面allignement)下面是不可分配的: 0,000,1,000,2,000到F,000,有时10,000(有时候我可以使用它),之后我到达400,000,600,000,600,001。

据我所知,我的代码加载到400.000而其他东西加载在600.000和601.000。 我如何控制程序和数据部分的加载位置,以防我希望这些地址是空闲的,并记录哪些内存地址应该可用。 为什么我不能将初始地址用作0.000到10.000? (应该是什么?)。

有点脏的代码如下:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>

int mprotect(void *addr, size_t len, int prot);

constexpr int64_t cc=0x5858585858585858;

#define Return asm volatile("movq $0x5858585858585858,%rax;");return;
int64_t funcEnd=0x0;
constexpr int maxCode=0x800;
int8_t code[maxCode];
constexpr int pageSz=8192;

char s[0x8];

void testCode(void){
    int a=8,b=7;
    a+=b*a;
    for(size_t i=0;i<sizeof(s);i++)s[i]=i;
    //Return;
}

typedef void (*action)(void);

int main(int argc, char **argv)
{
    action a=&testCode;
    //testCode();

    int8_t *p0=(int8_t*)a,*p=p0,*p1=p0+maxCode;
    while(p!=p1)
        if ( (*(int64_t*)p++)==cc) break;

    if(p!=p1){
            printf("found\n");
            void* myAddr=(void*)(1 * 0x1000);
            void* ma;int cnt=0;
            for(unsigned int i=0x0;i<0x100000;i++){
                void* p=(void*)(i*0x1000);
                ma=mmap(p,0x1000,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,0,0);
                if(ma!=p)
                    printf("mapping of %p failed\n",p);
            }
            p+=sizeof(int64_t)+2;
            if(ma==myAddr){
                memcpy(ma,(void*)a,p-(int8_t*)a);
                (*(action)ma)();
            }

    }else
      printf("not found");
    return 0;
}

0 个答案:

没有答案