1da0c48c4Sopenharmony_ci/* Test program for extracting ELF Note headers and getting whole notes. 2da0c48c4Sopenharmony_ci Copyright (C) 2019 Red Hat, Inc. 3da0c48c4Sopenharmony_ci This file is part of elfutils. 4da0c48c4Sopenharmony_ci 5da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 6da0c48c4Sopenharmony_ci it under the terms of the GNU General Public License as published by 7da0c48c4Sopenharmony_ci the Free Software Foundation; either version 3 of the License, or 8da0c48c4Sopenharmony_ci (at your option) any later version. 9da0c48c4Sopenharmony_ci 10da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 11da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13da0c48c4Sopenharmony_ci GNU General Public License for more details. 14da0c48c4Sopenharmony_ci 15da0c48c4Sopenharmony_ci You should have received a copy of the GNU General Public License 16da0c48c4Sopenharmony_ci along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17da0c48c4Sopenharmony_ci 18da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 19da0c48c4Sopenharmony_ci# include <config.h> 20da0c48c4Sopenharmony_ci#endif 21da0c48c4Sopenharmony_ci 22da0c48c4Sopenharmony_ci#include <errno.h> 23da0c48c4Sopenharmony_ci#include <fcntl.h> 24da0c48c4Sopenharmony_ci#include <inttypes.h> 25da0c48c4Sopenharmony_ci#include <stdio.h> 26da0c48c4Sopenharmony_ci#include <stdlib.h> 27da0c48c4Sopenharmony_ci#include <string.h> 28da0c48c4Sopenharmony_ci#include <unistd.h> 29da0c48c4Sopenharmony_ci 30da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(elf) 31da0c48c4Sopenharmony_ci#include <gelf.h> 32da0c48c4Sopenharmony_ci 33da0c48c4Sopenharmony_ciint 34da0c48c4Sopenharmony_cimain (int argc, char *argv[]) 35da0c48c4Sopenharmony_ci{ 36da0c48c4Sopenharmony_ci if (argc != 2) 37da0c48c4Sopenharmony_ci { 38da0c48c4Sopenharmony_ci printf ("No ELF file given as argument\n"); 39da0c48c4Sopenharmony_ci exit (1); 40da0c48c4Sopenharmony_ci } 41da0c48c4Sopenharmony_ci 42da0c48c4Sopenharmony_ci const char *fname = argv[1]; 43da0c48c4Sopenharmony_ci 44da0c48c4Sopenharmony_ci // Initialize libelf. 45da0c48c4Sopenharmony_ci elf_version (EV_CURRENT); 46da0c48c4Sopenharmony_ci 47da0c48c4Sopenharmony_ci /* Read the ELF from disk now. */ 48da0c48c4Sopenharmony_ci int fd = open (fname, O_RDONLY); 49da0c48c4Sopenharmony_ci if (fd == -1) 50da0c48c4Sopenharmony_ci { 51da0c48c4Sopenharmony_ci printf ("cannot open '%s': %s\n", fname, strerror (errno)); 52da0c48c4Sopenharmony_ci exit (1); 53da0c48c4Sopenharmony_ci } 54da0c48c4Sopenharmony_ci 55da0c48c4Sopenharmony_ci Elf *elf = elf_begin (fd, ELF_C_READ, NULL); 56da0c48c4Sopenharmony_ci if (elf == NULL) 57da0c48c4Sopenharmony_ci { 58da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 59da0c48c4Sopenharmony_ci exit (1); 60da0c48c4Sopenharmony_ci } 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ci GElf_Ehdr ehdr; 63da0c48c4Sopenharmony_ci if (gelf_getehdr (elf, &ehdr) == NULL) 64da0c48c4Sopenharmony_ci { 65da0c48c4Sopenharmony_ci printf ("cannot get Ehdr: %s\n", elf_errmsg (-1)); 66da0c48c4Sopenharmony_ci exit (1); 67da0c48c4Sopenharmony_ci } 68da0c48c4Sopenharmony_ci 69da0c48c4Sopenharmony_ci /* Search for all SHT_NOTE sections. */ 70da0c48c4Sopenharmony_ci Elf_Scn *scn = NULL; 71da0c48c4Sopenharmony_ci while ((scn = elf_nextscn (elf, scn)) != NULL) 72da0c48c4Sopenharmony_ci { 73da0c48c4Sopenharmony_ci /* Get the header. */ 74da0c48c4Sopenharmony_ci GElf_Shdr shdr; 75da0c48c4Sopenharmony_ci if (gelf_getshdr (scn, &shdr) == NULL) 76da0c48c4Sopenharmony_ci { 77da0c48c4Sopenharmony_ci printf ("couldn't get shdr: %s\n", elf_errmsg (-1)); 78da0c48c4Sopenharmony_ci exit (1); 79da0c48c4Sopenharmony_ci } 80da0c48c4Sopenharmony_ci 81da0c48c4Sopenharmony_ci if (shdr.sh_type == SHT_NOTE) 82da0c48c4Sopenharmony_ci { 83da0c48c4Sopenharmony_ci printf ("Notes in section %zd:\n", elf_ndxscn (scn)); 84da0c48c4Sopenharmony_ci 85da0c48c4Sopenharmony_ci Elf_Data *raw = elf_rawdata (scn, NULL); 86da0c48c4Sopenharmony_ci if (raw == NULL) 87da0c48c4Sopenharmony_ci { 88da0c48c4Sopenharmony_ci printf ("couldn't get raw data: %s\n", elf_errmsg (-1)); 89da0c48c4Sopenharmony_ci exit (1); 90da0c48c4Sopenharmony_ci } 91da0c48c4Sopenharmony_ci 92da0c48c4Sopenharmony_ci Elf_Data *data = elf_getdata (scn, NULL); 93da0c48c4Sopenharmony_ci if (data == NULL) 94da0c48c4Sopenharmony_ci { 95da0c48c4Sopenharmony_ci printf ("couldn't get data: %s\n", elf_errmsg (-1)); 96da0c48c4Sopenharmony_ci exit (1); 97da0c48c4Sopenharmony_ci } 98da0c48c4Sopenharmony_ci 99da0c48c4Sopenharmony_ci size_t off = 0; 100da0c48c4Sopenharmony_ci size_t next; 101da0c48c4Sopenharmony_ci GElf_Nhdr nhdr; 102da0c48c4Sopenharmony_ci size_t n_off; 103da0c48c4Sopenharmony_ci size_t d_off; 104da0c48c4Sopenharmony_ci while ((next = gelf_getnote (data, off, &nhdr, &n_off, &d_off)) > 0) 105da0c48c4Sopenharmony_ci { 106da0c48c4Sopenharmony_ci /* Now just get the note header "raw" (don't 107da0c48c4Sopenharmony_ci copy/translate the note data). This only handles 108da0c48c4Sopenharmony_ci traditional GNU ELF Notes, so we still use the next 109da0c48c4Sopenharmony_ci from gelf_getnote (padding is different for new style 110da0c48c4Sopenharmony_ci ELF_T_NHDR8 notes). */ 111da0c48c4Sopenharmony_ci Elf32_Nhdr nh; 112da0c48c4Sopenharmony_ci Elf_Data src = 113da0c48c4Sopenharmony_ci { 114da0c48c4Sopenharmony_ci .d_version = EV_CURRENT, .d_type = ELF_T_NHDR, 115da0c48c4Sopenharmony_ci .d_size = sizeof nh 116da0c48c4Sopenharmony_ci }; 117da0c48c4Sopenharmony_ci Elf_Data dst = src; 118da0c48c4Sopenharmony_ci src.d_buf = raw->d_buf + off; 119da0c48c4Sopenharmony_ci dst.d_buf = &nh; 120da0c48c4Sopenharmony_ci 121da0c48c4Sopenharmony_ci if (elf32_xlatetom (&dst, &src, ehdr.e_ident[EI_DATA]) == NULL) 122da0c48c4Sopenharmony_ci { 123da0c48c4Sopenharmony_ci printf ("couldn't xlate note: %s\n", elf_errmsg (-1)); 124da0c48c4Sopenharmony_ci exit (1); 125da0c48c4Sopenharmony_ci } 126da0c48c4Sopenharmony_ci 127da0c48c4Sopenharmony_ci printf ("type: %" PRId32 ",%" PRId32 128da0c48c4Sopenharmony_ci ", namesz: %" PRId32 ",%" PRId32 129da0c48c4Sopenharmony_ci ", descsz: %" PRId32 ",%" PRId32 "\n", 130da0c48c4Sopenharmony_ci nhdr.n_type, nh.n_type, 131da0c48c4Sopenharmony_ci nhdr.n_namesz, nh.n_namesz, 132da0c48c4Sopenharmony_ci nhdr.n_descsz, nh.n_descsz); 133da0c48c4Sopenharmony_ci 134da0c48c4Sopenharmony_ci if (nhdr.n_type != nh.n_type 135da0c48c4Sopenharmony_ci || nhdr.n_namesz != nh.n_namesz 136da0c48c4Sopenharmony_ci || nhdr.n_descsz != nh.n_descsz) 137da0c48c4Sopenharmony_ci { 138da0c48c4Sopenharmony_ci printf ("Nhdrs not equal!\n"); 139da0c48c4Sopenharmony_ci exit (1); 140da0c48c4Sopenharmony_ci } 141da0c48c4Sopenharmony_ci 142da0c48c4Sopenharmony_ci off = next; 143da0c48c4Sopenharmony_ci } 144da0c48c4Sopenharmony_ci } 145da0c48c4Sopenharmony_ci 146da0c48c4Sopenharmony_ci } 147da0c48c4Sopenharmony_ci 148da0c48c4Sopenharmony_ci if (elf_end (elf) != 0) 149da0c48c4Sopenharmony_ci { 150da0c48c4Sopenharmony_ci printf ("failure in elf_end: %s\n", elf_errmsg (-1)); 151da0c48c4Sopenharmony_ci exit (1); 152da0c48c4Sopenharmony_ci } 153da0c48c4Sopenharmony_ci 154da0c48c4Sopenharmony_ci close (fd); 155da0c48c4Sopenharmony_ci 156da0c48c4Sopenharmony_ci return 0; 157da0c48c4Sopenharmony_ci} 158