Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -315,6 +315,9 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA) const { switch (Type) { + case R_386_32: + add32le(Loc, SA); + break; case R_386_GOT32: add32le(Loc, SA - Out::Got->getVA()); break; @@ -324,9 +327,6 @@ case R_386_PC32: add32le(Loc, SA - P); break; - case R_386_32: - add32le(Loc, SA); - break; case R_386_TLS_LE: write32le(Loc, SA - Out::TlsPhdr->p_memsz); break; @@ -462,13 +462,13 @@ switch (Type) { default: return false; - case R_X86_64_PC64: - case R_X86_64_PC32: - case R_X86_64_PC16: - case R_X86_64_PC8: - case R_X86_64_PLT32: case R_X86_64_DTPOFF32: case R_X86_64_DTPOFF64: + case R_X86_64_PC8: + case R_X86_64_PC16: + case R_X86_64_PC32: + case R_X86_64_PC64: + case R_X86_64_PLT32: return true; } } @@ -568,20 +568,20 @@ uint32_t Type, uint64_t P, uint64_t SA) const { switch (Type) { + case R_X86_64_DTPOFF32: + relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA); + return 0; case R_X86_64_GOTTPOFF: relocateTlsIeToLe(Loc, BufEnd, P, SA); return 0; - case R_X86_64_TLSLD: - relocateTlsLdToLe(Loc, BufEnd, P, SA); - // The next relocation should be against __tls_get_addr, so skip it - return 1; case R_X86_64_TLSGD: relocateTlsGdToLe(Loc, BufEnd, P, SA); // The next relocation should be against __tls_get_addr, so skip it return 1; - case R_X86_64_DTPOFF32: - relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA); - return 0; + case R_X86_64_TLSLD: + relocateTlsLdToLe(Loc, BufEnd, P, SA); + // The next relocation should be against __tls_get_addr, so skip it + return 1; } llvm_unreachable("Unknown TLS optimization"); } @@ -589,18 +589,6 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA) const { switch (Type) { - case R_X86_64_PC32: - case R_X86_64_GOTPCREL: - case R_X86_64_PLT32: - case R_X86_64_TLSLD: - case R_X86_64_TLSGD: - case R_X86_64_TPOFF64: - write32le(Loc, SA - P); - break; - case R_X86_64_64: - case R_X86_64_DTPOFF64: - write64le(Loc, SA); - break; case R_X86_64_32: checkUInt<32>(SA, Type); write32le(Loc, SA); @@ -609,15 +597,31 @@ checkInt<32>(SA, Type); write32le(Loc, SA); break; + case R_X86_64_64: + write64le(Loc, SA); + break; case R_X86_64_DTPOFF32: write32le(Loc, SA); break; + case R_X86_64_DTPOFF64: + write64le(Loc, SA); + break; + case R_X86_64_GOTPCREL: + case R_X86_64_PC32: + case R_X86_64_PLT32: + case R_X86_64_TLSGD: + case R_X86_64_TLSLD: + write32le(Loc, SA - P); + break; case R_X86_64_TPOFF32: { uint64_t Val = SA - Out::TlsPhdr->p_memsz; checkInt<32>(Val, Type); write32le(Loc, Val); break; } + case R_X86_64_TPOFF64: + write32le(Loc, SA - P); + break; default: error("unrecognized reloc " + Twine(Type)); } @@ -706,10 +710,10 @@ switch (Type) { default: return false; case R_PPC64_GOT16: - case R_PPC64_GOT16_LO: - case R_PPC64_GOT16_HI: - case R_PPC64_GOT16_HA: case R_PPC64_GOT16_DS: + case R_PPC64_GOT16_HA: + case R_PPC64_GOT16_HI: + case R_PPC64_GOT16_LO: case R_PPC64_GOT16_LO_DS: return true; } @@ -724,8 +728,8 @@ switch (Type) { default: return true; - case R_PPC64_TOC: case R_PPC64_ADDR64: + case R_PPC64_TOC: return false; } } @@ -739,14 +743,21 @@ switch (Type) { case R_PPC64_TOC16: Type = R_PPC64_ADDR16; SA -= TB; break; case R_PPC64_TOC16_DS: Type = R_PPC64_ADDR16_DS; SA -= TB; break; + case R_PPC64_TOC16_HA: Type = R_PPC64_ADDR16_HA; SA -= TB; break; + case R_PPC64_TOC16_HI: Type = R_PPC64_ADDR16_HI; SA -= TB; break; case R_PPC64_TOC16_LO: Type = R_PPC64_ADDR16_LO; SA -= TB; break; case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; SA -= TB; break; - case R_PPC64_TOC16_HI: Type = R_PPC64_ADDR16_HI; SA -= TB; break; - case R_PPC64_TOC16_HA: Type = R_PPC64_ADDR16_HA; SA -= TB; break; default: break; } switch (Type) { + case R_PPC64_ADDR14: { + checkAlignment<4>(SA, Type); + // Preserve the AA/LK bits in the branch instruction + uint8_t AALK = Loc[3]; + write16be(Loc + 2, (AALK & 3) | (SA & 0xfffc)); + break; + } case R_PPC64_ADDR16: checkInt<16>(SA, Type); write16be(Loc, SA); @@ -755,18 +766,12 @@ checkInt<16>(SA, Type); write16be(Loc, (read16be(Loc) & 3) | (SA & ~3)); break; - case R_PPC64_ADDR16_LO: - write16be(Loc, applyPPCLo(SA)); - break; - case R_PPC64_ADDR16_LO_DS: - write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(SA) & ~3)); + case R_PPC64_ADDR16_HA: + write16be(Loc, applyPPCHa(SA)); break; case R_PPC64_ADDR16_HI: write16be(Loc, applyPPCHi(SA)); break; - case R_PPC64_ADDR16_HA: - write16be(Loc, applyPPCHa(SA)); - break; case R_PPC64_ADDR16_HIGHER: write16be(Loc, applyPPCHigher(SA)); break; @@ -779,25 +784,27 @@ case R_PPC64_ADDR16_HIGHESTA: write16be(Loc, applyPPCHighesta(SA)); break; - case R_PPC64_ADDR14: { - checkAlignment<4>(SA, Type); - // Preserve the AA/LK bits in the branch instruction - uint8_t AALK = Loc[3]; - write16be(Loc + 2, (AALK & 3) | (SA & 0xfffc)); + case R_PPC64_ADDR16_LO: + write16be(Loc, applyPPCLo(SA)); break; - } - case R_PPC64_REL16_LO: - write16be(Loc, applyPPCLo(SA - P)); + case R_PPC64_ADDR16_LO_DS: + write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(SA) & ~3)); break; - case R_PPC64_REL16_HI: - write16be(Loc, applyPPCHi(SA - P)); + case R_PPC64_ADDR32: + checkInt<32>(SA, Type); + write32be(Loc, SA); + break; + case R_PPC64_ADDR64: + write64be(Loc, SA); break; case R_PPC64_REL16_HA: write16be(Loc, applyPPCHa(SA - P)); break; - case R_PPC64_ADDR32: - checkInt<32>(SA, Type); - write32be(Loc, SA); + case R_PPC64_REL16_HI: + write16be(Loc, applyPPCHi(SA - P)); + break; + case R_PPC64_REL16_LO: + write16be(Loc, applyPPCLo(SA - P)); break; case R_PPC64_REL24: { // If we have an undefined weak symbol, we might get here with a symbol @@ -837,7 +844,6 @@ case R_PPC64_REL64: write64be(Loc, SA - P); break; - case R_PPC64_ADDR64: case R_PPC64_TOC: write64be(Loc, SA); break; @@ -915,8 +921,8 @@ switch (Type) { default: return false; - case R_AARCH64_JUMP26: case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: return canBePreempted(&S, true); } } @@ -957,39 +963,44 @@ // bits in Loc are zero. or32le(Loc, (SA & 0xFFF) << 10); break; + case R_AARCH64_ADR_GOT_PAGE: { + uint64_t X = getAArch64Page(SA) - getAArch64Page(P); + checkInt<33>(X, Type); + updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12] + break; + } case R_AARCH64_ADR_PREL_LO21: { uint64_t X = SA - P; checkInt<21>(X, Type); updateAArch64Adr(Loc, X & 0x1FFFFF); break; } - case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_ADR_PREL_PG_HI21: { uint64_t X = getAArch64Page(SA) - getAArch64Page(P); checkInt<33>(X, Type); updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12] break; } - case R_AARCH64_JUMP26: - case R_AARCH64_CALL26: { + case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: { uint64_t X = SA - P; checkInt<28>(X, Type); or32le(Loc, (X & 0x0FFFFFFC) >> 2); break; } - case R_AARCH64_LDST32_ABS_LO12_NC: - or32le(Loc, (SA & 0xFFC) << 8); - break; case R_AARCH64_LD64_GOT_LO12_NC: checkAlignment<8>(SA, Type); or32le(Loc, (SA & 0xFF8) << 7); break; - case R_AARCH64_LDST64_ABS_LO12_NC: - or32le(Loc, (SA & 0xFF8) << 7); - break; case R_AARCH64_LDST8_ABS_LO12_NC: or32le(Loc, (SA & 0xFFF) << 10); break; + case R_AARCH64_LDST32_ABS_LO12_NC: + or32le(Loc, (SA & 0xFFC) << 8); + break; + case R_AARCH64_LDST64_ABS_LO12_NC: + or32le(Loc, (SA & 0xFF8) << 7); + break; case R_AARCH64_PREL16: checkIntUInt<16>(SA - P, Type); write16le(Loc, SA - P);