blob: 1360c68838de12f8547a0c14485bde44fccc45c6 [file] [log] [blame]
Stephen Hines932bc6e2011-07-27 16:26:26 -07001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * Copyright 2011-2012, The Android Open Source Project
Stephen Hines932bc6e2011-07-27 16:26:26 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <bcinfo/BitcodeTranslator.h>
Stephen Hines04261e02012-01-21 17:11:22 -080018#include <bcinfo/BitcodeWrapper.h>
Stephen Hines932bc6e2011-07-27 16:26:26 -070019#include <bcinfo/MetadataExtractor.h>
20
21#include <ctype.h>
22#include <dlfcn.h>
23#include <stdarg.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <getopt.h>
29
30#include <errno.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33
34#include <unistd.h>
35
36#include <vector>
37
38// This file corresponds to the standalone bcinfo tool. It prints a variety of
39// information about a supplied bitcode input file.
40
41const char* inFile = NULL;
42
43extern int opterr;
44extern int optind;
45
Stephen Hines04261e02012-01-21 17:11:22 -080046bool translateFlag = false;
Stephen Hines932bc6e2011-07-27 16:26:26 -070047
48static int parseOption(int argc, char** argv) {
49 int c;
50 while ((c = getopt(argc, argv, "t")) != -1) {
51 opterr = 0;
52
53 switch(c) {
54 case '?':
55 // ignore any error
56 break;
57
58 case 't':
Stephen Hines04261e02012-01-21 17:11:22 -080059 translateFlag = true;
Stephen Hines932bc6e2011-07-27 16:26:26 -070060 break;
61
62 default:
63 // Critical error occurs
64 return 0;
65 break;
66 }
67 }
68
69 if(optind >= argc) {
70 fprintf(stderr, "input file required\n");
71 return 0;
72 }
73
74 inFile = argv[optind];
75 return 1;
76}
77
78
79static void dumpMetadata(bcinfo::MetadataExtractor *ME) {
80 if (!ME) {
81 return;
82 }
83
Stephen Hinese1fd8042012-03-27 11:03:46 -070084 printf("RSFloatPrecision: ");
85 switch (ME->getRSFloatPrecision()) {
86 case bcinfo::RS_FP_Full:
87 printf("Full\n\n");
88 break;
89 case bcinfo::RS_FP_Relaxed:
90 printf("Relaxed\n\n");
91 break;
92 case bcinfo::RS_FP_Imprecise:
93 printf("Imprecise\n\n");
94 break;
95 default:
96 printf("UNKNOWN\n\n");
97 break;
98 }
99
Stephen Hines932bc6e2011-07-27 16:26:26 -0700100 printf("exportVarCount: %u\n", ME->getExportVarCount());
Stephen Hines569986d2012-03-09 19:58:45 -0800101 const char **varNameList = ME->getExportVarNameList();
102 for (size_t i = 0; i < ME->getExportVarCount(); i++) {
103 printf("var[%u]: %s\n", i, varNameList[i]);
104 }
105 printf("\n");
106
Stephen Hines932bc6e2011-07-27 16:26:26 -0700107 printf("exportFuncCount: %u\n", ME->getExportFuncCount());
Stephen Hines569986d2012-03-09 19:58:45 -0800108 const char **funcNameList = ME->getExportFuncNameList();
109 for (size_t i = 0; i < ME->getExportFuncCount(); i++) {
110 printf("func[%u]: %s\n", i, funcNameList[i]);
111 }
112 printf("\n");
Stephen Hines33f8fe22011-08-17 12:56:22 -0700113
114 printf("exportForEachSignatureCount: %u\n",
115 ME->getExportForEachSignatureCount());
Stephen Hinescc366e52012-02-21 17:22:04 -0800116 const char **nameList = ME->getExportForEachNameList();
Stephen Hines33f8fe22011-08-17 12:56:22 -0700117 const uint32_t *sigList = ME->getExportForEachSignatureList();
118 for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800119 printf("exportForEachSignatureList[%u]: %s - %u\n", i, nameList[i],
120 sigList[i]);
Stephen Hines33f8fe22011-08-17 12:56:22 -0700121 }
Stephen Hines569986d2012-03-09 19:58:45 -0800122 printf("\n");
Stephen Hines33f8fe22011-08-17 12:56:22 -0700123
Stephen Hines932bc6e2011-07-27 16:26:26 -0700124 printf("pragmaCount: %u\n", ME->getPragmaCount());
125 const char **keyList = ME->getPragmaKeyList();
126 const char **valueList = ME->getPragmaValueList();
127 for (size_t i = 0; i < ME->getPragmaCount(); i++) {
128 printf("pragma[%u]: %s - %s\n", i, keyList[i], valueList[i]);
129 }
Stephen Hines569986d2012-03-09 19:58:45 -0800130 printf("\n");
Stephen Hines932bc6e2011-07-27 16:26:26 -0700131
132 printf("objectSlotCount: %u\n", ME->getObjectSlotCount());
133 const uint32_t *slotList = ME->getObjectSlotList();
134 for (size_t i = 0; i < ME->getObjectSlotCount(); i++) {
135 printf("objectSlotList[%u]: %u\n", i, slotList[i]);
136 }
Stephen Hines569986d2012-03-09 19:58:45 -0800137 printf("\n");
Stephen Hines932bc6e2011-07-27 16:26:26 -0700138
139 return;
140}
141
142
143static size_t readBitcode(const char **bitcode) {
144 if (!inFile) {
145 fprintf(stderr, "input file required\n");
146 return NULL;
147 }
148
149 struct stat statInFile;
150 if (stat(inFile, &statInFile) < 0) {
151 fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno));
152 return NULL;
153 }
154
155 if (!S_ISREG(statInFile.st_mode)) {
156 fprintf(stderr, "Input file should be a regular file.\n");
157 return NULL;
158 }
159
160 FILE *in = fopen(inFile, "r");
161 if (!in) {
162 fprintf(stderr, "Could not open input file %s\n", inFile);
163 return NULL;
164 }
165
166 size_t bitcodeSize = statInFile.st_size;
167
168 *bitcode = (const char*) calloc(1, bitcodeSize + 1);
169 size_t nread = fread((void*) *bitcode, 1, bitcodeSize, in);
170
171 if (nread != bitcodeSize)
172 fprintf(stderr, "Could not read all of file %s\n", inFile);
173
174 fclose(in);
175 return nread;
176}
177
178
179static void releaseBitcode(const char **bitcode) {
180 if (bitcode && *bitcode) {
181 free((void*) *bitcode);
182 *bitcode = NULL;
183 }
184 return;
185}
186
187
188int main(int argc, char** argv) {
189 if(!parseOption(argc, argv)) {
190 fprintf(stderr, "failed to parse option\n");
191 return 1;
192 }
193
194 const char *bitcode = NULL;
195 const char *translatedBitcode = NULL;
196 size_t bitcodeSize = readBitcode(&bitcode);
197
Stephen Hines04261e02012-01-21 17:11:22 -0800198 unsigned int version = 0;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700199
Stephen Hines04261e02012-01-21 17:11:22 -0800200 bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize);
Stephen Hines04261e02012-01-21 17:11:22 -0800201 if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) {
202 version = bcWrapper.getTargetAPI();
203 printf("Found bitcodeWrapper\n");
204 } else if (translateFlag) {
Stephen Hines932bc6e2011-07-27 16:26:26 -0700205 version = 12;
206 }
207
Stephen Hines7cd4c492012-03-13 19:57:37 -0700208 printf("targetAPI: %u\n", version);
209 printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion());
210 printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel());
Stephen Hines04261e02012-01-21 17:11:22 -0800211
Stephen Hines932bc6e2011-07-27 16:26:26 -0700212 bcinfo::BitcodeTranslator *BT =
213 new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version);
214 if (!BT->translate()) {
215 fprintf(stderr, "failed to translate bitcode\n");
Stephen Hines04261e02012-01-21 17:11:22 -0800216 return 3;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700217 }
218
219 bcinfo::MetadataExtractor *ME =
220 new bcinfo::MetadataExtractor(BT->getTranslatedBitcode(),
221 BT->getTranslatedBitcodeSize());
222 if (!ME->extract()) {
223 fprintf(stderr, "failed to get metadata\n");
Stephen Hines04261e02012-01-21 17:11:22 -0800224 return 4;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700225 }
226
227 dumpMetadata(ME);
228
229 delete ME;
230 delete BT;
231
232 releaseBitcode(&bitcode);
233
234 return 0;
235}