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

📄 bin.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "bin.h"

/*****************************************************************************/
bool write_bin(AddressList &hole_list, CopyList &copy_list,
                ModuleList &module_list, FileList &file_list, 
                MemoryList &memory_list, MemoryList &reserve_list,
                ModuleList::iterator &kernel, Config &config, MemoryList::iterator xip_mem){
  // open bin file
  if(config.output_file.empty())
    config.output_file = kernel->full_path();

  if(config.output_file.rfind("\\") != string::npos)
    config.output_file = config.output_file.substr(0, config.output_file.rfind("\\"));

  config.output_file += "\\" + xip_mem->name() + ".bin";

  ofstream image_file(config.output_file.c_str(), ios::trunc | ios::binary);
  if(image_file.bad()){
    cerr << "Error: Could not open '" << config.output_file << "' for writing\n";
    return false;
  }
  
  // write out bin file header
  DWORD image_length = 0;
  DWORD image_start = config.rom_info.offset + xip_mem->address();

  File::set_rom_offset(config.rom_info.offset);
  Module::write_bin(image_file, 0, 0, 0, false); // reset this function
  
  LAST_PASS_PRINT cout << "\nWriting " << config.output_file << endl;

  image_file.write("B000FF\n", 7);
  image_file.write((char *)&image_start, sizeof(DWORD));
  image_file.write((char *)&image_length, sizeof(DWORD));

  // clear up Module::s_romhdr
  Module::s_romhdr.nummods = 0;
  Module::s_romhdr.numfiles = 0;
  
  // dump the files and modules!
  DWORD romhdr_offset;
  Data temp;

  // get modules entries
  for(ModuleList::iterator mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++){
    if(mod_itr->memory_iterator() == xip_mem){
      Module::s_romhdr.nummods++;        
      TOCentry module_toc = mod_itr->get_TOC(); 
      temp.append(&module_toc, sizeof(module_toc));
    }
  }
  
  // get files entries
  for(FileList::iterator file_itr = file_list.begin(); file_itr != file_list.end(); file_itr++){
    if(file_itr->memory_iterator() == xip_mem){
      Module::s_romhdr.numfiles++;
      FILESentry file_toc = file_itr->get_TOC(); 
      temp.append(&file_toc, sizeof(file_toc));
    }
  }

  // set romhrd_offset for later.  
  // Romhdr needs to be written physically before the toc's and stuff but needs data from them so should
  // be written chronologically after them in the build process
  romhdr_offset = Memory::allocate_range(hole_list, sizeof(Module::s_romhdr) + temp.size());
  if(romhdr_offset == -1){
    fprintf(stderr, "Error: Ran out of space in ROM for %s\nsize %d", "ROMHDR/TOC", sizeof(Module::s_romhdr));
    return false;
  }
  
  // write module/file TOC data
  if(temp.size()){
    LAST_PASS_PRINT printf("Table of contents  %08x  %08x  (%10u)\n", romhdr_offset + sizeof(ROMHDR), temp.size(), temp.size());
    Module::write_bin(image_file, romhdr_offset + sizeof(ROMHDR), temp.ptr(), temp.size());
  }
  
  // write toc into kernel
  if(xip_mem->is_kernel() && kernel->is_kernel()) 
    kernel->write_TOC_ptr(romhdr_offset);
  
  // write modules data
  for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++)
    if(mod_itr->memory_iterator() == xip_mem)
      if(!mod_itr->write(image_file)) {
          fprintf(stderr, "Error: module write failed\n");
          return false;
      }

  // write files data
  for(file_itr = file_list.begin(); file_itr != file_list.end(); file_itr++)
    if(file_itr->memory_iterator() == xip_mem)
      file_itr->write(image_file); 
  
  // write out kernel signature
  DWORD signature[SIGNATURE_SIZE];
  signature[0] = ROM_SIGNATURE;
  signature[1] = romhdr_offset;
  
  LAST_PASS_PRINT printf("Writing ROM signature and TOC pointer at %08x\n", xip_mem->address() + ROM_SIGNATURE_OFFSET);
  
  File::write_bin(image_file, xip_mem->address() + ROM_SIGNATURE_OFFSET, (char *)signature, sizeof(signature));

  DWORD toc_offset = romhdr_offset - xip_mem->address();

  File::write_bin(image_file, xip_mem->address() + ROM_SIGNATURE_OFFSET + sizeof(signature), (char *)&toc_offset, sizeof(toc_offset));

  // write profile information if applicable
  if(config.profile && xip_mem->is_kernel()){
    Data address_hitcount;
    Data symbol_name;
  
    DWORD next_avail = 0;
    DWORD index = 0;

    // funky two pass thing just to get next_avail and correctly use that to compute the Symbol address in the profile entry
    for(int i = 0; i <= 1; i++){
      temp.clear();
      address_hitcount.clear();
      symbol_name.clear();
      
      ProfileList profile_list;    
      DWORD current_offset = 0;

      MemoryList::iterator mem_itr;
      for(mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
        if(mem_itr->type() == RAMIMAGE_TYPE || mem_itr->type() == NANDIMAGE_TYPE){
          for(ModuleList::iterator mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++){
            if(mod_itr->memory_iterator()->name() == mem_itr->name()){
              current_offset += sizeof(PROFentry);
            }
          }
        }
      }

      index = 0;
      for(mem_itr = memory_list.begin(); mem_itr != memory_list.end(); mem_itr++){
        if(mem_itr->type() == RAMIMAGE_TYPE || mem_itr->type() == NANDIMAGE_TYPE){
          for(ModuleList::iterator mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++){
            if(mod_itr->memory_iterator()->name() == mem_itr->name()){
              profile_list.push_back(mod_itr->get_profile(i));
        
              profile_list[index].ulModNum = index;
              profile_list[index].ulHitAddress = Module::s_romhdr.ulRAMFree + current_offset;
                
              current_offset += profile_list[index].m_function_list.size() * 8;
        
              index++;
            }
          }
        }
      }

#if 0      
      for(ModuleList::iterator mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++){
        if(mod_itr->memory_iterator() == xip_mem)
          current_offset += sizeof(PROFentry);
      }
  
      index = 0;
      for(mod_itr = module_list.begin(); mod_itr != module_list.end(); mod_itr++){
        if(mod_itr->memory_iterator() == xip_mem){
          profile_list.push_back(mod_itr->get_profile(i));
    
          profile_list[index].ulModNum = index;
          profile_list[index].ulHitAddress = Module::s_romhdr.ulRAMFree + current_offset;
            
          current_offset += profile_list[index].m_function_list.size() * 8;
    
          index++;
        }
      }
#endif

      static char *suppress = (suppress = getenv("ri_suppress_info")) ? strstr(suppress, "symbol") : NULL;
      if(!suppress && i){
        LAST_PASS_PRINT printf("   Module   Section    Start     End       Hits     Symbols   HitAddr  SymAddr\n");
        LAST_PASS_PRINT printf("---------- ---------- -------- -------- ---------- ---------- -------- --------\n");
      }
  
      for(ProfileList::iterator prof_itr = profile_list.begin(); prof_itr != profile_list.end(); prof_itr++){
        if(!prof_itr->m_function_list.empty())
          prof_itr->ulSymAddress = next_avail + current_offset;
  
        for(FunctionList::iterator fun_itr = prof_itr->m_function_list.begin(); fun_itr != prof_itr->m_function_list.end(); fun_itr++){
          DWORD name_length = fun_itr->name.size() + 1;  // + 1 for the null
  
          current_offset += name_length;
  
          address_hitcount.append(&*fun_itr, 8);
          symbol_name.append(fun_itr->name.c_str(), name_length);
        }
  
        DWORD zero = 0;
        current_offset = align_dword(current_offset);
        symbol_name.append(&zero, align_dword(symbol_name.size()) - symbol_name.size()); // dword pad      
  
        if(!suppress && i){
          static char *delim = getenv("ri_comma_delimit") ? "," : " ";
    
          LAST_PASS_PRINT 
            printf("%10d%s%10d%s%08x%s%08x%s%10d%s%10d%s%08x%s%08x\n",
                 prof_itr->ulModNum, delim,
                 prof_itr->ulSectNum, delim,
                 prof_itr->ulStartAddr, delim,
                 prof_itr->ulEndAddr, delim,
                 prof_itr->ulHits, delim,
                 prof_itr->ulNumSym, delim,
                 prof_itr->ulHitAddress, delim,
                 prof_itr->ulSymAddress);
        }
  
        temp.append(&*prof_itr, sizeof(PROFentry));
      }
  
      temp.append(address_hitcount);
      temp.append(symbol_name);

      if(!i){
        next_avail = Memory::allocate_range(hole_list, temp.size());

        if(next_avail == -1){
          fprintf(stderr, "Error: Ran out of space in ROM for %s\nsize %d", "Profile section", temp.size());
          return false;
        }
      }
    }

    CopyEntry ce;

    Module::s_romhdr.ulProfileOffset = Module::s_romhdr.ulRAMFree;
    
    ce.ulSource  = next_avail;
    ce.ulDest    = Module::s_romhdr.ulRAMFree;
    ce.ulCopyLen = index * sizeof(PROFentry) + address_hitcount.size();
    ce.ulDestLen = index * sizeof(PROFentry) + address_hitcount.size();
    ce.m_memory_iterator = xip_mem;

    copy_list.push_back(ce);

    Module::s_romhdr.ulProfileLen = temp.size();
    Module::s_romhdr.ulRAMFree += temp.size();

    LAST_PASS_PRINT printf("Profile Header:           %08x  %08x  (%10u)\n", next_avail, index * sizeof(PROFentry), index * sizeof(PROFentry));
      
    Module::write_bin(image_file, next_avail, temp.ptr(), temp.size());
  }

  // write copylist information if applicable
  temp.clear();

  // clear this first
  Module::s_romhdr.ulCopyEntries = 0;
  Module::s_romhdr.ulCopyOffset  = 0;
  for(unsigned i = 0; i < copy_list.size(); i++){
    if(copy_list[i].memory_iterator() == xip_mem){
      temp.append(&copy_list[i], sizeof(COPYentry)); // I really mean COPYentry and *NOT* the CopyEntry wrapper class
      Module::s_romhdr.ulCopyEntries++;
    }
  }

  if(Module::s_romhdr.ulCopyEntries){
    DWORD addr = Memory::allocate_range(hole_list, temp.size());
    if(addr == -1){
      fprintf(stderr, "Error: Ran out of space in ROM for %s\nsize %d", "CopyEntries", temp.size());
      return false;
    }

    Module::s_romhdr.ulCopyOffset  = addr;
  
    LAST_PASS_PRINT printf("Kernel data copy section  %08x  %08x  (%10u)\n", addr, temp.size(), temp.size());
    Module::write_bin(image_file, addr, temp.ptr(), temp.size());
  }
  
  // set glob stuff
  for(MemoryList::iterator ritr = reserve_list.begin(); ritr != reserve_list.end(); ritr++){
    if(ritr->name() == "drivglob"){
      Module::s_romhdr.ulDrivglobStart = ritr->address();
      Module::s_romhdr.ulDrivglobLen   = ritr->length();
    }

    if(ritr->name() == "tracking"){
      Module::s_romhdr.ulTrackingStart = ritr->address();
      Module::s_romhdr.ulTrackingLen   = ritr->length();
    }
  }

  if(xip_mem->dll_data_start < xip_mem->dll_data_bottom || xip_mem->dll_data_start > xip_mem->dll_data_orig){
    fprintf(stderr, "Error: Too much data space used by DLL's in MODULES section\n");
    fprintf(stderr, "  Current usage = %4dk, Maximum usage = %4dk.\n", 
            (xip_mem->dll_data_orig - xip_mem->dll_data_start) >> 10, 
            (xip_mem->dll_data_orig - xip_mem->dll_data_bottom) >> 10);
    fprintf(stderr, "  Reduce DLL usage or move some DLL's into the FILES section.\n");
    
    return false;
  }

  if(xip_mem->dll_code_start < xip_mem->dll_code_bottom || xip_mem->dll_code_start > xip_mem->dll_code_orig){
    fprintf(stderr, "Error: Too much code space used by DLL's in MODULES section\n");
    fprintf(stderr, "  Current usage = %4dk, Maximum usage = %4dk.\n", 
            (xip_mem->dll_code_orig - xip_mem->dll_code_start) >> 10, 
            (xip_mem->dll_code_orig - xip_mem->dll_code_bottom) >> 10);
    fprintf(stderr, "  Reduce DLL usage or move some DLL's into the FILES section.\n");

    return false;
  }
  
  // setup rest of romhdr
  if(!xip_mem->dll_data_split)

⌨️ 快捷键说明

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