Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[muen/linux.git] / tools / perf / util / symbol-elf.c
index 6e70cc00c161871defd9fea28d1b96812c3025b4..66a84d5846c88ed912aff027943c6f8e9ff78ff2 100644 (file)
@@ -1957,6 +1957,34 @@ void kcore_extract__delete(struct kcore_extract *kce)
 }
 
 #ifdef HAVE_GELF_GETNOTE_SUPPORT
+
+static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
+{
+       if (!base_off)
+               return;
+
+       if (tmp->bit32)
+               tmp->addr.a32[SDT_NOTE_IDX_LOC] =
+                       tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
+                       tmp->addr.a32[SDT_NOTE_IDX_BASE];
+       else
+               tmp->addr.a64[SDT_NOTE_IDX_LOC] =
+                       tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
+                       tmp->addr.a64[SDT_NOTE_IDX_BASE];
+}
+
+static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
+                             GElf_Addr base_off)
+{
+       if (!base_off)
+               return;
+
+       if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
+               tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+       else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
+               tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+}
+
 /**
  * populate_sdt_note : Parse raw data and identify SDT note
  * @elf: elf of the opened file
@@ -1974,7 +2002,6 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
        const char *provider, *name, *args;
        struct sdt_note *tmp = NULL;
        GElf_Ehdr ehdr;
-       GElf_Addr base_off = 0;
        GElf_Shdr shdr;
        int ret = -EINVAL;
 
@@ -2070,17 +2097,12 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
         * base address in the description of the SDT note. If its different,
         * then accordingly, adjust the note location.
         */
-       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
-               base_off = shdr.sh_offset;
-               if (base_off) {
-                       if (tmp->bit32)
-                               tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
-                                       tmp->addr.a32[1];
-                       else
-                               tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
-                                       tmp->addr.a64[1];
-               }
-       }
+       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
+               sdt_adjust_loc(tmp, shdr.sh_offset);
+
+       /* Adjust reference counter offset */
+       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
+               sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
 
        list_add_tail(&tmp->note_list, sdt_notes);
        return 0;