From 3711ddb95e23c12991f6b8c7bfeba4f1421d19d4 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 22 Sep 2024 19:28:53 +0900 Subject: [PATCH] Drop DEC Alpha processor support Keeping DEC Alpha support is difficult because there are no Alpha machines available for toolchain developers, and even if there were, no modern Linux distros still support Alpha. For example, Debian dropped Alpha support in Debian 6.0. As a result, I cannot test my linker with real-world programs. In fact, I believe mold has never been able to link real-world large programs. Object files for Alpha are compiled with the small code model by default, so it is not easy to support it in the linker. There's no means to verify that my implementation is correct for Alpha because Alpha's psABI has never been published by DEC. The most "reliable" source of correctness is GNU ld's source code and comments. Last but not least, I believe there are literally zero mold/Alpha users. Unlike some other retro computers like the m68k, Alpha doesn't seem to get much love from the community, perhaps because the availability of Alpha machines was limited in the first place, even in the 90s. Therefore, I'll remove Alpha support now. If there's someone who wants to keep it, we can resurrect and re-test it. This change should make the mold binary size a little smaller. --- CMakeLists.txt | 3 +- README.md | 3 +- install-cross-tools.sh | 2 +- src/arch-alpha.cc | 319 --------------------------------- src/cmdline.cc | 8 +- src/elf.cc | 40 ----- src/elf.h | 91 ---------- src/main.cc | 2 - src/mold.h | 36 ---- src/output-chunks.cc | 7 - src/passes.cc | 11 -- src/tls.cc | 4 +- test/CMakeLists.txt | 7 +- test/abs-error.sh | 1 - test/copyrel-alignment.sh | 1 - test/copyrel-norelro.sh | 1 - test/copyrel-protected.sh | 1 - test/glibc-2.22-bug.sh | 1 - test/nocopyreloc.sh | 1 - test/range-extension-thunk3.sh | 1 - 20 files changed, 9 insertions(+), 531 deletions(-) delete mode 100644 src/arch-alpha.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 60902c5e6d..fe526ebbfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,7 +305,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) # on a multicore machine. list(APPEND MOLD_ELF_TARGETS X86_64 I386 ARM64 ARM32 RV32LE RV32BE RV64LE RV64BE PPC32 PPC64V1 PPC64V2 - S390X SPARC64 M68K SH4 ALPHA LOONGARCH32 LOONGARCH64) + S390X SPARC64 M68K SH4 LOONGARCH32 LOONGARCH64) list(APPEND MOLD_ELF_TEMPLATE_FILES src/arch-loongarch.cc @@ -376,7 +376,6 @@ target_sources(mold PRIVATE lib/perf.cc lib/random.cc lib/tar.cc - src/arch-alpha.cc src/arch-arm32.cc src/arch-arm64.cc src/arch-i386.cc diff --git a/README.md b/README.md index 04dc957beb..c6ddf37bd0 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,7 @@ free to [file a bug report](https://github.com/rui314/mold/issues). mold supports x86-64, i386, ARM64, ARM32, 64-bit/32-bit little/big-endian RISC-V, 32-bit PowerPC, 64-bit big-endian PowerPC ELFv1, 64-bit little-endian -PowerPC ELFv2, s390x, 64-bit/32-bit LoongArch, SPARC64, m68k, SH-4, and DEC -Alpha. +PowerPC ELFv2, s390x, 64-bit/32-bit LoongArch, SPARC64, m68k, and SH-4. ## Why does linking speed matter? diff --git a/install-cross-tools.sh b/install-cross-tools.sh index 86dc10dda7..fcac8ef8f4 100755 --- a/install-cross-tools.sh +++ b/install-cross-tools.sh @@ -11,7 +11,7 @@ set -x case "$ID-$VERSION_ID" in ubuntu-* | pop-* | linuxmint-* | debian-* | raspbian-*) - apt-get install -y qemu-user {gcc,g++}-{i686,aarch64,riscv64,powerpc,powerpc64,powerpc64le,s390x,sparc64,m68k,sh4,alpha}-linux-gnu {gcc,g++}-arm-linux-gnueabihf + apt-get install -y qemu-user {gcc,g++}-{i686,aarch64,riscv64,powerpc,powerpc64,powerpc64le,s390x,sparc64,m68k,sh4}-linux-gnu {gcc,g++}-arm-linux-gnueabihf ;; *) echo "Error: don't know anything about build dependencies on $ID-$VERSION_ID" diff --git a/src/arch-alpha.cc b/src/arch-alpha.cc deleted file mode 100644 index c870151995..0000000000 --- a/src/arch-alpha.cc +++ /dev/null @@ -1,319 +0,0 @@ -// Alpha is a 64-bit RISC ISA developed by DEC (Digital Equipment -// Corporation) in the early '90s. It aimed to be an ISA that would last -// 25 years. DEC expected Alpha would become 1000x faster during that time -// span. Since the ISA was developed from scratch for future machines, -// it's 64-bit from the beginning. There's no 32-bit variant. -// -// DEC ported its own Unix (Tru64) to Alpha. Microsoft also ported Windows -// NT to it. But it wasn't a huge commercial success. -// -// DEC was acquired by Compaq in 1997. In the late '90s, Intel and -// Hewlett-Packard were advertising that their upcoming Itanium processor -// would achieve significantly better performance than RISC processors, so -// Compaq decided to discontinue the Alpha processor line to switch to -// Itanium. Itanium resulted in a miserable failure, but it still suceeded -// to wipe out several RISC processors just by promising overly optimistic -// perf numbers. Alpha as an ISA would probably have been fine after 25 -// years since its introduction (which is 1992 + 25 = 2017), but the -// company and its market didn't last that long. -// -// From the linker's point of view, there are a few peculiarities in its -// psABI as shown below: -// -// - Alpha lacks PC-relative memory load/store instructions, so it uses -// register-relative load/store instructions in position-independent -// code. Specifically, GP (which is an alias for $r29) is always -// maintained to refer to .got+0x8000, and global variables' addresses -// are loaded in a GP-relative manner. -// -// - It looks like even function addresses are first loaded to register -// in a GP-relative manner before calling it. We can relax it to -// convert the instruction sequence with a direct branch instruction, -// but by default, object files don't use a direct branch to call a -// function. Therefore, by default, we don't need to create a PLT. -// Any function call is made by first reading its address from GOT and -// jump to the address. - -#include "mold.h" - -namespace mold { - -using E = ALPHA; - -// A 32-bit immediate can be materialized in a register with a "load high" -// and a "load low" instruction sequence. The first instruction sets the -// upper 16 bits in a register, and the second one set the lower 16 -// bits. When doing so, they sign-extend an immediate. Therefore, if the -// 15th bit of an immediate happens to be 1, setting a "low half" value -// negates the upper 16 bit values that has already been set in a -// register. To compensate that, we need to add 0x8000 when setting the -// upper 16 bits. -static u32 hi(u32 val) { - return bits(val + 0x8000, 31, 16); -} - -template <> -void write_plt_header(Context &ctx, u8 *buf) {} - -template <> -void write_plt_entry(Context &ctx, u8 *buf, Symbol &sym) {} - -template <> -void write_pltgot_entry(Context &ctx, u8 *buf, Symbol &sym) {} - -template <> -void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel, - u64 offset, u64 val) { - u8 *loc = ctx.buf + this->shdr.sh_offset + offset; - - switch (rel.r_type) { - case R_NONE: - break; - case R_ALPHA_SREL32: - *(ul32 *)loc = val - this->shdr.sh_addr - offset; - break; - default: - Fatal(ctx) << "unsupported relocation in .eh_frame: " << rel; - } -} - -template <> -void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { - std::span> rels = get_rels(ctx); - - for (i64 i = 0; i < rels.size(); i++) { - const ElfRel &rel = rels[i]; - if (rel.r_type == R_NONE) - continue; - - Symbol &sym = *file.symbols[rel.r_sym]; - u8 *loc = base + rel.r_offset; - - u64 S = sym.get_addr(ctx); - u64 A = rel.r_addend; - u64 P = get_addr() + rel.r_offset; - u64 G = sym.get_got_idx(ctx) * sizeof(Word); - u64 GOT = ctx.got->shdr.sh_addr; - u64 GP = ctx.got->shdr.sh_addr + 0x8000; - - switch (rel.r_type) { - case R_ALPHA_GPREL32: - *(ul32 *)loc = S + A - GP; - break; - case R_ALPHA_LITERAL: - if (A) - *(ul16 *)loc = ctx.extra.got->get_addr(sym, A) - GP; - else - *(ul16 *)loc = GOT + G - GP; - break; - case R_ALPHA_BRSGP: - *(ul32 *)loc |= bits(S + A - P - 4, 22, 0); - break; - case R_ALPHA_GPDISP: - *(ul16 *)loc = hi(GP - P); - *(ul16 *)(loc + A) = GP - P; - break; - case R_ALPHA_SREL32: - *(ul32 *)loc = S + A - P; - break; - case R_ALPHA_GPRELHIGH: - *(ul16 *)loc = hi(S + A - GP); - break; - case R_ALPHA_GPRELLOW: - *(ul16 *)loc = S + A - GP; - break; - case R_ALPHA_TLSGD: - *(ul16 *)loc = sym.get_tlsgd_addr(ctx) - GP; - break; - case R_ALPHA_TLSLDM: - *(ul16 *)loc = ctx.got->get_tlsld_addr(ctx) - GP; - break; - case R_ALPHA_DTPRELHI: - *(ul16 *)loc = hi(S + A - ctx.dtp_addr); - break; - case R_ALPHA_DTPRELLO: - *(ul16 *)loc = S + A - ctx.dtp_addr; - break; - case R_ALPHA_GOTTPREL: - *(ul16 *)loc = sym.get_gottp_addr(ctx) + A - GP; - break; - case R_ALPHA_TPRELHI: - *(ul16 *)loc = hi(S + A - ctx.tp_addr); - break; - case R_ALPHA_TPRELLO: - *(ul16 *)loc = S + A - ctx.tp_addr; - break; - case R_ALPHA_REFQUAD: - case R_ALPHA_LITUSE: - case R_ALPHA_HINT: - break; - default: - unreachable(); - } - } -} - -template <> -void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) { - std::span> rels = get_rels(ctx); - - for (i64 i = 0; i < rels.size(); i++) { - const ElfRel &rel = rels[i]; - if (rel.r_type == R_NONE || record_undef_error(ctx, rel)) - continue; - - Symbol &sym = *file.symbols[rel.r_sym]; - u8 *loc = base + rel.r_offset; - - SectionFragment *frag; - i64 frag_addend; - std::tie(frag, frag_addend) = get_fragment(ctx, rel); - - u64 S = frag ? frag->get_addr(ctx) : sym.get_addr(ctx); - u64 A = frag ? frag_addend : (i64)rel.r_addend; - - switch (rel.r_type) { - case R_ALPHA_REFLONG: - if (std::optional val = get_tombstone(sym, frag)) - *(ul32 *)loc = *val; - else - *(ul32 *)loc = S + A; - break; - case R_ALPHA_REFQUAD: - if (std::optional val = get_tombstone(sym, frag)) - *(ul64 *)loc = *val; - else - *(ul64 *)loc = S + A; - break; - default: - Fatal(ctx) << *this << ": invalid relocation for non-allocated sections: " - << rel; - } - } -} - -template <> -void InputSection::scan_relocations(Context &ctx) { - assert(shdr().sh_flags & SHF_ALLOC); - std::span> rels = get_rels(ctx); - - for (i64 i = 0; i < rels.size(); i++) { - const ElfRel &rel = rels[i]; - if (rel.r_type == R_NONE || record_undef_error(ctx, rel)) - continue; - - Symbol &sym = *file.symbols[rel.r_sym]; - - if (sym.is_ifunc()) - Error(ctx) << sym << ": GNU ifunc symbol is not supported on Alpha"; - - switch (rel.r_type) { - case R_ALPHA_LITERAL: - if (rel.r_addend) - ctx.extra.got->add_symbol(sym, rel.r_addend); - else - sym.flags |= NEEDS_GOT; - break; - case R_ALPHA_SREL32: - scan_pcrel(ctx, sym, rel); - break; - case R_ALPHA_BRSGP: - if (sym.is_imported) - sym.flags |= NEEDS_PLT; - break; - case R_ALPHA_TLSGD: - sym.flags |= NEEDS_TLSGD; - break; - case R_ALPHA_TLSLDM: - ctx.needs_tlsld = true; - break; - case R_ALPHA_GOTTPREL: - sym.flags |= NEEDS_GOTTP; - break; - case R_ALPHA_TPRELHI: - case R_ALPHA_TPRELLO: - check_tlsle(ctx, sym, rel); - break; - case R_ALPHA_REFQUAD: - case R_ALPHA_GPREL32: - case R_ALPHA_LITUSE: - case R_ALPHA_GPDISP: - case R_ALPHA_HINT: - case R_ALPHA_GPRELHIGH: - case R_ALPHA_GPRELLOW: - case R_ALPHA_DTPRELHI: - case R_ALPHA_DTPRELLO: - break; - default: - Fatal(ctx) << *this << ": unknown relocation: " << rel; - } - } -} - -// An R_ALPHA_LITERAL relocation may request the linker to create a GOT -// entry for an external symbol with a non-zero addend. This is an unusual -// request which is not found in any other targets. -// -// Referring an external symbol with a non-zero addend is a bad practice -// because we need to create as many dynamic relocations as the number of -// distinctive addends for the same symbol. -// -// We don't want to mess up the implementation of the common GOT section -// for Alpha. So we create another GOT-like section, .alpha_got. Any GOT -// entry for an R_ALPHA_LITERAL reloc with a non-zero addend is created -// not in .got but in .alpha_got. -// -// Since .alpha_got entries are accessed relative to GP, .alpha_got -// needs to be close enough to .got. It's actually placed next to .got. -void AlphaGotSection::add_symbol(Symbol &sym, i64 addend) { - assert(addend); - std::scoped_lock lock(mu); - entries.push_back({&sym, addend}); -} - -bool operator<(const AlphaGotSection::Entry &a, const AlphaGotSection::Entry &b) { - return std::tuple(a.sym->file->priority, a.sym->sym_idx, a.addend) < - std::tuple(b.sym->file->priority, b.sym->sym_idx, b.addend); -}; - -u64 AlphaGotSection::get_addr(Symbol &sym, i64 addend) { - auto it = std::lower_bound(entries.begin(), entries.end(), Entry{&sym, addend}); - assert(it != entries.end()); - return this->shdr.sh_addr + (it - entries.begin()) * sizeof(Word); -} - -i64 AlphaGotSection::get_reldyn_size(Context &ctx) const { - i64 n = 0; - for (const Entry &e : entries) - if (e.sym->is_imported || (ctx.arg.pic && !e.sym->is_absolute())) - n++; - return n; -} - -void AlphaGotSection::finalize() { - sort(entries); - remove_duplicates(entries); - shdr.sh_size = entries.size() * sizeof(Word); -} - -void AlphaGotSection::copy_buf(Context &ctx) { - ElfRel *dynrel = (ElfRel *)(ctx.buf + ctx.reldyn->shdr.sh_offset + - reldyn_offset); - - for (i64 i = 0; i < entries.size(); i++) { - Entry &e = entries[i]; - u64 P = this->shdr.sh_addr + sizeof(Word) * i; - ul64 *buf = (ul64 *)(ctx.buf + this->shdr.sh_offset + sizeof(Word) * i); - - if (e.sym->is_imported) { - *buf = ctx.arg.apply_dynamic_relocs ? e.addend : 0; - *dynrel++ = ElfRel(P, E::R_ABS, e.sym->get_dynsym_idx(ctx), e.addend); - } else { - *buf = e.sym->get_addr(ctx) + e.addend; - if (ctx.arg.pic && !e.sym->is_absolute()) - *dynrel++ = ElfRel(P, E::R_RELATIVE, 0, *buf); - } - } -} - -} // namespace mold diff --git a/src/cmdline.cc b/src/cmdline.cc index 6d10875a88..bdb79ed9d4 100644 --- a/src/cmdline.cc +++ b/src/cmdline.cc @@ -222,8 +222,8 @@ inline const char helpmsg[] = R"( -z notext -z textoff -mold: supported targets: elf32-i386 elf64-x86-64 elf32-littlearm elf64-littleaarch64 elf32-littleriscv elf32-bigriscv elf64-littleriscv elf64-bigriscv elf32-powerpc elf64-powerpc elf64-powerpc elf64-powerpcle elf64-s390 elf64-sparc elf32-m68k elf32-sh-linux elf64-alpha elf64-loongarch elf32-loongarch -mold: supported emulations: elf_i386 elf_x86_64 armelf_linux_eabi aarch64linux aarch64elf elf32lriscv elf32briscv elf64lriscv elf64briscv elf32ppc elf32ppclinux elf64ppc elf64lppc elf64_s390 elf64_sparc m68kelf shlelf_linux elf64alpha elf64loongarch elf32loongarch)"; +mold: supported targets: elf32-i386 elf64-x86-64 elf32-littlearm elf64-littleaarch64 elf32-littleriscv elf32-bigriscv elf64-littleriscv elf64-bigriscv elf32-powerpc elf64-powerpc elf64-powerpc elf64-powerpcle elf64-s390 elf64-sparc elf32-m68k elf32-sh-linux elf64-loongarch elf32-loongarch +mold: supported emulations: elf_i386 elf_x86_64 armelf_linux_eabi aarch64linux aarch64elf elf32lriscv elf32briscv elf64lriscv elf64briscv elf32ppc elf32ppclinux elf64ppc elf64lppc elf64_s390 elf64_sparc m68kelf shlelf_linux elf64loongarch elf32loongarch)"; template static std::vector @@ -682,7 +682,7 @@ std::vector parse_nonpositional_args(Context &ctx) { << " elf64briscv\n elf32lriscv\n elf32briscv\n" << " elf32ppc\n elf64ppc\n elf64lppc\n elf64_s390\n" << " elf64_sparc\n m68kelf\n shlelf_linux\n" - << " elf64alpha\n elf64loongarch\n elf32loongarch"; + << " elf64loongarch\n elf32loongarch"; version_shown = true; } else if (read_arg("m")) { if (arg == "elf_x86_64") { @@ -715,8 +715,6 @@ std::vector parse_nonpositional_args(Context &ctx) { ctx.arg.emulation = M68K::target_name; } else if (arg == "shlelf_linux") { ctx.arg.emulation = SH4::target_name; - } else if (arg == "elf64alpha") { - ctx.arg.emulation = ALPHA::target_name; } else if (arg == "elf64loongarch") { ctx.arg.emulation = LOONGARCH64::target_name; } else if (arg == "elf32loongarch") { diff --git a/src/elf.cc b/src/elf.cc index 8e3af39d0c..8f78df67bc 100644 --- a/src/elf.cc +++ b/src/elf.cc @@ -890,46 +890,6 @@ std::string rel_to_string(u32 r_type) { return unknown_type(r_type); } -template <> -std::string rel_to_string(u32 r_type) { - switch (r_type) { - CASE(R_ALPHA_NONE); - CASE(R_ALPHA_REFLONG); - CASE(R_ALPHA_REFQUAD); - CASE(R_ALPHA_GPREL32); - CASE(R_ALPHA_LITERAL); - CASE(R_ALPHA_LITUSE); - CASE(R_ALPHA_GPDISP); - CASE(R_ALPHA_BRADDR); - CASE(R_ALPHA_HINT); - CASE(R_ALPHA_SREL16); - CASE(R_ALPHA_SREL32); - CASE(R_ALPHA_SREL64); - CASE(R_ALPHA_GPRELHIGH); - CASE(R_ALPHA_GPRELLOW); - CASE(R_ALPHA_GPREL16); - CASE(R_ALPHA_COPY); - CASE(R_ALPHA_GLOB_DAT); - CASE(R_ALPHA_JMP_SLOT); - CASE(R_ALPHA_RELATIVE); - CASE(R_ALPHA_BRSGP); - CASE(R_ALPHA_TLSGD); - CASE(R_ALPHA_TLSLDM); - CASE(R_ALPHA_DTPMOD64); - CASE(R_ALPHA_GOTDTPREL); - CASE(R_ALPHA_DTPREL64); - CASE(R_ALPHA_DTPRELHI); - CASE(R_ALPHA_DTPRELLO); - CASE(R_ALPHA_DTPREL16); - CASE(R_ALPHA_GOTTPREL); - CASE(R_ALPHA_TPREL64); - CASE(R_ALPHA_TPRELHI); - CASE(R_ALPHA_TPRELLO); - CASE(R_ALPHA_TPREL16); - } - return unknown_type(r_type); -} - template <> std::string rel_to_string(u32 r_type) { switch (r_type) { diff --git a/src/elf.h b/src/elf.h index 2467ec3d0e..08ca6db274 100644 --- a/src/elf.h +++ b/src/elf.h @@ -24,7 +24,6 @@ struct S390X; struct SPARC64; struct M68K; struct SH4; -struct ALPHA; struct LOONGARCH64; struct LOONGARCH32; @@ -239,7 +238,6 @@ enum : u32 { EM_AARCH64 = 183, EM_RISCV = 243, EM_LOONGARCH = 258, - EM_ALPHA = 0x9026, }; enum : u32 { @@ -386,8 +384,6 @@ enum : u32 { enum : u32 { STO_RISCV_VARIANT_CC = 0x80, - STO_ALPHA_NOPV = 0x20, - STO_ALPHA_STD_GPLOAD = 0x22, }; enum : u32 { @@ -1234,42 +1230,6 @@ enum : u32 { R_SH_GOTPLT32 = 168, }; -enum : u32 { - R_ALPHA_NONE = 0, - R_ALPHA_REFLONG = 1, - R_ALPHA_REFQUAD = 2, - R_ALPHA_GPREL32 = 3, - R_ALPHA_LITERAL = 4, - R_ALPHA_LITUSE = 5, - R_ALPHA_GPDISP = 6, - R_ALPHA_BRADDR = 7, - R_ALPHA_HINT = 8, - R_ALPHA_SREL16 = 9, - R_ALPHA_SREL32 = 10, - R_ALPHA_SREL64 = 11, - R_ALPHA_GPRELHIGH = 17, - R_ALPHA_GPRELLOW = 18, - R_ALPHA_GPREL16 = 19, - R_ALPHA_COPY = 24, - R_ALPHA_GLOB_DAT = 25, - R_ALPHA_JMP_SLOT = 26, - R_ALPHA_RELATIVE = 27, - R_ALPHA_BRSGP = 28, - R_ALPHA_TLSGD = 29, - R_ALPHA_TLSLDM = 30, - R_ALPHA_DTPMOD64 = 31, - R_ALPHA_GOTDTPREL = 32, - R_ALPHA_DTPREL64 = 33, - R_ALPHA_DTPRELHI = 34, - R_ALPHA_DTPRELLO = 35, - R_ALPHA_DTPREL16 = 36, - R_ALPHA_GOTTPREL = 37, - R_ALPHA_TPREL64 = 38, - R_ALPHA_TPRELHI = 39, - R_ALPHA_TPRELLO = 40, - R_ALPHA_TPREL16 = 41, -}; - enum : u32 { R_LARCH_NONE = 0, R_LARCH_32 = 1, @@ -1812,33 +1772,6 @@ struct ElfSym { ul64 st_size; }; -template <> -struct ElfSym { - bool is_undef() const { return st_shndx == SHN_UNDEF; } - bool is_abs() const { return st_shndx == SHN_ABS; } - bool is_common() const { return st_shndx == SHN_COMMON; } - bool is_weak() const { return st_bind == STB_WEAK; } - bool is_undef_weak() const { return is_undef() && is_weak(); } - - ul32 st_name; - -#ifdef __LITTLE_ENDIAN__ - u8 st_type : 4; - u8 st_bind : 4; - u8 st_visibility : 2; - u8 alpha_st_other : 6; // contains STO_ALPHA_NOPV, STO_ALPHA_STD_GPLOAD or 0 -#else - u8 st_bind : 4; - u8 st_type : 4; - u8 alpha_st_other : 6; - u8 st_visibility : 2; -#endif - - ul16 st_shndx; - ul64 st_value; - ul64 st_size; -}; - template <> struct ElfRel { ElfRel() = default; @@ -1892,7 +1825,6 @@ template concept is_s390x = std::same_as; template concept is_sparc64 = std::same_as; template concept is_m68k = std::same_as; template concept is_sh4 = std::same_as; -template concept is_alpha = std::same_as; template concept is_loongarch64 = std::same_as; template concept is_loongarch32 = std::same_as; @@ -2241,29 +2173,6 @@ struct SH4 { static constexpr u32 R_FUNCALL[] = { R_SH_PLT32 }; }; -struct ALPHA { - static constexpr std::string_view target_name = "alpha"; - static constexpr bool is_64 = true; - static constexpr bool is_le = true; - static constexpr bool is_rela = true; - static constexpr u32 page_size = 65536; - static constexpr u32 e_machine = EM_ALPHA; - static constexpr u32 plt_hdr_size = 0; - static constexpr u32 plt_size = 0; - static constexpr u32 pltgot_size = 0; - static constexpr u8 filler[] = { 0x81, 0x00, 0x00, 0x00 }; // bugchk - - static constexpr u32 R_COPY = R_ALPHA_COPY; - static constexpr u32 R_GLOB_DAT = R_ALPHA_GLOB_DAT; - static constexpr u32 R_JUMP_SLOT = R_ALPHA_JMP_SLOT; - static constexpr u32 R_ABS = R_ALPHA_REFQUAD; - static constexpr u32 R_RELATIVE = R_ALPHA_RELATIVE; - static constexpr u32 R_DTPOFF = R_ALPHA_DTPREL64; - static constexpr u32 R_TPOFF = R_ALPHA_TPREL64; - static constexpr u32 R_DTPMOD = R_ALPHA_DTPMOD64; - static constexpr u32 R_FUNCALL[] = {}; -}; - struct LOONGARCH64 { static constexpr std::string_view target_name = "loongarch64"; static constexpr bool is_64 = true; diff --git a/src/main.cc b/src/main.cc index 8e7d45721a..ce94043c99 100644 --- a/src/main.cc +++ b/src/main.cc @@ -74,8 +74,6 @@ get_machine_type(Context &ctx, ReaderContext &rctx, MappedFile *mf) { return M68K::target_name; case EM_SH: return SH4::target_name; - case EM_ALPHA: - return ALPHA::target_name; case EM_LOONGARCH: return is_64 ? LOONGARCH64::target_name : LOONGARCH32::target_name; default: diff --git a/src/mold.h b/src/mold.h index dc0f7cd9a6..322a0ea880 100644 --- a/src/mold.h +++ b/src/mold.h @@ -1713,37 +1713,6 @@ class PPC64SaveRestoreSection : public Chunk { template <> u64 get_eflags(Context &ctx); -// -// arch-alpha.cc -// - -class AlphaGotSection : public Chunk { -public: - AlphaGotSection() { - this->name = ".alpha_got"; - this->is_relro = true; - this->shdr.sh_type = SHT_PROGBITS; - this->shdr.sh_flags = SHF_ALLOC | SHF_WRITE; - this->shdr.sh_addralign = 8; - } - - void add_symbol(Symbol &sym, i64 addend); - void finalize(); - u64 get_addr(Symbol &sym, i64 addend); - i64 get_reldyn_size(Context &ctx) const override; - void copy_buf(Context &ctx) override; - - struct Entry { - bool operator==(const Entry &) const = default; - Symbol *sym; - i64 addend; - }; - -private: - std::vector entries; - std::mutex mu; -}; - // // main.cc // @@ -1852,11 +1821,6 @@ struct ContextExtras { Symbol *tls_get_addr = nullptr; }; -template <> -struct ContextExtras { - AlphaGotSection *got = nullptr; -}; - // Context represents a context object for each invocation of the linker. // It contains command line flags, pointers to singleton objects // (such as linker-synthesized output sections), unique_ptrs for diff --git a/src/output-chunks.cc b/src/output-chunks.cc index 03bc4b0d74..149859abeb 100644 --- a/src/output-chunks.cc +++ b/src/output-chunks.cc @@ -1771,9 +1771,6 @@ ElfSym to_output_esym(Context &ctx, Symbol &sym, u32 st_name, if constexpr (is_ppc64v2) esym.ppc_local_entry = sym.esym().ppc_local_entry; - if constexpr (is_alpha) - esym.alpha_st_other = sym.esym().alpha_st_other; - auto get_st_shndx = [&](Symbol &sym) -> u32 { if (SectionFragment *frag = sym.get_frag()) if (frag->is_alive) @@ -2962,10 +2959,6 @@ void RelocSection::copy_buf(Context &ctx) { i64 addend; std::tie(symidx, addend) = get_symidx_addend(isec, rel); - if constexpr (is_alpha) - if (rel.r_type == R_ALPHA_GPDISP || rel.r_type == R_ALPHA_LITUSE) - addend = rel.r_addend; - i64 r_offset = isec.output_section->shdr.sh_addr + isec.offset + rel.r_offset; out = ElfRel(r_offset, rel.r_type, symidx, addend); diff --git a/src/passes.cc b/src/passes.cc index 7f215ebe2b..807bb2bc7a 100644 --- a/src/passes.cc +++ b/src/passes.cc @@ -49,8 +49,6 @@ int redo_main(Context &ctx, int argc, char **argv) { return mold_main(argc, argv); if (target == SH4::target_name) return mold_main(argc, argv); - if (target == ALPHA::target_name) - return mold_main(argc, argv); if (target == LOONGARCH32::target_name) return mold_main(argc, argv); if (target == LOONGARCH64::target_name) @@ -188,9 +186,6 @@ void create_synthetic_sections(Context &ctx) { if constexpr (is_ppc64v2) ctx.extra.save_restore = push(new PPC64SaveRestoreSection); - - if constexpr (is_alpha) - ctx.extra.got = push(new AlphaGotSection); } template @@ -1533,9 +1528,6 @@ void scan_relocations(Context &ctx) { sym->flags = 0; } - if constexpr (is_alpha) - ctx.extra.got->finalize(); - if (ctx.has_textrel && ctx.arg.warn_textrel) Warn(ctx) << "creating a DT_TEXTREL in an output file"; } @@ -2145,7 +2137,6 @@ void compute_address_significance(Context &ctx) { // // .got // .toc -// .alpha_got // // .relro_padding // @@ -2238,8 +2229,6 @@ void sort_output_sections_regular(Context &ctx) { return 2; if (chunk->name == ".toc") return 3; - if (chunk->name == ".alpha_got") - return 4; if (chunk == ctx.relro_padding) return INT64_MAX; return 0; diff --git a/src/tls.cc b/src/tls.cc index 365fdb35b3..8d8476d2de 100644 --- a/src/tls.cc +++ b/src/tls.cc @@ -137,8 +137,8 @@ u64 get_tp_addr(const ElfPhdr &phdr) { // and %a0/%a1 on s390x) refers to past the end of the TLS block for // historical reasons. TLVs are accessed with negative offsets from TP. return align_to(phdr.p_vaddr + phdr.p_memsz, phdr.p_align); - } else if constexpr (is_arm || is_sh4 || is_alpha) { - // On ARM, SH4 and Alpha, the runtime appends two words at the beginning + } else if constexpr (is_arm || is_sh4) { + // On ARM and SH4, the runtime appends two words at the beginning // of TLV template image when copying TLVs to the TLS block, so we need // to offset it. return align_down(phdr.p_vaddr - sizeof(Word) * 2, phdr.p_align); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fb22c0e425..e64a1f0ee0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,7 +31,7 @@ endif() if(MOLD_ENABLE_QEMU_TESTS) list(APPEND QEMU_ARCHS x86_64 i386 arm aarch64 ppc ppc64 ppc64le sparc64 sh4 s390x - alpha riscv64 riscv32 m68k loongarch64) + riscv64 riscv32 m68k loongarch64) LIST(APPEND TRIPLES x86_64-linux-gnu @@ -45,7 +45,6 @@ if(MOLD_ENABLE_QEMU_TESTS) sparc64-linux-gnu s390x-linux-gnu sh4-linux-gnu - alpha-linux-gnu riscv32-linux-gnu m68k-linux-gnu loongarch64-linux-gnu) @@ -168,10 +167,6 @@ if(${MACHINE} STREQUAL "sh4" OR (HAS_qemu-sh4 AND HAS_sh4-linux-gnu-gcc)) add_target(sh4 sh4-linux-gnu) endif() -if(${MACHINE} STREQUAL "alpha" OR (HAS_qemu-alpha AND HAS_alpha-linux-gnu-gcc)) - add_target(alpha alpha-linux-gnu) -endif() - if(${MACHINE} STREQUAL "m68k" OR (HAS_qemu-m68k AND HAS_m68k-linux-gnu-gcc)) add_target(m68k m68k-linux-gnu) endif() diff --git a/test/abs-error.sh b/test/abs-error.sh index ca1cc1d7fe..65499c3101 100755 --- a/test/abs-error.sh +++ b/test/abs-error.sh @@ -5,7 +5,6 @@ [ $MACHINE = ppc64 ] && skip [ $MACHINE = ppc64le ] && skip [ $MACHINE = s390x ] && skip -[ $MACHINE = alpha ] && skip [[ $MACHINE = loongarch* ]] && skip cat < $t/a.c