1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Changeset 321

Show
Ignore:
Timestamp:
03/07/09 16:59:14 (5 years ago)
Author:
jkoshy
Message:

Add support for translating sections of type ELF_T_GNUHASH.

Submitted by: kaiwang27 (original patch)

Location:
projects/libelf/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • projects/libelf/trunk/elf_types.m4

    r189 r321  
    4141        `DYN,           Dyn', 
    4242        `EHDR,          Ehdr', 
     43        `GNUHASH,       -', 
    4344        `HALF,          Half', 
    4445        `LWORD,         Lword', 
  • projects/libelf/trunk/libelf_convert.m4

    r316 r321  
    231231IGNORE(MOVEP) 
    232232IGNORE(NOTE) 
     233IGNORE(GNUHASH) 
    233234 
    234235define(IGNORE_BYTE,             1)      /* 'lator, leave 'em bytes alone */ 
     
    501502} 
    502503 
     504#if     LIBELF_CONFIG_GNUHASH 
     505/* 
     506 * Section of type ELF_T_GNUHASH start with a header containing 4 32-bit 
     507 * words.  Bloom filter data and the hash buckets follow the header. 
     508 * 
     509 * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit 
     510 * wide on ELFCLASS32 objects.  The other objects in this section are 32 
     511 * bits wide. 
     512 */ 
     513 
     514static int 
     515libelf_cvt64_GNUHASH_tom(char *dst, size_t dsz, char *src, size_t count, 
     516    int byteswap) 
     517{ 
     518        size_t sz; 
     519        uint64_t t64, *bloom64; 
     520        Elf_GNU_Hash_Header *gh; 
     521        uint32_t n, nbuckets, symndx, maskwords, shift2, t32, *buckets; 
     522 
     523        sz = 4 * sizeof(uint32_t);      /* File header is 4 words long. */ 
     524        if (dsz < sizeof(Elf_GNU_Hash_Header) || count < sz) 
     525                return (0); 
     526 
     527        /* Read in the section header and byteswap if needed. */ 
     528        READ_WORD(src, nbuckets); 
     529        READ_WORD(src, symndx); 
     530        READ_WORD(src, maskwords); 
     531        READ_WORD(src, shift2); 
     532 
     533        count -= sz; 
     534 
     535        if (byteswap) { 
     536                SWAP_WORD(nbuckets); 
     537                SWAP_WORD(symndx); 
     538                SWAP_WORD(maskwords); 
     539                SWAP_WORD(shift2); 
     540        } 
     541 
     542        /* Check source buffer and destination buffer sizes. */ 
     543        sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); 
     544        if (count < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) 
     545                return (0); 
     546 
     547        gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; 
     548        gh->gh_nbuckets  = nbuckets; 
     549        gh->gh_symndx    = symndx; 
     550        gh->gh_maskwords = maskwords; 
     551        gh->gh_shift2    = shift2; 
     552         
     553        dsz -= sizeof(Elf_GNU_Hash_Header); 
     554        dst += sizeof(Elf_GNU_Hash_Header); 
     555 
     556        bloom64 = (uint64_t *) (uintptr_t) dst; 
     557 
     558        /* Copy the bloom filter and the hash table. */ 
     559        for (n = 0; n < maskwords; n++) { 
     560                READ_XWORD(src, t64); 
     561                if (byteswap) 
     562                        SWAP_XWORD(t64); 
     563                bloom64[n] = t64; 
     564        } 
     565 
     566        dst += maskwords * sizeof(uint64_t); 
     567        buckets = (uint32_t *) (uintptr_t) dst; 
     568 
     569        for (n = 0; n < nbuckets; n++) { 
     570                READ_WORD(src, t32); 
     571                if (byteswap) 
     572                        SWAP_XWORD(t32); 
     573                buckets[n] = t32; 
     574        } 
     575 
     576        return (1); 
     577} 
     578 
     579static int 
     580libelf_cvt64_GNUHASH_tof(char *dst, size_t dsz, char *src, size_t count, 
     581    int byteswap) 
     582{ 
     583        size_t sz, hdrsz; 
     584        Elf_GNU_Hash_Header *gh; 
     585        uint32_t *s32, t32, n, maskwords, nbuckets; 
     586        uint64_t *s64, t64; 
     587 
     588        hdrsz = 4 * sizeof(uint32_t);   /* Header is 4x32 bits. */ 
     589        if (dsz < hdrsz || count < sizeof(Elf_GNU_Hash_Header)) 
     590                return (0); 
     591 
     592        gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; 
     593 
     594        src   += sizeof(Elf_GNU_Hash_Header); 
     595        count -= sizeof(Elf_GNU_Hash_Header); 
     596 
     597        sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * 
     598            sizeof(uint64_t); 
     599 
     600        if (count < sz || dsz < sz + hdrsz) 
     601                return (0); 
     602 
     603        maskwords = gh->gh_maskwords; 
     604        nbuckets  = gh->gh_nbuckets; 
     605 
     606        /* Write out the header. */ 
     607        if (byteswap) { 
     608                SWAP_WORD(gh->gh_nbuckets); 
     609                SWAP_WORD(gh->gh_symndx); 
     610                SWAP_WORD(gh->gh_maskwords); 
     611                SWAP_WORD(gh->gh_shift2); 
     612        } 
     613 
     614        WRITE_WORD(dst, gh->gh_nbuckets); 
     615        WRITE_WORD(dst, gh->gh_symndx); 
     616        WRITE_WORD(dst, gh->gh_maskwords); 
     617        WRITE_WORD(dst, gh->gh_shift2); 
     618 
     619 
     620        /* Copy the bloom filter and the hash table. */ 
     621        s64 = (uint64_t *) (uintptr_t) src; 
     622 
     623        for (n = 0; n < maskwords; n++) { 
     624                t64 = *s64++; 
     625                if (byteswap) 
     626                        SWAP_XWORD(t64); 
     627                WRITE_WORD64(dst, t64); 
     628        } 
     629 
     630        s32 = (uint32_t *) s64; 
     631        for (n = 0; n < nbuckets; n++) { 
     632                t32 = *s32++; 
     633                if (byteswap) 
     634                        SWAP_WORD(t32); 
     635                WRITE_WORD(dst, t32); 
     636        } 
     637 
     638        return (1); 
     639} 
     640#endif  /* LIBELF_CONFIG_GNUHASH */ 
     641 
    503642#if     LIBELF_CONFIG_NOTE 
    504643/* 
     
    508647 * 
    509648 * Argument `count' denotes the total number of bytes to be converted. 
     649 * The destination buffer needs to be at least `count' bytes in size. 
    510650 */ 
    511651static int 
     
    565705 
    566706                count -= sz; 
     707                dsz -= sz; 
    567708        } 
    568709 
     
    674815                .tom64 = libelf_cvt_BYTE_tox 
    675816        }, 
     817 
     818        [ELF_T_GNUHASH] = { 
     819                .tof32 = libelf_cvt_WORD_tof, 
     820                .tom32 = libelf_cvt_WORD_tom, 
     821                .tof64 = libelf_cvt64_GNUHASH_tof, 
     822                .tom64 = libelf_cvt64_GNUHASH_tom 
     823        }, 
     824 
    676825#if     LIBELF_CONFIG_NOTE 
    677826        [ELF_T_NOTE] = {