diff options
author | Chih-Hung Hsieh <chh@google.com> | 2015-10-23 14:46:07 -0700 |
---|---|---|
committer | Chih-Hung Hsieh <chh@google.com> | 2015-10-23 14:46:07 -0700 |
commit | 5a7d0bdff1a6e4557ac843b0e142bf34fd2eb324 (patch) | |
tree | 922cdd35d4e1c16f3e3bc33582ff2958636a0d1d /libelf | |
parent | 385ca2d0e5bf80fb630db3a447bbd6a26e7e1875 (diff) | |
parent | 5eb3e901f9ffdc02d80f5df8f6963261a23f977c (diff) | |
download | android_external_elfutils-5a7d0bdff1a6e4557ac843b0e142bf34fd2eb324.tar.gz android_external_elfutils-5a7d0bdff1a6e4557ac843b0e142bf34fd2eb324.tar.bz2 android_external_elfutils-5a7d0bdff1a6e4557ac843b0e142bf34fd2eb324.zip |
Merge upstream SHA '5eb3e90'
* git merge 5eb3e90
* Android relevant upstream changes:
Move nested functions to file scope:
libdw/cfi.c, libdwelf, libelf
elf.h: Update from glibc. Add section compression constants and structures.
libelf: use the right size when preading in[0].sh_size
See all upstream changes since the previous merge:
git diff a1e17a2..5eb3e90
* No changes to the following generated files:
version.h, config.h, libdw/known-dwarf.h
Diffstat (limited to 'libelf')
-rw-r--r-- | libelf/ChangeLog | 17 | ||||
-rw-r--r-- | libelf/elf.h | 25 | ||||
-rw-r--r-- | libelf/elf32_updatefile.c | 50 | ||||
-rw-r--r-- | libelf/elf_begin.c | 32 |
4 files changed, 85 insertions, 39 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index d8651d75..18d77974 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,20 @@ +2015-10-14 Mark Wielaard <mjw@redhat.com> + + * elf.h: Update from glibc. Add section compression constants and + structures. + +2015-10-20 Jose E. Marchesi <jose.marchesi@oracle.com> + + * elf_begin.c (get_shnum): Elf64_Shdr.sh_size is an Elf64_Xword. + Fix the size argument to pread_retry. + +2015-10-13 Chih-Hung Hsieh <chh@google.com> + + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Move nested + function 'fill_mmap' to file scope. + * elf_begin.c (elf_begin): Move nested function 'lock_dup_elf' + to file scope. + 2015-10-09 Josh Stone <jistone@redhat.com> * libelf.h: Replace loff_t with int64_t throughout. diff --git a/libelf/elf.h b/libelf/elf.h index 39bafc22..12feb915 100644 --- a/libelf/elf.h +++ b/libelf/elf.h @@ -367,6 +367,7 @@ typedef struct required */ #define SHF_GROUP (1 << 9) /* Section is member of a group. */ #define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ #define SHF_MASKOS 0x0ff00000 /* OS-specific. */ #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ #define SHF_ORDERED (1 << 30) /* Special ordering requirement @@ -374,6 +375,30 @@ typedef struct #define SHF_EXCLUDE (1U << 31) /* Section is excluded unless referenced or allocated (Solaris).*/ +/* Section compression header. Used when SHF_COMPRESSED is set. */ + +typedef struct +{ + Elf32_Word ch_type; /* Compression format. */ + Elf32_Word ch_size; /* Uncompressed data size. */ + Elf32_Word ch_addralign; /* Uncompressed data alignment. */ +} Elf32_Chdr; + +typedef struct +{ + Elf64_Word ch_type; /* Compression format. */ + Elf64_Word ch_reserved; + Elf64_Xword ch_size; /* Uncompressed data size. */ + Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ +} Elf64_Chdr; + +/* Legal values for ch_type (compression algorithm). */ +#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ +#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ +#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ +#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ +#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ + /* Section group handling. */ #define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index 832f852d..09092197 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -101,6 +101,29 @@ sort_sections (Elf_Scn **scns, Elf_ScnList *list) } +static inline void +fill_mmap (size_t offset, char *last_position, char *scn_start, + char *const shdr_start, char *const shdr_end) +{ + 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) + { + char *fill_start = MAX (shdr_end, scn_start); + memset (fill_start, __libelf_fill_byte, + scn_start + offset - fill_start); + } +} + int internal_function __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) @@ -303,27 +326,6 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) 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) - { - char *fill_start = MAX (shdr_end, scn_start); - memset (fill_start, __libelf_fill_byte, - scn_start + offset - fill_start); - } - } - if (scn->data_list_rear != NULL) do { @@ -338,7 +340,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) || ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) != 0)) { - fill_mmap (dl->data.d.d_off); + fill_mmap (dl->data.d.d_off, last_position, scn_start, + shdr_start, shdr_end); last_position = scn_start + dl->data.d.d_off; } @@ -390,7 +393,8 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) /* 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); + fill_mmap (0, last_position, scn_start, + shdr_start, shdr_end); /* We have to trust the existing section header information. */ last_position = scn_start + shdr->sh_size; diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 213b5c0b..d2920c4e 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -216,7 +216,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, + offset))->sh_size, sizeof (Elf64_Xword)); else - if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Word), + if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Xword), offset + ehdr.e64->e_shoff + offsetof (Elf64_Shdr, sh_size)) != sizeof (Elf64_Xword))) @@ -1039,6 +1039,19 @@ write_file (int fd, Elf_Cmd cmd) return result; } +/* Lock if necessary before dup an archive. */ +static inline Elf * +lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref) +{ + /* We need wrlock to dup an archive. */ + if (ref->kind == ELF_K_AR) + { + rwlock_unlock (ref->lock); + rwlock_wrlock (ref->lock); + } + /* Duplicate the descriptor. */ + return dup_elf (fildes, cmd, ref); +} /* Return a descriptor for the file belonging to FILDES. */ Elf * @@ -1063,19 +1076,6 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) return NULL; } - Elf *lock_dup_elf (void) - { - /* We need wrlock to dup an archive. */ - if (ref->kind == ELF_K_AR) - { - rwlock_unlock (ref->lock); - rwlock_wrlock (ref->lock); - } - - /* Duplicate the descriptor. */ - return dup_elf (fildes, cmd, ref); - } - switch (cmd) { case ELF_C_NULL: @@ -1096,7 +1096,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) case ELF_C_READ: case ELF_C_READ_MMAP: if (ref != NULL) - retval = lock_dup_elf (); + retval = lock_dup_elf (fildes, cmd, ref); else /* Create descriptor for existing file. */ retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL); @@ -1117,7 +1117,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) retval = NULL; } else - retval = lock_dup_elf (); + retval = lock_dup_elf (fildes, cmd, ref); } else /* Create descriptor for existing file. */ |