Linux Perf
symbol-elf.c File Reference
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include "symbol.h"
#include "demangle-java.h"
#include "demangle-rust.h"
#include "machine.h"
#include "vdso.h"
#include "debug.h"
#include "sane_ctype.h"
#include <symbol/kallsyms.h>
#include <bfd.h>
Include dependency graph for symbol-elf.c:

Go to the source code of this file.

Classes

struct  kcore
 
struct  phdr_data
 
struct  sym_data
 
struct  kcore_copy_info
 

Macros

#define EM_AARCH64   183 /* ARM 64 bit */
 
#define PACKAGE   'perf'
 
#define NT_GNU_BUILD_ID   3
 
#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym)
 
#define STT_GNU_IFUNC   10
 
#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries)
 
#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries)
 
#define NOTE_ALIGN(n)   (((n) + 3) & -4U)
 
#define kcore_copy__for_each_phdr(k, p)   list_for_each_entry((p), &(k)->phdrs, node)
 

Typedefs

typedef Elf64_Nhdr GElf_Nhdr
 

Functions

static int elf_getphdrnum (Elf *elf, size_t *dst)
 
static int elf_getshdrstrndx (Elf *elf __maybe_unused, size_t *dst __maybe_unused)
 
static uint8_t elf_sym__type (const GElf_Sym *sym)
 
static int elf_sym__is_function (const GElf_Sym *sym)
 
static bool elf_sym__is_object (const GElf_Sym *sym)
 
static int elf_sym__is_label (const GElf_Sym *sym)
 
static bool elf_sym__filter (GElf_Sym *sym)
 
static const char * elf_sym__name (const GElf_Sym *sym, const Elf_Data *symstrs)
 
static const char * elf_sec__name (const GElf_Shdr *shdr, const Elf_Data *secstrs)
 
static int elf_sec__is_text (const GElf_Shdr *shdr, const Elf_Data *secstrs)
 
static bool elf_sec__is_data (const GElf_Shdr *shdr, const Elf_Data *secstrs)
 
static bool elf_sec__filter (GElf_Shdr *shdr, Elf_Data *secstrs)
 
static size_t elf_addr_to_index (Elf *elf, GElf_Addr addr)
 
Elf_Scn * elf_section_by_name (Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx)
 
static bool want_demangle (bool is_kernel_sym)
 
static char * demangle_sym (struct dso *dso, int kmodule, const char *elf_name)
 
int dso__synthesize_plt_symbols (struct dso *dso, struct symsrc *ss)
 
char * dso__demangle_sym (struct dso *dso, int kmodule, const char *elf_name)
 
static int elf_read_build_id (Elf *elf, void *bf, size_t size)
 
int filename__read_build_id (const char *filename, void *bf, size_t size)
 
int sysfs__read_build_id (const char *filename, void *build_id, size_t size)
 
int filename__read_debuglink (const char *filename, char *debuglink, size_t size)
 
static int dso__swap_init (struct dso *dso, unsigned char eidata)
 
bool symsrc__possibly_runtime (struct symsrc *ss)
 
bool symsrc__has_symtab (struct symsrc *ss)
 
void symsrc__destroy (struct symsrc *ss)
 
bool __weak elf__needs_adjust_symbols (GElf_Ehdr ehdr)
 
int symsrc__init (struct symsrc *ss, struct dso *dso, const char *name, enum dso_binary_type type)
 
static bool ref_reloc_sym_not_found (struct kmap *kmap)
 
static u64 ref_reloc (struct kmap *kmap)
 
void __weak arch__sym_update (struct symbol *s __maybe_unused, GElf_Sym *sym __maybe_unused)
 
static int dso__process_kernel_symbol (struct dso *dso, struct map *map, GElf_Sym *sym, GElf_Shdr *shdr, struct map_groups *kmaps, struct kmap *kmap, struct dso **curr_dsop, struct map **curr_mapp, const char *section_name, bool adjust_kernel_syms, bool kmodule, bool *remap_kernel)
 
int dso__load_sym (struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, int kmodule)
 
static int elf_read_maps (Elf *elf, bool exe, mapfn_t mapfn, void *data)
 
int file__read_maps (int fd, bool exe, mapfn_t mapfn, void *data, bool *is_64_bit)
 
enum dso_type dso__type_fd (int fd)
 
static int copy_bytes (int from, off_t from_offs, int to, off_t to_offs, u64 len)
 
static int kcore__open (struct kcore *kcore, const char *filename)
 
static int kcore__init (struct kcore *kcore, char *filename, int elfclass, bool temp)
 
static void kcore__close (struct kcore *kcore)
 
static int kcore__copy_hdr (struct kcore *from, struct kcore *to, size_t count)
 
static int kcore__add_phdr (struct kcore *kcore, int idx, off_t offset, u64 addr, u64 len)
 
static off_t kcore__write (struct kcore *kcore)
 
static struct phdr_dataphdr_data__new (u64 addr, u64 len, off_t offset)
 
static struct phdr_datakcore_copy_info__addnew (struct kcore_copy_info *kci, u64 addr, u64 len, off_t offset)
 
static void kcore_copy__free_phdrs (struct kcore_copy_info *kci)
 
static struct sym_datakcore_copy__new_sym (struct kcore_copy_info *kci, u64 addr)
 
static void kcore_copy__free_syms (struct kcore_copy_info *kci)
 
static int kcore_copy__process_kallsyms (void *arg, const char *name, char type, u64 start)
 
static int kcore_copy__parse_kallsyms (struct kcore_copy_info *kci, const char *dir)
 
static int kcore_copy__process_modules (void *arg, const char *name __maybe_unused, u64 start, u64 size __maybe_unused)
 
static int kcore_copy__parse_modules (struct kcore_copy_info *kci, const char *dir)
 
static int kcore_copy__map (struct kcore_copy_info *kci, u64 start, u64 end, u64 pgoff, u64 s, u64 e)
 
static int kcore_copy__read_map (u64 start, u64 len, u64 pgoff, void *data)
 
static int kcore_copy__read_maps (struct kcore_copy_info *kci, Elf *elf)
 
static void kcore_copy__find_remaps (struct kcore_copy_info *kci)
 
static void kcore_copy__layout (struct kcore_copy_info *kci)
 
static int kcore_copy__calc_maps (struct kcore_copy_info *kci, const char *dir, Elf *elf)
 
static int kcore_copy__copy_file (const char *from_dir, const char *to_dir, const char *name)
 
static int kcore_copy__unlink (const char *dir, const char *name)
 
static int kcore_copy__compare_fds (int from, int to)
 
static int kcore_copy__compare_files (const char *from_filename, const char *to_filename)
 
static int kcore_copy__compare_file (const char *from_dir, const char *to_dir, const char *name)
 
int kcore_copy (const char *from_dir, const char *to_dir)
 
int kcore_extract__create (struct kcore_extract *kce)
 
void kcore_extract__delete (struct kcore_extract *kce)
 
void symbol__elf_init (void)
 

Macro Definition Documentation

◆ elf_section__for_each_rel

#define elf_section__for_each_rel (   reldata,
  pos,
  pos_mem,
  idx,
  nr_entries 
)
Value:
for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
idx < nr_entries; \
++idx, pos = gelf_getrel(reldata, idx, &pos_mem))

Definition at line 228 of file symbol-elf.c.

◆ elf_section__for_each_rela

#define elf_section__for_each_rela (   reldata,
  pos,
  pos_mem,
  idx,
  nr_entries 
)
Value:
for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
idx < nr_entries; \
++idx, pos = gelf_getrela(reldata, idx, &pos_mem))

Definition at line 233 of file symbol-elf.c.

◆ elf_symtab__for_each_symbol

#define elf_symtab__for_each_symbol (   syms,
  nr_syms,
  idx,
  sym 
)
Value:
for (idx = 0, gelf_getsym(syms, idx, &sym);\
idx < nr_syms; \
idx++, gelf_getsym(syms, idx, &sym))
static int sym(yyscan_t scanner, int type, int config)
struct fake_sym * syms
Definition: hists_common.c:74
size_t nr_syms
Definition: hists_common.c:75

elf_symtab__for_each_symbol - iterate thru all the symbols

: struct elf_symtab instance to iterate : uint32_t idx : GElf_Sym iterator

Definition at line 80 of file symbol-elf.c.

◆ EM_AARCH64

#define EM_AARCH64   183 /* ARM 64 bit */

Definition at line 19 of file symbol-elf.c.

◆ kcore_copy__for_each_phdr

#define kcore_copy__for_each_phdr (   k,
 
)    list_for_each_entry((p), &(k)->phdrs, node)

Definition at line 1413 of file symbol-elf.c.

◆ NOTE_ALIGN

#define NOTE_ALIGN (   n)    (((n) + 3) & -4U)

Definition at line 406 of file symbol-elf.c.

◆ NT_GNU_BUILD_ID

#define NT_GNU_BUILD_ID   3

Definition at line 70 of file symbol-elf.c.

◆ PACKAGE

#define PACKAGE   'perf'

Definition at line 40 of file symbol-elf.c.

◆ STT_GNU_IFUNC

#define STT_GNU_IFUNC   10

Definition at line 91 of file symbol-elf.c.

Typedef Documentation

◆ GElf_Nhdr

typedef Elf64_Nhdr GElf_Nhdr

Definition at line 22 of file symbol-elf.c.

Function Documentation

◆ arch__sym_update()

void __weak arch__sym_update ( struct symbol *s  __maybe_unused,
GElf_Sym *sym  __maybe_unused 
)

Definition at line 797 of file symbol-elf.c.

◆ copy_bytes()

static int copy_bytes ( int  from,
off_t  from_offs,
int  to,
off_t  to_offs,
u64  len 
)
static

Definition at line 1212 of file symbol-elf.c.

Here is the call graph for this function:

◆ demangle_sym()

static char* demangle_sym ( struct dso dso,
int  kmodule,
const char *  elf_name 
)
static

Definition at line 202 of file symbol-elf.c.

Here is the call graph for this function:

◆ dso__demangle_sym()

char* dso__demangle_sym ( struct dso dso,
int  kmodule,
const char *  elf_name 
)

Definition at line 398 of file symbol-elf.c.

Here is the call graph for this function:

◆ dso__load_sym()

int dso__load_sym ( struct dso dso,
struct map map,
struct symsrc syms_ss,
struct symsrc runtime_ss,
int  kmodule 
)

Definition at line 904 of file symbol-elf.c.

Here is the call graph for this function:

◆ dso__process_kernel_symbol()

static int dso__process_kernel_symbol ( struct dso dso,
struct map map,
GElf_Sym *  sym,
GElf_Shdr *  shdr,
struct map_groups kmaps,
struct kmap kmap,
struct dso **  curr_dsop,
struct map **  curr_mapp,
const char *  section_name,
bool  adjust_kernel_syms,
bool  kmodule,
bool *  remap_kernel 
)
static

Definition at line 800 of file symbol-elf.c.

Here is the call graph for this function:

◆ dso__swap_init()

static int dso__swap_init ( struct dso dso,
unsigned char  eidata 
)
static

Definition at line 617 of file symbol-elf.c.

◆ dso__synthesize_plt_symbols()

int dso__synthesize_plt_symbols ( struct dso dso,
struct symsrc ss 
)

Definition at line 245 of file symbol-elf.c.

Here is the call graph for this function:

◆ dso__type_fd()

enum dso_type dso__type_fd ( int  fd)

Definition at line 1179 of file symbol-elf.c.

◆ elf__needs_adjust_symbols()

bool __weak elf__needs_adjust_symbols ( GElf_Ehdr  ehdr)

Definition at line 661 of file symbol-elf.c.

◆ elf_addr_to_index()

static size_t elf_addr_to_index ( Elf *  elf,
GElf_Addr  addr 
)
static

Definition at line 152 of file symbol-elf.c.

◆ elf_getphdrnum()

static int elf_getphdrnum ( Elf *  elf,
size_t *  dst 
)
static

Definition at line 46 of file symbol-elf.c.

◆ elf_getshdrstrndx()

static int elf_getshdrstrndx ( Elf *elf  __maybe_unused,
size_t *dst  __maybe_unused 
)
static

Definition at line 62 of file symbol-elf.c.

◆ elf_read_build_id()

static int elf_read_build_id ( Elf *  elf,
void *  bf,
size_t  size 
)
static

Definition at line 408 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_read_maps()

static int elf_read_maps ( Elf *  elf,
bool  exe,
mapfn_t  mapfn,
void *  data 
)
static

Definition at line 1128 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sec__filter()

static bool elf_sec__filter ( GElf_Shdr *  shdr,
Elf_Data *  secstrs 
)
static

Definition at line 146 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sec__is_data()

static bool elf_sec__is_data ( const GElf_Shdr *  shdr,
const Elf_Data *  secstrs 
)
inlinestatic

Definition at line 140 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sec__is_text()

static int elf_sec__is_text ( const GElf_Shdr *  shdr,
const Elf_Data *  secstrs 
)
inlinestatic

Definition at line 134 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sec__name()

static const char* elf_sec__name ( const GElf_Shdr *  shdr,
const Elf_Data *  secstrs 
)
inlinestatic

Definition at line 128 of file symbol-elf.c.

◆ elf_section_by_name()

Elf_Scn* elf_section_by_name ( Elf *  elf,
GElf_Ehdr *  ep,
GElf_Shdr *  shp,
const char *  name,
size_t *  idx 
)

Definition at line 171 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sym__filter()

static bool elf_sym__filter ( GElf_Sym *  sym)
static

Definition at line 117 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sym__is_function()

static int elf_sym__is_function ( const GElf_Sym *  sym)
inlinestatic

Definition at line 94 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sym__is_label()

static int elf_sym__is_label ( const GElf_Sym *  sym)
inlinestatic

Definition at line 109 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sym__is_object()

static bool elf_sym__is_object ( const GElf_Sym *  sym)
inlinestatic

Definition at line 102 of file symbol-elf.c.

Here is the call graph for this function:

◆ elf_sym__name()

static const char* elf_sym__name ( const GElf_Sym *  sym,
const Elf_Data *  symstrs 
)
inlinestatic

Definition at line 122 of file symbol-elf.c.

◆ elf_sym__type()

static uint8_t elf_sym__type ( const GElf_Sym *  sym)
inlinestatic

Definition at line 85 of file symbol-elf.c.

◆ file__read_maps()

int file__read_maps ( int fd  ,
bool exe  ,
mapfn_t mapfn  ,
void *  data,
bool *  is_64_bit 
)

Definition at line 1160 of file symbol-elf.c.

Here is the call graph for this function:

◆ filename__read_build_id()

int filename__read_build_id ( const char *  filename,
void *  bf,
size_t  size 
)

Definition at line 487 of file symbol-elf.c.

◆ filename__read_debuglink()

int filename__read_debuglink ( const char *  filename,
char *  debuglink,
size_t  size 
)

Definition at line 565 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore__add_phdr()

static int kcore__add_phdr ( struct kcore kcore,
int  idx,
off_t  offset,
u64  addr,
u64  len 
)
static

Definition at line 1362 of file symbol-elf.c.

◆ kcore__close()

static void kcore__close ( struct kcore kcore)
static

Definition at line 1320 of file symbol-elf.c.

◆ kcore__copy_hdr()

static int kcore__copy_hdr ( struct kcore from,
struct kcore to,
size_t  count 
)
static

Definition at line 1326 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore__init()

static int kcore__init ( struct kcore kcore,
char *  filename,
int  elfclass,
bool  temp 
)
static

Definition at line 1289 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore__open()

static int kcore__open ( struct kcore kcore,
const char *  filename 
)
static

Definition at line 1260 of file symbol-elf.c.

◆ kcore__write()

static off_t kcore__write ( struct kcore kcore)
static

Definition at line 1382 of file symbol-elf.c.

◆ kcore_copy()

int kcore_copy ( const char *  from_dir,
const char *  to_dir 
)

kcore_copy - copy kallsyms, modules and kcore from one directory to another. : from directory : to directory

This function copies kallsyms, modules and kcore files from one directory to another. kallsyms and modules are copied entirely. Only code segments are copied from kcore. It is assumed that two segments suffice: one for the kernel proper and one for all the modules. The code segments are determined from kallsyms and modules files. The kernel map starts at _stext or the lowest function symbol, and ends at _etext or the highest function symbol. The module map starts at the lowest module address and ends at the highest module symbol. Start addresses are rounded down to the nearest page. End addresses are rounded up to the nearest page. An extra page is added to the highest kernel symbol and highest module symbol to, hopefully, encompass that symbol too. Because it contains only code sections, the resulting kcore is unusual. One significant peculiarity is that the mapping (start -> pgoff) is not the same for the kernel map and the modules map. That happens because the data is copied adjacently whereas the original kcore has gaps. Finally, kallsyms and modules files are compared with their copies to check that modules have not been loaded or unloaded while the copies were taking place.

Return: %0 on success, %-1 on failure.

Definition at line 1818 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__calc_maps()

static int kcore_copy__calc_maps ( struct kcore_copy_info kci,
const char *  dir,
Elf *  elf 
)
static

Definition at line 1659 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__compare_fds()

static int kcore_copy__compare_fds ( int  from,
int  to 
)
static

Definition at line 1723 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__compare_file()

static int kcore_copy__compare_file ( const char *  from_dir,
const char *  to_dir,
const char *  name 
)
static

Definition at line 1782 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__compare_files()

static int kcore_copy__compare_files ( const char *  from_filename,
const char *  to_filename 
)
static

Definition at line 1761 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__copy_file()

static int kcore_copy__copy_file ( const char *  from_dir,
const char *  to_dir,
const char *  name 
)
static

Definition at line 1702 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__find_remaps()

static void kcore_copy__find_remaps ( struct kcore_copy_info kci)
static

Definition at line 1601 of file symbol-elf.c.

◆ kcore_copy__free_phdrs()

static void kcore_copy__free_phdrs ( struct kcore_copy_info kci)
static

Definition at line 1441 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__free_syms()

static void kcore_copy__free_syms ( struct kcore_copy_info kci)
static

Definition at line 1464 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__layout()

static void kcore_copy__layout ( struct kcore_copy_info kci)
static

Definition at line 1636 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__map()

static int kcore_copy__map ( struct kcore_copy_info kci,
u64  start,
u64  end,
u64  pgoff,
u64  s,
u64  e 
)
static

Definition at line 1556 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__new_sym()

static struct sym_data* kcore_copy__new_sym ( struct kcore_copy_info kci,
u64  addr 
)
static

Definition at line 1451 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__parse_kallsyms()

static int kcore_copy__parse_kallsyms ( struct kcore_copy_info kci,
const char *  dir 
)
static

Definition at line 1510 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__parse_modules()

static int kcore_copy__parse_modules ( struct kcore_copy_info kci,
const char *  dir 
)
static

Definition at line 1539 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__process_kallsyms()

static int kcore_copy__process_kallsyms ( void *  arg,
const char *  name,
char  type,
u64  start 
)
static

Definition at line 1474 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__process_modules()

static int kcore_copy__process_modules ( void *  arg,
const char *name  __maybe_unused,
u64  start,
u64 size  __maybe_unused 
)
static

Definition at line 1527 of file symbol-elf.c.

◆ kcore_copy__read_map()

static int kcore_copy__read_map ( u64  start,
u64  len,
u64  pgoff,
void *  data 
)
static

Definition at line 1570 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__read_maps()

static int kcore_copy__read_maps ( struct kcore_copy_info kci,
Elf *  elf 
)
static

Definition at line 1593 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_copy__unlink()

static int kcore_copy__unlink ( const char *  dir,
const char *  name 
)
static

Definition at line 1714 of file symbol-elf.c.

◆ kcore_copy_info__addnew()

static struct phdr_data* kcore_copy_info__addnew ( struct kcore_copy_info kci,
u64  addr,
u64  len,
off_t  offset 
)
static

Definition at line 1429 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_extract__create()

int kcore_extract__create ( struct kcore_extract kce)

Definition at line 1904 of file symbol-elf.c.

Here is the call graph for this function:

◆ kcore_extract__delete()

void kcore_extract__delete ( struct kcore_extract kce)

Definition at line 1944 of file symbol-elf.c.

Here is the call graph for this function:

◆ phdr_data__new()

static struct phdr_data* phdr_data__new ( u64  addr,
u64  len,
off_t  offset 
)
static

Definition at line 1416 of file symbol-elf.c.

Here is the call graph for this function:

◆ ref_reloc()

static u64 ref_reloc ( struct kmap kmap)
static

ref_reloc - kernel relocation offset. : kernel maps and relocation reference symbol

This function returns the offset of kernel addresses as determined by using the relocation reference symbol i.e. if the kernel has not been relocated then the return value is zero.

Definition at line 788 of file symbol-elf.c.

◆ ref_reloc_sym_not_found()

static bool ref_reloc_sym_not_found ( struct kmap kmap)
static

ref_reloc_sym_not_found - has kernel relocation symbol been found. : kernel maps and relocation reference symbol

This function returns true if we are dealing with the kernel maps and the relocation reference symbol has not yet been found. Otherwise false is returned.

Definition at line 774 of file symbol-elf.c.

◆ symbol__elf_init()

void symbol__elf_init ( void  )

Definition at line 2224 of file symbol-elf.c.

◆ symsrc__destroy()

void symsrc__destroy ( struct symsrc ss)

Definition at line 654 of file symbol-elf.c.

◆ symsrc__has_symtab()

bool symsrc__has_symtab ( struct symsrc ss)

Definition at line 649 of file symbol-elf.c.

◆ symsrc__init()

int symsrc__init ( struct symsrc ss,
struct dso dso,
const char *  name,
enum dso_binary_type  type 
)

Definition at line 666 of file symbol-elf.c.

◆ symsrc__possibly_runtime()

bool symsrc__possibly_runtime ( struct symsrc ss)

Definition at line 644 of file symbol-elf.c.

◆ sysfs__read_build_id()

int sysfs__read_build_id ( const char *  filename,
void *  build_id,
size_t  size 
)

Definition at line 514 of file symbol-elf.c.

◆ want_demangle()

static bool want_demangle ( bool  is_kernel_sym)
static

Definition at line 197 of file symbol-elf.c.