aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-12-07 21:25:30 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-12-11 06:53:04 -0500
commit77ba9a5b48a7c742f9a46d26596852e9cfec7900 (patch)
treeb89d783ec2076dab051c833341c546dffc113a0e /tools
parent973170e66726672518eb935eb0dc0e63876d133d (diff)
tools lib bpf: Fetch map names from correct strtab
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>
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/bpf/libbpf.c11
1 files 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 {
195 Elf *elf; 195 Elf *elf;
196 GElf_Ehdr ehdr; 196 GElf_Ehdr ehdr;
197 Elf_Data *symbols; 197 Elf_Data *symbols;
198 size_t strtabidx;
198 struct { 199 struct {
199 GElf_Shdr shdr; 200 GElf_Shdr shdr;
200 Elf_Data *data; 201 Elf_Data *data;
@@ -547,7 +548,7 @@ bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
547 continue; 548 continue;
548 549
549 map_name = elf_strptr(obj->efile.elf, 550 map_name = elf_strptr(obj->efile.elf,
550 obj->efile.ehdr.e_shstrndx, 551 obj->efile.strtabidx,
551 sym.st_name); 552 sym.st_name);
552 map_idx = sym.st_value / sizeof(struct bpf_map_def); 553 map_idx = sym.st_value / sizeof(struct bpf_map_def);
553 if (map_idx >= obj->nr_maps) { 554 if (map_idx >= obj->nr_maps) {
@@ -630,8 +631,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
630 pr_warning("bpf: multiple SYMTAB in %s\n", 631 pr_warning("bpf: multiple SYMTAB in %s\n",
631 obj->path); 632 obj->path);
632 err = -LIBBPF_ERRNO__FORMAT; 633 err = -LIBBPF_ERRNO__FORMAT;
633 } else 634 } else {
634 obj->efile.symbols = data; 635 obj->efile.symbols = data;
636 obj->efile.strtabidx = sh.sh_link;
637 }
635 } else if ((sh.sh_type == SHT_PROGBITS) && 638 } else if ((sh.sh_type == SHT_PROGBITS) &&
636 (sh.sh_flags & SHF_EXECINSTR) && 639 (sh.sh_flags & SHF_EXECINSTR) &&
637 (data->d_size > 0)) { 640 (data->d_size > 0)) {
@@ -667,6 +670,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
667 goto out; 670 goto out;
668 } 671 }
669 672
673 if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
674 pr_warning("Corrupted ELF file: index of strtab invalid\n");
675 return LIBBPF_ERRNO__FORMAT;
676 }
670 if (maps_shndx >= 0) 677 if (maps_shndx >= 0)
671 err = bpf_object__init_maps_name(obj, maps_shndx); 678 err = bpf_object__init_maps_name(obj, maps_shndx);
672out: 679out: