summaryrefslogtreecommitdiff
path: root/src/crash-stack
diff options
context:
space:
mode:
authorKarol Lewandowski <k.lewandowsk@samsung.com>2020-07-28 12:48:27 +0000
committerGerrit Code Review <gerrit@review>2020-07-28 12:48:27 +0000
commit79a74be4c7fb07d8b5efd08869385173462e599e (patch)
treef3ba13de43a906f9ad131b00c043d0a18d2f08a3 /src/crash-stack
parent49d99694bc9376642e726f14b201d14b7d484e0e (diff)
parent033bc9902ae6cc069acc2cfc8f813313a818bf4f (diff)
downloadcrash-worker-tizen_4.0.tar.gz
crash-worker-tizen_4.0.tar.bz2
crash-worker-tizen_4.0.zip
* changes: Release 4.0.5 Change the way ELF file are parsed Add an ELF file parser
Diffstat (limited to 'src/crash-stack')
-rw-r--r--src/crash-stack/CMakeLists.txt2
-rw-r--r--src/crash-stack/crash-stack-arm.c12
-rw-r--r--src/crash-stack/crash-stack.c59
3 files changed, 40 insertions, 33 deletions
diff --git a/src/crash-stack/CMakeLists.txt b/src/crash-stack/CMakeLists.txt
index 0c1a8a4..ff8bfbf 100644
--- a/src/crash-stack/CMakeLists.txt
+++ b/src/crash-stack/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CRASH_STACK_BIN "crash-stack")
# Common source code files
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
-set(CRASH_STACK_SRCS crash-stack.c crash-stack-libunw.c ${CMAKE_SOURCE_DIR}/src/shared/util.c)
+set(CRASH_STACK_SRCS crash-stack.c crash-stack-libunw.c ${CMAKE_SOURCE_DIR}/src/shared/util.c ${CMAKE_SOURCE_DIR}/src/shared/telf.c)
# Add architecture dependent source files
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
diff --git a/src/crash-stack/crash-stack-arm.c b/src/crash-stack/crash-stack-arm.c
index 5f9033f..948d893 100644
--- a/src/crash-stack/crash-stack-arm.c
+++ b/src/crash-stack/crash-stack-arm.c
@@ -24,6 +24,8 @@
*/
#include "crash-stack.h"
+#include <elf.h>
+#include <stdio.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/user.h>
@@ -41,11 +43,11 @@
* @brief Important registers for unwinding stack on ARM
*/
struct Regs {
- Dwarf_Addr regs[REGS_REGULAR_NUM]; ///< regular registers
- Dwarf_Addr sp; ///< register: stack pointer
- Dwarf_Addr lr; ///< register: link register
- Dwarf_Addr pc; ///< register: program counter
- Dwarf_Addr spsr; ///< register: status register
+ Elf64_Addr regs[REGS_REGULAR_NUM]; ///< regular registers
+ Elf64_Addr sp; ///< register: stack pointer
+ Elf64_Addr lr; ///< register: link register
+ Elf64_Addr pc; ///< register: program counter
+ Elf64_Addr spsr; ///< register: status register
};
typedef struct Regs Regs; ///< convenience type definition
diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c
index 653a064..8dd2b64 100644
--- a/src/crash-stack/crash-stack.c
+++ b/src/crash-stack/crash-stack.c
@@ -18,6 +18,7 @@
* RafaƂ Pietruch <r.pietruch@samsung.com>
*/
#define _GNU_SOURCE 1
+#define _LARGEFILE64_SOURCE
/**
* @file crash-stack.c
@@ -51,6 +52,7 @@
#include <elfutils/version.h>
#include <elfutils/libdwfl.h>
#include "shared/util.h"
+#include "shared/telf.h"
#define BUF_SIZE (BUFSIZ)
#define HEXA 16
@@ -134,48 +136,50 @@ static int __module_callback(Dwfl_Module *module, void **userdata,
return DWARF_CB_OK;
}
-static void __find_symbol_in_elf(ProcInfo *proc_info, Dwarf_Addr mapping_start)
+static void __find_symbol_in_elf(ProcInfo *proc_info, Elf64_Addr mapping_start)
{
- Elf *elf;
+ TElf *elf = malloc(sizeof(TElf));
int fd;
const char *elf_name = proc_info->module_name;
- Dwarf_Addr address = proc_info->addr;
+ Elf64_Addr address = proc_info->addr;
fd = open(elf_name, O_RDONLY);
- if (-1 == fd)
+ if (-1 == fd) {
+ free(elf);
return;
+ }
- elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
-
- if (NULL == elf) {
+ if (!teu_begin(fd, elf)) {
close(fd);
+ free(elf);
+ teu_close(elf);
return;
}
- Elf_Scn *scn = NULL;
int found = 0;
- while ((scn = elf_nextscn(elf, scn)) != NULL && !found) {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
- if (shdr != NULL && (shdr->sh_type == SHT_SYMTAB || shdr->sh_type == SHT_DYNSYM)) {
- Elf_Data *sdata = elf_getdata(scn, NULL);
- unsigned int nsyms = sdata->d_size / (gelf_getclass(elf) == ELFCLASS32 ?
- sizeof(Elf32_Sym) :
- sizeof(Elf64_Sym));
- unsigned int cnt;
+ for (size_t i = 0; i < elf->ehdr.e_shnum && !found; i++) {
+ Elf64_Shdr shdr;
+
+ if (!teu_getshdr(elf, i, &shdr))
+ break;
+
+ if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
+ void *data = teu_getsdata(elf, &shdr);
+
+ unsigned int nsyms = shdr.sh_size / shdr.sh_entsize;
uintptr_t address_offset = address;
- if (shdr->sh_type == SHT_DYNSYM)
+
+ if (shdr.sh_type == SHT_DYNSYM)
address_offset -= mapping_start;
- for (cnt = 0; cnt < nsyms; ++cnt) {
- GElf_Sym sym_mem;
- Elf32_Word xndx;
- GElf_Sym *sym = gelf_getsymshndx(sdata, NULL, cnt, &sym_mem, &xndx);
- if (sym != NULL && sym->st_shndx != SHN_UNDEF) {
- if (sym->st_value <= address_offset && address_offset < sym->st_value + sym->st_size) {
+
+ for (unsigned int cnt = 0; cnt < nsyms; ++cnt) {
+ Elf64_Sym sym;
+ if (teu_getsym(elf, &shdr, cnt, data, &sym) && sym.st_shndx != SHN_UNDEF) {
+ if (sym.st_value <= address_offset && address_offset < sym.st_value + sym.st_size) {
free(proc_info->name);
- proc_info->name = strdup(elf_strptr(elf, shdr->sh_link, sym->st_name));
- proc_info->offset = address_offset - sym->st_value;
+ proc_info->name = strdup(teu_strptr(elf, shdr.sh_link, sym.st_name));
+ proc_info->offset = address_offset - sym.st_value;
found = 1;
break;
}
@@ -184,7 +188,8 @@ static void __find_symbol_in_elf(ProcInfo *proc_info, Dwarf_Addr mapping_start)
}
}
- elf_end(elf);
+ teu_close(elf);
+ free(elf);
close(fd);
}