• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <algorithm>
6 #include <iostream>
7 #include <string>
8 #include <vector>
9 
10 #include "base/basictypes.h"
11 
12 // Include once to get the type definitions
13 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
14 
15 struct msginfo {
16   const char* name;
17   const char* file;
18   int id;
19   int in_count;
20   int out_count;
21 
operator <msginfo22   bool operator< (const msginfo& other) const {
23     return id < other.id;
24   }
25 };
26 
27 // Redefine macros to generate table
28 #include "ipc/ipc_message_null_macros.h"
29 #undef IPC_MESSAGE_DECL
30 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
31   { #name, __FILE__, IPC_MESSAGE_ID(), in, out },
32 
33 static msginfo msgtable[] = {
34 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
35 };
36 #define MSGTABLE_SIZE (sizeof(msgtable)/sizeof(msgtable[0]))
37 COMPILE_ASSERT(MSGTABLE_SIZE, CHECK_YOUR_HEADERS_FOR_AN_EXTRA_SEMICOLON);
38 
check_msgtable()39 static bool check_msgtable() {
40   bool result = true;
41   int previous_class_id = 0;
42   int highest_class_id = 0;
43   const char* file_name = "NONE";
44   const char* previous_file_name = "NONE";
45   std::vector<int> exemptions;
46 
47   // Exclude test and other non-browser files from consideration.  Do not
48   // include message files used inside the actual chrome browser in this list.
49   exemptions.push_back(TestMsgStart);
50   exemptions.push_back(FirefoxImporterUnittestMsgStart);
51   exemptions.push_back(ShellMsgStart);
52   exemptions.push_back(MetroViewerMsgStart);
53   exemptions.push_back(CCMsgStart);  // Nothing but param traits.
54   exemptions.push_back(CldDataProviderMsgStart); // Conditional build.
55 #if !defined(OS_ANDROID)
56   exemptions.push_back(JavaBridgeMsgStart);
57   exemptions.push_back(MediaPlayerMsgStart);
58   exemptions.push_back(EncryptedMediaMsgStart);
59   exemptions.push_back(GinJavaBridgeMsgStart);
60   exemptions.push_back(AndroidWebViewMsgStart);
61 #endif  // !defined(OS_ANDROID)
62 #if !defined(USE_OZONE)
63   exemptions.push_back(OzoneGpuMsgStart);
64 #endif  // !defined(USE_OZONE)
65 
66   for (size_t i = 0; i < MSGTABLE_SIZE; ++i) {
67     int class_id = IPC_MESSAGE_ID_CLASS(msgtable[i].id);
68     file_name = msgtable[i].file;
69     if (class_id >= LastIPCMsgStart) {
70       std::cout << "Invalid LastIPCMsgStart setting\n";
71       result = false;
72     }
73     if (class_id == previous_class_id &&
74         strcmp(file_name, previous_file_name) != 0) {
75       std::cerr << "enum used in multiple files: "
76                 << file_name << " vs "
77                 << previous_file_name << "\n";
78       result = false;
79     }
80     while (class_id > previous_class_id + 1) {
81       std::vector<int>::iterator iter;
82       iter = find(exemptions.begin(), exemptions.end(), previous_class_id + 1);
83       if (iter == exemptions.end()) {
84         std::cout << "Missing message file for enum "
85                   << class_id - (previous_class_id + 1)
86                   <<  " before enum used by " << file_name << "\n";
87         result = false;
88       }
89       ++previous_class_id;
90     }
91     previous_class_id = class_id;
92     previous_file_name = file_name;
93     if (class_id > highest_class_id)
94       highest_class_id = class_id;
95   }
96 
97   while (LastIPCMsgStart > highest_class_id + 1) {
98     std::vector<int>::iterator iter;
99     iter = find(exemptions.begin(), exemptions.end(), highest_class_id+1);
100     if (iter == exemptions.end()) {
101       std::cout << "Missing message file for enum "
102                 << LastIPCMsgStart - (highest_class_id + 1)
103                 << " before enum LastIPCMsgStart\n";
104       break;
105     }
106     ++highest_class_id;
107   }
108 
109   if (!result)
110     std::cout << "Please check tools/ipc_fuzzer/message_lib/all_messages.h\n";
111 
112   return result;
113 }
114 
dump_msgtable(bool show_args,bool show_ids,bool show_comma,const char * prefix)115 static void dump_msgtable(bool show_args, bool show_ids,
116                           bool show_comma, const char *prefix) {
117   bool first = true;
118   for (size_t i = 0; i < MSGTABLE_SIZE; ++i) {
119     if ((!prefix) || strstr(msgtable[i].name, prefix) == msgtable[i].name) {
120       if (show_comma) {
121         if (!first)
122           std::cout << ",";
123         first = false;
124         std::cout << msgtable[i].id;
125       } else {
126         if (show_ids)
127           std::cout << msgtable[i].id << " " <<
128               IPC_MESSAGE_ID_CLASS(msgtable[i].id) << "," <<
129               IPC_MESSAGE_ID_LINE(msgtable[i].id) << " ";
130         std::cout << msgtable[i].name;
131         if (show_args) {
132           std::cout << "(" << msgtable[i].in_count << " IN, "  <<
133               msgtable[i].out_count << " OUT)";
134         }
135         std::cout << "\n";
136       }
137     }
138   }
139   if (show_comma)
140     std::cout << "\n";
141 }
142 
main(int argc,char ** argv)143 int main(int argc, char **argv) {
144   bool show_args = false;
145   bool show_ids  = false;
146   bool skip_check = false;
147   bool show_comma = false;
148   const char *filter = NULL;
149 
150   while (--argc > 0) {
151     ++argv;
152     if (std::string("--args") == *argv) {
153       show_args = true;
154     } else if (std::string("--comma") == *argv) {
155       show_comma = true;
156     } else if (std::string("--filter") == *argv) {
157       filter = *(++argv);
158       --argc;
159     } else if (std::string("--ids") == *argv) {
160       show_ids = true;
161     } else if (std::string("--no-check") == *argv) {
162       skip_check = true;
163     } else {
164       std::cout <<
165           "usage: ipclist [--args] [--ids] [--no-check] [--filter prefix] "
166           "[--comma]\n";
167       return 1;
168     }
169   }
170 
171   std::sort(msgtable, msgtable + MSGTABLE_SIZE);
172 
173   if (!skip_check && check_msgtable() == false)
174     return 1;
175 
176   dump_msgtable(show_args, show_ids, show_comma, filter);
177   return 0;
178 }
179 
180