Exemplo n.º 1
0
static bfelf64_sword
private_get_relocation_tables(struct bfelf_file_t *ef)
{
    bfelf64_sword i = 0;
    bfelf64_sword ret = 0;

    for (i = 0; i < ef->ehdr->e_shnum; i++)
    {
        struct bfelf_shdr *shdr = private_get_section(ef, i);

        if (shdr->sh_type == bfsht_rel)
            unsupported_rel("the ELF loader does not support modules with REL "
                            "type relocation sections");

        if (shdr->sh_type == bfsht_rela)
        {
            if (ef->num_rela >= BFELF_MAX_RELATAB)
                return loader_full("increase BFELF_MAX_RELATAB");

            ret = private_check_section(shdr, bfsht_rela, bfshf_ai, 8,
                                        sizeof(struct bfelf_rela));
            if (ret != BFELF_SUCCESS)
                return ret;

            ef->relatab[ef->num_rela].num =
                shdr->sh_size / sizeof(struct bfelf_rela);
            ef->relatab[ef->num_rela].tab =
                (struct bfelf_rela *)(ef->file + shdr->sh_offset);
            ef->num_rela++;
        }
    }

    return BFELF_SUCCESS;
}
Exemplo n.º 2
0
int64_t
private_check_segments(struct bfelf_file_t *ef)
{
    bfelf64_xword i = 0;

    for (i = 0; i < ef->ehdr->e_phnum; i++)
    {
        struct bfelf_phdr *phdr = private_get_segment(ef, i);

        if (phdr->p_type != bfpt_load)
            continue;

        if (ef->num_loadable_segments >= BFELF_MAX_SEGMENTS)
            return loader_full("increase BFELF_MAX_SEGMENTS");

        if (phdr->p_memsz < phdr->p_filesz)
            return invalid_segment("segment mem size is less then file size");

        if (phdr->p_vaddr != phdr->p_paddr)
            return invalid_segment("expect p_vaddr == p_paddr");

        if (phdr->p_align != 0x1000 && phdr->p_align != 0x200000)
            return invalid_segment("expect 4k or 2M alignment");

        if (phdr->p_offset >= ef->fsize)
            return invalid_segment("segment offset out of bounds");

        ef->loadable_segments[ef->num_loadable_segments] = phdr;
        ef->num_loadable_segments++;
    }

    return BFELF_SUCCESS;
}
Exemplo n.º 3
0
bfelf64_sword
bfelf_loader_add(struct bfelf_loader_t *loader,
                 struct bfelf_file_t *ef,
                 char *exec)
{
    if (!loader)
        return invalid_argument("loader == NULL");

    if (!ef)
        return invalid_argument("ef == NULL");

    if (loader->num >= BFELF_MAX_MODULES)
        return loader_full("increase BFELF_MAX_MODULES");

    ef->exec = exec;
    loader->efs[loader->num++] = ef;

    return BFELF_SUCCESS;
}
Exemplo n.º 4
0
static bfelf64_sword
private_check_segments(struct bfelf_file_t *ef)
{
    bfelf64_sword i = 0;

    for (i = 0; i < ef->ehdr->e_phnum; i++)
    {
        struct bfelf_phdr *phdr = private_get_segment(ef, i);

        if (phdr->p_type != bfpt_load)
            continue;

        if (ef->num_loadable_segments >= BFELF_MAX_SEGMENTS)
            return loader_full("increase BFELF_MAX_SEGMENTS");

        if (phdr->p_memsz < phdr->p_filesz)
            return invalid_segment("segment mem size is less then file size");

        if (phdr->p_vaddr != phdr->p_paddr)
            return invalid_segment("expect p_vaddr == p_paddr");

        /*
         * At the moment, libc++.so has an alignment of 20, which is really
         * strange. Will need to find out why at some point
         *
         * if (phdr->p_align != 0x1000 && phdr->p_align != 0x200000)
         *     return invalid_segment("expect 4k or 2M alignment");
         */

        if (phdr->p_offset >= ef->fsize)
            return invalid_segment("segment offset out of bounds");

        ef->loadable_segments[ef->num_loadable_segments] = phdr;
        ef->num_loadable_segments++;
    }

    return BFELF_SUCCESS;
}