Changeset View
Standalone View
llvm/lib/Object/RelocationResolver.cpp
Show First 20 Lines • Show All 305 Lines • ▼ Show 20 Lines | static bool supportsARM(uint64_t Type) { | ||||
case ELF::R_ARM_ABS32: | case ELF::R_ARM_ABS32: | ||||
case ELF::R_ARM_REL32: | case ELF::R_ARM_REL32: | ||||
return true; | return true; | ||||
default: | default: | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, | static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, | ||||
MaskRay: The code is written in the assumption that targets preferring RELA always have Addend while… | |||||
I think adding LocData and Addend is wrong. When RELA is used, LocData (implicit addend) should be ignored. MaskRay: I think adding LocData and Addend is wrong. When RELA is used, LocData (implicit addend) should… | |||||
Agreed. The ELF spec says in http://www.sco.com/developers/gabi/latest/ch4.reloc.html "The typical application of an ELF relocation is to determine the referenced symbol value, extract the addend (either from the field to be relocated or from the addend field contained in the relocation record, as appropriate for the type of relocation record), apply the expression implied by the relocation type to the symbol and addend, extract the desired part of the expression result, and place it in the field to be relocated." peter.smith: Agreed. The ELF spec says in http://www.sco.com/developers/gabi/latest/ch4.reloc.html
"As… | |||||
Ah, thanks for pointing that out. It is curious, though, because some RISCV relocations clearly seem to use both addend and location data (see here). wolfgangp: Ah, thanks for pointing that out. It is curious, though, because some RISCV relocations clearly… | |||||
Not Done ReplyInline ActionsThe special RISC-V relocations are R_RISCV_SUB*. They do label differences and the explicit addend is always zero. It can be implemented by "consecutive relocations" but processing the relocation consecutively can also be correct. If anything, it should not be used as examples for other targets because it imposes many restrictions that other targets may not have. MaskRay: The special RISC-V relocations are `R_RISCV_SUB*`. They do label differences and the explicit… | |||||
uint64_t LocData, int64_t /*Addend*/) { | uint64_t LocData, int64_t Addend) { | ||||
// Support both RELA and REL relocations. The caller is responsible | |||||
// for supplying the correct values for LocData and Addend, i.e. | |||||
// Addend == 0 for REL and LocData == 0 for RELA. | |||||
Add an assert MaskRay: Add an assert | |||||
assert((LocData == 0 || Addend == 0) && | |||||
"one of LocData and Addend must be 0"); | |||||
switch (Type) { | switch (Type) { | ||||
case ELF::R_ARM_ABS32: | case ELF::R_ARM_ABS32: | ||||
return (S + LocData) & 0xFFFFFFFF; | return (S + LocData + Addend) & 0xFFFFFFFF; | ||||
case ELF::R_ARM_REL32: | case ELF::R_ARM_REL32: | ||||
return (S + LocData - Offset) & 0xFFFFFFFF; | return (S + LocData + Addend - Offset) & 0xFFFFFFFF; | ||||
} | } | ||||
llvm_unreachable("Invalid relocation type"); | llvm_unreachable("Invalid relocation type"); | ||||
} | } | ||||
static bool supportsAVR(uint64_t Type) { | static bool supportsAVR(uint64_t Type) { | ||||
switch (Type) { | switch (Type) { | ||||
case ELF::R_AVR_16: | case ELF::R_AVR_16: | ||||
case ELF::R_AVR_32: | case ELF::R_AVR_32: | ||||
▲ Show 20 Lines • Show All 410 Lines • ▼ Show 20 Lines | if (Obj->isELF()) { | ||||
if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) | if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) | ||||
return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | ||||
if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) | if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) | ||||
return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | ||||
auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj); | auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj); | ||||
return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; | ||||
}; | }; | ||||
if (GetRelSectionType() == ELF::SHT_RELA) | if (GetRelSectionType() == ELF::SHT_RELA) { | ||||
Addend = getELFAddend(R); | Addend = getELFAddend(R); | ||||
// RISCV relocations use both LocData and Addend. | |||||
if (Obj->getArch() != Triple::riscv32 && | |||||
Obj->getArch() != Triple::riscv64) | |||||
LocData = 0; | |||||
} | |||||
} | } | ||||
return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); | return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); | ||||
} | } | ||||
// Sometimes the caller might want to use its own specific implementation of | // Sometimes the caller might want to use its own specific implementation of | ||||
// the resolver function. E.g. this is used by LLD when it resolves debug | // the resolver function. E.g. this is used by LLD when it resolves debug | ||||
// relocations and assumes that all of them have the same computation (S + A). | // relocations and assumes that all of them have the same computation (S + A). | ||||
Show All 9 Lines |
The code is written in the assumption that targets preferring RELA always have Addend while targets preferring REL always have LocData.
Are you trying to add RELA support to ARM? I think it is unpopular but maybe you have specific needs which are not specified.
No objection, but a comment is needed.