From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk1-x742.google.com (mail-qk1-x742.google.com [IPv6:2607:f8b0:4864:20::742]) by sourceware.org (Postfix) with ESMTPS id 849813857C5C for ; Fri, 16 Oct 2020 14:37:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 849813857C5C Received: by mail-qk1-x742.google.com with SMTP id c2so2069117qkf.10 for ; Fri, 16 Oct 2020 07:37:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:references:autocrypt:subject:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=hC8ZbTOliz6yKYLd8M2tLjAlEJtbKr63LpcCP+Qh7Bk=; b=YShGeOTdqcisDjrUo87Xb5OzfDv4SGEt6n1iRYZXPgRVLpWYVAuG3RJLvh90I9s/x+ p/IaX6XHuPyCMswSYCwnUF+gKNnJaMvhwt7vhBEnQ3gCql2uMrXGhHHl4HHL/35uuCK/ wt7/gdtwbG1wW9OUfCa+BRpfwBaiRwH6UBIHuz1RG+b/3/a9oOGK8TwcUYN9lv4MlnOX 9v51Wk9+N/sXxXOcO5xhGnQGnmsVuVBjAp03WSQMxLnncDTP0TgXwAeAxZeJFHcXlHfQ Eaknv543oiJ9iNJ2uJRlbAnq6AmnqV8O//A3OglIf1nqItZbDV3pVVm79bKjPV/zCrcZ 0CYw== X-Gm-Message-State: AOAM533/JpQCDeXBqCInsZzdXvAff4MKg672ih/ez9Iyal1d69ht+jSg tiPfcO0k5A/B0L4VvbN/CDiaSqY9BR68LQ== X-Google-Smtp-Source: ABdhPJw0cZ7dg4bSTZqBDODnAhLPR80RxRLy26/kUAQxBDwzbFYtlhNCwJ1Dw6sBwT/b05WmdXekCg== X-Received: by 2002:a37:9045:: with SMTP id s66mr4313265qkd.223.1602859061608; Fri, 16 Oct 2020 07:37:41 -0700 (PDT) Received: from [192.168.1.4] ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id n2sm1069009qtr.6.2020.10.16.07.37.40 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 16 Oct 2020 07:37:40 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org References: Autocrypt: addr=adhemerval.zanella@linaro.org; prefer-encrypt=mutual; keydata= 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 Subject: Re: [PATCH 23/28] elf: Unify old and new format cache handling code in ld.so Message-ID: <286692c4-80ef-3115-0980-a5029fe8faa7@linaro.org> Date: Fri, 16 Oct 2020 11:37:38 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, 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: Fri, 16 Oct 2020 14:37:44 -0000 On 01/10/2020 13:34, Florian Weimer via Libc-alpha wrote: > struct file_entry_new starts with the fields of struct file_entry, > so the code can be shared if the size computation is made dynamic. LGTM, with some nits below. Reviewed-by: Adhemerval Zanella > --- > elf/dl-cache.c | 287 +++++++++++++++++++------------------ > sysdeps/generic/dl-cache.h | 17 ++- > 2 files changed, 158 insertions(+), 146 deletions(-) > > diff --git a/elf/dl-cache.c b/elf/dl-cache.c > index 3aa8ed6c13..02c46ffb0c 100644 > --- a/elf/dl-cache.c > +++ b/elf/dl-cache.c > @@ -35,103 +35,141 @@ static struct cache_file *cache; > static struct cache_file_new *cache_new; > static size_t cachesize; > > -/* 1 if cache_data + PTR points into the cache. */ > -#define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size) > - > -#define SEARCH_CACHE(cache) \ > -/* We use binary search since the table is sorted in the cache file. \ > - The first matching entry in the table is returned. \ > - It is important to use the same algorithm as used while generating \ > - the cache file. */ \ > -do \ > - { \ > - left = 0; \ > - right = cache->nlibs - 1; \ > - \ > - while (left <= right) \ > - { \ > - __typeof__ (cache->libs[0].key) key; \ > - \ > - middle = (left + right) / 2; \ > - \ > - key = cache->libs[middle].key; \ > - \ > - /* Make sure string table indices are not bogus before using \ > - them. */ \ > - if (! _dl_cache_verify_ptr (key)) \ > - { \ > - cmpres = 1; \ > - break; \ > - } \ > - \ > - /* Actually compare the entry with the key. */ \ > - cmpres = _dl_cache_libcmp (name, cache_data + key); \ > - if (__glibc_unlikely (cmpres == 0)) \ > - { \ > - /* Found it. LEFT now marks the last entry for which we \ > - know the name is correct. */ \ > - left = middle; \ > - \ > - /* There might be entries with this name before the one we \ > - found. So we have to find the beginning. */ \ > - while (middle > 0) \ > - { \ > - __typeof__ (cache->libs[0].key) key; \ > - \ > - key = cache->libs[middle - 1].key; \ > - /* Make sure string table indices are not bogus before \ > - using them. */ \ > - if (! _dl_cache_verify_ptr (key) \ > - /* Actually compare the entry. */ \ > - || _dl_cache_libcmp (name, cache_data + key) != 0) \ > - break; \ > - --middle; \ > - } \ > - \ > - do \ > - { \ > - int flags; \ > - __typeof__ (cache->libs[0]) *lib = &cache->libs[middle]; \ > - \ > - /* Only perform the name test if necessary. */ \ > - if (middle > left \ > - /* We haven't seen this string so far. Test whether the \ > - index is ok and whether the name matches. Otherwise \ > - we are done. */ \ > - && (! _dl_cache_verify_ptr (lib->key) \ > - || (_dl_cache_libcmp (name, cache_data + lib->key) \ > - != 0))) \ > - break; \ > - \ > - flags = lib->flags; \ > - if (_dl_cache_check_flags (flags) \ > - && _dl_cache_verify_ptr (lib->value)) \ > - { \ > - if (best == NULL || flags == GLRO(dl_correct_cache_id)) \ > - { \ > - HWCAP_CHECK; \ > - best = cache_data + lib->value; \ > - \ > - if (flags == GLRO(dl_correct_cache_id)) \ > - /* We've found an exact match for the shared \ > - object and no general `ELF' release. Stop \ > - searching. */ \ > - break; \ > - } \ > - } \ > - } \ > - while (++middle <= right); \ > - break; \ > - } \ > - \ > - if (cmpres < 0) \ > - left = middle + 1; \ > - else \ > - right = middle - 1; \ > - } \ > - } \ > -while (0) Ok. > +/* True if PTR is a valid string table index. */ > +static inline bool > +_dl_cache_verify_ptr (uint32_t ptr, size_t string_table_size) > +{ > + return ptr < string_table_size; > +} > + Ok. > +/* Compute the address of the element INDEX of the array at LIBS. > + Conceptually, this is &LIBS[INDEX], but use ENTRY_SIZE for the size > + of *LIBS. */ > +static inline const struct file_entry * > +_dl_cache_file_entry (const struct file_entry *libs, size_t entry_size, > + size_t index) > +{ > + return (const void *) libs + index * entry_size; > +} > + Although pointer arithmetic with void *is valid for gcc, I think we should use uintptr_t here. > +/* We use binary search since the table is sorted in the cache file. > + The first matching entry in the table is returned. It is important > + to use the same algorithm as used while generating the cache file. > + STRING_TABLE_SIZE indicates the maximum offset in STRING_TABLE at > + which data is mapped; it is not exact. */ > +static const char * > +search_cache (const char *string_table, uint32_t string_table_size, > + struct file_entry *libs, uint32_t nlibs, uint32_t entry_size, > + const char *name) > +{ > + /* Used by the HWCAP check in the struct file_entry_new case. */ > + uint64_t platform = _dl_string_platform (GLRO (dl_platform)); > + if (platform != (uint64_t) -1) > + platform = 1ULL << platform; Maybe UINT64_C(1) << platform? > + uint64_t hwcap_mask = GET_HWCAP_MASK (); > +#define _DL_HWCAP_TLS_MASK (1LL << 63) Same as before. > + uint64_t hwcap_exclude = ~((GLRO (dl_hwcap) & hwcap_mask) > + | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK); > + > + int left = 0; > + int right = nlibs - 1; > + const char *best = NULL; > + > + while (left <= right) > + { > + int middle = (left + right) / 2; > + uint32_t key = _dl_cache_file_entry (libs, entry_size, middle)->key; > + > + /* Make sure string table indices are not bogus before using > + them. */ > + if (!_dl_cache_verify_ptr (key, string_table_size)) > + return NULL; > > + /* Actually compare the entry with the key. */ > + int cmpres = _dl_cache_libcmp (name, string_table + key); > + if (__glibc_unlikely (cmpres == 0)) > + { > + /* Found it. LEFT now marks the last entry for which we > + know the name is correct. */ > + left = middle; > + > + /* There might be entries with this name before the one we > + found. So we have to find the beginning. */ > + while (middle > 0) > + { > + key = _dl_cache_file_entry (libs, entry_size, middle - 1)->key; > + /* Make sure string table indices are not bogus before > + using them. */ > + if (!_dl_cache_verify_ptr (key, string_table_size) > + /* Actually compare the entry. */ > + || _dl_cache_libcmp (name, string_table + key) != 0) > + break; > + --middle; > + } > + > + do > + { > + int flags; > + const struct file_entry *lib > + = _dl_cache_file_entry (libs, entry_size, middle); > + > + /* Only perform the name test if necessary. */ > + if (middle > left > + /* We haven't seen this string so far. Test whether the > + index is ok and whether the name matches. Otherwise > + we are done. */ > + && (! _dl_cache_verify_ptr (lib->key, string_table_size) > + || (_dl_cache_libcmp (name, string_table + lib->key) > + != 0))) > + break; > + > + flags = lib->flags; > + if (_dl_cache_check_flags (flags) > + && _dl_cache_verify_ptr (lib->value, string_table_size)) > + { > + if (best == NULL || flags == GLRO (dl_correct_cache_id)) > + { > + if (entry_size >= sizeof (struct file_entry_new)) > + { > + /* The entry is large enough to include > + HWCAP data. Check it. */ > + struct file_entry_new *libnew > + = (struct file_entry_new *) lib; > + > + if (libnew->hwcap & hwcap_exclude) > + continue; > + if (GLRO (dl_osversion) > + && libnew->osversion > GLRO (dl_osversion)) > + continue; > + if (_DL_PLATFORMS_COUNT > + && (libnew->hwcap & _DL_HWCAP_PLATFORM) != 0 > + && ((libnew->hwcap & _DL_HWCAP_PLATFORM) > + != platform)) > + continue; > + } Ok, this is HWCAP_CHECK expanded. > + > + best = string_table + lib->value; > + > + if (flags == GLRO (dl_correct_cache_id)) > + /* We've found an exact match for the shared > + object and no general `ELF' release. Stop Should we replace the grave accent with apostrophe in this case? > + searching. */ > + break; > + } > + } > + } > + while (++middle <= right); > + break; > + } > + > + if (cmpres < 0) > + left = middle + 1; > + else > + right = middle - 1; > + } > + > + return best; > +} > > int > _dl_cache_libcmp (const char *p1, const char *p2) Ok. > @@ -182,12 +220,6 @@ _dl_cache_libcmp (const char *p1, const char *p2) > char * > _dl_load_cache_lookup (const char *name) > { > - int left, right, middle; > - int cmpres; > - const char *cache_data; > - uint32_t cache_data_size; > - const char *best; > - > /* Print a message if the loading of libs is traced. */ > if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) > _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE); Ok. > @@ -265,51 +297,22 @@ _dl_load_cache_lookup (const char *name) > /* Previously looked for the cache file and didn't find it. */ > return NULL; > > - best = NULL; > - > + const char *best; > if (cache_new != (void *) -1) > { > - uint64_t platform; > - > - /* This is where the strings start. */ > - cache_data = (const char *) cache_new; > - > - /* Now we can compute how large the string table is. */ > - cache_data_size = (const char *) cache + cachesize - cache_data; > - > - platform = _dl_string_platform (GLRO(dl_platform)); > - if (platform != (uint64_t) -1) > - platform = 1ULL << platform; > - > - uint64_t hwcap_mask = GET_HWCAP_MASK(); > - > -#define _DL_HWCAP_TLS_MASK (1LL << 63) > - uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & hwcap_mask) > - | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK); > - > - /* Only accept hwcap if it's for the right platform. */ > -#define HWCAP_CHECK \ > - if (lib->hwcap & hwcap_exclude) \ > - continue; \ > - if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion)) \ > - continue; \ > - if (_DL_PLATFORMS_COUNT \ > - && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0 \ > - && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform) \ > - continue > - SEARCH_CACHE (cache_new); > + const char *string_table = (const char *) cache_new; > + best = search_cache (string_table, cachesize, > + &cache_new->libs[0].entry, cache_new->nlibs, > + sizeof (cache_new->libs[0]), name); > } Ok. > else > { > - /* This is where the strings start. */ > - cache_data = (const char *) &cache->libs[cache->nlibs]; > - > - /* Now we can compute how large the string table is. */ > - cache_data_size = (const char *) cache + cachesize - cache_data; > - > -#undef HWCAP_CHECK > -#define HWCAP_CHECK do {} while (0) > - SEARCH_CACHE (cache); > + const char *string_table = (const char *) &cache->libs[cache->nlibs]; > + uint32_t string_table_size > + = (const char *) cache + cachesize - string_table; > + best = search_cache (string_table, string_table_size, > + &cache->libs[0], cache->nlibs, > + sizeof (cache->libs[0]), name); > } > > /* Print our result if wanted. */ Ok. > diff --git a/sysdeps/generic/dl-cache.h b/sysdeps/generic/dl-cache.h > index b154740da9..fec209509d 100644 > --- a/sysdeps/generic/dl-cache.h > +++ b/sysdeps/generic/dl-cache.h > @@ -66,8 +66,8 @@ > */ > struct file_entry > { > - int flags; /* This is 1 for an ELF library. */ > - unsigned int key, value; /* String table indices. */ > + int32_t flags; /* This is 1 for an ELF library. */ > + uint32_t key, value; /* String table indices. */ > }; > Ok, although not sure if our code guidelines allows multiple fields in the same line. > struct cache_file > @@ -84,8 +84,17 @@ struct cache_file > > struct file_entry_new > { > - int32_t flags; /* This is 1 for an ELF library. */ > - uint32_t key, value; /* String table indices. */ > + union > + { > + /* Fields shared with struct file_entry. */ > + struct file_entry entry; > + /* Also expose these fields directly. */ > + struct > + { > + int32_t flags; /* This is 1 for an ELF library. */ > + uint32_t key, value; /* String table indices. */ > + }; > + }; > uint32_t osversion; /* Required OS version. */ > uint64_t hwcap; /* Hwcap entry. */ > }; > Ok.