| [163] | 1 | /* -*- c++ -*- | 
|---|
 | 2 |  * | 
|---|
 | 3 |  * SOCLIB_LGPL_HEADER_BEGIN | 
|---|
 | 4 |  *  | 
|---|
 | 5 |  * This file is part of SoCLib, GNU LGPLv2.1. | 
|---|
 | 6 |  *  | 
|---|
 | 7 |  * SoCLib is free software; you can redistribute vSO and/or modify vSO | 
|---|
 | 8 |  * under the terms of the GNU Lesser General Public License as published | 
|---|
 | 9 |  * by the Free Software Foundation; version 2.1 of the License. | 
|---|
 | 10 |  *  | 
|---|
 | 11 |  * SoCLib is distributed in the hope that vSO will be useful, but | 
|---|
 | 12 |  * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
 | 13 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
 | 14 |  * Lesser General Public License for more details. | 
|---|
 | 15 |  *  | 
|---|
 | 16 |  * You should have received a copy of the GNU Lesser General Public | 
|---|
 | 17 |  * License along with SoCLib; if not, write to the Free Software | 
|---|
 | 18 |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 
|---|
 | 19 |  * 02110-1301 USA | 
|---|
 | 20 |  *  | 
|---|
 | 21 |  * SOCLIB_LGPL_HEADER_END | 
|---|
 | 22 |  * | 
|---|
 | 23 |  * Copyright (c) UPMC, Lip6, SoC | 
|---|
 | 24 |  *         Mohamed Lamine KARAOUI <Mohamed.Karaoui@lip6.fr>, 2012 | 
|---|
 | 25 |  */ | 
|---|
 | 26 |  | 
|---|
 | 27 | #include <string.h> | 
|---|
 | 28 | #include <cassert> | 
|---|
 | 29 | #include <sstream> | 
|---|
 | 30 | #include <fstream> | 
|---|
 | 31 | #include <ios> | 
|---|
 | 32 | #include <iostream> | 
|---|
 | 33 | #include <cstdarg> | 
|---|
 | 34 | #include <cassert> | 
|---|
 | 35 | #include <iomanip> | 
|---|
 | 36 |  | 
|---|
 | 37 |  | 
|---|
 | 38 | #include "exception.h" | 
|---|
 | 39 | #include "memo.h" | 
|---|
 | 40 |  | 
|---|
| [187] | 41 | //#define MOVER_DEBUG  | 
|---|
| [163] | 42 |  | 
|---|
 | 43 | MeMo::MeMo( const std::string &filename,  | 
|---|
 | 44 |         const size_t pageSize) | 
|---|
 | 45 |         :m_path(filename), | 
|---|
 | 46 |         m_pathHandler(filename), | 
|---|
 | 47 |         m_ginit(false), | 
|---|
 | 48 |         m_generator(new elfpp::object()) | 
|---|
 | 49 | { | 
|---|
 | 50 |      | 
|---|
 | 51 |     PSeg::setPageSize(pageSize); | 
|---|
 | 52 |  | 
|---|
| [173] | 53 |     /* loading map_info blob */ | 
|---|
 | 54 |     m_data = std::malloc(bin_size(m_path)); | 
|---|
 | 55 |     if ( !m_data ) | 
|---|
 | 56 |         throw exception::RunTimeError("malloc failed... No memory space"); | 
|---|
| [163] | 57 |  | 
|---|
| [173] | 58 |     m_size = load_bin(m_path, m_data); | 
|---|
 | 59 |  | 
|---|
 | 60 |     /* checking signature */ | 
|---|
 | 61 |     mapping_header_t*   header = (mapping_header_t*)m_data;  | 
|---|
 | 62 |     //assert((IN_MAPPING_SIGNATURE == header->signature) and "wrong signature"); | 
|---|
 | 63 |     if((IN_MAPPING_SIGNATURE != header->signature)) | 
|---|
 | 64 |     { | 
|---|
 | 65 |         std::cout  << "wrong signature " << std::hex <<header->signature << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl; | 
|---|
 | 66 |         exit(1); | 
|---|
 | 67 |     } | 
|---|
 | 68 |      | 
|---|
 | 69 |      | 
|---|
 | 70 |  | 
|---|
| [163] | 71 | #ifdef MOVER_DEBUG | 
|---|
 | 72 |     std::cout << "Binary file path: " << m_path << std::endl; | 
|---|
| [165] | 73 |     print_mapping_info(m_data); | 
|---|
| [163] | 74 | #endif | 
|---|
 | 75 |  | 
|---|
 | 76 |     buildMap(m_data); | 
|---|
 | 77 |      | 
|---|
 | 78 | #ifdef MOVER_DEBUG | 
|---|
 | 79 |     std::cout << "parsing done" << std::endl ; | 
|---|
 | 80 | #endif | 
|---|
 | 81 |  | 
|---|
 | 82 | #ifdef MOVER_DEBUG | 
|---|
 | 83 |     print_mapping(); | 
|---|
 | 84 |     std::cout << *this << std::endl; | 
|---|
 | 85 | #endif | 
|---|
 | 86 |  | 
|---|
 | 87 |     m_psegh.check(); | 
|---|
 | 88 | #ifdef MOVER_DEBUG | 
|---|
 | 89 |     std::cout << "checking done" << std::endl ; | 
|---|
 | 90 | #endif | 
|---|
 | 91 |  | 
|---|
 | 92 | } | 
|---|
 | 93 |  | 
|---|
 | 94 | void MeMo::print( std::ostream &o ) const | 
|---|
 | 95 | { | 
|---|
 | 96 |     std::cout << "All sections:" << std::endl; | 
|---|
 | 97 |     FOREACH( sect, m_generator->get_section_table() ) | 
|---|
 | 98 |     { | 
|---|
 | 99 |         assert(&*sect != NULL); | 
|---|
 | 100 |         std::cout << *sect << std::endl;  | 
|---|
 | 101 |     } | 
|---|
 | 102 | } | 
|---|
 | 103 |  | 
|---|
 | 104 | void MeMo::print_mapping() const | 
|---|
 | 105 | { | 
|---|
 | 106 |     std::cout << m_psegh << std::endl; | 
|---|
 | 107 | } | 
|---|
 | 108 |  | 
|---|
 | 109 | elfpp::section* MeMo::get_sect_by_addr(elfpp::object *loader, unsigned int addr) | 
|---|
 | 110 | { | 
|---|
 | 111 |     FOREACH( sect, loader->get_section_table() ) | 
|---|
 | 112 |     { | 
|---|
 | 113 |         assert(&*sect != NULL); | 
|---|
 | 114 |         elfpp::sh_flags_e eflags = sect->get_flags(); | 
|---|
 | 115 |         if ( !(eflags & elfpp::SHF_ALLOC) ) | 
|---|
 | 116 |             continue; | 
|---|
 | 117 |         if(sect->get_load_address() == addr) //load_addr ? | 
|---|
 | 118 |         { | 
|---|
 | 119 |             return (&*sect); | 
|---|
 | 120 |         } | 
|---|
 | 121 |     } | 
|---|
 | 122 |     return NULL; | 
|---|
 | 123 | } | 
|---|
 | 124 |  | 
|---|
 | 125 |  | 
|---|
 | 126 | void MeMo::buildSoft(const std::string &filename) | 
|---|
 | 127 | { | 
|---|
 | 128 |     if(!m_ginit) | 
|---|
| [173] | 129 |         throw exception::RunTimeError(std::string("Can't get generator! ") ); | 
|---|
| [163] | 130 |  | 
|---|
 | 131 |     m_generator->write(filename); | 
|---|
 | 132 |  | 
|---|
 | 133 | } | 
|---|
 | 134 |  | 
|---|
| [173] | 135 | /* Load the content of filename in buffer, and send the size */ | 
|---|
 | 136 | //////////////////////////////////////////////////////// | 
|---|
 | 137 | size_t MeMo::load_bin(std::string filename, void* buffer) | 
|---|
 | 138 | { | 
|---|
 | 139 |  | 
|---|
 | 140 | #ifdef MOVER_DEBUG | 
|---|
 | 141 |     std::cout  << "Trying to load the binary blob from file '" << filename << "'" << std::endl; | 
|---|
 | 142 | #endif | 
|---|
 | 143 |  | 
|---|
 | 144 |     std::ifstream input(filename.c_str(), std::ios_base::binary|std::ios_base::in); | 
|---|
 | 145 |  | 
|---|
 | 146 |     if ( ! input.good() ) | 
|---|
 | 147 |         throw exception::RunTimeError(std::string("Can't open the file: ") + filename); | 
|---|
 | 148 |  | 
|---|
 | 149 |     input.seekg( 0, std::ifstream::end ); | 
|---|
 | 150 |     size_t size = input.tellg(); | 
|---|
 | 151 |     input.seekg( 0, std::ifstream::beg ); | 
|---|
 | 152 |  | 
|---|
 | 153 |     if ( !buffer ) | 
|---|
 | 154 |         throw exception::RunTimeError("Empty buffer!"); | 
|---|
 | 155 |  | 
|---|
 | 156 |     input.read( (char*)buffer, size ); | 
|---|
 | 157 |  | 
|---|
 | 158 |     input.close(); | 
|---|
 | 159 |  | 
|---|
 | 160 |     return size; | 
|---|
 | 161 | } | 
|---|
 | 162 |  | 
|---|
 | 163 |  | 
|---|
 | 164 | /* get the size of the content of the filename */ | 
|---|
| [165] | 165 | ////////////////////////////////////////// | 
|---|
| [173] | 166 | size_t MeMo::bin_size(std::string filename) | 
|---|
| [163] | 167 | { | 
|---|
| [173] | 168 |  | 
|---|
| [163] | 169 | #ifdef MOVER_DEBUG | 
|---|
| [173] | 170 |     std::cout  << "Trying to get the size of the binary blob '" << filename << "'" << std::endl; | 
|---|
| [163] | 171 | #endif | 
|---|
 | 172 |  | 
|---|
| [173] | 173 |     std::ifstream input(filename.c_str(), std::ios_base::binary|std::ios_base::in); | 
|---|
| [163] | 174 |  | 
|---|
 | 175 |     if ( ! input.good() ) | 
|---|
| [173] | 176 |         throw exception::RunTimeError(std::string("Can't open the file: ") + filename); | 
|---|
| [163] | 177 |  | 
|---|
 | 178 |     input.seekg( 0, std::ifstream::end ); | 
|---|
| [173] | 179 |     size_t size = input.tellg(); | 
|---|
| [163] | 180 |     input.seekg( 0, std::ifstream::beg ); | 
|---|
 | 181 |  | 
|---|
| [173] | 182 |     input.close(); | 
|---|
| [163] | 183 |  | 
|---|
| [173] | 184 |     return size; | 
|---|
| [163] | 185 | } | 
|---|
 | 186 |  | 
|---|
| [173] | 187 |  | 
|---|
| [165] | 188 | ///////////// | 
|---|
| [163] | 189 | MeMo::~MeMo() | 
|---|
 | 190 | { | 
|---|
 | 191 |     //std::cout << "Deleted MeMo " << *this << std::endl; | 
|---|
| [173] | 192 |     //std::free(m_data);//should be done by the elfpp driver since we passed the pointer | 
|---|
| [163] | 193 |     std::map<std::string, elfpp::object*>::iterator l; | 
|---|
 | 194 |     for(l = m_loaders.begin(); l != m_loaders.end(); l++) | 
|---|
 | 195 |     { | 
|---|
 | 196 |         delete (*l).second; | 
|---|
 | 197 |     } | 
|---|
 | 198 |     //delete m_generator; | 
|---|
 | 199 | } | 
|---|
 | 200 |  | 
|---|
 | 201 |  | 
|---|
 | 202 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 203 | // various mapping_info data structure access functions | 
|---|
 | 204 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
| [187] | 205 | mapping_cluster_t* MeMo::get_cluster_base( mapping_header_t* header ) | 
|---|
 | 206 | { | 
|---|
 | 207 |     return   (mapping_cluster_t*) ((char*)header + | 
|---|
 | 208 |                                   MAPPING_HEADER_SIZE); | 
|---|
 | 209 | } | 
|---|
| [163] | 210 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 211 | mapping_pseg_t* MeMo::get_pseg_base( mapping_header_t* header ) | 
|---|
 | 212 | { | 
|---|
 | 213 |     return   (mapping_pseg_t*)    ((char*)header + | 
|---|
 | 214 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 215 |                                   MAPPING_CLUSTER_SIZE*header->clusters); | 
|---|
 | 216 | } | 
|---|
 | 217 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 218 | mapping_vspace_t* MeMo::get_vspace_base( mapping_header_t* header ) | 
|---|
 | 219 | { | 
|---|
 | 220 |     return   (mapping_vspace_t*)  ((char*)header + | 
|---|
 | 221 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 222 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 223 |                                   MAPPING_PSEG_SIZE*header->psegs); | 
|---|
 | 224 | } | 
|---|
 | 225 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 226 | mapping_vseg_t* MeMo::get_vseg_base( mapping_header_t* header ) | 
|---|
 | 227 | { | 
|---|
 | 228 |     return   (mapping_vseg_t*)    ((char*)header + | 
|---|
 | 229 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 230 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 231 |                                   MAPPING_PSEG_SIZE*header->psegs + | 
|---|
 | 232 |                                   MAPPING_VSPACE_SIZE*header->vspaces); | 
|---|
 | 233 | } | 
|---|
 | 234 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 235 | mapping_vobj_t* MeMo::get_vobj_base( mapping_header_t* header ) | 
|---|
 | 236 | { | 
|---|
 | 237 |     return   (mapping_vobj_t*)    ((char*)header + | 
|---|
 | 238 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 239 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 240 |                                   MAPPING_PSEG_SIZE*header->psegs + | 
|---|
| [165] | 241 |                                   MAPPING_VSPACE_SIZE*header->vspaces + | 
|---|
 | 242 |                                   MAPPING_VSEG_SIZE*header->vsegs); | 
|---|
| [163] | 243 | } | 
|---|
 | 244 |  | 
|---|
 | 245 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 246 | // print the content of the mapping_info data structure  | 
|---|
 | 247 | //////////////////////////////////////////////////////////////////////// | 
|---|
 | 248 | void MeMo::print_mapping_info(void* desc) | 
|---|
 | 249 | { | 
|---|
 | 250 |     mapping_header_t*   header = (mapping_header_t*)desc;   | 
|---|
 | 251 |  | 
|---|
 | 252 |     mapping_pseg_t*         pseg    = get_pseg_base( header );; | 
|---|
 | 253 |     mapping_vspace_t*   vspace  = get_vspace_base ( header );; | 
|---|
 | 254 |     mapping_vseg_t*         vseg    = get_vseg_base ( header ); | 
|---|
 | 255 |     mapping_vobj_t*         vobj    = get_vobj_base ( header ); | 
|---|
 | 256 |  | 
|---|
 | 257 |     // header | 
|---|
| [165] | 258 |     std::cout << std::hex << "mapping_info" << std::dec << std::endl | 
|---|
| [163] | 259 |               << " + signature = " << header->signature << std::endl | 
|---|
| [165] | 260 |               << " + name      = " << header->name      << std::endl | 
|---|
 | 261 |               << " + clusters  = " << header->clusters  << std::endl | 
|---|
 | 262 |               << " + psegs     = " << header->psegs     << std::endl | 
|---|
 | 263 |               << " + ttys      = " << header->ttys      << std::endl | 
|---|
 | 264 |               << " + fbs       = " << header->fbs       << std::endl | 
|---|
 | 265 |               << " + vspaces   = " << header->vspaces   << std::endl | 
|---|
 | 266 |               << " + globals   = " << header->globals   << std::endl | 
|---|
 | 267 |               << " + vsegs     = " << header->vsegs     << std::endl | 
|---|
 | 268 |               << " + vobjs     = " << header->vsegs     << std::endl | 
|---|
 | 269 |               << " + tasks     = " << header->tasks     << std::endl; | 
|---|
| [163] | 270 |  | 
|---|
 | 271 |     // psegs | 
|---|
 | 272 |     for ( size_t pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ ) | 
|---|
 | 273 |     { | 
|---|
| [165] | 274 |         std::cout << "pseg " << pseg[pseg_id].name << std::hex << std::endl  | 
|---|
 | 275 |                   << " + base   = " << pseg[pseg_id].base   << std::endl  | 
|---|
 | 276 |                   << " + length = " << pseg[pseg_id].length << std::endl ; | 
|---|
| [163] | 277 |     } | 
|---|
 | 278 |  | 
|---|
 | 279 |     // globals | 
|---|
 | 280 |     for ( size_t vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) | 
|---|
 | 281 |     { | 
|---|
| [165] | 282 |         std::cout << std::endl; | 
|---|
 | 283 |         std::cout << "global vseg "   << vseg[vseg_id].name << std::hex << std::endl  | 
|---|
 | 284 |                   << " + vbase    = " << vseg[vseg_id].vbase << std::endl  | 
|---|
 | 285 |                   << " + length   = " << vseg[vseg_id].length << std::endl  | 
|---|
 | 286 |                   << " + mode     = " << (size_t)vseg[vseg_id].mode << std::endl  | 
|---|
 | 287 |                   << " + ident    = " << (bool)vseg[vseg_id].ident << std::endl  | 
|---|
 | 288 |                   << " + psegname = " << pseg[vseg[vseg_id].psegid].name << std::endl; | 
|---|
 | 289 |         for( size_t vobj_id = vseg[vseg_id].vobj_offset ;  | 
|---|
 | 290 |                     vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ;  | 
|---|
 | 291 |                     vobj_id++ ) | 
|---|
| [163] | 292 |         { | 
|---|
| [165] | 293 |             std::cout << "\t vobj "        << vobj[vobj_id].name    << std::endl | 
|---|
 | 294 |                       << "\t + index   = " << std::dec << vobj_id   << std::endl | 
|---|
 | 295 |                       << "\t + type    = " << vobj[vobj_id].type    << std::endl | 
|---|
 | 296 |                       << "\t + length  = " << vobj[vobj_id].length  << std::endl | 
|---|
 | 297 |                       << "\t + align   = " << vobj[vobj_id].align   << std::endl | 
|---|
 | 298 |                       << "\t + binpath = " << vobj[vobj_id].binpath << std::endl | 
|---|
 | 299 |                       << "\t + init    = " << vobj[vobj_id].init    << std::endl; | 
|---|
| [163] | 300 |         } | 
|---|
 | 301 |     } | 
|---|
 | 302 |  | 
|---|
 | 303 |     // vspaces | 
|---|
 | 304 |     for ( size_t vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) | 
|---|
 | 305 |     { | 
|---|
| [165] | 306 |         std::cout << "***vspace "  << vspace[vspace_id].name   << std::endl  | 
|---|
 | 307 |                   << " + vsegs = " <<  vspace[vspace_id].vsegs << std::endl  | 
|---|
 | 308 |                   << " + vobjs = " <<  vspace[vspace_id].vobjs << std::endl  | 
|---|
 | 309 |                   << " + tasks = " <<  vspace[vspace_id].tasks << std::endl; | 
|---|
| [163] | 310 |  | 
|---|
 | 311 |         for ( size_t vseg_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 312 |               vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ;  | 
|---|
 | 313 |               vseg_id++ ) | 
|---|
 | 314 |         { | 
|---|
| [165] | 315 |             std::cout << "\t vseg " << vseg[vseg_id].name  << std::endl | 
|---|
 | 316 |                       << "\t + vbase    = " << vseg[vseg_id].vbase             << std::endl | 
|---|
 | 317 |                       << "\t + length   = " << vseg[vseg_id].length            << std::endl | 
|---|
 | 318 |                       << "\t + mode     = " << (size_t)vseg[vseg_id].mode      << std::endl | 
|---|
 | 319 |                       << "\t + ident    = " << (bool)vseg[vseg_id].ident       << std::endl | 
|---|
 | 320 |                       << "\t + psegname = " << pseg[vseg[vseg_id].psegid].name << std::endl; | 
|---|
 | 321 |             for(size_t vobj_id = vseg[vseg_id].vobj_offset ;  | 
|---|
 | 322 |                        vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ;  | 
|---|
 | 323 |                        vobj_id++ ) | 
|---|
| [163] | 324 |             { | 
|---|
| [165] | 325 |                 std::cout << "\t\t vobj "      << vobj[vobj_id].name      << std::endl | 
|---|
 | 326 |                           << "\t\t + index   = " << std::dec << vobj_id   << std::endl | 
|---|
 | 327 |                           << "\t\t + type    = " << vobj[vobj_id].type    << std::endl | 
|---|
 | 328 |                           << "\t\t + length  = " << vobj[vobj_id].length  << std::endl | 
|---|
 | 329 |                           << "\t\t + align   = " << vobj[vobj_id].align   << std::endl | 
|---|
 | 330 |                           << "\t\t + binpath = " << vobj[vobj_id].binpath << std::endl | 
|---|
 | 331 |                           << "\t\t + init    = " << vobj[vobj_id].init    << std::endl; | 
|---|
| [163] | 332 |             } | 
|---|
 | 333 |         } | 
|---|
 | 334 |  | 
|---|
 | 335 |     } | 
|---|
 | 336 | } // end print_mapping_info() | 
|---|
 | 337 |  | 
|---|
 | 338 |  | 
|---|
| [165] | 339 | ////////////////////////////////////////// | 
|---|
| [173] | 340 | void MeMo::vseg_map( mapping_vseg_t* vseg) | 
|---|
| [163] | 341 | { | 
|---|
| [173] | 342 |     mapping_vobj_t*     vobj   = get_vobj_base( (mapping_header_t*) m_data ); | 
|---|
| [163] | 343 |     PSeg *ps = &(m_psegh.get(vseg->psegid));// get physical segment pointer(PSegHandler::get) | 
|---|
 | 344 |     elfpp::section* sect = NULL; | 
|---|
 | 345 |     size_t cur_vaddr; | 
|---|
 | 346 |     size_t cur_paddr; | 
|---|
 | 347 |     bool first = true; | 
|---|
 | 348 |     bool aligned = false; | 
|---|
 | 349 |  | 
|---|
 | 350 |     VSeg   *vSO = new VSeg; | 
|---|
 | 351 |  | 
|---|
 | 352 |     vSO->m_name = std::string(vseg->name); | 
|---|
 | 353 |     vSO->m_vma = vseg->vbase; | 
|---|
 | 354 |     vSO->m_lma = ps->nextLma(); | 
|---|
 | 355 |  | 
|---|
 | 356 |     cur_vaddr = vseg->vbase; | 
|---|
 | 357 |     cur_paddr = ps->nextLma(); | 
|---|
 | 358 |  | 
|---|
 | 359 |     mapping_vobj_t* cur_vobj; | 
|---|
 | 360 |     size_t simple_size = 0; //for debug | 
|---|
| [173] | 361 |  | 
|---|
| [163] | 362 | #ifdef MOVER_DEBUG | 
|---|
 | 363 |     std::cout << "--------------------vseg_map "<< vseg->name <<"---------------------" << std::endl; | 
|---|
 | 364 | #endif | 
|---|
| [173] | 365 |  | 
|---|
| [163] | 366 |     for ( size_t vobj_id = vseg->vobj_offset ; vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ ) | 
|---|
 | 367 |     { | 
|---|
 | 368 |         cur_vobj = &vobj[vobj_id]; | 
|---|
 | 369 |  | 
|---|
 | 370 | #ifdef MOVER_DEBUG | 
|---|
| [173] | 371 |         std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name << " (" <<cur_vobj->vaddr << ")" | 
|---|
| [163] | 372 |                         << " size: "<< cur_vobj->length << " type: " <<  cur_vobj->type << std::endl; | 
|---|
 | 373 | #endif | 
|---|
| [173] | 374 |         if(cur_vobj->type == VOBJ_TYPE_BLOB) | 
|---|
| [163] | 375 |         { | 
|---|
| [173] | 376 |             size_t blob_size; | 
|---|
 | 377 |             std::string filePath(m_pathHandler.getFullPath(std::string(cur_vobj->binpath))); | 
|---|
| [163] | 378 |  | 
|---|
 | 379 | #ifdef MOVER_DEBUG | 
|---|
| [173] | 380 |             std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl; | 
|---|
| [163] | 381 | #endif | 
|---|
| [173] | 382 |  | 
|---|
| [163] | 383 |             if(!filePath.compare(m_path))    //local blob: map_info | 
|---|
 | 384 |             { | 
|---|
 | 385 | #ifdef MOVER_DEBUG | 
|---|
 | 386 |                 std::cout << "Found the vseg of the mapping info" << std::endl; | 
|---|
 | 387 | #endif | 
|---|
| [173] | 388 |                 blob_size = this->m_size; | 
|---|
 | 389 |                 assert((blob_size >0) and "MAPPING INFO file is empty !?"); | 
|---|
| [163] | 390 |             } | 
|---|
 | 391 |             else | 
|---|
| [173] | 392 |             { | 
|---|
| [163] | 393 | #ifdef MOVER_DEBUG | 
|---|
| [173] | 394 |                 std::cout << "Found an BLOB vseg" << std::endl; | 
|---|
| [163] | 395 | #endif | 
|---|
| [173] | 396 |                 blob_size = bin_size(filePath); | 
|---|
 | 397 |             } | 
|---|
| [163] | 398 |  | 
|---|
 | 399 |  | 
|---|
| [173] | 400 |             /**creating a new section */ | 
|---|
 | 401 |             sect = new elfpp::section(*m_generator, elfpp::SHT_PROGBITS); | 
|---|
| [163] | 402 |  | 
|---|
| [173] | 403 |             sect->set_name(std::string(cur_vobj->name)); | 
|---|
 | 404 |             sect->set_flags(elfpp::SHF_ALLOC | elfpp::SHF_WRITE); | 
|---|
 | 405 |             sect->set_size(blob_size);//do the malloc for the get_content fonction | 
|---|
| [163] | 406 |  | 
|---|
| [173] | 407 |             assert(sect->get_content());//check allocation | 
|---|
| [163] | 408 |  | 
|---|
| [173] | 409 |             if(!filePath.compare(m_path))    //local blob: map_info | 
|---|
 | 410 |                 //memcpy(sect->get_content(), m_data, sect->get_size()); | 
|---|
 | 411 |                 /* this way the modification of the elf size are propageted to the giet */ | 
|---|
 | 412 |                 sect->set_content(this->m_data); | 
|---|
 | 413 |             else | 
|---|
 | 414 |                 load_bin(filePath, sect->get_content()); | 
|---|
| [163] | 415 |  | 
|---|
| [173] | 416 |  | 
|---|
 | 417 |             if(blob_size > cur_vobj->length) | 
|---|
 | 418 |             { | 
|---|
 | 419 |                 std::cout << std::hex << "!!! Warning, specified blob type vobj ("<< | 
|---|
 | 420 |                 cur_vobj->name  <<") size is "<< cur_vobj->length << ", the actual size is " | 
|---|
 | 421 |                 << blob_size  << " !!!" <<std::endl; | 
|---|
 | 422 |                 assert(0 and "blob vobj length smaller than the actual content" );//??? | 
|---|
| [163] | 423 |             } | 
|---|
 | 424 |  | 
|---|
| [173] | 425 |             cur_vobj->length = blob_size;//set the true size of this BLOB vobj | 
|---|
 | 426 |  | 
|---|
 | 427 |             vSO->m_file = filePath; | 
|---|
 | 428 |             vSO->m_loadable = true; | 
|---|
 | 429 |         } | 
|---|
 | 430 |         else if(cur_vobj->type == VOBJ_TYPE_ELF) | 
|---|
 | 431 |         { | 
|---|
 | 432 |             if(!first) | 
|---|
 | 433 |                 throw exception::RunTimeError(std::string("elf vobj type, must be placed first in a vseg")); | 
|---|
 | 434 |  | 
|---|
 | 435 |             size_t elf_size; | 
|---|
 | 436 |             std::string filePath(m_pathHandler.getFullPath(std::string(cur_vobj->binpath))); | 
|---|
 | 437 | #ifdef MOVER_DEBUG | 
|---|
 | 438 |             std::cout << "Handling: " << filePath << " ..." << std::endl; | 
|---|
 | 439 |             std::cout << "Found an ELF vseg" << std::endl; | 
|---|
 | 440 | #endif | 
|---|
 | 441 |             if(m_loaders.count(filePath) == 0 ) | 
|---|
 | 442 |                 m_loaders[filePath] = new elfpp::object(filePath); | 
|---|
 | 443 |             elfpp::object* loader = m_loaders[filePath];//TODO:free!? | 
|---|
 | 444 |  | 
|---|
 | 445 |             sect =  get_sect_by_addr(loader, cur_vaddr); | 
|---|
 | 446 |             assert(sect and "No section found"); | 
|---|
 | 447 |  | 
|---|
 | 448 |             sect->set_name(std::string(cur_vobj->name)); | 
|---|
 | 449 |  | 
|---|
 | 450 |  | 
|---|
 | 451 |             elf_size = sect->get_size(); | 
|---|
 | 452 |             assert((elf_size > 0) and "ELF section empty ?"); | 
|---|
 | 453 |  | 
|---|
 | 454 |             if(!m_ginit) | 
|---|
 | 455 |             { | 
|---|
 | 456 |                 /** Initailising the header of the generator from the first binary, | 
|---|
 | 457 |                 ** we suppose that the header is the same for all the binarys **/ | 
|---|
 | 458 |                 m_generator->copy_info(*loader); | 
|---|
 | 459 |                 m_ginit=true; | 
|---|
 | 460 |             } | 
|---|
 | 461 |  | 
|---|
| [163] | 462 |             if(elf_size > cur_vobj->length) | 
|---|
| [173] | 463 |             { | 
|---|
| [163] | 464 |                 std::cout << "Warning, specified elf type vobj ("<< | 
|---|
 | 465 |                 cur_vobj->name  <<") size is "<< cur_vobj->length << ", the actual size is " | 
|---|
 | 466 |                 << elf_size  << std::endl; | 
|---|
| [173] | 467 |                 //assert((elf_size < cur_vobj->length) and "elf vobj length smaller than the actual content" );//??? | 
|---|
 | 468 |                 assert((0) and "elf vobj length smaller than the actual content" );//??? | 
|---|
 | 469 |             } | 
|---|
| [163] | 470 |  | 
|---|
 | 471 |             cur_vobj->length = elf_size;//set the true size of this ELF vobj | 
|---|
 | 472 |  | 
|---|
 | 473 |             vSO->m_file = filePath; | 
|---|
| [173] | 474 |             vSO->m_loadable = true; | 
|---|
| [163] | 475 |         } | 
|---|
 | 476 |  | 
|---|
 | 477 |         //aligning the vobj->paddr if necessary | 
|---|
| [173] | 478 |         // | 
|---|
| [163] | 479 |         if(cur_vobj->align) | 
|---|
 | 480 |         { | 
|---|
 | 481 |             cur_paddr = PSeg::align(cur_paddr, cur_vobj->align); | 
|---|
 | 482 |             aligned = true; | 
|---|
 | 483 |         } | 
|---|
 | 484 |  | 
|---|
 | 485 |         cur_vaddr += cur_vobj->length; | 
|---|
 | 486 |         cur_paddr += cur_vobj->length; | 
|---|
 | 487 |         simple_size += cur_vobj->length; | 
|---|
| [173] | 488 |         first = false; | 
|---|
| [163] | 489 |     } | 
|---|
 | 490 |  | 
|---|
 | 491 |     assert((cur_vaddr >= vseg->vbase )); | 
|---|
 | 492 |     assert((cur_paddr >= ps->nextLma() )); | 
|---|
 | 493 |  | 
|---|
 | 494 |     vSO->m_length = (cur_paddr - ps->nextLma()); //pageAlign is done by the psegs | 
|---|
 | 495 |  | 
|---|
 | 496 | #ifdef MOVER_DEBUG | 
|---|
 | 497 |     if(aligned) | 
|---|
 | 498 |     { | 
|---|
 | 499 |         std::cout << "vseg base "<< std::hex << ps->nextLma() | 
|---|
 | 500 |         <<(ps->nextLma()+simple_size)  <<" size " << std::dec << simple_size << | 
|---|
| [173] | 501 |         std::endl; | 
|---|
| [163] | 502 |  | 
|---|
 | 503 |         std::cout << "vseg aligned to: base: " << std::hex << ps->nextLma() | 
|---|
 | 504 |         <<" to "<< std::hex << ps->nextLma()+vSO->m_length<< " size " << std::dec << | 
|---|
 | 505 |         vSO->m_length << std::endl; | 
|---|
 | 506 |     } | 
|---|
 | 507 | #endif | 
|---|
 | 508 |  | 
|---|
| [173] | 509 |     vSO->m_ident = vseg->ident; | 
|---|
 | 510 |  | 
|---|
| [163] | 511 |     //set the lma | 
|---|
 | 512 |     if ( vseg->ident != 0 )            // identity mapping required | 
|---|
 | 513 |         ps->addIdent( *vSO ); | 
|---|
 | 514 |     else | 
|---|
 | 515 |         ps->add( *vSO ); | 
|---|
| [173] | 516 |  | 
|---|
| [163] | 517 |     if(!sect) | 
|---|
 | 518 |         return; | 
|---|
 | 519 |  | 
|---|
 | 520 | #ifdef MOVER_DEBUG | 
|---|
 | 521 |     std::cout << "section: "<< *sect <<"\n seted to: " << (*vSO) << std::endl; | 
|---|
 | 522 | #endif | 
|---|
 | 523 |  | 
|---|
 | 524 |     sect->set_vaddr((*vSO).lma()); | 
|---|
 | 525 |     m_generator->add_section(*(new elfpp::section(*sect))); | 
|---|
 | 526 |  | 
|---|
 | 527 | } // end vseg_map() | 
|---|
| [173] | 528 |   | 
|---|
| [163] | 529 |  | 
|---|
| [165] | 530 | /////////////////////////////// | 
|---|
| [163] | 531 | void MeMo::buildMap(void* desc) | 
|---|
 | 532 | { | 
|---|
 | 533 |     mapping_header_t*   header = (mapping_header_t*)desc;   | 
|---|
 | 534 |  | 
|---|
| [187] | 535 |     mapping_cluster_t*  cluster = get_cluster_base( header );      | 
|---|
| [163] | 536 |     mapping_vspace_t*   vspace = get_vspace_base( header );      | 
|---|
 | 537 |     mapping_pseg_t*     pseg   = get_pseg_base( header );  | 
|---|
 | 538 |     mapping_vseg_t*     vseg   = get_vseg_base( header ); | 
|---|
 | 539 |  | 
|---|
 | 540 |     // get the psegs | 
|---|
| [165] | 541 |  | 
|---|
| [163] | 542 | #ifdef MOVER_DEBUG | 
|---|
 | 543 | std::cout << "\n******* Storing Pseg information *********\n" << std::endl; | 
|---|
 | 544 | #endif | 
|---|
| [165] | 545 |  | 
|---|
| [187] | 546 | #ifdef DISTRIBUTED_SCHEDULERS  | 
|---|
 | 547 |     char found; | 
|---|
 | 548 | #endif | 
|---|
 | 549 |  | 
|---|
 | 550 |     for ( size_t cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ ) | 
|---|
| [163] | 551 |     { | 
|---|
| [187] | 552 |  | 
|---|
 | 553 | #ifdef DISTRIBUTED_SCHEDULERS  | 
|---|
 | 554 |         found    = 0; | 
|---|
 | 555 | #endif | 
|---|
 | 556 |  | 
|---|
 | 557 |         for ( size_t pseg_id = cluster[cluster_id].pseg_offset ; | 
|---|
 | 558 |               pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs ; | 
|---|
 | 559 |               pseg_id++ ) | 
|---|
 | 560 |         { | 
|---|
 | 561 |             //build pseg | 
|---|
 | 562 |             std::string name(pseg[pseg_id].name); | 
|---|
 | 563 |             PSeg *ps = new PSeg(name, pseg[pseg_id].base, pseg[pseg_id].length); | 
|---|
 | 564 |  | 
|---|
 | 565 | #ifdef DISTRIBUTED_SCHEDULERS  | 
|---|
 | 566 |             if ( (pseg[pseg_id].type == PSEG_TYPE_RAM) && (found == 0) ) | 
|---|
 | 567 |             { | 
|---|
 | 568 |                 ps->incNextLma( (cluster[cluster_id].procs << 12) ); | 
|---|
 | 569 |                 found  = 1; | 
|---|
 | 570 |             } | 
|---|
 | 571 | #endif | 
|---|
 | 572 |             m_psegh.m_pSegs.push_back(*ps); | 
|---|
 | 573 |  | 
|---|
 | 574 |         } | 
|---|
| [163] | 575 |     } | 
|---|
 | 576 |  | 
|---|
 | 577 |     // map global vsegs | 
|---|
| [165] | 578 |  | 
|---|
| [163] | 579 | #ifdef MOVER_DEBUG | 
|---|
 | 580 | std::cout << "\n******* mapping global vsegs *********\n" << std::endl; | 
|---|
 | 581 | #endif | 
|---|
| [165] | 582 |  | 
|---|
| [163] | 583 |     for ( size_t vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) | 
|---|
 | 584 |     { | 
|---|
 | 585 |         vseg_map( &vseg[vseg_id]); | 
|---|
 | 586 |     } | 
|---|
 | 587 |  | 
|---|
| [165] | 588 |     // loop on virtual spaces to map private vsegs | 
|---|
| [163] | 589 |     for (size_t vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) | 
|---|
 | 590 |     { | 
|---|
 | 591 |  | 
|---|
 | 592 | #ifdef MOVER_DEBUG | 
|---|
 | 593 | std::cout << "\n******* mapping all vsegs of " << vspace[vspace_id].name << " *********\n" << std::endl; | 
|---|
 | 594 | #endif | 
|---|
 | 595 |              | 
|---|
 | 596 |         for ( size_t vseg_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 597 |               vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ;  | 
|---|
 | 598 |               vseg_id++ ) | 
|---|
 | 599 |         { | 
|---|
 | 600 |             vseg_map( &vseg[vseg_id]);  | 
|---|
 | 601 |         } | 
|---|
 | 602 |     }  | 
|---|
 | 603 |  | 
|---|
 | 604 | } // end buildMap() | 
|---|
 | 605 |  | 
|---|
 | 606 |  | 
|---|
 | 607 |  | 
|---|
 | 608 | // Local Variables: | 
|---|
 | 609 | // tab-width: 4 | 
|---|
 | 610 | // c-basic-offset: 4 | 
|---|
 | 611 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) | 
|---|
 | 612 | // indent-tabs-mode: nil | 
|---|
 | 613 | // End: | 
|---|
 | 614 |  | 
|---|
 | 615 | // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 | 
|---|
 | 616 |  | 
|---|