Index: llvm/trunk/include/llvm/Object/RelocVisitor.h =================================================================== --- llvm/trunk/include/llvm/Object/RelocVisitor.h +++ llvm/trunk/include/llvm/Object/RelocVisitor.h @@ -40,13 +40,13 @@ // TODO: Should handle multiple applied relocations via either passing in the // previously computed value or just count paired relocations as a single // visit. - uint64_t visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { + uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value = 0) { if (isa(ObjToVisit)) - return visitELF(RelocType, R, Value); + return visitELF(Rel, R, Value); if (isa(ObjToVisit)) - return visitCOFF(RelocType, R, Value); + return visitCOFF(Rel, R, Value); if (isa(ObjToVisit)) - return visitMachO(RelocType, R, Value); + return visitMachO(Rel, R, Value); HasError = true; return 0; @@ -58,214 +58,60 @@ const ObjectFile &ObjToVisit; bool HasError = false; - uint64_t visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitELF(uint32_t Rel, RelocationRef R, uint64_t Value) { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { case Triple::x86_64: - switch (RelocType) { - case ELF::R_X86_64_NONE: - return visitELF_X86_64_NONE(R); - case ELF::R_X86_64_64: - return visitELF_X86_64_64(R, Value); - case ELF::R_X86_64_PC32: - return visitELF_X86_64_PC32(R, Value); - case ELF::R_X86_64_32: - return visitELF_X86_64_32(R, Value); - case ELF::R_X86_64_32S: - return visitELF_X86_64_32S(R, Value); - default: - HasError = true; - return 0; - } + return visitX86_64(Rel, R, Value); case Triple::aarch64: case Triple::aarch64_be: - switch (RelocType) { - case ELF::R_AARCH64_ABS32: - return visitELF_AARCH64_ABS32(R, Value); - case ELF::R_AARCH64_ABS64: - return visitELF_AARCH64_ABS64(R, Value); - default: - HasError = true; - return 0; - } + return visitAarch64(Rel, R, Value); case Triple::bpfel: case Triple::bpfeb: - switch (RelocType) { - case ELF::R_BPF_64_64: - return visitELF_BPF_64_64(R, Value); - case ELF::R_BPF_64_32: - return visitELF_BPF_64_32(R, Value); - default: - HasError = true; - return 0; - } + return visitBpf(Rel, R, Value); case Triple::mips64el: case Triple::mips64: - switch (RelocType) { - case ELF::R_MIPS_32: - return visitELF_MIPS64_32(R, Value); - case ELF::R_MIPS_64: - return visitELF_MIPS64_64(R, Value); - default: - HasError = true; - return 0; - } + return visitMips64(Rel, R, Value); case Triple::ppc64le: case Triple::ppc64: - switch (RelocType) { - case ELF::R_PPC64_ADDR32: - return visitELF_PPC64_ADDR32(R, Value); - case ELF::R_PPC64_ADDR64: - return visitELF_PPC64_ADDR64(R, Value); - default: - HasError = true; - return 0; - } + return visitPPC64(Rel, R, Value); case Triple::systemz: - switch (RelocType) { - case ELF::R_390_32: - return visitELF_390_32(R, Value); - case ELF::R_390_64: - return visitELF_390_64(R, Value); - default: - HasError = true; - return 0; - } + return visitSystemz(Rel, R, Value); case Triple::sparcv9: - switch (RelocType) { - case ELF::R_SPARC_32: - case ELF::R_SPARC_UA32: - return visitELF_SPARCV9_32(R, Value); - case ELF::R_SPARC_64: - case ELF::R_SPARC_UA64: - return visitELF_SPARCV9_64(R, Value); - default: - HasError = true; - return 0; - } + return visitSparc64(Rel, R, Value); case Triple::amdgcn: - switch (RelocType) { - case ELF::R_AMDGPU_ABS32: - return visitELF_AMDGPU_ABS32(R, Value); - case ELF::R_AMDGPU_ABS64: - return visitELF_AMDGPU_ABS64(R, Value); - default: - HasError = true; - return 0; - } + return visitAmdgpu(Rel, R, Value); default: HasError = true; return 0; } - } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file - switch (ObjToVisit.getArch()) { - case Triple::x86: - switch (RelocType) { - case ELF::R_386_NONE: - return visitELF_386_NONE(R); - case ELF::R_386_32: - return visitELF_386_32(R, Value); - case ELF::R_386_PC32: - return visitELF_386_PC32(R, Value); - default: - HasError = true; - return 0; - } - case Triple::ppc: - switch (RelocType) { - case ELF::R_PPC_ADDR32: - return visitELF_PPC_ADDR32(R, Value); - default: - HasError = true; - return 0; - } - case Triple::arm: - case Triple::armeb: - switch (RelocType) { - default: - HasError = true; - return 0; - case ELF::R_ARM_ABS32: - return visitELF_ARM_ABS32(R, Value); - } - case Triple::lanai: - switch (RelocType) { - case ELF::R_LANAI_32: - return visitELF_Lanai_32(R, Value); - default: - HasError = true; - return 0; - } - case Triple::mipsel: - case Triple::mips: - switch (RelocType) { - case ELF::R_MIPS_32: - return visitELF_MIPS_32(R, Value); - default: - HasError = true; - return 0; - } - case Triple::sparc: - switch (RelocType) { - case ELF::R_SPARC_32: - case ELF::R_SPARC_UA32: - return visitELF_SPARC_32(R, Value); - default: - HasError = true; - return 0; - } - case Triple::hexagon: - switch (RelocType) { - case ELF::R_HEX_32: - return visitELF_HEX_32(R, Value); - default: - HasError = true; - return 0; - } - default: - HasError = true; - return 0; - } - } else { - report_fatal_error("Invalid word size in object file"); } - } - uint64_t visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) { - switch (ObjToVisit.getArch()) { - case Triple::x86: - switch (RelocType) { - case COFF::IMAGE_REL_I386_SECREL: - return visitCOFF_I386_SECREL(R, Value); - case COFF::IMAGE_REL_I386_DIR32: - return visitCOFF_I386_DIR32(R, Value); - } - break; - case Triple::x86_64: - switch (RelocType) { - case COFF::IMAGE_REL_AMD64_SECREL: - return visitCOFF_AMD64_SECREL(R, Value); - case COFF::IMAGE_REL_AMD64_ADDR64: - return visitCOFF_AMD64_ADDR64(R, Value); - } - break; - } - HasError = true; - return 0; - } + // 32-bit object file + assert(ObjToVisit.getBytesInAddress() == 4 && + "Invalid word size in object file"); - uint64_t visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { switch (ObjToVisit.getArch()) { - default: break; - case Triple::x86_64: - switch (RelocType) { - default: break; - case MachO::X86_64_RELOC_UNSIGNED: - return visitMACHO_X86_64_UNSIGNED(R, Value); - } + case Triple::x86: + return visitX86(Rel, R, Value); + case Triple::ppc: + return visitPPC32(Rel, R, Value); + case Triple::arm: + case Triple::armeb: + return visitARM(Rel, R, Value); + case Triple::lanai: + return visitLanai(Rel, R, Value); + case Triple::mipsel: + case Triple::mips: + return visitMips32(Rel, R, Value); + case Triple::sparc: + return visitSparc32(Rel, R, Value); + case Triple::hexagon: + return visitHexagon(Rel, R, Value); + default: + HasError = true; + return 0; } - HasError = true; - return 0; } int64_t getELFAddend(RelocationRef R) { @@ -275,176 +121,193 @@ return *AddendOrErr; } - /// Operations - - /// 386-ELF - uint64_t visitELF_386_NONE(RelocationRef R) { + uint64_t visitX86_64(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_X86_64_NONE: + return 0; + case ELF::R_X86_64_64: + return Value + getELFAddend(R); + case ELF::R_X86_64_PC32: + return Value + getELFAddend(R) - R.getOffset(); + case ELF::R_X86_64_32: + case ELF::R_X86_64_32S: + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + } + HasError = true; return 0; } - // Ideally the Addend here will be the addend in the data for - // the relocation. It's not actually the case for Rel relocations. - uint64_t visitELF_386_32(RelocationRef R, uint64_t Value) { - return Value; - } - - uint64_t visitELF_386_PC32(RelocationRef R, uint64_t Value) { - return Value - R.getOffset(); - } - - /// X86-64 ELF - uint64_t visitELF_X86_64_NONE(RelocationRef R) { + uint64_t visitAarch64(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_AARCH64_ABS32: { + int64_t Res = Value + getELFAddend(R); + if (Res < INT32_MIN || Res > UINT32_MAX) + HasError = true; + return static_cast(Res); + } + case ELF::R_AARCH64_ABS64: + return Value + getELFAddend(R); + } + HasError = true; return 0; } - uint64_t visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); - } - - uint64_t visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R) - R.getOffset(); - } - - uint64_t visitELF_X86_64_32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - uint64_t visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - /// BPF ELF - uint64_t visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { - return Value & 0xFFFFFFFF; - } - - uint64_t visitELF_BPF_64_64(RelocationRef R, uint64_t Value) { - return Value; - } - - /// PPC64 ELF - uint64_t visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - uint64_t visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); - } - - /// PPC32 ELF - uint64_t visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - /// Lanai ELF - uint64_t visitELF_Lanai_32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - /// MIPS ELF - uint64_t visitELF_MIPS_32(RelocationRef R, uint64_t Value) { - return Value & 0xFFFFFFFF; - } - - /// MIPS64 ELF - uint64_t visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { - return (Value + getELFAddend(R)) & 0xFFFFFFFF; - } - - uint64_t visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); - } - - // AArch64 ELF - uint64_t visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - int64_t Res = Value + Addend; - - // Overflow check allows for both signed and unsigned interpretation. - if (Res < INT32_MIN || Res > UINT32_MAX) - HasError = true; - - return static_cast(Res); - } - - uint64_t visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); + uint64_t visitBpf(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_BPF_64_32: + return Value & 0xFFFFFFFF; + case ELF::R_BPF_64_64: + return Value; + } + HasError = true; + return 0; } - // SystemZ ELF - uint64_t visitELF_390_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - int64_t Res = Value + Addend; - - // Overflow check allows for both signed and unsigned interpretation. - if (Res < INT32_MIN || Res > UINT32_MAX) - HasError = true; - - return static_cast(Res); + uint64_t visitMips64(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_MIPS_32: + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + case ELF::R_MIPS_64: + return Value + getELFAddend(R); + } + HasError = true; + return 0; } - uint64_t visitELF_390_64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); + uint64_t visitPPC64(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_PPC64_ADDR32: + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + case ELF::R_PPC64_ADDR64: + return Value + getELFAddend(R); + } + HasError = true; + return 0; } - uint64_t visitELF_SPARC_32(RelocationRef R, uint32_t Value) { - return Value + getELFAddend(R); + uint64_t visitSystemz(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_390_32: { + int64_t Res = Value + getELFAddend(R); + if (Res < INT32_MIN || Res > UINT32_MAX) + HasError = true; + return static_cast(Res); + } + case ELF::R_390_64: + return Value + getELFAddend(R); + } + HasError = true; + return 0; } - uint64_t visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); + uint64_t visitSparc64(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_SPARC_32: + case ELF::R_SPARC_64: + case ELF::R_SPARC_UA32: + case ELF::R_SPARC_UA64: + return Value + getELFAddend(R); + } + HasError = true; + return 0; } - uint64_t visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) { - return Value + getELFAddend(R); + uint64_t visitAmdgpu(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_AMDGPU_ABS32: + case ELF::R_AMDGPU_ABS64: + return Value + getELFAddend(R); + } + HasError = true; + return 0; } - uint64_t visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) { - int64_t Res = Value; - - // Overflow check allows for both signed and unsigned interpretation. - if (Res < INT32_MIN || Res > UINT32_MAX) - HasError = true; - - return static_cast(Res); + uint64_t visitX86(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (Rel) { + case ELF::R_386_NONE: + return 0; + case ELF::R_386_32: + return Value; + case ELF::R_386_PC32: + return Value - R.getOffset(); + } + HasError = true; + return 0; } - uint64_t visitELF_HEX_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return Value + Addend; + uint64_t visitPPC32(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_PPC_ADDR32) + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + HasError = true; + return 0; } - uint64_t visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return Value + Addend; + uint64_t visitARM(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_ARM_ABS32) { + if ((int64_t)Value < INT32_MIN || (int64_t)Value > UINT32_MAX) + HasError = true; + return static_cast(Value); + } + HasError = true; + return 0; } - uint64_t visitELF_AMDGPU_ABS64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return Value + Addend; + uint64_t visitLanai(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_LANAI_32) + return (Value + getELFAddend(R)) & 0xFFFFFFFF; + HasError = true; + return 0; } - /// I386 COFF - uint64_t visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) { - return static_cast(Value); + uint64_t visitMips32(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_MIPS_32) + return Value & 0xFFFFFFFF; + HasError = true; + return 0; } - uint64_t visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) { - return static_cast(Value); + uint64_t visitSparc32(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32) + return Value + getELFAddend(R); + HasError = true; + return 0; } - /// AMD64 COFF - uint64_t visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) { - return static_cast(Value); + uint64_t visitHexagon(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (Rel == ELF::R_HEX_32) + return Value + getELFAddend(R); + HasError = true; + return 0; } - uint64_t visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { - return Value; + uint64_t visitCOFF(uint32_t Rel, RelocationRef R, uint64_t Value) { + switch (ObjToVisit.getArch()) { + case Triple::x86: + switch (Rel) { + case COFF::IMAGE_REL_I386_SECREL: + case COFF::IMAGE_REL_I386_DIR32: + return static_cast(Value); + } + break; + case Triple::x86_64: + switch (Rel) { + case COFF::IMAGE_REL_AMD64_SECREL: + return static_cast(Value); + case COFF::IMAGE_REL_AMD64_ADDR64: + return Value; + } + break; + } + HasError = true; + return 0; } - // X86_64 MachO - uint64_t visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { - return Value; + uint64_t visitMachO(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (ObjToVisit.getArch() == Triple::x86_64 && + Rel == MachO::X86_64_RELOC_UNSIGNED) + return Value; + HasError = true; + return 0; } };