1da0c48c4Sopenharmony_ci/* Test program for adding section and program headers and ehdr updates. 2da0c48c4Sopenharmony_ci Copyright (C) 2015 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#include <config.h> 19da0c48c4Sopenharmony_ci#include <assert.h> 20da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(elf) 21da0c48c4Sopenharmony_ci#include <gelf.h> 22da0c48c4Sopenharmony_ci 23da0c48c4Sopenharmony_ci#include <stdio.h> 24da0c48c4Sopenharmony_ci#include <stdlib.h> 25da0c48c4Sopenharmony_ci 26da0c48c4Sopenharmony_ci#include <sys/types.h> 27da0c48c4Sopenharmony_ci#include <sys/stat.h> 28da0c48c4Sopenharmony_ci#include <fcntl.h> 29da0c48c4Sopenharmony_ci#include <unistd.h> 30da0c48c4Sopenharmony_ci 31da0c48c4Sopenharmony_ci#include <stdbool.h> 32da0c48c4Sopenharmony_ci 33da0c48c4Sopenharmony_civoid 34da0c48c4Sopenharmony_cicheck (const char *msg, bool statement) 35da0c48c4Sopenharmony_ci{ 36da0c48c4Sopenharmony_ci if (! statement) 37da0c48c4Sopenharmony_ci { 38da0c48c4Sopenharmony_ci fprintf (stderr, "%s FAILED\n", msg); 39da0c48c4Sopenharmony_ci exit (-1); 40da0c48c4Sopenharmony_ci } 41da0c48c4Sopenharmony_ci else 42da0c48c4Sopenharmony_ci fprintf (stderr, "%s OK\n", msg); 43da0c48c4Sopenharmony_ci} 44da0c48c4Sopenharmony_ci 45da0c48c4Sopenharmony_civoid 46da0c48c4Sopenharmony_cicheck_elf (const char *msg, bool statement) 47da0c48c4Sopenharmony_ci{ 48da0c48c4Sopenharmony_ci if (! statement) 49da0c48c4Sopenharmony_ci { 50da0c48c4Sopenharmony_ci fprintf (stderr, "%s: %s\n", msg, elf_errmsg (-1)); 51da0c48c4Sopenharmony_ci exit (-1); 52da0c48c4Sopenharmony_ci } 53da0c48c4Sopenharmony_ci else 54da0c48c4Sopenharmony_ci fprintf (stderr, "%s OK\n", msg); 55da0c48c4Sopenharmony_ci} 56da0c48c4Sopenharmony_ci 57da0c48c4Sopenharmony_civoid 58da0c48c4Sopenharmony_citest (Elf *elf, int class, bool layout) 59da0c48c4Sopenharmony_ci{ 60da0c48c4Sopenharmony_ci fprintf (stderr, "testing ELF class: %d, layout: %d\n", class, layout); 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ci check_elf ("gelf_newehdr", gelf_newehdr (elf, class) != 0); 63da0c48c4Sopenharmony_ci check_elf ("gelf_getclass", gelf_getclass (elf) == class); 64da0c48c4Sopenharmony_ci 65da0c48c4Sopenharmony_ci check_elf ("elf_flagelf", elf_flagelf (elf, layout ? ELF_C_SET : ELF_C_CLR, 66da0c48c4Sopenharmony_ci ELF_F_LAYOUT) != 0); 67da0c48c4Sopenharmony_ci 68da0c48c4Sopenharmony_ci GElf_Ehdr ehdr; 69da0c48c4Sopenharmony_ci check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL); 70da0c48c4Sopenharmony_ci check ("e_shnum == 0", ehdr.e_shnum == 0); 71da0c48c4Sopenharmony_ci check ("e_phnum == 0", ehdr.e_phnum == 0); 72da0c48c4Sopenharmony_ci check ("e_shoff == 0", ehdr.e_shoff == 0); 73da0c48c4Sopenharmony_ci check ("e_phoff == 0", ehdr.e_phoff == 0); 74da0c48c4Sopenharmony_ci 75da0c48c4Sopenharmony_ci size_t shnum; 76da0c48c4Sopenharmony_ci check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0); 77da0c48c4Sopenharmony_ci check ("shnum == 0", shnum == 0); 78da0c48c4Sopenharmony_ci 79da0c48c4Sopenharmony_ci size_t phnum; 80da0c48c4Sopenharmony_ci check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0); 81da0c48c4Sopenharmony_ci check ("phnum == 0", phnum == 0); 82da0c48c4Sopenharmony_ci 83da0c48c4Sopenharmony_ci /* Lets fill in some info we are always responsible for. */ 84da0c48c4Sopenharmony_ci ehdr.e_ident[EI_DATA] = ELFDATANONE; /* Ask for native encoding. */ 85da0c48c4Sopenharmony_ci ehdr.e_type = ET_EXEC; 86da0c48c4Sopenharmony_ci ehdr.e_machine = EM_386; 87da0c48c4Sopenharmony_ci ehdr.e_version = EV_NONE; /* Ask for current version. */ 88da0c48c4Sopenharmony_ci check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0); 89da0c48c4Sopenharmony_ci 90da0c48c4Sopenharmony_ci check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0); 91da0c48c4Sopenharmony_ci 92da0c48c4Sopenharmony_ci check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL); 93da0c48c4Sopenharmony_ci check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE); 94da0c48c4Sopenharmony_ci check ("e_version", ehdr.e_version == EV_CURRENT); 95da0c48c4Sopenharmony_ci 96da0c48c4Sopenharmony_ci /* The sh/ph values shouldn't have changed. */ 97da0c48c4Sopenharmony_ci check ("e_shnum == 0", ehdr.e_shnum == 0); 98da0c48c4Sopenharmony_ci check ("e_phnum == 0", ehdr.e_phnum == 0); 99da0c48c4Sopenharmony_ci check ("e_shoff == 0", ehdr.e_shoff == 0); 100da0c48c4Sopenharmony_ci check ("e_phoff == 0", ehdr.e_phoff == 0); 101da0c48c4Sopenharmony_ci 102da0c48c4Sopenharmony_ci check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0); 103da0c48c4Sopenharmony_ci check ("shnum == 0", shnum == 0); 104da0c48c4Sopenharmony_ci 105da0c48c4Sopenharmony_ci check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0); 106da0c48c4Sopenharmony_ci check ("phnum == 0", phnum == 0); 107da0c48c4Sopenharmony_ci 108da0c48c4Sopenharmony_ci /* Lets add a header. */ 109da0c48c4Sopenharmony_ci check_elf ("elf_newscn", elf_newscn (elf) != NULL); 110da0c48c4Sopenharmony_ci check_elf ("gelf_newphdr", gelf_newphdr (elf, 1) != 0); 111da0c48c4Sopenharmony_ci 112da0c48c4Sopenharmony_ci /* If we are responsible for the layout ourselves we should also 113da0c48c4Sopenharmony_ci tell where to put them. */ 114da0c48c4Sopenharmony_ci if (layout) 115da0c48c4Sopenharmony_ci { 116da0c48c4Sopenharmony_ci check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL); 117da0c48c4Sopenharmony_ci /* phdrs go right after the ehdr. */ 118da0c48c4Sopenharmony_ci ehdr.e_phoff = ehdr.e_ehsize; 119da0c48c4Sopenharmony_ci /* shdrs go right after the phdrs. */ 120da0c48c4Sopenharmony_ci ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize; 121da0c48c4Sopenharmony_ci check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0); 122da0c48c4Sopenharmony_ci } 123da0c48c4Sopenharmony_ci 124da0c48c4Sopenharmony_ci check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0); 125da0c48c4Sopenharmony_ci 126da0c48c4Sopenharmony_ci check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0); 127da0c48c4Sopenharmony_ci check ("shnum == 1", shnum == 2); /* section zero is also created. */ 128da0c48c4Sopenharmony_ci 129da0c48c4Sopenharmony_ci check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0); 130da0c48c4Sopenharmony_ci check ("phnum == 1", phnum == 1); 131da0c48c4Sopenharmony_ci 132da0c48c4Sopenharmony_ci check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL); 133da0c48c4Sopenharmony_ci 134da0c48c4Sopenharmony_ci check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE); 135da0c48c4Sopenharmony_ci check ("e_version", ehdr.e_version == EV_CURRENT); 136da0c48c4Sopenharmony_ci 137da0c48c4Sopenharmony_ci check ("e_shnum == 2", ehdr.e_shnum == 2); 138da0c48c4Sopenharmony_ci check ("e_phnum == 1", ehdr.e_phnum == 1); 139da0c48c4Sopenharmony_ci check ("e_shoff != 0", ehdr.e_shoff != 0); 140da0c48c4Sopenharmony_ci check ("e_phoff != 0", ehdr.e_phoff != 0); 141da0c48c4Sopenharmony_ci 142da0c48c4Sopenharmony_ci size_t shentsize = (class == ELFCLASS32 143da0c48c4Sopenharmony_ci ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr)); 144da0c48c4Sopenharmony_ci check ("e_shentsize", ehdr.e_shentsize == shentsize); 145da0c48c4Sopenharmony_ci size_t phentsize = (class == ELFCLASS32 146da0c48c4Sopenharmony_ci ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr)); 147da0c48c4Sopenharmony_ci check ("e_phentsize", ehdr.e_phentsize == phentsize); 148da0c48c4Sopenharmony_ci} 149da0c48c4Sopenharmony_ci 150da0c48c4Sopenharmony_ciint 151da0c48c4Sopenharmony_cimain (int argc __attribute__ ((unused)), char **argv __attribute ((unused))) 152da0c48c4Sopenharmony_ci{ 153da0c48c4Sopenharmony_ci elf_version (EV_CURRENT); 154da0c48c4Sopenharmony_ci 155da0c48c4Sopenharmony_ci int fd = open("/dev/null", O_WRONLY); 156da0c48c4Sopenharmony_ci check ("open", fd >= 0); 157da0c48c4Sopenharmony_ci 158da0c48c4Sopenharmony_ci Elf *elf; 159da0c48c4Sopenharmony_ci 160da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_WRITE, NULL); 161da0c48c4Sopenharmony_ci check_elf ("elf_begin", elf != NULL); 162da0c48c4Sopenharmony_ci test (elf, ELFCLASS32, false); 163da0c48c4Sopenharmony_ci elf_end (elf); 164da0c48c4Sopenharmony_ci 165da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_WRITE, NULL); 166da0c48c4Sopenharmony_ci check_elf ("elf_begin", elf != NULL); 167da0c48c4Sopenharmony_ci test (elf, ELFCLASS32, true); 168da0c48c4Sopenharmony_ci elf_end (elf); 169da0c48c4Sopenharmony_ci 170da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_WRITE, NULL); 171da0c48c4Sopenharmony_ci check_elf ("elf_begin", elf != NULL); 172da0c48c4Sopenharmony_ci test (elf, ELFCLASS64, false); 173da0c48c4Sopenharmony_ci elf_end (elf); 174da0c48c4Sopenharmony_ci 175da0c48c4Sopenharmony_ci elf = elf_begin (fd, ELF_C_WRITE, NULL); 176da0c48c4Sopenharmony_ci check_elf ("elf_begin", elf != NULL); 177da0c48c4Sopenharmony_ci test (elf, ELFCLASS64, true); 178da0c48c4Sopenharmony_ci elf_end (elf); 179da0c48c4Sopenharmony_ci 180da0c48c4Sopenharmony_ci close (fd); 181da0c48c4Sopenharmony_ci return 0; 182da0c48c4Sopenharmony_ci} 183