// SPDX-License-Identifier: GPL-2.0-only
#include <ctype.h>
#include <elf.h>
#ifndef EF_CSKY_ABIMASK
#define EF_CSKY_ABIMASK 0XF0000000
#endif
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <regex.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/string.h>
#include <subcmd/run-command.h>
#include "annotate.h"
#include "annotate-data.h"
#include "build-id.h"
#include "capstone.h"
#include "debug.h"
#include "disasm.h"
#include "dso.h"
#include "dwarf-regs.h"
#include "env.h"
#include "evsel.h"
#include "libbfd.h"
#include "llvm.h"
#include "map.h"
#include "maps.h"
#include "namespaces.h"
#include "srcline.h"
#include "symbol.h"
#include "thread.h"
#include "util.h"
static regex_t file_lineno;
/* These can be referred from the arch-dependent code */
const struct ins_ops call_ops;
const struct ins_ops dec_ops;
const struct ins_ops jump_ops;
const struct ins_ops mov_ops;
const struct ins_ops nop_ops;
const struct ins_ops lock_ops;
const struct ins_ops ret_ops;
const struct ins_ops load_store_ops;
const struct ins_ops arithmetic_ops;
static void ins__sort(struct arch *arch);
static int disasm_line__parse(char *line, const char **namep, char **rawp);
static int disasm_line__parse_powerpc(struct disasm_line *dl, struct annotate_args *args);
static __attribute__((constructor)) void symbol__init_regexpr(void)
{
regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
}
static int arch__grow_instructions(struct arch *arch)
{
struct ins *new_instructions;
size_t new_nr_allocated;
if (arch->nr_instructions_allocated == 0 && arch->instructions)
goto grow_from_non_allocated_table;
new_nr_allocated = arch->nr_instructions_allocated + 128;
new_instructions = realloc((void *)arch->instructions,
new_nr_allocated * sizeof(struct ins));
if (new_instructions == NULL)
return -1;
out_update_instructions:
arch->instructions = new_instructions;
arch->nr_instructions_allocated = new_nr_allocated;
return 0;
grow_from_non_allocated_table:
new_nr_allocated = arch->nr_instructions + 128;
new_instructions = calloc(new_nr_allocated, sizeof(struct ins));
if (new_instructions == NULL)
return -1;
memcpy(new_instructions, arch->instructions, arch->nr_instructions * sizeof(struct ins));
goto out_update_instructions;
}
int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops)
{
struct ins *ins;
if (arch->nr_instructions == arch->nr_instructions_allocated &&
arch__grow_instructions(arch))
return -1;
ins = (struct ins *)&arch->instructions[arch->nr_instructions];
ins->name = strdup(name);
if (!ins->name)
return -1;
ins->ops = ops;
arch->nr_instructions++;
ins__sort(arch);
return 0;
}
static int e_machine_and_eflags__cmp(const struct e_machine_and_e_flags *val1,
const struct e_machine_and_e_flags *val2)
{
if (val1->e_machine == val2->e_machine) {
if (val1->e_machine != EM_CSKY)
return 0;
if ((val1->e_flags & EF_CSKY_ABIMASK) < (val2->e_flags & EF_CSKY_ABIMASK))
return -1;
return (val1->e_flags & EF_CSKY_ABIMASK) > (val2->e_flags & EF_CSKY_ABIMASK);
}
return val
|