1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
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 "idmap2/RawPrintVisitor.h"
18
19 #include <algorithm>
20 #include <cstdarg>
21 #include <string>
22 #include <utility>
23
24 #include "android-base/macros.h"
25 #include "android-base/stringprintf.h"
26 #include "idmap2/PolicyUtils.h"
27 #include "idmap2/ResourceUtils.h"
28 #include "idmap2/Result.h"
29
30 using android::idmap2::policy::PoliciesToDebugString;
31
32 namespace android::idmap2 {
33
visit(const Idmap & idmap ATTRIBUTE_UNUSED)34 void RawPrintVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) {
35 }
36
visit(const IdmapHeader & header)37 void RawPrintVisitor::visit(const IdmapHeader& header) {
38 print(header.GetMagic(), "magic");
39 print(header.GetVersion(), "version");
40 print(header.GetTargetCrc(), "target crc");
41 print(header.GetOverlayCrc(), "overlay crc");
42 print(header.GetFulfilledPolicies(), "fulfilled policies: %s",
43 PoliciesToDebugString(header.GetFulfilledPolicies()).c_str());
44 print(static_cast<uint32_t>(header.GetEnforceOverlayable()), "enforce overlayable");
45 print(header.GetTargetPath(), true /* print_value */, "target path");
46 print(header.GetOverlayPath(), true /* print_value */, "overlay path");
47 print(header.GetOverlayName(), true /* print_value */, "overlay name");
48 print(header.GetDebugInfo(), false /* print_value */, "debug info");
49
50 if (auto target = TargetResourceContainer::FromPath(header.GetTargetPath())) {
51 target_ = std::move(*target);
52 }
53 if (auto overlay = OverlayResourceContainer::FromPath(header.GetOverlayPath())) {
54 overlay_ = std::move(*overlay);
55 }
56 }
57
visit(const IdmapData & data ATTRIBUTE_UNUSED)58 void RawPrintVisitor::visit(const IdmapData& data ATTRIBUTE_UNUSED) {
59 for (auto& target_entry : data.GetTargetEntries()) {
60 Result<std::string> target_name(Error(""));
61 if (target_ != nullptr) {
62 target_name = target_->GetResourceName(target_entry.target_id);
63 }
64 if (target_name) {
65 print(target_entry.target_id, "target id: %s", target_name->c_str());
66 } else {
67 print(target_entry.target_id, "target id");
68 }
69
70 Result<std::string> overlay_name(Error(""));
71 if (overlay_ != nullptr) {
72 overlay_name = overlay_->GetResourceName(target_entry.overlay_id);
73 }
74 if (overlay_name) {
75 print(target_entry.overlay_id, "overlay id: %s", overlay_name->c_str());
76 } else {
77 print(target_entry.overlay_id, "overlay id");
78 }
79 }
80
81 for (auto& target_entry : data.GetTargetInlineEntries()) {
82 Result<std::string> target_name(Error(""));
83 if (target_ != nullptr) {
84 target_name = target_->GetResourceName(target_entry.target_id);
85 }
86 if (target_name) {
87 print(target_entry.target_id, "target id: %s", target_name->c_str());
88 } else {
89 print(target_entry.target_id, "target id");
90 }
91
92
93 pad(sizeof(Res_value::size) + sizeof(Res_value::res0));
94
95 for (auto& target_entry_value : target_entry.values) {
96 auto value = target_entry_value.second;
97
98 print(target_entry_value.first.to_string(), false, "config: %s",
99 target_entry_value.first.toString().c_str());
100
101 print(value.data_type, "type: %s",
102 utils::DataTypeToString(value.data_type).data());
103
104 Result<std::string> overlay_name(Error(""));
105 if (overlay_ != nullptr &&
106 (value.data_value == Res_value::TYPE_REFERENCE ||
107 value.data_value == Res_value::TYPE_DYNAMIC_REFERENCE)) {
108 overlay_name = overlay_->GetResourceName(value.data_value);
109 }
110
111 if (overlay_name) {
112 print(value.data_value, "data: %s", overlay_name->c_str());
113 } else {
114 print(value.data_value, "data");
115 }
116 }
117 }
118
119 for (auto& overlay_entry : data.GetOverlayEntries()) {
120 Result<std::string> overlay_name(Error(""));
121 if (overlay_ != nullptr) {
122 overlay_name = overlay_->GetResourceName(overlay_entry.overlay_id);
123 }
124
125 if (overlay_name) {
126 print(overlay_entry.overlay_id, "overlay id: %s", overlay_name->c_str());
127 } else {
128 print(overlay_entry.overlay_id, "overlay id");
129 }
130
131 Result<std::string> target_name(Error(""));
132 if (target_ != nullptr) {
133 target_name = target_->GetResourceName(overlay_entry.target_id);
134 }
135
136 if (target_name) {
137 print(overlay_entry.target_id, "target id: %s", target_name->c_str());
138 } else {
139 print(overlay_entry.target_id, "target id");
140 }
141 }
142
143 print(data.GetStringPoolData(), false /* print_value */, "string pool");
144 }
145
visit(const IdmapData::Header & header)146 void RawPrintVisitor::visit(const IdmapData::Header& header) {
147 print(header.GetTargetEntryCount(), "target entry count");
148 print(header.GetTargetInlineEntryCount(), "target inline entry count");
149 print(header.GetTargetInlineEntryValueCount(), "target inline entry value count");
150 print(header.GetConfigCount(), "config count");
151 print(header.GetOverlayEntryCount(), "overlay entry count");
152 print(header.GetStringPoolIndexOffset(), "string pool index offset");
153 }
154
155 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint8_t value,const char * fmt,...)156 void RawPrintVisitor::print(uint8_t value, const char* fmt, ...) {
157 va_list ap;
158 va_start(ap, fmt);
159 std::string comment;
160 base::StringAppendV(&comment, fmt, ap);
161 va_end(ap);
162
163 stream_ << base::StringPrintf("%08zx: %02x", offset_, value) << " " << comment
164 << '\n';
165 offset_ += sizeof(uint8_t);
166 }
167
168 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint16_t value,const char * fmt,...)169 void RawPrintVisitor::print(uint16_t value, const char* fmt, ...) {
170 va_list ap;
171 va_start(ap, fmt);
172 std::string comment;
173 base::StringAppendV(&comment, fmt, ap);
174 va_end(ap);
175
176 stream_ << base::StringPrintf("%08zx: %04x", offset_, value) << " " << comment << '\n';
177 offset_ += sizeof(uint16_t);
178 }
179
180 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint32_t value,const char * fmt,...)181 void RawPrintVisitor::print(uint32_t value, const char* fmt, ...) {
182 va_list ap;
183 va_start(ap, fmt);
184 std::string comment;
185 base::StringAppendV(&comment, fmt, ap);
186 va_end(ap);
187
188 stream_ << base::StringPrintf("%08zx: %08x", offset_, value) << " " << comment << '\n';
189 offset_ += sizeof(uint32_t);
190 }
191
192 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(const std::string & value,bool print_value,const char * fmt,...)193 void RawPrintVisitor::print(const std::string& value, bool print_value, const char* fmt, ...) {
194 va_list ap;
195 va_start(ap, fmt);
196 std::string comment;
197 base::StringAppendV(&comment, fmt, ap);
198 va_end(ap);
199
200 stream_ << base::StringPrintf("%08zx: %08x", offset_, (uint32_t)value.size()) << " " << comment
201 << " size" << '\n';
202 offset_ += sizeof(uint32_t);
203
204 stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment;
205 offset_ += value.size() + CalculatePadding(value.size());
206
207 if (print_value) {
208 stream_ << ": " << value;
209 }
210 stream_ << '\n';
211 }
212
align()213 void RawPrintVisitor::align() {
214 offset_ += CalculatePadding(offset_);
215 }
216
pad(size_t padding)217 void RawPrintVisitor::pad(size_t padding) {
218 offset_ += padding;
219 }
220 } // namespace android::idmap2
221