arch/arm64/kvm/hyp/nvhe/gen-hyprel.c

Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/kvm/hyp/nvhe/gen-hyprel.c
Extension
.c
Size
13068 bytes
Lines
463
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!(_lhs op _rhs)) {					\
			fatal_error("assertion " #lhs " " #op " " #rhs	\
				" failed (lhs=" fmt ", rhs=" fmt	\
				", line=%d)", _lhs, _rhs, __LINE__);	\
		}							\
	})

#define assert_eq(lhs, rhs, fmt)	assert_op(lhs, rhs, fmt, ==)
#define assert_ne(lhs, rhs, fmt)	assert_op(lhs, rhs, fmt, !=)
#define assert_lt(lhs, rhs, fmt)	assert_op(lhs, rhs, fmt, <)
#define assert_ge(lhs, rhs, fmt)	assert_op(lhs, rhs, fmt, >=)

/*
 * Return a pointer of a given type at a given offset from
 * the beginning of the ELF file.
 */
#define elf_ptr(type, off) ((type *)(elf.begin + (off)))

/* Iterate over all sections in the ELF. */
#define for_each_section(var) \
	for (var = elf.sh_table; var < elf.sh_table + elf16toh(elf.ehdr->e_shnum); ++var)

/* Iterate over all Elf64_Rela relocations in a given section. */
#define for_each_rela(shdr, var)					\
	for (var = elf_ptr(Elf64_Rela, elf64toh(shdr->sh_offset));	\
	     var < elf_ptr(Elf64_Rela, elf64toh(shdr->sh_offset) + elf64toh(shdr->sh_size)); var++)

/* True if a string starts with a given prefix. */
static inline bool starts_with(const char *str, const char *prefix)
{
	return memcmp(str, prefix, strlen(prefix)) == 0;
}

/* Returns a string containing the name of a given section. */
static inline const char *section_name(Elf64_Shdr *shdr)
{
	return elf.sh_string + elf32toh(shdr->sh_name);
}

/* Returns a pointer to the first byte of section data. */
static inline const char *section_begin(Elf64_Shdr *shdr)
{
	return elf_ptr(char, elf64toh(shdr->sh_offset));
}

/* Find a section by its offset from the beginning of the file. */
static inline Elf64_Shdr *section_by_off(Elf64_Off off)
{
	assert_ne(off, 0UL, "%lu");
	return elf_ptr(Elf64_Shdr, off);
}

/* Find a section by its index. */
static inline Elf64_Shdr *section_by_idx(uint16_t idx)
{
	assert_ne(idx, SHN_UNDEF, "%u");
	return &elf.sh_table[idx];
}

/*
 * Memory-map the given ELF file, perform sanity checks, and
 * populate global state.
 */
static void init_elf(const char *path)
{
	int fd, ret;
	struct stat stat;

	/* Store path in the global struct for error printing. */
	elf.path = path;

	/* Open the ELF file. */
	fd = open(path, O_RDONLY);
	if (fd < 0)
		fatal_perror("Could not open ELF file");

	/* Get status of ELF file to obtain its size. */
	ret = fstat(fd, &stat);
	if (ret < 0) {
		close(fd);
		fatal_perror("Could not get status of ELF file");
	}

	/* mmap() the entire ELF file read-only at an arbitrary address. */
	elf.begin = mmap(0, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (elf.begin == MAP_FAILED) {
		close(fd);
		fatal_perror("Could not mmap ELF file");
	}

Annotation

Implementation Notes