Skip to content

Commit

Permalink
perf symbols: Filename__read_build_id should look at .notes section too
Browse files Browse the repository at this point in the history
In the kernel we have more than one notes section, so the linker
script combines all and puts them into a ".notes" combined
section. So we need to look at both sections and also traverse
them looking at multiple GElf_Nhdr entries till we find the one
we want, with the build_id.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1258757489-5978-2-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Nov 21, 2009
1 parent 6671cb1 commit fd7a346
Showing 1 changed file with 38 additions and 9 deletions.
47 changes: 38 additions & 9 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,13 +899,19 @@ bool dsos__read_build_ids(void)
return have_build_id;
}

/*
* Align offset to 4 bytes as needed for note name and descriptor data.
*/
#define NOTE_ALIGN(n) (((n) + 3) & -4U)

int filename__read_build_id(const char *filename, void *bf, size_t size)
{
int fd, err = -1;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
Elf_Data *build_id_data;
Elf_Data *data;
Elf_Scn *sec;
void *ptr;
Elf *elf;

if (size < BUILD_ID_SIZE)
Expand All @@ -928,14 +934,37 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)

sec = elf_section_by_name(elf, &ehdr, &shdr,
".note.gnu.build-id", NULL);
if (sec == NULL)
goto out_elf_end;
if (sec == NULL) {
sec = elf_section_by_name(elf, &ehdr, &shdr,
".notes", NULL);
if (sec == NULL)
goto out_elf_end;
}

build_id_data = elf_getdata(sec, NULL);
if (build_id_data == NULL)
data = elf_getdata(sec, NULL);
if (data == NULL)
goto out_elf_end;
memcpy(bf, build_id_data->d_buf + 16, BUILD_ID_SIZE);
err = BUILD_ID_SIZE;

ptr = data->d_buf;
while (ptr < (data->d_buf + data->d_size)) {
GElf_Nhdr *nhdr = ptr;
int namesz = NOTE_ALIGN(nhdr->n_namesz),
descsz = NOTE_ALIGN(nhdr->n_descsz);
const char *name;

ptr += sizeof(*nhdr);
name = ptr;
ptr += namesz;
if (nhdr->n_type == NT_GNU_BUILD_ID &&
nhdr->n_namesz == sizeof("GNU")) {
if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
memcpy(bf, ptr, BUILD_ID_SIZE);
err = BUILD_ID_SIZE;
break;
}
}
ptr += descsz;
}
out_elf_end:
elf_end(elf);
out_close:
Expand Down Expand Up @@ -963,8 +992,8 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
break;

namesz = (nhdr.n_namesz + 3) & -4U;
descsz = (nhdr.n_descsz + 3) & -4U;
namesz = NOTE_ALIGN(nhdr.n_namesz);
descsz = NOTE_ALIGN(nhdr.n_descsz);
if (nhdr.n_type == NT_GNU_BUILD_ID &&
nhdr.n_namesz == sizeof("GNU")) {
if (read(fd, bf, namesz) != namesz)
Expand Down

0 comments on commit fd7a346

Please sign in to comment.