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

📄 outelf64.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
        add_sectname("", ".debug_aranges");
        add_sectname(".rela", ".debug_aranges");
        add_sectname("", ".debug_pubnames");
        add_sectname("", ".debug_info");
        add_sectname(".rela", ".debug_info");
        add_sectname("", ".debug_abbrev");
        add_sectname("", ".debug_line");
        add_sectname(".rela", ".debug_line");
        add_sectname("", ".debug_frame");
        add_sectname("", ".debug_loc");
    }

    /*
     * Do the comment.
     */
    *comment = '\0';
    commlen =
        2 + sprintf(comment + 1, "The Netwide Assembler %s", NASM_VER);

    /*
     * Output the ELF header.
     */
    fwrite("\177ELF\2\1\1", 7, 1, elffp);
    fputc(elf_osabi, elffp);
    fputc(elf_abiver, elffp);
    fwrite("\0\0\0\0\0\0\0", 7, 1, elffp);
    fwriteint16_t(ET_REL, elffp);      /* relocatable file */
    fwriteint16_t(EM_X86_64, elffp);      /* processor ID */
    fwriteint32_t(1L, elffp);      /* EV_CURRENT file format version */
    fwriteint64_t(0L, elffp);      /* no entry point */
    fwriteint64_t(0L, elffp);      /* no program header table */
    fwriteint64_t(0x40L, elffp);   /* section headers straight after
                                 * ELF header plus alignment */
    fwriteint32_t(0L, elffp);      /* 386 defines no special flags */
    fwriteint16_t(0x40, elffp);   /* size of ELF header */
    fwriteint16_t(0, elffp);      /* no program header table, again */
    fwriteint16_t(0, elffp);      /* still no program header table */
    fwriteint16_t(sizeof(Elf64_Shdr), elffp);   /* size of section header */
    fwriteint16_t(nsections, elffp);      /* number of sections */
    fwriteint16_t(nsects + 2, elffp);     /* string table section index for
                                         * section header table */

    /*
     * Build the symbol table and relocation tables.
     */
    symtab = elf_build_symtab(&symtablen, &symtablocal);
    for (i = 0; i < nsects; i++)
        if (sects[i]->head)
            sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
                                             sects[i]->head);

    /*
     * Now output the section header table.
     */

    elf_foffs = 0x40 + sizeof(Elf64_Shdr) * nsections;
    align = ((elf_foffs + SEG_ALIGN_1) & ~SEG_ALIGN_1) - elf_foffs;
    elf_foffs += align;
    elf_nsect = 0;
    elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
    elf_section_header(0, 0, 0, NULL, false, 0L, 0, 0, 0, 0);   /* SHN_UNDEF */
    scount = 1;                 /* needed for the stabs debugging to track the symtable section */
    p = shstrtab + 1;
    for (i = 0; i < nsects; i++) {
        elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
                           (sects[i]->type == SHT_PROGBITS ?
                            sects[i]->data : NULL), true,
                           sects[i]->len, 0, 0, sects[i]->align, 0);
        p += strlen(p) + 1;
        scount++;               /* ditto */
    }
    elf_section_header(p - shstrtab, 1, 0, comment, false, (int32_t)commlen, 0, 0, 1, 0);  /* .comment */
    scount++;                   /* ditto */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 3, 0, shstrtab, false, (int32_t)shstrtablen, 0, 0, 1, 0);     /* .shstrtab */
    scount++;                   /* ditto */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 2, 0, symtab, true, symtablen, nsects + 4, symtablocal, 4, 24);    /* .symtab */
    symtabsection = scount;     /* now we got the symtab section index in the ELF file */
    p += strlen(p) + 1;
    elf_section_header(p - shstrtab, 3, 0, strs, true, strslen, 0, 0, 1, 0);    /* .strtab */
    for (i = 0; i < nsects; i++)
        if (sects[i]->head) {
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab,SHT_RELA, 0, sects[i]->rel, true,
                               sects[i]->rellen, nsects + 3, i + 1, 4, 24);
        }
    if (of_elf64.current_dfmt == &df_stabs) {
        /* for debugging information, create the last three sections
           which are the .stab , .stabstr and .rel.stab sections respectively */

        /* this function call creates the stab sections in memory */
        stabs64_generate();

        if ((stabbuf) && (stabstrbuf) && (stabrelbuf)) {
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, 1, 0, stabbuf, false, stablen,
                               nsections - 2, 0, 4, 12);

            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, 3, 0, stabstrbuf, false,
                               stabstrlen, 0, 0, 4, 0);

            p += strlen(p) + 1;
            /* link -> symtable  info -> section to refer to */
            elf_section_header(p - shstrtab, 9, 0, stabrelbuf, false,
                               stabrellen, symtabsection, nsections - 3, 4,
                               16);
        }
    }
    else if (of_elf64.current_dfmt == &df_dwarf) {
            /* for dwarf debugging information, create the ten dwarf sections */

            /* this function call creates the dwarf sections in memory */
            if (dwarf_fsect) dwarf64_generate();

            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
                               arangeslen, 0, 0, 1, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
                               arangesrellen, symtabsection, debug_aranges, 1, 24);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf, false,
                               pubnameslen, 0, 0, 1, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
                               infolen, 0, 0, 1, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
                               inforellen, symtabsection, debug_info, 1, 24);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
                               abbrevlen, 0, 0, 1, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
                               linelen, 0, 0, 1, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
                               linerellen, symtabsection, debug_line, 1, 24);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
                               framelen, 0, 0, 8, 0);
            p += strlen(p) + 1;
            elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
                               loclen, 0, 0, 1, 0);

    }
    fwrite(align_str, align, 1, elffp);

    /*
     * Now output the sections.
     */
    elf_write_sections();

    nasm_free(elf_sects);
    saa_free(symtab);
}

static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
{
    struct SAA *s = saa_init(1L);
    struct Symbol *sym;
    uint8_t entry[24], *p;
    int i;

    *len = *local = 0;

    /*
     * First, an all-zeros entry, required by the ELF spec.
     */
    saa_wbytes(s, NULL, 24L);   /* null symbol table entry */
    *len += 24;
    (*local)++;

    /*
     * Next, an entry for the file name.
     */
    p = entry;
    WRITELONG(p, 1);            /* we know it's 1st entry in strtab */
    WRITESHORT(p, STT_FILE);    /* type FILE */
    WRITESHORT(p, SHN_ABS);
    WRITEDLONG(p, (uint64_t) 0);  /* no value */
    WRITEDLONG(p, (uint64_t) 0);  /* no size either */
    saa_wbytes(s, entry, 24L);
    *len += 24;
    (*local)++;

    /*
     * Now some standard symbols defining the segments, for relocation
     * purposes.
     */
    for (i = 1; i <= nsects; i++) {
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, i);       /* section id */
        WRITEDLONG(p, (uint64_t) 0);        /* offset zero */
        WRITEDLONG(p, (uint64_t) 0);        /* size zero */
        saa_wbytes(s, entry, 24L);
        *len += 24;
        (*local)++;
    }


    /*
     * Now the other local symbols.
     */
    saa_rewind(syms);
    while ((sym = saa_rstruct(syms))) {
        if (sym->type & SYM_GLOBAL)
            continue;
        p = entry;
        WRITELONG(p, sym->strpos);	/* index into symbol string table */
        WRITECHAR(p, sym->type);        /* type and binding */
        WRITECHAR(p, sym->other);	/* visibility */
        WRITESHORT(p, sym->section);    /* index into section header table */
        WRITEDLONG(p, (int64_t)sym->value); /* value of symbol */
        WRITEDLONG(p, (int64_t)sym->size);  /* size of symbol */
        saa_wbytes(s, entry, 24L);
        *len += 24;
        (*local)++;
    }
     /*
      * dwarf needs symbols for debug sections
      * which are relocation targets.
      */  
     if (of_elf64.current_dfmt == &df_dwarf) {
        dwarf_infosym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_info);       /* section id */
        WRITEDLONG(p, (uint64_t) 0);        /* offset zero */
        WRITEDLONG(p, (uint64_t) 0);        /* size zero */
        saa_wbytes(s, entry, 24L);
        *len += 24;
        (*local)++;
        dwarf_abbrevsym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_abbrev);       /* section id */
        WRITEDLONG(p, (uint64_t) 0);        /* offset zero */
        WRITEDLONG(p, (uint64_t) 0);        /* size zero */
        saa_wbytes(s, entry, 24L);
        *len += 24;
        (*local)++;
        dwarf_linesym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_line);       /* section id */
        WRITEDLONG(p, (uint64_t) 0);        /* offset zero */
        WRITEDLONG(p, (uint64_t) 0);        /* size zero */
        saa_wbytes(s, entry, 24L);
        *len += 24;
        (*local)++;
     }

    /*
     * Now the global symbols.
     */
    saa_rewind(syms);
    while ((sym = saa_rstruct(syms))) {
        if (!(sym->type & SYM_GLOBAL))
            continue;
        p = entry;
        WRITELONG(p, sym->strpos);
        WRITECHAR(p, sym->type);        /* type and binding */
        WRITECHAR(p, sym->other);       /* visibility */
        WRITESHORT(p, sym->section);
        WRITEDLONG(p, (int64_t)sym->value);
        WRITEDLONG(p, (int64_t)sym->size);
        saa_wbytes(s, entry, 24L);
        *len += 24;
    }

    return s;
}

static struct SAA *elf_build_reltab(uint64_t *len, struct Reloc *r)
{
    struct SAA *s;
    uint8_t *p, entry[24];

    if (!r)
        return NULL;

    s = saa_init(1L);
    *len = 0;

    while (r) {
        int64_t sym = r->symbol;

        if (sym >= GLOBAL_TEMP_BASE)
        {
           if (of_elf64.current_dfmt == &df_dwarf)
              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
           else   sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
        }
        p = entry;
        WRITEDLONG(p, r->address);
        WRITEDLONG(p, (sym << 32) + r->type);
	WRITEDLONG(p, r->offset);
        saa_wbytes(s, entry, 24L);
        *len += 24;

        r = r->next;
    }

    return s;
}

static void elf_section_header(int name, int type, uint64_t flags,
                               void *data, bool is_saa, uint64_t datalen,
                               int link, int info, int align, int eltsize)
{
    elf_sects[elf_nsect].data = data;
    elf_sects[elf_nsect].len = datalen;
    elf_sects[elf_nsect].is_saa = is_saa;
    elf_nsect++;

    fwriteint32_t((int32_t)name, elffp);
    fwriteint32_t((int32_t)type, elffp);
    fwriteint64_t((int64_t)flags, elffp);
    fwriteint64_t(0L, elffp);      /* no address, ever, in object files */
    fwriteint64_t(type == 0 ? 0L : elf_foffs, elffp);
    fwriteint64_t(datalen, elffp);
    if (data)
        elf_foffs += (datalen + SEG_ALIGN_1) & ~SEG_ALIGN_1;
    fwriteint32_t((int32_t)link, elffp);
    fwriteint32_t((int32_t)info, elffp);
    fwriteint64_t((int64_t)align, elffp);
    fwriteint64_t((int64_t)eltsize, elffp);
}

static void elf_write_sections(void)
{
    int i;
    for (i = 0; i < elf_nsect; i++)
        if (elf_sects[i].data) {
            int32_t len = elf_sects[i].len;
            int32_t reallen = (len + SEG_ALIGN_1) & ~SEG_ALIGN_1;
            int32_t align = reallen - len;
            if (elf_sects[i].is_saa)
                saa_fpwrite(elf_sects[i].data, elffp);
            else
                fwrite(elf_sects[i].data, len, 1, elffp);
            fwrite(align_str, align, 1, elffp);
        }
}

static void elf_sect_write(struct Section *sect, const void *data, size_t len)
{
    saa_wbytes(sect->data, data, len);
    sect->len += len;
}
static void elf_sect_writeaddr(struct Section *sect, int64_t data, size_t len)
{
    saa_writeaddr(sect->data, data, len);
    sect->len += len;
}

static int32_t elf_segbase(int32_t segment)
{
    return segment;
}

static int elf_directive(char *directive, char *value, int pass)
{
    bool err;
    int64_t n;
    char *p;

    if (!strcmp(directive, "osabi")) {
	if (pass == 2)
	    return 1;		/* ignore in pass 2 */

	n = readnum(value, &err);
	if (err) {
	    error(ERR_NONFATAL, "`osabi' directive requires a parameter");
	    return 1;
	}
	if (n < 0 || n > 255) {
	    error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
	    return 1;
	}
	elf_osabi  = n;
	elf_abiver = 0;

	if ((p = strchr(value,',')) == NULL)
	    return 1;

	n = readnum(p+1, &err);
	if (err || n < 0 || n > 255) {
	    error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
	    return 1;
	}
	
	elf_abiver = n;

⌨️ 快捷键说明

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