https://sourceware.org/bugzilla/show_bug.cgi?id=29660
Bug ID: 29660 Summary: Duplicated symbols count twice for linker script sections? Product: binutils Version: 2.33 Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: jsmith at crackofdawn dot onmicrosoft.com Target Milestone: --- Created attachment 14385 --> https://sourceware.org/bugzilla/attachment.cgi?id=14385&action=edit Minimal Example First a bit of background. Embedded firmware projects really like to use weak symbols, because they provide a way for C functions to override each other across multiple files with no runtime overhead. However, these have an Achilles' heel: if you compile your code into .a libraries, the linker won't resolve weak symbols properly because it will discard certain .o files. So, I'm trying to work around this by linking the entire project using `-Wl,--whole-archive` , which causes the linker to read all of the .o files inside every .a file. Unfortunately, because of how CMake handles .a dependencies, some of the .a files end up on the final link line multiple times, causing duplicate symbols in the final result. So, to fix that, I also pass `-Wl,--allow-multiple-definition` to the linker, so that it will not generate an error in this case. I claim this should be OK, because it's how the linker already handles inline symbols like C++ functions, correct? However, I noticed a pretty weird link error a while after implementing this fix. It seems like, when calculating the sizes of memory regions, ld is counting symbols multiple times instead of merging them together. I set up a minimal example, which is attached. This project declares a dedicated RAM region, SPECIAL_RAM, that is just 0x100 bytes long. It also declares an array that is exactly that length and which is supposed to get put in that section. When building, it compiles the one source file into two .a files, then links them together. But even though the variable is exactly as large as the RAM region it's supposed to go in, linking produces an error: c:/program files (x86)/gnu tools arm embedded/9 2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: build/executable.elf section `.special' will not fit in region `SPECIAL_RAM' c:/program files (x86)/gnu tools arm embedded/9 2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: region `SPECIAL_RAM' overflowed by 256 bytes collect2.exe: error: ld returned 1 exit status I claim that LD should be merging the two copies of `array2` together, so this program should be able to link correctly. But in order for it to link, I have to pass only one of the two static libraries, or I have to increase SPECIAL_RAM to 0x200 bytes. This is despite the map file showing that only one copy of `array2` was produced in the final result. This seems like incorrect behavior, right? P.S. I'm using the LD distributed with GNU Arm Embedded > arm-none-eabi-ld --version GNU ld (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 2.33.1.20191025 Copyright (C) 2019 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) a later version. This program has absolutely no warranty. -- You are receiving this mail because: You are on the CC list for the bug.