diff options
Diffstat (limited to 'llvm/lib/MC/MCBTFContext.cpp')
-rw-r--r-- | llvm/lib/MC/MCBTFContext.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCBTFContext.cpp b/llvm/lib/MC/MCBTFContext.cpp new file mode 100644 index 00000000000..cb846ee5e51 --- /dev/null +++ b/llvm/lib/MC/MCBTFContext.cpp @@ -0,0 +1,235 @@ +//===- lib/MC/MCBTFContext.cpp - Machine Code BTF Context -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCBTFContext.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/raw_ostream.h" +#include <cstdlib> +#include <tuple> +#include <utility> + +using namespace llvm; + +#define DEBUG_TYPE "btf" + +void MCBTFContext::addTypeEntry(std::unique_ptr<BTFTypeEntry> Entry) { + TypeEntries.push_back(std::move(Entry)); +} + +void MCBTFContext::dump(raw_ostream &OS) { + OS << "Type Table:\n"; + for (size_t i = 0; i < TypeEntries.size(); i++) { + auto TypeEntry = TypeEntries[i].get(); + TypeEntry->print(OS, *this); + } + + OS << "\nString Table:\n"; + StringTable.showTable(OS); + + OS << "\nFuncInfo Table:\n"; + for (auto &FuncSec : FuncInfoTable) { + OS << "sec_name_off=" << FuncSec.first << "\n"; + for (auto &FuncInfo : FuncSec.second) { + OS << "\tinsn_offset=<Omitted> type_id=" + << FuncInfo.TypeId << "\n"; + } + } + + OS << "\nLineInfo Table:\n"; + for (auto &LineSec : LineInfoTable) { + OS << "sec_name_off=" << LineSec.first << "\n"; + for (auto &LineInfo : LineSec.second) { + OS << "\tinsn_offset=<Omitted> file_name_off=" + << LineInfo.FileNameOff + << " line_off=" << LineInfo.LineOff + << " line_num=" << LineInfo.LineNum + << " column_num=" << LineInfo.ColumnNum + << "\n"; + } + } +} + +void MCBTFContext::emitCommonHeader(MCObjectStreamer *MCOS) { + MCOS->EmitIntValue(BTF_MAGIC, 2); + MCOS->EmitIntValue(BTF_VERSION, 1); + MCOS->EmitIntValue(0, 1); +} + +void MCBTFContext::emitBTFSection(MCObjectStreamer *MCOS) { + MCContext &context = MCOS->getContext(); + MCOS->SwitchSection(context.getObjectFileInfo()->getBTFSection()); + + // emit header + emitCommonHeader(MCOS); + MCOS->EmitIntValue(sizeof(struct btf_header), 4); + + uint32_t type_len = 0, str_len; + for (auto &TypeEntry : TypeEntries) + type_len += TypeEntry->getSize(); + str_len = StringTable.getSize(); + + MCOS->EmitIntValue(0, 4); + MCOS->EmitIntValue(type_len, 4); + MCOS->EmitIntValue(type_len, 4); + MCOS->EmitIntValue(str_len, 4); + + // emit type table + for (auto &TypeEntry: TypeEntries) + TypeEntry->emitData(MCOS); + + // emit string table + for (auto &S : StringTable.getTable()) { + for (auto C : S) + MCOS->EmitIntValue(C, 1); + MCOS->EmitIntValue('\0', 1); + } +} + +void MCBTFContext::emitBTFExtSection(MCObjectStreamer *MCOS) { + MCContext &context = MCOS->getContext(); + MCOS->SwitchSection(context.getObjectFileInfo()->getBTFExtSection()); + + // emit header + emitCommonHeader(MCOS); + MCOS->EmitIntValue(sizeof(struct btf_ext_header), 4); + + uint32_t func_len = 0, line_len = 0; + for (auto &FuncSec : FuncInfoTable) { + func_len += sizeof(struct btf_sec_func_info); + func_len += FuncSec.second.size() * sizeof(struct bpf_func_info); + } + for (auto &LineSec : LineInfoTable) { + line_len += sizeof(struct btf_sec_line_info); + line_len += LineSec.second.size() * sizeof(struct bpf_line_info); + } + + MCOS->EmitIntValue(0, 4); + MCOS->EmitIntValue(func_len, 4); + MCOS->EmitIntValue(func_len, 4); + MCOS->EmitIntValue(line_len, 4); + + // emit func_info table + for (const auto &FuncSec : FuncInfoTable) { + MCOS->EmitIntValue(FuncSec.first, 4); + MCOS->EmitIntValue(FuncSec.second.size(), 4); + for (const auto &FuncInfo : FuncSec.second) { + MCOS->EmitBTFAdvanceLineAddr(FuncInfo.Label, 4); + MCOS->EmitIntValue(FuncInfo.TypeId, 4); + } + } + + // emit line_info table + for (const auto &LineSec : LineInfoTable) { + MCOS->EmitIntValue(LineSec.first, 4); + MCOS->EmitIntValue(LineSec.second.size(), 4); + for (const auto &LineInfo : LineSec.second) { + MCOS->EmitBTFAdvanceLineAddr(LineInfo.Label, 4); + MCOS->EmitIntValue(LineInfo.FileNameOff, 4); + MCOS->EmitIntValue(LineInfo.LineOff, 4); + MCOS->EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4); + } + } +} + +void MCBTFContext::emitAll(MCObjectStreamer *MCOS) { + LLVM_DEBUG(dump(dbgs())); + emitBTFSection(MCOS); + emitBTFExtSection(MCOS); +} + +void BTFTypeEntry::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + OS << "[" << Id << "] " + << btf_kind_str[BTF_INFO_KIND(BTFType.info)] + << " name_off=" << BTFType.name_off + << " info=" << format("0x%08lx", BTFType.info) + << " size/type=" << BTFType.size << "\n"; +} + +void BTFTypeEntry::emitData(MCObjectStreamer *MCOS) { + MCOS->EmitIntValue(BTFType.name_off, 4); + MCOS->EmitIntValue(BTFType.info, 4); + MCOS->EmitIntValue(BTFType.size, 4); +} + +void BTFTypeEntryInt::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + BTFTypeEntry::print(OS, MCBTFContext); + OS << "\tdesc=" << format("0x%08lx", IntVal) << "\n"; +} + +void BTFTypeEntryInt::emitData(MCObjectStreamer *MCOS) { + BTFTypeEntry::emitData(MCOS); + MCOS->EmitIntValue(IntVal, 4); +} + +void BTFTypeEntryEnum::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + BTFTypeEntry::print(OS, MCBTFContext); + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) { + auto &EnumValue = EnumValues[i]; + OS << "\tname_off=" << EnumValue.name_off + << " value=" << EnumValue.val << "\n"; + } +} + +void BTFTypeEntryEnum::emitData(MCObjectStreamer *MCOS) { + BTFTypeEntry::emitData(MCOS); + for (auto &EnumValue : EnumValues) { + MCOS->EmitIntValue(EnumValue.name_off, 4); + MCOS->EmitIntValue(EnumValue.val, 4); + } +} + +void BTFTypeEntryArray::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + BTFTypeEntry::print(OS, MCBTFContext); + OS << "\telem_type=" << format("0x%08lx", ArrayInfo.type) + << " index_type=" << format("0x%08lx", ArrayInfo.index_type) + << " num_element=" << ArrayInfo.nelems << "\n"; +} + +void BTFTypeEntryArray::emitData(MCObjectStreamer *MCOS) { + BTFTypeEntry::emitData(MCOS); + MCOS->EmitIntValue(ArrayInfo.type, 4); + MCOS->EmitIntValue(ArrayInfo.index_type, 4); + MCOS->EmitIntValue(ArrayInfo.nelems, 4); +} + +void BTFTypeEntryStruct::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + BTFTypeEntry::print(OS, MCBTFContext); + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) { + auto &Member = Members[i]; + OS << "\tname_off=" << Member.name_off + << " type=" << Member.type + << " bit_offset=" << Member.offset << "\n"; + } +} + +void BTFTypeEntryStruct::emitData(MCObjectStreamer *MCOS) { + BTFTypeEntry::emitData(MCOS); + for (auto &Member : Members) { + MCOS->EmitIntValue(Member.name_off, 4); + MCOS->EmitIntValue(Member.type, 4); + MCOS->EmitIntValue(Member.offset, 4); + } +} + +void BTFTypeEntryFunc::print(raw_ostream &OS, MCBTFContext& MCBTFContext) { + BTFTypeEntry::print(OS, MCBTFContext); + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) { + auto Parameter = Parameters[i]; + OS << "\tparam_type=" << Parameter << "\n"; + } +} + +void BTFTypeEntryFunc::emitData(MCObjectStreamer *MCOS) { + BTFTypeEntry::emitData(MCOS); + for (auto &Parameter: Parameters) + MCOS->EmitIntValue(Parameter, 4); +} |