diff options
author | Eduard Zingerman <eddyz87@gmail.com> | 2023-05-07 23:59:24 +0300 |
---|---|---|
committer | Eduard Zingerman <eddyz87@gmail.com> | 2023-09-21 21:59:10 +0300 |
commit | d15f96fe4b64e24d262fcc727dc0eede327804ba (patch) | |
tree | 8d45e939a6e69d27de9e7ccfd1fa94cea8af4655 /llvm/lib/Target/BPF | |
parent | 4dec62f4d4a0a496a8067e283bf66897fbf6e598 (diff) | |
download | llvm-d15f96fe4b64e24d262fcc727dc0eede327804ba.zip llvm-d15f96fe4b64e24d262fcc727dc0eede327804ba.tar.gz llvm-d15f96fe4b64e24d262fcc727dc0eede327804ba.tar.bz2 |
[BPF][DebugInfo] Show CO-RE relocations in llvm-objdump
Extend llvm-objdump to show CO-RE relocations when `-r` option is
passed and object file has .BTF and .BTF.ext sections.
For example, the following C program:
#define __pai __attribute__((preserve_access_index))
struct foo { int i; int j;} __pai;
struct bar { struct foo f[7]; } __pai;
extern void sink(void *);
void root(struct bar *bar) {
sink(&bar[2].f[3].j);
}
Should lead to the following objdump output:
$ clang --target=bpf -O2 -g t.c -c -o - | \
llvm-objdump --no-addresses --no-show-raw-insn -dr -
...
r2 = 0x94
CO-RE <byte_off> [2] struct bar::[2].f[3].j (2:0:3:1)
r1 += r2
call -0x1
R_BPF_64_32 sink
exit
...
More examples could be found in unit tests, see BTFParserTest.cpp.
To achieve this:
- Move CO-RE relocation kinds definitions from BPFCORE.h to BTF.h.
- Extend BTF.h with types derived from BTF::CommonType, e.g.
BTF::IntType and BTF::StrutType, to allow dyn_cast() and access to
type additional data.
- Extend BTFParser to load BTF type and relocation data.
- Modify llvm-objdump.cpp to create instance of BTFParser when
disassembly of object file with BTF sections is processed and `-r`
flag is supplied.
Additional information about CO-RE is available at [1].
[1] https://docs.kernel.org/bpf/llvm_reloc.html
Depends on D149058
Differential Revision: https://reviews.llvm.org/D150079
Diffstat (limited to 'llvm/lib/Target/BPF')
-rw-r--r-- | llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp | 39 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BPFCORE.h | 18 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BPFPreserveDIType.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/BPF/BTFDebug.cpp | 6 |
4 files changed, 25 insertions, 43 deletions
diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp index 9c99765..a878eaa 100644 --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -78,6 +78,7 @@ #include "BPFCORE.h" #include "BPFTargetMachine.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/BTF/BTF.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instruction.h" @@ -369,7 +370,7 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, CInfo.Metadata = nullptr; // Check validity of info_kind as clang did not check this. uint64_t InfoKind = getConstant(Call->getArgOperand(1)); - if (InfoKind >= BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND) + if (InfoKind >= BTF::MAX_FIELD_RELOC_KIND) report_fatal_error("Incorrect info_kind for llvm.bpf.preserve.field.info intrinsic"); CInfo.AccessIndex = InfoKind; return true; @@ -383,11 +384,11 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_TYPE_INFO_FLAG) report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic"); if (Flag == BPFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE) - CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_EXISTENCE; + CInfo.AccessIndex = BTF::TYPE_EXISTENCE; else if (Flag == BPFCoreSharedInfo::PRESERVE_TYPE_INFO_MATCH) - CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_MATCH; + CInfo.AccessIndex = BTF::TYPE_MATCH; else - CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_SIZE; + CInfo.AccessIndex = BTF::TYPE_SIZE; return true; } if (GV->getName().startswith("llvm.bpf.preserve.enum.value")) { @@ -399,9 +400,9 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_ENUM_VALUE_FLAG) report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic"); if (Flag == BPFCoreSharedInfo::PRESERVE_ENUM_VALUE_EXISTENCE) - CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE; + CInfo.AccessIndex = BTF::ENUM_VALUE_EXISTENCE; else - CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE; + CInfo.AccessIndex = BTF::ENUM_VALUE; return true; } @@ -672,11 +673,11 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, uint32_t AccessIndex, uint32_t PatchImm, MaybeAlign RecordAlignment) { - if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE) - return 1; + if (InfoKind == BTF::FIELD_EXISTENCE) + return 1; uint32_t Tag = CTy->getTag(); - if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_OFFSET) { + if (InfoKind == BTF::FIELD_BYTE_OFFSET) { if (Tag == dwarf::DW_TAG_array_type) { auto *EltTy = stripQualifiers(CTy->getBaseType()); PatchImm += AccessIndex * calcArraySize(CTy, 1) * @@ -695,7 +696,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, return PatchImm; } - if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_SIZE) { + if (InfoKind == BTF::FIELD_BYTE_SIZE) { if (Tag == dwarf::DW_TAG_array_type) { auto *EltTy = stripQualifiers(CTy->getBaseType()); return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3); @@ -715,7 +716,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, } } - if (InfoKind == BPFCoreSharedInfo::FIELD_SIGNEDNESS) { + if (InfoKind == BTF::FIELD_SIGNEDNESS) { const DIType *BaseTy; if (Tag == dwarf::DW_TAG_array_type) { // Signedness only checked when final array elements are accessed. @@ -741,7 +742,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char); } - if (InfoKind == BPFCoreSharedInfo::FIELD_LSHIFT_U64) { + if (InfoKind == BTF::FIELD_LSHIFT_U64) { // The value is loaded into a value with FIELD_BYTE_SIZE size, // and then zero or sign extended to U64. // FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are operations @@ -778,7 +779,7 @@ uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind, return OffsetInBits + 64 - NextSBitOffset; } - if (InfoKind == BPFCoreSharedInfo::FIELD_RSHIFT_U64) { + if (InfoKind == BTF::FIELD_RSHIFT_U64) { DIDerivedType *MemberTy = nullptr; bool IsBitField = false; uint32_t SizeInBits; @@ -849,7 +850,7 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, // we will skip them. uint32_t FirstIndex = 0; uint32_t PatchImm = 0; // AccessOffset or the requested field info - uint32_t InfoKind = BPFCoreSharedInfo::FIELD_BYTE_OFFSET; + uint32_t InfoKind = BTF::FIELD_BYTE_OFFSET; while (CallStack.size()) { auto StackElem = CallStack.top(); Call = StackElem.first; @@ -939,7 +940,7 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, if (CInfo.Kind == BPFPreserveFieldInfoAI) { InfoKind = CInfo.AccessIndex; - if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE) + if (InfoKind == BTF::FIELD_EXISTENCE) PatchImm = 1; break; } @@ -987,10 +988,10 @@ MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call, int64_t PatchImm; std::string AccessStr("0"); - if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_EXISTENCE || - CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_MATCH) { + if (CInfo.AccessIndex == BTF::TYPE_EXISTENCE || + CInfo.AccessIndex == BTF::TYPE_MATCH) { PatchImm = 1; - } else if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_SIZE) { + } else if (CInfo.AccessIndex == BTF::TYPE_SIZE) { // typedef debuginfo type has size 0, get the eventual base type. DIType *BaseTy = stripQualifiers(Ty, true); PatchImm = BaseTy->getSizeInBits() / 8; @@ -1026,7 +1027,7 @@ MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call, EnumIndex++; } - if (CInfo.AccessIndex == BPFCoreSharedInfo::ENUM_VALUE) { + if (CInfo.AccessIndex == BTF::ENUM_VALUE) { StringRef EValueStr = ValueStr.substr(Separator + 1); PatchImm = std::stoll(std::string(EValueStr)); } else { diff --git a/llvm/lib/Target/BPF/BPFCORE.h b/llvm/lib/Target/BPF/BPFCORE.h index c9aa135..9a547a7 100644 --- a/llvm/lib/Target/BPF/BPFCORE.h +++ b/llvm/lib/Target/BPF/BPFCORE.h @@ -19,24 +19,6 @@ class Module; class BPFCoreSharedInfo { public: - enum PatchableRelocKind : uint32_t { - FIELD_BYTE_OFFSET = 0, - FIELD_BYTE_SIZE, - FIELD_EXISTENCE, - FIELD_SIGNEDNESS, - FIELD_LSHIFT_U64, - FIELD_RSHIFT_U64, - BTF_TYPE_ID_LOCAL, - BTF_TYPE_ID_REMOTE, - TYPE_EXISTENCE, - TYPE_SIZE, - ENUM_VALUE_EXISTENCE, - ENUM_VALUE, - TYPE_MATCH, - - MAX_FIELD_RELOC_KIND, - }; - enum BTFTypeIdFlag : uint32_t { BTF_TYPE_ID_LOCAL_RELOC = 0, BTF_TYPE_ID_REMOTE_RELOC, diff --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp index ec770ee..78e1bf9 100644 --- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp +++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp @@ -13,6 +13,7 @@ #include "BPF.h" #include "BPFCORE.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/BTF/BTF.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instruction.h" @@ -82,9 +83,9 @@ static bool BPFPreserveDITypeImpl(Function &F) { uint32_t Reloc; if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC) { - Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL; + Reloc = BTF::BTF_TYPE_ID_LOCAL; } else { - Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE; + Reloc = BTF::BTF_TYPE_ID_REMOTE; DIType *Ty = cast<DIType>(MD); while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) { unsigned Tag = DTy->getTag(); diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index 2fe4206..f91ce7f 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1518,10 +1518,8 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) { return false; } - if (Reloc == BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE || - Reloc == BPFCoreSharedInfo::ENUM_VALUE || - Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL || - Reloc == BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE) + if (Reloc == BTF::ENUM_VALUE_EXISTENCE || Reloc == BTF::ENUM_VALUE || + Reloc == BTF::BTF_TYPE_ID_LOCAL || Reloc == BTF::BTF_TYPE_ID_REMOTE) OutMI.setOpcode(BPF::LD_imm64); else OutMI.setOpcode(BPF::MOV_ri); |