<div style="min-height:22px;margin-bottom:8px;">Hi Peter,</div><div style="min-height:22px;margin-bottom:8px;">Reducing Alighnment is my monkey patch :) I want to find the root cause why not 1 as LD, I am reading LinkerScript assignAddress, I will upload Map file to Google Drive next week, thanks a lot!</div><div style="min-height:22px;margin-bottom:8px;"><br></div><span class="mail-footer">发自我的iPad</span><div id="original-content"><br><br><div><div style="font-size:70%;padding:2px 0;">------------------ Original ------------------</div><div style="font-size:70%;background:#f0f0f0;color:#212121;padding:8px;border-radius:4px"><div><b>From:</b> Peter Smith <peter.smith@linaro.org></div><div><b>Date:</b> 周五,9月 15,2017 18:24</div><div><b>To:</b> Leslie Zhai <lesliezhai@llvm.org.cn></div><div><b>Cc:</b> Rui Ueyama <ruiu@google.com>, LLVM Developers Mailing List <llvm-dev@lists.llvm.org>, petecoup <petecoup@synopsys.com></div><div><b>Subject:</b> Re: [llvm-dev] Do I need to modify the AddrLoc of LLD for ARC target?</div></div></div><br>Hello Leslie,<br><br>If I understand you correctly, ld is aligning giving an Output or<br>Input Section alignment 1 and lld is giving an Output or Input Section<br>alignment 4 and you are trying to reduce the alignment in lld?<br><br>What I would do is try and work out why the Output or Input Section<br>has a higher alignment in lld. It is not a good idea to try and lower<br>the alignment of an OutputSection as this must have a high enough<br>alignment that every InputSection is aligned according to its<br>requirements, this means that at a minimum it must be set the maximum<br>alignment requested by an InputSection.<br><br>First think I would do would be to look at the linker map -M or<br>--Map=map.txt to put it in a file and look at the Output and<br>InputSections, if there is at least one InputSection that has<br>alignment 4 then I would expect the OutputSection to have alignment 4.<br>If all the InputSections in an OutputSection have alignment 1 I would<br>expect the OutputSection to have alignment 1 unless there is some<br>other bit of code enforcing a minimum alignment of 4.<br><br>In general overaligning an OutputSection is safe although the size of<br>the bytes added to align the Sections can get significant in a very<br>small embedded system.<br><br>Hope this is of some use.<br><br>Peter<br><br>On 15 September 2017 at 09:14, Leslie Zhai <lesliezhai@llvm.org.cn> wrote:<br>> Hi Peter,<br>><br>> Thanks for your hint! it is the Alignment issue :)<br>><br>> avr-ld and LLD both use the *same* Alignment 1 for<br>> input_section->output_section->vma, so VMA is same:<br>><br>> DEBUG: avr-ld: R_AVR_CALL: VMA: 5 Output Offset: 1 Reloc Offset: 0<br>><br>> DEBUG: avr-ld: R_AVR_8_LO8: VMA: 6 Output Offset: 0 Reloc Offset: 7<br>><br>> ...<br>><br>> DEBUG: lld: R_AVR_CALL TargetVA: 49 A: 44 P: 5 Align: 1 VMA: 5 Output<br>> Offset: 0 Reloc Offset: 0<br>><br>> DEBUG: lld: R_AVR_8_LO8 TargetVA: 50 A: 44 P: 13 Align: 1 VMA: 6 Output<br>> Offset: 0 Reloc Offset: 7<br>><br>> ...<br>><br>> But arc-ld use Alignment 1 and LLD use *different* Alignment 4:<br>><br>> alignTo<br>> https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/MathExtras.h#L657<br>><br>> alignTo(0x5, 1) = 5<br>><br>> alignTo(0x5, 4) = 8<br>><br>> alignTo(0x9, 1) = 9<br>><br>> alignTo(0x9, 4) = 12<br>><br>> alignTo(0x11, 1) = 17<br>><br>> alignTo(0x11, 4) = 20<br>><br>> ...<br>><br>> I can *not* use updateAlignment to modify the Alignment for a smaller value,<br>> such as 1, it is monkey patch, not the root cause, so how to correctly<br>> modify the Alignment for LLD? please give me some hint, thanks a lot!<br>><br>><br>> PS: arc-ld's sym_section->output_section->vma is equals to LLD's<br>> SymbolBody::getVA, so the value of (S + A) is same.<br>><br>><br>> 在 2017年09月15日 12:33, Leslie Zhai 写道:<br>>><br>>><br>>><br>>> 在 2017年09月14日 17:36, Peter Smith 写道:<br>>>><br>>>> Hello Leslie,<br>>>><br>>>> I think we are going to need to know a bit more about the ELF ABI for<br>>>> what looks like the ArcCompact before we can help you.<br>>>><br>>>> LLD's calculation of P (the place to be relocated) is as it is in the<br>>>> generic ELF specification. The Rel.Offset corresponds to the ELF<br>>>> r_offset field. This is covered by: "For a relocatable file, the value<br>>>> is the byte offset from the beginning of the section to the storage<br>>>> unit affected by the relocation."<br>>>><br>>>> For LLD we are calculating the virtual address (VA) of P, as I<br>>>> understand it this is equivalent to the vma used in BFD. Assuming that<br>>>> the relocation is relocating a regular InputSection from the<br>>>> basic-arc.o object then the LLD calculation of P =<br>>>> getOutputSection()->Addr + getOffset(Rel.Offset); translates to: (VA<br>>>> of OutputSection) + (Offset of InputSection within OutputSection) +<br>>>> (Offset within InputSection given by r_offset)<br>>>><br>>>> The BFD linker seems to be doing the equivalent calculation with an<br>>>> extra modification of the (Offset within InputSection given by<br>>>> r_offset) and is rounding down the result to the nearest 4-byte<br>>>> boundary. This looks unfamiliar to me, and could well be specific to<br>>>> ArcCompact. I think that you will need to refer to the ELF ABI<br>>>> documentation as this should tell you if there are any processor<br>>>> specific modifications to generic ELF that you have to follow.<br>>>><br>>>> The other thing that you should do is try and work out why the VA<br>>>> (vma) is 6 in LD and 8 in LLD and whether this is actually a problem.<br>>>> The VA of the OutputSection is not guaranteed to be the same between<br>>>> different linkers so it may have just been that differences in order<br>>>> of InputSections or alignment has caused a different VA. I would check<br>>>> the output of the linker map file to see where it placed the Output<br>>>> and Input Sections to see what the answer should be.<br>>><br>>><br>>> VMA in LD and LLD is the same for AVR target<br>>> https://reviews.llvm.org/D37615<br>>><br>>> $ avr-gcc -mmcu=atmega328p -o basic-avr.o -c basic-avr.s<br>>> $ avr-ld -o basic-avr basic-avr.o -Ttext=6 /*with-different-high-address*/<br>>><br>>> DEBUG: avr-ld: R_AVR_CALL: VMA: 6 Output Offset: 0 Reloc Offset: 0<br>>> DEBUG: avr-ld: R_AVR_16_PM: VMA: 6 Output Offset: 0 Reloc Offset: 4<br>>> DEBUG: avr-ld: R_AVR_8: VMA: 6 Output Offset: 0 Reloc Offset: 6<br>>> DEBUG: avr-ld: R_AVR_8_LO8: VMA: 6 Output Offset: 0 Reloc Offset: 7<br>>> DEBUG: avr-ld: R_AVR_8_HI8: VMA: 6 Output Offset: 0 Reloc Offset: 8<br>>> DEBUG: avr-ld: R_AVR_8_HLO8: VMA: 6 Output Offset: 0 Reloc Offset: 9<br>>> DEBUG: avr-ld: R_AVR_LO8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 10<br>>> DEBUG: avr-ld: R_AVR_HI8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 12<br>>> DEBUG: avr-ld: R_AVR_HH8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 14<br>>> DEBUG: avr-ld: R_AVR_MS8_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 16<br>>> DEBUG: avr-ld: R_AVR_LDI: VMA: 6 Output Offset: 0 Reloc Offset: 18<br>>> DEBUG: avr-ld: R_AVR_LO8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc Offset: 20<br>>> DEBUG: avr-ld: R_AVR_HI8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc Offset: 22<br>>> DEBUG: avr-ld: R_AVR_HH8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc Offset: 24<br>>> DEBUG: avr-ld: R_AVR_MS8_LDI_NEG: VMA: 6 Output Offset: 0 Reloc Offset: 26<br>>> DEBUG: avr-ld: R_AVR_LO8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 28<br>>> DEBUG: avr-ld: R_AVR_HI8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 30<br>>> DEBUG: avr-ld: R_AVR_HH8_LDI_PM: VMA: 6 Output Offset: 0 Reloc Offset: 32<br>>> DEBUG: avr-ld: R_AVR_LO8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc Offset:<br>>> 34<br>>> DEBUG: avr-ld: R_AVR_HI8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc Offset:<br>>> 36<br>>> DEBUG: avr-ld: R_AVR_HH8_LDI_PM_NEG: VMA: 6 Output Offset: 0 Reloc Offset:<br>>> 38<br>>> DEBUG: avr-ld: R_AVR_7_PCREL: VMA: 6 Output Offset: 0 Reloc Offset: 40<br>>> DEBUG: avr-ld: R_AVR_13_PCREL: VMA: 6 Output Offset: 0 Reloc Offset: 42<br>>> DEBUG: avr-ld: R_AVR_6: VMA: 6 Output Offset: 0 Reloc Offset: 52<br>>> DEBUG: avr-ld: R_AVR_16: VMA: 6 Output Offset: 0 Reloc Offset: 56<br>>> DEBUG: avr-ld: R_AVR_LO8_LDI_GS: VMA: 6 Output Offset: 0 Reloc Offset: 58<br>>> DEBUG: avr-ld: R_AVR_HI8_LDI_GS: VMA: 6 Output Offset: 0 Reloc Offset: 60<br>>> DEBUG: avr-ld: R_AVR_PORT6: VMA: 6 Output Offset: 0 Reloc Offset: 62<br>>> DEBUG: avr-ld: R_AVR_PORT5: VMA: 6 Output Offset: 0 Reloc Offset: 64<br>>> DEBUG: avr-ld: R_AVR_6_ADIW: VMA: 6 Output Offset: 0 Reloc Offset: 66<br>>><br>>> $ llvm/build/bin/ld.lld -o basic-avr-lld basic-avr.o -Ttext=6<br>>> /*with-different-high-address*/<br>>><br>>> DEBUG: lld: R_AVR_CALL TargetVA: 50 A: 44 P: 6 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 0<br>>> DEBUG: lld: R_AVR_16_PM TargetVA: 50 A: 44 P: 10 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 4<br>>> DEBUG: lld: R_AVR_8 TargetVA: 50 A: 44 P: 12 VMA: 6 Output Offset: 0 Reloc<br>>> Offset: 6<br>>> DEBUG: lld: R_AVR_8_LO8 TargetVA: 50 A: 44 P: 13 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 7<br>>> DEBUG: lld: R_AVR_8_HI8 TargetVA: 50 A: 44 P: 14 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 8<br>>> DEBUG: lld: R_AVR_8_HLO8 TargetVA: 50 A: 44 P: 15 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 9<br>>> DEBUG: lld: R_AVR_LO8_LDI TargetVA: 50 A: 44 P: 16 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 10<br>>> DEBUG: lld: R_AVR_HI8_LDI TargetVA: 50 A: 44 P: 18 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 12<br>>> DEBUG: lld: R_AVR_HH8_LDI TargetVA: 50 A: 44 P: 20 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 14<br>>> DEBUG: lld: R_AVR_MS8_LDI TargetVA: 50 A: 44 P: 22 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 16<br>>> DEBUG: lld: R_AVR_LDI TargetVA: 50 A: 44 P: 24 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 18<br>>> DEBUG: lld: R_AVR_LO8_LDI_NEG TargetVA: 50 A: 44 P: 26 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 20<br>>> DEBUG: lld: R_AVR_HI8_LDI_NEG TargetVA: 50 A: 44 P: 28 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 22<br>>> DEBUG: lld: R_AVR_HH8_LDI_NEG TargetVA: 50 A: 44 P: 30 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 24<br>>> DEBUG: lld: R_AVR_MS8_LDI_NEG TargetVA: 50 A: 44 P: 32 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 26<br>>> DEBUG: lld: R_AVR_LO8_LDI_PM TargetVA: 50 A: 44 P: 34 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 28<br>>> DEBUG: lld: R_AVR_HI8_LDI_PM TargetVA: 50 A: 44 P: 36 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 30<br>>> DEBUG: lld: R_AVR_HH8_LDI_PM TargetVA: 50 A: 44 P: 38 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 32<br>>> DEBUG: lld: R_AVR_LO8_LDI_PM_NEG TargetVA: 50 A: 44 P: 40 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 34<br>>> DEBUG: lld: R_AVR_HI8_LDI_PM_NEG TargetVA: 50 A: 44 P: 42 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 36<br>>> DEBUG: lld: R_AVR_HH8_LDI_PM_NEG TargetVA: 50 A: 44 P: 44 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 38<br>>> DEBUG: lld: R_AVR_7_PCREL TargetVA: 4 A: 44 P: 46 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 40<br>>> DEBUG: lld: R_AVR_13_PCREL TargetVA: 2 A: 44 P: 48 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 42<br>>> DEBUG: lld: R_AVR_6 TargetVA: 50 A: 44 P: 58 VMA: 6 Output Offset: 0 Reloc<br>>> Offset: 52<br>>> DEBUG: lld: R_AVR_16 TargetVA: 50 A: 44 P: 62 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 56<br>>> DEBUG: lld: R_AVR_LO8_LDI_GS TargetVA: 50 A: 44 P: 64 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 58<br>>> DEBUG: lld: R_AVR_HI8_LDI_GS TargetVA: 50 A: 44 P: 66 VMA: 6 Output<br>>> Offset: 0 Reloc Offset: 60<br>>> DEBUG: lld: R_AVR_PORT6 TargetVA: 51 A: 45 P: 68 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 62<br>>> DEBUG: lld: R_AVR_PORT5 TargetVA: 6 A: 0 P: 70 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 64<br>>> DEBUG: lld: R_AVR_6_ADIW TargetVA: 50 A: 44 P: 72 VMA: 6 Output Offset: 0<br>>> Reloc Offset: 66<br>>><br>>> interesting :)<br>>><br>>>><br>>>> In summary:<br>>>> It looks like there are some Arc specific things that might need to be<br>>>> done. Unfortunately I don't have any experience with Arc, and I'm not<br>>>> sure the other people that work on LLD do either. I suggest looking at<br>>>> the public ABI documentation and making any arguments for changes<br>>>> based on that documentation, it is worth assuming that we know nothing<br>>>> about Arc, don't have the documentation to hand and don't know where<br>>>> to find it!<br>>>><br>>>> Hope that is of some help, with a bit more context I might be able to<br>>>> help a bit more, unfortunately I can't spend a lot of time learning<br>>>> about Arc.<br>>>><br>>>> Peter<br>>>><br>>>><br>>>> On 14 September 2017 at 07:16, Leslie Zhai via llvm-dev<br>>>> <llvm-dev@lists.llvm.org> wrote:<br>>>>><br>>>>> Hi LLVM developers,<br>>>>><br>>>>> basic-arc.s:<br>>>>><br>>>>> main:<br>>>>>    bl memset<br>>>>><br>>>>> $ arc-elf32-gcc -mcpu=arc600 -o basic-arc.o -c<br>>>>><br>>>>> $ arc-elf32-readelf -r basic-arc.o<br>>>>><br>>>>> Relocation section '.rela.text' at offset 0xd4 contains 1 entries:<br>>>>>   Offset     Info    Type            Sym.Value  Sym. Name + Addend<br>>>>> 00000000  00000611 R_ARC_S25W_PCREL  00000000   memset + 0<br>>>>><br>>>>> High address: 0x0<br>>>>><br>>>>> $ arc-elf32-ld -o basic-arc basic-arc.o<br>>>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/arc600<br>>>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/../../../../arc-elf32/lib/arc600<br>>>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1<br>>>>> -L/opt/arc-gnu/lib/gcc/arc-elf32/7.1.1/../../../../arc-elf32/lib<br>>>>> --start-group -lgcc -lc -lnosys --end-group -Ttext=0<br>>>>><br>>>>> DEBUG: arc-ld: R_ARC_S25W_PCREL relocation: 1 S: 4 A: 0 P: 0 = (vma: 0 +<br>>>>> output_offset: 0 + reloc_offset: 0 - 0) & ~0x3<br>>>>> DEBUG: arc-ld: type: R_ARC_S25W_PCREL insn: 2054<br>>>>><br>>>>> $ ld.lld -o basic-arc-lld basic-arc.o $ARC_LINKER_LIB -Ttext=0<br>>>>><br>>>>> DEBUG: lld: R_ARC_S25W_PCREL TargetVA: 4 A: 0 P: 0 <-- same P as arc-ld<br>>>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2050 Rel: 1<br>>>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2054 <-- same relocation value as<br>>>>> arc-ld<br>>>>><br>>>>> But with several different high address *not* 0x0, such as 0x6:<br>>>>><br>>>>> DEBUG: arc-ld: R_ARC_S25W_PCREL relocation: 2 S: 12 A: 0 P: 4 = (vma: 6<br>>>>> +<br>>>>> output_offset: 0 + reloc_offset: 0 - 0) & ~0x3<br>>>>> DEBUG: arc-ld: type: R_ARC_S25W_PCREL insn: 2058<br>>>>><br>>>>> DEBUG: lld: R_ARC_S25W_PCREL TargetVA: 4 A: 0 P: 8 <-- different P?<br>>>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2050 Rel: 1<br>>>>> DEBUG: lld: R_ARC_S25W_PCREL: Insn: 2054 <-- different relocation value<br>>>>><br>>>>> How arc-ld calculates P?<br>>>>><br>>>>> P = ((reloc_data.input_section->output_section ?<br>>>>> reloc_data.input_section->output_section->vma : 0) +<br>>>>> reloc_data.input_section->output_offset + (reloc_data.reloc_offset -<br>>>>> (reloc_data.bitsize >= 32 ? 4 : 0))) & ~0x3;<br>>>>><br>>>>> for example, R_ARC_S25W_PCREL's bitsize < 32, P = (6 + 0 + 0 - 0) & ~0x3<br>>>>> =<br>>>>> 4, when vma is 6, output and reloc offset is 0.<br>>>>><br>>>>> How LLD calculates P (AddrLoc)?<br>>>>><br>>>>> P = getOutputSection()->Addr + getOffset(Rel.Offset);<br>>>>><br>>>>> for example, the same high address 0x6, LLD's P is 8, different with<br>>>>> arc-ld?<br>>>>> so do I need to modify the value of P for R_PC case in the<br>>>>> getRelocTargetVA?<br>>>>> please give me some hints, thanks a lot!<br>>>>><br>>>>><br>>>>> PS: arc-ld R_ARC_S25W_PCREL's FORMULA is: ( S + A ) - P ) >> 2, and it<br>>>>> needs<br>>>>> middle endian convert, so:<br>>>>><br>>>>> Insn = middleEndianConvert (insn, TRUE);<br>>>>><br>>>>> Insn = replaceDisp25w(Insn, ( S + A ) - P ) >> 2);<br>>>>><br>>>>> Insn = middleEndianConvert (insn, TRUE);<br>>>>><br>>>>> write32le(Loc, Insn);<br>>>>><br>>>>> --<br>>>>> Regards,<br>>>>> Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/<br>>>>><br>>>>><br>>>>><br>>>>> _______________________________________________<br>>>>> LLVM Developers mailing list<br>>>>> llvm-dev@lists.llvm.org<br>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br>>><br>>><br>><br>> --<br>> Regards,<br>> Leslie Zhai -https://reviews.llvm.org/p/xiangzhai/<br>><br>><br>><br></div>