Mercurial > hg > truffle
comparison src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c @ 6095:9c1709c4c80c
7165598: enable FDS on Solaris X64 when 7165593 is fixed
Summary: Work around 'gobjcopy' failure on Solaris X64 by adding a temporary tool that removes the SHF_ALLOC flag from "empty" section headers.
Reviewed-by: sspitsyn, acorn
author | dcubed |
---|---|
date | Thu, 24 May 2012 12:03:42 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
6077:7d4e6dabc6bf | 6095:9c1709c4c80c |
---|---|
1 /* | |
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 /* | |
26 * Name: fix_empty_sec_hdr_flags.c | |
27 * | |
28 * Description: Remove the SHF_ALLOC flag from "empty" section headers. | |
29 * An "empty" section header has sh_addr == 0 and sh_size == 0. | |
30 * | |
31 * This program is adapted from the example program shown on the | |
32 * elf(3elf) man page and from code from the Solaris compiler | |
33 * driver. | |
34 */ | |
35 | |
36 #include <fcntl.h> | |
37 #include <stdio.h> | |
38 #include <libelf.h> | |
39 #include <stdlib.h> | |
40 #include <string.h> | |
41 #include <unistd.h> | |
42 | |
43 static void failure(void); | |
44 | |
45 void | |
46 main(int argc, char ** argv) { | |
47 void * ehdr; /* ELF header */ | |
48 unsigned int i; /* section counter */ | |
49 int fd; /* descriptor for file */ | |
50 Elf * elf; /* ELF descriptor */ | |
51 char * elf_ident; /* ELF identity string */ | |
52 char * elf_obj; /* elf_obj file */ | |
53 int fix_count; /* number of flags fixed */ | |
54 int is_elfclass64; /* is an ELFCLASS64 file? */ | |
55 Elf_Scn * scn; /* ELF section descriptor */ | |
56 void * shdr; /* ELF section header */ | |
57 Elf_Data * shstrtab; /* ELF section header string table */ | |
58 | |
59 if (argc != 2) { | |
60 (void) fprintf(stderr, "Usage: %s elf_obj\n", argv[0]); | |
61 exit(2); | |
62 } | |
63 | |
64 /* open the elf_obj */ | |
65 elf_obj = argv[1]; | |
66 if ((fd = open(elf_obj, O_RDWR)) == -1) { | |
67 (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj); | |
68 exit(3); | |
69 } | |
70 | |
71 (void) printf("Opening '%s' for update\n", elf_obj); | |
72 (void) fflush(stdout); | |
73 (void) elf_version(EV_CURRENT); /* coordinate ELF versions */ | |
74 | |
75 /* obtain the ELF descriptors from the input file */ | |
76 if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) { | |
77 failure(); | |
78 } | |
79 | |
80 /* determine if ELFCLASS64 or not? */ | |
81 elf_ident = elf_getident(elf, NULL); | |
82 is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64); | |
83 | |
84 /* get the ELF header */ | |
85 if (is_elfclass64) { | |
86 ehdr = elf64_getehdr(elf); | |
87 } else { | |
88 ehdr = elf32_getehdr(elf); | |
89 } | |
90 if (ehdr == NULL) { | |
91 failure(); | |
92 } | |
93 | |
94 /* get the ELF section descriptor */ | |
95 if (is_elfclass64) { | |
96 scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx); | |
97 } else { | |
98 scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx); | |
99 } | |
100 if (scn == NULL) { | |
101 failure(); | |
102 } | |
103 | |
104 /* get the section header string table */ | |
105 shstrtab = elf_getdata(scn, NULL); | |
106 if (shstrtab == NULL) { | |
107 failure(); | |
108 } | |
109 | |
110 fix_count = 0; | |
111 | |
112 /* traverse the sections of the input file */ | |
113 for (i = 1, scn = NULL; scn = elf_nextscn(elf, scn); i++) { | |
114 int has_flag_set; /* is SHF_ALLOC flag set? */ | |
115 int is_empty; /* is section empty? */ | |
116 char * name; /* short hand pointer */ | |
117 | |
118 /* get the section header */ | |
119 if (is_elfclass64) { | |
120 shdr = elf64_getshdr(scn); | |
121 } else { | |
122 shdr = elf32_getshdr(scn); | |
123 } | |
124 if (shdr == NULL) { | |
125 failure(); | |
126 } | |
127 | |
128 if (is_elfclass64) { | |
129 name = (char *)shstrtab->d_buf + ((Elf64_Shdr *) shdr)->sh_name; | |
130 } else { | |
131 name = (char *)shstrtab->d_buf + ((Elf32_Shdr *) shdr)->sh_name; | |
132 } | |
133 | |
134 if (is_elfclass64) { | |
135 has_flag_set = ((Elf64_Shdr *) shdr)->sh_flags & SHF_ALLOC; | |
136 is_empty = ((Elf64_Shdr *) shdr)->sh_addr == 0 && | |
137 ((Elf64_Shdr *) shdr)->sh_size == 0; | |
138 } else { | |
139 has_flag_set = ((Elf32_Shdr *) shdr)->sh_flags & SHF_ALLOC; | |
140 is_empty = ((Elf32_Shdr *) shdr)->sh_addr == 0 && | |
141 ((Elf32_Shdr *) shdr)->sh_size == 0; | |
142 } | |
143 | |
144 if (is_empty && has_flag_set) { | |
145 (void) printf("section[%u] '%s' is empty, " | |
146 "but SHF_ALLOC flag is set.\n", i, name); | |
147 (void) printf("Clearing the SHF_ALLOC flag.\n"); | |
148 | |
149 if (is_elfclass64) { | |
150 ((Elf64_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC; | |
151 } else { | |
152 ((Elf32_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC; | |
153 } | |
154 fix_count++; | |
155 } | |
156 } /* end for each ELF section */ | |
157 | |
158 if (fix_count > 0) { | |
159 (void) printf("Saving %d updates to '%s'\n", fix_count, elf_obj); | |
160 (void) fflush(stdout); | |
161 (void) elf_update(elf, ELF_C_NULL); /* recalc ELF memory structures */ | |
162 (void) elf_update(elf, ELF_C_WRITE); /* write out changes to ELF obj */ | |
163 } else { | |
164 (void) printf("No SHF_ALLOC flags needed to be cleared.\n"); | |
165 } | |
166 | |
167 (void) elf_end(elf); /* done with ELF obj */ | |
168 (void) close(fd); | |
169 | |
170 (void) printf("Done %s '%s'\n", | |
171 (fix_count > 0) ? "updating" : "with", elf_obj); | |
172 (void) fflush(stdout); | |
173 exit(0); | |
174 } /* end main */ | |
175 | |
176 | |
177 static void | |
178 failure() { | |
179 (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno())); | |
180 exit(6); | |
181 } |