https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78529
Renlin Li <renlin at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |renlin at gcc dot gnu.org --- Comment #22 from Renlin Li <renlin at gcc dot gnu.org> --- (In reply to James Greenhalgh from comment #19) > That would be an error: > > /tmp/ccpefK3l.ltrans0.ltrans.o: In function `memset': > <artificial>:(.text+0x4a0): multiple definition of `memset' > .../aarch64-none-elf/lib/libc.a(lib_a-memset.o): > .../newlib/libc/machine/aarch64/memset.S:90: first defined here > > Were it not for the flag added to resolve PR55994 > -Wl,--allow-multiple-definition . > > So, in my opinion, the testcase is broken and could always have failed in > this way. The combination of register allocation, LTO and order the linker > sees symbols explains why this is hard to reproduce. I had exactly the same errors and issues today. I reduced it to a minimum test case. Please check the new attachment The build command line is: aarch64-none-elf-gcc -O2 -specs=aem-ve.specs -Wl,--allow-multiple-definition -lm -flto main.c memset.c -o new.exe The expected output should be "A A A 2" 0000000080001038 <main>: 80001038: a9bf7bfd stp x29, x30, [sp,#-16]! 8000103c: 90000123 adrp x3, 80025000 <__global_locale+0x68> 80001040: 52800044 mov w4, #0x2 // #2 80001044: 91060060 add x0, x3, #0x180 80001048: 910003fd mov x29, sp 8000104c: b9018064 str w4, [x3,#384] 80001050: d2800402 mov x2, #0x20 // #32 80001054: 52800821 mov w1, #0x41 // #65 80001058: 91002000 add x0, x0, #0x8 # At this function entry, x4 is not saved. Because LTO thinks the local memset # implementation will not clobber it. However, the libc version of memeset is # linked in the final binary. The implementation there will clobber x4. This # will cause run-time data corruption, which is shown here. 8000105c: 94000a39 bl 80003940 <memset> 80001060: a8c17bfd ldp x29, x30, [sp],#16 80001064: 52800823 mov w3, #0x41 // #65 80001068: 90000080 adrp x0, 80011000 <__swbuf_r+0x70> 8000106c: 2a0303e2 mov w2, w3 80001070: 2a0303e1 mov w1, w3 80001074: 91152000 add x0, x0, #0x548 80001078: 140015c0 b 80006778 <printf> 8000107c: 00000000 .inst 0x00000000 ; undefined This is mentioned above. But allow me to ask again: "aarch64-none-elf-gcc -O2 main.c memset.c -o new.o -specs=aem-ve.specs -lm -flto" will give the "multiple definition of `memset'" error while "aarch64-none-elf-gcc -O2 main.c memset.c -o new.o -specs=aem-ve.specs -lm" won't. Should them behavior the same? By adding "-Wl,--allow-multiple-definition" do fix this erro. But why it's the test case that is broken instead of the lto pass?