18
18
#include "annotate.h"
19
19
#include "evsel.h"
20
20
#include "block-range.h"
21
+ #include "arch/common.h"
21
22
#include <regex.h>
22
23
#include <pthread.h>
23
24
#include <linux/bitops.h>
25
+ #include <sys/utsname.h>
24
26
25
27
const char * disassembler_style ;
26
28
const char * objdump_path ;
@@ -29,6 +31,28 @@ static regex_t file_lineno;
29
31
static struct ins * ins__find (const char * name );
30
32
static int disasm_line__parse (char * line , char * * namep , char * * rawp );
31
33
34
+ struct arch {
35
+ const char * name ;
36
+ struct {
37
+ char comment_char ;
38
+ } objdump ;
39
+ };
40
+
41
+ static struct arch architectures [] = {
42
+ {
43
+ .name = "arm" ,
44
+ .objdump = {
45
+ .comment_char = ';' ,
46
+ },
47
+ },
48
+ {
49
+ .name = "x86" ,
50
+ .objdump = {
51
+ .comment_char = '#' ,
52
+ },
53
+ },
54
+ };
55
+
32
56
static void ins__delete (struct ins_operands * ops )
33
57
{
34
58
if (ops == NULL )
@@ -54,7 +78,7 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size,
54
78
return ins__raw_scnprintf (ins , bf , size , ops );
55
79
}
56
80
57
- static int call__parse (struct ins_operands * ops , struct map * map )
81
+ static int call__parse (struct arch * arch __maybe_unused , struct ins_operands * ops , struct map * map )
58
82
{
59
83
char * endptr , * tok , * name ;
60
84
@@ -118,7 +142,7 @@ bool ins__is_call(const struct ins *ins)
118
142
return ins -> ops == & call_ops ;
119
143
}
120
144
121
- static int jump__parse (struct ins_operands * ops , struct map * map __maybe_unused )
145
+ static int jump__parse (struct arch * arch __maybe_unused , struct ins_operands * ops , struct map * map __maybe_unused )
122
146
{
123
147
const char * s = strchr (ops -> raw , '+' );
124
148
@@ -173,7 +197,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
173
197
return 0 ;
174
198
}
175
199
176
- static int lock__parse (struct ins_operands * ops , struct map * map )
200
+ static int lock__parse (struct arch * arch , struct ins_operands * ops , struct map * map )
177
201
{
178
202
char * name ;
179
203
@@ -194,7 +218,7 @@ static int lock__parse(struct ins_operands *ops, struct map *map)
194
218
return 0 ;
195
219
196
220
if (ops -> locked .ins -> ops -> parse &&
197
- ops -> locked .ins -> ops -> parse (ops -> locked .ops , map ) < 0 )
221
+ ops -> locked .ins -> ops -> parse (arch , ops -> locked .ops , map ) < 0 )
198
222
goto out_free_ops ;
199
223
200
224
return 0 ;
@@ -237,7 +261,7 @@ static struct ins_ops lock_ops = {
237
261
.scnprintf = lock__scnprintf ,
238
262
};
239
263
240
- static int mov__parse (struct ins_operands * ops , struct map * map __maybe_unused )
264
+ static int mov__parse (struct arch * arch , struct ins_operands * ops , struct map * map __maybe_unused )
241
265
{
242
266
char * s = strchr (ops -> raw , ',' ), * target , * comment , prev ;
243
267
@@ -252,11 +276,7 @@ static int mov__parse(struct ins_operands *ops, struct map *map __maybe_unused)
252
276
return -1 ;
253
277
254
278
target = ++ s ;
255
- #ifdef __arm__
256
- comment = strchr (s , ';' );
257
- #else
258
- comment = strchr (s , '#' );
259
- #endif
279
+ comment = strchr (s , arch -> objdump .comment_char );
260
280
261
281
if (comment != NULL )
262
282
s = comment - 1 ;
@@ -304,7 +324,7 @@ static struct ins_ops mov_ops = {
304
324
.scnprintf = mov__scnprintf ,
305
325
};
306
326
307
- static int dec__parse (struct ins_operands * ops , struct map * map __maybe_unused )
327
+ static int dec__parse (struct arch * arch __maybe_unused , struct ins_operands * ops , struct map * map __maybe_unused )
308
328
{
309
329
char * target , * comment , * s , prev ;
310
330
@@ -492,6 +512,41 @@ static struct ins *ins__find(const char *name)
492
512
return bsearch (name , instructions , nmemb , sizeof (struct ins ), ins__key_cmp );
493
513
}
494
514
515
+ static int arch__key_cmp (const void * name , const void * archp )
516
+ {
517
+ const struct arch * arch = archp ;
518
+
519
+ return strcmp (name , arch -> name );
520
+ }
521
+
522
+ static int arch__cmp (const void * a , const void * b )
523
+ {
524
+ const struct arch * aa = a ;
525
+ const struct arch * ab = b ;
526
+
527
+ return strcmp (aa -> name , ab -> name );
528
+ }
529
+
530
+ static void arch__sort (void )
531
+ {
532
+ const int nmemb = ARRAY_SIZE (architectures );
533
+
534
+ qsort (architectures , nmemb , sizeof (struct arch ), arch__cmp );
535
+ }
536
+
537
+ static struct arch * arch__find (const char * name )
538
+ {
539
+ const int nmemb = ARRAY_SIZE (architectures );
540
+ static bool sorted ;
541
+
542
+ if (!sorted ) {
543
+ arch__sort ();
544
+ sorted = true;
545
+ }
546
+
547
+ return bsearch (name , architectures , nmemb , sizeof (struct arch ), arch__key_cmp );
548
+ }
549
+
495
550
int symbol__alloc_hist (struct symbol * sym )
496
551
{
497
552
struct annotation * notes = symbol__annotation (sym );
@@ -709,7 +764,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
709
764
return symbol__inc_addr_samples (he -> ms .sym , he -> ms .map , evidx , ip );
710
765
}
711
766
712
- static void disasm_line__init_ins (struct disasm_line * dl , struct map * map )
767
+ static void disasm_line__init_ins (struct disasm_line * dl , struct arch * arch , struct map * map )
713
768
{
714
769
dl -> ins = ins__find (dl -> name );
715
770
@@ -719,7 +774,7 @@ static void disasm_line__init_ins(struct disasm_line *dl, struct map *map)
719
774
if (!dl -> ins -> ops )
720
775
return ;
721
776
722
- if (dl -> ins -> ops -> parse && dl -> ins -> ops -> parse (& dl -> ops , map ) < 0 )
777
+ if (dl -> ins -> ops -> parse && dl -> ins -> ops -> parse (arch , & dl -> ops , map ) < 0 )
723
778
dl -> ins = NULL ;
724
779
}
725
780
@@ -762,6 +817,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
762
817
763
818
static struct disasm_line * disasm_line__new (s64 offset , char * line ,
764
819
size_t privsize , int line_nr ,
820
+ struct arch * arch ,
765
821
struct map * map )
766
822
{
767
823
struct disasm_line * dl = zalloc (sizeof (* dl ) + privsize );
@@ -777,7 +833,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line,
777
833
if (disasm_line__parse (dl -> line , & dl -> name , & dl -> ops .raw ) < 0 )
778
834
goto out_free_line ;
779
835
780
- disasm_line__init_ins (dl , map );
836
+ disasm_line__init_ins (dl , arch , map );
781
837
}
782
838
}
783
839
@@ -1087,6 +1143,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
1087
1143
* The ops.raw part will be parsed further according to type of the instruction.
1088
1144
*/
1089
1145
static int symbol__parse_objdump_line (struct symbol * sym , struct map * map ,
1146
+ struct arch * arch ,
1090
1147
FILE * file , size_t privsize ,
1091
1148
int * line_nr )
1092
1149
{
@@ -1149,7 +1206,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
1149
1206
parsed_line = tmp2 + 1 ;
1150
1207
}
1151
1208
1152
- dl = disasm_line__new (offset , parsed_line , privsize , * line_nr , map );
1209
+ dl = disasm_line__new (offset , parsed_line , privsize , * line_nr , arch , map );
1153
1210
free (line );
1154
1211
(* line_nr )++ ;
1155
1212
@@ -1280,10 +1337,23 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
1280
1337
return 0 ;
1281
1338
}
1282
1339
1283
- int symbol__disassemble (struct symbol * sym , struct map * map , size_t privsize )
1340
+ static const char * annotate__norm_arch (const char * arch_name )
1341
+ {
1342
+ struct utsname uts ;
1343
+
1344
+ if (!arch_name ) { /* Assume we are annotating locally. */
1345
+ if (uname (& uts ) < 0 )
1346
+ return NULL ;
1347
+ arch_name = uts .machine ;
1348
+ }
1349
+ return normalize_arch ((char * )arch_name );
1350
+ }
1351
+
1352
+ int symbol__disassemble (struct symbol * sym , struct map * map , const char * arch_name , size_t privsize )
1284
1353
{
1285
1354
struct dso * dso = map -> dso ;
1286
1355
char command [PATH_MAX * 2 ];
1356
+ struct arch * arch = NULL ;
1287
1357
FILE * file ;
1288
1358
char symfs_filename [PATH_MAX ];
1289
1359
struct kcore_extract kce ;
@@ -1297,6 +1367,14 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
1297
1367
if (err )
1298
1368
return err ;
1299
1369
1370
+ arch_name = annotate__norm_arch (arch_name );
1371
+ if (!arch_name )
1372
+ return -1 ;
1373
+
1374
+ arch = arch__find (arch_name );
1375
+ if (arch == NULL )
1376
+ return - ENOTSUP ;
1377
+
1300
1378
pr_debug ("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n" , __func__ ,
1301
1379
symfs_filename , sym -> name , map -> unmap_ip (map , sym -> start ),
1302
1380
map -> unmap_ip (map , sym -> end ));
@@ -1395,7 +1473,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
1395
1473
1396
1474
nline = 0 ;
1397
1475
while (!feof (file )) {
1398
- if (symbol__parse_objdump_line (sym , map , file , privsize ,
1476
+ if (symbol__parse_objdump_line (sym , map , arch , file , privsize ,
1399
1477
& lineno ) < 0 )
1400
1478
break ;
1401
1479
nline ++ ;
@@ -1793,7 +1871,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1793
1871
struct rb_root source_line = RB_ROOT ;
1794
1872
u64 len ;
1795
1873
1796
- if (symbol__disassemble (sym , map , 0 ) < 0 )
1874
+ if (symbol__disassemble (sym , map , perf_evsel__env_arch ( evsel ), 0 ) < 0 )
1797
1875
return -1 ;
1798
1876
1799
1877
len = symbol__size (sym );
0 commit comments