| 223 | |
| 224 | template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData> |
| 225 | bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, |
| 226 | const std::string& location, |
| 227 | const char* declaring_class_descriptor, |
| 228 | const std::vector<const char*>& arg_descriptors, |
| 229 | const std::string& method_name, |
| 230 | bool is_static, |
| 231 | uint16_t registers_size, |
| 232 | uint16_t ins_size, |
| 233 | uint16_t insns_size_in_code_units, |
| 234 | IndexToStringData index_to_string_data, |
| 235 | TypeIndexToStringData type_index_to_string_data, |
| 236 | NewLocalCallback new_local_callback, |
| 237 | void* context) { |
| 238 | if (stream == nullptr) { |
| 239 | return false; |
| 240 | } |
| 241 | std::vector<LocalInfo> local_in_reg(registers_size); |
| 242 | |
| 243 | uint16_t arg_reg = registers_size - ins_size; |
| 244 | if (!is_static) { |
| 245 | const char* descriptor = declaring_class_descriptor; |
| 246 | local_in_reg[arg_reg].name_ = "this"; |
| 247 | local_in_reg[arg_reg].descriptor_ = descriptor; |
| 248 | local_in_reg[arg_reg].signature_ = nullptr; |
| 249 | local_in_reg[arg_reg].start_address_ = 0; |
| 250 | local_in_reg[arg_reg].reg_ = arg_reg; |
| 251 | local_in_reg[arg_reg].is_live_ = true; |
| 252 | arg_reg++; |
| 253 | } |
| 254 | |
| 255 | DecodeUnsignedLeb128(&stream); // Line. |
| 256 | uint32_t parameters_size = DecodeUnsignedLeb128(&stream); |
| 257 | uint32_t i; |
| 258 | if (parameters_size != arg_descriptors.size()) { |
| 259 | LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location |
| 260 | << " for method " << method_name; |
| 261 | return false; |
| 262 | } |
| 263 | for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) { |
| 264 | if (arg_reg >= registers_size) { |
| 265 | LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg |
| 266 | << " >= " << registers_size << ") in " << location; |
| 267 | return false; |
| 268 | } |
| 269 | uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); |
| 270 | const char* descriptor = arg_descriptors[i]; |
| 271 | local_in_reg[arg_reg].name_ = index_to_string_data(name_idx); |
| 272 | local_in_reg[arg_reg].descriptor_ = descriptor; |
| 273 | local_in_reg[arg_reg].signature_ = nullptr; |
| 274 | local_in_reg[arg_reg].start_address_ = 0; |
| 275 | local_in_reg[arg_reg].reg_ = arg_reg; |
| 276 | local_in_reg[arg_reg].is_live_ = true; |
| 277 | switch (*descriptor) { |
| 278 | case 'D': |
| 279 | case 'J': |
| 280 | arg_reg += 2; |
| 281 | break; |
| 282 | default: |
nothing calls this directly
no test coverage detected