aboutsummaryrefslogtreecommitdiff
path: root/elf/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/cache.c')
-rw-r--r--elf/cache.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/elf/cache.c b/elf/cache.c
index 11ce4ad..c01d302 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -146,6 +146,7 @@ struct cache_entry
struct stringtable_entry *path; /* Path to find library. */
int flags; /* Flags to indicate kind of library. */
unsigned int osversion; /* Required OS version. */
+ unsigned int isa_level; /* Required ISA level. */
uint64_t hwcap; /* Important hardware capabilities. */
int bits_hwcap; /* Number of bits set in hwcap. */
@@ -549,6 +550,19 @@ write_extensions (int fd, uint32_t str_offset,
free (ext);
}
+/* Compute the hwcap value from ENTRY. */
+static inline uint64_t
+compute_hwcap_value (struct cache_entry *entry)
+{
+ if (entry->isa_level > DL_CACHE_HWCAP_ISA_LEVEL_MASK)
+ error (EXIT_FAILURE, 0, _("%s: ISA level is too high (%d > %d)"),
+ entry->path->string, entry->isa_level,
+ DL_CACHE_HWCAP_ISA_LEVEL_MASK);
+ return (DL_CACHE_HWCAP_EXTENSION
+ | (((uint64_t) entry->isa_level) << 32)
+ | entry->hwcaps->section_index);
+}
+
/* Save the contents of the cache. */
void
save_cache (const char *cache_name)
@@ -662,7 +676,7 @@ save_cache (const char *cache_name)
file_entries_new->libs[idx_new].hwcap = entry->hwcap;
else
file_entries_new->libs[idx_new].hwcap
- = DL_CACHE_HWCAP_EXTENSION | entry->hwcaps->section_index;
+ = compute_hwcap_value (entry);
file_entries_new->libs[idx_new].key
= str_offset + entry->lib->offset;
file_entries_new->libs[idx_new].value
@@ -777,7 +791,8 @@ save_cache (const char *cache_name)
/* Add one library to the cache. */
void
add_to_cache (const char *path, const char *filename, const char *soname,
- int flags, unsigned int osversion, uint64_t hwcap,
+ int flags, unsigned int osversion,
+ unsigned int isa_level, uint64_t hwcap,
struct glibc_hwcaps_subdirectory *hwcaps)
{
struct cache_entry *new_entry = xmalloc (sizeof (*new_entry));
@@ -795,6 +810,7 @@ add_to_cache (const char *path, const char *filename, const char *soname,
new_entry->path = path_interned;
new_entry->flags = flags;
new_entry->osversion = osversion;
+ new_entry->isa_level = isa_level;
new_entry->hwcap = hwcap;
new_entry->hwcaps = hwcaps;
new_entry->bits_hwcap = 0;
@@ -851,6 +867,7 @@ struct aux_cache_entry
struct aux_cache_entry_id id;
int flags;
unsigned int osversion;
+ unsigned int isa_level;
int used;
char *soname;
struct aux_cache_entry *next;
@@ -864,7 +881,7 @@ struct aux_cache_file_entry
int32_t flags; /* This is 1 for an ELF library. */
uint32_t soname; /* String table indice. */
uint32_t osversion; /* Required OS version. */
- int32_t pad;
+ uint32_t isa_level; /* Required ISA level. */
};
/* ldconfig maintains an auxiliary cache file that allows
@@ -915,7 +932,8 @@ init_aux_cache (void)
int
search_aux_cache (struct stat64 *stat_buf, int *flags,
- unsigned int *osversion, char **soname)
+ unsigned int *osversion, unsigned int *isa_level,
+ char **soname)
{
struct aux_cache_entry_id id;
id.ino = (uint64_t) stat_buf->st_ino;
@@ -933,6 +951,7 @@ search_aux_cache (struct stat64 *stat_buf, int *flags,
{
*flags = entry->flags;
*osversion = entry->osversion;
+ *isa_level = entry->isa_level;
if (entry->soname != NULL)
*soname = xstrdup (entry->soname);
else
@@ -946,7 +965,8 @@ search_aux_cache (struct stat64 *stat_buf, int *flags,
static void
insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
- unsigned int osversion, const char *soname, int used)
+ unsigned int osversion, unsigned int isa_level,
+ const char *soname, int used)
{
size_t hash = aux_cache_entry_id_hash (id) % aux_hash_size;
struct aux_cache_entry *entry;
@@ -962,6 +982,7 @@ insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
entry->id = *id;
entry->flags = flags;
entry->osversion = osversion;
+ entry->isa_level = isa_level;
entry->used = used;
if (soname != NULL)
entry->soname = memcpy ((char *) (entry + 1), soname, len);
@@ -973,14 +994,15 @@ insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
void
add_to_aux_cache (struct stat64 *stat_buf, int flags,
- unsigned int osversion, const char *soname)
+ unsigned int osversion, unsigned int isa_level,
+ const char *soname)
{
struct aux_cache_entry_id id;
id.ino = (uint64_t) stat_buf->st_ino;
id.ctime = (uint64_t) stat_buf->st_ctime;
id.size = (uint64_t) stat_buf->st_size;
id.dev = (uint64_t) stat_buf->st_dev;
- insert_to_aux_cache (&id, flags, osversion, soname, 1);
+ insert_to_aux_cache (&id, flags, osversion, isa_level, soname, 1);
}
/* Load auxiliary cache to search for unchanged entries. */
@@ -1026,6 +1048,7 @@ load_aux_cache (const char *aux_cache_name)
insert_to_aux_cache (&aux_cache->libs[i].id,
aux_cache->libs[i].flags,
aux_cache->libs[i].osversion,
+ aux_cache->libs[i].isa_level,
aux_cache->libs[i].soname == 0
? NULL : aux_cache_data + aux_cache->libs[i].soname,
0);
@@ -1094,7 +1117,7 @@ save_aux_cache (const char *aux_cache_name)
str_offset += len;
}
file_entries->libs[idx].osversion = entry->osversion;
- file_entries->libs[idx++].pad = 0;
+ file_entries->libs[idx++].isa_level = entry->isa_level;
}
/* Write out auxiliary cache file. */