1da0c48c4Sopenharmony_ci/* Test program for elf_newdata function.
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#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#include "system.h"
30da0c48c4Sopenharmony_ci
31da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(elf)
32da0c48c4Sopenharmony_ci#include <gelf.h>
33da0c48c4Sopenharmony_ci
34da0c48c4Sopenharmony_ci// Random data string (16 bytes).
35da0c48c4Sopenharmony_cistatic char *DATA = "123456789ABCDEF";
36da0c48c4Sopenharmony_cistatic size_t DATA_LEN = 16;
37da0c48c4Sopenharmony_ci
38da0c48c4Sopenharmony_cistatic void
39da0c48c4Sopenharmony_ciadd_section_data (Elf *elf, char *buf, size_t len)
40da0c48c4Sopenharmony_ci{
41da0c48c4Sopenharmony_ci  printf ("Adding %zd bytes.\n", len);
42da0c48c4Sopenharmony_ci
43da0c48c4Sopenharmony_ci  Elf_Scn *scn = elf_getscn (elf, 1);
44da0c48c4Sopenharmony_ci  if (scn == NULL)
45da0c48c4Sopenharmony_ci    {
46da0c48c4Sopenharmony_ci      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
47da0c48c4Sopenharmony_ci      exit (1);
48da0c48c4Sopenharmony_ci    }
49da0c48c4Sopenharmony_ci
50da0c48c4Sopenharmony_ci  Elf_Data *data = elf_newdata (scn);
51da0c48c4Sopenharmony_ci  if (data == NULL)
52da0c48c4Sopenharmony_ci    {
53da0c48c4Sopenharmony_ci      printf ("cannot create newdata for section: %s\n", elf_errmsg (-1));
54da0c48c4Sopenharmony_ci      exit (1);
55da0c48c4Sopenharmony_ci    }
56da0c48c4Sopenharmony_ci
57da0c48c4Sopenharmony_ci  data->d_buf = buf;
58da0c48c4Sopenharmony_ci  data->d_type = ELF_T_BYTE;
59da0c48c4Sopenharmony_ci  data->d_size = len;
60da0c48c4Sopenharmony_ci  data->d_align = 1;
61da0c48c4Sopenharmony_ci  data->d_version = EV_CURRENT;
62da0c48c4Sopenharmony_ci
63da0c48c4Sopenharmony_ci  // Let the library compute the internal structure information.
64da0c48c4Sopenharmony_ci  if (elf_update (elf, ELF_C_NULL) < 0)
65da0c48c4Sopenharmony_ci    {
66da0c48c4Sopenharmony_ci      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
67da0c48c4Sopenharmony_ci      exit (1);
68da0c48c4Sopenharmony_ci    }
69da0c48c4Sopenharmony_ci
70da0c48c4Sopenharmony_ci}
71da0c48c4Sopenharmony_ci
72da0c48c4Sopenharmony_cistatic Elf *
73da0c48c4Sopenharmony_cicreate_elf (int fd, int class, int use_mmap)
74da0c48c4Sopenharmony_ci{
75da0c48c4Sopenharmony_ci  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
76da0c48c4Sopenharmony_ci  if (elf == NULL)
77da0c48c4Sopenharmony_ci    {
78da0c48c4Sopenharmony_ci      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
79da0c48c4Sopenharmony_ci      exit (1);
80da0c48c4Sopenharmony_ci    }
81da0c48c4Sopenharmony_ci
82da0c48c4Sopenharmony_ci  // Create an ELF header.
83da0c48c4Sopenharmony_ci  if (gelf_newehdr (elf, class) == 0)
84da0c48c4Sopenharmony_ci    {
85da0c48c4Sopenharmony_ci      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
86da0c48c4Sopenharmony_ci      exit (1);
87da0c48c4Sopenharmony_ci    }
88da0c48c4Sopenharmony_ci
89da0c48c4Sopenharmony_ci  GElf_Ehdr ehdr_mem;
90da0c48c4Sopenharmony_ci  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
91da0c48c4Sopenharmony_ci  if (ehdr == NULL)
92da0c48c4Sopenharmony_ci    {
93da0c48c4Sopenharmony_ci      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
94da0c48c4Sopenharmony_ci      exit (1);
95da0c48c4Sopenharmony_ci    }
96da0c48c4Sopenharmony_ci
97da0c48c4Sopenharmony_ci  // Initialize header.
98da0c48c4Sopenharmony_ci  ehdr->e_ident[EI_DATA] = class == ELFCLASS32 ? ELFDATA2LSB : ELFDATA2MSB;
99da0c48c4Sopenharmony_ci  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
100da0c48c4Sopenharmony_ci  ehdr->e_type = ET_NONE;
101da0c48c4Sopenharmony_ci  ehdr->e_machine = class == ELFCLASS32 ? EM_PPC : EM_X86_64;
102da0c48c4Sopenharmony_ci  ehdr->e_version = EV_CURRENT;
103da0c48c4Sopenharmony_ci
104da0c48c4Sopenharmony_ci  // Update the ELF header.
105da0c48c4Sopenharmony_ci  if (gelf_update_ehdr (elf, ehdr) == 0)
106da0c48c4Sopenharmony_ci    {
107da0c48c4Sopenharmony_ci      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
108da0c48c4Sopenharmony_ci      exit (1);
109da0c48c4Sopenharmony_ci    }
110da0c48c4Sopenharmony_ci
111da0c48c4Sopenharmony_ci  // Create a section.
112da0c48c4Sopenharmony_ci  Elf_Scn *scn = elf_newscn (elf);
113da0c48c4Sopenharmony_ci  if (scn == NULL)
114da0c48c4Sopenharmony_ci    {
115da0c48c4Sopenharmony_ci      printf ("cannot create new section: %s\n", elf_errmsg (-1));
116da0c48c4Sopenharmony_ci      exit (1);
117da0c48c4Sopenharmony_ci    }
118da0c48c4Sopenharmony_ci
119da0c48c4Sopenharmony_ci  GElf_Shdr shdr_mem;
120da0c48c4Sopenharmony_ci  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
121da0c48c4Sopenharmony_ci  if (shdr == NULL)
122da0c48c4Sopenharmony_ci    {
123da0c48c4Sopenharmony_ci      printf ("cannot get header for data section: %s\n", elf_errmsg (-1));
124da0c48c4Sopenharmony_ci      exit (1);
125da0c48c4Sopenharmony_ci    }
126da0c48c4Sopenharmony_ci
127da0c48c4Sopenharmony_ci  shdr->sh_type = SHT_PROGBITS;
128da0c48c4Sopenharmony_ci  shdr->sh_flags = 0;
129da0c48c4Sopenharmony_ci  shdr->sh_addr = 0;
130da0c48c4Sopenharmony_ci  shdr->sh_link = SHN_UNDEF;
131da0c48c4Sopenharmony_ci  shdr->sh_info = SHN_UNDEF;
132da0c48c4Sopenharmony_ci  shdr->sh_addralign = 1;
133da0c48c4Sopenharmony_ci  shdr->sh_entsize = 1;
134da0c48c4Sopenharmony_ci  shdr->sh_name = 0;
135da0c48c4Sopenharmony_ci
136da0c48c4Sopenharmony_ci  // Finish section, update the header.
137da0c48c4Sopenharmony_ci  if (gelf_update_shdr (scn, shdr) == 0)
138da0c48c4Sopenharmony_ci    {
139da0c48c4Sopenharmony_ci      printf ("cannot update header for DATA section: %s\n", elf_errmsg (-1));
140da0c48c4Sopenharmony_ci      exit (1);
141da0c48c4Sopenharmony_ci    }
142da0c48c4Sopenharmony_ci
143da0c48c4Sopenharmony_ci  // Add some data to the section.
144da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
145da0c48c4Sopenharmony_ci
146da0c48c4Sopenharmony_ci  // Write everything to disk.
147da0c48c4Sopenharmony_ci  if (elf_update (elf, ELF_C_WRITE) < 0)
148da0c48c4Sopenharmony_ci    {
149da0c48c4Sopenharmony_ci      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
150da0c48c4Sopenharmony_ci      exit (1);
151da0c48c4Sopenharmony_ci    }
152da0c48c4Sopenharmony_ci
153da0c48c4Sopenharmony_ci  return elf;
154da0c48c4Sopenharmony_ci}
155da0c48c4Sopenharmony_ci
156da0c48c4Sopenharmony_cistatic Elf *
157da0c48c4Sopenharmony_ciread_elf (int fd, int use_mmap)
158da0c48c4Sopenharmony_ci{
159da0c48c4Sopenharmony_ci  printf ("Reading ELF file\n");
160da0c48c4Sopenharmony_ci  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
161da0c48c4Sopenharmony_ci  if (elf == NULL)
162da0c48c4Sopenharmony_ci    {
163da0c48c4Sopenharmony_ci      printf ("cannot create ELF descriptor read-again: %s\n", elf_errmsg (-1));
164da0c48c4Sopenharmony_ci      exit (1);
165da0c48c4Sopenharmony_ci    }
166da0c48c4Sopenharmony_ci
167da0c48c4Sopenharmony_ci  return elf;
168da0c48c4Sopenharmony_ci}
169da0c48c4Sopenharmony_ci
170da0c48c4Sopenharmony_cistatic void
171da0c48c4Sopenharmony_cicheck_section_size (Elf *elf, size_t size)
172da0c48c4Sopenharmony_ci{
173da0c48c4Sopenharmony_ci  Elf_Scn *scn = elf_getscn (elf, 1);
174da0c48c4Sopenharmony_ci  if (scn == NULL)
175da0c48c4Sopenharmony_ci    {
176da0c48c4Sopenharmony_ci      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
177da0c48c4Sopenharmony_ci      exit (1);
178da0c48c4Sopenharmony_ci    }
179da0c48c4Sopenharmony_ci
180da0c48c4Sopenharmony_ci  GElf_Shdr shdr_mem;
181da0c48c4Sopenharmony_ci  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
182da0c48c4Sopenharmony_ci  if (shdr == NULL)
183da0c48c4Sopenharmony_ci    {
184da0c48c4Sopenharmony_ci      printf ("cannot get header for DATA section: %s\n", elf_errmsg (-1));
185da0c48c4Sopenharmony_ci      exit (1);
186da0c48c4Sopenharmony_ci    }
187da0c48c4Sopenharmony_ci
188da0c48c4Sopenharmony_ci  if (shdr->sh_size == size)
189da0c48c4Sopenharmony_ci    printf ("OK %zd bytes.\n", size);
190da0c48c4Sopenharmony_ci  else
191da0c48c4Sopenharmony_ci    {
192da0c48c4Sopenharmony_ci      printf ("BAD size, expected %zd, got %" PRIu64 "\n",
193da0c48c4Sopenharmony_ci	      size, shdr->sh_size);
194da0c48c4Sopenharmony_ci      exit (-1);
195da0c48c4Sopenharmony_ci    }
196da0c48c4Sopenharmony_ci}
197da0c48c4Sopenharmony_ci
198da0c48c4Sopenharmony_cistatic void
199da0c48c4Sopenharmony_cicheck_section_data (Elf *elf, char *data, size_t len, size_t times)
200da0c48c4Sopenharmony_ci{
201da0c48c4Sopenharmony_ci  Elf_Scn *scn = elf_getscn (elf, 1);
202da0c48c4Sopenharmony_ci  if (scn == NULL)
203da0c48c4Sopenharmony_ci    {
204da0c48c4Sopenharmony_ci      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
205da0c48c4Sopenharmony_ci      exit (1);
206da0c48c4Sopenharmony_ci    }
207da0c48c4Sopenharmony_ci
208da0c48c4Sopenharmony_ci  Elf_Data *d = NULL;
209da0c48c4Sopenharmony_ci  for (size_t i = 0; i < times; i++)
210da0c48c4Sopenharmony_ci    {
211da0c48c4Sopenharmony_ci      if (d == NULL || i * len >= d->d_off + d->d_size)
212da0c48c4Sopenharmony_ci	{
213da0c48c4Sopenharmony_ci	  d = elf_getdata (scn, d);
214da0c48c4Sopenharmony_ci	  if (d == NULL)
215da0c48c4Sopenharmony_ci	    {
216da0c48c4Sopenharmony_ci	      printf ("cannot get data for section item %zd: %s\n",
217da0c48c4Sopenharmony_ci		      i, elf_errmsg (-1));
218da0c48c4Sopenharmony_ci	      exit (1);
219da0c48c4Sopenharmony_ci	    }
220da0c48c4Sopenharmony_ci	  else
221da0c48c4Sopenharmony_ci	    printf ("OK, section data item %zd (d_off: %" PRId64
222da0c48c4Sopenharmony_ci		    ", d_size: %zd)\n", i, d->d_off, d->d_size);
223da0c48c4Sopenharmony_ci	}
224da0c48c4Sopenharmony_ci      char *d_data = (char *) d->d_buf + (len * i) - d->d_off;
225da0c48c4Sopenharmony_ci      printf ("%zd data (d_off: %" PRId64
226da0c48c4Sopenharmony_ci	      ", len * i: %zd): (%p + %" PRId64 ") %s\n",
227da0c48c4Sopenharmony_ci	      i, d->d_off, len * i, d->d_buf, (len * i) - d->d_off, d_data);
228da0c48c4Sopenharmony_ci      if (memcmp (data, d_data, len) != 0)
229da0c48c4Sopenharmony_ci	{
230da0c48c4Sopenharmony_ci	  printf ("Got bad data in section for item %zd.\n", i);
231da0c48c4Sopenharmony_ci	  exit (1);
232da0c48c4Sopenharmony_ci	}
233da0c48c4Sopenharmony_ci    }
234da0c48c4Sopenharmony_ci}
235da0c48c4Sopenharmony_ci
236da0c48c4Sopenharmony_cistatic void
237da0c48c4Sopenharmony_cicheck_elf (int class, int use_mmap)
238da0c48c4Sopenharmony_ci{
239da0c48c4Sopenharmony_ci  static const char *fname;
240da0c48c4Sopenharmony_ci  if (class == ELFCLASS32)
241da0c48c4Sopenharmony_ci    fname = use_mmap ? "newdata.elf32.mmap" : "newdata.elf32";
242da0c48c4Sopenharmony_ci  else
243da0c48c4Sopenharmony_ci    fname = use_mmap ? "newdata.elf64.mmap" : "newdata.elf64";
244da0c48c4Sopenharmony_ci
245da0c48c4Sopenharmony_ci  printf ("\ncheck_elf: %s\n", fname);
246da0c48c4Sopenharmony_ci
247da0c48c4Sopenharmony_ci  int fd = open (fname, O_RDWR|O_CREAT|O_TRUNC, DEFFILEMODE);
248da0c48c4Sopenharmony_ci  if (fd == -1)
249da0c48c4Sopenharmony_ci    {
250da0c48c4Sopenharmony_ci      printf ("cannot create `%s': %s\n", fname, strerror (errno));
251da0c48c4Sopenharmony_ci      exit (1);
252da0c48c4Sopenharmony_ci    }
253da0c48c4Sopenharmony_ci
254da0c48c4Sopenharmony_ci  Elf *elf = create_elf (fd, class, use_mmap);
255da0c48c4Sopenharmony_ci  check_section_size (elf, DATA_LEN);
256da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 1);
257da0c48c4Sopenharmony_ci
258da0c48c4Sopenharmony_ci  // Add some more data (won't be written to disk).
259da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
260da0c48c4Sopenharmony_ci  check_section_size (elf, 2 * DATA_LEN);
261da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 2);
262da0c48c4Sopenharmony_ci
263da0c48c4Sopenharmony_ci  if (elf_end (elf) != 0)
264da0c48c4Sopenharmony_ci    {
265da0c48c4Sopenharmony_ci      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
266da0c48c4Sopenharmony_ci      exit (1);
267da0c48c4Sopenharmony_ci    }
268da0c48c4Sopenharmony_ci
269da0c48c4Sopenharmony_ci  close (fd);
270da0c48c4Sopenharmony_ci
271da0c48c4Sopenharmony_ci  // Read the ELF from disk now.  And add new data directly.
272da0c48c4Sopenharmony_ci  fd = open (fname, O_RDONLY);
273da0c48c4Sopenharmony_ci  if (fd == -1)
274da0c48c4Sopenharmony_ci    {
275da0c48c4Sopenharmony_ci      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
276da0c48c4Sopenharmony_ci      exit (1);
277da0c48c4Sopenharmony_ci    }
278da0c48c4Sopenharmony_ci
279da0c48c4Sopenharmony_ci  elf = read_elf (fd, use_mmap);
280da0c48c4Sopenharmony_ci  check_section_size (elf, DATA_LEN);
281da0c48c4Sopenharmony_ci  // But don't check contents, that would read the data...
282da0c48c4Sopenharmony_ci
283da0c48c4Sopenharmony_ci  // Add some more data.
284da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
285da0c48c4Sopenharmony_ci  check_section_size (elf, 2 * DATA_LEN);
286da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 2);
287da0c48c4Sopenharmony_ci
288da0c48c4Sopenharmony_ci  // And some more.
289da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
290da0c48c4Sopenharmony_ci  check_section_size (elf, 3 * DATA_LEN);
291da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 3);
292da0c48c4Sopenharmony_ci
293da0c48c4Sopenharmony_ci  if (elf_end (elf) != 0)
294da0c48c4Sopenharmony_ci    {
295da0c48c4Sopenharmony_ci      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
296da0c48c4Sopenharmony_ci      exit (1);
297da0c48c4Sopenharmony_ci    }
298da0c48c4Sopenharmony_ci
299da0c48c4Sopenharmony_ci  close (fd);
300da0c48c4Sopenharmony_ci
301da0c48c4Sopenharmony_ci  // Read the ELF from disk now.  And add new data after raw reading.
302da0c48c4Sopenharmony_ci  fd = open (fname, O_RDONLY);
303da0c48c4Sopenharmony_ci  if (fd == -1)
304da0c48c4Sopenharmony_ci    {
305da0c48c4Sopenharmony_ci      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
306da0c48c4Sopenharmony_ci      exit (1);
307da0c48c4Sopenharmony_ci    }
308da0c48c4Sopenharmony_ci
309da0c48c4Sopenharmony_ci  elf = read_elf (fd, use_mmap);
310da0c48c4Sopenharmony_ci  check_section_size (elf, DATA_LEN);
311da0c48c4Sopenharmony_ci  // But don't check contents, that would read the data...
312da0c48c4Sopenharmony_ci
313da0c48c4Sopenharmony_ci  // Get raw data before adding new data.
314da0c48c4Sopenharmony_ci  Elf_Scn *scn = elf_getscn (elf, 1);
315da0c48c4Sopenharmony_ci  if (scn == NULL)
316da0c48c4Sopenharmony_ci    {
317da0c48c4Sopenharmony_ci      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
318da0c48c4Sopenharmony_ci      exit (1);
319da0c48c4Sopenharmony_ci    }
320da0c48c4Sopenharmony_ci
321da0c48c4Sopenharmony_ci  printf ("elf_rawdata\n");
322da0c48c4Sopenharmony_ci  Elf_Data *data = elf_rawdata (scn, NULL);
323da0c48c4Sopenharmony_ci  if (data == NULL)
324da0c48c4Sopenharmony_ci    {
325da0c48c4Sopenharmony_ci      printf ("couldn't get raw data from section: %s\n", elf_errmsg (-1));
326da0c48c4Sopenharmony_ci      exit (1);
327da0c48c4Sopenharmony_ci    }
328da0c48c4Sopenharmony_ci
329da0c48c4Sopenharmony_ci  if (data->d_size != DATA_LEN)
330da0c48c4Sopenharmony_ci    {
331da0c48c4Sopenharmony_ci      printf ("Unexpected Elf_Data: %zd", data->d_size);
332da0c48c4Sopenharmony_ci      exit (1);
333da0c48c4Sopenharmony_ci    }
334da0c48c4Sopenharmony_ci
335da0c48c4Sopenharmony_ci  // Now add more data.
336da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
337da0c48c4Sopenharmony_ci  check_section_size (elf, 2 * DATA_LEN);
338da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 2);
339da0c48c4Sopenharmony_ci
340da0c48c4Sopenharmony_ci  // And some more.
341da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
342da0c48c4Sopenharmony_ci  check_section_size (elf, 3 * DATA_LEN);
343da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 3);
344da0c48c4Sopenharmony_ci
345da0c48c4Sopenharmony_ci  if (elf_end (elf) != 0)
346da0c48c4Sopenharmony_ci    {
347da0c48c4Sopenharmony_ci      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
348da0c48c4Sopenharmony_ci      exit (1);
349da0c48c4Sopenharmony_ci    }
350da0c48c4Sopenharmony_ci
351da0c48c4Sopenharmony_ci  close (fd);
352da0c48c4Sopenharmony_ci
353da0c48c4Sopenharmony_ci  // Read the ELF from disk now.  And add new data after data reading.
354da0c48c4Sopenharmony_ci  fd = open (fname, O_RDONLY);
355da0c48c4Sopenharmony_ci  if (fd == -1)
356da0c48c4Sopenharmony_ci    {
357da0c48c4Sopenharmony_ci      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
358da0c48c4Sopenharmony_ci      exit (1);
359da0c48c4Sopenharmony_ci    }
360da0c48c4Sopenharmony_ci
361da0c48c4Sopenharmony_ci  elf = read_elf (fd, use_mmap);
362da0c48c4Sopenharmony_ci  check_section_size (elf, DATA_LEN);
363da0c48c4Sopenharmony_ci  // Get (converted) data before adding new data.
364da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 1);
365da0c48c4Sopenharmony_ci
366da0c48c4Sopenharmony_ci  printf ("elf_getdata\n");
367da0c48c4Sopenharmony_ci
368da0c48c4Sopenharmony_ci  // Now add more data.
369da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
370da0c48c4Sopenharmony_ci  check_section_size (elf, 2 * DATA_LEN);
371da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 2);
372da0c48c4Sopenharmony_ci
373da0c48c4Sopenharmony_ci  // And some more.
374da0c48c4Sopenharmony_ci  add_section_data (elf, DATA, DATA_LEN);
375da0c48c4Sopenharmony_ci  check_section_size (elf, 3 * DATA_LEN);
376da0c48c4Sopenharmony_ci  check_section_data (elf, DATA, DATA_LEN, 3);
377da0c48c4Sopenharmony_ci
378da0c48c4Sopenharmony_ci  if (elf_end (elf) != 0)
379da0c48c4Sopenharmony_ci    {
380da0c48c4Sopenharmony_ci      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
381da0c48c4Sopenharmony_ci      exit (1);
382da0c48c4Sopenharmony_ci    }
383da0c48c4Sopenharmony_ci
384da0c48c4Sopenharmony_ci  close (fd);
385da0c48c4Sopenharmony_ci
386da0c48c4Sopenharmony_ci  unlink (fname);
387da0c48c4Sopenharmony_ci}
388da0c48c4Sopenharmony_ci
389da0c48c4Sopenharmony_ciint
390da0c48c4Sopenharmony_cimain (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
391da0c48c4Sopenharmony_ci{
392da0c48c4Sopenharmony_ci  // Initialize libelf.
393da0c48c4Sopenharmony_ci  elf_version (EV_CURRENT);
394da0c48c4Sopenharmony_ci
395da0c48c4Sopenharmony_ci  // Fill holes with something non-zero to more easily spot bad data.
396da0c48c4Sopenharmony_ci  elf_fill ('X');
397da0c48c4Sopenharmony_ci
398da0c48c4Sopenharmony_ci  check_elf (ELFCLASS32, 0);
399da0c48c4Sopenharmony_ci  check_elf (ELFCLASS32, 1);
400da0c48c4Sopenharmony_ci  check_elf (ELFCLASS64, 0);
401da0c48c4Sopenharmony_ci  check_elf (ELFCLASS64, 1);
402da0c48c4Sopenharmony_ci
403da0c48c4Sopenharmony_ci  return 0;
404da0c48c4Sopenharmony_ci}
405