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]
22 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
26 * acom: Append Comment
28 * This program demonstrates the use of the libelf interface to
29 * modify a ELF file. This program will open an ELF file and
30 * either modify an existing .comment section and/or append
31 * a new .comment section to an existing ELF file.
43 static const char *CommentStr
= ".comment";
46 update_comment(Elf
*elf
, const char *file
, const char *comment
)
53 if (elf_getshdrstrndx(elf
, &shstrndx
) == -1) {
54 (void) fprintf(stderr
, "%s: gelf_getshdrstrdx() failed: %s\n",
59 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
61 * Do a string compare to examine each section header
62 * to see if it is a ".comment" section. If it is then
63 * this is the section we want to process.
65 if (gelf_getshdr(scn
, &shdr
) == NULL
) {
66 (void) fprintf(stderr
, "%s: elf_getshdr() failed: %s\n",
70 if (strcmp(CommentStr
, elf_strptr(elf
, shstrndx
,
78 (void) printf("%s has no .comment section. "
79 "Creating one...\n", file
);
81 * First add the ".comment" string to the string table
83 if ((scn
= elf_getscn(elf
, shstrndx
)) == NULL
) {
84 (void) fprintf(stderr
, "%s: elf_getscn() failed: %s\n",
88 if ((data
= elf_getdata(scn
, NULL
)) == NULL
) {
89 (void) fprintf(stderr
, "%s: elf_getdata() failed: %s\n",
93 ndx
= data
->d_off
+ data
->d_size
;
94 if ((data
= elf_newdata(scn
)) == NULL
) {
95 (void) fprintf(stderr
, "%s: elf_newdata() failed: %s\n",
99 data
->d_buf
= (void *)CommentStr
;
100 data
->d_size
= strlen(CommentStr
) + 1;
104 * Add the ".comment" section to the end of the file.
105 * Initialize the fields in the Section Header that
106 * libelf will not fill in.
108 if ((scn
= elf_newscn(elf
)) == NULL
) {
109 (void) fprintf(stderr
, "%s: elf_newscn() failed: %s\n",
110 file
, elf_errmsg(0));
113 if (gelf_getshdr(scn
, &shdr
) == NULL
) {
114 (void) fprintf(stderr
, "%s: elf_getshdr() failed: %s\n",
115 file
, elf_errmsg(0));
119 shdr
.sh_type
= SHT_PROGBITS
;
126 * Flush the changes to the underlying elf32 or elf64
129 (void) gelf_update_shdr(scn
, &shdr
);
132 if (shdr
.sh_addr
!= 0) {
133 (void) printf("%s: .comment section is part of a "
134 "loadable segment, it cannot be changed.\n", file
);
138 if ((data
= elf_newdata(scn
)) == NULL
) {
139 (void) fprintf(stderr
, "%s: elf_getdata() failed: %s\n",
140 file
, elf_errmsg(0));
143 data
->d_buf
= (void *)comment
;
144 data
->d_size
= strlen(comment
) + 1;
147 if (elf_update(elf
, ELF_C_WRITE
) == -1)
148 (void) fprintf(stderr
, "%s: elf_update() failed: %s\n", file
,
153 main(int argc
, char **argv
)
160 (void) printf("usage: %s <new comment> elf_file ...\n",
166 * Initialize the elf library, must be called before elf_begin()
169 if (elf_version(EV_CURRENT
) == EV_NONE
) {
170 (void) fprintf(stderr
, "elf_version() failed: %s\n",
176 * The new comment is passed in through the command line.
177 * This string will be used to update the .comment section of
178 * the specified ELF files.
180 new_comment
= argv
[1];
181 for (i
= 2; i
< argc
; i
++) {
187 if ((fd
= open(elf_fname
, O_RDWR
)) == -1) {
193 * Attempt to open an Elf descriptor Read/Write
196 if ((elf
= elf_begin(fd
, ELF_C_RDWR
, 0)) == NULL
) {
197 (void) fprintf(stderr
, "elf_begin() failed: %s\n",
203 * Determine what kind of elf file this is:
205 if (elf_kind(elf
) == ELF_K_ELF
)
206 update_comment(elf
, elf_fname
, new_comment
);
208 (void) printf("%s not of type ELF_K_ELF. "
209 "elf_kind == %d\n", elf_fname
, elf_kind(elf
));