// void __cdecl DiagServiceReadPresentation(int *inBase, DECODED_PRESENTATION *outPresentation)
        // Looks like its actually a presentation
        // See DIDiagservice* functions
        public DiagPreparation(BinaryReader reader, CTFLanguage language, long baseAddress, int bitPosition, ushort modeConfig, ECU parentEcu, DiagService parentDiagService)
        {
            BitPosition       = bitPosition;
            ModeConfig        = modeConfig;
            Language          = language;
            BaseAddress       = baseAddress;
            ParentECU         = parentEcu;
            ParentDiagService = parentDiagService;

            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt32();


            Qualifier           = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            Name_CTF            = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk1                = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk2                = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            AlternativeBitWidth = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            IITOffset           = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            InfoPoolIndex       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            PresPoolIndex       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Field1E             = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            SystemParam         = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1);
            DumpMode            = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            DumpSize            = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            if (DumpMode == 5)
            {
                // dump is actually a string, use
                // CaesarReader.ReadBitflagDumpWithReaderAsString
            }
            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress);

            SizeInBits = GetSizeInBits(reader);
            // PrintDebug();
        }
Beispiel #2
0
        // DIIAddCBFFile

        /*
         *  21 bits active
         *  f [6, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 1],
         */
        public FlashHeader(BinaryReader reader)
        {
            reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin);
            CffHeaderSize = reader.ReadInt32();

            BaseAddress = reader.BaseStream.Position;

            ulong bitFlags = reader.ReadUInt32();

            reader.ReadUInt16(); // unused

            FlashName             = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            FlashGenerationParams = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            Unk3                        = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            Unk4                        = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            FileAuthor                  = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            FileCreationTime            = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            AuthoringToolVersion        = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            FTRAFOVersionString         = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            FTRAFOVersionNumber         = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            CFFVersionString            = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);
            NumberOfFlashAreas          = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            FlashDescriptionTable       = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            DataBlockTableCountProbably = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            DataBlockRefTable           = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            CTFHeaderTable              = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            LanguageBlockLength         = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            NumberOfECURefs             = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            ECURefTable                 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            UnkTableCount               = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            UnkTableProbably            = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);
            Unk15                       = CaesarReader.ReadBitflagUInt8(ref bitFlags, reader);

            DescriptionHeaders = new List <FlashDescriptionHeader>();
            for (int flashDescIndex = 0; flashDescIndex < NumberOfFlashAreas; flashDescIndex++)
            {
                long flashTableEntryAddress = FlashDescriptionTable + BaseAddress + (flashDescIndex * 4);
                reader.BaseStream.Seek(flashTableEntryAddress, SeekOrigin.Begin);

                long flashEntryBaseAddress = FlashDescriptionTable + BaseAddress + reader.ReadInt32();
                FlashDescriptionHeader fdh = new FlashDescriptionHeader(reader, flashEntryBaseAddress);
                DescriptionHeaders.Add(fdh);
            }

            DataBlocks = new List <FlashDataBlock>();
            for (int dataBlockIndex = 0; dataBlockIndex < DataBlockTableCountProbably; dataBlockIndex++)
            {
                long datablockEntryAddress = DataBlockRefTable + BaseAddress + (dataBlockIndex * 4);
                reader.BaseStream.Seek(datablockEntryAddress, SeekOrigin.Begin);

                long           datablockBaseAddress = DataBlockRefTable + BaseAddress + reader.ReadInt32();
                FlashDataBlock fdb = new FlashDataBlock(reader, datablockBaseAddress);
                DataBlocks.Add(fdb);
            }
        }
        public ECUVariantPattern(BinaryReader reader, long baseAddress)
        {
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt32();

            UnkBufferSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            UnkBuffer  = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, UnkBufferSize, baseAddress);
            Unk3       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk4       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk5       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            VendorName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            KwpVendorID = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);
            Unk8        = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            Unk9        = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            Unk10       = CaesarReader.ReadBitflagInt16(ref bitflags, reader);

            Unk11 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk12 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk13 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk14 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk15 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);

            Unk16 = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, 5, baseAddress); // read with a constant size

            Unk17 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk18 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk19 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);
            Unk20 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);

            Unk21 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            Unk22       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Unk23       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            UdsVendorID = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            PatternType = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            VariantID = UdsVendorID == 0 ? KwpVendorID : UdsVendorID;
            // type 3 contains a vendor name
        }
Beispiel #4
0
        public ECUInterfaceSubtype(BinaryReader reader, long baseAddress, int index)
        {
            Index       = index;
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            // we can now properly operate on the interface block
            ulong ctBitflags = reader.ReadUInt32();

            Qualifier       = CaesarReader.ReadBitflagStringWithReader(ref ctBitflags, reader, BaseAddress);
            Name_CTF        = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);

            Unk3 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);
            Unk4 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);

            Unk5 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);
            Unk6 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);
            Unk7 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);

            Unk8  = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);
            Unk9  = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);
            Unk10 = CaesarReader.ReadBitflagInt8(ref ctBitflags, reader); // might be signed
        }
Beispiel #5
0
        public DiagService(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)
        {
            ParentECU   = parentEcu;
            PoolIndex   = poolIndex;
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);

            ulong bitflags        = reader.ReadUInt32();
            ulong bitflagExtended = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            Name_CTF        = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            DataClass_ServiceType        = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);
            DataClass_ServiceTypeShifted = 1 << (DataClass_ServiceType - 1);

            IsExecutable        = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;
            ClientAccessLevel   = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;
            SecurityAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;

            T_ComParam_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            T_ComParam_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Q_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Q_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            R_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            R_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            InputRefNameMaybe = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            U_prep_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            U_prep_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            // array of DWORDs, probably reference to elsewhere
            V_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            V_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            RequestBytes_Count  = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            RequestBytes_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            W_OutPres_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            W_OutPres_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            field50 = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);

            NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); // negative response name
            UnkStr3 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            UnkStr4 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            P_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            P_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            DiagServiceCodeCount  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            DiagServiceCodeOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            S_Count  = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            S_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            bitflags = bitflagExtended;

            X_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            X_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Y_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Y_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Z_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Z_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            if (RequestBytes_Count > 0)
            {
                reader.BaseStream.Seek(baseAddress + RequestBytes_Offset, SeekOrigin.Begin);
                RequestBytes = reader.ReadBytes(RequestBytes_Count);
            }
            else
            {
                RequestBytes = new byte[] { };
            }

            // u_table to u_entries
            InputPreparations = new List <DiagPreparation>();
            for (int prepIndex = 0; prepIndex < U_prep_Count; prepIndex++)
            {
                long presentationTableOffset = baseAddress + U_prep_Offset;
                reader.BaseStream.Seek(presentationTableOffset + (prepIndex * 10), SeekOrigin.Begin);

                // DIOpenDiagService (reads 4, 4, 2 then calls DiagServiceReadPresentation) to build a presentation
                int    prepEntryOffset = reader.ReadInt32();  // file: 0 (DW)
                int    prepEntryBitPos = reader.ReadInt32();  // file: 4 (DW)
                ushort prepEntryMode   = reader.ReadUInt16(); // file: 8 (W)

                DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                //preparation.PrintDebug();
                InputPreparations.Add(preparation);
            }


            OutputPreparations = new List <List <DiagPreparation> >();
            long outPresBaseAddress = BaseAddress + W_OutPres_Offset;

            for (int presIndex = 0; presIndex < W_OutPres_Count; presIndex++)
            {
                reader.BaseStream.Seek(outPresBaseAddress + (presIndex * 8), SeekOrigin.Begin);
                int resultPresentationCount  = reader.ReadInt32();
                int resultPresentationOffset = reader.ReadInt32();

                List <DiagPreparation> ResultPresentationSet = new List <DiagPreparation>();
                for (int presInnerIndex = 0; presInnerIndex < resultPresentationCount; presInnerIndex++)
                {
                    long presentationTableOffset = outPresBaseAddress + resultPresentationOffset;
                    reader.BaseStream.Seek(presentationTableOffset + (presIndex * 10), SeekOrigin.Begin);

                    int    prepEntryOffset = reader.ReadInt32();  // file: 0 (DW)
                    int    prepEntryBitPos = reader.ReadInt32();  // file: 4 (DW)
                    ushort prepEntryMode   = reader.ReadUInt16(); // file: 8 (W)

                    DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                    ResultPresentationSet.Add(preparation);
                }
                OutputPreparations.Add(ResultPresentationSet);
            }

            DiagComParameters = new List <ComParameter>();
            long comParamTableBaseAddress = BaseAddress + T_ComParam_Offset;

            for (int cpIndex = 0; cpIndex < T_ComParam_Count; cpIndex++)
            {
                reader.BaseStream.Seek(comParamTableBaseAddress + (cpIndex * 4), SeekOrigin.Begin);
                int          resultCpOffset     = reader.ReadInt32();
                long         cpEntryBaseAddress = comParamTableBaseAddress + resultCpOffset;
                ComParameter cp = new ComParameter(reader, cpEntryBaseAddress, parentEcu.ECUInterfaces);
                DiagComParameters.Add(cp);
            }

            // DJ_Zugriffsberechtigung_Abgleich
            // DJ_Zugriffsberechtigung
            // DT_Abgasklappe_kontinuierlich
            // FN_HardReset
            // WVC_Implizite_Variantenkodierung_Write

            // NR_Disable_Resp_required noexec
            // DT_Laufzeiten_Resetzaehler_nicht_implementiert exec

            /*
             * if (false && qualifierName.Contains("RVC_SCN_Variantencodierung_VGS_73_Lesen"))
             * {
             *
             *  Console.WriteLine($"{nameof(field50)} : {field50}");
             *  Console.WriteLine($"{nameof(IsExecutable)} : {IsExecutable} {IsExecutable != 0}");
             *  Console.WriteLine($"{nameof(AccessLevel)} : {AccessLevel}");
             *  Console.WriteLine($"{nameof(SecurityAccessLevel)} : {SecurityAccessLevel}");
             *  Console.WriteLine($"{nameof(DataClass)} : {DataClass}");
             *
             *
             *
             *  Console.WriteLine($"{qualifierName} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, Preparation: {U_prep_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");
             *  Console.WriteLine($"at 0x{baseAddress:X}, W @ 0x{W_Offset:X}, DSC @ 0x{DiagServiceCodeOffset:X}");
             *  Console.WriteLine($"ReqBytes: {BitUtility.BytesToHex(RequestBytes)}");
             * }
             */
            //Console.WriteLine($"{qualifierName} - O: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, U: {U_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");


            byte[] dscPool             = parentEcu.ParentContainer.CaesarCFFHeader.DSCPool;
            long   dscTableBaseAddress = BaseAddress + DiagServiceCodeOffset;

            using (BinaryReader dscPoolReader = new BinaryReader(new MemoryStream(dscPool)))
            {
                for (int dscIndex = 0; dscIndex < DiagServiceCodeCount; dscIndex++)
                {
                    reader.BaseStream.Seek(dscTableBaseAddress + (4 * dscIndex), SeekOrigin.Begin);
                    long dscEntryBaseAddress = reader.ReadInt32() + dscTableBaseAddress;
                    reader.BaseStream.Seek(dscEntryBaseAddress, SeekOrigin.Begin);

                    ulong  dscEntryBitflags = reader.ReadUInt16();
                    uint   idk1             = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    uint   idk2             = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    int    dscPoolOffset    = CaesarReader.ReadBitflagInt32(ref dscEntryBitflags, reader);
                    string dscQualifier     = CaesarReader.ReadBitflagStringWithReader(ref dscEntryBitflags, reader, dscEntryBaseAddress);

                    dscPoolReader.BaseStream.Seek(dscPoolOffset * 8, SeekOrigin.Begin);
                    long dscRecordOffset = dscPoolReader.ReadInt32() + parentEcu.ParentContainer.CaesarCFFHeader.DscBlockOffset;
                    int  dscRecordSize   = dscPoolReader.ReadInt32();

                    reader.BaseStream.Seek(dscRecordOffset, SeekOrigin.Begin);

                    // Console.WriteLine($"DSC {qualifierName} @ 0x{dscTableBaseAddress:X8} {idk1}/{idk2} pool @ 0x{dscPoolOffset:X}, name: {dscQualifier}");
                    byte[] dscBytes = reader.ReadBytes(dscRecordSize);
#if DEBUG
                    //string dscName = $"{parentEcu.Qualifier}_{Qualifier}_{dscIndex}.pal";
                    //Console.WriteLine($"Exporting DSC: {dscName}");
                    //File.WriteAllBytes(dscName, dscBytes);
#endif
                    // at this point, the DSC binary is available in dscBytes, intended for use in DSCContext (but is currently unimplemented)
                    // Console.WriteLine($"DSC actual at 0x{dscRecordOffset:X}, size=0x{dscRecordSize:X}\n");
                }
            }
        }
Beispiel #6
0
        public VCFragment(BinaryReader reader, VCDomain parentDomain, long fragmentTable, int fragmentIndex, CTFLanguage language, ECU parentEcu)
        {
            // see DIOpenVarCodeFrag
            ParentDomain = parentDomain;
            ParentECU    = parentEcu;

            long fragmentTableEntry = fragmentTable + (10 * fragmentIndex);

            reader.BaseStream.Seek(fragmentTableEntry, SeekOrigin.Begin);
            // no bitflag required for 10-byte table entry since it is mandatory
            int fragmentNewBaseOffset = reader.ReadInt32();

            ByteBitPos         = reader.ReadInt32();
            ImplementationType = reader.ReadUInt16();

            // Console.WriteLine($"Fragment new base @ 0x{fragmentNewBaseOffset:X}, byteBitPos 0x{fragmentByteBitPos:X}, implementationType: 0x{implementationType:X}");
            long fragmentBaseAddress = fragmentTable + fragmentNewBaseOffset;

            reader.BaseStream.Seek(fragmentBaseAddress, SeekOrigin.Begin);
            ulong fragmentBitflags = reader.ReadUInt32();

            // Console.WriteLine($"Fragment new bitflag @ 0x{fragmentBitflags:X}");

            Name_CTF              = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);
            Description_CTF       = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);
            ReadAccessLevel       = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader);
            WriteAccessLevel      = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader);
            ByteOrder             = CaesarReader.ReadBitflagUInt16(ref fragmentBitflags, reader);
            RawBitLength          = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);
            IttOffset             = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);
            InfoPoolIndex         = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);
            MeaningB              = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);
            MeaningC              = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);
            CCFHandle             = CaesarReader.ReadBitflagInt16(ref fragmentBitflags, reader, -1);
            VarcodeDumpSize       = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);
            VarcodeDump           = CaesarReader.ReadBitflagDumpWithReader(ref fragmentBitflags, reader, VarcodeDumpSize, fragmentBaseAddress);
            SubfragmentCount      = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);
            SubfragmentFileOffset = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);
            Qualifier             = CaesarReader.ReadBitflagStringWithReader(ref fragmentBitflags, reader, fragmentBaseAddress);

            // Console.WriteLine($"{nameof(fragmentName)} : {fragmentName}, child {fragmentNoOfSubFragments} @ 0x{fragmentSubfragmentFileOffset:X} base {fragmentBaseAddress:X}");


            if ((ByteOrder != 0) && (BitLength > 0))
            {
                //throw new Exception("Currently assumes everything is little-endian");
                Console.WriteLine($"WARNING: {Qualifier} (Size: {BitLength}) has an unsupported byte order. Please proceed with caution");
                //PrintDebug(true);
            }


            long subfragmentTableAddress = SubfragmentFileOffset + fragmentBaseAddress;

            Subfragments.Clear();
            for (int subfragmentIndex = 0; subfragmentIndex < SubfragmentCount; subfragmentIndex++)
            {
                reader.BaseStream.Seek(subfragmentTableAddress + (subfragmentIndex * 4), SeekOrigin.Begin);
                long          subfragmentAddress = reader.ReadInt32() + subfragmentTableAddress;
                VCSubfragment subfragment        = new VCSubfragment(reader, this, language, subfragmentAddress);
                Subfragments.Add(subfragment);
            }
            // PrintDebug();
            // Console.WriteLine($"implementation-default : {implementationType:X4} upper: {(implementationType & 0xFF0):X4} lower: {(implementationType & 0xF):X4}");
            FindFragmentSize(reader);
        }