arch/mips/vdso/genvdso.c

Source file repositories/reference/linux-study-clean/arch/mips/vdso/genvdso.c

File Facts

System
Linux kernel
Corpus path
arch/mips/vdso/genvdso.c
Extension
.c
Size
7888 bytes
Lines
309
Domain
Architecture Layer
Bucket
arch/mips
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015 Imagination Technologies
 * Author: Alex Smith <alex.smith@imgtec.com>
 */

/*
 * This tool is used to generate the real VDSO images from the raw image. It
 * first patches up the MIPS ABI flags and GNU attributes sections defined in
 * elf.S to have the correct name and type. It then generates a C source file
 * to be compiled into the kernel containing the VDSO image data and a
 * mips_vdso_image struct for it, including symbol offsets extracted from the
 * image.
 *
 * We need to be passed both a stripped and unstripped VDSO image. The stripped
 * image is compiled into the kernel, but we must also patch up the unstripped
 * image's ABI flags sections so that it can be installed and used for
 * debugging.
 */

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <byteswap.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Define these in case the system elf.h is not new enough to have them. */
#ifndef SHT_GNU_ATTRIBUTES
# define SHT_GNU_ATTRIBUTES	0x6ffffff5
#endif
#ifndef SHT_MIPS_ABIFLAGS
# define SHT_MIPS_ABIFLAGS	0x7000002a
#endif

enum {
	ABI_O32 = (1 << 0),
	ABI_N32 = (1 << 1),
	ABI_N64 = (1 << 2),

	ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64,
};

/* Symbols the kernel requires offsets for. */
static struct {
	const char *name;
	const char *offset_name;
	unsigned int abis;
} vdso_symbols[] = {
	{ "__vdso_sigreturn", "off_sigreturn", ABI_O32 },
	{ "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL },
	{}
};

static const char *program_name;
static const char *vdso_name;
static unsigned char elf_class;
static unsigned int elf_abi;
static bool need_swap;
static FILE *out_file;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define HOST_ORDER		ELFDATA2LSB
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define HOST_ORDER		ELFDATA2MSB
#endif

#define BUILD_SWAP(bits)						\
	static uint##bits##_t swap_uint##bits(uint##bits##_t val)	\
	{								\
		return need_swap ? bswap_##bits(val) : val;		\
	}

BUILD_SWAP(16)
BUILD_SWAP(32)
BUILD_SWAP(64)

#define __FUNC(name, bits) name##bits
#define _FUNC(name, bits) __FUNC(name, bits)
#define FUNC(name) _FUNC(name, ELF_BITS)

Annotation

Implementation Notes