tools/perf/util/symbol-minimal.c

Source file repositories/reference/linux-study-clean/tools/perf/util/symbol-minimal.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/symbol-minimal.c
Extension
.c
Size
7810 bytes
Lines
368
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (need_swap) {
			nhdr->n_namesz = bswap_32(nhdr->n_namesz);
			nhdr->n_descsz = bswap_32(nhdr->n_descsz);
			nhdr->n_type = bswap_32(nhdr->n_type);
		}

		namesz = NOTE_ALIGN(nhdr->n_namesz);
		descsz = NOTE_ALIGN(nhdr->n_descsz);

		ptr += sizeof(*nhdr);
		name = ptr;
		ptr += namesz;
		if (nhdr->n_type == NT_GNU_BUILD_ID &&
		    nhdr->n_namesz == sizeof("GNU")) {
			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
				size_t sz = min(size, descsz);
				memcpy(bid->data, ptr, sz);
				memset(bid->data + sz, 0, size - sz);
				bid->size = sz;
				return 0;
			}
		}
		ptr += descsz;
	}

	return -1;
}

int filename__read_debuglink(const char *filename __maybe_unused,
			     char *debuglink __maybe_unused,
			     size_t size __maybe_unused)
{
	return -1;
}

/*
 * Just try PT_NOTE header otherwise fails
 */
int filename__read_build_id(const char *filename, struct build_id *bid)
{
	int fd, ret = -1;
	bool need_swap = false, elf32;
	union {
		struct {
			Elf32_Ehdr ehdr32;
			Elf32_Phdr *phdr32;
		};
		struct {
			Elf64_Ehdr ehdr64;
			Elf64_Phdr *phdr64;
		};
	} hdrs;
	void *phdr, *buf = NULL;
	ssize_t phdr_size, ehdr_size, buf_size = 0;

	if (!filename)
		return -EFAULT;

	errno = 0;
	if (!is_regular_file(filename))
		return errno == 0 ? -EWOULDBLOCK : -errno;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return -1;

	if (read(fd, hdrs.ehdr32.e_ident, EI_NIDENT) != EI_NIDENT)
		goto out;

	if (memcmp(hdrs.ehdr32.e_ident, ELFMAG, SELFMAG) ||
	    hdrs.ehdr32.e_ident[EI_VERSION] != EV_CURRENT)
		goto out;

	need_swap = check_need_swap(hdrs.ehdr32.e_ident[EI_DATA]);
	elf32 = hdrs.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
	ehdr_size = (elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64)) - EI_NIDENT;

	if (read(fd,
		 (elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64) + EI_NIDENT,
		 ehdr_size) != ehdr_size)
		goto out;

	if (need_swap) {
		if (elf32) {
			hdrs.ehdr32.e_phoff = bswap_32(hdrs.ehdr32.e_phoff);
			hdrs.ehdr32.e_phentsize = bswap_16(hdrs.ehdr32.e_phentsize);
			hdrs.ehdr32.e_phnum = bswap_16(hdrs.ehdr32.e_phnum);
		} else {
			hdrs.ehdr64.e_phoff = bswap_64(hdrs.ehdr64.e_phoff);
			hdrs.ehdr64.e_phentsize = bswap_16(hdrs.ehdr64.e_phentsize);

Annotation

Implementation Notes