Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'agent/tcf/services/tcf_elf.h')
-rw-r--r--agent/tcf/services/tcf_elf.h594
1 files changed, 594 insertions, 0 deletions
diff --git a/agent/tcf/services/tcf_elf.h b/agent/tcf/services/tcf_elf.h
new file mode 100644
index 00000000..912a0307
--- /dev/null
+++ b/agent/tcf/services/tcf_elf.h
@@ -0,0 +1,594 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * This module implements reading and caching of ELF files.
+ */
+#ifndef D_elf
+#define D_elf
+
+#include <config.h>
+
+#if ENABLE_ELF
+
+#if !defined(WIN32) && !defined(__APPLE__)
+# include <elf.h>
+#endif
+#include <framework/context.h>
+
+#if defined(WIN32) || defined(__APPLE__)
+
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_ABIVERSION 8
+#define EI_PAD 9
+#define EI_NIDENT 16
+
+#define ELFMAG0 0x7F
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EM_NONE 0
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SPARC */
+#define EM_386 3 /* Intel Architecture */
+#define EM_68K 4 /* Motorola 68000 */
+#define EM_88K 5 /* Motorola 88000 */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS RS3000 Big-Endian */
+#define EM_MIPS_RS4_BE 10 /* MIPS RS4000 Big-Endian */
+#define EM_ARM 40 /* ARM */
+#define EM_SH 42 /* Hitachi Super-H */
+#define EM_SPARCV9 43 /* SPARC Version 9 */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOOS 0xFE00
+#define ET_HIOS 0xFEFF
+#define ET_LOPROC 0xFF00
+#define ET_HIPROC 0xFFFF
+
+#define EV_CURRENT 1
+
+#define SHN_UNDEF 0
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+
+#define STN_UNDEF 0
+
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+
+#define PF_X (1 << 0)
+#define PF_W (1 << 1)
+#define PF_R (1 << 2)
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24
+#define DT_INIT_ARRAY 25
+#define DT_FINI_ARRAY 26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+#define DT_RUNPATH 29
+#define DT_FLAGS 30
+#define DT_ENCODING 32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define DT_NUM 34
+#define DT_LOOS 0x6000000d
+#define DT_HIOS 0x6ffff000
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+typedef struct Elf32_Ehdr {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct Elf32_Shdr {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+#define SHF_ALLOC 0x00000002
+
+typedef struct Elf32_Phdr {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct Elf32_Sym {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+#define ELF32_ST_BIND(i) ((i)>>4)
+#define ELF32_ST_TYPE(i) ((i)&0xf)
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((uint8_t)(i))
+
+typedef struct {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+#endif
+
+#if defined(_WRS_KERNEL) || defined(WIN32) || defined(__APPLE__)
+
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+typedef uint64_t Elf64_Off;
+typedef uint16_t Elf64_Section;
+typedef Elf64_Half Elf64_Versym;
+typedef uint16_t Elf64_Quarter;
+
+typedef struct {
+ uint8_t e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+typedef struct {
+ Elf64_Word st_name;
+ uint8_t st_info;
+ uint8_t st_other;
+ Elf64_Section st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+#define ELF64_R_SYM(i) ((uint32_t)((i) >> 32))
+#define ELF64_R_TYPE(i) ((uint32_t)(i))
+
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+typedef struct {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+#endif
+
+#ifndef EM_ARM
+#define EM_ARM 40
+#endif
+#ifndef EM_X86_64
+#define EM_X86_64 62
+#endif
+#ifndef EM_PPC
+#define EM_PPC 20
+#endif
+#ifndef EM_PPC64
+#define EM_PPC64 21
+#endif
+
+typedef struct ElfX_Sym {
+ union {
+ Elf32_Sym Elf32;
+ Elf64_Sym Elf64;
+ } u;
+} ElfX_Sym;
+
+typedef uint8_t U1_T;
+typedef int8_t I1_T;
+typedef uint16_t U2_T;
+typedef int16_t I2_T;
+typedef uint32_t U4_T;
+typedef int32_t I4_T;
+typedef uint64_t U8_T;
+typedef int64_t I8_T;
+
+typedef struct ELF_File ELF_File;
+typedef struct ELF_Section ELF_Section;
+typedef struct ELF_SecSymbol ELF_SecSymbol;
+typedef struct ELF_SymbolInfo ELF_SymbolInfo;
+typedef struct ELF_PHeader ELF_PHeader;
+
+struct ELF_File {
+ ELF_File * next;
+
+ char * name;
+ dev_t dev;
+ ino_t ino;
+ int64_t mtime;
+ int mtime_changed;
+ ErrorReport * error;
+ int fd;
+
+ uint8_t big_endian; /* 0 - least significant first, 1 - most significat first */
+ uint8_t byte_swap; /* > 0 if file endianness not same as the agent endianness */
+ uint8_t elf64;
+ uint16_t type;
+ uint16_t machine;
+ uint8_t os_abi;
+
+ unsigned section_cnt;
+ ELF_Section * sections;
+ char * str_pool;
+
+ unsigned pheader_cnt;
+ ELF_PHeader * pheaders;
+
+ void * dwarf_io_cache;
+ void * dwarf_dt_cache;
+
+ int age;
+ int listed;
+ int debug_info_file;
+ char * debug_info_file_name;
+};
+
+struct ELF_SecSymbol {
+ ELF_Section * section;
+ unsigned index;
+ U8_T address;
+};
+
+struct ELF_SymbolInfo {
+ ELF_Section * sym_section;
+ U4_T sym_index;
+ unsigned addr_index;
+ ELF_Section * section;
+ U4_T section_index;
+ char * name;
+ U1_T bind;
+ U1_T type;
+ U8_T value;
+ U8_T size;
+};
+
+struct ELF_Section {
+ ELF_File * file;
+ U4_T index;
+ unsigned name_offset;
+ char * name;
+ void * data;
+ U4_T type;
+ U4_T flags;
+ U4_T alignment;
+ U8_T offset;
+ U8_T size;
+ U8_T addr;
+ U4_T link;
+ U4_T info;
+ U4_T entsize;
+
+ void * mmap_addr;
+ size_t mmap_size;
+
+ int relocate;
+
+ unsigned sym_count;
+
+ /* Symbol by address search index */
+ ELF_SecSymbol * sym_addr_table;
+ unsigned sym_addr_cnt;
+ unsigned sym_addr_max;
+
+ /* Symbol by name search index */
+ unsigned * sym_names_hash;
+ unsigned * sym_names_next;
+};
+
+struct ELF_PHeader {
+ U4_T type;
+ U8_T offset;
+ U8_T address;
+ U8_T file_size;
+ U8_T mem_size;
+ U4_T flags;
+ U4_T align;
+};
+
+#define SYM_HASH_SIZE (32 * MEM_USAGE_FACTOR - 1)
+
+/*
+ * Swap bytes in a buffer.
+ * The function is used when ELF file endianness mismatch agent endianness.
+ */
+extern void swap_bytes(void * buf, size_t size);
+#define SWAP(x) swap_bytes(&(x), sizeof(x))
+
+/*
+ * Open ELF file for reading.
+ * Same file can be opened mutiple times.
+ * Returns the file descriptior on success. If error, returns NULL and sets errno.
+ * The file descriptor is valid only during single dispatch cycle.
+ */
+extern ELF_File * elf_open(const char * file_name);
+
+/*
+ * Load section data into memory.
+ * section->data is set to section data address in memory.
+ * Data will stay in memory at least until file is closed.
+ * Returns zero on success. If error, returns -1 and sets errno.
+ */
+extern int elf_load(ELF_Section * section);
+
+/*
+ * Register ELF file close callback.
+ * The callback is called each time an ELF file data is about to be disposed.
+ * Service implementation can use the callback to deallocate
+ * cached data related to the file.
+ */
+typedef void (*ELFCloseListener)(ELF_File *);
+extern void elf_add_close_listener(ELFCloseListener listener);
+
+#if ENABLE_DebugContext
+
+/*
+ * Open ELF file for reading for given device and inode.
+ * Same file can be opened mutiple times.
+ * Returns the file descriptior on success. If error, returns NULL and sets errno.
+ * The file descriptor is valid only during single dispatch cycle.
+ */
+extern ELF_File * elf_open_inode(Context * ctx, dev_t dev, ino_t ino, int64_t mtime);
+
+/*
+ * Iterate context ELF files that are mapped in context memory in given address range (inclusive).
+ * Returns the file descriptior on success. If error, returns NULL and sets errno.
+ */
+extern ELF_File * elf_list_first(Context * ctx, ContextAddress addr0, ContextAddress addr1);
+extern ELF_File * elf_list_next(Context * ctx);
+
+/*
+ * Finish iteration of context ELF files.
+ * Clients should always call elf_list_done() after calling elf_list_first().
+ */
+extern void elf_list_done(Context * ctx);
+
+/*
+ * Map link-time address in an ELF file to run-time address in a context.
+ * Return 0 if the address is not currently mapped.
+ */
+extern ContextAddress elf_map_to_run_time_address(Context * ctx, ELF_File * file, ELF_Section * section, ContextAddress addr);
+
+/*
+ * Map run-time address in a context to link time address in an ELF file.
+ * Return 0 if the address is not currently mapped.
+ */
+extern ContextAddress elf_map_to_link_time_address(Context * ctx, ContextAddress addr, ELF_File ** file, ELF_Section ** sec);
+
+/*
+ * Read a word from context memory. Word size and endianess are determened by ELF file.
+ */
+extern int elf_read_memory_word(Context * ctx, ELF_File * file, ContextAddress addr, ContextAddress * word);
+
+/*
+ * Return run-time address of the debug structrure that is normally pointed by DT_DEBUG entry in ".dynamic" section.
+ * "file" is assigned a file that contains DT_DEBUG entry.
+ * Return 0 if the structure could not be found.
+ */
+extern ContextAddress elf_get_debug_structure_address(Context * ctx, ELF_File ** file);
+
+#endif
+
+/* Return symbol name hash. The hash is used to build sym_names_hash table. */
+extern unsigned calc_symbol_name_hash(const char * s);
+
+/* Compare symbol names. */
+extern int cmp_symbol_names(const char * x, const char * y);
+
+/*
+ * Get ELF_SymbolInfo.
+ * Call exception() on error.
+ */
+extern void unpack_elf_symbol_info(ELF_Section * section, U4_T index, ELF_SymbolInfo * info);
+
+/*
+ * Find ELF symbol by link-time address in a section.
+ * Return info for nearest symbol at or before given address.
+ * If not found, set all 'info' fields to zeros.
+ * Call exception() on error.
+ */
+extern void elf_find_symbol_by_address(ELF_Section * section, ContextAddress addr, ELF_SymbolInfo * info);
+
+/*
+ * Get prev/next ELF symbol by link-time address in a section.
+ * If not found, set all 'info' fields to zeros.
+ * Call exception() on error.
+ */
+extern void elf_prev_symbol_by_address(ELF_SymbolInfo * info);
+extern void elf_next_symbol_by_address(ELF_SymbolInfo * info);
+
+/*
+ * Initialize ELF support module.
+ */
+extern void ini_elf(void);
+
+#endif /* ENABLE_ELF */
+
+#endif /* D_elf */

Back to the top