#define NT_GNU_BUILD_ID 3
#endif
+static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
+static int elf_read_build_id(Elf *elf, void *bf, size_t size);
static void dsos__add(struct list_head *head, struct dso *dso);
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
static int dso__load_kernel_sym(struct dso *self, struct map *map,
goto out_elf_end;
}
+ if (self->has_build_id) {
+ u8 build_id[BUILD_ID_SIZE];
+
+ if (elf_read_build_id(elf, build_id,
+ BUILD_ID_SIZE) != BUILD_ID_SIZE)
+ goto out_elf_end;
+
+ if (!dso__build_id_equal(self, build_id))
+ goto out_elf_end;
+ }
+
sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
if (sec == NULL) {
sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
*/
#define NOTE_ALIGN(n) (((n) + 3) & -4U)
-int filename__read_build_id(const char *filename, void *bf, size_t size)
+static int elf_read_build_id(Elf *elf, void *bf, size_t size)
{
- int fd, err = -1;
+ int err = -1;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
Elf_Data *data;
Elf_Scn *sec;
Elf_Kind ek;
void *ptr;
- Elf *elf;
if (size < BUILD_ID_SIZE)
goto out;
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto out;
-
- elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
- if (elf == NULL) {
- pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
- goto out_close;
- }
-
ek = elf_kind(elf);
if (ek != ELF_K_ELF)
- goto out_elf_end;
+ goto out;
if (gelf_getehdr(elf, &ehdr) == NULL) {
pr_err("%s: cannot get elf header.\n", __func__);
- goto out_elf_end;
+ goto out;
}
sec = elf_section_by_name(elf, &ehdr, &shdr,
sec = elf_section_by_name(elf, &ehdr, &shdr,
".notes", NULL);
if (sec == NULL)
- goto out_elf_end;
+ goto out;
}
data = elf_getdata(sec, NULL);
if (data == NULL)
- goto out_elf_end;
+ goto out;
ptr = data->d_buf;
while (ptr < (data->d_buf + data->d_size)) {
}
ptr += descsz;
}
-out_elf_end:
+
+out:
+ return err;
+}
+
+int filename__read_build_id(const char *filename, void *bf, size_t size)
+{
+ int fd, err = -1;
+ Elf *elf;
+
+ if (size < BUILD_ID_SIZE)
+ goto out;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ goto out;
+
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+ if (elf == NULL) {
+ pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
+ goto out_close;
+ }
+
+ err = elf_read_build_id(elf, bf, size);
+
elf_end(elf);
out_close:
close(fd);
{
int size = PATH_MAX;
char *name;
- u8 build_id[BUILD_ID_SIZE];
int ret = -1;
int fd;
struct machine *machine;
self->long_name);
break;
case DSO__ORIG_BUILDID:
- if (filename__read_build_id(self->long_name, build_id,
- sizeof(build_id))) {
+ if (self->has_build_id) {
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- build_id__sprintf(build_id, sizeof(build_id),
+ build_id__sprintf(self->build_id,
+ sizeof(self->build_id),
build_id_hex);
snprintf(name, size,
"/usr/lib/debug/.build-id/%.2s/%s.debug",
build_id_hex, build_id_hex + 2);
- if (self->has_build_id)
- goto compare_build_id;
break;
}
self->origin++;
default:
goto out;
}
-
- if (self->has_build_id) {
- if (filename__read_build_id(name, build_id,
- sizeof(build_id)) < 0)
- goto more;
-compare_build_id:
- if (!dso__build_id_equal(self, build_id))
- goto more;
- }
open_file:
fd = open(name, O_RDONLY);
} while (fd < 0);