You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内核ELF阅读器执行异常问题求助【已解决】

内核ELF阅读器字符串加载异常问题排查与解决

我在自制操作系统的内核中编写ELF阅读器时,遇到了字符串相关的执行异常。有两段测试代码:

第一段代码:

printf("HELLO\n");

第二段代码:

char msg[10] = "HELLO\n";
printf(msg);

只有第二段能在可执行程序中正常运行。我已确认printf函数本身无问题,两者的核心区别在于:第一段中的"HELLO\n"字符串位于ELF文件末尾,第二段的字符串则靠近文件开头。我也验证过第一种情况下数据已被加载至ELF_exe_buffer,但程序仍出现异常。

以下是自制操作系统中ELF阅读器的实现代码:

void* ELF_exe_buffer;

void* ELF_read(const char* path) {
    struct FATContent* content = FAT_get_content(path);
    if (content->file == NULL) {
        kprintf("File not found\n");
        return NULL;
    }

    char* file_content = FAT_read_content(content);
    char* header_content = file_content;

    Elf32_Ehdr *ehdr = (Elf32_Ehdr*)header_content;
    if (ehdr->e_ident[0] != '\x7f' || ehdr->e_ident[1] != 'E') {
        kprintf("\r\nError: Not ELF.\r\n");
        free(file_content);
        return NULL;
    }

    if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
        kprintf("\r\nError: Program is not an executable or dynamic executable.\r\n");
        free(file_content);
        return NULL;
    }

    Elf32_Phdr* phdr = (Elf32_Phdr*)(header_content + ehdr->e_phoff);

    uint32_t mem_min   = 0xFFFFFFFF, mem_max = 0;
    uint32_t alignment = PAGE_SIZE;
    uint32_t align     = alignment;

    for (uint32_t i = 0; i < ehdr->e_phnum; i++) {
        if (phdr[i].p_type != PT_LOAD) continue;
        if (align < phdr[i].p_align) align = phdr[i].p_align;

        uint32_t mem_begin = phdr[i].p_vaddr;
        uint32_t mem_end = phdr[i].p_vaddr + phdr[i].p_memsz + align - 1;

        mem_begin &= ~(align - 1);
        mem_end &= ~(align - 1);

        if (mem_begin < mem_min) mem_min = mem_begin;
        if (mem_end > mem_max) mem_max = mem_end;
    }

    uint32_t buffer_size = mem_max - mem_min;
    uint32_t buffer_alignment = align - 1;
    ELF_exe_buffer = calloc(1, buffer_size);
    if (ELF_exe_buffer == NULL) {
        kprintf("\r\nError: Could not malloc() enough memory for program\r\n");
        free(file_content);
        return NULL;
    }

    memset(ELF_exe_buffer, 0, buffer_size);
    for (uint32_t i = 0; i < ehdr->e_phnum; i++) {
        if (phdr[i].p_type != PT_LOAD) continue;

        uint32_t relative_offset = phdr[i].p_vaddr - mem_min;

        uint8_t* dst = (uint8_t*)ELF_exe_buffer + relative_offset; 
        uint8_t* src = file_content + phdr[i].p_offset;
        uint32_t len = phdr[i].p_memsz;

        memcpy(dst, src, len);
    }

    free(file_content);
    FAT_unload_content_system(content);
    return (void*)((uint8_t*)ELF_exe_buffer + (ehdr->e_entry - mem_min));
}

问题解决方法

该问题已通过在编译选项CCFLAGS中添加-fpic参数解决。


内容的提问来源于stack exchange,提问作者j1sk1ss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:33:13