2 * Copyright (c) 2006 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
29 #include <sys/param.h>
31 #include <sys/sysmacros.h>
45 * Update the internal data structures associated with an ELF object.
46 * Returns the size in bytes the ELF object would occupy in its file
49 * After a successful call to this function, the following structures
52 * - The ELF header is updated.
53 * - All sections are sorted in order of ascending addresses and their
54 * section header table entries updated. An error is signalled
55 * if an overlap was detected among sections.
56 * - All data descriptors associated with a section are sorted in order
57 * of ascending addresses. Overlaps, if detected, are signalled as
58 * errors. Other sanity checks for alignments, section types etc. are
61 * After a resync_elf() successfully returns, the ELF descriptor is
62 * ready for being handed over to _libelf_write_elf().
68 * XXX: how do we handle 'flags'.
72 * Compute the extents of a section, by looking at the.
75 _libelf_compute_section_extents(Elf
*e
, Elf_Scn
*s
, off_t
*rc
)
82 uint64_t sh_align
, sh_entsize
, sh_offset
, sh_size
;
83 uint64_t scn_size
, scn_alignment
;
86 * We need to recompute library private data structures if one
87 * or more of the following is true:
88 * - The underlying Shdr structure has been marked `dirty'. Significant
89 * fields include: `sh_offset', `sh_type', `sh_size', `sh_addralign'.
90 * - The Elf_Data structures part of this section have been marked
91 * `dirty'. Affected members include `d_align', `d_offset', `d_type',
93 * - The section as a whole is `dirty', e.g., it has been allocated
94 * using elf_newscn(), or if a new Elf_Data structure was added using
97 * Each of these conditions would result in the ELF_F_DIRTY bit being
98 * set on the section descriptor's `s_flags' field.
103 if (ec
== ELFCLASS32
) {
104 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
105 sh_align
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_addralign
;
106 sh_entsize
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_entsize
;
107 sh_offset
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_offset
;
108 sh_size
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_size
;
110 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
111 sh_align
= s
->s_shdr
.s_shdr64
.sh_addralign
;
112 sh_entsize
= s
->s_shdr
.s_shdr64
.sh_entsize
;
113 sh_offset
= s
->s_shdr
.s_shdr64
.sh_offset
;
114 sh_size
= s
->s_shdr
.s_shdr64
.sh_size
;
117 if (sh_type
== SHT_NULL
|| sh_type
== SHT_NOBITS
)
120 if ((s
->s_flags
& ELF_F_DIRTY
) == 0) {
121 if ((size_t) *rc
< sh_offset
+ sh_size
)
122 *rc
= sh_offset
+ sh_size
;
126 elftype
= _libelf_xlate_shtype(sh_type
);
127 if (elftype
> ELF_T_LAST
) {
128 LIBELF_SET_ERROR(SECTION
, 0);
133 * Compute the extent of the data descriptors associated with
138 sh_align
= _libelf_falign(elftype
, ec
);
140 /* Compute the section alignment. */
141 STAILQ_FOREACH(d
, &s
->s_data
, d_next
) {
142 if (d
->d_type
!= elftype
) {
143 LIBELF_SET_ERROR(DATA
, 0);
146 if (d
->d_version
!= e
->e_version
) {
147 LIBELF_SET_ERROR(VERSION
, 0);
150 if ((d_align
= d
->d_align
) % sh_align
) {
151 LIBELF_SET_ERROR(LAYOUT
, 0);
154 if (d_align
== 0 || (d_align
& (d_align
- 1))) {
155 LIBELF_SET_ERROR(DATA
, 0);
158 if (d_align
> scn_alignment
)
159 scn_alignment
= d_align
;
164 STAILQ_FOREACH_SAFE(d
, &s
->s_data
, d_next
, td
) {
165 if (e
->e_flags
& ELF_F_LAYOUT
) {
166 if ((uint64_t) d
->d_off
+ d
->d_size
> scn_size
)
167 scn_size
= d
->d_off
+ d
->d_size
;
169 scn_size
= roundup(scn_size
, scn_alignment
);
171 scn_size
+= d
->d_size
;
176 * If the application is requesting full control over the layout
177 * of the section, check its values for sanity.
179 if (e
->e_flags
& ELF_F_LAYOUT
) {
180 if (scn_alignment
> sh_align
|| sh_offset
% sh_align
||
181 sh_size
< scn_size
) {
182 LIBELF_SET_ERROR(LAYOUT
, 0);
187 * Otherwise compute the values in the section header.
190 if (scn_alignment
> sh_align
)
191 sh_align
= scn_alignment
;
194 * If the section entry size is zero, try and fill in an
195 * appropriate entry size. Per the elf(5) manual page
196 * sections without fixed-size entries should have their
197 * 'sh_entsize' field set to zero.
199 if (sh_entsize
== 0 &&
200 (sh_entsize
= _libelf_fsize(elftype
, ec
, e
->e_version
,
205 sh_offset
= roundup(*rc
, sh_align
);
207 if (ec
== ELFCLASS32
) {
208 s
->s_shdr
.s_shdr32
.sh_addralign
= (uint32_t) sh_align
;
209 s
->s_shdr
.s_shdr32
.sh_entsize
= (uint32_t) sh_entsize
;
210 s
->s_shdr
.s_shdr32
.sh_offset
= (uint32_t) sh_offset
;
211 s
->s_shdr
.s_shdr32
.sh_size
= (uint32_t) sh_size
;
213 s
->s_shdr
.s_shdr64
.sh_addralign
= sh_align
;
214 s
->s_shdr
.s_shdr64
.sh_entsize
= sh_entsize
;
215 s
->s_shdr
.s_shdr64
.sh_offset
= sh_offset
;
216 s
->s_shdr
.s_shdr64
.sh_size
= sh_size
;
220 if ((size_t) *rc
< sh_offset
+ sh_size
)
221 *rc
= sh_offset
+ sh_size
;
224 s
->s_offset
= sh_offset
;
230 * Insert a section in ascending order in the list
234 _libelf_insert_section(Elf
*e
, Elf_Scn
*s
)
237 uint64_t smax
, smin
, tmax
, tmin
;
240 smax
= smin
+ s
->s_size
;
243 STAILQ_FOREACH(t
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
245 tmax
= tmin
+ t
->s_size
;
247 /* check if there is an overlap */
251 } else if (smax
< tmin
)
254 LIBELF_SET_ERROR(LAYOUT
, 0);
260 STAILQ_INSERT_AFTER(&e
->e_u
.e_elf
.e_scn
, prevt
, s
, s_next
);
262 STAILQ_INSERT_HEAD(&e
->e_u
.e_elf
.e_scn
, s
, s_next
);
267 _libelf_resync_sections(Elf
*e
, off_t rc
)
277 * Make a pass through sections, computing the extent of each
278 * section. Order in increasing order of addresses.
282 STAILQ_FOREACH(s
, &e
->e_u
.e_elf
.e_scn
, s_next
)
283 if (_libelf_compute_section_extents(e
, s
, &nrc
) == 0)
286 STAILQ_FOREACH_SAFE(s
, &e
->e_u
.e_elf
.e_scn
, s_next
, ts
) {
287 if (ec
== ELFCLASS32
)
288 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
290 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
292 /* XXX Do we need the 'size' field of an SHT_NOBITS section */
293 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
)
296 if (s
->s_offset
< (uint64_t) rc
) {
297 if (s
->s_offset
+ s
->s_size
< (uint64_t) rc
) {
299 * Try insert this section in the
300 * correct place in the list,
301 * detecting overlaps if any.
303 STAILQ_REMOVE(&e
->e_u
.e_elf
.e_scn
, s
, _Elf_Scn
,
305 if (_libelf_insert_section(e
, s
) == 0)
308 LIBELF_SET_ERROR(LAYOUT
, 0);
312 rc
= s
->s_offset
+ s
->s_size
;
321 _libelf_resync_elf(Elf
*e
)
323 int ec
, eh_class
, eh_type
;
324 unsigned int eh_byteorder
, eh_version
;
327 off_t rc
, phoff
, shoff
;
336 assert(ec
== ELFCLASS32
|| ec
== ELFCLASS64
);
341 if ((ehdr
= _libelf_ehdr(e
, ec
, 0)) == NULL
)
347 if (ec
== ELFCLASS32
) {
348 eh_byteorder
= eh32
->e_ident
[EI_DATA
];
349 eh_class
= eh32
->e_ident
[EI_CLASS
];
350 phoff
= (uint64_t) eh32
->e_phoff
;
351 shoff
= (uint64_t) eh32
->e_shoff
;
352 eh_type
= eh32
->e_type
;
353 eh_version
= eh32
->e_version
;
355 eh_byteorder
= eh64
->e_ident
[EI_DATA
];
356 eh_class
= eh64
->e_ident
[EI_CLASS
];
357 phoff
= eh64
->e_phoff
;
358 shoff
= eh64
->e_shoff
;
359 eh_type
= eh64
->e_type
;
360 eh_version
= eh64
->e_version
;
363 if (eh_version
== EV_NONE
)
364 eh_version
= EV_CURRENT
;
366 if (eh_version
!= e
->e_version
) { /* always EV_CURRENT */
367 LIBELF_SET_ERROR(VERSION
, 0);
371 if (eh_class
!= e
->e_class
) {
372 LIBELF_SET_ERROR(CLASS
, 0);
376 if (e
->e_cmd
!= ELF_C_WRITE
&& eh_byteorder
!= e
->e_byteorder
) {
377 LIBELF_SET_ERROR(HEADER
, 0);
381 shnum
= e
->e_u
.e_elf
.e_nscn
;
382 phnum
= e
->e_u
.e_elf
.e_nphdr
;
384 e
->e_byteorder
= eh_byteorder
;
386 #define INITIALIZE_EHDR(E,EC,V) do { \
387 (E)->e_ident[EI_MAG0] = ELFMAG0; \
388 (E)->e_ident[EI_MAG1] = ELFMAG1; \
389 (E)->e_ident[EI_MAG2] = ELFMAG2; \
390 (E)->e_ident[EI_MAG3] = ELFMAG3; \
391 (E)->e_ident[EI_CLASS] = (EC); \
392 (E)->e_ident[EI_VERSION] = (V); \
393 (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \
395 (E)->e_phentsize = _libelf_fsize(ELF_T_PHDR, (EC), (V), \
397 (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \
401 if (ec
== ELFCLASS32
)
402 INITIALIZE_EHDR(eh32
, ec
, eh_version
);
404 INITIALIZE_EHDR(eh64
, ec
, eh_version
);
406 (void) elf_flagehdr(e
, ELF_C_SET
, ELF_F_DIRTY
);
408 rc
+= _libelf_fsize(ELF_T_EHDR
, ec
, eh_version
, (size_t) 1);
411 * Compute the layout the program header table, if one is
412 * present. The program header table needs to be aligned to a
413 * `natural' boundary.
416 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, eh_version
, phnum
);
417 align
= _libelf_falign(ELF_T_PHDR
, ec
);
419 if (e
->e_flags
& ELF_F_LAYOUT
) {
421 * Check offsets for sanity.
424 LIBELF_SET_ERROR(HEADER
, 0);
429 LIBELF_SET_ERROR(LAYOUT
, 0);
434 phoff
= roundup(rc
, align
);
441 * Compute the layout of the sections associated with the
445 if ((rc
= _libelf_resync_sections(e
, rc
)) < 0)
449 * Compute the space taken up by the section header table, if
453 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, eh_version
, (size_t) 1);
454 align
= _libelf_falign(ELF_T_SHDR
, ec
);
456 if (e
->e_flags
& ELF_F_LAYOUT
) {
458 LIBELF_SET_ERROR(HEADER
, 0);
463 LIBELF_SET_ERROR(LAYOUT
, 0);
467 shoff
= roundup(rc
, align
);
469 rc
= shoff
+ fsz
* shnum
;
474 * Set the fields of the Executable Header that could potentially use
475 * extended numbering.
477 _libelf_setphnum(e
, ehdr
, ec
, phnum
);
478 _libelf_setshnum(e
, ehdr
, ec
, shnum
);
481 * Update the `e_phoff' and `e_shoff' fields if the library is
484 if ((e
->e_flags
& ELF_F_LAYOUT
) == 0) {
485 if (ec
== ELFCLASS32
) {
486 eh32
->e_phoff
= (uint32_t) phoff
;
487 eh32
->e_shoff
= (uint32_t) shoff
;
489 eh64
->e_phoff
= (uint64_t) phoff
;
490 eh64
->e_shoff
= (uint64_t) shoff
;
498 * Write out the contents of a section.
502 _libelf_write_scn(Elf
*e
, char *nf
, Elf_Scn
*s
, off_t rc
)
505 size_t fsz
, msz
, nobjects
;
511 if ((ec
= e
->e_class
) == ELFCLASS32
)
512 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
514 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
517 * Ignore sections that do not allocate space in the file.
519 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
)
523 elftype
= _libelf_xlate_shtype(sh_type
);
524 assert(elftype
>= ELF_T_FIRST
&& elftype
<= ELF_T_LAST
);
526 msz
= _libelf_msize(elftype
, ec
, e
->e_version
);
528 sh_off
= s
->s_offset
;
529 assert(sh_off
% _libelf_falign(elftype
, ec
) == 0);
532 * If the section has a `rawdata' descriptor, and the section
533 * contents have not been modified, use its contents directly.
534 * The `s_rawoff' member contains the offset into the original
535 * file, while `s_offset' contains its new location in the
539 if (STAILQ_EMPTY(&s
->s_data
)) {
541 if ((d
= elf_rawdata(s
, NULL
)) == NULL
)
544 STAILQ_FOREACH(d
, &s
->s_rawdata
, d_next
) {
545 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
546 (void) memset(nf
+ rc
,
547 LIBELF_PRIVATE(fillchar
), sh_off
+
549 rc
= sh_off
+ d
->d_off
;
551 assert(d
->d_buf
!= NULL
);
552 assert(d
->d_type
== ELF_T_BYTE
);
553 assert(d
->d_version
== e
->e_version
);
555 (void) memcpy(nf
+ rc
,
556 e
->e_rawfile
+ s
->s_rawoff
+ d
->d_off
, d
->d_size
);
565 * Iterate over the set of data descriptors for this section.
566 * The prior call to _libelf_resync_elf() would have setup the
567 * descriptors for this step.
570 dst
.d_version
= e
->e_version
;
572 STAILQ_FOREACH(d
, &s
->s_data
, d_next
) {
574 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
575 (void) memset(nf
+ rc
,
576 LIBELF_PRIVATE(fillchar
), sh_off
+ d
->d_off
- rc
);
578 rc
= sh_off
+ d
->d_off
;
580 assert(d
->d_buf
!= NULL
);
581 assert(d
->d_type
== (Elf_Type
) elftype
);
582 assert(d
->d_version
== e
->e_version
);
583 assert(d
->d_size
% msz
== 0);
585 nobjects
= d
->d_size
/ msz
;
587 fsz
= _libelf_fsize(elftype
, ec
, e
->e_version
, nobjects
);
592 if (_libelf_xlate(&dst
, d
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
603 * Write out the file image.
605 * The original file could have been mapped in with an ELF_C_RDWR
606 * command and the application could have added new content or
607 * re-arranged its sections before calling elf_update(). Consequently
608 * its not safe to work `in place' on the original file. So we
609 * malloc() the required space for the updated ELF object and build
610 * the object there and write it out to the underlying file at the
611 * end. Note that the application may have opened the underlying file
612 * in ELF_C_RDWR and only retrieved/modified a few sections. We take
613 * care to avoid translating file sections unnecessarily.
615 * Gaps in the coverage of the file by the file's sections will be
616 * filled with the fill character set by elf_fill(3).
620 _libelf_write_elf(Elf
*e
, off_t newsize
)
624 size_t fsz
, msz
, phnum
, shnum
;
625 uint64_t phoff
, shoff
;
633 assert(e
->e_kind
== ELF_K_ELF
);
634 assert(e
->e_cmd
!= ELF_C_READ
);
635 assert(e
->e_fd
>= 0);
637 if ((newfile
= malloc((size_t) newsize
)) == NULL
) {
638 LIBELF_SET_ERROR(RESOURCE
, errno
);
644 ehdr
= _libelf_ehdr(e
, ec
, 0);
645 assert(ehdr
!= NULL
);
647 phnum
= e
->e_u
.e_elf
.e_nphdr
;
649 if (ec
== ELFCLASS32
) {
650 eh32
= (Elf32_Ehdr
*) ehdr
;
652 phoff
= (uint64_t) eh32
->e_phoff
;
653 shnum
= eh32
->e_shnum
;
654 shoff
= (uint64_t) eh32
->e_shoff
;
656 eh64
= (Elf64_Ehdr
*) ehdr
;
658 phoff
= eh64
->e_phoff
;
659 shnum
= eh64
->e_shnum
;
660 shoff
= eh64
->e_shoff
;
663 fsz
= _libelf_fsize(ELF_T_EHDR
, ec
, e
->e_version
, (size_t) 1);
664 msz
= _libelf_msize(ELF_T_EHDR
, ec
, e
->e_version
);
666 (void) memset(&dst
, 0, sizeof(dst
));
667 (void) memset(&src
, 0, sizeof(src
));
671 src
.d_type
= ELF_T_EHDR
;
672 src
.d_version
= dst
.d_version
= e
->e_version
;
676 dst
.d_buf
= newfile
+ rc
;
679 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
686 * Write the program header table if present.
689 if (phnum
!= 0 && phoff
!= 0) {
690 assert((unsigned) rc
<= phoff
);
692 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, e
->e_version
, phnum
);
694 assert(phoff
% _libelf_falign(ELF_T_PHDR
, ec
) == 0);
697 src
.d_version
= dst
.d_version
= e
->e_version
;
698 src
.d_type
= ELF_T_PHDR
;
700 if (ec
== ELFCLASS32
)
701 src
.d_buf
= e
->e_u
.e_elf
.e_phdr
.e_phdr32
;
703 src
.d_buf
= e
->e_u
.e_elf
.e_phdr
.e_phdr64
;
705 src
.d_size
= phnum
* _libelf_msize(ELF_T_PHDR
, ec
,
710 if ((uint64_t) rc
< phoff
)
711 (void) memset(newfile
+ rc
,
712 LIBELF_PRIVATE(fillchar
), phoff
- rc
);
714 dst
.d_buf
= newfile
+ rc
;
716 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
724 * Write out individual sections.
727 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
)
728 if ((rc
= _libelf_write_scn(e
, newfile
, scn
, rc
)) < 0)
732 * Write out the section header table, if required.
735 if (shnum
!= 0 && shoff
!= 0) {
736 assert((unsigned) rc
<= shoff
);
738 if ((uint64_t) rc
< shoff
)
739 (void) memset(newfile
+ rc
,
740 LIBELF_PRIVATE(fillchar
), shoff
- rc
);
744 assert(rc
% _libelf_falign(ELF_T_SHDR
, ec
) == 0);
746 src
.d_type
= ELF_T_SHDR
;
747 src
.d_size
= _libelf_msize(ELF_T_SHDR
, ec
, e
->e_version
);
748 src
.d_version
= dst
.d_version
= e
->e_version
;
750 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, e
->e_version
, (size_t) 1);
752 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
753 if (ec
== ELFCLASS32
)
754 src
.d_buf
= &scn
->s_shdr
.s_shdr32
;
756 src
.d_buf
= &scn
->s_shdr
.s_shdr64
;
759 dst
.d_buf
= newfile
+ rc
;
761 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
,
772 assert(rc
== newsize
);
775 * Write out the constructed contents and remap the file in
779 if (e
->e_rawfile
&& munmap(e
->e_rawfile
, e
->e_rawsize
) < 0) {
780 LIBELF_SET_ERROR(IO
, errno
);
784 if (write(e
->e_fd
, newfile
, (size_t) newsize
) != newsize
||
785 lseek(e
->e_fd
, (off_t
) 0, SEEK_SET
) < 0) {
786 LIBELF_SET_ERROR(IO
, errno
);
790 if (e
->e_cmd
!= ELF_C_WRITE
) {
791 if ((e
->e_rawfile
= mmap(NULL
, (size_t) newsize
, PROT_READ
,
792 MAP_PRIVATE
, e
->e_fd
, (off_t
) 0)) == MAP_FAILED
) {
793 LIBELF_SET_ERROR(IO
, errno
);
796 e
->e_rawsize
= newsize
;
800 * Reset flags, remove existing section descriptors and
801 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr()
802 * and elf_getscn() will function correctly.
805 e
->e_flags
&= ~ELF_F_DIRTY
;
807 STAILQ_FOREACH_SAFE(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
, tscn
)
808 _libelf_release_scn(scn
);
810 if (ec
== ELFCLASS32
) {
811 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
);
812 if (e
->e_u
.e_elf
.e_phdr
.e_phdr32
)
813 free(e
->e_u
.e_elf
.e_phdr
.e_phdr32
);
815 e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
= NULL
;
816 e
->e_u
.e_elf
.e_phdr
.e_phdr32
= NULL
;
818 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
);
819 if (e
->e_u
.e_elf
.e_phdr
.e_phdr64
)
820 free(e
->e_u
.e_elf
.e_phdr
.e_phdr64
);
822 e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
= NULL
;
823 e
->e_u
.e_elf
.e_phdr
.e_phdr64
= NULL
;
835 elf_update(Elf
*e
, Elf_Cmd c
)
842 if (e
== NULL
|| e
->e_kind
!= ELF_K_ELF
||
843 (c
!= ELF_C_NULL
&& c
!= ELF_C_WRITE
)) {
844 LIBELF_SET_ERROR(ARGUMENT
, 0);
848 if ((ec
= e
->e_class
) != ELFCLASS32
&& ec
!= ELFCLASS64
) {
849 LIBELF_SET_ERROR(CLASS
, 0);
853 if (e
->e_version
== EV_NONE
)
854 e
->e_version
= EV_CURRENT
;
856 if (c
== ELF_C_WRITE
&& e
->e_cmd
== ELF_C_READ
) {
857 LIBELF_SET_ERROR(MODE
, 0);
861 if ((rc
= _libelf_resync_elf(e
)) < 0)
867 if (e
->e_cmd
== ELF_C_READ
) {
869 * This descriptor was opened in read-only mode or by
873 LIBELF_SET_ERROR(MODE
, 0);
875 LIBELF_SET_ERROR(ARGUMENT
, 0);
880 LIBELF_SET_ERROR(SEQUENCE
, 0);
884 return (_libelf_write_elf(e
, rc
));