- Correctly handle sections of type SHT_NOBITS. For these sections:
- elf_getdata() and elf_rawdata() should return an "Elf_Data" structure that has its "d_buf" member set to NULL and "d_size" member set to the nominal 'size' of the section. [1] - Update the manual page for these functions. - Fix a memory leak in an error handling path inside elf_getdata(). - Use _libelf_allocate_data() in elf_newdata() for consistency. Obtained from: elftoolchain MFC after: 1 month
This commit is contained in:
parent
6a464b6e13
commit
19ba81c75a
@ -39,7 +39,6 @@ Elf_Data *
|
||||
elf_getdata(Elf_Scn *s, Elf_Data *d)
|
||||
{
|
||||
Elf *e;
|
||||
char *dst;
|
||||
size_t fsz, msz, count;
|
||||
int elfclass, elftype;
|
||||
unsigned int sh_type;
|
||||
@ -79,20 +78,22 @@ elf_getdata(Elf_Scn *s, Elf_Data *d)
|
||||
sh_align = s->s_shdr.s_shdr64.sh_addralign;
|
||||
}
|
||||
|
||||
if (sh_type == SHT_NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
|
||||
elftype > ELF_T_LAST ||
|
||||
sh_offset + sh_size > (uint64_t) e->e_rawsize) {
|
||||
elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
|
||||
sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
|
||||
LIBELF_SET_ERROR(SECTION, 0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)(elftype,
|
||||
(size_t) 1, e->e_version)) == 0) {
|
||||
if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
|
||||
(elftype, (size_t) 1, e->e_version)) == 0) {
|
||||
LIBELF_SET_ERROR(UNIMPL, 0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
if (sh_size % fsz) {
|
||||
LIBELF_SET_ERROR(SECTION, 0);
|
||||
return (NULL);
|
||||
@ -104,21 +105,25 @@ elf_getdata(Elf_Scn *s, Elf_Data *d)
|
||||
|
||||
assert(msz > 0);
|
||||
|
||||
if ((dst = malloc(msz*count)) == NULL) {
|
||||
LIBELF_SET_ERROR(RESOURCE, 0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((d = _libelf_allocate_data(s)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
d->d_buf = dst;
|
||||
d->d_buf = NULL;
|
||||
d->d_off = 0;
|
||||
d->d_align = sh_align;
|
||||
d->d_size = msz * count;
|
||||
d->d_type = elftype;
|
||||
d->d_version = e->e_version;
|
||||
|
||||
if (sh_type == SHT_NOBITS)
|
||||
return (d);
|
||||
|
||||
if ((d->d_buf = malloc(msz*count)) == NULL) {
|
||||
(void) _libelf_release_data(d);
|
||||
LIBELF_SET_ERROR(RESOURCE, 0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
d->d_flags |= LIBELF_F_MALLOCED;
|
||||
STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
|
||||
|
||||
@ -149,14 +154,10 @@ elf_newdata(Elf_Scn *s)
|
||||
if (elf_getdata(s, NULL) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((d = malloc(sizeof(Elf_Data))) == NULL) {
|
||||
LIBELF_SET_ERROR(RESOURCE, errno);
|
||||
if ((d = _libelf_allocate_data(s)) == NULL)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
|
||||
d->d_flags = 0;
|
||||
d->d_scn = s;
|
||||
|
||||
d->d_align = 1;
|
||||
d->d_buf = NULL;
|
||||
@ -180,6 +181,7 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d)
|
||||
{
|
||||
Elf *e;
|
||||
int elf_class;
|
||||
uint32_t sh_type;
|
||||
uint64_t sh_align, sh_offset, sh_size;
|
||||
|
||||
if (s == NULL || (e = s->s_elf) == NULL ||
|
||||
@ -199,19 +201,24 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d)
|
||||
assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64);
|
||||
|
||||
if (elf_class == ELFCLASS32) {
|
||||
sh_type = s->s_shdr.s_shdr32.sh_type;
|
||||
sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
|
||||
sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size;
|
||||
sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
|
||||
} else {
|
||||
sh_type = s->s_shdr.s_shdr64.sh_type;
|
||||
sh_offset = s->s_shdr.s_shdr64.sh_offset;
|
||||
sh_size = s->s_shdr.s_shdr64.sh_size;
|
||||
sh_align = s->s_shdr.s_shdr64.sh_addralign;
|
||||
}
|
||||
|
||||
if (sh_type == SHT_NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((d = _libelf_allocate_data(s)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
d->d_buf = e->e_rawfile + sh_offset;
|
||||
d->d_buf = sh_type == SHT_NOBITS ? NULL : e->e_rawfile + sh_offset;
|
||||
d->d_off = 0;
|
||||
d->d_align = sh_align;
|
||||
d->d_size = sh_size;
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2006 Joseph Koshy. All rights reserved.
|
||||
.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -142,6 +142,32 @@ always returns
|
||||
.Vt Elf_Data
|
||||
structures of type
|
||||
.Dv ELF_T_BYTE .
|
||||
.Ss Special handling of SHT_NOBITS sections
|
||||
For sections of type
|
||||
.Dv SHT_NOBITS ,
|
||||
the functions
|
||||
.Fn elf_getdata
|
||||
and
|
||||
.Fn elf_rawdata
|
||||
return a pointer to a valid
|
||||
.Vt Elf_Data
|
||||
structure that has its
|
||||
.Va d_buf
|
||||
member set to NULL and its
|
||||
.Va d_size
|
||||
member set to the size of the section.
|
||||
.Pp
|
||||
If an application wishes to create a section of type
|
||||
.Dv SHT_NOBITS ,
|
||||
it should add a data buffer to the section using function
|
||||
.Fn elf_newdata .
|
||||
It should then set the
|
||||
.Va d_buf
|
||||
and
|
||||
.Va d_size
|
||||
members of the returned
|
||||
.Vt Elf_Data
|
||||
structure to NULL and the desired size of the section respectively.
|
||||
.Sh RETURN VALUES
|
||||
These functions return a valid pointer to a data descriptor if successful, or
|
||||
NULL if an error occurs.
|
||||
|
Loading…
Reference in New Issue
Block a user