bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/29660] New: Duplicated symbols count twice for linker scri


From: jsmith at crackofdawn dot onmicrosoft.com
Subject: [Bug binutils/29660] New: Duplicated symbols count twice for linker script sections?
Date: Fri, 07 Oct 2022 14:57:18 +0000

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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]