Example #1
0
Fragment* GenFragment (unsigned char Type, unsigned short Len)
/* Generate a new fragment, add it to the current segment and return it. */
{
    /* Create the new fragment */
    Fragment* F = NewFragment (Type, Len);

    /* Insert the fragment into the current segment */
    if (ActiveSeg->Root) {
    	ActiveSeg->Last->Next = F;
    	ActiveSeg->Last = F;
    } else {
    	ActiveSeg->Root = ActiveSeg->Last = F;
    }
    ++ActiveSeg->FragCount;

    /* Add this fragment to the current listing line */
    if (LineCur) {
	if (LineCur->FragList == 0) {
	    LineCur->FragList = F;
	} else {
       	    LineCur->FragLast->LineList = F;
     	}
     	LineCur->FragLast = F;
    }

    /* Increment the program counter */
    ActiveSeg->PC += F->Len;
    if (OrgPerSeg) {
        /* Relocatable mode is switched per segment */
        if (!ActiveSeg->RelocMode) {
            ActiveSeg->AbsPC += F->Len;
        }
    } else {
        /* Relocatable mode is switched globally */
        if (!RelocMode) {
            AbsPC += F->Len;
        }
    }

    /* Return the fragment */
    return F;
}
Example #2
0
File: segments.c Project: cc65/cc65
Section* ReadSection (FILE* F, ObjData* O)
/* Read a section from a file */
{
    unsigned      Name;
    unsigned      Size;
    unsigned long Alignment;
    unsigned char Type;
    unsigned      FragCount;
    Segment*      S;
    Section*      Sec;

    /* Read the segment data */
    (void) Read32 (F);          /* File size of data */
    Name      = MakeGlobalStringId (O, ReadVar (F));    /* Segment name */
                ReadVar (F);    /* Segment flags (currently unused) */
    Size      = ReadVar (F);    /* Size of data */
    Alignment = ReadVar (F);    /* Alignment */
    Type      = Read8 (F);      /* Segment type */
    FragCount = ReadVar (F);    /* Number of fragments */


    /* Print some data */
    Print (stdout, 2,
           "Module '%s': Found segment '%s', size = %u, alignment = %lu, type = %u\n",
           GetObjFileName (O), GetString (Name), Size, Alignment, Type);

    /* Get the segment for this section */
    S = GetSegment (Name, Type, GetObjFileName (O));

    /* Allocate the section we will return later */
    Sec = NewSection (S, Alignment, Type);

    /* Remember the object file this section was from */
    Sec->Obj = O;

    /* Set up the combined segment alignment */
    if (Sec->Alignment > 1) {
        Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment);
        if (Alignment > MAX_ALIGNMENT) {
            Error ("Combined alignment for segment '%s' is %lu which exceeds "
                   "%lu. Last module requiring alignment was '%s'.",
                   GetString (Name), Alignment, MAX_ALIGNMENT,
                   GetObjFileName (O));
        } else if (Alignment >= LARGE_ALIGNMENT) {
            Warning ("Combined alignment for segment '%s' is suspiciously "
                     "large (%lu). Last module requiring alignment was '%s'.",
                     GetString (Name), Alignment, GetObjFileName (O));
        }
        S->Alignment = Alignment;
    }

    /* Start reading fragments from the file and insert them into the section . */
    while (FragCount--) {

        Fragment* Frag;

        /* Read the fragment type */
        unsigned char Type = Read8 (F);

        /* Extract the check mask from the type */
        unsigned char Bytes = Type & FRAG_BYTEMASK;
        Type &= FRAG_TYPEMASK;

        /* Handle the different fragment types */
        switch (Type) {

            case FRAG_LITERAL:
                Frag = NewFragment (Type, ReadVar (F), Sec);
                ReadData (F, Frag->LitBuf, Frag->Size);
                break;

            case FRAG_EXPR:
            case FRAG_SEXPR:
                Frag = NewFragment (Type, Bytes, Sec);
                Frag->Expr = ReadExpr (F, O);
                break;

            case FRAG_FILL:
                /* Will allocate memory, but we don't care... */
                Frag = NewFragment (Type, ReadVar (F), Sec);
                break;

            default:
                Error ("Unknown fragment type in module '%s', segment '%s': %02X",
                       GetObjFileName (O), GetString (S->Name), Type);
                /* NOTREACHED */
                return 0;
        }

        /* Read the line infos into the list of the fragment */
        ReadLineInfoList (F, O, &Frag->LineInfos);

        /* Remember the module we had this fragment from */
        Frag->Obj = O;
    }

    /* Return the section */
    return Sec;
}