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