The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8 is
detected. libelf 0.8 is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Signed-off-by: Marti Raudsepp <[email protected]>
---
tools/perf/Makefile | 6 +++++-
tools/perf/util/symbol.c | 12 ++++++++++++
2 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 742a32e..46e877b 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 47ea060..8d1df1e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -413,7 +413,11 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
if (fd < 0)
goto out;
+#ifdef LIBELF_NO_MMAP
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+#else
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+#endif
if (elf == NULL)
goto out_close;
@@ -533,7 +537,11 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
+#ifdef LIBELF_NO_MMAP
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+#else
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+#endif
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +683,11 @@ static char *dso__read_build_id(struct dso *self, int v)
if (fd < 0)
goto out;
+#ifdef LIBELF_NO_MMAP
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+#else
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+#endif
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
--
1.6.5.1
* Marti Raudsepp <[email protected]> wrote:
> The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8 is
> detected. libelf 0.8 is still maintained and some distributions such as
> Arch Linux use it instead of elfutils.
>
> Signed-off-by: Marti Raudsepp <[email protected]>
> ---
> tools/perf/Makefile | 6 +++++-
> tools/perf/util/symbol.c | 12 ++++++++++++
> 2 files changed, 17 insertions(+), 1 deletions(-)
Nice fix!
Mind doing a small change:
> diff --git a/tools/perf/Makefile b/tools/perf/Makefile
> index 742a32e..46e877b 100644
> --- a/tools/perf/Makefile
> +++ b/tools/perf/Makefile
> @@ -422,7 +422,11 @@ ifeq ($(uname_S),Darwin)
> PTHREAD_LIBS =
> endif
>
> -ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> +ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> + ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> + BASIC_CFLAGS += -DLIBELF_NO_MMAP
> + endif
> +else
> msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
> endif
>
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 47ea060..8d1df1e 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -413,7 +413,11 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
> if (fd < 0)
> goto out;
>
> +#ifdef LIBELF_NO_MMAP
> + elf = elf_begin(fd, ELF_C_READ, NULL);
> +#else
> elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> +#endif
> if (elf == NULL)
> goto out_close;
>
> @@ -533,7 +537,11 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
> Elf *elf;
> int nr = 0, kernel = !strcmp("[kernel]", self->name);
>
> +#ifdef LIBELF_NO_MMAP
> + elf = elf_begin(fd, ELF_C_READ, NULL);
> +#else
> elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> +#endif
> if (elf == NULL) {
> if (v)
> fprintf(stderr, "%s: cannot read %s ELF file.\n",
> @@ -675,7 +683,11 @@ static char *dso__read_build_id(struct dso *self, int v)
> if (fd < 0)
> goto out;
>
> +#ifdef LIBELF_NO_MMAP
> + elf = elf_begin(fd, ELF_C_READ, NULL);
> +#else
> elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> +#endif
> if (elf == NULL) {
> if (v)
> fprintf(stderr, "%s: cannot read %s ELF file.\n",
I think we want a small cleanup here: a perf_elf_begin() wrapper in a
header file to hide this #ifdef. (That's how Git wraps environmental
libraries as well.)
Also, this would be an urgent fix for v2.6.32 too, to make perf build on
Arch Linux, agreed?
Ingo
On Sat, Oct 24, 2009 at 12:02 AM, Ingo Molnar <[email protected]> wrote:
> Mind doing a small change:
>
> I think we want a small cleanup here: a perf_elf_begin() wrapper in a
> header file to hide this #ifdef. (That's how Git wraps environmental
> libraries as well.)
Ok, does this patch do what you had in mind? I wasn't quite sure how to
implement; changing the cmd behind someone's back might be considered
surprising.
Another take would be to #define our own ELF_C_READ_MMAP, but that would be
lying, too...
> Also, this would be an urgent fix for v2.6.32 too, to make perf build on
> Arch Linux, agreed?
Hopefully :)
Regards,
Marti
[PATCH] perf tools: add compatibility with libelf 0.8 and autodetect
The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8 is
detected. libelf 0.8 is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Signed-off-by: Marti Raudsepp <[email protected]>
---
tools/perf/Makefile | 6 +++++-
tools/perf/util/symbol.c | 9 +++++----
tools/perf/util/symbol.h | 11 +++++++++++
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 742a32e..46e877b 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 47ea060..ec69c42 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -5,7 +5,6 @@
#include "debug.h"
-#include <libelf.h>
#include <gelf.h>
#include <elf.h>
@@ -413,7 +412,8 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
+
if (elf == NULL)
goto out_close;
@@ -533,7 +533,8 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
+
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +676,7 @@ static char *dso__read_build_id(struct dso *self, int v)
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6e84907..50750e9 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -8,6 +8,8 @@
#include "module.h"
#include "event.h"
+#include <libelf.h>
+
#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);
@@ -27,6 +29,15 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
#endif
#endif
+static inline Elf *perf_elf_begin(int fd, Elf_Cmd cmd, Elf *ref)
+{
+#ifndef LIBELF_NO_MMAP
+ if (cmd == ELF_C_READ)
+ cmd = ELF_C_READ_MMAP;
+#endif
+ return elf_begin(fd, cmd, ref);
+}
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
--
1.6.5.1
* Marti Raudsepp <[email protected]> wrote:
> On Sat, Oct 24, 2009 at 12:02 AM, Ingo Molnar <[email protected]> wrote:
> > Mind doing a small change:
> >
> > I think we want a small cleanup here: a perf_elf_begin() wrapper in a
> > header file to hide this #ifdef. (That's how Git wraps environmental
> > libraries as well.)
>
> Ok, does this patch do what you had in mind? I wasn't quite sure how to
> implement; changing the cmd behind someone's back might be considered
> surprising.
>
> Another take would be to #define our own ELF_C_READ_MMAP, but that would be
> lying, too...
>
> > Also, this would be an urgent fix for v2.6.32 too, to make perf build on
> > Arch Linux, agreed?
>
> Hopefully :)
>
> Regards,
> Marti
>
>
> [PATCH] perf tools: add compatibility with libelf 0.8 and autodetect
>
> The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8 is
> detected. libelf 0.8 is still maintained and some distributions such as
> Arch Linux use it instead of elfutils.
>
> Signed-off-by: Marti Raudsepp <[email protected]>
> ---
> tools/perf/Makefile | 6 +++++-
> tools/perf/util/symbol.c | 9 +++++----
> tools/perf/util/symbol.h | 11 +++++++++++
> 3 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/tools/perf/Makefile b/tools/perf/Makefile
> index 742a32e..46e877b 100644
> --- a/tools/perf/Makefile
> +++ b/tools/perf/Makefile
> @@ -422,7 +422,11 @@ ifeq ($(uname_S),Darwin)
> PTHREAD_LIBS =
> endif
>
> -ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> +ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> + ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
> + BASIC_CFLAGS += -DLIBELF_NO_MMAP
> + endif
> +else
> msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
> endif
>
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 47ea060..ec69c42 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -5,7 +5,6 @@
>
> #include "debug.h"
>
> -#include <libelf.h>
> #include <gelf.h>
> #include <elf.h>
>
> @@ -413,7 +412,8 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
> if (fd < 0)
> goto out;
>
> - elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> + elf = perf_elf_begin(fd, ELF_C_READ, NULL);
> +
> if (elf == NULL)
> goto out_close;
>
> @@ -533,7 +533,8 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
> Elf *elf;
> int nr = 0, kernel = !strcmp("[kernel]", self->name);
>
> - elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> + elf = perf_elf_begin(fd, ELF_C_READ, NULL);
> +
> if (elf == NULL) {
> if (v)
> fprintf(stderr, "%s: cannot read %s ELF file.\n",
> @@ -675,7 +676,7 @@ static char *dso__read_build_id(struct dso *self, int v)
> if (fd < 0)
> goto out;
>
> - elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
> + elf = perf_elf_begin(fd, ELF_C_READ, NULL);
> if (elf == NULL) {
> if (v)
> fprintf(stderr, "%s: cannot read %s ELF file.\n",
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 6e84907..50750e9 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -8,6 +8,8 @@
> #include "module.h"
> #include "event.h"
>
> +#include <libelf.h>
> +
> #ifdef HAVE_CPLUS_DEMANGLE
> extern char *cplus_demangle(const char *, int);
>
> @@ -27,6 +29,15 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
> #endif
> #endif
>
> +static inline Elf *perf_elf_begin(int fd, Elf_Cmd cmd, Elf *ref)
> +{
> +#ifndef LIBELF_NO_MMAP
> + if (cmd == ELF_C_READ)
> + cmd = ELF_C_READ_MMAP;
> +#endif
> + return elf_begin(fd, cmd, ref);
> +}
> +
> #ifndef DMGL_PARAMS
> #define DMGL_PARAMS (1 << 0) /* Include function args */
> #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
Looks nice!
Mind adding a comment as well to document the version dependency?
Also, there's a few probably unintended whitespaces in the patch not
matching surrounding style (which is the kernel coding style) - please
run the patch through scripts/checkpatch.pl.
Ingo
(sorry, Ingo, forgot to reply-all)
On Fri, Oct 23, 2009 at 19:02, Ingo Molnar <[email protected]> wrote:
> Also, this would be an urgent fix for v2.6.32 too, to make perf build on
> Arch Linux, agreed?
>
If the fix is as simple as this patch, and will not cause any other
problems, may it be sent to -stable as well?
To make perf build on Arch is also possible to install elfutils from
AUR (http://aur.archlinux.org/packages.php?ID=5300) and I've made a
request some months ago to switch to this library instead of using
libelf but got no answers.
I think it's Arch's fault to continue using an unmaintained library
when there's an easy replacement, but if the "fix" is easy, why not?
Lucas De Marchi
On Sat, Oct 24, 2009 at 12:56 AM, Lucas De Marchi
<[email protected]> wrote:
> I think it's Arch's fault to continue using an unmaintained library
> when there's an easy replacement, but if the "fix" is easy, why not?
As far as I can tell, libelf is still maintained; the latest release
is from July 2009.
Regards,
Marti
On Sat, Oct 24, 2009 at 12:52 AM, Ingo Molnar <[email protected]> wrote:
> Mind adding a comment as well to document the version dependency?
Sure
> Also, there's a few probably unintended whitespaces
Fixed
--
perf tools: add compatibility with libelf 0.8 and autodetect
The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8 is
detected. libelf 0.8 is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Signed-off-by: Marti Raudsepp <[email protected]>
---
tools/perf/Makefile | 6 +++++-
tools/perf/util/symbol.c | 9 +++++----
tools/perf/util/symbol.h | 16 ++++++++++++++++
3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 742a32e..46e877b 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 47ea060..ec69c42 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -5,7 +5,6 @@
#include "debug.h"
-#include <libelf.h>
#include <gelf.h>
#include <elf.h>
@@ -413,7 +412,8 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
+
if (elf == NULL)
goto out_close;
@@ -533,7 +533,8 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
+
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +676,7 @@ static char *dso__read_build_id(struct dso *self, int v)
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = perf_elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6e84907..38bc832 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -8,6 +8,8 @@
#include "module.h"
#include "event.h"
+#include <libelf.h>
+
#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);
@@ -27,6 +29,20 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
#endif
#endif
+static inline Elf *perf_elf_begin(int fd, Elf_Cmd cmd, Elf *ref)
+{
+#ifndef LIBELF_NO_MMAP
+ /*
+ * libelf 0.8 and earlier do not support ELF_C_READ_MMAP; for newer
+ * versions we can use mmap to reduce memory usage
+ */
+
+ if (cmd == ELF_C_READ)
+ cmd = ELF_C_READ_MMAP;
+#endif
+ return elf_begin(fd, cmd, ref);
+}
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
--
1.6.5.1
On Fri, Oct 23, 2009 at 19:59, Marti Raudsepp <[email protected]> wrote:
> On Sat, Oct 24, 2009 at 12:56 AM, Lucas De Marchi
> <[email protected]> wrote:
>> I think it's Arch's fault to continue using an unmaintained library
>> when there's an easy replacement, but if the "fix" is easy, why not?
>
> As far as I can tell, libelf is still maintained; the latest release
> is from July 2009.
>
humn... I was looking at FSF site
(http://directory.fsf.org/project/libelf/) where version was not
updated anymore.
Lucas De Marchi
On Fri, Oct 23, 2009 at 19:48, Marti Raudsepp <[email protected]> wrote:
> On Sat, Oct 24, 2009 at 12:02 AM, Ingo Molnar <[email protected]> wrote:
>> Mind doing a small change:
>>
>> I think we want a small cleanup here: a perf_elf_begin() wrapper in a
>> header file to hide this #ifdef. (That's how Git wraps environmental
>> libraries as well.)
>
Why don't you do something like?:
#ifdef LIBELF_NO_MMAP
#define ELF_C_READ_MMAP ELF_C_READ
#endif
+ changes to Makefile
or:
#ifndef ELF_C_READ_MMAP
#define ELF_C_READ_MMAP ELF_C_READ
#endif
On Sat, Oct 24, 2009 at 4:07 AM, Lucas De Marchi
<[email protected]> wrote:
> Why don't you do something like?:
>
> #ifdef LIBELF_NO_MMAP
> #define ELF_C_READ_MMAP ELF_C_READ
> #endif
Seemed like bad programming practice to redefine enum constants from
third-party include files. But you are right, it would significantly
simplify the patch. Can we get a third opinion?
Marti
* Lucas De Marchi <[email protected]> wrote:
> On Fri, Oct 23, 2009 at 19:48, Marti Raudsepp <[email protected]> wrote:
> > On Sat, Oct 24, 2009 at 12:02 AM, Ingo Molnar <[email protected]> wrote:
> >> Mind doing a small change:
> >>
> >> I think we want a small cleanup here: a perf_elf_begin() wrapper in a
> >> header file to hide this #ifdef. (That's how Git wraps environmental
> >> libraries as well.)
> >
> Why don't you do something like?:
>
> #ifdef LIBELF_NO_MMAP
> #define ELF_C_READ_MMAP ELF_C_READ
> #endif
> + changes to Makefile
>
> or:
>
> #ifndef ELF_C_READ_MMAP
> #define ELF_C_READ_MMAP ELF_C_READ
> #endif
Makes sense - i'd suggest to prefix it with PERF_ in that case, to make
sure all callsites are aware of the wrapped nature of this constant.
I.e. something like this:
/*
* libelf 0.8 and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
*/
#ifndef ELF_C_READ_MMAP
# define PERF_ELF_C_READ_MMAP ELF_C_READ
#endif
Ingo
On Sat, Oct 24, 2009 at 06:30, Ingo Molnar <[email protected]> wrote:
> I.e. something like this:
>
> /*
> ?* libelf 0.8 and earlier do not support ELF_C_READ_MMAP;
> ?* for newer versions we can use mmap to reduce memory usage:
> ?*/
> #ifndef ELF_C_READ_MMAP
> # define PERF_ELF_C_READ_MMAP ELF_C_READ
> #endif
In this case you should define PERF_ELF_C_READ_MMAP as ELF_C_READ_MMAP
when using elftutils:
#ifndef ELF_C_READ_MMAP
# define PERF_ELF_C_READ_MMAP ELF_C_READ
#else
# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
#endif
and change all places to use PERF_ELF_C_READ_MMAP
I think the comment is wrong. I downloaded the latest version of
libelf, i.e. 0.8.12 at http://www.mr511.de/software/english.html, and
there's no support to ELF_C_READ_MMAP. It's a elfutils' feature only.
On Sat, 2009-10-24 at 11:26 -0200, Lucas De Marchi wrote:
> In this case you should define PERF_ELF_C_READ_MMAP as ELF_C_READ_MMAP
> when using elftutils:
> #ifndef ELF_C_READ_MMAP
> # define PERF_ELF_C_READ_MMAP ELF_C_READ
> #else
> # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
> #endif
That's what I wanted to do at first, but it doesn't work because
ELF_C_READ_MMAP is an enum constant -- not a #define
But defining our own PERF_ELF_C_READ_MMAP is a good idea and much
cleaner than the earlier mess. Thanks
> I think the comment is wrong. I downloaded the latest version of
> libelf, i.e. 0.8.12 at http://www.mr511.de/software/english.html, and
> there's no support to ELF_C_READ_MMAP. It's a elfutils' feature only.
I guess the comment was confusing. With "libelf 0.8" I meant the whole
0.8.x series.
Marti
--
perf tools: add compatibility with libelf 0.8.x and autodetect
The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8.x is
detected. libelf 0.8.x is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Can't use #ifdef ELF_C_READ_MMAP because it's an enum constant not a
define.
Signed-off-by: Marti Raudsepp <[email protected]>
---
Makefile | 6 +++++-
util/symbol.c | 6 +++---
util/symbol.h | 10 ++++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -413,7 +413,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL)
goto out_close;
@@ -533,7 +533,7 @@
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +675,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -27,6 +27,16 @@
#endif
#endif
+/*
+ * libelf 0.8.x and earlier do not support elf_c_read_mmap; for newer versions
+ * we can use mmap to reduce memory usage
+ */
+#ifdef LIBELF_NO_MMAP
+# define PERF_ELF_C_READ_MMAP ELF_C_READ
+#else
+# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
+#endif
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
Re-sending small fix; somehow I typed "elf_c_read_mmap" in lower case in
the comment.
Marti
--
perf tools: add compatibility with libelf 0.8.x and autodetect
The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8.x is
detected. libelf 0.8.x is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Can't use #ifdef ELF_C_READ_MMAP because it's an enum constant not a
define.
Signed-off-by: Marti Raudsepp <[email protected]>
---
Makefile | 6 +++++-
util/symbol.c | 6 +++---
util/symbol.h | 10 ++++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -413,7 +413,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL)
goto out_close;
@@ -533,7 +533,7 @@
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +675,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -27,6 +27,16 @@
#endif
#endif
+/*
+ * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; for newer versions
+ * we can use mmap to reduce memory usage
+ */
+#ifdef LIBELF_NO_MMAP
+# define PERF_ELF_C_READ_MMAP ELF_C_READ
+#else
+# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
+#endif
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
* Marti Raudsepp <[email protected]> wrote:
> Re-sending small fix; somehow I typed "elf_c_read_mmap" in lower case
> in the comment.
The patch got whitespace damaged (tabs are spaces, etc.) - please see
Documentation/email-clients.txt.
Ingo
On Sat, 2009-10-24 at 17:41 +0200, Ingo Molnar wrote:
> The patch got whitespace damaged (tabs are spaces, etc.) - please see
> Documentation/email-clients.txt.
Jeez, I spent most of my morning testing how to use different email
clients and I still can't get it right. :/
Marti
---
perf tools: add compatibility with libelf 0.8.x and autodetect
The Makefile now automatically defines LIBELF_NO_MMAP when libelf 0.8.x is
detected. libelf 0.8 is still maintained and some distributions such as
Arch Linux use it instead of elfutils.
Signed-off-by: Marti Raudsepp <[email protected]>
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -422,7 +422,11 @@
PTHREAD_LIBS =
endif
-ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
+ BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ endif
+else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -413,7 +413,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL)
goto out_close;
@@ -533,7 +533,7 @@
Elf *elf;
int nr = 0, kernel = !strcmp("[kernel]", self->name);
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
@@ -675,7 +675,7 @@
if (fd < 0)
goto out;
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+ elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
if (elf == NULL) {
if (v)
fprintf(stderr, "%s: cannot read %s ELF file.\n",
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -27,6 +27,16 @@
#endif
#endif
+/*
+ * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; for newer versions
+ * we can use mmap to reduce memory usage
+ */
+#ifdef LIBELF_NO_MMAP
+# define PERF_ELF_C_READ_MMAP ELF_C_READ
+#else
+# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
+#endif
+
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */