Bug 25806 - [ld] Search for input files relative to the current linker script
Summary: [ld] Search for input files relative to the current linker script
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.35
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-09 04:17 UTC by Fangrui Song
Modified: 2020-04-22 15:22 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2020-04-09 04:17:50 UTC
This is a feature request.

commit 51dee2fec3afad5e6fc9f78b8c1d8486ebf3a334 added the feature for gold.

// p/libm.a
INPUT(libm.a.1)

gold a.o p/libm.a

gold can find p/libm.a.1 even if -L p is not specified. gold names the directory `extra_search_path` and prefers it over -L:

 // If the filename is not absolute, we assume it is in the current
 // directory *except* when:
 //    A) input_argument_->is_lib() is true; or
 //    B) input_argument_->extra_search_path() is not empty.
 // In both cases, we look in extra_search_path + library_path to find
 // the file location, rather than the current directory.

In theory, if we had this feature many years ago. For glibc libm.a

% cat /usr/lib/x86_64-linux-gnu/libm.a
/* GNU ld script
*/
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /usr/lib/x86_64-linux-gnu/libm-2.29.a /usr/lib/x86_64-linux-gnu/libmvec.a )

We can simplify the script to:

GROUP(libm-2.29.a libmvec.a)
Comment 1 Fangrui Song 2020-04-09 06:49:58 UTC
I made some investigations.

Notation: CWD => current working directory
For a relative pathname (not absolute path or -l) in INPUT() or GROUP():

* GNU ld searches in CWD then in -L
* gold searches in the parent directory of the current linker script then in -L.
  It does not fall back to CWD.

I am going to change the search order of lld

* the parent directory of the current linker script
* next in CWD
* then in -L.

https://reviews.llvm.org/D77779

libstdc++.a currently includes object files from libsupc++. It could use a linker script as an alternative if GNU ld had this feature... Though there is probably no point to do this

For libc++.a, it probably makes more sense because several C++ ABI libraries can be plugged in.
Comment 2 Nick Clifton 2020-04-09 10:20:54 UTC
Hi Fangrui,

> gold a.o p/libm.a
> 
> gold can find p/libm.a.1 even if -L p is not specified.

A couple of questions:

1. Does the extra search path persist beyond the end of the linker
   script ?  For example, using your sample script:

      % ld p/libm.a foo.o

   Should the linker load p/foo.o ?  (If it exists, of course).


2. Is this feature restricted to libraries, or should it also affect
   object files ?  For example:

    % cat p/libm.a
    INPUT(libm.a.1)
    INPUT(foo.o)

    % ld p/libm.a

   Is this expected to load p/foo.o ?

Cheers
  Nick
Comment 3 Fangrui Song 2020-04-09 16:46:31 UTC
(In reply to Nick Clifton from comment #2)
> Hi Fangrui,
> 
> > gold a.o p/libm.a
> > 
> > gold can find p/libm.a.1 even if -L p is not specified.
> 
> A couple of questions:
> 
> 1. Does the extra search path persist beyond the end of the linker
>    script ?  For example, using your sample script:
> 
>       % ld p/libm.a foo.o
> 
>    Should the linker load p/foo.o ?  (If it exists, of course).

No. I think we should make the intuitive choice: the extra search path is local to the linker script.

> 2. Is this feature restricted to libraries, or should it also affect
>    object files ?  For example:
> 
>     % cat p/libm.a
>     INPUT(libm.a.1)
>     INPUT(foo.o)
> 
>     % ld p/libm.a
> 
>    Is this expected to load p/foo.o ?
> 
> Cheers
>   Nick

p/foo.o will be loaded. The extra search rule should apply to any relative pathname (my observation of the gold behavior). They can be: libm.a.1 , foo.o , foo.so , relative/foo.so , etc

The -l form does not apply.



I hope the rules above are all intuitive and likely what users expect... For me, I did feel strange when I first noticed that INPUT() and GROUP() do not search for the "local files" but I did not think hard about the rule.
Comment 4 Fangrui Song 2020-04-20 06:08:01 UTC
Proposed patch: https://sourceware.org/pipermail/binutils/2020-April/110743.html
Comment 5 Sourceware Commits 2020-04-22 15:20:54 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=161719466ac9ea5f186514312f6bce842181804f

commit 161719466ac9ea5f186514312f6bce842181804f
Author: Fangrui Song <maskray@google.com>
Date:   Wed Apr 22 16:20:02 2020 +0100

    For relative paths in INPUT() and GROUP(), search the directory of the current linker script before searching other paths.
    
            PR ld/25806
            * ldlang.h (struct lang_input_statement_struct): Add extra_search_path.
            * ldlang.c (current_input_file): New.
            (ldirname): New.
            (new_afile): Add from_filename parameter. Set extra_search_path.
            (lang_add_input_file): Pass current_input_file to new_afile.
            (load_symbols): Set current_input_file.
Comment 6 Nick Clifton 2020-04-22 15:22:17 UTC
Patch applied.
Note - testsuite patch may follow.