Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 583202 - sys-devel/binutils-config: Extend ldwrapper to work with cross-toolchains
Summary: sys-devel/binutils-config: Extend ldwrapper to work with cross-toolchains
Status: RESOLVED FIXED
Alias: None
Product: Gentoo/Alt
Classification: Unclassified
Component: Prefix Support (show other bugs)
Hardware: All OS X
: Normal enhancement (vote)
Assignee: Gentoo Prefix
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-16 16:45 UTC by Michael Weiser
Modified: 2017-12-27 09:05 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments
Extend ldwrapper to work with cross-toolchains (ldwrapper.c,11.44 KB, text/x-csrc)
2016-05-16 16:45 UTC, Michael Weiser
Details
Extend ldwrapper to work with cross-toolchains (ldwrapper-20171223-cross.patch,14.22 KB, patch)
2017-12-23 16:34 UTC, Michael Weiser
Details | Diff
Fix gcc dir case (binutils-config-5-r03.2-ldwrapper-gccdir.patch,487 bytes, patch)
2017-12-26 00:58 UTC, Michael Weiser
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Weiser 2016-05-16 16:45:18 UTC
I've extended ldwrapper:
- to detect a cross-ld at runtime from the argv[0] it was called with,
- always call ld with the full path in argv[0] so it can find its ldscript directory relative to that
- incidentally fix a bug where finding ld via binutils-config could never have worked since previous tries to find it via PATH had reduced PATH to its first component where binutils-config would not usually be

Find it attached for your consideration.

Reproducible: Always
Comment 1 Michael Weiser 2016-05-16 16:45:57 UTC
Created attachment 434442 [details]
Extend ldwrapper to work with cross-toolchains
Comment 2 Michael Weiser 2017-12-23 16:34:14 UTC
Created attachment 511552 [details, diff]
Extend ldwrapper to work with cross-toolchains

This is an updated patch against current binutils-config-5-r03.1.
Comment 3 Larry the Git Cow gentoo-dev 2017-12-25 19:47:22 UTC
The bug has been closed via the following commit(s):

https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=548521db9b370ac42d6497a4bdcc9fe73ce25019

commit 548521db9b370ac42d6497a4bdcc9fe73ce25019
Author:     Fabian Groffen <grobian@gentoo.org>
AuthorDate: 2017-12-25 19:47:01 +0000
Commit:     Fabian Groffen <grobian@gentoo.org>
CommitDate: 2017-12-25 19:47:01 +0000

    sys-devel/binutils-config: rework cross-support
    
    This is on top of previous commit which is Michael Weiser's work from
    bug #583202.  This rework avoids some mallocs, and tries to optimise the
    path needed for a run.
    
    Closes: https://bugs.gentoo.org/583202
    Package-Manager: Portage-2.3.18-prefix, Repoman-2.3.6

 sys-devel/binutils-config/Manifest                 |   1 +
 .../binutils-config/binutils-config-5-r03.1.ebuild |   8 +-
 .../binutils-config/binutils-config-5-r03.2.ebuild |  74 +++++
 sys-devel/binutils-config/files/ldwrapper.c        | 334 +++++++++------------
 4 files changed, 229 insertions(+), 188 deletions(-)
Comment 4 Michael Weiser 2017-12-25 22:06:00 UTC
Works like a charm. Thanks!
Comment 5 Michael Weiser 2017-12-26 00:58:38 UTC
Created attachment 511616 [details, diff]
Fix gcc dir case

I'm sorry, my celebrations were premature: The case where the wrapper is called via EPREFIX/usr/libexec/gcc/CTARGET/ld does not work. A cross-gcc build does just that from a script called collect-ld:

ORIGINAL_LD_FOR_TARGET="/usr/local/gentoo/usr/libexec/gcc/armv7veb-hardfloat-linux-gnueabi/ld"

and fails with:

ld: unknown option: -shared
collect2: error: ld returned 1 exit status

The one complaining about not knowing -shared is the host system's ld64 as opposed to the binutils-cross-ld. Attached patch fixes the handling.
Comment 6 Fabian Groffen gentoo-dev 2017-12-26 10:43:22 UTC
the first change (p-1 -> wrapper) I don't understand, the strncmp return check feels like a thinko indeed.
Comment 7 Michael Weiser 2017-12-26 12:04:58 UTC
(In reply to Fabian Groffen from comment #6)
> the first change (p-1 -> wrapper) I don't understand

strrchr needs to be given the *beginning* of the string to search backwards from the end. p-1 is the byte before the new end we've just made. So we're giving it an empty string to search.
Comment 8 Fabian Groffen gentoo-dev 2017-12-26 20:47:05 UTC
(In reply to Michael Weiser from comment #7)
> (In reply to Fabian Groffen from comment #6)
> > the first change (p-1 -> wrapper) I don't understand
> 
> strrchr needs to be given the *beginning* of the string to search backwards
> from the end. p-1 is the byte before the new end we've just made. So we're
> giving it an empty string to search.

but the code above this line does exactly that using wrapper and wrapper isn't modified, so ?

p was /, it's set to \0, then we search backwards for the next /, from the position before, if you replace that with wrapper it would have to skip over the \0 (guess it does), and then find the next /, which is just more work for no reason?
Comment 9 Michael Weiser 2017-12-26 21:19:56 UTC
(In reply to Fabian Groffen from comment #8)

> > strrchr needs to be given the *beginning* of the string to search backwards
> 
> but the code above this line does exactly that using wrapper and wrapper
> isn't modified, so ?
> 
> p was /, it's set to \0, then we search backwards for the next /, from the
> position before, if you replace that with wrapper it would have to skip over
> the \0 (guess it does), and then find the next /, which is just more work
> for no reason?

wrapper still points to the beginning of the whole string and p to the new end. A call of strrchr(p - 1, '\0') doesn't continue to search to the left starting at p - 1 but goes to p - 1 + strlen(p - 1) and searches backwards from there until it reaches p - 1. Otherwise it wouldn't know when to stop searching left.

ASCII art! :)

// wrapper:
// EPREFIX/usr/libexec/gcc/<CTARGET>/ld
// ^ strrchr -- searches ------<<------^
if ((p = strrchr(wrapper, '/')) != NULL) { 
// EPREFIX/usr/libexec/gcc/<CTARGET>/ld
//                                  ^ p
        *p = '\0'; 
// EPREFIX/usr/libexec/gcc/<CTARGET>\0ld
//                                  ^ p
// ^ strrchr -- searches ----<<-----^
        if ((q = strrchr(wrapper, '/')) != NULL) { 
// EPREFIX/usr/libexec/gcc/<CTARGET>\0ld
//                        ^ q       ^ p
                /* q points to "/<CTARGET>" now */
                len = strlen("/gcc");
                if (q - len > wrapper && strncmp(q - len, "/gcc", len) == 0)
                        wrapperctarget = q + 1;

With p - 1 instead of wrapper it'd be:

// wrapper:
// EPREFIX/usr/libexec/gcc/<CTARGET>/ld
// ^ strrchr -- searches -----<<-------^
if ((p = strrchr(wrapper, '/')) != NULL) { 
// EPREFIX/usr/libexec/gcc/<CTARGET>/ld
//                                  ^ p
        *p = '\0'; 
// EPREFIX/usr/libexec/gcc/<CTARGET>\0ld
//                                  ^ p
//                                 ^^ strrchr searches <<
        if ((q = strrchr(p-1, '/')) != NULL) { 
//                                 ^ q or NULL

So we're actually giving a string to search that's only one byte long. This could only success if there was a double-slash after <CTARGET> and then the /gcc match would still fail.
Comment 10 Fabian Groffen gentoo-dev 2017-12-27 08:58:48 UTC
right, it was late yesterday, thanks
Comment 11 Larry the Git Cow gentoo-dev 2017-12-27 09:05:07 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=e30f557eb73bff37366a44ebbbf4efdc0c616c58

commit e30f557eb73bff37366a44ebbbf4efdc0c616c58
Author:     Fabian Groffen <grobian@gentoo.org>
AuthorDate: 2017-12-27 09:04:46 +0000
Commit:     Fabian Groffen <grobian@gentoo.org>
CommitDate: 2017-12-27 09:04:46 +0000

    sys-devel/binutils-config: fix path unraveling, thanks Michael Weiser, bug #583202
    
    Bug: https://bugs.gentoo.org/583202
    Package-Manager: Portage-2.3.18-prefix, Repoman-2.3.6

 sys-devel/binutils-config/files/ldwrapper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)}