Example #1
0
bool ObjIeeeAscii::LocalSymbol(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int index = 0;
    ObjString name = GetSymbolName(buffer, &index);
    ObjSymbol *sym = factory->MakeLocalSymbol(name, index);
    PutSymbol(locals, index, sym);
    sym->SetSourceFile(GetFile(0));
    return false;
}
Example #2
0
bool ObjIeeeAscii::TypeSpec(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int pos = 2;
    char ch = buffer[pos++];
    int index = ObjUtil::FromHex(buffer, &pos);
    if (buffer[pos++] != ',')
        ThrowSyntax(buffer, ParseType);
    switch (ch)
    {
        case 'A':
        case 'E':
        case 'X':
        case 'N':
        case 'I':
        {
            ObjSymbol *symbol = FindSymbol(ch, index);
            if (!symbol)
                ThrowSyntax(buffer, ParseType);
            if (buffer[pos++] != 'T')
                ThrowSyntax(buffer, ParseType);
            index = ObjUtil::FromHex(buffer, &pos);
            CheckTerm(buffer + pos);
            ObjType *type;
            /* won't get a 'special' type deriving type here */
            if (index < ObjType::eReservedTop)
                type = factory->MakeType((ObjType::eType)index);
            else
                type = GetType(index);
            if (!type)
                ThrowSyntax(buffer, ParseType);
            symbol->SetBaseType(type);	
            break;
        }
        case 'T':
        {
            DefineType(index, buffer, &pos);
            CheckTerm(buffer + pos);
            break;
        }
        default:
            ThrowSyntax(buffer, ParseType);
            break;
    }
    return false;
}
Example #3
0
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;
}
Example #4
0
bool ObjIeeeAscii::AutoSymbol(const char *buffer, eParseType ParseType)
{
    if (!file)
        ThrowSyntax(buffer, ParseType);
    int index = 0;
    ObjString name = GetSymbolName(buffer, &index);
    
    ObjSymbol *sym = GetSymbol(autos,index);
    // autos can be forward declared in function type declarations
    if (sym)
    {
        sym->SetName(name);
    }
    else
    {
         sym = factory->MakeAutoSymbol(name, index);
        PutSymbol(autos, index, sym);
    }
    return false;
}
Example #5
0
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;
}
Example #6
0
void PEImportObject::Setup(ObjInt &endVa, ObjInt &endPhys)
{
    if (virtual_addr == 0)
    {
        virtual_addr = endVa;
    }
    else
    {
        if (virtual_addr != endVa)
            Utils::fatal("Internal error");
    }
    raw_addr = endPhys;
    std::map<ObjString, ObjSymbol *> externs;
    for (ObjFile::SymbolIterator it = file->ExternalBegin(); it != file->ExternalEnd(); ++it)
    {
        externs[(*it)->GetName()] = (*it);
    }
    std::map<std::string, Module *> modules;
    int nameSize = 0;
    int impNameSize = 0;
    int importCount = 0;
    int dllCount = 0;
    for (ObjFile::SymbolIterator it = file->ImportBegin(); it != file->ImportEnd(); ++it)
    {
        ObjImportSymbol *s = (ObjImportSymbol *)(*it);
        // uppercase the module name for NT... 98 doesn't need it but can accept it
        std::string name = s->GetDllName();
        for (int i =0; i < name.size(); i++)
            name[i] = toupper(name[i]);
        s->SetDllName(name);
        if (externs.find((*it)->GetName()) != externs.end())
        {
            Module *m = modules[s->GetDllName()];
            int sz = s->GetDllName().size() + 1;
            if (sz & 1)
                sz ++;
            nameSize += sz;
            if (m == NULL)
            {
                modules[s->GetDllName()] = m = new Module;
                m->module = s->GetDllName();
                dllCount++;
            }
            if (s->GetExternalName().size() == 0)
            {
                m->externalNames.push_back(s->GetName());
                sz = s->GetName().size() + 1;
            }
            else
            {
                m->externalNames.push_back(s->GetExternalName());
                sz = s->GetExternalName().size() + 1;
            }
            sz += 2;
            if (sz & 1)
                sz ++;
            impNameSize += sz;
            m->publicNames.push_back(s->GetName());
            m->ordinals.push_back(s->GetByOrdinal() ? s->GetOrdinal() : 0xffffffff);
            importCount ++;
        }
    }
    data = new unsigned char[(modules.size() + 1) * sizeof(Dir) +
                             ((nameSize + 3) & ~3) + (importCount + dllCount) * sizeof(Entry) * 2 +
                             ((impNameSize + 3) & ~3)];
    Dir *dirPos = (Dir *)data;
    char *namePos = (char *)data + sizeof(Dir) * (modules.size() + 1);
    Entry *lookupPos = (Entry *)((char *)namePos + ((nameSize + 3) & ~3));
    char *hintPos = ((char *)lookupPos)	+ (importCount + dllCount) * sizeof(Entry);
    Entry *addressPos = (Entry *)(hintPos + ((impNameSize + 3) & ~3));
    size = initSize = (unsigned)(((unsigned char *)addressPos) - data + (importCount + dllCount) * sizeof(Entry));
    memset(data, 0, size); // note this does clean out some areas we deliberately are not initializing
    for (std::map<std::string, Module *>::iterator it = modules.begin(); it != modules.end(); ++it)
    {
        dirPos->time = 0;
        dirPos->version = 0;
        dirPos->dllName = (unsigned char *)namePos - data + virtual_addr;
        dirPos->thunkPos = ((unsigned char *)lookupPos) - data + virtual_addr;
        dirPos->thunkPos2 = ((unsigned char *)addressPos) - data + virtual_addr;
        dirPos++;
        strcpy(namePos, it->first.c_str());
        int n = it->first.size() + 1;
        if (n & 1)
            n++;
        namePos += n;
        for (int i = 0; i < it->second->externalNames.size(); i++)
        {
            const std::string &str = it->second->externalNames[i];
            if (str.size())
            {
                lookupPos->ord_or_rva = (unsigned char *)hintPos - data + virtual_addr;
                addressPos->ord_or_rva = (unsigned char *) hintPos - data + virtual_addr;
                *(short *)hintPos = 0; //it->second->ordinals[i];
                hintPos += 2;
                strcpy(hintPos, str.c_str());
                int n = str.size() + 1;
                if (n & 1)
                    n++;
                hintPos += n;
            }
            else
            {
                lookupPos->ord_or_rva = addressPos->ord_or_rva = it->second->ordinals[i] | IMPORT_BY_ORDINAL;
            }
            // next up we make a thunk that will get us from the rel calls genned by
            // the compiler to the import table;		
            ObjSymbol *sym = externs[it->second->publicNames[i]];
            int en = sym->GetIndex();
            for (std::deque<PEObject *>::iterator it1 = objects.begin(); it1 != objects.end(); ++ it1)
            {
                ObjInt val;
                if ((val = (*it1)->SetThunk(en, ((unsigned char *)lookupPos) - data + virtual_addr + imageBase)) != -1)
                    sym->SetOffset(new ObjExpression(val));
            }
            lookupPos++;
            addressPos++;
        }
        // skip the null entry at the end of a module
        lookupPos++;
        addressPos++;
    }
    for (std::map<std::string, Module *>::iterator it = modules.begin(); it != modules.end(); ++it)
    {
        Module *p = it->second;
        delete p;
    }

    endVa = ObjectAlign(objectAlign, endVa + size);
    endPhys = ObjectAlign(fileAlign, endPhys + initSize);
}