root/tools/perf/arch/common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lookup_path
  2. lookup_triplets
  3. perf_env__lookup_binutils_path
  4. perf_env__lookup_objdump
  5. perf_env__single_address_space

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <limits.h>
   3 #include <stdio.h>
   4 #include <stdlib.h>
   5 #include <string.h>
   6 #include <unistd.h>
   7 #include "common.h"
   8 #include "../util/env.h"
   9 #include "../util/debug.h"
  10 #include <linux/zalloc.h>
  11 
  12 const char *const arc_triplets[] = {
  13         "arc-linux-",
  14         "arc-snps-linux-uclibc-",
  15         "arc-snps-linux-gnu-",
  16         NULL
  17 };
  18 
  19 const char *const arm_triplets[] = {
  20         "arm-eabi-",
  21         "arm-linux-androideabi-",
  22         "arm-unknown-linux-",
  23         "arm-unknown-linux-gnu-",
  24         "arm-unknown-linux-gnueabi-",
  25         "arm-linux-gnu-",
  26         "arm-linux-gnueabihf-",
  27         "arm-none-eabi-",
  28         NULL
  29 };
  30 
  31 const char *const arm64_triplets[] = {
  32         "aarch64-linux-android-",
  33         "aarch64-linux-gnu-",
  34         NULL
  35 };
  36 
  37 const char *const powerpc_triplets[] = {
  38         "powerpc-unknown-linux-gnu-",
  39         "powerpc-linux-gnu-",
  40         "powerpc64-unknown-linux-gnu-",
  41         "powerpc64-linux-gnu-",
  42         "powerpc64le-linux-gnu-",
  43         NULL
  44 };
  45 
  46 const char *const s390_triplets[] = {
  47         "s390-ibm-linux-",
  48         "s390x-linux-gnu-",
  49         NULL
  50 };
  51 
  52 const char *const sh_triplets[] = {
  53         "sh-unknown-linux-gnu-",
  54         "sh64-unknown-linux-gnu-",
  55         "sh-linux-gnu-",
  56         "sh64-linux-gnu-",
  57         NULL
  58 };
  59 
  60 const char *const sparc_triplets[] = {
  61         "sparc-unknown-linux-gnu-",
  62         "sparc64-unknown-linux-gnu-",
  63         "sparc64-linux-gnu-",
  64         NULL
  65 };
  66 
  67 const char *const x86_triplets[] = {
  68         "x86_64-pc-linux-gnu-",
  69         "x86_64-unknown-linux-gnu-",
  70         "i686-pc-linux-gnu-",
  71         "i586-pc-linux-gnu-",
  72         "i486-pc-linux-gnu-",
  73         "i386-pc-linux-gnu-",
  74         "i686-linux-android-",
  75         "i686-android-linux-",
  76         "x86_64-linux-gnu-",
  77         "i586-linux-gnu-",
  78         NULL
  79 };
  80 
  81 const char *const mips_triplets[] = {
  82         "mips-unknown-linux-gnu-",
  83         "mipsel-linux-android-",
  84         "mips-linux-gnu-",
  85         "mips64-linux-gnu-",
  86         "mips64el-linux-gnuabi64-",
  87         "mips64-linux-gnuabi64-",
  88         "mipsel-linux-gnu-",
  89         NULL
  90 };
  91 
  92 static bool lookup_path(char *name)
  93 {
  94         bool found = false;
  95         char *path, *tmp = NULL;
  96         char buf[PATH_MAX];
  97         char *env = getenv("PATH");
  98 
  99         if (!env)
 100                 return false;
 101 
 102         env = strdup(env);
 103         if (!env)
 104                 return false;
 105 
 106         path = strtok_r(env, ":", &tmp);
 107         while (path) {
 108                 scnprintf(buf, sizeof(buf), "%s/%s", path, name);
 109                 if (access(buf, F_OK) == 0) {
 110                         found = true;
 111                         break;
 112                 }
 113                 path = strtok_r(NULL, ":", &tmp);
 114         }
 115         free(env);
 116         return found;
 117 }
 118 
 119 static int lookup_triplets(const char *const *triplets, const char *name)
 120 {
 121         int i;
 122         char buf[PATH_MAX];
 123 
 124         for (i = 0; triplets[i] != NULL; i++) {
 125                 scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name);
 126                 if (lookup_path(buf))
 127                         return i;
 128         }
 129         return -1;
 130 }
 131 
 132 static int perf_env__lookup_binutils_path(struct perf_env *env,
 133                                           const char *name, const char **path)
 134 {
 135         int idx;
 136         const char *arch = perf_env__arch(env), *cross_env;
 137         const char *const *path_list;
 138         char *buf = NULL;
 139 
 140         /*
 141          * We don't need to try to find objdump path for native system.
 142          * Just use default binutils path (e.g.: "objdump").
 143          */
 144         if (!strcmp(perf_env__arch(NULL), arch))
 145                 goto out;
 146 
 147         cross_env = getenv("CROSS_COMPILE");
 148         if (cross_env) {
 149                 if (asprintf(&buf, "%s%s", cross_env, name) < 0)
 150                         goto out_error;
 151                 if (buf[0] == '/') {
 152                         if (access(buf, F_OK) == 0)
 153                                 goto out;
 154                         goto out_error;
 155                 }
 156                 if (lookup_path(buf))
 157                         goto out;
 158                 zfree(&buf);
 159         }
 160 
 161         if (!strcmp(arch, "arc"))
 162                 path_list = arc_triplets;
 163         else if (!strcmp(arch, "arm"))
 164                 path_list = arm_triplets;
 165         else if (!strcmp(arch, "arm64"))
 166                 path_list = arm64_triplets;
 167         else if (!strcmp(arch, "powerpc"))
 168                 path_list = powerpc_triplets;
 169         else if (!strcmp(arch, "sh"))
 170                 path_list = sh_triplets;
 171         else if (!strcmp(arch, "s390"))
 172                 path_list = s390_triplets;
 173         else if (!strcmp(arch, "sparc"))
 174                 path_list = sparc_triplets;
 175         else if (!strcmp(arch, "x86"))
 176                 path_list = x86_triplets;
 177         else if (!strcmp(arch, "mips"))
 178                 path_list = mips_triplets;
 179         else {
 180                 ui__error("binutils for %s not supported.\n", arch);
 181                 goto out_error;
 182         }
 183 
 184         idx = lookup_triplets(path_list, name);
 185         if (idx < 0) {
 186                 ui__error("Please install %s for %s.\n"
 187                           "You can add it to PATH, set CROSS_COMPILE or "
 188                           "override the default using --%s.\n",
 189                           name, arch, name);
 190                 goto out_error;
 191         }
 192 
 193         if (asprintf(&buf, "%s%s", path_list[idx], name) < 0)
 194                 goto out_error;
 195 
 196 out:
 197         *path = buf;
 198         return 0;
 199 out_error:
 200         free(buf);
 201         *path = NULL;
 202         return -1;
 203 }
 204 
 205 int perf_env__lookup_objdump(struct perf_env *env, const char **path)
 206 {
 207         /*
 208          * For live mode, env->arch will be NULL and we can use
 209          * the native objdump tool.
 210          */
 211         if (env->arch == NULL)
 212                 return 0;
 213 
 214         return perf_env__lookup_binutils_path(env, "objdump", path);
 215 }
 216 
 217 /*
 218  * Some architectures have a single address space for kernel and user addresses,
 219  * which makes it possible to determine if an address is in kernel space or user
 220  * space.
 221  */
 222 bool perf_env__single_address_space(struct perf_env *env)
 223 {
 224         return strcmp(perf_env__arch(env), "sparc");
 225 }

/* [<][>][^][v][top][bottom][index][help] */