diff options
| -rw-r--r-- | tools/perf/util/symbol.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 3b23c18cd36b..d22030828c21 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -899,13 +899,19 @@ bool dsos__read_build_ids(void) | |||
| 899 | return have_build_id; | 899 | return have_build_id; |
| 900 | } | 900 | } |
| 901 | 901 | ||
| 902 | /* | ||
| 903 | * Align offset to 4 bytes as needed for note name and descriptor data. | ||
| 904 | */ | ||
| 905 | #define NOTE_ALIGN(n) (((n) + 3) & -4U) | ||
| 906 | |||
| 902 | int filename__read_build_id(const char *filename, void *bf, size_t size) | 907 | int filename__read_build_id(const char *filename, void *bf, size_t size) |
| 903 | { | 908 | { |
| 904 | int fd, err = -1; | 909 | int fd, err = -1; |
| 905 | GElf_Ehdr ehdr; | 910 | GElf_Ehdr ehdr; |
| 906 | GElf_Shdr shdr; | 911 | GElf_Shdr shdr; |
| 907 | Elf_Data *build_id_data; | 912 | Elf_Data *data; |
| 908 | Elf_Scn *sec; | 913 | Elf_Scn *sec; |
| 914 | void *ptr; | ||
| 909 | Elf *elf; | 915 | Elf *elf; |
| 910 | 916 | ||
| 911 | if (size < BUILD_ID_SIZE) | 917 | if (size < BUILD_ID_SIZE) |
| @@ -928,14 +934,37 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
| 928 | 934 | ||
| 929 | sec = elf_section_by_name(elf, &ehdr, &shdr, | 935 | sec = elf_section_by_name(elf, &ehdr, &shdr, |
| 930 | ".note.gnu.build-id", NULL); | 936 | ".note.gnu.build-id", NULL); |
| 931 | if (sec == NULL) | 937 | if (sec == NULL) { |
| 932 | goto out_elf_end; | 938 | sec = elf_section_by_name(elf, &ehdr, &shdr, |
| 939 | ".notes", NULL); | ||
| 940 | if (sec == NULL) | ||
| 941 | goto out_elf_end; | ||
| 942 | } | ||
| 933 | 943 | ||
| 934 | build_id_data = elf_getdata(sec, NULL); | 944 | data = elf_getdata(sec, NULL); |
| 935 | if (build_id_data == NULL) | 945 | if (data == NULL) |
| 936 | goto out_elf_end; | 946 | goto out_elf_end; |
| 937 | memcpy(bf, build_id_data->d_buf + 16, BUILD_ID_SIZE); | 947 | |
| 938 | err = BUILD_ID_SIZE; | 948 | ptr = data->d_buf; |
| 949 | while (ptr < (data->d_buf + data->d_size)) { | ||
| 950 | GElf_Nhdr *nhdr = ptr; | ||
| 951 | int namesz = NOTE_ALIGN(nhdr->n_namesz), | ||
| 952 | descsz = NOTE_ALIGN(nhdr->n_descsz); | ||
| 953 | const char *name; | ||
| 954 | |||
| 955 | ptr += sizeof(*nhdr); | ||
| 956 | name = ptr; | ||
| 957 | ptr += namesz; | ||
| 958 | if (nhdr->n_type == NT_GNU_BUILD_ID && | ||
| 959 | nhdr->n_namesz == sizeof("GNU")) { | ||
| 960 | if (memcmp(name, "GNU", sizeof("GNU")) == 0) { | ||
| 961 | memcpy(bf, ptr, BUILD_ID_SIZE); | ||
| 962 | err = BUILD_ID_SIZE; | ||
| 963 | break; | ||
| 964 | } | ||
| 965 | } | ||
| 966 | ptr += descsz; | ||
| 967 | } | ||
| 939 | out_elf_end: | 968 | out_elf_end: |
| 940 | elf_end(elf); | 969 | elf_end(elf); |
| 941 | out_close: | 970 | out_close: |
| @@ -963,8 +992,8 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size) | |||
| 963 | if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr)) | 992 | if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr)) |
| 964 | break; | 993 | break; |
| 965 | 994 | ||
| 966 | namesz = (nhdr.n_namesz + 3) & -4U; | 995 | namesz = NOTE_ALIGN(nhdr.n_namesz); |
| 967 | descsz = (nhdr.n_descsz + 3) & -4U; | 996 | descsz = NOTE_ALIGN(nhdr.n_descsz); |
| 968 | if (nhdr.n_type == NT_GNU_BUILD_ID && | 997 | if (nhdr.n_type == NT_GNU_BUILD_ID && |
| 969 | nhdr.n_namesz == sizeof("GNU")) { | 998 | nhdr.n_namesz == sizeof("GNU")) { |
| 970 | if (read(fd, bf, namesz) != namesz) | 999 | if (read(fd, bf, namesz) != namesz) |
