arch/s390/tools/relocs.c

Source file repositories/reference/linux-study-clean/arch/s390/tools/relocs.c

File Facts

System
Linux kernel
Corpus path
arch/s390/tools/relocs.c
Extension
.c
Size
9244 bytes
Lines
388
Domain
Architecture Layer
Bucket
arch/s390
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

struct relocs {
	uint32_t	*offset;
	unsigned long	count;
	unsigned long	size;
};

static struct relocs relocs64;
#define FMT PRIu64

struct section {
	Elf_Shdr	shdr;
	struct section	*link;
	Elf_Rel		*reltab;
};

static struct section *secs;

#if BYTE_ORDER == LITTLE_ENDIAN
#define le16_to_cpu(val)	(val)
#define le32_to_cpu(val)	(val)
#define le64_to_cpu(val)	(val)
#define be16_to_cpu(val)	bswap_16(val)
#define be32_to_cpu(val)	bswap_32(val)
#define be64_to_cpu(val)	bswap_64(val)
#endif

#if BYTE_ORDER == BIG_ENDIAN
#define le16_to_cpu(val)	bswap_16(val)
#define le32_to_cpu(val)	bswap_32(val)
#define le64_to_cpu(val)	bswap_64(val)
#define be16_to_cpu(val)	(val)
#define be32_to_cpu(val)	(val)
#define be64_to_cpu(val)	(val)
#endif

static uint16_t elf16_to_cpu(uint16_t val)
{
	if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
		return le16_to_cpu(val);
	else
		return be16_to_cpu(val);
}

static uint32_t elf32_to_cpu(uint32_t val)
{
	if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
		return le32_to_cpu(val);
	else
		return be32_to_cpu(val);
}

#define elf_half_to_cpu(x)	elf16_to_cpu(x)
#define elf_word_to_cpu(x)	elf32_to_cpu(x)

static uint64_t elf64_to_cpu(uint64_t val)
{
	return be64_to_cpu(val);
}

#define elf_addr_to_cpu(x)	elf64_to_cpu(x)
#define elf_off_to_cpu(x)	elf64_to_cpu(x)
#define elf_xword_to_cpu(x)	elf64_to_cpu(x)

static void die(char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	exit(1);
}

static void read_ehdr(FILE *fp)
{
	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
		die("Cannot read ELF header: %s\n", strerror(errno));
	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
		die("No ELF magic\n");
	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
		die("Not a %d bit executable\n", ELF_BITS);
	if (ehdr.e_ident[EI_DATA] != ELF_ENDIAN)
		die("ELF endian mismatch\n");
	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
		die("Unknown ELF version\n");

	/* Convert the fields to native endian */
	ehdr.e_type	 = elf_half_to_cpu(ehdr.e_type);
	ehdr.e_machine	 = elf_half_to_cpu(ehdr.e_machine);
	ehdr.e_version	 = elf_word_to_cpu(ehdr.e_version);

Annotation

Implementation Notes