Patchwork Using external toolchain wrapper outside of buildroot

login
register
mail settings
Submitter Greg Beresford
Date Feb. 15, 2013, 11:22 a.m.
Message ID <BF980CD5635D994FA25831A4A9C113BF1328583EBE@THHS2E12BE9X.hostedservice2.net>
Download mbox | patch
Permalink /patch/220720/
State Superseded
Headers show

Comments

Greg Beresford - Feb. 15, 2013, 11:22 a.m.
Hi all,

It looks like making the external toolchain wrapper relocatable may have broken it for use outside of buildroot. If you add the wrapper directory to your path and invoke the wrapper as arm-linux-gcc (for example), execution will enter the 'else' on line 76 of ext-toolchain-wrapper.c. This sets basename to arm-linux-gcc, which is fine, but it also sets absbasedir to whatever $(pwd)/../.. resolves to which then gets used when calculating the sysroot directory, resulting in gcc not having the real sysroot in its search paths.

The above all works fine if the wrapper is invoked with an absolute path. (I've not tried with a relative path with slashes in.)

I've attached a patch with a fix below which calculates absbasedir from /proc/self/exe. (I don't know of any other way of reliably getting the path to the current executable.) My C is rusty though, so it might need to be fixed up before it's applied. (Was there a reason for avoiding the basename and dirname functions from libgen.h?)

Cheers
Greg

zbd
d +44 (0) 1344 292 123  t +44 (0)1344 292 110
w  www.zbdsolutions.com
ZBD Displays Ltd | Building 3 | Kingswood | Kings Ride | Ascot | Berkshire | SL5 8AD | UK

From 9f0a2566bc15e2f7115dce58db9dec84d98b844b Mon Sep 17 00:00:00 2001
From: Greg Beresford <greg.beresford@zbdsolutions.com>
Date: Thu, 14 Feb 2013 18:25:43 +0000
Subject: [PATCH] Fix toolchain wrapper when used outside of buildroot

---
 .../toolchain-external/ext-toolchain-wrapper.c     | 50 ++++++++++++++--------
 1 file changed, 32 insertions(+), 18 deletions(-)

--
1.8.0



Disclaimer: This email contains proprietary information some or all of which may be legally privileged and/or is confidential. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you must not use, disclose, distribute, copy or print this email. Any views expressed in this message are those of the individual sender, except where the message states otherwise. ZBD Displays accepts no responsibility for any computer virus which might be transferred by way of this email. We may monitor all email communication through our networks. If you contact us by email, we may store your name and address to facilitate communication. ZBD Displays Ltd is registered in England and Wales, company registration number: 03929602. Registered Office: Malvern Hills Science Park, Geraldine Road, Malvern,  Worcestershire, WR14 3SZ, UK
Daniel Nyström - Feb. 20, 2013, 3:17 p.m.
Hi Greg

On Fri, Feb 15, 2013 at 12:22 PM, Greg Beresford
<greg.beresford@zbdsolutions.com> wrote:
> I've attached a patch with a fix below which calculates absbasedir from /proc/self/exe. (I don't know of any other way of reliably getting the path to the current executable.) My C is rusty though, so it might need to be fixed up before it's applied. (Was there a reason for avoiding the basename and dirname functions from libgen.h?)

I've tested it and it solved my problems with the external toolchain.
I can't find any obvious C flaws either, so for what it's worth:

Acked-by: Daniel Nyström <daniel.nystrom@timeterminal.se>

Patch

diff --git a/toolchain/toolchain-external/ext-toolchain-wrapper.c b/toolchain/toolchain-external/ext-toolchain-wrapper.c
index a92bada..f570554 100644
--- a/toolchain/toolchain-external/ext-toolchain-wrapper.c
+++ b/toolchain/toolchain-external/ext-toolchain-wrapper.c
@@ -19,6 +19,7 @@ 
 #include <limits.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <libgen.h>

 static char path[PATH_MAX];
 static char sysroot[PATH_MAX];
@@ -56,26 +57,37 @@  int main(int argc, char **argv)
 {
        char **args, **cur;
        char *relbasedir, *absbasedir;
-       char *progpath = argv[0];
-       char *basename;
+       char exepath[PATH_MAX + 1] = {0};
+       char *dupbase, *base, *dir;
        int ret;
+       ssize_t ret_size;
+
+       ret_size = readlink("/proc/self/exe", exepath, sizeof(exepath) - 1);
+       if (ret_size < 0)
+       {
+               perror(__FILE__ ": readlink");
+               return 2;
+       }
+       else if (ret_size >= sizeof(exepath))
+       {
+               perror(__FILE__ ": readlink return value out of bounds");
+               return 2;
+       }
+       exepath[ret_size] = '\0';

        /* Calculate the relative paths */
-       basename = strrchr(progpath, '/');
-       if (basename) {
-               *basename = '\0';
-               basename++;
-               relbasedir = malloc(strlen(progpath) + 7);
-               if (relbasedir == NULL) {
-                       perror(__FILE__ ": malloc");
-                       return 2;
-               }
-               sprintf(relbasedir, "%s/../..", argv[0]);
-               absbasedir = realpath(relbasedir, NULL);
-       } else {
-               basename = progpath;
-               absbasedir = realpath("../..", NULL);
+       dupbase = strdup(argv[0]);
+       base = basename(dupbase);
+       dir = dirname(exepath);
+
+       relbasedir = malloc(strlen(dir) + 7);
+       if (relbasedir == NULL) {
+               perror(__FILE__ ": malloc");
+               return 2;
        }
+       sprintf(relbasedir, "%s/../..", dir);
+       absbasedir = realpath(relbasedir, NULL);
+
        if (absbasedir == NULL) {
                perror(__FILE__ ": realpath");
                return 2;
@@ -83,10 +95,12 @@  int main(int argc, char **argv)

        /* Fill in the relative paths */
 #ifdef BR_CROSS_PATH_REL
-       ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, basename);
+       ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, base);
 #else /* BR_CROSS_PATH_ABS */
-       ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", basename);
+       ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", base);
 #endif
+       free(dupbase);
+
        if (ret >= sizeof(path)) {
                perror(__FILE__ ": overflow");
                return 3;