Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; Export* E; /* Read the type */ unsigned char Type = Read8 (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = GET_EXP_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; unsigned I; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte * which contains the type and the priority. In memory, we will use * an array of types which contain the priority. This array was * cleared by the constructor (NewExport), so we must only set the * fields that contain values. */ for (I = 0; I < ConDesCount; ++I) { unsigned ConDesType = CD_GET_TYPE (ConDes[I]); unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]); E->ConDes[ConDesType] = ConDesPrio; } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (IS_EXP_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Last is the file position where the definition was done */ ReadFilePos (F, &E->Pos); /* Return the new export */ return E; }
Export* CreateConstExport (unsigned Name, long Value) /* Create an export for a literal date */ { /* Create a new export */ Export* E = NewExport (EXP_CONST | EXP_EQUATE, ADDR_SIZE_ABS, Name, 0); /* Assign the value */ E->Expr = LiteralExpr (Value, 0); /* Insert the export */ InsertExport (E); /* Return the new export */ return E; }
ExprNode* SectionExpr (Section* Sec, long Offs, ObjData* O) /* Return an expression tree that encodes an offset into a section */ { ExprNode* Root; ExprNode* Expr = NewExprNode (O, EXPR_SECTION); Expr->V.Sec = Sec; if (Offs != 0) { Root = NewExprNode (O, EXPR_PLUS); Root->Left = Expr; Root->Right = LiteralExpr (Offs, O); } else { Root = Expr; } return Root; }
ExprNode* SegmentExpr (Segment* Seg, long Offs, ObjData* O) /* Return an expression tree that encodes an offset into a segment */ { ExprNode* Root; ExprNode* Expr = NewExprNode (O, EXPR_SEGMENT); Expr->V.Seg = Seg; if (Offs != 0) { Root = NewExprNode (O, EXPR_PLUS); Root->Left = Expr; Root->Right = LiteralExpr (Offs, O); } else { Root = Expr; } return Root; }
ExprNode* MemoryExpr (MemoryArea* Mem, long Offs, ObjData* O) /* Return an expression tree that encodes an offset into a memory area */ { ExprNode* Root; ExprNode* Expr = NewExprNode (O, EXPR_MEMAREA); Expr->V.Mem = Mem; if (Offs != 0) { Root = NewExprNode (O, EXPR_PLUS); Root->Left = Expr; Root->Right = LiteralExpr (Offs, O); } else { Root = Expr; } return Root; }
Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; unsigned I; Export* E; /* Read the type */ unsigned Type = ReadVar (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = SYM_GET_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte ** which contains the type and the priority. In memory, we will use ** an array of types which contain the priority. */ for (I = 0; I < ConDesCount; ++I) { E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]); } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (SYM_IS_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Read the size */ if (SYM_HAS_SIZE (Type)) { E->Size = ReadVar (F); } /* Last are the locations */ ReadLineInfoList (F, O, &E->DefLines); ReadLineInfoList (F, O, &E->RefLines); /* If this symbol is exported as a condes, and the condes type declares a ** forced import, add this import to the object module. */ for (I = 0; I < CD_TYPE_COUNT; ++I) { const ConDesImport* CDI; if (E->ConDes[I] != CD_PRIO_NONE && (CDI = ConDesGetImport (I)) != 0) { unsigned J; /* Generate a new import, and add it to the module's import list. */ Import* Imp = GenImport (CDI->Name, CDI->AddrSize); Imp->Obj = O; CollAppend (&O->Imports, Imp); /* Add line info for the export that is actually the condes that ** forces the import. Then, add line info for the config. file. ** The export's info is added first because the import pretends ** that it came from the object module instead of the config. file. */ for (J = 0; J < CollCount (&E->DefLines); ++J) { CollAppend (&Imp->RefLines, DupLineInfo (CollAt (&E->DefLines, J))); } CollAppend (&Imp->RefLines, GenLineInfo (&CDI->Pos)); } } /* Return the new export */ return E; }