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

📄 outelf32.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
   (void)params;
}

void debug32_typevalue(int32_t type)
{
    int32_t stype, ssize;
    switch (TYM_TYPE(type)) {
        case TY_LABEL:
            ssize = 0;
            stype = STT_NOTYPE;
            break;
        case TY_BYTE:
            ssize = 1;
            stype = STT_OBJECT;
            break;
        case TY_WORD:
            ssize = 2;
            stype = STT_OBJECT;
            break;
        case TY_DWORD:
            ssize = 4;
            stype = STT_OBJECT;
            break;
        case TY_FLOAT:
            ssize = 4;
            stype = STT_OBJECT;
            break;
        case TY_QWORD:
            ssize = 8;
            stype = STT_OBJECT;
            break;
        case TY_TBYTE:
            ssize = 10;
            stype = STT_OBJECT;
            break;
        case TY_OWORD:
            ssize = 8;
            stype = STT_OBJECT;
            break;
        case TY_COMMON:
            ssize = 0;
            stype = STT_COMMON;
            break;
        case TY_SEG:
            ssize = 0;
            stype = STT_SECTION;
            break;
        case TY_EXTERN:
            ssize = 0;
            stype = STT_NOTYPE;
            break;
        case TY_EQU:
            ssize = 0;
            stype = STT_NOTYPE;
            break;
        default:
            ssize = 0;
            stype = STT_NOTYPE;
            break;
    }
    if (stype == STT_OBJECT && lastsym && !lastsym->type) {
        lastsym->size = ssize;
        lastsym->type = stype;
    }
}

void stabs32_output(int type, void *param)
{
    struct symlininfo *s;
    struct linelist *el;
    if (type == TY_STABSSYMLIN) {
        if (debug_immcall) {
            s = (struct symlininfo *)param;
            if (!(sects[s->section]->flags & SHF_EXECINSTR))
                return;         /* we are only interested in the text stuff */
            numlinestabs++;
            el = (struct linelist *)nasm_malloc(sizeof(struct linelist));
            el->info.offset = s->offset;
            el->info.section = s->section;
            el->info.name = s->name;
            el->line = currentline;
            el->filename = stabs_filename;
            el->next = 0;
            if (stabslines) {
                stabslines->last->next = el;
                stabslines->last = el;
            } else {
                stabslines = el;
                stabslines->last = el;
            }
        }
    }
    debug_immcall = 0;
}

#define WRITE_STAB(p,n_strx,n_type,n_other,n_desc,n_value) \
  do {\
    WRITELONG(p,n_strx); \
    WRITECHAR(p,n_type); \
    WRITECHAR(p,n_other); \
    WRITESHORT(p,n_desc); \
    WRITELONG(p,n_value); \
  } while (0)

/* for creating the .stab , .stabstr and .rel.stab sections in memory */

void stabs32_generate(void)
{
    int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
    uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
    char **allfiles;
    int *fileidx;

    struct linelist *ptr;

    ptr = stabslines;

    allfiles = (char **)nasm_malloc(numlinestabs * sizeof(char *));
    for (i = 0; i < numlinestabs; i++)
        allfiles[i] = 0;
    numfiles = 0;
    while (ptr) {
        if (numfiles == 0) {
            allfiles[0] = ptr->filename;
            numfiles++;
        } else {
            for (i = 0; i < numfiles; i++) {
                if (!strcmp(allfiles[i], ptr->filename))
                    break;
            }
            if (i >= numfiles) {
                allfiles[i] = ptr->filename;
                numfiles++;
            }
        }
        ptr = ptr->next;
    }
    strsize = 1;
    fileidx = (int *)nasm_malloc(numfiles * sizeof(int));
    for (i = 0; i < numfiles; i++) {
        fileidx[i] = strsize;
        strsize += strlen(allfiles[i]) + 1;
    }
    mainfileindex = 0;
    for (i = 0; i < numfiles; i++) {
        if (!strcmp(allfiles[i], elf_module)) {
            mainfileindex = i;
            break;
        }
    }

    /* worst case size of the stab buffer would be:
       the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
     */
    sbuf =
        (uint8_t *)nasm_malloc((numlinestabs * 2 + 3) *
                                     sizeof(struct stabentry));

    ssbuf = (uint8_t *)nasm_malloc(strsize);

    rbuf = (uint8_t *)nasm_malloc(numlinestabs * 8 * (2 + 3));
    rptr = rbuf;

    for (i = 0; i < numfiles; i++) {
        strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
    }
    ssbuf[0] = 0;

    stabstrlen = strsize;       /* set global variable for length of stab strings */

    sptr = sbuf;
    ptr = stabslines;
    numstabs = 0;

    if (ptr) {
        /* this is the first stab, its strx points to the filename of the
        the source-file, the n_desc field should be set to the number
        of remaining stabs
        */
        WRITE_STAB(sptr, fileidx[0], 0, 0, 0, strlen(allfiles[0] + 12));

        /* this is the stab for the main source file */
        WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);

        /* relocation table entry */

        /* Since the symbol table has two entries before */
        /* the section symbols, the index in the info.section */
        /* member must be adjusted by adding 2 */

        WRITELONG(rptr, (sptr - sbuf) - 4);
        WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);

        numstabs++;
        currfile = mainfileindex;
    }

    while (ptr) {
        if (strcmp(allfiles[currfile], ptr->filename)) {
            /* oops file has changed... */
            for (i = 0; i < numfiles; i++)
                if (!strcmp(allfiles[i], ptr->filename))
                    break;
            currfile = i;
            WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
                       ptr->info.offset);
            numstabs++;

            /* relocation table entry */
            WRITELONG(rptr, (sptr - sbuf) - 4);
            WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
        }

        WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
        numstabs++;

        /* relocation table entry */

        WRITELONG(rptr, (sptr - sbuf) - 4);
        WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);

        ptr = ptr->next;

    }

    ((struct stabentry *)sbuf)->n_desc = numstabs;

    nasm_free(allfiles);
    nasm_free(fileidx);

    stablen = (sptr - sbuf);
    stabrellen = (rptr - rbuf);
    stabrelbuf = rbuf;
    stabbuf = sbuf;
    stabstrbuf = ssbuf;
}

void stabs32_cleanup(void)
{
    struct linelist *ptr, *del;
    if (!stabslines)
        return;
    ptr = stabslines;
    while (ptr) {
        del = ptr;
        ptr = ptr->next;
        nasm_free(del);
    }
    if (stabbuf)
        nasm_free(stabbuf);
    if (stabrelbuf)
        nasm_free(stabrelbuf);
    if (stabstrbuf)
        nasm_free(stabstrbuf);
}
/* dwarf routines */


void dwarf32_linenum(const char *filename, int32_t linenumber, int32_t segto)
{
    (void)segto;
    dwarf32_findfile(filename);
    debug_immcall = 1;
    currentline = linenumber;
}

/* called from elf_out with type == TY_DEBUGSYMLIN */
void dwarf32_output(int type, void *param)
{
  int ln, aa, inx, maxln, soc;
  struct symlininfo *s;
  struct SAA *plinep;

  (void)type;

  s = (struct symlininfo *)param;
   /* line number info is only gathered for executable sections */
   if (!(sects[s->section]->flags & SHF_EXECINSTR))
     return;
  /* Check if section index has changed */
  if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
  {
     dwarf32_findsect(s->section);
  }
  /* do nothing unless line or file has changed */
  if (debug_immcall)
  {
    ln = currentline - dwarf_csect->line;
    aa = s->offset - dwarf_csect->offset;
    inx = dwarf_clist->line;
    plinep = dwarf_csect->psaa;
    /* check for file change */
    if (!(inx == dwarf_csect->file))
    {
       saa_write8(plinep,DW_LNS_set_file);
       saa_write8(plinep,inx);
       dwarf_csect->file = inx;
    }
    /* check for line change */
    if (ln)
    {
       /* test if in range of special op code */
       maxln = line_base + line_range;
       soc = (ln - line_base) + (line_range * aa) + opcode_base;
       if (ln >= line_base && ln < maxln && soc < 256)
       {
          saa_write8(plinep,soc);
       }
       else
       {
          if (ln)
          {
          saa_write8(plinep,DW_LNS_advance_line);
          saa_wleb128s(plinep,ln);
          }
          if (aa)
          {
          saa_write8(plinep,DW_LNS_advance_pc);
          saa_wleb128u(plinep,aa);
          }
       }
       dwarf_csect->line = currentline;
       dwarf_csect->offset = s->offset;
    }
    /* show change handled */
    debug_immcall = 0;
  }
}


void dwarf32_generate(void)
{
    static const char nasm_signature[] = "NASM " NASM_VER;
    uint8_t *pbuf;
    int indx;
    struct linelist *ftentry;
    struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
    struct SAA *parangesrel, *plinesrel, *pinforel;
    struct sectlist *psect;
    size_t saalen, linepoff, totlen, highaddr;

    /* write epilogues for each line program range */
    /* and build aranges section */
    paranges = saa_init(1L);
    parangesrel = saa_init(1L);
    saa_write16(paranges,2);		/* dwarf version */
    saa_write32(parangesrel, paranges->datalen+4);
    saa_write32(parangesrel, (dwarf_infosym << 8) +  R_386_32); /* reloc to info */
    saa_write32(parangesrel, 0);
    saa_write32(paranges,0);		/* offset into info */
    saa_write8(paranges,4);		/* pointer size */
    saa_write8(paranges,0);		/* not segmented */
    saa_write32(paranges,0);		/* padding */
    /* iterate though sectlist entries */
     psect = dwarf_fsect;
     totlen = 0;
     highaddr = 0;
     for (indx = 0; indx < dwarf_nsections; indx++)
     {
         plinep = psect->psaa;
         /* Line Number Program Epilogue */
         saa_write8(plinep,2);			/* std op 2 */
         saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
         saa_write8(plinep,DW_LNS_extended_op);
         saa_write8(plinep,1);			/* operand length */
         saa_write8(plinep,DW_LNE_end_sequence);
         totlen += plinep->datalen;
         /* range table relocation entry */
         saa_write32(parangesrel, paranges->datalen + 4);
         saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
         saa_write32(parangesrel, (uint32_t) 0);
         /* range table entry */
         saa_write32(paranges,0x0000);		/* range start */
         saa_write32(paranges,sects[psect->section]->len);	/* range length */
         highaddr += sects[psect->section]->len;
         /* done with this entry */
         psect = psect->next;
     }
    saa_write32(paranges,0);		/* null address */
    saa_write32(paranges,0);		/* null length */
    saalen = paranges->datalen;
    arangeslen = saalen + 4;
    arangesbuf = pbuf = nasm_malloc(arangeslen);
    WRITELONG(pbuf,saalen);			/* initial length */
    saa_rnbytes(paranges, pbuf, saalen);
    saa_free(paranges);

    /* build rela.aranges section */
    arangesrellen = saalen = parangesrel->datalen;
    arangesrelbuf = pbuf = nasm_malloc(arangesrellen); 
    saa_rnbytes(parangesrel, pbuf, saalen);
    saa_free(parangesrel);

    /* build pubnames section */
    ppubnames = saa_init(1L);
    saa_write16(ppubnames,3);			/* dwarf version */
    saa_write32(ppubnames,0);			/* offset into info */
    saa_write32(ppubnames,0);			/* space used in info */
    saa_write32(ppubnames,0);			/* end of l

⌨️ 快捷键说明

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