diff options
| author | Khem Raj <raj.khem@gmail.com> | 2019-01-11 00:15:25 -0800 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-01-14 11:35:55 +0000 |
| commit | 4ebe398b1da64f9e6a02a1e617e38cd8bd6b0eda (patch) | |
| tree | bf5a0de83e03d03c532cefbdcdbbe858e51516d1 | |
| parent | 227aafa1cff4d9e0f9353c4e87b7adc85f603703 (diff) | |
| download | poky-4ebe398b1da64f9e6a02a1e617e38cd8bd6b0eda.tar.gz | |
binutils: bfd doesn't handle ELF compressed data alignment
Backport patches for ld/gold from master
[YOCTO# 13136]
(From OE-Core rev: e0ed2313f22c2ca30477942fc57877b8b194428a)
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
3 files changed, 534 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.31.inc b/meta/recipes-devtools/binutils/binutils-2.31.inc index b8b2d97884..62acec500e 100644 --- a/meta/recipes-devtools/binutils/binutils-2.31.inc +++ b/meta/recipes-devtools/binutils/binutils-2.31.inc | |||
| @@ -37,6 +37,8 @@ SRC_URI = "\ | |||
| 37 | file://0014-Detect-64-bit-MIPS-targets.patch \ | 37 | file://0014-Detect-64-bit-MIPS-targets.patch \ |
| 38 | file://0015-sync-with-OE-libtool-changes.patch \ | 38 | file://0015-sync-with-OE-libtool-changes.patch \ |
| 39 | file://0016-add-i386pep-emulation-for-x86_64.patch \ | 39 | file://0016-add-i386pep-emulation-for-x86_64.patch \ |
| 40 | file://0022-Handle-ELF-compressed-header-alignment-correctly-by-.patch \ | ||
| 41 | file://0023-gold-Get-alignment-of-uncompressed-section-from-ch_a.patch \ | ||
| 40 | file://clang-bfd-fix.patch \ | 42 | file://clang-bfd-fix.patch \ |
| 41 | file://CVE-2018-17358.patch \ | 43 | file://CVE-2018-17358.patch \ |
| 42 | file://CVE-2018-17360.patch \ | 44 | file://CVE-2018-17360.patch \ |
diff --git a/meta/recipes-devtools/binutils/binutils/0022-Handle-ELF-compressed-header-alignment-correctly-by-.patch b/meta/recipes-devtools/binutils/binutils/0022-Handle-ELF-compressed-header-alignment-correctly-by-.patch new file mode 100644 index 0000000000..650de9b9a3 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0022-Handle-ELF-compressed-header-alignment-correctly-by-.patch | |||
| @@ -0,0 +1,332 @@ | |||
| 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 | |||
diff --git a/meta/recipes-devtools/binutils/binutils/0023-gold-Get-alignment-of-uncompressed-section-from-ch_a.patch b/meta/recipes-devtools/binutils/binutils/0023-gold-Get-alignment-of-uncompressed-section-from-ch_a.patch new file mode 100644 index 0000000000..1f072a6057 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0023-gold-Get-alignment-of-uncompressed-section-from-ch_a.patch | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | From 0261ec511ac07177fa488133e0bb3c03860977b3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
| 3 | Date: Sun, 2 Dec 2018 05:42:36 -0800 | ||
| 4 | Subject: [PATCH 2/2] gold: Get alignment of uncompressed section from | ||
| 5 | ch_addralign | ||
| 6 | |||
| 7 | The ELF compression header has a field (ch_addralign) that is set to | ||
| 8 | the alignment of the uncompressed section. This way the section itself | ||
| 9 | can have a different alignment than the decompressed section. Update | ||
| 10 | decompress_input_section to get alignment of the decompressed section | ||
| 11 | and use it when merging decompressed strings. | ||
| 12 | |||
| 13 | PR binutils/23919 | ||
| 14 | * merge.cc (Output_merge_string<Char_type>::do_add_input_section): | ||
| 15 | Get addralign from decompressed_section_contents. | ||
| 16 | * object.cc (build_compressed_section_map): Set info.addralign. | ||
| 17 | (Object::decompressed_section_contents): Add a palign | ||
| 18 | argument and store p->second.addralign in *palign if it isn't | ||
| 19 | NULL. | ||
| 20 | * object.h (Compressed_section_info): Add addralign. | ||
| 21 | (section_is_compressed): Add a palign argument, default it | ||
| 22 | to NULL, store p->second.addralign in *palign if it isn't NULL. | ||
| 23 | (Object::decompressed_section_contents): Likewise. | ||
| 24 | * output.cc (Output_section::add_input_section): Get addralign | ||
| 25 | from section_is_compressed. | ||
| 26 | --- | ||
| 27 | gold/merge.cc | 8 +++++--- | ||
| 28 | gold/object.cc | 11 +++++++++-- | ||
| 29 | gold/object.h | 8 ++++++-- | ||
| 30 | gold/output.cc | 11 ++++++----- | ||
| 31 | 4 files changed, 26 insertions(+), 12 deletions(-) | ||
| 32 | |||
| 33 | Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5f6c22aee74f17393b82934a5682d985672e011a] | ||
| 34 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 35 | |||
| 36 | |||
| 37 | diff --git a/gold/merge.cc b/gold/merge.cc | ||
| 38 | index de00ee9ae9..d7de11789f 100644 | ||
| 39 | --- a/gold/merge.cc | ||
| 40 | +++ b/gold/merge.cc | ||
| 41 | @@ -440,9 +440,11 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object, | ||
| 42 | { | ||
| 43 | section_size_type sec_len; | ||
| 44 | bool is_new; | ||
| 45 | + uint64_t addralign = this->addralign(); | ||
| 46 | const unsigned char* pdata = object->decompressed_section_contents(shndx, | ||
| 47 | &sec_len, | ||
| 48 | - &is_new); | ||
| 49 | + &is_new, | ||
| 50 | + &addralign); | ||
| 51 | |||
| 52 | const Char_type* p = reinterpret_cast<const Char_type*>(pdata); | ||
| 53 | const Char_type* pend = p + sec_len / sizeof(Char_type); | ||
| 54 | @@ -494,7 +496,7 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object, | ||
| 55 | // aligned, so each string within the section must retain the same | ||
| 56 | // modulo. | ||
| 57 | uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata) | ||
| 58 | - & (this->addralign() - 1)); | ||
| 59 | + & (addralign - 1)); | ||
| 60 | bool has_misaligned_strings = false; | ||
| 61 | |||
| 62 | while (p < pend) | ||
| 63 | @@ -503,7 +505,7 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object, | ||
| 64 | |||
| 65 | // Within merge input section each string must be aligned. | ||
| 66 | if (len != 0 | ||
| 67 | - && ((reinterpret_cast<uintptr_t>(p) & (this->addralign() - 1)) | ||
| 68 | + && ((reinterpret_cast<uintptr_t>(p) & (addralign - 1)) | ||
| 69 | != init_align_modulo)) | ||
| 70 | has_misaligned_strings = true; | ||
| 71 | |||
| 72 | diff --git a/gold/object.cc b/gold/object.cc | ||
| 73 | index 374340fa16..711793e5e4 100644 | ||
| 74 | --- a/gold/object.cc | ||
| 75 | +++ b/gold/object.cc | ||
| 76 | @@ -751,11 +751,13 @@ build_compressed_section_map( | ||
| 77 | const unsigned char* contents = | ||
| 78 | obj->section_contents(i, &len, false); | ||
| 79 | uint64_t uncompressed_size; | ||
| 80 | + Compressed_section_info info; | ||
| 81 | if (is_zcompressed) | ||
| 82 | { | ||
| 83 | // Skip over the ".zdebug" prefix. | ||
| 84 | name += 7; | ||
| 85 | uncompressed_size = get_uncompressed_size(contents, len); | ||
| 86 | + info.addralign = shdr.get_sh_addralign(); | ||
| 87 | } | ||
| 88 | else | ||
| 89 | { | ||
| 90 | @@ -763,8 +765,8 @@ build_compressed_section_map( | ||
| 91 | name += 6; | ||
| 92 | elfcpp::Chdr<size, big_endian> chdr(contents); | ||
| 93 | uncompressed_size = chdr.get_ch_size(); | ||
| 94 | + info.addralign = chdr.get_ch_addralign(); | ||
| 95 | } | ||
| 96 | - Compressed_section_info info; | ||
| 97 | info.size = convert_to_section_size_type(uncompressed_size); | ||
| 98 | info.flag = shdr.get_sh_flags(); | ||
| 99 | info.contents = NULL; | ||
| 100 | @@ -3060,7 +3062,8 @@ const unsigned char* | ||
| 101 | Object::decompressed_section_contents( | ||
| 102 | unsigned int shndx, | ||
| 103 | section_size_type* plen, | ||
| 104 | - bool* is_new) | ||
| 105 | + bool* is_new, | ||
| 106 | + uint64_t* palign) | ||
| 107 | { | ||
| 108 | section_size_type buffer_size; | ||
| 109 | const unsigned char* buffer = this->do_section_contents(shndx, &buffer_size, | ||
| 110 | @@ -3087,6 +3090,8 @@ Object::decompressed_section_contents( | ||
| 111 | { | ||
| 112 | *plen = uncompressed_size; | ||
| 113 | *is_new = false; | ||
| 114 | + if (palign != NULL) | ||
| 115 | + *palign = p->second.addralign; | ||
| 116 | return p->second.contents; | ||
| 117 | } | ||
| 118 | |||
| 119 | @@ -3108,6 +3113,8 @@ Object::decompressed_section_contents( | ||
| 120 | // once in this pass. | ||
| 121 | *plen = uncompressed_size; | ||
| 122 | *is_new = true; | ||
| 123 | + if (palign != NULL) | ||
| 124 | + *palign = p->second.addralign; | ||
| 125 | return uncompressed_data; | ||
| 126 | } | ||
| 127 | |||
| 128 | diff --git a/gold/object.h b/gold/object.h | ||
| 129 | index 0b786a5471..b99548463d 100644 | ||
| 130 | --- a/gold/object.h | ||
| 131 | +++ b/gold/object.h | ||
| 132 | @@ -373,6 +373,7 @@ struct Compressed_section_info | ||
| 133 | { | ||
| 134 | section_size_type size; | ||
| 135 | elfcpp::Elf_Xword flag; | ||
| 136 | + uint64_t addralign; | ||
| 137 | const unsigned char* contents; | ||
| 138 | }; | ||
| 139 | typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map; | ||
| 140 | @@ -808,7 +809,8 @@ class Object | ||
| 141 | |||
| 142 | bool | ||
| 143 | section_is_compressed(unsigned int shndx, | ||
| 144 | - section_size_type* uncompressed_size) const | ||
| 145 | + section_size_type* uncompressed_size, | ||
| 146 | + elfcpp::Elf_Xword* palign = NULL) const | ||
| 147 | { | ||
| 148 | if (this->compressed_sections_ == NULL) | ||
| 149 | return false; | ||
| 150 | @@ -818,6 +820,8 @@ class Object | ||
| 151 | { | ||
| 152 | if (uncompressed_size != NULL) | ||
| 153 | *uncompressed_size = p->second.size; | ||
| 154 | + if (palign != NULL) | ||
| 155 | + *palign = p->second.addralign; | ||
| 156 | return true; | ||
| 157 | } | ||
| 158 | return false; | ||
| 159 | @@ -828,7 +832,7 @@ class Object | ||
| 160 | // by the caller. | ||
| 161 | const unsigned char* | ||
| 162 | decompressed_section_contents(unsigned int shndx, section_size_type* plen, | ||
| 163 | - bool* is_cached); | ||
| 164 | + bool* is_cached, uint64_t* palign = NULL); | ||
| 165 | |||
| 166 | // Discard any buffers of decompressed sections. This is done | ||
| 167 | // at the end of the Add_symbols task. | ||
| 168 | diff --git a/gold/output.cc b/gold/output.cc | ||
| 169 | index 1701db1c99..75ac3bcf97 100644 | ||
| 170 | --- a/gold/output.cc | ||
| 171 | +++ b/gold/output.cc | ||
| 172 | @@ -2448,7 +2448,13 @@ Output_section::add_input_section(Layout* layout, | ||
| 173 | unsigned int reloc_shndx, | ||
| 174 | bool have_sections_script) | ||
| 175 | { | ||
| 176 | + section_size_type input_section_size = shdr.get_sh_size(); | ||
| 177 | + section_size_type uncompressed_size; | ||
| 178 | elfcpp::Elf_Xword addralign = shdr.get_sh_addralign(); | ||
| 179 | + if (object->section_is_compressed(shndx, &uncompressed_size, | ||
| 180 | + &addralign)) | ||
| 181 | + input_section_size = uncompressed_size; | ||
| 182 | + | ||
| 183 | if ((addralign & (addralign - 1)) != 0) | ||
| 184 | { | ||
| 185 | object->error(_("invalid alignment %lu for section \"%s\""), | ||
| 186 | @@ -2498,11 +2504,6 @@ Output_section::add_input_section(Layout* layout, | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | - section_size_type input_section_size = shdr.get_sh_size(); | ||
| 191 | - section_size_type uncompressed_size; | ||
| 192 | - if (object->section_is_compressed(shndx, &uncompressed_size)) | ||
| 193 | - input_section_size = uncompressed_size; | ||
| 194 | - | ||
| 195 | off_t offset_in_section; | ||
| 196 | |||
| 197 | if (this->has_fixed_layout()) | ||
| 198 | -- | ||
| 199 | 2.20.1 | ||
| 200 | |||
