tools/objtool/arch/loongarch/orc.c

Source file repositories/reference/linux-study-clean/tools/objtool/arch/loongarch/orc.c

File Facts

System
Linux kernel
Corpus path
tools/objtool/arch/loongarch/orc.c
Extension
.c
Size
3536 bytes
Lines
171
Domain
Support Tooling And Documentation
Bucket
tools
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

// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/objtool_types.h>
#include <asm/orc_types.h>

#include <objtool/check.h>
#include <objtool/orc.h>
#include <objtool/warn.h>

int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn)
{
	struct cfi_reg *fp = &cfi->regs[CFI_FP];
	struct cfi_reg *ra = &cfi->regs[CFI_RA];

	memset(orc, 0, sizeof(*orc));

	if (!cfi) {
		/*
		 * This is usually either unreachable nops/traps (which don't
		 * trigger unreachable instruction warnings), or
		 * STACK_FRAME_NON_STANDARD functions.
		 */
		orc->type = ORC_TYPE_UNDEFINED;
		return 0;
	}

	switch (cfi->type) {
	case UNWIND_HINT_TYPE_UNDEFINED:
		orc->type = ORC_TYPE_UNDEFINED;
		return 0;
	case UNWIND_HINT_TYPE_END_OF_STACK:
		orc->type = ORC_TYPE_END_OF_STACK;
		return 0;
	case UNWIND_HINT_TYPE_CALL:
		orc->type = ORC_TYPE_CALL;
		break;
	case UNWIND_HINT_TYPE_REGS:
		orc->type = ORC_TYPE_REGS;
		break;
	case UNWIND_HINT_TYPE_REGS_PARTIAL:
		orc->type = ORC_TYPE_REGS_PARTIAL;
		break;
	default:
		ERROR_INSN(insn, "unknown unwind hint type %d", cfi->type);
		return -1;
	}

	orc->signal = cfi->signal;

	switch (cfi->cfa.base) {
	case CFI_SP:
		orc->sp_reg = ORC_REG_SP;
		break;
	case CFI_FP:
		orc->sp_reg = ORC_REG_FP;
		break;
	default:
		ERROR_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base);
		return -1;
	}

	switch (fp->base) {
	case CFI_UNDEFINED:
		orc->fp_reg = ORC_REG_UNDEFINED;
		orc->fp_offset = 0;
		break;
	case CFI_CFA:
		orc->fp_reg = ORC_REG_PREV_SP;
		orc->fp_offset = fp->offset;
		break;
	case CFI_FP:
		orc->fp_reg = ORC_REG_FP;
		break;
	default:
		ERROR_INSN(insn, "unknown FP base reg %d", fp->base);
		return -1;
	}

	switch (ra->base) {
	case CFI_UNDEFINED:
		orc->ra_reg = ORC_REG_UNDEFINED;
		orc->ra_offset = 0;
		break;
	case CFI_CFA:
		orc->ra_reg = ORC_REG_PREV_SP;
		orc->ra_offset = ra->offset;
		break;
	case CFI_FP:
		orc->ra_reg = ORC_REG_FP;
		break;
	default:

Annotation

Implementation Notes