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 pad(sizeof(Res_value::size) + sizeof(Res_value::res0));
93
94 print(target_entry.value.data_type, "type: %s",
95 utils::DataTypeToString(target_entry.value.data_type).data());
96
97 Result<std::string> overlay_name(Error(""));
98 if (overlay_ != nullptr &&
99 (target_entry.value.data_value == Res_value::TYPE_REFERENCE ||
100 target_entry.value.data_value == Res_value::TYPE_DYNAMIC_REFERENCE)) {
101 overlay_name = overlay_->GetResourceName(target_entry.value.data_value);
102 }
103
104 if (overlay_name) {
105 print(target_entry.value.data_value, "data: %s", overlay_name->c_str());
106 } else {
107 print(target_entry.value.data_value, "data");
108 }
109 }
110
111 for (auto& overlay_entry : data.GetOverlayEntries()) {
112 Result<std::string> overlay_name(Error(""));
113 if (overlay_ != nullptr) {
114 overlay_name = overlay_->GetResourceName(overlay_entry.overlay_id);
115 }
116
117 if (overlay_name) {
118 print(overlay_entry.overlay_id, "overlay id: %s", overlay_name->c_str());
119 } else {
120 print(overlay_entry.overlay_id, "overlay id");
121 }
122
123 Result<std::string> target_name(Error(""));
124 if (target_ != nullptr) {
125 target_name = target_->GetResourceName(overlay_entry.target_id);
126 }
127
128 if (target_name) {
129 print(overlay_entry.target_id, "target id: %s", target_name->c_str());
130 } else {
131 print(overlay_entry.target_id, "target id");
132 }
133 }
134
135 print(data.GetStringPoolData(), false /* print_value */, "string pool");
136 }
137
visit(const IdmapData::Header & header)138 void RawPrintVisitor::visit(const IdmapData::Header& header) {
139 print(header.GetTargetEntryCount(), "target entry count");
140 print(header.GetTargetInlineEntryCount(), "target inline entry count");
141 print(header.GetOverlayEntryCount(), "overlay entry count");
142 print(header.GetStringPoolIndexOffset(), "string pool index offset");
143 }
144
145 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint8_t value,const char * fmt,...)146 void RawPrintVisitor::print(uint8_t value, const char* fmt, ...) {
147 va_list ap;
148 va_start(ap, fmt);
149 std::string comment;
150 base::StringAppendV(&comment, fmt, ap);
151 va_end(ap);
152
153 stream_ << base::StringPrintf("%08zx: %02x", offset_, value) << " " << comment
154 << std::endl;
155 offset_ += sizeof(uint8_t);
156 }
157
158 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint16_t value,const char * fmt,...)159 void RawPrintVisitor::print(uint16_t value, const char* fmt, ...) {
160 va_list ap;
161 va_start(ap, fmt);
162 std::string comment;
163 base::StringAppendV(&comment, fmt, ap);
164 va_end(ap);
165
166 stream_ << base::StringPrintf("%08zx: %04x", offset_, value) << " " << comment << std::endl;
167 offset_ += sizeof(uint16_t);
168 }
169
170 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(uint32_t value,const char * fmt,...)171 void RawPrintVisitor::print(uint32_t value, const char* fmt, ...) {
172 va_list ap;
173 va_start(ap, fmt);
174 std::string comment;
175 base::StringAppendV(&comment, fmt, ap);
176 va_end(ap);
177
178 stream_ << base::StringPrintf("%08zx: %08x", offset_, value) << " " << comment << std::endl;
179 offset_ += sizeof(uint32_t);
180 }
181
182 // NOLINTNEXTLINE(cert-dcl50-cpp)
print(const std::string & value,bool print_value,const char * fmt,...)183 void RawPrintVisitor::print(const std::string& value, bool print_value, const char* fmt, ...) {
184 va_list ap;
185 va_start(ap, fmt);
186 std::string comment;
187 base::StringAppendV(&comment, fmt, ap);
188 va_end(ap);
189
190 stream_ << base::StringPrintf("%08zx: %08x", offset_, (uint32_t)value.size()) << " " << comment
191 << " size" << std::endl;
192 offset_ += sizeof(uint32_t);
193
194 stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment;
195 offset_ += value.size() + CalculatePadding(value.size());
196
197 if (print_value) {
198 stream_ << ": " << value;
199 }
200 stream_ << std::endl;
201 }
202
align()203 void RawPrintVisitor::align() {
204 offset_ += CalculatePadding(offset_);
205 }
206
pad(size_t padding)207 void RawPrintVisitor::pad(size_t padding) {
208 offset_ += padding;
209 }
210 } // namespace android::idmap2
211