1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-14 07:18:42 +03:00

Keep .ctors/.dtors sections if they are read from crtbegin.o or crtend.o

This is needed by Gentoo's dev-lang/gnat-gpl-2018-r3 package,
which still uses GCC7's CRT files.
This commit is contained in:
Rui Ueyama 2021-06-20 17:16:11 +09:00
parent 9a219c0048
commit 83b14328ec
3 changed files with 31 additions and 11 deletions

View File

@ -2,6 +2,36 @@
#include <limits> #include <limits>
template <typename E>
InputSection<E>::InputSection(Context<E> &ctx, ObjectFile<E> &file,
const ElfShdr<E> &shdr, std::string_view name,
std::string_view contents, i64 section_idx)
: file(file), shdr(shdr), nameptr(name.data()), namelen(name.size()),
contents(contents), section_idx(section_idx) {
// As a special case, we want to map .ctors and .dtors to
// .init_array and .fini_array, respectively. However, old CRT
// object files are not compatible with this translation, so we need
// to keep them as-is if a section came from crtbegin.o or crtend.o.
//
// Yeah, this is an ugly hack, but the fundamental problem is that
// we have two different mechanism, ctors/dtors and init_array/fini_array
// for the same purpose. The latter was introduced to replace the
// former, but as it is often the case, the former still lingers
// around, so we need to keep this code to conver the old mechanism
// to the new one.
std::string_view stem = path_filename(file.filename);
if (stem != "crtbegin.o" && stem != "crtend.o" &&
stem != "crtbeginS.o" && stem != "crtendS.o") {
if (name == ".ctors" || name.starts_with(".ctors."))
name = ".init_array";
else if (name == ".dtors" || name.starts_with(".dtors."))
name = ".fini_array";
}
output_section =
OutputSection<E>::get_instance(ctx, name, shdr.sh_type, shdr.sh_flags);
}
template <typename E> template <typename E>
void InputSection<E>::write_to(Context<E> &ctx, u8 *buf) { void InputSection<E>::write_to(Context<E> &ctx, u8 *buf) {
if (shdr.sh_type == SHT_NOBITS || shdr.sh_size == 0) if (shdr.sh_type == SHT_NOBITS || shdr.sh_size == 0)

7
mold.h
View File

@ -255,12 +255,7 @@ class InputSection {
public: public:
InputSection(Context<E> &ctx, ObjectFile<E> &file, const ElfShdr<E> &shdr, InputSection(Context<E> &ctx, ObjectFile<E> &file, const ElfShdr<E> &shdr,
std::string_view name, std::string_view contents, std::string_view name, std::string_view contents,
i64 section_idx) i64 section_idx);
: file(file), shdr(shdr), nameptr(name.data()), namelen(name.size()),
contents(contents), section_idx(section_idx) {
output_section =
OutputSection<E>::get_instance(ctx, name, shdr.sh_type, shdr.sh_flags);
}
void scan_relocations(Context<E> &ctx); void scan_relocations(Context<E> &ctx);
void write_to(Context<E> &ctx, u8 *buf); void write_to(Context<E> &ctx, u8 *buf);

View File

@ -584,11 +584,6 @@ static std::string_view get_output_name(Context<E> &ctx, std::string_view name)
return stem; return stem;
} }
if (name == ".ctors" || name.starts_with(".ctors."))
return ".init_array";
if (name == ".dtors" || name.starts_with(".dtors."))
return ".fini_array";
if (name == ".zdebug_aranges") if (name == ".zdebug_aranges")
return ".debug_aranges"; return ".debug_aranges";
if (name == ".zdebug_frame") if (name == ".zdebug_frame")