0001
0002 #include <inttypes.h>
0003 #include <limits.h>
0004 #include <stdio.h>
0005 #include <stdlib.h>
0006 #include <string.h>
0007 #include <linux/string.h>
0008 #include <linux/zalloc.h>
0009 #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
0010 #include "debug.h"
0011 #include "dso.h"
0012 #include "map.h"
0013 #include "namespaces.h"
0014 #include "srcline.h"
0015 #include "symbol.h"
0016 #include "thread.h"
0017 #include "vdso.h"
0018
0019 static inline int is_android_lib(const char *filename)
0020 {
0021 return strstarts(filename, "/data/app-lib/") ||
0022 strstarts(filename, "/system/lib/");
0023 }
0024
0025 static inline bool replace_android_lib(const char *filename, char *newfilename)
0026 {
0027 const char *libname;
0028 char *app_abi;
0029 size_t app_abi_length, new_length;
0030 size_t lib_length = 0;
0031
0032 libname = strrchr(filename, '/');
0033 if (libname)
0034 lib_length = strlen(libname);
0035
0036 app_abi = getenv("APP_ABI");
0037 if (!app_abi)
0038 return false;
0039
0040 app_abi_length = strlen(app_abi);
0041
0042 if (strstarts(filename, "/data/app-lib/")) {
0043 char *apk_path;
0044
0045 if (!app_abi_length)
0046 return false;
0047
0048 new_length = 7 + app_abi_length + lib_length;
0049
0050 apk_path = getenv("APK_PATH");
0051 if (apk_path) {
0052 new_length += strlen(apk_path) + 1;
0053 if (new_length > PATH_MAX)
0054 return false;
0055 snprintf(newfilename, new_length,
0056 "%s/libs/%s/%s", apk_path, app_abi, libname);
0057 } else {
0058 if (new_length > PATH_MAX)
0059 return false;
0060 snprintf(newfilename, new_length,
0061 "libs/%s/%s", app_abi, libname);
0062 }
0063 return true;
0064 }
0065
0066 if (strstarts(filename, "/system/lib/")) {
0067 char *ndk, *app;
0068 const char *arch;
0069 int ndk_length, app_length;
0070
0071 ndk = getenv("NDK_ROOT");
0072 app = getenv("APP_PLATFORM");
0073
0074 if (!(ndk && app))
0075 return false;
0076
0077 ndk_length = strlen(ndk);
0078 app_length = strlen(app);
0079
0080 if (!(ndk_length && app_length && app_abi_length))
0081 return false;
0082
0083 arch = !strncmp(app_abi, "arm", 3) ? "arm" :
0084 !strncmp(app_abi, "mips", 4) ? "mips" :
0085 !strncmp(app_abi, "x86", 3) ? "x86" : NULL;
0086
0087 if (!arch)
0088 return false;
0089
0090 new_length = 27 + ndk_length +
0091 app_length + lib_length
0092 + strlen(arch);
0093
0094 if (new_length > PATH_MAX)
0095 return false;
0096 snprintf(newfilename, new_length,
0097 "%.*s/platforms/%.*s/arch-%s/usr/lib/%s",
0098 ndk_length, ndk, app_length, app, arch, libname);
0099
0100 return true;
0101 }
0102 return false;
0103 }
0104
0105 void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
0106 {
0107 map->start = start;
0108 map->end = end;
0109 map->pgoff = pgoff;
0110 map->reloc = 0;
0111 map->dso = dso__get(dso);
0112 map->map_ip = map__map_ip;
0113 map->unmap_ip = map__unmap_ip;
0114 RB_CLEAR_NODE(&map->rb_node);
0115 map->erange_warned = false;
0116 refcount_set(&map->refcnt, 1);
0117 }
0118
0119 struct map *map__new(struct machine *machine, u64 start, u64 len,
0120 u64 pgoff, struct dso_id *id,
0121 u32 prot, u32 flags, struct build_id *bid,
0122 char *filename, struct thread *thread)
0123 {
0124 struct map *map = malloc(sizeof(*map));
0125 struct nsinfo *nsi = NULL;
0126 struct nsinfo *nnsi;
0127
0128 if (map != NULL) {
0129 char newfilename[PATH_MAX];
0130 struct dso *dso, *header_bid_dso;
0131 int anon, no_dso, vdso, android;
0132
0133 android = is_android_lib(filename);
0134 anon = is_anon_memory(filename) || flags & MAP_HUGETLB;
0135 vdso = is_vdso_map(filename);
0136 no_dso = is_no_dso_memory(filename);
0137 map->prot = prot;
0138 map->flags = flags;
0139 nsi = nsinfo__get(thread->nsinfo);
0140
0141 if ((anon || no_dso) && nsi && (prot & PROT_EXEC)) {
0142 snprintf(newfilename, sizeof(newfilename),
0143 "/tmp/perf-%d.map", nsinfo__pid(nsi));
0144 filename = newfilename;
0145 }
0146
0147 if (android) {
0148 if (replace_android_lib(filename, newfilename))
0149 filename = newfilename;
0150 }
0151
0152 if (vdso) {
0153
0154
0155
0156
0157 nnsi = nsinfo__copy(nsi);
0158 if (nnsi) {
0159 nsinfo__put(nsi);
0160 nsinfo__clear_need_setns(nnsi);
0161 nsi = nnsi;
0162 }
0163 pgoff = 0;
0164 dso = machine__findnew_vdso(machine, thread);
0165 } else
0166 dso = machine__findnew_dso_id(machine, filename, id);
0167
0168 if (dso == NULL)
0169 goto out_delete;
0170
0171 map__init(map, start, start + len, pgoff, dso);
0172
0173 if (anon || no_dso) {
0174 map->map_ip = map->unmap_ip = identity__map_ip;
0175
0176
0177
0178
0179
0180
0181 if (!(prot & PROT_EXEC))
0182 dso__set_loaded(dso);
0183 }
0184 dso->nsinfo = nsi;
0185
0186 if (build_id__is_defined(bid)) {
0187 dso__set_build_id(dso, bid);
0188 } else {
0189
0190
0191
0192
0193
0194
0195 down_read(&machine->dsos.lock);
0196 header_bid_dso = __dsos__find(&machine->dsos, filename, false);
0197 up_read(&machine->dsos.lock);
0198 if (header_bid_dso && header_bid_dso->header_build_id) {
0199 dso__set_build_id(dso, &header_bid_dso->bid);
0200 dso->header_build_id = 1;
0201 }
0202 }
0203 dso__put(dso);
0204 }
0205 return map;
0206 out_delete:
0207 nsinfo__put(nsi);
0208 free(map);
0209 return NULL;
0210 }
0211
0212
0213
0214
0215
0216
0217 struct map *map__new2(u64 start, struct dso *dso)
0218 {
0219 struct map *map = calloc(1, (sizeof(*map) +
0220 (dso->kernel ? sizeof(struct kmap) : 0)));
0221 if (map != NULL) {
0222
0223
0224
0225 map__init(map, start, 0, 0, dso);
0226 }
0227
0228 return map;
0229 }
0230
0231 bool __map__is_kernel(const struct map *map)
0232 {
0233 if (!map->dso->kernel)
0234 return false;
0235 return machine__kernel_map(map__kmaps((struct map *)map)->machine) == map;
0236 }
0237
0238 bool __map__is_extra_kernel_map(const struct map *map)
0239 {
0240 struct kmap *kmap = __map__kmap((struct map *)map);
0241
0242 return kmap && kmap->name[0];
0243 }
0244
0245 bool __map__is_bpf_prog(const struct map *map)
0246 {
0247 const char *name;
0248
0249 if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
0250 return true;
0251
0252
0253
0254
0255
0256
0257 name = map->dso->short_name;
0258 return name && (strstr(name, "bpf_prog_") == name);
0259 }
0260
0261 bool __map__is_bpf_image(const struct map *map)
0262 {
0263 const char *name;
0264
0265 if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE)
0266 return true;
0267
0268
0269
0270
0271
0272
0273 name = map->dso->short_name;
0274 return name && is_bpf_image(name);
0275 }
0276
0277 bool __map__is_ool(const struct map *map)
0278 {
0279 return map->dso && map->dso->binary_type == DSO_BINARY_TYPE__OOL;
0280 }
0281
0282 bool map__has_symbols(const struct map *map)
0283 {
0284 return dso__has_symbols(map->dso);
0285 }
0286
0287 static void map__exit(struct map *map)
0288 {
0289 BUG_ON(refcount_read(&map->refcnt) != 0);
0290 dso__zput(map->dso);
0291 }
0292
0293 void map__delete(struct map *map)
0294 {
0295 map__exit(map);
0296 free(map);
0297 }
0298
0299 void map__put(struct map *map)
0300 {
0301 if (map && refcount_dec_and_test(&map->refcnt))
0302 map__delete(map);
0303 }
0304
0305 void map__fixup_start(struct map *map)
0306 {
0307 struct rb_root_cached *symbols = &map->dso->symbols;
0308 struct rb_node *nd = rb_first_cached(symbols);
0309 if (nd != NULL) {
0310 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
0311 map->start = sym->start;
0312 }
0313 }
0314
0315 void map__fixup_end(struct map *map)
0316 {
0317 struct rb_root_cached *symbols = &map->dso->symbols;
0318 struct rb_node *nd = rb_last(&symbols->rb_root);
0319 if (nd != NULL) {
0320 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
0321 map->end = sym->end;
0322 }
0323 }
0324
0325 #define DSO__DELETED "(deleted)"
0326
0327 int map__load(struct map *map)
0328 {
0329 const char *name = map->dso->long_name;
0330 int nr;
0331
0332 if (dso__loaded(map->dso))
0333 return 0;
0334
0335 nr = dso__load(map->dso, map);
0336 if (nr < 0) {
0337 if (map->dso->has_build_id) {
0338 char sbuild_id[SBUILD_ID_SIZE];
0339
0340 build_id__sprintf(&map->dso->bid, sbuild_id);
0341 pr_debug("%s with build id %s not found", name, sbuild_id);
0342 } else
0343 pr_debug("Failed to open %s", name);
0344
0345 pr_debug(", continuing without symbols\n");
0346 return -1;
0347 } else if (nr == 0) {
0348 #ifdef HAVE_LIBELF_SUPPORT
0349 const size_t len = strlen(name);
0350 const size_t real_len = len - sizeof(DSO__DELETED);
0351
0352 if (len > sizeof(DSO__DELETED) &&
0353 strcmp(name + real_len + 1, DSO__DELETED) == 0) {
0354 pr_debug("%.*s was updated (is prelink enabled?). "
0355 "Restart the long running apps that use it!\n",
0356 (int)real_len, name);
0357 } else {
0358 pr_debug("no symbols found in %s, maybe install a debug package?\n", name);
0359 }
0360 #endif
0361 return -1;
0362 }
0363
0364 return 0;
0365 }
0366
0367 struct symbol *map__find_symbol(struct map *map, u64 addr)
0368 {
0369 if (map__load(map) < 0)
0370 return NULL;
0371
0372 return dso__find_symbol(map->dso, addr);
0373 }
0374
0375 struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
0376 {
0377 if (map__load(map) < 0)
0378 return NULL;
0379
0380 if (!dso__sorted_by_name(map->dso))
0381 dso__sort_by_name(map->dso);
0382
0383 return dso__find_symbol_by_name(map->dso, name);
0384 }
0385
0386 struct map *map__clone(struct map *from)
0387 {
0388 size_t size = sizeof(struct map);
0389 struct map *map;
0390
0391 if (from->dso && from->dso->kernel)
0392 size += sizeof(struct kmap);
0393
0394 map = memdup(from, size);
0395 if (map != NULL) {
0396 refcount_set(&map->refcnt, 1);
0397 RB_CLEAR_NODE(&map->rb_node);
0398 dso__get(map->dso);
0399 }
0400
0401 return map;
0402 }
0403
0404 size_t map__fprintf(struct map *map, FILE *fp)
0405 {
0406 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
0407 map->start, map->end, map->pgoff, map->dso->name);
0408 }
0409
0410 size_t map__fprintf_dsoname(struct map *map, FILE *fp)
0411 {
0412 char buf[symbol_conf.pad_output_len_dso + 1];
0413 const char *dsoname = "[unknown]";
0414
0415 if (map && map->dso) {
0416 if (symbol_conf.show_kernel_path && map->dso->long_name)
0417 dsoname = map->dso->long_name;
0418 else
0419 dsoname = map->dso->name;
0420 }
0421
0422 if (symbol_conf.pad_output_len_dso) {
0423 scnprintf_pad(buf, symbol_conf.pad_output_len_dso, "%s", dsoname);
0424 dsoname = buf;
0425 }
0426
0427 return fprintf(fp, "%s", dsoname);
0428 }
0429
0430 char *map__srcline(struct map *map, u64 addr, struct symbol *sym)
0431 {
0432 if (map == NULL)
0433 return SRCLINE_UNKNOWN;
0434 return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, true, addr);
0435 }
0436
0437 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
0438 FILE *fp)
0439 {
0440 int ret = 0;
0441
0442 if (map && map->dso) {
0443 char *srcline = map__srcline(map, addr, NULL);
0444 if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)
0445 ret = fprintf(fp, "%s%s", prefix, srcline);
0446 free_srcline(srcline);
0447 }
0448 return ret;
0449 }
0450
0451 void srccode_state_free(struct srccode_state *state)
0452 {
0453 zfree(&state->srcfile);
0454 state->line = 0;
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 u64 map__rip_2objdump(struct map *map, u64 rip)
0469 {
0470 struct kmap *kmap = __map__kmap(map);
0471
0472
0473
0474
0475
0476
0477 if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps && kmap->kmaps->machine) {
0478 struct map *kernel_map = machine__kernel_map(kmap->kmaps->machine);
0479
0480 if (kernel_map)
0481 map = kernel_map;
0482 }
0483
0484 if (!map->dso->adjust_symbols)
0485 return rip;
0486
0487 if (map->dso->rel)
0488 return rip - map->pgoff;
0489
0490
0491
0492
0493
0494 if (map->dso->kernel == DSO_SPACE__USER)
0495 return rip + map->dso->text_offset;
0496
0497 return map->unmap_ip(map, rip) - map->reloc;
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 u64 map__objdump_2mem(struct map *map, u64 ip)
0513 {
0514 if (!map->dso->adjust_symbols)
0515 return map->unmap_ip(map, ip);
0516
0517 if (map->dso->rel)
0518 return map->unmap_ip(map, ip + map->pgoff);
0519
0520
0521
0522
0523
0524 if (map->dso->kernel == DSO_SPACE__USER)
0525 return map->unmap_ip(map, ip - map->dso->text_offset);
0526
0527 return ip + map->reloc;
0528 }
0529
0530 bool map__contains_symbol(const struct map *map, const struct symbol *sym)
0531 {
0532 u64 ip = map->unmap_ip(map, sym->start);
0533
0534 return ip >= map->start && ip < map->end;
0535 }
0536
0537 static struct map *__map__next(struct map *map)
0538 {
0539 struct rb_node *next = rb_next(&map->rb_node);
0540
0541 if (next)
0542 return rb_entry(next, struct map, rb_node);
0543 return NULL;
0544 }
0545
0546 struct map *map__next(struct map *map)
0547 {
0548 return map ? __map__next(map) : NULL;
0549 }
0550
0551 struct kmap *__map__kmap(struct map *map)
0552 {
0553 if (!map->dso || !map->dso->kernel)
0554 return NULL;
0555 return (struct kmap *)(map + 1);
0556 }
0557
0558 struct kmap *map__kmap(struct map *map)
0559 {
0560 struct kmap *kmap = __map__kmap(map);
0561
0562 if (!kmap)
0563 pr_err("Internal error: map__kmap with a non-kernel map\n");
0564 return kmap;
0565 }
0566
0567 struct maps *map__kmaps(struct map *map)
0568 {
0569 struct kmap *kmap = map__kmap(map);
0570
0571 if (!kmap || !kmap->kmaps) {
0572 pr_err("Internal error: map__kmaps with a non-kernel map\n");
0573 return NULL;
0574 }
0575 return kmap->kmaps;
0576 }
0577
0578 u64 map__map_ip(const struct map *map, u64 ip)
0579 {
0580 return ip - map->start + map->pgoff;
0581 }
0582
0583 u64 map__unmap_ip(const struct map *map, u64 ip)
0584 {
0585 return ip + map->start - map->pgoff;
0586 }
0587
0588 u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip)
0589 {
0590 return ip;
0591 }