Example #1
0
void outdata(symbol *s)
{
#if HTOD
    return;
#endif
    int seg;
    targ_size_t offset;
    int flags;
    const int codeseg = cseg;

    symbol_debug(s);
#ifdef DEBUG
    debugy && dbg_printf("outdata('%s')\n",s->Sident);
#endif
    //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty);
    //symbol_print(s);

    // Data segment variables are always live on exit from a function
    s->Sflags |= SFLlivexit;

    dt_t *dtstart = s->Sdt;
    s->Sdt = NULL;                      // it will be free'd
    targ_size_t datasize = 0;
    tym_t ty = s->ty();
#if SCPP && TARGET_WINDOS
    if (eecontext.EEcompile)
    {   s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern;
        s->Sseg = UNKNOWN;
        goto Lret;                      // don't output any data
    }
#endif
    if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic)
        objmod->export_symbol(s,0);        // export data definition
    for (dt_t *dt = dtstart; dt; dt = dt->DTnext)
    {
        //printf("\tdt = %p, dt = %d\n",dt,dt->dt);
        switch (dt->dt)
        {   case DT_abytes:
            {   // Put out the data for the string, and
                // reserve a spot for a pointer to that string
                datasize += size(dt->Dty);      // reserve spot for pointer to string
#if TARGET_SEGMENTED
                if (tybasic(dt->Dty) == TYcptr)
                {   dt->DTseg = codeseg;
                    dt->DTabytes += Offset(codeseg);
                    goto L1;
                }
                else if (tybasic(dt->Dty) == TYfptr &&
                         dt->DTnbytes > config.threshold)
                {
                    targ_size_t foffset;
                    dt->DTseg = objmod->fardata(s->Sident,dt->DTnbytes,&foffset);
                    dt->DTabytes += foffset;
                L1:
                    objmod->write_bytes(SegData[dt->DTseg],dt->DTnbytes,dt->DTpbytes);
                    break;
                }
                else
#endif
                {
                    dt->DTabytes += objmod->data_readonly(dt->DTpbytes,dt->DTnbytes,&dt->DTseg);
                }
                break;
            }
            case DT_ibytes:
                datasize += dt->DTn;
                break;
            case DT_nbytes:
                //printf("DT_nbytes %d\n", dt->DTnbytes);
                datasize += dt->DTnbytes;
                break;

            case DT_azeros:
                /* A block of zeros
                 */
                //printf("DT_azeros %d\n", dt->DTazeros);
            case_azeros:
                datasize += dt->DTazeros;
                if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat &&
                    (s->Sseg == UNKNOWN || s->Sseg <= UDATA))
                {   /* first and only, so put in BSS segment
                     */
                    switch (ty & mTYLINK)
                    {
#if TARGET_SEGMENTED
                        case mTYfar:                    // if far data
                            s->Sseg = objmod->fardata(s->Sident,datasize,&s->Soffset);
                            s->Sfl = FLfardata;
                            break;

                        case mTYcs:
                            s->Sseg = codeseg;
                            Offset(codeseg) = _align(datasize,Offset(codeseg));
                            s->Soffset = Offset(codeseg);
                            Offset(codeseg) += datasize;
                            s->Sfl = FLcsdata;
                            break;
#endif
                        case mTYthreadData:
                            assert(config.objfmt == OBJ_MACH && I64);
                        case mTYthread:
                        {   seg_data *pseg = objmod->tlsseg_bss();
                            s->Sseg = pseg->SDseg;
                            objmod->data_start(s, datasize, pseg->SDseg);
                            if (config.objfmt == OBJ_OMF)
                                pseg->SDoffset += datasize;
                            else
                                objmod->lidata(pseg->SDseg, pseg->SDoffset, datasize);
                            s->Sfl = FLtlsdata;
                            break;
                        }
                        default:
                            s->Sseg = UDATA;
                            objmod->data_start(s,datasize,UDATA);
                            objmod->lidata(s->Sseg,s->Soffset,datasize);
                            s->Sfl = FLudata;           // uninitialized data
                            break;
                    }
                    assert(s->Sseg && s->Sseg != UNKNOWN);
                    if (s->Sclass == SCglobal || (s->Sclass == SCstatic && config.objfmt != OBJ_OMF)) // if a pubdef to be done
                        objmod->pubdefsize(s->Sseg,s,s->Soffset,datasize);   // do the definition
                    searchfixlist(s);
                    if (config.fulltypes &&
                        !(s->Sclass == SCstatic && funcsym_p)) // not local static
                        cv_outsym(s);
#if SCPP
                    out_extdef(s);
#endif
                    goto Lret;
                }
                break;
            case DT_common:
                assert(!dt->DTnext);
                outcommon(s,dt->DTazeros);
                goto Lret;

            case DT_xoff:
            {   symbol *sb = dt->DTsym;

                if (tyfunc(sb->ty()))
#if SCPP
                    nwc_mustwrite(sb);
#else
                    ;
#endif
                else if (sb->Sdt)               // if initializer for symbol
{ if (!s->Sseg) s->Sseg = DATA;
                    outdata(sb);                // write out data for symbol
}
            }
            case DT_coff:
                datasize += size(dt->Dty);
                break;
            default:
#ifdef DEBUG
                dbg_printf("dt = %p, dt = %d\n",dt,dt->dt);
#endif
                assert(0);
        }
    }
Example #2
0
void outdata(symbol *s)
{
#if HTOD
    return;
#endif
    dt_t *dtstart,*dt;
    targ_size_t datasize,a;
    int seg;
    targ_size_t offset;
    int flags;
    char *p;
    tym_t ty;
    int tls;

    symbol_debug(s);
#ifdef DEBUG
    debugy && dbg_printf("outdata('%s')\n",s->Sident);
#endif
    //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty);
    //symbol_print(s);

    // Data segment variables are always live on exit from a function
    s->Sflags |= SFLlivexit;

    dtstart = s->Sdt;
    s->Sdt = NULL;                      // it will be free'd
#if SCPP && TARGET_WINDOS
    if (eecontext.EEcompile)
    {   s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern;
        s->Sseg = UNKNOWN;
        goto Lret;                      // don't output any data
    }
#endif
    datasize = 0;
    tls = 0;
    ty = s->ty();
    if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic)
        obj_export(s,0);        // export data definition
    for (dt = dtstart; dt; dt = dt->DTnext)
    {
        //printf("dt = %p, dt = %d\n",dt,dt->dt);
        switch (dt->dt)
        {   case DT_abytes:
            {   // Put out the data for the string, and
                // reserve a spot for a pointer to that string
#if ELFOBJ || MACHOBJ
                datasize += size(dt->Dty);
                dt->DTabytes += elf_data_cdata(dt->DTpbytes,dt->DTnbytes,&dt->DTseg);
#else
                targ_size_t *poffset;
                datasize += size(dt->Dty);
                if (tybasic(dt->Dty) == TYcptr)
                {   seg = cseg;
                    poffset = &Coffset;
                }
#if SCPP
                else if (tybasic(dt->Dty) == TYfptr &&
                         dt->DTnbytes > config.threshold)
                {
                    seg = obj_fardata(s->Sident,dt->DTnbytes,&offset);
                    poffset = &offset;
                }
#endif
                else
                {   seg = DATA;
                    poffset = &Doffset;
                }
                dt->DTseg = seg;
                dt->DTabytes += *poffset;
                obj_bytes(seg,*poffset,dt->DTnbytes,dt->DTpbytes);
                *poffset += dt->DTnbytes;
#endif
                break;
            }
            case DT_ibytes:
                datasize += dt->DTn;
                break;
            case DT_nbytes:
                //printf("DT_nbytes %d\n", dt->DTnbytes);
                datasize += dt->DTnbytes;
                break;
            case DT_symsize:
#if MARS
                assert(0);
#else
                dt->DTazeros = type_size(s->Stype);
#endif
                goto case_azeros;
            case DT_azeros:
                /* A block of zeros
                 */
                //printf("DT_azeros %d\n", dt->DTazeros);
            case_azeros:
                datasize += dt->DTazeros;
                if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat)
                {   /* first and only, so put in BSS segment
                     */
                    switch (ty & mTYLINK)
                    {
#if OMFOBJ
                        case mTYfar:                    // if far data
                            seg = obj_fardata(s->Sident,datasize,&s->Soffset);
                            s->Sfl = FLfardata;
                            break;
#endif
                        case mTYcs:
                            seg = cseg;
                            Coffset = align(datasize,Coffset);
                            s->Soffset = Coffset;
                            Coffset += datasize;
                            s->Sfl = FLcsdata;
                            break;
                        case mTYthread:
                        {   seg_data *pseg = obj_tlsseg_bss();
#if ELFOBJ || MACHOBJ
                            s->Sseg = pseg->SDseg;
                            elf_data_start(s, datasize, pseg->SDseg);
                            obj_lidata(pseg->SDseg, pseg->SDoffset, datasize);
#else
                            targ_size_t TDoffset = pseg->SDoffset;
                            TDoffset = align(datasize,TDoffset);
                            s->Soffset = TDoffset;
                            TDoffset += datasize;
                            pseg->SDoffset = TDoffset;
#endif
                            seg = pseg->SDseg;
                            s->Sfl = FLtlsdata;
                            tls = 1;
                            break;
                        }
                        default:
#if ELFOBJ || MACHOBJ
                            seg = elf_data_start(s,datasize,UDATA);
                            obj_lidata(s->Sseg,s->Soffset,datasize);
#else
                            seg = UDATA;
                            UDoffset = align(datasize,UDoffset);
                            s->Soffset = UDoffset;
                            UDoffset += datasize;
#endif
                            s->Sfl = FLudata;           // uninitialized data
                            break;
                    }
#if ELFOBJ || MACHOBJ
                    assert(s->Sseg != UNKNOWN);
                    if (s->Sclass == SCglobal || s->Sclass == SCstatic)
                        objpubdef(s->Sseg,s,s->Soffset);        /* do the definition    */
                                            /* if a pubdef to be done */
#else
                    s->Sseg = seg;
                    if (s->Sclass == SCglobal)          /* if a pubdef to be done */
                        objpubdef(seg,s,s->Soffset);    /* do the definition    */
#endif
                    searchfixlist(s);
                    if (config.fulltypes &&
                        !(s->Sclass == SCstatic && funcsym_p)) // not local static
                        cv_outsym(s);
#if SCPP
                    out_extdef(s);
#endif
                    goto Lret;
                }
                break;
            case DT_common:
                assert(!dt->DTnext);
                outcommon(s,dt->DTazeros);
                goto Lret;

            case DT_xoff:
            {   symbol *sb = dt->DTsym;

                if (tyfunc(sb->ty()))
#if SCPP
                    nwc_mustwrite(sb);
#else
                    ;
#endif
                else if (sb->Sdt)               // if initializer for symbol
                    outdata(sb);                // write out data for symbol
            }
            case DT_coff:
                datasize += size(dt->Dty);
                break;
            case DT_1byte:
                datasize++;
                break;
            default:
#ifdef DEBUG
                dbg_printf("dt = %p, dt = %d\n",dt,dt->dt);
#endif
                assert(0);
        }
    }