PERFORCE change 109209 for review
John Birrell
jb at FreeBSD.org
Sat Nov 4 03:27:02 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109209
Change 109209 by jb at 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);
}
More information about the p4-projects
mailing list