Messages in this thread | | | Date | Mon, 30 Nov 2015 17:27:57 +0800 | From | "Wangnan (F)" <> | Subject | 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 +0000, 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 <wangnan0@huawei.com> >>>> Signed-off-by: He Kuang <hekuang@huawei.com> >>>> Cc: Alexei Starovoitov <ast@kernel.org> >>>> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> >>>> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> >>>> Cc: Namhyung Kim <namhyung@kernel.org> >>>> Cc: Zefan Li <lizefan@huawei.com> >>>> Cc: pi3orama@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 0000000000000000 00000098 0000000000000054 0000000000000000 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) 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: 10 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
This time it is strtab.
And here is the content of strtab:
$ 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] -
Note that I don't use BPF backend. This is a normal x86 compiling.
So seems it is the default behavior of LLVM.
Thank you.
| |