1da0c48c4Sopenharmony_ci/* Test program for changing data in one section (but not others) with gaps. 2da0c48c4Sopenharmony_ci Copyright (C) 2017 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 19da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 20da0c48c4Sopenharmony_ci# include <config.h> 21da0c48c4Sopenharmony_ci#endif 22da0c48c4Sopenharmony_ci 23da0c48c4Sopenharmony_ci#include <errno.h> 24da0c48c4Sopenharmony_ci#include <fcntl.h> 25da0c48c4Sopenharmony_ci#include <inttypes.h> 26da0c48c4Sopenharmony_ci#include <stdio.h> 27da0c48c4Sopenharmony_ci#include <stdlib.h> 28da0c48c4Sopenharmony_ci#include <string.h> 29da0c48c4Sopenharmony_ci#include <unistd.h> 30da0c48c4Sopenharmony_ci#include "system.h" 31da0c48c4Sopenharmony_ci 32da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(elf) 33da0c48c4Sopenharmony_ci#include <gelf.h> 34da0c48c4Sopenharmony_ci 35da0c48c4Sopenharmony_ci 36da0c48c4Sopenharmony_ci/* Index of last string added. Returned by add_string (). */ 37da0c48c4Sopenharmony_cistatic size_t stridx = 0; 38da0c48c4Sopenharmony_ci 39da0c48c4Sopenharmony_ci/* Adds a string and returns the offset in the section. */ 40da0c48c4Sopenharmony_cistatic size_t 41da0c48c4Sopenharmony_ciadd_strtab_entry (Elf_Scn *strtab, const char *str) 42da0c48c4Sopenharmony_ci{ 43da0c48c4Sopenharmony_ci size_t lastidx = stridx; 44da0c48c4Sopenharmony_ci size_t size = strlen (str) + 1; 45da0c48c4Sopenharmony_ci 46da0c48c4Sopenharmony_ci Elf_Data *data = elf_newdata (strtab); 47da0c48c4Sopenharmony_ci if (data == NULL) 48da0c48c4Sopenharmony_ci { 49da0c48c4Sopenharmony_ci printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1)); 50da0c48c4Sopenharmony_ci exit (1); 51da0c48c4Sopenharmony_ci } 52da0c48c4Sopenharmony_ci 53da0c48c4Sopenharmony_ci data->d_buf = (char *) str; /* Discards const, but we will not change. */ 54da0c48c4Sopenharmony_ci data->d_type = ELF_T_BYTE; 55da0c48c4Sopenharmony_ci data->d_size = size; 56da0c48c4Sopenharmony_ci data->d_align = 1; 57da0c48c4Sopenharmony_ci data->d_version = EV_CURRENT; 58da0c48c4Sopenharmony_ci 59da0c48c4Sopenharmony_ci stridx += size; 60da0c48c4Sopenharmony_ci printf ("add_string: '%s', stridx: %zd, lastidx: %zd\n", 61da0c48c4Sopenharmony_ci str, stridx, lastidx); 62da0c48c4Sopenharmony_ci return lastidx; 63da0c48c4Sopenharmony_ci} 64da0c48c4Sopenharmony_ci 65da0c48c4Sopenharmony_cistatic Elf_Scn * 66da0c48c4Sopenharmony_cicreate_strtab (Elf *elf) 67da0c48c4Sopenharmony_ci{ 68da0c48c4Sopenharmony_ci // Create strtab section. 69da0c48c4Sopenharmony_ci Elf_Scn *scn = elf_newscn (elf); 70da0c48c4Sopenharmony_ci if (scn == NULL) 71da0c48c4Sopenharmony_ci { 72da0c48c4Sopenharmony_ci printf ("cannot create strings section: %s\n", elf_errmsg (-1)); 73da0c48c4Sopenharmony_ci exit (1); 74da0c48c4Sopenharmony_ci } 75da0c48c4Sopenharmony_ci 76da0c48c4Sopenharmony_ci // Add an empty string to the table as NUL entry for section zero. 77da0c48c4Sopenharmony_ci add_strtab_entry (scn, ""); 78da0c48c4Sopenharmony_ci 79da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 80da0c48c4Sopenharmony_ci GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 81da0c48c4Sopenharmony_ci if (shdr == NULL) 82da0c48c4Sopenharmony_ci { 83da0c48c4Sopenharmony_ci printf ("cannot get header for new strtab section: %s\n", 84da0c48c4Sopenharmony_ci elf_errmsg (-1)); 85da0c48c4Sopenharmony_ci exit (1); 86da0c48c4Sopenharmony_ci } 87da0c48c4Sopenharmony_ci 88da0c48c4Sopenharmony_ci shdr->sh_type = SHT_STRTAB; 89da0c48c4Sopenharmony_ci shdr->sh_flags = 0; 90da0c48c4Sopenharmony_ci shdr->sh_addr = 0; 91da0c48c4Sopenharmony_ci shdr->sh_link = SHN_UNDEF; 92da0c48c4Sopenharmony_ci shdr->sh_info = SHN_UNDEF; 93da0c48c4Sopenharmony_ci shdr->sh_addralign = 1; 94da0c48c4Sopenharmony_ci shdr->sh_entsize = 0; 95da0c48c4Sopenharmony_ci shdr->sh_name = add_strtab_entry (scn, ".strtab"); 96da0c48c4Sopenharmony_ci 97da0c48c4Sopenharmony_ci // We have to store the section strtab index in the ELF header. 98da0c48c4Sopenharmony_ci // So sections have actual names. 99da0c48c4Sopenharmony_ci GElf_Ehdr ehdr_mem; 100da0c48c4Sopenharmony_ci GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 101da0c48c4Sopenharmony_ci if (ehdr == NULL) 102da0c48c4Sopenharmony_ci { 103da0c48c4Sopenharmony_ci printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 104da0c48c4Sopenharmony_ci exit (1); 105da0c48c4Sopenharmony_ci } 106da0c48c4Sopenharmony_ci 107da0c48c4Sopenharmony_ci int ndx = elf_ndxscn (scn); 108da0c48c4Sopenharmony_ci ehdr->e_shstrndx = ndx; 109da0c48c4Sopenharmony_ci 110da0c48c4Sopenharmony_ci if (gelf_update_ehdr (elf, ehdr) == 0) 111da0c48c4Sopenharmony_ci { 112da0c48c4Sopenharmony_ci printf ("cannot update ELF header: %s\n", elf_errmsg (-1)); 113da0c48c4Sopenharmony_ci exit (1); 114da0c48c4Sopenharmony_ci } 115da0c48c4Sopenharmony_ci 116da0c48c4Sopenharmony_ci // Finished strtab section, update the header. 117da0c48c4Sopenharmony_ci if (gelf_update_shdr (scn, shdr) == 0) 118da0c48c4Sopenharmony_ci { 119da0c48c4Sopenharmony_ci printf ("cannot update STRTAB section header: %s\n", elf_errmsg (-1)); 120da0c48c4Sopenharmony_ci exit (1); 121da0c48c4Sopenharmony_ci } 122da0c48c4Sopenharmony_ci 123da0c48c4Sopenharmony_ci return scn; 124da0c48c4Sopenharmony_ci} 125da0c48c4Sopenharmony_ci 126da0c48c4Sopenharmony_cistatic char sec_data[] = { 1, 2, 3, 4, 5 }; 127da0c48c4Sopenharmony_cistatic char new_data[] = { 5, 4, 3, 2, 1 }; 128da0c48c4Sopenharmony_ci 129da0c48c4Sopenharmony_cistatic void 130da0c48c4Sopenharmony_ciadd_data_section (Elf *elf, Elf_Scn *strtab, const char *sname) 131da0c48c4Sopenharmony_ci{ 132da0c48c4Sopenharmony_ci printf ("Add data section %s\n", sname); 133da0c48c4Sopenharmony_ci Elf_Scn *scn = elf_newscn (elf); 134da0c48c4Sopenharmony_ci if (scn == NULL) 135da0c48c4Sopenharmony_ci { 136da0c48c4Sopenharmony_ci printf ("cannot create strings section: %s\n", elf_errmsg (-1)); 137da0c48c4Sopenharmony_ci exit (1); 138da0c48c4Sopenharmony_ci } 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 141da0c48c4Sopenharmony_ci GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 142da0c48c4Sopenharmony_ci if (shdr == NULL) 143da0c48c4Sopenharmony_ci { 144da0c48c4Sopenharmony_ci printf ("cannot get header for new %s section: %s\n", 145da0c48c4Sopenharmony_ci sname, elf_errmsg (-1)); 146da0c48c4Sopenharmony_ci exit (1); 147da0c48c4Sopenharmony_ci } 148da0c48c4Sopenharmony_ci 149da0c48c4Sopenharmony_ci shdr->sh_type = SHT_PROGBITS; 150da0c48c4Sopenharmony_ci shdr->sh_flags = 0; 151da0c48c4Sopenharmony_ci shdr->sh_addr = 0; 152da0c48c4Sopenharmony_ci shdr->sh_link = SHN_UNDEF; 153da0c48c4Sopenharmony_ci shdr->sh_info = SHN_UNDEF; 154da0c48c4Sopenharmony_ci shdr->sh_addralign = 128; // Large alignment to force gap between sections. 155da0c48c4Sopenharmony_ci shdr->sh_entsize = 1; 156da0c48c4Sopenharmony_ci shdr->sh_name = add_strtab_entry (strtab, sname); 157da0c48c4Sopenharmony_ci 158da0c48c4Sopenharmony_ci if (gelf_update_shdr (scn, shdr) == 0) 159da0c48c4Sopenharmony_ci { 160da0c48c4Sopenharmony_ci printf ("cannot update %s section header: %s\n", sname, elf_errmsg (-1)); 161da0c48c4Sopenharmony_ci exit (1); 162da0c48c4Sopenharmony_ci } 163da0c48c4Sopenharmony_ci 164da0c48c4Sopenharmony_ci /* Add some data, but less than alignment. */ 165da0c48c4Sopenharmony_ci Elf_Data *data = elf_newdata (scn); 166da0c48c4Sopenharmony_ci if (data == NULL) 167da0c48c4Sopenharmony_ci { 168da0c48c4Sopenharmony_ci printf ("cannot update %s section header: %s\n", sname, elf_errmsg (-1)); 169da0c48c4Sopenharmony_ci exit (1); 170da0c48c4Sopenharmony_ci } 171da0c48c4Sopenharmony_ci data->d_buf = sec_data; 172da0c48c4Sopenharmony_ci data->d_size = 5; 173da0c48c4Sopenharmony_ci} 174da0c48c4Sopenharmony_ci 175da0c48c4Sopenharmony_cistatic void 176da0c48c4Sopenharmony_cicheck_data (const char *sname, Elf_Data *data, char *buf) 177da0c48c4Sopenharmony_ci{ 178da0c48c4Sopenharmony_ci printf ("check data %s [", sname); 179da0c48c4Sopenharmony_ci for (int i = 0; i < 5; i++) 180da0c48c4Sopenharmony_ci printf ("%d%s", buf[i], i < 4 ? "," : ""); 181da0c48c4Sopenharmony_ci printf ("]\n"); 182da0c48c4Sopenharmony_ci if (data == NULL || data->d_buf == NULL) 183da0c48c4Sopenharmony_ci { 184da0c48c4Sopenharmony_ci printf ("No data in section %s\n", sname); 185da0c48c4Sopenharmony_ci exit (1); 186da0c48c4Sopenharmony_ci } 187da0c48c4Sopenharmony_ci 188da0c48c4Sopenharmony_ci if (data->d_size != 5 || memcmp (data->d_buf, buf, 5) != 0) 189da0c48c4Sopenharmony_ci { 190da0c48c4Sopenharmony_ci printf ("Wrong data in section %s [", sname); 191da0c48c4Sopenharmony_ci for (size_t i = 0; i < data->d_size; i++) 192da0c48c4Sopenharmony_ci printf ("%d%s", ((char *)data->d_buf)[i], 193da0c48c4Sopenharmony_ci i < data->d_size - 1 ? "," : ""); 194da0c48c4Sopenharmony_ci printf ("]\n"); 195da0c48c4Sopenharmony_ci exit(1); 196da0c48c4Sopenharmony_ci } 197da0c48c4Sopenharmony_ci} 198da0c48c4Sopenharmony_ci 199da0c48c4Sopenharmony_cistatic void 200da0c48c4Sopenharmony_cicheck_elf (const char *fname, int class, int use_mmap) 201da0c48c4Sopenharmony_ci{ 202da0c48c4Sopenharmony_ci printf ("\nfname: %s\n", fname); 203da0c48c4Sopenharmony_ci stridx = 0; // Reset strtab strings index 204da0c48c4Sopenharmony_ci 205da0c48c4Sopenharmony_ci int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE); 206da0c48c4Sopenharmony_ci if (fd == -1) 207da0c48c4Sopenharmony_ci { 208da0c48c4Sopenharmony_ci printf ("cannot open `%s': %s\n", fname, strerror (errno)); 209da0c48c4Sopenharmony_ci exit (1); 210da0c48c4Sopenharmony_ci } 211da0c48c4Sopenharmony_ci 212da0c48c4Sopenharmony_ci Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL); 213da0c48c4Sopenharmony_ci if (elf == NULL) 214da0c48c4Sopenharmony_ci { 215da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1)); 216da0c48c4Sopenharmony_ci exit (1); 217da0c48c4Sopenharmony_ci } 218da0c48c4Sopenharmony_ci 219da0c48c4Sopenharmony_ci // Create an ELF header. 220da0c48c4Sopenharmony_ci if (gelf_newehdr (elf, class) == 0) 221da0c48c4Sopenharmony_ci { 222da0c48c4Sopenharmony_ci printf ("cannot create ELF header: %s\n", elf_errmsg (-1)); 223da0c48c4Sopenharmony_ci exit (1); 224da0c48c4Sopenharmony_ci } 225da0c48c4Sopenharmony_ci 226da0c48c4Sopenharmony_ci GElf_Ehdr ehdr_mem; 227da0c48c4Sopenharmony_ci GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 228da0c48c4Sopenharmony_ci if (ehdr == NULL) 229da0c48c4Sopenharmony_ci { 230da0c48c4Sopenharmony_ci printf ("cannot get ELF header: %s\n", elf_errmsg (-1)); 231da0c48c4Sopenharmony_ci exit (1); 232da0c48c4Sopenharmony_ci } 233da0c48c4Sopenharmony_ci 234da0c48c4Sopenharmony_ci // Initialize header. 235da0c48c4Sopenharmony_ci ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB; 236da0c48c4Sopenharmony_ci ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU; 237da0c48c4Sopenharmony_ci ehdr->e_type = ET_NONE; 238da0c48c4Sopenharmony_ci ehdr->e_machine = EM_X86_64; 239da0c48c4Sopenharmony_ci ehdr->e_version = EV_CURRENT; 240da0c48c4Sopenharmony_ci 241da0c48c4Sopenharmony_ci if (gelf_update_ehdr (elf, ehdr) == 0) 242da0c48c4Sopenharmony_ci { 243da0c48c4Sopenharmony_ci printf ("cannot update ELF header: %s\n", elf_errmsg (-1)); 244da0c48c4Sopenharmony_ci exit (1); 245da0c48c4Sopenharmony_ci } 246da0c48c4Sopenharmony_ci 247da0c48c4Sopenharmony_ci Elf_Scn *strtab = create_strtab (elf); 248da0c48c4Sopenharmony_ci add_data_section (elf, strtab, ".data1"); 249da0c48c4Sopenharmony_ci add_data_section (elf, strtab, ".data2"); 250da0c48c4Sopenharmony_ci add_data_section (elf, strtab, ".data3"); 251da0c48c4Sopenharmony_ci add_data_section (elf, strtab, ".data4"); 252da0c48c4Sopenharmony_ci 253da0c48c4Sopenharmony_ci // Write everything to disk. 254da0c48c4Sopenharmony_ci if (elf_update (elf, ELF_C_WRITE) < 0) 255da0c48c4Sopenharmony_ci { 256da0c48c4Sopenharmony_ci printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1)); 257da0c48c4Sopenharmony_ci exit (1); 258da0c48c4Sopenharmony_ci } 259da0c48c4Sopenharmony_ci 260da0c48c4Sopenharmony_ci if (elf_end (elf) != 0) 261da0c48c4Sopenharmony_ci { 262da0c48c4Sopenharmony_ci printf ("failure in elf_end: %s\n", elf_errmsg (-1)); 263da0c48c4Sopenharmony_ci exit (1); 264da0c48c4Sopenharmony_ci } 265da0c48c4Sopenharmony_ci 266da0c48c4Sopenharmony_ci close (fd); 267da0c48c4Sopenharmony_ci 268da0c48c4Sopenharmony_ci /* Reread the ELF from disk now. */ 269da0c48c4Sopenharmony_ci printf ("Rereading %s\n", fname); 270da0c48c4Sopenharmony_ci fd = open (fname, O_RDWR); 271da0c48c4Sopenharmony_ci if (fd == -1) 272da0c48c4Sopenharmony_ci { 273da0c48c4Sopenharmony_ci printf ("cannot (re)open `%s': %s\n", fname, strerror (errno)); 274da0c48c4Sopenharmony_ci exit (1); 275da0c48c4Sopenharmony_ci } 276da0c48c4Sopenharmony_ci 277da0c48c4Sopenharmony_ci elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL); 278da0c48c4Sopenharmony_ci if (elf == NULL) 279da0c48c4Sopenharmony_ci { 280da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1)); 281da0c48c4Sopenharmony_ci exit (1); 282da0c48c4Sopenharmony_ci } 283da0c48c4Sopenharmony_ci 284da0c48c4Sopenharmony_ci /* We are going to change some data (in-place), but want the layout 285da0c48c4Sopenharmony_ci to stay exactly the same. */ 286da0c48c4Sopenharmony_ci elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT); 287da0c48c4Sopenharmony_ci 288da0c48c4Sopenharmony_ci size_t shdrstrndx; 289da0c48c4Sopenharmony_ci if (elf_getshdrstrndx (elf, &shdrstrndx) != 0) 290da0c48c4Sopenharmony_ci { 291da0c48c4Sopenharmony_ci printf ("cannot get shdr str ndx\n"); 292da0c48c4Sopenharmony_ci exit (1); 293da0c48c4Sopenharmony_ci } 294da0c48c4Sopenharmony_ci printf ("shdrstrndx: %zd\n", shdrstrndx); 295da0c48c4Sopenharmony_ci 296da0c48c4Sopenharmony_ci // Get third data section and change it. 297da0c48c4Sopenharmony_ci Elf_Scn *checkscn = NULL; 298da0c48c4Sopenharmony_ci Elf_Scn *scn = elf_nextscn (elf, NULL); 299da0c48c4Sopenharmony_ci while (scn != NULL) 300da0c48c4Sopenharmony_ci { 301da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 302da0c48c4Sopenharmony_ci GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 303da0c48c4Sopenharmony_ci if (shdr == NULL) 304da0c48c4Sopenharmony_ci { 305da0c48c4Sopenharmony_ci printf ("cannot get header for section: %s\n", elf_errmsg (-1)); 306da0c48c4Sopenharmony_ci exit (1); 307da0c48c4Sopenharmony_ci } 308da0c48c4Sopenharmony_ci const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name); 309da0c48c4Sopenharmony_ci if (sname != NULL && strcmp (".data3", sname) == 0) 310da0c48c4Sopenharmony_ci checkscn = scn; 311da0c48c4Sopenharmony_ci 312da0c48c4Sopenharmony_ci // Get all data, but don't really use it 313da0c48c4Sopenharmony_ci // (this triggered the original bug). 314da0c48c4Sopenharmony_ci Elf_Data *data = elf_getdata (scn, NULL); 315da0c48c4Sopenharmony_ci if (data != NULL && data->d_buf != NULL && data->d_size == 0) 316da0c48c4Sopenharmony_ci { 317da0c48c4Sopenharmony_ci printf ("Bad data...n"); 318da0c48c4Sopenharmony_ci exit (1); 319da0c48c4Sopenharmony_ci } 320da0c48c4Sopenharmony_ci scn = elf_nextscn (elf, scn); 321da0c48c4Sopenharmony_ci } 322da0c48c4Sopenharmony_ci 323da0c48c4Sopenharmony_ci if (checkscn == NULL) 324da0c48c4Sopenharmony_ci { 325da0c48c4Sopenharmony_ci printf ("ELF file doesn't have a .data3 section\n"); 326da0c48c4Sopenharmony_ci exit (1); 327da0c48c4Sopenharmony_ci } 328da0c48c4Sopenharmony_ci 329da0c48c4Sopenharmony_ci Elf_Data *data = elf_getdata (checkscn, NULL); 330da0c48c4Sopenharmony_ci check_data (".data3", data, sec_data); 331da0c48c4Sopenharmony_ci memcpy (data->d_buf, new_data, 5); 332da0c48c4Sopenharmony_ci elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY); 333da0c48c4Sopenharmony_ci 334da0c48c4Sopenharmony_ci // Write everything to disk. 335da0c48c4Sopenharmony_ci if (elf_update (elf, ELF_C_WRITE) < 0) 336da0c48c4Sopenharmony_ci { 337da0c48c4Sopenharmony_ci printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1)); 338da0c48c4Sopenharmony_ci exit (1); 339da0c48c4Sopenharmony_ci } 340da0c48c4Sopenharmony_ci 341da0c48c4Sopenharmony_ci if (elf_end (elf) != 0) 342da0c48c4Sopenharmony_ci { 343da0c48c4Sopenharmony_ci printf ("failure in elf_end: %s\n", elf_errmsg (-1)); 344da0c48c4Sopenharmony_ci exit (1); 345da0c48c4Sopenharmony_ci } 346da0c48c4Sopenharmony_ci 347da0c48c4Sopenharmony_ci close (fd); 348da0c48c4Sopenharmony_ci 349da0c48c4Sopenharmony_ci // And read it in one last time. 350da0c48c4Sopenharmony_ci printf ("Rereading %s again\n", fname); 351da0c48c4Sopenharmony_ci fd = open (fname, O_RDONLY); 352da0c48c4Sopenharmony_ci if (fd == -1) 353da0c48c4Sopenharmony_ci { 354da0c48c4Sopenharmony_ci printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno)); 355da0c48c4Sopenharmony_ci exit (1); 356da0c48c4Sopenharmony_ci } 357da0c48c4Sopenharmony_ci 358da0c48c4Sopenharmony_ci elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL); 359da0c48c4Sopenharmony_ci if (elf == NULL) 360da0c48c4Sopenharmony_ci { 361da0c48c4Sopenharmony_ci printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1)); 362da0c48c4Sopenharmony_ci exit (1); 363da0c48c4Sopenharmony_ci } 364da0c48c4Sopenharmony_ci 365da0c48c4Sopenharmony_ci // Get all .data sections and check them. 366da0c48c4Sopenharmony_ci Elf_Scn *scn1 = NULL; 367da0c48c4Sopenharmony_ci Elf_Scn *scn2 = NULL; 368da0c48c4Sopenharmony_ci Elf_Scn *scn3 = NULL; 369da0c48c4Sopenharmony_ci Elf_Scn *scn4 = NULL; 370da0c48c4Sopenharmony_ci scn = elf_nextscn (elf, NULL); 371da0c48c4Sopenharmony_ci while (scn != NULL) 372da0c48c4Sopenharmony_ci { 373da0c48c4Sopenharmony_ci GElf_Shdr shdr_mem; 374da0c48c4Sopenharmony_ci GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 375da0c48c4Sopenharmony_ci if (shdr == NULL) 376da0c48c4Sopenharmony_ci { 377da0c48c4Sopenharmony_ci printf ("cannot get header for section: %s\n", elf_errmsg (-1)); 378da0c48c4Sopenharmony_ci exit (1); 379da0c48c4Sopenharmony_ci } 380da0c48c4Sopenharmony_ci const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name); 381da0c48c4Sopenharmony_ci if (sname != NULL && strcmp (".data1", sname) == 0) 382da0c48c4Sopenharmony_ci scn1 = scn; 383da0c48c4Sopenharmony_ci else if (sname != NULL && strcmp (".data2", sname) == 0) 384da0c48c4Sopenharmony_ci scn2 = scn; 385da0c48c4Sopenharmony_ci else if (sname != NULL && strcmp (".data3", sname) == 0) 386da0c48c4Sopenharmony_ci scn3 = scn; 387da0c48c4Sopenharmony_ci else if (sname != NULL && strcmp (".data4", sname) == 0) 388da0c48c4Sopenharmony_ci scn4 = scn; 389da0c48c4Sopenharmony_ci scn = elf_nextscn (elf, scn); 390da0c48c4Sopenharmony_ci } 391da0c48c4Sopenharmony_ci 392da0c48c4Sopenharmony_ci if (scn1 == NULL) 393da0c48c4Sopenharmony_ci { 394da0c48c4Sopenharmony_ci printf ("ELF file doesn't have a .data1 section\n"); 395da0c48c4Sopenharmony_ci exit (1); 396da0c48c4Sopenharmony_ci } 397da0c48c4Sopenharmony_ci data = elf_getdata (scn1, NULL); 398da0c48c4Sopenharmony_ci check_data (".data1", data, sec_data); 399da0c48c4Sopenharmony_ci 400da0c48c4Sopenharmony_ci if (scn2 == NULL) 401da0c48c4Sopenharmony_ci { 402da0c48c4Sopenharmony_ci printf ("ELF file doesn't have a .data2 section\n"); 403da0c48c4Sopenharmony_ci exit (1); 404da0c48c4Sopenharmony_ci } 405da0c48c4Sopenharmony_ci data = elf_getdata (scn2, NULL); 406da0c48c4Sopenharmony_ci check_data (".data2", data, sec_data); 407da0c48c4Sopenharmony_ci 408da0c48c4Sopenharmony_ci if (scn3 == NULL) 409da0c48c4Sopenharmony_ci { 410da0c48c4Sopenharmony_ci printf ("ELF file doesn't have a .data3 section\n"); 411da0c48c4Sopenharmony_ci exit (1); 412da0c48c4Sopenharmony_ci } 413da0c48c4Sopenharmony_ci data = elf_getdata (scn3, NULL); 414da0c48c4Sopenharmony_ci check_data (".data3", data, new_data); 415da0c48c4Sopenharmony_ci 416da0c48c4Sopenharmony_ci if (scn4 == NULL) 417da0c48c4Sopenharmony_ci { 418da0c48c4Sopenharmony_ci printf ("ELF file doesn't have a .data4 section\n"); 419da0c48c4Sopenharmony_ci exit (1); 420da0c48c4Sopenharmony_ci } 421da0c48c4Sopenharmony_ci data = elf_getdata (scn4, NULL); 422da0c48c4Sopenharmony_ci check_data (".data4", data, sec_data); 423da0c48c4Sopenharmony_ci 424da0c48c4Sopenharmony_ci if (elf_end (elf) != 0) 425da0c48c4Sopenharmony_ci { 426da0c48c4Sopenharmony_ci printf ("failure in elf_end: %s\n", elf_errmsg (-1)); 427da0c48c4Sopenharmony_ci exit (1); 428da0c48c4Sopenharmony_ci } 429da0c48c4Sopenharmony_ci 430da0c48c4Sopenharmony_ci close (fd); 431da0c48c4Sopenharmony_ci 432da0c48c4Sopenharmony_ci unlink (fname); 433da0c48c4Sopenharmony_ci} 434da0c48c4Sopenharmony_ci 435da0c48c4Sopenharmony_ciint 436da0c48c4Sopenharmony_cimain (int argc __attribute__ ((unused)), 437da0c48c4Sopenharmony_ci char *argv[] __attribute__ ((unused))) 438da0c48c4Sopenharmony_ci{ 439da0c48c4Sopenharmony_ci elf_version (EV_CURRENT); 440da0c48c4Sopenharmony_ci 441da0c48c4Sopenharmony_ci elf_fill (0xA); 442da0c48c4Sopenharmony_ci 443da0c48c4Sopenharmony_ci check_elf ("fill.elf.32", ELFCLASS32, 0); 444da0c48c4Sopenharmony_ci check_elf ("fill.elf.32.mmap", ELFCLASS32, 1); 445da0c48c4Sopenharmony_ci check_elf ("fill.elf.64", ELFCLASS64, 0); 446da0c48c4Sopenharmony_ci check_elf ("fill.elf.64.mmap", ELFCLASS64, 1); 447da0c48c4Sopenharmony_ci 448da0c48c4Sopenharmony_ci return 0; 449da0c48c4Sopenharmony_ci} 450