Peter Smith via llvm-dev
2017-Sep-14 09:36 UTC
[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
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. 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
Leslie Zhai via llvm-dev
2017-Sep-15 03:19 UTC
[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
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/
Leslie Zhai via llvm-dev
2017-Sep-15 04:33 UTC
[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
在 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/
Leslie Zhai via llvm-dev
2017-Sep-15 08:14 UTC
[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
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/
Peter Smith via llvm-dev
2017-Sep-15 10:24 UTC
[llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?
Hello Leslie, If I understand you correctly, ld is aligning giving an Output or Input Section alignment 1 and lld is giving an Output or Input Section alignment 4 and you are trying to reduce the alignment in lld? What I would do is try and work out why the Output or Input Section has a higher alignment in lld. It is not a good idea to try and lower the alignment of an OutputSection as this must have a high enough alignment that every InputSection is aligned according to its requirements, this means that at a minimum it must be set the maximum alignment requested by an InputSection. First think I would do would be to look at the linker map -M or --Map=map.txt to put it in a file and look at the Output and InputSections, if there is at least one InputSection that has alignment 4 then I would expect the OutputSection to have alignment 4. If all the InputSections in an OutputSection have alignment 1 I would expect the OutputSection to have alignment 1 unless there is some other bit of code enforcing a minimum alignment of 4. In general overaligning an OutputSection is safe although the size of the bytes added to align the Sections can get significant in a very small embedded system. Hope this is of some use. Peter On 15 September 2017 at 09:14, Leslie Zhai <lesliezhai at llvm.org.cn> wrote:> 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/ > > >