/[gentoo-alt]/trunk/toolchain-prefix-wrapper/ld/hpuxplugin.c
Gentoo

Contents of /trunk/toolchain-prefix-wrapper/ld/hpuxplugin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1655 - (show annotations) (download) (as text)
Mon Jul 6 14:19:20 2009 UTC (5 years, 2 months ago) by haubi
File MIME type: text/x-csrc
File size: 13702 byte(s)
always filter all default lib- and runpaths added by gcc and ld from
cmdline, re-add gcc-ones always and ld-defaults upon "+b :" only.

1 /*
2 * Copyright 2007-2009 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * Author: Michael Haubenwallner <haubi@gentoo.org>
5 */
6
7 #include <config.h>
8
9 #include "hpuxplugin.h"
10
11 #include <stdlib.h>
12 #include <string.h>
13
14 #if defined(__cplusplus)
15 extern "C" {
16 #else
17 typedef enum { false = 0, true = 1 } bool;
18 #endif
19
20 typedef enum { EnvRpath_No = 0, EnvRpath_First = 1, EnvRpath_Second = 2 } EnvRpathFlag;
21 typedef enum { UseRpath_Concat = 0, UseRpath_First = 1, UseRpath_Last = 2 } UseRpathFlag;
22 typedef enum { LinkMode_ELF = 0, LinkMode_SOM = 1, LinkMode_Compat = 2 } LinkModeType;
23
24 /* HPUX-ld:
25 * ELF: When there is no explicit runpath on the linker commandline (+b runpath),
26 * then all library paths (-L) are recorded as runpath
27 * SOM: Runpath used to be stored on explicit flag (+b runpath) only.
28 * When there is "+b :", then library paths (-L) are recorded as runpath.
29 * We assume "+b :" is set at least, to get our paths searched always.
30 */
31 int hpuxplugin(LdPluginData *data)
32 {
33 int argc = 0;
34 int err;
35 int index, count;
36 bool isIA64;
37 bool is64bit;
38
39 /* ELF settings */
40 bool needLibpathAsRunpath = true;
41 bool needAutoRunpath = false;
42 UseRpathFlag useRpathFlag = UseRpath_Last;
43 bool needCDPflag = false; /* need +cdp linker flag to drop DESTDIR */
44
45 EnvRpathFlag envRpathFlag = EnvRpath_No; /* +s */
46 StringList *tmpArgList = NULL;
47 StringList *userLibpathList = NULL;
48 StringList *runpathList = NULL;
49 StringList *defaultRunpathList = NULL;
50 StringList *sysRunpathList = NULL;
51 StringList *autoRunpathList = NULL;
52 String *newString = NULL;
53 String const *argString;
54 char const *argBuffer;
55 int argBufferLength;
56 char const *portageD = NULL;
57 int portageDlength = 0;
58
59 do { /* dummy loop */
60 err = -1;
61
62 tmpArgList = StringListCreate(NULL, 0, 0);
63 if (tmpArgList == NULL)
64 break;
65
66 userLibpathList = StringListCreate(NULL, 0, 0);
67 if (userLibpathList == NULL)
68 break;
69
70 runpathList = StringListCreate(NULL, 0, 0);
71 if (runpathList == NULL)
72 break;
73
74 defaultRunpathList = StringListCreate(NULL, 0, 0);
75 if (defaultRunpathList == NULL)
76 break;
77
78 sysRunpathList = StringListCreate(NULL, 0, 0);
79 if (sysRunpathList == NULL)
80 break;
81
82 autoRunpathList = StringListCreate(NULL, 0, 0);
83 if (autoRunpathList == NULL)
84 break;
85
86 #define STRnLEN(x) (x), strlen((x))
87 argBuffer = StringGetBuffer(data->in->host.triplet);
88 if (strncmp(argBuffer, "ia64", strlen("ia64")) == 0) {
89 isIA64 = true;
90 if (argBuffer[strlen("ia64")] == 'w') {
91 /* ia64w: ELF, 64bit */
92 is64bit = true;
93 if (0
94 /* added by gcc always */
95 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/ccs/lib/hpux64"), NULL) < 0
96 || StringListAppendConcat(sysRunpathList, STRnLEN("/lib/hpux64" ), NULL) < 0
97 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/lib/hpux64" ), NULL) < 0
98 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/ccs/lib" ), NULL) < 0
99 /* added by ld upon "+b :" */
100 || StringListAppendConcat(autoRunpathList, STRnLEN("/usr/lib/hpux64" ), NULL) < 0
101 )
102 break;
103 } else {
104 is64bit = false;
105 if (0
106 /* added by gcc always */
107 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/ccs/lib" ), NULL) < 0
108 /* added by ld upon "+b :" */
109 || StringListAppendConcat(autoRunpathList, STRnLEN("/usr/lib/hpux32"), NULL) < 0
110 )
111 break;
112 }
113 } else
114 if (strncmp(argBuffer, "hppa64", strlen("hppa64")) == 0) {
115 /* hppa64: ELF, 64bit */
116 isIA64 = false;
117 is64bit = true;
118 if (0
119 /* added by gcc always */
120 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/ccs/lib/pa20_64" ), NULL) < 0
121 || StringListAppendConcat(sysRunpathList, STRnLEN("/opt/langtools/lib/pa20_64"), NULL) < 0
122 || StringListAppendConcat(sysRunpathList, STRnLEN("/lib/pa20_64" ), NULL) < 0
123 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/lib/pa20_64" ), NULL) < 0
124 /* added by ld among "+b :" */
125 || StringListAppendConcat(autoRunpathList, STRnLEN("/usr/lib/pa20_64" ), NULL) < 0
126 || StringListAppendConcat(autoRunpathList, STRnLEN("/usr/ccs/lib/pa20_64" ), NULL) < 0
127 )
128 break;
129 } else {
130 /* hppa: SOM, 32bit */
131 isIA64 = false;
132 is64bit = false;
133 if (0
134 /* added by gcc always */
135 || StringListAppendConcat(sysRunpathList, STRnLEN("/usr/ccs/lib" ), NULL) < 0
136 || StringListAppendConcat(sysRunpathList, STRnLEN("/opt/langtools/lib"), NULL) < 0
137 /* added by ld among "+b :" */
138 )
139 break;
140 }
141
142 if (!isIA64 && is64bit) {
143 /* hppa64 only */
144 for(argc = 1; argc < StringListGetSize(data->in->argList); argc++) {
145 argString = StringListGetString(data->in->argList, argc);
146 argBuffer = StringGetBuffer(argString);
147 if (strcmp(argBuffer, "+concatrpath") == 0) {
148 useRpathFlag = UseRpath_Concat;
149 } else
150 if (strcmp(argBuffer, "+noconcatrpath") == 0) {
151 useRpathFlag = UseRpath_Last;
152 }
153 }
154 }
155
156 if (!isIA64 && !is64bit) {
157 /* hppa only */
158 useRpathFlag = UseRpath_First;
159 /* help elibtoolize with old libtool */
160 portageD = getenv("D");
161 if (portageD != NULL) {
162 portageDlength = strlen(portageD);
163 needCDPflag = true;
164 }
165 }
166
167 for(argc = 1; argc < StringListGetSize(data->in->argList); argc++) {
168 argString = StringListGetString(data->in->argList, argc);
169 argBuffer = StringGetBuffer(argString);
170 argBufferLength = StringGetLength(argString);
171
172 if (strcmp(argBuffer, "+s") == 0) {
173 if (StringListGetSize(runpathList) + StringListGetSize(autoRunpathList))
174 envRpathFlag = EnvRpath_Second;
175 else
176 envRpathFlag = EnvRpath_First;
177 continue;
178 } else
179 if (strcmp(argBuffer, "+nodefaultrpath") == 0) {
180 needLibpathAsRunpath = false;
181 continue;
182 } else
183 if (strcmp(argBuffer, "+defaultrpath") == 0) {
184 /* SOM: Unrecognized argument */
185 if (isIA64 || is64bit) {
186 needLibpathAsRunpath = true;
187 continue;
188 } /* else append to args */
189 } else
190 if (strncmp(argBuffer, "+b", 2) == 0) {
191 /* collect runpath from "+b runpath1:runpathN" */
192 char const *curr, *next;
193
194 argBuffer += 2;
195 argBufferLength -= 2;
196
197 if (*argBuffer == 0 && argc < StringListGetSize(data->in->argList)) {
198 argc++;
199 argString = StringListGetString(data->in->argList, argc);
200 argBuffer = StringGetBuffer(argString);
201 argBufferLength = StringGetLength(argString);
202 }
203
204 needLibpathAsRunpath = false;
205
206 if (useRpathFlag != UseRpath_Concat) {
207 if (StringListGetSize(runpathList) + StringListGetSize(autoRunpathList)) {
208 if (useRpathFlag == UseRpath_First) {
209 continue;
210 }
211 StringListClear(runpathList);
212 StringListClear(autoRunpathList);
213 }
214
215 if (argBufferLength == 1 && argBuffer[0] == ':') {
216 /* "+b:" collects all "-L" paths and LPATH envvar */
217 needLibpathAsRunpath = true;
218 needAutoRunpath = true;
219 continue;
220 }
221 }
222
223 for(curr = next = argBuffer; *next != '\0'; curr = next+1) {
224 for(next = curr; *next != '\0' && *next != ':'; next++);
225
226 if (next - curr <= 1) {
227 /* skip empty path */
228 continue;
229 }
230
231 if (StringListContains(data->in->sysLibpath, curr, next - curr)) {
232 /* sys runpath will be added later */
233 continue;
234 }
235
236 if (StringListContains(runpathList, curr, next - curr)) {
237 /* already recorded user runpath */
238 continue;
239 }
240
241 /* record this path into libpath list */
242 if (StringListAppendConcat(runpathList, curr, next - curr, NULL) < 0)
243 break;
244 }
245
246 /* end "+b" handling */
247 continue;
248 } else
249 if (strncmp(argBuffer, "-L", 2) == 0) {
250 /* drop -L arguments from commandline,
251 * we need to pass them before any libs.
252 * The path list already is collected in userLibpath.
253 */
254 continue;
255 } else
256 if (strncmp(argBuffer, "-R", 2) == 0) {
257 /* extension:
258 * collect additional default runpath from "-R runpath"
259 */
260
261 argBuffer += 2;
262 argBufferLength -= 2;
263
264 if (*argBuffer == 0 && argc < StringListGetSize(data->in->argList)) {
265 argc++;
266 argString = StringListGetString(data->in->argList, argc);
267 argBuffer = StringGetBuffer(argString);
268 argBufferLength = StringGetLength(argString);
269 }
270 if (StringListContains(data->in->sysLibpath, argBuffer, argBufferLength))
271 continue;
272
273 if (StringListAppendConcat(defaultRunpathList, argBuffer, argBufferLength, NULL) < 0)
274 break;
275
276 continue;
277 } else
278 if (strncmp(argBuffer, "+cdp", strlen("+cdp")) == 0) {
279 needCDPflag = false;
280 /* append this flag */
281 }
282
283 /* keep other arguments on commandline */
284 if (StringListAppendString(tmpArgList, argString) < 0)
285 break;
286 }
287 if (argc < StringListGetSize(data->in->argList)) {
288 /* error during argument parsing */
289 break;
290 }
291
292 /* uniq userLibpath, filter hpux system runpath from userLibpath */
293 count = StringListGetSize(data->in->userLibpath);
294 for(index = 0; index < count; ++index) {
295 String const* pathString;
296 char const* pathBuffer;
297 int pathLength;
298 pathString = StringListGetString(data->in->userLibpath, index);
299 pathBuffer = StringGetBuffer(pathString);
300 pathLength = StringGetLength(pathString);
301 if (StringListContains(userLibpathList, pathBuffer, pathLength)
302 || StringListContains(sysRunpathList, pathBuffer, pathLength)
303 || StringListContains(autoRunpathList, pathBuffer, pathLength)
304 )
305 continue;
306 if (StringListAppendConcat(userLibpathList, pathBuffer, pathLength, NULL) < 0)
307 break;
308 }
309 if (index < count)
310 break;
311
312 /*
313 * first, put libpath list (-L) on the commandline
314 */
315 if (StringListAppendListModify(data->out->argList, userLibpathList, 0, -1, "-L", 2, NULL, 0) < 0)
316 break;
317
318 /* also put sys libpath list as libpath (-L) on commandline */
319 if (StringListAppendListModify(data->out->argList, data->in->sysLibpath, 0, -1, "-L", 2, NULL, 0) < 0)
320 break;
321
322 /* finally, put the host system runpath as libpath (-L) on commandline */
323 if (StringListAppendListModify(data->out->argList, sysRunpathList, 0, -1, "-L", 2, NULL, 0) < 0)
324 break;
325
326 /* do we need to use env-runpath first? */
327 if (envRpathFlag == EnvRpath_First
328 && StringListAppendConcat(data->out->argList, "+s", 2, NULL) < 0
329 ) break;
330
331 /*
332 * now put runpath list (from -R, +b) on the commandline
333 */
334
335 /* append "+b" to commandline */
336 if (StringListAppendConcat(data->out->argList, "+b", 2, NULL) < 0)
337 break;
338
339 /* if there is no runpath (+b), use libpath as runpath
340 * if not disabled with "+nodefaultrpath"
341 */
342 if (StringListGetSize(runpathList) == 0
343 && needLibpathAsRunpath == true
344 ) {
345 if (needCDPflag) {
346 count = StringListGetSize(userLibpathList);
347 bool found = false;
348 for(index = 0; index < count; ++index) {
349 String const* pathString;
350 char const* pathBuffer;
351 int pathLength;
352 pathString = StringListGetString(userLibpathList, index);
353 pathBuffer = StringGetBuffer(pathString);
354 pathLength = StringGetLength(pathString);
355 if (strncmp(portageD, pathBuffer, portageDlength) == 0) {
356 found = true;
357 pathBuffer += portageDlength;
358 pathLength -= portageDlength;
359 if (StringListContains(runpathList, pathBuffer, pathLength)
360 || StringListContains(defaultRunpathList, pathBuffer, pathLength)
361 || StringListContains(data->in->sysRunpath, pathBuffer, pathLength)
362 || StringListContains(sysRunpathList, pathBuffer, pathLength)
363 || StringListContains(autoRunpathList, pathBuffer, pathLength)
364 )
365 continue;
366 }
367 if (StringListAppendConcat(runpathList, pathBuffer, pathLength, NULL) < 0)
368 break;
369 }
370 if (index < count)
371 break;
372 if (!found)
373 needCDPflag = false;
374 } else
375 if (StringListAppendList(runpathList, userLibpathList, 0, -1) < 0)
376 break;
377 }
378
379 /* append default runpath list (-R) to runpath list */
380 if (StringListAppendList(runpathList, defaultRunpathList, 0, -1) < 0)
381 break;
382
383 /* append sys libpath list to runpath list */
384 if (StringListAppendList(runpathList, data->in->sysRunpath, 0, -1) < 0)
385 break;
386
387 /* append local sys libpath list to runpath list */
388 if (StringListAppendList(runpathList, sysRunpathList, 0, -1) < 0)
389 break;
390
391 /* append automatic sys libpath list to runpath list */
392 if (needAutoRunpath
393 && StringListAppendList(runpathList, autoRunpathList, 0, -1) < 0
394 )
395 break;
396
397 /* create runpath string: runpath1:runpathN */
398 newString = StringListJoin(runpathList, NULL, 0, ":", 1, NULL, 0);
399 if (newString == NULL)
400 break;
401
402 /* append runpath string to commandline */
403 if (StringListAppendString(data->out->argList, newString) < 0)
404 break;
405
406 /* do we need to use env-runpath second? */
407 if (envRpathFlag == EnvRpath_Second
408 && StringListAppendConcat(data->out->argList, "+s", 2, NULL) < 0
409 ) break;
410
411 /* do we need the "+cdp ${D}:" flag? */
412 if (needCDPflag
413 && (StringListAppendConcat(data->out->argList, STRnLEN("+cdp"), NULL) < 0
414 || StringListAppendConcat(data->out->argList, portageD, portageDlength, ":", 1, NULL) < 0
415 ))
416 break;
417
418 /*
419 * third, put other arguments on commandline
420 */
421 if (StringListAppendList(data->out->argList, tmpArgList, 0, -1) < 0)
422 break;
423
424 err = 0;
425 } while(0); /* end dummy loop */
426
427 newString = StringDestroy(newString);
428 autoRunpathList = StringListDestroy(autoRunpathList);
429 sysRunpathList = StringListDestroy(sysRunpathList);
430 defaultRunpathList = StringListDestroy(defaultRunpathList);
431 runpathList = StringListDestroy(runpathList);
432 userLibpathList = StringListDestroy(userLibpathList);
433 tmpArgList = StringListDestroy(tmpArgList);
434
435 return err;
436 }
437
438 #if defined(__cplusplus)
439 }
440 #endif

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.20