source: soft/giet_vm/memo/src/memo.cpp @ 408

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