linux/tools/perf/util/symbol-elf.c
<<
>>
Prefs
   1#include <fcntl.h>
   2#include <stdio.h>
   3#include <errno.h>
   4#include <string.h>
   5#include <unistd.h>
   6#include <inttypes.h>
   7
   8#include "symbol.h"
   9#include "demangle-java.h"
  10#include "demangle-rust.h"
  11#include "machine.h"
  12#include "vdso.h"
  13#include "debug.h"
  14#include "sane_ctype.h"
  15#include <symbol/kallsyms.h>
  16
  17#ifndef EM_AARCH64
  18#define EM_AARCH64      183  /* ARM 64 bit */
  19#endif
  20
  21typedef Elf64_Nhdr GElf_Nhdr;
  22
  23#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
  24extern char *cplus_demangle(const char *, int);
  25
  26static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i)
  27{
  28        return cplus_demangle(c, i);
  29}
  30#else
  31#ifdef NO_DEMANGLE
  32static inline char *bfd_demangle(void __maybe_unused *v,
  33                                 const char __maybe_unused *c,
  34                                 int __maybe_unused i)
  35{
  36        return NULL;
  37}
  38#else
  39#define PACKAGE 'perf'
  40#include <bfd.h>
  41#endif
  42#endif
  43
  44#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
  45static int elf_getphdrnum(Elf *elf, size_t *dst)
  46{
  47        GElf_Ehdr gehdr;
  48        GElf_Ehdr *ehdr;
  49
  50        ehdr = gelf_getehdr(elf, &gehdr);
  51        if (!ehdr)
  52                return -1;
  53
  54        *dst = ehdr->e_phnum;
  55
  56        return 0;
  57}
  58#endif
  59
  60#ifndef HAVE_ELF_GETSHDRSTRNDX_SUPPORT
  61static int elf_getshdrstrndx(Elf *elf __maybe_unused, size_t *dst __maybe_unused)
  62{
  63        pr_err("%s: update your libelf to > 0.140, this one lacks elf_getshdrstrndx().\n", __func__);
  64        return -1;
  65}
  66#endif
  67
  68#ifndef NT_GNU_BUILD_ID
  69#define NT_GNU_BUILD_ID 3
  70#endif
  71
  72/**
  73 * elf_symtab__for_each_symbol - iterate thru all the symbols
  74 *
  75 * @syms: struct elf_symtab instance to iterate
  76 * @idx: uint32_t idx
  77 * @sym: GElf_Sym iterator
  78 */
  79#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
  80        for (idx = 0, gelf_getsym(syms, idx, &sym);\
  81             idx < nr_syms; \
  82             idx++, gelf_getsym(syms, idx, &sym))
  83
  84static inline uint8_t elf_sym__type(const GElf_Sym *sym)
  85{
  86        return GELF_ST_TYPE(sym->st_info);
  87}
  88
  89#ifndef STT_GNU_IFUNC
  90#define STT_GNU_IFUNC 10
  91#endif
  92
  93static inline int elf_sym__is_function(const GElf_Sym *sym)
  94{
  95        return (elf_sym__type(sym) == STT_FUNC ||
  96                elf_sym__type(sym) == STT_GNU_IFUNC) &&
  97               sym->st_name != 0 &&
  98               sym->st_shndx != SHN_UNDEF;
  99}
 100
 101static inline bool elf_sym__is_object(const GElf_Sym *sym)
 102{
 103        return elf_sym__type(sym) == STT_OBJECT &&
 104                sym->st_name != 0 &&
 105                sym->st_shndx != SHN_UNDEF;
 106}
 107
 108static inline int elf_sym__is_label(const GElf_Sym *sym)
 109{
 110        return elf_sym__type(sym) == STT_NOTYPE &&
 111                sym->st_name != 0 &&
 112                sym->st_shndx != SHN_UNDEF &&
 113                sym->st_shndx != SHN_ABS;
 114}
 115
 116static bool elf_sym__filter(GElf_Sym *sym)
 117{
 118        return elf_sym__is_function(sym) || elf_sym__is_object(sym);
 119}
 120
 121static inline const char *elf_sym__name(const GElf_Sym *sym,
 122                                        const Elf_Data *symstrs)
 123{
 124        return symstrs->d_buf + sym->st_name;
 125}
 126
 127static inline const char *elf_sec__name(const GElf_Shdr *shdr,
 128                                        const Elf_Data *secstrs)
 129{
 130        return secstrs->d_buf + shdr->sh_name;
 131}
 132
 133static inline int elf_sec__is_text(const GElf_Shdr *shdr,
 134                                        const Elf_Data *secstrs)
 135{
 136        return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
 137}
 138
 139static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
 140                                    const Elf_Data *secstrs)
 141{
 142        return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
 143}
 144
 145static bool elf_sec__filter(GElf_Shdr *shdr, Elf_Data *secstrs)
 146{
 147        return elf_sec__is_text(shdr, secstrs) || 
 148               elf_sec__is_data(shdr, secstrs);
 149}
 150
 151static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
 152{
 153        Elf_Scn *sec = NULL;
 154        GElf_Shdr shdr;
 155        size_t cnt = 1;
 156
 157        while ((sec = elf_nextscn(elf, sec)) != NULL) {
 158                gelf_getshdr(sec, &shdr);
 159
 160                if ((addr >= shdr.sh_addr) &&
 161                    (addr < (shdr.sh_addr + shdr.sh_size)))
 162                        return cnt;
 163
 164                ++cnt;
 165        }
 166
 167        return -1;
 168}
 169
 170Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
 171                             GElf_Shdr *shp, const char *name, size_t *idx)
 172{
 173        Elf_Scn *sec = NULL;
 174        size_t cnt = 1;
 175
 176        /* Elf is corrupted/truncated, avoid calling elf_strptr. */
 177        if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
 178                return NULL;
 179
 180        while ((sec = elf_nextscn(elf, sec)) != NULL) {
 181                char *str;
 182
 183                gelf_getshdr(sec, shp);
 184                str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
 185                if (str && !strcmp(name, str)) {
 186                        if (idx)
 187                                *idx = cnt;
 188                        return sec;
 189                }
 190                ++cnt;
 191        }
 192
 193        return NULL;
 194}
 195
 196static bool want_demangle(bool is_kernel_sym)
 197{
 198        return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
 199}
 200
 201static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
 202{
 203        int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS;
 204        char *demangled = NULL;
 205
 206        /*
 207         * We need to figure out if the object was created from C++ sources
 208         * DWARF DW_compile_unit has this, but we don't always have access
 209         * to it...
 210         */
 211        if (!want_demangle(dso->kernel || kmodule))
 212            return demangled;
 213
 214        demangled = bfd_demangle(NULL, elf_name, demangle_flags);
 215        if (demangled == NULL)
 216                demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
 217        else if (rust_is_mangled(demangled))
 218                /*
 219                    * Input to Rust demangling is the BFD-demangled
 220                    * name which it Rust-demangles in place.
 221                    */
 222                rust_demangle_sym(demangled);
 223
 224        return demangled;
 225}
 226
 227#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
 228        for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
 229             idx < nr_entries; \
 230             ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
 231
 232#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
 233        for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
 234             idx < nr_entries; \
 235             ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
 236
 237/*
 238 * We need to check if we have a .dynsym, so that we can handle the
 239 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
 240 * .dynsym or .symtab).
 241 * And always look at the original dso, not at debuginfo packages, that
 242 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
 243 */
 244int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
 245{
 246        uint32_t nr_rel_entries, idx;
 247        GElf_Sym sym;
 248        u64 plt_offset, plt_header_size, plt_entry_size;
 249        GElf_Shdr shdr_plt;
 250        struct symbol *f;
 251        GElf_Shdr shdr_rel_plt, shdr_dynsym;
 252        Elf_Data *reldata, *syms, *symstrs;
 253        Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
 254        size_t dynsym_idx;
 255        GElf_Ehdr ehdr;
 256        char sympltname[1024];
 257        Elf *elf;
 258        int nr = 0, symidx, err = 0;
 259
 260        if (!ss->dynsym)
 261                return 0;
 262
 263        elf = ss->elf;
 264        ehdr = ss->ehdr;
 265
 266        scn_dynsym = ss->dynsym;
 267        shdr_dynsym = ss->dynshdr;
 268        dynsym_idx = ss->dynsym_idx;
 269
 270        if (scn_dynsym == NULL)
 271                goto out_elf_end;
 272
 273        scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
 274                                          ".rela.plt", NULL);
 275        if (scn_plt_rel == NULL) {
 276                scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
 277                                                  ".rel.plt", NULL);
 278                if (scn_plt_rel == NULL)
 279                        goto out_elf_end;
 280        }
 281
 282        err = -1;
 283
 284        if (shdr_rel_plt.sh_link != dynsym_idx)
 285                goto out_elf_end;
 286
 287        if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
 288                goto out_elf_end;
 289
 290        /*
 291         * Fetch the relocation section to find the idxes to the GOT
 292         * and the symbols in the .dynsym they refer to.
 293         */
 294        reldata = elf_getdata(scn_plt_rel, NULL);
 295        if (reldata == NULL)
 296                goto out_elf_end;
 297
 298        syms = elf_getdata(scn_dynsym, NULL);
 299        if (syms == NULL)
 300                goto out_elf_end;
 301
 302        scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
 303        if (scn_symstrs == NULL)
 304                goto out_elf_end;
 305
 306        symstrs = elf_getdata(scn_symstrs, NULL);
 307        if (symstrs == NULL)
 308                goto out_elf_end;
 309
 310        if (symstrs->d_size == 0)
 311                goto out_elf_end;
 312
 313        nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
 314        plt_offset = shdr_plt.sh_offset;
 315        switch (ehdr.e_machine) {
 316                case EM_ARM:
 317                        plt_header_size = 20;
 318                        plt_entry_size = 12;
 319                        break;
 320
 321                case EM_AARCH64:
 322                        plt_header_size = 32;
 323                        plt_entry_size = 16;
 324                        break;
 325
 326                case EM_SPARC:
 327                        plt_header_size = 48;
 328                        plt_entry_size = 12;
 329                        break;
 330
 331                case EM_SPARCV9:
 332                        plt_header_size = 128;
 333                        plt_entry_size = 32;
 334                        break;
 335
 336                default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/xtensa need to be checked */
 337                        plt_header_size = shdr_plt.sh_entsize;
 338                        plt_entry_size = shdr_plt.sh_entsize;
 339                        break;
 340        }
 341        plt_offset += plt_header_size;
 342
 343        if (shdr_rel_plt.sh_type == SHT_RELA) {
 344                GElf_Rela pos_mem, *pos;
 345
 346                elf_section__for_each_rela(reldata, pos, pos_mem, idx,
 347                                           nr_rel_entries) {
 348                        const char *elf_name = NULL;
 349                        char *demangled = NULL;
 350                        symidx = GELF_R_SYM(pos->r_info);
 351                        gelf_getsym(syms, symidx, &sym);
 352
 353                        elf_name = elf_sym__name(&sym, symstrs);
 354                        demangled = demangle_sym(dso, 0, elf_name);
 355                        if (demangled != NULL)
 356                                elf_name = demangled;
 357                        snprintf(sympltname, sizeof(sympltname),
 358                                 "%s@plt", elf_name);
 359                        free(demangled);
 360
 361                        f = symbol__new(plt_offset, plt_entry_size,
 362                                        STB_GLOBAL, STT_FUNC, sympltname);
 363                        if (!f)
 364                                goto out_elf_end;
 365
 366                        plt_offset += plt_entry_size;
 367                        symbols__insert(&dso->symbols, f);
 368                        ++nr;
 369                }
 370        } else if (shdr_rel_plt.sh_type == SHT_REL) {
 371                GElf_Rel pos_mem, *pos;
 372                elf_section__for_each_rel(reldata, pos, pos_mem, idx,
 373                                          nr_rel_entries) {
 374                        const char *elf_name = NULL;
 375                        char *demangled = NULL;
 376                        symidx = GELF_R_SYM(pos->r_info);
 377                        gelf_getsym(syms, symidx, &sym);
 378
 379                        elf_name = elf_sym__name(&sym, symstrs);
 380                        demangled = demangle_sym(dso, 0, elf_name);
 381                        if (demangled != NULL)
 382                                elf_name = demangled;
 383                        snprintf(sympltname, sizeof(sympltname),
 384                                 "%s@plt", elf_name);
 385                        free(demangled);
 386
 387                        f = symbol__new(plt_offset, plt_entry_size,
 388                                        STB_GLOBAL, STT_FUNC, sympltname);
 389                        if (!f)
 390                                goto out_elf_end;
 391
 392                        plt_offset += plt_entry_size;
 393                        symbols__insert(&dso->symbols, f);
 394                        ++nr;
 395                }
 396        }
 397
 398        err = 0;
 399out_elf_end:
 400        if (err == 0)
 401                return nr;
 402        pr_debug("%s: problems reading %s PLT info.\n",
 403                 __func__, dso->long_name);
 404        return 0;
 405}
 406
 407char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
 408{
 409        return demangle_sym(dso, kmodule, elf_name);
 410}
 411
 412/*
 413 * Align offset to 4 bytes as needed for note name and descriptor data.
 414 */
 415#define NOTE_ALIGN(n) (((n) + 3) & -4U)
 416
 417static int elf_read_build_id(Elf *elf, void *bf, size_t size)
 418{
 419        int err = -1;
 420        GElf_Ehdr ehdr;
 421        GElf_Shdr shdr;
 422        Elf_Data *data;
 423        Elf_Scn *sec;
 424        Elf_Kind ek;
 425        void *ptr;
 426
 427        if (size < BUILD_ID_SIZE)
 428                goto out;
 429
 430        ek = elf_kind(elf);
 431        if (ek != ELF_K_ELF)
 432                goto out;
 433
 434        if (gelf_getehdr(elf, &ehdr) == NULL) {
 435                pr_err("%s: cannot get elf header.\n", __func__);
 436                goto out;
 437        }
 438
 439        /*
 440         * Check following sections for notes:
 441         *   '.note.gnu.build-id'
 442         *   '.notes'
 443         *   '.note' (VDSO specific)
 444         */
 445        do {
 446                sec = elf_section_by_name(elf, &ehdr, &shdr,
 447                                          ".note.gnu.build-id", NULL);
 448                if (sec)
 449                        break;
 450
 451                sec = elf_section_by_name(elf, &ehdr, &shdr,
 452                                          ".notes", NULL);
 453                if (sec)
 454                        break;
 455
 456                sec = elf_section_by_name(elf, &ehdr, &shdr,
 457                                          ".note", NULL);
 458                if (sec)
 459                        break;
 460
 461                return err;
 462
 463        } while (0);
 464
 465        data = elf_getdata(sec, NULL);
 466        if (data == NULL)
 467                goto out;
 468
 469        ptr = data->d_buf;
 470        while (ptr < (data->d_buf + data->d_size)) {
 471                GElf_Nhdr *nhdr = ptr;
 472                size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
 473                       descsz = NOTE_ALIGN(nhdr->n_descsz);
 474                const char *name;
 475
 476                ptr += sizeof(*nhdr);
 477                name = ptr;
 478                ptr += namesz;
 479                if (nhdr->n_type == NT_GNU_BUILD_ID &&
 480                    nhdr->n_namesz == sizeof("GNU")) {
 481                        if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
 482                                size_t sz = min(size, descsz);
 483                                memcpy(bf, ptr, sz);
 484                                memset(bf + sz, 0, size - sz);
 485                                err = descsz;
 486                                break;
 487                        }
 488                }
 489                ptr += descsz;
 490        }
 491
 492out:
 493        return err;
 494}
 495
 496int filename__read_build_id(const char *filename, void *bf, size_t size)
 497{
 498        int fd, err = -1;
 499        Elf *elf;
 500
 501        if (size < BUILD_ID_SIZE)
 502                goto out;
 503
 504        fd = open(filename, O_RDONLY);
 505        if (fd < 0)
 506                goto out;
 507
 508        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 509        if (elf == NULL) {
 510                pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
 511                goto out_close;
 512        }
 513
 514        err = elf_read_build_id(elf, bf, size);
 515
 516        elf_end(elf);
 517out_close:
 518        close(fd);
 519out:
 520        return err;
 521}
 522
 523int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
 524{
 525        int fd, err = -1;
 526
 527        if (size < BUILD_ID_SIZE)
 528                goto out;
 529
 530        fd = open(filename, O_RDONLY);
 531        if (fd < 0)
 532                goto out;
 533
 534        while (1) {
 535                char bf[BUFSIZ];
 536                GElf_Nhdr nhdr;
 537                size_t namesz, descsz;
 538
 539                if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
 540                        break;
 541
 542                namesz = NOTE_ALIGN(nhdr.n_namesz);
 543                descsz = NOTE_ALIGN(nhdr.n_descsz);
 544                if (nhdr.n_type == NT_GNU_BUILD_ID &&
 545                    nhdr.n_namesz == sizeof("GNU")) {
 546                        if (read(fd, bf, namesz) != (ssize_t)namesz)
 547                                break;
 548                        if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
 549                                size_t sz = min(descsz, size);
 550                                if (read(fd, build_id, sz) == (ssize_t)sz) {
 551                                        memset(build_id + sz, 0, size - sz);
 552                                        err = 0;
 553                                        break;
 554                                }
 555                        } else if (read(fd, bf, descsz) != (ssize_t)descsz)
 556                                break;
 557                } else {
 558                        int n = namesz + descsz;
 559
 560                        if (n > (int)sizeof(bf)) {
 561                                n = sizeof(bf);
 562                                pr_debug("%s: truncating reading of build id in sysfs file %s: n_namesz=%u, n_descsz=%u.\n",
 563                                         __func__, filename, nhdr.n_namesz, nhdr.n_descsz);
 564                        }
 565                        if (read(fd, bf, n) != n)
 566                                break;
 567                }
 568        }
 569        close(fd);
 570out:
 571        return err;
 572}
 573
 574int filename__read_debuglink(const char *filename, char *debuglink,
 575                             size_t size)
 576{
 577        int fd, err = -1;
 578        Elf *elf;
 579        GElf_Ehdr ehdr;
 580        GElf_Shdr shdr;
 581        Elf_Data *data;
 582        Elf_Scn *sec;
 583        Elf_Kind ek;
 584
 585        fd = open(filename, O_RDONLY);
 586        if (fd < 0)
 587                goto out;
 588
 589        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 590        if (elf == NULL) {
 591                pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
 592                goto out_close;
 593        }
 594
 595        ek = elf_kind(elf);
 596        if (ek != ELF_K_ELF)
 597                goto out_elf_end;
 598
 599        if (gelf_getehdr(elf, &ehdr) == NULL) {
 600                pr_err("%s: cannot get elf header.\n", __func__);
 601                goto out_elf_end;
 602        }
 603
 604        sec = elf_section_by_name(elf, &ehdr, &shdr,
 605                                  ".gnu_debuglink", NULL);
 606        if (sec == NULL)
 607                goto out_elf_end;
 608
 609        data = elf_getdata(sec, NULL);
 610        if (data == NULL)
 611                goto out_elf_end;
 612
 613        /* the start of this section is a zero-terminated string */
 614        strncpy(debuglink, data->d_buf, size);
 615
 616        err = 0;
 617
 618out_elf_end:
 619        elf_end(elf);
 620out_close:
 621        close(fd);
 622out:
 623        return err;
 624}
 625
 626static int dso__swap_init(struct dso *dso, unsigned char eidata)
 627{
 628        static unsigned int const endian = 1;
 629
 630        dso->needs_swap = DSO_SWAP__NO;
 631
 632        switch (eidata) {
 633        case ELFDATA2LSB:
 634                /* We are big endian, DSO is little endian. */
 635                if (*(unsigned char const *)&endian != 1)
 636                        dso->needs_swap = DSO_SWAP__YES;
 637                break;
 638
 639        case ELFDATA2MSB:
 640                /* We are little endian, DSO is big endian. */
 641                if (*(unsigned char const *)&endian != 0)
 642                        dso->needs_swap = DSO_SWAP__YES;
 643                break;
 644
 645        default:
 646                pr_err("unrecognized DSO data encoding %d\n", eidata);
 647                return -EINVAL;
 648        }
 649
 650        return 0;
 651}
 652
 653bool symsrc__possibly_runtime(struct symsrc *ss)
 654{
 655        return ss->dynsym || ss->opdsec;
 656}
 657
 658bool symsrc__has_symtab(struct symsrc *ss)
 659{
 660        return ss->symtab != NULL;
 661}
 662
 663void symsrc__destroy(struct symsrc *ss)
 664{
 665        zfree(&ss->name);
 666        elf_end(ss->elf);
 667        close(ss->fd);
 668}
 669
 670bool __weak elf__needs_adjust_symbols(GElf_Ehdr ehdr)
 671{
 672        return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL;
 673}
 674
 675int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 676                 enum dso_binary_type type)
 677{
 678        int err = -1;
 679        GElf_Ehdr ehdr;
 680        Elf *elf;
 681        int fd;
 682
 683        if (dso__needs_decompress(dso)) {
 684                fd = dso__decompress_kmodule_fd(dso, name);
 685                if (fd < 0)
 686                        return -1;
 687
 688                type = dso->symtab_type;
 689        } else {
 690                fd = open(name, O_RDONLY);
 691                if (fd < 0) {
 692                        dso->load_errno = errno;
 693                        return -1;
 694                }
 695        }
 696
 697        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
 698        if (elf == NULL) {
 699                pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
 700                dso->load_errno = DSO_LOAD_ERRNO__INVALID_ELF;
 701                goto out_close;
 702        }
 703
 704        if (gelf_getehdr(elf, &ehdr) == NULL) {
 705                dso->load_errno = DSO_LOAD_ERRNO__INVALID_ELF;
 706                pr_debug("%s: cannot get elf header.\n", __func__);
 707                goto out_elf_end;
 708        }
 709
 710        if (dso__swap_init(dso, ehdr.e_ident[EI_DATA])) {
 711                dso->load_errno = DSO_LOAD_ERRNO__INTERNAL_ERROR;
 712                goto out_elf_end;
 713        }
 714
 715        /* Always reject images with a mismatched build-id: */
 716        if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) {
 717                u8 build_id[BUILD_ID_SIZE];
 718
 719                if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0) {
 720                        dso->load_errno = DSO_LOAD_ERRNO__CANNOT_READ_BUILDID;
 721                        goto out_elf_end;
 722                }
 723
 724                if (!dso__build_id_equal(dso, build_id)) {
 725                        pr_debug("%s: build id mismatch for %s.\n", __func__, name);
 726                        dso->load_errno = DSO_LOAD_ERRNO__MISMATCHING_BUILDID;
 727                        goto out_elf_end;
 728                }
 729        }
 730
 731        ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
 732
 733        ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
 734                        NULL);
 735        if (ss->symshdr.sh_type != SHT_SYMTAB)
 736                ss->symtab = NULL;
 737
 738        ss->dynsym_idx = 0;
 739        ss->dynsym = elf_section_by_name(elf, &ehdr, &ss->dynshdr, ".dynsym",
 740                        &ss->dynsym_idx);
 741        if (ss->dynshdr.sh_type != SHT_DYNSYM)
 742                ss->dynsym = NULL;
 743
 744        ss->opdidx = 0;
 745        ss->opdsec = elf_section_by_name(elf, &ehdr, &ss->opdshdr, ".opd",
 746                        &ss->opdidx);
 747        if (ss->opdshdr.sh_type != SHT_PROGBITS)
 748                ss->opdsec = NULL;
 749
 750        if (dso->kernel == DSO_TYPE_USER)
 751                ss->adjust_symbols = true;
 752        else
 753                ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
 754
 755        ss->name   = strdup(name);
 756        if (!ss->name) {
 757                dso->load_errno = errno;
 758                goto out_elf_end;
 759        }
 760
 761        ss->elf    = elf;
 762        ss->fd     = fd;
 763        ss->ehdr   = ehdr;
 764        ss->type   = type;
 765
 766        return 0;
 767
 768out_elf_end:
 769        elf_end(elf);
 770out_close:
 771        close(fd);
 772        return err;
 773}
 774
 775/**
 776 * ref_reloc_sym_not_found - has kernel relocation symbol been found.
 777 * @kmap: kernel maps and relocation reference symbol
 778 *
 779 * This function returns %true if we are dealing with the kernel maps and the
 780 * relocation reference symbol has not yet been found.  Otherwise %false is
 781 * returned.
 782 */
 783static bool ref_reloc_sym_not_found(struct kmap *kmap)
 784{
 785        return kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
 786               !kmap->ref_reloc_sym->unrelocated_addr;
 787}
 788
 789/**
 790 * ref_reloc - kernel relocation offset.
 791 * @kmap: kernel maps and relocation reference symbol
 792 *
 793 * This function returns the offset of kernel addresses as determined by using
 794 * the relocation reference symbol i.e. if the kernel has not been relocated
 795 * then the return value is zero.
 796 */
 797static u64 ref_reloc(struct kmap *kmap)
 798{
 799        if (kmap && kmap->ref_reloc_sym &&
 800            kmap->ref_reloc_sym->unrelocated_addr)
 801                return kmap->ref_reloc_sym->addr -
 802                       kmap->ref_reloc_sym->unrelocated_addr;
 803        return 0;
 804}
 805
 806void __weak arch__sym_update(struct symbol *s __maybe_unused,
 807                GElf_Sym *sym __maybe_unused) { }
 808
 809static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
 810                                      GElf_Sym *sym, GElf_Shdr *shdr,
 811                                      struct map_groups *kmaps, struct kmap *kmap,
 812                                      struct dso **curr_dsop, struct map **curr_mapp,
 813                                      const char *section_name,
 814                                      bool adjust_kernel_syms, bool kmodule, bool *remap_kernel)
 815{
 816        struct dso *curr_dso = *curr_dsop;
 817        struct map *curr_map;
 818        char dso_name[PATH_MAX];
 819
 820        /* Adjust symbol to map to file offset */
 821        if (adjust_kernel_syms)
 822                sym->st_value -= shdr->sh_addr - shdr->sh_offset;
 823
 824        if (strcmp(section_name, (curr_dso->short_name + dso->short_name_len)) == 0)
 825                return 0;
 826
 827        if (strcmp(section_name, ".text") == 0) {
 828                /*
 829                 * The initial kernel mapping is based on
 830                 * kallsyms and identity maps.  Overwrite it to
 831                 * map to the kernel dso.
 832                 */
 833                if (*remap_kernel && dso->kernel) {
 834                        *remap_kernel = false;
 835                        map->start = shdr->sh_addr + ref_reloc(kmap);
 836                        map->end = map->start + shdr->sh_size;
 837                        map->pgoff = shdr->sh_offset;
 838                        map->map_ip = map__map_ip;
 839                        map->unmap_ip = map__unmap_ip;
 840                        /* Ensure maps are correctly ordered */
 841                        if (kmaps) {
 842                                map__get(map);
 843                                map_groups__remove(kmaps, map);
 844                                map_groups__insert(kmaps, map);
 845                                map__put(map);
 846                        }
 847                }
 848
 849                /*
 850                 * The initial module mapping is based on
 851                 * /proc/modules mapped to offset zero.
 852                 * Overwrite it to map to the module dso.
 853                 */
 854                if (*remap_kernel && kmodule) {
 855                        *remap_kernel = false;
 856                        map->pgoff = shdr->sh_offset;
 857                }
 858
 859                *curr_mapp = map;
 860                *curr_dsop = dso;
 861                return 0;
 862        }
 863
 864        if (!kmap)
 865                return 0;
 866
 867        snprintf(dso_name, sizeof(dso_name), "%s%s", dso->short_name, section_name);
 868
 869        curr_map = map_groups__find_by_name(kmaps, dso_name);
 870        if (curr_map == NULL) {
 871                u64 start = sym->st_value;
 872
 873                if (kmodule)
 874                        start += map->start + shdr->sh_offset;
 875
 876                curr_dso = dso__new(dso_name);
 877                if (curr_dso == NULL)
 878                        return -1;
 879                curr_dso->kernel = dso->kernel;
 880                curr_dso->long_name = dso->long_name;
 881                curr_dso->long_name_len = dso->long_name_len;
 882                curr_map = map__new2(start, curr_dso);
 883                dso__put(curr_dso);
 884                if (curr_map == NULL)
 885                        return -1;
 886
 887                if (adjust_kernel_syms) {
 888                        curr_map->start  = shdr->sh_addr + ref_reloc(kmap);
 889                        curr_map->end    = curr_map->start + shdr->sh_size;
 890                        curr_map->pgoff  = shdr->sh_offset;
 891                } else {
 892                        curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
 893                }
 894                curr_dso->symtab_type = dso->symtab_type;
 895                map_groups__insert(kmaps, curr_map);
 896                /*
 897                 * Add it before we drop the referece to curr_map, i.e. while
 898                 * we still are sure to have a reference to this DSO via
 899                 * *curr_map->dso.
 900                 */
 901                dsos__add(&map->groups->machine->dsos, curr_dso);
 902                /* kmaps already got it */
 903                map__put(curr_map);
 904                dso__set_loaded(curr_dso);
 905                *curr_mapp = curr_map;
 906                *curr_dsop = curr_dso;
 907        } else
 908                *curr_dsop = curr_map->dso;
 909
 910        return 0;
 911}
 912
 913int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 914                  struct symsrc *runtime_ss, int kmodule)
 915{
 916        struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
 917        struct map_groups *kmaps = kmap ? map__kmaps(map) : NULL;
 918        struct map *curr_map = map;
 919        struct dso *curr_dso = dso;
 920        Elf_Data *symstrs, *secstrs;
 921        uint32_t nr_syms;
 922        int err = -1;
 923        uint32_t idx;
 924        GElf_Ehdr ehdr;
 925        GElf_Shdr shdr;
 926        GElf_Shdr tshdr;
 927        Elf_Data *syms, *opddata = NULL;
 928        GElf_Sym sym;
 929        Elf_Scn *sec, *sec_strndx;
 930        Elf *elf;
 931        int nr = 0;
 932        bool remap_kernel = false, adjust_kernel_syms = false;
 933
 934        if (kmap && !kmaps)
 935                return -1;
 936
 937        dso->symtab_type = syms_ss->type;
 938        dso->is_64_bit = syms_ss->is_64_bit;
 939        dso->rel = syms_ss->ehdr.e_type == ET_REL;
 940
 941        /*
 942         * Modules may already have symbols from kallsyms, but those symbols
 943         * have the wrong values for the dso maps, so remove them.
 944         */
 945        if (kmodule && syms_ss->symtab)
 946                symbols__delete(&dso->symbols);
 947
 948        if (!syms_ss->symtab) {
 949                /*
 950                 * If the vmlinux is stripped, fail so we will fall back
 951                 * to using kallsyms. The vmlinux runtime symbols aren't
 952                 * of much use.
 953                 */
 954                if (dso->kernel)
 955                        goto out_elf_end;
 956
 957                syms_ss->symtab  = syms_ss->dynsym;
 958                syms_ss->symshdr = syms_ss->dynshdr;
 959        }
 960
 961        elf = syms_ss->elf;
 962        ehdr = syms_ss->ehdr;
 963        sec = syms_ss->symtab;
 964        shdr = syms_ss->symshdr;
 965
 966        if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr,
 967                                ".text", NULL))
 968                dso->text_offset = tshdr.sh_addr - tshdr.sh_offset;
 969
 970        if (runtime_ss->opdsec)
 971                opddata = elf_rawdata(runtime_ss->opdsec, NULL);
 972
 973        syms = elf_getdata(sec, NULL);
 974        if (syms == NULL)
 975                goto out_elf_end;
 976
 977        sec = elf_getscn(elf, shdr.sh_link);
 978        if (sec == NULL)
 979                goto out_elf_end;
 980
 981        symstrs = elf_getdata(sec, NULL);
 982        if (symstrs == NULL)
 983                goto out_elf_end;
 984
 985        sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
 986        if (sec_strndx == NULL)
 987                goto out_elf_end;
 988
 989        secstrs = elf_getdata(sec_strndx, NULL);
 990        if (secstrs == NULL)
 991                goto out_elf_end;
 992
 993        nr_syms = shdr.sh_size / shdr.sh_entsize;
 994
 995        memset(&sym, 0, sizeof(sym));
 996
 997        /*
 998         * The kernel relocation symbol is needed in advance in order to adjust
 999         * kernel maps correctly.
1000         */
1001        if (ref_reloc_sym_not_found(kmap)) {
1002                elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1003                        const char *elf_name = elf_sym__name(&sym, symstrs);
1004
1005                        if (strcmp(elf_name, kmap->ref_reloc_sym->name))
1006                                continue;
1007                        kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
1008                        map->reloc = kmap->ref_reloc_sym->addr -
1009                                     kmap->ref_reloc_sym->unrelocated_addr;
1010                        break;
1011                }
1012        }
1013
1014        /*
1015         * Handle any relocation of vdso necessary because older kernels
1016         * attempted to prelink vdso to its virtual address.
1017         */
1018        if (dso__is_vdso(dso))
1019                map->reloc = map->start - dso->text_offset;
1020
1021        dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
1022        /*
1023         * Initial kernel and module mappings do not map to the dso.
1024         * Flag the fixups.
1025         */
1026        if (dso->kernel || kmodule) {
1027                remap_kernel = true;
1028                adjust_kernel_syms = dso->adjust_symbols;
1029        }
1030        elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1031                struct symbol *f;
1032                const char *elf_name = elf_sym__name(&sym, symstrs);
1033                char *demangled = NULL;
1034                int is_label = elf_sym__is_label(&sym);
1035                const char *section_name;
1036                bool used_opd = false;
1037
1038                if (!is_label && !elf_sym__filter(&sym))
1039                        continue;
1040
1041                /* Reject ARM ELF "mapping symbols": these aren't unique and
1042                 * don't identify functions, so will confuse the profile
1043                 * output: */
1044                if (ehdr.e_machine == EM_ARM || ehdr.e_machine == EM_AARCH64) {
1045                        if (elf_name[0] == '$' && strchr("adtx", elf_name[1])
1046                            && (elf_name[2] == '\0' || elf_name[2] == '.'))
1047                                continue;
1048                }
1049
1050                if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) {
1051                        u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr;
1052                        u64 *opd = opddata->d_buf + offset;
1053                        sym.st_value = DSO__SWAP(dso, u64, *opd);
1054                        sym.st_shndx = elf_addr_to_index(runtime_ss->elf,
1055                                        sym.st_value);
1056                        used_opd = true;
1057                }
1058                /*
1059                 * When loading symbols in a data mapping, ABS symbols (which
1060                 * has a value of SHN_ABS in its st_shndx) failed at
1061                 * elf_getscn().  And it marks the loading as a failure so
1062                 * already loaded symbols cannot be fixed up.
1063                 *
1064                 * I'm not sure what should be done. Just ignore them for now.
1065                 * - Namhyung Kim
1066                 */
1067                if (sym.st_shndx == SHN_ABS)
1068                        continue;
1069
1070                sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
1071                if (!sec)
1072                        goto out_elf_end;
1073
1074                gelf_getshdr(sec, &shdr);
1075
1076                if (is_label && !elf_sec__filter(&shdr, secstrs))
1077                        continue;
1078
1079                section_name = elf_sec__name(&shdr, secstrs);
1080
1081                /* On ARM, symbols for thumb functions have 1 added to
1082                 * the symbol address as a flag - remove it */
1083                if ((ehdr.e_machine == EM_ARM) &&
1084                    (GELF_ST_TYPE(sym.st_info) == STT_FUNC) &&
1085                    (sym.st_value & 1))
1086                        --sym.st_value;
1087
1088                if (dso->kernel || kmodule) {
1089                        if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
1090                                                       section_name, adjust_kernel_syms, kmodule, &remap_kernel))
1091                                goto out_elf_end;
1092                } else if ((used_opd && runtime_ss->adjust_symbols) ||
1093                           (!used_opd && syms_ss->adjust_symbols)) {
1094                        pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1095                                  "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1096                                  (u64)sym.st_value, (u64)shdr.sh_addr,
1097                                  (u64)shdr.sh_offset);
1098                        sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1099                }
1100
1101                demangled = demangle_sym(dso, kmodule, elf_name);
1102                if (demangled != NULL)
1103                        elf_name = demangled;
1104
1105                f = symbol__new(sym.st_value, sym.st_size,
1106                                GELF_ST_BIND(sym.st_info),
1107                                GELF_ST_TYPE(sym.st_info), elf_name);
1108                free(demangled);
1109                if (!f)
1110                        goto out_elf_end;
1111
1112                arch__sym_update(f, &sym);
1113
1114                __symbols__insert(&curr_dso->symbols, f, dso->kernel);
1115                nr++;
1116        }
1117
1118        /*
1119         * For misannotated, zeroed, ASM function sizes.
1120         */
1121        if (nr > 0) {
1122                symbols__fixup_end(&dso->symbols);
1123                symbols__fixup_duplicate(&dso->symbols);
1124                if (kmap) {
1125                        /*
1126                         * We need to fixup this here too because we create new
1127                         * maps here, for things like vsyscall sections.
1128                         */
1129                        map_groups__fixup_end(kmaps);
1130                }
1131        }
1132        err = nr;
1133out_elf_end:
1134        return err;
1135}
1136
1137static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
1138{
1139        GElf_Phdr phdr;
1140        size_t i, phdrnum;
1141        int err;
1142        u64 sz;
1143
1144        if (elf_getphdrnum(elf, &phdrnum))
1145                return -1;
1146
1147        for (i = 0; i < phdrnum; i++) {
1148                if (gelf_getphdr(elf, i, &phdr) == NULL)
1149                        return -1;
1150                if (phdr.p_type != PT_LOAD)
1151                        continue;
1152                if (exe) {
1153                        if (!(phdr.p_flags & PF_X))
1154                                continue;
1155                } else {
1156                        if (!(phdr.p_flags & PF_R))
1157                                continue;
1158                }
1159                sz = min(phdr.p_memsz, phdr.p_filesz);
1160                if (!sz)
1161                        continue;
1162                err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data);
1163                if (err)
1164                        return err;
1165        }
1166        return 0;
1167}
1168
1169int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
1170                    bool *is_64_bit)
1171{
1172        int err;
1173        Elf *elf;
1174
1175        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1176        if (elf == NULL)
1177                return -1;
1178
1179        if (is_64_bit)
1180                *is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
1181
1182        err = elf_read_maps(elf, exe, mapfn, data);
1183
1184        elf_end(elf);
1185        return err;
1186}
1187
1188enum dso_type dso__type_fd(int fd)
1189{
1190        enum dso_type dso_type = DSO__TYPE_UNKNOWN;
1191        GElf_Ehdr ehdr;
1192        Elf_Kind ek;
1193        Elf *elf;
1194
1195        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1196        if (elf == NULL)
1197                goto out;
1198
1199        ek = elf_kind(elf);
1200        if (ek != ELF_K_ELF)
1201                goto out_end;
1202
1203        if (gelf_getclass(elf) == ELFCLASS64) {
1204                dso_type = DSO__TYPE_64BIT;
1205                goto out_end;
1206        }
1207
1208        if (gelf_getehdr(elf, &ehdr) == NULL)
1209                goto out_end;
1210
1211        if (ehdr.e_machine == EM_X86_64)
1212                dso_type = DSO__TYPE_X32BIT;
1213        else
1214                dso_type = DSO__TYPE_32BIT;
1215out_end:
1216        elf_end(elf);
1217out:
1218        return dso_type;
1219}
1220
1221static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)
1222{
1223        ssize_t r;
1224        size_t n;
1225        int err = -1;
1226        char *buf = malloc(page_size);
1227
1228        if (buf == NULL)
1229                return -1;
1230
1231        if (lseek(to, to_offs, SEEK_SET) != to_offs)
1232                goto out;
1233
1234        if (lseek(from, from_offs, SEEK_SET) != from_offs)
1235                goto out;
1236
1237        while (len) {
1238                n = page_size;
1239                if (len < n)
1240                        n = len;
1241                /* Use read because mmap won't work on proc files */
1242                r = read(from, buf, n);
1243                if (r < 0)
1244                        goto out;
1245                if (!r)
1246                        break;
1247                n = r;
1248                r = write(to, buf, n);
1249                if (r < 0)
1250                        goto out;
1251                if ((size_t)r != n)
1252                        goto out;
1253                len -= n;
1254        }
1255
1256        err = 0;
1257out:
1258        free(buf);
1259        return err;
1260}
1261
1262struct kcore {
1263        int fd;
1264        int elfclass;
1265        Elf *elf;
1266        GElf_Ehdr ehdr;
1267};
1268
1269static int kcore__open(struct kcore *kcore, const char *filename)
1270{
1271        GElf_Ehdr *ehdr;
1272
1273        kcore->fd = open(filename, O_RDONLY);
1274        if (kcore->fd == -1)
1275                return -1;
1276
1277        kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL);
1278        if (!kcore->elf)
1279                goto out_close;
1280
1281        kcore->elfclass = gelf_getclass(kcore->elf);
1282        if (kcore->elfclass == ELFCLASSNONE)
1283                goto out_end;
1284
1285        ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
1286        if (!ehdr)
1287                goto out_end;
1288
1289        return 0;
1290
1291out_end:
1292        elf_end(kcore->elf);
1293out_close:
1294        close(kcore->fd);
1295        return -1;
1296}
1297
1298static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
1299                       bool temp)
1300{
1301        kcore->elfclass = elfclass;
1302
1303        if (temp)
1304                kcore->fd = mkstemp(filename);
1305        else
1306                kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
1307        if (kcore->fd == -1)
1308                return -1;
1309
1310        kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL);
1311        if (!kcore->elf)
1312                goto out_close;
1313
1314        if (!gelf_newehdr(kcore->elf, elfclass))
1315                goto out_end;
1316
1317        memset(&kcore->ehdr, 0, sizeof(GElf_Ehdr));
1318
1319        return 0;
1320
1321out_end:
1322        elf_end(kcore->elf);
1323out_close:
1324        close(kcore->fd);
1325        unlink(filename);
1326        return -1;
1327}
1328
1329static void kcore__close(struct kcore *kcore)
1330{
1331        elf_end(kcore->elf);
1332        close(kcore->fd);
1333}
1334
1335static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
1336{
1337        GElf_Ehdr *ehdr = &to->ehdr;
1338        GElf_Ehdr *kehdr = &from->ehdr;
1339
1340        memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT);
1341        ehdr->e_type      = kehdr->e_type;
1342        ehdr->e_machine   = kehdr->e_machine;
1343        ehdr->e_version   = kehdr->e_version;
1344        ehdr->e_entry     = 0;
1345        ehdr->e_shoff     = 0;
1346        ehdr->e_flags     = kehdr->e_flags;
1347        ehdr->e_phnum     = count;
1348        ehdr->e_shentsize = 0;
1349        ehdr->e_shnum     = 0;
1350        ehdr->e_shstrndx  = 0;
1351
1352        if (from->elfclass == ELFCLASS32) {
1353                ehdr->e_phoff     = sizeof(Elf32_Ehdr);
1354                ehdr->e_ehsize    = sizeof(Elf32_Ehdr);
1355                ehdr->e_phentsize = sizeof(Elf32_Phdr);
1356        } else {
1357                ehdr->e_phoff     = sizeof(Elf64_Ehdr);
1358                ehdr->e_ehsize    = sizeof(Elf64_Ehdr);
1359                ehdr->e_phentsize = sizeof(Elf64_Phdr);
1360        }
1361
1362        if (!gelf_update_ehdr(to->elf, ehdr))
1363                return -1;
1364
1365        if (!gelf_newphdr(to->elf, count))
1366                return -1;
1367
1368        return 0;
1369}
1370
1371static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
1372                           u64 addr, u64 len)
1373{
1374        GElf_Phdr phdr = {
1375                .p_type         = PT_LOAD,
1376                .p_flags        = PF_R | PF_W | PF_X,
1377                .p_offset       = offset,
1378                .p_vaddr        = addr,
1379                .p_paddr        = 0,
1380                .p_filesz       = len,
1381                .p_memsz        = len,
1382                .p_align        = page_size,
1383        };
1384
1385        if (!gelf_update_phdr(kcore->elf, idx, &phdr))
1386                return -1;
1387
1388        return 0;
1389}
1390
1391static off_t kcore__write(struct kcore *kcore)
1392{
1393        return elf_update(kcore->elf, ELF_C_WRITE);
1394}
1395
1396struct phdr_data {
1397        off_t offset;
1398        off_t rel;
1399        u64 addr;
1400        u64 len;
1401        struct list_head node;
1402        struct phdr_data *remaps;
1403};
1404
1405struct sym_data {
1406        u64 addr;
1407        struct list_head node;
1408};
1409
1410struct kcore_copy_info {
1411        u64 stext;
1412        u64 etext;
1413        u64 first_symbol;
1414        u64 last_symbol;
1415        u64 first_module;
1416        u64 last_module_symbol;
1417        size_t phnum;
1418        struct list_head phdrs;
1419        struct list_head syms;
1420};
1421
1422#define kcore_copy__for_each_phdr(k, p) \
1423        list_for_each_entry((p), &(k)->phdrs, node)
1424
1425static struct phdr_data *phdr_data__new(u64 addr, u64 len, off_t offset)
1426{
1427        struct phdr_data *p = zalloc(sizeof(*p));
1428
1429        if (p) {
1430                p->addr   = addr;
1431                p->len    = len;
1432                p->offset = offset;
1433        }
1434
1435        return p;
1436}
1437
1438static struct phdr_data *kcore_copy_info__addnew(struct kcore_copy_info *kci,
1439                                                 u64 addr, u64 len,
1440                                                 off_t offset)
1441{
1442        struct phdr_data *p = phdr_data__new(addr, len, offset);
1443
1444        if (p)
1445                list_add_tail(&p->node, &kci->phdrs);
1446
1447        return p;
1448}
1449
1450static void kcore_copy__free_phdrs(struct kcore_copy_info *kci)
1451{
1452        struct phdr_data *p, *tmp;
1453
1454        list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
1455                list_del(&p->node);
1456                free(p);
1457        }
1458}
1459
1460static struct sym_data *kcore_copy__new_sym(struct kcore_copy_info *kci,
1461                                            u64 addr)
1462{
1463        struct sym_data *s = zalloc(sizeof(*s));
1464
1465        if (s) {
1466                s->addr = addr;
1467                list_add_tail(&s->node, &kci->syms);
1468        }
1469
1470        return s;
1471}
1472
1473static void kcore_copy__free_syms(struct kcore_copy_info *kci)
1474{
1475        struct sym_data *s, *tmp;
1476
1477        list_for_each_entry_safe(s, tmp, &kci->syms, node) {
1478                list_del(&s->node);
1479                free(s);
1480        }
1481}
1482
1483static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
1484                                        u64 start)
1485{
1486        struct kcore_copy_info *kci = arg;
1487
1488        if (!kallsyms__is_function(type))
1489                return 0;
1490
1491        if (strchr(name, '[')) {
1492                if (start > kci->last_module_symbol)
1493                        kci->last_module_symbol = start;
1494                return 0;
1495        }
1496
1497        if (!kci->first_symbol || start < kci->first_symbol)
1498                kci->first_symbol = start;
1499
1500        if (!kci->last_symbol || start > kci->last_symbol)
1501                kci->last_symbol = start;
1502
1503        if (!strcmp(name, "_stext")) {
1504                kci->stext = start;
1505                return 0;
1506        }
1507
1508        if (!strcmp(name, "_etext")) {
1509                kci->etext = start;
1510                return 0;
1511        }
1512
1513        if (is_entry_trampoline(name) && !kcore_copy__new_sym(kci, start))
1514                return -1;
1515
1516        return 0;
1517}
1518
1519static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci,
1520                                      const char *dir)
1521{
1522        char kallsyms_filename[PATH_MAX];
1523
1524        scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir);
1525
1526        if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms"))
1527                return -1;
1528
1529        if (kallsyms__parse(kallsyms_filename, kci,
1530                            kcore_copy__process_kallsyms) < 0)
1531                return -1;
1532
1533        return 0;
1534}
1535
1536static int kcore_copy__process_modules(void *arg,
1537                                       const char *name __maybe_unused,
1538                                       u64 start, u64 size __maybe_unused)
1539{
1540        struct kcore_copy_info *kci = arg;
1541
1542        if (!kci->first_module || start < kci->first_module)
1543                kci->first_module = start;
1544
1545        return 0;
1546}
1547
1548static int kcore_copy__parse_modules(struct kcore_copy_info *kci,
1549                                     const char *dir)
1550{
1551        char modules_filename[PATH_MAX];
1552
1553        scnprintf(modules_filename, PATH_MAX, "%s/modules", dir);
1554
1555        if (symbol__restricted_filename(modules_filename, "/proc/modules"))
1556                return -1;
1557
1558        if (modules__parse(modules_filename, kci,
1559                           kcore_copy__process_modules) < 0)
1560                return -1;
1561
1562        return 0;
1563}
1564
1565static int kcore_copy__map(struct kcore_copy_info *kci, u64 start, u64 end,
1566                           u64 pgoff, u64 s, u64 e)
1567{
1568        u64 len, offset;
1569
1570        if (s < start || s >= end)
1571                return 0;
1572
1573        offset = (s - start) + pgoff;
1574        len = e < end ? e - s : end - s;
1575
1576        return kcore_copy_info__addnew(kci, s, len, offset) ? 0 : -1;
1577}
1578
1579static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data)
1580{
1581        struct kcore_copy_info *kci = data;
1582        u64 end = start + len;
1583        struct sym_data *sdat;
1584
1585        if (kcore_copy__map(kci, start, end, pgoff, kci->stext, kci->etext))
1586                return -1;
1587
1588        if (kcore_copy__map(kci, start, end, pgoff, kci->first_module,
1589                            kci->last_module_symbol))
1590                return -1;
1591
1592        list_for_each_entry(sdat, &kci->syms, node) {
1593                u64 s = round_down(sdat->addr, page_size);
1594
1595                if (kcore_copy__map(kci, start, end, pgoff, s, s + len))
1596                        return -1;
1597        }
1598
1599        return 0;
1600}
1601
1602static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf)
1603{
1604        if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0)
1605                return -1;
1606
1607        return 0;
1608}
1609
1610static void kcore_copy__find_remaps(struct kcore_copy_info *kci)
1611{
1612        struct phdr_data *p, *k = NULL;
1613        u64 kend;
1614
1615        if (!kci->stext)
1616                return;
1617
1618        /* Find phdr that corresponds to the kernel map (contains stext) */
1619        kcore_copy__for_each_phdr(kci, p) {
1620                u64 pend = p->addr + p->len - 1;
1621
1622                if (p->addr <= kci->stext && pend >= kci->stext) {
1623                        k = p;
1624                        break;
1625                }
1626        }
1627
1628        if (!k)
1629                return;
1630
1631        kend = k->offset + k->len;
1632
1633        /* Find phdrs that remap the kernel */
1634        kcore_copy__for_each_phdr(kci, p) {
1635                u64 pend = p->offset + p->len;
1636
1637                if (p == k)
1638                        continue;
1639
1640                if (p->offset >= k->offset && pend <= kend)
1641                        p->remaps = k;
1642        }
1643}
1644
1645static void kcore_copy__layout(struct kcore_copy_info *kci)
1646{
1647        struct phdr_data *p;
1648        off_t rel = 0;
1649
1650        kcore_copy__find_remaps(kci);
1651
1652        kcore_copy__for_each_phdr(kci, p) {
1653                if (!p->remaps) {
1654                        p->rel = rel;
1655                        rel += p->len;
1656                }
1657                kci->phnum += 1;
1658        }
1659
1660        kcore_copy__for_each_phdr(kci, p) {
1661                struct phdr_data *k = p->remaps;
1662
1663                if (k)
1664                        p->rel = p->offset - k->offset + k->rel;
1665        }
1666}
1667
1668static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir,
1669                                 Elf *elf)
1670{
1671        if (kcore_copy__parse_kallsyms(kci, dir))
1672                return -1;
1673
1674        if (kcore_copy__parse_modules(kci, dir))
1675                return -1;
1676
1677        if (kci->stext)
1678                kci->stext = round_down(kci->stext, page_size);
1679        else
1680                kci->stext = round_down(kci->first_symbol, page_size);
1681
1682        if (kci->etext) {
1683                kci->etext = round_up(kci->etext, page_size);
1684        } else if (kci->last_symbol) {
1685                kci->etext = round_up(kci->last_symbol, page_size);
1686                kci->etext += page_size;
1687        }
1688
1689        kci->first_module = round_down(kci->first_module, page_size);
1690
1691        if (kci->last_module_symbol) {
1692                kci->last_module_symbol = round_up(kci->last_module_symbol,
1693                                                   page_size);
1694                kci->last_module_symbol += page_size;
1695        }
1696
1697        if (!kci->stext || !kci->etext)
1698                return -1;
1699
1700        if (kci->first_module && !kci->last_module_symbol)
1701                return -1;
1702
1703        if (kcore_copy__read_maps(kci, elf))
1704                return -1;
1705
1706        kcore_copy__layout(kci);
1707
1708        return 0;
1709}
1710
1711static int kcore_copy__copy_file(const char *from_dir, const char *to_dir,
1712                                 const char *name)
1713{
1714        char from_filename[PATH_MAX];
1715        char to_filename[PATH_MAX];
1716
1717        scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
1718        scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
1719
1720        return copyfile_mode(from_filename, to_filename, 0400);
1721}
1722
1723static int kcore_copy__unlink(const char *dir, const char *name)
1724{
1725        char filename[PATH_MAX];
1726
1727        scnprintf(filename, PATH_MAX, "%s/%s", dir, name);
1728
1729        return unlink(filename);
1730}
1731
1732static int kcore_copy__compare_fds(int from, int to)
1733{
1734        char *buf_from;
1735        char *buf_to;
1736        ssize_t ret;
1737        size_t len;
1738        int err = -1;
1739
1740        buf_from = malloc(page_size);
1741        buf_to = malloc(page_size);
1742        if (!buf_from || !buf_to)
1743                goto out;
1744
1745        while (1) {
1746                /* Use read because mmap won't work on proc files */
1747                ret = read(from, buf_from, page_size);
1748                if (ret < 0)
1749                        goto out;
1750
1751                if (!ret)
1752                        break;
1753
1754                len = ret;
1755
1756                if (readn(to, buf_to, len) != (int)len)
1757                        goto out;
1758
1759                if (memcmp(buf_from, buf_to, len))
1760                        goto out;
1761        }
1762
1763        err = 0;
1764out:
1765        free(buf_to);
1766        free(buf_from);
1767        return err;
1768}
1769
1770static int kcore_copy__compare_files(const char *from_filename,
1771                                     const char *to_filename)
1772{
1773        int from, to, err = -1;
1774
1775        from = open(from_filename, O_RDONLY);
1776        if (from < 0)
1777                return -1;
1778
1779        to = open(to_filename, O_RDONLY);
1780        if (to < 0)
1781                goto out_close_from;
1782
1783        err = kcore_copy__compare_fds(from, to);
1784
1785        close(to);
1786out_close_from:
1787        close(from);
1788        return err;
1789}
1790
1791static int kcore_copy__compare_file(const char *from_dir, const char *to_dir,
1792                                    const char *name)
1793{
1794        char from_filename[PATH_MAX];
1795        char to_filename[PATH_MAX];
1796
1797        scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
1798        scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
1799
1800        return kcore_copy__compare_files(from_filename, to_filename);
1801}
1802
1803/**
1804 * kcore_copy - copy kallsyms, modules and kcore from one directory to another.
1805 * @from_dir: from directory
1806 * @to_dir: to directory
1807 *
1808 * This function copies kallsyms, modules and kcore files from one directory to
1809 * another.  kallsyms and modules are copied entirely.  Only code segments are
1810 * copied from kcore.  It is assumed that two segments suffice: one for the
1811 * kernel proper and one for all the modules.  The code segments are determined
1812 * from kallsyms and modules files.  The kernel map starts at _stext or the
1813 * lowest function symbol, and ends at _etext or the highest function symbol.
1814 * The module map starts at the lowest module address and ends at the highest
1815 * module symbol.  Start addresses are rounded down to the nearest page.  End
1816 * addresses are rounded up to the nearest page.  An extra page is added to the
1817 * highest kernel symbol and highest module symbol to, hopefully, encompass that
1818 * symbol too.  Because it contains only code sections, the resulting kcore is
1819 * unusual.  One significant peculiarity is that the mapping (start -> pgoff)
1820 * is not the same for the kernel map and the modules map.  That happens because
1821 * the data is copied adjacently whereas the original kcore has gaps.  Finally,
1822 * kallsyms and modules files are compared with their copies to check that
1823 * modules have not been loaded or unloaded while the copies were taking place.
1824 *
1825 * Return: %0 on success, %-1 on failure.
1826 */
1827int kcore_copy(const char *from_dir, const char *to_dir)
1828{
1829        struct kcore kcore;
1830        struct kcore extract;
1831        int idx = 0, err = -1;
1832        off_t offset, sz;
1833        struct kcore_copy_info kci = { .stext = 0, };
1834        char kcore_filename[PATH_MAX];
1835        char extract_filename[PATH_MAX];
1836        struct phdr_data *p;
1837
1838        INIT_LIST_HEAD(&kci.phdrs);
1839        INIT_LIST_HEAD(&kci.syms);
1840
1841        if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms"))
1842                return -1;
1843
1844        if (kcore_copy__copy_file(from_dir, to_dir, "modules"))
1845                goto out_unlink_kallsyms;
1846
1847        scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir);
1848        scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir);
1849
1850        if (kcore__open(&kcore, kcore_filename))
1851                goto out_unlink_modules;
1852
1853        if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf))
1854                goto out_kcore_close;
1855
1856        if (kcore__init(&extract, extract_filename, kcore.elfclass, false))
1857                goto out_kcore_close;
1858
1859        if (kcore__copy_hdr(&kcore, &extract, kci.phnum))
1860                goto out_extract_close;
1861
1862        offset = gelf_fsize(extract.elf, ELF_T_EHDR, 1, EV_CURRENT) +
1863                 gelf_fsize(extract.elf, ELF_T_PHDR, kci.phnum, EV_CURRENT);
1864        offset = round_up(offset, page_size);
1865
1866        kcore_copy__for_each_phdr(&kci, p) {
1867                off_t offs = p->rel + offset;
1868
1869                if (kcore__add_phdr(&extract, idx++, offs, p->addr, p->len))
1870                        goto out_extract_close;
1871        }
1872
1873        sz = kcore__write(&extract);
1874        if (sz < 0 || sz > offset)
1875                goto out_extract_close;
1876
1877        kcore_copy__for_each_phdr(&kci, p) {
1878                off_t offs = p->rel + offset;
1879
1880                if (p->remaps)
1881                        continue;
1882                if (copy_bytes(kcore.fd, p->offset, extract.fd, offs, p->len))
1883                        goto out_extract_close;
1884        }
1885
1886        if (kcore_copy__compare_file(from_dir, to_dir, "modules"))
1887                goto out_extract_close;
1888
1889        if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
1890                goto out_extract_close;
1891
1892        err = 0;
1893
1894out_extract_close:
1895        kcore__close(&extract);
1896        if (err)
1897                unlink(extract_filename);
1898out_kcore_close:
1899        kcore__close(&kcore);
1900out_unlink_modules:
1901        if (err)
1902                kcore_copy__unlink(to_dir, "modules");
1903out_unlink_kallsyms:
1904        if (err)
1905                kcore_copy__unlink(to_dir, "kallsyms");
1906
1907        kcore_copy__free_phdrs(&kci);
1908        kcore_copy__free_syms(&kci);
1909
1910        return err;
1911}
1912
1913int kcore_extract__create(struct kcore_extract *kce)
1914{
1915        struct kcore kcore;
1916        struct kcore extract;
1917        size_t count = 1;
1918        int idx = 0, err = -1;
1919        off_t offset = page_size, sz;
1920
1921        if (kcore__open(&kcore, kce->kcore_filename))
1922                return -1;
1923
1924        strcpy(kce->extract_filename, PERF_KCORE_EXTRACT);
1925        if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true))
1926                goto out_kcore_close;
1927
1928        if (kcore__copy_hdr(&kcore, &extract, count))
1929                goto out_extract_close;
1930
1931        if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len))
1932                goto out_extract_close;
1933
1934        sz = kcore__write(&extract);
1935        if (sz < 0 || sz > offset)
1936                goto out_extract_close;
1937
1938        if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len))
1939                goto out_extract_close;
1940
1941        err = 0;
1942
1943out_extract_close:
1944        kcore__close(&extract);
1945        if (err)
1946                unlink(kce->extract_filename);
1947out_kcore_close:
1948        kcore__close(&kcore);
1949
1950        return err;
1951}
1952
1953void kcore_extract__delete(struct kcore_extract *kce)
1954{
1955        unlink(kce->extract_filename);
1956}
1957
1958#ifdef HAVE_GELF_GETNOTE_SUPPORT
1959
1960static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
1961{
1962        if (!base_off)
1963                return;
1964
1965        if (tmp->bit32)
1966                tmp->addr.a32[SDT_NOTE_IDX_LOC] =
1967                        tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
1968                        tmp->addr.a32[SDT_NOTE_IDX_BASE];
1969        else
1970                tmp->addr.a64[SDT_NOTE_IDX_LOC] =
1971                        tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
1972                        tmp->addr.a64[SDT_NOTE_IDX_BASE];
1973}
1974
1975static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
1976                              GElf_Addr base_off)
1977{
1978        if (!base_off)
1979                return;
1980
1981        if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
1982                tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
1983        else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
1984                tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
1985}
1986
1987/**
1988 * populate_sdt_note : Parse raw data and identify SDT note
1989 * @elf: elf of the opened file
1990 * @data: raw data of a section with description offset applied
1991 * @len: note description size
1992 * @type: type of the note
1993 * @sdt_notes: List to add the SDT note
1994 *
1995 * Responsible for parsing the @data in section .note.stapsdt in @elf and
1996 * if its an SDT note, it appends to @sdt_notes list.
1997 */
1998static int populate_sdt_note(Elf **elf, const char *data, size_t len,
1999                             struct list_head *sdt_notes)
2000{
2001        const char *provider, *name, *args;
2002        struct sdt_note *tmp = NULL;
2003        GElf_Ehdr ehdr;
2004        GElf_Shdr shdr;
2005        int ret = -EINVAL;
2006
2007        union {
2008                Elf64_Addr a64[NR_ADDR];
2009                Elf32_Addr a32[NR_ADDR];
2010        } buf;
2011
2012        Elf_Data dst = {
2013                .d_buf = &buf, .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
2014                .d_size = gelf_fsize((*elf), ELF_T_ADDR, NR_ADDR, EV_CURRENT),
2015                .d_off = 0, .d_align = 0
2016        };
2017        Elf_Data src = {
2018                .d_buf = (void *) data, .d_type = ELF_T_ADDR,
2019                .d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
2020                .d_align = 0
2021        };
2022
2023        tmp = (struct sdt_note *)calloc(1, sizeof(struct sdt_note));
2024        if (!tmp) {
2025                ret = -ENOMEM;
2026                goto out_err;
2027        }
2028
2029        INIT_LIST_HEAD(&tmp->note_list);
2030
2031        if (len < dst.d_size + 3)
2032                goto out_free_note;
2033
2034        /* Translation from file representation to memory representation */
2035        if (gelf_xlatetom(*elf, &dst, &src,
2036                          elf_getident(*elf, NULL)[EI_DATA]) == NULL) {
2037                pr_err("gelf_xlatetom : %s\n", elf_errmsg(-1));
2038                goto out_free_note;
2039        }
2040
2041        /* Populate the fields of sdt_note */
2042        provider = data + dst.d_size;
2043
2044        name = (const char *)memchr(provider, '\0', data + len - provider);
2045        if (name++ == NULL)
2046                goto out_free_note;
2047
2048        tmp->provider = strdup(provider);
2049        if (!tmp->provider) {
2050                ret = -ENOMEM;
2051                goto out_free_note;
2052        }
2053        tmp->name = strdup(name);
2054        if (!tmp->name) {
2055                ret = -ENOMEM;
2056                goto out_free_prov;
2057        }
2058
2059        args = memchr(name, '\0', data + len - name);
2060
2061        /*
2062         * There is no argument if:
2063         * - We reached the end of the note;
2064         * - There is not enough room to hold a potential string;
2065         * - The argument string is empty or just contains ':'.
2066         */
2067        if (args == NULL || data + len - args < 2 ||
2068                args[1] == ':' || args[1] == '\0')
2069                tmp->args = NULL;
2070        else {
2071                tmp->args = strdup(++args);
2072                if (!tmp->args) {
2073                        ret = -ENOMEM;
2074                        goto out_free_name;
2075                }
2076        }
2077
2078        if (gelf_getclass(*elf) == ELFCLASS32) {
2079                memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr));
2080                tmp->bit32 = true;
2081        } else {
2082                memcpy(&tmp->addr, &buf, 3 * sizeof(Elf64_Addr));
2083                tmp->bit32 = false;
2084        }
2085
2086        if (!gelf_getehdr(*elf, &ehdr)) {
2087                pr_debug("%s : cannot get elf header.\n", __func__);
2088                ret = -EBADF;
2089                goto out_free_args;
2090        }
2091
2092        /* Adjust the prelink effect :
2093         * Find out the .stapsdt.base section.
2094         * This scn will help us to handle prelinking (if present).
2095         * Compare the retrieved file offset of the base section with the
2096         * base address in the description of the SDT note. If its different,
2097         * then accordingly, adjust the note location.
2098         */
2099        if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
2100                sdt_adjust_loc(tmp, shdr.sh_offset);
2101
2102        /* Adjust reference counter offset */
2103        if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
2104                sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
2105
2106        list_add_tail(&tmp->note_list, sdt_notes);
2107        return 0;
2108
2109out_free_args:
2110        free(tmp->args);
2111out_free_name:
2112        free(tmp->name);
2113out_free_prov:
2114        free(tmp->provider);
2115out_free_note:
2116        free(tmp);
2117out_err:
2118        return ret;
2119}
2120
2121/**
2122 * construct_sdt_notes_list : constructs a list of SDT notes
2123 * @elf : elf to look into
2124 * @sdt_notes : empty list_head
2125 *
2126 * Scans the sections in 'elf' for the section
2127 * .note.stapsdt. It, then calls populate_sdt_note to find
2128 * out the SDT events and populates the 'sdt_notes'.
2129 */
2130static int construct_sdt_notes_list(Elf *elf, struct list_head *sdt_notes)
2131{
2132        GElf_Ehdr ehdr;
2133        Elf_Scn *scn = NULL;
2134        Elf_Data *data;
2135        GElf_Shdr shdr;
2136        size_t shstrndx, next;
2137        GElf_Nhdr nhdr;
2138        size_t name_off, desc_off, offset;
2139        int ret = 0;
2140
2141        if (gelf_getehdr(elf, &ehdr) == NULL) {
2142                ret = -EBADF;
2143                goto out_ret;
2144        }
2145        if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
2146                ret = -EBADF;
2147                goto out_ret;
2148        }
2149
2150        /* Look for the required section */
2151        scn = elf_section_by_name(elf, &ehdr, &shdr, SDT_NOTE_SCN, NULL);
2152        if (!scn) {
2153                ret = -ENOENT;
2154                goto out_ret;
2155        }
2156
2157        if ((shdr.sh_type != SHT_NOTE) || (shdr.sh_flags & SHF_ALLOC)) {
2158                ret = -ENOENT;
2159                goto out_ret;
2160        }
2161
2162        data = elf_getdata(scn, NULL);
2163
2164        /* Get the SDT notes */
2165        for (offset = 0; (next = gelf_getnote(data, offset, &nhdr, &name_off,
2166                                              &desc_off)) > 0; offset = next) {
2167                if (nhdr.n_namesz == sizeof(SDT_NOTE_NAME) &&
2168                    !memcmp(data->d_buf + name_off, SDT_NOTE_NAME,
2169                            sizeof(SDT_NOTE_NAME))) {
2170                        /* Check the type of the note */
2171                        if (nhdr.n_type != SDT_NOTE_TYPE)
2172                                goto out_ret;
2173
2174                        ret = populate_sdt_note(&elf, ((data->d_buf) + desc_off),
2175                                                nhdr.n_descsz, sdt_notes);
2176                        if (ret < 0)
2177                                goto out_ret;
2178                }
2179        }
2180        if (list_empty(sdt_notes))
2181                ret = -ENOENT;
2182
2183out_ret:
2184        return ret;
2185}
2186
2187/**
2188 * get_sdt_note_list : Wrapper to construct a list of sdt notes
2189 * @head : empty list_head
2190 * @target : file to find SDT notes from
2191 *
2192 * This opens the file, initializes
2193 * the ELF and then calls construct_sdt_notes_list.
2194 */
2195int get_sdt_note_list(struct list_head *head, const char *target)
2196{
2197        Elf *elf;
2198        int fd, ret;
2199
2200        fd = open(target, O_RDONLY);
2201        if (fd < 0)
2202                return -EBADF;
2203
2204        elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
2205        if (!elf) {
2206                ret = -EBADF;
2207                goto out_close;
2208        }
2209        ret = construct_sdt_notes_list(elf, head);
2210        elf_end(elf);
2211out_close:
2212        close(fd);
2213        return ret;
2214}
2215
2216/**
2217 * cleanup_sdt_note_list : free the sdt notes' list
2218 * @sdt_notes: sdt notes' list
2219 *
2220 * Free up the SDT notes in @sdt_notes.
2221 * Returns the number of SDT notes free'd.
2222 */
2223int cleanup_sdt_note_list(struct list_head *sdt_notes)
2224{
2225        struct sdt_note *tmp, *pos;
2226        int nr_free = 0;
2227
2228        list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
2229                list_del(&pos->note_list);
2230                free(pos->name);
2231                free(pos->provider);
2232                free(pos);
2233                nr_free++;
2234        }
2235        return nr_free;
2236}
2237
2238/**
2239 * sdt_notes__get_count: Counts the number of sdt events
2240 * @start: list_head to sdt_notes list
2241 *
2242 * Returns the number of SDT notes in a list
2243 */
2244int sdt_notes__get_count(struct list_head *start)
2245{
2246        struct sdt_note *sdt_ptr;
2247        int count = 0;
2248
2249        list_for_each_entry(sdt_ptr, start, note_list)
2250                count++;
2251        return count;
2252}
2253#endif
2254
2255void symbol__elf_init(void)
2256{
2257        elf_version(EV_CURRENT);
2258}
2259