tools/objtool/disas.c

Source file repositories/reference/linux-study-clean/tools/objtool/disas.c

File Facts

System
Linux kernel
Corpus path
tools/objtool/disas.c
Extension
.c
Size
29078 bytes
Lines
1249
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

struct disas_context {
	struct objtool_file *file;
	struct instruction *insn;
	bool alt_applied;
	char result[DISAS_RESULT_SIZE];
	disassembler_ftype disassembler;
	struct disassemble_info info;
};

/*
 * Maximum number of alternatives
 */
#define DISAS_ALT_MAX		5

/*
 * Maximum number of instructions per alternative
 */
#define DISAS_ALT_INSN_MAX	50

/*
 * Information to disassemble an alternative
 */
struct disas_alt {
	struct instruction *orig_insn;		/* original instruction */
	struct alternative *alt;		/* alternative or NULL if default code */
	char *name;				/* name for this alternative */
	int width;				/* formatting width */
	struct {
		char *str;			/* instruction string */
		int offset;			/* instruction offset */
		int nops;			/* number of nops */
	} insn[DISAS_ALT_INSN_MAX];		/* alternative instructions */
	int insn_idx;				/* index of the next instruction to print */
};

#define DALT_DEFAULT(dalt)	(!(dalt)->alt)
#define DALT_INSN(dalt)		(DALT_DEFAULT(dalt) ? (dalt)->orig_insn : (dalt)->alt->insn)
#define DALT_GROUP(dalt)	(DALT_INSN(dalt)->alt_group)
#define DALT_ALTID(dalt)	((dalt)->orig_insn->offset)

#define ALT_FLAGS_SHIFT		16
#define ALT_FLAG_NOT		(1 << 0)
#define ALT_FLAG_DIRECT_CALL	(1 << 1)
#define ALT_FEATURE_MASK	((1 << ALT_FLAGS_SHIFT) - 1)

static int alt_feature(unsigned int ft_flags)
{
	return (ft_flags & ALT_FEATURE_MASK);
}

static int alt_flags(unsigned int ft_flags)
{
	return (ft_flags >> ALT_FLAGS_SHIFT);
}

/*
 * Wrapper around asprintf() to allocate and format a string.
 * Return the allocated string or NULL on error.
 */
static char *strfmt(const char *fmt, ...)
{
	va_list ap;
	char *str;
	int rv;

	va_start(ap, fmt);
	rv = vasprintf(&str, fmt, ap);
	va_end(ap);

	return rv == -1 ? NULL : str;
}

static int sprint_name(char *str, const char *name, unsigned long offset)
{
	int len;

	if (offset)
		len = sprintf(str, "%s+0x%lx", name, offset);
	else
		len = sprintf(str, "%s", name);

	return len;
}

#define DINFO_FPRINTF(dinfo, ...)	\
	((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__))
#define bfd_vma_fmt			\
	__builtin_choose_expr(sizeof(bfd_vma) == sizeof(unsigned long), "%#lx <%s>", "%#llx <%s>")

static int disas_result_fprintf(struct disas_context *dctx,

Annotation

Implementation Notes