1 /* $NetBSD: elf_update.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2006-2011 Joseph Koshy
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #if HAVE_NBTOOL_CONFIG_H
30 # include "nbtool_config.h"
33 #include <sys/param.h>
50 __RCSID("$NetBSD: elf_update.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
51 ELFTC_VCSID("Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy ");
56 * - Case 1: ELF_F_LAYOUT is asserted
57 * In this case the application has full control over where the
58 * section header table, program header table, and section data
59 * will reside. The library only perform error checks.
61 * - Case 2: ELF_F_LAYOUT is not asserted
63 * The library will do the object layout using the following
65 * - The executable header is placed first, are required by the
67 * - The program header table is placed immediately following the
69 * - Section data, if any, is placed after the program header
70 * table, aligned appropriately.
71 * - The section header table, if needed, is placed last.
73 * There are two sub-cases to be taken care of:
75 * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR
77 * In this sub-case, the underlying ELF object may already have
78 * content in it, which the application may have modified. The
79 * library will retrieve content from the existing object as
82 * - Case 2b: e->e_cmd == ELF_C_WRITE
84 * The ELF object is being created afresh in this sub-case;
85 * there is no pre-existing content in the underlying ELF
90 * The types of extents in an ELF object.
100 * A extent descriptor, used when laying out an ELF object.
103 SLIST_ENTRY(_Elf_Extent
) ex_next
;
104 uint64_t ex_start
; /* Start of the region. */
105 uint64_t ex_size
; /* The size of the region. */
106 enum elf_extent ex_type
; /* Type of region. */
107 void *ex_desc
; /* Associated descriptor. */
110 SLIST_HEAD(_Elf_Extent_List
, _Elf_Extent
);
113 * Compute the extents of a section, by looking at the data
114 * descriptors associated with it. The function returns 1
115 * if successful, or zero if an error was detected.
118 _libelf_compute_section_extents(Elf
*e
, Elf_Scn
*s
, off_t rc
)
127 unsigned int elftype
;
128 struct _Libelf_Data
*ld
;
129 uint64_t scn_size
, scn_alignment
;
130 uint64_t sh_align
, sh_entsize
, sh_offset
, sh_size
;
134 shdr32
= &s
->s_shdr
.s_shdr32
;
135 shdr64
= &s
->s_shdr
.s_shdr64
;
136 if (ec
== ELFCLASS32
) {
137 sh_type
= shdr32
->sh_type
;
138 sh_align
= (uint64_t) shdr32
->sh_addralign
;
139 sh_entsize
= (uint64_t) shdr32
->sh_entsize
;
140 sh_offset
= (uint64_t) shdr32
->sh_offset
;
141 sh_size
= (uint64_t) shdr32
->sh_size
;
143 sh_type
= shdr64
->sh_type
;
144 sh_align
= shdr64
->sh_addralign
;
145 sh_entsize
= shdr64
->sh_entsize
;
146 sh_offset
= shdr64
->sh_offset
;
147 sh_size
= shdr64
->sh_size
;
150 assert(sh_type
!= SHT_NULL
&& sh_type
!= SHT_NOBITS
);
152 elftype
= _libelf_xlate_shtype(sh_type
);
153 if (elftype
> ELF_T_LAST
) {
154 LIBELF_SET_ERROR(SECTION
, 0);
159 sh_align
= _libelf_falign(elftype
, ec
);
162 * Compute the section's size and alignment using the data
163 * descriptors associated with the section.
165 if (STAILQ_EMPTY(&s
->s_data
)) {
167 * The section's content (if any) has not been read in
168 * yet. If section is not dirty marked dirty, we can
169 * reuse the values in the 'sh_size' and 'sh_offset'
170 * fields of the section header.
172 if ((s
->s_flags
& ELF_F_DIRTY
) == 0) {
174 * If the library is doing the layout, then we
175 * compute the new start offset for the
176 * section based on the current offset and the
177 * section's alignment needs.
179 * If the application is doing the layout, we
180 * can use the value in the 'sh_offset' field
181 * in the section header directly.
183 if (e
->e_flags
& ELF_F_LAYOUT
)
184 goto updatedescriptor
;
190 * Otherwise, we need to bring in the section's data
191 * from the underlying ELF object.
193 if (e
->e_cmd
!= ELF_C_WRITE
&& elf_getdata(s
, NULL
) == NULL
)
198 * Loop through the section's data descriptors.
202 STAILQ_FOREACH(ld
, &s
->s_data
, d_next
) {
207 * The data buffer's type is known.
209 if (d
->d_type
>= ELF_T_NUM
) {
210 LIBELF_SET_ERROR(DATA
, 0);
215 * The data buffer's version is supported.
217 if (d
->d_version
!= e
->e_version
) {
218 LIBELF_SET_ERROR(VERSION
, 0);
223 * The buffer's alignment is non-zero and a power of
226 if ((d_align
= d
->d_align
) == 0 ||
227 (d_align
& (d_align
- 1))) {
228 LIBELF_SET_ERROR(DATA
, 0);
233 * The buffer's size should be a multiple of the
234 * memory size of the underlying type.
236 msz
= _libelf_msize(d
->d_type
, ec
, e
->e_version
);
237 if (d
->d_size
% msz
) {
238 LIBELF_SET_ERROR(DATA
, 0);
243 * If the application is controlling layout, then the
244 * d_offset field should be compatible with the
245 * buffer's specified alignment.
247 if ((e
->e_flags
& ELF_F_LAYOUT
) &&
248 (d
->d_off
& (d_align
- 1))) {
249 LIBELF_SET_ERROR(LAYOUT
, 0);
254 * Compute the section's size.
256 if (e
->e_flags
& ELF_F_LAYOUT
) {
257 if ((uint64_t) d
->d_off
+ d
->d_size
> scn_size
)
258 scn_size
= d
->d_off
+ d
->d_size
;
260 scn_size
= roundup2(scn_size
, d
->d_align
);
262 fsz
= _libelf_fsize(d
->d_type
, ec
, d
->d_version
,
268 * The section's alignment is the maximum alignment
269 * needed for its data buffers.
271 if (d_align
> scn_alignment
)
272 scn_alignment
= d_align
;
277 * If the application is requesting full control over the
278 * layout of the section, check the section's specified size,
279 * offsets and alignment for sanity.
281 if (e
->e_flags
& ELF_F_LAYOUT
) {
282 if (scn_alignment
> sh_align
|| sh_offset
% sh_align
||
283 sh_size
< scn_size
) {
284 LIBELF_SET_ERROR(LAYOUT
, 0);
287 goto updatedescriptor
;
291 * Otherwise, compute the values in the section header.
293 * The section alignment is the maximum alignment for any of
294 * its contained data descriptors.
296 if (scn_alignment
> sh_align
)
297 sh_align
= scn_alignment
;
300 * If the section entry size is zero, try and fill in an
301 * appropriate entry size. Per the elf(5) manual page
302 * sections without fixed-size entries should have their
303 * 'sh_entsize' field set to zero.
305 if (sh_entsize
== 0 &&
306 (sh_entsize
= _libelf_fsize(elftype
, ec
, e
->e_version
,
314 * Compute the new offset for the section based on
315 * the section's alignment needs.
317 sh_offset
= roundup(rc
, sh_align
);
320 * Update the section header.
322 if (ec
== ELFCLASS32
) {
323 shdr32
->sh_addralign
= (uint32_t) sh_align
;
324 shdr32
->sh_entsize
= (uint32_t) sh_entsize
;
325 shdr32
->sh_offset
= (uint32_t) sh_offset
;
326 shdr32
->sh_size
= (uint32_t) sh_size
;
328 shdr64
->sh_addralign
= sh_align
;
329 shdr64
->sh_entsize
= sh_entsize
;
330 shdr64
->sh_offset
= sh_offset
;
331 shdr64
->sh_size
= sh_size
;
336 * Update the section descriptor.
339 s
->s_offset
= sh_offset
;
345 * Free a list of extent descriptors.
349 _libelf_release_extents(struct _Elf_Extent_List
*extents
)
351 struct _Elf_Extent
*ex
;
353 while ((ex
= SLIST_FIRST(extents
)) != NULL
) {
354 SLIST_REMOVE_HEAD(extents
, ex_next
);
360 * Check if an extent 's' defined by [start..start+size) is free.
361 * This routine assumes that the given extent list is sorted in order
362 * of ascending extent offsets.
366 _libelf_extent_is_unused(struct _Elf_Extent_List
*extents
,
367 const uint64_t start
, const uint64_t size
, struct _Elf_Extent
**prevt
)
370 struct _Elf_Extent
*t
, *pt
;
371 const uint64_t smax
= start
+ size
;
373 /* First, look for overlaps with existing extents. */
375 SLIST_FOREACH(t
, extents
, ex_next
) {
377 tmax
= tmin
+ t
->ex_size
;
381 * 't' lies entirely before 's': ...| t |...| s |...
385 } else if (smax
<= tmin
) {
387 * 's' lies entirely before 't', and after 'pt':
388 * ...| pt |...| s |...| t |...
391 pt
->ex_start
+ pt
->ex_size
<= start
);
394 /* 's' and 't' overlap. */
404 * Insert an extent into the list of extents.
408 _libelf_insert_extent(struct _Elf_Extent_List
*extents
, int type
,
409 uint64_t start
, uint64_t size
, void *desc
)
411 struct _Elf_Extent
*ex
, *prevt
;
413 assert(type
>= ELF_EXTENT_EHDR
&& type
<= ELF_EXTENT_SHDR
);
418 * If the requested range overlaps with an existing extent,
421 if (!_libelf_extent_is_unused(extents
, start
, size
, &prevt
)) {
422 LIBELF_SET_ERROR(LAYOUT
, 0);
426 /* Allocate and fill in a new extent descriptor. */
427 if ((ex
= malloc(sizeof(struct _Elf_Extent
))) == NULL
) {
428 LIBELF_SET_ERROR(RESOURCE
, errno
);
431 ex
->ex_start
= start
;
436 /* Insert the region descriptor into the list. */
438 SLIST_INSERT_AFTER(prevt
, ex
, ex_next
);
440 SLIST_INSERT_HEAD(extents
, ex
, ex_next
);
445 * Recompute section layout.
449 _libelf_resync_sections(Elf
*e
, off_t rc
, struct _Elf_Extent_List
*extents
)
458 * Make a pass through sections, computing the extent of each
461 STAILQ_FOREACH(s
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
462 if (ec
== ELFCLASS32
)
463 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
465 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
467 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
)
470 if (_libelf_compute_section_extents(e
, s
, rc
) == 0)
476 if (!_libelf_insert_extent(extents
, ELF_EXTENT_SECTION
,
477 s
->s_offset
, s
->s_size
, s
))
480 if ((size_t) rc
< s
->s_offset
+ s
->s_size
)
481 rc
= s
->s_offset
+ s
->s_size
;
488 * Recompute the layout of the ELF object and update the internal data
489 * structures associated with the ELF descriptor.
491 * Returns the size in bytes the ELF object would occupy in its file
494 * After a successful call to this function, the following structures
497 * - The ELF header is updated.
498 * - All extents in the ELF object are sorted in order of ascending
499 * addresses. Sections have their section header table entries
500 * updated. An error is signalled if an overlap was detected among
502 * - Data descriptors associated with sections are checked for valid
503 * types, offsets and alignment.
505 * After a resync_elf() successfully returns, the ELF descriptor is
506 * ready for being handed over to _libelf_write_elf().
510 _libelf_resync_elf(Elf
*e
, struct _Elf_Extent_List
*extents
)
513 unsigned int eh_byteorder
, eh_version
;
516 off_t rc
, phoff
, shoff
;
525 assert(ec
== ELFCLASS32
|| ec
== ELFCLASS64
);
530 if ((ehdr
= _libelf_ehdr(e
, ec
, 0)) == NULL
)
536 if (ec
== ELFCLASS32
) {
537 eh_byteorder
= eh32
->e_ident
[EI_DATA
];
538 eh_class
= eh32
->e_ident
[EI_CLASS
];
539 phoff
= (uint64_t) eh32
->e_phoff
;
540 shoff
= (uint64_t) eh32
->e_shoff
;
541 eh_version
= eh32
->e_version
;
543 eh_byteorder
= eh64
->e_ident
[EI_DATA
];
544 eh_class
= eh64
->e_ident
[EI_CLASS
];
545 phoff
= eh64
->e_phoff
;
546 shoff
= eh64
->e_shoff
;
547 eh_version
= eh64
->e_version
;
550 if (eh_version
== EV_NONE
)
551 eh_version
= EV_CURRENT
;
553 if (eh_version
!= e
->e_version
) { /* always EV_CURRENT */
554 LIBELF_SET_ERROR(VERSION
, 0);
558 if (eh_class
!= e
->e_class
) {
559 LIBELF_SET_ERROR(CLASS
, 0);
563 if (e
->e_cmd
!= ELF_C_WRITE
&& eh_byteorder
!= e
->e_byteorder
) {
564 LIBELF_SET_ERROR(HEADER
, 0);
568 shnum
= e
->e_u
.e_elf
.e_nscn
;
569 phnum
= e
->e_u
.e_elf
.e_nphdr
;
571 e
->e_byteorder
= eh_byteorder
;
573 #define INITIALIZE_EHDR(E,EC,V) do { \
574 (E)->e_ident[EI_MAG0] = ELFMAG0; \
575 (E)->e_ident[EI_MAG1] = ELFMAG1; \
576 (E)->e_ident[EI_MAG2] = ELFMAG2; \
577 (E)->e_ident[EI_MAG3] = ELFMAG3; \
578 (E)->e_ident[EI_CLASS] = (EC); \
579 (E)->e_ident[EI_VERSION] = (V); \
580 (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \
582 (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \
583 ELF_T_PHDR, (EC), (V), (size_t) 1); \
584 (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \
586 } while (/*CONSTCOND*/0)
588 if (ec
== ELFCLASS32
)
589 INITIALIZE_EHDR(eh32
, ec
, eh_version
);
591 INITIALIZE_EHDR(eh64
, ec
, eh_version
);
593 (void) elf_flagehdr(e
, ELF_C_SET
, ELF_F_DIRTY
);
595 rc
+= _libelf_fsize(ELF_T_EHDR
, ec
, eh_version
, (size_t) 1);
597 if (!_libelf_insert_extent(extents
, ELF_EXTENT_EHDR
, 0, rc
, ehdr
))
601 * Compute the layout the program header table, if one is
602 * present. The program header table needs to be aligned to a
603 * `natural' boundary.
606 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, eh_version
, phnum
);
607 align
= _libelf_falign(ELF_T_PHDR
, ec
);
609 if (e
->e_flags
& ELF_F_LAYOUT
) {
611 * Check offsets for sanity.
614 LIBELF_SET_ERROR(LAYOUT
, 0);
619 LIBELF_SET_ERROR(LAYOUT
, 0);
624 phoff
= roundup(rc
, align
);
628 phdr
= _libelf_getphdr(e
, ec
);
630 if (!_libelf_insert_extent(extents
, ELF_EXTENT_PHDR
, phoff
,
637 * Compute the layout of the sections associated with the
641 if (e
->e_cmd
!= ELF_C_WRITE
&&
642 (e
->e_flags
& LIBELF_F_SHDRS_LOADED
) == 0 &&
643 _libelf_load_section_headers(e
, ehdr
) == 0)
646 if ((rc
= _libelf_resync_sections(e
, rc
, extents
)) < 0)
650 * Compute the space taken up by the section header table, if
653 * If ELF_F_LAYOUT has been asserted, the application may have
654 * placed the section header table in between existing
655 * sections, so the net size of the file need not increase due
656 * to the presence of the section header table.
658 * If the library is responsible for laying out the object,
659 * the section header table is placed after section data.
662 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, eh_version
, shnum
);
663 align
= _libelf_falign(ELF_T_SHDR
, ec
);
665 if (e
->e_flags
& ELF_F_LAYOUT
) {
667 LIBELF_SET_ERROR(LAYOUT
, 0);
671 shoff
= roundup(rc
, align
);
673 if (shoff
+ fsz
> (size_t) rc
)
676 if (!_libelf_insert_extent(extents
, ELF_EXTENT_SHDR
, shoff
,
683 * Set the fields of the Executable Header that could potentially use
684 * extended numbering.
686 _libelf_setphnum(e
, ehdr
, ec
, phnum
);
687 _libelf_setshnum(e
, ehdr
, ec
, shnum
);
690 * Update the `e_phoff' and `e_shoff' fields if the library is
693 if ((e
->e_flags
& ELF_F_LAYOUT
) == 0) {
694 if (ec
== ELFCLASS32
) {
695 eh32
->e_phoff
= (uint32_t) phoff
;
696 eh32
->e_shoff
= (uint32_t) shoff
;
698 eh64
->e_phoff
= (uint64_t) phoff
;
699 eh64
->e_shoff
= (uint64_t) shoff
;
707 * Write out the contents of an ELF section.
711 _libelf_write_scn(Elf
*e
, char *nf
, struct _Elf_Extent
*ex
)
718 struct _Libelf_Data
*ld
;
719 uint64_t sh_off
, sh_size
;
720 size_t fsz
, msz
, nobjects
, rc
;
722 assert(ex
->ex_type
== ELF_EXTENT_SECTION
);
727 if ((ec
= e
->e_class
) == ELFCLASS32
) {
728 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
729 sh_size
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_size
;
731 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
732 sh_size
= s
->s_shdr
.s_shdr64
.sh_size
;
736 * Ignore sections that do not allocate space in the file.
738 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
|| sh_size
== 0)
741 elftype
= _libelf_xlate_shtype(sh_type
);
742 assert(elftype
>= ELF_T_FIRST
&& elftype
<= ELF_T_LAST
);
744 sh_off
= s
->s_offset
;
745 assert(sh_off
% _libelf_falign(elftype
, ec
) == 0);
748 * If the section has a `rawdata' descriptor, and the section
749 * contents have not been modified, use its contents directly.
750 * The `s_rawoff' member contains the offset into the original
751 * file, while `s_offset' contains its new location in the
755 if (STAILQ_EMPTY(&s
->s_data
)) {
757 if ((d
= elf_rawdata(s
, NULL
)) == NULL
)
760 STAILQ_FOREACH(ld
, &s
->s_rawdata
, d_next
) {
764 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
765 (void) memset(nf
+ rc
,
766 LIBELF_PRIVATE(fillchar
), sh_off
+
768 rc
= sh_off
+ d
->d_off
;
770 assert(d
->d_buf
!= NULL
);
771 assert(d
->d_type
== ELF_T_BYTE
);
772 assert(d
->d_version
== e
->e_version
);
774 (void) memcpy(nf
+ rc
,
775 e
->e_rawfile
+ s
->s_rawoff
+ d
->d_off
, d
->d_size
);
784 * Iterate over the set of data descriptors for this section.
785 * The prior call to _libelf_resync_elf() would have setup the
786 * descriptors for this step.
789 dst
.d_version
= e
->e_version
;
791 STAILQ_FOREACH(ld
, &s
->s_data
, d_next
) {
795 msz
= _libelf_msize(d
->d_type
, ec
, e
->e_version
);
797 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
798 (void) memset(nf
+ rc
,
799 LIBELF_PRIVATE(fillchar
), sh_off
+ d
->d_off
- rc
);
801 rc
= sh_off
+ d
->d_off
;
803 assert(d
->d_buf
!= NULL
);
804 assert(d
->d_version
== e
->e_version
);
805 assert(d
->d_size
% msz
== 0);
807 nobjects
= d
->d_size
/ msz
;
809 fsz
= _libelf_fsize(d
->d_type
, ec
, e
->e_version
, nobjects
);
814 if (_libelf_xlate(&dst
, d
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
825 * Write out an ELF Executable Header.
829 _libelf_write_ehdr(Elf
*e
, char *nf
, struct _Elf_Extent
*ex
)
836 assert(ex
->ex_type
== ELF_EXTENT_EHDR
);
837 assert(ex
->ex_start
== 0); /* Ehdr always comes first. */
841 ehdr
= _libelf_ehdr(e
, ec
, 0);
842 assert(ehdr
!= NULL
);
844 fsz
= _libelf_fsize(ELF_T_EHDR
, ec
, e
->e_version
, (size_t) 1);
845 msz
= _libelf_msize(ELF_T_EHDR
, ec
, e
->e_version
);
847 (void) memset(&dst
, 0, sizeof(dst
));
848 (void) memset(&src
, 0, sizeof(src
));
852 src
.d_type
= ELF_T_EHDR
;
853 src
.d_version
= dst
.d_version
= e
->e_version
;
858 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
862 return ((off_t
) fsz
);
866 * Write out an ELF program header table.
870 _libelf_write_phdr(Elf
*e
, char *nf
, struct _Elf_Extent
*ex
)
880 assert(ex
->ex_type
== ELF_EXTENT_PHDR
);
883 ehdr
= _libelf_ehdr(e
, ec
, 0);
884 phnum
= e
->e_u
.e_elf
.e_nphdr
;
888 if (ec
== ELFCLASS32
) {
889 eh32
= (Elf32_Ehdr
*) ehdr
;
890 phoff
= (uint64_t) eh32
->e_phoff
;
892 eh64
= (Elf64_Ehdr
*) ehdr
;
893 phoff
= eh64
->e_phoff
;
897 assert(ex
->ex_start
== phoff
);
898 assert(phoff
% _libelf_falign(ELF_T_PHDR
, ec
) == 0);
900 (void) memset(&dst
, 0, sizeof(dst
));
901 (void) memset(&src
, 0, sizeof(src
));
903 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, e
->e_version
, phnum
);
906 src
.d_buf
= _libelf_getphdr(e
, ec
);
907 src
.d_version
= dst
.d_version
= e
->e_version
;
908 src
.d_type
= ELF_T_PHDR
;
909 src
.d_size
= phnum
* _libelf_msize(ELF_T_PHDR
, ec
,
913 dst
.d_buf
= nf
+ ex
->ex_start
;
915 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
919 return (phoff
+ fsz
);
923 * Write out an ELF section header table.
927 _libelf_write_shdr(Elf
*e
, char *nf
, struct _Elf_Extent
*ex
)
938 assert(ex
->ex_type
== ELF_EXTENT_SHDR
);
941 ehdr
= _libelf_ehdr(e
, ec
, 0);
942 nscn
= e
->e_u
.e_elf
.e_nscn
;
944 if (ec
== ELFCLASS32
) {
945 eh32
= (Elf32_Ehdr
*) ehdr
;
946 shoff
= (uint64_t) eh32
->e_shoff
;
948 eh64
= (Elf64_Ehdr
*) ehdr
;
949 shoff
= eh64
->e_shoff
;
953 assert(shoff
% _libelf_falign(ELF_T_SHDR
, ec
) == 0);
954 assert(ex
->ex_start
== shoff
);
956 (void) memset(&dst
, 0, sizeof(dst
));
957 (void) memset(&src
, 0, sizeof(src
));
959 src
.d_type
= ELF_T_SHDR
;
960 src
.d_size
= _libelf_msize(ELF_T_SHDR
, ec
, e
->e_version
);
961 src
.d_version
= dst
.d_version
= e
->e_version
;
963 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, e
->e_version
, (size_t) 1);
965 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
966 if (ec
== ELFCLASS32
)
967 src
.d_buf
= &scn
->s_shdr
.s_shdr32
;
969 src
.d_buf
= &scn
->s_shdr
.s_shdr64
;
972 dst
.d_buf
= nf
+ ex
->ex_start
+ scn
->s_ndx
* fsz
;
974 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
,
979 return (ex
->ex_start
+ nscn
* fsz
);
983 * Write out the file image.
985 * The original file could have been mapped in with an ELF_C_RDWR
986 * command and the application could have added new content or
987 * re-arranged its sections before calling elf_update(). Consequently
988 * its not safe to work `in place' on the original file. So we
989 * malloc() the required space for the updated ELF object and build
990 * the object there and write it out to the underlying file at the
991 * end. Note that the application may have opened the underlying file
992 * in ELF_C_RDWR and only retrieved/modified a few sections. We take
993 * care to avoid translating file sections unnecessarily.
995 * Gaps in the coverage of the file by the file's sections will be
996 * filled with the fill character set by elf_fill(3).
1000 _libelf_write_elf(Elf
*e
, off_t newsize
, struct _Elf_Extent_List
*extents
)
1004 Elf_Scn
*scn
, *tscn
;
1005 struct _Elf_Extent
*ex
;
1007 assert(e
->e_kind
== ELF_K_ELF
);
1008 assert(e
->e_cmd
== ELF_C_RDWR
|| e
->e_cmd
== ELF_C_WRITE
);
1009 assert(e
->e_fd
>= 0);
1011 if ((newfile
= malloc((size_t) newsize
)) == NULL
) {
1012 LIBELF_SET_ERROR(RESOURCE
, errno
);
1013 return ((off_t
) -1);
1017 SLIST_FOREACH(ex
, extents
, ex_next
) {
1019 /* Fill inter-extent gaps. */
1020 if (ex
->ex_start
> (size_t) rc
)
1021 (void) memset(newfile
+ rc
, LIBELF_PRIVATE(fillchar
),
1024 switch (ex
->ex_type
) {
1025 case ELF_EXTENT_EHDR
:
1026 if ((nrc
= _libelf_write_ehdr(e
, newfile
, ex
)) < 0)
1030 case ELF_EXTENT_PHDR
:
1031 if ((nrc
= _libelf_write_phdr(e
, newfile
, ex
)) < 0)
1035 case ELF_EXTENT_SECTION
:
1036 if ((nrc
= _libelf_write_scn(e
, newfile
, ex
)) < 0)
1040 case ELF_EXTENT_SHDR
:
1041 if ((nrc
= _libelf_write_shdr(e
, newfile
, ex
)) < 0)
1050 assert(ex
->ex_start
+ ex
->ex_size
== (size_t) nrc
);
1056 assert(rc
== newsize
);
1059 * For regular files, throw away existing file content and
1060 * unmap any existing mappings.
1062 if ((e
->e_flags
& LIBELF_F_SPECIAL_FILE
) == 0) {
1063 if (ftruncate(e
->e_fd
, (off_t
) 0) < 0 ||
1064 lseek(e
->e_fd
, (off_t
) 0, SEEK_SET
)) {
1065 LIBELF_SET_ERROR(IO
, errno
);
1069 if (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
) {
1070 assert(e
->e_rawfile
!= NULL
);
1071 assert(e
->e_cmd
== ELF_C_RDWR
);
1072 if (munmap(e
->e_rawfile
, e
->e_rawsize
) < 0) {
1073 LIBELF_SET_ERROR(IO
, errno
);
1081 * Write out the new contents.
1083 if (write(e
->e_fd
, newfile
, (size_t) newsize
) != newsize
) {
1084 LIBELF_SET_ERROR(IO
, errno
);
1089 * For files opened in ELF_C_RDWR mode, set up the new 'raw'
1092 if (e
->e_cmd
== ELF_C_RDWR
) {
1093 assert(e
->e_rawfile
!= NULL
);
1094 assert((e
->e_flags
& LIBELF_F_RAWFILE_MALLOC
) ||
1095 (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
));
1096 if (e
->e_flags
& LIBELF_F_RAWFILE_MALLOC
) {
1098 e
->e_rawfile
= newfile
;
1102 else if (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
) {
1103 if ((e
->e_rawfile
= mmap(NULL
, (size_t) newsize
,
1104 PROT_READ
, MAP_PRIVATE
, e
->e_fd
, (off_t
) 0)) ==
1106 LIBELF_SET_ERROR(IO
, errno
);
1110 #endif /* ELFTC_HAVE_MMAP */
1112 /* Record the new size of the file. */
1113 e
->e_rawsize
= newsize
;
1115 /* File opened in ELF_C_WRITE mode. */
1116 assert(e
->e_rawfile
== NULL
);
1120 * Reset flags, remove existing section descriptors and
1121 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr()
1122 * and elf_getscn() will function correctly.
1125 e
->e_flags
&= ~ELF_F_DIRTY
;
1127 STAILQ_FOREACH_SAFE(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
, tscn
)
1128 _libelf_release_scn(scn
);
1130 if (e
->e_class
== ELFCLASS32
) {
1131 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
);
1132 if (e
->e_u
.e_elf
.e_phdr
.e_phdr32
)
1133 free(e
->e_u
.e_elf
.e_phdr
.e_phdr32
);
1135 e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
= NULL
;
1136 e
->e_u
.e_elf
.e_phdr
.e_phdr32
= NULL
;
1138 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
);
1139 if (e
->e_u
.e_elf
.e_phdr
.e_phdr64
)
1140 free(e
->e_u
.e_elf
.e_phdr
.e_phdr64
);
1142 e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
= NULL
;
1143 e
->e_u
.e_elf
.e_phdr
.e_phdr64
= NULL
;
1146 /* Free the temporary buffer. */
1155 return ((off_t
) -1);
1159 * Update an ELF object.
1163 elf_update(Elf
*e
, Elf_Cmd c
)
1167 struct _Elf_Extent_List extents
;
1171 if (e
== NULL
|| e
->e_kind
!= ELF_K_ELF
||
1172 (c
!= ELF_C_NULL
&& c
!= ELF_C_WRITE
)) {
1173 LIBELF_SET_ERROR(ARGUMENT
, 0);
1177 if ((ec
= e
->e_class
) != ELFCLASS32
&& ec
!= ELFCLASS64
) {
1178 LIBELF_SET_ERROR(CLASS
, 0);
1182 if (e
->e_version
== EV_NONE
)
1183 e
->e_version
= EV_CURRENT
;
1185 if (c
== ELF_C_WRITE
&& e
->e_cmd
== ELF_C_READ
) {
1186 LIBELF_SET_ERROR(MODE
, 0);
1190 SLIST_INIT(&extents
);
1192 if ((rc
= _libelf_resync_elf(e
, &extents
)) < 0)
1195 if (c
== ELF_C_NULL
)
1200 LIBELF_SET_ERROR(SEQUENCE
, 0);
1204 rc
= _libelf_write_elf(e
, rc
, &extents
);
1207 _libelf_release_extents(&extents
);