Index: ELF/DWARF.cpp =================================================================== --- ELF/DWARF.cpp +++ ELF/DWARF.cpp @@ -54,6 +54,25 @@ } } +namespace { +template struct LLDRelocationResolver { + // In the ELF ABIs, S sepresents the value of the symbol in the relocation + // entry. For Rela, the addend is stored as part of the relocation entry. + static uint64_t Resolve(object::RelocationRef Ref, uint64_t S, + uint64_t /* A */) { + return S + Ref.getRawDataRefImpl().p; + } +}; + +template struct LLDRelocationResolver> { + // For Rel, the addend A is supplied by the caller. + static uint64_t Resolve(object::RelocationRef /*Ref*/, uint64_t S, + uint64_t A) { + return S + A; + } +}; +} // namespace + // Find if there is a relocation at Pos in Sec. The code is a bit // more complicated than usual because we need to pass a section index // to llvm since it has no idea about InputSection. @@ -83,14 +102,17 @@ llvm::utohexstr(Rel.r_offset) + " has unsupported target"); return None; } - uint64_t Val = DR->Value + getAddend(Rel); + uint64_t Val = DR->Value; // FIXME: We should be consistent about always adding the file // offset or not. if (DR->Section->Flags & ELF::SHF_ALLOC) Val += cast(DR->Section)->getOffsetInFile(); - return RelocAddrEntry{SecIndex, Val}; + DataRefImpl D; + D.p = getAddend(Rel); + return RelocAddrEntry{SecIndex, RelocationRef(D, nullptr), + LLDRelocationResolver::Resolve, Val}; } template