summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/BPF
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2019-11-22 08:45:37 -0800
committerYonghong Song <yhs@fb.com>2019-12-09 21:53:29 -0800
commit4448125007712d78fd114997a6fffc44b61b131d (patch)
tree4467d6962c540413ae782a429eb6a25aa9b5525e /llvm/lib/Target/BPF
parentcefac9dfaac9c806433ad88cca85bd2f3ba1edad (diff)
downloadbcm5719-llvm-4448125007712d78fd114997a6fffc44b61b131d.tar.gz
bcm5719-llvm-4448125007712d78fd114997a6fffc44b61b131d.zip
[BPF] Support to emit debugInfo for extern variables
extern variable usage in BPF is different from traditional pure user space application. Recent discussion in linux bpf mailing list has two use cases where debug info types are required to use extern variables: - extern types are required to have a suitable interface in libbpf (bpf loader) to provide kernel config parameters to bpf programs. https://lore.kernel.org/bpf/CAEf4BzYCNo5GeVGMhp3fhysQ=_axAf=23PtwaZs-yAyafmXC9g@mail.gmail.com/T/#t - extern types are required so kernel bpf verifier can verify program which uses external functions more precisely. This will make later link with actual external function no need to reverify. https://lore.kernel.org/bpf/87eez4odqp.fsf@toke.dk/T/#m8d5c3e87ffe7f2764e02d722cb0d8cbc136880ed This patch added bpf support to consume such info into BTF, which can then be used by bpf loader. Function processFuncPrototypes() only adds extern function definitions into BTF. The functions with actual definition have been added to BTF in some other places. Differential Revision: https://reviews.llvm.org/D70697
Diffstat (limited to 'llvm/lib/Target/BPF')
-rw-r--r--llvm/lib/Target/BPF/BTF.h1
-rw-r--r--llvm/lib/Target/BPF/BTFDebug.cpp65
-rw-r--r--llvm/lib/Target/BPF/BTFDebug.h3
3 files changed, 54 insertions, 15 deletions
diff --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h
index 9f1a9f915b5..ee06176a881 100644
--- a/llvm/lib/Target/BPF/BTF.h
+++ b/llvm/lib/Target/BPF/BTF.h
@@ -180,6 +180,7 @@ struct BTFParam {
enum : uint8_t {
VAR_STATIC = 0, ///< Linkage: InternalLinkage
VAR_GLOBAL_ALLOCATED = 1, ///< Linkage: ExternalLinkage
+ VAR_GLOBAL_EXTERNAL = 2, ///< Linkage: ExternalLinkage
};
/// BTF_KIND_DATASEC are followed by multiple "struct BTFDataSecVar".
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 51a6142ece2..9dce734ea08 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -1055,15 +1055,11 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
// Collect all types referenced by globals.
const Module *M = MMI->getModule();
for (const GlobalVariable &Global : M->globals()) {
- // Ignore external globals for now.
- if (!Global.hasInitializer() && Global.hasExternalLinkage())
- continue;
-
// Decide the section name.
StringRef SecName;
if (Global.hasSection()) {
SecName = Global.getSection();
- } else {
+ } else if (Global.hasInitializer()) {
// data, bss, or readonly sections
if (Global.isConstant())
SecName = ".rodata";
@@ -1093,25 +1089,33 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
// Only support the following globals:
// . static variables
// . non-static weak or non-weak global variables
- // Essentially means:
- // . .bcc/.data/.rodata DataSec entities only contain static data
- // . Other DataSec entities contain static or initialized global data.
- // Initialized global data are mostly used for finding map key/value type
- // id's. Whether DataSec is readonly or not can be found from
- // corresponding ELF section flags.
+ // . weak or non-weak extern global variables
+ // Whether DataSec is readonly or not can be found from corresponding ELF
+ // section flags. Whether a BTF_KIND_VAR is a weak symbol or not
+ // can be found from the corresponding ELF symbol table.
auto Linkage = Global.getLinkage();
if (Linkage != GlobalValue::InternalLinkage &&
Linkage != GlobalValue::ExternalLinkage &&
- Linkage != GlobalValue::WeakAnyLinkage)
+ Linkage != GlobalValue::WeakAnyLinkage &&
+ Linkage != GlobalValue::ExternalWeakLinkage)
continue;
- uint32_t GVarInfo = Linkage == GlobalValue::InternalLinkage
- ? BTF::VAR_STATIC
- : BTF::VAR_GLOBAL_ALLOCATED;
+ uint32_t GVarInfo;
+ if (Linkage == GlobalValue::InternalLinkage) {
+ GVarInfo = BTF::VAR_STATIC;
+ } else if (Global.hasInitializer()) {
+ GVarInfo = BTF::VAR_GLOBAL_ALLOCATED;
+ } else {
+ GVarInfo = BTF::VAR_GLOBAL_EXTERNAL;
+ }
+
auto VarEntry =
std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
uint32_t VarId = addType(std::move(VarEntry));
+ if (SecName.empty())
+ continue;
+
// Find or create a DataSec
if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
DataSecEntries[SecName] = std::make_unique<BTFKindDataSec>(Asm, SecName);
@@ -1145,6 +1149,34 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
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;
+
+ uint32_t ProtoTypeId;
+ const std::unordered_map<uint32_t, StringRef> FuncArgNames;
+ visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
+
+ auto VarEntry =
+ std::make_unique<BTFKindVar>(SP->getName(), ProtoTypeId,
+ BTF::VAR_GLOBAL_EXTERNAL);
+ uint32_t VarId = addType(std::move(VarEntry));
+
+ StringRef SecName = F.getSection();
+ if (SecName.empty())
+ continue;
+
+ if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
+ DataSecEntries[SecName] = std::make_unique<BTFKindDataSec>(Asm, SecName);
+ }
+
+ DataSecEntries[SecName]->addVar(VarId, Asm->getSymbol(&F), 8);
+ }
+}
+
void BTFDebug::endModule() {
// Collect MapDef globals if not collected yet.
if (MapDefNotCollected) {
@@ -1154,6 +1186,9 @@ void BTFDebug::endModule() {
// 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 c01e0d1d161..c0d3f36fa8b 100644
--- a/llvm/lib/Target/BPF/BTFDebug.h
+++ b/llvm/lib/Target/BPF/BTFDebug.h
@@ -293,6 +293,9 @@ class BTFDebug : public DebugHandlerBase {
/// Generate types and variables for globals.
void processGlobals(bool ProcessingMapDef);
+ /// Generate types for function prototypes.
+ void processFuncPrototypes();
+
/// Generate one offset relocation record.
void generateFieldReloc(const MachineInstr *MI, const MCSymbol *ORSym,
DIType *RootTy, StringRef AccessPattern);
OpenPOWER on IntegriCloud