summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol-minimal.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol-minimal.c')
-rw-r--r--tools/perf/util/symbol-minimal.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index bd15f490d04f..fd8477cacf88 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -129,6 +129,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
void *tmp;
+ long offset;
if (need_swap) {
phdr->p_type = bswap_32(phdr->p_type);
@@ -140,12 +141,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
continue;
buf_size = phdr->p_filesz;
+ offset = phdr->p_offset;
tmp = realloc(buf, buf_size);
if (tmp == NULL)
goto out_free;
buf = tmp;
- fseek(fp, phdr->p_offset, SEEK_SET);
+ fseek(fp, offset, SEEK_SET);
if (fread(buf, buf_size, 1, fp) != 1)
goto out_free;
@@ -178,6 +180,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
void *tmp;
+ long offset;
if (need_swap) {
phdr->p_type = bswap_32(phdr->p_type);
@@ -189,12 +192,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
continue;
buf_size = phdr->p_filesz;
+ offset = phdr->p_offset;
tmp = realloc(buf, buf_size);
if (tmp == NULL)
goto out_free;
buf = tmp;
- fseek(fp, phdr->p_offset, SEEK_SET);
+ fseek(fp, offset, SEEK_SET);
if (fread(buf, buf_size, 1, fp) != 1)
goto out_free;
@@ -242,13 +246,12 @@ out:
return ret;
}
-int symsrc__init(struct symsrc *ss, struct dso *dso __maybe_unused,
- const char *name,
+int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
enum dso_binary_type type)
{
int fd = open(name, O_RDONLY);
if (fd < 0)
- return -1;
+ goto out_errno;
ss->name = strdup(name);
if (!ss->name)
@@ -260,6 +263,8 @@ int symsrc__init(struct symsrc *ss, struct dso *dso __maybe_unused,
return 0;
out_close:
close(fd);
+out_errno:
+ dso->load_errno = errno;
return -1;
}
@@ -288,6 +293,44 @@ int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
return 0;
}
+static int fd__is_64_bit(int fd)
+{
+ u8 e_ident[EI_NIDENT];
+
+ if (lseek(fd, 0, SEEK_SET))
+ return -1;
+
+ if (readn(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
+ return -1;
+
+ if (memcmp(e_ident, ELFMAG, SELFMAG) ||
+ e_ident[EI_VERSION] != EV_CURRENT)
+ return -1;
+
+ return e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+enum dso_type dso__type_fd(int fd)
+{
+ Elf64_Ehdr ehdr;
+ int ret;
+
+ ret = fd__is_64_bit(fd);
+ if (ret < 0)
+ return DSO__TYPE_UNKNOWN;
+
+ if (ret)
+ return DSO__TYPE_64BIT;
+
+ if (readn(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
+ return DSO__TYPE_UNKNOWN;
+
+ if (ehdr.e_machine == EM_X86_64)
+ return DSO__TYPE_X32BIT;
+
+ return DSO__TYPE_32BIT;
+}
+
int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
struct symsrc *ss,
struct symsrc *runtime_ss __maybe_unused,
@@ -295,10 +338,14 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
int kmodule __maybe_unused)
{
unsigned char *build_id[BUILD_ID_SIZE];
+ int ret;
+
+ ret = fd__is_64_bit(ss->fd);
+ if (ret >= 0)
+ dso->is_64_bit = ret;
if (filename__read_build_id(ss->name, build_id, BUILD_ID_SIZE) > 0) {
dso__set_build_id(dso, build_id);
- return 1;
}
return 0;
}
OpenPOWER on IntegriCloud