scripts/elf-parse.c

Source file repositories/reference/linux-study-clean/scripts/elf-parse.c

File Facts

System
Linux kernel
Corpus path
scripts/elf-parse.c
Extension
.c
Size
4795 bytes
Lines
199
Domain
Support Tooling And Documentation
Bucket
scripts
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

#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include "elf-parse.h"

struct elf_funcs elf_parser;

/*
 * Get the whole file as a programming convenience in order to avoid
 * malloc+lseek+read+free of many pieces.  If successful, then mmap
 * avoids copying unused pieces; else just read the whole file.
 * Open for both read and write.
 */
static void *map_file(char const *fname, size_t *size)
{
	int fd;
	struct stat sb;
	void *addr = NULL;

	fd = open(fname, O_RDWR);
	if (fd < 0) {
		perror(fname);
		return NULL;
	}
	if (fstat(fd, &sb) < 0) {
		perror(fname);
		goto out;
	}
	if (!S_ISREG(sb.st_mode)) {
		fprintf(stderr, "not a regular file: %s\n", fname);
		goto out;
	}

	addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (addr == MAP_FAILED) {
		fprintf(stderr, "Could not mmap file: %s\n", fname);
		goto out;
	}

	*size = sb.st_size;

out:
	close(fd);
	return addr;
}

static int elf_parse(const char *fname, void *addr, uint32_t types)
{
	Elf_Ehdr *ehdr = addr;
	uint16_t type;

	switch (ehdr->e32.e_ident[EI_DATA]) {
	case ELFDATA2LSB:
		elf_parser.r	= rle;
		elf_parser.r2	= r2le;
		elf_parser.r8	= r8le;
		elf_parser.w	= wle;
		elf_parser.w8	= w8le;
		break;
	case ELFDATA2MSB:
		elf_parser.r	= rbe;
		elf_parser.r2	= r2be;
		elf_parser.r8	= r8be;
		elf_parser.w	= wbe;
		elf_parser.w8	= w8be;
		break;
	default:
		fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
			ehdr->e32.e_ident[EI_DATA], fname);
		return -1;
	}

	if (memcmp(ELFMAG, ehdr->e32.e_ident, SELFMAG) != 0 ||
	    ehdr->e32.e_ident[EI_VERSION] != EV_CURRENT) {
		fprintf(stderr, "unrecognized ELF file %s\n", fname);
		return -1;
	}

	type = elf_parser.r2(&ehdr->e32.e_type);
	if (!((1 << type) & types)) {
		fprintf(stderr, "Invalid ELF type file %s\n", fname);
		return -1;

Annotation

Implementation Notes