[ELF] Convert {read,write}*be to endianness-aware read/write.
Subscribers: emaste, nemanjai, arichardson, kbarton, llvm-commits Differential Revision: https://reviews.llvm.org/D44227 llvm-svn: 327156
This commit is contained in:
parent
bc94b98c44
commit
0c483024e4
|
@ -14,7 +14,6 @@
|
|||
#include "llvm/Support/Endian.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::support::endian;
|
||||
using namespace llvm::ELF;
|
||||
using namespace lld;
|
||||
using namespace lld::elf;
|
||||
|
@ -112,14 +111,14 @@ void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
|
|||
// be a pointer to the function descriptor in the .opd section. Using
|
||||
// this scheme is simpler, but requires an extra indirection per PLT dispatch.
|
||||
|
||||
write32be(Buf, 0xf8410028); // std %r2, 40(%r1)
|
||||
write32be(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
|
||||
write32be(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
|
||||
write32be(Buf + 12, 0xe96c0000); // ld %r11,0(%r12)
|
||||
write32be(Buf + 16, 0x7d6903a6); // mtctr %r11
|
||||
write32be(Buf + 20, 0xe84c0008); // ld %r2,8(%r12)
|
||||
write32be(Buf + 24, 0xe96c0010); // ld %r11,16(%r12)
|
||||
write32be(Buf + 28, 0x4e800420); // bctr
|
||||
write32(Buf, 0xf8410028); // std %r2, 40(%r1)
|
||||
write32(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
|
||||
write32(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
|
||||
write32(Buf + 12, 0xe96c0000); // ld %r11,0(%r12)
|
||||
write32(Buf + 16, 0x7d6903a6); // mtctr %r11
|
||||
write32(Buf + 20, 0xe84c0008); // ld %r2,8(%r12)
|
||||
write32(Buf + 24, 0xe96c0010); // ld %r11,16(%r12)
|
||||
write32(Buf + 28, 0x4e800420); // bctr
|
||||
}
|
||||
|
||||
static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
|
||||
|
@ -152,58 +151,58 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
checkAlignment<4>(Loc, Val, Type);
|
||||
// Preserve the AA/LK bits in the branch instruction
|
||||
uint8_t AALK = Loc[3];
|
||||
write16be(Loc + 2, (AALK & 3) | (Val & 0xfffc));
|
||||
write16(Loc + 2, (AALK & 3) | (Val & 0xfffc));
|
||||
break;
|
||||
}
|
||||
case R_PPC64_ADDR16:
|
||||
checkInt<16>(Loc, Val, Type);
|
||||
write16be(Loc, Val);
|
||||
write16(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_ADDR16_DS:
|
||||
checkInt<16>(Loc, Val, Type);
|
||||
write16be(Loc, (read16be(Loc) & 3) | (Val & ~3));
|
||||
write16(Loc, (read16(Loc) & 3) | (Val & ~3));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HA:
|
||||
case R_PPC64_REL16_HA:
|
||||
write16be(Loc, applyPPCHa(Val));
|
||||
write16(Loc, applyPPCHa(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HI:
|
||||
case R_PPC64_REL16_HI:
|
||||
write16be(Loc, applyPPCHi(Val));
|
||||
write16(Loc, applyPPCHi(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HIGHER:
|
||||
write16be(Loc, applyPPCHigher(Val));
|
||||
write16(Loc, applyPPCHigher(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HIGHERA:
|
||||
write16be(Loc, applyPPCHighera(Val));
|
||||
write16(Loc, applyPPCHighera(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HIGHEST:
|
||||
write16be(Loc, applyPPCHighest(Val));
|
||||
write16(Loc, applyPPCHighest(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_HIGHESTA:
|
||||
write16be(Loc, applyPPCHighesta(Val));
|
||||
write16(Loc, applyPPCHighesta(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_LO:
|
||||
write16be(Loc, applyPPCLo(Val));
|
||||
write16(Loc, applyPPCLo(Val));
|
||||
break;
|
||||
case R_PPC64_ADDR16_LO_DS:
|
||||
case R_PPC64_REL16_LO:
|
||||
write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(Val) & ~3));
|
||||
write16(Loc, (read16(Loc) & 3) | (applyPPCLo(Val) & ~3));
|
||||
break;
|
||||
case R_PPC64_ADDR32:
|
||||
case R_PPC64_REL32:
|
||||
checkInt<32>(Loc, Val, Type);
|
||||
write32be(Loc, Val);
|
||||
write32(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_ADDR64:
|
||||
case R_PPC64_REL64:
|
||||
case R_PPC64_TOC:
|
||||
write64be(Loc, Val);
|
||||
write64(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_REL24: {
|
||||
uint32_t Mask = 0x03FFFFFC;
|
||||
checkInt<24>(Loc, Val, Type);
|
||||
write32be(Loc, (read32be(Loc) & ~Mask) | (Val & Mask));
|
||||
write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -47,16 +47,14 @@ using namespace llvm::dwarf;
|
|||
using namespace llvm::ELF;
|
||||
using namespace llvm::object;
|
||||
using namespace llvm::support;
|
||||
using namespace llvm::support::endian;
|
||||
|
||||
using namespace lld;
|
||||
using namespace lld::elf;
|
||||
|
||||
constexpr size_t MergeNoTailSection::NumShards;
|
||||
using llvm::support::endian::write32le;
|
||||
using llvm::support::endian::write64le;
|
||||
|
||||
static void write32(void *Buf, uint32_t Val) {
|
||||
endian::write32(Buf, Val, Config->Endianness);
|
||||
}
|
||||
constexpr size_t MergeNoTailSection::NumShards;
|
||||
|
||||
uint64_t SyntheticSection::getVA() const {
|
||||
if (OutputSection *Sec = getParent())
|
||||
|
@ -381,7 +379,7 @@ EhFrameSection::EhFrameSection()
|
|||
template <class ELFT, class RelTy>
|
||||
CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) {
|
||||
auto *Sec = cast<EhInputSection>(Cie.Sec);
|
||||
if (read32(Cie.data().data() + 4, Config->Endianness) != 0)
|
||||
if (read32(Cie.data().data() + 4) != 0)
|
||||
fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame");
|
||||
|
||||
Symbol *Personality = nullptr;
|
||||
|
@ -440,7 +438,7 @@ void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
|
|||
return;
|
||||
|
||||
size_t Offset = Piece.InputOff;
|
||||
uint32_t ID = read32(Piece.data().data() + 4, Config->Endianness);
|
||||
uint32_t ID = read32(Piece.data().data() + 4);
|
||||
if (ID == 0) {
|
||||
OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels);
|
||||
continue;
|
||||
|
@ -538,11 +536,11 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
|
|||
static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
|
||||
switch (Size) {
|
||||
case DW_EH_PE_udata2:
|
||||
return read16(Buf, Config->Endianness);
|
||||
return read16(Buf);
|
||||
case DW_EH_PE_udata4:
|
||||
return read32(Buf, Config->Endianness);
|
||||
return read32(Buf);
|
||||
case DW_EH_PE_udata8:
|
||||
return read64(Buf, Config->Endianness);
|
||||
return read64(Buf);
|
||||
case DW_EH_PE_absptr:
|
||||
return readUint(Buf);
|
||||
}
|
||||
|
|
|
@ -179,6 +179,31 @@ static void checkAlignment(uint8_t *Loc, uint64_t V, RelType Type) {
|
|||
lld::toString(Type) + ": 0x" + llvm::utohexstr(V) +
|
||||
" is not aligned to " + Twine(N) + " bytes");
|
||||
}
|
||||
|
||||
// Endianness-aware read/write.
|
||||
inline uint16_t read16(const void *P) {
|
||||
return llvm::support::endian::read16(P, Config->Endianness);
|
||||
}
|
||||
|
||||
inline uint32_t read32(const void *P) {
|
||||
return llvm::support::endian::read32(P, Config->Endianness);
|
||||
}
|
||||
|
||||
inline uint64_t read64(const void *P) {
|
||||
return llvm::support::endian::read64(P, Config->Endianness);
|
||||
}
|
||||
|
||||
inline void write16(void *P, uint16_t V) {
|
||||
llvm::support::endian::write16(P, V, Config->Endianness);
|
||||
}
|
||||
|
||||
inline void write32(void *P, uint32_t V) {
|
||||
llvm::support::endian::write32(P, V, Config->Endianness);
|
||||
}
|
||||
|
||||
inline void write64(void *P, uint64_t V) {
|
||||
llvm::support::endian::write64(P, V, Config->Endianness);
|
||||
}
|
||||
} // namespace elf
|
||||
} // namespace lld
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
using namespace llvm::support::endian;
|
||||
using namespace llvm::ELF;
|
||||
|
||||
namespace lld {
|
||||
|
@ -307,10 +306,10 @@ bool ThumbV7PILongThunk::isCompatibleWith(RelType Type) const {
|
|||
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
|
||||
void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const {
|
||||
uint64_t S = Destination.getVA();
|
||||
write32(Buf, 0x3c190000, Config->Endianness); // lui $25, %hi(func)
|
||||
write32(Buf + 4, 0x08000000 | (S >> 2), Config->Endianness); // j func
|
||||
write32(Buf + 8, 0x27390000, Config->Endianness); // addiu $25, $25, %lo(func)
|
||||
write32(Buf + 12, 0x00000000, Config->Endianness); // nop
|
||||
write32(Buf, 0x3c190000); // lui $25, %hi(func)
|
||||
write32(Buf + 4, 0x08000000 | (S >> 2)); // j func
|
||||
write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
|
||||
write32(Buf + 12, 0x00000000); // nop
|
||||
Target->relocateOne(Buf, R_MIPS_HI16, S);
|
||||
Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
|
||||
}
|
||||
|
@ -330,10 +329,10 @@ InputSection *MipsThunk::getTargetInputSection() const {
|
|||
// to call PIC function from the non-PIC one.
|
||||
void MicroMipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const {
|
||||
uint64_t S = Destination.getVA() | 1;
|
||||
write16(Buf, 0x41b9, Config->Endianness); // lui $25, %hi(func)
|
||||
write16(Buf + 4, 0xd400, Config->Endianness); // j func
|
||||
write16(Buf + 8, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func)
|
||||
write16(Buf + 12, 0x0c00, Config->Endianness); // nop
|
||||
write16(Buf, 0x41b9); // lui $25, %hi(func)
|
||||
write16(Buf + 4, 0xd400); // j func
|
||||
write16(Buf + 8, 0x3339); // addiu $25, $25, %lo(func)
|
||||
write16(Buf + 12, 0x0c00); // nop
|
||||
Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
|
||||
Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S);
|
||||
Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S);
|
||||
|
@ -356,9 +355,9 @@ InputSection *MicroMipsThunk::getTargetInputSection() const {
|
|||
void MicroMipsR6Thunk::writeTo(uint8_t *Buf, ThunkSection &) const {
|
||||
uint64_t S = Destination.getVA() | 1;
|
||||
uint64_t P = ThunkSym->getVA();
|
||||
write16(Buf, 0x1320, Config->Endianness); // lui $25, %hi(func)
|
||||
write16(Buf + 4, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func)
|
||||
write16(Buf + 8, 0x9400, Config->Endianness); // bc func
|
||||
write16(Buf, 0x1320); // lui $25, %hi(func)
|
||||
write16(Buf + 4, 0x3339); // addiu $25, $25, %lo(func)
|
||||
write16(Buf + 8, 0x9400); // bc func
|
||||
Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
|
||||
Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S);
|
||||
Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12);
|
||||
|
|
Loading…
Reference in New Issue