[llvm] r344366 - [BPF] Add BTF generation for BPF target

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 12 13:32:29 PDT 2018



On 10/12/18 10:57 AM, Zachary Turner wrote:
> Hello, please take more care next time in ensuring that the patch will 
> work on multiple platforms.  For example, #include <linux/types.h> is 
> obviously going to break on any platform that isn't linux.

Completely sorry about this.

> 
> The other issue is C99 designated initializers, which are not supported 
> by all platforms.
> 
> In the future please use types like uint32_t instead of __u32 and don't 
> include platform specific headers.

Sorry about. Original thinking is to keep coding style/text close to
what linux code is at
https://github.com/torvalds/linux/blob/master/include/uapi/linux/btf.h
so future syncing is easier. But I completely understand LLVM code
itself should be consistent, so I will change that in the next
revision.


> 
> On Fri, Oct 12, 2018 at 10:04 AM 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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=iwBInPRzab0cDd1JWx9OAflW4MNOB_lx4p1v3uqSuWc&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=JCyu-CIMkOuR03EqFmWVVSMqFOEw3htnL1oOrqSw2Vw&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=kIObZgiTiIUa-SgiR7l03tnz6Z9ORLtjz2lZSTTlNDc&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=92hQPUKYB6DjpvKew9lkKNspi9y6ociua6m-b2biiZE&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> &params) :
>     +    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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=4wDtjMmSToEBReJQFmH_MGEj9h7ZAfwLX-B5BtusxFQ&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=rVeav4K8X-MSdcOllxqb67Ufvv8Cmlr-NSHcuRgj3P8&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=abP8kyC5KjoNWVYazinXQiNpDzTilkS_funYVcfbuZI&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=LvHL0glJh9UbSy-9fUoJR1Z-1MZeWhj1tL1eBET8cOg&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=nR47cwy-iPHbsz3oUHD459MxNvgIxrh5F9G4aFEgwCQ&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=nmg52O1rN-Dn87O6xav83SV_H3xrSnPhxkTZw03KE9Y&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=q1S_Ql5pP2xhTjilSbaAJ90duXhR9B2LNBwnr8tN5dc&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=V7I7bM2zLrp54snEplnbEJC3xmL-qMKKm7DsQAtl1Rk&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=1QKL5Teh_O_phaowUFQFdXGiMtqtMhLp3rJSJ9jNFSI&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=WfBpG3COYEkfeGxFkj1J-Sn5EIyWiu6TnwE1pdFBGDY&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=6_TzXa3nIe_fKQaEzUHc2PglB7gvjEIJtfTSUKgwr6U&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=QInDQk7_9G5IzDNG2xNiUiMCRASDbmFITe0WlrRVHxw&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=GYxRUEBKrBnvUmsve5fwmDHpCH_ZvZ8LHl6-9tepT-8&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=LRNni2kzTnPsPhXWzvwai59-KXLzdBP6URq2mKQVsCg&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=JsGO3Bodd4rSEWEXdXsGbHVnp2qei-IYKsfQLJeVG3Y&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=rBt8vKrUMlPFNW7CpnOyJikE0WCgdSIc5yjUFUjrP_4&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=B0tRDn7w4zqHajW9sgTWpagbEyGpJDoefe-L_TJnLG0&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=Gx2tS8IEBf-qo2yzRnYVmGCZ8gV3_kSZ_Yj6W_9E28Y&s=cr--oLLUp37IU072YWaLvxeHQmIB0r5mVsaC85Oa2yM&e=>
> 


More information about the llvm-commits mailing list