Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
On 2015/11/30 17:43, Namhyung Kim wrote: On November 30, 2015 6:27:57 PM GMT+09:00, "Wangnan (F)" wrote: On 2015/11/30 16:51, Namhyung Kim wrote: On Mon, Nov 30, 2015 at 01:00:46PM +0800, Wangnan (F) wrote: On 2015/11/30 0:14, Namhyung Kim wrote: Hi Wang, On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: This patch collects name of maps in BPF object files and saves them into 'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is introduced to retrive fd and definitions of a map through its name. Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Alexei Starovoitov Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/lib/bpf/libbpf.c | 65 +++--- tools/lib/bpf/libbpf.h | 3 +++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index f509825..a298614 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -165,6 +165,7 @@ struct bpf_program { struct bpf_map { int fd; + char *name; struct bpf_map_def def; void *priv; bpf_map_clear_priv_t clear_priv; @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void *data, return 0; } +static void +bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) +{ + int i; + Elf_Data *symbols = obj->efile.symbols; + + if (!symbols || maps_shndx < 0) + return; + + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { + GElf_Sym sym; + size_t map_idx; + const char *map_name; + + if (!gelf_getsym(symbols, i, &sym)) + continue; + if (sym.st_shndx != maps_shndx) + continue; + + map_name = elf_strptr(obj->efile.elf, + obj->efile.ehdr.e_shstrndx, + sym.st_name); It means that each map name is saved in section header string table? According to elf format specification: For an symbol table entry, the st_name field "holds an index into the object file’s symbol string table, which holds the character representations of the symbol names. If the value is non-zero, it represents a string table index that gives the symbol name. Otherwise, the symbol table entry has no name." And so called "object file’s symbol string table" is a section in the object file which index is stored into ehdr and be loaded during gelf_getehdr(), and its index would be set to ehdr->e_shstrndx. So I think for each map its name should be saved in that string table. AFAIK there're two symbol string tables in a ELF file. One for section headers (.shstrtab) and another for normal symbols (.strtab). And ehdr->e_shstrndx is the index of section header string table so your code assumes map names are saved in the section header string table, right? Thanks, Namhyung In case of gcc: $ echo 'int func() {return 0;}' | gcc -x c -c -o ./temp.o - $ readelf -h ./temp.o ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI:UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 240 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 11 Section header string table index: 8 Let's see what is section 8: $ readelf -S ./temp.o ... [ 8] .shstrtab STRTAB 0098 0054 0 0 1 ... Yes, in this case it is .shstrtab. However, this is what I found when using llvm: $ echo 'int func() {return 0;}' | x86_64-oe-linux-clang -x c -c -o ./temp.o - ELF Header: Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI:UNIX - GNU ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry
Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
On November 30, 2015 6:27:57 PM GMT+09:00, "Wangnan (F)" wrote: > > >On 2015/11/30 16:51, Namhyung Kim wrote: >> On Mon, Nov 30, 2015 at 01:00:46PM +0800, Wangnan (F) wrote: >>> >>> On 2015/11/30 0:14, Namhyung Kim wrote: Hi Wang, On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: > This patch collects name of maps in BPF object files and saves >them into > 'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' >is > introduced to retrive fd and definitions of a map through its >name. > > Signed-off-by: Wang Nan > Signed-off-by: He Kuang > Cc: Alexei Starovoitov > Cc: Arnaldo Carvalho de Melo > Cc: Masami Hiramatsu > Cc: Namhyung Kim > Cc: Zefan Li > Cc: pi3or...@163.com > --- > tools/lib/bpf/libbpf.c | 65 >+++--- > tools/lib/bpf/libbpf.h | 3 +++ > 2 files changed, 65 insertions(+), 3 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index f509825..a298614 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -165,6 +165,7 @@ struct bpf_program { > struct bpf_map { > int fd; > + char *name; > struct bpf_map_def def; > void *priv; > bpf_map_clear_priv_t clear_priv; > @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object >*obj, void *data, > return 0; > } > +static void > +bpf_object__init_maps_name(struct bpf_object *obj, int >maps_shndx) > +{ > + int i; > + Elf_Data *symbols = obj->efile.symbols; > + > + if (!symbols || maps_shndx < 0) > + return; > + > + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { > + GElf_Sym sym; > + size_t map_idx; > + const char *map_name; > + > + if (!gelf_getsym(symbols, i, &sym)) > + continue; > + if (sym.st_shndx != maps_shndx) > + continue; > + > + map_name = elf_strptr(obj->efile.elf, > + obj->efile.ehdr.e_shstrndx, > + sym.st_name); It means that each map name is saved in section header string >table? >>> According to elf format specification: >>> >>> For an symbol table entry, the st_name field "holds an index >>> into the object file’s symbol string table, which holds the >>> character representations of the symbol names. If the value >>> is non-zero, it represents a string table index that gives >>> the symbol name. Otherwise, the symbol table entry has no >>> name." >>> >>> And so called "object file’s symbol string table" is a >>> section in the object file which index is stored into >>> ehdr and be loaded during gelf_getehdr(), and its index >>> would be set to ehdr->e_shstrndx. So I think for each map >>> its name should be saved in that string table. >> AFAIK there're two symbol string tables in a ELF file. One for >> section headers (.shstrtab) and another for normal symbols (.strtab). >> And ehdr->e_shstrndx is the index of section header string table so >> your code assumes map names are saved in the section header string >> table, right? >> >> Thanks, >> Namhyung > >In case of gcc: > >$ echo 'int func() {return 0;}' | gcc -x c -c -o ./temp.o - >$ readelf -h ./temp.o >ELF Header: > Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 > Class: ELF64 > Data: 2's complement, little endian > Version: 1 (current) > OS/ABI:UNIX - System V > ABI Version: 0 > Type: REL (Relocatable file) > Machine: Advanced Micro Devices X86-64 > Version: 0x1 > Entry point address: 0x0 > Start of program headers: 0 (bytes into file) > Start of section headers: 240 (bytes into file) > Flags: 0x0 > Size of this header: 64 (bytes) > Size of program headers: 0 (bytes) > Number of program headers: 0 > Size of section headers: 64 (bytes) > Number of section headers: 11 > Section header string table index: 8 > >Let's see what is section 8: > >$ readelf -S ./temp.o > ... > [ 8] .shstrtab STRTAB 0098 >0054 0 0 1 > ... > >Yes, in this case it is .shstrtab. > >However, this is what I found when using llvm: > >$ echo 'int func() {return 0;}' | x86_64-oe-linux-clang -x c -c -o >./temp.o - >ELF Header: > Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 > Class: ELF64 > Data: 2's complement, little en
Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
On 2015/11/30 16:51, Namhyung Kim wrote: On Mon, Nov 30, 2015 at 01:00:46PM +0800, Wangnan (F) wrote: On 2015/11/30 0:14, Namhyung Kim wrote: Hi Wang, On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: This patch collects name of maps in BPF object files and saves them into 'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is introduced to retrive fd and definitions of a map through its name. Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Alexei Starovoitov Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/lib/bpf/libbpf.c | 65 +++--- tools/lib/bpf/libbpf.h | 3 +++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index f509825..a298614 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -165,6 +165,7 @@ struct bpf_program { struct bpf_map { int fd; + char *name; struct bpf_map_def def; void *priv; bpf_map_clear_priv_t clear_priv; @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void *data, return 0; } +static void +bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) +{ + int i; + Elf_Data *symbols = obj->efile.symbols; + + if (!symbols || maps_shndx < 0) + return; + + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { + GElf_Sym sym; + size_t map_idx; + const char *map_name; + + if (!gelf_getsym(symbols, i, &sym)) + continue; + if (sym.st_shndx != maps_shndx) + continue; + + map_name = elf_strptr(obj->efile.elf, + obj->efile.ehdr.e_shstrndx, + sym.st_name); It means that each map name is saved in section header string table? According to elf format specification: For an symbol table entry, the st_name field "holds an index into the object file’s symbol string table, which holds the character representations of the symbol names. If the value is non-zero, it represents a string table index that gives the symbol name. Otherwise, the symbol table entry has no name." And so called "object file’s symbol string table" is a section in the object file which index is stored into ehdr and be loaded during gelf_getehdr(), and its index would be set to ehdr->e_shstrndx. So I think for each map its name should be saved in that string table. AFAIK there're two symbol string tables in a ELF file. One for section headers (.shstrtab) and another for normal symbols (.strtab). And ehdr->e_shstrndx is the index of section header string table so your code assumes map names are saved in the section header string table, right? Thanks, Namhyung In case of gcc: $ echo 'int func() {return 0;}' | gcc -x c -c -o ./temp.o - $ readelf -h ./temp.o ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI:UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 240 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 11 Section header string table index: 8 Let's see what is section 8: $ readelf -S ./temp.o ... [ 8] .shstrtab STRTAB 0098 0054 0 0 1 ... Yes, in this case it is .shstrtab. However, this is what I found when using llvm: $ echo 'int func() {return 0;}' | x86_64-oe-linux-clang -x c -c -o ./temp.o - ELF Header: Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI:UNIX - GNU ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 648 (bytes into file) Flag
Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
On Mon, Nov 30, 2015 at 01:00:46PM +0800, Wangnan (F) wrote: > > > On 2015/11/30 0:14, Namhyung Kim wrote: > >Hi Wang, > > > >On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: > >>This patch collects name of maps in BPF object files and saves them into > >>'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is > >>introduced to retrive fd and definitions of a map through its name. > >> > >>Signed-off-by: Wang Nan > >>Signed-off-by: He Kuang > >>Cc: Alexei Starovoitov > >>Cc: Arnaldo Carvalho de Melo > >>Cc: Masami Hiramatsu > >>Cc: Namhyung Kim > >>Cc: Zefan Li > >>Cc: pi3or...@163.com > >>--- > >> tools/lib/bpf/libbpf.c | 65 > >> +++--- > >> tools/lib/bpf/libbpf.h | 3 +++ > >> 2 files changed, 65 insertions(+), 3 deletions(-) > >> > >>diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > >>index f509825..a298614 100644 > >>--- a/tools/lib/bpf/libbpf.c > >>+++ b/tools/lib/bpf/libbpf.c > >>@@ -165,6 +165,7 @@ struct bpf_program { > >> struct bpf_map { > >>int fd; > >>+ char *name; > >>struct bpf_map_def def; > >>void *priv; > >>bpf_map_clear_priv_t clear_priv; > >>@@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void > >>*data, > >>return 0; > >> } > >>+static void > >>+bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) > >>+{ > >>+ int i; > >>+ Elf_Data *symbols = obj->efile.symbols; > >>+ > >>+ if (!symbols || maps_shndx < 0) > >>+ return; > >>+ > >>+ for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { > >>+ GElf_Sym sym; > >>+ size_t map_idx; > >>+ const char *map_name; > >>+ > >>+ if (!gelf_getsym(symbols, i, &sym)) > >>+ continue; > >>+ if (sym.st_shndx != maps_shndx) > >>+ continue; > >>+ > >>+ map_name = elf_strptr(obj->efile.elf, > >>+ obj->efile.ehdr.e_shstrndx, > >>+ sym.st_name); > >It means that each map name is saved in section header string table? > > According to elf format specification: > > For an symbol table entry, the st_name field "holds an index > into the object file’s symbol string table, which holds the > character representations of the symbol names. If the value > is non-zero, it represents a string table index that gives > the symbol name. Otherwise, the symbol table entry has no > name." > > And so called "object file’s symbol string table" is a > section in the object file which index is stored into > ehdr and be loaded during gelf_getehdr(), and its index > would be set to ehdr->e_shstrndx. So I think for each map > its name should be saved in that string table. AFAIK there're two symbol string tables in a ELF file. One for section headers (.shstrtab) and another for normal symbols (.strtab). And ehdr->e_shstrndx is the index of section header string table so your code assumes map names are saved in the section header string table, right? Thanks, Namhyung > > > > >>+ map_idx = sym.st_value / sizeof(struct bpf_map_def); > >>+ if (map_idx >= obj->nr_maps) { > >>+ pr_warning("index of map \"%s\" is buggy: %zu > %zu\n", > >>+ map_name, map_idx, obj->nr_maps); > >>+ continue; > >>+ } > >>+ obj->maps[map_idx].name = strdup(map_name); > >You need to check the return value. > > Will send a patch for it. > > Thank you. > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
On 2015/11/30 0:14, Namhyung Kim wrote: Hi Wang, On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: This patch collects name of maps in BPF object files and saves them into 'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is introduced to retrive fd and definitions of a map through its name. Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Alexei Starovoitov Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/lib/bpf/libbpf.c | 65 +++--- tools/lib/bpf/libbpf.h | 3 +++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index f509825..a298614 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -165,6 +165,7 @@ struct bpf_program { struct bpf_map { int fd; + char *name; struct bpf_map_def def; void *priv; bpf_map_clear_priv_t clear_priv; @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void *data, return 0; } +static void +bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) +{ + int i; + Elf_Data *symbols = obj->efile.symbols; + + if (!symbols || maps_shndx < 0) + return; + + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { + GElf_Sym sym; + size_t map_idx; + const char *map_name; + + if (!gelf_getsym(symbols, i, &sym)) + continue; + if (sym.st_shndx != maps_shndx) + continue; + + map_name = elf_strptr(obj->efile.elf, + obj->efile.ehdr.e_shstrndx, + sym.st_name); It means that each map name is saved in section header string table? According to elf format specification: For an symbol table entry, the st_name field "holds an index into the object file’s symbol string table, which holds the character representations of the symbol names. If the value is non-zero, it represents a string table index that gives the symbol name. Otherwise, the symbol table entry has no name." And so called "object file’s symbol string table" is a section in the object file which index is stored into ehdr and be loaded during gelf_getehdr(), and its index would be set to ehdr->e_shstrndx. So I think for each map its name should be saved in that string table. + map_idx = sym.st_value / sizeof(struct bpf_map_def); + if (map_idx >= obj->nr_maps) { + pr_warning("index of map \"%s\" is buggy: %zu > %zu\n", + map_name, map_idx, obj->nr_maps); + continue; + } + obj->maps[map_idx].name = strdup(map_name); You need to check the return value. Will send a patch for it. Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 02/13] bpf tools: Extract and collect map names from BPF object file
Hi Wang, On Fri, Nov 27, 2015 at 08:47:36AM +, Wang Nan wrote: > This patch collects name of maps in BPF object files and saves them into > 'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is > introduced to retrive fd and definitions of a map through its name. > > Signed-off-by: Wang Nan > Signed-off-by: He Kuang > Cc: Alexei Starovoitov > Cc: Arnaldo Carvalho de Melo > Cc: Masami Hiramatsu > Cc: Namhyung Kim > Cc: Zefan Li > Cc: pi3or...@163.com > --- > tools/lib/bpf/libbpf.c | 65 > +++--- > tools/lib/bpf/libbpf.h | 3 +++ > 2 files changed, 65 insertions(+), 3 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index f509825..a298614 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -165,6 +165,7 @@ struct bpf_program { > > struct bpf_map { > int fd; > + char *name; > struct bpf_map_def def; > void *priv; > bpf_map_clear_priv_t clear_priv; > @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void > *data, > return 0; > } > > +static void > +bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) > +{ > + int i; > + Elf_Data *symbols = obj->efile.symbols; > + > + if (!symbols || maps_shndx < 0) > + return; > + > + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { > + GElf_Sym sym; > + size_t map_idx; > + const char *map_name; > + > + if (!gelf_getsym(symbols, i, &sym)) > + continue; > + if (sym.st_shndx != maps_shndx) > + continue; > + > + map_name = elf_strptr(obj->efile.elf, > + obj->efile.ehdr.e_shstrndx, > + sym.st_name); It means that each map name is saved in section header string table? > + map_idx = sym.st_value / sizeof(struct bpf_map_def); > + if (map_idx >= obj->nr_maps) { > + pr_warning("index of map \"%s\" is buggy: %zu > %zu\n", > +map_name, map_idx, obj->nr_maps); > + continue; > + } > + obj->maps[map_idx].name = strdup(map_name); You need to check the return value. thanks, Namhyung > + pr_debug("map %zu is \"%s\"\n", map_idx, > + obj->maps[map_idx].name); > + } > +} > + -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/