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

📄 module.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    s_cpu_id = m_e32.e32_cpu;
    s_page_size = page_size();
  }

  // check for pb_private_build in comment area
  {
    Data temp;

    // skip past all o32 sections
    DWORD offset = e32_ptr + sizeof(m_e32) + m_o32_list.size() * sizeof(o32_obj); 
    file.seekg(offset);

    // read whole block
    DWORD size = m_o32_list[0].o32_dataptr - offset;

    if(size){
      file.read((char*)temp.user_fill(size), size);
      if(file.fail()){
        cerr << "Error: Failed reading comment structure" << m_name << endl;
        return false;
      }
  
      if(strstr((const char *)temp.ptr(), "pb_private_source"))
        m_flags |= FLAG_WARN_PRIVATE_BITS;
    }
  }

  if(is_kernel()){
    // read in any kernel debug info if doing fixups
    if(is_kernel_fixup_enabled() && m_e32.e32_unit[DEB].size){
      IMAGE_DEBUG_DIRECTORY debug_dir = {0};
      int debug_count = m_e32.e32_unit[DEB].size / sizeof(debug_dir);

      // search for a fixup type debug dir
      file.seekg(debug_offset);
      for(int i = 0; i < debug_count && debug_dir.Type != IMAGE_DEBUG_TYPE_FIXUP; i++){
        file.read((char *)&debug_dir, sizeof(debug_dir));
        if(file.fail()){
          cerr << "Error: Failed reading debug data in module " << m_name << endl;
          return false;
        }
      }
      
      if(debug_dir.Type != IMAGE_DEBUG_TYPE_FIXUP)
        // cerr << "Warning: NK image debug type fixups not found, using standard fixups\n";
        ;
      else{
        // read in fixup data
        FixupInfo fixup;

        file.seekg(debug_dir.PointerToRawData);
        for(unsigned i = 0; i < debug_dir.SizeOfData / sizeof(fixup); i++){
          file.read((char *)&fixup, sizeof(fixup));
          if(file.fail()){
            cerr << "Error: Failed reading fixup data in module " << m_name << endl;
            return false;
          }

          m_kernel_fixup_list.push_back(fixup);
        }
      }
    }
  }

  return true;
}

/*****************************************************************************
  set_load_address()

  in:
    DWORD addr - address to load module in memory

  out:
    none

  desc:
    sets the load address and also the e32 and o32 table load offsets
 *****************************************************************************/
void Module::set_load_address(DWORD addr){
  m_load_offset = addr;

  DWORD size = page_size();

  // Compute size of sections
  for(O32List::const_iterator o32_itr = m_o32_list.begin(); o32_itr != m_o32_list.end(); o32_itr++)
    size += align_page(o32_itr->max_size());

  // add in size of e32
  m_e32_offset = m_load_offset + size;
  size += sizeof(m_e32);

  // add in size of o32's
  m_o32_offset = m_load_offset + size;
}

/*****************************************************************************
  get_load_size()

  in:
    none

  out:
    DWORD - size of module

  desc:
    returns module size as read from disk (ie. uncompressed)
 *****************************************************************************/
DWORD Module::get_load_size(){
  DWORD size = page_size();

  // Compute size of sections
  for(O32List::const_iterator o32_itr = m_o32_list.begin(); o32_itr != m_o32_list.end(); o32_itr++)
    size += align_page(o32_itr->max_size());  

  // add in size of e32
  size += sizeof(m_e32);
  
  // add in size of o32's
  size += sizeof(o32_obj) * m_e32.e32_objcnt;

  // round up to next page
  return align_page(size); 
}

/*****************************************************************************
  set_base()

  in:
    MemoryList - list of reserved regions for kernel fixed up modules to look out for

  out:
    bool - invalid address

  desc:
    sets the relocation location for the module with a small check for 
    stripped kernels

    dll    - to next 64k aligned address DOWN!
    kernel - to specified address
    exe... if stripped  - doesn't move
           not stripped - moves to 0x10000
 *****************************************************************************/
bool Module::set_base(const MemoryList &reserve_list){
  static DWORD kernel_readonly_offset = 0;

  // reinitialize some pass specific variables
  if(is_kernel()){
    kernel_readonly_offset = 0;
  }    

//  if(is_resource_only())
//    return true;

  if(memory_iterator()->code_space_full)
    set_code_split(false);
  
  // give me some shorter names for all the references below
  DWORD &code_addr = memory_iterator()->dll_code_start;
  DWORD &data_addr = memory_iterator()->dll_data_start;
      
  if(is_dll() && !fixup_like_kernel()){
    if(is_code_split()){
      // if we're going, old we can't go back
      assert(!memory_iterator()->dll_data_split);
      
      DWORD code_orig = code_addr;
      DWORD data_orig = data_addr;
  
      data_addr -= page_size();
  
      for(O32List::const_iterator c_o32_itr = m_o32_list.begin(); c_o32_itr != m_o32_list.end(); c_o32_itr++){
        if(c_o32_itr->is_writable() && !c_o32_itr->is_shared())
          data_addr -= align_page(c_o32_itr->max_size());
  
        code_addr -= align_page(c_o32_itr->max_size());
      }
  
      code_addr -= align_page(sizeof(e32_exe) + sizeof(o32_obj) * m_e32.e32_objcnt);
      
      data_addr &= 0xfffff000; // round DOWN to next PAGE boundry
      code_addr &= 0xffff0000; // round DOWN to next 64k boundry

      if(code_addr < memory_iterator()->dll_code_bottom){
        code_addr = code_orig;
        data_addr = data_orig;

        set_code_split(false);
        memory_iterator()->code_space_full = true;

        goto OLD_FIXUP;
      }
  
      DWORD data = data_addr + page_size();
      DWORD code = code_addr + page_size();
  
      for(O32List::iterator o32_itr = m_o32_list.begin(); o32_itr != m_o32_list.end(); o32_itr++)
        if(o32_itr->is_writable() && !o32_itr->is_shared()){
          o32_itr->o32_realaddr = data;
          data += align_page(o32_itr->max_size());
          code += align_page(o32_itr->max_size());
        }
        else{
          o32_itr->o32_realaddr = code;
          code += align_page(o32_itr->max_size());
        }
    }
    else{
OLD_FIXUP:
      if(memory_iterator()->code_space_full){
        cout << "Code space full, fixing up " << m_name << " to ram space\n";
      }

      // add in gaps for first low module and set split address
      if(!memory_iterator()->dll_data_split){
        data_addr -= memory_iterator()->dll_data_gap;

        data_addr &= 0xffff0000;      // round DOWN to next 64k boundry 
        memory_iterator()->dll_data_split = data_addr;

        data_addr -= memory_iterator()->dll_gap;  
      }
        
      data_addr -= get_load_size() - page_size();
      data_addr &= 0xffff0000;      // round DOWN to next 64k boundry

      m_vreloc = data_addr;
    }
  }
  else if(is_kernel()){
    m_vreloc = memory_iterator()->address();

    kernel_readonly_offset = page_size();
    for(unsigned i = 0; i < m_o32_list.size(); i++)
      if(!m_o32_list[i].is_writable() && !m_o32_list[i].is_discardable())
        kernel_readonly_offset += align_page(m_o32_list[i].min_size());
  }
  else if(fixup_like_kernel()){
    m_vreloc = memory_iterator()->address() + kernel_readonly_offset;

    kernel_readonly_offset += page_size();
    for(O32List::const_iterator o32_itr = m_o32_list.begin(); o32_itr != m_o32_list.end(); o32_itr++)
      if(!o32_itr->is_writable() && !o32_itr->is_discardable())
        kernel_readonly_offset += align_page(o32_itr->min_size());

    DWORD size = kernel_readonly_offset - (m_vreloc - memory_iterator()->address());
    DWORD temp = align_page(Memory::find_next_gap(reserve_list, m_vreloc, size));

    if(m_vreloc != temp){
      m_vreloc = temp;
      kernel_readonly_offset = temp + size;
    }
  }
  else if(m_e32.e32_imageflags & IMAGE_FILE_RELOCS_STRIPPED)
    m_vreloc =  m_e32.e32_vbase;
  else
    m_vreloc = 0x10000;

  if(m_vreloc)
    for(O32List::iterator o32_itr = m_o32_list.begin(); o32_itr != m_o32_list.end(); o32_itr++)
      o32_itr->o32_realaddr = m_vreloc + o32_itr->o32_rva;

  // checking to make sure a stripped kernel is in some arbitrary range
  if(is_kernel() && m_e32.e32_imageflags & IMAGE_FILE_RELOCS_STRIPPED && 
     (m_vreloc < 0x10000 || m_vreloc > 0x400000)){
    cerr << "Error: Module " << m_name << " relocations stripped, remove -fixed from link command\n";
    return false;
  }

  return true;
}

/*****************************************************************************
  verify_cpu()

  in:
    none

  out:
    bool - indicating good status

  desc:
    checks to make sure the the cpu the module was compiled for is compatible
    with that which the kernel was compiled with
 *****************************************************************************/
bool Module::verify_cpu() const{
  if(ignore_cpu())
    return true;

  // Allow ARM & Strongarm to mix, even though on SA1100 it won't work.  Even though we can't
  // detect this, the kernel will detect it and fail to load something that he can't handle.
  if(m_e32.e32_cpu != s_cpu_id &&
     !m_e32.e32_unit[RS4].rva &&
     !(m_e32.e32_cpu == IMAGE_FILE_MACHINE_SH3   && s_cpu_id == IMAGE_FILE_MACHINE_SH3DSP) &&
     !(m_e32.e32_cpu == IMAGE_FILE_MACHINE_SH3   && s_cpu_id == IMAGE_FILE_MACHINE_SH4   ) &&
     !(m_e32.e32_cpu == IMAGE_FILE_MACHINE_R4000 && s_cpu_id == IMAGE_FILE_MACHINE_MIPS16) &&
     !(m_e32.e32_cpu == IMAGE_FILE_MACHINE_ARM   && s_cpu_id == IMAGE_FILE_MACHINE_THUMB )
     ){

    map<DWORD, string> cpu_id_list;

    cpu_id_list[IMAGE_FILE_MACHINE_I386]    = "I386";
    cpu_id_list[IMAGE_FILE_MACHINE_R3000]   = "R3000";
    cpu_id_list[IMAGE_FILE_MACHINE_R4000]   = "R4000";
    cpu_id_list[IMAGE_FILE_MACHINE_MIPS16]  = "mips";
    cpu_id_list[IMAGE_FILE_MACHINE_ALPHA]   = "ALPHA";
    cpu_id_list[IMAGE_FILE_MACHINE_SH3]     = "SH3";
    cpu_id_list[IMAGE_FILE_MACHINE_SH4]     = "SH4";
    cpu_id_list[IMAGE_FILE_MACHINE_POWERPC] = "PowerPC";
    cpu_id_list[IMAGE_FILE_MACHINE_ARM]     = "ARM";
    cpu_id_list[IMAGE_FILE_MACHINE_THUMB]   = "Thumb";
    cpu_id_list[IMAGE_FILE_MACHINE_UNKNOWN] = "Unknown";
     
    cerr << "Error: Module " << m_name << " built for " << cpu_id_list[m_e32.e32_cpu]
         << ", kernel built for " << cpu_id_list[s_cpu_id] << endl;
    
    return false;
  }

  return true;
}

/*****************************************************************************
  get_symbols()
  
  in:
    none
    
  out:
    bool - value indicating success

  desc:
    Load the symbol information
 *****************************************************************************/
bool Module::get_symbols(bool profile_all, MemoryList &memory_list){
  if(!m_e32.e32_symcount) // mo symbols in module, use map file
    return get_map_symbols(profile_all, memory_list);

  // open the file
  ifstream file(m_release_path.c_str(), ios::in | ios::binary);
  if(file.bad()){
    cerr << "Error: Could not open '" << m_release_path << "' for reading\n";
    return false;
  }

  // seek to the start of the symbol table
  file.seekg(m_e32.e32_symtaboff);

  // read symbol table
  SymbolList symbol_list;
  for(unsigned i = 0; i < m_e32.e32_symcount; i++){
    COFF_Symbol coff_sym;

    file.read((char *)&coff_sym, sizeof(coff_sym));
    if(file.fail()){
      cerr << "Error: Failed reading COFF symbol structure in module " << m_name << endl;
      return false;
    }

    symbol_list.push_back(coff_sym);
  }

  // read the length of the string table (imediatly follows the symbol table)
  DWORD string_table_len = 0;
  Data string_table;
  file.read((char *)&string_table_len, sizeof(string_table_len));
  if(file.fail()){
    cerr << "Error: Failed reading string table length in module " << m_name << endl;
    return false;
  }

  // read the table itself (imediatly follows the length)
  if(string_table_len){
    file.read((char *)string_table.user_fill(string_table_len), string_table_len);
    if(file.fail()){
      cerr << "Error: Failed reading string table in module " << m_name << endl;
      return false;
    }
  }

  file.close();

  // check each symbol against the string table names
  for(i = 0; i < symbol_list.size(); i++){
    if(symbol_list[i].usType == 0x20 ||
       (profile_all && symbol_list[i].ulValue >= m_e32.e32_codebase && symbol_list[i].ulValue < m_e32.e32_database)){
      string buffer;

      // get the name either from the Coff symbol or string table lookup
      if(symbol_list[i].dwNULL != NULL)
        buffer.assign((char *)symbol_list[i].szName, 8);
      else{
        assert(!string_table.empty());
        buffer = (char *)string_table.ptr() + symbol_list[i].dwPosLow - 4;
      }

      // skip strings with .'s in them
      if(buffer.find('.') != string::npos)
        continue;

⌨️ 快捷键说明

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