[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
Sun Sep 17 19:28:27 PDT 2017


Hi Peter,

Map file about LD for ARC target 
https://drive.google.com/open?id=0ByE8c-y74l_uRWpQdUh2c0VXZ1k

LLD for ARC https://drive.google.com/open?id=0ByE8c-y74l_ueGVuYkR0a3RSWjQ


arm-thumb-undefined-weak.s 
https://github.com/llvm-mirror/lld/blob/master/test/ELF/arm-thumb-undefined-weak.s

$ llvm/build/bin/llvm-mc -filetype=obj 
-triple=thumbv7a-none-linux-gnueabi arm-thumb-undefined-weak.s -o 
arm-thumb-undefined-weak.o
$ llvm/build/bin/ld.lld -o arm-thumb-undefined-weak-lld 
arm-thumb-undefined-weak.o -Ttext=11006
$ arm-linux-gnu-ld -o arm-thumb-undefined-weak-ld 
arm-thumb-undefined-weak.o -Ttext=11006

$ arm-linux-gnu-readelf -r arm-thumb-undefined-weak.o

Relocation section '.rel.text' at offset 0x8c contains 6 entries:
  Offset     Info    Type            Sym.Value  Sym. Name
00000000  00000333 R_ARM_THM_JUMP19  00000000   target
00000004  0000031e R_ARM_THM_JUMP24  00000000   target
00000008  0000030a R_ARM_THM_CALL    00000000   target
0000000c  0000030a R_ARM_THM_CALL    00000000   target
00000010  00000332 R_ARM_THM_MOVT_PR 00000000   target
00000014  00000331 R_ARM_THM_MOVW_PR 00000000   target


DEBUG: lld: R_ARM_THM_JUMP19 TargetVA: 0 A: -4 P: 69640 Align: 4 VMA: 
69640 Output Offset: 0 Reloc Offset: 0
DEBUG: lld: R_ARM_THM_JUMP24 TargetVA: 0 A: -4 P: 69644 Align: 4 VMA: 
69640 Output Offset: 0 Reloc Offset: 4
DEBUG: lld: R_ARM_THM_CALL TargetVA: 1 A: -4 P: 69648 Align: 4 VMA: 
69640 Output Offset: 0 Reloc Offset: 8
DEBUG: lld: R_ARM_THM_CALL TargetVA: 1 A: -4 P: 69652 Align: 4 VMA: 
69640 Output Offset: 0 Reloc Offset: 12
DEBUG: lld: R_ARM_THM_MOVT_PREL TargetVA: 0 A: 0 P: 69656 Align: 4 VMA: 
69640 Output Offset: 0 Reloc Offset: 16
DEBUG: lld: R_ARM_THM_MOVW_PREL_NC TargetVA: 0 A: 0 P: 69660 Align: 4 
VMA: 69640 Output Offset: 0 Reloc Offset: 20

DEBUG: arm-linux-gnu-ld: R_ARM_THM_JUMP19: VMA: 69638 Output Offset: 2 
Reloc Offset: 0
DEBUG: arm-linux-gnu-ld: R_ARM_THM_JUMP24: VMA: 69638 Output Offset: 2 
Reloc Offset: 4
DEBUG: arm-linux-gnu-ld: R_ARM_THM_CALL: VMA: 69638 Output Offset: 2 
Reloc Offset: 8
DEBUG: arm-linux-gnu-ld: R_ARM_THM_CALL: VMA: 69638 Output Offset: 2 
Reloc Offset: 12
DEBUG: arm-linux-gnu-ld: R_ARM_THM_MOVT_PREL: VMA: 69638 Output Offset: 
2 Reloc Offset: 16
DEBUG: arm-linux-gnu-ld: R_ARM_THM_MOVW_PREL_NC: VMA: 69638 Output 
Offset: 2 Reloc Offset: 20


$ llvm/build/bin/llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d 
arm-thumb-undefined-weak-lld

arm-thumb-undefined-weak-lld:   file format ELF32-arm-little

Disassembly of section .text:
_start:
    11008:       00 f0 00 80     beq.w   #0 <_start+0x4>
    1100c:       00 f0 00 b8     b.w     #0 <_start+0x8>
    11010:       00 f0 00 f8     bl      #0
    11014:       00 f0 00 f8     bl      #0
    11018:       c0 f2 00 00     movt    r0, #0
    1101c:       40 f2 00 00     movw    r0, #0


$ llvm/build/bin/llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d 
arm-thumb-undefined-weak-ld

arm-thumb-undefined-weak-ld:    file format ELF32-arm-little

Disassembly of section .text:
.text:
    11006:       00 00   movs    r0, r0

_start:
    11008:       2e f4 fa af     beq.w   #-69644
    1100c:       00 e0   b       #0 <_start+0x8>
    1100e:       00 bf   nop
    11010:       00 e0   b       #0 <_start+0xC>
    11012:       00 bf   nop
    11014:       00 e0   b       #0 <_start+0x10>
    11016:       00 bf   nop
    11018:       cf f6 fe 70     movt    r0, #65534
    1101c:       4e f6 e4 70     movw    r0, #61412



在 2017年09月15日 20:49, Peter Smith 写道:
> Just a thought I had about the calculation of P. I think that
> following the ld approach too closely may be a mistake.
>
> I'm speculating that the reason for this change in the value of P is
> similar to the situation in Arm for a Thumb BLX immediate instruction
> (Branch Link and Exchange with the immediate an offset from the PC).
> When calculating the target address the immediate is added to
> Align(PC, 4) where Align rounds down to nearest 4-byte boundary. The
> linker needs to account for this when resolving the relocation
> R_ARM_THM_CALL.
>
> To handle the alignment difference for this one special case in lld I
> accounted for the alignment difference in relocateOne. You may be able
> to use a similar method for Arc rather than writing modifyARCAddrLoc.
> Again I know nothing about Arc so you'll need to look at the
> Architecture reference manual to understand what the instruction the
> relocation applies to works.
>
> Peter
>
>
> On 15 September 2017 at 04:19, Leslie Zhai <lesliezhai at llvm.org.cn> wrote:
>> Hi Peter,
>>
>> Thanks for your kind response!
>>
>>
>> 在 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.
>> https://github.com/foss-for-synopsys-dwc-arc-processors/arc-ABI-manual
>>
>> But I prefer to read  bfd linker's source code about ARC instead:
>> 1. Specific e_flags
>> https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/blob/arc-2017.09/include/elf/arc.h
>> 2. Relocation define
>> https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/blob/arc-2017.09/include/elf/arc-reloc.def
>> 3. Relocation replace function
>> https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/blob/arc-2017.09/include/opcode/arc-func.h
>> 4. Calculation of S, A, P, PDATA, GOT, etc.
>> https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/blob/arc-2017.09/bfd/elf32-arc.c#L1156
>>
>>
>>> 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.
>> I implemented the MOD P for ARC:
>>
>> static void modifyARCAddrLoc(uint64_t &AddrLoc, const uint16_t EMachine,
>>                               RelExpr Expr, uint32_t Type, uint64_t VMA,
>>                               uint64_t OutSecOff, uint64_t RelOff) {
>>    if (EMachine != EM_ARC_COMPACT || EMachine != EM_ARC_COMPACT2 ||
>>        Expr != R_PC || Expr != R_GOT_PC) {
>> return;
>> }
>>
>>    uint64_t M = 0;
>>    if (Type == R_ARC_32_PCREL || Type == R_ARC_PC32 || Type == R_ARC_GOTPC32
>> ||
>>        Type == R_ARC_GOTPC) {
>>      M = 4; // bitsize >= 32 ? 4 : 0
>> }
>>    AddrLoc = (VMA + OutSecOff + RelOff - M) & ~0x3;
>> }
>>
>> modifyARCAddrLoc(AddrLoc, Config->EMachine, Expr, Type,
>>                       getOutputSection()->Addr,  <-- VMA is important!
>>                       cast<InputSection>(this)->OutSecOff, Rel.Offset);
>>
>>
>>> 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.
>> LLD's getOutputSection()->Addr =
>> https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L530
>>
>>
>>
>>> 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/
>>
>>
>>

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





More information about the llvm-dev mailing list