コード例 #1
0
ファイル: ObjIeeeAsciiRead.cpp プロジェクト: jossk/OrangeC
bool ObjIeeeAscii::SectionAlignment(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int pos = 2;
    int index = ObjUtil::FromHex(buffer, &pos);
    if (buffer[pos++] != ',')
        ThrowSyntax(buffer, ParseType);
    int align = ObjUtil::FromHex(buffer, &pos);
    CheckTerm(buffer + pos);
    ObjSection *sect = GetSection(index);
    if (!sect)
        ThrowSyntax(buffer, ParseType);
    sect->SetAlignment(align);
    return false;
}
コード例 #2
0
ファイル: ObjIeeeAsciiRead.cpp プロジェクト: jossk/OrangeC
bool ObjIeeeAscii::GetOffset(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int pos =3 ;
    char ch = buffer[2];
    int index = 0;
    if (ch != 'G')
        index = ObjUtil::FromHex(buffer, &pos);
    if (buffer[pos++] != ',')
        ThrowSyntax(buffer, ParseType);
    ObjExpression *exp = GetExpression(buffer, &pos);
    CheckTerm(buffer + pos);
    switch(ch)
    {
        case 'G':
            SetStartAddress(file, exp);
            break;
        case 'S':
        {
            ObjSection *sect = GetSection(index);
            if (!sect)
                ThrowSyntax(buffer, ParseType);
            sect->SetSize(exp);
            break;
        }
        case 'L':
        {
            ObjSection *sect = GetSection(index);
            if (!sect)
                ThrowSyntax(buffer, ParseType);
            sect->SetOffset(exp);
            break;
        }
        default:
        {
            ObjSymbol *sym = FindSymbol(ch, index);
            if (!sym)
                ThrowSyntax(buffer, ParseType);
            sym->SetOffset(exp);
            break;
        }
    }		
    return false;
}
コード例 #3
0
ファイル: Real.cpp プロジェクト: bencz/OrangeC
bool Real::ReadSections(ObjFile *file, ObjExpression *start)
{
    size = 0;
    int base = GetFirstSeg(start);
    startOffs = start->Eval(0);
    startSeg = base >> 16;
    for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it)
    {
        if ((*it)->GetName() == ".stack")
        {
            stackSeg = (*it)->GetOffset()->Eval(0) / 16;
            stackOffs = (*it)->GetSize()->Eval(0);
        }
        else
        {
            int n = (*it)->GetOffset()->Eval(0) + (*it)->GetSize()->Eval(0);
            if (n > size)
                size = n;
        }
    }
    data = new unsigned char[size];
    int ofs = 0;
    for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it)
    {
        if ((*it)->GetName() != ".stack")
        {
            ObjSection *sect = *it;
            ObjMemoryManager &m = sect->GetMemoryManager();
            for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it)
            {
                int msize = (*it)->GetSize();
                ObjByte *mdata = (*it)->GetData();
                if (msize)
                {
                    ObjExpression *fixup = (*it)->GetFixup();
                    if (fixup)
                    {
                        int sbase = sect->GetOffset()->Eval(0);
                        int n = GetFixupOffset(fixup, sbase, ofs);
                        int bigEndian = file->GetBigEndian();
                        if (n < 0)
                            Utils::fatal("Fixup offset negative");
                        if (msize == 1)
                        {
                            data[ofs] = n & 0xff;
                        }
                        else if (msize == 2)
                        {
                            if (n >65535)
                                Utils::fatal("16-bit offset outside of segment");
                            if (bigEndian)
                            {
                                data[ofs] = n >> 8;
                                data[ofs + 1] = n & 0xff;
                            }
                            else
                            {
                                data[ofs] = n & 0xff;
                                data[ofs+1] = n >> 8;
                            }
                        }
                        else // msize == 4
                        {
                            if (bigEndian)
                            {
                                data[ofs + 0] = n >> 24;
                                data[ofs + 1] = n >> 16;
                                data[ofs + 2] = n >>  8;
                                data[ofs + 3] = n & 0xff;
                            }
                            else
                            {
                                data[ofs] = n & 0xff;
                                data[ofs+1] = n >> 8;
                                data[ofs+2] = n >> 16;
                                data[ofs+3] = n >> 24;
                            }
                        }
                    }
                    else
                    {
                        if ((*it)->IsEnumerated())
コード例 #4
0
ファイル: ObjIeeeAsciiRead.cpp プロジェクト: jossk/OrangeC
bool ObjIeeeAscii::SectionAttributes(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int pos = 2;
    int index = ObjUtil::FromHex(buffer, &pos);
    if (buffer[pos++] != ',')
        ThrowSyntax(buffer, ParseType);
    ObjInt quals = 0;
    ObjString name;
    while (buffer[pos])
    {
        switch (buffer[pos++])
        {
            case 'A':
                quals |= ObjSection::absolute;
                break;
            case 'B':
                quals |= ObjSection::bit;
                break;
            case 'C':
                quals |= ObjSection::common;
                break;
            case 'E':
                quals |= ObjSection::equal;
                break;
            case 'M':
                quals |= ObjSection::max;
                break;
            case 'N':
                quals |= ObjSection::now;
                break;
            case 'P':
                quals |= ObjSection::postpone;
                break;
            case 'R':
                quals |= ObjSection::rom;
                break;
            case 'S':
                quals |= ObjSection::separate;
                break;
            case 'U':
                quals |= ObjSection::unique;
                break;
            case 'W':
                quals |= ObjSection::ram;
                break;
            case 'x':
                quals |= ObjSection::exec;
                break;
            case 'Z':
                quals |= ObjSection::zero;
                break;
            default:
                --pos;
                name = ParseString(buffer, &pos);
                break;
        }
        if (buffer[pos] != ',')
            break;
        pos++;
    }
    CheckTerm(buffer + pos);
    ObjSection *sect = factory->MakeSection(name, index);
    sect->SetQuals(quals);
    PutSection(index, sect);
    return false;
}
コード例 #5
0
ファイル: test.cpp プロジェクト: doniexun/OrangeC
ObjFile *MakeData(ObjFactory &factory)
{
    ObjFile *rv = factory.MakeFile("test.dat");
    std::time_t x = std::time(0);
    rv->SetFileTime(*std::localtime(&x));
    ObjSourceFile *sf = factory.MakeSourceFile("test.dat");
    rv->Add(sf);
    ObjSourceFile *sf1 = factory.MakeSourceFile("q.dat");
    rv->Add(sf1);
    ObjSection *sect = factory.MakeSection("code");
    codeSection = sect;
    rv->Add(sect);
    ObjSymbol *s1 = factory.MakePublicSymbol("public");
    rv->Add(s1);
    ObjSymbol *s1a = factory.MakePublicSymbol("2public");
    s1a->SetBaseType(BuildType(*rv, factory));
    rv->Add(s1a);
    ObjSymbol *s2 = factory.MakeLocalSymbol("local");
    s2->SetBaseType(factory.MakeType(ObjType::eInt));
    rv->Add(s2);
    ObjSymbol *s3 = factory.MakeAutoSymbol("auto");
    s3->SetOffset(factory.MakeExpression(-8));
    rv->Add(s3);
    ObjSymbol *s4 = factory.MakeExternalSymbol("extern");
    rv->Add(s4);
    ObjMemory *mem = factory.MakeData((ObjByte *)"\x44\x22\x33\x11", 4);
    ObjLineNo *l = factory.MakeLineNo(sf, 3);
    mem->Add(factory.MakeDebugTag(l));
    sect->Add(mem);
    mem = factory.MakeData((ObjByte *)"\xaa\xbb\x33", 3);
    mem->Add(factory.MakeDebugTag(s1));
    sect->Add(mem);
    mem = factory.MakeData((ObjByte *)"\xf1\x9a\x33", 3);
    mem->Add(factory.MakeDebugTag(s2));
    l = factory.MakeLineNo(sf1, 4);
    mem->Add(factory.MakeDebugTag(l));
    sect->Add(mem);
    mem = factory.MakeData((ObjByte *)"\x32\x17\x33", 3);
    mem->Add(factory.MakeDebugTag(s3));
    sect->Add(mem);
    ObjExpression *left = factory.MakeExpression(s4);
    ObjExpression *right = factory.MakeExpression(7);
    mem = factory.MakeFixup(factory.MakeExpression(ObjExpression::eAdd, left, right), 4);
    sect->Add(mem);
    mem = factory.MakeData((ObjByte *)"\x55\x44\x33", 3);
    mem->Add(factory.MakeDebugTag(s4));
    mem->Add(factory.MakeDebugTag(s1a));
    sect->Add(mem);
    BuildBrowse(*rv, factory, l);
    
    ObjExportSymbol *es = factory.MakeExportSymbol("export");
    es->SetExternalName("myexport");
    es->SetByOrdinal(false);
    rv->Add(es);
    ObjExportSymbol *es1 = factory.MakeExportSymbol("export1");
    es1->SetOrdinal(500);
    es1->SetByOrdinal(true);
    rv->Add(es1);
    ObjImportSymbol *is = factory.MakeImportSymbol("import");
    is->SetExternalName("myimport");
    is->SetDllName("mydll");
    rv->Add(is);
    ObjImportSymbol *is1 = factory.MakeImportSymbol("import1");
    is1->SetByOrdinal(true);
    is1->SetOrdinal(512);
    is1->SetDllName("mydll");
    rv->Add(is1);
    return rv;
}
コード例 #6
0
ファイル: CoffFile.cpp プロジェクト: NoSuchProcess/OrangeC
ObjFile *CoffFile::ConvertToObject(std::string outputName, ObjFactory &factory)
{
    ObjFile *fil = new ObjFile(outputName);
    std::vector<ObjSection *> objectSections;
    std::map<int, ObjSymbol *> externalMapping;
    // Create the sections;
    for (int i=0; i < header.NumberOfSections; i++)
    {
        if (!(sections[i].Characteristics & (IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_LNK_INFO)) && strnicmp(sections[i].Name, ".debug", 6))
        {
            std::string sectname = GetSectionName(i);
            ObjSection * sect = factory.MakeSection(sectname);
            CoffSectionAux *aux = (CoffSectionAux *)& sectionSymbols[i][1];
            sect->SetSize(new ObjExpression(aux->Length));
            sect->SetAlignment(IMAGE_SCN_ALIGN(sections[i].Characteristics));
            sect->SetQuals(GetSectionQualifiers(i));
            fil->Add(sect);
            objectSections.push_back(sect);
        }
        else
        {
            objectSections.push_back(NULL);
        }
    }
    // dump comdefs
    for (int i=1; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1)
    {
        if (symbols[i].SectionNumber > header.NumberOfSections && symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].Value)
        {
            char *sname = symbols[i].Name;
            std::string symbolName;
            if (*(unsigned *)sname == 0)
            {
                symbolName = strings + *(unsigned *)(sname + 4); 
            }            
            else
            {
                symbolName = symbols[i].Name;
                if (symbolName.size() > 8)
                    symbolName = symbolName.substr(0, 8);
            }
            symbolName = std::string("vsb") + symbolName;
            ObjSection * sect = factory.MakeSection(symbolName);
            sect->SetSize(new ObjExpression(symbols[i].Value));
            sect->SetAlignment(8);
            sect->SetQuals(ObjSection::ram | ObjSection::max | ObjSection::virt);
            fil->Add(sect);
            objectSections.push_back(sect);
        }
    }
    // create the symbols
    for (int i=0; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1)
    {
        if (symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].SectionNumber <= header.NumberOfSections)
        {
            if (symbols[i].SectionNumber <= 0 || (((CoffSectionAux *)&sectionSymbols[symbols[i].SectionNumber-1][1])->Selection <= 1))
            {
                char *sname = symbols[i].Name;
                std::string symbolName;
                if (*(unsigned *)sname == 0)
                {
                    symbolName = strings + *(unsigned *)(sname + 4); 
                    if (symbolName == "_WinMain@16")
                        symbolName = "WinMain";
                }            
                else
                {
                    symbolName = symbols[i].Name;
                    if (symbolName.size() > 8)
                        symbolName = symbolName.substr(0, 8);
                }
                if (symbols[i].SectionNumber == -1)
                {
                    ObjSymbol *symbol = factory.MakePublicSymbol(symbolName);
                    ObjExpression *exp = new ObjExpression(symbols[i].Value);
                    symbol->SetOffset(exp);       
                    fil->Add(symbol);
                }
                else if (symbols[i].SectionNumber)
                {
                    ObjSymbol *symbol = factory.MakePublicSymbol(symbolName);
                    ObjExpression *exp = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[i].SectionNumber-1]), new ObjExpression(symbols[i].Value));
                    symbol->SetOffset(exp);       
                    fil->Add(symbol);
                }
                else
                {
                    ObjSymbol *symbol = factory.MakeExternalSymbol(symbolName);
                    externalMapping[i] = symbol;
                    fil->Add(symbol);
                }
            }
        }
    }
    // dump data to the sections
    for (int i=0; i < header.NumberOfSections; i++)
    {
        if (objectSections[i])
        {
            int len = sections[i].SizeOfRawData;
            if (len)
            {
                inputFile->seekg(sections[i].PointerToRawData + libOffset);
                int relocCount = sections[i].NumberOfRelocations;
                CoffReloc * relocPointer = relocs[i];
                if (relocCount == 0xffff && (sections[i].Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL))
                {
                    relocCount = relocPointer[0].VirtualAddress;
                    relocPointer++;
                }
                unsigned offset = 0;
                inputFile->clear();
                while (offset < sections[i].SizeOfRawData)
                {
                    if (!relocCount)
                    {
                        ObjByte *data = new ObjByte[sections[i].SizeOfRawData-offset];
                        inputFile->read((char *)data, sections[i].SizeOfRawData-offset);
                        if (inputFile->fail())
                        {
                            return NULL;
                        }
                        ObjMemory *newMem = new ObjMemory(data, sections[i].SizeOfRawData-offset);
                        objectSections[i]->Add(newMem);
                        offset = sections[i].SizeOfRawData;
                    }
                    else
                    {
                        unsigned fixupOffset;
                        int n = relocPointer->VirtualAddress - offset;
                        if (n)
                        {
                            ObjByte *data = new ObjByte[n];
                            inputFile->read((char *)data, n);
                            if (inputFile->fail())
                            {
                                return NULL;
                            }
                            ObjMemory *newMem = new ObjMemory(data, n);
                            objectSections[i]->Add(newMem);
                        }
                        inputFile->read((char *)&fixupOffset, sizeof(unsigned));
                        if (inputFile->fail())
                        {
                            return NULL;
                        }
                        switch (relocPointer->Type)
                        {
                            ObjExpression *fixupExpr;
                            case IMAGE_REL_I386_DIR32:
                            case IMAGE_REL_I386_REL32:
                                if (symbols[relocPointer->SymbolTableIndex].StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
                                {
                                    if  (symbols[relocPointer->SymbolTableIndex].SectionNumber == 0)
                                    {
                                        // external
                                        fixupExpr = new ObjExpression(externalMapping[relocPointer->SymbolTableIndex]);
                                    }
                                    else if  (symbols[relocPointer->SymbolTableIndex].SectionNumber > header.NumberOfSections)
                                    {
                                        fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(0));
                                    }
                                    else
                                    {
                                        
                                        // public 
                                        fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(symbols[relocPointer->SymbolTableIndex].Value));
                                    }    
                                    
                                }
                                else
                                {
                                    // local static
                                    fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(symbols[relocPointer->SymbolTableIndex].Value));
                                }
                                if (relocPointer->Type == IMAGE_REL_I386_REL32)
                                {
                                    fixupExpr = new ObjExpression(ObjExpression::eAdd, fixupExpr, new ObjExpression(fixupOffset - 4));
                                    fixupExpr = new ObjExpression(ObjExpression::eSub, fixupExpr, new ObjExpression(ObjExpression::ePC) );
                                }
                                else if (fixupOffset)
                                {
                                    fixupExpr = new ObjExpression(ObjExpression::eAdd, fixupExpr, new ObjExpression(fixupOffset));
                                }
                                objectSections[i]->Add(new ObjMemory(fixupExpr, 4));
   
                                break;
                            default:
                                std::cout << "Invalid relocation" << std::endl;
                                return NULL;
                        }
                        
                        offset += n + 4;
                        relocPointer++;
                        relocCount--;
                    }
                }                
            }
        }
    }
    for (int i=1; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1)
    {
        if (symbols[i].SectionNumber > header.NumberOfSections && symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].Value)
        {
            int n = symbols[i].SectionNumber-1;
            ObjByte *data = new ObjByte[symbols[i].Value];
            memset(data,0, symbols[i].Value);
            ObjMemory *newMem = new ObjMemory(data, symbols[i].Value);
            objectSections[n]->Add(newMem);
        }
    }
    return fil;
}
コード例 #7
0
ファイル: Section.cpp プロジェクト: bencz/OrangeC
bool Section::MakeData(ObjFactory &factory, AsmFile *fil)
{
    bool rv = true;
    int pc = 0;
    int pos = 0;
    unsigned char buf[1024];
    Fixup f;
    int n;
    ObjSection *sect = objectSection;
    if (sect)
    {
        sect->SetAlignment(align);
        instructionPos = 0;
        while ((n = GetNext(f, buf+pos, sizeof(buf) - pos)) != 0)
        {
            if (n > 0)
            {
                pos += n;
                if (pos == sizeof(buf))
                {
                    ObjMemory *mem = factory.MakeData(buf, pos);
                    sect->Add(mem);
                    pos = 0;
                }
                pc += n;
            }
            else
            {
                if (pos)
                {
                    ObjMemory *mem = factory.MakeData(buf, pos);
                    sect->Add(mem);
                    pos = 0;
                }
                ObjExpression *t;
                try
                {
                    t = ConvertExpression(f.GetExpr(), fil, factory);
                    SwapSectionIntoPlace(t);
                }
                catch (std::runtime_error *e)
                {
                    Errors::IncrementCount();
                    std::cout << "Error " << f.GetFileName().c_str() << "(" << f.GetErrorLine() << "):" << e->what() << std::endl;
                    delete e;
                    t = nullptr;
                    rv = false;
                }
                if (t && f.IsRel())
                {
                    ObjExpression *left = factory.MakeExpression(f.GetRelOffs());
                    t = factory.MakeExpression(ObjExpression::eSub, t, left);
                    left = factory.MakeExpression(ObjExpression::ePC);
                    t = factory.MakeExpression(ObjExpression::eSub, t, left);
                }
                if (t)
                {
                
                    ObjMemory *mem = factory.MakeFixup(t, f.GetSize());
                    if (mem)
                        sect->Add(mem);
                }
                pc += f.GetSize();
            }
        }
        if (pos)
        {
            ObjMemory *mem = factory.MakeData(buf, pos);
            sect->Add(mem);
        }
    }
    return rv;
}
コード例 #8
0
ファイル: dlPmMain.cpp プロジェクト: bencz/OrangeC
void dlPmMain::GetInputSections(const std::vector<std::string> &names, ObjFile *file, ObjFactory *factory)
{

    for (auto name : names)
    {
        ObjSection *s = file->FindSection(name);
        ObjInt size = s->GetSize()->Eval(0);
        ObjInt addr = s->GetOffset()->Eval(0);
        Section *p = new Section(addr, size);
        p->data = new char[size];
        sections.push_back(p);
        s->ResolveSymbols(factory);
        ObjMemoryManager &m = s->GetMemoryManager();
        int ofs = 0;
        for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it)
        {
            int msize = (*it)->GetSize();
            ObjByte *mdata = (*it)->GetData();
            if (msize)
            {
                ObjExpression *fixup = (*it)->GetFixup();
                if (fixup)
                {
                    int sbase = s->GetOffset()->Eval(0);
                    int n = fixup->Eval(sbase + ofs);
                    int bigEndian = file->GetBigEndian();
                    if (msize == 1)
                    {
                        p->data[ofs] = n & 0xff;
                    }
                    else if (msize == 2)
                    {
                        if (bigEndian)
                        {
                            p->data[ofs] = n >> 8;
                            p->data[ofs + 1] = n & 0xff;
                        }
                        else
                        {
                            p->data[ofs] = n & 0xff;
                            p->data[ofs+1] = n >> 8;
                        }
                    }
                    else // msize == 4
                    {
                        if (bigEndian)
                        {
                            p->data[ofs + 0] = n >> 24;
                            p->data[ofs + 1] = n >> 16;
                            p->data[ofs + 2] = n >>  8;
                            p->data[ofs + 3] = n & 0xff;
                        }
                        else
                        {
                            p->data[ofs] = n & 0xff;
                            p->data[ofs+1] = n >> 8;
                            p->data[ofs+2] = n >> 16;
                            p->data[ofs+3] = n >> 24;
                        }
                    }
                }
                else
                {
                    if ((*it)->IsEnumerated())
コード例 #9
0
ファイル: Tiny.cpp プロジェクト: jossk/OrangeC
bool Tiny::ReadSections(ObjFile *file, ObjExpression *start)
{
    startOffs = start->Eval(0);
    if (startOffs != 0x100)
        Utils::fatal("Start address for tiny program must be 0100h");
    int count = 0;
    ObjSection *sect;
    for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it)
    {
        sect = *it;
        size = (*it)->GetOffset()->Eval(0) + (*it)->GetSize()->Eval(0);
        count ++;
    }
    if (count != 1 || size < 0x100)
        return false;
    data = new unsigned char[size];
    ObjMemoryManager &m = sect->GetMemoryManager();
    int ofs = 0;
    for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it)
    {
        int msize = (*it)->GetSize();
        ObjByte *mdata = (*it)->GetData();
        if (msize)
        {
            ObjExpression *fixup = (*it)->GetFixup();
            if (fixup)
            {
                if (fixup->GetOperator() == ObjExpression::eDiv)
                    Utils::fatal("Tiny program cannot have fixups");
                int sbase = sect->GetOffset()->Eval(0);
                int n = fixup->Eval(sbase + ofs);
                int bigEndian = file->GetBigEndian();
                if (msize == 1)
                {
                    data[ofs] = n & 0xff;
                }
                else if (msize == 2)
                {
                    if (bigEndian)
                    {
                        data[ofs] = n >> 8;
                        data[ofs + 1] = n & 0xff;
                    }
                    else
                    {
                        data[ofs] = n & 0xff;
                        data[ofs+1] = n >> 8;
                    }
                }
                else // msize == 4
                {
                    if (bigEndian)
                    {
                        data[ofs + 0] = n >> 24;
                        data[ofs + 1] = n >> 16;
                        data[ofs + 2] = n >>  8;
                        data[ofs + 3] = n & 0xff;
                    }
                    else
                    {
                        data[ofs] = n & 0xff;
                        data[ofs+1] = n >> 8;
                        data[ofs+2] = n >> 16;
                        data[ofs+3] = n >> 24;
                    }
                }
            }