⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fc_binutils.cpp

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        string::size_type pos2;

            /* 拞恎傪嬻偵偟偰偍偔 */
        address = 0;
        if(!attribute.empty())
            attribute.erase();
        if(!symbolname.empty())
            symbolname.erase();

            //師偺峴傪庢摼 (嬻峴, 枹掕媊僔儞儃儖偼撉傒旘偽偡)
        do {
            if(file.eof())
                return false;

            getline(file, src, '\n');
        } while(src.empty() || src.at(0) == ' ');

            //峴傪暘夝
        pos1 = src.find_first_of(' ');
        addr = src.substr(0, pos1);

        pos2 = src.find_first_of(' ', pos1 + 1);
        attribute  = src.substr(pos1 + 1, pos2 - pos1 - 1);
        symbolname = src.substr(pos2 + 1);

            //傾僪儗僗偺僷乕僗  (拲 : 側傫偱偙傫側偪傑偪傑傗偭偰傞偐偲偄偆偲丄傾僪儗僗偑32bit傪挻偊傞僞乕僎僢僩偑偄傞偐傜)
        while(!addr.empty()) {
            size_t length = addr.size();
            const char * src = addr.c_str();
            if(length > sizeof(unsigned int) * 2)
                length = sizeof(unsigned int) * 2;
            address = (address << (length * 2)) | (hextodec(src, length));
            addr.erase(0, length);
        }

        return true;
    }

        /* 僔儞儃儖偺撉傒崬傒 */
    void FileContainerBinutilsImpl::loadSymbols(fstream & file) throw(Exception)
    {
        assert(file.is_open());

        address_t address;
        string    attribute;
        string    symbolname;

        while(readGnuNmLine(file, address, attribute, symbolname)) {
            symbol_table.insert(map<string, address_t>::value_type(symbolname, address));
        }

		VerboseMessage("% symbols loaded\n") << symbol_table.size() << &throwException;

        file.close();
    }

        /* contents偵1僶僀僩彂偒崬傒 */
    void FileContainerBinutilsImpl::writeByte(address_t address, unsigned int value) throw(Exception)
    {
        address_t & base = last_address;
        char *    & page = last_page;

            /* 僉儍僢僔儏傕偳偒偑巊偊側偄側傜丄儁乕僕傪扵偡 */
        if(MAKE_BASEADDRESS(address) != last_address || last_page == 0) {
            map<address_t, char *>::iterator scope;

            base  = MAKE_BASEADDRESS(address);
            scope = contents.find(base);
            if(scope == contents.end()) {
                page = new(nothrow) char [SIZE_LOADPAGE];
                if(page == 0) {
                    ExceptionMessage("Not enough memory available to store the contents","嬻偒儊儌儕晄懌偺偨傔丄僨乕僞偺奿擺偵幐攕偟傑偟偨").throwException();
                    return;
                }
                contents.insert(map<address_t,char*>::value_type(base, page));
            }
            else
                page = scope->second;
        }

        *(page + (address - base)) = static_cast<char>(value & 0xff);
    }

        /* 枛旜偺嬻敀暥帤傪愗傝庢傞 */
    void trimString(string & src) throw()
    {
        string::size_type pos;

        pos = src.find_last_not_of(" \t\r\n");
        if(pos != string::npos && pos != src.size())
            src.erase(pos + 1);
    }

        /* 儌僩儘乕儔S儗僐乕僪傪堦峴撉傒崬傓 */
        /*
                The general format of an S-record follows: 
                +-------------------//------------------//-----------------------+
                | type | count | address  |            data           | checksum |
                +-------------------//------------------//-----------------------+
        */
    bool readRecord(fstream & file, string & dest) throw(Exception)
    {
        unsigned int sum;
        unsigned int count;
        unsigned int i;
        const char * pos;

            /* 師偺峴傪撉傒崬傓 */
        do {
                //getline偑ReadFile傪屇傫偱僽儘僢僋偡傞偺偱丄妋幚偵EOF傪斀墳偝偣傞偨傔偵偙偆偡傞
            int ch = file.get();
            if(ch == EOF)
                return false;

            file.putback(static_cast<char>(ch));
            getline(file, dest);
        } while(dest.empty());

        trimString(dest);

            /* 惓摉惈偺敾掕 */

        if(dest[0] != 'S')      //峴摢偑'S'偱巒傑傜側偄
            ExceptionMessage("The file is not a Motorola S-Record file.","儌僩儘乕儔S僼僅乕儅僢僩偱柍偄峴偑尒偮偐傝傑偟偨") << throwException;

        pos = dest.c_str() + 2;
        count = hextodec(pos, 2);
        if(dest.size() != (count + 2)*2)
            ExceptionMessage("Illegal S-Record found (count unmatched).","晄惓側S儗僐乕僪偑偁傝傑偡 (僒僀僘晄堦抳)") << throwException;

        sum = count;
        for(i = 0; i < count; ++ i)
            sum += hextodec(pos, 2);

        if((sum & 0xff) != 0xff)
            ExceptionMessage("Illegal S-Record found (check-sum unmatched).","晄惓側S儗僐乕僪偑偁傝傑偡 (僠僃僢僋僒儉晄堦抳)") << throwException;

        return true;
    }

        /* 師偺奐巒傾僪儗僗傪摼傞 */
    FileContainer::address_t parseRecordAddress(const string & src, FileContainer::address_t base) throw()
    {
        const char * record = src.c_str();
        FileContainer::address_t result = 0;

        record += 4;
        switch(*(record - 3)) {
            case '1':
                result = hextodec(record, 4);
                break;
            case '2':
                result = hextodec(record, 6);
                break;
            case '3':
                result = hextodec(record, 8);
                break;
            case '5':
                result = base;
                break;
            default:
                break;
        }

        return result;
    }

        /* 僨乕僞晹暘偩偗傪巆偟偰僠儑僢僾 */
    void chopRecord(string & src) throw()
    {
        string::size_type start;

        switch(src[1]) {
            case '1':  start = 4 + 4;  break;
            case '2':  start = 4 + 6;  break;
            case '3':  start = 4 + 8;  break;
            default:   start = 4;      break;
        }

            //愭摢4僶僀僩 + 傾僪儗僗晹 + 嵟屻偺僒儉傪庢傝彍偔
        src = src.substr(start, src.size() - start - 2);
    }

        /* 僾儘僌儔儉僨乕僞偺撉傒崬傒 */
    void FileContainerBinutilsImpl::loadDataContents(fstream & file) throw(Exception)
    {
        assert(file.is_open());

        address_t address;
        string    line;

        address = 0;
        while(readRecord(file, line)) {

            address = parseRecordAddress(line, address);

            chopRecord(line);

                /* 僨乕僞偺奿擺 */
            const char * pos = line.c_str();
            while(*pos != '\x0') {
                unsigned int data = hextodec(pos, 2);
                writeByte(address, data);
                ++ address;
            }
        }

        file.close();
    }

        /* 僔儞儃儖僾儗僼傿僋僗偺帺摦敾掕 */
    void FileContainerBinutilsImpl::searchSymbolPrefix(void) throw()
    {
        const char *  candidate_list[] = {"", "_", NULL};
        const char ** candidate;

        for(candidate = candidate_list; *candidate != NULL; ++ candidate) {
            map<string, address_t>::const_iterator scope;
            string symbol;
            
            symbol = string(*candidate) + MAGIC_SYMBOL;
            scope  = symbol_table.find(symbol);

            if(scope != symbol_table.end())
                break;
        }

        if(*candidate != NULL)
            symbol_prefix.assign(*candidate);
    }

        /* 僄儞僨傿傾儞偺帺摦敾掕 */
    void FileContainerBinutilsImpl::searchByteOrder(void) throw()
    {
        address_t address;
        union {
            char         buffer[4];
            unsigned int value;
        };

        try {
            value   = 0;
            address = getSymbolAddress(MAGIC_SYMBOL);
            loadContents(buffer, address, 4);

            if(value == MAGIC_NUMBER) {
                byteorder = HOSTORDER;
            }
            else {
                buffer[0] ^= buffer[3], buffer[3] ^= buffer[0], buffer[0] ^= buffer[3]; // swap(buffer[0], buffer[3])
                buffer[1] ^= buffer[2], buffer[2] ^= buffer[1], buffer[1] ^= buffer[2]; // swap(buffer[1], buffer[2])

                if(value == MAGIC_NUMBER)
                    byteorder = HOSTORDER == LITTLE ? BIG : LITTLE;
                else
                    throw false;
            }
        }
        catch(...) {}
    }

        /* 儌僕儏乕儖偺傾僞僢僠 -> 僔儞儃儖撉弌偟, 僨乕僞奿擺 */
    void FileContainerBinutilsImpl::attachModule(const string & filename) throw(Exception)
    {
        fstream file;
        string  symbol_filename;
        string  contents_filename;

        splitFilename(filename, symbol_filename, contents_filename);

        openTextFile(file, symbol_filename, interceptWithGnuNM);
        loadSymbols(file);

        openTextFile(file, contents_filename, interceptWithGnuObjcopy);
        loadDataContents(file);

        searchSymbolPrefix();
        searchByteOrder();
    }

        /* 奿擺偟偰偄傞撪梕偺庢摼 */
    void FileContainerBinutilsImpl::loadContents(void * _dest, address_t address, size_t size) throw(Exception)
    {
        char * dest = static_cast<char *>(_dest);

        while(size > 0) {
            map<address_t, char *>::const_iterator scope;

            address_t  base   = MAKE_BASEADDRESS(address);
            address_t  offset = MAKE_OFFSETADDRESS(address);
            size_t     transfer_size = size;

            if(transfer_size > SIZE_LOADPAGE - offset)
                transfer_size = SIZE_LOADPAGE - offset;

            scope = contents.find(base);
            if(scope == contents.end())
                ExceptionMessage("[Internel error] Memory read with unmapped address","[撪晹僄儔乕] 儅僢僾偝傟偰側偄傾僪儗僗傪巊偭偰儊儌儕儕乕僪偑峴傢傟傑偟偨").throwException();

            memcpy(dest, scope->second + offset, transfer_size);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -