2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2007-2016 Arnaldo Carvalho de Melo <acme@kernel.org>
6 System call sign extender
18 static const char *prefix
= "sys_";
19 static size_t prefix_len
= 4;
21 static struct conf_fprintf conf
;
23 static struct conf_load conf_load
= {
24 .conf_fprintf
= &conf
,
27 static bool filter(struct function
*f
)
29 if (f
->proto
.nr_parms
!= 0) {
30 const char *name
= function__name(f
);
32 if (strlen(name
) > prefix_len
&&
33 memcmp(name
, prefix
, prefix_len
) == 0)
39 static void zero_extend(const int regparm
, const struct base_type
*bt
, const char *parm
)
41 const char *instr
= "INVALID";
43 switch (bt
->bit_size
) {
56 printf("\t%s\t$a%d, $a%d, 0"
57 "\t/* zero extend $a%d(%s %s) from %d to 64-bit */\n",
58 instr
, regparm
, regparm
, regparm
,
59 base_type__name(bt
, bf
, sizeof(bf
)),
63 static void emit_wrapper(struct function
*f
, struct cu
*cu
)
65 struct parameter
*parm
;
66 const char *name
= function__name(f
);
67 int regparm
= 0, needs_wrapper
= 0;
69 function__for_each_parameter(f
, cu
, parm
) {
70 const type_id_t type_id
= parm
->tag
.type
;
71 struct tag
*type
= cu__type(cu
, type_id
);
73 tag__assert_search_result(type
, parm
->tag
.tag
, parameter__name(parm
));
74 if (type
->tag
== DW_TAG_base_type
) {
75 struct base_type
*bt
= tag__base_type(type
);
78 if (bt
->bit_size
< 64 &&
79 strncmp(base_type__name(bt
, bf
, sizeof(bf
)), "unsigned", 8) == 0) {
81 printf("wrap_%s:\n", name
);
84 zero_extend(regparm
, bt
, parameter__name(parm
));
91 printf("\tj\t%s\n\n", name
);
94 static int cu__emit_wrapper(struct cu
*cu
, void *cookie __maybe_unused
)
99 cu__for_each_function(cu
, id
, pos
)
101 emit_wrapper(pos
, cu
);
105 static void cus__emit_wrapper(struct cus
*cu
)
107 cus__for_each_cu(cu
, cu__emit_wrapper
, NULL
, NULL
);
110 /* Name and version of program. */
111 ARGP_PROGRAM_VERSION_HOOK_DEF
= dwarves_print_version
;
113 static const struct argp_option options
[] = {
118 .doc
= "function prefix",
125 static error_t
options_parser(int key
, char *arg
, struct argp_state
*state
)
129 if (state
->child_inputs
!= NULL
)
130 state
->child_inputs
[0] = state
->input
;
134 prefix_len
= strlen(prefix
);
137 return ARGP_ERR_UNKNOWN
;
142 static const char args_doc
[] = "FILE";
144 static struct argp argp
= {
146 .parser
= options_parser
,
147 .args_doc
= args_doc
,
150 int main(int argc
, char *argv
[])
153 struct cus
*cus
= cus__new();
156 fprintf(stderr
, "%s: insufficient memory\n", argv
[0]);
160 if (argp_parse(&argp
, argc
, argv
, 0, &remaining
, NULL
) ||
162 argp_help(&argp
, stderr
, ARGP_HELP_SEE
, argv
[0]);
165 err
= cus__load_files(cus
, &conf_load
, argv
+ remaining
);
167 cus__fprintf_load_files_err(cus
, "syscse", argv
+ remaining
, err
, stderr
);
171 cus__emit_wrapper(cus
);