gold: Get alignment of uncompressed section from ch_addralign

The ELF compression header has a field (ch_addralign) that is set to
the alignment of the uncompressed section. This way the section itself
can have a different alignment than the decompressed section.  Update
decompress_input_section to get alignment of the decompressed section
and use it when merging decompressed strings.

	PR binutils/23919
	* merge.cc (Output_merge_string<Char_type>::do_add_input_section):
	Get addralign from decompressed_section_contents.
	* object.cc (build_compressed_section_map): Set info.addralign.
	(Object::decompressed_section_contents): Add a palign
	argument and store p->second.addralign in *palign if it isn't
	NULL.
	* object.h (Compressed_section_info): Add addralign.
	(section_is_compressed): Add a palign argument, default it
	to NULL, store p->second.addralign in *palign if it isn't NULL.
	(Object::decompressed_section_contents): Likewise.
	* output.cc (Output_section::add_input_section): Get addralign
	from section_is_compressed.
This commit is contained in:
H.J. Lu 2018-12-02 05:42:36 -08:00
parent 3134061ce6
commit 5f6c22aee7
5 changed files with 42 additions and 12 deletions

View File

@ -1,3 +1,19 @@
2018-12-02 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/23919
* merge.cc (Output_merge_string<Char_type>::do_add_input_section):
Get addralign from decompressed_section_contents.
* object.cc (build_compressed_section_map): Set info.addralign.
(Object::decompressed_section_contents): Add a palign
argument and store p->second.addralign in *palign if it isn't
NULL.
* object.h (Compressed_section_info): Add addralign.
(section_is_compressed): Add a palign argument, default it
to NULL, store p->second.addralign in *palign if it isn't NULL.
(Object::decompressed_section_contents): Likewise.
* output.cc (Output_section::add_input_section): Get addralign
from section_is_compressed.
2018-11-26 Alan Modra <amodra@gmail.com> 2018-11-26 Alan Modra <amodra@gmail.com>
* testsuite/Makefile.am (justsyms_lib): Link with -z norelro. * testsuite/Makefile.am (justsyms_lib): Link with -z norelro.

View File

@ -440,9 +440,11 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
{ {
section_size_type sec_len; section_size_type sec_len;
bool is_new; bool is_new;
uint64_t addralign = this->addralign();
const unsigned char* pdata = object->decompressed_section_contents(shndx, const unsigned char* pdata = object->decompressed_section_contents(shndx,
&sec_len, &sec_len,
&is_new); &is_new,
&addralign);
const Char_type* p = reinterpret_cast<const Char_type*>(pdata); const Char_type* p = reinterpret_cast<const Char_type*>(pdata);
const Char_type* pend = p + sec_len / sizeof(Char_type); const Char_type* pend = p + sec_len / sizeof(Char_type);
@ -494,7 +496,7 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
// aligned, so each string within the section must retain the same // aligned, so each string within the section must retain the same
// modulo. // modulo.
uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata) uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata)
& (this->addralign() - 1)); & (addralign - 1));
bool has_misaligned_strings = false; bool has_misaligned_strings = false;
while (p < pend) while (p < pend)
@ -503,7 +505,7 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
// Within merge input section each string must be aligned. // Within merge input section each string must be aligned.
if (len != 0 if (len != 0
&& ((reinterpret_cast<uintptr_t>(p) & (this->addralign() - 1)) && ((reinterpret_cast<uintptr_t>(p) & (addralign - 1))
!= init_align_modulo)) != init_align_modulo))
has_misaligned_strings = true; has_misaligned_strings = true;

View File

@ -751,11 +751,13 @@ build_compressed_section_map(
const unsigned char* contents = const unsigned char* contents =
obj->section_contents(i, &len, false); obj->section_contents(i, &len, false);
uint64_t uncompressed_size; uint64_t uncompressed_size;
Compressed_section_info info;
if (is_zcompressed) if (is_zcompressed)
{ {
// Skip over the ".zdebug" prefix. // Skip over the ".zdebug" prefix.
name += 7; name += 7;
uncompressed_size = get_uncompressed_size(contents, len); uncompressed_size = get_uncompressed_size(contents, len);
info.addralign = shdr.get_sh_addralign();
} }
else else
{ {
@ -763,8 +765,8 @@ build_compressed_section_map(
name += 6; name += 6;
elfcpp::Chdr<size, big_endian> chdr(contents); elfcpp::Chdr<size, big_endian> chdr(contents);
uncompressed_size = chdr.get_ch_size(); uncompressed_size = chdr.get_ch_size();
info.addralign = chdr.get_ch_addralign();
} }
Compressed_section_info info;
info.size = convert_to_section_size_type(uncompressed_size); info.size = convert_to_section_size_type(uncompressed_size);
info.flag = shdr.get_sh_flags(); info.flag = shdr.get_sh_flags();
info.contents = NULL; info.contents = NULL;
@ -3064,7 +3066,8 @@ const unsigned char*
Object::decompressed_section_contents( Object::decompressed_section_contents(
unsigned int shndx, unsigned int shndx,
section_size_type* plen, section_size_type* plen,
bool* is_new) bool* is_new,
uint64_t* palign)
{ {
section_size_type buffer_size; section_size_type buffer_size;
const unsigned char* buffer = this->do_section_contents(shndx, &buffer_size, const unsigned char* buffer = this->do_section_contents(shndx, &buffer_size,
@ -3091,6 +3094,8 @@ Object::decompressed_section_contents(
{ {
*plen = uncompressed_size; *plen = uncompressed_size;
*is_new = false; *is_new = false;
if (palign != NULL)
*palign = p->second.addralign;
return p->second.contents; return p->second.contents;
} }
@ -3112,6 +3117,8 @@ Object::decompressed_section_contents(
// once in this pass. // once in this pass.
*plen = uncompressed_size; *plen = uncompressed_size;
*is_new = true; *is_new = true;
if (palign != NULL)
*palign = p->second.addralign;
return uncompressed_data; return uncompressed_data;
} }

View File

@ -373,6 +373,7 @@ struct Compressed_section_info
{ {
section_size_type size; section_size_type size;
elfcpp::Elf_Xword flag; elfcpp::Elf_Xword flag;
uint64_t addralign;
const unsigned char* contents; const unsigned char* contents;
}; };
typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map; typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map;
@ -808,7 +809,8 @@ class Object
bool bool
section_is_compressed(unsigned int shndx, section_is_compressed(unsigned int shndx,
section_size_type* uncompressed_size) const section_size_type* uncompressed_size,
elfcpp::Elf_Xword* palign = NULL) const
{ {
if (this->compressed_sections_ == NULL) if (this->compressed_sections_ == NULL)
return false; return false;
@ -818,6 +820,8 @@ class Object
{ {
if (uncompressed_size != NULL) if (uncompressed_size != NULL)
*uncompressed_size = p->second.size; *uncompressed_size = p->second.size;
if (palign != NULL)
*palign = p->second.addralign;
return true; return true;
} }
return false; return false;
@ -828,7 +832,7 @@ class Object
// by the caller. // by the caller.
const unsigned char* const unsigned char*
decompressed_section_contents(unsigned int shndx, section_size_type* plen, decompressed_section_contents(unsigned int shndx, section_size_type* plen,
bool* is_cached); bool* is_cached, uint64_t* palign = NULL);
// Discard any buffers of decompressed sections. This is done // Discard any buffers of decompressed sections. This is done
// at the end of the Add_symbols task. // at the end of the Add_symbols task.

View File

@ -2448,7 +2448,13 @@ Output_section::add_input_section(Layout* layout,
unsigned int reloc_shndx, unsigned int reloc_shndx,
bool have_sections_script) bool have_sections_script)
{ {
section_size_type input_section_size = shdr.get_sh_size();
section_size_type uncompressed_size;
elfcpp::Elf_Xword addralign = shdr.get_sh_addralign(); elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
if (object->section_is_compressed(shndx, &uncompressed_size,
&addralign))
input_section_size = uncompressed_size;
if ((addralign & (addralign - 1)) != 0) if ((addralign & (addralign - 1)) != 0)
{ {
object->error(_("invalid alignment %lu for section \"%s\""), object->error(_("invalid alignment %lu for section \"%s\""),
@ -2498,11 +2504,6 @@ Output_section::add_input_section(Layout* layout,
} }
} }
section_size_type input_section_size = shdr.get_sh_size();
section_size_type uncompressed_size;
if (object->section_is_compressed(shndx, &uncompressed_size))
input_section_size = uncompressed_size;
off_t offset_in_section; off_t offset_in_section;
if (this->has_fixed_layout()) if (this->has_fixed_layout())