diff options
Diffstat (limited to 'libelf')
-rw-r--r-- | libelf/ChangeLog | 52 | ||||
-rw-r--r-- | libelf/Makefile.am | 4 | ||||
-rw-r--r-- | libelf/elf.h | 85 | ||||
-rw-r--r-- | libelf/elf32_updatefile.c | 164 | ||||
-rw-r--r-- | libelf/elf32_updatenull.c | 7 | ||||
-rw-r--r-- | libelf/elf_error.c | 83 | ||||
-rw-r--r-- | libelf/elf_strptr.c | 6 | ||||
-rw-r--r-- | libelf/libelfP.h | 4 | ||||
-rw-r--r-- | libelf/note_xlate.h | 4 |
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); |