コード例 #1
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;
}
コード例 #2
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;
}