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

📄 outelf32.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
                               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, 12);
            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, 12);
            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[16], *p;
    int i;

    *len = *local = 0;

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

    /*
     * Next, an entry for the file name.
     */
    p = entry;
    WRITELONG(p, 1);            /* we know it's 1st entry in strtab */
    WRITELONG(p, 0);            /* no value */
    WRITELONG(p, 0);            /* no size either */
    WRITESHORT(p, STT_FILE);    /* type FILE */
    WRITESHORT(p, SHN_ABS);
    saa_wbytes(s, entry, 16L);
    *len += 16;
    (*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 */
        WRITELONG(p, 0);        /* offset zero */
        WRITELONG(p, 0);        /* size zero */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, i);       /* section id */
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*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);
        WRITELONG(p, sym->value);
        WRITELONG(p, sym->size);
        WRITECHAR(p, sym->type);        /* type and binding */
        WRITECHAR(p, sym->other);       /* visibility */
        WRITESHORT(p, sym->section);
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*local)++;
    }
     /*
      * dwarf needs symbols for debug sections
      * which are relocation targets.
      */  
//*** fix for 32 bit
     if (of_elf32.current_dfmt == &df_dwarf) {
        dwarf_infosym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITELONG(p, (uint32_t) 0);        /* offset zero */
        WRITELONG(p, (uint32_t) 0);        /* size zero */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_info);       /* section id */
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*local)++;
        dwarf_abbrevsym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITELONG(p, (uint32_t) 0);        /* offset zero */
        WRITELONG(p, (uint32_t) 0);        /* size zero */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_abbrev);       /* section id */
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*local)++;
        dwarf_linesym = *local;
        p = entry;
        WRITELONG(p, 0);        /* no symbol name */
        WRITELONG(p, (uint32_t) 0);        /* offset zero */
        WRITELONG(p, (uint32_t) 0);        /* size zero */
        WRITESHORT(p, STT_SECTION);       /* type, binding, and visibility */
        WRITESHORT(p, debug_line);       /* section id */
        saa_wbytes(s, entry, 16L);
        *len += 16;
        (*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);
        WRITELONG(p, sym->value);
        WRITELONG(p, sym->size);
        WRITECHAR(p, sym->type);        /* type and binding */
        WRITECHAR(p, sym->other);       /* visibility */
        WRITESHORT(p, sym->section);
        saa_wbytes(s, entry, 16L);
        *len += 16;
    }

    return s;
}

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

    if (!r)
        return NULL;

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

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

        if (sym >= GLOBAL_TEMP_BASE)
        {
           if (of_elf32.current_dfmt == &df_dwarf)
              sym += -GLOBAL_TEMP_BASE + (nsects + 5) + nlocals;
           else   sym += -GLOBAL_TEMP_BASE + (nsects + 2) + nlocals;
        }

        p = entry;
        WRITELONG(p, r->address);
        WRITELONG(p, (sym << 8) + r->type);
        saa_wbytes(s, entry, 8L);
        *len += 8;

        r = r->next;
    }

    return s;
}

static void elf_section_header(int name, int type, int flags,
                               void *data, bool is_saa, int32_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);
    fwriteint32_t((int32_t)flags, elffp);
    fwriteint32_t(0L, elffp);      /* no address, ever, in object files */
    fwriteint32_t(type == 0 ? 0L : elf_foffs, elffp);
    fwriteint32_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);
    fwriteint32_t((int32_t)align, elffp);
    fwriteint32_t((int32_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 uint8_t *data, uint32_t len)
{
    saa_wbytes(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;
	return 1;
    }
	
    return 0;
}

static void elf_filename(char *inname, char *outname, efunc error)
{
    strcpy(elf_module, inname);
    standard_extension(inname, outname, ".o", error);
}

extern macros_t elf_stdmac[];

static int elf_set_info(enum geninfo type, char **val)
{
    (void)type;
    (void)val;
    return 0;
}
static struct dfmt df_dwarf = {
    "ELF32 (i386) dwarf debug format for Linux",
    "dwarf",
    debug32_init,
    dwarf32_linenum,
    debug32_deflabel,
    debug32_directive,
    debug32_typevalue,
    dwarf32_output,
    dwarf32_cleanup
};
static struct dfmt df_stabs = {
    "ELF32 (i386) stabs debug format for Linux",
    "stabs",
    debug32_init,
    stabs32_linenum,
    debug32_deflabel,
    debug32_directive,
    debug32_typevalue,
    stabs32_output,
    stabs32_cleanup
};

struct dfmt *elf32_debugs_arr[3] = { &df_stabs, &df_dwarf, NULL };

struct ofmt of_elf32 = {
    "ELF32 (i386) object files (e.g. Linux)",
    "elf32",
    NULL,
    elf32_debugs_arr,
    &null_debug_form,
    elf_stdmac,
    elf_init,
    elf_set_info,
    elf_out,
    elf_deflabel,
    elf_section_names,
    elf_segbase,
    elf_directive,
    elf_filename,
    elf_cleanup
};

struct ofmt of_elf = {
    "ELF (short name for ELF32) ",
    "elf",
    NULL,
    elf32_debugs_arr,
    &null_debug_form,
    elf_stdmac,
    elf_init,
    elf_set_info,
    elf_out,
    elf_deflabel,
    elf_section_names,
    elf_segbase,
    elf_directive,
    elf_filename,
    elf_cleanup
};
/* again, the stabs debugging stuff (code) */

void debug32_init(struct ofmt *of, void *id, FILE * fp, efunc error)
{
    (void)of;
    (void)id;
    (void)fp;
    (void)error;
}

void stabs32_linenum(const char *filename, int32_t linenumber, int32_t segto)
{
    (void)segto;

    if (!stabs_filename) {
        stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
        strcpy(stabs_filename, filename);
    } else {
        if (strcmp(stabs_filename, filename)) {
            /* yep, a memory leak...this program is one-shot anyway, so who cares...
               in fact, this leak comes in quite handy to maintain a list of files
               encountered so far in the symbol lines... */

            /* why not nasm_free(stabs_filename); we're done with the old one */

            stabs_filename = (char *)nasm_malloc(strlen(filename) + 1);
            strcpy(stabs_filename, filename);
        }
    }
    debug_immcall = 1;
    currentline = linenumber;
}

void debug32_deflabel(char *name, int32_t segment, int64_t offset, int is_global,
                    char *special)
{
   (void)name;
   (void)segment;
   (void)offset;
   (void)is_global;
   (void)special;
}

void debug32_directive(const char *directive, const char *params)
{
   (void)directive;

⌨️ 快捷键说明

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