static void GetPlotSettingsCB(XtPointer client_data, XtIntervalId *id) { (void) id; // Use it PlotWindowInfo *plot = (PlotWindowInfo *)client_data; assert(plot->settings_timer == *id); plot->settings_timer = 0; // Check for settings file to be created string settings; slurp_file(plot->settings_file, settings); if (settings.contains("set zero")) { // Settings are complete unlink(plot->settings_file.chars()); plot->settings = settings; configure_plot(plot); delete plot->settings_delay; plot->settings_delay = 0; } else { // Try again in 500 ms plot->settings_timer = XtAppAddTimeOut(XtWidgetToApplicationContext(plot->shell), 500, GetPlotSettingsCB, XtPointer(plot)); } }
bool load_classad_from_old_file(const char * filename, ClassAd & ad) { // Load old classad strings. MyString ad_string = slurp_file(filename); // Read in as old ClassAds format ClassAd ad((char *)ad_string.Value(),'\n'); return true; }
static void get_gw_data(char *username, char *device, JsonNode *last) { JsonNode *array; static char *types[] = { "batt", "ext", "status", NULL }; char **t, *js; static UT_string *ts = NULL, *u = NULL, *d = NULL; if (last == NULL || last->tag != JSON_OBJECT) return; for (t = types; t && *t; t++) { utstring_renew(u); utstring_renew(d); utstring_printf(u, "%s", username); utstring_printf(d, "%s", device); lowercase(UB(u)); lowercase(UB(d)); utstring_renew(ts); utstring_printf(ts, "%s/last/%s/%s/%s.json", STORAGEDIR, UB(u), UB(d), *t); /* Read file into JSON array and append to `last' object */ if ((js = slurp_file(UB(ts), TRUE)) != NULL) { if ((array = json_decode(js)) != NULL) { json_append_member(last, *t, array); } free(js); } } }
bool callback_with_text_tileset(enum iiformat iif, bool (*callback)(uint8_t *, size_t)) { /* The best way to create a temporary file is tmpfile(), which is simple and secure. However, it doesn't work properly on mingw (I /think/ it's trying to create files in the root directory; mingw tmpnam() does that). Thus, we fall back to a hardcoded filename in the current directory when that happens; it's insecure if the current directory happens to be world-writable, but it should at least work. */ FILE *t = tmpfile(); const char *tn = NULL; if (!t) t = (fopen)(((tn = "tileset-temp.bin")), "w+b"); if (!t) { fprintf(stderr, "Error opening temporary file '%s': %s", tn ? tn : "(anonymous)", strerror(errno)); return 0; } if (!write_text_tileset_inner(NULL, t, iif)) { fclose(t); if (tn) remove(tn); return 0; } rewind(t); return slurp_file(t, NULL, 0, tn, callback); }
void load_trapnumbers () { static const char fname[] = DATA_PREFIX"/trapnumbers"; long traptext_size; traptext = slurp_file (fname, "r", &traptext_size); if (traptext) { unsigned int i; /* Skip the first line, which could contain spurious '*' characters. */ char *s = strchr (traptext, '\n'); s = strchr (s, '*'); sscanf (s, "*%*d%x%x", &minvector, &maxvector); trapname = xmalloc ((maxvector - minvector + 1) * sizeof (const char *)); for (i = minvector; i <= maxvector; i++) trapname[i - minvector] = NULL; /* Skip to the end of the line, so we're aimed at the first trap line. */ s = strchr (s, '\n'); for (s = strtok (s, " \t\n"); s; s = strtok (NULL, " \t\n")) trapname[strtoul (s, NULL, 0) - minvector] = strtok (NULL, " \t\n"); } else { error ("can't open '%s': @P", fname); #ifdef ENOENT if (errno == ENOENT) error ("(rerun palmdev-prep to create the trapnumbers data file)"); #endif minvector = 1; maxvector = 0; } }
static std::string get_entire_translation(const char *filename) { int sz; unsigned char *bytes = slurp_file(getResource("%s.utf8", filename), &sz); if (!bytes) { native_error("Load error.", filename); } ALLEGRO_FILE *f = al_open_memfile(bytes, sz, "rb"); ALLEGRO_USTR *ustr; std::string whole_translation; while ((ustr = al_fget_ustr(f)) != NULL) { // remove newline int size = (int)al_ustr_size(ustr); const char *cstr = al_cstr(ustr); int count = 0; if (cstr[strlen(cstr)-1] == 0xa) count++; if (cstr[strlen(cstr)-2] == 0xd) count++; if (count > 0) { al_ustr_remove_range(ustr, size-count, size); } ustr_replace_all(ustr, '^', '\n'); whole_translation += al_cstr(ustr); } al_fclose(f); delete[] bytes; return whole_translation; }
/* * read_position_from_ams() - read the (x,y,z) position from AMS via sysfs file */ static int read_position_from_ams (int *x, int *y, int *z) { char buf[BUF_LEN]; int ret; if ((ret = slurp_file(AMS_POSITION_FILE, buf))) return ret; return (sscanf (buf, "%d %d %d\n", x, y, z) != 3); }
/* * read_position_from_hdaps() - read the (x,y) position pair from hdaps via sysfs files * This method is not recommended for frequent polling, since it causes unnecessary interrupts * and a phase difference between hdaps-to-EC polling vs. hdapsd-to-hdaps polling. */ static int read_position_from_hdaps (int *x, int *y) { char buf[BUF_LEN]; int ret; if ((ret = slurp_file(HDAPS_POSITION_FILE, buf))) return ret; return (sscanf (buf, "(%d,%d)\n", x, y) != 2); }
/* * read_position_from_applesmc() - read the (x,y,z) position from APPLESMC * via sysfs file */ static int read_position_from_applesmc (int *x, int *y, int *z) { char buf[BUF_LEN]; int ret; if ((ret = slurp_file(APPLESMC_POSITION_FILE, buf))) return ret; return (sscanf (buf, "(%d,%d,%d)\n", x, y, z) != 3); }
/* * read_int() - read an integer from a file */ static int read_int (const char* filename) { char buf[BUF_LEN]; int ret; if ((ret = slurp_file(filename, buf))) return ret; if (sscanf (buf, "%d\n", &ret) != 1) return -EIO; return ret; }
static int parse_file(const char *fname, parser_fn *parse) { char *args; int ret; args = slurp_file(fname); if (!args) return -1; ret = parse_args(args, parse); free(args); return ret; }
static int restore_bridge_info(const char *filename, struct bridge_info *b, unsigned char *pwdhash) { char *contents; int rc; void *base_address[] = { &b->entity, b }; contents = slurp_file(filename, NULL); if (!contents) return -1; memcpy(b->pwdhash, pwdhash, 20); rc = key_value_parse_lines(snis_entity_kvs, contents, base_address); free(contents); return rc; }
couch_args* couch_parse_args(int argc, const char* argv[]) { couch_args* args; int i = 1; args = (couch_args*) malloc(sizeof(couch_args)); if(args == NULL) return NULL; memset(args, '\0', sizeof(couch_args)); args->stack_size = 8L * 1024L; while(i < argc) { if(strcmp("--http", argv[i]) == 0) { args->use_http = 1; } else if(strcmp("--stack-size", argv[i]) == 0) { args->stack_size = atoi(argv[i+1]); if(args->stack_size <= 0) { fprintf(stderr, "Invalid stack size.\n"); exit(2); } } else { args->script = slurp_file(args->script, argv[i]); if(args->script_name == NULL) { if(strcmp(argv[i], "-") == 0) { args->script_name = "<stdin>"; } else { args->script_name = argv[i]; } } else { args->script_name = "<multiple_files>"; } } i++; } if(args->script_name == NULL || args->script == NULL) { fprintf(stderr, "No script provided.\n"); exit(3); } return args; }
int json_copy_from_file(JsonNode *obj, char *filename) { char *js_string; JsonNode *node; if ((js_string = slurp_file(filename, TRUE)) == NULL) { return (FALSE); } if ((node = json_decode(js_string)) == NULL) { fprintf(stderr, "json_copy_from_file can't decode JSON from %s\n", filename); free(js_string); return (FALSE); } json_copy_to_object(obj, node, FALSE); json_delete(node); free(js_string); return (TRUE); }
struct entry *read_crontabs (int user, int system) { struct entry *list = NULL; if (user) { char *buf = slurp_command("crontab -l"); if (buf) { char *username = get_username(); list = add_entries(buf, username, list); free(username); free(buf); } } if (system) { char *buf = slurp_file("/etc/crontab"); if (buf) { list = add_entries(buf, NULL, list); free(buf); } } return list; }
bool callback_with_binary_tileset(bool (*callback)(uint8_t *, size_t)) { FILE *t = tmpfile(); const char *tn = NULL; if (!t) t = (fopen)(((tn = "tileset-temp.bin")), "w+b"); if (!t) { fprintf(stderr, "Error opening temporary file '%s': %s", tn ? tn : "(anonymous)", strerror(errno)); return 0; } if (!write_binary_tileset_inner(NULL, t)) { fclose(t); if (tn) remove(tn); return 0; } rewind(t); return slurp_file(t, NULL, 0, tn, callback); }
main(int argc, char** argv) #endif { if ( argc < 2 ) { std::cout << "\nusage: testdriver [testfile_1] [testfile_2] ..." << std::endl; return 1; } int errors; Specification lSpec; std::string lModulePath; // Instantiate the store and the zorba query processor void* store = zorba::StoreManager::getStore(); if (store == NULL) return 20; zorba::Zorba * engine = zorba::Zorba::getInstance(store); if (engine == NULL) return 21; int i = 1; while (i < argc) { // std::cout << "i: " << i << ", argc: " << argc << std::endl; if (strcmp (argv [i], "--rbkt-src") == 0) { rbkt_src_dir = argv [i + 1]; i += 2; } else if (strcmp (argv [i], "--rbkt-bin") == 0) { rbkt_bin_dir = argv [i + 1]; i += 2; } else if (strcmp (argv [i], "--module-path") == 0) { lModulePath = argv [i + 1]; i += 2; } else break; } zorba::XQuery_t lQuery; TestDiagnosticHandler errHandler; DriverContext driverContext(engine); driverContext.theRbktSourceDir = rbkt_src_dir; driverContext.theRbktBinaryDir = rbkt_bin_dir; driverContext.theSpec = &lSpec; for (int testcnt = 1; i < argc; ++i, ++testcnt) { std::string lQueryFile( rbkt_src_dir ); zorba::fs::append( lQueryFile, "Queries" ); zorba::fs::append( lQueryFile, argv[i] ); #ifndef ZORBA_TEST_PLAN_SERIALIZATION_EXECUTION_ONLY if ( zorba::fs::get_type( lQueryFile ) != zorba::fs::file ) { std::cout << "\n query file " << lQueryFile << " does not exist or is not a file" << std::endl; return 2; } #endif /* ZORBA_TEST_PLAN_SERIALIZATION_EXECUTION_ONLY */ // Check if this is w3c_testsuite test. std::string path = lQueryFile; bool isW3CXQTStest = path.find( "w3c_testsuite" ) != std::string::npos; bool isW3CFTtest = path.find( "w3c_full_text_testsuite" ) != std::string::npos; bool isW3Ctest = isW3CFTtest || isW3CXQTStest; std::string lQueryWithoutSuffix = std::string(argv[i]).substr( 0, std::string(argv[i]).rfind('.') ); std::unique_ptr<zorba::TestSchemaURIMapper> smapper; std::unique_ptr<zorba::TestModuleURIMapper> mmapper; std::unique_ptr<zorba::TestCollectionURIMapper> cmapper; std::unique_ptr<zorba::TestSchemeURIMapper> dmapper; std::unique_ptr<zorba::TestURLResolver> tresolver; // Create the static context. If this is a w3c query, install special uri // resolvers in the static context. zorba::StaticContext_t lContext = engine->createStaticContext(); if ( isW3Ctest ) { #ifndef MY_D_WIN32 std::string w3cDataDir = "/Queries/w3c_testsuite/TestSources/"; #else std::string w3cDataDir = "/Queries/TestSources/"; #endif std::string uri_map_file = rbkt_src_dir + w3cDataDir + "uri.txt"; std::string mod_map_file = rbkt_src_dir + w3cDataDir + "module.txt"; std::string col_map_file = rbkt_src_dir + w3cDataDir + "collection.txt"; smapper.reset(new zorba::TestSchemaURIMapper(uri_map_file.c_str())); mmapper.reset(new zorba::TestModuleURIMapper (mod_map_file.c_str(), lQueryWithoutSuffix)); cmapper.reset( new zorba::TestCollectionURIMapper(driverContext.theXmlDataMgr, col_map_file.c_str(), rbkt_src_dir)); addURIMapper(driverContext, lContext, smapper.get() ); addURIMapper(driverContext, lContext, mmapper.get() ); addURIMapper(driverContext, lContext, cmapper.get() ); // the w3c testsuite always uses xquery 1.0 lContext->setXQueryVersion( zorba::xquery_version_1_0 ); zorba::Item lEnable = engine->getItemFactory()->createQName( "http://zorba.io/options/features", "", "enable"); zorba::Item lDisable = engine->getItemFactory()->createQName( "http://zorba.io/options/features", "", "disable"); lContext->declareOption(lDisable, "scripting"); } // Form the full pathname for the files that will receive the result or the // errors of this query. Then, delete these files if they exist already from // previous runs of the query. Finaly, create (if necessary) all the dirs // in the pathname of the result and error files. std::cout << "test " << lQueryWithoutSuffix << std::endl; #ifndef ZORBA_TEST_PLAN_SERIALIZATION_COMPILE_ONLY std::string lResultFile( rbkt_bin_dir ); zorba::fs::append( lResultFile, "QueryResults" ); zorba::fs::append( lResultFile, lQueryWithoutSuffix ); lResultFile += ".xml.res"; zorba::fs::remove( lResultFile, true ); // Form the full pathname for the .spec file that may be associated // with this query. If the .spec file exists, read its contents to // extract args to be passed to the query (e.g., external var bindings), // exprected errors, or the pathnames of reference-result files. std::string lSpecFile( rbkt_src_dir ); zorba::fs::append( lSpecFile, "Queries" ); zorba::fs::append( lSpecFile, lQueryWithoutSuffix ); lSpecFile += ".spec"; if ( zorba::fs::get_type( lSpecFile ) ) { bool lParsed = lSpec.parseFile(lSpecFile, rbkt_src_dir, rbkt_bin_dir); if (!lParsed) { std::cout << "Spec file " << lSpecFile << " is malformed!" << std::endl; return 1; } } // If --enable-uritestresolver is specified, enable our document // URI resolver for test:// scheme URIs as well as a silly URLResolver if (lSpec.getEnableUriTestResolver()) { dmapper.reset(new zorba::TestSchemeURIMapper(rbkt_src_dir)); addURIMapper(driverContext, lContext, dmapper.get()); tresolver.reset(new zorba::TestURLResolver()); addURLResolver(driverContext, lContext, tresolver.get()); } // Bind any options from the .spec file to the static context setOptions(driverContext, lContext); // Bind any full-text URI resolvers from the .spec file to the // static context setFullTextURIMappers(driverContext, lContext); // If command-line argument --module-path passed, set up module paths. setModulePaths(lModulePath, lContext); // Get the pathnames of the reference-result files found in the .spec // file (if any). std::vector<std::string> lRefFiles; bool lRefFileExists = false; for (std::vector<std::string>::const_iterator lIter = lSpec.resultsBegin(); lIter != lSpec.resultsEnd(); ++lIter) { std::string lRefFile(*lIter); if ( zorba::fs::get_type( lRefFile ) ) { lRefFileExists = true; } else { std::cout << "Warning: missing reference result file " << lRefFile << std::endl; } lRefFiles.push_back(lRefFile); } // If no ref-results file was specified in the .spec file, create a default // finename for that file. For w3c tests, the ref file is the same for // xqueryx and xquery tests, hence, we remove the string xqueryx or xquery // from the path if (lRefFiles.size () == 0) { std::string lRefFileTmpString = lQueryWithoutSuffix; if (isW3Ctest) { size_t pos = lQueryWithoutSuffix.find("XQueryX"); if (pos != std::string::npos) lRefFileTmpString = lRefFileTmpString.erase(pos, 8); pos = lQueryWithoutSuffix.find("XQuery"); if (pos != std::string::npos) lRefFileTmpString = lRefFileTmpString.erase(pos, 7); } std::string lRefFile( rbkt_src_dir ); zorba::fs::append( lRefFile, "ExpQueryResults" ); zorba::fs::append( lRefFile, lRefFileTmpString ); lRefFile += ".xml.res"; lRefFiles.push_back( lRefFile ); if ( zorba::fs::get_type( lRefFiles[0] ) ) lRefFileExists = true; } #endif//ZORBA_TEST_PLAN_SERIALIZATION_COMPILE_ONLY #ifndef ZORBA_TEST_PLAN_SERIALIZATION_EXECUTION_ONLY // print the query std::cout << "=== Query: ===" << std::endl; zorba::printFile(std::cout, lQueryFile); std::cout << "=== end of Query ===" << std::endl; #endif // Stopwatch starts now // QQQ this should use util/time.h #ifndef WIN32 struct timeval start_time, end_time; gettimeofday(&start_time, NULL); #else clock_t start_time, end_time; start_time = clock(); #endif #ifndef ZORBA_TEST_PLAN_SERIALIZATION_EXECUTION_ONLY // create and compile the query std::string lQueryString; slurp_file(lQueryFile.c_str(), lQueryString, rbkt_src_dir, rbkt_bin_dir); lQuery = engine->createQuery(&errHandler); lQuery->setFileName(lQueryFile); bool lJSONiqMode = (lQueryFile.rfind(".jq") == lQueryFile.size() - 3); if (lJSONiqMode) lContext->setJSONiqVersion(zorba::jsoniq_version_1_0); lQuery->compile(lQueryString.c_str(), lContext, getCompilerHints()); errors = -1; if ( errHandler.errors() ) { errors = analyzeError (lSpec, errHandler); if( errors == UNEXPECTED_ERROR ) return 6; std::cout << "testdriver: success" << std::endl; continue; } // no compilation errors #ifdef ZORBA_TEST_PLAN_SERIALIZATION try { clock_t t0, t1; std::string binary_path; binary_path = rbkt_bin_dir + "/QueryResults/" + lQueryWithoutSuffix + ".plan"; t0 = clock(); std::ofstream fbinary(binary_path.c_str(), std::ios_base::binary); if(!lQuery->saveExecutionPlan(fbinary)) { printf("save execution plan FAILED\n"); return 0x0badc0de; } fbinary.close(); t1 = clock(); printf("save execution plan in %f sec\n", (float)(t1-t0)/CLOCKS_PER_SEC); } catch(zorba::ZorbaException &err) { std::cout << err << std::endl; return -1; } #endif // ZORBA_TEST_PLAN_SERIALIZATION #endif // #ifndef ZORBA_TEST_PLAN_SERIALIZATION_EXECUTION_ONLY #ifndef ZORBA_TEST_PLAN_SERIALIZATION_COMPILE_ONLY #ifdef ZORBA_TEST_PLAN_SERIALIZATION try { clock_t t0, t1; std::string binary_path; binary_path = rbkt_bin_dir + "/QueryResults/" + lQueryWithoutSuffix + ".plan"; lQuery = engine->createQuery (&errHandler); t0 = clock(); std::ifstream ifbinary(binary_path.c_str(), std::ios_base::binary); if(!ifbinary.is_open()) { std::cout << "cannot open plan " << binary_path << std::endl; return 15; } bool load_ret; zorba::TestSerializationCallback serl_callback(driverContext.theURIMappers, driverContext.theURLResolvers); load_ret = lQuery->loadExecutionPlan(ifbinary, &serl_callback); if(!load_ret) { std::cout << "cannot load plan " << binary_path << std::endl; return 16; } t1 = clock(); printf("load execution plan in %f sec\n", (float)(t1-t0)/CLOCKS_PER_SEC); } catch(zorba::ZorbaException &err) { std::cout << err << std::endl; return -1; } #endif // Create dynamic context and set in it the external variables, the current // date & time, and the timezone. createDynamicContext(driverContext, lContext, lQuery, lSpec.getEnableDtd(), errHandler); Zorba_SerializerOptions lSerOptions; if (errHandler.errors()) { errors = analyzeError (lSpec, errHandler); } else { errors = -1; { // serialize xml/txt std::ofstream lResFileStream(lResultFile.c_str()); assert (lResFileStream.good()); // QQQ all this code should be in testdriver_common and used by // testdriver_mt as well // Initialize default serialization method lSerOptions.ser_method = ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID; lSerOptions.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES; // Now set any options specified in .spec file std::vector<Specification::Option>::const_iterator lIter; for (lIter = lSpec.serializerOptionsBegin(); lIter != lSpec.serializerOptionsEnd(); ++lIter) { try { lSerOptions.set(lIter->theOptName.c_str(), lIter->theOptValue.c_str()); } catch ( std::exception const &e ) { std::cerr << e.what() << std::endl; return -1; } } lQuery->execute(lResFileStream, &lSerOptions); } // Stopwatch ends here #ifndef WIN32 gettimeofday(&end_time, NULL); #else end_time = clock(); #endif if (! lRefFileExists ) { if (lSpec.getComparisonMethod() == "Ignore") { std::cout << "Since the comparison method is set to 'Ignore' the test is considered successful." << std::endl; return 0; } if(lSpec.errorsSize() == 0) { std::cout << "No reference result and no expected errors." << std::endl; return 3; } } if (errHandler.errors()) { errors = analyzeError (lSpec, errHandler); } else if ( lSpec.errorsSize() > 0 ) { if ( ! lRefFileExists ) { std::cout << "Expected error(s)"; for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin(); lIter != lSpec.errorsEnd(); ++lIter) { std::cout << " " << *lIter; } zorba::fs::info fs_info; if ( zorba::fs::get_type( lResultFile, &fs_info ) && !fs_info.size ) { std::cout << " but got empty result" << std::endl; } else { std::cout << " but got result:" << std::endl; zorba::printFile(std::cout, lResultFile); std::cout << "=== end of result ===" << std::endl; } return 7; } } } if( errors == UNEXPECTED_ERROR) { return 6; } else if( errors == -1 ) { std::cout << "=== Result: ===" << std::endl; zorba::printFile(std::cout, lResultFile); std::cout << "=== end of result ===" << std::endl; std::cout.flush(); size_t i = 1; bool lResultMatches = false; for (std::vector<std::string>::const_iterator lIter = lRefFiles.begin(); lIter != lRefFiles.end(); ++lIter) { int lLine, lCol; // where do the files differ std::string lRefLine, lResultLine; bool lRes = zorba::fileEquals(lIter->c_str(), lResultFile.c_str(), lLine, lCol, lRefLine, lResultLine); if (lRes) { std::cout << "testdriver: success (non-canonical result # " << i << " matches)" << std::endl; lResultMatches = true; break; } std::cout << "testdriver: non-canonical result for reference result # " << i << " doesn't match." << std::endl; // Don't attempt canonical comparison for test cases using --indent; // can lead to false positives. if (lSerOptions.indent == ZORBA_INDENT_YES) { std::cout << "testdriver: skipping canonicalization " "when testing with indent==yes" << std::endl; } // Also skip canonicalization for tests using method==xhtml or html // (so we can test for correct serialization of empty elements) else if (lSerOptions.ser_method == ZORBA_SERIALIZATION_METHOD_XHTML || lSerOptions.ser_method == ZORBA_SERIALIZATION_METHOD_HTML) { std::cout << "testdriver: skipping canonicalization " "when testing with method=[x]html" << std::endl; } // Also skip canonicalization for tests using method==json else if (lSerOptions.ser_method == ZORBA_SERIALIZATION_METHOD_JSON) { std::cout << "testdriver: skipping canonicalization " "when testing with method=json" << std::endl; } else { int lCanonicalRes = zorba::canonicalizeAndCompare(lSpec.getComparisonMethod(), lIter->c_str(), lResultFile.c_str()); if (lCanonicalRes == 0) { std::cout << "testdriver: success (canonical result # " << i << " matches)" << std::endl; lResultMatches = true; break; } std::cout << "testdriver: canonical result for reference result # " << i << " doesn't match." << std::endl; } ++i; } // for if (!lResultMatches) { std::cout << "testdriver: none of the reference results matched" << std::endl; return 8; } } // Check timing // QQQ only do this if .spec file says to #ifndef WIN32 long mstime = ( (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec) ); #else long mstime = (long)(((double)(end_time - start_time)) / CLOCKS_PER_SEC * 1000000); #endif std::cout << "testdriver: test runtime was " << mstime << "us" << std::endl; #endif//ifndef ZORBA_TEST_PLAN_SERIALIZATION_COMPILE_ONLY } // for (int testcnt = 1; i < argc; ++i, ++testcnt) std::cout << "testdriver: success" << std::endl; return 0; }
int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { unsigned long base; unsigned int atag_offset = 0x1000; /* 4k offset from memory start */ unsigned int offset = 0x8000; /* 32k offset from memory start */ const char *command_line; off_t command_line_len; const char *ramdisk; char *ramdisk_buf; char *modified_cmdline; off_t ramdisk_length; int opt; #define OPT_APPEND 'a' #define OPT_RAMDISK 'r' static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_APPEND }, { "append", 1, 0, OPT_APPEND }, { "initrd", 1, 0, OPT_RAMDISK }, { "ramdisk", 1, 0, OPT_RAMDISK }, { 0, 0, 0, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR "a:r:"; /* * Parse the command line arguments */ command_line = 0; command_line_len = 0; ramdisk = 0; ramdisk_buf = 0; ramdisk_length = 0; while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case '?': usage(); return -1; case OPT_APPEND: command_line = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; } } if (command_line) { command_line_len = strlen(command_line) + 1; if (command_line_len > COMMAND_LINE_SIZE) command_line_len = COMMAND_LINE_SIZE; } if (ramdisk) { ramdisk_buf = slurp_file(ramdisk, &ramdisk_length); } /* This code is just to load the elf headers for /proc/vmcore */ if (info->kexec_flags & KEXEC_ON_CRASH) { modified_cmdline = xmalloc(COMMAND_LINE_SIZE); memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); if (command_line) { strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } /* If panic kernel is being loaded, additional segments need * to be created. load_crashdump_segments will take care of * loading the segments as high in memory as possible, hence * in turn as away as possible from kernel to avoid being * stomped by the kernel. */ if (load_crashdump_segments(info, modified_cmdline, -1, 0) < 0) return -1; /* Use new command line buffer */ command_line = modified_cmdline; command_line_len = strlen(command_line) + 1; } //base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX); base = crashkernel_mem_start(); if (base == ULONG_MAX) return -1; if (atag_arm_load(info, base + atag_offset, command_line, command_line_len, ramdisk_buf, ramdisk_length) == -1) return -1; add_segment(info, buf, len, base + offset, len); info->entry = (void*)base + offset; return 0; }
int main(int argc, char* argv[]) { int ret = 0; if (argc) progname = argv[0]; if (argc > 1 && !strcmp(argv[1], "--run-tests")) { return jq_testsuite(argc - 1, argv + 1); } const char* program = 0; input_filenames = jv_mem_alloc(sizeof(const char*) * argc); ninput_files = 0; int further_args_are_files = 0; int jq_flags = 0; jv program_arguments = jv_array(); for (int i=1; i<argc; i++) { if (further_args_are_files) { input_filenames[ninput_files++] = argv[i]; } else if (!strcmp(argv[i], "--")) { if (!program) usage(); further_args_are_files = 1; } else if (!isoptish(argv[i])) { if (program) { input_filenames[ninput_files++] = argv[i]; } else { program = argv[i]; } } else if (isoption(argv[i], 's', "slurp")) { options |= SLURP; } else if (isoption(argv[i], 'r', "raw-output")) { options |= RAW_OUTPUT; } else if (isoption(argv[i], 'c', "compact-output")) { options |= COMPACT_OUTPUT; } else if (isoption(argv[i], 'C', "color-output")) { options |= COLOUR_OUTPUT; } else if (isoption(argv[i], 'M', "monochrome-output")) { options |= NO_COLOUR_OUTPUT; } else if (isoption(argv[i], 'a', "ascii-output")) { options |= ASCII_OUTPUT; } else if (isoption(argv[i], 'R', "raw-input")) { options |= RAW_INPUT; } else if (isoption(argv[i], 'n', "null-input")) { options |= PROVIDE_NULL; } else if (isoption(argv[i], 'f', "from-file")) { options |= FROM_FILE; } else if (isoption(argv[i], 0, "arg")) { if (i >= argc - 2) { fprintf(stderr, "%s: --arg takes two parameters (e.g. -a varname value)\n", progname); die(); } jv arg = jv_object(); arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1])); arg = jv_object_set(arg, jv_string("value"), jv_string(argv[i+2])); program_arguments = jv_array_append(program_arguments, arg); i += 2; // skip the next two arguments } else if (isoption(argv[i], 0, "debug-dump-disasm")) { options |= DUMP_DISASM; } else if (isoption(argv[i], 0, "debug-trace")) { jq_flags |= JQ_DEBUG_TRACE; } else if (isoption(argv[i], 'h', "help")) { usage(); } else if (isoption(argv[i], 'V', "version")) { fprintf(stderr, "jq version %s\n", PACKAGE_VERSION); return 0; } else { fprintf(stderr, "%s: Unknown option %s\n", progname, argv[i]); die(); } } if (!program) usage(); if (ninput_files == 0) current_input = stdin; if ((options & PROVIDE_NULL) && (options & (RAW_INPUT | SLURP))) { fprintf(stderr, "%s: --null-input cannot be used with --raw-input or --slurp\n", progname); die(); } if (options & FROM_FILE) { jv data = slurp_file(program); if (!jv_is_valid(data)) { data = jv_invalid_get_msg(data); fprintf(stderr, "%s: %s\n", progname, jv_string_value(data)); jv_free(data); return 1; } bc = jq_compile_args(jv_string_value(data), program_arguments); jv_free(data); } else { bc = jq_compile_args(program, program_arguments); } if (!bc) return 1; if (options & DUMP_DISASM) { dump_disassembly(0, bc); printf("\n"); } if (options & PROVIDE_NULL) { process(jv_null(), jq_flags); } else { jv slurped; if (options & SLURP) { if (options & RAW_INPUT) { slurped = jv_string(""); } else { slurped = jv_array(); } } struct jv_parser parser; jv_parser_init(&parser); char buf[4096]; while (read_more(buf, sizeof(buf))) { if (options & RAW_INPUT) { int len = strlen(buf); if (len > 0) { if (options & SLURP) { slurped = jv_string_concat(slurped, jv_string(buf)); } else { if (buf[len-1] == '\n') buf[len-1] = 0; process(jv_string(buf), jq_flags); } } } else { jv_parser_set_buf(&parser, buf, strlen(buf), !feof(stdin)); jv value; while (jv_is_valid((value = jv_parser_next(&parser)))) { if (options & SLURP) { slurped = jv_array_append(slurped, value); } else { process(value, jq_flags); } } if (jv_invalid_has_msg(jv_copy(value))) { jv msg = jv_invalid_get_msg(value); fprintf(stderr, "parse error: %s\n", jv_string_value(msg)); jv_free(msg); ret = 1; break; } else { jv_free(value); } } } jv_parser_free(&parser); if (ret != 0) goto out; if (options & SLURP) { process(slurped, jq_flags); } } out: jv_mem_free(input_filenames); bytecode_free(bc); return ret; }
int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { struct mem_ehdr ehdr; char *cmdline, *modified_cmdline = NULL; const char *devicetreeblob; int cmdline_len, modified_cmdline_len; uint64_t max_addr, hole_addr; unsigned char *seg_buf = NULL; off_t seg_size = 0; struct mem_phdr *phdr; size_t size; uint64_t *rsvmap_ptr; struct bootblock *bb_ptr; unsigned int nr_segments, i; int result, opt; uint64_t my_kernel, my_dt_offset; unsigned int my_panic_kernel; uint64_t my_stack, my_backup_start; uint64_t toc_addr; unsigned int slave_code[256/sizeof (unsigned int)], master_entry; #define OPT_APPEND (OPT_ARCH_MAX+0) #define OPT_RAMDISK (OPT_ARCH_MAX+1) #define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2) #define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, { "append", 1, NULL, OPT_APPEND }, { "ramdisk", 1, NULL, OPT_RAMDISK }, { "initrd", 1, NULL, OPT_RAMDISK }, { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, { 0, 0, NULL, 0 }, }; static const char short_options[] = KEXEC_OPT_STR ""; /* Parse command line arguments */ initrd_base = 0; initrd_size = 0; cmdline = 0; ramdisk = 0; devicetreeblob = 0; max_addr = 0xFFFFFFFFFFFFFFFFUL; hole_addr = 0; while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch (opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) break; case '?': usage(); return -1; case OPT_APPEND: cmdline = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; case OPT_DEVICETREEBLOB: devicetreeblob = optarg; break; case OPT_ARGS_IGNORE: break; } } cmdline_len = 0; if (cmdline) cmdline_len = strlen(cmdline) + 1; else fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n"); if (ramdisk && reuse_initrd) die("Can't specify --ramdisk or --initrd with --reuseinitrd\n"); setup_memory_ranges(info->kexec_flags); /* Need to append some command line parameters internally in case of * taking crash dumps. */ if (info->kexec_flags & KEXEC_ON_CRASH) { modified_cmdline = xmalloc(COMMAND_LINE_SIZE); memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); if (cmdline) { strncpy(modified_cmdline, cmdline, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } modified_cmdline_len = strlen(modified_cmdline); } /* Parse the Elf file */ result = build_elf_exec_info(buf, len, &ehdr, 0); if (result < 0) { free_elf_info(&ehdr); return result; } /* Load the Elf data. Physical load addresses in elf64 header do not * show up correctly. Use user supplied address for now to patch the * elf header */ phdr = &ehdr.e_phdr[0]; size = phdr->p_filesz; if (size > phdr->p_memsz) size = phdr->p_memsz; hole_addr = (uint64_t)locate_hole(info, size, 0, 0, max_addr, 1); ehdr.e_phdr[0].p_paddr = hole_addr; result = elf_exec_load(&ehdr, info); if (result < 0) { free_elf_info(&ehdr); return result; } /* If panic kernel is being loaded, additional segments need * to be created. */ if (info->kexec_flags & KEXEC_ON_CRASH) { result = load_crashdump_segments(info, modified_cmdline, max_addr, 0); if (result < 0) return -1; /* Use new command line. */ cmdline = modified_cmdline; cmdline_len = strlen(modified_cmdline) + 1; } /* Add v2wrap to the current image */ seg_buf = NULL; seg_size = 0; seg_buf = (unsigned char *) malloc(purgatory_size); if (seg_buf == NULL) { free_elf_info(&ehdr); return -1; } memcpy(seg_buf, purgatory, purgatory_size); seg_size = purgatory_size; elf_rel_build_load(info, &info->rhdr, (const char *)purgatory, purgatory_size, 0, max_addr, 1, 0); /* Add a ram-disk to the current image * Note: Add the ramdisk after elf_rel_build_load */ if (ramdisk) { if (devicetreeblob) { fprintf(stderr, "Can't use ramdisk with device tree blob input\n"); return -1; } seg_buf = (unsigned char *)slurp_file(ramdisk, &seg_size); add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1); hole_addr = (uint64_t) info->segment[info->nr_segments-1].mem; initrd_base = hole_addr; initrd_size = (uint64_t) info->segment[info->nr_segments-1].memsz; } /* ramdisk */ if (devicetreeblob) { unsigned char *blob_buf = NULL; off_t blob_size = 0; /* Grab device tree from buffer */ blob_buf = (unsigned char *)slurp_file(devicetreeblob, &blob_size); add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, max_addr, -1); } else { /* create from fs2dt */ seg_buf = NULL; seg_size = 0; create_flatten_tree(info, (unsigned char **)&seg_buf, (unsigned long *)&seg_size,cmdline); add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, -1); } /* patch reserve map address for flattened device-tree * find last entry (both 0) in the reserve mem list. Assume DT * entry is before this one */ bb_ptr = (struct bootblock *)( (unsigned char *)info->segment[(info->nr_segments)-1].buf); rsvmap_ptr = (uint64_t *)( (unsigned char *)info->segment[(info->nr_segments)-1].buf + bb_ptr->off_mem_rsvmap); while (*rsvmap_ptr || *(rsvmap_ptr+1)) rsvmap_ptr += 2; rsvmap_ptr -= 2; *rsvmap_ptr = (uint64_t)( info->segment[(info->nr_segments)-1].mem); rsvmap_ptr++; *rsvmap_ptr = (uint64_t)bb_ptr->totalsize; nr_segments = info->nr_segments; /* Set kernel */ my_kernel = (uint64_t)info->segment[0].mem; elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); /* Set dt_offset */ my_dt_offset = (uint64_t)info->segment[nr_segments-1].mem; elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset, sizeof(my_dt_offset)); /* get slave code from new kernel, put in purgatory */ elf_rel_get_symbol(&info->rhdr, "purgatory_start", slave_code, sizeof(slave_code)); master_entry = slave_code[0]; memcpy(slave_code, info->segment[0].buf, sizeof(slave_code)); slave_code[0] = master_entry; elf_rel_set_symbol(&info->rhdr, "purgatory_start", slave_code, sizeof(slave_code)); if (info->kexec_flags & KEXEC_ON_CRASH) { my_panic_kernel = 1; /* Set panic flag */ elf_rel_set_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, sizeof(my_panic_kernel)); /* Set backup address */ my_backup_start = info->backup_start; elf_rel_set_symbol(&info->rhdr, "backup_start", &my_backup_start, sizeof(my_backup_start)); } /* Set stack address */ my_stack = locate_hole(info, 16*1024, 0, 0, max_addr, 1); my_stack += 16*1024; elf_rel_set_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); /* Set toc */ toc_addr = (unsigned long) my_r2(&info->rhdr); elf_rel_set_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); #ifdef DEBUG my_kernel = 0; my_dt_offset = 0; my_panic_kernel = 0; my_backup_start = 0; my_stack = 0; toc_addr = 0; elf_rel_get_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); elf_rel_get_symbol(&info->rhdr, "dt_offset", &my_dt_offset, sizeof(my_dt_offset)); elf_rel_get_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, sizeof(my_panic_kernel)); elf_rel_get_symbol(&info->rhdr, "backup_start", &my_backup_start, sizeof(my_backup_start)); elf_rel_get_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); elf_rel_get_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); fprintf(stderr, "info->entry is %p\n", info->entry); fprintf(stderr, "kernel is %lx\n", my_kernel); fprintf(stderr, "dt_offset is %lx\n", my_dt_offset); fprintf(stderr, "panic_kernel is %x\n", my_panic_kernel); fprintf(stderr, "backup_start is %lx\n", my_backup_start); fprintf(stderr, "stack is %lx\n", my_stack); fprintf(stderr, "toc_addr is %lx\n", toc_addr); fprintf(stderr, "purgatory size is %lu\n", purgatory_size); #endif for (i = 0; i < nr_segments; i++) fprintf(stderr, "segment[%d].mem:%p memsz:%ld\n", i, info->segment[i].mem, info->segment[i].memsz); return 0; }
int vanilla2grid(int argc, char **argv) { if(argc != 3) { fprintf(stderr, "Usage:\n" " %s filename 'gridurl'\n" " filename - filename of classad to process\n" " girdurl - Unified grid URL\n", argv[0]); return 1; } // Load old classad string. MyString s_jobad = slurp_file(argv[1]); // Read in as old ClassAds format ClassAd jobad((char *)s_jobad.Value(),'\n'); int orig_cluster; if( ! jobad.EvaluateAttrInt(ATTR_CLUSTER_ID, orig_cluster) ) { dprintf(D_ALWAYS, "Vanilla job lacks a cluster\n"); return 1; } int orig_proc; if( ! jobad.EvaluateAttrInt(ATTR_PROC_ID, orig_proc) ) { dprintf(D_ALWAYS, "Vanilla job lacks a proc\n"); return 1; } //==================================================================== // Do something interesting: VanillaToGrid::vanillaToGrid(&jobad, argv[2]); printf("Claiming job %d.%d\n", orig_cluster, orig_proc); MyString errors; switch(claim_job(jobad, NULL, NULL, orig_cluster, orig_proc, &errors, MYID)) { case CJR_OK: break; case CJR_BUSY: fprintf(stderr, "Unable to claim original job %d.%d because it's busy (%s)\n. Continuing anyway.\n", orig_cluster, orig_proc, errors.Value()); break; case CJR_ERROR: fprintf(stderr, "Unable to claim original job %d.%d because of an error: %s\n. Continuing anyway.\n", orig_cluster, orig_proc, errors.Value()); break; } int cluster,proc; if( ! submit_job( jobad, 0, 0, &cluster, &proc ) ) { fprintf(stderr, "Failed to submit job\n"); } printf("Successfully submitted %d.%d\n",cluster,proc); if(0) // Print the transformed add. { // Convert to old classad string MyString out; sPrintAd(out, jobad); printf("%s\n", out.Value()); } return 0; }
static int ppc_load_bare_bits(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info, unsigned int load_addr, unsigned int ep) { char *command_line; int command_line_len; char *dtb; unsigned int addr; unsigned long dtb_addr; #define FIXUP_ENTRYS (20) char *fixup_nodes[FIXUP_ENTRYS + 1]; int cur_fixup = 0; int opt; int ret; command_line = NULL; dtb = NULL; while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch (opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case '?': usage(); return -1; case OPT_APPEND: command_line = optarg; break; case OPT_DTB: dtb = optarg; break; case OPT_NODES: if (cur_fixup >= FIXUP_ENTRYS) { fprintf(stderr, "The number of entries for the fixup is too large\n"); exit(1); } fixup_nodes[cur_fixup] = optarg; cur_fixup++; break; } } command_line_len = 0; if (command_line) command_line_len = strlen(command_line) + 1; fixup_nodes[cur_fixup] = NULL; /* * len contains the length of the whole kernel image except the bss * section. The 3 MiB should cover it. The purgatory and the dtb are * allocated from memtop down towards zero so we should never get too * close to the bss :) */ ret = valid_memory_range(info, load_addr, len + 3 * 1024 * 1024); if (!ret) { printf("Can't add kernel to addr 0x%08x len %ld\n", load_addr, len + 3 * 1024 * 1024); return -1; } add_segment(info, buf, len, load_addr, len + 3 * 1024 * 1024); if (dtb) { char *blob_buf; off_t blob_size = 0; /* Grab device tree from buffer */ blob_buf = slurp_file(dtb, &blob_size); if (!blob_buf || !blob_size) die("Device tree seems to be an empty file.\n"); blob_buf = fixup_dtb_nodes(blob_buf, &blob_size, fixup_nodes, command_line); dtb_addr = add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, KERNEL_ACCESS_TOP, -1); } else { dtb_addr = 0; } elf_rel_build_load(info, &info->rhdr, (const char *)purgatory, purgatory_size, 0, -1, -1, 0); /* set various variables for the purgatory */ addr = ep; elf_rel_set_symbol(&info->rhdr, "kernel", &addr, sizeof(addr)); addr = dtb_addr; elf_rel_set_symbol(&info->rhdr, "dt_offset", &addr, sizeof(addr)); addr = rmo_top; elf_rel_set_symbol(&info->rhdr, "mem_size", &addr, sizeof(addr)); #define PUL_STACK_SIZE (16 * 1024) addr = locate_hole(info, PUL_STACK_SIZE, 0, 0, -1, 1); addr += PUL_STACK_SIZE; elf_rel_set_symbol(&info->rhdr, "pul_stack", &addr, sizeof(addr)); /* No allocation past here in order not to overwrite the stack */ #undef PUL_STACK_SIZE addr = elf_rel_get_addr(&info->rhdr, "purgatory_start"); info->entry = (void *)addr; return 0; }
// Parse all rules from STDIN. int main(int argc, char *argv[]) { golem_world *world = new_world(rules_from_string(slurp_file(stdin))); dump_item(world->current, 0); return 0; }
int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { unsigned long base; unsigned int atag_offset = 0x1000; /* 4k offset from memory start */ unsigned int offset = 0x8000; /* 32k offset from memory start */ const char *command_line; char *modified_cmdline = NULL; off_t command_line_len; const char *ramdisk; char *ramdisk_buf; int opt; int use_atags; char *dtb_buf; off_t dtb_length; char *dtb_file; off_t dtb_offset; char *end; /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_APPEND }, { "append", 1, 0, OPT_APPEND }, { "initrd", 1, 0, OPT_RAMDISK }, { "ramdisk", 1, 0, OPT_RAMDISK }, { "dtb", 1, 0, OPT_DTB }, { "atags", 0, 0, OPT_ATAGS }, { "image-size", 1, 0, OPT_IMAGE_SIZE }, { "atags-file", 1, 0, OPT_ATAGS }, { 0, 0, 0, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR "a:r:"; /* * Parse the command line arguments */ command_line = 0; command_line_len = 0; ramdisk = 0; ramdisk_buf = 0; initrd_size = 0; use_atags = 0; dtb_file = NULL; while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case OPT_APPEND: command_line = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; case OPT_DTB: dtb_file = optarg; break; case OPT_ATAGS: use_atags = 1; break; case OPT_IMAGE_SIZE: kexec_arm_image_size = strtoul(optarg, &end, 0); break; case OPT_ATAGS_FILE: atags_file = optarg; break; } } if (use_atags && dtb_file) { fprintf(stderr, "You can only use ATAGs if you don't specify a " "dtb file.\n"); return -1; } if (command_line) { command_line_len = strlen(command_line) + 1; if (command_line_len > COMMAND_LINE_SIZE) command_line_len = COMMAND_LINE_SIZE; } if (ramdisk) { ramdisk_buf = slurp_file(ramdisk, &initrd_size); } /* * If we are loading a dump capture kernel, we need to update kernel * command line and also add some additional segments. */ if (info->kexec_flags & KEXEC_ON_CRASH) { uint64_t start, end; modified_cmdline = xmalloc(COMMAND_LINE_SIZE); if (!modified_cmdline) return -1; if (command_line) { (void) strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } if (load_crashdump_segments(info, modified_cmdline) < 0) { free(modified_cmdline); return -1; } command_line = modified_cmdline; command_line_len = strlen(command_line) + 1; /* * We put the dump capture kernel at the start of crashkernel * reserved memory. */ if (parse_iomem_single("Crash kernel\n", &start, &end)) { /* * No crash kernel memory reserved. We cannot do more * but just bail out. */ return -1; } base = start; } else { base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX); } if (base == ULONG_MAX) return -1; printf("Kernel segment stats: %lx (%ld)\n", base, len); if (kexec_arm_image_size) { /* If the image size was passed as command line argument, * use that value for determining the address for initrd, * atags and dtb images. page-align the given length.*/ initrd_base = base + _ALIGN(kexec_arm_image_size, getpagesize()); } else { /* Otherwise, assume the maximum kernel compression ratio * is 4, and just to be safe, place ramdisk after that */ initrd_base = base + _ALIGN(len * 4, getpagesize()); } if (use_atags) { /* * use ATAGs from /proc/atags */ if (atag_arm_load(info, base + atag_offset, command_line, command_line_len, ramdisk_buf, initrd_size, initrd_base) == -1) return -1; } else { /* * Read a user-specified DTB file. */ if (dtb_file) { dtb_buf = slurp_file(dtb_file, &dtb_length); if (fdt_check_header(dtb_buf) != 0) { fprintf(stderr, "Invalid FDT buffer.\n"); return -1; } if (command_line) { /* * Error should have been reported so * directly return -1 */ if (setup_dtb_prop(&dtb_buf, &dtb_length, "/chosen", "bootargs", command_line, strlen(command_line) + 1)) return -1; } } else { /* * Extract the DTB from /proc/device-tree. */ create_flatten_tree(&dtb_buf, &dtb_length, command_line); } if (base + atag_offset + dtb_length > base + offset) { fprintf(stderr, "DTB too large!\n"); return -1; } if (ramdisk) { add_segment(info, ramdisk_buf, initrd_size, initrd_base, initrd_size); unsigned long start, end; start = cpu_to_be32((unsigned long)(initrd_base)); end = cpu_to_be32((unsigned long)(initrd_base + initrd_size)); if (setup_dtb_prop(&dtb_buf, &dtb_length, "/chosen", "linux,initrd-start", &start, sizeof(start))) return -1; if (setup_dtb_prop(&dtb_buf, &dtb_length, "/chosen", "linux,initrd-end", &end, sizeof(end))) return -1; } /* Stick the dtb at the end of the initrd and page * align it. */ dtb_offset = initrd_base + initrd_size + getpagesize(); dtb_offset = _ALIGN_DOWN(dtb_offset, getpagesize()); add_segment(info, dtb_buf, dtb_length, dtb_offset, dtb_length); } printf("Kernel segment info: %lx (%d)\n", base+offset, len); add_segment(info, buf, len, base + offset, len); info->entry = (void*)base + offset; return 0; }
int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { unsigned long base; unsigned int atag_offset = 0x1000; /* 4k offset from memory start */ unsigned int offset = 0x8000; /* 32k offset from memory start */ const char *command_line; char *modified_cmdline = NULL; off_t command_line_len; const char *ramdisk; char *ramdisk_buf; off_t ramdisk_length; off_t ramdisk_offset; int opt; /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_APPEND }, { "append", 1, 0, OPT_APPEND }, { "initrd", 1, 0, OPT_RAMDISK }, { "ramdisk", 1, 0, OPT_RAMDISK }, { 0, 0, 0, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR "a:r:"; /* * Parse the command line arguments */ command_line = 0; command_line_len = 0; ramdisk = 0; ramdisk_buf = 0; ramdisk_length = 0; while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case '?': usage(); return -1; case OPT_APPEND: command_line = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; } } if (command_line) { command_line_len = strlen(command_line) + 1; if (command_line_len > COMMAND_LINE_SIZE) command_line_len = COMMAND_LINE_SIZE; } if (ramdisk) { ramdisk_buf = slurp_file(ramdisk, &ramdisk_length); } /* * If we are loading a dump capture kernel, we need to update kernel * command line and also add some additional segments. */ if (info->kexec_flags & KEXEC_ON_CRASH) { uint64_t start, end; modified_cmdline = xmalloc(COMMAND_LINE_SIZE); if (!modified_cmdline) return -1; if (command_line) { (void) strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } if (load_crashdump_segments(info, modified_cmdline) < 0) { free(modified_cmdline); return -1; } command_line = modified_cmdline; command_line_len = strlen(command_line) + 1; /* * We put the dump capture kernel at the start of crashkernel * reserved memory. */ if (parse_iomem_single("Crash kernel\n", &start, &end)) { /* * No crash kernel memory reserved. We cannot do more * but just bail out. */ return -1; } base = start; } else { base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX); } if (base == ULONG_MAX) return -1; /* assume the maximum kernel compression ratio is 4, * and just to be safe, place ramdisk after that */ ramdisk_offset = base + len * 4; if (atag_arm_load(info, base + atag_offset, command_line, command_line_len, ramdisk_buf, ramdisk_length, ramdisk_offset) == -1) return -1; add_segment(info, buf, len, base + offset, len); info->entry = (void*)base + offset; return 0; }
char *slurp_decompress_file(const char *filename, off_t *r_size) { return slurp_file(filename, r_size); }
int elf_x86_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { struct mem_ehdr ehdr; char *command_line = NULL, *modified_cmdline = NULL; const char *append = NULL; char *tmp_cmdline = NULL; char *error_msg = NULL; int result; int command_line_len; const char *ramdisk; unsigned long entry, max_addr; int arg_style; #define ARG_STYLE_ELF 0 #define ARG_STYLE_LINUX 1 #define ARG_STYLE_NONE 2 int opt; /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, { "append", 1, NULL, OPT_APPEND }, { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, { "initrd", 1, NULL, OPT_RAMDISK }, { "ramdisk", 1, NULL, OPT_RAMDISK }, { "args-elf", 0, NULL, OPT_ARGS_ELF }, { "args-linux", 0, NULL, OPT_ARGS_LINUX }, { "args-none", 0, NULL, OPT_ARGS_NONE }, { 0, 0, NULL, 0 }, }; static const char short_options[] = KEXEC_OPT_STR ""; /* * Parse the command line arguments */ arg_style = ARG_STYLE_ELF; ramdisk = 0; result = 0; while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case OPT_APPEND: append = optarg; break; case OPT_REUSE_CMDLINE: tmp_cmdline = get_command_line(); break; case OPT_RAMDISK: ramdisk = optarg; break; case OPT_ARGS_ELF: arg_style = ARG_STYLE_ELF; break; case OPT_ARGS_LINUX: arg_style = ARG_STYLE_LINUX; break; case OPT_ARGS_NONE: #ifdef __i386__ arg_style = ARG_STYLE_NONE; #else die("--args-none only works on arch i386\n"); #endif break; } } command_line = concat_cmdline(tmp_cmdline, append); if (tmp_cmdline) { free(tmp_cmdline); } command_line_len = 0; if (command_line) { command_line_len = strlen(command_line) +1; } else { command_line = strdup("\0"); command_line_len = 1; } /* Need to append some command line parameters internally in case of * taking crash dumps. */ if (info->kexec_flags & (KEXEC_ON_CRASH|KEXEC_PRESERVE_CONTEXT)) { modified_cmdline = xmalloc(COMMAND_LINE_SIZE); memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); if (command_line) { strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } } /* Load the ELF executable */ elf_exec_build_load(info, &ehdr, buf, len, 0); entry = ehdr.e_entry; max_addr = elf_max_addr(&ehdr); /* Do we want arguments? */ if (arg_style != ARG_STYLE_NONE) { /* Load the setup code */ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ULONG_MAX, 1, 0); } if (arg_style == ARG_STYLE_NONE) { info->entry = (void *)entry; } else if (arg_style == ARG_STYLE_ELF) { unsigned long note_base; struct entry32_regs regs; uint32_t arg1, arg2; /* Setup the ELF boot notes */ note_base = elf_boot_notes(info, max_addr, command_line, command_line_len); /* Initialize the stack arguments */ arg2 = 0; /* No return address */ arg1 = note_base; elf_rel_set_symbol(&info->rhdr, "stack_arg32_1", &arg1, sizeof(arg1)); elf_rel_set_symbol(&info->rhdr, "stack_arg32_2", &arg2, sizeof(arg2)); /* Initialize the registers */ elf_rel_get_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); regs.eip = entry; /* The entry point */ regs.esp = elf_rel_get_addr(&info->rhdr, "stack_arg32_2"); elf_rel_set_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); if (ramdisk) { error_msg = "Ramdisks not supported with generic elf arguments"; goto out; } } else if (arg_style == ARG_STYLE_LINUX) { struct x86_linux_faked_param_header *hdr; unsigned long param_base; const char *ramdisk_buf; off_t ramdisk_length; struct entry32_regs regs; int rc = 0; /* Get the linux parameter header */ hdr = xmalloc(sizeof(*hdr)); /* Hack: With some ld versions, vmlinux program headers show * a gap of two pages between bss segment and data segment * but effectively kernel considers it as bss segment and * overwrites the any data placed there. Hence bloat the * memsz of parameter segment to 16K to avoid being placed * in such gaps. * This is a makeshift solution until it is fixed in kernel */ param_base = add_buffer(info, hdr, sizeof(*hdr), 16*1024, 16, 0, max_addr, 1); /* Initialize the parameter header */ memset(hdr, 0, sizeof(*hdr)); init_linux_parameters(&hdr->hdr); /* Add a ramdisk to the current image */ ramdisk_buf = NULL; ramdisk_length = 0; if (ramdisk) { ramdisk_buf = slurp_file(ramdisk, &ramdisk_length); } /* If panic kernel is being loaded, additional segments need * to be created. */ if (info->kexec_flags & (KEXEC_ON_CRASH|KEXEC_PRESERVE_CONTEXT)) { rc = load_crashdump_segments(info, modified_cmdline, max_addr, 0); if (rc < 0) { result = -1; goto out; } /* Use new command line. */ free(command_line); command_line = modified_cmdline; command_line_len = strlen(modified_cmdline) + 1; modified_cmdline = NULL; } /* Tell the kernel what is going on */ setup_linux_bootloader_parameters(info, &hdr->hdr, param_base, offsetof(struct x86_linux_faked_param_header, command_line), command_line, command_line_len, ramdisk_buf, ramdisk_length); /* Fill in the information bios calls would usually provide */ setup_linux_system_parameters(info, &hdr->hdr); /* Initialize the registers */ elf_rel_get_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); regs.ebx = 0; /* Bootstrap processor */ regs.esi = param_base; /* Pointer to the parameters */ regs.eip = entry; /* The entry point */ regs.esp = elf_rel_get_addr(&info->rhdr, "stack_end"); /* Stack, unused */ elf_rel_set_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); } else {
static void fixup_buggy_yacc_file(char *f) { char *slurped_file, *x; off_t textsize; char *newname; int fd; off_t bytesleft, byteswritten; newname = alloca(strlen(f) + 10); strcpy(newname, "broken-"); strcat(newname, f); slurped_file = slurp_file(f, &textsize); if (!slurped_file) return; if (!detect_buggy_yacc(slurped_file)) return; printf("Buggy yacc output detected in '%s', fixing.\n", f); x = slurped_file; /* * Fixup the '#line' directives which yacc botched. * Note: this is vulnerable to false positives, but * since this program is just a hack to make this particular * program work, it is sufficient for our purposes. * regexp could make this better, but the real fix needs * to be made in yacc/bison. */ while ((x = strstr(x, " #line ")) != NULL) { *x = '\n'; } if (rename(f, newname) != 0) { fprintf(stderr, "%s: Failed to rename '%s' to '%s': %s\n", programname, f, newname, strerror(errno)); return; } fd = open(f, O_CREAT | O_TRUNC | O_RDWR, 0644); if (fd < 0) { fprintf(stderr, "%s: failed to create '%s': %s\n", programname, f, strerror(errno)); return; } bytesleft = textsize; x = slurped_file; do { byteswritten = write(fd, x, bytesleft); if (byteswritten < 0) { fprintf(stderr, "%s: Error writing '%s': %s\n", programname, f, strerror(errno)); return; } if (byteswritten == 0 && errno == EINTR) continue; x += byteswritten; bytesleft -= byteswritten; } while (bytesleft > 0); close(fd); }
int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { unsigned long base; unsigned int atag_offset = 0x1000; /* 4k offset from memory start */ unsigned int offset = 0x8000; /* 32k offset from memory start */ unsigned int opt_ramdisk_addr; unsigned int opt_atags_addr; const char *command_line; char *modified_cmdline = NULL; off_t command_line_len; const char *ramdisk; char *ramdisk_buf; int opt; char *endptr; int use_dtb; const char *dtb_file; char *dtb_buf; off_t dtb_length; off_t dtb_offset; struct arm_mach *mach; /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_APPEND }, { "append", 1, 0, OPT_APPEND }, { "initrd", 1, 0, OPT_RAMDISK }, { "ramdisk", 1, 0, OPT_RAMDISK }, { "dtb", 2, 0, OPT_DTB }, { "rd-addr", 1, 0, OPT_RD_ADDR }, { "atags-addr", 1, 0, OPT_ATAGS_ADDR }, { "boardname", 1, 0, OPT_BOARDNAME }, { 0, 0, 0, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR "a:r:d::i:g:b:"; /* * Parse the command line arguments */ command_line = 0; command_line_len = 0; ramdisk = 0; ramdisk_buf = 0; use_dtb = 0; dtb_file = NULL; opt_ramdisk_addr = 0; opt_atags_addr = 0; mach = NULL; while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) { break; } case '?': usage(); return -1; case OPT_APPEND: command_line = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; case OPT_DTB: use_dtb = 1; if(optarg) dtb_file = optarg; break; case OPT_RD_ADDR: opt_ramdisk_addr = strtoul(optarg, &endptr, 0); if (*endptr) { fprintf(stderr, "Bad option value in --rd-addr=%s\n", optarg); usage(); return -1; } break; case OPT_ATAGS_ADDR: opt_atags_addr = strtoul(optarg, &endptr, 0); if (*endptr) { fprintf(stderr, "Bad option value in --atag-addr=%s\n", optarg); usage(); return -1; } break; case OPT_BOARDNAME: mach = arm_mach_choose(optarg); if(!mach) { fprintf(stderr, "Unknown boardname '%s'!\n", optarg); return -1; } break; } } if (command_line) { command_line_len = strlen(command_line) + 1; if (command_line_len > COMMAND_LINE_SIZE) command_line_len = COMMAND_LINE_SIZE; } if (ramdisk) { ramdisk_buf = slurp_file(ramdisk, &initrd_size); } /* * If we are loading a dump capture kernel, we need to update kernel * command line and also add some additional segments. */ if (info->kexec_flags & KEXEC_ON_CRASH) { uint64_t start, end; modified_cmdline = xmalloc(COMMAND_LINE_SIZE); if (!modified_cmdline) return -1; if (command_line) { (void) strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } if (load_crashdump_segments(info, modified_cmdline) < 0) { free(modified_cmdline); return -1; } command_line = modified_cmdline; command_line_len = strlen(command_line) + 1; /* * We put the dump capture kernel at the start of crashkernel * reserved memory. */ if (parse_iomem_single("Crash kernel\n", &start, &end)) { /* * No crash kernel memory reserved. We cannot do more * but just bail out. */ return -1; } base = start; } else { base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX); } if (base == ULONG_MAX) return -1; /* assume the maximum kernel compression ratio is 4, * and just to be safe, place ramdisk after that */ if(opt_ramdisk_addr == 0) initrd_base = _ALIGN(base + len * 4, getpagesize()); else initrd_base = opt_ramdisk_addr; if(!use_dtb) { if (atag_arm_load(info, base + atag_offset, command_line, command_line_len, ramdisk_buf, initrd_size, initrd_base) == -1) return -1; } else { char *dtb_img = NULL; off_t dtb_img_len = 0; int free_dtb_img = 0; int choose_res = 0; if(!mach) { fprintf(stderr, "DTB: --boardname was not specified.\n"); return -1; } if(dtb_file) { if(!load_dtb_image(dtb_file, &dtb_img, &dtb_img_len)) return -1; printf("DTB: Using DTB from file %s\n", dtb_file); free_dtb_img = 1; } else { if(!get_appended_dtb(buf, len, &dtb_img, &dtb_img_len)) return -1; printf("DTB: Using DTB appended to zImage\n"); } choose_res = (mach->choose_dtb)(dtb_img, dtb_img_len, &dtb_buf, &dtb_length); if(free_dtb_img) free(dtb_img); if(choose_res) { int ret, off; dtb_length = fdt_totalsize(dtb_buf) + DTB_PAD_SIZE; dtb_buf = xrealloc(dtb_buf, dtb_length); ret = fdt_open_into(dtb_buf, dtb_buf, dtb_length); if(ret) die("DTB: fdt_open_into failed"); ret = (mach->add_extra_regs)(dtb_buf); if (ret < 0) { fprintf(stderr, "DTB: error while adding mach-specific extra regs\n"); return -1; } if (command_line) { const char *node_name = "/chosen"; const char *prop_name = "bootargs"; /* check if a /choosen subnode already exists */ off = fdt_path_offset(dtb_buf, node_name); if (off == -FDT_ERR_NOTFOUND) off = fdt_add_subnode(dtb_buf, off, node_name); if (off < 0) { fprintf(stderr, "DTB: Error adding %s node.\n", node_name); return -1; } if (fdt_setprop(dtb_buf, off, prop_name, command_line, strlen(command_line) + 1) != 0) { fprintf(stderr, "DTB: Error setting %s/%s property.\n", node_name, prop_name); return -1; } } if(ramdisk) { const char *node_name = "/chosen"; uint32_t initrd_start, initrd_end; /* check if a /choosen subnode already exists */ off = fdt_path_offset(dtb_buf, node_name); if (off == -FDT_ERR_NOTFOUND) off = fdt_add_subnode(dtb_buf, off, node_name); if (off < 0) { fprintf(stderr, "DTB: Error adding %s node.\n", node_name); return -1; } initrd_start = cpu_to_fdt32(initrd_base); initrd_end = cpu_to_fdt32(initrd_base + initrd_size); ret = fdt_setprop(dtb_buf, off, "linux,initrd-start", &initrd_start, sizeof(initrd_start)); if (ret) die("DTB: Error setting %s/linux,initrd-start property.\n", node_name); ret = fdt_setprop(dtb_buf, off, "linux,initrd-end", &initrd_end, sizeof(initrd_end)); if (ret) die("DTB: Error setting %s/linux,initrd-end property.\n", node_name); } fdt_pack(dtb_buf); } else { /* * Extract the DTB from /proc/device-tree. */ printf("DTB: Failed to load dtb from zImage or dtb.img, using /proc/device-tree. This is unlikely to work.\n"); create_flatten_tree(&dtb_buf, &dtb_length, command_line); } if(ramdisk) { add_segment(info, ramdisk_buf, initrd_size, initrd_base, initrd_size); } if(opt_atags_addr != 0) dtb_offset = opt_atags_addr; else { dtb_offset = initrd_base + initrd_size + getpagesize(); dtb_offset = _ALIGN_DOWN(dtb_offset, getpagesize()); } printf("DTB: add dtb segment 0x%x\n", (unsigned int)dtb_offset); add_segment(info, dtb_buf, dtb_length, dtb_offset, dtb_length); } add_segment(info, buf, len, base + offset, len); info->entry = (void*)base + offset; return 0; }
int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { struct mem_ehdr ehdr; char *cmdline, *modified_cmdline = NULL; const char *devicetreeblob; uint64_t max_addr, hole_addr; char *seg_buf = NULL; off_t seg_size = 0; struct mem_phdr *phdr; size_t size; #ifdef NEED_RESERVE_DTB uint64_t *rsvmap_ptr; struct bootblock *bb_ptr; #endif int result, opt; uint64_t my_kernel, my_dt_offset; uint64_t my_opal_base = 0, my_opal_entry = 0; unsigned int my_panic_kernel; uint64_t my_stack, my_backup_start; uint64_t toc_addr; uint32_t my_run_at_load; unsigned int slave_code[256/sizeof (unsigned int)], master_entry; /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, { "append", 1, NULL, OPT_APPEND }, { "ramdisk", 1, NULL, OPT_RAMDISK }, { "initrd", 1, NULL, OPT_RAMDISK }, { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, { "dtb", 1, NULL, OPT_DEVICETREEBLOB }, { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, { 0, 0, NULL, 0 }, }; static const char short_options[] = KEXEC_OPT_STR ""; if (info->file_mode) return elf_ppc64_load_file(argc, argv, info); /* Parse command line arguments */ initrd_base = 0; initrd_size = 0; cmdline = 0; ramdisk = 0; devicetreeblob = 0; max_addr = 0xFFFFFFFFFFFFFFFFULL; hole_addr = 0; while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch (opt) { default: /* Ignore core options */ if (opt < OPT_ARCH_MAX) break; case OPT_APPEND: cmdline = optarg; break; case OPT_RAMDISK: ramdisk = optarg; break; case OPT_DEVICETREEBLOB: devicetreeblob = optarg; break; case OPT_ARGS_IGNORE: break; } } if (!cmdline) fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n"); if (ramdisk && reuse_initrd) die("Can't specify --ramdisk or --initrd with --reuseinitrd\n"); /* Need to append some command line parameters internally in case of * taking crash dumps. */ if (info->kexec_flags & KEXEC_ON_CRASH) { modified_cmdline = xmalloc(COMMAND_LINE_SIZE); memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); if (cmdline) { strncpy(modified_cmdline, cmdline, COMMAND_LINE_SIZE); modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; } } /* Parse the Elf file */ result = build_elf_exec_info(buf, len, &ehdr, 0); if (result < 0) { free_elf_info(&ehdr); return result; } /* Load the Elf data. Physical load addresses in elf64 header do not * show up correctly. Use user supplied address for now to patch the * elf header */ phdr = &ehdr.e_phdr[0]; size = phdr->p_filesz; if (size > phdr->p_memsz) size = phdr->p_memsz; my_kernel = hole_addr = locate_hole(info, size, 0, 0, max_addr, 1); ehdr.e_phdr[0].p_paddr = hole_addr; result = elf_exec_load(&ehdr, info); if (result < 0) { free_elf_info(&ehdr); return result; } /* If panic kernel is being loaded, additional segments need * to be created. */ if (info->kexec_flags & KEXEC_ON_CRASH) { result = load_crashdump_segments(info, modified_cmdline, max_addr, 0); if (result < 0) return -1; /* Use new command line. */ cmdline = modified_cmdline; } /* Add v2wrap to the current image */ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, max_addr, 1, 0); /* Add a ram-disk to the current image * Note: Add the ramdisk after elf_rel_build_load */ if (ramdisk) { if (devicetreeblob) { fprintf(stderr, "Can't use ramdisk with device tree blob input\n"); return -1; } seg_buf = slurp_file(ramdisk, &seg_size); hole_addr = add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1); initrd_base = hole_addr; initrd_size = seg_size; } /* ramdisk */ if (devicetreeblob) { /* Grab device tree from buffer */ seg_buf = slurp_file(devicetreeblob, &seg_size); } else { /* create from fs2dt */ create_flatten_tree(&seg_buf, &seg_size, cmdline); } result = fixup_dt(&seg_buf, &seg_size); if (result < 0) return result; my_dt_offset = add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, -1); #ifdef NEED_RESERVE_DTB /* patch reserve map address for flattened device-tree * find last entry (both 0) in the reserve mem list. Assume DT * entry is before this one */ bb_ptr = (struct bootblock *)(seg_buf); rsvmap_ptr = (uint64_t *)(seg_buf + be32_to_cpu(bb_ptr->off_mem_rsvmap)); while (*rsvmap_ptr || *(rsvmap_ptr+1)) rsvmap_ptr += 2; rsvmap_ptr -= 2; *rsvmap_ptr = cpu_to_be64(my_dt_offset); rsvmap_ptr++; *rsvmap_ptr = cpu_to_be64((uint64_t)be32_to_cpu(bb_ptr->totalsize)); #endif if (read_prop("/proc/device-tree/ibm,opal/opal-base-address", &my_opal_base, sizeof(my_opal_base)) == 0) { my_opal_base = be64_to_cpu(my_opal_base); elf_rel_set_symbol(&info->rhdr, "opal_base", &my_opal_base, sizeof(my_opal_base)); } if (read_prop("/proc/device-tree/ibm,opal/opal-entry-address", &my_opal_entry, sizeof(my_opal_entry)) == 0) { my_opal_entry = be64_to_cpu(my_opal_entry); elf_rel_set_symbol(&info->rhdr, "opal_entry", &my_opal_entry, sizeof(my_opal_entry)); } /* Set kernel */ elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); /* Set dt_offset */ elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset, sizeof(my_dt_offset)); /* get slave code from new kernel, put in purgatory */ elf_rel_get_symbol(&info->rhdr, "purgatory_start", slave_code, sizeof(slave_code)); master_entry = slave_code[0]; memcpy(slave_code, phdr->p_data, sizeof(slave_code)); slave_code[0] = master_entry; elf_rel_set_symbol(&info->rhdr, "purgatory_start", slave_code, sizeof(slave_code)); if (info->kexec_flags & KEXEC_ON_CRASH) { my_panic_kernel = 1; /* Set panic flag */ elf_rel_set_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, sizeof(my_panic_kernel)); /* Set backup address */ my_backup_start = info->backup_start; elf_rel_set_symbol(&info->rhdr, "backup_start", &my_backup_start, sizeof(my_backup_start)); /* Tell relocatable kernel to run at load address * via word before slave code in purgatory */ elf_rel_get_symbol(&info->rhdr, "run_at_load", &my_run_at_load, sizeof(my_run_at_load)); if (my_run_at_load == KERNEL_RUN_AT_ZERO_MAGIC) my_run_at_load = 1; /* else it should be a fixed offset image */ elf_rel_set_symbol(&info->rhdr, "run_at_load", &my_run_at_load, sizeof(my_run_at_load)); } /* Set stack address */ my_stack = locate_hole(info, 16*1024, 0, 0, max_addr, 1); my_stack += 16*1024; elf_rel_set_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); /* Set toc */ toc_addr = my_r2(&info->rhdr); elf_rel_set_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); /* Set debug */ elf_rel_set_symbol(&info->rhdr, "debug", &my_debug, sizeof(my_debug)); my_kernel = 0; my_dt_offset = 0; my_panic_kernel = 0; my_backup_start = 0; my_stack = 0; toc_addr = 0; my_run_at_load = 0; my_debug = 0; my_opal_base = 0; my_opal_entry = 0; elf_rel_get_symbol(&info->rhdr, "opal_base", &my_opal_base, sizeof(my_opal_base)); elf_rel_get_symbol(&info->rhdr, "opal_entry", &my_opal_entry, sizeof(my_opal_entry)); elf_rel_get_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); elf_rel_get_symbol(&info->rhdr, "dt_offset", &my_dt_offset, sizeof(my_dt_offset)); elf_rel_get_symbol(&info->rhdr, "run_at_load", &my_run_at_load, sizeof(my_run_at_load)); elf_rel_get_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, sizeof(my_panic_kernel)); elf_rel_get_symbol(&info->rhdr, "backup_start", &my_backup_start, sizeof(my_backup_start)); elf_rel_get_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); elf_rel_get_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); elf_rel_get_symbol(&info->rhdr, "debug", &my_debug, sizeof(my_debug)); dbgprintf("info->entry is %p\n", info->entry); dbgprintf("kernel is %llx\n", (unsigned long long)my_kernel); dbgprintf("dt_offset is %llx\n", (unsigned long long)my_dt_offset); dbgprintf("run_at_load flag is %x\n", my_run_at_load); dbgprintf("panic_kernel is %x\n", my_panic_kernel); dbgprintf("backup_start is %llx\n", (unsigned long long)my_backup_start); dbgprintf("stack is %llx\n", (unsigned long long)my_stack); dbgprintf("toc_addr is %llx\n", (unsigned long long)toc_addr); dbgprintf("purgatory size is %zu\n", purgatory_size); dbgprintf("debug is %d\n", my_debug); dbgprintf("opal_base is %llx\n", (unsigned long long) my_opal_base); dbgprintf("opal_entry is %llx\n", (unsigned long long) my_opal_entry); return 0; }