.llvm.callgraph Section Layout

The .llvm.callgraph section is used to store call graph information for each function. The section contains a series of records, with each record corresponding to a single function.

Per Function Record Layout

Each record in the .llvm.callgraph section has the following binary layout:

FieldTypeSize (bits)Description
Format Versionuint8_t8The version of the record format. The current version is 0.
Flagsuint8_t8A bitfield where: Bit 0 is set if the function is a potential indirect call target; Bit 1 is set if there are direct callees; Bit 2 is set if there are indirect callees. The remaining 5 bits are reserved.
Function Entry PCuintptr_t32/64The address of the function's entry point.
Function Type IDuint64_t64The type ID of the function. This field is non-zero if the function is a potential indirect call target and its type is known.
Number of Unique Direct CalleesULEB128VariableThe number of unique direct call destinations from this function. This field is only present if there is at least one direct callee.
Direct Callees Arrayuintptr_t[]VariableAn array of unique direct callee entry point addresses. This field is only present if there is at least one direct callee.
Number of Unique Indirect Target Type IDsULEB128VariableThe number of unique indirect call target type IDs. This field is only present if there is at least one indirect target type ID.
Indirect Target Type IDs Arrayuint64_t[]VariableAn array of unique indirect call target type IDs. This field is only present if there is at least one indirect target type ID.

Dumping with llvm-readobj

{option}llvm-readobj --call-graph-info prints the records of every SHT_LLVM_CALL_GRAPH section in a file. With {option}llvm-readobj --elf-output-style set to JSON, the output is a CallGraph array that holds one Function object per record. The default LLVM output style prints the same fields, with addresses and type IDs in hexadecimal. {program}llvm-readelf prints the same output with {option}llvm-readelf --call-graph-info.

Each function and direct callee is identified by exactly one of Address or Relocation. In a relocatable object file, the address fields hold placeholders, so each field is identified by the relocation that applies to it, as Relocation. In any other file, and for a field in a relocatable object file that doesn't have exactly one relocation, Address holds the value stored in the field. Either one may be accompanied by Names, the symbolization of that address for human readers.

Function Object

FieldTypeDescription
Namesarray of stringsThe symbolization of the function‘s entry address, similar to what llvm-symbolizer shows: the names of the function symbols defined at that address, demangled with {option}llvm-readobj --demangle. When Relocation is present, the address is the one that the relocation resolves to, within the symbol’s section. For human readers only, so it can differ from the relocation‘s SymbolName, for example when the relocation uses a section symbol. Omitted if there are none, for example when the relocation’s symbol is undefined.
AddressintegerThe value stored in the function entry PC field, which in executables and shared objects is the function's entry address. On ARM, the Thumb bit is cleared. Printed when Relocation is not.
RelocationobjectThe relocation that applies to the function entry PC field. See below. Printed instead of Address.
VersionintegerThe format version.
IsIndirectTargetbooleanWhether the function is a potential indirect call target.
TypeIDintegerThe function type ID.
DirectCalleesarray of objectsOne object per direct callee, with the same Names, Address and Relocation fields as the function. Callees identified by Address are listed once per address.
IndirectTypeIDsarray of integersThe indirect call target type IDs.

Relocation Object

FieldTypeDescription
SymbolIndexintegerThe symbol table index of the relocation's symbol, or 0 if it has none.
SymbolNamestringThe symbol's name exactly as given by st_name, never demangled. Omitted if the symbol has no name, such as an STT_SECTION symbol.
DemangledNamestringThe demangled form of SymbolName. Printed only with {option}llvm-readobj --demangle, and only when SymbolName is.
AddendintegerThe relocation addend. For relocations without an explicit addend, such as SHT_REL relocations, this is the value stored in the field. Omitted if zero.

Examples

A function in a shared object that calls foo and bar:

"CallGraph": [
  {
    "Function": {
      "Names": [
        "main"
      ],
      "Address": 6080,
      "Version": 0,
      "IsIndirectTarget": false,
      "TypeID": 0,
      "DirectCallees": [
        {
          "Names": [
            "foo"
          ],
          "Address": 6032
        },
        {
          "Names": [
            "bar"
          ],
          "Address": 6048
        }
      ],
      "IndirectTypeIDs": []
    }
  }
]

A function in a relocatable object file that calls a local function foo, a global function bar and an undefined function ext. The relocation for foo uses the .text section symbol, which has no name, so it has no SymbolName, but Names still shows foo. ext is not defined in the file, so it has no Names:

"CallGraph": [
  {
    "Function": {
      "Names": [
        "caller"
      ],
      "Relocation": {
        "SymbolIndex": 6,
        "SymbolName": "caller"
      },
      "Version": 0,
      "IsIndirectTarget": true,
      "TypeID": 9080559750644022485,
      "DirectCallees": [
        {
          "Names": [
            "foo"
          ],
          "Relocation": {
            "SymbolIndex": 2,
            "Addend": 48
          }
        },
        {
          "Names": [
            "bar"
          ],
          "Relocation": {
            "SymbolIndex": 4,
            "SymbolName": "bar"
          }
        },
        {
          "Relocation": {
            "SymbolIndex": 7,
            "SymbolName": "ext"
          }
        }
      ],
      "IndirectTypeIDs": []
    }
  }
]