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/StringRef.h> 22e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines#include <llvm/Bitcode/ReaderWriter.h> 23c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include <llvm/IR/AssemblyAnnotationWriter.h> 24b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/LLVMContext.h> 25b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h> 26a630078b32eb37a8de91ae09e26babf235d4fc9fStephen Hines#include <llvm/Support/FileSystem.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 default: 169e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines printf("UNKNOWN\n\n"); 170e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines break; 171e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines } 172e1fd804a58c0ed67c75566c784d0b20d81e97adaStephen Hines 173932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("exportVarCount: %u\n", ME->getExportVarCount()); 174569986da116ed602c752395f9563260db38f6945Stephen Hines const char **varNameList = ME->getExportVarNameList(); 175569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportVarCount(); i++) { 176569986da116ed602c752395f9563260db38f6945Stephen Hines printf("var[%u]: %s\n", i, varNameList[i]); 177569986da116ed602c752395f9563260db38f6945Stephen Hines } 178569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 179569986da116ed602c752395f9563260db38f6945Stephen Hines 180932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("exportFuncCount: %u\n", ME->getExportFuncCount()); 181569986da116ed602c752395f9563260db38f6945Stephen Hines const char **funcNameList = ME->getExportFuncNameList(); 182569986da116ed602c752395f9563260db38f6945Stephen Hines for (size_t i = 0; i < ME->getExportFuncCount(); i++) { 183569986da116ed602c752395f9563260db38f6945Stephen Hines printf("func[%u]: %s\n", i, funcNameList[i]); 184569986da116ed602c752395f9563260db38f6945Stephen Hines } 185569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 18633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 18733f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines printf("exportForEachSignatureCount: %u\n", 18833f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines ME->getExportForEachSignatureCount()); 189cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines const char **nameList = ME->getExportForEachNameList(); 19033f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines const uint32_t *sigList = ME->getExportForEachSignatureList(); 19133f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) { 192cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines printf("exportForEachSignatureList[%u]: %s - %u\n", i, nameList[i], 193cc366e573e31f43a6101fd6e04b90c6afdc3b7a7Stephen Hines sigList[i]); 19433f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines } 195569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 19633f8fe2bfafe00ad2c74e4590ffdd0bcfc5eb31dStephen Hines 197932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("pragmaCount: %u\n", ME->getPragmaCount()); 198932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **keyList = ME->getPragmaKeyList(); 199932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char **valueList = ME->getPragmaValueList(); 200932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getPragmaCount(); i++) { 201932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("pragma[%u]: %s - %s\n", i, keyList[i], valueList[i]); 202932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 203569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 204932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 205932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("objectSlotCount: %u\n", ME->getObjectSlotCount()); 206932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const uint32_t *slotList = ME->getObjectSlotList(); 207932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines for (size_t i = 0; i < ME->getObjectSlotCount(); i++) { 208932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines printf("objectSlotList[%u]: %u\n", i, slotList[i]); 209932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 210569986da116ed602c752395f9563260db38f6945Stephen Hines printf("\n"); 211932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 212932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 213932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 214932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 215932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 216932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic size_t readBitcode(const char **bitcode) { 217e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (!inFile.length()) { 218932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "input file required\n"); 219e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 220932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 221932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 222932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines struct stat statInFile; 223e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines if (stat(inFile.c_str(), &statInFile) < 0) { 224932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno)); 225e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 226932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 227932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 228932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!S_ISREG(statInFile.st_mode)) { 229932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "Input file should be a regular file.\n"); 230e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 231932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 232932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 233e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines FILE *in = fopen(inFile.c_str(), "r"); 234932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!in) { 235e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not open input file %s\n", inFile.c_str()); 236e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines return 0; 237932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 238932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 239932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = statInFile.st_size; 240932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 241932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *bitcode = (const char*) calloc(1, bitcodeSize + 1); 242932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t nread = fread((void*) *bitcode, 1, bitcodeSize, in); 243932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 244932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (nread != bitcodeSize) 245e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines fprintf(stderr, "Could not read all of file %s\n", inFile.c_str()); 246932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 247932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fclose(in); 248932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return nread; 249932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 250932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 251932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 252932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic void releaseBitcode(const char **bitcode) { 253932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (bitcode && *bitcode) { 254932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines free((void*) *bitcode); 255932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *bitcode = NULL; 256932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 257932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 258932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 259932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 260932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 261932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesint main(int argc, char** argv) { 262932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if(!parseOption(argc, argv)) { 263932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to parse option\n"); 264932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return 1; 265932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 266932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 267932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines const char *bitcode = NULL; 268932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines size_t bitcodeSize = readBitcode(&bitcode); 269932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 27004261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines unsigned int version = 0; 271932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 27204261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize); 27304261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) { 27404261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines version = bcWrapper.getTargetAPI(); 2753ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 2763ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("Found bitcodeWrapper\n"); 2773ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 27804261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines } else if (translateFlag) { 279932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines version = 12; 280932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 281932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 2823ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 2833ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("targetAPI: %u\n", version); 2843ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion()); 2853ffc8330d765599e357197883f72c01bd43837c8Stephen Hines printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel()); 2863ffc8330d765599e357197883f72c01bd43837c8Stephen Hines } 28704261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines 288f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<bcinfo::BitcodeTranslator> BT; 289e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT.reset(new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version)); 290932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!BT->translate()) { 291932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to translate bitcode\n"); 29204261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 3; 293932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 294932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 295f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<bcinfo::MetadataExtractor> ME; 296e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines ME.reset(new bcinfo::MetadataExtractor(BT->getTranslatedBitcode(), 297e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines BT->getTranslatedBitcodeSize())); 298932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!ME->extract()) { 299932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines fprintf(stderr, "failed to get metadata\n"); 30004261e0bf97b15033efd697bd0e4cfbae7107f4bStephen Hines return 4; 301932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 302932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 3033ffc8330d765599e357197883f72c01bd43837c8Stephen Hines if (verbose) { 3043ffc8330d765599e357197883f72c01bd43837c8Stephen Hines dumpMetadata(ME.get()); 305e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3063ffc8330d765599e357197883f72c01bd43837c8Stephen Hines const char *translatedBitcode = BT->getTranslatedBitcode(); 3073ffc8330d765599e357197883f72c01bd43837c8Stephen Hines size_t translatedBitcodeSize = BT->getTranslatedBitcodeSize(); 308e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3093ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::LLVMContext &ctx = llvm::getGlobalContext(); 3103ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::llvm_shutdown_obj called_on_exit; 311e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 312f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<llvm::MemoryBuffer> mem; 313e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 3143ffc8330d765599e357197883f72c01bd43837c8Stephen Hines mem.reset(llvm::MemoryBuffer::getMemBuffer( 3153ffc8330d765599e357197883f72c01bd43837c8Stephen Hines llvm::StringRef(translatedBitcode, translatedBitcodeSize), 3163ffc8330d765599e357197883f72c01bd43837c8Stephen Hines inFile.c_str(), false)); 317e126b62760b4bf115cfed162f0234e4e722011dfStephen Hines 318f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<llvm::Module> module; 319c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray llvm::ErrorOr<llvm::Module*> moduleOrError = llvm::parseBitcodeFile(mem.get(), ctx); 320f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::error_code ec = moduleOrError.getError(); 321c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray if (!ec) { 322c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray module.reset(moduleOrError.get()); 323c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray ec = module->materializeAllPermanently(); 324c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray } 3253ffc8330d765599e357197883f72c01bd43837c8Stephen Hines std::string errmsg; 326c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray if (ec) { 327c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray errmsg = ec.message(); 3283ffc8330d765599e357197883f72c01bd43837c8Stephen Hines module.reset(); 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 337f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<llvm::tool_output_file> tof( 3383ffc8330d765599e357197883f72c01bd43837c8Stephen Hines new llvm::tool_output_file(outFile.c_str(), errmsg, 339c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray llvm::sys::fs::F_None)); 340f21590eae009b4f596d7e448d0b8e142c46fc382Stephen Hines std::unique_ptr<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