/* * @licence app begin@ * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. * @licence end@ */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_coredump.c */ #include #include #include #include #include #include #include #include #include #include "dlt_cdh.h" cdh_status_t read_elf_headers(proc_info_t *p_proc) { int phnum = 0; /* Read ELF header */ stream_read(&p_proc->streamer, &p_proc->m_Ehdr, sizeof(p_proc->m_Ehdr)); /* Read until PROG position */ stream_move_to_offest(&p_proc->streamer, p_proc->m_Ehdr.e_phoff); /* Read and store all program headers */ p_proc->m_pPhdr = (ELF_Phdr *)malloc(sizeof(ELF_Phdr) * p_proc->m_Ehdr.e_phnum); if (p_proc->m_pPhdr == NULL) { syslog(LOG_ERR, "Cannot allocate Phdr memory (%d headers)", p_proc->m_Ehdr.e_phnum); return CDH_NOK; } for (phnum = 0; phnum < p_proc->m_Ehdr.e_phnum; phnum++) /* Read Programm header */ stream_read(&p_proc->streamer, &p_proc->m_pPhdr[phnum], sizeof(ELF_Phdr)); return CDH_OK; } int getNotePageIndex(proc_info_t *p_proc) { int i = 0; /* Search PT_NOTE section */ for (i = 0; i < p_proc->m_Ehdr.e_phnum; i++) { syslog(LOG_INFO, "==Note section prog_note:%d type:0x%X offset:0x%X size:0x%X (%dbytes)", i, p_proc->m_pPhdr[i].p_type, p_proc->m_pPhdr[i].p_offset, p_proc->m_pPhdr[i].p_filesz, p_proc->m_pPhdr[i].p_filesz); if (p_proc->m_pPhdr[i].p_type == PT_NOTE) break; } return i == p_proc->m_Ehdr.e_phnum ? CDH_NOK : i; } cdh_status_t read_notes(proc_info_t *p_proc) { int prog_note = getNotePageIndex(p_proc); /* p_proc->m_note_page_size = 0; */ p_proc->m_Nhdr = NULL; /* note page not found, abort */ if (prog_note < 0) { syslog(LOG_ERR, "Cannot find note header page index"); return CDH_NOK; } /* Move to NOTE header position */ if (stream_move_to_offest(&p_proc->streamer, p_proc->m_pPhdr[prog_note].p_offset) != CDH_OK) { syslog(LOG_ERR, "Cannot move to note header"); return CDH_NOK; } if ((p_proc->m_Nhdr = (char *)malloc(p_proc->m_pPhdr[prog_note].p_filesz)) == NULL) { syslog(LOG_ERR, "Cannot allocate Nhdr memory (note size %d bytes)", p_proc->m_pPhdr[prog_note].p_filesz); return CDH_NOK; } if (stream_read(&p_proc->streamer, p_proc->m_Nhdr, p_proc->m_pPhdr[prog_note].p_filesz) != CDH_OK) { syslog(LOG_ERR, "Cannot read note header"); return CDH_NOK; } p_proc->m_note_page_size = p_proc->m_pPhdr[prog_note].p_filesz; return CDH_OK; } cdh_status_t init_coredump(proc_info_t *p_proc) { if (p_proc == NULL) return CDH_NOK; if (p_proc->can_create_coredump) { char l_dst_filename[CORE_MAX_FILENAME_LENGTH]; snprintf(l_dst_filename, sizeof(l_dst_filename), CORE_FILE_PATTERN, CORE_TMP_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); stream_init(&p_proc->streamer, 0, l_dst_filename); } else { stream_init(&p_proc->streamer, 0, NULL); } return CDH_OK; } cdh_status_t close_coredump(proc_info_t *p_proc) { stream_close(&p_proc->streamer); return CDH_OK; } cdh_status_t treat_coredump(proc_info_t *p_proc) { cdh_status_t ret = CDH_OK; /* open src and dest files, allocate read buffer */ if (init_coredump(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot init coredump system"); ret = CDH_NOK; goto finished; } if (read_elf_headers(p_proc) == CDH_OK) { /* TODO: No NOTES here leads to crash elsewhere!!! dlt_cdh_crashid.c: around line 76 */ if (read_notes(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot read NOTES"); ret = CDH_NOK; goto finished; } } else if (read_elf_headers(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot read ELF header"); ret = CDH_NOK; goto finished; } finished: /* In all cases, we try to finish to read/compress the coredump until the end */ if (stream_finish(&p_proc->streamer) != CDH_OK) syslog(LOG_ERR, "cannot finish coredump compression"); /* In all cases, let's close the files */ if (close_coredump(p_proc) != CDH_OK) syslog(LOG_ERR, "cannot close coredump system"); return ret; }