⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flatload.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    flags     = ntohl(hdr->flags);    rev       = ntohl(hdr->rev);    DBG_FLT("BINFMT_FLAT: Loading file: %s\n", bprm->filename);    if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {        fprintf(stderr, "BINFMT_FLAT: bad magic/rev (0x%x, need 0x%x)\n",                rev, (int) FLAT_VERSION);        return -ENOEXEC;    }    /* Don't allow old format executables to use shared libraries */    if (rev == OLD_FLAT_VERSION && id != 0) {        fprintf(stderr, "BINFMT_FLAT: shared libraries are not available\n");        return -ENOEXEC;    }    /*     * fix up the flags for the older format,  there were all kinds     * of endian hacks,  this only works for the simple cases     */    if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))        flags = FLAT_FLAG_RAM;#ifndef CONFIG_BINFMT_ZFLAT    if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {        fprintf(stderr, "Support for ZFLAT executables is not enabled\n");        return -ENOEXEC;    }#endif    /*     * calculate the extra space we need to map in     */    extra = relocs * sizeof(abi_ulong);    if (extra < bss_len + stack_len)        extra = bss_len + stack_len;    /* Add space for library base pointers.  Make sure this does not       misalign the  doesn't misalign the data segment.  */    indx_len = MAX_SHARED_LIBS * sizeof(abi_ulong);    indx_len = (indx_len + 15) & ~(abi_ulong)15;    /*     * there are a couple of cases here,  the separate code/data     * case,  and then the fully copied to RAM case which lumps     * it all together.     */    if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {        /*         * this should give us a ROM ptr,  but if it doesn't we don't         * really care         */        DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");        textpos = target_mmap(0, text_len, PROT_READ|PROT_EXEC,                              MAP_PRIVATE, bprm->fd, 0);        if (textpos == -1) {            fprintf(stderr, "Unable to mmap process text\n");            return -1;        }        realdatastart = target_mmap(0, data_len + extra + indx_len,                                    PROT_READ|PROT_WRITE|PROT_EXEC,                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);        if (realdatastart == -1) {            fprintf(stderr, "Unable to allocate RAM for process data\n");            return realdatastart;        }        datapos = realdatastart + indx_len;        DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",                        (int)(data_len + bss_len + stack_len), (int)datapos);        fpos = ntohl(hdr->data_start);#ifdef CONFIG_BINFMT_ZFLAT        if (flags & FLAT_FLAG_GZDATA) {            result = decompress_exec(bprm, fpos, (char *) datapos,                                     data_len + (relocs * sizeof(abi_ulong)))        } else#endif        {            result = target_pread(bprm->fd, datapos,                                  data_len + (relocs * sizeof(abi_ulong)),                                  fpos);        }        if (result < 0) {            fprintf(stderr, "Unable to read data+bss\n");            return result;        }        reloc = datapos + (ntohl(hdr->reloc_start) - text_len);        memp = realdatastart;    } else {        textpos = target_mmap(0, text_len + data_len + extra + indx_len,                              PROT_READ | PROT_EXEC | PROT_WRITE,                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);        if (textpos == -1 ) {            fprintf(stderr, "Unable to allocate RAM for process text/data\n");            return -1;        }        realdatastart = textpos + ntohl(hdr->data_start);        datapos = realdatastart + indx_len;        reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);        memp = textpos;#ifdef CONFIG_BINFMT_ZFLAT#error code needs checking        /*         * load it all in and treat it like a RAM load from now on         */        if (flags & FLAT_FLAG_GZIP) {                result = decompress_exec(bprm, sizeof (struct flat_hdr),                                 (((char *) textpos) + sizeof (struct flat_hdr)),                                 (text_len + data_len + (relocs * sizeof(unsigned long))                                          - sizeof (struct flat_hdr)),                                 0);                memmove((void *) datapos, (void *) realdatastart,                                data_len + (relocs * sizeof(unsigned long)));        } else if (flags & FLAT_FLAG_GZDATA) {                fpos = 0;                result = bprm->file->f_op->read(bprm->file,                                (char *) textpos, text_len, &fpos);                if (result < (unsigned long) -4096)                        result = decompress_exec(bprm, text_len, (char *) datapos,                                         data_len + (relocs * sizeof(unsigned long)), 0);        }        else#endif        {            result = target_pread(bprm->fd, textpos,                                  text_len, 0);            if (result >= 0) {                result = target_pread(bprm->fd, datapos,                    data_len + (relocs * sizeof(abi_ulong)),                    ntohl(hdr->data_start));            }        }        if (result < 0) {            fprintf(stderr, "Unable to read code+data+bss\n");            return result;        }    }    DBG_FLT("Mapping is 0x%x, Entry point is 0x%x, data_start is 0x%x\n",            (int)textpos, 0x00ffffff&ntohl(hdr->entry),            ntohl(hdr->data_start));    /* The main program needs a little extra setup in the task structure */    start_code = textpos + sizeof (struct flat_hdr);    end_code = textpos + text_len;    DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",            id ? "Lib" : "Load", bprm->filename,            (int) start_code, (int) end_code,            (int) datapos,            (int) (datapos + data_len),            (int) (datapos + data_len),            (int) (((datapos + data_len + bss_len) + 3) & ~3));    text_len -= sizeof(struct flat_hdr); /* the real code len */    /* Store the current module values into the global library structure */    libinfo[id].start_code = start_code;    libinfo[id].start_data = datapos;    libinfo[id].end_data = datapos + data_len;    libinfo[id].start_brk = datapos + data_len + bss_len;    libinfo[id].text_len = text_len;    libinfo[id].loaded = 1;    libinfo[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;    libinfo[id].build_date = ntohl(hdr->build_date);    /*     * We just load the allocations into some temporary memory to     * help simplify all this mumbo jumbo     *     * We've got two different sections of relocation entries.     * The first is the GOT which resides at the begining of the data segment     * and is terminated with a -1.  This one can be relocated in place.     * The second is the extra relocation entries tacked after the image's     * data segment. These require a little more processing as the entry is     * really an offset into the image which contains an offset into the     * image.     */    if (flags & FLAT_FLAG_GOTPIC) {        rp = datapos;        while (1) {            abi_ulong addr;            if (get_user_ual(addr, rp))                return -EFAULT;            if (addr == -1)                break;            if (addr) {                addr = calc_reloc(addr, libinfo, id, 0);                if (addr == RELOC_FAILED)                    return -ENOEXEC;                if (put_user_ual(addr, rp))                    return -EFAULT;            }            rp += sizeof(abi_ulong);        }    }    /*     * Now run through the relocation entries.     * We've got to be careful here as C++ produces relocatable zero     * entries in the constructor and destructor tables which are then     * tested for being not zero (which will always occur unless we're     * based from address zero).  This causes an endless loop as __start     * is at zero.  The solution used is to not relocate zero addresses.     * This has the negative side effect of not allowing a global data     * reference to be statically initialised to _stext (I've moved     * __start to address 4 so that is okay).     */    if (rev > OLD_FLAT_VERSION) {        for (i = 0; i < relocs; i++) {            abi_ulong addr, relval;            /* Get the address of the pointer to be               relocated (of course, the address has to be               relocated first).  */            if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))                return -EFAULT;            addr = flat_get_relocate_addr(relval);            rp = calc_reloc(addr, libinfo, id, 1);            if (rp == RELOC_FAILED)                return -ENOEXEC;            /* Get the pointer's value.  */            if (get_user_ual(addr, rp))                return -EFAULT;            if (addr != 0) {                /*                 * Do the relocation.  PIC relocs in the data section are                 * already in target order                 */#ifndef TARGET_WORDS_BIGENDIAN                if ((flags & FLAT_FLAG_GOTPIC) == 0)                    addr = bswap32(addr);#endif                addr = calc_reloc(addr, libinfo, id, 0);                if (addr == RELOC_FAILED)                    return -ENOEXEC;                /* Write back the relocated pointer.  */                if (put_user_ual(addr, rp))                    return -EFAULT;            }        }    } else {        for (i = 0; i < relocs; i++) {            abi_ulong relval;            if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))                return -EFAULT;            old_reloc(&libinfo[0], relval);        }    }    /* zero the BSS.  */    memset((void*)(datapos + data_len), 0, bss_len);    return 0;}/****************************************************************************/#ifdef CONFIG_BINFMT_SHARED_FLAT/* * Load a shared library into memory.  The library gets its own data * segment (including bss) but not argv/argc/environ. */static int load_flat_shared_library(int id, struct lib_info *libs){	struct linux_binprm bprm;	int res;	char buf[16];	/* Create the file name */	sprintf(buf, "/lib/lib%d.so", id);	/* Open the file up */	bprm.filename = buf;	bprm.file = open_exec(bprm.filename);	res = PTR_ERR(bprm.file);	if (IS_ERR(bprm.file))		return res;	res = prepare_binprm(&bprm);	if (res <= (unsigned long)-4096)		res = load_flat_file(&bprm, libs, id, NULL);	if (bprm.file) {		allow_write_access(bprm.file);		fput(bprm.file);		bprm.file = NULL;	}	return(res);}#endif /* CONFIG_BINFMT_SHARED_FLAT */int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,                    struct image_info * info){    struct lib_info libinfo[MAX_SHARED_LIBS];    abi_ulong p = bprm->p;    abi_ulong stack_len;    abi_ulong start_addr;    abi_ulong sp;    int res;    int i, j;    memset(libinfo, 0, sizeof(libinfo));    /*     * We have to add the size of our arguments to our stack size     * otherwise it's too easy for users to create stack overflows     * by passing in a huge argument list.  And yes,  we have to be     * pedantic and include space for the argv/envp array as it may have     * a lot of entries.     */#define TOP_OF_ARGS (TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *))    stack_len = TOP_OF_ARGS - bprm->p;             /* the strings */    stack_len += (bprm->argc + 1) * 4; /* the argv array */    stack_len += (bprm->envc + 1) * 4; /* the envp array */    res = load_flat_file(bprm, libinfo, 0, &stack_len);    if (res > (unsigned long)-4096)            return res;    /* Update data segment pointers for all libraries */    for (i=0; i<MAX_SHARED_LIBS; i++) {        if (libinfo[i].loaded) {            abi_ulong p;            p = libinfo[i].start_data;            for (j=0; j<MAX_SHARED_LIBS; j++) {                p -= 4;                /* FIXME - handle put_user() failures */                if (put_user_ual(libinfo[j].loaded                                 ? libinfo[j].start_data                                 : UNLOADED_LIB,                                 p))                    return -EFAULT;            }        }    }    p = ((libinfo[0].start_brk + stack_len + 3) & ~3) - 4;    DBG_FLT("p=%x\n", (int)p);    /* Copy argv/envp.  */    p = copy_strings(p, bprm->envc, bprm->envp);    p = copy_strings(p, bprm->argc, bprm->argv);    /* Align stack.  */    sp = p & ~(abi_ulong)(sizeof(abi_ulong) - 1);    /* Enforce final stack alignment of 16 bytes.  This is sufficient       for all current targets, and excess alignment is harmless.  */    stack_len = bprm->envc + bprm->argc + 2;    stack_len += 3;	/* argc, arvg, argp */    stack_len *= sizeof(abi_ulong);    if ((sp + stack_len) & 15)        sp -= 16 - ((sp + stack_len) & 15);    sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1);    /* Fake some return addresses to ensure the call chain will     * initialise library in order for us.  We are required to call     * lib 1 first, then 2, ... and finally the main program (id 0).     */    start_addr = libinfo[0].entry;#ifdef CONFIG_BINFMT_SHARED_FLAT#error here    for (i = MAX_SHARED_LIBS-1; i>0; i--) {            if (libinfo[i].loaded) {                    /* Push previos first to call address */                    --sp;                    if (put_user_ual(start_addr, sp))                        return -EFAULT;                    start_addr = libinfo[i].entry;            }    }#endif    /* Stash our initial stack pointer into the mm structure */    info->start_code = libinfo[0].start_code;    info->end_code = libinfo[0].start_code = libinfo[0].text_len;    info->start_data = libinfo[0].start_data;    info->end_data = libinfo[0].end_data;    info->start_brk = libinfo[0].start_brk;    info->start_stack = sp;    info->entry = start_addr;    info->code_offset = info->start_code;    info->data_offset = info->start_data - libinfo[0].text_len;    DBG_FLT("start_thread(entry=0x%x, start_stack=0x%x)\n",            (int)info->entry, (int)info->start_stack);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -