Lines Matching +full:line +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0-only
12 #include <subcmd/run-command.h>
15 #include "annotate-data.h"
16 #include "build-id.h"
21 #include "dwarf-regs.h"
33 /* These can be referred from the arch-dependent code */
50 static int disasm_line__parse(char *line, const char **namep, char **rawp);
52 static char *expand_tabs(char *line, char **storage, size_t *storage_len);
56 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED); in symbol__init_regexpr()
64 if (arch->nr_instructions_allocated == 0 && arch->instructions) in arch__grow_instructions()
67 new_nr_allocated = arch->nr_instructions_allocated + 128; in arch__grow_instructions()
68 new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins)); in arch__grow_instructions()
70 return -1; in arch__grow_instructions()
73 arch->instructions = new_instructions; in arch__grow_instructions()
74 arch->nr_instructions_allocated = new_nr_allocated; in arch__grow_instructions()
78 new_nr_allocated = arch->nr_instructions + 128; in arch__grow_instructions()
81 return -1; in arch__grow_instructions()
83 memcpy(new_instructions, arch->instructions, arch->nr_instructions); in arch__grow_instructions()
87 static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) in arch__associate_ins_ops() argument
91 if (arch->nr_instructions == arch->nr_instructions_allocated && in arch__associate_ins_ops()
93 return -1; in arch__associate_ins_ops()
95 ins = &arch->instructions[arch->nr_instructions]; in arch__associate_ins_ops()
96 ins->name = strdup(name); in arch__associate_ins_ops()
97 if (!ins->name) in arch__associate_ins_ops()
98 return -1; in arch__associate_ins_ops()
100 ins->ops = ops; in arch__associate_ins_ops()
101 arch->nr_instructions++; in arch__associate_ins_ops()
121 .name = "arc",
125 .name = "arm",
129 .name = "arm64",
133 .name = "csky",
137 .name = "mips",
144 .name = "x86",
160 .name = "powerpc",
167 .name = "riscv64",
171 .name = "s390",
178 .name = "sparc",
185 .name = "loongarch",
193 static int arch__key_cmp(const void *name, const void *archp) in arch__key_cmp() argument
197 return strcmp(name, arch->name); in arch__key_cmp()
205 return strcmp(aa->name, ab->name); in arch__cmp()
215 struct arch *arch__find(const char *name) in arch__find() argument
225 return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp); in arch__find()
228 bool arch__is(struct arch *arch, const char *name) in arch__is() argument
230 return !strcmp(arch->name, name); in arch__is()
237 zfree(&ops->source.raw); in ins_ops__delete()
238 zfree(&ops->source.name); in ins_ops__delete()
239 zfree(&ops->target.raw); in ins_ops__delete()
240 zfree(&ops->target.name); in ins_ops__delete()
246 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); in ins__raw_scnprintf()
252 if (ins->ops->scnprintf) in ins__scnprintf()
253 return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); in ins__scnprintf()
260 if (!arch || !arch->ins_is_fused) in ins__is_fused()
263 return arch->ins_is_fused(arch, ins1, ins2); in ins__is_fused()
269 char *endptr, *tok, *name; in call__parse() local
270 struct map *map = ms->map; in call__parse()
275 ops->target.addr = strtoull(ops->raw, &endptr, 16); in call__parse()
277 name = strchr(endptr, '<'); in call__parse()
278 if (name == NULL) in call__parse()
281 name++; in call__parse()
283 if (arch->objdump.skip_functions_char && in call__parse()
284 strchr(name, arch->objdump.skip_functions_char)) in call__parse()
285 return -1; in call__parse()
287 tok = strchr(name, '>'); in call__parse()
289 return -1; in call__parse()
292 ops->target.name = strdup(name); in call__parse()
295 if (ops->target.name == NULL) in call__parse()
296 return -1; in call__parse()
298 target.addr = map__objdump_2mem(map, ops->target.addr); in call__parse()
300 if (maps__find_ams(ms->maps, &target) == 0 && in call__parse()
301 map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) in call__parse()
302 ops->target.sym = target.ms.sym; in call__parse()
311 /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx). in call__parse()
314 ops->target.addr = strtoull(endptr, NULL, 16); in call__parse()
322 if (ops->target.sym) in call__scnprintf()
323 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); in call__scnprintf()
325 if (ops->target.addr == 0) in call__scnprintf()
328 if (ops->target.name) in call__scnprintf()
329 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.name); in call__scnprintf()
331 return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr); in call__scnprintf()
341 return ins->ops == &call_ops || ins->ops == &s390_call_ops || ins->ops == &loongarch_call_ops; in ins__is_call()
353 if (ops->jump.raw_comment && c > ops->jump.raw_comment) in validate_comma()
356 if (ops->jump.raw_func_start && c > ops->jump.raw_func_start) in validate_comma()
365 struct map *map = ms->map; in jump__parse()
366 struct symbol *sym = ms->sym; in jump__parse()
370 const char *c = strchr(ops->raw, ','); in jump__parse()
373 ops->jump.raw_comment = strchr(ops->raw, arch->objdump.comment_char); in jump__parse()
374 ops->jump.raw_func_start = strchr(ops->raw, '<'); in jump__parse()
394 ops->target.addr = strtoull(c, NULL, 16); in jump__parse()
395 if (!ops->target.addr) { in jump__parse()
399 ops->target.addr = strtoull(c, NULL, 16); in jump__parse()
402 ops->target.addr = strtoull(ops->raw, NULL, 16); in jump__parse()
405 target.addr = map__objdump_2mem(map, ops->target.addr); in jump__parse()
406 start = map__unmap_ip(map, sym->start); in jump__parse()
407 end = map__unmap_ip(map, sym->end); in jump__parse()
409 ops->target.outside = target.addr < start || target.addr > end; in jump__parse()
418 * cpp_named_operator2name is marked as being 32-bytes long, but it in in jump__parse()
420 * routine that looks for >= current->start and < next_symbol->start, in jump__parse()
429 if (maps__find_ams(ms->maps, &target) == 0 && in jump__parse()
430 map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) in jump__parse()
431 ops->target.sym = target.ms.sym; in jump__parse()
433 if (!ops->target.outside) { in jump__parse()
434 ops->target.offset = target.addr - start; in jump__parse()
435 ops->target.offset_avail = true; in jump__parse()
437 ops->target.offset_avail = false; in jump__parse()
448 if (!ops->target.addr || ops->target.offset < 0) in jump__scnprintf()
451 if (ops->target.outside && ops->target.sym != NULL) in jump__scnprintf()
452 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); in jump__scnprintf()
454 c = strchr(ops->raw, ','); in jump__scnprintf()
461 /* check for 3-op insn */ in jump__scnprintf()
466 /* mirror arch objdump's space-after-comma style */ in jump__scnprintf()
471 return scnprintf(bf, size, "%-*s %.*s%" PRIx64, max_ins_name, in jump__scnprintf()
472 ins->name, c ? c - ops->raw : 0, ops->raw, in jump__scnprintf()
473 ops->target.offset); in jump__scnprintf()
479 * The ops->jump.raw_comment and ops->jump.raw_func_start belong to the in jump__delete()
492 return ins->ops == &jump_ops || ins->ops == &loongarch_jump_ops; in ins__is_jump()
497 char *endptr, *name, *t; in comment__symbol() local
505 name = strchr(endptr, '<'); in comment__symbol()
506 if (name == NULL) in comment__symbol()
507 return -1; in comment__symbol()
509 name++; in comment__symbol()
511 t = strchr(name, '>'); in comment__symbol()
516 *namep = strdup(name); in comment__symbol()
525 ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); in lock__parse()
526 if (ops->locked.ops == NULL) in lock__parse()
529 if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0) in lock__parse()
532 ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name, 0); in lock__parse()
534 if (ops->locked.ins.ops == NULL) in lock__parse()
537 if (ops->locked.ins.ops->parse && in lock__parse()
538 ops->locked.ins.ops->parse(arch, ops->locked.ops, ms, NULL) < 0) in lock__parse()
544 zfree(&ops->locked.ops); in lock__parse()
553 if (ops->locked.ins.ops == NULL) in lock__scnprintf()
556 printed = scnprintf(bf, size, "%-*s ", max_ins_name, ins->name); in lock__scnprintf()
557 return printed + ins__scnprintf(&ops->locked.ins, bf + printed, in lock__scnprintf()
558 size - printed, ops->locked.ops, max_ins_name); in lock__scnprintf()
563 struct ins *ins = &ops->locked.ins; in lock__delete()
565 if (ins->ops && ins->ops->free) in lock__delete()
566 ins->ops->free(ops->locked.ops); in lock__delete()
568 ins_ops__delete(ops->locked.ops); in lock__delete()
570 zfree(&ops->locked.ops); in lock__delete()
571 zfree(&ops->locked.ins.name); in lock__delete()
572 zfree(&ops->target.raw); in lock__delete()
573 zfree(&ops->target.name); in lock__delete()
593 if (arch->objdump.register_char == 0) in check_multi_regs()
596 if (arch->objdump.memory_ref_char) { in check_multi_regs()
597 op = strchr(op, arch->objdump.memory_ref_char); in check_multi_regs()
602 while ((op = strchr(op, arch->objdump.register_char)) != NULL) { in check_multi_regs()
613 char *s = strchr(ops->raw, ','), *target, *comment, prev; in mov__parse()
616 return -1; in mov__parse()
624 if (strchr(ops->raw, '(')) { in mov__parse()
626 s = strchr(ops->raw, ')'); in mov__parse()
628 return -1; in mov__parse()
632 ops->source.raw = strdup(ops->raw); in mov__parse()
635 if (ops->source.raw == NULL) in mov__parse()
636 return -1; in mov__parse()
638 ops->source.multi_regs = check_multi_regs(arch, ops->source.raw); in mov__parse()
641 comment = strchr(s, arch->objdump.comment_char); in mov__parse()
644 s = comment - 1; in mov__parse()
646 s = strchr(s, '\0') - 1; in mov__parse()
649 --s; in mov__parse()
654 ops->target.raw = strdup(target); in mov__parse()
657 if (ops->target.raw == NULL) in mov__parse()
660 ops->target.multi_regs = check_multi_regs(arch, ops->target.raw); in mov__parse()
666 comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name); in mov__parse()
667 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); in mov__parse()
672 zfree(&ops->source.raw); in mov__parse()
673 return -1; in mov__parse()
679 return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name, in mov__scnprintf()
680 ops->source.name ?: ops->source.raw, in mov__scnprintf()
681 ops->target.name ?: ops->target.raw); in mov__scnprintf()
698 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, in arithmetic__scnprintf()
699 ops->raw); in arithmetic__scnprintf()
704 * "mem_ref" is set for ops->source which is later used to
705 * fill the objdump->memory_ref-char field. This ops is currently
711 * - Add to Minus One Extended XO-form ( Ex: addme, addmeo )
712 * - Subtract From Minus One Extended XO-form ( Ex: subfme )
713 * - Add to Zero Extended XO-form ( Ex: addze, addzeo )
714 * - Subtract From Zero Extended XO-form ( Ex: subfze )
719 int opcode = PPC_OP(dl->raw.raw_insn); in arithmetic__parse()
721 ops->source.mem_ref = false; in arithmetic__parse()
725 ops->source.multi_regs = true; in arithmetic__parse()
728 ops->target.mem_ref = false; in arithmetic__parse()
729 ops->target.multi_regs = false; in arithmetic__parse()
742 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, in load_store__scnprintf()
743 ops->raw); in load_store__scnprintf()
748 * "mem_ref" is set for ops->source which is later used to
749 * fill the objdump->memory_ref-char field. This ops is currently
756 ops->source.mem_ref = true; in load_store__parse()
757 ops->source.multi_regs = false; in load_store__parse()
759 if (PPC_OP(dl->raw.raw_insn) == 31) in load_store__parse()
760 ops->source.multi_regs = true; in load_store__parse()
762 ops->target.mem_ref = false; in load_store__parse()
763 ops->target.multi_regs = false; in load_store__parse()
778 target = s = ops->raw; in dec__parse()
785 ops->target.raw = strdup(target); in dec__parse()
788 if (ops->target.raw == NULL) in dec__parse()
789 return -1; in dec__parse()
791 comment = strchr(s, arch->objdump.comment_char); in dec__parse()
796 comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); in dec__parse()
804 return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, in dec__scnprintf()
805 ops->target.name ?: ops->target.raw); in dec__scnprintf()
816 return scnprintf(bf, size, "%-*s", max_ins_name, "nop"); in nop__scnprintf()
829 return ins->ops == &nop_ops; in ins__is_nop()
834 return ins->ops == &ret_ops; in ins__is_ret()
839 return ins->ops == &lock_ops; in ins__is_lock()
842 static int ins__key_cmp(const void *name, const void *insp) in ins__key_cmp() argument
846 return strcmp(name, ins->name); in ins__key_cmp()
854 return strcmp(ia->name, ib->name); in ins__cmp()
859 const int nmemb = arch->nr_instructions; in ins__sort()
861 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); in ins__sort()
864 static struct ins_ops *__ins__find(struct arch *arch, const char *name, struct disasm_line *dl) in __ins__find() argument
867 const int nmemb = arch->nr_instructions; in __ins__find()
881 if (!arch->sorted_instructions) { in __ins__find()
883 arch->sorted_instructions = true; in __ins__find()
886 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); in __ins__find()
888 return ins->ops; in __ins__find()
890 if (arch->insn_suffix) { in __ins__find()
893 size_t len = strlen(name); in __ins__find()
898 suffix = name[len - 1]; in __ins__find()
899 if (strchr(arch->insn_suffix, suffix) == NULL) in __ins__find()
902 strcpy(tmp, name); in __ins__find()
903 tmp[len - 1] = '\0'; /* remove the suffix and check again */ in __ins__find()
905 ins = bsearch(tmp, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); in __ins__find()
907 return ins ? ins->ops : NULL; in __ins__find()
910 struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl) in ins__find() argument
912 struct ins_ops *ops = __ins__find(arch, name, dl); in ins__find()
914 if (!ops && arch->associate_instruction_ops) in ins__find()
915 ops = arch->associate_instruction_ops(arch, name); in ins__find()
922 dl->ins.ops = ins__find(arch, dl->ins.name, dl); in disasm_line__init_ins()
924 if (!dl->ins.ops) in disasm_line__init_ins()
927 if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, ms, dl) < 0) in disasm_line__init_ins()
928 dl->ins.ops = NULL; in disasm_line__init_ins()
931 static int disasm_line__parse(char *line, const char **namep, char **rawp) in disasm_line__parse() argument
933 char tmp, *name = skip_spaces(line); in disasm_line__parse() local
935 if (name[0] == '\0') in disasm_line__parse()
936 return -1; in disasm_line__parse()
938 *rawp = name + 1; in disasm_line__parse()
945 *namep = strdup(name); in disasm_line__parse()
956 return -1; in disasm_line__parse()
961 * Example, line read from DSO file in powerpc:
962 * line: 38 01 81 e8
973 char *line = dl->al.line; in disasm_line__parse_powerpc() local
974 const char **namep = &dl->ins.name; in disasm_line__parse_powerpc()
975 char **rawp = &dl->ops.raw; in disasm_line__parse_powerpc()
976 char *tmp_raw_insn, *name_raw_insn = skip_spaces(line); in disasm_line__parse_powerpc()
977 char *name = skip_spaces(name_raw_insn + RAW_BYTES); in disasm_line__parse_powerpc() local
980 if (strlen(line) > RAW_BYTES) in disasm_line__parse_powerpc()
984 return -1; in disasm_line__parse_powerpc()
987 disasm_line__parse(name, namep, rawp); in disasm_line__parse_powerpc()
993 return -1; in disasm_line__parse_powerpc()
997 sscanf(tmp_raw_insn, "%x", &dl->raw.raw_insn); in disasm_line__parse_powerpc()
999 dl->raw.raw_insn = be32_to_cpu(dl->raw.raw_insn); in disasm_line__parse_powerpc()
1008 al->offset = args->offset; in annotation_line__init()
1009 al->line = strdup(args->line); in annotation_line__init()
1010 al->line_nr = args->line_nr; in annotation_line__init()
1011 al->fileloc = args->fileloc; in annotation_line__init()
1012 al->data_nr = nr; in annotation_line__init()
1017 zfree_srcline(&al->path); in annotation_line__exit()
1018 zfree(&al->line); in annotation_line__exit()
1019 zfree(&al->cycles); in annotation_line__exit()
1020 zfree(&al->br_cntr); in annotation_line__exit()
1027 return (sizeof(struct disasm_line) + (sizeof(al->data[0]) * nr)); in disasm_line_size()
1031 * Allocating the disasm annotation line data with
1034 * -------------------------------------------
1036 * -------------------------------------------
1044 struct annotation *notes = symbol__annotation(args->ms.sym); in disasm_line__new()
1045 int nr = notes->src->nr_events; in disasm_line__new()
1051 annotation_line__init(&dl->al, args, nr); in disasm_line__new()
1052 if (dl->al.line == NULL) in disasm_line__new()
1055 if (args->offset != -1) { in disasm_line__new()
1056 if (arch__is(args->arch, "powerpc")) { in disasm_line__new()
1059 } else if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) in disasm_line__new()
1062 disasm_line__init_ins(dl, args->arch, &args->ms); in disasm_line__new()
1068 zfree(&dl->al.line); in disasm_line__new()
1076 if (dl->ins.ops && dl->ins.ops->free) in disasm_line__free()
1077 dl->ins.ops->free(&dl->ops); in disasm_line__free()
1079 ins_ops__delete(&dl->ops); in disasm_line__free()
1080 zfree(&dl->ins.name); in disasm_line__free()
1081 annotation_line__exit(&dl->al); in disasm_line__free()
1087 if (raw || !dl->ins.ops) in disasm_line__scnprintf()
1088 return scnprintf(bf, size, "%-*s %s", max_ins_name, dl->ins.name, dl->ops.raw); in disasm_line__scnprintf()
1090 return ins__scnprintf(&dl->ins, bf, size, &dl->ops, max_ins_name); in disasm_line__scnprintf()
1094 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw)
1107 * <offset> <name> <ops.raw>
1109 * The offset will be a relative offset from the start of the symbol and -1
1110 * means that it's not a disassembly line so should be treated differently.
1117 struct map *map = args->ms.map; in symbol__parse_objdump_line()
1121 s64 line_ip, offset = -1; in symbol__parse_objdump_line()
1124 /* /filename:linenr ? Save line number and ignore. */ in symbol__parse_objdump_line()
1135 u64 start = map__rip_2objdump(map, sym->start), in symbol__parse_objdump_line()
1136 end = map__rip_2objdump(map, sym->end); in symbol__parse_objdump_line()
1138 offset = line_ip - start; in symbol__parse_objdump_line()
1140 offset = -1; in symbol__parse_objdump_line()
1145 args->offset = offset; in symbol__parse_objdump_line()
1146 args->line = parsed_line; in symbol__parse_objdump_line()
1147 args->line_nr = *line_nr; in symbol__parse_objdump_line()
1148 args->fileloc = *fileloc; in symbol__parse_objdump_line()
1149 args->ms.sym = sym; in symbol__parse_objdump_line()
1155 return -1; in symbol__parse_objdump_line()
1158 dl->ops.target.offset = dl->ops.target.addr - in symbol__parse_objdump_line()
1159 map__rip_2objdump(map, sym->start); in symbol__parse_objdump_line()
1160 dl->ops.target.offset_avail = true; in symbol__parse_objdump_line()
1164 if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) { in symbol__parse_objdump_line()
1166 .addr = dl->ops.target.addr, in symbol__parse_objdump_line()
1170 if (!maps__find_ams(args->ms.maps, &target) && in symbol__parse_objdump_line()
1171 target.ms.sym->start == target.al_addr) in symbol__parse_objdump_line()
1172 dl->ops.target.sym = target.ms.sym; in symbol__parse_objdump_line()
1175 annotation_line__add(&dl->al, ¬es->src->source); in symbol__parse_objdump_line()
1182 struct list_head *list = ¬es->src->source; in delete_last_nop()
1186 dl = list_entry(list->prev, struct disasm_line, al.node); in delete_last_nop()
1188 if (dl->ins.ops) { in delete_last_nop()
1189 if (!ins__is_nop(&dl->ins)) in delete_last_nop()
1192 if (!strstr(dl->al.line, " nop ") && in delete_last_nop()
1193 !strstr(dl->al.line, " nopl ") && in delete_last_nop()
1194 !strstr(dl->al.line, " nopw ")) in delete_last_nop()
1198 list_del_init(&dl->al.node); in delete_last_nop()
1205 struct dso *dso = map__dso(ms->map); in symbol__strerror_disassemble()
1227 " perf buildid-cache -vu vmlinux\n\n" in symbol__strerror_disassemble()
1229 " --vmlinux vmlinux\n", build_id_msg ?: ""); in symbol__strerror_disassemble()
1236 scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); in symbol__strerror_disassemble()
1245 scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", in symbol__strerror_disassemble()
1286 * old style build-id cache has name of XX/XXXXXXX.. while in dso__disassemble_filename()
1288 * extract the build-id part of dirname in the new style only. in dso__disassemble_filename()
1291 if (pos && strlen(pos) < SBUILD_ID_SIZE - 2) in dso__disassemble_filename()
1297 len = readlink(build_id_path, linkname, sizeof(linkname) - 1); in dso__disassemble_filename()
1306 * If we don't have build-ids or the build-id file isn't in the in dso__disassemble_filename()
1340 struct annotation_options *opt = args->options; in open_capstone_handle()
1344 if (!arch__is(args->arch, "x86")) in open_capstone_handle()
1345 return -1; in open_capstone_handle()
1348 return -1; in open_capstone_handle()
1350 if (!opt->disassembler_style || in open_capstone_handle()
1351 !strcmp(opt->disassembler_style, "att")) in open_capstone_handle()
1375 if (start <= data->ip && data->ip < start + len) { in find_file_offset()
1376 data->offset = pgoff + data->ip - start; in find_file_offset()
1388 u64 start = map__rip_2objdump(map, sym->start); in read_symbol()
1389 u64 end = map__rip_2objdump(map, sym->end); in read_symbol()
1408 *len = end - start; in read_symbol()
1415 fd = -1; in read_symbol()
1435 disassembler, sym->name, filename); in symbol__disassembler_missing()
1444 struct map *map = args->ms.map; in print_capstone_detail()
1448 if (!arch__is(args->arch, "x86")) in print_capstone_detail()
1451 if (insn->detail == NULL) in print_capstone_detail()
1454 for (i = 0; i < insn->detail->x86.op_count; i++) { in print_capstone_detail()
1455 cs_x86_op *op = &insn->detail->x86.operands[i]; in print_capstone_detail()
1458 if (op->type != X86_OP_MEM) in print_capstone_detail()
1461 /* only print RIP-based global symbols for now */ in print_capstone_detail()
1462 if (op->mem.base != X86_REG_RIP) in print_capstone_detail()
1466 orig_addr = addr + insn->size + op->mem.disp; in print_capstone_detail()
1479 /* convert it to map-relative address for search */ in print_capstone_detail()
1486 if (addr == sym->start) { in print_capstone_detail()
1488 orig_addr, sym->name); in print_capstone_detail()
1491 orig_addr, sym->name, addr - sym->start); in print_capstone_detail()
1501 struct map *map = args->ms.map; in symbol__disassemble_capstone_powerpc()
1504 u64 start = map__rip_2objdump(map, sym->start); in symbol__disassemble_capstone_powerpc()
1505 u64 end = map__rip_2objdump(map, sym->end); in symbol__disassemble_capstone_powerpc()
1506 u64 len = end - start; in symbol__disassemble_capstone_powerpc()
1518 u32 *line; in symbol__disassemble_capstone_powerpc() local
1521 if (args->options->objdump_path) in symbol__disassemble_capstone_powerpc()
1522 return -1; in symbol__disassemble_capstone_powerpc()
1528 return -1; in symbol__disassemble_capstone_powerpc()
1534 if (!args->options->disassembler_style || in symbol__disassemble_capstone_powerpc()
1535 !strcmp(args->options->disassembler_style, "att")) in symbol__disassemble_capstone_powerpc()
1538 if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) in symbol__disassemble_capstone_powerpc()
1549 fd = -1; in symbol__disassemble_capstone_powerpc()
1554 line = (u32 *)buf; in symbol__disassemble_capstone_powerpc()
1556 /* add the function address and name */ in symbol__disassemble_capstone_powerpc()
1558 start, sym->name); in symbol__disassemble_capstone_powerpc()
1560 args->offset = -1; in symbol__disassemble_capstone_powerpc()
1561 args->line = disasm_buf; in symbol__disassemble_capstone_powerpc()
1562 args->line_nr = 0; in symbol__disassemble_capstone_powerpc()
1563 args->fileloc = NULL; in symbol__disassemble_capstone_powerpc()
1564 args->ms.sym = sym; in symbol__disassemble_capstone_powerpc()
1570 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_capstone_powerpc()
1576 * For now, only binary code is saved in disassembled line in symbol__disassemble_capstone_powerpc()
1584 args->offset = offset; in symbol__disassemble_capstone_powerpc()
1585 sprintf(args->line, "%x", line[i]); in symbol__disassemble_capstone_powerpc()
1591 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_capstone_powerpc()
1598 struct list_head *list = ¬es->src->source; in symbol__disassemble_capstone_powerpc()
1604 list_del_init(&dl->al.node); in symbol__disassemble_capstone_powerpc()
1607 count = -1; in symbol__disassemble_capstone_powerpc()
1619 count = -1; in symbol__disassemble_capstone_powerpc()
1627 struct map *map = args->ms.map; in symbol__disassemble_capstone()
1628 u64 start = map__rip_2objdump(map, sym->start); in symbol__disassemble_capstone()
1640 if (args->options->objdump_path) in symbol__disassemble_capstone()
1641 return -1; in symbol__disassemble_capstone()
1645 return -1; in symbol__disassemble_capstone()
1647 /* add the function address and name */ in symbol__disassemble_capstone()
1649 start, sym->name); in symbol__disassemble_capstone()
1651 args->offset = -1; in symbol__disassemble_capstone()
1652 args->line = disasm_buf; in symbol__disassemble_capstone()
1653 args->line_nr = 0; in symbol__disassemble_capstone()
1654 args->fileloc = NULL; in symbol__disassemble_capstone()
1655 args->ms.sym = sym; in symbol__disassemble_capstone()
1661 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_capstone()
1673 " %-7s %s", in symbol__disassemble_capstone()
1676 sizeof(disasm_buf) - printed, args, in symbol__disassemble_capstone()
1679 args->offset = offset; in symbol__disassemble_capstone()
1680 args->line = disasm_buf; in symbol__disassemble_capstone()
1686 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_capstone()
1693 struct list_head *list = ¬es->src->source; in symbol__disassemble_capstone()
1699 list_del_init(&dl->al.node); in symbol__disassemble_capstone()
1702 count = -1; in symbol__disassemble_capstone()
1722 list_for_each_entry_safe(dl, tmp, ¬es->src->source, al.node) { in symbol__disassemble_capstone()
1723 list_del(&dl->al.node); in symbol__disassemble_capstone()
1727 count = -1; in symbol__disassemble_capstone()
1735 return -1; in symbol__disassemble_capstone()
1742 return -1; in symbol__disassemble_capstone_powerpc()
1750 struct map *map = args->ms.map; in symbol__disassemble_raw()
1752 u64 start = map__rip_2objdump(map, sym->start); in symbol__disassemble_raw()
1753 u64 end = map__rip_2objdump(map, sym->end); in symbol__disassemble_raw()
1754 u64 len = end - start; in symbol__disassemble_raw()
1760 u32 *line; in symbol__disassemble_raw() local
1763 if (args->options->objdump_path) in symbol__disassemble_raw()
1764 return -1; in symbol__disassemble_raw()
1772 count = dso__data_read_offset(dso, NULL, sym->start, buf, len); in symbol__disassemble_raw()
1774 line = (u32 *)buf; in symbol__disassemble_raw()
1779 /* add the function address and name */ in symbol__disassemble_raw()
1781 start, sym->name); in symbol__disassemble_raw()
1783 args->offset = -1; in symbol__disassemble_raw()
1784 args->line = disasm_buf; in symbol__disassemble_raw()
1785 args->line_nr = 0; in symbol__disassemble_raw()
1786 args->fileloc = NULL; in symbol__disassemble_raw()
1787 args->ms.sym = sym; in symbol__disassemble_raw()
1793 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_raw()
1799 args->offset = offset; in symbol__disassemble_raw()
1800 sprintf(args->line, "%x", line[i]); in symbol__disassemble_raw()
1805 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_raw()
1811 struct list_head *list = ¬es->src->source; in symbol__disassemble_raw()
1817 list_del_init(&dl->al.node); in symbol__disassemble_raw()
1820 count = -1; in symbol__disassemble_raw()
1828 count = -1; in symbol__disassemble_raw()
1833 #include <llvm-c/Disassembler.h>
1834 #include <llvm-c/Target.h>
1835 #include "util/llvm-c-helpers.h"
1846 * that there is a branch or PC-relative address in the expression that we
1859 storage->branch_addr = value; in symbol_lookup_callback()
1861 storage->pcrel_load_addr = value; in symbol_lookup_callback()
1870 struct map *map = args->ms.map; in symbol__disassemble_llvm()
1872 u64 start = map__rip_2objdump(map, sym->start); in symbol__disassemble_llvm()
1885 int ret = -1; in symbol__disassemble_llvm()
1887 if (args->options->objdump_path) in symbol__disassemble_llvm()
1888 return -1; in symbol__disassemble_llvm()
1896 return -1; in symbol__disassemble_llvm()
1898 if (arch__is(args->arch, "x86")) { in symbol__disassemble_llvm()
1900 scnprintf(triplet, sizeof(triplet), "x86_64-pc-linux"); in symbol__disassemble_llvm()
1902 scnprintf(triplet, sizeof(triplet), "i686-pc-linux"); in symbol__disassemble_llvm()
1904 scnprintf(triplet, sizeof(triplet), "%s-linux-gnu", in symbol__disassemble_llvm()
1905 args->arch->name); in symbol__disassemble_llvm()
1913 if (args->options->disassembler_style && in symbol__disassemble_llvm()
1914 !strcmp(args->options->disassembler_style, "intel")) in symbol__disassemble_llvm()
1926 /* add the function address and name */ in symbol__disassemble_llvm()
1928 start, sym->name); in symbol__disassemble_llvm()
1930 args->offset = -1; in symbol__disassemble_llvm()
1931 args->line = disasm_buf; in symbol__disassemble_llvm()
1932 args->line_nr = 0; in symbol__disassemble_llvm()
1933 args->fileloc = NULL; in symbol__disassemble_llvm()
1934 args->ms.sym = sym; in symbol__disassemble_llvm()
1940 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_llvm()
1950 len - offset, pc, in symbol__disassemble_llvm()
1957 char *name = llvm_name_for_code(dso, filename, in symbol__disassemble_llvm() local
1959 if (name != NULL) { in symbol__disassemble_llvm()
1961 sizeof(disasm_buf) - in symbol__disassemble_llvm()
1963 " <%s>", name); in symbol__disassemble_llvm()
1964 free(name); in symbol__disassemble_llvm()
1968 char *name = llvm_name_for_data(dso, filename, in symbol__disassemble_llvm() local
1971 sizeof(disasm_buf) - disasm_len, in symbol__disassemble_llvm()
1974 if (name) { in symbol__disassemble_llvm()
1976 sizeof(disasm_buf) - in symbol__disassemble_llvm()
1978 " <%s>", name); in symbol__disassemble_llvm()
1979 free(name); in symbol__disassemble_llvm()
1983 args->offset = offset; in symbol__disassemble_llvm()
1984 args->line = expand_tabs(disasm_buf, &line_storage, in symbol__disassemble_llvm()
1986 args->line_nr = 0; in symbol__disassemble_llvm()
1987 args->fileloc = NULL; in symbol__disassemble_llvm()
1988 args->ms.sym = sym; in symbol__disassemble_llvm()
1990 llvm_addr2line(filename, pc, &args->fileloc, in symbol__disassemble_llvm()
1991 (unsigned int *)&args->line_nr, false, NULL); in symbol__disassemble_llvm()
1997 annotation_line__add(&dl->al, ¬es->src->source); in symbol__disassemble_llvm()
1999 free(args->fileloc); in symbol__disassemble_llvm()
2017 return -1; in symbol__disassemble_llvm()
2022 * Possibly create a new version of line with tabs expanded. Returns the
2023 * existing or new line, storage is updated if a new line is allocated. If
2026 static char *expand_tabs(char *line, char **storage, size_t *storage_len) in expand_tabs() argument
2030 size_t line_len = strlen(line); in expand_tabs()
2033 if (line[i] == '\t') in expand_tabs()
2037 return line; in expand_tabs()
2040 * Space for the line and '\0', less the leading and trailing in expand_tabs()
2057 if (line[i] == '\t') { in expand_tabs()
2058 len = i - src; in expand_tabs()
2059 memcpy(&new_line[dst], &line[src], len); in expand_tabs()
2065 num_tabs--; in expand_tabs()
2070 len = line_len - src; in expand_tabs()
2071 memcpy(&new_line[dst], &line[src], len); in expand_tabs()
2085 struct map *map = args->ms.map; in symbol__disassemble_objdump()
2092 char *line; in symbol__disassemble_objdump() local
2096 "-c", in symbol__disassemble_objdump()
2098 "--", in symbol__disassemble_objdump()
2106 "%s %s%s --start-address=0x%016" PRIx64 in symbol__disassemble_objdump()
2107 " --stop-address=0x%016" PRIx64 in symbol__disassemble_objdump()
2108 " %s -d %s %s %s %c%s%c %s%s -C \"$1\"", in symbol__disassemble_objdump()
2109 opts->objdump_path ?: "objdump", in symbol__disassemble_objdump()
2110 opts->disassembler_style ? "-M " : "", in symbol__disassemble_objdump()
2111 opts->disassembler_style ?: "", in symbol__disassemble_objdump()
2112 map__rip_2objdump(map, sym->start), in symbol__disassemble_objdump()
2113 map__rip_2objdump(map, sym->end), in symbol__disassemble_objdump()
2114 opts->show_linenr ? "-l" : "", in symbol__disassemble_objdump()
2115 opts->show_asm_raw ? "" : "--no-show-raw-insn", in symbol__disassemble_objdump()
2116 opts->annotate_src ? "-S" : "", in symbol__disassemble_objdump()
2117 opts->prefix ? "--prefix " : "", in symbol__disassemble_objdump()
2118 opts->prefix ? '"' : ' ', in symbol__disassemble_objdump()
2119 opts->prefix ?: "", in symbol__disassemble_objdump()
2120 opts->prefix ? '"' : ' ', in symbol__disassemble_objdump()
2121 opts->prefix_strip ? "--prefix-strip=" : "", in symbol__disassemble_objdump()
2122 opts->prefix_strip ?: ""); in symbol__disassemble_objdump()
2137 objdump_process.out = -1; in symbol__disassemble_objdump()
2138 objdump_process.err = -1; in symbol__disassemble_objdump()
2142 err = -1; in symbol__disassemble_objdump()
2153 err = -1; in symbol__disassemble_objdump()
2158 line = NULL; in symbol__disassemble_objdump()
2166 if (getline(&line, &line_len, file) < 0 || !line) in symbol__disassemble_objdump()
2170 match = strstr(line, filename); in symbol__disassemble_objdump()
2174 expanded_line = strim(line); in symbol__disassemble_objdump()
2175 expanded_line = expand_tabs(expanded_line, &line, &line_len); in symbol__disassemble_objdump()
2180 * The source code line number (lineno) needs to be kept in in symbol__disassemble_objdump()
2190 free(line); in symbol__disassemble_objdump()
2198 err = -1; in symbol__disassemble_objdump()
2221 struct annotation_options *options = args->options; in symbol__disassemble()
2222 struct map *map = args->ms.map; in symbol__disassemble()
2234 symfs_filename, sym->name, map__unmap_ip(map, sym->start), in symbol__disassemble()
2235 map__unmap_ip(map, sym->end)); in symbol__disassemble()
2237 pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso__long_name(dso), sym, sym->name); in symbol__disassemble()
2246 kce.addr = map__rip_2objdump(map, sym->start); in symbol__disassemble()
2248 kce.len = sym->end - sym->start; in symbol__disassemble()
2249 kce.offs = sym->start; in symbol__disassemble()
2259 return -1; in symbol__disassemble()
2272 if (arch__is(args->arch, "powerpc")) { in symbol__disassemble()
2286 err = -1; in symbol__disassemble()
2287 for (u8 i = 0; i < ARRAY_SIZE(options->disassemblers) && err != 0; i++) { in symbol__disassemble()
2288 enum perf_disassembler dis = options->disassemblers[i]; in symbol__disassemble()