diff --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h --- a/llvm/lib/Target/BPF/BTF.h +++ b/llvm/lib/Target/BPF/BTF.h @@ -180,8 +180,8 @@ enum : uint8_t { VAR_STATIC = 0, ///< Linkage: InternalLinkage VAR_GLOBAL_ALLOCATED = 1, ///< Linkage: ExternalLinkage - VAR_GLOBAL_TENTATIVE = 2, ///< Linkage: CommonLinkage - VAR_GLOBAL_EXTERNAL = 3, ///< Linkage: ExternalLinkage + VAR_GLOBAL_EXTERNAL = 2, ///< Linkage: ExternalLinkage + VAR_GLOBAL_TENTATIVE = 3, ///< Linkage: CommonLinkage }; /// 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 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1055,20 +1055,40 @@ // 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; + // Support all globals: + // . static: VAR_STATIC, in DataSec. + // . initialized global (0 or non-0): VAR_GLOBAL_ALLOCATED, in DataSec. + // . external global: VAR_GLOBAL_EXTERNAL, not in DataSec. + // . common global: VAR_GLOBAL_TENTATIVE, not in DataSec. + // Whether DataSec is readonly or not can be found from the + // corresponding ELF section flags. // Decide the section name. + // CommonLinkage variables do not have section names, and we + // don't want to put them into .bss/.data/.rodata sections. StringRef SecName; - if (Global.hasSection()) { - SecName = Global.getSection(); - } else { - // data, bss, or readonly sections - if (Global.isConstant()) - SecName = ".rodata"; + uint32_t GVarInfo; + auto Linkage = Global.getLinkage(); + if (Global.hasInitializer() && Linkage != GlobalValue::CommonLinkage) { + if (Global.hasSection()) { + SecName = Global.getSection(); + } else { + // data, bss, or readonly sections + if (Global.isConstant()) + SecName = ".rodata"; + else + SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data"; + } + if (Linkage == GlobalValue::InternalLinkage) + GVarInfo = BTF::VAR_STATIC; else - SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data"; + GVarInfo = BTF::VAR_GLOBAL_ALLOCATED; + } else if (Linkage == GlobalValue::CommonLinkage) { + GVarInfo = BTF::VAR_GLOBAL_TENTATIVE; + } else { + // External variables. + GVarInfo = BTF::VAR_GLOBAL_EXTERNAL; + SecName = Global.getSection(); } if (ProcessingMapDef != SecName.startswith(".maps")) @@ -1085,27 +1105,13 @@ break; } - // Only support the following globals: - // . static variables - // . non-static global variables with section attributes - // 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. - auto Linkage = Global.getLinkage(); - if (Linkage != GlobalValue::InternalLinkage && - (Linkage != GlobalValue::ExternalLinkage || !Global.hasSection())) - continue; - - uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage - ? BTF::VAR_GLOBAL_ALLOCATED - : BTF::VAR_STATIC; auto VarEntry = std::make_unique(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(Asm, SecName);