class CFITest : public dwarf::DwarfTest { public: void GenerateExpected(FILE* f, InstructionSet isa, constchar* isa_str,
ArrayRef<const uint8_t> actual_asm,
ArrayRef<const uint8_t> actual_cfi) {
std::vector<std::string> lines; // Print the raw bytes.
fprintf(f, "static constexpr uint8_t expected_asm_%s[] = {", isa_str);
HexDump(f, actual_asm);
fprintf(f, "\n};\n");
fprintf(f, "static constexpr uint8_t expected_cfi_%s[] = {", isa_str);
HexDump(f, actual_cfi);
fprintf(f, "\n};\n"); // Pretty-print CFI opcodes. bool is64bit = Is64BitInstructionSet(isa);
dwarf::DebugFrameOpCodeWriter<> initial_opcodes; // Output a DW_CFA_def_cfa (reg + offset) in the CIE so that llvm-dwarfdump // doesn't complain about DW_CFA_cfa_offset in the FDE.
initial_opcodes.DefCFA(dwarf::Reg(8), 0);
dwarf::WriteCIE(is64bit, dwarf::Reg(8), initial_opcodes, &debug_frame_data_);
dwarf::WriteFDE(is64bit, /* cie_pointer= */ 0, /* code_address= */ 0,
actual_asm.size(),
actual_cfi,
&debug_frame_data_);
ReformatCfi(Objdump(isa, "--debug-frame"), &lines); // Pretty-print assembly. const uint8_t* asm_base = actual_asm.data(); const uint8_t* asm_end = asm_base + actual_asm.size(); auto* opts = new DisassemblerOptions(false,
asm_base,
asm_end, true,
is64bit
? &Thread::DumpThreadOffset<PointerSize::k64>
: &Thread::DumpThreadOffset<PointerSize::k32>);
std::unique_ptr<Disassembler> disasm(Disassembler::Create(isa, opts));
std::stringstream stream; const uint8_t* base = actual_asm.data() + (isa == InstructionSet::kThumb2 ? 1 : 0);
disasm->Dump(stream, base, base + actual_asm.size());
ReformatAsm(&stream, &lines); // Print CFI and assembly interleaved.
std::stable_sort(lines.begin(), lines.end(), CompareByAddress); for (const std::string& line : lines) {
fprintf(f, "// %s\n", line.c_str());
}
fprintf(f, "\n");
}
private: // Helper - get offset just past the end of given string. static size_t FindEndOf(const std::string& str, constchar* substr) {
size_t pos = str.find(substr);
CHECK_NE(std::string::npos, pos); return pos + strlen(substr);
}
// Spit to lines and remove raw instruction bytes. staticvoid ReformatAsm(std::stringstream* stream,
std::vector<std::string>* output) {
std::string line; while (std::getline(*stream, line)) {
line = line.substr(0, FindEndOf(line, ": ")) +
line.substr(FindEndOf(line, "\t"));
size_t pos; while ((pos = line.find(" ")) != std::string::npos) {
line = line.replace(pos, 2, " ");
} while (!line.empty() && line.back() == ' ') {
line.pop_back();
}
output->push_back(line);
}
}
// Find interesting parts of objdump output and prefix the lines with address. staticvoid ReformatCfi(const std::vector<std::string>& lines,
std::vector<std::string>* output) {
uint32_t address = 0; for (const std::string& line : lines) { if (line.find("DW_CFA_nop") != std::string::npos) { // Ignore.
} elseif (line.find("DW_CFA_advance_loc") != std::string::npos) { // Example line: "DW_CFA_advance_loc: 4 to 0x28"
size_t pos = line.rfind("0x");
ASSERT_NE(std::string::npos, pos); bool success = android::base::ParseUint(line.substr(pos), &address);
ASSERT_TRUE(success);
} elseif (line.find("DW_CFA_") != std::string::npos) { // Use the .cfi_ prefix.
std::string new_line = ".cfi_" + line.substr(FindEndOf(line, "DW_CFA_"));
output->push_back(ART_FORMAT("0x{:08x}: {}", address, new_line));
}
}
}
// Pretty-print byte array. 12 bytes per line. staticvoid HexDump(FILE* f, ArrayRef<const uint8_t> data) { for (size_t i = 0; i < data.size(); i++) {
fprintf(f, i % 12 == 0 ? "\n " : " "); // Whitespace.
fprintf(f, "0x%02X,", data[i]);
}
}
};
} // namespace art
#endif// ART_COMPILER_CFI_TEST_H_
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.