static void * osTryReserveHeapMemory (W_ len, void *hint) { void *base, *top; void *start, *end; /* We try to allocate len + MBLOCK_SIZE, because we need memory which is MBLOCK_SIZE aligned, and then we discard what we don't need */ base = my_mmap(hint, len + MBLOCK_SIZE, MEM_RESERVE); top = (void*)((W_)base + len + MBLOCK_SIZE); if (((W_)base & MBLOCK_MASK) != 0) { start = MBLOCK_ROUND_UP(base); end = MBLOCK_ROUND_DOWN(top); ASSERT(((W_)end - (W_)start) == len); if (munmap(base, (W_)start-(W_)base) < 0) { sysErrorBelch("unable to release slop before heap"); } if (munmap(end, (W_)top-(W_)end) < 0) { sysErrorBelch("unable to release slop after heap"); } } else { start = base; } return start; }
Heap_t* Heap_Alloc(int MinSize, int MaxSize) { static int heap_count = 0; Heap_t *res = &(Heaps[heap_count++]); int maxsize_pageround = RoundUp(MaxSize,TILT_PAGESIZE); res->size = maxsize_pageround; res->bottom = (mem_t) my_mmap(maxsize_pageround, PROT_READ | PROT_WRITE); res->cursor = res->bottom; res->top = res->bottom + MinSize / (sizeof (val_t)); res->writeableTop = res->bottom + maxsize_pageround / (sizeof (val_t)); res->mappedTop = res->writeableTop; SetRange(&(res->range), res->bottom, res->mappedTop); res->valid = 1; res->bitmap = paranoid ? CreateBitmap(maxsize_pageround / 4) : NULL; res->freshPages = (int *)emalloc( DivideUp(maxsize_pageround / TILT_PAGESIZE, 32) * sizeof(int)); memset((int *)res->freshPages, 0, DivideUp(maxsize_pageround / TILT_PAGESIZE, 32) * sizeof(int)); assert(res->bottom != (mem_t) -1); assert(heap_count < NumHeap); assert(MaxSize >= MinSize); /* Try to lock down pages and force page-table to be initialized; otherwise, PadHeapArea can often take 0.1 - 0.2 ms. Even with this, there are occasional (but far fewer) page table misses. */ if (geteuid() == 0) (void)mlock((caddr_t) res->bottom, maxsize_pageround); return res; }
void * osGetMBlocks(nat n) { caddr_t ret; W_ size = MBLOCK_SIZE * (W_)n; if (next_request == 0) { // use gen_map_mblocks the first time. ret = gen_map_mblocks(size); } else { ret = my_mmap(next_request, size, MEM_RESERVE_AND_COMMIT); if (((W_)ret & MBLOCK_MASK) != 0) { // misaligned block! #if 0 // defined(DEBUG) errorBelch("warning: getMBlock: misaligned block %p returned " "when allocating %d megablock(s) at %p", ret, n, next_request); #endif // unmap this block... if (munmap(ret, size) == -1) { barf("getMBlock: munmap failed"); } // and do it the hard way ret = gen_map_mblocks(size); } } // Next time, we'll try to allocate right after the block we just got. // ToDo: check that we haven't already grabbed the memory at next_request next_request = ret + size; return ret; }
static Stacklet_t* Stacklet_Alloc(StackChain_t* stackChain) { int i; Stacklet_t *res = NULL; /* Each stacklet contains the primary and replica. Each one starts with a guard page, a C area, and then an ML area. */ int size = (GuardStackletSize + MLStackletSize + CStackletSize) * kilobyte; /* for just one of the two: primary and replica */ assert(stackletOffset == size); for (i=0; i<NumStacklet; i++) if (CompareAndSwap(&Stacklets[i].count, 0, 1) == 0) { res = &Stacklets[i]; break; } if (res == NULL) DIE("out of stack space"); res->parent = stackChain; res->state = Inconsistent; if (!res->mapped) { mem_t start = my_mmap(2 * size, PROT_READ | PROT_WRITE); mem_t middle = start + size / (sizeof (val_t)); res->baseExtendedBottom = start + (GuardStackletSize * kilobyte) / (sizeof (val_t)); res->baseBottom = res->baseExtendedBottom + (CStackletSize * kilobyte) / (sizeof (val_t)); res->baseTop = res->baseBottom + (MLStackletSize * kilobyte) / (sizeof (val_t)); assert(res->baseTop == middle); /* Get some initial room in multiples of 64 bytes; Sparc requires at least 68 byte for the save area. */ res->baseTop -= (128 / sizeof(val_t)); my_mprotect(0, (caddr_t) start, GuardStackletSize * kilobyte, PROT_NONE); /* Guard page at bottom of primary */ my_mprotect(1, (caddr_t) middle, GuardStackletSize * kilobyte, PROT_NONE); /* Guard page at bottom of replica */ res->callinfoStack = SetCreate(size / (32 * sizeof (val_t))); res->mapped = 1; } res->baseCursor = res->baseTop; for (i=0; i<32; i++) res->bottomBaseRegs[i] = 0; SetReset(res->callinfoStack); return res; }
static void * gen_map_mblocks (W_ size) { int slop; StgWord8 *ret; // Try to map a larger block, and take the aligned portion from // it (unmap the rest). size += MBLOCK_SIZE; ret = my_mmap(0, size, MEM_RESERVE_AND_COMMIT); // unmap the slop bits around the chunk we allocated slop = (W_)ret & MBLOCK_MASK; if (munmap((void*)ret, MBLOCK_SIZE - slop) == -1) { barf("gen_map_mblocks: munmap failed"); } if (slop > 0 && munmap((void*)(ret+size-slop), slop) == -1) { barf("gen_map_mblocks: munmap failed"); } // ToDo: if we happened to get an aligned block, then don't // unmap the excess, just use it. For this to work, you // need to keep in mind the following: // * Calling my_mmap() with an 'addr' arg pointing to // already my_mmap()ed space is OK and won't fail. // * If my_mmap() can't satisfy the request at the // given 'next_request' address in getMBlocks(), that // you unmap the extra mblock mmap()ed here (or simply // satisfy yourself that the slop introduced isn't worth // salvaging.) // // next time, try after the block we just got. ret += MBLOCK_SIZE - slop; return ret; }
int main(int argc, char** argv) { if(argc == 2) { strcpy(my_video_dev, argv[1]); } else { strcpy(my_video_dev, "/dev/video0"); } //if (-1 == (fd = open(my_video_dev, O_RDWR))) { if (-1 == (fd = v4l1_open(my_video_dev, O_RDWR))) { printf("Error opening device: %s\n", my_video_dev); goto error; } //if( -1 == ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) ) { if( ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) < 0 ) { printf("asd 1\n"); if( -1 == ioctl(fd, VIDIOCGCAP, &capability) ) { printf("asd 2\n"); printf("Error1: ioctl(fd,VIDIOCGCAP,&capability)\n"); camDriver = DRIVER_NONE; goto error; } else { printf("asd 3\n"); camDriver = DRIVER_V4L; } } else { printf("asd 4\n"); camDriver = DRIVER_V4L2; v4l1_close(fd); fd = v4l1_open(my_video_dev, O_RDWR); if( -1 == my_ioctl(VIDIOCGCAP, &capability)) { printf("asd 5\n"); printf("Error2: ioctl(fd,VIDIOCGCAP,&capability)\n"); goto error; } } // if( DRIVER_V4L == camDriver ) { printf("\n -----[ VIDIOCGCAP returns ]-----\n"); printf(" name: %s\n", capability.name); printf(" type: %i\n", capability.type); printf(" channels: %i\n", capability.channels); printf(" audios: %i\n", capability.audios); printf(" maxwidth: %i\n", capability.maxwidth); printf(" maxheight: %i\n", capability.maxheight); printf(" minwidth: %i\n", capability.minwidth); printf(" minheight: %i\n", capability.minheight); // } if (-1 == my_ioctl(VIDIOCGPICT,&picture)) { printf("Error: ioctl(fd,VIDIOCGCPICT,&picture)\n"); goto error; } printf("\n -----[ VIDIOCGPICT returns ]-----\n"); printf(" brightness: %i\n", picture.brightness); printf(" hue: %i\n", picture.hue); printf(" colour: %i\n", picture.colour); printf(" contrast: %i\n", picture.contrast); printf(" whiteness: %i\n", picture.whiteness); printf(" depth: %i\n", picture.depth); char static palet_tipi_str[64]; palette_name(palet_tipi_str, picture.palette); printf(" palette: %s\n\n", palet_tipi_str); vch.channel = 0; // vch.norm = VIDEO_MODE_PAL; if(-1 == my_ioctl(VIDIOCSCHAN,&vch)) { perror("Setting channel\n"); goto error; } fcntl(fd,F_SETFD,FD_CLOEXEC); if (-1 == my_ioctl(VIDIOCGMBUF,&gb_buffers)) { printf("Error: Error getting buffers\n"); goto error; } map = my_mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (map == NULL) { printf("Error: Mmap returned NULL\n"); goto error; } // Set up out capture to use the correct resolution my_buf.width = mywidth; my_buf.height = myheight; my_buf.format = VIDEO_PALETTE_RGB24; // Set up out video output SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(mywidth, myheight, 24, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } SDL_WM_SetCaption("Oy oy oy teve pirogrami", NULL); // Tell the capture card to fill frame 0 my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" ilk my_buf.frame=0 da hata olustu\n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } // This is the infinate loop // We basically: // capture frame 1 // sync frame 0 // process frame 0 // capture frame 0 // sync frame 1 // process frame 1 // For more information, read the programming how-to that came with xawtv do { my_buf.frame = 1; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=1 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map); my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=0 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 1; if (-1 == my_ioctl(VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map + gb_buffers.offsets[1]); SDL_PollEvent(&event); } while (event.type != SDL_KEYDOWN); error: SDL_Quit(); return EXIT_SUCCESS; }
void osCommitMemory(void *at, W_ size) { my_mmap(at, size, MEM_COMMIT); }
// ================================================= MAIN ============================================== int main(int argc, char* argv[]) { // ========================================== Parameters =========================================== bool verbose = false; bool drawM = false; bool ram_db = true; bool load_k = false; std::string filename_db = ":memory:"; const char* filename_calib; const char* inputFilename_rgb; const char* outputFilename; std::vector< std::string > imageList_rgb; // ========================================== Check parameters ========================================== if( argc < 2 ) { help(); return 0; } else { for(int i = 1; i < argc; i++ ) { const char* s = argv[i]; if( strcmp( s, "-i" ) == 0 ) { i++; inputFilename_rgb = argv[i]; } else if( strcmp( s, "-db" ) == 0 ) { i++; filename_db = argv[i]; ram_db = false; } else if( strcmp( s, "-k" ) == 0 ) { i++; filename_calib = argv[i]; load_k = true; } else if( strcmp( s, "-o" ) == 0 ) { i++; outputFilename = argv[i]; } else if( strcmp( s, "-v" ) == 0 ) { verbose = true; } else if( strcmp( s, "-m" ) == 0 ) { drawM = true; } else { help(); return fprintf( stderr, "Unknown option %s\n", s ), -1; } } } if (verbose) cout << "\nParameters read...\t\t[OK]" << '\n'; if (verbose) cout << "Data init...\t\t\t"; // ========================================== Varible declaration ========================================== int num_features; int num_cameras; timer_wall timer1; std::vector< cv::Mat > images, images_depth;//, images_matches; // ==================================================================================================== // ========================================== Start execution ========================================= // ==================================================================================================== // ========================================== Read Images ========================================== if (verbose) { std::cout << "[OK]" << '\n'; // DATA initialization OK std::cout << "Reading Files:\t" << inputFilename_rgb << "\n"; std::cout << "File list...\t\t\t"; } importXMLImageList(inputFilename_rgb, imageList_rgb); //Reading list of images from XML list if (verbose) { std::cout << "[OK]\n"; std::cout << "Loading Images...\t\t"; } for (int i = 0; i < (int)imageList_rgb.size(); i++ ) //Store all images in std::vector<cv::Mat> { images.push_back( cv::imread(imageList_rgb[i], 1) ); } if (verbose) { std::cout << "[OK]\n"; std::cout << "Number of Images: " << images.size() << "\n"; printf("Size of Images: \tWidth: %i || Height: %i\n", images[0].size().width, images[0].size().height); } // ======================================== END Read Images ======================================== Eigen::Matrix3d K; if (load_k) // If Calibration matrix is taken from txt file { Eigen::MatrixXd K_load; importTXTEigen(filename_calib, K_load); K << K_load; } else { double wimg = images[0].size().width; double himg = images[0].size().height; double f = 1000.0; K << f, 0.0, wimg/2, 0.0, f, himg/2, 0.0, 0.0, 1.0; // Camera Matrix (intrinsics) } if (verbose) std::cout << "\nCalibration Matrix:\n" << K << "\n"; HandleDB mydb( (char*)filename_db.c_str() ); mydb.openDB(); if ( ram_db ) // If database is in ram, create table and index { mydb.createFeaturesTable(); mydb.createIndex1(); } if (!mydb.isOpen()) exit(0); if ( ram_db ) // If database is in ram, solve features map and store in db { boost::shared_ptr< SiftED > myfeat( new SiftED(&imageList_rgb) ); myfeat->solveSift(); // myfeat->loadImages(); if( drawM ) myfeat->enableKeyPoint(); boost::shared_ptr< MatchesMap > my_mmap( new MatchesMap(500,35) ); my_mmap->solveMatches(myfeat->getDescriptorsGPU()); my_mmap->robustifyMatches(myfeat->getKeypointsGPU()); timer1.start(); my_mmap->solveDB( &mydb, myfeat->getKeypointsGPU() ); std::cout << "Elapsed time to solve DB: " << timer1.elapsed_s() << " [s]\n"; // my_mmap.txt((char*)"./match.txt", myfeat->getKeypointsGPU()); if( drawM ) my_mmap->plot( &images, myfeat->getKeypointsSet() ); } boost::shared_ptr< FeaturesMap > featM (new FeaturesMap()); featM->solveVisibility( &mydb ); printf("Visibility Matrix [%d x %d]\n",featM->getVisibility()->rows(),featM->getVisibility()->cols()); num_cameras = featM->getNumberCameras(); num_features = featM->getNumberFeatures(); mydb.closeDB(); // SfM sfm01( num_cameras, num_features, K ); // // sfm01.solvePose( &my_mmap.globalMatch, &myfeat.set_of_keypoints); // sfm01.solvePose( (featM->getVisibility()).get(), (featM->getCoordinates()).get() ); // sfm01.solveStructure( (featM->getVisibility()).get(), (featM->getCoordinates()).get() ); // std::cout << "Structure =\n" << sfm01.Structure.transpose() << "\n"; // ========================================== Optimization ========================================== // double intrinsics[4] = { K(0,0), K(1,1), K(0,2), K(1,2) }; // std::vector< double > intrinsics_param(&intrinsics[0], &intrinsics[4]); double distcoeff[5] = {2.5552679187075661e-01, -5.8740292343503686e-01, -3.0863014649845459e-04, 1.9066445284294834e-03, 5.1108649981093257e-01}; std::vector< double > coefficients(&distcoeff[0], &distcoeff[5]); // std::vector< double > coefficients(5,0.0);/// active for dinosaur /* GlobalOptimizerSfM opt01; opt01.setParameters( (featM->getVisibility()).get(), (featM->getCoordinates()).get(), &sfm01.Quat_cumulative, &sfm01.tr_global, &sfm01.Structure ); opt01.setIntrinsics( &K ); opt01.setDistortion( &coefficients ); opt01.runBA();// argv[0] );// bundle adjustment to all data // FINAL DATA PRINTING *************************** sfm01.updateCamera(); // std::cout << "Recover structure matrix:\n" << sfm01.Structure.transpose() << "\n"; writePMVS("./pmvs", imageList_rgb, sfm01.Cameras_RCV, K, coefficients); */ timer1.start(); IncrementalBA opt01( (featM->getVisibility()).get(), (featM->getCoordinates()).get() ); opt01.setIntrinsics( K ); opt01.setDistortion( &coefficients ); opt01.runC(); GlobalOptimizerSfM opt03; opt03.setParameters( (featM->getVisibility()).get(), (featM->getCoordinates()).get(), &opt01.quaternion, &opt01.translation, &opt01.structure ); opt03.setIntrinsics( &K ); opt03.setDistortion( &coefficients ); opt03.runBA();// argv[0] );// bundle adjustment to all data std::cout << "Incrementel BA time: "<< timer1.elapsed_s() << " [s]\n"; opt01.updateCamera(); std::vector< Eigen::Matrix3d > Rotation(opt01.quaternion.size()); for (register int i = 0; i < Rotation.size(); ++i) Rotation[i] = opt01.quaternion[i].toRotationMatrix(); exportPMVS("./pmvs", imageList_rgb, opt01.Camera, K, coefficients); // ========================================== END Optimization ========================================== // plot TESTING // int max_WP = sfm01.plotSt.maxCoeff(); // std::cout << "maximum in plot WP = " << max_WP << "\n"; // std::cout << "plotSt = " << sfm01.plotSt.transpose() << "\n"; // std::vector< std::vector<cv::Point3d> > WP(max_WP+1); // std::vector<cv::Point3d> x3plot; // for (int cam = 0; cam < max_WP+1; cam++) // { // x3plot.clear(); // for (int ft = 0; ft < num_features; ft++) // { // if (cam == sfm01.plotSt(ft)) // { // x3plot.push_back( cv::Point3d(sfm01.Structure(0,ft),sfm01.Structure(1,ft),sfm01.Structure(2,ft)) ); // } // } // std::cout << "x3plot size = " << x3plot.size() << "\n"; // std::cout << "cam = " << cam << "\n"; // WP[cam] = x3plot; // } // end plot TESTING // Plot for IncrementalBA structure in one vector (Global) std::vector< std::vector<cv::Point3d> > WP; std::vector<cv::Point3d> pts; eigen2point3_vector( opt01.structure , pts ); WP.push_back(pts); // sfm data PlotGL::viewer.setRotation( &Rotation ); PlotGL::viewer.setTranslation( &opt01.translation ); PlotGL::viewer.setStructure( &WP ); // PlotGL::viewer.setColor( &Color ); // PLOT for sfm object structure in one vector (Global) // std::vector< std::vector<cv::Point3d> > WP; // std::vector<cv::Point3d> pts; // eigen2point3_vector( sfm01.Structure , pts ); // WP.push_back(pts); // // // sfm data // PlotGL::viewer.setRotation( &sfm01.Rot_global ); // PlotGL::viewer.setTranslation( &sfm01.tr_global ); // PlotGL::viewer.setStructure( &WP ); // // PlotGL::viewer.setColor( &Color ); PlotGL::viewer.run(argc, argv, !ram_db); // false); exit(0); }
// ================================================= MAIN ============================================== int main(int argc, char* argv[]) { // ========================================== Parameters =========================================== bool ram_db = true; bool verbose = false; bool drawM = false; bool load_k = false; bool save_ply = false; const char* filename_calib; const char* inputFilename_rgb; const char* inputFilename_depth; const char* outputFilename; std::string filename_db = ":memory:"; std::vector< std::string > imageList_rgb; std::vector< std::string > imageList_depth; // ========================================== Check parameters ========================================== if( argc < 2 ) { help(argv[0]); return 0; } else { for(int i = 1; i < argc; i++ ) { const char* s = argv[i]; if( strcmp( s, "-i" ) == 0 ) { i++; inputFilename_rgb = argv[i]; } else if( strcmp( s, "-d" ) == 0 ) { i++; inputFilename_depth = argv[i]; } else if( strcmp( s, "-o" ) == 0 ) { i++; outputFilename = argv[i]; save_ply = true; } else if( strcmp( s, "-db" ) == 0 ) { i++; filename_db = argv[i]; ram_db = false; } else if( strcmp( s, "-k" ) == 0 ) { i++; filename_calib = argv[i]; load_k = true; } else if( strcmp( s, "-v" ) == 0 ) { verbose = true; } else if( strcmp( s, "-m" ) == 0 ) { drawM = true; } else { help(argv[0]); return fprintf( stderr, "Unknown option %s\n", s ), -1; } } } if (verbose) cout << "Parameters read...\t\t[OK]" << '\n'; if (verbose) cout << "Data init...\t\t\t"; // ========================================== Varible declaration ========================================== int num_goodmatch = 35; int num_features; int num_cameras; timer_wall timer1; std::vector< cv::Mat > images, images_depth;//, images_matches; typedef std::vector< Eigen::Quaternion<double> > Qd_vector; typedef std::vector< Eigen::Vector3d > V3d_vector; boost::shared_ptr< Qd_vector > Qn_global; boost::shared_ptr< V3d_vector > tr_global; // ========================================== Read Images ========================================== if (verbose) { std::cout << "[OK]" << '\n'; // DATA initialization OK std::cout << "Reading Files:\t" << inputFilename_rgb << " & " << inputFilename_depth << '\n'; std::cout << "File list...\t\t\t"; } importXMLImageList(inputFilename_rgb, imageList_rgb); //Reading list of images from XML list importXMLImageList(inputFilename_depth, imageList_depth); if (verbose) { std::cout << "[OK]\n"; std::cout << "Loading Images...\t\t"; } for (int i = 0; i < (int)imageList_rgb.size(); i++ ) //Store all images in std::vector<cv::Mat> { images.push_back( cv::imread(imageList_rgb[i], 1) ); images_depth.push_back( cv::imread(imageList_depth[i], -1) ); } if (verbose) { std::cout << "[OK]\n"; std::cout << "Number of Images: " << images.size() << "\n"; printf("Size of Images: \tWidth: %i\t||\t Height: %i\n", images[0].size().width, images[0].size().height); std::cout << "\nDetection and Descriptor...\t"; } // ======================================== END Read Images ======================================== Eigen::Matrix3d K; if (load_k) // If Calibration matrix is taken from txt file { Eigen::MatrixXd K_load; importTXTEigen(filename_calib, K_load); K << K_load; } else { double wimg = images[0].size().width - 1.0; double himg = images[0].size().height - 1.0; double f = 520.0; K << f, 0.0, wimg/2, 0.0, f, himg/2, 0.0, 0.0, 1.0; // Camera Matrix (intrinsics) } if (verbose) std::cout << "\nCalibration Matrix:\n" << K << "\n"; // ==================================================================================================== // ========================================== Start execution ========================================= // ==================================================================================================== HandleDB mydb( (char*)filename_db.c_str() ); mydb.openDB(); if ( ram_db ) // If database is in ram, create table and index { mydb.createFeaturesTable(); mydb.createIndex1(); } if (!mydb.isOpen()) exit(0); if ( ram_db ) // If database is in ram, solve features map and store in db { boost::shared_ptr< SiftED > myfeat( new SiftED(&imageList_rgb) ); myfeat->solveSift(); // myfeat->loadImages(); if( drawM ) myfeat->enableKeyPoint(); boost::shared_ptr< MatchesMap > my_mmap( new MatchesMap(500,35) ); my_mmap->solveMatches(myfeat->getDescriptorsGPU()); my_mmap->robustifyMatches(myfeat->getKeypointsGPU()); my_mmap->depthFilter(myfeat->getKeypointsGPU(), &imageList_depth, 3); timer1.start(); my_mmap->solveDB( &mydb, myfeat->getKeypointsGPU() ); DEBUG_1( std::cout << "Elapsed time to solve DB: " << timer1.elapsed_s() << " [s]\n"; ) // my_mmap.txt((char*)"./match.txt", &myfeat.keypointsGPU); if( drawM ) my_mmap->plot( &images, myfeat->getKeypointsSet() ); }
/* * Open an ELF file and load it into memory. */ static Elf32_Addr load_elf_file(const char *filename, size_t pagesize, Elf32_Addr *out_base, Elf32_Addr *out_phdr, Elf32_Addr *out_phnum, const char **out_interp) { int fd = open_program(filename); if (fd < 0) { fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); exit(2); } uintptr_t pread_pos = 0; Elf32_Ehdr ehdr; my_pread(filename, "Failed to read ELF header from file! ", fd, &ehdr, sizeof(ehdr), 0, &pread_pos); if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || ehdr.e_version != EV_CURRENT || ehdr.e_ehsize != sizeof(ehdr) || ehdr.e_phentsize != sizeof(Elf32_Phdr)) { fprintf(stderr, "%s has no valid ELF header!\n", filename); exit(1); } switch (ehdr.e_machine) { #if defined(__i386__) case EM_386: #elif defined(__x86_64__) case EM_X86_64: #elif defined(__arm__) case EM_ARM: #elif defined(__mips__) case EM_MIPS: #else # error "Don't know the e_machine value for this architecture!" #endif break; default: fprintf(stderr, "%s: ELF file has wrong architecture (e_machine=%u)\n", filename, ehdr.e_machine); exit(1); } Elf32_Phdr phdr[MAX_PHNUM]; if (ehdr.e_phnum > sizeof(phdr) / sizeof(phdr[0]) || ehdr.e_phnum < 1) { fprintf(stderr, "%s: ELF file has unreasonable e_phnum=%u\n", filename, ehdr.e_phnum); exit(1); } bool anywhere; switch (ehdr.e_type) { case ET_EXEC: anywhere = false; break; case ET_DYN: anywhere = true; break; default: fprintf(stderr, "%s: ELF file has unexpected e_type=%u\n", filename, ehdr.e_type); exit(1); } my_pread(filename, "Failed to read program headers from ELF file! ", fd, phdr, sizeof(phdr[0]) * ehdr.e_phnum, ehdr.e_phoff, &pread_pos); size_t i = 0; while (i < ehdr.e_phnum && phdr[i].p_type != PT_LOAD) ++i; if (i == ehdr.e_phnum) { fprintf(stderr, "%s: ELF file has no PT_LOAD header!", filename); exit(1); } /* * ELF requires that PT_LOAD segments be in ascending order of p_vaddr. * Find the last one to calculate the whole address span of the image. */ const Elf32_Phdr *first_load = &phdr[i]; const Elf32_Phdr *last_load = &phdr[ehdr.e_phnum - 1]; while (last_load > first_load && last_load->p_type != PT_LOAD) --last_load; /* * For NaCl, the first load segment must always be the code segment. */ if (first_load->p_flags != (PF_R | PF_X)) { fprintf(stderr, "%s: First PT_LOAD has p_flags=%#x (expecting RX=%#x)\n", filename, first_load->p_flags, PF_R | PF_X); exit(1); } if (first_load->p_filesz != first_load->p_memsz) { fprintf(stderr, "%s: Code segment has p_filesz %u != p_memsz %u\n", filename, first_load->p_filesz, first_load->p_memsz); exit(1); } /* * Decide where to load the image and reserve the portions of the address * space where it will reside. */ Elf32_Addr load_bias = choose_load_bias(filename, pagesize, first_load, last_load, anywhere); DEBUG_PRINTF("XXX load_bias (%s) %#x\n", anywhere ? "anywhere" : "fixed", load_bias); /* * Map the code segment in. */ my_mmap(filename, "code segment", first_load - phdr, load_bias + round_down(first_load->p_vaddr, pagesize), first_load->p_memsz, prot_from_phdr(first_load), MAP_PRIVATE | MAP_FIXED, fd, round_down(first_load->p_offset, pagesize)); Elf32_Addr last_end = first_load->p_vaddr + load_bias + first_load->p_memsz; Elf32_Addr last_page_end = round_up(last_end, pagesize); /* * Map the remaining segments, and protect any holes between them. * The large hole after the code segment does not need to be * protected (and cannot be). It covers the whole large tail of the * dynamic text area, which cannot be touched by mprotect. */ const Elf32_Phdr *ph; for (ph = first_load + 1; ph <= last_load; ++ph) { if (ph->p_type == PT_LOAD) { Elf32_Addr start = round_down(ph->p_vaddr + load_bias, pagesize); if (start > last_page_end && ph > first_load + 1) { if (mprotect((void *) last_page_end, start - last_page_end, PROT_NONE) != 0) { fprintf(stderr, "%s: Failed to mprotect segment %u hole! (%s)\n", filename, ph - phdr, strerror(errno)); exit(1); } } last_end = ph->p_vaddr + load_bias + ph->p_memsz; last_page_end = round_up(last_end, pagesize); Elf32_Addr map_end = last_page_end; /* * Unlike POSIX mmap, NaCl's mmap does not reliably handle COW * faults in the remainder of the final partial page. So to get * the expected behavior for the unaligned boundary between data * and bss, it's necessary to allocate the final partial page of * data as anonymous memory rather than mapping it from the file. */ Elf32_Addr file_end = ph->p_vaddr + load_bias + ph->p_filesz; if (ph->p_memsz > ph->p_filesz) map_end = round_down(file_end, pagesize); if (map_end > start) { my_mmap(filename, "segment", ph - phdr, start, map_end - start, prot_from_phdr(ph), MAP_PRIVATE | MAP_FIXED, fd, round_down(ph->p_offset, pagesize)); } if (map_end < last_page_end) { /* * Handle the "bss" portion of a segment, where the memory size * exceeds the file size and we zero-fill the difference. We map * anonymous pages for all the pages containing bss space. Then, * if there is any partial-page tail of the file data, we read that * into the first such page. * * This scenario is invalid for an unwritable segment. */ if ((ph->p_flags & PF_W) == 0) { fprintf(stderr, "%s: Segment %u has p_memsz %u > p_filesz %u but no PF_W!\n", filename, ph - phdr, ph->p_memsz, ph->p_filesz); exit(1); } my_mmap(filename, "bss segment", ph - phdr, map_end, last_page_end - map_end, prot_from_phdr(ph), MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); if (file_end > map_end) { /* * There is a partial page of data to read in. */ my_pread(filename, "Failed to read final partial page of data! ", fd, (void *) map_end, file_end - map_end, round_down(ph->p_offset + ph->p_filesz, pagesize), &pread_pos); } } } } /* * We've finished with the file now. */ close(fd); /* * Find the PT_INTERP header, if there is one. */ const Elf32_Phdr *interp = NULL; if (out_interp != NULL) { for (i = 0; i < ehdr.e_phnum; ++i) { if (phdr[i].p_type == PT_INTERP) { interp = &phdr[i]; break; } } } /* * Find the PT_LOAD segments containing the PT_INTERP data and the phdrs. */ for (ph = first_load; ph <= last_load && (interp != NULL || out_phdr != NULL); ++ph) { if (interp != NULL && segment_contains(ph, interp->p_offset, interp->p_filesz)) { *out_interp = (const char *) (interp->p_vaddr + load_bias); interp = NULL; } if (out_phdr != NULL && segment_contains(ph, ehdr.e_phoff, ehdr.e_phnum * sizeof(phdr[0]))) { *out_phdr = ehdr.e_phoff - ph->p_offset + ph->p_vaddr + load_bias; out_phdr = NULL; } } if (interp != NULL) { fprintf(stderr, "%s: PT_INTERP not within any PT_LOAD segment\n", filename); exit(1); } if (out_phdr != NULL) { *out_phdr = 0; fprintf(stderr, "Warning: %s: ELF program headers not within any PT_LOAD segment\n", filename); } if (out_phnum != NULL) *out_phnum = ehdr.e_phnum; if (out_base != NULL) *out_base = load_bias; return ehdr.e_entry + load_bias; }