OLD | NEW |
1 /* Native Client support for ELF | 1 /* Native Client support for ELF |
2 Copyright 2012, 2013 Free Software Foundation, Inc. | 2 Copyright 2012, 2013 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of BFD, the Binary File Descriptor library. | 4 This file is part of BFD, the Binary File Descriptor library. |
5 | 5 |
6 This program is free software; you can redistribute it and/or modify | 6 This program is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation; either version 3 of the License, or | 8 the Free Software Foundation; either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 so we have to look through the sections. */ | 37 so we have to look through the sections. */ |
38 unsigned int i; | 38 unsigned int i; |
39 for (i = 0; i < seg->count; ++i) | 39 for (i = 0; i < seg->count; ++i) |
40 if (seg->sections[i]->flags & SEC_CODE) | 40 if (seg->sections[i]->flags & SEC_CODE) |
41 return TRUE; | 41 return TRUE; |
42 } | 42 } |
43 return FALSE; | 43 return FALSE; |
44 } | 44 } |
45 | 45 |
46 /* Determine if this segment is eligible to receive the file and program | 46 /* Determine if this segment is eligible to receive the file and program |
47 headers. It must be read-only, non-executable, and have contents. | 47 headers. It must be read-only and non-executable. |
48 Its first section must start far enough past the page boundary to | 48 Its first section must start far enough past the page boundary to |
49 allow space for the headers. */ | 49 allow space for the headers. */ |
50 static bfd_boolean | 50 static bfd_boolean |
51 segment_eligible_for_headers (struct elf_segment_map *seg, | 51 segment_eligible_for_headers (struct elf_segment_map *seg, |
52 bfd_vma minpagesize, bfd_vma sizeof_headers) | 52 bfd_vma minpagesize, bfd_vma sizeof_headers) |
53 { | 53 { |
54 bfd_boolean any_contents = FALSE; | |
55 unsigned int i; | 54 unsigned int i; |
56 if (seg->count == 0 || seg->sections[0]->lma % minpagesize < sizeof_headers) | 55 if (seg->count == 0 || seg->sections[0]->lma % minpagesize < sizeof_headers) |
57 return FALSE; | 56 return FALSE; |
58 for (i = 0; i < seg->count; ++i) | 57 for (i = 0; i < seg->count; ++i) |
59 { | 58 { |
60 if ((seg->sections[i]->flags & (SEC_CODE|SEC_READONLY)) != SEC_READONLY) | 59 if ((seg->sections[i]->flags & (SEC_CODE|SEC_READONLY)) != SEC_READONLY) |
61 return FALSE; | 60 return FALSE; |
62 if (seg->sections[i]->flags & SEC_HAS_CONTENTS) | |
63 any_contents = TRUE; | |
64 } | 61 } |
65 return any_contents; | 62 return TRUE; |
66 } | 63 } |
67 | 64 |
68 | 65 |
69 /* We permute the segment_map to get BFD to do the file layout we want: | 66 /* We permute the segment_map to get BFD to do the file layout we want: |
70 The first non-executable PT_LOAD segment appears first in the file | 67 The first non-executable PT_LOAD segment appears first in the file |
71 and contains the ELF file header and phdrs. */ | 68 and contains the ELF file header and phdrs. */ |
72 bfd_boolean | 69 bfd_boolean |
73 nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info) | 70 nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info) |
74 { | 71 { |
| 72 const struct elf_backend_data *const bed = get_elf_backend_data (abfd); |
75 struct elf_segment_map **m = &elf_tdata (abfd)->segment_map; | 73 struct elf_segment_map **m = &elf_tdata (abfd)->segment_map; |
76 struct elf_segment_map **first_load = NULL; | 74 struct elf_segment_map **first_load = NULL; |
77 struct elf_segment_map **last_load = NULL; | 75 struct elf_segment_map **last_load = NULL; |
78 bfd_boolean moved_headers = FALSE; | 76 bfd_boolean moved_headers = FALSE; |
79 int sizeof_headers = info == NULL ? 0 : bfd_sizeof_headers (abfd, info); | 77 int sizeof_headers; |
80 bfd_vma minpagesize = get_elf_backend_data (abfd)->minpagesize; | |
81 | 78 |
82 if (info != NULL && info->user_phdrs) | 79 if (info != NULL && info->user_phdrs) |
83 /* The linker script used PHDRS explicitly, so don't change what the | 80 /* The linker script used PHDRS explicitly, so don't change what the |
84 user asked for. */ | 81 user asked for. */ |
85 return TRUE; | 82 return TRUE; |
86 | 83 |
| 84 if (info != NULL) |
| 85 /* We're doing linking, so evalute SIZEOF_HEADERS as in a linker script. */ |
| 86 sizeof_headers = bfd_sizeof_headers (abfd, info); |
| 87 else |
| 88 { |
| 89 /* We're not doing linking, so this is objcopy or suchlike. |
| 90 We just need to collect the size of the existing headers. */ |
| 91 struct elf_segment_map *seg; |
| 92 sizeof_headers = bed->s->sizeof_ehdr; |
| 93 for (seg = *m; seg != NULL; seg = seg->next) |
| 94 sizeof_headers += bed->s->sizeof_phdr; |
| 95 } |
| 96 |
87 while (*m != NULL) | 97 while (*m != NULL) |
88 { | 98 { |
89 struct elf_segment_map *seg = *m; | 99 struct elf_segment_map *seg = *m; |
90 | 100 |
91 if (seg->p_type == PT_LOAD) | 101 if (seg->p_type == PT_LOAD) |
92 { | 102 { |
93 bfd_boolean executable = segment_executable (seg); | 103 bfd_boolean executable = segment_executable (seg); |
94 | 104 |
95 if (executable | 105 if (executable |
96 && seg->count > 0 | 106 && seg->count > 0 |
97 » && seg->sections[0]->vma % minpagesize == 0) | 107 » && seg->sections[0]->vma % bed->minpagesize == 0) |
98 { | 108 { |
99 asection *lastsec = seg->sections[seg->count - 1]; | 109 asection *lastsec = seg->sections[seg->count - 1]; |
100 bfd_vma end = lastsec->vma + lastsec->size; | 110 bfd_vma end = lastsec->vma + lastsec->size; |
101 » if (end % minpagesize != 0) | 111 » if (end % bed->minpagesize != 0) |
102 { | 112 { |
103 /* This is an executable segment that starts on a page | 113 /* This is an executable segment that starts on a page |
104 boundary but does not end on a page boundary. Fill | 114 boundary but does not end on a page boundary. Fill |
105 it out to a whole page with code fill (the tail of | 115 it out to a whole page with code fill (the tail of |
106 the segment will not be within any section). Thus | 116 the segment will not be within any section). Thus |
107 the entire code segment can be mapped from the file | 117 the entire code segment can be mapped from the file |
108 as whole pages and that mapping will contain only | 118 as whole pages and that mapping will contain only |
109 valid instructions. | 119 valid instructions. |
110 | 120 |
111 To accomplish this, we must fake out the code in | 121 To accomplish this, we must fake out the code in |
(...skipping 20 matching lines...) Expand all Loading... |
132 return FALSE; | 142 return FALSE; |
133 | 143 |
134 sec = bfd_zalloc (abfd, sizeof *sec); | 144 sec = bfd_zalloc (abfd, sizeof *sec); |
135 if (sec == NULL) | 145 if (sec == NULL) |
136 return FALSE; | 146 return FALSE; |
137 | 147 |
138 /* Fill in only the fields that actually affect the logic | 148 /* Fill in only the fields that actually affect the logic |
139 in assign_file_positions_for_load_sections. */ | 149 in assign_file_positions_for_load_sections. */ |
140 sec->vma = end; | 150 sec->vma = end; |
141 sec->lma = lastsec->lma + lastsec->size; | 151 sec->lma = lastsec->lma + lastsec->size; |
142 » » sec->size = minpagesize - (end % minpagesize); | 152 » » sec->size = bed->minpagesize - (end % bed->minpagesize); |
143 sec->flags = (SEC_ALLOC | SEC_LOAD | 153 sec->flags = (SEC_ALLOC | SEC_LOAD |
144 | SEC_READONLY | SEC_CODE | SEC_LINKER_CREATED); | 154 | SEC_READONLY | SEC_CODE | SEC_LINKER_CREATED); |
145 sec->used_by_bfd = secdata; | 155 sec->used_by_bfd = secdata; |
146 | 156 |
147 secdata->this_hdr.sh_type = SHT_PROGBITS; | 157 secdata->this_hdr.sh_type = SHT_PROGBITS; |
148 secdata->this_hdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; | 158 secdata->this_hdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; |
149 secdata->this_hdr.sh_addr = sec->vma; | 159 secdata->this_hdr.sh_addr = sec->vma; |
150 secdata->this_hdr.sh_size = sec->size; | 160 secdata->this_hdr.sh_size = sec->size; |
151 | 161 |
152 newseg = bfd_alloc (abfd, | 162 newseg = bfd_alloc (abfd, |
(...skipping 14 matching lines...) Expand all Loading... |
167 last_load = m; | 177 last_load = m; |
168 if (first_load == NULL) | 178 if (first_load == NULL) |
169 { | 179 { |
170 if (!executable) | 180 if (!executable) |
171 goto next; | 181 goto next; |
172 first_load = m; | 182 first_load = m; |
173 } | 183 } |
174 /* Now that we've noted the first PT_LOAD, we're looking for | 184 /* Now that we've noted the first PT_LOAD, we're looking for |
175 the first non-executable PT_LOAD with a nonempty p_filesz. */ | 185 the first non-executable PT_LOAD with a nonempty p_filesz. */ |
176 else if (!moved_headers | 186 else if (!moved_headers |
177 » » && segment_eligible_for_headers (seg, minpagesize, | 187 » » && segment_eligible_for_headers (seg, bed->minpagesize, |
178 sizeof_headers)) | 188 sizeof_headers)) |
179 { | 189 { |
180 /* This is the one we were looking for! | 190 /* This is the one we were looking for! |
181 | 191 |
182 First, clear the flags on previous segments that | 192 First, clear the flags on previous segments that |
183 say they include the file header and phdrs. */ | 193 say they include the file header and phdrs. */ |
184 struct elf_segment_map *prevseg; | 194 struct elf_segment_map *prevseg; |
185 for (prevseg = *first_load; | 195 for (prevseg = *first_load; |
186 prevseg != seg; | 196 prevseg != seg; |
187 prevseg = prevseg->next) | 197 prevseg = prevseg->next) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 { | 346 { |
337 /* We don't have a proper way to report an error here. So | 347 /* We don't have a proper way to report an error here. So |
338 instead fudge things so that elf_write_shdrs_and_ehdr will | 348 instead fudge things so that elf_write_shdrs_and_ehdr will |
339 fail. */ | 349 fail. */ |
340 elf_elfheader (abfd)->e_shoff = (file_ptr) -1; | 350 elf_elfheader (abfd)->e_shoff = (file_ptr) -1; |
341 } | 351 } |
342 | 352 |
343 free (fill); | 353 free (fill); |
344 } | 354 } |
345 } | 355 } |
OLD | NEW |