@@ -2102,6 +2102,57 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
21022102 return 0 ;
21032103}
21042104
2105+ const char * const perf_disassembler__strs [] = {
2106+ [PERF_DISASM_UNKNOWN ] = "unknown" ,
2107+ [PERF_DISASM_LLVM ] = "llvm" ,
2108+ [PERF_DISASM_CAPSTONE ] = "capstone" ,
2109+ [PERF_DISASM_OBJDUMP ] = "objdump" ,
2110+ };
2111+
2112+
2113+ static void annotation_options__add_disassembler (struct annotation_options * options ,
2114+ enum perf_disassembler dis )
2115+ {
2116+ for (u8 i = 0 ; i < ARRAY_SIZE (options -> disassemblers ); i ++ ) {
2117+ if (options -> disassemblers [i ] == dis ) {
2118+ /* Disassembler is already present then don't add again. */
2119+ return ;
2120+ }
2121+ if (options -> disassemblers [i ] == PERF_DISASM_UNKNOWN ) {
2122+ /* Found a free slot. */
2123+ options -> disassemblers [i ] = dis ;
2124+ return ;
2125+ }
2126+ }
2127+ pr_err ("Failed to add disassembler %d\n" , dis );
2128+ }
2129+
2130+ static int annotation_options__add_disassemblers_str (struct annotation_options * options ,
2131+ const char * str )
2132+ {
2133+ while (str && * str != '\0' ) {
2134+ const char * comma = strchr (str , ',' );
2135+ int len = comma ? comma - str : (int )strlen (str );
2136+ bool match = false;
2137+
2138+ for (u8 i = 0 ; i < ARRAY_SIZE (perf_disassembler__strs ); i ++ ) {
2139+ const char * dis_str = perf_disassembler__strs [i ];
2140+
2141+ if (len == (int )strlen (dis_str ) && !strncmp (str , dis_str , len )) {
2142+ annotation_options__add_disassembler (options , i );
2143+ match = true;
2144+ break ;
2145+ }
2146+ }
2147+ if (!match ) {
2148+ pr_err ("Invalid disassembler '%.*s'\n" , len , str );
2149+ return -1 ;
2150+ }
2151+ str = comma ? comma + 1 : NULL ;
2152+ }
2153+ return 0 ;
2154+ }
2155+
21052156static int annotation__config (const char * var , const char * value , void * data )
21062157{
21072158 struct annotation_options * opt = data ;
@@ -2116,6 +2167,11 @@ static int annotation__config(const char *var, const char *value, void *data)
21162167 opt -> offset_level = ANNOTATION__MAX_OFFSET_LEVEL ;
21172168 else if (opt -> offset_level < ANNOTATION__MIN_OFFSET_LEVEL )
21182169 opt -> offset_level = ANNOTATION__MIN_OFFSET_LEVEL ;
2170+ } else if (!strcmp (var , "annotate.disassemblers" )) {
2171+ int err = annotation_options__add_disassemblers_str (opt , value );
2172+
2173+ if (err )
2174+ return err ;
21192175 } else if (!strcmp (var , "annotate.hide_src_code" )) {
21202176 opt -> hide_src_code = perf_config_bool ("hide_src_code" , value );
21212177 } else if (!strcmp (var , "annotate.jump_arrows" )) {
@@ -2181,9 +2237,25 @@ void annotation_options__exit(void)
21812237 zfree (& annotate_opts .objdump_path );
21822238}
21832239
2240+ static void annotation_options__default_init_disassemblers (struct annotation_options * options )
2241+ {
2242+ if (options -> disassemblers [0 ] != PERF_DISASM_UNKNOWN ) {
2243+ /* Already initialized. */
2244+ return ;
2245+ }
2246+ #ifdef HAVE_LIBLLVM_SUPPORT
2247+ annotation_options__add_disassembler (options , PERF_DISASM_LLVM );
2248+ #endif
2249+ #ifdef HAVE_LIBCAPSTONE_SUPPORT
2250+ annotation_options__add_disassembler (options , PERF_DISASM_CAPSTONE );
2251+ #endif
2252+ annotation_options__add_disassembler (options , PERF_DISASM_OBJDUMP );
2253+ }
2254+
21842255void annotation_config__init (void )
21852256{
21862257 perf_config (annotation__config , & annotate_opts );
2258+ annotation_options__default_init_disassemblers (& annotate_opts );
21872259}
21882260
21892261static unsigned int parse_percent_type (char * str1 , char * str2 )
0 commit comments