|
@@ -1,6 +1,57 @@
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/compiler.h>
|
|
#include <linux/compiler.h>
|
|
|
|
|
|
|
|
+static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
|
|
|
|
+ struct map *map)
|
|
|
|
+{
|
|
|
|
+ char *endptr, *tok, *name;
|
|
|
|
+ struct addr_map_symbol target = {
|
|
|
|
+ .map = map,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ tok = strchr(ops->raw, ',');
|
|
|
|
+ if (!tok)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ ops->target.addr = strtoull(tok + 1, &endptr, 16);
|
|
|
|
+
|
|
|
|
+ name = strchr(endptr, '<');
|
|
|
|
+ if (name == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ name++;
|
|
|
|
+
|
|
|
|
+ if (arch->objdump.skip_functions_char &&
|
|
|
|
+ strchr(name, arch->objdump.skip_functions_char))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ tok = strchr(name, '>');
|
|
|
|
+ if (tok == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ *tok = '\0';
|
|
|
|
+ ops->target.name = strdup(name);
|
|
|
|
+ *tok = '>';
|
|
|
|
+
|
|
|
|
+ if (ops->target.name == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ target.addr = map__objdump_2mem(map, ops->target.addr);
|
|
|
|
+
|
|
|
|
+ if (map_groups__find_ams(&target) == 0 &&
|
|
|
|
+ map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
|
|
|
|
+ ops->target.sym = target.sym;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int call__scnprintf(struct ins *ins, char *bf, size_t size,
|
|
|
|
+ struct ins_operands *ops);
|
|
|
|
+
|
|
|
|
+static struct ins_ops s390_call_ops = {
|
|
|
|
+ .parse = s390_call__parse,
|
|
|
|
+ .scnprintf = call__scnprintf,
|
|
|
|
+};
|
|
|
|
+
|
|
static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name)
|
|
static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name)
|
|
{
|
|
{
|
|
struct ins_ops *ops = NULL;
|
|
struct ins_ops *ops = NULL;
|
|
@@ -14,7 +65,7 @@ static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *na
|
|
if (!strcmp(name, "bras") ||
|
|
if (!strcmp(name, "bras") ||
|
|
!strcmp(name, "brasl") ||
|
|
!strcmp(name, "brasl") ||
|
|
!strcmp(name, "basr"))
|
|
!strcmp(name, "basr"))
|
|
- ops = &call_ops;
|
|
|
|
|
|
+ ops = &s390_call_ops;
|
|
if (!strcmp(name, "br"))
|
|
if (!strcmp(name, "br"))
|
|
ops = &ret_ops;
|
|
ops = &ret_ops;
|
|
|
|
|