|
Packit |
6c4009 |
/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
|
|
Packit |
6c4009 |
Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
|
Packit |
6c4009 |
This file is part of the GNU C Library.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The GNU C Library is free software; you can redistribute it and/or
|
|
Packit |
6c4009 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
6c4009 |
License as published by the Free Software Foundation; either
|
|
Packit |
6c4009 |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The GNU C Library is distributed in the hope that it will be useful,
|
|
Packit |
6c4009 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6c4009 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6c4009 |
Lesser General Public License for more details.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6c4009 |
License along with the GNU C Library; if not, see
|
|
Packit |
6c4009 |
<http://www.gnu.org/licenses/>. */
|
|
Packit |
6c4009 |
|
|
Packit Bot |
adb887 |
#ifndef _DL_CACHE_H
|
|
Packit Bot |
adb887 |
#define _DL_CACHE_H
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
#include <endian.h>
|
|
Packit Bot |
adb887 |
#include <stdbool.h>
|
|
Packit Bot |
27c3f3 |
#include <stddef.h>
|
|
Packit |
6c4009 |
#include <stdint.h>
|
|
Packit Bot |
27c3f3 |
#include <string.h>
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifndef _DL_CACHE_DEFAULT_ID
|
|
Packit |
6c4009 |
# define _DL_CACHE_DEFAULT_ID 3
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifndef _dl_cache_check_flags
|
|
Packit |
6c4009 |
# define _dl_cache_check_flags(flags) \
|
|
Packit |
6c4009 |
((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID)
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifndef LD_SO_CACHE
|
|
Packit |
6c4009 |
# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache"
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifndef add_system_dir
|
|
Packit |
6c4009 |
# define add_system_dir(dir) add_dir (dir)
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#define CACHEMAGIC "ld.so-1.7.0"
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* libc5 and glibc 2.0/2.1 use the same format. For glibc 2.2 another
|
|
Packit |
6c4009 |
format has been added in a compatible way:
|
|
Packit |
6c4009 |
The beginning of the string table is used for the new table:
|
|
Packit |
6c4009 |
old_magic
|
|
Packit |
6c4009 |
nlibs
|
|
Packit |
6c4009 |
libs[0]
|
|
Packit |
6c4009 |
...
|
|
Packit |
6c4009 |
libs[nlibs-1]
|
|
Packit |
6c4009 |
pad, new magic needs to be aligned
|
|
Packit |
6c4009 |
- this is string[0] for the old format
|
|
Packit |
6c4009 |
new magic - this is string[0] for the new format
|
|
Packit |
6c4009 |
newnlibs
|
|
Packit |
6c4009 |
...
|
|
Packit |
6c4009 |
newlibs[0]
|
|
Packit |
6c4009 |
...
|
|
Packit |
6c4009 |
newlibs[newnlibs-1]
|
|
Packit |
6c4009 |
string 1
|
|
Packit |
6c4009 |
string 2
|
|
Packit |
6c4009 |
...
|
|
Packit |
6c4009 |
*/
|
|
Packit |
6c4009 |
struct file_entry
|
|
Packit |
6c4009 |
{
|
|
Packit Bot |
5df1b6 |
int32_t flags; /* This is 1 for an ELF library. */
|
|
Packit Bot |
5df1b6 |
uint32_t key, value; /* String table indices. */
|
|
Packit |
6c4009 |
};
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
struct cache_file
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
char magic[sizeof CACHEMAGIC - 1];
|
|
Packit |
6c4009 |
unsigned int nlibs;
|
|
Packit |
6c4009 |
struct file_entry libs[0];
|
|
Packit |
6c4009 |
};
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#define CACHEMAGIC_NEW "glibc-ld.so.cache"
|
|
Packit |
6c4009 |
#define CACHE_VERSION "1.1"
|
|
Packit |
6c4009 |
#define CACHEMAGIC_VERSION_NEW CACHEMAGIC_NEW CACHE_VERSION
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
struct file_entry_new
|
|
Packit |
6c4009 |
{
|
|
Packit Bot |
5df1b6 |
union
|
|
Packit Bot |
5df1b6 |
{
|
|
Packit Bot |
5df1b6 |
/* Fields shared with struct file_entry. */
|
|
Packit Bot |
5df1b6 |
struct file_entry entry;
|
|
Packit Bot |
5df1b6 |
/* Also expose these fields directly. */
|
|
Packit Bot |
5df1b6 |
struct
|
|
Packit Bot |
5df1b6 |
{
|
|
Packit Bot |
5df1b6 |
int32_t flags; /* This is 1 for an ELF library. */
|
|
Packit Bot |
5df1b6 |
uint32_t key, value; /* String table indices. */
|
|
Packit Bot |
5df1b6 |
};
|
|
Packit Bot |
5df1b6 |
};
|
|
Packit |
6c4009 |
uint32_t osversion; /* Required OS version. */
|
|
Packit |
6c4009 |
uint64_t hwcap; /* Hwcap entry. */
|
|
Packit |
6c4009 |
};
|
|
Packit |
6c4009 |
|
|
Packit Bot |
9798e1 |
/* This bit in the hwcap field of struct file_entry_new indicates that
|
|
Packit Bot |
9798e1 |
the lower 32 bits contain an index into the
|
|
Packit Bot |
9798e1 |
cache_extension_tag_glibc_hwcaps section. Older glibc versions do
|
|
Packit Bot |
9798e1 |
not know about this HWCAP bit, so they will ignore these
|
|
Packit Bot |
9798e1 |
entries. */
|
|
Packit Bot |
9798e1 |
#define DL_CACHE_HWCAP_EXTENSION (1ULL << 62)
|
|
Packit Bot |
9798e1 |
|
|
Packit Bot |
9798e1 |
/* Return true if the ENTRY->hwcap value indicates that
|
|
Packit Bot |
9798e1 |
DL_CACHE_HWCAP_EXTENSION is used. */
|
|
Packit Bot |
9798e1 |
static inline bool
|
|
Packit Bot |
9798e1 |
dl_cache_hwcap_extension (struct file_entry_new *entry)
|
|
Packit Bot |
9798e1 |
{
|
|
Packit Bot |
9798e1 |
/* If DL_CACHE_HWCAP_EXTENSION is set, but other bits as well, this
|
|
Packit Bot |
9798e1 |
is a different kind of extension. */
|
|
Packit Bot |
9798e1 |
return (entry->hwcap >> 32) == (DL_CACHE_HWCAP_EXTENSION >> 32);
|
|
Packit Bot |
9798e1 |
}
|
|
Packit Bot |
9798e1 |
|
|
Packit Bot |
adb887 |
/* See flags member of struct cache_file_new below. */
|
|
Packit Bot |
adb887 |
enum
|
|
Packit Bot |
adb887 |
{
|
|
Packit Bot |
adb887 |
/* No endianness information available. An old ldconfig version
|
|
Packit Bot |
adb887 |
without endianness support wrote the file. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_unset = 0,
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Cache is invalid and should be ignored. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_invalid = 1,
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Cache format is little endian. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_little = 2,
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Cache format is big endian. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_big = 3,
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Bit mask to extract the cache_file_new_flags_endian_*
|
|
Packit Bot |
adb887 |
values. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_mask = 3,
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Expected value of the endian bits in the flags member for the
|
|
Packit Bot |
adb887 |
current architecture. */
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_current
|
|
Packit Bot |
adb887 |
= (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
Packit Bot |
adb887 |
? cache_file_new_flags_endian_little
|
|
Packit Bot |
adb887 |
: cache_file_new_flags_endian_big),
|
|
Packit Bot |
adb887 |
};
|
|
Packit Bot |
adb887 |
|
|
Packit |
6c4009 |
struct cache_file_new
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
char magic[sizeof CACHEMAGIC_NEW - 1];
|
|
Packit |
6c4009 |
char version[sizeof CACHE_VERSION - 1];
|
|
Packit |
6c4009 |
uint32_t nlibs; /* Number of entries. */
|
|
Packit |
6c4009 |
uint32_t len_strings; /* Size of string table. */
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* flags & cache_file_new_flags_endian_mask is one of the values
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_unset, cache_file_new_flags_endian_invalid,
|
|
Packit Bot |
adb887 |
cache_file_new_flags_endian_little, cache_file_new_flags_endian_big.
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
The remaining bits are unused and should be generated as zero and
|
|
Packit Bot |
adb887 |
ignored by readers. */
|
|
Packit Bot |
adb887 |
uint8_t flags;
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
uint8_t padding_unsed[3]; /* Not used, for future extensions. */
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
27c3f3 |
/* File offset of the extension directory. See struct
|
|
Packit Bot |
27c3f3 |
cache_extension below. Must be a multiple of four. */
|
|
Packit Bot |
27c3f3 |
uint32_t extension_offset;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
uint32_t unused[3]; /* Leave space for future extensions
|
|
Packit |
6c4009 |
and align to 8 byte boundary. */
|
|
Packit |
6c4009 |
struct file_entry_new libs[0]; /* Entries describing libraries. */
|
|
Packit |
6c4009 |
/* After this the string table of size len_strings is found. */
|
|
Packit |
6c4009 |
};
|
|
Packit Bot |
adb887 |
_Static_assert (sizeof (struct cache_file_new) == 48,
|
|
Packit Bot |
adb887 |
"size of struct cache_file_new");
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
/* Returns false if *CACHE has the wrong endianness for this
|
|
Packit Bot |
adb887 |
architecture, and true if the endianness matches (or is
|
|
Packit Bot |
adb887 |
unknown). */
|
|
Packit Bot |
adb887 |
static inline bool
|
|
Packit Bot |
adb887 |
cache_file_new_matches_endian (const struct cache_file_new *cache)
|
|
Packit Bot |
adb887 |
{
|
|
Packit Bot |
adb887 |
/* A zero value for cache->flags means that no endianness
|
|
Packit Bot |
adb887 |
information is available. */
|
|
Packit Bot |
adb887 |
return cache->flags == 0
|
|
Packit Bot |
adb887 |
|| ((cache->flags & cache_file_new_flags_endian_big)
|
|
Packit Bot |
adb887 |
== cache_file_new_flags_endian_current);
|
|
Packit Bot |
adb887 |
}
|
|
Packit Bot |
adb887 |
|
|
Packit Service |
138d0c |
|
|
Packit Bot |
27c3f3 |
/* Randomly chosen magic value, which allows for additional
|
|
Packit Bot |
27c3f3 |
consistency verification. */
|
|
Packit Bot |
27c3f3 |
enum { cache_extension_magic = (uint32_t) -358342284 };
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Tag values for different kinds of extension sections. Similar to
|
|
Packit Bot |
27c3f3 |
SHT_* constants. */
|
|
Packit Bot |
27c3f3 |
enum cache_extension_tag
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
/* Array of bytes containing the glibc version that generated this
|
|
Packit Bot |
27c3f3 |
cache file. */
|
|
Packit Bot |
27c3f3 |
cache_extension_tag_generator,
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
9798e1 |
/* glibc-hwcaps subdirectory information. An array of uint32_t
|
|
Packit Bot |
9798e1 |
values, which are indices into the string table. The strings
|
|
Packit Bot |
9798e1 |
are sorted lexicographically (according to strcmp). The extra
|
|
Packit Bot |
9798e1 |
level of indirection (instead of using string table indices
|
|
Packit Bot |
9798e1 |
directly) allows the dynamic loader to compute the preference
|
|
Packit Bot |
9798e1 |
order of the hwcaps names more efficiently.
|
|
Packit Bot |
9798e1 |
|
|
Packit Bot |
9798e1 |
For this section, 4-byte alignment is required, and the section
|
|
Packit Bot |
9798e1 |
size must be a multiple of 4. */
|
|
Packit Bot |
9798e1 |
cache_extension_tag_glibc_hwcaps,
|
|
Packit Bot |
9798e1 |
|
|
Packit Bot |
27c3f3 |
/* Total number of known cache extension tags. */
|
|
Packit Bot |
27c3f3 |
cache_extension_count
|
|
Packit Bot |
27c3f3 |
};
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Element in the array following struct cache_extension. Similar to
|
|
Packit Bot |
27c3f3 |
an ELF section header. */
|
|
Packit Bot |
27c3f3 |
struct cache_extension_section
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
/* Type of the extension section. A enum cache_extension_tag value. */
|
|
Packit Bot |
27c3f3 |
uint32_t tag;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Extension-specific flags. Currently generated as zero. */
|
|
Packit Bot |
27c3f3 |
uint32_t flags;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Offset from the start of the file for the data in this extension
|
|
Packit Bot |
27c3f3 |
section. Specific extensions can have alignment constraints. */
|
|
Packit Bot |
27c3f3 |
uint32_t offset;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Length in bytes of the extension data. Specific extensions may
|
|
Packit Bot |
27c3f3 |
have size requirements. */
|
|
Packit Bot |
27c3f3 |
uint32_t size;
|
|
Packit Bot |
27c3f3 |
};
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* The extension directory in the cache. An array of struct
|
|
Packit Bot |
27c3f3 |
cache_extension_section entries. */
|
|
Packit Bot |
27c3f3 |
struct cache_extension
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
uint32_t magic; /* Always cache_extension_magic. */
|
|
Packit Bot |
27c3f3 |
uint32_t count; /* Number of following entries. */
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* count section descriptors of type struct cache_extension_section
|
|
Packit Bot |
27c3f3 |
follow. */
|
|
Packit Bot |
27c3f3 |
struct cache_extension_section sections[];
|
|
Packit Bot |
27c3f3 |
};
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* A relocated version of struct cache_extension_section. */
|
|
Packit Bot |
27c3f3 |
struct cache_extension_loaded
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
/* Address and size of this extension section. base is NULL if the
|
|
Packit Bot |
27c3f3 |
section is missing from the file. */
|
|
Packit Bot |
27c3f3 |
const void *base;
|
|
Packit Bot |
27c3f3 |
size_t size;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* Flags from struct cache_extension_section. */
|
|
Packit Bot |
27c3f3 |
uint32_t flags;
|
|
Packit Bot |
27c3f3 |
};
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
/* All supported extension sections, relocated. Filled in by
|
|
Packit Bot |
27c3f3 |
cache_extension_load below. */
|
|
Packit Bot |
27c3f3 |
struct cache_extension_all_loaded
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
struct cache_extension_loaded sections[cache_extension_count];
|
|
Packit Bot |
27c3f3 |
};
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
9798e1 |
/* Performs basic data validation based on section tag, and removes
|
|
Packit Bot |
9798e1 |
the sections which are invalid. */
|
|
Packit Bot |
9798e1 |
static void
|
|
Packit Bot |
9798e1 |
cache_extension_verify (struct cache_extension_all_loaded *loaded)
|
|
Packit Bot |
9798e1 |
{
|
|
Packit Bot |
9798e1 |
{
|
|
Packit Bot |
9798e1 |
/* Section must not be empty, it must be aligned at 4 bytes, and
|
|
Packit Bot |
9798e1 |
the size must be a multiple of 4. */
|
|
Packit Bot |
9798e1 |
struct cache_extension_loaded *hwcaps
|
|
Packit Bot |
9798e1 |
= &loaded->sections[cache_extension_tag_glibc_hwcaps];
|
|
Packit Bot |
9798e1 |
if (hwcaps->size == 0
|
|
Packit Bot |
9798e1 |
|| ((uintptr_t) hwcaps->base % 4) != 0
|
|
Packit Bot |
9798e1 |
|| (hwcaps->size % 4) != 0)
|
|
Packit Bot |
9798e1 |
{
|
|
Packit Bot |
9798e1 |
hwcaps->base = NULL;
|
|
Packit Bot |
9798e1 |
hwcaps->size = 0;
|
|
Packit Bot |
9798e1 |
hwcaps->flags = 0;
|
|
Packit Bot |
9798e1 |
}
|
|
Packit Bot |
9798e1 |
}
|
|
Packit Bot |
9798e1 |
}
|
|
Packit Bot |
9798e1 |
|
|
Packit Bot |
27c3f3 |
static bool __attribute__ ((unused))
|
|
Packit Bot |
27c3f3 |
cache_extension_load (const struct cache_file_new *cache,
|
|
Packit Bot |
27c3f3 |
const void *file_base, size_t file_size,
|
|
Packit Bot |
27c3f3 |
struct cache_extension_all_loaded *loaded)
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
memset (loaded, 0, sizeof (*loaded));
|
|
Packit Bot |
27c3f3 |
if (cache->extension_offset == 0)
|
|
Packit Bot |
27c3f3 |
/* No extensions present. This is not a format error. */
|
|
Packit Bot |
27c3f3 |
return true;
|
|
Packit Bot |
27c3f3 |
if ((cache->extension_offset % 4) != 0)
|
|
Packit Bot |
27c3f3 |
/* Extension offset is misaligned. */
|
|
Packit Bot |
27c3f3 |
return false;
|
|
Packit Bot |
27c3f3 |
size_t size_tmp;
|
|
Packit Bot |
27c3f3 |
if (__builtin_add_overflow (cache->extension_offset,
|
|
Packit Bot |
27c3f3 |
sizeof (struct cache_extension), &size_tmp)
|
|
Packit Bot |
27c3f3 |
|| size_tmp > file_size)
|
|
Packit Bot |
27c3f3 |
/* Extension extends beyond the end of the file. */
|
|
Packit Bot |
27c3f3 |
return false;
|
|
Packit Bot |
27c3f3 |
const struct cache_extension *ext = file_base + cache->extension_offset;
|
|
Packit Bot |
27c3f3 |
if (ext->magic != cache_extension_magic)
|
|
Packit Bot |
27c3f3 |
return false;
|
|
Packit Bot |
27c3f3 |
if (__builtin_mul_overflow (ext->count,
|
|
Packit Bot |
27c3f3 |
sizeof (struct cache_extension_section),
|
|
Packit Bot |
27c3f3 |
&size_tmp)
|
|
Packit Bot |
27c3f3 |
|| __builtin_add_overflow (cache->extension_offset
|
|
Packit Bot |
27c3f3 |
+ sizeof (struct cache_extension), size_tmp,
|
|
Packit Bot |
27c3f3 |
&size_tmp)
|
|
Packit Bot |
27c3f3 |
|| size_tmp > file_size)
|
|
Packit Bot |
27c3f3 |
/* Extension array extends beyond the end of the file. */
|
|
Packit Bot |
27c3f3 |
return false;
|
|
Packit Bot |
27c3f3 |
for (uint32_t i = 0; i < ext->count; ++i)
|
|
Packit Bot |
27c3f3 |
{
|
|
Packit Bot |
27c3f3 |
if (__builtin_add_overflow (ext->sections[i].offset,
|
|
Packit Bot |
27c3f3 |
ext->sections[i].size, &size_tmp)
|
|
Packit Bot |
27c3f3 |
|| size_tmp > file_size)
|
|
Packit Bot |
27c3f3 |
/* Extension data extends beyond the end of the file. */
|
|
Packit Bot |
27c3f3 |
return false;
|
|
Packit Bot |
27c3f3 |
|
|
Packit Bot |
27c3f3 |
uint32_t tag = ext->sections[i].tag;
|
|
Packit Bot |
27c3f3 |
if (tag >= cache_extension_count)
|
|
Packit Bot |
27c3f3 |
/* Tag is out of range and unrecognized. */
|
|
Packit Bot |
27c3f3 |
continue;
|
|
Packit Bot |
27c3f3 |
loaded->sections[tag].base = file_base + ext->sections[i].offset;
|
|
Packit Bot |
27c3f3 |
loaded->sections[tag].size = ext->sections[i].size;
|
|
Packit Bot |
27c3f3 |
loaded->sections[tag].flags = ext->sections[i].flags;
|
|
Packit Bot |
27c3f3 |
}
|
|
Packit Bot |
9798e1 |
cache_extension_verify (loaded);
|
|
Packit Bot |
27c3f3 |
return true;
|
|
Packit Bot |
27c3f3 |
}
|
|
Packit Bot |
27c3f3 |
|
|
Packit |
6c4009 |
/* Used to align cache_file_new. */
|
|
Packit |
6c4009 |
#define ALIGN_CACHE(addr) \
|
|
Packit |
6c4009 |
(((addr) + __alignof__ (struct cache_file_new) -1) \
|
|
Packit |
6c4009 |
& (~(__alignof__ (struct cache_file_new) - 1)))
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
extern int _dl_cache_libcmp (const char *p1, const char *p2) attribute_hidden;
|
|
Packit Bot |
adb887 |
|
|
Packit Bot |
adb887 |
#endif /* _DL_CACHE_H */
|