bug-binutils
[Top][All Lists]
Advanced

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

[Bug ld/30590] Section matching broken by prefix tree change (b1eecf6f66


From: matz at suse dot de
Subject: [Bug ld/30590] Section matching broken by prefix tree change (b1eecf6f66a4a642)
Date: Wed, 28 Jun 2023 13:33:11 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=30590

--- Comment #3 from Michael Matz <matz at suse dot de> ---
When you move the libs into a subdir (and accordingly don't have them in the
current dir anymore!) then your "lib1.a(*)" should have given you an error,
with old ld, with new ld and with patch:

% ls -l lib* subdir/lib*
-rw-r--r-- 1 matz suse 3028 Jun 26 15:02 lib1.a.away
-rw-r--r-- 1 matz suse 1422 Jun 26 15:02 lib2.a.away
-rw-r--r-- 1 matz suse 3028 Jun 26 15:02 subdir/lib1.a
-rw-r--r-- 1 matz suse 1422 Jun 26 15:02 subdir/lib2.a
% grep lib1 linker.ld
    lib1.a(*)
% ld -Map bla.map -o out.bin -T linker.ld subdir/lib1.a subdir/lib2.a
ld: cannot find lib1.a: No such file or directory

(this is with an oldish system linker, i.e. before the prefix tree change).

The thing is the following: with a bare-word filename part in the section
statement (i.e. no colons and no wildcards), the named "thing" is loaded in a
special mode: as if named on command line, but with searching in search paths.
E.g. adding '-L subdir' above would make the error message go away (but
doing that would still not make just mentioning "lib1.a" on the cmdline work).

If you name the bare-word part also on the command line, then the thing
might be loaded twice.  It's usually not, because obvious duplicates, based
on filenames are not loaded twice, but with enough work you could make ld
do that, and get e.g. duplicate symbol definitions.  As the above are archives
it's even harder, but if they are for instance normal .o files you can easily
run into that:

% ln test1.o subdir/test1.o
% egrep 'lib|test' linker.ld
    test1.o(*)
    test2.o(*)
% ld -Map bla.map -o out.bin -T linker.ld subdir/test1.o subdir/lib1.a
subdir/lib2.a
ld: subdir/test1.o: in function `func1':
test1.c:(.text+0x0): multiple definition of `func1';
test1.o:test1.c:(.text+0x0): first defined here

Compare with:

% egrep 'lib|test' linker.ld 
    test*.o(*)
% ld -Map bla.map -o out.bin -T linker.ld subdir/test1.o subdir/lib1.a
subdir/lib2.a 
% # worked

I.e. non-bare-word parts don't actively load anything, they only match against
things that are otherwise loaded (per cmdline, INPUT statements or the above
form of bare-word pseudo-INPUT statements).

So, if your 'lib1.a(*)' statement worked also when lib1.a was in a subdir,
that was because it somehow was loaded without error, either because of
a searchpath (-L) or because a file named lib1.a was still in the current dir,
in which case that probably wasn't the intention.  If the latter then it wasn't
really matching against the subdir/lib1.a, but rather against ./lib1.a which
may or may not have been the same file.

It's all mightily confusing, I agree.  But parts of all this is historic
baggage, and parts of this is even documented (e.g. that bare-words are
loading stuff), so we can't easily remove that behaviour.

IMHO it's best to avoid bare-word section "matchers" (certainly with
archives) and just name all to-be-loaded things either on the cmdline
or in explicit INPUT statements.  Otherwise there's always the danger
to run into confusions in mildly complex directory layout situations.

-- 
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]