[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?

Leslie Zhai via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 15 01:14:51 PDT 2017


Hi Peter,

Thanks for your hint! it is the Alignment issue :)

avr-ld and LLD both use the *same* Alignment 1 for 
input_section->output_section->vma, so VMA is same:

DEBUG: avr-ld: R_AVR_CALL: VMA: 5 Output Offset: 1 Reloc Offset: 0

DEBUG: avr-ld: R_AVR_8_LO8: VMA: 6 Output Offset: 0 Reloc Offset: 7

...

DEBUG: lld: R_AVR_CALL TargetVA: 49 A: 44 P: 5 Align: 1 VMA: 5 Output 
Offset: 0 Reloc Offset: 0

DEBUG: lld: R_AVR_8_LO8 TargetVA: 50 A: 44 P: 13 Align: 1 VMA: 6 Output 
Offset: 0 Reloc Offset: 7

...

But arc-ld use Alignment 1 and LLD use *different* Alignment 4:

alignTo 
https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/MathExtras.h#L657

alignTo(0x5, 1) = 5

alignTo(0x5, 4) = 8

alignTo(0x9, 1) = 9

alignTo(0x9, 4) = 12

alignTo(0x11, 1) = 17

alignTo(0x11, 4) = 20

...

I can *not* use updateAlignment to modify the Alignment for a smaller 
value, such as 1, it is monkey patch, not the root cause, so how to 
correctly modify the Alignment for LLD? please give me some hint, thanks 
a lot!


PS: arc-ld's sym_section->output_section->vma is equals to LLD's 
SymbolBody::getVA, so the value of (S + A) is same.


在 2017年09月15日 12:33, Leslie Zhai 写道:
>
>
> 在 2017年09月14日 17:36, Peter Smith 写道:
>> Hello Leslie,
>>
>> I think we are going to need to know a bit more about the ELF ABI for
>> what looks like the ArcCompact before we can help you.
>>
>> LLD's calculation of P (the place to be relocated) is as it is in the
>> generic ELF specification. The Rel.Offset corresponds to the ELF
>> r_offset field. This is covered by: "For a relocatable file, the value
>> is the byte offset from the beginning of the section to the storage
>> unit affected by the relocation."
>>
>> For LLD we are calculating the virtual address (VA) of P, as I
>> understand it this is equivalent to the vma used in BFD. Assuming that
>> the relocation is relocating a regular InputSection from the
>> basic-arc.o object then the LLD calculation of P =
>> getOutputSection()->Addr + getOffset(Rel.Offset); translates to: (VA
>> of OutputSection) + (Offset of InputSection within OutputSection) +
>> (Offset within InputSection given by r_offset)
>>
>> The BFD linker seems to be doing the equivalent calculation with an
>> extra modification of the (Offset within InputSection given by
>> r_offset) and is rounding down the result to the nearest 4-byte
>> boundary. This looks unfamiliar to me, and could well be specific to
>> ArcCompact. I think that you will need to refer to the ELF ABI
>> documentation as this should tell you if there are any processor
>> specific modifications to generic ELF that you have to follow.
>>
>> The other thing that you should do is try and work out why the VA
>> (vma) is 6 in LD and 8 in LLD and whether this is actually a problem.
>> The VA of the OutputSection is not guaranteed to be the same between
>> different linkers so it may have just been that differences in order
>> of InputSections or alignment has caused a different VA. I would check
>> the output of the linker map file to see where it placed the Output
>> and Input Sections to see what the answer should be.
>
> VMA in LD and LLD is the same for AVR target 
> https://reviews.llvm.org/D37615
>
> $ avr-gcc -mmcu=atmega328p -o basic-avr.o -c basic-avr.s
> $ avr-ld -o basic-avr basic-avr.o -Ttext=6 
> /*with-different-high-address*/
>
> DEBUG: avr-ld: R_AVR_CALL: VMA: 6 Output Offset: 0 Reloc Offset: 0
> DEBUG: avr-ld: R_AVR_16_PM: VMA: 6 Output Offset: 0 Reloc Offset: 4
> DEBUG: avr-ld: R_AVR_8: VMA: 6 Output Offset: 0 Reloc Offset: 6
> DEBUG: avr-ld: R_AVR_8_LO8: VMA: 6 Output Offset: 0 Reloc Offset: 7
> DEBUG: avr-ld: R_AVR_8_HI8: VMA: 6 Output Offset: 0 Reloc Offset: 8
> DEBUG: avr-ld: R_AVR_8_HLO8: VMA: 6 Output Offset: 0 Reloc Offset: 9
> DEBUG: avr-ld: R_AVR_LO8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 10
> DEBUG: avr-ld: R_AVR_HI8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 12
> DEBUG: avr-ld: R_AVR_HH8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 14
> DEBUG: avr-ld: R_AVR_MS8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 16
> DEBUG: avr-ld: R_AVR_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 18
> DEBUG: avr-ld: R_AVR_LO8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 20
> DEBUG: avr-ld: R_AVR_HI8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 22
> DEBUG: avr-ld: R_AVR_HH8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 24
> DEBUG: avr-ld: R_AVR_MS8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 26
> DEBUG: avr-ld: R_AVR_LO8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 28
> DEBUG: avr-ld: R_AVR_HI8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 30
> DEBUG: avr-ld: R_AVR_HH8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 32
> DEBUG: avr-ld: R_AVR_LO8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 34
> DEBUG: avr-ld: R_AVR_HI8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 36
> DEBUG: avr-ld: R_AVR_HH8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc 
> Offset: 38
> DEBUG: avr-ld: R_AVR_7_PCREL: VMA: 6 Output Offset: 0 Reloc Offset: 40
> DEBUG: avr-ld: R_AVR_13_PCREL: VMA: 6 Output Offset: 0 Reloc Offset: 42
> DEBUG: avr-ld: R_AVR_6: VMA: 6 Output Offset: 0 Reloc Offset: 52
> DEBUG: avr-ld: R_AVR_16: VMA: 6 Output Offset: 0 Reloc Offset: 56
> DEBUG: avr-ld: R_AVR_LO8_LDI_GS: VMA: 6 Output Offset: 0 Reloc Offset: 58
> DEBUG: avr-ld: R_AVR_HI8_LDI_GS: VMA: 6 Output Offset: 0 Reloc Offset: 60
> DEBUG: avr-ld: R_AVR_PORT6: VMA: 6 Output Offset: 0 Reloc Offset: 62
> DEBUG: avr-ld: R_AVR_PORT5: VMA: 6 Output Offset: 0 Reloc Offset: 64
> DEBUG: avr-ld: R_AVR_6_ADIW: VMA: 6 Output Offset: 0 Reloc Offset: 66
>
> $ llvm/build/bin/ld.lld -o basic-avr-lld basic-avr.o -Ttext=6 
> /*with-different-high-address*/
>
> DEBUG: lld: R_AVR_CALL TargetVA: 50 A: 44 P: 6 VMA: 6 Output Offset: 0 
> Reloc Offset: 0
> DEBUG: lld: R_AVR_16_PM TargetVA: 50 A: 44 P: 10 VMA: 6 Output Offset: 
> 0 Reloc Offset: 4
> DEBUG: lld: R_AVR_8 TargetVA: 50 A: 44 P: 12 VMA: 6 Output Offset: 0 
> Reloc Offset: 6
> DEBUG: lld: R_AVR_8_LO8 TargetVA: 50 A: 44 P: 13 VMA: 6 Output Offset: 
> 0 Reloc Offset: 7
> DEBUG: lld: R_AVR_8_HI8 TargetVA: 50 A: 44 P: 14 VMA: 6 Output Offset: 
> 0 Reloc Offset: 8
> DEBUG: lld: R_AVR_8_HLO8 TargetVA: 50 A: 44 P: 15 VMA: 6 Output 
> Offset: 0 Reloc Offset: 9
> DEBUG: lld: R_AVR_LO8_LDI TargetVA: 50 A: 44 P: 16 VMA: 6 Output 
> Offset: 0 Reloc Offset: 10
> DEBUG: lld: R_AVR_HI8_LDI TargetVA: 50 A: 44 P: 18 VMA: 6 Output 
> Offset: 0 Reloc Offset: 12
> DEBUG: lld: R_AVR_HH8_LDI TargetVA: 50 A: 44 P: 20 VMA: 6 Output 
> Offset: 0 Reloc Offset: 14
> DEBUG: lld: R_AVR_MS8_LDI TargetVA: 50 A: 44 P: 22 VMA: 6 Output 
> Offset: 0 Reloc Offset: 16
> DEBUG: lld: R_AVR_LDI TargetVA: 50 A: 44 P: 24 VMA: 6 Output Offset: 0 
> Reloc Offset: 18
> DEBUG: lld: R_AVR_LO8_LDI_NEG TargetVA: 50 A: 44 P: 26 VMA: 6 Output 
> Offset: 0 Reloc Offset: 20
> DEBUG: lld: R_AVR_HI8_LDI_NEG TargetVA: 50 A: 44 P: 28 VMA: 6 Output 
> Offset: 0 Reloc Offset: 22
> DEBUG: lld: R_AVR_HH8_LDI_NEG TargetVA: 50 A: 44 P: 30 VMA: 6 Output 
> Offset: 0 Reloc Offset: 24
> DEBUG: lld: R_AVR_MS8_LDI_NEG TargetVA: 50 A: 44 P: 32 VMA: 6 Output 
> Offset: 0 Reloc Offset: 26
> DEBUG: lld: R_AVR_LO8_LDI_PM TargetVA: 50 A: 44 P: 34 VMA: 6 Output 
> Offset: 0 Reloc Offset: 28
> DEBUG: lld: R_AVR_HI8_LDI_PM TargetVA: 50 A: 44 P: 36 VMA: 6 Output 
> Offset: 0 Reloc Offset: 30
> DEBUG: lld: R_AVR_HH8_LDI_PM TargetVA: 50 A: 44 P: 38 VMA: 6 Output 
> Offset: 0 Reloc Offset: 32
> DEBUG: lld: R_AVR_LO8_LDI_PM_NEG TargetVA: 50 A: 44 P: 40 VMA: 6 
> Output Offset: 0 Reloc Offset: 34
> DEBUG: lld: R_AVR_HI8_LDI_PM_NEG TargetVA: 50 A: 44 P: 42 VMA: 6 
> Output Offset: 0 Reloc Offset: 36
> DEBUG: lld: R_AVR_HH8_LDI_PM_NEG TargetVA: 50 A: 44 P: 44 VMA: 6 
> Output Offset: 0 Reloc Offset: 38
> DEBUG: lld: R_AVR_7_PCREL TargetVA: 4 A: 44 P: 46 VMA: 6 Output 
> Offset: 0 Reloc Offset: 40
> DEBUG: lld: R_AVR_13_PCREL TargetVA: 2 A: 44 P: 48 VMA: 6 Output 
> Offset: 0 Reloc Offset: 42
> DEBUG: lld: R_AVR_6 TargetVA: 50 A: 44 P: 58 VMA: 6 Output Offset: 0 
> Reloc Offset: 52
> DEBUG: lld: R_AVR_16 TargetVA: 50 A: 44 P: 62 VMA: 6 Output Offset: 0 
> Reloc Offset: 56
> DEBUG: lld: R_AVR_LO8_LDI_GS TargetVA: 50 A: 44 P: 64 VMA: 6 Output 
> Offset: 0 Reloc Offset: 58
> DEBUG: lld: R_AVR_HI8_LDI_GS TargetVA: 50 A: 44 P: 66 VMA: 6 Output 
> Offset: 0 Reloc Offset: 60
> DEBUG: lld: R_AVR_PORT6 TargetVA: 51 A: 45 P: 68 VMA: 6 Output Offset: 
> 0 Reloc Offset: 62
> DEBUG: lld: R_AVR_PORT5 TargetVA: 6 A: 0 P: 70 VMA: 6 Output Offset: 0 
> Reloc Offset: 64
> DEBUG: lld: R_AVR_6_ADIW TargetVA: 50 A: 44 P: 72 VMA: 6 Output 
> Offset: 0 Reloc Offset: 66
>
> interesting :)
>
>>
>> In summary:
>> It looks like there are some Arc specific things that might need to be
>> done. Unfortunately I don't have any experience with Arc, and I'm not
>> sure the other people that work on LLD do either. I suggest looking at
>> the public ABI documentation and making any arguments for changes
>> based on that documentation, it is worth assuming that we know nothing
>> about Arc, don't have the documentation to hand and don't know where
>> to find it!
>>
>> Hope that is of some help, with a bit more context I might be able to
>> help a bit more, unfortunately I can't spend a lot of time learning
>> about Arc.
>>
>> Peter
>>
>>
>> On 14 September 2017 at 07:16, Leslie Zhai via llvm-dev
>> <llvm-dev at lists.llvm.org> wrote:
>>> Hi LLVM developers,
>>>
>>> basic-arc.s:
>>>
>>> main:
>>>    bl memset
>>>
>>> $ arc-elf32-gcc -mcpu=arc600 -o basic-arc.o -c
>>>
>>> $ arc-elf32-readelf -r basic-arc.o
>>>
>>> Relocation section '.rela.text' at offset 0xd4 contains 1 entries:
>>>   Offset     Info    Type            Sym.Value  Sym. Name + Addend
>>> 00000000  00000611 R_ARC_S25W_PCREL  00000000   memset + 0
>>>
>>> High address: 0x0
>>>
>>> $ arc-elf32-ld -o basic-arc basic-arc.o
>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/arc600
>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/../../../../arc-elf32/lib/arc600
>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1
>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/../../../../arc-elf32/lib
>>> --start-group -lgcc -lc -lnosys --end-group -Ttext=0
>>>
>>> DEBUG: arc-ld: R_ARC_S25W_PCREL relocation: 1 S: 4 A: 0 P: 0 = (vma: 
>>> 0 +
>>> output_offset: 0 + reloc_offset: 0 - 0) & ~0x3
>>> DEBUG: arc-ld: type: R_ARC_S25W_PCREL insn: 2054
>>>
>>> $ ld.lld -o basic-arc-lld basic-arc.o $ARC_LINKER_LIB -Ttext=0
>>>
>>> DEBUG: lld: R_ARC_S25W_PCREL TargetVA: 4 A: 0 P: 0 <-- same P as arc-ld
>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2050 Rel: 1
>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2054 <-- same relocation value 
>>> as arc-ld
>>>
>>> But with several different high address *not* 0x0, such as 0x6:
>>>
>>> DEBUG: arc-ld: R_ARC_S25W_PCREL relocation: 2 S: 12 A: 0 P: 4 = 
>>> (vma: 6 +
>>> output_offset: 0 + reloc_offset: 0 - 0) & ~0x3
>>> DEBUG: arc-ld: type: R_ARC_S25W_PCREL insn: 2058
>>>
>>> DEBUG: lld: R_ARC_S25W_PCREL TargetVA: 4 A: 0 P: 8 <-- different P?
>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2050 Rel: 1
>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2054 <-- different relocation value
>>>
>>> How arc-ld calculates P?
>>>
>>> P = ((reloc_data.input_section->output_section ?
>>> reloc_data.input_section->output_section->vma : 0) +
>>> reloc_data.input_section->output_offset + (reloc_data.reloc_offset -
>>> (reloc_data.bitsize >= 32 ? 4 : 0))) & ~0x3;
>>>
>>> for example, R_ARC_S25W_PCREL's bitsize < 32, P = (6 + 0 + 0 - 0) & 
>>> ~0x3 =
>>> 4, when vma is 6, output and reloc offset is 0.
>>>
>>> How LLD calculates P (AddrLoc)?
>>>
>>> P = getOutputSection()->Addr + getOffset(Rel.Offset);
>>>
>>> for example, the same high address 0x6, LLD's P is 8, different with 
>>> arc-ld?
>>> so do I need to modify the value of P for R_PC case in the 
>>> getRelocTargetVA?
>>> please give me some hints, thanks a lot!
>>>
>>>
>>> PS: arc-ld R_ARC_S25W_PCREL's FORMULA is: ( S + A ) - P ) >> 2, and 
>>> it needs
>>> middle endian convert, so:
>>>
>>> Insn = middleEndianConvert (insn, TRUE);
>>>
>>> Insn = replaceDisp25w(Insn, ( S + A ) - P ) >> 2);
>>>
>>> Insn = middleEndianConvert (insn, TRUE);
>>>
>>> write32le(Loc, Insn);
>>>
>>> -- 
>>> Regards,
>>> Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
>>>
>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>

-- 
Regards,
Leslie Zhai -https://reviews.llvm.org/p/xiangzhai/





More information about the llvm-dev mailing list