Index: binutils-config/files/ldwrapper-1.2.c =================================================================== --- binutils-config/files/ldwrapper-1.2.c (revision 5558) +++ binutils-config/files/ldwrapper-1.2.c (working copy) @@ -411,6 +411,11 @@ if (!newargv) wrapper_exit("%s wrapper: out of memory\n", argv[0]); +#if defined(PLUGIN) + extern char **PLUGIN(char **); + newargv = PLUGIN(newargv); +#endif + /* Ok, lets do it one more time ... */ if (execv(data.bin, newargv) < 0) wrapper_exit("Could not run/locate \"%s\" (%s)\n", data.name, data.bin); Index: binutils-config/files/stringutil-0.1.c =================================================================== --- binutils-config/files/stringutil-0.1.c (revision 0) +++ binutils-config/files/stringutil-0.1.c (revision 0) @@ -0,0 +1,281 @@ + +#include "stringutil.h" + +#include +#include + +struct _String { + int length; + int alloced; + char *buffer; +}; + +int StringGetLength(String *string) +{ + if (string == NULL) { + return -1; + } + return string->length; +} + +char *StringGetBuffer(String *string) +{ + if (string == NULL) { + return NULL; + } + return string->buffer; +} + +String *StringDestroy(String *string) +{ + if (string == NULL) { + return NULL; + } + string->length = 0; + string->alloced = 0; + if (string->buffer != NULL) { + free(string->buffer); + string->buffer = NULL; + } + free(string); + return NULL; +} + +String *StringCreate(void) +{ + String *string = (String*)malloc(sizeof(String)); + if (string == NULL) { + return NULL; + } + + string->length = 0; + string->alloced = 0; + string->buffer = NULL; + + return string; +} + +int StringAppend(String *string, char const *start, char const *end) +{ + int length; + + if (start == NULL) { + start = ""; + end = start; + } + if (end != NULL) { + length = end - start; + } else { + length = strlen(start); + } + + if (string->length + length + 1 > string->alloced) { + char *tmp; + +/* align string allocations to 256 */ +#define ALIGNSIZE(x) (((unsigned long)(x) + 0xff) & ~0xff) + + int alloced = ALIGNSIZE(string->length + length + 1); + tmp = (char*)malloc(alloced * sizeof(char)); + if (tmp == NULL) { + return -1; + } + if (string->length > 0) { + memcpy(tmp, string->buffer, string->length); + } + if (string->buffer != NULL) { + free(string->buffer); + } + string->buffer = tmp; + string->alloced = alloced; + } + + memcpy(&string->buffer[string->length], start, length); + string->length += length; + string->buffer[string->length] = '\0'; + + return 0; +} + +int StringAppendString(String *string, String const *that) +{ + if (that == NULL || that->buffer == NULL) { + return 0; + } + return StringAppend(string, &that->buffer[0], &that->buffer[that->length]); +} + +String *StringCreateNew(char const *start, char const *end) +{ + String *string = StringCreate(); + if (string == NULL) { + return NULL; + } + + if (StringAppend(string, start, end) < 0) { + string = StringDestroy(string); + } + + return string; +} + +void StringInject(String *string, char *buf) +{ + if (string->buffer != NULL) { + free(string->buffer); + string->buffer = NULL; + } + + /* occupy ownership of string-buffer */ + string->buffer = buf; + string->length = strlen(buf); + string->alloced = string->length + 1; + + return; +} + +String *StringCreateInject(char *from) +{ + String *string; + if (from == NULL) { + return StringCreateNew(NULL, NULL); + } + + string = StringCreate(); + if (string == NULL) { + return NULL; + } + + StringInject(string, from); + + return string; +} + +char *StringDegenerate(String *string) +{ + /* transfer ownership of stored buffer to caller */ + char *str = string->buffer; + string->buffer = NULL; + string->alloced = 0; + string->length = 0; + return str; +} + +int StringCompare(String *string, char const *start, char const *end) +{ + int rv = 0; + int length = -1; + if (start == NULL) { + start = ""; + end = NULL; + length = 0; + } + if (end != NULL) { + length = end - start; + } + if (length < 0) { + return strcmp(string->buffer ? string->buffer : "", start); + } + + if (rv == 0) rv = length - string->length; + if (rv == 0) rv = strncmp(string->buffer ? string->buffer : "", start, length); + return 0; +} + +struct _StringList { + int size; + int alloced; + String **list; +}; + +int StringListGetSize(StringList *list) +{ + if (list == NULL) { + return -1; + } + return list->size; +} + +String *StringListGetString(StringList *list, int index) +{ + if (list == NULL || list->size <= index || index < 0) { + return NULL; + } + return list->list[index]; +} + +StringList *StringListDestroy(StringList *list) +{ + if (list == NULL) { + return NULL; + } + + while(list->size > 0) { + list->size --; + list->list[list->size] = StringDestroy(list->list[list->size]); + } + if (list->list != NULL) { + free(list->list); + list->list = NULL; + } + list->alloced = 0; + + free(list); + return NULL; +} + +int StringListAppend(StringList *list, String *string) +{ + if (string == NULL) { + return 0; + } + if (list->size == list->alloced) { + /* always have trailing NULL string in list */ + String **tmp = (String**)realloc(list->list, (list->alloced + 5) * sizeof(char*)); + if (tmp == NULL) { + return -1; + } + list->list = tmp; + list->alloced += 5; + } + list->list[list->size++] = string; + return 0; +} + +StringList *StringListCreate(String *initial) +{ + StringList *list = (StringList*)malloc(sizeof(StringList)); + if (list == NULL) { + return NULL; + } + list->size = 0; + list->alloced = 0; + list->list = NULL; + + if (StringListAppend(list, initial) < 0) { + list = StringListDestroy(list); + } + return list; +} + +char **StringListToArgv(StringList *list) +{ + char **argv; + if (list == NULL) { + return NULL; + } + argv = (char**)malloc((list->size + 1) * sizeof(char*)); + if (argv == NULL) { + return NULL; + } + + argv[list->size] = NULL; + while(list->size > 0) { + list->size --; + argv[list->size] = StringDegenerate(list->list[list->size]); + list->list[list->size] = StringDestroy(list->list[list->size]); + } + + return argv; +} + Index: binutils-config/files/stringutil-0.1.h =================================================================== --- binutils-config/files/stringutil-0.1.h (revision 0) +++ binutils-config/files/stringutil-0.1.h (revision 0) @@ -0,0 +1,35 @@ +#if !defined(_STRINGUTIL_H_) +#define _STRINGUTIL_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct _String String; + +extern int StringGetLength(String *string); +extern char *StringGetBuffer(String *string); +extern String *StringDestroy(String *string); +extern String *StringCreate(void); +extern int StringAppend(String *string, char const *start, char const *end); +extern int StringAppendString(String *string, String const *that); +extern String *StringCreateNew(char const *start, char const *end); +extern void StringInject(String *string, char *buf); +extern String *StringCreateInject(char *from); +extern char *StringDegenerate(String *string); +extern int StringCompare(String *string, char const *start, char const *end); + +typedef struct _StringList StringList; + +extern int StringListGetSize(StringList *list); +extern String *StringListGetString(StringList *list, int index); +extern StringList *StringListDestroy(StringList *list); +extern int StringListAppend(StringList *list, String *string); +extern StringList *StringListCreate(String *initial); +extern char **StringListToArgv(StringList *list); + +#if defined(__cplusplus) +} +#endif + +#endif /* _STRINGUTIL_H_ */ Index: binutils-config/files/aixplugin-0.1.c =================================================================== --- binutils-config/files/aixplugin-0.1.c (revision 0) +++ binutils-config/files/aixplugin-0.1.c (revision 0) @@ -0,0 +1,168 @@ +#include "stringutil.h" +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct _PathList { + int length; + char const *buffer; +} PathList; + +static PathList const *getDefaultLibpath(void) +{ + static PathList const defaultLibpaths[] = { +#define INIT(x) (sizeof(x) - 1), x + { INIT("@GENTOO_PORTAGE_EPREFIX@/usr/lib"), }, + { INIT("@GENTOO_PORTAGE_EPREFIX@/lib"), }, + { INIT("/usr/lib"), }, + { INIT("/lib"), }, + { 0, NULL }, + }; + + return defaultLibpaths; +} + +char **aixplugin(char **argv) +{ + char **newArgv = NULL; + int argc = 0; + int i; + int haveLibpath = 0; + StringList *newArgList = NULL; + StringList *trashArgList = NULL; + StringList *libpathList = NULL; + String *tmpString = NULL; + PathList const *defaultLibpath; + + do { /* dummy loop */ + + newArgList = StringListCreate(NULL); + if (newArgList == NULL) break; + + libpathList = StringListCreate(NULL); + if (libpathList == NULL) break; + + trashArgList = StringListCreate(NULL); + if (trashArgList == NULL) break; + + /* keep argv[0] */ + tmpString = StringCreateInject(argv[0]); + if (tmpString == NULL) break; + if (StringListAppend(newArgList, tmpString) < 0) break; + tmpString = NULL; + + /* always pass "-brtl" */ + tmpString = StringCreateNew("-brtl", NULL); + if (tmpString == NULL) break; + if (StringListAppend(newArgList, tmpString) < 0) break; + tmpString = NULL; + + for(argc = 1; argv[argc] != NULL; argc++) { + tmpString = StringCreateInject(argv[argc]); + if (tmpString == NULL) break; + + if (strncmp(argv[argc], "-blibpath:", 10) == 0) { + char *curr, *next; + if (StringListAppend(trashArgList, tmpString) < 0) break; + tmpString = NULL; + + haveLibpath = 1; + for(curr = next = &argv[argc][10]; *next != '\0'; curr = next+1) { + for(next = curr; *next != '\0' && *next != ':'; next++); + + if (next - curr <= 1) { + /* skip empty path */ + continue; + } + + /* search default path list */ + for(defaultLibpath = getDefaultLibpath(); defaultLibpath->length != 0; defaultLibpath++) { + if (defaultLibpath->length == next - curr + && strncmp(defaultLibpath->buffer, curr, defaultLibpath->length) == 0 + ) { + /* found default path */ + break; + } + } + if (defaultLibpath->length != 0) { + /* skip default path */ + continue; + } + + /* search already recorded path list */ + for(i = 0; i < StringListGetSize(libpathList); i++) { + if (StringCompare(StringListGetString(libpathList, i), curr, next) == 0) { + /* found already recorded path */ + break; + } + } + if (i < StringListGetSize(libpathList)) { + /* skip already recorded path */ + continue; + } + + /* record this path into libpath list */ + tmpString = StringCreateNew(curr, next); + if (tmpString == NULL) break; + + if (StringListAppend(libpathList, tmpString) < 0) break; + tmpString = NULL; + } + + /* end "-blibpath:" handling */ + continue; + } + + /* keep other arguments */ + if (StringListAppend(newArgList, tmpString) < 0) break; + tmpString = NULL; + } + if (argv[argc] != NULL) { + /* error during argument parsing */ + break; + } + + if (haveLibpath != 0) { + char const *colon = ":"; + char const *blibpath = "-blibpath"; + + for(defaultLibpath = getDefaultLibpath(); defaultLibpath->length != 0; defaultLibpath++) { + tmpString = StringCreateNew(&defaultLibpath->buffer[0], &defaultLibpath->buffer[defaultLibpath->length]); + if (tmpString == NULL) break; + if (StringListAppend(libpathList, tmpString) < 0) break; + tmpString = NULL; + } + + tmpString = StringCreateNew(&blibpath[0], &blibpath[9]); + if (tmpString == NULL) break; + + for(i = 0; i < StringListGetSize(libpathList); i++) { + if (StringAppend(tmpString, &colon[0], &colon[1]) < 0) break; + if (StringAppendString(tmpString, StringListGetString(libpathList, i)) < 0) break; + } + if (i < StringListGetSize(libpathList)) { + break; + } + + if (StringListAppend(newArgList, tmpString) < 0) break; + tmpString = NULL; + + } + + newArgv = StringListToArgv(newArgList); + } while(0); /* end dummy loop */ + + if (tmpString != NULL) tmpString = StringDestroy(tmpString); + if (libpathList != NULL) libpathList = StringListDestroy(libpathList); + if (trashArgList != NULL) trashArgList = StringListDestroy(trashArgList); + if (newArgList != NULL) newArgList = StringListDestroy(newArgList); + + return newArgv; +} + +#if defined(__cplusplus) +} +#endif Index: binutils-config/binutils-config-1.9-r03.5.ebuild =================================================================== --- binutils-config/binutils-config-1.9-r03.5.ebuild (revision 5558) +++ binutils-config/binutils-config-1.9-r03.5.ebuild (working copy) @@ -18,16 +18,23 @@ RDEPEND=">=sys-apps/findutils-4.2" W_VER=1.2 +STRINGUTIL_VER=0.1 +AIXPLUGIN_VER=0.1 src_unpack() { - cp "${FILESDIR}"/${PN}-${PV} "${T}"/ - cp "${FILESDIR}"/ldwrapper-${W_VER}.c "${T}"/ - eprefixify "${T}"/${PN}-${PV} "${T}"/ldwrapper-${W_VER}.c + cd "${WORKDIR}" + cp "${FILESDIR}"/${PN}-${PV} . + cp "${FILESDIR}"/ldwrapper-${W_VER}.c ./ldwrapper.c + cp "${FILESDIR}"/stringutil-${STRINGUTIL_VER}.c ./stringutil.c + cp "${FILESDIR}"/stringutil-${STRINGUTIL_VER}.h ./stringutil.h + cp "${FILESDIR}"/aixplugin-${AIXPLUGIN_VER}.c ./aixplugin.c + eprefixify ./${PN}-${PV} ./ldwrapper.c ./aixplugin.c + } src_compile() { - cd "${T}" - + cd "${WORKDIR}" + local sources="ldwrapper.c stringutil.c" # based on what system we have do some adjusting of the wrapper's work case ${CHOST} in *-darwin*) @@ -35,7 +42,8 @@ defines="${defines}"' -DNEEDS_EXTRAS -DEXTRA="-search_paths_first"' ;; *-aix*) - defines='-DNEEDS_LIBRARY_INCLUDES -DLIBINC="-L"' + defines='-DNEEDS_LIBRARY_INCLUDES -DLIBINC="-L" -DPLUGIN=aixplugin' + sources="${sources} aixplugin.c" ;; *-solaris*) defines='-DNEEDS_LIBRARY_INCLUDES -DLIBINC="-L"' @@ -50,18 +58,18 @@ ;; esac - echo "$(tc-getCC) -O2 -Wall ${defines} -o ldwrapper \ - ldwrapper-${W_VER}.c" - $(tc-getCC) -O2 -Wall ${defines} -o ldwrapper \ - ldwrapper-${W_VER}.c || die "compile wrapper" + echo "$(tc-getCC) ${CFLAGS:--O2} -Wall ${defines} -o ldwrapper ${sources}" + $(tc-getCC) ${CFLAGS:--O2} -Wall ${defines} -o ldwrapper ${sources} || + die "compile wrapper" } src_install() { - newbin "${T}"/${PN}-${PV} ${PN} || die + cd "${WORKDIR}" + newbin ${PN}-${PV} ${PN} || die doman "${FILESDIR}"/${PN}.8 exeinto /usr/$(get_libdir)/misc - newexe "${T}"/ldwrapper binutils-config || die "install ldwrapper" + newexe ldwrapper binutils-config || die "install ldwrapper" } pkg_postinst() {