summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/cache.c5
-rw-r--r--elf/chroot_canon.c5
-rw-r--r--elf/dl-close.c6
-rw-r--r--elf/dl-load.c38
-rw-r--r--elf/elf.h23
-rw-r--r--elf/ldconfig.c5
-rw-r--r--elf/readelflib.c37
-rw-r--r--elf/readlib.c5
8 files changed, 91 insertions, 33 deletions
diff --git a/elf/cache.c b/elf/cache.c
index e18446644e..6dbd5a6c08 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -3,8 +3,9 @@
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
index 3ef2fdf08f..3c16a43ebb 100644
--- a/elf/chroot_canon.c
+++ b/elf/chroot_canon.c
@@ -4,8 +4,9 @@
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 932e6110b6..67188bb6c1 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -494,11 +494,11 @@ _dl_close_worker (struct link_map *map)
|| (GL(dl_scope_free_list) != NULL
&& GL(dl_scope_free_list)->count)))
{
- struct dl_scope_free_list *fsl;
-
THREAD_GSCOPE_WAIT ();
+
/* Now we can free any queued old scopes. */
- if ((fsl = GL(dl_scope_free_list)) != NULL)
+ struct dl_scope_free_list *fsl = GL(dl_scope_free_list);
+ if (fsl != NULL)
while (fsl->count > 0)
free (fsl->list[--fsl->count]);
}
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 025b9fd86b..1a84e0fe43 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1634,7 +1634,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
{
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr, *ph;
- ElfW(Word) *abi_note, abi_note_buf[8];
+ ElfW(Word) *abi_note;
unsigned int osversion;
size_t maplength;
@@ -1751,20 +1751,37 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
/* Check .note.ABI-tag if present. */
for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph)
- if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4)
+ if (ph->p_type == PT_NOTE && ph->p_filesz >= 32 && ph->p_align >= 4)
{
- if (ph->p_offset + 32 <= (size_t) fbp->len)
+ ElfW(Addr) size = ph->p_filesz;
+
+ if (ph->p_offset + size <= (size_t) fbp->len)
abi_note = (void *) (fbp->buf + ph->p_offset);
else
{
+ abi_note = alloca (size);
__lseek (fd, ph->p_offset, SEEK_SET);
- if (__libc_read (fd, (void *) abi_note_buf, 32) != 32)
+ if (__libc_read (fd, (void *) abi_note, size) != size)
goto read_error;
+ }
+
+ while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
+ {
+#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ ElfW(Addr) note_size = 3 * sizeof (ElfW(Word))
+ + ROUND (abi_note[0])
+ + ROUND (abi_note[1]);
- abi_note = abi_note_buf;
+ if (size - 32 < note_size)
+ {
+ size = 0;
+ break;
+ }
+ size -= note_size;
+ abi_note = (void *) abi_note + note_size;
}
- if (memcmp (abi_note, &expected_note, sizeof (expected_note)))
+ if (size == 0)
continue;
osversion = (abi_note[5] & 0xff) * 65536
@@ -2256,14 +2273,17 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
if (counting)
{
si->dls_cnt++;
- si->dls_size += r->dirnamelen;
+ si->dls_size += r->dirnamelen < 2 ? r->dirnamelen : 2;
}
else
{
Dl_serpath *const sp = &si->dls_serpath[idx++];
sp->dls_name = allocptr;
- allocptr = __mempcpy (allocptr,
- r->dirname, r->dirnamelen - 1);
+ if (r->dirnamelen < 2)
+ *allocptr++ = r->dirnamelen ? '/' : '.';
+ else
+ allocptr = __mempcpy (allocptr,
+ r->dirname, r->dirnamelen - 1);
*allocptr++ = '\0';
sp->dls_flags = flags;
}
diff --git a/elf/elf.h b/elf/elf.h
index 6c2d54c168..6cc547ef60 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -602,8 +602,8 @@ typedef struct
#define NT_UTSNAME 15 /* Contains copy of utsname struct */
#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
-#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/
-#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct*/
+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
/* Legal values for the note segment descriptor types for object files. */
@@ -1017,15 +1017,28 @@ typedef struct
word 2: minor version of the ABI
word 3: subminor version of the ABI
*/
-#define ELF_NOTE_ABI 1
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
-/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI
- note section entry. */
+/* Known OSes. These values can appear in word 0 of an
+ NT_GNU_ABI_TAG note section entry. */
#define ELF_NOTE_OS_LINUX 0
#define ELF_NOTE_OS_GNU 1
#define ELF_NOTE_OS_SOLARIS2 2
#define ELF_NOTE_OS_FREEBSD 3
+/* Synthetic hwcap information. The descriptor begins with two words:
+ word 0: number of entries
+ word 1: bitmask of enabled entries
+ Then follow variable-length entries, one byte followed by a
+ '\0'-terminated hwcap name string. The byte gives the bit
+ number to test if enabled, (1U << bit) & bitmask. */
+#define NT_GNU_HWCAP 2
+
+/* Build ID bits as generated by ld --build-id.
+ The descriptor consists of any nonzero number of bytes. */
+#define NT_GNU_BUILD_ID 3
+
/* Move records. */
typedef struct
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 1aa8376b65..7692e3a8af 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -3,8 +3,9 @@
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/elf/readelflib.c b/elf/readelflib.c
index 26444ad6b2..ea92d89b20 100644
--- a/elf/readelflib.c
+++ b/elf/readelflib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -127,16 +127,37 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
break;
case PT_NOTE:
- if (!*osversion && segment->p_filesz == 32 && segment->p_align >= 4)
+ if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
{
ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
+ segment->p_offset);
- if (abi_note [0] == 4 && abi_note [1] == 16 && abi_note [2] == 1
- && memcmp (abi_note + 3, "GNU", 4) == 0)
- *osversion = (abi_note [4] << 24) |
- ((abi_note [5] & 0xff) << 16) |
- ((abi_note [6] & 0xff) << 8) |
- (abi_note [7] & 0xff);
+ ElfW(Addr) size = segment->p_filesz;
+
+ while (abi_note [0] != 4 || abi_note [1] != 16
+ || abi_note [2] != 1
+ || memcmp (abi_note + 3, "GNU", 4) != 0)
+ {
+#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ ElfW(Addr) note_size = 3 * sizeof (ElfW(Word))
+ + ROUND (abi_note[0])
+ + ROUND (abi_note[1]);
+
+ if (size - 32 < note_size || note_size == 0)
+ {
+ size = 0;
+ break;
+ }
+ size -= note_size;
+ abi_note = (void *) abi_note + note_size;
+ }
+
+ if (size == 0)
+ break;
+
+ *osversion = (abi_note [4] << 24) |
+ ((abi_note [5] & 0xff) << 16) |
+ ((abi_note [6] & 0xff) << 8) |
+ (abi_note [7] & 0xff);
}
break;
diff --git a/elf/readlib.c b/elf/readlib.c
index 8896bbdaca..a3278d935e 100644
--- a/elf/readlib.c
+++ b/elf/readlib.c
@@ -4,8 +4,9 @@
Jakub Jelinek <jakub@redhat.com>, 1999.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of