static BCCScriptRef loadScript() { if (!inFile) { fprintf(stderr, "input file required\n"); return NULL; } struct stat statInFile; if (stat(inFile, &statInFile) < 0) { fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno)); return NULL; } if (!S_ISREG(statInFile.st_mode)) { fprintf(stderr, "Input file should be a regular file.\n"); return NULL; } FILE *in = fopen(inFile, "r"); if (!in) { fprintf(stderr, "Could not open input file %s\n", inFile); return NULL; } size_t bitcodeSize = statInFile.st_size; std::vector<char> bitcode(bitcodeSize + 1, '\0'); size_t nread = fread(&*bitcode.begin(), 1, bitcodeSize, in); if (nread != bitcodeSize) fprintf(stderr, "Could not read all of file %s\n", inFile); BCCScriptRef script = bccCreateScript(); if (bccReadBC(script, "file", &*bitcode.begin(), bitcodeSize, 0) != 0) { fprintf(stderr, "bcc: FAILS to read bitcode"); bccDisposeScript(script); return NULL; } bccRegisterSymbolCallback(script, lookupSymbol, NULL); if (bccPrepareExecutable(script, ".", "cache", 0) != 0) { fprintf(stderr, "bcc: FAILS to prepare executable.\n"); bccDisposeScript(script); return NULL; } return script; }
int main(int argc, char** argv) { if(parseOption(argc, argv)) { return 1; } BCCScriptRef script; if((script = loadScript()) == NULL) { return 2; } if(RunRoot && runRoot(script)) { return 6; } bccDisposeScript(script); return 0; }
static BCCScriptRef loadScript() { if (!InFile) { fprintf(stderr, "input file required.\n"); return NULL; } BCCScriptRef script = bccCreateScript(); if (bccReadFile(script, InFile, /* flags */BCC_SKIP_DEP_SHA1) != 0) { fprintf(stderr, "bcc: FAILS to read bitcode."); bccDisposeScript(script); return NULL; } char *output = NULL; if (OutFile != NULL) { // Copy the outFile since we're going to modify it size_t outFileLen = strlen(OutFile); output = new char [outFileLen + 1]; strncpy(output, OutFile, outFileLen); } else { if (OutType == OT_Executable) { output = new char [(sizeof(DEFAULT_OUTPUT_FILENAME) - 1) + 1]; strncpy(output, DEFAULT_OUTPUT_FILENAME, sizeof(DEFAULT_OUTPUT_FILENAME) - 1); } else { size_t inFileLen = strlen(InFile); output = new char [inFileLen + 3 /* ensure there's room for .so */ + 1]; strncpy(output, InFile, inFileLen); char *fileExtension = strrchr(output, '.'); if (fileExtension == NULL) { // append suffix fileExtension = output + inFileLen; *fileExtension = '.'; } fileExtension++; // skip '.' if (OutType == OT_Relocatable) { *fileExtension++ = 'o'; } else /* must be OT_SharedObject */{ *fileExtension++ = 's'; *fileExtension++ = 'o'; } *fileExtension++ = '\0'; } } int bccResult = 0; const char *errMsg = NULL; switch (OutType) { case OT_Executable: { bccResult = 1; errMsg = "generation of executable is unsupported currently."; break; } case OT_Relocatable: { bccResult = bccPrepareRelocatable(script, output, OutRelocModel, 0); errMsg = "failed to generate relocatable."; break; } case OT_SharedObject: { if (IntermediateOutFile != NULL) { bccResult = bccPrepareRelocatable(script, IntermediateOutFile, bccRelocPIC, 0); errMsg = "failed to generate intermediate relocatable."; } if (bccResult == 0) { bccResult = bccPrepareSharedObject(script, IntermediateOutFile, output, 0); errMsg = "failed to generate shared library."; } break; } } delete [] output; if (bccResult == 0) { return script; } else { fprintf(stderr, "bcc: %s\n", errMsg); bccDisposeScript(script); return NULL; } }