From owner-p4-projects@FreeBSD.ORG Sat Nov 4 03:27:01 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C746E16A416; Sat, 4 Nov 2006 03:27:01 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7111F16A40F for ; Sat, 4 Nov 2006 03:27:01 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3E23343D5E for ; Sat, 4 Nov 2006 03:27:01 +0000 (GMT) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kA43R1NR073860 for ; Sat, 4 Nov 2006 03:27:01 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kA43R0r9073857 for perforce@freebsd.org; Sat, 4 Nov 2006 03:27:00 GMT (envelope-from jb@freebsd.org) Date: Sat, 4 Nov 2006 03:27:00 GMT Message-Id: <200611040327.kA43R0r9073857@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 109209 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Nov 2006 03:27:02 -0000 http://perforce.freebsd.org/chv.cgi?CH=109209 Change 109209 by jb@jb_freebsd8 on 2006/11/04 03:26:42 IFlibbsdelf Affected files ... .. //depot/projects/dtrace/src/lib/libelf/Makefile#17 integrate .. //depot/projects/dtrace/src/lib/libelf/_libelf.h#11 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_getscn.3#3 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_scn.c#6 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_shnum.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_update.c#6 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_getshdr.c#5 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_shdr.c#1 branch Differences ... ==== //depot/projects/dtrace/src/lib/libelf/Makefile#17 (text+ko) ==== @@ -43,6 +43,7 @@ libelf_data.c \ libelf_ehdr.c \ libelf_phdr.c \ + libelf_shdr.c \ libelf_xlate.c INCS= libelf.h gelf.h ==== //depot/projects/dtrace/src/lib/libelf/_libelf.h#11 (text+ko) ==== @@ -148,7 +148,8 @@ void (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) (char *_dst, char *_src, size_t _cnt, int _byteswap); void *_libelf_getphdr(Elf *_e, int _elfclass); -int _libelf_getshnum(void *_eh, int _elfclass, size_t *_shnum); +void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); +int _libelf_getshnum(Elf *_e, void *_eh, int _elfclass, size_t *_shnum); int _libelf_getshstrndx(void *_eh, int _elfclass, size_t *_shstrndx); void _libelf_init_elf(Elf *_e, Elf_Kind _kind); int _libelf_malign(Elf_Type _t, int _elfclass); @@ -157,7 +158,7 @@ Elf_Data *_libelf_release_data(Elf_Data *_d); Elf *_libelf_release_elf(Elf *_e); Elf_Scn *_libelf_release_scn(Elf_Scn *_s); -int _libelf_setshnum(void *_eh, int _elfclass, size_t _shnum); +int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); int _libelf_setshstrndx(void *_eh, int _elfclass, size_t _shstrndx); Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, unsigned int _encoding, int _elfclass, int _direction); ==== //depot/projects/dtrace/src/lib/libelf/elf_getscn.3#3 (text+ko) ==== @@ -133,6 +133,14 @@ Descriptor .Ar elf was of an unknown ELF class. +.It Bq Er ELF_E_SECTION +Argument +.Ar elf +specified extended section numbering in the ELF header with the section header at +index +.Dv SHN_UNDEF +not being of type +.Dv SHT_NULL . .El .Sh SEE ALSO .Xr elf 3 , ==== //depot/projects/dtrace/src/lib/libelf/elf_scn.c#6 (text+ko) ==== @@ -41,10 +41,11 @@ static int _libelf_load_scn(Elf *e, void *ehdr) { - int ec; + int ec, swapbytes; size_t fsz, i, shnum; uint64_t shoff; - char *src, *dst; + uint32_t shtype; + char *src; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; Elf_Scn *scn; @@ -79,20 +80,43 @@ xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); + swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); src = e->e_rawfile + shoff; + i = 0; + + if (shnum == (size_t) 0 && shoff != 0LL) { + /* Extended section numbering */ + if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) + return (0); + + (*xlator)((char *) &scn->s_shdr, src, (size_t) 1, swapbytes); + + if (ec == ELFCLASS32) { + shtype = scn->s_shdr.s_shdr32.sh_type; + shnum = scn->s_shdr.s_shdr32.sh_size; + } else { + shtype = scn->s_shdr.s_shdr64.sh_type; + shnum = scn->s_shdr.s_shdr64.sh_size; + } + + if (shtype != SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (0); + } + + scn->s_size = 0LL; + scn->s_offset = scn->s_rawoff = 0LL; - for (i = 0; i < shnum; i++, src += fsz) { + i++; + src += fsz; + } + + for (; i < shnum; i++, src += fsz) { if ((scn = _libelf_allocate_scn(e, i)) == NULL) return (0); - if (ec == ELFCLASS32) - dst = (char *) &scn->s_shdr.s_shdr32; - else - dst = (char *) &scn->s_shdr.s_shdr64; + (*xlator)((char *) &scn->s_shdr, src, (size_t) 1, swapbytes); - (*xlator)(dst, src, (size_t) 1, - e->e_byteorder != LIBELF_PRIVATE(byteorder)); - if (ec == ELFCLASS32) { scn->s_offset = scn->s_rawoff = scn->s_shdr.s_shdr32.sh_offset; @@ -112,7 +136,6 @@ { int ec; void *ehdr; - uint16_t *pshnum; Elf_Scn *s; if (e == NULL || e->e_kind != ELF_K_ELF || @@ -124,16 +147,6 @@ if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (NULL); - if (ec == ELFCLASS32) - pshnum = &((Elf32_Ehdr *) ehdr)->e_shnum; - else - pshnum = &((Elf64_Ehdr *) ehdr)->e_shnum; - - if (index >= *pshnum) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - if (e->e_cmd != ELF_C_WRITE && STAILQ_EMPTY(&e->e_u.e_elf.e_scn) && _libelf_load_scn(e, ehdr) == 0) return (NULL); @@ -142,6 +155,7 @@ if (s->s_ndx == index) return (s); + LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -190,7 +204,7 @@ _libelf_load_scn(e, ehdr) == 0) return (NULL); - if (_libelf_getshnum(ehdr, ec, &shnum) == 0) + if (_libelf_getshnum(e, ehdr, ec, &shnum) == 0) return (NULL); if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { @@ -208,7 +222,7 @@ shnum++; - if (_libelf_setshnum(ehdr, ec, shnum) == 0) + if (_libelf_setshnum(e, ehdr, ec, shnum) == 0) return (NULL); (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); ==== //depot/projects/dtrace/src/lib/libelf/elf_shnum.c#2 (text+ko) ==== @@ -36,54 +36,75 @@ #include "_libelf.h" int -_libelf_getshnum(void *eh, int ec, size_t *shnum) +_libelf_getshnum(Elf *e, void *eh, int ec, size_t *shnum) { - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; Elf64_Off off; + Elf_Scn *scn; + void *sh; size_t n; - eh32 = eh; - eh64 = eh; if (ec == ELFCLASS32) { - n = eh32->e_shnum; - off = (Elf64_Off) eh32->e_shoff; + n = ((Elf32_Ehdr *) eh)->e_shnum; + off = (Elf64_Off) ((Elf32_Ehdr *) eh)->e_shoff; } else { - n = eh64->e_shnum; - off = eh64->e_shoff; + n = ((Elf64_Ehdr *) eh)->e_shnum; + off = ((Elf64_Ehdr *) eh)->e_shoff; + } + + if (n != 0) { + *shnum = n; + return (1); + } + + if (off == 0L) { + *shnum = (size_t) 0; + return (1); } - if (n == 0) - if (off != 0) { - /* TODO */ - LIBELF_SET_ERROR(UNIMPL, 0); - return (0); - } else - *shnum = 0; + /* + * If 'e_shnum' is zero and 'e_shoff' is non-zero, the file is + * using extended section numbering, and the true section + * number is kept in the 'sh_size' field of the section header + * at offset SHN_UNDEF. + */ + if ((scn = elf_getscn(e, SHN_UNDEF)) == NULL) + return (0); + if ((sh = _libelf_getshdr(scn, ec)) == NULL) + return (0); + + if (ec == ELFCLASS32) + *shnum = ((Elf32_Shdr *) sh)->sh_size; else - *shnum = n; + *shnum = ((Elf64_Shdr *) sh)->sh_size; return (1); } int -_libelf_setshnum(void *eh, int ec, size_t shnum) +_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) { - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; + Elf_Scn *scn; + void *sh; - eh32 = eh; - eh64 = eh; + if (shnum < SHN_LORESERVE) { + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shnum = shnum; + else + ((Elf64_Ehdr *) eh)->e_shnum = shnum; + return (1); + } - if (shnum >= SHN_XINDEX) { - LIBELF_SET_ERROR(UNIMPL, 0); + if ((scn = elf_getscn(e, SHN_UNDEF)) == NULL) + return (0); + if ((sh = _libelf_getshdr(scn, ec)) == NULL) return (0); - } - if (ec == ELFCLASS32) { - eh32->e_shnum = shnum; - } else { - eh64->e_shnum = shnum; - } + + if (ec == ELFCLASS32) + ((Elf32_Shdr *) sh)->sh_size = shnum; + else + ((Elf64_Shdr *) sh)->sh_size = shnum; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); return (1); } @@ -101,5 +122,5 @@ return (0); } - return (_libelf_getshnum(eh, ec, shnum)); + return (_libelf_getshnum(e, eh, ec, shnum)); } ==== //depot/projects/dtrace/src/lib/libelf/elf_update.c#6 (text+ko) ==== @@ -76,6 +76,7 @@ int ec; Elf_Data *d, *td; unsigned int elftype; + uint32_t sh_type; uint64_t sh_align, sh_entsize, sh_offset, sh_size; uint64_t scn_size, scn_alignment; @@ -101,19 +102,23 @@ ec = e->e_class; if (ec == ELFCLASS32) { - elftype = _libelf_xlate_shtype(s->s_shdr.s_shdr32.sh_type); + sh_type = s->s_shdr.s_shdr32.sh_type; sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; sh_entsize = (uint64_t) s->s_shdr.s_shdr32.sh_entsize; sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; } else { - elftype = _libelf_xlate_shtype(s->s_shdr.s_shdr64.sh_type); + sh_type = s->s_shdr.s_shdr64.sh_type; sh_align = s->s_shdr.s_shdr64.sh_addralign; sh_entsize = s->s_shdr.s_shdr64.sh_entsize; sh_offset = s->s_shdr.s_shdr64.sh_offset; sh_size = s->s_shdr.s_shdr64.sh_size; } + if (sh_type == SHT_NULL || sh_type == SHT_NOBITS) + return (1); + + elftype = _libelf_xlate_shtype(sh_type); if (elftype > ELF_T_LAST) { LIBELF_SET_ERROR(SECTION, 0); return (0); @@ -356,7 +361,7 @@ return ((off_t) -1); } - if (_libelf_getshnum(ehdr, ec, &shnum) == 0) + if (_libelf_getshnum(e, ehdr, ec, &shnum) == 0) return ((off_t) -1); e->e_byteorder = eh_byteorder; ==== //depot/projects/dtrace/src/lib/libelf/gelf_getshdr.c#5 (text+ko) ==== @@ -36,69 +36,36 @@ Elf32_Shdr * elf32_getshdr(Elf_Scn *s) { - int ec; - Elf *e; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec != ELFCLASS32) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - return (&s->s_shdr.s_shdr32); + return (_libelf_getshdr(s, ELFCLASS32)); } Elf64_Shdr * elf64_getshdr(Elf_Scn *s) { - int ec; - Elf *e; - - if (s == NULL || (e = s->s_elf) == NULL || - e->e_kind != ELF_K_ELF) { - LIBELF_SET_ERROR(ARGUMENT, 0); - return (NULL); - } - - ec = e->e_class; - - assert(ec == ELFCLASS32 || ec == ELFCLASS64); - - if (ec != ELFCLASS64) { - LIBELF_SET_ERROR(CLASS, 0); - return (NULL); - } - - return (&s->s_shdr.s_shdr64); + return (_libelf_getshdr(s, ELFCLASS64)); } GElf_Shdr * gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) { int ec; - Elf *e; + void *sh; Elf32_Shdr *sh32; + Elf64_Shdr *sh64; - if (s == NULL || d == NULL || - (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) { + if (d == NULL) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } - ec = e->e_class; + if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) + return (NULL); + + ec = s->s_elf->e_class; assert(ec == ELFCLASS32 || ec == ELFCLASS64); if (ec == ELFCLASS32) { - sh32 = &s->s_shdr.s_shdr32; + sh32 = (Elf32_Shdr *) sh; d->sh_name = sh32->sh_name; d->sh_type = sh32->sh_type; @@ -110,8 +77,10 @@ d->sh_info = sh32->sh_info; d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; - } else - *d = s->s_shdr.s_shdr64; + } else { + sh64 = (Elf64_Shdr *) sh; + *d = *sh64; + } return (d); }