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