4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1988 AT&T
26 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
36 * Type used to pass state information for the current
37 * file between routines.
43 Seg_Table
*b_e_seg_table
;
44 section_info_table
*sec_table
;
45 int64_t *off_table
; /* maintains section's offset; set to */
46 /* retain old offset, else 0 */
47 int64_t *nobits_table
; /* maintains NOBITS sections */
53 * Function prototypes.
55 static void copy_file(int, char *, Tmp_File
*);
57 copy_non_elf_to_temp_ar(int, Elf
*, int, Elf_Arhdr
*, char *, Cmd_Info
*);
58 static void copy_elf_file_to_temp_ar_file(int, Elf_Arhdr
*, char *);
59 static int process_file(Elf
*, char *, Cmd_Info
*);
60 static void initialize(int shnum
, Cmd_Info
*, file_state_t
*);
61 static int build_segment_table(Elf
*, GElf_Ehdr
*, file_state_t
*);
62 static int traverse_file(Elf
*, GElf_Ehdr
*, char *, Cmd_Info
*,
64 static uint64_t location(int64_t, int, Elf
*, file_state_t
*);
65 static uint64_t scn_location(Elf_Scn
*, Elf
*, file_state_t
*);
66 static int build_file(Elf
*, GElf_Ehdr
*, Cmd_Info
*, file_state_t
*);
67 static void post_process(Cmd_Info
*, file_state_t
*);
72 each_file(char *cur_file
, Cmd_Info
*cmd_info
)
77 Elf_Arhdr
*mem_header
;
78 char *cur_filenm
= NULL
;
80 int error
= 0, err
= 0;
86 if (cmd_info
->flags
& MIGHT_CHG
)
91 if ((fd
= open(cur_file
, oflag
)) == -1) {
92 error_message(OPEN_ERROR
, SYSTEM_ERROR
, strerror(errno
),
98 * Note, elf_begin requires ELF_C_READ even if MIGHT_CHK is in effect.
99 * libelf does not allow elf_begin() with ELF_C_RDWR when processing
100 * archive file members. Because we are limited to ELF_C_READ use, any
101 * ELF data modification must be provided by updating a copy of
102 * the data, rather than updating the original file data.
105 if ((arf
= elf_begin(fd
, cmd
, NULL
)) == NULL
) {
106 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
108 (void) close(fd
); /* done processing this file */
112 if ((elf_kind(arf
) == ELF_K_AR
)) {
114 if (CHK_OPT(cmd_info
, MIGHT_CHG
)) {
115 artmpfile
.tmp_name
= tempnam(TMPDIR
, "mcs2");
116 if ((fdartmp
= open(artmpfile
.tmp_name
,
117 O_WRONLY
| O_APPEND
| O_CREAT
,
118 (mode_t
)0666)) == -1) {
119 error_message(OPEN_TEMP_ERROR
,
120 SYSTEM_ERROR
, strerror(errno
),
126 artmpfile
.tmp_unlink
= 1;
127 /* write magic string to artmpfile */
128 if ((write(fdartmp
, ARMAG
, SARMAG
)) != SARMAG
) {
129 error_message(WRITE_ERROR
,
130 SYSTEM_ERROR
, strerror(errno
),
131 prog
, artmpfile
.tmp_name
, cur_file
);
137 cur_filenm
= cur_file
;
141 * Holds temporary file;
142 * if archive, holds the current member file if it has an ehdr,
143 * and there were no errors in
144 * processing the object file.
146 elftmpfile
.tmp_name
= tempnam(TMPDIR
, "mcs1");
148 while ((elf
= elf_begin(fd
, cmd
, arf
)) != 0) {
149 if (ar_file
) /* get header info */ {
152 if ((mem_header
= elf_getarhdr(elf
)) == NULL
) {
153 error_message(GETARHDR_ERROR
, LIBelf_ERROR
,
154 elf_errmsg(-1), prog
, cur_file
,
159 free_tempfile(&artmpfile
);
165 len
= (strlen(cur_file
) + 3 +
166 strlen(mem_header
->ar_name
));
168 if ((cur_filenm
= malloc(len
)) == NULL
) {
169 error_message(MALLOC_ERROR
,
170 PLAIN_ERROR
, NULL
, prog
);
174 (void) snprintf(cur_filenm
, len
, "%s[%s]",
175 cur_file
, mem_header
->ar_name
);
178 if (elf_kind(elf
) == ELF_K_ELF
) {
179 if ((code
= process_file(elf
, cur_filenm
, cmd_info
)) ==
187 copy_non_elf_to_temp_ar(fd
, elf
,
192 } else if (ar_file
&& CHK_OPT(cmd_info
, MIGHT_CHG
)) {
193 if (code
== DONT_BUILD
)
194 copy_non_elf_to_temp_ar(fd
, elf
,
198 copy_elf_file_to_temp_ar_file(
199 fdartmp
, mem_header
, cur_file
);
203 * decide what to do with non-ELF file
206 error_message(FILE_TYPE_ERROR
, PLAIN_ERROR
,
207 NULL
, prog
, cur_filenm
);
211 if (CHK_OPT(cmd_info
, MIGHT_CHG
))
212 copy_non_elf_to_temp_ar(fd
, elf
,
223 error_message(LIBELF_ERROR
, LIBelf_ERROR
,
224 elf_errmsg(err
), prog
);
225 error_message(NOT_MANIPULATED_ERROR
, PLAIN_ERROR
, NULL
,
232 if (ar_file
&& CHK_OPT(cmd_info
, MIGHT_CHG
)) {
233 (void) close(fdartmp
); /* done writing to ar_temp_file */
234 /* copy ar_temp_file to FILE */
235 copy_file(fd
, cur_file
, &artmpfile
);
236 } else if (code
!= DONT_BUILD
&& CHK_OPT(cmd_info
, MIGHT_CHG
))
237 copy_file(fd
, cur_file
, &elftmpfile
);
238 (void) close(fd
); /* done processing this file */
243 process_file(Elf
*elf
, char *cur_file
, Cmd_Info
*cmd_info
)
254 if (gelf_getehdr(elf
, &ehdr
) == NULL
) {
255 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
259 if (elf_getshdrnum(elf
, &shnum
) == -1) {
260 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
264 /* Initialize per-file state */
265 state
.Sect_exists
= 0;
266 state
.notesegndx
= -1;
267 state
.notesctndx
= -1;
268 state
.b_e_seg_table
= NULL
;
269 state
.sec_table
= NULL
;
271 state
.nobits_table
= NULL
;
272 state
.new_sec_string
= NULL
;
274 initialize(shnum
, cmd_info
, &state
);
276 if ((ehdr
.e_phnum
!= 0) &&
277 (build_segment_table(elf
, &ehdr
, &state
) == FAILURE
)) {
279 } else if ((x
= traverse_file(elf
, &ehdr
, cur_file
,
280 cmd_info
, &state
)) == FAILURE
) {
281 error_message(WRN_MANIPULATED_ERROR
, PLAIN_ERROR
, NULL
,
284 } else if (x
!= DONT_BUILD
&& x
!= FAILURE
) {
285 post_process(cmd_info
, &state
);
286 if (build_file(elf
, &ehdr
, cmd_info
, &state
) == FAILURE
) {
287 error_message(WRN_MANIPULATED_ERROR
, PLAIN_ERROR
,
288 NULL
, prog
, cur_file
);
293 /* Release any dynamicaly allocated buffers */
294 free(state
.b_e_seg_table
);
295 free(state
.sec_table
);
296 free(state
.off_table
);
297 free(state
.nobits_table
);
298 free(state
.new_sec_string
);
307 traverse_file(Elf
*elf
, GElf_Ehdr
* ehdr
, char *cur_file
, Cmd_Info
*cmd_info
,
315 section_info_table
* sinfo
;
317 int ret
= 0, SYM
= 0; /* used by strip command */
318 int phnum
= ehdr
->e_phnum
;
319 unsigned int i
, scn_index
;
320 size_t shstrndx
, shnum
;
322 state
->Sect_exists
= 0;
324 if (elf_getshdrnum(elf
, &shnum
) == -1) {
325 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
328 if (elf_getshdrstrndx(elf
, &shstrndx
) == -1) {
329 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
335 sinfo
= &state
->sec_table
[scn_index
];
336 while ((scn
= elf_nextscn(elf
, scn
)) != 0) {
339 shdr
= &(sinfo
->shdr
);
340 if (gelf_getshdr(scn
, shdr
) == NULL
) {
341 error_message(NO_SECT_TABLE_ERROR
,
342 LIBelf_ERROR
, elf_errmsg(-1), prog
, cur_file
);
347 * Note: If the object has problems, name
348 * may be set to NULL by the following.
350 name
= elf_strptr(elf
, shstrndx
, (size_t)shdr
->sh_name
);
353 sinfo
->secno
= scn_index
;
354 sinfo
->osecno
= scn_index
;
355 SET_ACTION(sinfo
->flags
, ACT_NOP
);
357 if (ehdr
->e_phnum
== 0)
358 SET_LOC(sinfo
->flags
, NOSEG
);
360 SET_LOC(sinfo
->flags
, scn_location(scn
, elf
, state
));
362 if (shdr
->sh_type
== SHT_GROUP
) {
363 if (aplist_append(&cmd_info
->sh_groups
,
364 sinfo
, 10) == NULL
) {
365 error_message(MALLOC_ERROR
, PLAIN_ERROR
,
372 * If the target section is pointed by a section
373 * holding relocation infomation, then the
374 * pointing section would be useless if the
375 * target section is removed.
377 if ((shdr
->sh_type
== SHT_REL
||
378 shdr
->sh_type
== SHT_RELA
) &&
379 (shdr
->sh_info
!= SHN_UNDEF
&&
380 (temp_scn
= elf_getscn(elf
, shdr
->sh_info
)) != 0)) {
382 if (gelf_getshdr(temp_scn
, &tmp_shdr
) != NULL
) {
383 temp_name
= elf_strptr(elf
, shstrndx
,
384 (size_t)tmp_shdr
.sh_name
);
385 sinfo
->rel_name
= temp_name
;
386 sinfo
->rel_scn_index
=
389 sinfo
->rel_loc
= NOSEG
;
392 scn_location(temp_scn
, elf
, state
);
396 if ((data
= elf_getdata(scn
, data
)) == NULL
) {
397 error_message(LIBELF_ERROR
,
398 LIBelf_ERROR
, elf_errmsg(-1), prog
);
404 * Check if this section is a candidate for
405 * action to be processes.
407 if ((name
!= NULL
) && (sectcmp(name
) == 0)) {
408 SET_CANDIDATE(sinfo
->flags
);
411 * This flag just shows that there was a
414 state
->Sect_exists
++;
418 * Any of the following section types should
419 * also be removed (if possible) if invoked via
420 * the 'strip' command.
422 if (CHK_OPT(cmd_info
, I_AM_STRIP
) &&
423 ((shdr
->sh_type
== SHT_SUNW_DEBUG
) ||
424 (shdr
->sh_type
== SHT_SUNW_DEBUGSTR
))) {
425 SET_CANDIDATE(sinfo
->flags
);
426 state
->Sect_exists
++;
433 if ((cmd_info
->flags
& zFLAG
) &&
434 (shdr
->sh_type
== SHT_PROGBITS
)) {
435 SET_CANDIDATE(sinfo
->flags
);
436 state
->Sect_exists
++;
438 x
= GET_LOC(sinfo
->flags
);
441 * Remember the note section index so that we can
442 * reset the NOTE segment offset to point to it. Depending
443 * on the operation being carried out, the note section may
444 * be assigned a new location in the resulting ELF
445 * image, and the program header needs to reflect that.
447 * There can be multiple contiguous note sections in
448 * an object, referenced by a single NOTE segment. We
449 * want to be sure and remember the one referenced by
450 * the program header, and not one of the others.
452 if ((shdr
->sh_type
== SHT_NOTE
) && (state
->notesctndx
== -1) &&
453 (state
->notesegndx
!= -1) &&
454 (state
->b_e_seg_table
[state
->notesegndx
].p_offset
456 state
->notesctndx
= scn_index
;
458 if (x
== IN
|| x
== PRIOR
)
459 state
->off_table
[scn_index
] = shdr
->sh_offset
;
460 if (shdr
->sh_type
== SHT_NOBITS
)
461 state
->nobits_table
[scn_index
] = 1;
464 * If this section satisfies the condition,
465 * apply the actions specified.
467 if (ISCANDIDATE(sinfo
->flags
)) {
468 ret
+= apply_action(sinfo
, cur_file
, cmd_info
);
472 * If I am strip command, determine if symtab can go or not.
474 if (CHK_OPT(cmd_info
, I_AM_STRIP
) &&
475 (CHK_OPT(cmd_info
, xFLAG
) == 0) &&
476 (CHK_OPT(cmd_info
, lFLAG
) == 0)) {
477 if (shdr
->sh_type
== SHT_SYMTAB
&&
478 GET_LOC(sinfo
->flags
) == AFTER
) {
485 sinfo
->scn
= (Elf_Scn
*) -1;
488 * If there were any errors traversing the file,
495 * Remove symbol table if possible
497 if (CHK_OPT(cmd_info
, I_AM_STRIP
) && SYM
!= 0) {
500 (void) gelf_getshdr(state
->sec_table
[SYM
].scn
, &tmp_shdr
);
501 state
->sec_table
[SYM
].secno
= (GElf_Word
)DELETED
;
502 ++(cmd_info
->no_of_nulled
);
503 if (state
->Sect_exists
== 0)
504 ++state
->Sect_exists
;
505 SET_ACTION(state
->sec_table
[SYM
].flags
, ACT_DELETE
);
506 state
->off_table
[SYM
] = 0;
508 * Can I remove section header
511 if ((tmp_shdr
.sh_link
< shnum
) &&
512 (tmp_shdr
.sh_link
!= SHN_UNDEF
) &&
513 (tmp_shdr
.sh_link
!= shstrndx
) &&
514 (GET_LOC(state
->sec_table
[tmp_shdr
.sh_link
].flags
) ==
516 state
->sec_table
[tmp_shdr
.sh_link
].secno
=
518 ++(cmd_info
->no_of_nulled
);
519 if (state
->Sect_exists
== 0)
520 ++state
->Sect_exists
;
521 SET_ACTION(state
->sec_table
[tmp_shdr
.sh_link
].flags
,
523 state
->off_table
[tmp_shdr
.sh_link
] = 0;
528 * If I only printed the contents, then
531 if (CHK_OPT(cmd_info
, pFLAG
) && !CHK_OPT(cmd_info
, MIGHT_CHG
))
532 return (DONT_BUILD
); /* don't bother creating a new file */
533 /* since the file has not changed */
536 * I might need to add a new section. Check it.
538 if (state
->Sect_exists
== 0 && CHK_OPT(cmd_info
, aFLAG
)) {
540 state
->new_sec_string
= calloc(1, cmd_info
->str_size
+ 1);
541 if (state
->new_sec_string
== NULL
)
543 for (act
= 0; act
< actmax
; act
++) {
544 if (Action
[act
].a_action
== ACT_APPEND
) {
545 (void) strcat(state
->new_sec_string
,
546 Action
[act
].a_string
);
547 (void) strcat(state
->new_sec_string
, "\n");
548 cmd_info
->no_of_append
= 1;
554 * If I did not append any new sections, and I did not
555 * modify/delete any sections, then just report so.
557 if ((state
->Sect_exists
== 0 && cmd_info
->no_of_append
== 0) ||
558 !CHK_OPT(cmd_info
, MIGHT_CHG
))
562 * Found at least one section which was processed.
563 * Deleted or Appended or Compressed.
565 if (state
->Sect_exists
) {
567 * First, handle the deleted sections.
569 if (cmd_info
->no_of_delete
!= 0 ||
570 cmd_info
->no_of_nulled
!= 0) {
575 * Handle relocation/target
578 sinfo
= &(state
->sec_table
[0]);
579 for (i
= 1; i
< shnum
; i
++) {
581 rel_idx
= sinfo
->rel_scn_index
;
586 * If I am removed, then remove my
589 if (((sinfo
->secno
==
590 (GElf_Word
)DELETED
) ||
592 (GElf_Word
)NULLED
)) &&
593 sinfo
->rel_loc
!= IN
) {
595 sec_table
[rel_idx
].flags
) == PRIOR
)
596 state
->sec_table
[rel_idx
].
597 secno
= (GElf_Word
)NULLED
;
599 state
->sec_table
[rel_idx
].
600 secno
= (GElf_Word
)DELETED
;
601 SET_ACTION(state
->sec_table
[rel_idx
].
606 * I am not removed. Check if my target is
607 * removed or nulled. If so, let me try to
610 if (((state
->sec_table
[rel_idx
].secno
==
611 (GElf_Word
)DELETED
) ||
612 (state
->sec_table
[rel_idx
].secno
==
613 (GElf_Word
)NULLED
)) &&
614 (GET_LOC(sinfo
->flags
) != IN
)) {
615 if (GET_LOC(sinfo
->flags
) ==
622 SET_ACTION(sinfo
->flags
, ACT_DELETE
);
627 * Now, take care of DELETED sections
629 sinfo
= &(state
->sec_table
[1]);
630 for (i
= 1; i
< shnum
; i
++) {
631 shdr
= &(sinfo
->shdr
);
632 if (sinfo
->secno
== (GElf_Word
)DELETED
) {
635 * The SHT_GROUP section which this
636 * section is a member may be able
637 * to be removed. See post_process().
639 if (shdr
->sh_flags
& SHF_GROUP
)
644 * The data buffer of SHT_GROUP this
645 * section is a member needs to be
646 * updated. See post_process().
649 if ((shdr
->sh_flags
& SHF_GROUP
) &&
660 * I know that the file has been modified.
661 * A new file need to be created.
667 build_file(Elf
*src_elf
, GElf_Ehdr
*src_ehdr
, Cmd_Info
*cmd_info
,
672 int new_sh_name
= 0; /* to hold the offset for the new */
678 size_t no_of_symbols
= 0;
679 section_info_table
*info
;
685 GElf_Off new_offset
= 0, r
;
686 size_t shnum
, shstrndx
;
689 if (elf_getshdrnum(src_elf
, &shnum
) == -1) {
690 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
693 if (elf_getshdrstrndx(src_elf
, &shstrndx
) == -1) {
694 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
698 if ((fdtmp
= open(elftmpfile
.tmp_name
, O_RDWR
| O_TRUNC
| O_CREAT
,
699 (mode_t
)0666)) == -1) {
700 error_message(OPEN_TEMP_ERROR
, SYSTEM_ERROR
, strerror(errno
),
701 prog
, elftmpfile
.tmp_name
);
704 elftmpfile
.tmp_unlink
= 1;
706 if ((dst_elf
= elf_begin(fdtmp
, ELF_C_WRITE
, (Elf
*) 0)) == NULL
) {
707 error_message(READ_ERROR
, LIBelf_ERROR
, elf_errmsg(-1),
708 prog
, elftmpfile
.tmp_name
);
713 if (gelf_newehdr(dst_elf
, gelf_getclass(src_elf
)) == 0) {
714 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
718 /* initialize dst_ehdr */
719 (void) gelf_getehdr(dst_elf
, &dst_ehdr
);
720 dst_ehdr
= *src_ehdr
;
723 * If we are removing the header string table section,
724 * remove the reference to it from the ELF header.
726 if ((shstrndx
!= SHN_UNDEF
) &&
727 (state
->sec_table
[shstrndx
].secno
== (GElf_Word
)DELETED
))
728 dst_ehdr
.e_shstrndx
= SHN_UNDEF
;
731 * flush the changes to the ehdr so the ident
732 * array and header string table index are filled in.
734 (void) gelf_update_ehdr(dst_elf
, &dst_ehdr
);
737 if (src_ehdr
->e_phnum
!= 0) {
738 (void) elf_flagelf(dst_elf
, ELF_C_SET
, ELF_F_LAYOUT
);
740 if (gelf_newphdr(dst_elf
, src_ehdr
->e_phnum
) == 0) {
741 error_message(LIBELF_ERROR
, LIBelf_ERROR
,
742 elf_errmsg(-1), prog
);
746 for (x
= 0; x
< src_ehdr
->e_phnum
; ++x
) {
751 (void) gelf_getphdr(src_elf
, (int)x
, &src
);
753 (void) gelf_getphdr(dst_elf
, (int)x
, &dst
);
754 (void) memcpy(&dst
, &src
, sizeof (GElf_Phdr
));
756 (void) gelf_update_phdr(dst_elf
, (int)x
, &dst
);
759 x
= location(dst_ehdr
.e_phoff
, 0, src_elf
, state
);
761 new_offset
= (GElf_Off
)src_ehdr
->e_ehsize
;
765 while ((src_scn
= state
->sec_table
[scn_no
].scn
) != (Elf_Scn
*) -1) {
766 info
= &state
->sec_table
[scn_no
];
767 /* If section should be copied to new file NOW */
768 if ((info
->secno
!= (GElf_Word
)DELETED
) &&
769 info
->secno
<= scn_no
) {
770 if ((dst_scn
= elf_newscn(dst_elf
)) == NULL
) {
771 error_message(LIBELF_ERROR
,
772 LIBelf_ERROR
, elf_errmsg(-1), prog
);
775 (void) gelf_getshdr(dst_scn
, &dst_shdr
);
776 (void) gelf_getshdr(info
->scn
, &src_shdr
);
777 (void) memcpy(&dst_shdr
, &src_shdr
, sizeof (GElf_Shdr
));
780 * Update link and info fields
781 * The sh_link field may have special values so
784 if ((src_shdr
.sh_link
>= shnum
) ||
785 (src_shdr
.sh_link
== 0))
786 dst_shdr
.sh_link
= src_shdr
.sh_link
;
787 else if ((int)state
->sec_table
[src_shdr
.sh_link
].secno
<
789 dst_shdr
.sh_link
= 0;
792 state
->sec_table
[src_shdr
.sh_link
].secno
;
794 if ((src_shdr
.sh_type
== SHT_REL
) ||
795 (src_shdr
.sh_type
== SHT_RELA
)) {
796 if ((src_shdr
.sh_info
>= shnum
) ||
797 ((int)state
->sec_table
[src_shdr
.
799 dst_shdr
.sh_info
= 0;
801 dst_shdr
.sh_info
= state
->
802 sec_table
[src_shdr
.sh_info
].secno
;
805 data
= state
->sec_table
[scn_no
].data
;
806 if ((elf_data
= elf_newdata(dst_scn
)) == NULL
) {
807 error_message(LIBELF_ERROR
,
808 LIBelf_ERROR
, elf_errmsg(-1), prog
);
814 * SHT_{DYNSYM, SYMTAB} might need some change, as
815 * they may contain section symbols that reference
816 * removed sections. SHT_SUNW_LDYNSYM does not
817 * contain section symbols, and therefore does not
820 if (((src_shdr
.sh_type
== SHT_SYMTAB
) ||
821 (src_shdr
.sh_type
== SHT_DYNSYM
)) &&
822 src_shdr
.sh_entsize
!= 0 &&
823 (cmd_info
->no_of_delete
!= 0 ||
824 cmd_info
->no_of_nulled
!= 0)) {
827 no_of_symbols
= src_shdr
.sh_size
/
829 new_sym
= malloc(no_of_symbols
*
830 src_shdr
.sh_entsize
);
831 if (new_sym
== NULL
) {
832 error_message(MALLOC_ERROR
,
833 PLAIN_ERROR
, NULL
, prog
);
838 elf_data
->d_buf
= (void *) new_sym
;
839 for (c
= 0; c
< no_of_symbols
; c
++) {
842 (void) gelf_getsym(data
, c
, &csym
);
844 if ((csym
.st_shndx
< SHN_LORESERVE
) &&
845 (csym
.st_shndx
!= SHN_UNDEF
)) {
846 section_info_table
*i
;
848 sec_table
[csym
.st_shndx
];
849 if (((int)i
->secno
!=
851 ((int)i
->secno
!= NULLED
)) {
856 if (src_shdr
.sh_type
==
860 * this * symbol relates
864 * just change the shndx
871 * .dynsym, NULL it out.
885 (void) gelf_update_sym(elf_data
, c
,
890 /* update SHT_SYMTAB_SHNDX */
891 if ((src_shdr
.sh_type
== SHT_SYMTAB_SHNDX
) &&
892 (src_shdr
.sh_entsize
!= 0) &&
893 ((cmd_info
->no_of_delete
!= 0) ||
894 (cmd_info
->no_of_nulled
!= 0))) {
899 entcnt
= src_shdr
.sh_size
/
901 oldshndx
= data
->d_buf
;
902 newshndx
= malloc(entcnt
* src_shdr
.sh_entsize
);
903 if (newshndx
== NULL
) {
904 error_message(MALLOC_ERROR
,
905 PLAIN_ERROR
, NULL
, prog
);
908 elf_data
->d_buf
= (void *)newshndx
;
909 for (c
= 0; c
< entcnt
; c
++) {
910 if (oldshndx
[c
] != SHN_UNDEF
) {
911 section_info_table
*i
;
913 sec_table
[oldshndx
[c
]];
914 if (((int)i
->secno
!=
916 ((int)i
->secno
!= NULLED
))
917 newshndx
[c
] = i
->secno
;
928 * If the section is to be updated,
931 if (ISCANDIDATE(info
->flags
)) {
932 if ((GET_LOC(info
->flags
) == PRIOR
) &&
933 (((int)info
->secno
== NULLED
) ||
934 ((int)info
->secno
== EXPANDED
) ||
935 ((int)info
->secno
== SHRUNK
))) {
937 * The section is updated,
938 * but the position is not too
939 * good. Need to NULL this out.
941 dst_shdr
.sh_name
= 0;
942 dst_shdr
.sh_type
= SHT_PROGBITS
;
943 if ((int)info
->secno
!= NULLED
) {
944 (cmd_info
->no_of_moved
)++;
945 SET_MOVING(info
->flags
);
949 * The section is positioned AFTER,
950 * or there are no segments.
951 * It is safe to update this section.
953 data
= state
->sec_table
[scn_no
].mdata
;
955 dst_shdr
.sh_size
= elf_data
->d_size
;
958 /* add new section name to shstrtab? */
959 else if (!state
->Sect_exists
&&
960 (state
->new_sec_string
!= NULL
) &&
961 (scn_no
== shstrndx
) &&
962 (dst_shdr
.sh_type
== SHT_STRTAB
) &&
963 ((src_ehdr
->e_phnum
== 0) ||
964 ((x
= scn_location(dst_scn
, dst_elf
, state
))
969 sect_len
= strlen(SECT_NAME
);
970 if ((elf_data
->d_buf
=
971 malloc((dst_shdr
.sh_size
+
972 sect_len
+ 1))) == NULL
) {
973 error_message(MALLOC_ERROR
,
974 PLAIN_ERROR
, NULL
, prog
);
977 /* put original data plus new data in section */
978 (void) memcpy(elf_data
->d_buf
,
979 data
->d_buf
, data
->d_size
);
980 (void) memcpy(&((char *)elf_data
->d_buf
)
981 [data
->d_size
], SECT_NAME
, sect_len
+ 1);
983 new_sh_name
= (int)dst_shdr
.sh_size
;
984 dst_shdr
.sh_size
+= sect_len
+ 1;
985 elf_data
->d_size
+= sect_len
+ 1;
991 if (src_ehdr
->e_phnum
!= 0) {
993 * Compute section offset.
995 if (state
->off_table
[scn_no
] == 0) {
996 if (dst_shdr
.sh_addralign
!= 0) {
998 dst_shdr
.sh_addralign
;
1004 dst_shdr
.sh_offset
= new_offset
;
1005 elf_data
->d_off
= 0;
1007 if (state
->nobits_table
[scn_no
] == 0)
1009 state
->off_table
[scn_no
];
1011 if (state
->nobits_table
[scn_no
] == 0)
1012 new_offset
+= dst_shdr
.sh_size
;
1016 (void) gelf_update_shdr(dst_scn
, &dst_shdr
);
1022 * This is the real new section.
1024 if (!state
->Sect_exists
&& state
->new_sec_string
!= NULL
) {
1026 string_size
= strlen(state
->new_sec_string
) + 1;
1027 if ((dst_scn
= elf_newscn(dst_elf
)) == NULL
) {
1028 error_message(LIBELF_ERROR
,
1029 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1032 (void) gelf_getshdr(dst_scn
, &dst_shdr
);
1034 dst_shdr
.sh_name
= new_sh_name
;
1035 dst_shdr
.sh_type
= SHT_PROGBITS
;
1036 dst_shdr
.sh_flags
= 0;
1037 dst_shdr
.sh_addr
= 0;
1038 if (src_ehdr
->e_phnum
!= 0)
1039 dst_shdr
.sh_offset
= new_offset
;
1041 dst_shdr
.sh_offset
= 0;
1042 dst_shdr
.sh_size
= string_size
+ 1;
1043 dst_shdr
.sh_link
= 0;
1044 dst_shdr
.sh_info
= 0;
1045 dst_shdr
.sh_addralign
= 1;
1046 dst_shdr
.sh_entsize
= 0;
1047 (void) gelf_update_shdr(dst_scn
, &dst_shdr
); /* flush changes */
1049 if ((elf_data
= elf_newdata(dst_scn
)) == NULL
) {
1050 error_message(LIBELF_ERROR
,
1051 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1054 elf_data
->d_size
= string_size
+ 1;
1055 if ((elf_data
->d_buf
= (char *)
1056 calloc(1, string_size
+ 1)) == NULL
) {
1057 error_message(MALLOC_ERROR
,
1058 PLAIN_ERROR
, NULL
, prog
);
1061 (void) memcpy(&((char *)elf_data
->d_buf
)[1],
1062 state
->new_sec_string
, string_size
);
1063 elf_data
->d_align
= 1;
1064 new_offset
+= string_size
+ 1;
1068 * If there are sections which needed to be moved,
1071 if (cmd_info
->no_of_moved
!= 0) {
1073 info
= &state
->sec_table
[0];
1075 for (cnt
= 0; cnt
< shnum
; cnt
++, info
++) {
1076 if ((GET_MOVING(info
->flags
)) == 0)
1079 if ((src_scn
= elf_getscn(src_elf
, info
->osecno
)) ==
1081 error_message(LIBELF_ERROR
,
1082 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1085 if (gelf_getshdr(src_scn
, &src_shdr
) == NULL
) {
1086 error_message(LIBELF_ERROR
,
1087 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1090 if ((dst_scn
= elf_newscn(dst_elf
)) == NULL
) {
1091 error_message(LIBELF_ERROR
,
1092 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1095 if (gelf_getshdr(dst_scn
, &dst_shdr
) == NULL
) {
1096 error_message(LIBELF_ERROR
,
1097 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1100 dst_shdr
= src_shdr
;
1104 dst_shdr
.sh_offset
= new_offset
; /* UPDATE fields */
1105 dst_shdr
.sh_size
= data
->d_size
;
1107 if ((shnum
>= src_shdr
.sh_link
) ||
1108 (src_shdr
.sh_link
== 0))
1109 dst_shdr
.sh_link
= src_shdr
.sh_link
;
1112 state
->sec_table
[src_shdr
.sh_link
].osecno
;
1114 if ((shnum
>= src_shdr
.sh_info
) ||
1115 (src_shdr
.sh_info
== 0))
1116 dst_shdr
.sh_info
= src_shdr
.sh_info
;
1119 state
->sec_table
[src_shdr
.sh_info
].osecno
;
1120 (void) gelf_update_shdr(dst_scn
, &dst_shdr
);
1121 if ((elf_data
= elf_newdata(dst_scn
)) == NULL
) {
1122 error_message(LIBELF_ERROR
,
1123 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1126 (void) memcpy(elf_data
, data
, sizeof (Elf_Data
));
1128 new_offset
+= data
->d_size
;
1133 * In the event that the position of the sting table has changed,
1134 * as a result of deleted sections, update the ehdr->e_shstrndx.
1136 if ((shstrndx
> 0) && (shnum
> 0) &&
1137 (state
->sec_table
[shstrndx
].secno
< shnum
)) {
1138 if (state
->sec_table
[shstrndx
].secno
< SHN_LORESERVE
) {
1139 dst_ehdr
.e_shstrndx
=
1140 state
->sec_table
[dst_ehdr
.e_shstrndx
].secno
;
1146 * If shstrndx requires 'Extended ELF Sections'
1147 * then it is stored in shdr[0].sh_link
1149 dst_ehdr
.e_shstrndx
= SHN_XINDEX
;
1150 if ((_scn
= elf_getscn(dst_elf
, 0)) == NULL
) {
1151 error_message(LIBELF_ERROR
,
1152 LIBelf_ERROR
, elf_errmsg(-1), prog
);
1155 (void) gelf_getshdr(_scn
, &shdr0
);
1156 shdr0
.sh_link
= state
->sec_table
[shstrndx
].secno
;
1157 (void) gelf_update_shdr(_scn
, &shdr0
);
1161 if (src_ehdr
->e_phnum
!= 0) {
1162 size_t align
= gelf_fsize(dst_elf
, ELF_T_ADDR
, 1, EV_CURRENT
);
1164 /* UPDATE location of program header table */
1165 if (location(dst_ehdr
.e_phoff
, 0, dst_elf
, state
) == AFTER
) {
1166 r
= new_offset
% align
;
1168 new_offset
+= align
- r
;
1170 dst_ehdr
.e_phoff
= new_offset
;
1171 new_offset
+= dst_ehdr
.e_phnum
* dst_ehdr
.e_phentsize
;
1173 /* UPDATE location of section header table */
1174 if ((location(dst_ehdr
.e_shoff
, 0, src_elf
, state
) == AFTER
) ||
1175 ((location(dst_ehdr
.e_shoff
, 0, src_elf
, state
) == PRIOR
) &&
1176 (!state
->Sect_exists
&& state
->new_sec_string
!= NULL
))) {
1177 r
= new_offset
% align
;
1179 new_offset
+= align
- r
;
1181 dst_ehdr
.e_shoff
= new_offset
;
1185 * The NOTE segment is the one segment whos
1186 * sections might get moved by mcs processing.
1187 * Make sure that the NOTE segments offset points
1188 * to the .note section.
1190 if ((state
->notesegndx
!= -1) && (state
->notesctndx
!= -1) &&
1191 (state
->sec_table
[state
->notesctndx
].secno
)) {
1195 notescn
= elf_getscn(dst_elf
,
1196 state
->sec_table
[state
->notesctndx
].secno
);
1197 (void) gelf_getshdr(notescn
, &nshdr
);
1199 if (gelf_getclass(dst_elf
) == ELFCLASS32
) {
1200 Elf32_Phdr
* ph
= elf32_getphdr(dst_elf
) +
1203 ph
->p_offset
= (Elf32_Off
)nshdr
.sh_offset
;
1205 Elf64_Phdr
* ph
= elf64_getphdr(dst_elf
) +
1207 ph
->p_offset
= (Elf64_Off
)nshdr
.sh_offset
;
1212 /* copy ehdr changes back into real ehdr */
1213 (void) gelf_update_ehdr(dst_elf
, &dst_ehdr
);
1214 if (elf_update(dst_elf
, ELF_C_WRITE
) < 0) {
1215 error_message(LIBELF_ERROR
, LIBelf_ERROR
, elf_errmsg(-1), prog
);
1219 (void) elf_end(dst_elf
);
1220 (void) close(fdtmp
);
1225 * Search through PHT saving the beginning and ending segment offsets
1228 build_segment_table(Elf
* elf
, GElf_Ehdr
* ehdr
, file_state_t
*state
)
1232 state
->b_e_seg_table
= (Seg_Table
*)
1233 calloc(ehdr
->e_phnum
, sizeof (Seg_Table
));
1234 if (state
->b_e_seg_table
== NULL
) {
1235 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
, prog
);
1239 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
1242 (void) gelf_getphdr(elf
, i
, &ph
);
1245 * remember the note SEGMENTS index so that we can
1246 * re-set it's p_offset later if needed.
1248 if (ph
.p_type
== PT_NOTE
)
1249 state
->notesegndx
= i
;
1251 state
->b_e_seg_table
[i
].p_offset
= ph
.p_offset
;
1252 state
->b_e_seg_table
[i
].p_memsz
= ph
.p_offset
+ ph
.p_memsz
;
1253 state
->b_e_seg_table
[i
].p_filesz
= ph
.p_offset
+ ph
.p_filesz
;
1260 copy_elf_file_to_temp_ar_file(
1262 Elf_Arhdr
*mem_header
,
1266 char mem_header_buf
[sizeof (struct ar_hdr
) + 1];
1270 if ((fdtmp3
= open(elftmpfile
.tmp_name
, O_RDONLY
)) == -1) {
1271 error_message(OPEN_TEMP_ERROR
, SYSTEM_ERROR
, strerror(errno
),
1272 prog
, elftmpfile
.tmp_name
);
1276 (void) stat(elftmpfile
.tmp_name
, &stbuf
); /* for size of file */
1279 malloc(ROUNDUP(stbuf
.st_size
))) == NULL
) {
1280 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
, prog
);
1284 if (read(fdtmp3
, buf
, stbuf
.st_size
) != stbuf
.st_size
) {
1285 error_message(READ_MANI_ERROR
, SYSTEM_ERROR
, strerror(errno
),
1286 prog
, elftmpfile
.tmp_name
, cur_file
);
1290 (void) sprintf(mem_header_buf
, FORMAT
, mem_header
->ar_rawname
,
1291 mem_header
->ar_date
, (unsigned)mem_header
->ar_uid
,
1292 (unsigned)mem_header
->ar_gid
, (unsigned)mem_header
->ar_mode
,
1293 stbuf
.st_size
, ARFMAG
);
1295 if (write(fdartmp
, mem_header_buf
,
1296 (unsigned)sizeof (struct ar_hdr
)) !=
1297 (unsigned)sizeof (struct ar_hdr
)) {
1298 error_message(WRITE_MANI_ERROR
, SYSTEM_ERROR
, strerror(errno
),
1299 prog
, elftmpfile
.tmp_name
, cur_file
);
1303 if (stbuf
.st_size
& 0x1) {
1304 buf
[stbuf
.st_size
] = '\n';
1305 if (write(fdartmp
, buf
, (size_t)ROUNDUP(stbuf
.st_size
)) !=
1306 (size_t)ROUNDUP(stbuf
.st_size
)) {
1307 error_message(WRITE_MANI_ERROR
, SYSTEM_ERROR
,
1308 strerror(errno
), prog
, elftmpfile
.tmp_name
,
1312 } else if (write(fdartmp
, buf
, stbuf
.st_size
) != stbuf
.st_size
) {
1313 error_message(WRITE_MANI_ERROR
, SYSTEM_ERROR
,
1314 strerror(errno
), prog
, elftmpfile
.tmp_name
,
1319 (void) close(fdtmp3
);
1323 copy_non_elf_to_temp_ar(
1327 Elf_Arhdr
*mem_header
,
1331 char mem_header_buf
[sizeof (struct ar_hdr
) + 1];
1334 if ((strcmp(mem_header
->ar_name
, "/") != 0) &&
1335 (strcmp(mem_header
->ar_name
, "/SYM64/") != 0)) {
1336 (void) sprintf(mem_header_buf
, FORMAT
, mem_header
->ar_rawname
,
1337 mem_header
->ar_date
, (unsigned)mem_header
->ar_uid
,
1338 (unsigned)mem_header
->ar_gid
, (unsigned)mem_header
->ar_mode
,
1339 mem_header
->ar_size
, ARFMAG
);
1341 if (write(fdartmp
, mem_header_buf
, sizeof (struct ar_hdr
)) !=
1342 sizeof (struct ar_hdr
)) {
1343 error_message(WRITE_MANI_ERROR
, SYSTEM_ERROR
,
1344 strerror(errno
), prog
, cur_file
);
1348 malloc(ROUNDUP(mem_header
->ar_size
))) == NULL
) {
1349 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
,
1354 if (lseek(fd
, elf_getbase(elf
), 0) != elf_getbase(elf
)) {
1355 error_message(WRITE_MANI_ERROR
, prog
, cur_file
);
1359 if (read(fd
, file_buf
,
1360 (size_t)ROUNDUP(mem_header
->ar_size
)) !=
1361 (size_t)ROUNDUP(mem_header
->ar_size
)) {
1362 error_message(READ_MANI_ERROR
, SYSTEM_ERROR
,
1363 strerror(errno
), prog
, cur_file
);
1368 (size_t)ROUNDUP(mem_header
->ar_size
)) !=
1369 (size_t)ROUNDUP(mem_header
->ar_size
)) {
1370 error_message(WRITE_MANI_ERROR
, SYSTEM_ERROR
,
1371 strerror(errno
), prog
, cur_file
);
1375 } else if (CHK_OPT(cmd_info
, MIGHT_CHG
)) {
1376 error_message(SYM_TAB_AR_ERROR
, PLAIN_ERROR
, NULL
,
1378 error_message(EXEC_AR_ERROR
, PLAIN_ERROR
, NULL
, cur_file
);
1383 * Replace contents of file
1386 * ofd - Open file descriptor for file fname
1387 * fname - Name of file being processed
1388 * temp_file_name - Address of pointer to temporary
1389 * file containing new contents for fname.
1392 * The contents of the file given by temp_file->tmp_name are
1393 * copied to the file fname. The temporary file is
1394 * unlinked, and temp_file reset.
1397 copy_file(int ofd
, char *fname
, Tmp_File
*temp_file
)
1399 enum { MMAP_USED
, MMAP_UNUSED
} mmap_status
;
1405 for (i
= 0; signum
[i
]; i
++) /* started writing, cannot interrupt */
1406 (void) signal(signum
[i
], SIG_IGN
);
1408 if ((fdtmp2
= open(temp_file
->tmp_name
, O_RDONLY
)) == -1) {
1409 error_message(OPEN_TEMP_ERROR
, SYSTEM_ERROR
, strerror(errno
),
1410 prog
, temp_file
->tmp_name
);
1414 (void) stat(temp_file
->tmp_name
, &stbuf
); /* for size of file */
1417 * Get the contents of the updated file.
1418 * First try mmap()'ing. If mmap() fails,
1419 * then use the malloc() and read().
1421 mmap_status
= MMAP_USED
;
1422 buf
= mmap(NULL
, stbuf
.st_size
, PROT_READ
, MAP_SHARED
, fdtmp2
, 0);
1423 if (buf
== (caddr_t
)-1) {
1425 malloc(stbuf
.st_size
* sizeof (char))) == NULL
) {
1426 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
,
1431 if (read(fdtmp2
, buf
, stbuf
.st_size
) != stbuf
.st_size
) {
1432 error_message(READ_SYS_ERROR
, SYSTEM_ERROR
,
1433 strerror(errno
), prog
, temp_file
->tmp_name
);
1436 mmap_status
= MMAP_UNUSED
;
1439 if (ftruncate(ofd
, 0) == -1) {
1440 error_message(WRITE_MANI_ERROR2
, SYSTEM_ERROR
, strerror(errno
),
1444 if (lseek(ofd
, 0, SEEK_SET
) == -1) {
1445 error_message(WRITE_MANI_ERROR2
, SYSTEM_ERROR
, strerror(errno
),
1449 if ((write(ofd
, buf
, stbuf
.st_size
)) != stbuf
.st_size
) {
1450 error_message(WRITE_MANI_ERROR2
, SYSTEM_ERROR
, strerror(errno
),
1458 if (mmap_status
== MMAP_USED
)
1459 (void) munmap(buf
, stbuf
.st_size
);
1462 (void) close(fdtmp2
);
1463 free_tempfile(temp_file
);
1467 location(int64_t offset
, int mem_search
, Elf
* elf
, file_state_t
*state
)
1473 (void) gelf_getehdr(elf
, &ehdr
);
1475 for (i
= 0; i
< ehdr
.e_phnum
; i
++) {
1477 upper
= state
->b_e_seg_table
[i
].p_memsz
;
1479 upper
= state
->b_e_seg_table
[i
].p_filesz
;
1480 if ((offset
>= state
->b_e_seg_table
[i
].p_offset
) &&
1483 else if (offset
< state
->b_e_seg_table
[i
].p_offset
)
1490 scn_location(Elf_Scn
* scn
, Elf
* elf
, file_state_t
*state
)
1494 (void) gelf_getshdr(scn
, &shdr
);
1497 * If the section is not a NOTE section and it has no
1498 * virtual address then it is not part of a mapped segment.
1500 if (shdr
.sh_addr
== 0)
1501 return (location(shdr
.sh_offset
+ shdr
.sh_size
, 0, elf
, state
));
1503 return (location(shdr
.sh_offset
+ shdr
.sh_size
, 1, elf
, state
));
1507 initialize(int shnum
, Cmd_Info
*cmd_info
, file_state_t
*state
)
1510 * Initialize command info
1512 cmd_info
->no_of_append
= cmd_info
->no_of_delete
=
1513 cmd_info
->no_of_nulled
= cmd_info
->no_of_compressed
=
1514 cmd_info
->no_of_moved
= 0;
1515 cmd_info
->sh_groups
= NULL
;
1517 state
->sec_table
= (section_info_table
*)
1518 calloc(shnum
+ 1, sizeof (section_info_table
));
1519 if (state
->sec_table
== NULL
) {
1520 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
, prog
);
1524 state
->off_table
= (int64_t *)calloc(shnum
, sizeof (int64_t));
1525 if (state
->off_table
== NULL
) {
1526 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
, prog
);
1530 state
->nobits_table
= (int64_t *)calloc(shnum
, sizeof (int64_t));
1531 if (state
->nobits_table
== NULL
) {
1532 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
, prog
);
1538 * Update the contents of SHT_GROUP if needed
1541 post_process(Cmd_Info
*cmd_info
, file_state_t
*state
)
1544 section_info_table
*sinfo
;
1545 Word
*grpdata
, *ngrpdata
;
1550 * If no change is required, then return.
1552 if ((cmd_info
->flags
& (SHF_GROUP_MOVE
|SHF_GROUP_DEL
)) == 0)
1556 * If SHF_GROUP sections were removed, we might need to
1557 * remove SHT_GROUP sections.
1559 if (cmd_info
->flags
& SHF_GROUP_DEL
) {
1563 for (APLIST_TRAVERSE(cmd_info
->sh_groups
, idx
, sinfo
)) {
1564 if (sinfo
->secno
== (GElf_Word
)DELETED
)
1566 num
= (sinfo
->shdr
).sh_size
/sizeof (Word
);
1568 grpdata
= (Word
*)(sinfo
->data
->d_buf
);
1569 for (i
= 1; i
< num
; i
++) {
1570 if (state
->sec_table
[grpdata
[i
]].secno
!=
1576 * All members in this SHT_GROUP were removed.
1577 * We can remove this SHT_GROUP.
1580 sinfo
->secno
= (GElf_Word
)DELETED
;
1581 (cmd_info
->no_of_delete
)++;
1587 * If we deleted a SHT_GROUP section,
1588 * we need to reasign section numbers.
1591 section_info_table
*sinfo
;
1595 while (state
->sec_table
[sno
].scn
!= (Elf_Scn
*)-1) {
1596 sinfo
= &state
->sec_table
[sno
];
1597 if (sinfo
->secno
!= (GElf_Word
) DELETED
)
1598 sinfo
->secno
= sno2
++;
1605 * Now we can update data buffers of the SHT_GROUP sections.
1607 for (APLIST_TRAVERSE(cmd_info
->sh_groups
, idx
, sinfo
)) {
1608 if (sinfo
->secno
== (GElf_Word
)DELETED
)
1610 num
= (sinfo
->shdr
).sh_size
/sizeof (Word
);
1613 * Need to generate the updated data buffer
1615 if ((sinfo
->mdata
= malloc(sizeof (Elf_Data
))) == NULL
) {
1616 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
,
1620 *(sinfo
->mdata
) = *(sinfo
->data
);
1621 if ((ngrpdata
= sinfo
->mdata
->d_buf
=
1622 malloc(sinfo
->data
->d_size
)) == NULL
) {
1623 error_message(MALLOC_ERROR
, PLAIN_ERROR
, NULL
,
1628 grpdata
= (Word
*)(sinfo
->data
->d_buf
);
1629 ngrpdata
[0] = grpdata
[0];
1631 for (i
= 1; i
< num
; i
++) {
1632 if (state
->sec_table
[grpdata
[i
]].secno
!=
1633 (GElf_Word
)DELETED
) {
1635 state
->sec_table
[grpdata
[i
]].secno
;
1638 sinfo
->mdata
->d_size
= j
* sizeof (Word
);
1639 sinfo
->data
= sinfo
->mdata
;
1641 free(cmd_info
->sh_groups
);
1642 cmd_info
->sh_groups
= NULL
;