Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: bfd/elf-nacl.c

Issue 256623012: Cherry pick some binutils NaCl strip/objcopy fixes in pnacl 2.23 branch. (Closed) Base URL: https://chromium.googlesource.com/native_client/nacl-binutils.git@master
Patch Set: need to cherry pick nops change too Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « bfd/cpu-i386.c ('k') | bfd/elf32-i386.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « bfd/cpu-i386.c ('k') | bfd/elf32-i386.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698