示例#1
0
文件: exports.c 项目: Aliandrana/cc65
void PrintImportMap (FILE* F)
/* Print an import map to the given file */
{
    unsigned I;
    const Import* Imp;

    /* Loop over all exports */
    for (I = 0; I < ExpCount; ++I) {

        /* Get the export */
        const Export* Exp = ExpPool [I];

        /* Print the symbol only if there are imports, or if a verbose map
        ** file is requested.
        */
        if (VerboseMap || Exp->ImpCount > 0) {

            /* Print the export */
            fprintf (F,
                     "%s (%s):\n",
                     GetString (Exp->Name),
                     GetObjFileName (Exp->Obj));

            /* Print all imports for this symbol */
            Imp = Exp->ImpList;
            while (Imp) {

                /* Print the import. Beware: The import might be linker
                ** generated, in which case there is no object file and
                ** sometimes no line information.
                */
                const LineInfo* LI = GetImportPos (Imp);
                if (LI) {
                    fprintf (F,
                             "    %-25s %s(%u)\n",
                             GetObjFileName (Imp->Obj),
                             GetSourceName (LI),
                             GetSourceLine (LI));
                } else {
                    fprintf (F,
                             "    %-25s\n",
                             GetObjFileName (Imp->Obj));
                }

                /* Next import */
                Imp = Imp->Next;
            }
        }
    }
    fprintf (F, "\n");
}
示例#2
0
Import* GenImport (const char* Name, unsigned char AddrSize)
/* Generate a new import with the given name and address size and return it */
{
    /* Create a new import */
    Import* I = NewImport (AddrSize, 0);

    /* Read the name */
    I->Name = GetStringId (Name);

    /* Check the address size */
    if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
        /* Beware: This function may be called in cases where the object file
         * is not read completely into memory. In this case, the file list is
         * invalid. Be sure not to access it in this case.
         */
        if (ObjHasFiles (I->Obj)) {
            Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
                   GetString (I->Name),
                   GetSourceFileName (I->Obj, I->Pos.Name),
                   I->Pos.Line,
                   I->AddrSize);
        } else {
            Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
                   GetString (I->Name),
                   GetObjFileName (I->Obj),
                   I->AddrSize);
        }
    }

    /* Return the new import */
    return I;
}
示例#3
0
void PrintDbgModules (FILE* F)
/* Output the modules to a debug info file */
{
    unsigned I;

    /* Output modules */
    for (I = 0; I < CollCount (&ObjDataList); ++I) {

        /* Get this object file */
        const ObjData* O = CollConstAt (&ObjDataList, I);

        /* The main source file is the one at index zero */
        const FileInfo* Source = CollConstAt (&O->Files, 0);

        /* Output the module line */
        fprintf (F,
                 "mod\tid=%u,name=\"%s\",file=%u",
                 I,
                 GetObjFileName (O),
                 Source->Id);

        /* Add library if any */
        if (O->Lib != 0) {
            fprintf (F, ",lib=%u", GetLibId (O->Lib));
        }

        /* Terminate the output line */
        fputc ('\n', F);
    }

}
示例#4
0
static void DumpSection(IDiaSectionContrib *item)
{
    DWORD           sectionNo;
    DWORD           offset;
    DWORD           length;

    item->get_addressSection(&sectionNo);
    item->get_addressOffset(&offset);
    item->get_length(&length);

    //DWORD compilandId;
    //item->get_compilandId(&compilandId);

    const char *sectionType = GetSectionType(item);
    const char *objFileName = GetObjFileName(item);

    if (g_compact) {
        // type | sectionNo | length | offset | objFileId
        int objFileId = InternString(objFileName);
        g_report.AppendFmt("%s|%d|%d|%d|%d\n", sectionType, sectionNo, length, offset, objFileId);
    } else {
        // type | sectionNo | length | offset | objFile
        g_report.AppendFmt("%s|%d|%d|%d|%s\n", sectionType, sectionNo, length, offset, objFileName);
    }
}
示例#5
0
struct Scope* GetObjScope (const ObjData* O, unsigned Id)
/* Get a scope from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Scopes)) {
        Error ("Invalid scope index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Scopes, Id);
}
示例#6
0
struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
/* Get a debug symbol from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->DbgSyms)) {
        Error ("Invalid debug symbol index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->DbgSyms, Id);
}
示例#7
0
struct Export* GetObjExport (const ObjData* O, unsigned Id)
/* Get an export from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Exports)) {
        Error ("Invalid export index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Exports, Id);
}
示例#8
0
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
/* Convert a local string id into a global one and return it. */
{
    if (Index >= O->StringCount) {
        Error ("Invalid string index (%u) in module `%s'",
               Index, GetObjFileName (O));
    }
    return O->Strings[Index];
}
示例#9
0
void PrintImportMap (FILE* F)
/* Print an import map to the given file */
{
    unsigned I;
    const Import* Imp;

    /* Loop over all exports */
    for (I = 0; I < ExpCount; ++I) {

	/* Get the export */
     	const Export* Exp = ExpPool [I];

	/* Print the symbol only if there are imports, or if a verbose map
	 * file is requested.
	 */
	if (VerboseMap || Exp->ImpCount > 0) {

	    /* Print the export */
	    fprintf (F,
	      	     "%s (%s):\n",
	      	     GetString (Exp->Name),
	      	     GetObjFileName (Exp->Obj));

	    /* Print all imports for this symbol */
	    Imp = Exp->ImpList;
	    while (Imp) {

	      	/* Print the import */
	      	fprintf (F,
	      		 "    %-25s %s(%lu)\n",
	      		 GetObjFileName (Imp->Obj),
	      		 GetSourceFileName (Imp->Obj, Imp->Pos.Name),
	      	       	 Imp->Pos.Line);

	      	/* Next import */
	      	Imp = Imp->Next;
	    }
	}
    }
    fprintf (F, "\n");
}
示例#10
0
static void CheckSymType (const Export* E)
/* Check the types for one export */
{
    /* External with matching imports */
    Import* Imp = E->ImpList;
    while (Imp) {
       	if (E->AddrSize != Imp->AddrSize) {
	    /* Export is ZP, import is abs or the other way round */
            const char* ExpAddrSize = AddrSizeToStr (E->AddrSize);
            const char* ImpAddrSize = AddrSizeToStr (Imp->AddrSize);
            const char* ExpObjName  = GetObjFileName (E->Obj);
            const char* ImpObjName  = GetObjFileName (Imp->Obj);
	    if (E->Obj) {
	      	/* User defined export */
       	       	Warning ("Address size mismatch for `%s': Exported from %s, "
			 "%s(%lu) as `%s', import in %s, %s(%lu) as `%s'",
			 GetString (E->Name),
                         ExpObjName,
                         GetSourceFileName (E->Obj, E->Pos.Name),
    			 E->Pos.Line,
                         ExpAddrSize,
                         ImpObjName,
                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
		   	 Imp->Pos.Line,
                         ImpAddrSize);
	    } else {
		/* Export created by the linker */
		Warning ("Address size mismatch for `%s': Symbol is `%s'"
                         ", but imported from %s, %s(%lu) as `%s'",
			 GetString (E->Name),
                         ExpAddrSize,
                         ImpObjName,
                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
			 Imp->Pos.Line,
                         ImpAddrSize);
	    }
	}
	Imp = Imp->Next;
    }
}
示例#11
0
文件: exports.c 项目: Aliandrana/cc65
Import* ReadImport (FILE* F, ObjData* Obj)
/* Read an import from a file and return it */
{
    Import* I;

    /* Read the import address size */
    unsigned char AddrSize = Read8 (F);

    /* Create a new import */
    I = NewImport (AddrSize, Obj);

    /* Read the name */
    I->Name = MakeGlobalStringId (Obj, ReadVar (F));

    /* Read the line infos */
    ReadLineInfoList (F, Obj, &I->DefLines);
    ReadLineInfoList (F, Obj, &I->RefLines);

    /* Check the address size */
    if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
        /* Beware: This function may be called in cases where the object file
        ** is not read completely into memory. In this case, the file list is
        ** invalid. Be sure not to access it in this case.
        */
        if (ObjHasFiles (I->Obj)) {
            const LineInfo* LI = GetImportPos (I);
            Error ("Invalid import size in for `%s', imported from %s(%u): 0x%02X",
                   GetString (I->Name),
                   GetSourceName (LI),
                   GetSourceLine (LI),
                   I->AddrSize);
        } else {
            Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
                   GetString (I->Name),
                   GetObjFileName (I->Obj),
                   I->AddrSize);
        }
    }

    /* Return the new import */
    return I;
}
示例#12
0
文件: exports.c 项目: Aliandrana/cc65
static void CheckSymType (const Export* E)
/* Check the types for one export */
{
    /* External with matching imports */
    Import* I = E->ImpList;
    while (I) {
        if (E->AddrSize != I->AddrSize) {
            /* Export and import address sizes do not match */
            StrBuf ExportLoc = STATIC_STRBUF_INITIALIZER;
            StrBuf ImportLoc = STATIC_STRBUF_INITIALIZER;
            const char* ExpAddrSize = AddrSizeToStr ((unsigned char) E->AddrSize);
            const char* ImpAddrSize = AddrSizeToStr ((unsigned char) I->AddrSize);
            const LineInfo* ExportLI = GetExportPos (E);
            const LineInfo* ImportLI = GetImportPos (I);

            /* Generate strings that describe the location of the im- and
            ** exports. This depends on the place from where they come:
            ** Object file or linker config.
            */
            if (E->Obj) {
                /* The export comes from an object file */
                SB_Printf (&ExportLoc, "%s, %s(%u)",
                           GetString (E->Obj->Name),
                           GetSourceName (ExportLI),
                           GetSourceLine (ExportLI));
            } else {
                SB_Printf (&ExportLoc, "%s(%u)",
                           GetSourceName (ExportLI),
                           GetSourceLine (ExportLI));
            }
            if (I->Obj) {
                /* The import comes from an object file */
                SB_Printf (&ImportLoc, "%s, %s(%u)",
                           GetString (I->Obj->Name),
                           GetSourceName (ImportLI),
                           GetSourceLine (ImportLI));
            } else if (ImportLI) {
                /* The import is linker generated and we have line
                ** information
                */
                SB_Printf (&ImportLoc, "%s(%u)",
                           GetSourceName (ImportLI),
                           GetSourceLine (ImportLI));
            } else {
                /* The import is linker generated and we don't have line
                ** information
                */
                SB_Printf (&ImportLoc, "%s", GetObjFileName (I->Obj));
            }

            /* Output the diagnostic */
            Warning ("Address size mismatch for `%s': "
                     "Exported from %s as `%s', "
                     "import in %s as `%s'",
                     GetString (E->Name),
                     SB_GetConstBuf (&ExportLoc),
                     ExpAddrSize,
                     SB_GetConstBuf (&ImportLoc),
                     ImpAddrSize);

            /* Free the temporary strings */
            SB_Done (&ExportLoc);
            SB_Done (&ImportLoc);
        }
        I = I->Next;
    }
}
示例#13
0
文件: segments.c 项目: cc65/cc65
void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
/* Write the data from the given segment to a file. For expressions, F is
** called (see description of SegWriteFunc above).
*/
{
    unsigned      I;
    int           Sign;
    unsigned long Offs = 0;


    /* Remember the output file and offset for the segment */
    S->OutputName = TgtName;
    S->OutputOffs = (unsigned long) ftell (Tgt);

    /* Loop over all sections in this segment */
    for (I = 0; I < CollCount (&S->Sections); ++I) {

        Section*        Sec = CollAtUnchecked (&S->Sections, I);
        Fragment*       Frag;
        unsigned char   FillVal;

        /* Output were this section is from */
        Print (stdout, 2, "      Section from \"%s\"\n", GetObjFileName (Sec->Obj));

        /* If we have fill bytes, write them now. Beware: If this is the
        ** first section, the fill value is not considered part of the segment
        ** and therefore taken from the memory area.
        */
        FillVal = (I == 0)? S->MemArea->FillVal : S->FillVal;
        Print (stdout, 2, "        Filling 0x%lx bytes with 0x%02x\n",
               Sec->Fill, FillVal);
        WriteMult (Tgt, FillVal, Sec->Fill);
        Offs += Sec->Fill;

        /* Loop over all fragments in this section */
        Frag = Sec->FragRoot;
        while (Frag) {

            /* Output fragment data */
            switch (Frag->Type) {

                case FRAG_LITERAL:
                    WriteData (Tgt, Frag->LitBuf, Frag->Size);
                    break;

                case FRAG_EXPR:
                case FRAG_SEXPR:
                    Sign = (Frag->Type == FRAG_SEXPR);
                    /* Call the users function and evaluate the result */
                    switch (F (Frag->Expr, Sign, Frag->Size, Offs, Data)) {

                        case SEG_EXPR_OK:
                            break;

                        case SEG_EXPR_RANGE_ERROR:
                            Error ("Range error in module '%s', line %u",
                                   GetFragmentSourceName (Frag),
                                   GetFragmentSourceLine (Frag));
                            break;

                        case SEG_EXPR_TOO_COMPLEX:
                            Error ("Expression too complex in module '%s', line %u",
                                   GetFragmentSourceName (Frag),
                                   GetFragmentSourceLine (Frag));
                            break;

                        case SEG_EXPR_INVALID:
                            Error ("Invalid expression in module '%s', line %u",
                                   GetFragmentSourceName (Frag),
                                   GetFragmentSourceLine (Frag));
                            break;

                        default:
                            Internal ("Invalid return code from SegWriteFunc");
                    }
                    break;

                case FRAG_FILL:
                    WriteMult (Tgt, S->FillVal, Frag->Size);
                    break;

                default:
                    Internal ("Invalid fragment type: %02X", Frag->Type);
            }

            /* Update the offset */
            Print (stdout, 2, "        Fragment with 0x%x bytes\n",
                   Frag->Size);
            Offs += Frag->Size;

            /* Next fragment */
            Frag = Frag->Next;
        }
    }
}
示例#14
0
文件: segments.c 项目: 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;
}