All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org, Wang Nan <wangnan0@huawei.com>,
	Zefan Li <lizefan@huawei.com>,
	pi3orama@163.com, Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 6/9] tools lib bpf: Fetch map names from correct strtab
Date: Fri, 11 Dec 2015 11:22:29 -0300	[thread overview]
Message-ID: <1449843752-28395-7-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1449843752-28395-1-git-send-email-acme@kernel.org>

From: Wang Nan <wangnan0@huawei.com>

Namhyung Kim pointed out a potential problem in original code that it
fetches names of maps from section header string table, which is used
to store section names.

Original code doesn't cause error because of a LLVM behavior that, it
combines shstrtab into strtab. For example:

 $ echo 'int func() {return 0;}' | x86_64-oe-linux-clang -x c -o temp.o -c -
 $ readelf -h ./temp.o
 ELF Header:
   Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
   ...
   Section header string table index: 1
 $ readelf -S ./temp.o
 There are 10 section headers, starting at offset 0x288:

 Section Headers:
   [Nr] Name              Type             Address           Offset
        Size              EntSize          Flags  Link  Info  Align
   [ 0]                   NULL             0000000000000000  00000000
        0000000000000000  0000000000000000           0     0     0
   [ 1] .strtab           STRTAB           0000000000000000  00000230
        0000000000000051  0000000000000000           0     0     1
        ...
 $ readelf -p .strtab ./temp.o

 String dump of section '.strtab':
   [     1]  .text
   [     7]  .comment
   [    10]  .bss
   [    15]  .note.GNU-stack
   [    25]  .rela.eh_frame
   [    34]  func
   [    39]  .strtab
   [    41]  .symtab
   [    49]  .data
   [    4f]  -

 $ readelf -p .shstrtab ./temp.o
 readelf: Warning: Section '.shstrtab' was not dumped because it does not exist!

Where, 'section header string table index' points to '.strtab', and
symbol names are also stored there.

However, in case of gcc:

 $ echo 'int func() {return 0;}' | gcc -x c -o temp.o -c -
 $ readelf -p .shstrtab ./temp.o

 String dump of section '.shstrtab':
   [     1]  .symtab
   [     9]  .strtab
   [    11]  .shstrtab
   [    1b]  .text
   [    21]  .data
   [    27]  .bss
   [    2c]  .comment
   [    35]  .note.GNU-stack
   [    45]  .rela.eh_frame
 $ readelf -p .strtab ./temp.o

 String dump of section '.strtab':
   [     1]  func

They are separated sections.

Although original code doesn't cause error, we'd better use canonical
method for fetching symbol names to avoid potential behavior changing.
This patch learns from readelf's code, fetches string from sh_link
of .symbol section.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Reported-and-Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1449541544-67621-3-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 16485ab05fc1..8334a5a9d5d7 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -195,6 +195,7 @@ struct bpf_object {
 		Elf *elf;
 		GElf_Ehdr ehdr;
 		Elf_Data *symbols;
+		size_t strtabidx;
 		struct {
 			GElf_Shdr shdr;
 			Elf_Data *data;
@@ -547,7 +548,7 @@ bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
 			continue;
 
 		map_name = elf_strptr(obj->efile.elf,
-				      obj->efile.ehdr.e_shstrndx,
+				      obj->efile.strtabidx,
 				      sym.st_name);
 		map_idx = sym.st_value / sizeof(struct bpf_map_def);
 		if (map_idx >= obj->nr_maps) {
@@ -630,8 +631,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
 				pr_warning("bpf: multiple SYMTAB in %s\n",
 					   obj->path);
 				err = -LIBBPF_ERRNO__FORMAT;
-			} else
+			} else {
 				obj->efile.symbols = data;
+				obj->efile.strtabidx = sh.sh_link;
+			}
 		} else if ((sh.sh_type == SHT_PROGBITS) &&
 			   (sh.sh_flags & SHF_EXECINSTR) &&
 			   (data->d_size > 0)) {
@@ -667,6 +670,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
 			goto out;
 	}
 
+	if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
+		pr_warning("Corrupted ELF file: index of strtab invalid\n");
+		return LIBBPF_ERRNO__FORMAT;
+	}
 	if (maps_shndx >= 0)
 		err = bpf_object__init_maps_name(obj, maps_shndx);
 out:
-- 
2.1.0


  parent reply	other threads:[~2015-12-11 14:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-11 14:22 [GIT PULL 0/9] perf/core improvements and fixes Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 1/9] perf top: Do not convert address for perf_top__record_precise_ip() Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 2/9] perf top: Access hists->lock only if needed Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 3/9] perf top: Fix annotation on --stdio Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 4/9] perf top: Cleanup condition in perf_top__record_precise_ip() Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 5/9] tools lib bpf: Check return value of strdup when reading map names Arnaldo Carvalho de Melo
2015-12-11 14:22 ` Arnaldo Carvalho de Melo [this message]
2015-12-11 14:22 ` [PATCH 7/9] perf data: Add u32_hex data type Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 8/9] perf script: Add support for PERF_TYPE_BREAKPOINT Arnaldo Carvalho de Melo
2015-12-11 14:22 ` [PATCH 9/9] perf tools: Clear struct machine during machine__init() Arnaldo Carvalho de Melo
2015-12-14  8:32 ` [GIT PULL 0/9] perf/core improvements and fixes Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1449843752-28395-7-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=mingo@kernel.org \
    --cc=pi3orama@163.com \
    --cc=wangnan0@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.