hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/tools/perf/util/symbol-elf.c
....@@ -2,25 +2,58 @@
22 #include <fcntl.h>
33 #include <stdio.h>
44 #include <errno.h>
5
+#include <stdlib.h>
56 #include <string.h>
67 #include <unistd.h>
78 #include <inttypes.h>
89
10
+#include "dso.h"
11
+#include "map.h"
12
+#include "maps.h"
913 #include "symbol.h"
14
+#include "symsrc.h"
1015 #include "demangle-java.h"
1116 #include "demangle-rust.h"
1217 #include "machine.h"
1318 #include "vdso.h"
1419 #include "debug.h"
15
-#include "sane_ctype.h"
20
+#include "util/copyfile.h"
21
+#include <linux/ctype.h>
22
+#include <linux/kernel.h>
23
+#include <linux/zalloc.h>
1624 #include <symbol/kallsyms.h>
25
+#include <internal/lib.h>
1726
1827 #ifndef EM_AARCH64
1928 #define EM_AARCH64 183 /* ARM 64 bit */
2029 #endif
2130
31
+#ifndef ELF32_ST_VISIBILITY
32
+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
33
+#endif
34
+
35
+/* For ELF64 the definitions are the same. */
36
+#ifndef ELF64_ST_VISIBILITY
37
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
38
+#endif
39
+
40
+/* How to extract information held in the st_other field. */
41
+#ifndef GELF_ST_VISIBILITY
42
+#define GELF_ST_VISIBILITY(val) ELF64_ST_VISIBILITY (val)
43
+#endif
44
+
2245 typedef Elf64_Nhdr GElf_Nhdr;
2346
47
+#ifndef DMGL_PARAMS
48
+#define DMGL_NO_OPTS 0 /* For readability... */
49
+#define DMGL_PARAMS (1 << 0) /* Include function args */
50
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
51
+#endif
52
+
53
+#ifdef HAVE_LIBBFD_SUPPORT
54
+#define PACKAGE 'perf'
55
+#include <bfd.h>
56
+#else
2457 #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
2558 extern char *cplus_demangle(const char *, int);
2659
....@@ -36,9 +69,7 @@
3669 {
3770 return NULL;
3871 }
39
-#else
40
-#define PACKAGE 'perf'
41
-#include <bfd.h>
72
+#endif
4273 #endif
4374 #endif
4475
....@@ -199,6 +230,33 @@
199230 }
200231
201232 return NULL;
233
+}
234
+
235
+static int elf_read_program_header(Elf *elf, u64 vaddr, GElf_Phdr *phdr)
236
+{
237
+ size_t i, phdrnum;
238
+ u64 sz;
239
+
240
+ if (elf_getphdrnum(elf, &phdrnum))
241
+ return -1;
242
+
243
+ for (i = 0; i < phdrnum; i++) {
244
+ if (gelf_getphdr(elf, i, phdr) == NULL)
245
+ return -1;
246
+
247
+ if (phdr->p_type != PT_LOAD)
248
+ continue;
249
+
250
+ sz = max(phdr->p_memsz, phdr->p_filesz);
251
+ if (!sz)
252
+ continue;
253
+
254
+ if (vaddr >= phdr->p_vaddr && (vaddr < phdr->p_vaddr + sz))
255
+ return 0;
256
+ }
257
+
258
+ /* Not found any valid program header */
259
+ return -1;
202260 }
203261
204262 static bool want_demangle(bool is_kernel_sym)
....@@ -490,7 +548,7 @@
490548 size_t sz = min(size, descsz);
491549 memcpy(bf, ptr, sz);
492550 memset(bf + sz, 0, size - sz);
493
- err = descsz;
551
+ err = sz;
494552 break;
495553 }
496554 }
....@@ -501,8 +559,40 @@
501559 return err;
502560 }
503561
504
-int filename__read_build_id(const char *filename, void *bf, size_t size)
562
+#ifdef HAVE_LIBBFD_BUILDID_SUPPORT
563
+
564
+int filename__read_build_id(const char *filename, struct build_id *bid)
505565 {
566
+ size_t size = sizeof(bid->data);
567
+ int err = -1;
568
+ bfd *abfd;
569
+
570
+ abfd = bfd_openr(filename, NULL);
571
+ if (!abfd)
572
+ return -1;
573
+
574
+ if (!bfd_check_format(abfd, bfd_object)) {
575
+ pr_debug2("%s: cannot read %s bfd file.\n", __func__, filename);
576
+ goto out_close;
577
+ }
578
+
579
+ if (!abfd->build_id || abfd->build_id->size > size)
580
+ goto out_close;
581
+
582
+ memcpy(bid->data, abfd->build_id->data, abfd->build_id->size);
583
+ memset(bid->data + abfd->build_id->size, 0, size - abfd->build_id->size);
584
+ err = bid->size = abfd->build_id->size;
585
+
586
+out_close:
587
+ bfd_close(abfd);
588
+ return err;
589
+}
590
+
591
+#else // HAVE_LIBBFD_BUILDID_SUPPORT
592
+
593
+int filename__read_build_id(const char *filename, struct build_id *bid)
594
+{
595
+ size_t size = sizeof(bid->data);
506596 int fd, err = -1;
507597 Elf *elf;
508598
....@@ -519,7 +609,9 @@
519609 goto out_close;
520610 }
521611
522
- err = elf_read_build_id(elf, bf, size);
612
+ err = elf_read_build_id(elf, bid->data, size);
613
+ if (err > 0)
614
+ bid->size = err;
523615
524616 elf_end(elf);
525617 out_close:
....@@ -528,12 +620,12 @@
528620 return err;
529621 }
530622
531
-int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
532
-{
533
- int fd, err = -1;
623
+#endif // HAVE_LIBBFD_BUILDID_SUPPORT
534624
535
- if (size < BUILD_ID_SIZE)
536
- goto out;
625
+int sysfs__read_build_id(const char *filename, struct build_id *bid)
626
+{
627
+ size_t size = sizeof(bid->data);
628
+ int fd, err = -1;
537629
538630 fd = open(filename, O_RDONLY);
539631 if (fd < 0)
....@@ -555,8 +647,9 @@
555647 break;
556648 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
557649 size_t sz = min(descsz, size);
558
- if (read(fd, build_id, sz) == (ssize_t)sz) {
559
- memset(build_id + sz, 0, size - sz);
650
+ if (read(fd, bid->data, sz) == (ssize_t)sz) {
651
+ memset(bid->data + sz, 0, size - sz);
652
+ bid->size = sz;
560653 err = 0;
561654 break;
562655 }
....@@ -578,6 +671,44 @@
578671 out:
579672 return err;
580673 }
674
+
675
+#ifdef HAVE_LIBBFD_SUPPORT
676
+
677
+int filename__read_debuglink(const char *filename, char *debuglink,
678
+ size_t size)
679
+{
680
+ int err = -1;
681
+ asection *section;
682
+ bfd *abfd;
683
+
684
+ abfd = bfd_openr(filename, NULL);
685
+ if (!abfd)
686
+ return -1;
687
+
688
+ if (!bfd_check_format(abfd, bfd_object)) {
689
+ pr_debug2("%s: cannot read %s bfd file.\n", __func__, filename);
690
+ goto out_close;
691
+ }
692
+
693
+ section = bfd_get_section_by_name(abfd, ".gnu_debuglink");
694
+ if (!section)
695
+ goto out_close;
696
+
697
+ if (section->size > size)
698
+ goto out_close;
699
+
700
+ if (!bfd_get_section_contents(abfd, section, debuglink, 0,
701
+ section->size))
702
+ goto out_close;
703
+
704
+ err = 0;
705
+
706
+out_close:
707
+ bfd_close(abfd);
708
+ return err;
709
+}
710
+
711
+#else
581712
582713 int filename__read_debuglink(const char *filename, char *debuglink,
583714 size_t size)
....@@ -631,6 +762,8 @@
631762 return err;
632763 }
633764
765
+#endif
766
+
634767 static int dso__swap_init(struct dso *dso, unsigned char eidata)
635768 {
636769 static unsigned int const endian = 1;
....@@ -675,15 +808,20 @@
675808 close(ss->fd);
676809 }
677810
678
-bool __weak elf__needs_adjust_symbols(GElf_Ehdr ehdr)
811
+bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
679812 {
680
- return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL;
813
+ /*
814
+ * Usually vmlinux is an ELF file with type ET_EXEC for most
815
+ * architectures; except Arm64 kernel is linked with option
816
+ * '-share', so need to check type ET_DYN.
817
+ */
818
+ return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL ||
819
+ ehdr.e_type == ET_DYN;
681820 }
682821
683822 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
684823 enum dso_binary_type type)
685824 {
686
- int err = -1;
687825 GElf_Ehdr ehdr;
688826 Elf *elf;
689827 int fd;
....@@ -723,13 +861,17 @@
723861 /* Always reject images with a mismatched build-id: */
724862 if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) {
725863 u8 build_id[BUILD_ID_SIZE];
864
+ struct build_id bid;
865
+ int size;
726866
727
- if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0) {
867
+ size = elf_read_build_id(elf, build_id, BUILD_ID_SIZE);
868
+ if (size <= 0) {
728869 dso->load_errno = DSO_LOAD_ERRNO__CANNOT_READ_BUILDID;
729870 goto out_elf_end;
730871 }
731872
732
- if (!dso__build_id_equal(dso, build_id)) {
873
+ build_id__init(&bid, build_id, size);
874
+ if (!dso__build_id_equal(dso, &bid)) {
733875 pr_debug("%s: build id mismatch for %s.\n", __func__, name);
734876 dso->load_errno = DSO_LOAD_ERRNO__MISMATCHING_BUILDID;
735877 goto out_elf_end;
....@@ -755,7 +897,7 @@
755897 if (ss->opdshdr.sh_type != SHT_PROGBITS)
756898 ss->opdsec = NULL;
757899
758
- if (dso->kernel == DSO_TYPE_USER)
900
+ if (dso->kernel == DSO_SPACE__USER)
759901 ss->adjust_symbols = true;
760902 else
761903 ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
....@@ -777,7 +919,7 @@
777919 elf_end(elf);
778920 out_close:
779921 close(fd);
780
- return err;
922
+ return -1;
781923 }
782924
783925 /**
....@@ -816,7 +958,7 @@
816958
817959 static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
818960 GElf_Sym *sym, GElf_Shdr *shdr,
819
- struct map_groups *kmaps, struct kmap *kmap,
961
+ struct maps *kmaps, struct kmap *kmap,
820962 struct dso **curr_dsop, struct map **curr_mapp,
821963 const char *section_name,
822964 bool adjust_kernel_syms, bool kmodule, bool *remap_kernel)
....@@ -838,7 +980,7 @@
838980 * kallsyms and identity maps. Overwrite it to
839981 * map to the kernel dso.
840982 */
841
- if (*remap_kernel && dso->kernel) {
983
+ if (*remap_kernel && dso->kernel && !kmodule) {
842984 *remap_kernel = false;
843985 map->start = shdr->sh_addr + ref_reloc(kmap);
844986 map->end = map->start + shdr->sh_size;
....@@ -848,8 +990,8 @@
848990 /* Ensure maps are correctly ordered */
849991 if (kmaps) {
850992 map__get(map);
851
- map_groups__remove(kmaps, map);
852
- map_groups__insert(kmaps, map);
993
+ maps__remove(kmaps, map);
994
+ maps__insert(kmaps, map);
853995 map__put(map);
854996 }
855997 }
....@@ -874,7 +1016,7 @@
8741016
8751017 snprintf(dso_name, sizeof(dso_name), "%s%s", dso->short_name, section_name);
8761018
877
- curr_map = map_groups__find_by_name(kmaps, dso_name);
1019
+ curr_map = maps__find_by_name(kmaps, dso_name);
8781020 if (curr_map == NULL) {
8791021 u64 start = sym->st_value;
8801022
....@@ -892,6 +1034,9 @@
8921034 if (curr_map == NULL)
8931035 return -1;
8941036
1037
+ if (curr_dso->kernel)
1038
+ map__kmap(curr_map)->kmaps = kmaps;
1039
+
8951040 if (adjust_kernel_syms) {
8961041 curr_map->start = shdr->sh_addr + ref_reloc(kmap);
8971042 curr_map->end = curr_map->start + shdr->sh_size;
....@@ -900,13 +1045,13 @@
9001045 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
9011046 }
9021047 curr_dso->symtab_type = dso->symtab_type;
903
- map_groups__insert(kmaps, curr_map);
1048
+ maps__insert(kmaps, curr_map);
9041049 /*
9051050 * Add it before we drop the referece to curr_map, i.e. while
9061051 * we still are sure to have a reference to this DSO via
9071052 * *curr_map->dso.
9081053 */
909
- dsos__add(&map->groups->machine->dsos, curr_dso);
1054
+ dsos__add(&kmaps->machine->dsos, curr_dso);
9101055 /* kmaps already got it */
9111056 map__put(curr_map);
9121057 dso__set_loaded(curr_dso);
....@@ -922,7 +1067,7 @@
9221067 struct symsrc *runtime_ss, int kmodule)
9231068 {
9241069 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
925
- struct map_groups *kmaps = kmap ? map__kmaps(map) : NULL;
1070
+ struct maps *kmaps = kmap ? map__kmaps(map) : NULL;
9261071 struct map *curr_map = map;
9271072 struct dso *curr_dso = dso;
9281073 Elf_Data *symstrs, *secstrs;
....@@ -1031,7 +1176,7 @@
10311176 * Initial kernel and module mappings do not map to the dso.
10321177 * Flag the fixups.
10331178 */
1034
- if (dso->kernel || kmodule) {
1179
+ if (dso->kernel) {
10351180 remap_kernel = true;
10361181 adjust_kernel_syms = dso->adjust_symbols;
10371182 }
....@@ -1063,6 +1208,7 @@
10631208 sym.st_value);
10641209 used_opd = true;
10651210 }
1211
+
10661212 /*
10671213 * When loading symbols in a data mapping, ABS symbols (which
10681214 * has a value of SHN_ABS in its st_shndx) failed at
....@@ -1093,17 +1239,39 @@
10931239 (sym.st_value & 1))
10941240 --sym.st_value;
10951241
1096
- if (dso->kernel || kmodule) {
1242
+ if (dso->kernel) {
10971243 if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
10981244 section_name, adjust_kernel_syms, kmodule, &remap_kernel))
10991245 goto out_elf_end;
11001246 } else if ((used_opd && runtime_ss->adjust_symbols) ||
11011247 (!used_opd && syms_ss->adjust_symbols)) {
1102
- pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1103
- "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1104
- (u64)sym.st_value, (u64)shdr.sh_addr,
1105
- (u64)shdr.sh_offset);
1106
- sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1248
+ GElf_Phdr phdr;
1249
+
1250
+ if (elf_read_program_header(runtime_ss->elf,
1251
+ (u64)sym.st_value, &phdr)) {
1252
+ pr_debug4("%s: failed to find program header for "
1253
+ "symbol: %s st_value: %#" PRIx64 "\n",
1254
+ __func__, elf_name, (u64)sym.st_value);
1255
+ pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1256
+ "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n",
1257
+ __func__, (u64)sym.st_value, (u64)shdr.sh_addr,
1258
+ (u64)shdr.sh_offset);
1259
+ /*
1260
+ * Fail to find program header, let's rollback
1261
+ * to use shdr.sh_addr and shdr.sh_offset to
1262
+ * calibrate symbol's file address, though this
1263
+ * is not necessary for normal C ELF file, we
1264
+ * still need to handle java JIT symbols in this
1265
+ * case.
1266
+ */
1267
+ sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1268
+ } else {
1269
+ pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1270
+ "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
1271
+ __func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
1272
+ (u64)phdr.p_offset);
1273
+ sym.st_value -= phdr.p_vaddr - phdr.p_offset;
1274
+ }
11071275 }
11081276
11091277 demangled = demangle_sym(dso, kmodule, elf_name);
....@@ -1127,14 +1295,14 @@
11271295 * For misannotated, zeroed, ASM function sizes.
11281296 */
11291297 if (nr > 0) {
1130
- symbols__fixup_end(&dso->symbols);
1298
+ symbols__fixup_end(&dso->symbols, false);
11311299 symbols__fixup_duplicate(&dso->symbols);
11321300 if (kmap) {
11331301 /*
11341302 * We need to fixup this here too because we create new
11351303 * maps here, for things like vsyscall sections.
11361304 */
1137
- map_groups__fixup_end(kmaps);
1305
+ maps__fixup_end(kmaps);
11381306 }
11391307 }
11401308 err = nr;
....@@ -1461,7 +1629,7 @@
14611629 struct phdr_data *p, *tmp;
14621630
14631631 list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
1464
- list_del(&p->node);
1632
+ list_del_init(&p->node);
14651633 free(p);
14661634 }
14671635 }
....@@ -1484,7 +1652,7 @@
14841652 struct sym_data *s, *tmp;
14851653
14861654 list_for_each_entry_safe(s, tmp, &kci->syms, node) {
1487
- list_del(&s->node);
1655
+ list_del_init(&s->node);
14881656 free(s);
14891657 }
14901658 }
....@@ -1834,8 +2002,8 @@
18342002 * unusual. One significant peculiarity is that the mapping (start -> pgoff)
18352003 * is not the same for the kernel map and the modules map. That happens because
18362004 * the data is copied adjacently whereas the original kcore has gaps. Finally,
1837
- * kallsyms and modules files are compared with their copies to check that
1838
- * modules have not been loaded or unloaded while the copies were taking place.
2005
+ * kallsyms file is compared with its copy to check that modules have not been
2006
+ * loaded or unloaded while the copies were taking place.
18392007 *
18402008 * Return: %0 on success, %-1 on failure.
18412009 */
....@@ -1897,9 +2065,6 @@
18972065 if (copy_bytes(kcore.fd, p->offset, extract.fd, offs, p->len))
18982066 goto out_extract_close;
18992067 }
1900
-
1901
- if (kcore_copy__compare_file(from_dir, to_dir, "modules"))
1902
- goto out_extract_close;
19032068
19042069 if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
19052070 goto out_extract_close;
....@@ -1971,6 +2136,34 @@
19712136 }
19722137
19732138 #ifdef HAVE_GELF_GETNOTE_SUPPORT
2139
+
2140
+static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
2141
+{
2142
+ if (!base_off)
2143
+ return;
2144
+
2145
+ if (tmp->bit32)
2146
+ tmp->addr.a32[SDT_NOTE_IDX_LOC] =
2147
+ tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
2148
+ tmp->addr.a32[SDT_NOTE_IDX_BASE];
2149
+ else
2150
+ tmp->addr.a64[SDT_NOTE_IDX_LOC] =
2151
+ tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
2152
+ tmp->addr.a64[SDT_NOTE_IDX_BASE];
2153
+}
2154
+
2155
+static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
2156
+ GElf_Addr base_off)
2157
+{
2158
+ if (!base_off)
2159
+ return;
2160
+
2161
+ if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
2162
+ tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
2163
+ else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
2164
+ tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
2165
+}
2166
+
19742167 /**
19752168 * populate_sdt_note : Parse raw data and identify SDT note
19762169 * @elf: elf of the opened file
....@@ -1988,7 +2181,6 @@
19882181 const char *provider, *name, *args;
19892182 struct sdt_note *tmp = NULL;
19902183 GElf_Ehdr ehdr;
1991
- GElf_Addr base_off = 0;
19922184 GElf_Shdr shdr;
19932185 int ret = -EINVAL;
19942186
....@@ -2084,27 +2276,22 @@
20842276 * base address in the description of the SDT note. If its different,
20852277 * then accordingly, adjust the note location.
20862278 */
2087
- if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
2088
- base_off = shdr.sh_offset;
2089
- if (base_off) {
2090
- if (tmp->bit32)
2091
- tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
2092
- tmp->addr.a32[1];
2093
- else
2094
- tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
2095
- tmp->addr.a64[1];
2096
- }
2097
- }
2279
+ if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
2280
+ sdt_adjust_loc(tmp, shdr.sh_offset);
2281
+
2282
+ /* Adjust reference counter offset */
2283
+ if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
2284
+ sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
20982285
20992286 list_add_tail(&tmp->note_list, sdt_notes);
21002287 return 0;
21012288
21022289 out_free_args:
2103
- free(tmp->args);
2290
+ zfree(&tmp->args);
21042291 out_free_name:
2105
- free(tmp->name);
2292
+ zfree(&tmp->name);
21062293 out_free_prov:
2107
- free(tmp->provider);
2294
+ zfree(&tmp->provider);
21082295 out_free_note:
21092296 free(tmp);
21102297 out_err:
....@@ -2219,9 +2406,10 @@
22192406 int nr_free = 0;
22202407
22212408 list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
2222
- list_del(&pos->note_list);
2223
- free(pos->name);
2224
- free(pos->provider);
2409
+ list_del_init(&pos->note_list);
2410
+ zfree(&pos->args);
2411
+ zfree(&pos->name);
2412
+ zfree(&pos->provider);
22252413 free(pos);
22262414 nr_free++;
22272415 }