<p dir="ltr">In that case we even do not need to pass `A` because addend should be read from the relication location. But we have to pass `nullptr` instead of `Body` in many all cases of the `relicateOne` invocation. That is why I rejected this solution when implement the patch. But if it looks better than current variant, I am ready to change it.</p>
<div class="gmail_quote">On Dec 24, 2015 3:39 PM, "George Rimar" <<a href="mailto:grimar@accesssoftek.com">grimar@accesssoftek.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">>On Thu, Dec 24, 2015 at 2:22 PM, George Rimar <<a href="mailto:grimar@accesssoftek.com">grimar@accesssoftek.com</a>> wrote:<br>
>>>>I thinking about that place last time.<br>
>>>>May be we should add A argument to Target->relocateOne()  ?<br>
>>>>That can help to move that calculation to mips target, since it looks like absence of A inside relocateOne() is the only stoppable for doing that.<br>
>>>><br>
>>>Currently S+A is a single parameter SA. Are you suggesting split that as two parameters, S and A?<br>
>>><br>
>>>I don't know if that makes code simpler, but it may worth trying.<br>
>><br>
>> Not sure about splitting. That seems to be more complicated. Just adding A can save from complicating logic outside allowing relocateOne to use it if it is needed for concrete relocation`s code like here for mips.<br>
><br>
>What part of the `getMipsGpAddr<ELFT>() - AddrLoc` expression do you<br>
>suggest to pass a a separate A argument? And do you suggest to pass<br>
>the `Body` to the `relocateOne` as well to be able to recognize a<br>
>special _gp_disp case of R_MIPS_HI16 / LO16 relocations?<br>
><br>
>--<br>
>Simon Atanasyan<br>
<br>
Whole calculations can be inside relocateOne().<br>
Yes, forgot about body, its also needed. So it could probably look something like that:<br>
<br>
template <class ELFT><br>
void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,<br>
                                       uint32_t Type, uint64_t P, uint64_t SA,<br>
                                       uint64_t ZA, uint8_t *PairedLoc,<br>
                                       uint64_t A, const SymbolBody *S) const {<br>
  const endianness E = ELFT::TargetEndianness;<br>
  switch (Type) {<br>
....<br>
  case R_MIPS_HI16: {<br>
    if (S == Config->MipsGpDisp)<br>
      SA = getMipsGpAddr<ELFT>() - P + A;<br>
    uint32_t Instr = read32<E>(Loc);<br>
    if (PairedLoc) {<br>
      uint64_t AHL = ((Instr & 0xffff) << 16) +<br>
                     SignExtend64<16>(read32<E>(PairedLoc) & 0xffff);<br>
      write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA + AHL));<br>
    } else {<br>
      warning("Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16");<br>
      write32<E>(Loc, (Instr & 0xffff0000) | mipsHigh(SA));<br>
    }<br>
    break;<br>
  }<br>
......<br>
  case R_MIPS_LO16: {<br>
    if (S == Config->MipsGpDisp)<br>
      SA = getMipsGpAddr<ELFT>() - P + A + 4;<br>
    uint32_t Instr = read32<E>(Loc);<br>
    int64_t AHL = SignExtend64<16>(Instr & 0xffff);<br>
    write32<E>(Loc, (Instr & 0xffff0000) | ((SA + AHL) & 0xffff));<br>
    break;<br>
  }<br>
......</blockquote></div>