1710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard/* Test program for elf_strptr function.
2710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   Copyright (C) 2015 Red Hat, Inc.
3710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   This file is part of elfutils.
4710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
5710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   This file is free software; you can redistribute it and/or modify
6710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   it under the terms of the GNU General Public License as published by
7710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   the Free Software Foundation; either version 3 of the License, or
8710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   (at your option) any later version.
9710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
10710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
11710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   WITHOUT ANY WARRANTY; without even the implied warranty of
12710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   GNU General Public License for more details.
14710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
15710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   You should have received a copy of the GNU General Public License
16710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
18710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#ifdef HAVE_CONFIG_H
19710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard# include <config.h>
20710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#endif
21710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
22710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <errno.h>
23710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <fcntl.h>
24710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <inttypes.h>
25710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <stdio.h>
26710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <stdlib.h>
27710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <string.h>
28710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <unistd.h>
29710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
30710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include ELFUTILS_HEADER(elf)
31710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard#include <gelf.h>
32710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
33710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
34710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard/* Index of last string added.  Returned by add_string ().  */
35710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t stridx = 0;
36710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
37710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard/* Some random strings.  */
38710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *str1;
39710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t str1_off;
40710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *str2;
41710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t str2_off;
42710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *str3;
43710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t str3_off;
44710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
45710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard/* First three strings we write out. They should always be there.  */
46710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *orig_str1;
47710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t orig_str1_off;
48710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *orig_str2;
49710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t orig_str2_off;
50710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic char *orig_str3;
51710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t orig_str3_off;
52710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
53710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic void
54710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardcheck_orig_strings (Elf *elf, int ndx, const char *msg)
55710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard{
56710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("checking orig strings: %s\n", msg);
57710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
58710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  const char *str = elf_strptr (elf, ndx, 0);
59710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
60710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp ("", str) != 0)
61710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
62710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
63710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, 1);
64710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
65710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (".strings", str) != 0)
66710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
67710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
68710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, orig_str1_off);
69710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
70710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (orig_str1, str) != 0)
71710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
72710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
73710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, orig_str2_off);
74710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
75710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (orig_str2, str) != 0)
76710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
77710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
78710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, orig_str3_off);
79710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
80710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (orig_str3, str) != 0)
81710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
82710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard}
83710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
84710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic void
85710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardcheck_strings (Elf *elf, int ndx, const char *msg)
86710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard{
87710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_orig_strings (elf, ndx, msg);
88710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
89710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  const char *str = elf_strptr (elf, ndx, str1_off);
90710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
91710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (str1, str) != 0)
92710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
93710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
94710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, str2_off);
95710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
96710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (str2, str) != 0)
97710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
98710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
99710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str = elf_strptr (elf, ndx, str3_off);
100710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\t'%s'\n", str);
101710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (str == NULL || strcmp (str3, str) != 0)
102710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    exit (1);
103710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard}
104710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
105710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard/* Adds a string and returns the offset in the section.  */
106710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic size_t
107710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardadd_string (Elf_Scn *scn, char *str)
108710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard{
109710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  size_t lastidx = stridx;
110710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  size_t size = strlen (str) + 1;
111710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
112710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  Elf_Data *data = elf_newdata (scn);
113710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (data == NULL)
114710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
115710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
116710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
117710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
118710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
119710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  data->d_buf = str;
120710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  data->d_type = ELF_T_BYTE;
121710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  data->d_size = size;
122710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  data->d_align = 1;
123710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  data->d_version = EV_CURRENT;
124710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
125710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  stridx += size;
126710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("add_string: '%s', stridx: %zd, lastidx: %zd\n",
127710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard	  str, stridx, lastidx);
128710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  return lastidx;
129710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard}
130710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
131710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardstatic void
132710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardcheck_elf (const char *fname, int class, int use_mmap)
133710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard{
134710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("\nfname: %s\n", fname);
135710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  stridx = 0;
136710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
137710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
138710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (fd == -1)
139710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
140710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot open `%s': %s\n", fname, strerror (errno));
141710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
142710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
143710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
144710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
145710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf == NULL)
146710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
147710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
148710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
149710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
150710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
151710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Create an ELF header.
152710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (gelf_newehdr (elf, class) == 0)
153710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
154710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
155710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
156710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
157710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
158710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  GElf_Ehdr ehdr_mem;
159710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
160710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (ehdr == NULL)
161710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
162710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
163710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
164710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
165710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
166710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Initialize header.
167710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB;
168710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
169710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_type = ET_NONE;
170710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_machine = EM_X86_64;
171710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_version = EV_CURRENT;
172710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
173710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Create strings section.
174710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  Elf_Scn *scn = elf_newscn (elf);
175710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (scn == NULL)
176710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
177710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create strings section: %s\n", elf_errmsg (-1));
178710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
179710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
180710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
181710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Add an empty string to the table as NUL entry for section zero.
182710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  add_string (scn, "");
183710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
184710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  GElf_Shdr shdr_mem;
185710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
186710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (shdr == NULL)
187710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
188710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot get header for strings section: %s\n", elf_errmsg (-1));
189710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
190710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
191710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
192710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_type = SHT_STRTAB;
193710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_flags = 0;
194710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_addr = 0;
195710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_link = SHN_UNDEF;
196710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_info = SHN_UNDEF;
197710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_addralign = 1;
198710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_entsize = 0;
199710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr->sh_name = add_string (scn, ".strings");
200710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
201710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // We have to store the section strtab index in the ELF header.
202710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // So sections have actual names.
203710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  int ndx = elf_ndxscn (scn);
204710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  ehdr->e_shstrndx = ndx;
205710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
206710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (gelf_update_ehdr (elf, ehdr) == 0)
207710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
208710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
209710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
210710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
211710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
212710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Add some random strings. These are the original ones. They should
213710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // always be there (together with the empty "" and .strings section
214710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // name strings.
215710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str1 = "elfutils";
216710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str1_off = add_string (scn, orig_str1);
217710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str2 = "strtabelf";
218710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str2_off = add_string (scn, orig_str2);
219710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str3 = "three";
220710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  orig_str3_off = add_string (scn, orig_str3);
221710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
222710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Finished strings section, update the header.
223710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (gelf_update_shdr (scn, shdr) == 0)
224710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
225710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot update STRTAB section header: %s\n", elf_errmsg (-1));
226710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
227710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
228710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
229710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Let the library compute the internal structure information.
230710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_update (elf, ELF_C_NULL) < 0)
231710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
232710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
233710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
234710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
235710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
236710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Check our strings are there.
237710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_orig_strings (elf, ndx, "first elf_update, before write");
238710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
239710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Write everything to disk.
240710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_update (elf, ELF_C_WRITE) < 0)
241710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
242710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
243710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
244710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
245710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
246710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Check out strings are there.
247710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_orig_strings (elf, ndx, "first elf_update, after write");
248710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
249710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Add some more random strings.  These will not be written to disk.
250710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  scn = elf_getscn (elf, ndx);
251710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (scn == NULL)
252710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
253710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("couldn't re-get strings section: %s\n", elf_errmsg (-1));
254710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
255710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
256710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
257710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str1 = "elfutils2";
258710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str1_off = add_string (scn, str1);
259710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str2 = "strtabelf2";
260710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str2_off = add_string (scn, str2);
261710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str3 = "three2";
262710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str3_off = add_string (scn, str3);
263710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
264710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Update internal structure information again.
265710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_update (elf, ELF_C_NULL) < 0)
266710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
267710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in re-elf_update(NULL): %s\n", elf_errmsg (-1));
268710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
269710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
270710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
271710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Check our new strings are there.
272710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_strings (elf, ndx, "first extra strings");
273710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
274710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_end (elf) != 0)
275710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
276710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
277710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
278710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
279710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
280710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  close (fd);
281710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
282710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  /* Read the ELF from disk now.  */
283710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  fd = open (fname, O_RDWR, 0666);
284710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (fd == -1)
285710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
286710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
287710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
288710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
289710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
290710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
291710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf == NULL)
292710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
293710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
294710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
295710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
296710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
297710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  /* Are our strings there?  */
298710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_orig_strings (elf, ndx, "read ELF file, orig strings");
299710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
300710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Add some more random strings.
301710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  scn = elf_getscn (elf, ndx);
302710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (scn == NULL)
303710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
304710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("couldn't re-get strings section: %s\n", elf_errmsg (-1));
305710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
306710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
307710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
308710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  shdr = gelf_getshdr (scn, &shdr_mem);
309710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (shdr == NULL)
310710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
311710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot get header for strings section: %s\n", elf_errmsg (-1));
312710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
313710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
314710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
315710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Reset stridx to end of section.
316710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  printf ("sh_size: %" PRIu64 "\n", shdr->sh_size);
317710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  stridx = shdr->sh_size;
318710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
319710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str1 = "0123456789";
320710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str1_off = add_string (scn, str1);
321710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str2 = "supercalifragilisticexpialidocious";
322710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str2_off = add_string (scn, str2);
323710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str3 = "forty-two";
324710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  str3_off = add_string (scn, str3);
325710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
326710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Update internal structure information.
327710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_update (elf, ELF_C_NULL) < 0)
328710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
329710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in rw-elf_update(NULL): %s\n", elf_errmsg (-1));
330710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
331710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
332710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
333710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  /* Check our new strings are there.  */
334710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_strings (elf, ndx, "read file, added strings");
335710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
336710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Write updated ELF file.
337710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_update (elf, ELF_C_WRITE) < 0)
338710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
339710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in re-elf_update(NULL): %s\n", elf_errmsg (-1));
340710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
341710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
342710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
343710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_end (elf) != 0)
344710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
345710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
346710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
347710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
348710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
349710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  close (fd);
350710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
351710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // And read it in one last time.
352710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  fd = open (fname, O_RDONLY, 0666);
353710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (fd == -1)
354710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
355710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
356710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
357710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
358710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
359710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
360710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf == NULL)
361710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
362710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
363710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
364710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
365710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
366710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  /* Are all our strings there?  */
367710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_strings (elf, ndx, "all together now");
368710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
369710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  if (elf_end (elf) != 0)
370710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    {
371710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
372710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard      exit (1);
373710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard    }
374710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
375710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  close (fd);
376710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
377710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  unlink (fname);
378710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard}
379710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
380710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardint
381710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaardmain (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
382710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard{
383710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  elf_version (EV_CURRENT);
384710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
385710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // Fill holes with something non-zero to more easily spot
386710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  // unterminated strings.
387710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  elf_fill ('X');
388710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
389710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_elf ("strtab.elf.32", ELFCLASS32, 0);
390710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_elf ("strtab.elf.32.mmap", ELFCLASS32, 1);
391710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_elf ("strtab.elf.64", ELFCLASS64, 0);
392710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  check_elf ("strtab.elf.64.mmap", ELFCLASS64, 1);
393710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
394710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard  return 0;
395710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard}
396710ca87893bef2fa186265a8624a6402509ba1f3Mark Wielaard
397