2018-12-20 00:40:25 +08:00
|
|
|
//===- BTFDebug.h -----------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2018-12-20 00:40:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
|
|
|
/// This file contains support for writing BTF debug info.
|
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H
|
|
|
|
#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H
|
|
|
|
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/CodeGen/DebugHandlerBase.h"
|
|
|
|
#include <unordered_map>
|
|
|
|
#include "BTF.h"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
class AsmPrinter;
|
|
|
|
class BTFDebug;
|
|
|
|
class DIType;
|
|
|
|
class MCStreamer;
|
|
|
|
class MCSymbol;
|
|
|
|
class MachineFunction;
|
|
|
|
|
|
|
|
/// The base class for BTF type generation.
|
|
|
|
class BTFTypeBase {
|
|
|
|
protected:
|
|
|
|
uint8_t Kind;
|
|
|
|
uint32_t Id;
|
|
|
|
struct BTF::CommonType BTFType;
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~BTFTypeBase() = default;
|
|
|
|
void setId(uint32_t Id) { this->Id = Id; }
|
|
|
|
uint32_t getId() { return Id; }
|
|
|
|
uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
|
|
|
|
/// Get the size of this BTF type entry.
|
|
|
|
virtual uint32_t getSize() { return BTF::CommonTypeSize; }
|
|
|
|
/// Complete BTF type generation after all related DebugInfo types
|
|
|
|
/// have been visited so their BTF type id's are available
|
|
|
|
/// for cross referece.
|
|
|
|
virtual void completeType(BTFDebug &BDebug) {}
|
|
|
|
/// Emit types for this BTF type entry.
|
|
|
|
virtual void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle several derived types include pointer, const,
|
|
|
|
/// volatile, typedef and restrict.
|
|
|
|
class BTFTypeDerived : public BTFTypeBase {
|
|
|
|
const DIDerivedType *DTy;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag);
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle struct or union forward declaration.
|
|
|
|
class BTFTypeFwd : public BTFTypeBase {
|
|
|
|
StringRef Name;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeFwd(StringRef Name, bool IsUnion);
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle int type.
|
|
|
|
class BTFTypeInt : public BTFTypeBase {
|
|
|
|
StringRef Name;
|
|
|
|
uint32_t IntVal; ///< Encoding, offset, bits
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
|
|
|
|
StringRef TypeName);
|
|
|
|
uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle enumerate type.
|
|
|
|
class BTFTypeEnum : public BTFTypeBase {
|
|
|
|
const DICompositeType *ETy;
|
|
|
|
std::vector<struct BTF::BTFEnum> EnumValues;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues);
|
|
|
|
uint32_t getSize() {
|
|
|
|
return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
|
|
|
|
}
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle array type.
|
|
|
|
class BTFTypeArray : public BTFTypeBase {
|
|
|
|
struct BTF::BTFArray ArrayInfo;
|
|
|
|
|
|
|
|
public:
|
2019-03-29 05:59:49 +08:00
|
|
|
BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
|
2018-12-20 00:40:25 +08:00
|
|
|
uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle struct/union type.
|
|
|
|
class BTFTypeStruct : public BTFTypeBase {
|
|
|
|
const DICompositeType *STy;
|
|
|
|
bool HasBitField;
|
|
|
|
std::vector<struct BTF::BTFMember> Members;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
|
|
|
|
uint32_t NumMembers);
|
|
|
|
uint32_t getSize() {
|
|
|
|
return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
|
|
|
|
}
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle function pointer.
|
|
|
|
class BTFTypeFuncProto : public BTFTypeBase {
|
|
|
|
const DISubroutineType *STy;
|
|
|
|
std::unordered_map<uint32_t, StringRef> FuncArgNames;
|
|
|
|
std::vector<struct BTF::BTFParam> Parameters;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
|
|
|
|
const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
|
|
|
|
uint32_t getSize() {
|
|
|
|
return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
|
|
|
|
}
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle subprogram
|
|
|
|
class BTFTypeFunc : public BTFTypeBase {
|
|
|
|
StringRef Name;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
|
|
|
|
uint32_t getSize() { return BTFTypeBase::getSize(); }
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
/// Handle variable instances
|
|
|
|
class BTFKindVar : public BTFTypeBase {
|
|
|
|
StringRef Name;
|
|
|
|
uint32_t Info;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
|
|
|
|
uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Handle data sections
|
|
|
|
class BTFKindDataSec : public BTFTypeBase {
|
|
|
|
AsmPrinter *Asm;
|
|
|
|
std::string Name;
|
|
|
|
std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
|
|
|
|
uint32_t getSize() {
|
|
|
|
return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
|
|
|
|
}
|
|
|
|
void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
|
|
|
|
Vars.push_back(std::make_tuple(Id, Sym, Size));
|
|
|
|
}
|
|
|
|
std::string getName() { return Name; }
|
|
|
|
void completeType(BTFDebug &BDebug);
|
|
|
|
void emitType(MCStreamer &OS);
|
|
|
|
};
|
|
|
|
|
2018-12-20 00:40:25 +08:00
|
|
|
/// String table.
|
|
|
|
class BTFStringTable {
|
|
|
|
/// String table size in bytes.
|
|
|
|
uint32_t Size;
|
|
|
|
/// A mapping from string table offset to the index
|
|
|
|
/// of the Table. It is used to avoid putting
|
|
|
|
/// duplicated strings in the table.
|
|
|
|
std::unordered_map<uint32_t, uint32_t> OffsetToIdMap;
|
|
|
|
/// A vector of strings to represent the string table.
|
|
|
|
std::vector<std::string> Table;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFStringTable() : Size(0) {}
|
|
|
|
uint32_t getSize() { return Size; }
|
|
|
|
std::vector<std::string> &getTable() { return Table; }
|
|
|
|
/// Add a string to the string table and returns its offset
|
|
|
|
/// in the table.
|
|
|
|
uint32_t addString(StringRef S);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Represent one func and its type id.
|
|
|
|
struct BTFFuncInfo {
|
|
|
|
const MCSymbol *Label; ///< Func MCSymbol
|
|
|
|
uint32_t TypeId; ///< Type id referring to .BTF type section
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Represent one line info.
|
|
|
|
struct BTFLineInfo {
|
|
|
|
MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo
|
|
|
|
uint32_t FileNameOff; ///< file name offset in the .BTF string table
|
|
|
|
uint32_t LineOff; ///< line offset in the .BTF string table
|
|
|
|
uint32_t LineNum; ///< the line number
|
|
|
|
uint32_t ColumnNum; ///< the column number
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Collect and emit BTF information.
|
|
|
|
class BTFDebug : public DebugHandlerBase {
|
|
|
|
MCStreamer &OS;
|
|
|
|
bool SkipInstruction;
|
|
|
|
bool LineInfoGenerated;
|
|
|
|
uint32_t SecNameOff;
|
|
|
|
uint32_t ArrayIndexTypeId;
|
|
|
|
BTFStringTable StringTable;
|
|
|
|
std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
|
|
|
|
std::unordered_map<const DIType *, uint32_t> DIToIdMap;
|
2019-03-27 23:45:27 +08:00
|
|
|
std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
|
|
|
|
std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
|
2018-12-20 00:40:25 +08:00
|
|
|
StringMap<std::vector<std::string>> FileContent;
|
2019-03-27 23:45:27 +08:00
|
|
|
std::map<std::string, std::unique_ptr<BTFKindDataSec>>
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
DataSecEntries;
|
2018-12-20 00:40:25 +08:00
|
|
|
|
|
|
|
/// Add types to TypeEntries.
|
|
|
|
/// @{
|
|
|
|
/// Add types to TypeEntries and DIToIdMap.
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
|
2018-12-20 00:40:25 +08:00
|
|
|
/// Add types to TypeEntries only and return type id.
|
|
|
|
uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
|
|
|
|
/// @}
|
|
|
|
|
|
|
|
/// IR type visiting functions.
|
|
|
|
/// @{
|
|
|
|
void visitTypeEntry(const DIType *Ty);
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
void visitTypeEntry(const DIType *Ty, uint32_t &TypeId);
|
|
|
|
void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
|
2018-12-20 00:40:25 +08:00
|
|
|
void visitSubroutineType(
|
|
|
|
const DISubroutineType *STy, bool ForSubprog,
|
|
|
|
const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
|
|
|
|
uint32_t &TypeId);
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
|
|
|
|
uint32_t &TypeId);
|
|
|
|
void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
|
|
|
|
void visitStructType(const DICompositeType *STy, bool IsStruct,
|
|
|
|
uint32_t &TypeId);
|
|
|
|
void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
|
|
|
|
void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
|
|
|
|
void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId);
|
2018-12-20 00:40:25 +08:00
|
|
|
/// @}
|
|
|
|
|
|
|
|
/// Get the file content for the subprogram. Certain lines of the file
|
|
|
|
/// later may be put into string table and referenced by line info.
|
|
|
|
std::string populateFileContent(const DISubprogram *SP);
|
|
|
|
|
|
|
|
/// Construct a line info.
|
|
|
|
void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
|
|
|
|
uint32_t Column);
|
|
|
|
|
[BPF] Add BTF Var and DataSec Support
Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added.
BTF_KIND_VAR has the following specification:
btf_type.name: var name
btf_type.info: type kind
btf_type.type: var type
// btf_type is followed by one u32
u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections)
Not all globals are supported in this patch. The following globals are supported:
. static variables with or without section attributes
. global variables with section attributes
The inclusion of globals with section attributes
is for future potential extraction of key/value
type id's from map definition.
BTF_KIND_DATASEC has the following specification:
btf_type.name: section name associated with variable or
one of .data/.bss/.readonly
btf_type.info: type kind and vlen for # of variables
btf_type.size: 0
#vlen number of the following:
u32: id of corresponding BTF_KIND_VAR
u32: in-session offset of the var
u32: the size of memory var occupied
At the time of debug info emission, the data section
size is unknown, so the btf_type.size = 0 for
BTF_KIND_DATASEC. The loader can patch it during
loading time.
The in-session offseet of the var is only available
for static variables. For global variables, the
loader neeeds to assign the global variable symbol value in
symbol table to in-section offset.
The size of memory is used to specify the amount of the
memory a variable occupies. Typically, it equals to
the type size, but for certain structures, e.g.,
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
The static variable s2 has size of 20.
Note that for BTF_KIND_DATASEC name, the section name
does not contain object name. The compiler does have
input module name. For example, two cases below:
. clang -target bpf -O2 -g -c test.c
The compiler knows the input file (module) is test.c
and can generate sec name like test.data/test.bss etc.
. clang -target bpf -O2 -g -emit-llvm -c test.c -o - |
llc -march=bpf -filetype=obj -o test.o
The llc compiler has the input file as stdin, and
would generate something like stdin.data/stdin.bss etc.
which does not really make sense.
For any user specificed section name, e.g.,
static volatile int a __attribute__((section("id1")));
static volatile const int b __attribute__((section("id2")));
The DataSec with name "id1" and "id2" does not contain
information whether the section is readonly or not.
The loader needs to check the corresponding elf section
flags for such information.
A simple example:
-bash-4.4$ cat t.c
int g1;
int g2 = 3;
const int g3 = 4;
static volatile int s1;
struct tt {
int a;
int b;
char c[];
};
static volatile struct tt s2 = {3, 4, "abcdefghi"};
static volatile const int s3 = 4;
int m __attribute__((section("maps"), used)) = 4;
int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; }
-bash-4.4$ clang -target bpf -O2 -g -S t.c
Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m).
4 BTF_KIND_DATASEC's are generated with names
".data", ".bss", ".rodata" and "maps".
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D59441
llvm-svn: 356326
2019-03-16 23:36:31 +08:00
|
|
|
/// Generate types and variables for globals.
|
|
|
|
void processGlobals(void);
|
|
|
|
|
2018-12-20 00:40:25 +08:00
|
|
|
/// Emit common header of .BTF and .BTF.ext sections.
|
|
|
|
void emitCommonHeader();
|
|
|
|
|
|
|
|
/// Emit the .BTF section.
|
|
|
|
void emitBTFSection();
|
|
|
|
|
|
|
|
/// Emit the .BTF.ext section.
|
|
|
|
void emitBTFExtSection();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// Gather pre-function debug information.
|
|
|
|
void beginFunctionImpl(const MachineFunction *MF) override;
|
|
|
|
|
|
|
|
/// Post process after all instructions in this function are processed.
|
|
|
|
void endFunctionImpl(const MachineFunction *MF) override;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BTFDebug(AsmPrinter *AP);
|
|
|
|
|
|
|
|
/// Get the special array index type id.
|
|
|
|
uint32_t getArrayIndexTypeId() {
|
|
|
|
assert(ArrayIndexTypeId);
|
|
|
|
return ArrayIndexTypeId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Add string to the string table.
|
|
|
|
size_t addString(StringRef S) { return StringTable.addString(S); }
|
|
|
|
|
|
|
|
/// Get the type id for a particular DIType.
|
|
|
|
uint32_t getTypeId(const DIType *Ty) {
|
|
|
|
assert(Ty && "Invalid null Type");
|
|
|
|
assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
|
|
|
|
"DIType not added in the BDIToIdMap");
|
|
|
|
return DIToIdMap[Ty];
|
|
|
|
}
|
|
|
|
|
|
|
|
void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
|
|
|
|
|
|
|
|
/// Process beginning of an instruction.
|
|
|
|
void beginInstruction(const MachineInstr *MI) override;
|
|
|
|
|
|
|
|
/// Complete all the types and emit the BTF sections.
|
|
|
|
void endModule() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif
|