2 * Copyright (c) 2006-2011 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
27 #include <sys/param.h>
44 ELFTC_VCSID("$Id: elf_update.c 3190 2015-05-04 15:23:08Z jkoshy $");
49 * - Case 1: ELF_F_LAYOUT is asserted
50 * In this case the application has full control over where the
51 * section header table, program header table, and section data
52 * will reside. The library only perform error checks.
54 * - Case 2: ELF_F_LAYOUT is not asserted
56 * The library will do the object layout using the following
58 * - The executable header is placed first, are required by the
60 * - The program header table is placed immediately following the
62 * - Section data, if any, is placed after the program header
63 * table, aligned appropriately.
64 * - The section header table, if needed, is placed last.
66 * There are two sub-cases to be taken care of:
68 * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR
70 * In this sub-case, the underlying ELF object may already have
71 * content in it, which the application may have modified. The
72 * library will retrieve content from the existing object as
75 * - Case 2b: e->e_cmd == ELF_C_WRITE
77 * The ELF object is being created afresh in this sub-case;
78 * there is no pre-existing content in the underlying ELF
83 * The types of extents in an ELF object.
93 * A extent descriptor, used when laying out an ELF object.
96 SLIST_ENTRY(_Elf_Extent
) ex_next
;
97 uint64_t ex_start
; /* Start of the region. */
98 uint64_t ex_size
; /* The size of the region. */
99 enum elf_extent ex_type
; /* Type of region. */
100 void *ex_desc
; /* Associated descriptor. */
103 SLIST_HEAD(_Elf_Extent_List
, _Elf_Extent
);
106 * Compute the extents of a section, by looking at the data
107 * descriptors associated with it. The function returns 1
108 * if successful, or zero if an error was detected.
111 _libelf_compute_section_extents(Elf
*e
, Elf_Scn
*s
, off_t rc
)
120 struct _Libelf_Data
*ld
;
121 uint64_t scn_size
, scn_alignment
;
122 uint64_t sh_align
, sh_entsize
, sh_offset
, sh_size
;
126 shdr32
= &s
->s_shdr
.s_shdr32
;
127 shdr64
= &s
->s_shdr
.s_shdr64
;
128 if (ec
== ELFCLASS32
) {
129 sh_type
= shdr32
->sh_type
;
130 sh_align
= (uint64_t) shdr32
->sh_addralign
;
131 sh_entsize
= (uint64_t) shdr32
->sh_entsize
;
132 sh_offset
= (uint64_t) shdr32
->sh_offset
;
133 sh_size
= (uint64_t) shdr32
->sh_size
;
135 sh_type
= shdr64
->sh_type
;
136 sh_align
= shdr64
->sh_addralign
;
137 sh_entsize
= shdr64
->sh_entsize
;
138 sh_offset
= shdr64
->sh_offset
;
139 sh_size
= shdr64
->sh_size
;
142 assert(sh_type
!= SHT_NULL
&& sh_type
!= SHT_NOBITS
);
144 elftype
= _libelf_xlate_shtype(sh_type
);
145 if (elftype
> ELF_T_LAST
) {
146 LIBELF_SET_ERROR(SECTION
, 0);
151 sh_align
= _libelf_falign(elftype
, ec
);
154 * Compute the section's size and alignment using the data
155 * descriptors associated with the section.
157 if (STAILQ_EMPTY(&s
->s_data
)) {
159 * The section's content (if any) has not been read in
160 * yet. If section is not dirty marked dirty, we can
161 * reuse the values in the 'sh_size' and 'sh_offset'
162 * fields of the section header.
164 if ((s
->s_flags
& ELF_F_DIRTY
) == 0) {
166 * If the library is doing the layout, then we
167 * compute the new start offset for the
168 * section based on the current offset and the
169 * section's alignment needs.
171 * If the application is doing the layout, we
172 * can use the value in the 'sh_offset' field
173 * in the section header directly.
175 if (e
->e_flags
& ELF_F_LAYOUT
)
176 goto updatedescriptor
;
182 * Otherwise, we need to bring in the section's data
183 * from the underlying ELF object.
185 if (e
->e_cmd
!= ELF_C_WRITE
&& elf_getdata(s
, NULL
) == NULL
)
190 * Loop through the section's data descriptors.
194 STAILQ_FOREACH(ld
, &s
->s_data
, d_next
) {
199 * The data buffer's type is known.
201 if (d
->d_type
>= ELF_T_NUM
) {
202 LIBELF_SET_ERROR(DATA
, 0);
207 * The data buffer's version is supported.
209 if (d
->d_version
!= e
->e_version
) {
210 LIBELF_SET_ERROR(VERSION
, 0);
215 * The buffer's alignment is non-zero and a power of
218 if ((d_align
= d
->d_align
) == 0 ||
219 (d_align
& (d_align
- 1))) {
220 LIBELF_SET_ERROR(DATA
, 0);
225 * The buffer's size should be a multiple of the
226 * memory size of the underlying type.
228 msz
= _libelf_msize(d
->d_type
, ec
, e
->e_version
);
229 if (d
->d_size
% msz
) {
230 LIBELF_SET_ERROR(DATA
, 0);
235 * If the application is controlling layout, then the
236 * d_offset field should be compatible with the
237 * buffer's specified alignment.
239 if ((e
->e_flags
& ELF_F_LAYOUT
) &&
240 (d
->d_off
& (d_align
- 1))) {
241 LIBELF_SET_ERROR(LAYOUT
, 0);
246 * Compute the section's size.
248 if (e
->e_flags
& ELF_F_LAYOUT
) {
249 if ((uint64_t) d
->d_off
+ d
->d_size
> scn_size
)
250 scn_size
= d
->d_off
+ d
->d_size
;
252 scn_size
= roundup2(scn_size
, d
->d_align
);
254 fsz
= _libelf_fsize(d
->d_type
, ec
, d
->d_version
,
255 (size_t) d
->d_size
/ msz
);
260 * The section's alignment is the maximum alignment
261 * needed for its data buffers.
263 if (d_align
> scn_alignment
)
264 scn_alignment
= d_align
;
269 * If the application is requesting full control over the
270 * layout of the section, check the section's specified size,
271 * offsets and alignment for sanity.
273 if (e
->e_flags
& ELF_F_LAYOUT
) {
274 if (scn_alignment
> sh_align
||
275 sh_offset
% sh_align
||
276 sh_size
< scn_size
||
277 sh_offset
% _libelf_falign(elftype
, ec
)) {
278 LIBELF_SET_ERROR(LAYOUT
, 0);
281 goto updatedescriptor
;
285 * Otherwise, compute the values in the section header.
287 * The section alignment is the maximum alignment for any of
288 * its contained data descriptors.
290 if (scn_alignment
> sh_align
)
291 sh_align
= scn_alignment
;
294 * If the section entry size is zero, try and fill in an
295 * appropriate entry size. Per the elf(5) manual page
296 * sections without fixed-size entries should have their
297 * 'sh_entsize' field set to zero.
299 if (sh_entsize
== 0 &&
300 (sh_entsize
= _libelf_fsize(elftype
, ec
, e
->e_version
,
308 * Compute the new offset for the section based on
309 * the section's alignment needs.
311 sh_offset
= roundup((uint64_t) rc
, sh_align
);
314 * Update the section header.
316 if (ec
== ELFCLASS32
) {
317 shdr32
->sh_addralign
= (uint32_t) sh_align
;
318 shdr32
->sh_entsize
= (uint32_t) sh_entsize
;
319 shdr32
->sh_offset
= (uint32_t) sh_offset
;
320 shdr32
->sh_size
= (uint32_t) sh_size
;
322 shdr64
->sh_addralign
= sh_align
;
323 shdr64
->sh_entsize
= sh_entsize
;
324 shdr64
->sh_offset
= sh_offset
;
325 shdr64
->sh_size
= sh_size
;
330 * Update the section descriptor.
333 s
->s_offset
= sh_offset
;
339 * Free a list of extent descriptors.
343 _libelf_release_extents(struct _Elf_Extent_List
*extents
)
345 struct _Elf_Extent
*ex
;
347 while ((ex
= SLIST_FIRST(extents
)) != NULL
) {
348 SLIST_REMOVE_HEAD(extents
, ex_next
);
354 * Check if an extent 's' defined by [start..start+size) is free.
355 * This routine assumes that the given extent list is sorted in order
356 * of ascending extent offsets.
360 _libelf_extent_is_unused(struct _Elf_Extent_List
*extents
,
361 const uint64_t start
, const uint64_t size
, struct _Elf_Extent
**prevt
)
364 struct _Elf_Extent
*t
, *pt
;
365 const uint64_t smax
= start
+ size
;
367 /* First, look for overlaps with existing extents. */
369 SLIST_FOREACH(t
, extents
, ex_next
) {
371 tmax
= tmin
+ t
->ex_size
;
375 * 't' lies entirely before 's': ...| t |...| s |...
379 } else if (smax
<= tmin
) {
381 * 's' lies entirely before 't', and after 'pt':
382 * ...| pt |...| s |...| t |...
385 pt
->ex_start
+ pt
->ex_size
<= start
);
388 /* 's' and 't' overlap. */
398 * Insert an extent into the list of extents.
402 _libelf_insert_extent(struct _Elf_Extent_List
*extents
, int type
,
403 uint64_t start
, uint64_t size
, void *desc
)
405 struct _Elf_Extent
*ex
, *prevt
;
407 assert(type
>= ELF_EXTENT_EHDR
&& type
<= ELF_EXTENT_SHDR
);
412 * If the requested range overlaps with an existing extent,
415 if (!_libelf_extent_is_unused(extents
, start
, size
, &prevt
)) {
416 LIBELF_SET_ERROR(LAYOUT
, 0);
420 /* Allocate and fill in a new extent descriptor. */
421 if ((ex
= malloc(sizeof(struct _Elf_Extent
))) == NULL
) {
422 LIBELF_SET_ERROR(RESOURCE
, errno
);
425 ex
->ex_start
= start
;
430 /* Insert the region descriptor into the list. */
432 SLIST_INSERT_AFTER(prevt
, ex
, ex_next
);
434 SLIST_INSERT_HEAD(extents
, ex
, ex_next
);
439 * Recompute section layout.
443 _libelf_resync_sections(Elf
*e
, off_t rc
, struct _Elf_Extent_List
*extents
)
452 * Make a pass through sections, computing the extent of each
455 STAILQ_FOREACH(s
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
456 if (ec
== ELFCLASS32
)
457 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
459 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
461 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
)
464 if (_libelf_compute_section_extents(e
, s
, rc
) == 0)
470 if (!_libelf_insert_extent(extents
, ELF_EXTENT_SECTION
,
471 s
->s_offset
, s
->s_size
, s
))
474 if ((size_t) rc
< s
->s_offset
+ s
->s_size
)
475 rc
= (off_t
) (s
->s_offset
+ s
->s_size
);
482 * Recompute the layout of the ELF object and update the internal data
483 * structures associated with the ELF descriptor.
485 * Returns the size in bytes the ELF object would occupy in its file
488 * After a successful call to this function, the following structures
491 * - The ELF header is updated.
492 * - All extents in the ELF object are sorted in order of ascending
493 * addresses. Sections have their section header table entries
494 * updated. An error is signalled if an overlap was detected among
496 * - Data descriptors associated with sections are checked for valid
497 * types, offsets and alignment.
499 * After a resync_elf() successfully returns, the ELF descriptor is
500 * ready for being handed over to _libelf_write_elf().
504 _libelf_resync_elf(Elf
*e
, struct _Elf_Extent_List
*extents
)
507 unsigned int eh_byteorder
, eh_version
;
510 off_t rc
, phoff
, shoff
;
519 assert(ec
== ELFCLASS32
|| ec
== ELFCLASS64
);
524 if ((ehdr
= _libelf_ehdr(e
, ec
, 0)) == NULL
)
530 if (ec
== ELFCLASS32
) {
531 eh_byteorder
= eh32
->e_ident
[EI_DATA
];
532 eh_class
= eh32
->e_ident
[EI_CLASS
];
533 phoff
= (off_t
) eh32
->e_phoff
;
534 shoff
= (off_t
) eh32
->e_shoff
;
535 eh_version
= eh32
->e_version
;
537 eh_byteorder
= eh64
->e_ident
[EI_DATA
];
538 eh_class
= eh64
->e_ident
[EI_CLASS
];
539 phoff
= (off_t
) eh64
->e_phoff
;
540 shoff
= (off_t
) eh64
->e_shoff
;
541 eh_version
= eh64
->e_version
;
544 if (phoff
< 0 || shoff
< 0) {
545 LIBELF_SET_ERROR(HEADER
, 0);
549 if (eh_version
== EV_NONE
)
550 eh_version
= EV_CURRENT
;
552 if (eh_version
!= e
->e_version
) { /* always EV_CURRENT */
553 LIBELF_SET_ERROR(VERSION
, 0);
557 if (eh_class
!= e
->e_class
) {
558 LIBELF_SET_ERROR(CLASS
, 0);
562 if (e
->e_cmd
!= ELF_C_WRITE
&& eh_byteorder
!= e
->e_byteorder
) {
563 LIBELF_SET_ERROR(HEADER
, 0);
567 shnum
= e
->e_u
.e_elf
.e_nscn
;
568 phnum
= e
->e_u
.e_elf
.e_nphdr
;
570 e
->e_byteorder
= eh_byteorder
;
572 #define INITIALIZE_EHDR(E,EC,V) do { \
573 unsigned int _version = (unsigned int) (V); \
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] = (unsigned char) (EC); \
579 (E)->e_ident[EI_VERSION] = (_version & 0xFFU); \
580 (E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \
581 (EC), _version, (size_t) 1); \
582 (E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \
583 _libelf_fsize(ELF_T_PHDR, (EC), _version, \
585 (E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \
586 (EC), _version, (size_t) 1); \
589 if (ec
== ELFCLASS32
)
590 INITIALIZE_EHDR(eh32
, ec
, eh_version
);
592 INITIALIZE_EHDR(eh64
, ec
, eh_version
);
594 (void) elf_flagehdr(e
, ELF_C_SET
, ELF_F_DIRTY
);
596 rc
+= (off_t
) _libelf_fsize(ELF_T_EHDR
, ec
, eh_version
, (size_t) 1);
598 if (!_libelf_insert_extent(extents
, ELF_EXTENT_EHDR
, 0, (uint64_t) rc
,
603 * Compute the layout the program header table, if one is
604 * present. The program header table needs to be aligned to a
605 * `natural' boundary.
608 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, eh_version
, phnum
);
609 align
= _libelf_falign(ELF_T_PHDR
, ec
);
611 if (e
->e_flags
& ELF_F_LAYOUT
) {
613 * Check offsets for sanity.
616 LIBELF_SET_ERROR(LAYOUT
, 0);
620 if (phoff
% (off_t
) align
) {
621 LIBELF_SET_ERROR(LAYOUT
, 0);
626 phoff
= roundup(rc
, (off_t
) align
);
628 rc
= phoff
+ (off_t
) fsz
;
630 phdr
= _libelf_getphdr(e
, ec
);
632 if (!_libelf_insert_extent(extents
, ELF_EXTENT_PHDR
,
633 (uint64_t) phoff
, fsz
, phdr
))
639 * Compute the layout of the sections associated with the
643 if (e
->e_cmd
!= ELF_C_WRITE
&&
644 (e
->e_flags
& LIBELF_F_SHDRS_LOADED
) == 0 &&
645 _libelf_load_section_headers(e
, ehdr
) == 0)
648 if ((rc
= _libelf_resync_sections(e
, rc
, extents
)) < 0)
652 * Compute the space taken up by the section header table, if
655 * If ELF_F_LAYOUT has been asserted, the application may have
656 * placed the section header table in between existing
657 * sections, so the net size of the file need not increase due
658 * to the presence of the section header table.
660 * If the library is responsible for laying out the object,
661 * the section header table is placed after section data.
664 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, eh_version
, shnum
);
665 align
= _libelf_falign(ELF_T_SHDR
, ec
);
667 if (e
->e_flags
& ELF_F_LAYOUT
) {
668 if (shoff
% (off_t
) align
) {
669 LIBELF_SET_ERROR(LAYOUT
, 0);
673 shoff
= roundup(rc
, (off_t
) align
);
675 if (shoff
+ (off_t
) fsz
> rc
)
676 rc
= shoff
+ (off_t
) fsz
;
678 if (!_libelf_insert_extent(extents
, ELF_EXTENT_SHDR
,
679 (uint64_t) shoff
, fsz
, NULL
))
685 * Set the fields of the Executable Header that could potentially use
686 * extended numbering.
688 _libelf_setphnum(e
, ehdr
, ec
, phnum
);
689 _libelf_setshnum(e
, ehdr
, ec
, shnum
);
692 * Update the `e_phoff' and `e_shoff' fields if the library is
695 if ((e
->e_flags
& ELF_F_LAYOUT
) == 0) {
696 if (ec
== ELFCLASS32
) {
697 eh32
->e_phoff
= (uint32_t) phoff
;
698 eh32
->e_shoff
= (uint32_t) shoff
;
700 eh64
->e_phoff
= (uint64_t) phoff
;
701 eh64
->e_shoff
= (uint64_t) shoff
;
709 * Write out the contents of an ELF section.
713 _libelf_write_scn(Elf
*e
, unsigned char *nf
, struct _Elf_Extent
*ex
)
721 struct _Libelf_Data
*ld
;
722 uint64_t sh_off
, sh_size
;
723 size_t fsz
, msz
, nobjects
;
725 assert(ex
->ex_type
== ELF_EXTENT_SECTION
);
728 rc
= (off_t
) ex
->ex_start
;
730 if ((ec
= e
->e_class
) == ELFCLASS32
) {
731 sh_type
= s
->s_shdr
.s_shdr32
.sh_type
;
732 sh_size
= (uint64_t) s
->s_shdr
.s_shdr32
.sh_size
;
734 sh_type
= s
->s_shdr
.s_shdr64
.sh_type
;
735 sh_size
= s
->s_shdr
.s_shdr64
.sh_size
;
739 * Ignore sections that do not allocate space in the file.
741 if (sh_type
== SHT_NOBITS
|| sh_type
== SHT_NULL
|| sh_size
== 0)
744 elftype
= _libelf_xlate_shtype(sh_type
);
745 assert(elftype
>= ELF_T_FIRST
&& elftype
<= ELF_T_LAST
);
747 sh_off
= s
->s_offset
;
748 assert(sh_off
% _libelf_falign(elftype
, ec
) == 0);
751 * If the section has a `rawdata' descriptor, and the section
752 * contents have not been modified, use its contents directly.
753 * The `s_rawoff' member contains the offset into the original
754 * file, while `s_offset' contains its new location in the
758 if (STAILQ_EMPTY(&s
->s_data
)) {
760 if ((d
= elf_rawdata(s
, NULL
)) == NULL
)
763 STAILQ_FOREACH(ld
, &s
->s_rawdata
, d_next
) {
767 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
768 (void) memset(nf
+ rc
,
769 LIBELF_PRIVATE(fillchar
),
770 (size_t) (sh_off
+ d
->d_off
-
772 rc
= (off_t
) (sh_off
+ d
->d_off
);
774 assert(d
->d_buf
!= NULL
);
775 assert(d
->d_type
== ELF_T_BYTE
);
776 assert(d
->d_version
== e
->e_version
);
778 (void) memcpy(nf
+ rc
,
779 e
->e_rawfile
+ s
->s_rawoff
+ d
->d_off
,
782 rc
+= (off_t
) d
->d_size
;
789 * Iterate over the set of data descriptors for this section.
790 * The prior call to _libelf_resync_elf() would have setup the
791 * descriptors for this step.
794 dst
.d_version
= e
->e_version
;
796 STAILQ_FOREACH(ld
, &s
->s_data
, d_next
) {
800 msz
= _libelf_msize(d
->d_type
, ec
, e
->e_version
);
802 if ((uint64_t) rc
< sh_off
+ d
->d_off
)
803 (void) memset(nf
+ rc
,
804 LIBELF_PRIVATE(fillchar
),
805 (size_t) (sh_off
+ d
->d_off
- (uint64_t) rc
));
807 rc
= (off_t
) (sh_off
+ d
->d_off
);
809 assert(d
->d_buf
!= NULL
);
810 assert(d
->d_version
== e
->e_version
);
811 assert(d
->d_size
% msz
== 0);
813 nobjects
= (size_t) (d
->d_size
/ msz
);
815 fsz
= _libelf_fsize(d
->d_type
, ec
, e
->e_version
, nobjects
);
820 if (_libelf_xlate(&dst
, d
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
831 * Write out an ELF Executable Header.
835 _libelf_write_ehdr(Elf
*e
, unsigned char *nf
, struct _Elf_Extent
*ex
)
842 assert(ex
->ex_type
== ELF_EXTENT_EHDR
);
843 assert(ex
->ex_start
== 0); /* Ehdr always comes first. */
847 ehdr
= _libelf_ehdr(e
, ec
, 0);
848 assert(ehdr
!= NULL
);
850 fsz
= _libelf_fsize(ELF_T_EHDR
, ec
, e
->e_version
, (size_t) 1);
851 msz
= _libelf_msize(ELF_T_EHDR
, ec
, e
->e_version
);
853 (void) memset(&dst
, 0, sizeof(dst
));
854 (void) memset(&src
, 0, sizeof(src
));
858 src
.d_type
= ELF_T_EHDR
;
859 src
.d_version
= dst
.d_version
= e
->e_version
;
864 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
868 return ((off_t
) fsz
);
872 * Write out an ELF program header table.
876 _libelf_write_phdr(Elf
*e
, unsigned char *nf
, struct _Elf_Extent
*ex
)
886 assert(ex
->ex_type
== ELF_EXTENT_PHDR
);
889 ehdr
= _libelf_ehdr(e
, ec
, 0);
890 phnum
= e
->e_u
.e_elf
.e_nphdr
;
894 if (ec
== ELFCLASS32
) {
895 eh32
= (Elf32_Ehdr
*) ehdr
;
896 phoff
= (uint64_t) eh32
->e_phoff
;
898 eh64
= (Elf64_Ehdr
*) ehdr
;
899 phoff
= eh64
->e_phoff
;
903 assert(ex
->ex_start
== phoff
);
904 assert(phoff
% _libelf_falign(ELF_T_PHDR
, ec
) == 0);
906 (void) memset(&dst
, 0, sizeof(dst
));
907 (void) memset(&src
, 0, sizeof(src
));
909 fsz
= _libelf_fsize(ELF_T_PHDR
, ec
, e
->e_version
, phnum
);
912 src
.d_buf
= _libelf_getphdr(e
, ec
);
913 src
.d_version
= dst
.d_version
= e
->e_version
;
914 src
.d_type
= ELF_T_PHDR
;
915 src
.d_size
= phnum
* _libelf_msize(ELF_T_PHDR
, ec
,
919 dst
.d_buf
= nf
+ ex
->ex_start
;
921 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
, ELF_TOFILE
) ==
925 return ((off_t
) (phoff
+ fsz
));
929 * Write out an ELF section header table.
933 _libelf_write_shdr(Elf
*e
, unsigned char *nf
, struct _Elf_Extent
*ex
)
944 assert(ex
->ex_type
== ELF_EXTENT_SHDR
);
947 ehdr
= _libelf_ehdr(e
, ec
, 0);
948 nscn
= e
->e_u
.e_elf
.e_nscn
;
950 if (ec
== ELFCLASS32
) {
951 eh32
= (Elf32_Ehdr
*) ehdr
;
952 shoff
= (uint64_t) eh32
->e_shoff
;
954 eh64
= (Elf64_Ehdr
*) ehdr
;
955 shoff
= eh64
->e_shoff
;
959 assert(shoff
% _libelf_falign(ELF_T_SHDR
, ec
) == 0);
960 assert(ex
->ex_start
== shoff
);
962 (void) memset(&dst
, 0, sizeof(dst
));
963 (void) memset(&src
, 0, sizeof(src
));
965 src
.d_type
= ELF_T_SHDR
;
966 src
.d_size
= _libelf_msize(ELF_T_SHDR
, ec
, e
->e_version
);
967 src
.d_version
= dst
.d_version
= e
->e_version
;
969 fsz
= _libelf_fsize(ELF_T_SHDR
, ec
, e
->e_version
, (size_t) 1);
971 STAILQ_FOREACH(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
) {
972 if (ec
== ELFCLASS32
)
973 src
.d_buf
= &scn
->s_shdr
.s_shdr32
;
975 src
.d_buf
= &scn
->s_shdr
.s_shdr64
;
978 dst
.d_buf
= nf
+ ex
->ex_start
+ scn
->s_ndx
* fsz
;
980 if (_libelf_xlate(&dst
, &src
, e
->e_byteorder
, ec
,
985 return ((off_t
) (ex
->ex_start
+ nscn
* fsz
));
989 * Write out the file image.
991 * The original file could have been mapped in with an ELF_C_RDWR
992 * command and the application could have added new content or
993 * re-arranged its sections before calling elf_update(). Consequently
994 * its not safe to work `in place' on the original file. So we
995 * malloc() the required space for the updated ELF object and build
996 * the object there and write it out to the underlying file at the
997 * end. Note that the application may have opened the underlying file
998 * in ELF_C_RDWR and only retrieved/modified a few sections. We take
999 * care to avoid translating file sections unnecessarily.
1001 * Gaps in the coverage of the file by the file's sections will be
1002 * filled with the fill character set by elf_fill(3).
1006 _libelf_write_elf(Elf
*e
, off_t newsize
, struct _Elf_Extent_List
*extents
)
1009 Elf_Scn
*scn
, *tscn
;
1010 struct _Elf_Extent
*ex
;
1011 unsigned char *newfile
;
1013 assert(e
->e_kind
== ELF_K_ELF
);
1014 assert(e
->e_cmd
== ELF_C_RDWR
|| e
->e_cmd
== ELF_C_WRITE
);
1015 assert(e
->e_fd
>= 0);
1017 if ((newfile
= malloc((size_t) newsize
)) == NULL
) {
1018 LIBELF_SET_ERROR(RESOURCE
, errno
);
1019 return ((off_t
) -1);
1023 SLIST_FOREACH(ex
, extents
, ex_next
) {
1025 /* Fill inter-extent gaps. */
1026 if (ex
->ex_start
> (size_t) rc
)
1027 (void) memset(newfile
+ rc
, LIBELF_PRIVATE(fillchar
),
1028 (size_t) (ex
->ex_start
- (uint64_t) rc
));
1030 switch (ex
->ex_type
) {
1031 case ELF_EXTENT_EHDR
:
1032 if ((nrc
= _libelf_write_ehdr(e
, newfile
, ex
)) < 0)
1036 case ELF_EXTENT_PHDR
:
1037 if ((nrc
= _libelf_write_phdr(e
, newfile
, ex
)) < 0)
1041 case ELF_EXTENT_SECTION
:
1042 if ((nrc
= _libelf_write_scn(e
, newfile
, ex
)) < 0)
1046 case ELF_EXTENT_SHDR
:
1047 if ((nrc
= _libelf_write_shdr(e
, newfile
, ex
)) < 0)
1056 assert(ex
->ex_start
+ ex
->ex_size
== (size_t) nrc
);
1062 assert(rc
== newsize
);
1065 * For regular files, throw away existing file content and
1066 * unmap any existing mappings.
1068 if ((e
->e_flags
& LIBELF_F_SPECIAL_FILE
) == 0) {
1069 if (ftruncate(e
->e_fd
, (off_t
) 0) < 0 ||
1070 lseek(e
->e_fd
, (off_t
) 0, SEEK_SET
)) {
1071 LIBELF_SET_ERROR(IO
, errno
);
1075 if (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
) {
1076 assert(e
->e_rawfile
!= NULL
);
1077 assert(e
->e_cmd
== ELF_C_RDWR
);
1078 if (munmap(e
->e_rawfile
, e
->e_rawsize
) < 0) {
1079 LIBELF_SET_ERROR(IO
, errno
);
1087 * Write out the new contents.
1089 if (write(e
->e_fd
, newfile
, (size_t) newsize
) != newsize
) {
1090 LIBELF_SET_ERROR(IO
, errno
);
1095 * For files opened in ELF_C_RDWR mode, set up the new 'raw'
1098 if (e
->e_cmd
== ELF_C_RDWR
) {
1099 assert(e
->e_rawfile
!= NULL
);
1100 assert((e
->e_flags
& LIBELF_F_RAWFILE_MALLOC
) ||
1101 (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
));
1102 if (e
->e_flags
& LIBELF_F_RAWFILE_MALLOC
) {
1104 e
->e_rawfile
= newfile
;
1108 else if (e
->e_flags
& LIBELF_F_RAWFILE_MMAP
) {
1109 if ((e
->e_rawfile
= mmap(NULL
, (size_t) newsize
,
1110 PROT_READ
, MAP_PRIVATE
, e
->e_fd
, (off_t
) 0)) ==
1112 LIBELF_SET_ERROR(IO
, errno
);
1116 #endif /* ELFTC_HAVE_MMAP */
1118 /* Record the new size of the file. */
1119 e
->e_rawsize
= (size_t) newsize
;
1121 /* File opened in ELF_C_WRITE mode. */
1122 assert(e
->e_rawfile
== NULL
);
1126 * Reset flags, remove existing section descriptors and
1127 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr()
1128 * and elf_getscn() will function correctly.
1131 e
->e_flags
&= ~ELF_F_DIRTY
;
1133 STAILQ_FOREACH_SAFE(scn
, &e
->e_u
.e_elf
.e_scn
, s_next
, tscn
)
1134 _libelf_release_scn(scn
);
1136 if (e
->e_class
== ELFCLASS32
) {
1137 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
);
1138 if (e
->e_u
.e_elf
.e_phdr
.e_phdr32
)
1139 free(e
->e_u
.e_elf
.e_phdr
.e_phdr32
);
1141 e
->e_u
.e_elf
.e_ehdr
.e_ehdr32
= NULL
;
1142 e
->e_u
.e_elf
.e_phdr
.e_phdr32
= NULL
;
1144 free(e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
);
1145 if (e
->e_u
.e_elf
.e_phdr
.e_phdr64
)
1146 free(e
->e_u
.e_elf
.e_phdr
.e_phdr64
);
1148 e
->e_u
.e_elf
.e_ehdr
.e_ehdr64
= NULL
;
1149 e
->e_u
.e_elf
.e_phdr
.e_phdr64
= NULL
;
1152 /* Free the temporary buffer. */
1161 return ((off_t
) -1);
1165 * Update an ELF object.
1169 elf_update(Elf
*e
, Elf_Cmd c
)
1173 struct _Elf_Extent_List extents
;
1177 if (e
== NULL
|| e
->e_kind
!= ELF_K_ELF
||
1178 (c
!= ELF_C_NULL
&& c
!= ELF_C_WRITE
)) {
1179 LIBELF_SET_ERROR(ARGUMENT
, 0);
1183 if ((ec
= e
->e_class
) != ELFCLASS32
&& ec
!= ELFCLASS64
) {
1184 LIBELF_SET_ERROR(CLASS
, 0);
1188 if (e
->e_version
== EV_NONE
)
1189 e
->e_version
= EV_CURRENT
;
1191 if (c
== ELF_C_WRITE
&& e
->e_cmd
== ELF_C_READ
) {
1192 LIBELF_SET_ERROR(MODE
, 0);
1196 SLIST_INIT(&extents
);
1198 if ((rc
= _libelf_resync_elf(e
, &extents
)) < 0)
1201 if (c
== ELF_C_NULL
)
1206 LIBELF_SET_ERROR(SEQUENCE
, 0);
1210 rc
= _libelf_write_elf(e
, rc
, &extents
);
1213 _libelf_release_extents(&extents
);