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