1 /* Handling of dynamic sring tokens.
2    Copyright (C) 1999-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include "trusted-dirs.h"
20 
21 #ifdef SHARED
22 # define IS_RTLD(l) (l) == &GL(dl_rtld_map)
23 #else
24 # define IS_RTLD(l) 0
25 #endif
26 /* Guess from the number of DSTs the length of the result string.  */
27 #define DL_DST_REQUIRED(l, name, len, cnt) \
28   ({									      \
29     size_t __len = (len);						      \
30     size_t __cnt = (cnt);						      \
31 									      \
32     if (__cnt > 0)							      \
33       {									      \
34 	size_t dst_len;							      \
35 	/* Now we make a guess how many extra characters on top of the	      \
36 	   length of S we need to represent the result.  We know that	      \
37 	   we have CNT replacements.  Each at most can use		      \
38 	     MAX (MAX (strlen (ORIGIN), strlen (_dl_platform)),		      \
39 		  strlen (DL_DST_LIB))					      \
40 	   minus 4 (which is the length of "$LIB").			      \
41 									      \
42 	   First get the origin string if it is not available yet.	      \
43 	   This can only happen for the map of the executable or, when	      \
44 	   auditing, in ld.so.  */					      \
45 	if ((l)->l_origin == NULL)					      \
46 	  {								      \
47 	    assert ((l)->l_name[0] == '\0' || IS_RTLD (l));		      \
48 	    (l)->l_origin = _dl_get_origin ();				      \
49 	    dst_len = ((l)->l_origin && (l)->l_origin != (char *) -1	      \
50 			  ? strlen ((l)->l_origin) : 0);		      \
51 	  }								      \
52 	else								      \
53 	  dst_len = (l)->l_origin == (char *) -1			      \
54 	    ? 0 : strlen ((l)->l_origin);				      \
55 	dst_len = MAX (MAX (dst_len, GLRO(dl_platformlen)),		      \
56 		       strlen (DL_DST_LIB));				      \
57 	if (dst_len > 4)						      \
58 	  __len += __cnt * (dst_len - 4);				      \
59       }									      \
60 									      \
61     __len; })
62