arch/loongarch/kernel/unwind_prologue.c

Source file repositories/reference/linux-study-clean/arch/loongarch/kernel/unwind_prologue.c

File Facts

System
Linux kernel
Corpus path
arch/loongarch/kernel/unwind_prologue.c
Extension
.c
Size
6209 bytes
Lines
263
Domain
Architecture Layer
Bucket
arch/loongarch
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration 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 (is_stack_alloc_ins(ip)) {
			frame_size = (1 << 12) - ip->reg2i12_format.immediate;
			ip++;
			break;
		}
		ip++;
	}

	/*
	 * Can't find stack alloc action, PC may be in a leaf function. Only the
	 * first being true is reasonable, otherwise indicate analysis is broken.
	 */
	if (!frame_size) {
		if (state->first)
			goto first;

		return false;
	}

	while (ip < ip_end) {
		if (is_ra_save_ins(ip)) {
			frame_ra = ip->reg2i12_format.immediate;
			break;
		}
		if (is_branch_ins(ip))
			break;
		ip++;
	}

	/* Can't find save $ra action, PC may be in a leaf function, too. */
	if (frame_ra < 0) {
		if (state->first) {
			state->sp = state->sp + frame_size;
			goto first;
		}
		return false;
	}

	state->pc = *(unsigned long *)(state->sp + frame_ra);
	state->sp = state->sp + frame_size;
	goto out;

first:
	state->pc = state->ra;

out:
	state->first = false;
	return unwind_state_fixup(state) || __kernel_text_address(state->pc);
}

static bool next_frame(struct unwind_state *state)
{
	unsigned long pc;
	struct pt_regs *regs;
	struct stack_info *info = &state->stack_info;

	if (unwind_done(state))
		return false;

	do {
		if (unwind_by_prologue(state)) {
			state->pc = unwind_graph_addr(state, state->pc, state->sp);
			return true;
		}

		if (info->type == STACK_TYPE_IRQ && info->end == state->sp) {
			regs = (struct pt_regs *)info->next_sp;
			pc = regs->csr_era;

			if (user_mode(regs) || !__kernel_text_address(pc))
				goto out;

			state->first = true;
			state->pc = pc;
			state->ra = regs->regs[1];
			state->sp = regs->regs[3];
			get_stack_info(state->sp, state->task, info);

			return true;
		}

		state->sp = info->next_sp;

	} while (!get_stack_info(state->sp, state->task, info));

out:
	state->stack_info.type = STACK_TYPE_UNKNOWN;
	return false;
}

Annotation

Implementation Notes