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

📄 tccelf.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
            p = section_ptr_add(plt, 16);	    put32(p  , 0xe59fc004);	    put32(p+4, 0xe08fc00c);	    put32(p+8, 0xe59cf000);	    put32(p+12, s1->got->data_offset);            /* the symbol is modified so that it will be relocated to               the PLT */            if (s1->output_type == TCC_OUTPUT_EXE)                offset = plt->data_offset - 16;        }#elif defined(TCC_TARGET_C67)        error("C67 got not implemented");#else#error unsupported CPU#endif        index = put_elf_sym(s1->dynsym, offset,                             size, info, 0, sym->st_shndx, name);        /* put a got entry */        put_elf_reloc(s1->dynsym, s1->got,                       s1->got->data_offset,                       reloc_type, index);    }    ptr = section_ptr_add(s1->got, sizeof(int));    *ptr = 0;}/* build GOT and PLT entries */static void build_got_entries(TCCState *s1){    Section *s, *symtab;    Elf32_Rel *rel, *rel_end;    Elf32_Sym *sym;    int i, type, reloc_type, sym_index;    for(i = 1; i < s1->nb_sections; i++) {        s = s1->sections[i];        if (s->sh_type != SHT_REL)            continue;        /* no need to handle got relocations */        if (s->link != symtab_section)            continue;        symtab = s->link;        rel_end = (Elf32_Rel *)(s->data + s->data_offset);        for(rel = (Elf32_Rel *)s->data;            rel < rel_end;            rel++) {            type = ELF32_R_TYPE(rel->r_info);            switch(type) {#if defined(TCC_TARGET_I386)            case R_386_GOT32:            case R_386_GOTOFF:            case R_386_GOTPC:            case R_386_PLT32:                if (!s1->got)                    build_got(s1);                if (type == R_386_GOT32 || type == R_386_PLT32) {                    sym_index = ELF32_R_SYM(rel->r_info);                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];                    /* look at the symbol got offset. If none, then add one */                    if (type == R_386_GOT32)                        reloc_type = R_386_GLOB_DAT;                    else                        reloc_type = R_386_JMP_SLOT;                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,                                   sym_index);                }                break;#elif defined(TCC_TARGET_ARM)	    case R_ARM_GOT32:            case R_ARM_GOTOFF:            case R_ARM_GOTPC:            case R_ARM_PLT32:                if (!s1->got)                    build_got(s1);                if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {                    sym_index = ELF32_R_SYM(rel->r_info);                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];                    /* look at the symbol got offset. If none, then add one */                    if (type == R_ARM_GOT32)                        reloc_type = R_ARM_GLOB_DAT;                    else                        reloc_type = R_ARM_JUMP_SLOT;                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,                                   sym_index);                }                break;#elif defined(TCC_TARGET_C67)	    case R_C60_GOT32:            case R_C60_GOTOFF:            case R_C60_GOTPC:            case R_C60_PLT32:                if (!s1->got)                    build_got(s1);                if (type == R_C60_GOT32 || type == R_C60_PLT32) {                    sym_index = ELF32_R_SYM(rel->r_info);                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];                    /* look at the symbol got offset. If none, then add one */                    if (type == R_C60_GOT32)                        reloc_type = R_C60_GLOB_DAT;                    else                        reloc_type = R_C60_JMP_SLOT;                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,                                   sym_index);                }                break;#else#error unsupported CPU#endif            default:                break;            }        }    }}static Section *new_symtab(TCCState *s1,                           const char *symtab_name, int sh_type, int sh_flags,                           const char *strtab_name,                            const char *hash_name, int hash_sh_flags){    Section *symtab, *strtab, *hash;    int *ptr, nb_buckets;    symtab = new_section(s1, symtab_name, sh_type, sh_flags);    symtab->sh_entsize = sizeof(Elf32_Sym);    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);    put_elf_str(strtab, "");    symtab->link = strtab;    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);        nb_buckets = 1;    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);    hash->sh_entsize = sizeof(int);    symtab->hash = hash;    hash->link = symtab;    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));    ptr[0] = nb_buckets;    ptr[1] = 1;    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));    return symtab;}/* put dynamic tag */static void put_dt(Section *dynamic, int dt, unsigned long val){    Elf32_Dyn *dyn;    dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));    dyn->d_tag = dt;    dyn->d_un.d_val = val;}static void add_init_array_defines(TCCState *s1, const char *section_name){    Section *s;    long end_offset;    char sym_start[1024];    char sym_end[1024];        snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);    s = find_section(s1, section_name);    if (!s) {        end_offset = 0;        s = data_section;    } else {        end_offset = s->data_offset;    }    add_elf_sym(symtab_section,                 0, 0,                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                s->sh_num, sym_start);    add_elf_sym(symtab_section,                 end_offset, 0,                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                s->sh_num, sym_end);}/* add tcc runtime libraries */static void tcc_add_runtime(TCCState *s1){    char buf[1024];#ifdef CONFIG_TCC_BCHECK    if (do_bounds_check) {        unsigned long *ptr;        Section *init_section;        unsigned char *pinit;        int sym_index;        /* XXX: add an object file to do that */        ptr = section_ptr_add(bounds_section, sizeof(unsigned long));        *ptr = 0;        add_elf_sym(symtab_section, 0, 0,                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                    bounds_section->sh_num, "__bounds_start");        /* add bound check code */        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");        tcc_add_file(s1, buf);#ifdef TCC_TARGET_I386        if (s1->output_type != TCC_OUTPUT_MEMORY) {            /* add 'call __bound_init()' in .init section */            init_section = find_section(s1, ".init");            pinit = section_ptr_add(init_section, 5);            pinit[0] = 0xe8;            put32(pinit + 1, -4);            sym_index = find_elf_sym(symtab_section, "__bound_init");            put_elf_reloc(symtab_section, init_section,                           init_section->data_offset - 4, R_386_PC32, sym_index);        }#endif    }#endif    /* add libc */    if (!s1->nostdlib) {        tcc_add_library(s1, "c");        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");        tcc_add_file(s1, buf);    }    /* add crt end if not memory output */    if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");    }}/* add various standard linker symbols (must be done after the   sections are filled (for example after allocating common   symbols)) */static void tcc_add_linker_symbols(TCCState *s1){    char buf[1024];    int i;    Section *s;    add_elf_sym(symtab_section,                 text_section->data_offset, 0,                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                text_section->sh_num, "_etext");    add_elf_sym(symtab_section,                 data_section->data_offset, 0,                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                data_section->sh_num, "_edata");    add_elf_sym(symtab_section,                 bss_section->data_offset, 0,                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                bss_section->sh_num, "_end");    /* horrible new standard ldscript defines */    add_init_array_defines(s1, ".preinit_array");    add_init_array_defines(s1, ".init_array");    add_init_array_defines(s1, ".fini_array");        /* add start and stop symbols for sections whose name can be       expressed in C */    for(i = 1; i < s1->nb_sections; i++) {        s = s1->sections[i];        if (s->sh_type == SHT_PROGBITS &&            (s->sh_flags & SHF_ALLOC)) {            const char *p;            int ch;            /* check if section name can be expressed in C */            p = s->name;            for(;;) {                ch = *p;                if (!ch)                    break;                if (!isid(ch) && !isnum(ch))                    goto next_sec;                p++;            }            snprintf(buf, sizeof(buf), "__start_%s", s->name);            add_elf_sym(symtab_section,                         0, 0,                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                        s->sh_num, buf);            snprintf(buf, sizeof(buf), "__stop_%s", s->name);            add_elf_sym(symtab_section,                        s->data_offset, 0,                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),                        s->sh_num, buf);        }    next_sec: ;    }}/* name of ELF interpreter */#ifdef __FreeBSD__static char elf_interp[] = "/usr/libexec/ld-elf.so.1";#elsestatic char elf_interp[] = "/lib/ld-linux.so.2";#endifstatic void tcc_output_binary(TCCState *s1, FILE *f,                              const int *section_order){    Section *s;    int i, offset, size;    offset = 0;    for(i=1;i<s1->nb_sections;i++) {        s = s1->sections[section_order[i]];        if (s->sh_type != SHT_NOBITS &&            (s->sh_flags & SHF_ALLOC)) {            while (offset < s->sh_offset) {                fputc(0, f);                offset++;            }            size = s->sh_size;            fwrite(s->data, 1, size, f);            offset += size;        }    }}/* output an ELF file *//* XXX: suppress unneeded sections */int tcc_output_file(TCCState *s1, const char *filename){    Elf32_Ehdr ehdr;    FILE *f;    int fd, mode, ret;    int *section_order;    int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;    unsigned long addr;    Section *strsec, *s;    Elf32_Shdr shdr, *sh;    Elf32_Phdr *phdr, *ph;    Section *interp, *dynamic, *dynstr;    unsigned long saved_dynamic_data_offset;    Elf32_Sym *sym;    int type, file_type;    unsigned long rel_addr, rel_size;        file_type = s1->output_type;    s1->nb_errors = 0;    if (file_type != TCC_OUTPUT_OBJ) {        tcc_add_runtime(s1);    }    phdr = NULL;    section_order = NULL;    interp = NULL;    dynamic = NULL;    dynstr = NULL; /* avoid warning */    saved_dynamic_data_offset = 0; /* avoid warning */        if (file_type != TCC_OUTPUT_OBJ) {        relocate_common_syms();        tcc_add_linker_symbols(s1);        if (!s1->static_link) {            const char *name;            int sym_index, index;            Elf32_Sym *esym, *sym_end;                        if (file_type == TCC_OUTPUT_EXE) {                char *ptr;                /* add interpreter section only if executable */                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);                interp->sh_addralign = 1;                ptr = section_ptr_add(interp, sizeof(elf_interp));                strcpy(ptr, elf_interp);            }                    /* add dynamic symbol table */            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,                                    ".dynstr",                                     ".hash", SHF_ALLOC);            dynstr = s1->dynsym->link;                        /* add dynamic section */            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,                                   SHF_ALLOC | SHF_WRITE);            dynamic->link = dynstr;            dynamic->sh_entsize = sizeof(Elf32_Dyn);                    /* add PLT */            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,                                   SHF_ALLOC | SHF_EXECINSTR);            s1->plt->sh_entsize = 4;

⌨️ 快捷键说明

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