diff options
Diffstat (limited to 'ELF/Target.cpp')
| -rw-r--r-- | ELF/Target.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/ELF/Target.cpp b/ELF/Target.cpp index b6c6e70893650..ee5a7690fc64c 100644 --- a/ELF/Target.cpp +++ b/ELF/Target.cpp @@ -35,8 +35,8 @@ #include "Thunks.h" #include "Writer.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" -#include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" using namespace llvm; @@ -537,7 +537,17 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, write16le(Loc, Val); break; case R_386_PC16: - checkInt<16>(Loc, Val, Type); + // R_386_PC16 is normally used with 16 bit code. In that situation + // the PC is 16 bits, just like the addend. This means that it can + // point from any 16 bit address to any other if the possibility + // of wrapping is included. + // The only restriction we have to check then is that the destination + // address fits in 16 bits. That is impossible to do here. The problem is + // that we are passed the final value, which already had the + // current location subtracted from it. + // We just check that Val fits in 17 bits. This misses some cases, but + // should have no false positives. + checkInt<17>(Loc, Val, Type); write16le(Loc, Val); break; default: @@ -2085,7 +2095,7 @@ RelExpr MipsTargetInfo<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, return R_MIPS_GOT_GP_PC; if (&S == ElfSym::MipsLocalGp) return R_MIPS_GOT_GP; - // fallthrough + LLVM_FALLTHROUGH; case R_MIPS_GOT_OFST: return R_ABS; case R_MIPS_PC32: @@ -2099,7 +2109,7 @@ RelExpr MipsTargetInfo<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, case R_MIPS_GOT16: if (S.isLocal()) return R_MIPS_GOT_LOCAL_PAGE; - // fallthrough + LLVM_FALLTHROUGH; case R_MIPS_CALL16: case R_MIPS_GOT_DISP: case R_MIPS_TLS_GOTTPREL: @@ -2353,7 +2363,7 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, case R_MIPS_TLS_GD: case R_MIPS_TLS_LDM: checkInt<16>(Loc, Val, Type); - // fallthrough + LLVM_FALLTHROUGH; case R_MIPS_CALL16: case R_MIPS_CALL_LO16: case R_MIPS_GOT_LO16: |
