[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target? (original) (raw)
Leslie Zhai via llvm-dev llvm-dev at lists.llvm.org
Sun Sep 17 19:28:27 PDT 2017
- Previous message: [llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
- Next message: [llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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 > RARMTHMCALL. >> 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 eflags >> 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 >>> roffset 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 roffset) >>>>>> The BFD linker seems to be doing the equivalent calculation with an >>> extra modification of the (Offset within InputSection given by >>> roffset) 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(uint64t &AddrLoc, const uint16t EMachine, >> RelExpr Expr, uint32t Type, uint64t VMA, >> uint64t OutSecOff, uint64t RelOff) { >> if (EMachine != EMARCCOMPACT || EMachine != EMARCCOMPACT2 || >> Expr != RPC || Expr != RGOTPC) { >> return; >> } >>>> uint64t M = 0; >> if (Type == RARC32PCREL || Type == RARCPC32 || Type == RARCGOTPC32 >> || >> Type == RARCGOTPC) { >> M = 4; // bitsize >= 32 ? 4 : 0 >> } >> AddrLoc = (VMA + OutSecOff + RelOff - M) & ~0x3; >> } >>>> modifyARCAddrLoc(AddrLoc, Config->EMachine, Expr, Type, >> _getOutputSection()->Addr, <-- VMA is important!_ >> cast(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 RARCS25WPCREL 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: RARCS25WPCREL relocation: 1 S: 4 A: 0 P: 0 = (vma: 0 + >>>> outputoffset: 0 + relocoffset: 0 - 0) & ~0x3 >>>> DEBUG: arc-ld: type: RARCS25WPCREL insn: 2054 >>>>>>>> $ ld.lld -o basic-arc-lld basic-arc.o $ARCLINKERLIB -Ttext=0 >>>>>>>> _DEBUG: lld: RARCS25WPCREL TargetVA: 4 A: 0 P: 0 <-- same P as arc-ld_ >>>> DEBUG: lld: RARCS25WPCREL: Insn: 2050 Rel: 1 >>>> _DEBUG: lld: RARCS25WPCREL: Insn: 2054 <-- same relocation value as_ >>>> arc-ld >>>>>>>> But with several different high address not 0x0, such as 0x6: >>>>>>>> DEBUG: arc-ld: RARCS25WPCREL relocation: 2 S: 12 A: 0 P: 4 = (vma: 6 + >>>> outputoffset: 0 + relocoffset: 0 - 0) & ~0x3 >>>> DEBUG: arc-ld: type: RARCS25WPCREL insn: 2058 >>>>>>>> _DEBUG: lld: RARCS25WPCREL TargetVA: 4 A: 0 P: 8 <-- different P?_ >>>> DEBUG: lld: RARCS25WPCREL: Insn: 2050 Rel: 1 >>>> _DEBUG: lld: RARCS25WPCREL: Insn: 2054 <-- different relocation value_ >>>>>>>> How arc-ld calculates P? >>>>>>>> P = ((relocdata.inputsection->outputsection ? >>>> relocdata.inputsection->outputsection->vma : 0) + >>>> relocdata.inputsection->outputoffset + (relocdata.relocoffset - >>>> (relocdata.bitsize >= 32 ? 4 : 0))) & ~0x3; >>>>>>>> _for example, RARCS25WPCREL'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 RPC case in the >>>> getRelocTargetVA? >>>> please give me some hints, thanks a lot! >>>>>>>>>>>> PS: arc-ld RARCS25WPCREL'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/
- Previous message: [llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
- Next message: [llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]