arch/mips/boot/elf2ecoff.c

Source file repositories/reference/linux-study-clean/arch/mips/boot/elf2ecoff.c

File Facts

System
Linux kernel
Corpus path
arch/mips/boot/elf2ecoff.c
Extension
.c
Size
16906 bytes
Lines
622
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

struct sect {
	uint32_t vaddr;
	uint32_t len;
};

int *symTypeTable;
int must_convert_endian;
int format_bigendian;

static void copy(int out, int in, off_t offset, off_t size)
{
	char ibuf[4096];
	int remaining, cur, count;

	/* Go to the start of the ELF symbol table... */
	if (lseek(in, offset, SEEK_SET) < 0) {
		perror("copy: lseek");
		exit(1);
	}

	remaining = size;
	while (remaining) {
		cur = remaining;
		if (cur > sizeof ibuf)
			cur = sizeof ibuf;
		remaining -= cur;
		if ((count = read(in, ibuf, cur)) != cur) {
			fprintf(stderr, "copy: read: %s\n",
				count ? strerror(errno) :
				"premature end of file");
			exit(1);
		}
		if ((count = write(out, ibuf, cur)) != cur) {
			perror("copy: write");
			exit(1);
		}
	}
}

/*
 * Combine two segments, which must be contiguous.   If pad is true, it's
 * okay for there to be padding between.
 */
static void combine(struct sect *base, struct sect *new, int pad)
{
	if (!base->len)
		*base = *new;
	else if (new->len) {
		if (base->vaddr + base->len != new->vaddr) {
			if (pad)
				base->len = new->vaddr - base->vaddr;
			else {
				fprintf(stderr,
					"Non-contiguous data can't be converted.\n");
				exit(1);
			}
		}
		base->len += new->len;
	}
}

static int phcmp(const void *v1, const void *v2)
{
	const Elf32_Phdr *h1 = v1;
	const Elf32_Phdr *h2 = v2;

	if (h1->p_vaddr > h2->p_vaddr)
		return 1;
	else if (h1->p_vaddr < h2->p_vaddr)
		return -1;
	else
		return 0;
}

static char *saveRead(int file, off_t offset, off_t len, char *name)
{
	char *tmp;
	int count;
	off_t off;
	if ((off = lseek(file, offset, SEEK_SET)) < 0) {
		fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
		exit(1);
	}
	if (!(tmp = (char *) malloc(len))) {
		fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
			len);
		exit(1);
	}
	count = read(file, tmp, len);
	if (count != len) {

Annotation

Implementation Notes