]> code.ossystems Code Review - openembedded-core.git/blob
650de9b9a39d456cc02045e33417006955c95caa
[openembedded-core.git] /
1 From bb9c8cc3c5f4ffd6019a8c53adead429954162e1 Mon Sep 17 00:00:00 2001
2 From: Mark Wielaard <mark@klomp.org>
3 Date: Tue, 27 Nov 2018 11:59:10 +0000
4 Subject: [PATCH 1/2] Handle ELF compressed header alignment correctly by
5  setting up the section alignment correctly for the Elf32_Chdr or Elf64_Chdr
6  type and respect the ch_addralign field when decompressing the section data.
7
8         PR binutils/23919
9 binutils* readelf.c (dump_sections_as_strings): Remove bogus addralign check.
10         (dump_sections_as_bytes): Likewise.
11         (load_specific_debug_sections): Likewise.
12         * testsuite/binutils-all/dw2-3.rS: Adjust alignment.
13         * testsuite/binutils-all/dw2-3.rt: Likewise.
14
15 bfd     * bfd.c (bfd_update_compression_header): Explicitly set alignment.
16         (bfd_check_compression_header): Add uncompressed_alignment_power
17         argument. Check ch_addralign is a power of 2.
18         * bfd-in2.h: Regenerated.
19         * compress.c (bfd_compress_section_contents): Get and set
20         orig_uncompressed_alignment_pow if section is decompressed.
21         (bfd_is_section_compressed_with_header): Add and get
22         uncompressed_align_pow_p argument.
23         (bfd_is_section_compressed): Add uncompressed_align_power argument
24         to bfd_is_section_compressed_with_header call.
25         (bfd_init_section_decompress_status): Get and set
26         uncompressed_alignment_power.
27         * elf.c (_bfd_elf_make_section_from_shdr): Add
28         uncompressed_align_power argument to
29         bfd_is_section_compressed_with_header call.
30 ---
31  bfd/bfd-in2.h                            |  6 ++--
32  bfd/bfd.c                                | 20 ++++++++++----
33  bfd/compress.c                           | 35 +++++++++++++++++-------
34  bfd/elf.c                                |  5 ++--
35  binutils/readelf.c                       | 18 ------------
36  binutils/testsuite/binutils-all/dw2-3.rS |  2 +-
37  binutils/testsuite/binutils-all/dw2-3.rt |  2 +-
38  7 files changed, 49 insertions(+), 39 deletions(-)
39
40 Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4207142d6a5d2359170c5f9a140fc1a2351fbda9]
41 Signed-off-by: Khem Raj <raj.khem@gmail.com>
42
43 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
44 index f53dbb5e8c..d0c2190d0b 100644
45 --- a/bfd/bfd-in2.h
46 +++ b/bfd/bfd-in2.h
47 @@ -7279,7 +7279,8 @@ void bfd_update_compression_header
48  
49  bfd_boolean bfd_check_compression_header
50     (bfd *abfd, bfd_byte *contents, asection *sec,
51 -    bfd_size_type *uncompressed_size);
52 +    bfd_size_type *uncompressed_size,
53 +    unsigned int *uncompressed_alignment_power);
54  
55  int bfd_get_compression_header_size (bfd *abfd, asection *sec);
56  
57 @@ -7855,7 +7856,8 @@ void bfd_cache_section_contents
58  bfd_boolean bfd_is_section_compressed_with_header
59     (bfd *abfd, asection *section,
60      int *compression_header_size_p,
61 -    bfd_size_type *uncompressed_size_p);
62 +    bfd_size_type *uncompressed_size_p,
63 +    unsigned int *uncompressed_alignment_power_p);
64  
65  bfd_boolean bfd_is_section_compressed
66     (bfd *abfd, asection *section);
67 diff --git a/bfd/bfd.c b/bfd/bfd.c
68 index 851710401e..ea10d7b185 100644
69 --- a/bfd/bfd.c
70 +++ b/bfd/bfd.c
71 @@ -2332,6 +2332,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
72                   bfd_put_32 (abfd, sec->size, &echdr->ch_size);
73                   bfd_put_32 (abfd, 1 << sec->alignment_power,
74                               &echdr->ch_addralign);
75 +                 /* bfd_log2 (alignof (Elf32_Chdr)) */
76 +                 bfd_set_section_alignment (abfd, sec, 2);
77                 }
78               else
79                 {
80 @@ -2342,6 +2344,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
81                   bfd_put_64 (abfd, sec->size, &echdr->ch_size);
82                   bfd_put_64 (abfd, 1 << sec->alignment_power,
83                               &echdr->ch_addralign);
84 +                 /* bfd_log2 (alignof (Elf64_Chdr)) */
85 +                 bfd_set_section_alignment (abfd, sec, 3);
86                 }
87             }
88           else
89 @@ -2354,6 +2358,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
90                  order.  */
91               memcpy (contents, "ZLIB", 4);
92               bfd_putb64 (sec->size, contents + 4);
93 +             /* No way to keep the original alignment, just use 1 always. */
94 +             bfd_set_section_alignment (abfd, sec, 0);
95             }
96         }
97      }
98 @@ -2368,12 +2374,14 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
99     SYNOPSIS
100         bfd_boolean bfd_check_compression_header
101           (bfd *abfd, bfd_byte *contents, asection *sec,
102 -         bfd_size_type *uncompressed_size);
103 +         bfd_size_type *uncompressed_size,
104 +         unsigned int *uncompressed_alignment_power);
105  
106  DESCRIPTION
107         Check the compression header at CONTENTS of SEC in ABFD and
108 -       store the uncompressed size in UNCOMPRESSED_SIZE if the
109 -       compression header is valid.
110 +       store the uncompressed size in UNCOMPRESSED_SIZE and the
111 +       uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER
112 +       if the compression header is valid.
113  
114  RETURNS
115         Return TRUE if the compression header is valid.
116 @@ -2382,7 +2390,8 @@ RETURNS
117  bfd_boolean
118  bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
119                               asection *sec,
120 -                             bfd_size_type *uncompressed_size)
121 +                             bfd_size_type *uncompressed_size,
122 +                             unsigned int *uncompressed_alignment_power)
123  {
124    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
125        && (elf_section_flags (sec) & SHF_COMPRESSED) != 0)
126 @@ -2404,9 +2413,10 @@ bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
127           chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign);
128         }
129        if (chdr.ch_type == ELFCOMPRESS_ZLIB
130 -         && chdr.ch_addralign == 1U << sec->alignment_power)
131 +         && chdr.ch_addralign == (1U << bfd_log2 (chdr.ch_addralign)))
132         {
133           *uncompressed_size = chdr.ch_size;
134 +         *uncompressed_alignment_power = bfd_log2 (chdr.ch_addralign);
135           return TRUE;
136         }
137      }
138 diff --git a/bfd/compress.c b/bfd/compress.c
139 index 53e566e498..97ea624eb8 100644
140 --- a/bfd/compress.c
141 +++ b/bfd/compress.c
142 @@ -84,11 +84,13 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
143    int zlib_size = 0;
144    int orig_compression_header_size;
145    bfd_size_type orig_uncompressed_size;
146 +  unsigned int orig_uncompressed_alignment_pow;
147    int header_size = bfd_get_compression_header_size (abfd, NULL);
148    bfd_boolean compressed
149      = bfd_is_section_compressed_with_header (abfd, sec,
150                                              &orig_compression_header_size,
151 -                                            &orig_uncompressed_size);
152 +                                            &orig_uncompressed_size,
153 +                                            &orig_uncompressed_alignment_pow);
154  
155    /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
156       overhead in .zdebug* section.  */
157 @@ -153,6 +155,9 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
158               return 0;
159             }
160           free (uncompressed_buffer);
161 +         bfd_set_section_alignment (abfd, sec,
162 +                                    orig_uncompressed_alignment_pow);
163 +
164           sec->contents = buffer;
165           sec->compress_status = COMPRESS_SECTION_DONE;
166           return orig_uncompressed_size;
167 @@ -364,20 +369,24 @@ SYNOPSIS
168         bfd_boolean bfd_is_section_compressed_with_header
169           (bfd *abfd, asection *section,
170           int *compression_header_size_p,
171 -         bfd_size_type *uncompressed_size_p);
172 +         bfd_size_type *uncompressed_size_p,
173 +         unsigned int *uncompressed_alignment_power_p);
174  
175  DESCRIPTION
176         Return @code{TRUE} if @var{section} is compressed.  Compression
177 -       header size is returned in @var{compression_header_size_p} and
178 -       uncompressed size is returned in @var{uncompressed_size_p}.  If
179 -       compression is unsupported, compression header size is returned
180 -       with -1 and uncompressed size is returned with 0.
181 +       header size is returned in @var{compression_header_size_p},
182 +       uncompressed size is returned in @var{uncompressed_size_p}
183 +       and the uncompressed data alignement power is returned in
184 +       @var{uncompressed_align_pow_p}.  If compression is
185 +       unsupported, compression header size is returned with -1
186 +       and uncompressed size is returned with 0.
187  */
188  
189  bfd_boolean
190  bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
191                                        int *compression_header_size_p,
192 -                                      bfd_size_type *uncompressed_size_p)
193 +                                      bfd_size_type *uncompressed_size_p,
194 +                                      unsigned int *uncompressed_align_pow_p)
195  {
196    bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
197    int compression_header_size;
198 @@ -412,7 +421,8 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
199        if (compression_header_size != 0)
200         {
201           if (!bfd_check_compression_header (abfd, header, sec,
202 -                                            uncompressed_size_p))
203 +                                            uncompressed_size_p,
204 +                                            uncompressed_align_pow_p))
205             compression_header_size = -1;
206         }
207        /* Check for the pathalogical case of a debug string section that
208 @@ -449,9 +459,11 @@ bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
209  {
210    int compression_header_size;
211    bfd_size_type uncompressed_size;
212 +  unsigned int uncompressed_align_power;
213    return (bfd_is_section_compressed_with_header (abfd, sec,
214                                                  &compression_header_size,
215 -                                                &uncompressed_size)
216 +                                                &uncompressed_size,
217 +                                                &uncompressed_align_power)
218           && compression_header_size >= 0
219           && uncompressed_size > 0);
220  }
221 @@ -480,6 +492,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
222    int compression_header_size;
223    int header_size;
224    bfd_size_type uncompressed_size;
225 +  unsigned int uncompressed_alignment_power = 0;
226  
227    compression_header_size = bfd_get_compression_header_size (abfd, sec);
228    if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
229 @@ -508,7 +521,8 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
230        uncompressed_size = bfd_getb64 (header + 4);
231      }
232    else if (!bfd_check_compression_header (abfd, header, sec,
233 -                                        &uncompressed_size))
234 +                                         &uncompressed_size,
235 +                                         &uncompressed_alignment_power))
236      {
237        bfd_set_error (bfd_error_wrong_format);
238        return FALSE;
239 @@ -516,6 +530,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
240  
241    sec->compressed_size = sec->size;
242    sec->size = uncompressed_size;
243 +  bfd_set_section_alignment (abfd, sec, uncompressed_alignment_power);
244    sec->compress_status = DECOMPRESS_SECTION_SIZED;
245  
246    return TRUE;
247 diff --git a/bfd/elf.c b/bfd/elf.c
248 index 828241d48a..c4f131ddcf 100644
249 --- a/bfd/elf.c
250 +++ b/bfd/elf.c
251 @@ -1177,11 +1177,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
252        enum { nothing, compress, decompress } action = nothing;
253        int compression_header_size;
254        bfd_size_type uncompressed_size;
255 +      unsigned int uncompressed_align_power;
256        bfd_boolean compressed
257         = bfd_is_section_compressed_with_header (abfd, newsect,
258                                                  &compression_header_size,
259 -                                                &uncompressed_size);
260 -
261 +                                                &uncompressed_size,
262 +                                                &uncompressed_align_power);
263        if (compressed)
264         {
265           /* Compressed section.  Check if we should decompress.  */
266 diff --git a/binutils/readelf.c b/binutils/readelf.c
267 index f4df697a7d..4b0efa884f 100644
268 --- a/binutils/readelf.c
269 +++ b/binutils/readelf.c
270 @@ -13345,12 +13345,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
271                     printable_section_name (filedata, section), chdr.ch_type);
272               return FALSE;
273             }
274 -         else if (chdr.ch_addralign != section->sh_addralign)
275 -           {
276 -             warn (_("compressed section '%s' is corrupted\n"),
277 -                   printable_section_name (filedata, section));
278 -             return FALSE;
279 -           }
280           uncompressed_size = chdr.ch_size;
281           start += compression_header_size;
282           new_size -= compression_header_size;
283 @@ -13492,12 +13486,6 @@ dump_section_as_bytes (Elf_Internal_Shdr *  section,
284                     printable_section_name (filedata, section), chdr.ch_type);
285               return FALSE;
286             }
287 -         else if (chdr.ch_addralign != section->sh_addralign)
288 -           {
289 -             warn (_("compressed section '%s' is corrupted\n"),
290 -                   printable_section_name (filedata, section));
291 -             return FALSE;
292 -           }
293           uncompressed_size = chdr.ch_size;
294           start += compression_header_size;
295           new_size -= compression_header_size;
296 @@ -13667,12 +13655,6 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
297                     section->name, chdr.ch_type);
298               return FALSE;
299             }
300 -         else if (chdr.ch_addralign != sec->sh_addralign)
301 -           {
302 -             warn (_("compressed section '%s' is corrupted\n"),
303 -                   section->name);
304 -             return FALSE;
305 -           }
306           uncompressed_size = chdr.ch_size;
307           start += compression_header_size;
308           size -= compression_header_size;
309 diff --git a/binutils/testsuite/binutils-all/dw2-3.rS b/binutils/testsuite/binutils-all/dw2-3.rS
310 index f1637e9149..86bc73d9a2 100644
311 --- a/binutils/testsuite/binutils-all/dw2-3.rS
312 +++ b/binutils/testsuite/binutils-all/dw2-3.rS
313 @@ -1,3 +1,3 @@
314  #...
315 - +\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +1
316 + +\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +(4|8)
317  #pass
318 diff --git a/binutils/testsuite/binutils-all/dw2-3.rt b/binutils/testsuite/binutils-all/dw2-3.rt
319 index f59cbaa22b..74e7f8deca 100644
320 --- a/binutils/testsuite/binutils-all/dw2-3.rt
321 +++ b/binutils/testsuite/binutils-all/dw2-3.rt
322 @@ -1,6 +1,6 @@
323  #...
324   +\[[ 0-9]+\] .debug_info
325 - +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +1
326 + +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +(4|8)
327   +\[0+800\]: COMPRESSED
328   +ZLIB, 0+9d, 1
329  #pass
330 -- 
331 2.20.1
332