1 /* Update data structures for changes and write them out.
2 Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc.
3 This file is part of elfutils.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
43 write_file (Elf
*elf
, off_t size
, int change_bo
, size_t shnum
)
45 int class = elf
->class;
47 /* Check the mode bits now, before modification might change them. */
49 if (unlikely (fstat (elf
->fildes
, &st
) != 0))
51 __libelf_seterrno (ELF_E_WRITE_ERROR
);
55 /* Adjust the size in any case. We do this even if we use `write'.
56 We cannot do this if this file is in an archive. We also don't
57 do it *now* if we are shortening the file since this would
58 prevent programs to use the data of the file in generating the
59 new file. We truncate the file later in this case. */
60 if (elf
->parent
== NULL
61 && (elf
->maximum_size
== ~((size_t) 0)
62 || (size_t) size
> elf
->maximum_size
)
63 && unlikely (ftruncate (elf
->fildes
, size
) != 0))
65 __libelf_seterrno (ELF_E_WRITE_ERROR
);
69 /* Try to map the file if this isn't done yet. */
70 if (elf
->map_address
== NULL
&& elf
->cmd
== ELF_C_WRITE_MMAP
)
73 /* Mudflap doesn't grok that our mmap'd data is ok. */
75 elf
->map_address
= mmap (NULL
, size
, PROT_READ
| PROT_WRITE
,
76 MAP_SHARED
, elf
->fildes
, 0);
77 if (unlikely (elf
->map_address
== MAP_FAILED
))
78 elf
->map_address
= NULL
;
82 if (elf
->map_address
!= NULL
)
84 /* The file is mmaped. */
85 if ((class == ELFCLASS32
86 ? __elf32_updatemmap (elf
, change_bo
, shnum
)
87 : __elf64_updatemmap (elf
, change_bo
, shnum
)) != 0)
88 /* Some problem while writing. */
93 /* The file is not mmaped. */
94 if ((class == ELFCLASS32
95 ? __elf32_updatefile (elf
, change_bo
, shnum
)
96 : __elf64_updatefile (elf
, change_bo
, shnum
)) != 0)
97 /* Some problem while writing. */
102 && elf
->parent
== NULL
103 && elf
->maximum_size
!= ~((size_t) 0)
104 && (size_t) size
< elf
->maximum_size
105 && unlikely (ftruncate (elf
->fildes
, size
) != 0))
107 __libelf_seterrno (ELF_E_WRITE_ERROR
);
111 /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID
112 mode bits. So make sure we restore them afterwards if they were set.
113 This is not atomic if someone else chmod's the file while we operate. */
115 && unlikely (st
.st_mode
& (S_ISUID
| S_ISGID
))
116 /* fchmod ignores the bits we cannot change. */
117 && unlikely (fchmod (elf
->fildes
, st
.st_mode
) != 0))
119 __libelf_seterrno (ELF_E_WRITE_ERROR
);
123 if (size
!= -1 && elf
->parent
== NULL
)
124 elf
->maximum_size
= size
;
131 elf_update (elf
, cmd
)
139 if (cmd
!= ELF_C_NULL
140 && cmd
!= ELF_C_WRITE
141 && unlikely (cmd
!= ELF_C_WRITE_MMAP
))
143 __libelf_seterrno (ELF_E_INVALID_CMD
);
150 if (elf
->kind
!= ELF_K_ELF
)
152 __libelf_seterrno (ELF_E_INVALID_HANDLE
);
156 rwlock_wrlock (elf
->lock
);
158 /* Make sure we have an ELF header. */
159 if (elf
->state
.elf
.ehdr
== NULL
)
161 __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR
);
166 /* Determine the number of sections. */
167 shnum
= (elf
->state
.elf
.scns_last
->cnt
== 0
169 : 1 + elf
->state
.elf
.scns_last
->data
[elf
->state
.elf
.scns_last
->cnt
- 1].index
);
171 /* Update the ELF descriptor. First, place the program header. It
172 will come right after the ELF header. The count the size of all
173 sections and finally place the section table. */
174 size
= (elf
->class == ELFCLASS32
175 ? __elf32_updatenull_wrlock (elf
, &change_bo
, shnum
)
176 : __elf64_updatenull_wrlock (elf
, &change_bo
, shnum
));
177 if (likely (size
!= -1)
178 /* See whether we actually have to write out the data. */
179 && (cmd
== ELF_C_WRITE
|| cmd
== ELF_C_WRITE_MMAP
))
181 if (elf
->cmd
!= ELF_C_RDWR
182 && elf
->cmd
!= ELF_C_RDWR_MMAP
183 && elf
->cmd
!= ELF_C_WRITE
184 && unlikely (elf
->cmd
!= ELF_C_WRITE_MMAP
))
186 __libelf_seterrno (ELF_E_UPDATE_RO
);
189 else if (unlikely (elf
->fildes
== -1))
191 /* We closed the file already. */
192 __libelf_seterrno (ELF_E_FD_DISABLED
);
196 size
= write_file (elf
, size
, change_bo
, shnum
);
200 rwlock_unlock (elf
->lock
);