[BPF] extend BTF_KIND_FUNC to cover global, static and extern funcs
Previously extern function is added as BTF_KIND_VAR. This does not work
well with existing BTF infrastructure as function expected to use
BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO.
This patch added extern function to BTF_KIND_FUNC. The two bits 0:1
of btf_type.info are used to indicate what kind of function it is:
0: static
1: global
2: extern
Differential Revision: https://reviews.llvm.org/D71638
diff --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h
index ee06176..ad3dcc1 100644
--- a/llvm/lib/Target/BPF/BTF.h
+++ b/llvm/lib/Target/BPF/BTF.h
@@ -176,6 +176,13 @@
uint32_t Type;
};
+/// BTF_KIND_FUNC can be global, static or extern.
+enum : uint8_t {
+ FUNC_STATIC = 0,
+ FUNC_GLOBAL = 1,
+ FUNC_EXTERN = 2,
+};
+
/// Variable scoping information.
enum : uint8_t {
VAR_STATIC = 0, ///< Linkage: InternalLinkage
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 86e625b..a9fb04f 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -308,10 +308,11 @@
}
}
-BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId)
+BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId,
+ uint32_t Scope)
: Name(FuncName) {
Kind = BTF::BTF_KIND_FUNC;
- BTFType.Info = Kind << 24;
+ BTFType.Info = (Kind << 24) | Scope;
BTFType.Type = ProtoTypeId;
}
@@ -897,8 +898,9 @@
visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
// Construct subprogram func type
+ uint8_t Scope = SP->isLocalToUnit() ? BTF::FUNC_STATIC : BTF::FUNC_GLOBAL;
auto FuncTypeEntry =
- std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId);
+ std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
for (const auto &TypeEntry : TypeEntries)
@@ -1012,6 +1014,12 @@
MI->getOpcode() == BPF::CORE_SHIFT) {
// relocation insn is a load, store or shift insn.
processReloc(MI->getOperand(3));
+ } else if (MI->getOpcode() == BPF::JAL) {
+ // check extern function references
+ const MachineOperand &MO = MI->getOperand(0);
+ if (MO.isGlobal()) {
+ processFuncPrototypes(dyn_cast<Function>(MO.getGlobal()));
+ }
}
// Skip this instruction if no DebugLoc or the DebugLoc
@@ -1162,32 +1170,27 @@
return false;
}
-void BTFDebug::processFuncPrototypes() {
- const Module *M = MMI->getModule();
- for (const Function &F : M->functions()) {
- const DISubprogram *SP = F.getSubprogram();
- if (!SP || SP->isDefinition())
- continue;
+void BTFDebug::processFuncPrototypes(const Function *F) {
+ if (!F)
+ return;
- uint32_t ProtoTypeId;
- const std::unordered_map<uint32_t, StringRef> FuncArgNames;
- visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
+ const DISubprogram *SP = F->getSubprogram();
+ if (!SP || SP->isDefinition())
+ return;
- auto VarEntry =
- std::make_unique<BTFKindVar>(SP->getName(), ProtoTypeId,
- BTF::VAR_GLOBAL_EXTERNAL);
- uint32_t VarId = addType(std::move(VarEntry));
+ // Do not emit again if already emitted.
+ if (ProtoFunctions.find(F) != ProtoFunctions.end())
+ return;
+ ProtoFunctions.insert(F);
- StringRef SecName = F.getSection();
- if (SecName.empty())
- SecName = ".extern";
+ uint32_t ProtoTypeId;
+ const std::unordered_map<uint32_t, StringRef> FuncArgNames;
+ visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
- if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
- DataSecEntries[SecName] = std::make_unique<BTFKindDataSec>(Asm, SecName);
- }
-
- DataSecEntries[SecName]->addVar(VarId, Asm->getSymbol(&F), 8);
- }
+ uint8_t Scope = BTF::FUNC_EXTERN;
+ auto FuncTypeEntry =
+ std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
+ addType(std::move(FuncTypeEntry));
}
void BTFDebug::endModule() {
@@ -1200,8 +1203,6 @@
// Collect global types/variables except MapDef globals.
processGlobals(false);
- processFuncPrototypes();
-
for (auto &DataSec : DataSecEntries)
addType(std::move(DataSec.second));
diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h
index da23ef0..0812c4f 100644
--- a/llvm/lib/Target/BPF/BTFDebug.h
+++ b/llvm/lib/Target/BPF/BTFDebug.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/DebugHandlerBase.h"
+#include <set>
#include <unordered_map>
#include "BTF.h"
@@ -151,7 +152,7 @@
StringRef Name;
public:
- BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
+ BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);
uint32_t getSize() { return BTFTypeBase::getSize(); }
void completeType(BTFDebug &BDebug);
void emitType(MCStreamer &OS);
@@ -251,6 +252,7 @@
std::map<std::string, uint32_t> PatchImms;
std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
FixupDerivedTypes;
+ std::set<const Function *>ProtoFunctions;
/// Add types to TypeEntries.
/// @{
@@ -294,7 +296,7 @@
void processGlobals(bool ProcessingMapDef);
/// Generate types for function prototypes.
- void processFuncPrototypes();
+ void processFuncPrototypes(const Function *);
/// Generate one field relocation record.
void generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy,