tools/perf/util/llvm-c-helpers.cpp

Source file repositories/reference/linux-study-clean/tools/perf/util/llvm-c-helpers.cpp

File Facts

System
Linux kernel
Corpus path
tools/perf/util/llvm-c-helpers.cpp
Extension
.cpp
Size
5166 bytes
Lines
197
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: tools
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (line_info.FileName == "<invalid>") {
			/* Match the convention of libbfd. */
			*file = nullptr;
		} else {
			/* The caller expects to get something it can free(). */
			*file = strdup(line_info.FileName.c_str());
			if (*file == nullptr)
				return 0;
		}
	}
	if (line)
		*line = line_info.Line;
	return 1;
}

extern "C"
int llvm_addr2line(const char *dso_name, u64 addr,
		   char **file, unsigned int *line,
		   bool unwind_inlines,
		   llvm_a2l_frame **inline_frames)
{
	LLVMSymbolizer *symbolizer = get_symbolizer();
	object::SectionedAddress sectioned_addr = {
		addr,
		object::SectionedAddress::UndefSection
	};

	if (unwind_inlines) {
		Expected<DIInliningInfo> res_or_err =
			symbolizer->symbolizeInlinedCode(dso_name,
							 sectioned_addr);
		if (!res_or_err)
			return 0;
		unsigned num_frames = res_or_err->getNumberOfFrames();
		if (num_frames == 0)
			return 0;

		if (extract_file_and_line(res_or_err->getFrame(0),
					  file, line) == 0)
			return 0;

		*inline_frames = (llvm_a2l_frame *)calloc(
			num_frames, sizeof(**inline_frames));
		if (*inline_frames == nullptr)
			return 0;

		for (unsigned i = 0; i < num_frames; ++i) {
			const DILineInfo &src = res_or_err->getFrame(i);

			llvm_a2l_frame &dst = (*inline_frames)[i];
			if (src.FileName == "<invalid>")
				/* Match the convention of libbfd. */
				dst.filename = nullptr;
			else
				dst.filename = strdup(src.FileName.c_str());
			dst.funcname = strdup(src.FunctionName.c_str());
			dst.line = src.Line;

			if (dst.filename == nullptr ||
			    dst.funcname == nullptr) {
				for (unsigned j = 0; j <= i; ++j) {
					zfree(&(*inline_frames)[j].filename);
					zfree(&(*inline_frames)[j].funcname);
				}
				zfree(inline_frames);
				return 0;
			}
		}

		return num_frames;

Annotation

Implementation Notes