[llvm] r344366 - [BPF] Add BTF generation for BPF target
Yonghong Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 12 13:08:32 PDT 2018
> Hi Yonghong,
>
> This is causing compilation errors in my local build. Could you please
> take a look?
> ```
>
> llvm/include/llvm/MC/MCBTFContext.h:175:5: error: designated initializers are a C99 feature [-Werror,-Wc99-extensions]
> [BTF_KIND_UNKN] = "UNKNOWN", [BTF_KIND_INT] = "INT",
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>
Sorry. This has been fixed and then the whole patch set is reverted. We
will work on to make it work on multiple platforms next revision.
> ```
>
>
> Thanks,
>
> Eric
>
>
> On Fri, Oct 12, 2018 at 7:03 PM Yonghong Song via llvm-commits
> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>
> Author: yhs
> Date: Fri Oct 12 10:01:46 2018
> New Revision: 344366
>
> URL: http://llvm.org/viewvc/llvm-project?rev=344366&view=rev
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D344366-26view-3Drev&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=4l32GQxcHXtsnymDRAe7u1x6xtpjzQ1vzgR5G85f8bA&e=>
> Log:
> [BPF] Add BTF generation for BPF target
>
> BTF is the debug format for BPF, a kernel virtual machine
> and widely used for tracing, networking and security, etc ([1]).
>
> Currently only instruction streams are passed to kernel,
> the kernel verifier verifies them before execution. In order to
> provide better visibility of bpf programs to user space
> tools, some debug information, e.g., function names and
> debug line information are desirable for kernel so tools
> can get such information with better annotation
> for jited instructions for performance or other reasons.
>
> The dwarf is too complicated in kernel and for BPF.
> Hence, BTF is designed to be the debug format for BPF ([2]).
> Right now, pahole supports BTF for types, which
> are generated based on dwarf sections in the ELF file.
>
> In order to annotate performance metrics for jited bpf insns,
> it is necessary to pass debug line info to the kernel.
> Furthermore, we want to pass the actual code to the
> kernel because of the following reasons:
>
> . bpf program typically is small so storage overhead
> should be small.
> . in bpf land, it is totally possible that
> an application loads the bpf program into the
> kernel and then that application quits, so
> holding debug info by the user space application
> is not practical.
> . having source codes directly kept by kernel
> would ease deployment since the original source
> code does not need ship on every hosts and
> kernel-devel package does not need to be
> deployed even if kernel headers are used.
>
> The only reliable time to get the source code is
> during compilation time. This will result in both more
> accurate information and easier deployment as
> stated in the above.
>
> Another consideration is for JIT. The project like bcc
> use MCJIT to compile a C program into bpf insns and
> load them to the kernel ([3]). The generated BTF sections
> will be readily available for such cases as well.
>
> This patch implemented generation of BTF info in llvm
> compiler. The BTF related sections will be generated
> when both -target bpf and -g are specified. Two sections
> are generated:
> .BTF contains all the type and string information, and
> .BTF.ext contains the func_info and line_info.
>
> The separation is related to how two sections are used
> differently in bpf loader, e.g., linux libbpf ([4]).
> The .BTF section can be loaded into the kernel directly
> while .BTF.ext needs loader manipulation before loading
> to the kernel. The format of the each section is roughly
> defined in llvm:include/llvm/MC/MCBTFContext.h and
> from the implementation in llvm:lib/MC/MCBTFContext.cpp.
> A later example also shows the contents in each section.
>
> The type and func_info are gathered during CodeGen/AsmPrinter
> by traversing dwarf debug_info. The line_info is
> gathered in MCObjectStreamer before writing to
> the object file. After all the information is gathered,
> the two sections are emitted in MCObjectStreamer::finishImpl.
>
> With cmake CMAKE_BUILD_TYPE=Debug, the compiler can
> dump out all the tables except insn offset, which
> will be resolved later as relocation records.
> The debug type "btf" is used for BTFContext dump.
>
> Dwarf tests the debug info generation with
> llvm-dwarfdump to decode the binary sections and
> check whether the result is expected. Currently
> we do not have such a tool yet. We will implement
> btf dump functionality in bpftool ([5]) as the bpftool is
> considered the recommended tool for bpf introspection.
> The implementation for type and func_info is tested
> with linux kernel test cases. The line_info is visually
> checked with dump from linux kernel libbpf ([4]) and
> checked with readelf dumping section raw data.
>
> Note that the .BTF and .BTF.ext information will not
> be emitted to assembly code and there is no assembler
> support for BTF either.
>
> In the below, with a clang/llvm built with CMAKE_BUILD_TYPE=Debug,
> Each table contents are shown for a simple C program.
>
> -bash-4.2$ cat -n test.c
> 1 struct A {
> 2 int a;
> 3 char b;
> 4 };
> 5
> 6 int test(struct A *t) {
> 7 return t->a;
> 8 }
> -bash-4.2$ clang -O2 -target bpf -g -mllvm -debug-only=btf -c test.c
> Type Table:
> [1] FUNC name_off=1 info=0x0c000001 size/type=2
> param_type=3
> [2] INT name_off=12 info=0x01000000 size/type=4
> desc=0x01000020
> [3] PTR name_off=0 info=0x02000000 size/type=4
> [4] STRUCT name_off=16 info=0x04000002 size/type=8
> name_off=18 type=2 bit_offset=0
> name_off=20 type=5 bit_offset=32
> [5] INT name_off=22 info=0x01000000 size/type=1
> desc=0x02000008
>
> String Table:
> 0 :
> 1 : test
> 6 : .text
> 12 : int
> 16 : A
> 18 : a
> 20 : b
> 22 : char
> 27 : test.c
> 34 : int test(struct A *t) {
> 58 : return t->a;
>
> FuncInfo Table:
> sec_name_off=6
> insn_offset=<Omitted> type_id=1
>
> LineInfo Table:
> sec_name_off=6
> insn_offset=<Omitted> file_name_off=27 line_off=34
> line_num=6 column_num=0
> insn_offset=<Omitted> file_name_off=27 line_off=58
> line_num=7 column_num=3
> -bash-4.2$ readelf -S test.o
> ......
> [12] .BTF PROGBITS 0000000000000000 0000028d
> 00000000000000c1 0000000000000000 0 0 1
> [13] .BTF.ext PROGBITS 0000000000000000 0000034e
> 0000000000000050 0000000000000000 0 0 1
> [14] .rel.BTF.ext REL 0000000000000000 00000648
> 0000000000000030 0000000000000010 16 13 8
> ......
> -bash-4.2$
>
> The latest linux kernel ([6]) can already support .BTF with type
> information.
> The [7] has the reference implementation in linux kernel side
> to support .BTF.ext func_info. The .BTF.ext line_info support is not
> implemented yet. If you have difficulty accessing [6], you can
> manually do the following to access the code:
>
> git clone https://github.com/yonghong-song/bpf-next-linux.git
> cd bpf-next-linux
> git checkout btf
>
> The change will push to linux kernel soon once this patch is landed.
>
> References:
> [1]. https://www.kernel.org/doc/Documentation/networking/filter.txt
> [2]. https://lwn.net/Articles/750695/
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__lwn.net_Articles_750695_&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=Y8mkUt-UDEcHk1iVys8g8XGCTswC9c6lcyFtkfegFNs&e=>
> [3]. https://github.com/iovisor/bcc
> [4]. https://github.com/torvalds/linux/tree/master/tools/lib/bpf
> [5]. https://github.com/torvalds/linux/tree/master/tools/bpf/bpftool
> [6]. https://github.com/torvalds/linux
> [7]. https://github.com/yonghong-song/bpf-next-linux/tree/btf
>
> Signed-off-by: Song Liu <songliubraving at fb.com
> <mailto:songliubraving at fb.com>>
> Signed-off-by: Yonghong Song <yhs at fb.com <mailto:yhs at fb.com>>
> Acked-by: Alexei Starovoitov <ast at kernel.org <mailto:ast at kernel.org>>
>
> Differential Revision: https://reviews.llvm.org/D52950
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__reviews.llvm.org_D52950&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=6NdWup5JJRo0two5ngGDb2TpKPDGimkPcM6rb0UMuHI&e=>
>
> Added:
> llvm/trunk/include/llvm/MC/MCBTFContext.h
> llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.cpp
> llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.h
> llvm/trunk/lib/MC/MCBTFContext.cpp
> llvm/trunk/lib/MC/MCDwarf2BTF.cpp
> llvm/trunk/lib/MC/MCDwarf2BTF.h
> Modified:
> llvm/trunk/include/llvm/MC/MCContext.h
> llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
> llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
> llvm/trunk/lib/MC/CMakeLists.txt
> llvm/trunk/lib/MC/MCContext.cpp
> llvm/trunk/lib/MC/MCObjectFileInfo.cpp
> llvm/trunk/lib/MC/MCObjectStreamer.cpp
>
> Added: llvm/trunk/include/llvm/MC/MCBTFContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCBTFContext.h?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_MC_MCBTFContext.h-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=M081CwJxXbzmINMedkcTH38cwg-EREL11pa4DTVH_Gs&e=>
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCBTFContext.h (added)
> +++ llvm/trunk/include/llvm/MC/MCBTFContext.h Fri Oct 12 10:01:46 2018
> @@ -0,0 +1,364 @@
> +//===- MCBTFContext.h ---------------------------------------- *-
> C++ --*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// This header file contains two parts. The first part is the BTF ELF
> +// specification in C format, and the second part is the various
> +// C++ classes to manipulate the data structure in order to generate
> +// the BTF related ELF sections.
> +//===----------------------------------------------------------------------===//
> +#ifndef LLVM_MC_MCBTFCONTEXT_H
> +#define LLVM_MC_MCBTFCONTEXT_H
> +
> +#include <linux/types.h>
> +
> +#define BTF_MAGIC 0xeB9F
> +#define BTF_VERSION 1
> +
> +struct btf_header {
> + __u16 magic;
> + __u8 version;
> + __u8 flags;
> + __u32 hdr_len;
> +
> + /* All offsets are in bytes relative to the end of this
> header */
> + __u32 type_off; /* offset of type section */
> + __u32 type_len; /* length of type section */
> + __u32 str_off; /* offset of string section */
> + __u32 str_len; /* length of string section */
> +};
> +
> +/* Max # of type identifier */
> +#define BTF_MAX_TYPE 0x0000ffff
> +/* Max offset into the string section */
> +#define BTF_MAX_NAME_OFFSET 0x0000ffff
> +/* Max # of struct/union/enum members or func args */
> +#define BTF_MAX_VLEN 0xffff
> +
> +struct btf_type {
> + __u32 name_off;
> + /* "info" bits arrangement
> + * bits 0-15: vlen (e.g. # of struct's members)
> + * bits 16-23: unused
> + * bits 24-27: kind (e.g. int, ptr, array...etc)
> + * bits 28-31: unused
> + */
> + __u32 info;
> + /* "size" is used by INT, ENUM, STRUCT and UNION.
> + * "size" tells the size of the type it is describing.
> + *
> + * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
> + * FUNC and FUNC_PROTO.
> + * "type" is a type_id referring to another type.
> + */
> + union {
> + __u32 size;
> + __u32 type;
> + };
> +};
> +
> +#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
> +#define BTF_INFO_VLEN(info) ((info) & 0xffff)
> +
> +#define BTF_KIND_UNKN 0 /* Unknown */
> +#define BTF_KIND_INT 1 /* Integer */
> +#define BTF_KIND_PTR 2 /* Pointer */
> +#define BTF_KIND_ARRAY 3 /* Array */
> +#define BTF_KIND_STRUCT 4 /* Struct */
> +#define BTF_KIND_UNION 5 /* Union */
> +#define BTF_KIND_ENUM 6 /* Enumeration */
> +#define BTF_KIND_FWD 7 /* Forward */
> +#define BTF_KIND_TYPEDEF 8 /* Typedef */
> +#define BTF_KIND_VOLATILE 9 /* Volatile */
> +#define BTF_KIND_CONST 10 /* Const */
> +#define BTF_KIND_RESTRICT 11 /* Restrict */
> +#define BTF_KIND_FUNC 12 /* Function */
> +#define BTF_KIND_FUNC_PROTO 13 /* Function Prototype */
> +#define BTF_KIND_MAX 13
> +#define NR_BTF_KINDS 14
> +
> +/* For some specific BTF_KIND, "struct btf_type" is immediately
> + * followed by extra data.
> + */
> +
> +/* BTF_KIND_INT is followed by a u32 and the following
> + * is the 32 bits arrangement:
> + */
> +#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
> +#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
> +#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
> +
> +/* Attributes stored in the BTF_INT_ENCODING */
> +#define BTF_INT_SIGNED (1 << 0)
> +#define BTF_INT_CHAR (1 << 1)
> +#define BTF_INT_BOOL (1 << 2)
> +
> +/* BTF_KIND_ENUM is followed by multiple "struct btf_enum".
> + * The exact number of btf_enum is stored in the vlen (of the
> + * info in "struct btf_type").
> + */
> +struct btf_enum {
> + __u32 name_off;
> + __s32 val;
> +};
> +
> +/* BTF_KIND_ARRAY is followed by one "struct btf_array" */
> +struct btf_array {
> + __u32 type;
> + __u32 index_type;
> + __u32 nelems;
> +};
> +
> +/* BTF_KIND_STRUCT and BTF_KIND_UNION are followed
> + * by multiple "struct btf_member". The exact number
> + * of btf_member is stored in the vlen (of the info in
> + * "struct btf_type").
> + */
> +struct btf_member {
> + __u32 name_off;
> + __u32 type;
> + __u32 offset; /* offset in bits */
> +};
> +
> +/* .BTF.ext section contains func_info and line_info.
> + */
> +struct btf_ext_header {
> + __u16 magic;
> + __u8 version;
> + __u8 flags;
> + __u32 hdr_len;
> +
> + __u32 func_info_off;
> + __u32 func_info_len;
> + __u32 line_info_off;
> + __u32 line_info_len;
> +};
> +
> +struct bpf_func_info {
> + __u32 insn_offset;
> + __u32 type_id;
> +};
> +
> +struct btf_sec_func_info {
> + __u32 sec_name_off;
> + __u32 num_func_info;
> +};
> +
> +struct bpf_line_info {
> + __u32 insn_offset;
> + __u32 file_name_off;
> + __u32 line_off;
> + __u32 line_col; /* line num: line_col >> 10, col num:
> line_col & 0x3ff */
> +};
> +
> +struct btf_sec_line_info {
> + __u32 sec_name_off;
> + __u32 num_line_info;
> +};
> +
> +namespace llvm {
> +
> +const char *const btf_kind_str[NR_BTF_KINDS] = {
> + [BTF_KIND_UNKN] = "UNKNOWN",
> + [BTF_KIND_INT] = "INT",
> + [BTF_KIND_PTR] = "PTR",
> + [BTF_KIND_ARRAY] = "ARRAY",
> + [BTF_KIND_STRUCT] = "STRUCT",
> + [BTF_KIND_UNION] = "UNION",
> + [BTF_KIND_ENUM] = "ENUM",
> + [BTF_KIND_FWD] = "FWD",
> + [BTF_KIND_TYPEDEF] = "TYPEDEF",
> + [BTF_KIND_VOLATILE] = "VOLATILE",
> + [BTF_KIND_CONST] = "CONST",
> + [BTF_KIND_RESTRICT] = "RESTRICT",
> + [BTF_KIND_FUNC] = "FUNC",
> + [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO",
> +};
> +
> +#include "llvm/ADT/SmallVector.h"
> +#include <map>
> +
> +class MCBTFContext;
> +class MCObjectStreamer;
> +
> +// This is base class of all BTF KIND. It is also used directly
> +// by the reference kinds:
> +// BTF_KIND_CONST, BTF_KIND_PTR, BTF_KIND_VOLATILE,
> +// BTF_KIND_TYPEDEF, BTF_KIND_RESTRICT, and BTF_KIND_FWD
> +class BTFTypeEntry {
> +protected:
> + size_t Id; /* type index in the BTF list, started from 1 */
> + struct btf_type BTFType;
> +
> +public:
> + BTFTypeEntry(size_t id, struct btf_type &type) :
> + Id(id), BTFType(type) {}
> + unsigned char getKind() { return BTF_INFO_KIND(BTFType.info); }
> + void setId(size_t Id) { this->Id = Id; }
> + size_t getId() { return Id; }
> + void setNameOff(unsigned NameOff) { BTFType.name_off = NameOff; }
> +
> + unsigned getTypeIndex() { return BTFType.type; }
> + unsigned getNameOff() { return BTFType.name_off; }
> + virtual size_t getSize() { return sizeof(struct btf_type); }
> + virtual void print(raw_ostream &s, MCBTFContext& BTFContext);
> + virtual void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +// BTF_KIND_INT
> +class BTFTypeEntryInt : public BTFTypeEntry {
> + unsigned IntVal; // encoding, offset, bits
> +
> +public:
> + BTFTypeEntryInt(size_t id, struct btf_type &type, unsigned intval) :
> + BTFTypeEntry(id, type), IntVal(intval) {}
> + size_t getSize() { return BTFTypeEntry::getSize() +
> sizeof(unsigned); }
> + void print(raw_ostream &s, MCBTFContext& BTFContext);
> + void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +// BTF_KIND_ENUM
> +class BTFTypeEntryEnum : public BTFTypeEntry {
> + std::vector<struct btf_enum> EnumValues;
> +
> +public:
> + BTFTypeEntryEnum(size_t id, struct btf_type &type,
> + std::vector<struct btf_enum> &values) :
> + BTFTypeEntry(id, type), EnumValues(values) {}
> + size_t getSize() {
> + return BTFTypeEntry::getSize() +
> + BTF_INFO_VLEN(BTFType.info) * sizeof(struct btf_enum);
> + }
> + void print(raw_ostream &s, MCBTFContext& BTFContext);
> + void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +// BTF_KIND_ARRAY
> +class BTFTypeEntryArray : public BTFTypeEntry {
> + struct btf_array ArrayInfo;
> +
> +public:
> + BTFTypeEntryArray(size_t id, struct btf_type &type,
> + struct btf_array &arrayinfo) :
> + BTFTypeEntry(id, type), ArrayInfo(arrayinfo) {}
> + size_t getSize() {
> + return BTFTypeEntry::getSize() + sizeof(struct btf_array);
> + }
> + void print(raw_ostream &s, MCBTFContext& BTFContext);
> + void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +// BTF_KIND_STRUCT and BTF_KIND_UNION
> +class BTFTypeEntryStruct : public BTFTypeEntry {
> + std::vector<struct btf_member> Members;
> +
> +public:
> + BTFTypeEntryStruct(size_t id, struct btf_type &type,
> + std::vector<struct btf_member> &members) :
> + BTFTypeEntry(id, type), Members(members) {}
> + size_t getSize() {
> + return BTFTypeEntry::getSize() +
> + BTF_INFO_VLEN(BTFType.info) * sizeof(struct btf_member);
> + }
> + void print(raw_ostream &s, MCBTFContext& BTFContext);
> + void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +// BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO
> +class BTFTypeEntryFunc : public BTFTypeEntry {
> + std::vector<unsigned> Parameters;
> +
> +public:
> + BTFTypeEntryFunc(size_t id, struct btf_type &type,
> + std::vector<unsigned> ¶ms) :
> + BTFTypeEntry(id, type), Parameters(params) {}
> + size_t getSize() {
> + return BTFTypeEntry::getSize() +
> + BTF_INFO_VLEN(BTFType.info) * sizeof(unsigned);
> + }
> + void print(raw_ostream &s, MCBTFContext& BTFContext);
> + void emitData(MCObjectStreamer *MCOS);
> +};
> +
> +class BTFStringTable {
> + size_t Size; // total size in bytes
> + std::map<size_t, unsigned> OffsetToIdMap;
> + std::vector<std::string> Table;
> +
> + public:
> + BTFStringTable() : Size(0) {}
> + size_t getSize() { return Size; }
> + std::vector<std::string> &getTable() { return Table; }
> + size_t addString(std::string S) {
> + // check whether the string already exists
> + for (auto &OffsetM : OffsetToIdMap) {
> + if (Table[OffsetM.second] == S)
> + return OffsetM.first;
> + }
> + // not find, add to the string table
> + size_t Offset = Size;
> + OffsetToIdMap[Offset] = Table.size();
> + Table.push_back(S);
> + Size += S.size() + 1;
> + return Offset;
> + }
> + std::string &getStringAtOffset(size_t Offset) {
> + return Table[OffsetToIdMap[Offset]];
> + }
> + void showTable(raw_ostream &OS) {
> + for (auto OffsetM : OffsetToIdMap)
> + OS << OffsetM.first << " : " << Table[OffsetM.second]
> + << "\n";
> + }
> +};
> +
> +struct BTFFuncInfo {
> + const MCSymbol *Label;
> + unsigned int TypeId;
> +};
> +
> +struct BTFLineInfo {
> + MCSymbol *Label;
> + unsigned int FileNameOff;
> + unsigned int LineOff;
> + unsigned int LineNum;
> + unsigned int ColumnNum;
> +};
> +
> +class MCBTFContext {
> + std::vector<std::unique_ptr<BTFTypeEntry>> TypeEntries;
> + BTFStringTable StringTable;
> + std::map<unsigned, std::vector<BTFFuncInfo>> FuncInfoTable;
> + std::map<unsigned, std::vector<BTFLineInfo>> LineInfoTable;
> +
> + friend class BTFTypeEntry;
> + friend class BTFTypeEntryInt;
> + friend class BTFTypeEntryEnum;
> + friend class BTFTypeEntryArray;
> + friend class BTFTypeEntryStruct;
> + friend class BTFTypeEntryFunc;
> +
> +public:
> + void dump(raw_ostream& OS);
> + void emitAll(MCObjectStreamer *MCOS);
> + void emitCommonHeader(MCObjectStreamer *MCOS);
> + void emitBTFSection(MCObjectStreamer *MCOS);
> + void emitBTFExtSection(MCObjectStreamer *MCOS);
> +
> + size_t addString(std::string S) {
> + return StringTable.addString(S);
> + }
> + void addTypeEntry(std::unique_ptr<BTFTypeEntry> Entry);
> + void addFuncInfo(unsigned SecNameOff, BTFFuncInfo Info) {
> + FuncInfoTable[SecNameOff].push_back(Info);
> + }
> + void addLineInfo(unsigned SecNameOff, BTFLineInfo Info) {
> + LineInfoTable[SecNameOff].push_back(Info);
> + }
> +};
> +
> +}
> +#endif
>
> Modified: llvm/trunk/include/llvm/MC/MCContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_MC_MCContext.h-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=v7BeiSITGSSNSrmbYHVS_1_SKh4xXAnQkhon1ZyGeIA&e=>
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCContext.h (original)
> +++ llvm/trunk/include/llvm/MC/MCContext.h Fri Oct 12 10:01:46 2018
> @@ -56,6 +56,7 @@ namespace llvm {
> class MCSymbolWasm;
> class SMLoc;
> class SourceMgr;
> + class MCBTFContext;
>
> /// Context object for machine code objects. This class owns
> all of the
> /// sections that it creates.
> @@ -278,6 +279,9 @@ namespace llvm {
> /// Map of currently defined macros.
> StringMap<MCAsmMacro> MacroMap;
>
> + /// for BTF debug information
> + std::unique_ptr<MCBTFContext> BTFCtx;
> +
> public:
> explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo
> *MRI,
> const MCObjectFileInfo *MOFI,
> @@ -286,6 +290,9 @@ namespace llvm {
> MCContext &operator=(const MCContext &) = delete;
> ~MCContext();
>
> + void setBTFContext(std::unique_ptr<MCBTFContext> Ctx);
> + std::unique_ptr<MCBTFContext> &getBTFContext() { return BTFCtx; }
> +
> const SourceMgr *getSourceManager() const { return SrcMgr; }
>
> void setInlineSourceManager(SourceMgr *SM) { InlineSrcMgr = SM; }
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_MC_MCObjectFileInfo.h-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=HhA4NzYm81nfy8u0RDCfu-ucYJ-NC9DwsS4fvg8N6bQ&e=>
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Fri Oct 12
> 10:01:46 2018
> @@ -207,6 +207,10 @@ protected:
> MCSection *SXDataSection;
> MCSection *GFIDsSection;
>
> + // BTF specific sections.
> + MCSection *BTFSection;
> + MCSection *BTFExtSection;
> +
> public:
> void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext
> &ctx,
> bool LargeCodeModel = false);
> @@ -372,6 +376,10 @@ public:
> return EHFrameSection;
> }
>
> + // BTF specific sections.
> + MCSection *getBTFSection() const { return BTFSection; }
> + MCSection *getBTFExtSection() const { return BTFExtSection; }
> +
> enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
> Environment getObjectFileType() const { return Env; }
>
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_MC_MCObjectStreamer.h-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=dtfeqC87qXAHOVrago8wBLvVAjotYcWeQEjr-1F4i7I&e=>
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Fri Oct 12
> 10:01:46 2018
> @@ -138,6 +138,7 @@ public:
> unsigned PointerSize);
> void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
> const MCSymbol *Label);
> + void EmitBTFAdvanceLineAddr(const MCSymbol *Label, unsigned Size);
> void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
> unsigned Line,
> unsigned Column, bool PrologueEnd, bool
> IsStmt,
> StringRef FileName, SMLoc Loc) override;
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_CMakeLists.txt-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=HAHodf30IDcm99KllFqNcUvXkIHxKHTUADy8gU9dz8g&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt Fri Oct 12
> 10:01:46 2018
> @@ -17,6 +17,7 @@ add_llvm_library(LLVMAsmPrinter
> DwarfFile.cpp
> DwarfStringPool.cpp
> DwarfUnit.cpp
> + Dwarf2BTF.cpp
> EHStreamer.cpp
> ErlangGCPrinter.cpp
> OcamlGCPrinter.cpp
>
> Added: llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.cpp?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_Dwarf2BTF.cpp-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=GVoTFTg16SEaAYRq2N3nLcUhPwC8P9-LhnUcwJeoAYw&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.cpp (added)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.cpp Fri Oct 12
> 10:01:46 2018
> @@ -0,0 +1,501 @@
> +//===- Dwarf2BTF.cpp ------------------------------------------ *-
> C++ --*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "DwarfUnit.h"
> +#include "Dwarf2BTF.h"
> +#include "llvm/MC/MCBTFContext.h"
> +#include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCSectionELF.h"
> +
> +namespace llvm {
> +
> +unsigned char Die2BTFEntry::getDieKind(const DIE & Die) {
> + auto Tag = Die.getTag();
> +
> + switch (Tag) {
> + case dwarf::DW_TAG_base_type:
> + if (getBaseTypeEncoding(Die) == BTF_INVALID_ENCODING)
> + return BTF_KIND_UNKN;
> + return BTF_KIND_INT;
> + case dwarf::DW_TAG_const_type:
> + return BTF_KIND_CONST;
> + case dwarf::DW_TAG_pointer_type:
> + return BTF_KIND_PTR;
> + case dwarf::DW_TAG_restrict_type:
> + return BTF_KIND_RESTRICT;
> + case dwarf::DW_TAG_volatile_type:
> + return BTF_KIND_VOLATILE;
> + case dwarf::DW_TAG_typedef:
> + return BTF_KIND_TYPEDEF;
> + case dwarf::DW_TAG_structure_type:
> + case dwarf::DW_TAG_class_type:
> + if (Die.findAttribute(dwarf::DW_AT_declaration).getType()
> + != DIEValue::isNone)
> + return BTF_KIND_FWD;
> + else
> + return BTF_KIND_STRUCT;
> + case dwarf::DW_TAG_union_type:
> + if (Die.findAttribute(dwarf::DW_AT_declaration).getType()
> + != DIEValue::isNone)
> + return BTF_KIND_FWD;
> + else
> + return BTF_KIND_UNION;
> + case dwarf::DW_TAG_enumeration_type:
> + return BTF_KIND_ENUM;
> + case dwarf::DW_TAG_array_type:
> + return BTF_KIND_ARRAY;
> + case dwarf::DW_TAG_subprogram:
> + return BTF_KIND_FUNC;
> + case dwarf::DW_TAG_subroutine_type:
> + return BTF_KIND_FUNC_PROTO;
> + default:
> + break;
> + }
> +
> + return BTF_KIND_UNKN;
> +}
> +
> +std::unique_ptr<Die2BTFEntry> Die2BTFEntry::dieToBTFTypeEntry(const
> DIE &Die) {
> + unsigned char Kind = getDieKind(Die);
> +
> + switch (Kind) {
> + case BTF_KIND_INT:
> + return make_unique<Die2BTFEntryInt>(Die);
> + case BTF_KIND_PTR:
> + case BTF_KIND_TYPEDEF:
> + case BTF_KIND_VOLATILE:
> + case BTF_KIND_CONST:
> + case BTF_KIND_RESTRICT:
> + case BTF_KIND_FWD:
> + return make_unique<Die2BTFEntry>(Die);
> + case BTF_KIND_ARRAY:
> + return make_unique<Die2BTFEntryArray>(Die);
> + case BTF_KIND_STRUCT:
> + case BTF_KIND_UNION:
> + return make_unique<Die2BTFEntryStruct>(Die);
> + case BTF_KIND_ENUM:
> + return make_unique<Die2BTFEntryEnum>(Die);
> + case BTF_KIND_FUNC:
> + case BTF_KIND_FUNC_PROTO:
> + return make_unique<Die2BTFEntryFunc>(Die);
> + default:
> + break;
> + }
> + return nullptr;
> +}
> +
> +bool Die2BTFEntry::shouldSkipDie(const DIE &Die) {
> + auto Tag = Die.getTag();
> +
> + switch (Tag) {
> + case dwarf::DW_TAG_const_type:
> + case dwarf::DW_TAG_pointer_type:
> + case dwarf::DW_TAG_restrict_type:
> + case dwarf::DW_TAG_typedef:
> + case dwarf::DW_TAG_volatile_type:
> + {
> + auto TypeV = Die.findAttribute(dwarf::DW_AT_type);
> + if (TypeV.getType() == DIEValue::isNone)
> + return false;
> + auto &TypeDie = TypeV.getDIEEntry().getEntry();
> + return Die2BTFEntry::shouldSkipDie(TypeDie);
> + }
> + default:
> + return getDieKind(Die) == BTF_KIND_UNKN;
> + }
> + return true;
> +}
> +unsigned char Die2BTFEntry::getBaseTypeEncoding(const DIE &Die) {
> + auto V = Die.findAttribute(dwarf::DW_AT_encoding);
> +
> + if (V.getType() != DIEValue::isInteger)
> + return BTF_INVALID_ENCODING;
> +
> + switch (V.getDIEInteger().getValue()) {
> + case dwarf::DW_ATE_boolean:
> + return BTF_INT_BOOL;
> + case dwarf::DW_ATE_signed:
> + return BTF_INT_SIGNED;
> + case dwarf::DW_ATE_signed_char:
> + return BTF_INT_CHAR;
> + case dwarf::DW_ATE_unsigned:
> + return 0;
> + case dwarf::DW_ATE_unsigned_char:
> + return BTF_INT_CHAR;
> + case dwarf::DW_ATE_imaginary_float:
> + case dwarf::DW_ATE_packed_decimal:
> + case dwarf::DW_ATE_numeric_string:
> + case dwarf::DW_ATE_edited:
> + case dwarf::DW_ATE_signed_fixed:
> + case dwarf::DW_ATE_address:
> + case dwarf::DW_ATE_complex_float:
> + case dwarf::DW_ATE_float:
> + default:
> + break;
> + }
> + return BTF_INVALID_ENCODING;
> +}
> +
> +Die2BTFEntry::Die2BTFEntry(const DIE &Die) : Die(Die) {
> + unsigned char Kind = getDieKind(Die);
> +
> + switch (Kind) {
> + case BTF_KIND_CONST:
> + case BTF_KIND_FWD:
> + case BTF_KIND_PTR:
> + case BTF_KIND_RESTRICT:
> + case BTF_KIND_TYPEDEF:
> + case BTF_KIND_VOLATILE:
> + break;
> + default:
> + assert("Invalid Die passed into BTFTypeEntry()");
> + break;
> + }
> +
> + BTFType.info = (Kind & 0xf) << 24;
> +}
> +
> +void Die2BTFEntry::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto TypeV = Die.findAttribute(dwarf::DW_AT_type);
> + if (TypeV.getType() == DIEValue::isNone) {
> + BTFType.type = 0;
> + } else {
> + auto &TypeDie = TypeV.getDIEEntry().getEntry();
> + auto Type = Dwarf2BTF.getTypeIndex(TypeDie);
> + BTFType.type = Type;
> + }
> +
> + unsigned char Kind = getDieKind(Die);
> + if (Kind != BTF_KIND_FWD) {
> + BTFType.name_off = 0;
> + } else {
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> + auto Str = NameV.getDIEString().getString();
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> + }
> +
> + auto typeEntry = make_unique<BTFTypeEntry>(Id, BTFType);
> + Dwarf2BTF.addBTFTypeEntry(std::move(typeEntry));
> +}
> +
> +Die2BTFEntryInt::Die2BTFEntryInt(const DIE &Die) : Die2BTFEntry(Die) {
> + unsigned char Kind = getDieKind(Die);
> +
> + switch (Kind) {
> + case BTF_KIND_INT:
> + break;
> + default:
> + assert("Invalid Die passed into BTFTypeEntryInt()");
> + break;
> + }
> +
> + // handle BTF_INT_ENCODING in IntVal
> + auto Encoding = Die2BTFEntry::getBaseTypeEncoding(Die);
> + assert((Encoding != BTF_INVALID_ENCODING) &&
> + "Invalid Die passed to BTFTypeEntryInt()");
> + __u32 IntVal = (Encoding & 0xf) << 24;
> +
> + // handle BTF_INT_OFFSET in IntVal
> + auto V = Die.findAttribute(dwarf::DW_AT_bit_offset);
> + if (V.getType() == DIEValue::isInteger)
> + IntVal |= (V.getDIEInteger().getValue() & 0xff) << 16;
> +
> + // get btf_type.size
> + V = Die.findAttribute(dwarf::DW_AT_byte_size);
> + __u32 Size = V.getDIEInteger().getValue() & 0xffffffff;
> +
> +// handle BTF_INT_BITS in IntVal
> + V = Die.findAttribute(dwarf::DW_AT_bit_size);
> + if (V.getType() == DIEValue::isInteger)
> + IntVal |= V.getDIEInteger().getValue() & 0xff;
> + else
> + IntVal |= (Size << 3) & 0xff;
> +
> + BTFType.info = BTF_KIND_INT << 24;
> + BTFType.size = Size;
> + this->IntVal = IntVal;
> +}
> +
> +void Die2BTFEntryInt::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> + auto TypeV = Die.findAttribute(dwarf::DW_AT_type);
> + auto Str = NameV.getDIEString().getString();
> +
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> +
> + auto typeEntry = make_unique<BTFTypeEntryInt>(Id, BTFType, IntVal);
> + Dwarf2BTF.addBTFTypeEntry(std::move(typeEntry));
> +}
> +
> +Die2BTFEntryEnum::Die2BTFEntryEnum(const DIE &Die) :
> Die2BTFEntry(Die) {
> + // get btf_type.size
> + auto V = Die.findAttribute(dwarf::DW_AT_byte_size);
> + __u32 Size = V.getDIEInteger().getValue() & 0xffffffff;
> +
> + int Vlen = 0;
> + for (auto &ChildDie : Die.children())
> + if (ChildDie.getTag() == dwarf::DW_TAG_enumerator)
> + Vlen++;
> +
> + BTFType.info = (BTF_KIND_ENUM << 24) | (Vlen & BTF_MAX_VLEN);
> + BTFType.type = Size;
> +}
> +
> +void Die2BTFEntryEnum::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto TypeV = Die.findAttribute(dwarf::DW_AT_type);
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> +
> + if (NameV.getType() != DIEValue::isNone) {
> + auto Str = NameV.getDIEString().getString();
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> + } else
> + BTFType.name_off = 0;
> +
> + for (auto &ChildDie : Die.children()) {
> + struct btf_enum BTFEnum;
> + auto ChildNameV = ChildDie.findAttribute(dwarf::DW_AT_name);
> + auto Str = ChildNameV.getDIEString().getString();
> +
> + BTFEnum.name_off = Dwarf2BTF.addBTFString(Str);
> + auto ChildValueV =
> ChildDie.findAttribute(dwarf::DW_AT_const_value);
> + BTFEnum.val = (__s32)(ChildValueV.getDIEInteger().getValue());
> +
> + EnumValues.push_back(BTFEnum);
> + }
> +
> + auto typeEntry = make_unique<BTFTypeEntryEnum>(Id, BTFType,
> EnumValues);
> + Dwarf2BTF.addBTFTypeEntry(std::move(typeEntry));
> +}
> +
> +Die2BTFEntryArray::Die2BTFEntryArray(const DIE &Die) :
> + Die2BTFEntry(Die) {
> + BTFType.info = (BTF_KIND_ARRAY << 24);
> + BTFType.size = 0;
> +}
> +
> +void Die2BTFEntryArray::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> +
> + std::string Str;
> + if (NameV.getType() != DIEValue::isNone)
> + Str = NameV.getDIEString().getString();
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> +
> + auto &ArrayTypeDie =
> Die.findAttribute(dwarf::DW_AT_type).getDIEEntry().getEntry();
> + ArrayInfo.type = Dwarf2BTF.getTypeIndex(ArrayTypeDie);
> +
> + // The number of elements should count all subranges
> + unsigned Nelems = 1;
> + bool IsFirstSubrange = true;
> + for (auto &ChildDie : Die.children()) {
> + if (ChildDie.getTag() == dwarf::DW_TAG_subrange_type) {
> + if (IsFirstSubrange) {
> + auto TypeV = ChildDie.findAttribute(dwarf::DW_AT_type);
> + auto &TypeDie = TypeV.getDIEEntry().getEntry();
> + ArrayInfo.index_type = Dwarf2BTF.getTypeIndex(TypeDie);
> + IsFirstSubrange = false;
> + }
> + auto CountV = ChildDie.findAttribute(dwarf::DW_AT_count);
> + if (CountV.getType() == DIEValue::isNone) {
> + // array like a[] which essentially a pointer
> + Nelems = 0;
> + break;
> + }
> + Nelems *= (__u32)(CountV.getDIEInteger().getValue());
> + }
> + }
> + ArrayInfo.nelems = Nelems;
> +
> + auto TypeEntry = make_unique<BTFTypeEntryArray>(Id, BTFType,
> ArrayInfo);
> + Dwarf2BTF.addBTFTypeEntry(std::move(TypeEntry));
> +}
> +
> +Die2BTFEntryStruct::Die2BTFEntryStruct(const DIE &Die) :
> Die2BTFEntry(Die) {
> + // get btf_type.size
> + auto V = Die.findAttribute(dwarf::DW_AT_byte_size);
> + __u32 Size = V.getDIEInteger().getValue() & 0xffffffff;
> + auto Kind = Die2BTFEntry::getDieKind(Die);
> +
> + int Vlen = 0;
> + for (auto &ChildDie : Die.children())
> + if (ChildDie.getTag() == dwarf::DW_TAG_member)
> + Vlen++;
> +
> + BTFType.size = Size;
> + BTFType.info = (Kind << 24) | (Vlen & BTF_MAX_VLEN);
> +}
> +
> +void Die2BTFEntryStruct::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> +
> + if (NameV.getType() != DIEValue::isNone) {
> + auto Str = NameV.getDIEString().getString();
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> + } else
> + BTFType.name_off = 0;
> +
> +
> + for (auto &ChildDie : Die.children()) {
> + if (ChildDie.getTag() != dwarf::DW_TAG_member)
> + continue;
> +
> + struct btf_member BTFMember;
> + auto ChildNameV = ChildDie.findAttribute(dwarf::DW_AT_name);
> +
> + if (ChildNameV.getType() != DIEValue::isNone) {
> + auto Str = ChildNameV.getDIEString().getString();
> + BTFMember.name_off = Dwarf2BTF.addBTFString(Str);
> + } else
> + BTFMember.name_off = 0;
> +
> + auto TypeV = ChildDie.findAttribute(dwarf::DW_AT_type);
> + auto &TypeDie = TypeV.getDIEEntry().getEntry();
> + BTFMember.type = Dwarf2BTF.getTypeIndex(TypeDie);
> +
> + auto MemLocV =
> ChildDie.findAttribute(dwarf::DW_AT_data_member_location);
> + unsigned MemLoc = MemLocV.getDIEInteger().getValue() * 8;
> +
> + auto ByteSizeV = ChildDie.findAttribute(dwarf::DW_AT_byte_size);
> + if (ByteSizeV.getType() != DIEValue::isNone) {
> + unsigned ByteSize = ByteSizeV.getDIEInteger().getValue();
> + auto BitOffsetV =
> ChildDie.findAttribute(dwarf::DW_AT_bit_offset);
> + unsigned BitOffset = BitOffsetV.getDIEInteger().getValue();
> + auto BitSizeV = ChildDie.findAttribute(dwarf::DW_AT_bit_size);
> + unsigned BitSize = BitSizeV.getDIEInteger().getValue();
> + if (Dwarf2BTF.isLittleEndian())
> + MemLoc += ByteSize * 8 - BitSize - BitOffset;
> + else
> + MemLoc += BitOffset;
> + }
> + BTFMember.offset = MemLoc;
> +
> + Members.push_back(BTFMember);
> + }
> +
> + auto typeEntry = make_unique<BTFTypeEntryStruct>(Id, BTFType,
> Members);
> + Dwarf2BTF.addBTFTypeEntry(std::move(typeEntry));
> +}
> +
> +Die2BTFEntryFunc::Die2BTFEntryFunc(const DIE &Die) :
> Die2BTFEntry(Die) {
> + auto Kind = Die2BTFEntry::getDieKind(Die);
> +
> + int Vlen = 0;
> + for (auto &ChildDie : Die.children())
> + if (ChildDie.getTag() == dwarf::DW_TAG_formal_parameter)
> + Vlen++;
> +
> + BTFType.size = 0;
> + BTFType.info = (Kind << 24) | (Vlen & BTF_MAX_VLEN);
> +}
> +
> +void Die2BTFEntryFunc::completeData(class Dwarf2BTF &Dwarf2BTF) {
> + auto NameV = Die.findAttribute(dwarf::DW_AT_name);
> + if (NameV.getType() == DIEValue::isNone) {
> + BTFType.name_off = 0;
> + } else {
> + auto Str = NameV.getDIEString().getString();
> + BTFType.name_off = Dwarf2BTF.addBTFString(Str);
> + }
> +
> + auto RetTypeV = Die.findAttribute(dwarf::DW_AT_type);
> + if (RetTypeV.getType() != DIEValue::isNone) {
> + auto &TypeDie = RetTypeV.getDIEEntry().getEntry();
> + BTFType.type = Dwarf2BTF.getTypeIndex(TypeDie);
> + } else {
> + BTFType.type = 0;
> + }
> +
> + for (auto &ChildDie : Die.children()) {
> + if (ChildDie.getTag() == dwarf::DW_TAG_formal_parameter) {
> + auto TypeV =
> ChildDie.findAttribute(dwarf::DW_AT_abstract_origin);
> + if (TypeV.getType() != DIEValue::isNone) {
> + auto &AbsOriginDie = TypeV.getDIEEntry().getEntry();
> + assert(AbsOriginDie.getTag() ==
> dwarf::DW_TAG_formal_parameter);
> + TypeV = AbsOriginDie.findAttribute(dwarf::DW_AT_type);
> + } else {
> + TypeV = ChildDie.findAttribute(dwarf::DW_AT_type);
> + }
> + auto &TypeDie = TypeV.getDIEEntry().getEntry();
> + Parameters.push_back(Dwarf2BTF.getTypeIndex(TypeDie));
> + } else if (ChildDie.getTag() ==
> dwarf::DW_TAG_unspecified_parameters) {
> + Parameters.push_back(0);
> + }
> + }
> +
> + auto typeEntry = make_unique<BTFTypeEntryFunc>(Id, BTFType,
> Parameters);
> + Dwarf2BTF.addBTFTypeEntry(std::move(typeEntry));
> +
> + if (BTF_INFO_KIND(BTFType.info) == BTF_KIND_FUNC) {
> + auto LowPCV = Die.findAttribute(dwarf::DW_AT_low_pc);
> + if (LowPCV.getType() != DIEValue::isNone) {
> + const MCSymbol *Label = LowPCV.getDIELabel().getValue();
> + BTFFuncInfo FuncInfo;
> + unsigned SecNameOff;
> +
> + FuncInfo.Label = Label;
> + FuncInfo.TypeId = Id;
> + if (Label->isInSection()) {
> + MCSection &Section = Label->getSection();
> + MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
> + assert(SectionELF);
> + SecNameOff =
> Dwarf2BTF.addBTFString(SectionELF->getSectionName().str());
> + } else {
> + SecNameOff = Dwarf2BTF.addBTFString(".text");
> + }
> + Dwarf2BTF.addBTFFuncInfo(SecNameOff, FuncInfo);
> + }
> + }
> +}
> +
> +Dwarf2BTF::Dwarf2BTF(MCContext &Context, bool IsLittleEndian)
> + : OuterCtx(Context), IsLE(IsLittleEndian) {
> + BTFContext = make_unique<MCBTFContext>();
> +}
> +
> +void Dwarf2BTF::addTypeEntry(const DIE &Die) {
> + for (auto &ChildDie : Die.children())
> + addTypeEntry(ChildDie);
> + if (Die2BTFEntry::shouldSkipDie(Die))
> + return;
> + auto Kind = Die2BTFEntry::getDieKind(Die);
> + if (Kind != BTF_KIND_UNKN) {
> + auto TypeEntry = Die2BTFEntry::dieToBTFTypeEntry(Die);
> + if (TypeEntry != nullptr) {
> + TypeEntry->setId(TypeEntries.size() + 1);
> + DieToIdMap[const_cast<DIE*>(&Die)] = TypeEntry->getId();
> + TypeEntries.push_back(std::move(TypeEntry));
> + }
> + }
> +}
> +
> +void Dwarf2BTF::addBTFTypeEntry(std::unique_ptr<BTFTypeEntry> Entry) {
> + BTFContext->addTypeEntry(std::move(Entry));
> +}
> +
> +void Dwarf2BTF::completeData() {
> + BTFContext->addString("\0");
> +
> + for (auto &TypeEntry : TypeEntries)
> + TypeEntry->completeData(*this);
> +}
> +
> +void Dwarf2BTF::addDwarfCU(DwarfUnit *TheU) {
> + DIE &CuDie = TheU->getUnitDie();
> +
> + assert((CuDie.getTag() == dwarf::DW_TAG_compile_unit) &&
> + "Not a compile unit");
> + addTypeEntry(CuDie);
> +}
> +
> +void Dwarf2BTF::finish() {
> + completeData();
> + OuterCtx.setBTFContext(std::move(BTFContext));
> +}
> +
> +}
>
> Added: llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.h?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_Dwarf2BTF.h-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=tTn4c_h2moTM8DNUOwQVGk8A5HmecvZQhDCTxdlF7CQ&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.h (added)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/Dwarf2BTF.h Fri Oct 12
> 10:01:46 2018
> @@ -0,0 +1,134 @@
> +//===- Dwarf2BTF.h -------------------------------------------- *-
> C++ --*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARF2BTF_H
> +#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARF2BTF_H
> +
> +#include "DwarfUnit.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/CodeGen/AsmPrinter.h"
> +#include "llvm/CodeGen/DIE.h"
> +#include "llvm/MC/MCBTFContext.h"
> +#include <map>
> +
> +namespace llvm {
> +
> +class Dwarf2BTF;
> +class MCBTFContext;
> +
> +#define BTF_INVALID_ENCODING 0xff
> +
> +class Die2BTFEntry {
> +protected:
> + const DIE &Die;
> + size_t Id; /* type index in the BTF list, started from 1 */
> + struct btf_type BTFType;
> +
> +public:
> + // Return desired BTF_KIND for the Die, return BTF_KIND_UNKN for
> + // invalid/unsupported Die
> + static unsigned char getDieKind(const DIE &Die);
> +
> + // Return proper BTF_INT_ENCODING of a basetype.
> + // Return BTF_INVALID_ENCODING for unsupported (float, etc.)
> + static unsigned char getBaseTypeEncoding(const DIE &Die);
> +
> + // Return whether this Die should be skipped.
> + // We currently skip unsupported data type (e.g. float)
> + // and references to unsupported types
> + static bool shouldSkipDie(const DIE &Die);
> +
> + static std::unique_ptr<Die2BTFEntry> dieToBTFTypeEntry(const DIE
> &Die);
> +
> + Die2BTFEntry(const DIE &Die);
> + void setId(size_t Id) { this->Id = Id; }
> + size_t getId() { return Id; }
> + virtual void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +// BTF_KIND_INT
> +class Die2BTFEntryInt : public Die2BTFEntry {
> + __u32 IntVal; // encoding, offset, bits
> +
> +public:
> + Die2BTFEntryInt(const DIE &Die);
> + void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +// BTF_KIND_ENUM
> +class Die2BTFEntryEnum : public Die2BTFEntry {
> + std::vector<struct btf_enum> EnumValues;
> +
> +public:
> + Die2BTFEntryEnum(const DIE &Die);
> + void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +// BTF_KIND_ARRAY
> +class Die2BTFEntryArray : public Die2BTFEntry {
> + struct btf_array ArrayInfo;
> +
> +public:
> + Die2BTFEntryArray(const DIE &Die);
> + void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +// BTF_KIND_STRUCT and BTF_KIND_UNION
> +class Die2BTFEntryStruct : public Die2BTFEntry {
> + std::vector<struct btf_member> Members;
> +
> +public:
> + Die2BTFEntryStruct(const DIE &Die);
> + void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +// BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO
> +class Die2BTFEntryFunc : public Die2BTFEntry {
> + std::vector<__u32> Parameters;
> +
> +public:
> + Die2BTFEntryFunc(const DIE &Die);
> + void completeData(class Dwarf2BTF &Dwarf2BTF);
> +};
> +
> +class Dwarf2BTF {
> + std::vector<std::unique_ptr<Die2BTFEntry>> TypeEntries;
> + std::map<DIE*, size_t> DieToIdMap;
> + std::unique_ptr<MCBTFContext> BTFContext;
> + MCContext &OuterCtx;
> + bool IsLE;
> +
> +public:
> + Dwarf2BTF(MCContext &Context, bool IsLittleEndian);
> + bool isLittleEndian() { return IsLE; }
> + void addDwarfCU(DwarfUnit *TheU);
> + void finish();
> + __u32 getTypeIndex(DIE &Die) {
> + DIE *DiePtr = const_cast<DIE*>(&Die);
> + assert((DieToIdMap.find(DiePtr) != DieToIdMap.end()) &&
> + "Die not added to in the BTFContext");
> + return DieToIdMap[DiePtr];
> + }
> + size_t addBTFString(std::string S) {
> + return BTFContext->addString(S);
> + }
> + void addBTFTypeEntry(std::unique_ptr<BTFTypeEntry> Entry);
> + void addBTFFuncInfo(unsigned SecNameOff, BTFFuncInfo FuncInfo) {
> + BTFContext->addFuncInfo(SecNameOff, FuncInfo);
> + }
> +
> +private:
> + void addTypeEntry(const DIE &Die);
> + bool alreadyAdded(DIE &Die) {
> + return DieToIdMap.find(const_cast<DIE*>(&Die)) != DieToIdMap.end();
> + }
> + void completeData();
> +};
> +
> +}
> +#endif
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_DwarfDebug.cpp-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=qYF-VBxaY1_53jfaKjlKiVuooGdELQ73MGuN7PwHAfc&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Oct 12
> 10:01:46 2018
> @@ -971,6 +971,10 @@ void DwarfDebug::endModule() {
> // Emit the pubnames and pubtypes sections if requested.
> emitDebugPubSections();
>
> + const Triple &TT = Asm->TM.getTargetTriple();
> + if (TT.getArch() == Triple::bpfel || TT.getArch() == Triple::bpfeb)
> + emitBTFSection(TT.getArch() == Triple::bpfel);
> +
> // clean up.
> // FIXME: AbstractVariables.clear();
> }
> @@ -2455,6 +2459,12 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoL
> return &SplitTypeUnitFileTable;
> }
>
> +void DwarfDebug::emitBTFSection(bool IsLittleEndian) {
> + DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
> +
> + Holder.emitBTFSection(IsLittleEndian);
> +}
> +
> uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) {
> MD5 Hash;
> Hash.update(Identifier);
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_DwarfDebug.h-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=TWeB3v76T2OO5qo-r0nFmHO6y42ksuWZV9xD1oydqi0&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Fri Oct 12
> 10:01:46 2018
> @@ -567,6 +567,9 @@ class DwarfDebug : public DebugHandlerBa
> /// Emit the reference to the section.
> void emitSectionReference(const DwarfCompileUnit &CU);
>
> + // Emit the BTF sections
> + void emitBTFSection(bool IsLittleEndian);
> +
> protected:
> /// Gather pre-function debug information.
> void beginFunctionImpl(const MachineFunction *MF) override;
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_DwarfFile.cpp-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=eyh9i6VfwONl4J52slw7FZdOI-juVRZHMWU4oMMi_nE&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp Fri Oct 12
> 10:01:46 2018
> @@ -7,6 +7,7 @@
> //
> //===----------------------------------------------------------------------===//
>
> +#include "Dwarf2BTF.h"
> #include "DwarfFile.h"
> #include "DwarfCompileUnit.h"
> #include "DwarfDebug.h"
> @@ -15,6 +16,8 @@
> #include "llvm/CodeGen/AsmPrinter.h"
> #include "llvm/CodeGen/DIE.h"
> #include "llvm/IR/DebugInfoMetadata.h"
> +#include "llvm/MC/MCBTFContext.h"
> +#include "llvm/MC/MCContext.h"
> #include "llvm/MC/MCStreamer.h"
> #include <algorithm>
> #include <cstdint>
> @@ -88,6 +91,13 @@ void DwarfFile::emitStrings(MCSection *S
> StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets);
> }
>
> +void DwarfFile::emitBTFSection(bool IsLittleEndian) {
> + Dwarf2BTF Dwarf2BTF(Asm->OutContext, IsLittleEndian);
> + for (auto &TheU : CUs)
> + Dwarf2BTF.addDwarfCU(TheU.get());
> + Dwarf2BTF.finish();
> +}
> +
> bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
> auto &ScopeVars = ScopeVariables[LS];
> const DILocalVariable *DV = Var->getVariable();
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_DwarfFile.h-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=uH70gCPd_6hTvrCtp_keRAE75oAU6RdnTh_nu3HU--4&e=>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h Fri Oct 12
> 10:01:46 2018
> @@ -114,6 +114,9 @@ public:
> void emitStrings(MCSection *StrSection, MCSection *OffsetSection
> = nullptr,
> bool UseRelativeOffsets = false);
>
> + // Emit all data for the BTF section
> + void emitBTFSection(bool IsLittleEndian);
> +
> /// Returns the string pool.
> DwarfStringPool &getStringPool() { return StrPool; }
>
>
> Modified: llvm/trunk/lib/MC/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_CMakeLists.txt-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=JfUaTcv8Z1zc4lJkWGVLIy7R3VmgypIecZkpLcqYRkQ&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/CMakeLists.txt (original)
> +++ llvm/trunk/lib/MC/CMakeLists.txt Fri Oct 12 10:01:46 2018
> @@ -10,11 +10,13 @@ add_llvm_library(LLVMMC
> MCAsmMacro.cpp
> MCAsmStreamer.cpp
> MCAssembler.cpp
> + MCBTFContext.cpp
> MCCodeEmitter.cpp
> MCCodePadder.cpp
> MCCodeView.cpp
> MCContext.cpp
> MCDwarf.cpp
> + MCDwarf2BTF.cpp
> MCELFObjectTargetWriter.cpp
> MCELFStreamer.cpp
> MCExpr.cpp
>
> Added: llvm/trunk/lib/MC/MCBTFContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCBTFContext.cpp?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCBTFContext.cpp-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=IxYJvQRHZhJ1s8XoyOOIS-8mNbj0j5HZrlt5Vl_5e90&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCBTFContext.cpp (added)
> +++ llvm/trunk/lib/MC/MCBTFContext.cpp Fri Oct 12 10:01:46 2018
> @@ -0,0 +1,235 @@
> +//===- lib/MC/MCBTFContext.cpp - Machine Code BTF Context
> -----------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCBTFContext.h"
> +#include "llvm/MC/MCObjectFileInfo.h"
> +#include "llvm/MC/MCObjectStreamer.h"
> +#include "llvm/MC/MCSymbol.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include <cstdlib>
> +#include <tuple>
> +#include <utility>
> +
> +using namespace llvm;
> +
> +#define DEBUG_TYPE "btf"
> +
> +void MCBTFContext::addTypeEntry(std::unique_ptr<BTFTypeEntry> Entry) {
> + TypeEntries.push_back(std::move(Entry));
> +}
> +
> +void MCBTFContext::dump(raw_ostream &OS) {
> + OS << "Type Table:\n";
> + for (size_t i = 0; i < TypeEntries.size(); i++) {
> + auto TypeEntry = TypeEntries[i].get();
> + TypeEntry->print(OS, *this);
> + }
> +
> + OS << "\nString Table:\n";
> + StringTable.showTable(OS);
> +
> + OS << "\nFuncInfo Table:\n";
> + for (auto &FuncSec : FuncInfoTable) {
> + OS << "sec_name_off=" << FuncSec.first << "\n";
> + for (auto &FuncInfo : FuncSec.second) {
> + OS << "\tinsn_offset=<Omitted> type_id="
> + << FuncInfo.TypeId << "\n";
> + }
> + }
> +
> + OS << "\nLineInfo Table:\n";
> + for (auto &LineSec : LineInfoTable) {
> + OS << "sec_name_off=" << LineSec.first << "\n";
> + for (auto &LineInfo : LineSec.second) {
> + OS << "\tinsn_offset=<Omitted> file_name_off="
> + << LineInfo.FileNameOff
> + << " line_off=" << LineInfo.LineOff
> + << " line_num=" << LineInfo.LineNum
> + << " column_num=" << LineInfo.ColumnNum
> + << "\n";
> + }
> + }
> +}
> +
> +void MCBTFContext::emitCommonHeader(MCObjectStreamer *MCOS) {
> + MCOS->EmitIntValue(BTF_MAGIC, 2);
> + MCOS->EmitIntValue(BTF_VERSION, 1);
> + MCOS->EmitIntValue(0, 1);
> +}
> +
> +void MCBTFContext::emitBTFSection(MCObjectStreamer *MCOS) {
> + MCContext &context = MCOS->getContext();
> + MCOS->SwitchSection(context.getObjectFileInfo()->getBTFSection());
> +
> + // emit header
> + emitCommonHeader(MCOS);
> + MCOS->EmitIntValue(sizeof(struct btf_header), 4);
> +
> + uint32_t type_len = 0, str_len;
> + for (auto &TypeEntry : TypeEntries)
> + type_len += TypeEntry->getSize();
> + str_len = StringTable.getSize();
> +
> + MCOS->EmitIntValue(0, 4);
> + MCOS->EmitIntValue(type_len, 4);
> + MCOS->EmitIntValue(type_len, 4);
> + MCOS->EmitIntValue(str_len, 4);
> +
> + // emit type table
> + for (auto &TypeEntry: TypeEntries)
> + TypeEntry->emitData(MCOS);
> +
> + // emit string table
> + for (auto &S : StringTable.getTable()) {
> + for (auto C : S)
> + MCOS->EmitIntValue(C, 1);
> + MCOS->EmitIntValue('\0', 1);
> + }
> +}
> +
> +void MCBTFContext::emitBTFExtSection(MCObjectStreamer *MCOS) {
> + MCContext &context = MCOS->getContext();
> + MCOS->SwitchSection(context.getObjectFileInfo()->getBTFExtSection());
> +
> + // emit header
> + emitCommonHeader(MCOS);
> + MCOS->EmitIntValue(sizeof(struct btf_ext_header), 4);
> +
> + uint32_t func_len = 0, line_len = 0;
> + for (auto &FuncSec : FuncInfoTable) {
> + func_len += sizeof(struct btf_sec_func_info);
> + func_len += FuncSec.second.size() * sizeof(struct bpf_func_info);
> + }
> + for (auto &LineSec : LineInfoTable) {
> + line_len += sizeof(struct btf_sec_line_info);
> + line_len += LineSec.second.size() * sizeof(struct bpf_line_info);
> + }
> +
> + MCOS->EmitIntValue(0, 4);
> + MCOS->EmitIntValue(func_len, 4);
> + MCOS->EmitIntValue(func_len, 4);
> + MCOS->EmitIntValue(line_len, 4);
> +
> + // emit func_info table
> + for (const auto &FuncSec : FuncInfoTable) {
> + MCOS->EmitIntValue(FuncSec.first, 4);
> + MCOS->EmitIntValue(FuncSec.second.size(), 4);
> + for (const auto &FuncInfo : FuncSec.second) {
> + MCOS->EmitBTFAdvanceLineAddr(FuncInfo.Label, 4);
> + MCOS->EmitIntValue(FuncInfo.TypeId, 4);
> + }
> + }
> +
> + // emit line_info table
> + for (const auto &LineSec : LineInfoTable) {
> + MCOS->EmitIntValue(LineSec.first, 4);
> + MCOS->EmitIntValue(LineSec.second.size(), 4);
> + for (const auto &LineInfo : LineSec.second) {
> + MCOS->EmitBTFAdvanceLineAddr(LineInfo.Label, 4);
> + MCOS->EmitIntValue(LineInfo.FileNameOff, 4);
> + MCOS->EmitIntValue(LineInfo.LineOff, 4);
> + MCOS->EmitIntValue(LineInfo.LineNum << 10 |
> LineInfo.ColumnNum, 4);
> + }
> + }
> +}
> +
> +void MCBTFContext::emitAll(MCObjectStreamer *MCOS) {
> + LLVM_DEBUG(dump(dbgs()));
> + emitBTFSection(MCOS);
> + emitBTFExtSection(MCOS);
> +}
> +
> +void BTFTypeEntry::print(raw_ostream &OS, MCBTFContext& MCBTFContext) {
> + OS << "[" << Id << "] "
> + << btf_kind_str[BTF_INFO_KIND(BTFType.info)]
> + << " name_off=" << BTFType.name_off
> + << " info=" << format("0x%08lx", BTFType.info)
> + << " size/type=" << BTFType.size << "\n";
> +}
> +
> +void BTFTypeEntry::emitData(MCObjectStreamer *MCOS) {
> + MCOS->EmitIntValue(BTFType.name_off, 4);
> + MCOS->EmitIntValue(BTFType.info, 4);
> + MCOS->EmitIntValue(BTFType.size, 4);
> +}
> +
> +void BTFTypeEntryInt::print(raw_ostream &OS, MCBTFContext&
> MCBTFContext) {
> + BTFTypeEntry::print(OS, MCBTFContext);
> + OS << "\tdesc=" << format("0x%08lx", IntVal) << "\n";
> +}
> +
> +void BTFTypeEntryInt::emitData(MCObjectStreamer *MCOS) {
> + BTFTypeEntry::emitData(MCOS);
> + MCOS->EmitIntValue(IntVal, 4);
> +}
> +
> +void BTFTypeEntryEnum::print(raw_ostream &OS, MCBTFContext&
> MCBTFContext) {
> + BTFTypeEntry::print(OS, MCBTFContext);
> + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) {
> + auto &EnumValue = EnumValues[i];
> + OS << "\tname_off=" << EnumValue.name_off
> + << " value=" << EnumValue.val << "\n";
> + }
> +}
> +
> +void BTFTypeEntryEnum::emitData(MCObjectStreamer *MCOS) {
> + BTFTypeEntry::emitData(MCOS);
> + for (auto &EnumValue : EnumValues) {
> + MCOS->EmitIntValue(EnumValue.name_off, 4);
> + MCOS->EmitIntValue(EnumValue.val, 4);
> + }
> +}
> +
> +void BTFTypeEntryArray::print(raw_ostream &OS, MCBTFContext&
> MCBTFContext) {
> + BTFTypeEntry::print(OS, MCBTFContext);
> + OS << "\telem_type=" << format("0x%08lx", ArrayInfo.type)
> + << " index_type=" << format("0x%08lx", ArrayInfo.index_type)
> + << " num_element=" << ArrayInfo.nelems << "\n";
> +}
> +
> +void BTFTypeEntryArray::emitData(MCObjectStreamer *MCOS) {
> + BTFTypeEntry::emitData(MCOS);
> + MCOS->EmitIntValue(ArrayInfo.type, 4);
> + MCOS->EmitIntValue(ArrayInfo.index_type, 4);
> + MCOS->EmitIntValue(ArrayInfo.nelems, 4);
> +}
> +
> +void BTFTypeEntryStruct::print(raw_ostream &OS, MCBTFContext&
> MCBTFContext) {
> + BTFTypeEntry::print(OS, MCBTFContext);
> + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) {
> + auto &Member = Members[i];
> + OS << "\tname_off=" << Member.name_off
> + << " type=" << Member.type
> + << " bit_offset=" << Member.offset << "\n";
> + }
> +}
> +
> +void BTFTypeEntryStruct::emitData(MCObjectStreamer *MCOS) {
> + BTFTypeEntry::emitData(MCOS);
> + for (auto &Member : Members) {
> + MCOS->EmitIntValue(Member.name_off, 4);
> + MCOS->EmitIntValue(Member.type, 4);
> + MCOS->EmitIntValue(Member.offset, 4);
> + }
> +}
> +
> +void BTFTypeEntryFunc::print(raw_ostream &OS, MCBTFContext&
> MCBTFContext) {
> + BTFTypeEntry::print(OS, MCBTFContext);
> + for (size_t i = 0; i < BTF_INFO_VLEN(BTFType.info); i++) {
> + auto Parameter = Parameters[i];
> + OS << "\tparam_type=" << Parameter << "\n";
> + }
> +}
> +
> +void BTFTypeEntryFunc::emitData(MCObjectStreamer *MCOS) {
> + BTFTypeEntry::emitData(MCOS);
> + for (auto &Parameter: Parameters)
> + MCOS->EmitIntValue(Parameter, 4);
> +}
>
> Modified: llvm/trunk/lib/MC/MCContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCContext.cpp-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=X5TKFMkQkWdHTdYLn9OUSIuv_mb_69h5raGftXgAm2s&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCContext.cpp (original)
> +++ llvm/trunk/lib/MC/MCContext.cpp Fri Oct 12 10:01:46 2018
> @@ -17,6 +17,7 @@
> #include "llvm/BinaryFormat/COFF.h"
> #include "llvm/BinaryFormat/ELF.h"
> #include "llvm/MC/MCAsmInfo.h"
> +#include "llvm/MC/MCBTFContext.h"
> #include "llvm/MC/MCCodeView.h"
> #include "llvm/MC/MCDwarf.h"
> #include "llvm/MC/MCExpr.h"
> @@ -60,7 +61,7 @@ MCContext::MCContext(const MCAsmInfo *ma
> : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri),
> MOFI(mofi),
> Symbols(Allocator), UsedNames(Allocator),
> CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
> - AutoReset(DoAutoReset) {
> + AutoReset(DoAutoReset), BTFCtx(nullptr) {
> SecureLogFile = AsSecureLogFileName;
>
> if (SrcMgr && SrcMgr->getNumBuffers())
> @@ -114,6 +115,14 @@ void MCContext::reset() {
> GenDwarfFileNumber = 0;
>
> HadError = false;
> + BTFCtx.reset();
> +}
> +
> +//===----------------------------------------------------------------------===//
> +// BTFCtx Manipulation
> +//===----------------------------------------------------------------------===//
> +void MCContext::setBTFContext(std::unique_ptr<MCBTFContext> Ctx) {
> + BTFCtx = std::move(Ctx);
> }
>
> //===----------------------------------------------------------------------===//
>
> Added: llvm/trunk/lib/MC/MCDwarf2BTF.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf2BTF.cpp?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCDwarf2BTF.cpp-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=zQQNlVwatmz8Huf4KI4onn4eOdTxGtQMetHXkM2IfIQ&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCDwarf2BTF.cpp (added)
> +++ llvm/trunk/lib/MC/MCDwarf2BTF.cpp Fri Oct 12 10:01:46 2018
> @@ -0,0 +1,99 @@
> +//===- MCDwarf2BTF.cpp ---------------------------------------- *-
> C++ --*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "MCDwarf2BTF.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/MC/MCAsmInfo.h"
> +#include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCObjectStreamer.h"
> +#include "llvm/MC/MCSection.h"
> +#include "llvm/MC/MCSectionELF.h"
> +#include "llvm/MC/MCBTFContext.h"
> +#include "llvm/Support/Endian.h"
> +#include "llvm/Support/EndianStream.h"
> +#include <fstream>
> +
> +using namespace llvm;
> +
> +void MCDwarf2BTF::addFiles(MCObjectStreamer *MCOS, std::string
> &FileName,
> + std::vector<FileContent> &Files) {
> + std::vector<std::string> Content;
> +
> + std::ifstream Inputfile(FileName);
> + std::string Line;
> + Content.push_back(Line); // line 0 for empty string
> + while (std::getline(Inputfile, Line))
> + Content.push_back(Line);
> +
> + Files.push_back(FileContent(FileName, Content));
> +}
> +
> +void MCDwarf2BTF::addLines(MCObjectStreamer *MCOS, StringRef
> &SectionName,
> + std::vector<FileContent> &Files,
> + const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
> + MCContext &Context = MCOS->getContext();
> + auto &BTFCxt = Context.getBTFContext();
> +
> + unsigned SecNameOff = BTFCxt->addString(SectionName.str());
> + for (const MCDwarfLineEntry &LineEntry : LineEntries) {
> + BTFLineInfo LineInfo;
> + unsigned FileNum = LineEntry.getFileNum();
> + unsigned Line = LineEntry.getLine();
> +
> + LineInfo.Label = LineEntry.getLabel();
> + if (FileNum < Files.size()) {
> + LineInfo.FileNameOff = BTFCxt->addString(Files[FileNum].first);
> + if (Line < Files[FileNum].second.size())
> + LineInfo.LineOff =
> BTFCxt->addString(Files[FileNum].second[Line]);
> + else
> + LineInfo.LineOff = 0;
> + } else {
> + LineInfo.FileNameOff = 0;
> + LineInfo.LineOff = 0;
> + }
> + LineInfo.LineNum = Line;
> + LineInfo.ColumnNum = LineEntry.getColumn();
> + BTFCxt->addLineInfo(SecNameOff, LineInfo);
> + }
> +}
> +
> +void MCDwarf2BTF::addDwarfLineInfo(MCObjectStreamer *MCOS) {
> + MCContext &Context = MCOS->getContext();
> +
> + auto &LineTables = Context.getMCDwarfLineTables();
> + if (LineTables.empty())
> + return;
> +
> + for (const auto &CUIDTablePair : LineTables) {
> + std::vector<std::string> Dirs;
> + std::vector<FileContent> Files;
> +
> + for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs())
> + Dirs.push_back(Dir);
> + for (auto &File : CUIDTablePair.second.getMCDwarfFiles()) {
> + std::string FileName;
> + if (File.DirIndex == 0)
> + FileName = File.Name;
> + else
> + FileName = Dirs[File.DirIndex - 1] + "/" + File.Name;
> + MCDwarf2BTF::addFiles(MCOS, FileName, Files);
> + }
> + for (const auto &LineSec:
> CUIDTablePair.second.getMCLineSections().getMCLineEntries()) {
> + MCSection *Section = LineSec.first;
> + const MCLineSection::MCDwarfLineEntryCollection &LineEntries
> = LineSec.second;
> +
> + StringRef SectionName;
> + if (MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(Section))
> + SectionName = SectionELF->getSectionName();
> + else
> + return;
> + MCDwarf2BTF::addLines(MCOS, SectionName, Files, LineEntries);
> + }
> + }
> +}
>
> Added: llvm/trunk/lib/MC/MCDwarf2BTF.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf2BTF.h?rev=344366&view=auto
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCDwarf2BTF.h-3Frev-3D344366-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=ohSiVGkUloCLTn51H-a8CDqMvDwRGUgHOTdRW6Rdi24&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCDwarf2BTF.h (added)
> +++ llvm/trunk/lib/MC/MCDwarf2BTF.h Fri Oct 12 10:01:46 2018
> @@ -0,0 +1,29 @@
> +//===- MCDwarf2BTF.h ------------------------------------------ *-
> C++ --*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +#ifndef LLVM_LIB_MC_MCDWARF2BTF_H
> +#define LLVM_LIB_MC_MCDWARF2BTF_H
> +
> +#include "llvm/MC/MCDwarf.h"
> +
> +namespace llvm {
> +
> +using FileContent = std::pair<std::string, std::vector<std::string>>;
> +
> +class MCDwarf2BTF {
> +public:
> + static void addFiles(MCObjectStreamer *MCOS, std::string &FileName,
> + std::vector<FileContent> &Files);
> + static void addLines(MCObjectStreamer *MCOS, StringRef &SectionName,
> + std::vector<FileContent> &Files,
> + const MCLineSection::MCDwarfLineEntryCollection &LineEntries);
> + static void addDwarfLineInfo(MCObjectStreamer *MCOS);
> +};
> +
> +}
> +#endif
>
> Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCObjectFileInfo.cpp-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=sgg7fltnaSfmUdLwPlTclfQiQZKcl67IndJ1HWVOSxQ&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)
> +++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Fri Oct 12 10:01:46 2018
> @@ -468,6 +468,9 @@ void MCObjectFileInfo::initELFMCObjectFi
> Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
>
> StackSizesSection = Ctx->getELFSection(".stack_sizes",
> ELF::SHT_PROGBITS, 0);
> +
> + BTFSection = Ctx->getELFSection(".BTF", ELF::SHT_PROGBITS, 0);
> + BTFExtSection = Ctx->getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0);
> }
>
> void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
>
> Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=344366&r1=344365&r2=344366&view=diff
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_MC_MCObjectStreamer.cpp-3Frev-3D344366-26r1-3D344365-26r2-3D344366-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=34xoXClW8a67TaA5vbWJcnzS_Hwt8jO8BW0GA3UGmT8&e=>
> ==============================================================================
> --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Fri Oct 12 10:01:46 2018
> @@ -14,6 +14,7 @@
> #include "llvm/MC/MCCodeEmitter.h"
> #include "llvm/MC/MCCodeView.h"
> #include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCBTFContext.h"
> #include "llvm/MC/MCDwarf.h"
> #include "llvm/MC/MCExpr.h"
> #include "llvm/MC/MCObjectWriter.h"
> @@ -21,6 +22,7 @@
> #include "llvm/MC/MCSymbol.h"
> #include "llvm/Support/ErrorHandling.h"
> #include "llvm/Support/SourceMgr.h"
> +#include "MCDwarf2BTF.h"
> using namespace llvm;
>
> MCObjectStreamer::MCObjectStreamer(MCContext &Context,
> @@ -439,6 +441,31 @@ void MCObjectStreamer::EmitDwarfAdvanceF
> insert(new MCDwarfCallFrameFragment(*AddrDelta));
> }
>
> +void MCObjectStreamer::EmitBTFAdvanceLineAddr(const MCSymbol *Label,
> + unsigned Size) {
> + const MCExpr *Value = MCSymbolRefExpr::create(Label, getContext());
> + MCDataFragment *DF = getOrCreateDataFragment();
> +
> + // Avoid fixups when possible.
> + int64_t AbsValue;
> + SMLoc Loc;
> +
> + if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
> + if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
> + getContext().reportError(
> + Loc, "value evaluated as " + Twine(AbsValue) + " is out
> of range.");
> + return;
> + }
> + EmitIntValue(AbsValue, Size);
> + return;
> + }
> +
> + DF->getFixups().push_back(
> + MCFixup::create(DF->getContents().size(), Value,
> + MCFixup::getKindForSize(Size, false), Loc));
> + DF->getContents().resize(DF->getContents().size() + Size, 0);
> +}
> +
> void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId,
> unsigned FileNo,
> unsigned Line, unsigned
> Column,
> bool PrologueEnd, bool
> IsStmt,
> @@ -688,6 +715,13 @@ void MCObjectStreamer::FinishImpl() {
> // Dump out the dwarf file & directory tables and line tables.
> MCDwarfLineTable::Emit(this,
> getAssembler().getDWARFLinetableParams());
>
> + auto &BTFCtx = getContext().getBTFContext();
> + if (BTFCtx) {
> + MCDwarf2BTF::addDwarfLineInfo(this);
> + BTFCtx->emitAll(this);
> + BTFCtx.reset();
> + }
> +
> flushPendingLabels();
> getAssembler().Finish();
> }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_llvm-2Dcommits&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=PoE9xQ4BuyXDSFwQeuwqkWtcE6FtuIvHeX-mkZ07v44&s=hxo35qX9M5IGMFbZpe2x4GHlegC0hrkQQ2mjPONX0i8&e=>
>
More information about the llvm-commits
mailing list