1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/* 2cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines * Copyright 2011-2012, The Android Open Source Project 3932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 4932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * you may not use this file except in compliance with the License. 6932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * You may obtain a copy of the License at 7932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 8932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 10932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Unless required by applicable law or agreed to in writing, software 11932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * See the License for the specific language governing permissions and 14932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * limitations under the License. 15932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */ 16932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 17932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <bcinfo/BitcodeTranslator.h> 1804261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines#include <bcinfo/BitcodeWrapper.h> 19932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <bcinfo/MetadataExtractor.h> 20932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 21e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/ADT/OwningPtr.h> 22e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/ADT/StringRef.h> 23e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Assembly/AssemblyAnnotationWriter.h> 24e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Bitcode/ReaderWriter.h> 25b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/LLVMContext.h> 26b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h> 27e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/ManagedStatic.h> 28e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/MemoryBuffer.h> 29e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Support/ToolOutputFile.h> 30e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 31932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <ctype.h> 32932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <dlfcn.h> 33932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdarg.h> 34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdint.h> 35932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdio.h> 36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <stdlib.h> 37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <string.h> 38932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <getopt.h> 39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 40932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <errno.h> 41932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <sys/stat.h> 42932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <sys/types.h> 43932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 44932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <unistd.h> 45932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 46e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <string> 47932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <vector> 48932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 49932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// This file corresponds to the standalone bcinfo tool. It prints a variety of 50932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines// information about a supplied bitcode input file. 51932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 52e126b62760b4bf115cfed162f0234e4e722011dfStephen Hinesstd::string inFile; 53e126b62760b4bf115cfed162f0234e4e722011dfStephen Hinesstd::string outFile; 543ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesstd::string infoFile; 55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesextern int opterr; 57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesextern int optind; 58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 5904261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hinesbool translateFlag = false; 603ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesbool infoFlag = false; 613ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesbool verbose = true; 62932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 63932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic int parseOption(int argc, char** argv) { 64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines int c; 653ffc8330d765599e357197883f72c01bd43837c8Stephen Hines while ((c = getopt(argc, argv, "itv")) != -1) { 66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines opterr = 0; 67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines switch(c) { 69932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines case '?': 70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // ignore any error 71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines case 't': 7404261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines translateFlag = true; 75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 773ffc8330d765599e357197883f72c01bd43837c8Stephen Hines case 'i': 783ffc8330d765599e357197883f72c01bd43837c8Stephen Hines // Turn off verbose so that we only generate the .info file. 793ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFlag = true; 803ffc8330d765599e357197883f72c01bd43837c8Stephen Hines verbose = false; 813ffc8330d765599e357197883f72c01bd43837c8Stephen Hines break; 823ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 833ffc8330d765599e357197883f72c01bd43837c8Stephen Hines case 'v': 843ffc8330d765599e357197883f72c01bd43837c8Stephen Hines verbose = true; 853ffc8330d765599e357197883f72c01bd43837c8Stephen Hines break; 863ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines default: 88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // Critical error occurs 89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines break; 91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if(optind >= argc) { 95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "input file required\n"); 96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines inFile = argv[optind]; 100e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 101e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines int l = inFile.length(); 102e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (l > 3 && inFile[l-3] == '.' && inFile[l-2] == 'b' && inFile[l-1] == 'c') { 103e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines outFile = std::string(inFile.begin(), inFile.end() - 3) + ".ll"; 1043ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFile = std::string(inFile.begin(), inFile.end() - 3) + ".bcinfo"; 105e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } else { 106e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines outFile = inFile + ".ll"; 1073ffc8330d765599e357197883f72c01bd43837c8Stephen Hines infoFile = inFile + ".bcinfo"; 108e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } 109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 1; 110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 1133ffc8330d765599e357197883f72c01bd43837c8Stephen Hinesstatic int dumpInfo(bcinfo::MetadataExtractor *ME) { 1143ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (!ME) { 1153ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 1; 1163ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1173ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1183ffc8330d765599e357197883f72c01bd43837c8Stephen Hines FILE *info = fopen(infoFile.c_str(), "w"); 1193ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (!info) { 1203ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "Could not open info file %s\n", infoFile.c_str()); 1213ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 2; 1223ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1233ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1243ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "exportVarCount: %u\n", ME->getExportVarCount()); 1253ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **varNameList = ME->getExportVarNameList(); 1263ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportVarCount(); i++) { 1273ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%s\n", varNameList[i]); 1283ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1293ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1303ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "exportFuncCount: %u\n", ME->getExportFuncCount()); 1313ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **funcNameList = ME->getExportFuncNameList(); 1323ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportFuncCount(); i++) { 1333ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%s\n", funcNameList[i]); 1343ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1353ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1363ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "exportForEachCount: %u\n", 1373ffc8330d765599e357197883f72c01bd43837c8Stephen Hines ME->getExportForEachSignatureCount()); 1383ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char **nameList = ME->getExportForEachNameList(); 1393ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const uint32_t *sigList = ME->getExportForEachSignatureList(); 1403ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) { 1413ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%u - %s\n", sigList[i], nameList[i]); 1423ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1433ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1443ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "objectSlotCount: %u\n", ME->getObjectSlotCount()); 1453ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const uint32_t *slotList = ME->getObjectSlotList(); 1463ffc8330d765599e357197883f72c01bd43837c8Stephen Hines for (size_t i = 0; i < ME->getObjectSlotCount(); i++) { 1473ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(info, "%u\n", slotList[i]); 1483ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 1493ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1503ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fclose(info); 1513ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 0; 1523ffc8330d765599e357197883f72c01bd43837c8Stephen Hines} 1533ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 1543ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 155932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic void dumpMetadata(bcinfo::MetadataExtractor *ME) { 156932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!ME) { 157932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 158932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 159932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 160e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("RSFloatPrecision: "); 161e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines switch (ME->getRSFloatPrecision()) { 162e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines case bcinfo::RS_FP_Full: 163e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("Full\n\n"); 164e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 165e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines case bcinfo::RS_FP_Relaxed: 166e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("Relaxed\n\n"); 167e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 168e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines case bcinfo::RS_FP_Imprecise: 169e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("Imprecise\n\n"); 170e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 171e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines default: 172e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("UNKNOWN\n\n"); 173e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 174e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines } 175e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines 176932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("exportVarCount: %u\n", ME->getExportVarCount()); 177569986da116ed602c752395f9563260db38f6945Stephen Hines const char **varNameList = ME->getExportVarNameList(); 178569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportVarCount(); i++) { 179569986da116ed602c752395f9563260db38f6945Stephen Hines printf("var[%u]: %s\n", i, varNameList[i]); 180569986da116ed602c752395f9563260db38f6945Stephen Hines } 181569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 182569986da116ed602c752395f9563260db38f6945Stephen Hines 183932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("exportFuncCount: %u\n", ME->getExportFuncCount()); 184569986da116ed602c752395f9563260db38f6945Stephen Hines const char **funcNameList = ME->getExportFuncNameList(); 185569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportFuncCount(); i++) { 186569986da116ed602c752395f9563260db38f6945Stephen Hines printf("func[%u]: %s\n", i, funcNameList[i]); 187569986da116ed602c752395f9563260db38f6945Stephen Hines } 188569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 18933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 19033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines printf("exportForEachSignatureCount: %u\n", 19133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines ME->getExportForEachSignatureCount()); 192cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines const char **nameList = ME->getExportForEachNameList(); 19333f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines const uint32_t *sigList = ME->getExportForEachSignatureList(); 19433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) { 195cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines printf("exportForEachSignatureList[%u]: %s - %u\n", i, nameList[i], 196cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines sigList[i]); 19733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines } 198569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 19933f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 200932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("pragmaCount: %u\n", ME->getPragmaCount()); 201932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **keyList = ME->getPragmaKeyList(); 202932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **valueList = ME->getPragmaValueList(); 203932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getPragmaCount(); i++) { 204932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("pragma[%u]: %s - %s\n", i, keyList[i], valueList[i]); 205932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 206569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 207932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 208932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("objectSlotCount: %u\n", ME->getObjectSlotCount()); 209932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const uint32_t *slotList = ME->getObjectSlotList(); 210932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getObjectSlotCount(); i++) { 211932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("objectSlotList[%u]: %u\n", i, slotList[i]); 212932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 213569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 214932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 215932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 216932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 217932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 218932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 219932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic size_t readBitcode(const char **bitcode) { 220e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (!inFile.length()) { 221932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "input file required\n"); 222e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 223932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 224932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 225932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines struct stat statInFile; 226e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (stat(inFile.c_str(), &statInFile) < 0) { 227932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno)); 228e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 229932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 230932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 231932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!S_ISREG(statInFile.st_mode)) { 232932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Input file should be a regular file.\n"); 233e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 234932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 235932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 236e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines FILE *in = fopen(inFile.c_str(), "r"); 237932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!in) { 238e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not open input file %s\n", inFile.c_str()); 239e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 240932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 241932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 242932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = statInFile.st_size; 243932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 244932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *bitcode = (const char*) calloc(1, bitcodeSize + 1); 245932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t nread = fread((void*) *bitcode, 1, bitcodeSize, in); 246932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 247932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (nread != bitcodeSize) 248e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not read all of file %s\n", inFile.c_str()); 249932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 250932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fclose(in); 251932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return nread; 252932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 253932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 254932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 255932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic void releaseBitcode(const char **bitcode) { 256932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (bitcode && *bitcode) { 257932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines free((void*) *bitcode); 258932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *bitcode = NULL; 259932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 260932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 261932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 262932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 263932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 264932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesint main(int argc, char** argv) { 265932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if(!parseOption(argc, argv)) { 266932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to parse option\n"); 267932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 1; 268932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 269932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 270932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char *bitcode = NULL; 271932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = readBitcode(&bitcode); 272932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 27304261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines unsigned int version = 0; 274932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 27504261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize); 27604261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) { 27704261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines version = bcWrapper.getTargetAPI(); 2783ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 2793ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("Found bitcodeWrapper\n"); 2803ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 28104261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines } else if (translateFlag) { 282932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines version = 12; 283932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 284932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 2853ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 2863ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("targetAPI: %u\n", version); 2873ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion()); 2883ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel()); 2893ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 29004261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines 291e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines llvm::OwningPtr<bcinfo::BitcodeTranslator> BT; 292e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT.reset(new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version)); 293932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!BT->translate()) { 294932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to translate bitcode\n"); 29504261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 3; 296932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 297932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 298e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines llvm::OwningPtr<bcinfo::MetadataExtractor> ME; 299e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines ME.reset(new bcinfo::MetadataExtractor(BT->getTranslatedBitcode(), 300e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT->getTranslatedBitcodeSize())); 301932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!ME->extract()) { 302932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to get metadata\n"); 30304261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 4; 304932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 305932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3063ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 3073ffc8330d765599e357197883f72c01bd43837c8Stephen Hines dumpMetadata(ME.get()); 308e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3093ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char *translatedBitcode = BT->getTranslatedBitcode(); 3103ffc8330d765599e357197883f72c01bd43837c8Stephen Hines size_t translatedBitcodeSize = BT->getTranslatedBitcodeSize(); 311e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3123ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::LLVMContext &ctx = llvm::getGlobalContext(); 3133ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::llvm_shutdown_obj called_on_exit; 314e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3153ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::OwningPtr<llvm::MemoryBuffer> mem; 316e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3173ffc8330d765599e357197883f72c01bd43837c8Stephen Hines mem.reset(llvm::MemoryBuffer::getMemBuffer( 3183ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::StringRef(translatedBitcode, translatedBitcodeSize), 3193ffc8330d765599e357197883f72c01bd43837c8Stephen Hines inFile.c_str(), false)); 320e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3213ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::OwningPtr<llvm::Module> module; 3223ffc8330d765599e357197883f72c01bd43837c8Stephen Hines std::string errmsg; 3233ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module.reset(llvm::ParseBitcodeFile(mem.get(), ctx, &errmsg)); 3243ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (module.get() != 0 && module->MaterializeAllPermanently(&errmsg)) { 3253ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module.reset(); 3263ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 327e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3283ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (module.get() == 0) { 3293ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (errmsg.size()) { 3303ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "error: %s\n", errmsg.c_str()); 3313ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } else { 3323ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "error: failed to parse bitcode file\n"); 3333ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 3343ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 5; 335e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines } 336e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3373ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::OwningPtr<llvm::tool_output_file> tof( 3383ffc8330d765599e357197883f72c01bd43837c8Stephen Hines new llvm::tool_output_file(outFile.c_str(), errmsg, 339b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines llvm::sys::fs::F_Binary)); 3403ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::OwningPtr<llvm::AssemblyAnnotationWriter> ann; 3413ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module->print(tof->os(), ann.get()); 3423ffc8330d765599e357197883f72c01bd43837c8Stephen Hines 3433ffc8330d765599e357197883f72c01bd43837c8Stephen Hines tof->keep(); 3443ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 345932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3463ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (infoFlag) { 3473ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (dumpInfo(ME.get()) != 0) { 3483ffc8330d765599e357197883f72c01bd43837c8Stephen Hines fprintf(stderr, "Error dumping info file\n"); 3493ffc8330d765599e357197883f72c01bd43837c8Stephen Hines return 6; 3503ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 3513ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 352932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 353932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines releaseBitcode(&bitcode); 354932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 355932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 0; 356932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 357