diff options
-rw-r--r-- | src/logic/slbt_exec_link.c | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c index 647abd2..2f97c32 100644 --- a/src/logic/slbt_exec_link.c +++ b/src/logic/slbt_exec_link.c @@ -151,7 +151,9 @@ static int slbt_get_deps_meta( static bool slbt_adjust_object_argument( char * arg, - bool fpic) + bool fpic, + bool fany, + int fdcwd) { char * slash; char * dot; @@ -160,27 +162,56 @@ static bool slbt_adjust_object_argument( if (*arg == '-') return false; + /* object argument: foo.lo or foo.o */ if (!(dot = strrchr(arg,'.'))) return false; - if (strcmp(dot,".lo")) + if ((dot[1]=='l') && (dot[2]=='o') && !dot[3]) { + dot[1] = 'o'; + dot[2] = 0; + + } else if ((dot[1]=='o') && !dot[2]) { + (void)0; + + } else { return false; + } - if (fpic) { - if ((slash = strrchr(arg,'/'))) - slash++; - else - slash = arg; + /* foo.o requested and is present? */ + if (!fpic && !faccessat(fdcwd,arg,0,0)) + return true; - if ((size_t)snprintf(base,sizeof(base),"%s", - slash) >= sizeof(base)) - return false; + /* .libs/foo.o */ + if ((slash = strrchr(arg,'/'))) + slash++; + else + slash = arg; - sprintf(slash,".libs/%s",base); - dot = strrchr(arg,'.'); + if ((size_t)snprintf(base,sizeof(base),"%s", + slash) >= sizeof(base)) + return false; + + sprintf(slash,".libs/%s",base); + + if (!faccessat(fdcwd,arg,0,0)) + return true; + + /* foo.o requested and neither is present? */ + if (!fpic) { + strcpy(slash,base); + return true; } - strcpy(dot,".o"); + /* .libs/foo.o explicitly requested and is not present? */ + if (!fany) + return true; + + /* use foo.o in place of .libs/foo.o */ + strcpy(slash,base); + + if (faccessat(fdcwd,arg,0,0)) + sprintf(slash,".libs/%s",base); + return true; } @@ -1049,6 +1080,7 @@ static int slbt_exec_link_create_archive( bool fpic, bool fprimary) { + int fdcwd; char ** aarg; char ** parg; char * base; @@ -1084,14 +1116,18 @@ static int slbt_exec_link_create_archive( dctx->cctx->host.ar) >= sizeof(program)) return SLBT_BUFFER_ERROR(dctx); + + /* fdcwd */ + fdcwd = slbt_driver_fdcwd(dctx); + + /* input argument adjustment */ aarg = ectx->altv; *aarg++ = program; *aarg++ = "crs"; *aarg++ = output; - /* input argument adjustment */ for (parg=ectx->cargv; *parg; parg++) - if (slbt_adjust_object_argument(*parg,fpic)) + if (slbt_adjust_object_argument(*parg,fpic,!fpic,fdcwd)) *aarg++ = *parg; *aarg = 0; @@ -1154,6 +1190,7 @@ static int slbt_exec_link_create_library( const char * dsofilename, const char * relfilename) { + int fdcwd; char ** parg; char ** xarg; char cwd [PATH_MAX]; @@ -1168,9 +1205,12 @@ static int slbt_exec_link_create_library( /* placeholders */ slbt_reset_placeholders(ectx); + /* fdcwd */ + fdcwd = slbt_driver_fdcwd(dctx); + /* input argument adjustment */ for (parg=ectx->cargv; *parg; parg++) - slbt_adjust_object_argument(*parg,true); + slbt_adjust_object_argument(*parg,true,false,fdcwd); /* .deps */ if (slbt_exec_link_create_dep_file( @@ -1350,7 +1390,7 @@ static int slbt_exec_link_create_executable( /* input argument adjustment */ for (parg=ectx->cargv; *parg; parg++) - slbt_adjust_object_argument(*parg,fpic); + slbt_adjust_object_argument(*parg,fpic,true,fdcwd); /* linker argument adjustment */ for (parg=ectx->cargv, xarg=ectx->xargv; *parg; parg++, xarg++) |