summaryrefslogtreecommitdiff
path: root/libelf
diff options
context:
space:
mode:
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog52
-rw-r--r--libelf/Makefile.am4
-rw-r--r--libelf/elf.h85
-rw-r--r--libelf/elf32_updatefile.c164
-rw-r--r--libelf/elf32_updatenull.c7
-rw-r--r--libelf/elf_error.c83
-rw-r--r--libelf/elf_strptr.c6
-rw-r--r--libelf/libelfP.h4
-rw-r--r--libelf/note_xlate.h4
9 files changed, 248 insertions, 161 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 9578f8bd..bfc3ee5f 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,55 @@
+2009-04-14 Roland McGrath <roland@redhat.com>
+
+ * elf.h: Update from glibc.
+
+2009-04-01 Roland McGrath <roland@redhat.com>
+
+ * elf.h: Update from glibc.
+
+2009-02-10 Ulrich Drepper <drepper@redhat.com>
+
+ * elf32_updatefile.c (updatefile): For the zeroth section we still
+ have to copy the section header.
+
+2009-02-01 Ulrich Drepper <drepper@redhat.com>
+
+ * elf_strptr.c: Add comment re possible problem.
+
+2009-01-26 Ulrich Drepper <drepper@redhat.com>
+
+ * elf32_updatenull.c (updatenull_wrlock): Fix comment of
+ ELF_F_LAYOUT behaviour re section header table.
+
+2009-01-22 Ulrich Drepper <drepper@redhat.com>
+
+ * elf32_updatefile.c (__elfXX_updatemmap): Fill the gap between
+ sections even if only the section at the start of the gap has been
+ changed.
+ (__elfXX_updatefile): Likewise.
+
+2009-01-21 Ulrich Drepper <drepper@redhat.com>
+
+ * elf32_updatefile.c (__elfXX_updatemmap): Skip most of the loop to
+ handle sections for NOBITS sections.
+ (elfXX_updatefile): Likewise.
+
+ * elf32_updatefile.c (__elfXX_updatemmap): When skipping non-NOBITS
+ sections we haven't loaded, update last_position based on scn_start,
+ not based on old value. Don't run the loop for the dummy section 0.
+ (elfXX_updatefile): Don't run the loop for the dummy section 0.
+
+2009-01-10 Ulrich Drepper <drepper@redhat.com>
+
+ * libelfP.h (_): We only have one translation domain, elfutils.
+
+ * Makefile.am: Use USE_LOCKS instead of USE_TLS.
+ * elf_error.c: Always use __thread. Remove all !USE_TLS code.
+
+2009-01-04 Roland McGrath <roland@redhat.com>
+
+ * note_xlate.h (elf_cvt_note): Don't examine a size too small to
+ container a note header.
+
2008-12-11 Roland McGrath <roland@redhat.com>
* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 2458ecbd..84b01a86 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
-## Copyright (C) 1996-2006, 2007, 2008 Red Hat, Inc.
+## Copyright (C) 1996-2006, 2007, 2008, 2009 Red Hat, Inc.
## This file is part of Red Hat elfutils.
##
## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -106,7 +106,7 @@ libelf_pic_a_SOURCES =
am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
libelf_so_LDLIBS =
-if USE_TLS
+if USE_LOCKS
libelf_so_LDLIBS += -lpthread
endif
diff --git a/libelf/elf.h b/libelf/elf.h
index b4d34754..062ef00f 100644
--- a/libelf/elf.h
+++ b/libelf/elf.h
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-2003,2004,2005,2006,2007,2008
+ Copyright (C) 1995-2003,2004,2005,2006,2007,2008,2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -459,6 +459,7 @@ typedef struct
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_LOOS 10 /* Start of OS-specific */
+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
#define STT_HIOS 12 /* End of OS-specific */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */
@@ -972,6 +973,10 @@ typedef struct
#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
+
+#define AT_RANDOM 25 /* Address of 16 random bytes. */
+
#define AT_EXECFN 31 /* Filename of executable. */
/* Pointer to the global system page used for system calls and other
@@ -1241,6 +1246,7 @@ typedef struct
#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
#define R_SPARC_7 43 /* Direct 7 bit */
#define R_SPARC_5 44 /* Direct 5 bit */
#define R_SPARC_6 45 /* Direct 6 bit */
@@ -1278,8 +1284,19 @@ typedef struct
#define R_SPARC_TLS_DTPOFF64 77
#define R_SPARC_TLS_TPOFF32 78
#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
/* Keep this the last entry. */
-#define R_SPARC_NUM 80
+#define R_SPARC_NUM 253
/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
@@ -2188,42 +2205,62 @@ typedef Elf32_Addr Elf32_Conflict;
/* ARM specific declarations */
/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x01
-#define EF_ARM_HASENTRY 0x02
-#define EF_ARM_INTERWORK 0x04
-#define EF_ARM_APCS_26 0x08
-#define EF_ARM_APCS_FLOAT 0x10
-#define EF_ARM_PIC 0x20
-#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-#define EF_ARM_NEW_ABI 0x80
-#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
/* Other constants defined in the ARM ELF spec. version B-01. */
/* NB. These conflict with values defined above. */
#define EF_ARM_SYMSARESORTED 0x04
-#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
#define EF_ARM_MAPSYMSFIRST 0x10
#define EF_ARM_EABIMASK 0XFF000000
-#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-#define EF_ARM_EABI_UNKNOWN 0x00000000
-#define EF_ARM_EABI_VER1 0x01000000
-#define EF_ARM_EABI_VER2 0x02000000
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC 0xd
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
- in the input to a link step */
+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
+ in the input to a link step. */
/* ARM-specific program header flags */
-#define PF_ARM_SB 0x10000000 /* Segment contains the location
- addressed by the static base */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location
+ addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
/* Processor specific values for the Phdr p_type field. */
-#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
+
/* ARM relocs. */
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index e88f4a45..a4d83a1c 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -126,11 +126,10 @@ int
internal_function
__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
{
- ElfW2(LIBELFBITS,Ehdr) *ehdr;
- char *last_position;
+ bool previous_scn_changed = false;
/* We need the ELF header several times. */
- ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+ ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
/* Write out the ELF header. */
if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY)
@@ -160,6 +159,10 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
sizeof (ElfW2(LIBELFBITS,Ehdr)));
elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+
+ /* We start writing sections after the ELF header only if there is
+ no program header. */
+ previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
}
/* Write out the program header table. */
@@ -200,14 +203,19 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
sizeof (ElfW2(LIBELFBITS,Phdr)) * ehdr->e_phnum);
elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+
+ /* We modified the program header. Maybe this created a gap so
+ we have to write fill bytes, if necessary. */
+ previous_scn_changed = true;
}
/* From now on we have to keep track of the last position to eventually
fill the gaps with the prescribed fill byte. */
- last_position = ((char *) elf->map_address + elf->start_offset
- + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
- ehdr->e_phoff)
- + elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum));
+ char *last_position = ((char *) elf->map_address + elf->start_offset
+ + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
+ ehdr->e_phoff)
+ + elf_typesize (LIBELFBITS, ELF_T_PHDR,
+ ehdr->e_phnum));
/* Write all the sections. Well, only those which are modified. */
if (shnum > 0)
@@ -283,14 +291,42 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
for (size_t cnt = 0; cnt < shnum; ++cnt)
{
Elf_Scn *scn = scns[cnt];
+ if (scn->index == 0)
+ {
+ /* The dummy section header entry. It should not be
+ possible to mark this "section" as dirty. */
+ assert ((scn->flags & ELF_F_DIRTY) == 0);
+ continue;
+ }
ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+ if (shdr->sh_type == SHT_NOBITS)
+ goto next;
char *scn_start = ((char *) elf->map_address
+ elf->start_offset + shdr->sh_offset);
Elf_Data_List *dl = &scn->data_list;
+ bool scn_changed = false;
+
+ void fill_mmap (size_t offset)
+ {
+ size_t written = 0;
+
+ if (last_position < shdr_start)
+ {
+ written = MIN (scn_start + offset - last_position,
+ shdr_start - last_position);
+
+ memset (last_position, __libelf_fill_byte, written);
+ }
+
+ if (last_position + written != scn_start + offset
+ && shdr_end < scn_start + offset)
+ memset (shdr_end, __libelf_fill_byte,
+ scn_start + offset - shdr_end);
+ }
- if (shdr->sh_type != SHT_NOBITS && scn->data_list_rear != NULL)
+ if (scn->data_list_rear != NULL)
do
{
assert (dl->data.d.d_off >= 0);
@@ -298,31 +334,15 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
assert (dl->data.d.d_size <= (shdr->sh_size
- (GElf_Off) dl->data.d.d_off));
+ /* If there is a gap, fill it. */
+ if (scn_start + dl->data.d.d_off > last_position
+ && ((previous_scn_changed && dl->data.d.d_off == 0)
+ || ((scn->flags | dl->flags | elf->flags)
+ & ELF_F_DIRTY) != 0))
+ fill_mmap (dl->data.d.d_off);
+
if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
{
- if (scn_start + dl->data.d.d_off > last_position)
- {
- /* This code assumes that the data blocks for
- a section are ordered by offset. */
- size_t written = 0;
-
- if (last_position < shdr_start)
- {
- written = MIN (scn_start + dl->data.d.d_off
- - last_position,
- shdr_start - last_position);
-
- memset (last_position, __libelf_fill_byte,
- written);
- }
-
- if (last_position + written
- != scn_start + dl->data.d.d_off
- && shdr_end < scn_start + dl->data.d.d_off)
- memset (shdr_end, __libelf_fill_byte,
- scn_start + dl->data.d.d_off - shdr_end);
- }
-
/* Let it go backward if the sections use a bogus
layout with overlaps. We'll overwrite the stupid
user's section data with the latest one, rather than
@@ -350,6 +370,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
last_position = mempcpy (last_position,
dl->data.d.d_buf,
dl->data.d.d_size);
+
+ scn_changed = true;
}
else
last_position += dl->data.d.d_size;
@@ -362,10 +384,20 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
dl = dl->next;
}
while (dl != NULL);
- else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
- /* We have to trust the existing section header information. */
- last_position += shdr->sh_size;
+ else
+ {
+ /* If the previous section (or the ELF/program
+ header) changed we might have to fill the gap. */
+ if (scn_start > last_position && previous_scn_changed)
+ fill_mmap (0);
+
+ /* We have to trust the existing section header information. */
+ last_position = scn_start + shdr->sh_size;
+ }
+
+ previous_scn_changed = scn_changed;
+ next:
scn->flags &= ~ELF_F_DIRTY;
}
@@ -470,6 +502,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
{
char fillbuf[FILLBUFSIZE];
size_t filled = 0;
+ bool previous_scn_changed = false;
/* We need the ELF header several times. */
ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
@@ -513,6 +546,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
}
elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+
+ /* We start writing sections after the ELF header only if there is
+ no program header. */
+ previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
}
/* If the type sizes should be different at some time we have to
@@ -578,6 +615,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
free (tmp_phdr);
elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+
+ /* We modified the program header. Maybe this created a gap so
+ we have to write fill bytes, if necessary. */
+ previous_scn_changed = true;
}
/* From now on we have to keep track of the last position to eventually
@@ -616,30 +657,43 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
for (size_t cnt = 0; cnt < shnum; ++cnt)
{
Elf_Scn *scn = scns[cnt];
+ if (scn->index == 0)
+ {
+ /* The dummy section header entry. It should not be
+ possible to mark this "section" as dirty. */
+ assert ((scn->flags & ELF_F_DIRTY) == 0);
+ goto next;
+ }
ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+ if (shdr->sh_type == SHT_NOBITS)
+ goto next;
off_t scn_start = elf->start_offset + shdr->sh_offset;
Elf_Data_List *dl = &scn->data_list;
+ bool scn_changed = false;
- if (shdr->sh_type != SHT_NOBITS && scn->data_list_rear != NULL
- && scn->index != 0)
+ if (scn->data_list_rear != NULL)
do
{
+ /* If there is a gap, fill it. */
+ if (scn_start + dl->data.d.d_off > last_offset
+ && ((previous_scn_changed && dl->data.d.d_off == 0)
+ || ((scn->flags | dl->flags | elf->flags)
+ & ELF_F_DIRTY) != 0))
+ {
+ if (unlikely (fill (elf->fildes, last_offset,
+ (scn_start + dl->data.d.d_off)
+ - last_offset, fillbuf,
+ &filled) != 0))
+ return 1;
+ }
+
if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
{
char tmpbuf[MAX_TMPBUF];
void *buf = dl->data.d.d_buf;
- if (scn_start + dl->data.d.d_off > last_offset)
- {
- if (unlikely (fill (elf->fildes, last_offset,
- (scn_start + dl->data.d.d_off)
- - last_offset, fillbuf,
- &filled) != 0))
- return 1;
- }
-
/* Let it go backward if the sections use a bogus
layout with overlaps. We'll overwrite the stupid
user's section data with the latest one, rather than
@@ -686,6 +740,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
if (buf != dl->data.d.d_buf && buf != tmpbuf)
free (buf);
+
+ scn_changed = true;
}
last_offset += dl->data.d.d_size;
@@ -695,9 +751,23 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
dl = dl->next;
}
while (dl != NULL);
- else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
- last_offset = scn_start + shdr->sh_size;
+ else
+ {
+ /* If the previous section (or the ELF/program
+ header) changed we might have to fill the gap. */
+ if (scn_start > last_offset && previous_scn_changed)
+ {
+ if (unlikely (fill (elf->fildes, last_offset,
+ scn_start - last_offset, fillbuf,
+ &filled) != 0))
+ return 1;
+ }
+
+ last_offset = scn_start + shdr->sh_size;
+ }
+ previous_scn_changed = scn_changed;
+ next:
/* Collect the section header table information. */
if (unlikely (change_bo))
(*shdr_fctp) (&shdr_data[scn->index],
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index a18d0bea..5ce8bbc9 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -1,5 +1,5 @@
/* Update data structures for changes.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -401,8 +401,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
/* Store section information. */
if (elf->flags & ELF_F_LAYOUT)
{
- /* The user is supposed to fill out e_phoff. Use it and
- e_phnum to determine the maximum extend. */
+ /* The user is supposed to fill out e_shoff. Use it and
+ e_shnum (or sh_size of the dummy, first section header)
+ to determine the maximum extend. */
size = MAX ((GElf_Word) size,
(ehdr->e_shoff
+ (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
diff --git a/libelf/elf_error.c b/libelf/elf_error.c
index 5e00372a..dc587828 100644
--- a/libelf/elf_error.c
+++ b/libelf/elf_error.c
@@ -1,5 +1,5 @@
/* Error handling in libelf.
- Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
+ Copyright (C) 1998,1999,2000,2002,2003,2004,2005,2006,2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -61,46 +61,14 @@
#include "libelfP.h"
-#ifdef USE_TLS
/* The error number. */
static __thread int global_error;
-#else
-/* This is the key for the thread specific memory. */
-static tls_key_t key;
-
-/* The error number. Used in non-threaded programs. */
-static int global_error;
-static bool threaded;
-/* We need to initialize the thread-specific data. */
-once_define (static, once);
-
-/* The initialization and destruction functions. */
-static void init (void);
-static void free_key_mem (void *mem);
-#endif /* TLS */
int
elf_errno (void)
{
- int result;
-
-#ifndef USE_TLS
- /* If we have not yet initialized the buffer do it now. */
- once_execute (once, init);
-
- if (threaded)
- {
- /* We do not allocate memory for the data. It is only a word.
- We can store it in place of the pointer. */
- result = (intptr_t) getspecific (key);
-
- setspecific (key, (void *) (intptr_t) ELF_E_NOERROR);
- return result;
- }
-#endif /* TLS */
-
- result = global_error;
+ int result = global_error;
global_error = ELF_E_NOERROR;
return result;
}
@@ -339,16 +307,6 @@ void
__libelf_seterrno (value)
int value;
{
-#ifndef USE_TLS
- /* If we have not yet initialized the buffer do it now. */
- once_execute (once, init);
-
- if (threaded)
- /* We do not allocate memory for the data. It is only a word.
- We can store it in place of the pointer. */
- setspecific (key, (void *) (intptr_t) value);
-#endif /* TLS */
-
global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
}
@@ -357,19 +315,7 @@ const char *
elf_errmsg (error)
int error;
{
- int last_error;
-
-#ifndef USE_TLS
- /* If we have not yet initialized the buffer do it now. */
- once_execute (once, init);
-
- if ((error == 0 || error == -1) && threaded)
- /* We do not allocate memory for the data. It is only a word.
- We can store it in place of the pointer. */
- last_error = (intptr_t) getspecific (key);
- else
-#endif /* TLS */
- last_error = global_error;
+ int last_error = global_error;
if (error == 0)
{
@@ -382,26 +328,3 @@ elf_errmsg (error)
assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr));
return _(msgstr + msgidx[error == -1 ? last_error : error]);
}
-
-
-#ifndef USE_TLS
-/* Free the thread specific data, this is done if a thread terminates. */
-static void
-free_key_mem (void *mem __attribute__ ((unused)))
-{
- setspecific (key, NULL);
-}
-
-
-/* Initialize the key for the global variable. */
-static void
-init (void)
-{
- // XXX Screw you, gcc4, the unused function attribute does not work.
- __asm ("" :: "r" (free_key_mem));
-
- if (key_create (&key, free_key_mem) == 0)
- /* Creating the key succeeded. */
- threaded = true;
-}
-#endif /* TLS */
diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c
index 35a0e9b6..7b837b09 100644
--- a/libelf/elf_strptr.c
+++ b/libelf/elf_strptr.c
@@ -1,5 +1,5 @@
/* Return string pointer from string section.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008 Red Hat, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -151,6 +151,10 @@ elf_strptr (elf, idx, offset)
}
if (likely (strscn->rawdata_base != NULL))
+ // XXX Is this correct if a file is read and then new data is added
+ // XXX to the string section? Likely needs to check offset against
+ // XXX size of rawdata_base buffer and then iterate over rest of the
+ // XXX list.
result = &strscn->rawdata_base[offset];
else
{
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index e8100397..818f42ac 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998-2003, 2005, 2006, 2007 Red Hat, Inc.
+ Copyright (C) 1998-2003, 2005, 2006, 2007, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -64,7 +64,7 @@
#include <string.h>
/* gettext helper macros. */
-#define _(Str) dgettext ("libelf", Str)
+#define _(Str) dgettext ("elfutils", Str)
/* Helper Macros to write 32 bit and 64 bit functions. */
diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h
index 6e8b78c6..a72fe868 100644
--- a/libelf/note_xlate.h
+++ b/libelf/note_xlate.h
@@ -1,5 +1,5 @@
/* Conversion functions for notes.
- Copyright (C) 2007 Red Hat, Inc.
+ Copyright (C) 2007, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@ elf_cvt_note (void *dest, const void *src, size_t len, int encode)
{
assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
- while (len > 0)
+ while (len >= sizeof (Elf32_Nhdr))
{
(1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
encode);