This patch collects relocation sections into 'struct object'.
Such sections are used for connecting maps to bpf programs.
'reloc' field in 'struct bpf_object' is introduced for storing
such informations.

This patch simply store the data into 'reloc' field. Following
patch will parse them to know the exact instructions which are
needed to be relocated.

Note that the collected data will be invalid after ELF object file
is closed.

Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 tools/lib/bpf/libbpf.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 18b221f..8fd29a9 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -110,6 +110,11 @@ struct bpf_object {
                Elf *elf;
                GElf_Ehdr ehdr;
                Elf_Data *symbols;
+               struct {
+                       GElf_Shdr shdr;
+                       Elf_Data *data;
+               } *reloc;
+               int nr_reloc;
        } elf;
 };
 #define obj_elf_valid(o)       ((o)->elf.fd >= 0)
@@ -233,6 +238,12 @@ static void bpf_obj_clear_elf(struct bpf_object *obj)
        }
        obj->elf.symbols = NULL;
 
+       if (obj->elf.reloc) {
+               free(obj->elf.reloc);
+               obj->elf.reloc = NULL;
+               obj->elf.nr_reloc = 0;
+       }
+
        if (obj->elf.fd >= 0) {
                close(obj->elf.fd);
                obj->elf.fd = -1;
@@ -484,6 +495,24 @@ static int bpf_obj_elf_collect(struct bpf_object *obj)
                        } else
                                pr_debug("found program %s\n",
                                         prog->section_name);
+               } else if (sh.sh_type == SHT_REL) {
+                       void *reloc = obj->elf.reloc;
+                       int nr_reloc = obj->elf.nr_reloc;
+
+                       reloc = realloc(reloc,
+                                       sizeof(*obj->elf.reloc) * (++nr_reloc));
+                       if (!reloc) {
+                               pr_warning("realloc failed\n");
+                               err = -ENOMEM;
+                       } else {
+                               int n = nr_reloc - 1;
+
+                               obj->elf.reloc = reloc;
+                               obj->elf.nr_reloc = nr_reloc;
+
+                               obj->elf.reloc[n].shdr = sh;
+                               obj->elf.reloc[n].data = data;
+                       }
                }
                if (err)
                        goto out;
-- 
1.8.3.4

--
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/

Reply via email to