2 * Copyright (c) 2006-2010 Joseph Koshy
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * Update the internal data structures associated with an ELF object.
45 * Returns the size in bytes the ELF object would occupy in its file
48 * After a successful call to this function, the following structures
51 * - The ELF header is updated.
52 * - All sections are sorted in order of ascending addresses and their
53 * section header table entries updated. An error is signalled
54 * if an overlap was detected among sections.
55 * - All data descriptors associated with a section are sorted in order
56 * of ascending addresses. Overlaps, if detected, are signalled as
57 * errors. Other sanity checks for alignments, section types etc. are
60 * After a resync_elf() successfully returns, the ELF descriptor is
61 * ready for being handed over to _libelf_write_elf().
67 * XXX: how do we handle 'flags'.
71 * Compute the extents of a section, by looking at the data
72 * descriptors associated with it. The function returns zero if an
73 * error was detected. `*rc' holds the maximum file extent seen so
77 _libelf_compute_section_extents(Elf
*e
, Elf_Scn
*s
, off_t
*rc
)
84 uint64_t sh_align
, sh_entsize
, sh_offset
, sh_size
;
85 uint64_t scn_size
, scn_alignment
;
88 * We need to recompute library private data structures if one
89 * or more of the following is true:
90 * - The underlying Shdr structure has been marked `dirty'. Significant
91 * fields include: `sh_offset', `sh_type', `sh_size', `sh_addralign'.
92 * - The Elf_Data structures part of this section have been marked
93 * `dirty'. Affected members include `d_align', `d_offset', `d_type',
95 * - The section as a whole is `dirty', e.g., it has been allocated
96 * using elf_newscn(), or if a new Elf_Data structure was added using
99 * Each of these conditions would result in the ELF_F_DIRTY bit being
100 * set on the section descriptor's `s_flags' field.
105 if (ec
== ELFCLASS32
) {
106 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
107 sh_align
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_addralign
;
108 sh_entsize
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_entsize
;
109 sh_offset
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_offset
;
110 sh_size
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_size
;
112 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
113 sh_align
= s
->s_shdr
.s_shdr64
.sh_addralign
;
114 sh_entsize
= s
->s_shdr
.s_shdr64
.sh_entsize
;
115 sh_offset
= s
->s_shdr
.s_shdr64
.sh_offset
;
116 sh_size
= s
->s_shdr
.s_shdr64
.sh_size
;
119 if (sh_type
== SHT_NULL
|| sh_type
== SHT_NOBITS
)
123 * Use the data in the section header entry
124 * - for sections that are not marked as 'dirty', and,
125 * - for sections in ELF objects opened in in read/write mode
126 * for which data descriptors have not been retrieved.
128 if ((s
->s_flags
& ELF_F_DIRTY
) == 0 ||
129 ((e
->e_cmd
== ELF_C_RDWR
) && STAILQ_EMPTY(&s
->s_data
))) {
130 if ((size_t) *rc
< sh_offset
+ sh_size
)
131 *rc
= sh_offset
+ sh_size
;
135 elftype
= _libelf_xlate_shtype(sh_type
);
136 if (elftype
> ELF_T_LAST
) {
137 LIBELF_SET_ERROR(SECTION
, 0);
142 * Compute the extent of the data descriptors associated with
147 sh_align
= _libelf_falign(elftype
, ec
);
149 /* Compute the section alignment. */
150 STAILQ_FOREACH(d
, &s
->s_data
, d_next
) {
151 if (d
->d_type
!= elftype
) {
152 LIBELF_SET_ERROR(DATA
, 0);
155 if (d
->d_version
!= e
->e_version
) {
156 LIBELF_SET_ERROR(VERSION
, 0);
159 if ((d_align
= d
->d_align
) % sh_align
) {
160 LIBELF_SET_ERROR(LAYOUT
, 0);
163 if (d_align
== 0 || (d_align
& (d_align
- 1))) {
164 LIBELF_SET_ERROR(DATA
, 0);
167 if (d_align
> scn_alignment
)
168 scn_alignment
= d_align
;
173 STAILQ_FOREACH_SAFE(d
, &s
->s_data
, d_next
, td
) {
174 if (e
->e_flags
& ELF_F_LAYOUT
) {
175 if ((uint64_t) d
->d_off
+ d
->d_size
> scn_size
)
176 scn_size
= d
->d_off
+ d
->d_size
;
178 scn_size
= roundup2(scn_size
, scn_alignment
);
180 scn_size
+= d
->d_size
;
185 * If the application is requesting full control over the layout
186 * of the section, check its values for sanity.
188 if (e
->e_flags
& ELF_F_LAYOUT
) {
189 if (scn_alignment
> sh_align
|| sh_offset
% sh_align
||
190 sh_size
< scn_size
) {
191 LIBELF_SET_ERROR(LAYOUT
, 0);
196 * Otherwise compute the values in the section header.
199 if (scn_alignment
> sh_align
)
200 sh_align
= scn_alignment
;
203 * If the section entry size is zero, try and fill in an
204 * appropriate entry size. Per the elf(5) manual page
205 * sections without fixed-size entries should have their
206 * 'sh_entsize' field set to zero.
208 if (sh_entsize
== 0 &&
209 (sh_entsize
= _libelf_fsize(elftype
, ec
, e
->e_version
,
214 sh_offset
= roundup(*rc
, sh_align
);
216 if (ec
== ELFCLASS32
) {
217 s
->s_shdr
.s_shdr32
.sh_addralign
= (uint32_t) sh_align
;
218 s
->s_shdr
.s_shdr32
.sh_entsize
= (uint32_t) sh_entsize
;
219 s
->s_shdr
.s_shdr32
.sh_offset
= (uint32_t) sh_offset
;
220 s
->s_shdr
.s_shdr32
.sh_size
= (uint32_t) sh_size
;
222 s
->s_shdr
.s_shdr64
.sh_addralign
= sh_align
;
223 s
->s_shdr
.s_shdr64
.sh_entsize
= sh_entsize
;
224 s
->s_shdr
.s_shdr64
.sh_offset
= sh_offset
;
225 s
->s_shdr
.s_shdr64
.sh_size
= sh_size
;
229 if ((size_t) *rc
< sh_offset
+ sh_size
)
230 *rc
= sh_offset
+ sh_size
;
233 s
->s_offset
= sh_offset
;
239 * Insert a section in ascending order in the list
243 _libelf_insert_section(Elf
*e
, Elf_Scn
*s
)
246 uint64_t smax
, smin
, tmax
, tmin
;
249 smax
= smin
+ s
->s_size
;
252 STAILQ_FOREACH(t
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
254 tmax
= tmin
+ t
->s_size
;
258 * 't' lies entirely before 's': ...| t |...| s |...
262 } else if (smax
<= tmin
)
264 * 's' lies entirely before 't', and after 'prevt':
265 * ...| prevt |...| s |...| t |...
268 else { /* 's' and 't' overlap. */
269 LIBELF_SET_ERROR(LAYOUT
, 0);
275 STAILQ_INSERT_AFTER(&e
->e_u
.e_elf
.e_scn
, prevt
, s
, s_next
);
277 STAILQ_INSERT_HEAD(&e
->e_u
.e_elf
.e_scn
, s
, s_next
);
282 _libelf_resync_sections(Elf
*e
, off_t rc
)
286 size_t sh_type
, shdr_start
, shdr_end
;
292 * Make a pass through sections, computing the extent of each
293 * section. Order in increasing order of addresses.
297 STAILQ_FOREACH(s
, &e
->e_u
.e_elf
.e_scn
, s_next
)
298 if (_libelf_compute_section_extents(e
, s
, &nrc
) == 0)
301 STAILQ_FOREACH_SAFE(s
, &e
->e_u
.e_elf
.e_scn
, s_next
, ts
) {
302 if (ec
== ELFCLASS32
)
303 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
305 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
307 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
)
310 if (s
->s_offset
< (uint64_t) rc
) {
311 if (s
->s_offset
+ s
->s_size
< (uint64_t) rc
) {
313 * Try insert this section in the
314 * correct place in the list,
315 * detecting overlaps if any.
317 STAILQ_REMOVE(&e
->e_u
.e_elf
.e_scn
, s
, _Elf_Scn
,
319 if (_libelf_insert_section(e
, s
) == 0)
322 LIBELF_SET_ERROR(LAYOUT
, 0);
326 rc
= s
->s_offset
+ s
->s_size
;
330 * If the application is controlling file layout, check for an
331 * overlap between this section's extents and the SHDR table.
333 if (e
->e_flags
& ELF_F_LAYOUT
) {
335 if (e
->e_class
== ELFCLASS32
)
336 shdr_start
= e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
->e_shoff
;
338 shdr_start
= e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
->e_shoff
;
340 shdr_end
= shdr_start
+ _libelf_fsize(ELF_T_SHDR
, e
->e_class
,
341 e
->e_version
, e
->e_u
.e_elf
.e_nscn
);
343 STAILQ_FOREACH(s
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
344 if (s
->s_offset
>= shdr_end
||
345 s
->s_offset
+ s
->s_size
<= shdr_start
)
347 LIBELF_SET_ERROR(LAYOUT
, 0);
358 _libelf_resync_elf(Elf
*e
)
360 int ec
, eh_class
, eh_type
;
361 unsigned int eh_byteorder
, eh_version
;
364 off_t rc
, phoff
, shoff
;
373 assert(ec
== ELFCLASS32
|| ec
== ELFCLASS64
);
378 if ((ehdr
= _libelf_ehdr(e
, ec
, 0)) == NULL
)
384 if (ec
== ELFCLASS32
) {
385 eh_byteorder
= eh32
->e_ident
[EI_DATA
];
386 eh_class
= eh32
->e_ident
[EI_CLASS
];
387 phoff
= (uint64_t) eh32
->e_phoff
;
388 shoff
= (uint64_t) eh32
->e_shoff
;
389 eh_type
= eh32
->e_type
;
390 eh_version
= eh32
->e_version
;
392 eh_byteorder
= eh64
->e_ident
[EI_DATA
];
393 eh_class
= eh64
->e_ident
[EI_CLASS
];
394 phoff
= eh64
->e_phoff
;
395 shoff
= eh64
->e_shoff
;
396 eh_type
= eh64
->e_type
;
397 eh_version
= eh64
->e_version
;
400 if (eh_version
== EV_NONE
)
401 eh_version
= EV_CURRENT
;
403 if (eh_version
!= e
->e_version
) { /* always EV_CURRENT */
404 LIBELF_SET_ERROR(VERSION
, 0);
408 if (eh_class
!= e
->e_class
) {
409 LIBELF_SET_ERROR(CLASS
, 0);
413 if (e
->e_cmd
!= ELF_C_WRITE
&& eh_byteorder
!= e
->e_byteorder
) {
414 LIBELF_SET_ERROR(HEADER
, 0);
418 shnum
= e
->e_u
.e_elf
.e_nscn
;
419 phnum
= e
->e_u
.e_elf
.e_nphdr
;
421 e
->e_byteorder
= eh_byteorder
;
423 #define INITIALIZE_EHDR(E,EC,V) do { \
424 (E)->e_ident[EI_MAG0] = ELFMAG0; \
425 (E)->e_ident[EI_MAG1] = ELFMAG1; \
426 (E)->e_ident[EI_MAG2] = ELFMAG2; \
427 (E)->e_ident[EI_MAG3] = ELFMAG3; \
428 (E)->e_ident[EI_CLASS] = (EC); \
429 (E)->e_ident[EI_VERSION] = (V); \
430 (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \
432 (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \
433 ELF_T_PHDR, (EC), (V), (size_t) 1); \
434 (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \
438 if (ec
== ELFCLASS32
)
439 INITIALIZE_EHDR(eh32
, ec
, eh_version
);
441 INITIALIZE_EHDR(eh64
, ec
, eh_version
);
443 (void) elf_flagehdr(e
, ELF_C_SET
, ELF_F_DIRTY
);
445 rc
+= _libelf_fsize(ELF_T_EHDR
, ec
, eh_version
, (size_t) 1);
448 * Compute the layout the program header table, if one is
449 * present. The program header table needs to be aligned to a
450 * `natural' boundary.
453 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, eh_version
, phnum
);
454 align
= _libelf_falign(ELF_T_PHDR
, ec
);
456 if (e
->e_flags
& ELF_F_LAYOUT
) {
458 * Check offsets for sanity.
461 LIBELF_SET_ERROR(HEADER
, 0);
466 LIBELF_SET_ERROR(LAYOUT
, 0);
471 phoff
= roundup(rc
, align
);
478 * Compute the layout of the sections associated with the
482 if (e
->e_cmd
!= ELF_C_WRITE
&&
483 (e
->e_flags
& LIBELF_F_SHDRS_LOADED
) == 0 &&
484 _libelf_load_section_headers(e
, ehdr
) == 0)
487 if ((rc
= _libelf_resync_sections(e
, rc
)) < 0)
491 * Compute the space taken up by the section header table, if
492 * one is needed. If ELF_F_LAYOUT is asserted, the
493 * application may have placed the section header table in
494 * between existing sections, so the net size of the file need
495 * not increase due to the presence of the section header
499 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, eh_version
, (size_t) 1);
500 align
= _libelf_falign(ELF_T_SHDR
, ec
);
502 if (e
->e_flags
& ELF_F_LAYOUT
) {
504 LIBELF_SET_ERROR(LAYOUT
, 0);
508 shoff
= roundup(rc
, align
);
510 if (shoff
+ fsz
* shnum
> (size_t) rc
)
511 rc
= shoff
+ fsz
* shnum
;
516 * Set the fields of the Executable Header that could potentially use
517 * extended numbering.
519 _libelf_setphnum(e
, ehdr
, ec
, phnum
);
520 _libelf_setshnum(e
, ehdr
, ec
, shnum
);
523 * Update the `e_phoff' and `e_shoff' fields if the library is
526 if ((e
->e_flags
& ELF_F_LAYOUT
) == 0) {
527 if (ec
== ELFCLASS32
) {
528 eh32
->e_phoff
= (uint32_t) phoff
;
529 eh32
->e_shoff
= (uint32_t) shoff
;
531 eh64
->e_phoff
= (uint64_t) phoff
;
532 eh64
->e_shoff
= (uint64_t) shoff
;
540 * Write out the contents of a section.
544 _libelf_write_scn(Elf
*e
, char *nf
, Elf_Scn
*s
, off_t rc
)
547 size_t fsz
, msz
, nobjects
;
549 uint64_t sh_off
, sh_size
;
553 if ((ec
= e
->e_class
) == ELFCLASS32
) {
554 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
555 sh_size
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_size
;
557 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
558 sh_size
= s
->s_shdr
.s_shdr64
.sh_size
;
562 * Ignore sections that do not allocate space in the file.
564 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
|| sh_size
== 0)
567 elftype
= _libelf_xlate_shtype(sh_type
);
568 assert(elftype
>= ELF_T_FIRST
&& elftype
<= ELF_T_LAST
);
570 msz
= _libelf_msize(elftype
, ec
, e
->e_version
);
572 sh_off
= s
->s_offset
;
573 assert(sh_off
% _libelf_falign(elftype
, ec
) == 0);
576 * If the section has a `rawdata' descriptor, and the section
577 * contents have not been modified, use its contents directly.
578 * The `s_rawoff' member contains the offset into the original
579 * file, while `s_offset' contains its new location in the
583 if (STAILQ_EMPTY(&s
->s_data
)) {
585 if ((d
= elf_rawdata(s
, NULL
)) == NULL
)
588 STAILQ_FOREACH(d
, &s
->s_rawdata
, d_next
) {
589 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
590 (void) memset(nf
+ rc
,
591 LIBELF_PRIVATE(fillchar
), sh_off
+
593 rc
= sh_off
+ d
->d_off
;
595 assert(d
->d_buf
!= NULL
);
596 assert(d
->d_type
== ELF_T_BYTE
);
597 assert(d
->d_version
== e
->e_version
);
599 (void) memcpy(nf
+ rc
,
600 e
->e_rawfile
+ s
->s_rawoff
+ d
->d_off
, d
->d_size
);
609 * Iterate over the set of data descriptors for this section.
610 * The prior call to _libelf_resync_elf() would have setup the
611 * descriptors for this step.
614 dst
.d_version
= e
->e_version
;
616 STAILQ_FOREACH(d
, &s
->s_data
, d_next
) {
618 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
619 (void) memset(nf
+ rc
,
620 LIBELF_PRIVATE(fillchar
), sh_off
+ d
->d_off
- rc
);
622 rc
= sh_off
+ d
->d_off
;
624 assert(d
->d_buf
!= NULL
);
625 assert(d
->d_type
== (Elf_Type
) elftype
);
626 assert(d
->d_version
== e
->e_version
);
627 assert(d
->d_size
% msz
== 0);
629 nobjects
= d
->d_size
/ msz
;
631 fsz
= _libelf_fsize(elftype
, ec
, e
->e_version
, nobjects
);
636 if (_libelf_xlate(&dst
, d
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
647 * Write out the file image.
649 * The original file could have been mapped in with an ELF_C_RDWR
650 * command and the application could have added new content or
651 * re-arranged its sections before calling elf_update(). Consequently
652 * its not safe to work `in place' on the original file. So we
653 * malloc() the required space for the updated ELF object and build
654 * the object there and write it out to the underlying file at the
655 * end. Note that the application may have opened the underlying file
656 * in ELF_C_RDWR and only retrieved/modified a few sections. We take
657 * care to avoid translating file sections unnecessarily.
659 * Gaps in the coverage of the file by the file's sections will be
660 * filled with the fill character set by elf_fill(3).
664 _libelf_write_elf(Elf
*e
, off_t newsize
)
668 size_t fsz
, msz
, phnum
, shnum
;
669 uint64_t phoff
, shoff
;
677 assert(e
->e_kind
== ELF_K_ELF
);
678 assert(e
->e_cmd
!= ELF_C_READ
);
679 assert(e
->e_fd
>= 0);
681 if ((newfile
= malloc((size_t) newsize
)) == NULL
) {
682 LIBELF_SET_ERROR(RESOURCE
, errno
);
688 ehdr
= _libelf_ehdr(e
, ec
, 0);
689 assert(ehdr
!= NULL
);
691 phnum
= e
->e_u
.e_elf
.e_nphdr
;
693 if (ec
== ELFCLASS32
) {
694 eh32
= (Elf32_Ehdr
*) ehdr
;
696 phoff
= (uint64_t) eh32
->e_phoff
;
697 shnum
= eh32
->e_shnum
;
698 shoff
= (uint64_t) eh32
->e_shoff
;
700 eh64
= (Elf64_Ehdr
*) ehdr
;
702 phoff
= eh64
->e_phoff
;
703 shnum
= eh64
->e_shnum
;
704 shoff
= eh64
->e_shoff
;
707 fsz
= _libelf_fsize(ELF_T_EHDR
, ec
, e
->e_version
, (size_t) 1);
708 msz
= _libelf_msize(ELF_T_EHDR
, ec
, e
->e_version
);
710 (void) memset(&dst
, 0, sizeof(dst
));
711 (void) memset(&src
, 0, sizeof(src
));
715 src
.d_type
= ELF_T_EHDR
;
716 src
.d_version
= dst
.d_version
= e
->e_version
;
720 dst
.d_buf
= newfile
+ rc
;
723 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
730 * Write the program header table if present.
733 if (phnum
!= 0 && phoff
!= 0) {
734 assert((unsigned) rc
<= phoff
);
736 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, e
->e_version
, phnum
);
738 assert(phoff
% _libelf_falign(ELF_T_PHDR
, ec
) == 0);
741 src
.d_buf
= _libelf_getphdr(e
, ec
);
742 src
.d_version
= dst
.d_version
= e
->e_version
;
743 src
.d_type
= ELF_T_PHDR
;
744 src
.d_size
= phnum
* _libelf_msize(ELF_T_PHDR
, ec
,
749 if ((uint64_t) rc
< phoff
)
750 (void) memset(newfile
+ rc
,
751 LIBELF_PRIVATE(fillchar
), phoff
- rc
);
753 dst
.d_buf
= newfile
+ rc
;
755 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
763 * Write out individual sections.
766 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
)
767 if ((rc
= _libelf_write_scn(e
, newfile
, scn
, rc
)) < 0)
771 * Write out the section header table, if required. Note that
772 * if flag ELF_F_LAYOUT has been set the section header table
773 * could reside in between byte ranges mapped by section
776 if (shnum
!= 0 && shoff
!= 0) {
777 if ((uint64_t) rc
< shoff
)
778 (void) memset(newfile
+ rc
,
779 LIBELF_PRIVATE(fillchar
), shoff
- rc
);
784 assert(rc
% _libelf_falign(ELF_T_SHDR
, ec
) == 0);
786 src
.d_type
= ELF_T_SHDR
;
787 src
.d_size
= _libelf_msize(ELF_T_SHDR
, ec
, e
->e_version
);
788 src
.d_version
= dst
.d_version
= e
->e_version
;
790 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, e
->e_version
, (size_t) 1);
792 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
793 if (ec
== ELFCLASS32
)
794 src
.d_buf
= &scn
->s_shdr
.s_shdr32
;
796 src
.d_buf
= &scn
->s_shdr
.s_shdr64
;
799 dst
.d_buf
= newfile
+ rc
+ scn
->s_ndx
* fsz
;
801 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
,
806 rc
+= e
->e_u
.e_elf
.e_nscn
* fsz
;
811 assert(rc
== newsize
);
814 * Write out the constructed contents and remap the file in
818 if (e
->e_rawfile
&& munmap(e
->e_rawfile
, e
->e_rawsize
) < 0) {
819 LIBELF_SET_ERROR(IO
, errno
);
823 if (write(e
->e_fd
, newfile
, (size_t) newsize
) != newsize
||
824 lseek(e
->e_fd
, (off_t
) 0, SEEK_SET
) < 0) {
825 LIBELF_SET_ERROR(IO
, errno
);
829 if (e
->e_cmd
!= ELF_C_WRITE
) {
830 if ((e
->e_rawfile
= mmap(NULL
, (size_t) newsize
, PROT_READ
,
831 MAP_PRIVATE
, e
->e_fd
, (off_t
) 0)) == MAP_FAILED
) {
832 LIBELF_SET_ERROR(IO
, errno
);
835 e
->e_rawsize
= newsize
;
839 * Reset flags, remove existing section descriptors and
840 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr()
841 * and elf_getscn() will function correctly.
844 e
->e_flags
&= ~ELF_F_DIRTY
;
846 STAILQ_FOREACH_SAFE(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
, tscn
)
847 _libelf_release_scn(scn
);
849 if (ec
== ELFCLASS32
) {
850 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
);
851 if (e
->e_u
.e_elf
.e_phdr
.e_phdr32
)
852 free(e
->e_u
.e_elf
.e_phdr
.e_phdr32
);
854 e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
= NULL
;
855 e
->e_u
.e_elf
.e_phdr
.e_phdr32
= NULL
;
857 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
);
858 if (e
->e_u
.e_elf
.e_phdr
.e_phdr64
)
859 free(e
->e_u
.e_elf
.e_phdr
.e_phdr64
);
861 e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
= NULL
;
862 e
->e_u
.e_elf
.e_phdr
.e_phdr64
= NULL
;
876 elf_update(Elf
*e
, Elf_Cmd c
)
883 if (e
== NULL
|| e
->e_kind
!= ELF_K_ELF
||
884 (c
!= ELF_C_NULL
&& c
!= ELF_C_WRITE
)) {
885 LIBELF_SET_ERROR(ARGUMENT
, 0);
889 if ((ec
= e
->e_class
) != ELFCLASS32
&& ec
!= ELFCLASS64
) {
890 LIBELF_SET_ERROR(CLASS
, 0);
894 if (e
->e_version
== EV_NONE
)
895 e
->e_version
= EV_CURRENT
;
897 if (c
== ELF_C_WRITE
&& e
->e_cmd
== ELF_C_READ
) {
898 LIBELF_SET_ERROR(MODE
, 0);
902 if ((rc
= _libelf_resync_elf(e
)) < 0)
908 if (e
->e_cmd
== ELF_C_READ
) {
910 * This descriptor was opened in read-only mode or by
914 LIBELF_SET_ERROR(MODE
, 0);
916 LIBELF_SET_ERROR(ARGUMENT
, 0);
921 LIBELF_SET_ERROR(SEQUENCE
, 0);
925 return (_libelf_write_elf(e
, rc
));