From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 8CB2D3861030 for ; Thu, 8 Oct 2020 23:16:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8CB2D3861030 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 098N2joq057386 for ; Thu, 8 Oct 2020 19:16:16 -0400 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 342btd0pee-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 08 Oct 2020 19:16:16 -0400 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 098N3Bke058624 for ; Thu, 8 Oct 2020 19:16:16 -0400 Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 342btd0pe3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 08 Oct 2020 19:16:16 -0400 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 098NBxp7004200; Thu, 8 Oct 2020 23:16:15 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma04dal.us.ibm.com with ESMTP id 3429hvscsc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 08 Oct 2020 23:16:15 +0000 Received: from b03ledav003.gho.boulder.ibm.com (b03ledav003.gho.boulder.ibm.com [9.17.130.234]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 098NGE0i51708192 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 8 Oct 2020 23:16:14 GMT Received: from b03ledav003.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3A62B6A054; Thu, 8 Oct 2020 23:16:14 +0000 (GMT) Received: from b03ledav003.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A77716A058; Thu, 8 Oct 2020 23:16:13 +0000 (GMT) Received: from li-24c3614c-2adc-11b2-a85c-85f334518bdb.ibm.com (unknown [9.80.194.154]) by b03ledav003.gho.boulder.ibm.com (Postfix) with ESMTPS; Thu, 8 Oct 2020 23:16:13 +0000 (GMT) Date: Thu, 8 Oct 2020 18:16:11 -0500 From: "Paul A. Clarke" To: Florian Weimer Cc: libc-alpha@sourceware.org Subject: Re: [PATCH 16/28] elf: Add glibc-hwcaps support for LD_LIBRARY_PATH Message-ID: <20201008231611.GA44221@li-24c3614c-2adc-11b2-a85c-85f334518bdb.ibm.com> References: <47cb6998ed91f70f122de115b2e03ea5e82e5884.1601569371.git.fweimer@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <47cb6998ed91f70f122de115b2e03ea5e82e5884.1601569371.git.fweimer@redhat.com> User-Agent: Mutt/1.10.1 (2018-07-13) X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687 definitions=2020-10-08_15:2020-10-08, 2020-10-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 mlxlogscore=999 clxscore=1015 bulkscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 phishscore=0 suspectscore=0 mlxscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2010080161 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Oct 2020 23:16:19 -0000 just a couple of nits found while browsing... On Thu, Oct 01, 2020 at 06:33:16PM +0200, Florian Weimer via Libc-alpha wrote: > diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c > index 44dbac099f..4de94759a2 100644 > --- a/elf/dl-hwcaps.c > +++ b/elf/dl-hwcaps.c > @@ -26,20 +26,97 @@ > #include > #include > > +/* This is the result of counting the substrings in a colon-separated > + hwcaps string. */ > +struct count_hwcaps > +{ > + /* Number of substrings. */ > + size_t count; > + > + /* Sum of the individual substring lengths (without separates or separators? > + null terminators). */ > + size_t total_length; > + > + /* Maximum length of an individual substring. */ > + size_t maximum_length; > +}; > + > +/* Update *COUNTS according to the contents of HWCAPS. Skip over > + entries whose bit is not set in MASK. */ > +static void > +count_hwcaps (struct count_hwcaps *counts, const char *hwcaps, > + int32_t bitmask, const char *mask) > +{ > + struct dl_hwcaps_split_masked sp; > + _dl_hwcaps_split_masked_init (&sp, hwcaps, bitmask, mask); > + while (_dl_hwcaps_split_masked (&sp)) > + { > + ++counts->count; > + counts->total_length += sp.split.length; > + if (sp.split.length > counts->maximum_length) > + counts->maximum_length = sp.split.length; > + } > +} > + > +/* State for copy_hwcaps. Must be initialized to point to > + the storage areas for the array and the strings themselves. */ > +struct copy_hwcaps > +{ > + struct r_strlenpair *next_pair; > + char *next_string; > +}; > + > +/* Copy HWCAPS into the string pairs and strings, advancing *TARGET. > + Skip over entries whose bit is not set in MASK. */ > +static void > +copy_hwcaps (struct copy_hwcaps *target, const char *hwcaps, > + int32_t bitmask, const char *mask) > +{ > + struct dl_hwcaps_split_masked sp; > + _dl_hwcaps_split_masked_init (&sp, hwcaps, bitmask, mask); > + while (_dl_hwcaps_split_masked (&sp)) > + { > + target->next_pair->str = target->next_string; > + char *slash = __mempcpy (__mempcpy (target->next_string, > + GLIBC_HWCAPS_PREFIX, > + strlen (GLIBC_HWCAPS_PREFIX)), > + sp.split.segment, sp.split.length); > + *slash = '/'; > + target->next_pair->len > + = strlen (GLIBC_HWCAPS_PREFIX) + sp.split.length + 1; > + ++target->next_pair; > + target->next_string = slash + 1; > + } > +} > + > /* Return an array of useful/necessary hardware capability names. */ > const struct r_strlenpair * > -_dl_important_hwcaps (size_t *sz, size_t *max_capstrlen) > +_dl_important_hwcaps (const char *glibc_hwcaps_prepend, > + const char *glibc_hwcaps_mask, > + size_t *sz, size_t *max_capstrlen) > { > uint64_t hwcap_mask = GET_HWCAP_MASK(); > /* Determine how many important bits are set. */ > uint64_t masked = GLRO(dl_hwcap) & hwcap_mask; > size_t cnt = GLRO (dl_platform) != NULL; > size_t n, m; > - size_t total; > struct r_strlenpair *result; > struct r_strlenpair *rp; > char *cp; > > + /* glibc-hwcaps subdirectories. These are exempted from the power > + set construction below below. */ remove one "below" :-) > + int32_t hwcaps_subdirs_active = _dl_hwcaps_subdirs_active (); > + struct count_hwcaps hwcaps_counts = { 0, }; > + count_hwcaps (&hwcaps_counts, glibc_hwcaps_prepend, -1, NULL); > + count_hwcaps (&hwcaps_counts, _dl_hwcaps_subdirs, hwcaps_subdirs_active, > + glibc_hwcaps_mask); > + > + /* Each hwcaps subdirectory has a GLIBC_HWCAPS_PREFIX string prefix > + and a "/" suffix once stored in the result. */ > + size_t total = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1) > + + hwcaps_counts.total_length); > + > /* Count the number of bits set in the masked value. */ > for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n) > if ((masked & (1ULL << n)) != 0) > diff --git a/elf/dl-hwcaps.h b/elf/dl-hwcaps.h > index b66da59b89..a6453f15f3 100644 > --- a/elf/dl-hwcaps.h > +++ b/elf/dl-hwcaps.h > @@ -28,3 +33,81 @@ > # define GET_HWCAP_MASK() (0) > # endif > #endif > + > +#define GLIBC_HWCAPS_SUBDIRECTORY "glibc-hwcaps" > +#define GLIBC_HWCAPS_PREFIX GLIBC_HWCAPS_SUBDIRECTORY "/" > + > +/* Used by _dl_hwcaps_split below, to split strings at ':' > + separators. */ > +struct dl_hwcaps_split > +{ > + const char *segment; /* Start of the current segment. */ > + size_t length; /* Number of bytes until ':' or NUL. */ > +}; > + > +/* Prepare *S to parse SUBJECT, for future _dl_hwcaps_split calls. If > + SUBJECT is NULL, it is treated as the empty string. */ > +static inline void > +_dl_hwcaps_split_init (struct dl_hwcaps_split *s, const char *subject) > +{ > + s->segment = subject; > + /* The initial call to _dl_hwcaps_split will not skip anything. */ > + s->length = 0; > +} > + > +/* Extract the next non-empty string segment, up to ':' or the null > + terminator. Return true if one more segment was found, or false if > + the end of the string was reached. On success, S->segment is the > + start of the segment found, and S->length is its length. > + (Typically, S->segment[S->length] is not null.) */ > +_Bool _dl_hwcaps_split (struct dl_hwcaps_split *s) attribute_hidden; > + > +/* Similar to dl_hwcaps_split, but with bit-based and name-based > + masking. */ > +struct dl_hwcaps_split_masked > +{ > + struct dl_hwcaps_split split; > + > + /* For used by the iterator implementation. */ > + const char *mask; > + int32_t bitmask; > +}; > + > +/* Prepare *S for iteration with _dl_hwcaps_split_masked. Only HWCAP > + names in SUBJECT whose bit is set in BITMASK and whose ane is in s/ane/name/ ? > + MASK will be returned. SUBJECT must not contain empty HWCAP names. > + If MASK is NULL, no name-based masking is applied. Likewise for > + BITMASK if BITMASK is -1 (infinite number of bits). */ > +static inline void > +_dl_hwcaps_split_masked_init (struct dl_hwcaps_split_masked *s, > + const char *subject, > + int32_t bitmask, const char *mask) > +{ > + _dl_hwcaps_split_init (&s->split, subject); > + s->bitmask = bitmask; > + s->mask = mask; > +} > + > +/* Like _dl_hwcaps_split, but apply masking. */ > +_Bool _dl_hwcaps_split_masked (struct dl_hwcaps_split_masked *s) > + attribute_hidden; > + > +/* Returns true if the colon-separated HWCAP list HWCAPS contains the > + capability NAME (with length NAME_LENGTH). If HWCAPS is NULL, the > + function returns true. */ > +_Bool _dl_hwcaps_contains (const char *hwcaps, const char *name, > + size_t name_length) attribute_hidden; > + > +/* Colon-separated string of glibc-hwcaps subdirectories, without the > + "glibc-hwcaps/" prefix. The most preferred subdirectory needs to > + be listed first. */ > +extern const char _dl_hwcaps_subdirs[] attribute_hidden; > + > +/* Returns a bitmap of active subdirectories in _dl_hwcaps_subdirs. > + Bit 0 (the LSB) corresponds to the first substring in > + _dl_hwcaps_subdirs, bit 1 to the second substring, and so on. > + There is no direct correspondence between HWCAP bitmasks and this > + bitmask. */ > +int32_t _dl_hwcaps_subdirs_active (void) attribute_hidden; > + > +#endif /* _DL_HWCAPS_H */ PC