tools/perf/util/llvm.c
Source file repositories/reference/linux-study-clean/tools/perf/util/llvm.c
File Facts
- System
- Linux kernel
- Corpus path
tools/perf/util/llvm.c- Extension
.c- Size
- 7438 bytes
- Lines
- 280
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
llvm.hannotate.hdebug.hdso.hmap.hnamespaces.hsrcline.hsymbol.herrno.hfcntl.hunistd.hlinux/zalloc.hllvm-c-helpers.hllvm-c/Disassembler.hllvm-c/Target.h
Detected Declarations
struct symbol_lookup_storagefunction free_llvm_inline_framesfunction llvm__addr2linefunction init_llvmfunction symbol_lookup_callbackfunction symbol__disassemble_llvm
Annotated Snippet
struct symbol_lookup_storage {
u64 branch_addr;
u64 pcrel_load_addr;
};
static const char *
symbol_lookup_callback(void *disinfo, uint64_t value,
uint64_t *ref_type,
uint64_t address __maybe_unused,
const char **ref __maybe_unused)
{
struct symbol_lookup_storage *storage = disinfo;
if (*ref_type == LLVMDisassembler_ReferenceType_In_Branch)
storage->branch_addr = value;
else if (*ref_type == LLVMDisassembler_ReferenceType_In_PCrel_Load)
storage->pcrel_load_addr = value;
*ref_type = LLVMDisassembler_ReferenceType_InOut_None;
return NULL;
}
#endif
int symbol__disassemble_llvm(const char *filename, struct symbol *sym,
struct annotate_args *args __maybe_unused)
{
#ifdef HAVE_LIBLLVM_SUPPORT
struct annotation *notes = symbol__annotation(sym);
struct map *map = args->ms->map;
struct dso *dso = map__dso(map);
u64 start = map__rip_2objdump(map, sym->start);
/* Malloc-ed buffer containing instructions read from disk. */
u8 *code_buf = NULL;
/* Pointer to code to be disassembled. */
const u8 *buf;
u64 buf_len;
u64 pc;
bool is_64bit;
char disasm_buf[2048];
size_t disasm_len;
struct disasm_line *dl;
LLVMDisasmContextRef disasm = NULL;
struct symbol_lookup_storage storage;
char *line_storage = NULL;
size_t line_storage_len = 0;
int ret = -1;
if (args->options->objdump_path)
return -1;
buf = dso__read_symbol(dso, filename, map, sym,
&code_buf, &buf_len, &is_64bit);
if (buf == NULL)
return errno;
init_llvm();
if (arch__is_x86(args->arch)) {
const char *triplet = is_64bit ? "x86_64-pc-linux" : "i686-pc-linux";
disasm = LLVMCreateDisasm(triplet, &storage, /*tag_type=*/0,
/*get_op_info=*/NULL, symbol_lookup_callback);
} else {
char triplet[64];
const char *features = NULL;
scnprintf(triplet, sizeof(triplet), "%s-linux-gnu",
args->arch->name);
if (args->arch->id.e_machine == EM_AARCH64)
features = "+all";
disasm = LLVMCreateDisasmCPUFeatures(triplet, /*cpu=*/"",
features, &storage,
/*tag_type=*/0,
/*get_op_info=*/NULL,
symbol_lookup_callback);
}
if (disasm == NULL)
goto err;
if (args->options->disassembler_style &&
!strcmp(args->options->disassembler_style, "intel"))
LLVMSetDisasmOptions(disasm,
LLVMDisassembler_Option_AsmPrinterVariant);
/*
* This needs to be set after AsmPrinterVariant, due to a bug in LLVM;
* setting AsmPrinterVariant makes a new instruction printer, making it
* forget about the PrintImmHex flag (which is applied before if both
* are given to the same call).
*/
LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_PrintImmHex);
Annotation
- Immediate include surface: `llvm.h`, `annotate.h`, `debug.h`, `dso.h`, `map.h`, `namespaces.h`, `srcline.h`, `symbol.h`.
- Detected declarations: `struct symbol_lookup_storage`, `function free_llvm_inline_frames`, `function llvm__addr2line`, `function init_llvm`, `function symbol_lookup_callback`, `function symbol__disassemble_llvm`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.