Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/elftoolchain/libelf/elf_scn.c
Show All 32 Lines | |||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "_libelf.h" | #include "_libelf.h" | ||||
ELFTC_VCSID("$Id: elf_scn.c 3632 2018-10-10 21:12:43Z jkoshy $"); | ELFTC_VCSID("$Id: elf_scn.c 3632 2018-10-10 21:12:43Z jkoshy $"); | ||||
static int | |||||
elfscn_cmp(struct _Elf_Scn *s1, struct _Elf_Scn *s2) | |||||
{ | |||||
if (s1->s_ndx < s2->s_ndx) | |||||
return (-1); | |||||
if (s1->s_ndx > s2->s_ndx) | |||||
return (1); | |||||
return (0); | |||||
} | |||||
RB_GENERATE(scntree, _Elf_Scn, s_tree, elfscn_cmp); | |||||
/* | /* | ||||
* Load an ELF section table and create a list of Elf_Scn structures. | * Load an ELF section table and create a list of Elf_Scn structures. | ||||
*/ | */ | ||||
int | int | ||||
_libelf_load_section_headers(Elf *e, void *ehdr) | _libelf_load_section_headers(Elf *e, void *ehdr) | ||||
{ | { | ||||
Elf_Scn *scn; | Elf_Scn *scn; | ||||
uint64_t shoff; | uint64_t shoff; | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | #define CHECK_EHDR(E,EH) do { \ | ||||
src = e->e_rawfile + shoff; | src = e->e_rawfile + shoff; | ||||
/* | /* | ||||
* If the file is using extended numbering then section #0 | * If the file is using extended numbering then section #0 | ||||
* would have already been read in. | * would have already been read in. | ||||
*/ | */ | ||||
i = 0; | i = 0; | ||||
if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { | if (!RB_EMPTY(&e->e_u.e_elf.e_scn)) { | ||||
assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == | assert(RB_MIN(scntree, &e->e_u.e_elf.e_scn) == | ||||
STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); | RB_MAX(scntree, &e->e_u.e_elf.e_scn)); | ||||
i = 1; | i = 1; | ||||
src += fsz; | src += fsz; | ||||
} | } | ||||
for (; i < shnum; i++, src += fsz) { | for (; i < shnum; i++, src += fsz) { | ||||
if ((scn = _libelf_allocate_scn(e, i)) == NULL) | if ((scn = _libelf_allocate_scn(e, i)) == NULL) | ||||
return (0); | return (0); | ||||
Show All 34 Lines | elf_getscn(Elf *e, size_t index) | ||||
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) | if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (e->e_cmd != ELF_C_WRITE && | if (e->e_cmd != ELF_C_WRITE && | ||||
(e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && | (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && | ||||
_libelf_load_section_headers(e, ehdr) == 0) | _libelf_load_section_headers(e, ehdr) == 0) | ||||
return (NULL); | return (NULL); | ||||
STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) | for (s = RB_ROOT(&e->e_u.e_elf.e_scn); s != NULL;) { | ||||
if (s->s_ndx == index) | if (s->s_ndx == index) | ||||
return (s); | return (s); | ||||
if (s->s_ndx < index) | |||||
s = RB_RIGHT(s, s_tree); | |||||
else | |||||
s = RB_LEFT(s, s_tree); | |||||
} | |||||
LIBELF_SET_ERROR(ARGUMENT, 0); | LIBELF_SET_ERROR(ARGUMENT, 0); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
size_t | size_t | ||||
elf_ndxscn(Elf_Scn *s) | elf_ndxscn(Elf_Scn *s) | ||||
{ | { | ||||
if (s == NULL) { | if (s == NULL) { | ||||
Show All 33 Lines | elf_newscn(Elf *e) | ||||
* file using ELF_C_READ, mess with its internal structure and | * file using ELF_C_READ, mess with its internal structure and | ||||
* use elf_update(...,ELF_C_NULL) to compute its new layout. | * use elf_update(...,ELF_C_NULL) to compute its new layout. | ||||
*/ | */ | ||||
if (e->e_cmd != ELF_C_WRITE && | if (e->e_cmd != ELF_C_WRITE && | ||||
(e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && | (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && | ||||
_libelf_load_section_headers(e, ehdr) == 0) | _libelf_load_section_headers(e, ehdr) == 0) | ||||
return (NULL); | return (NULL); | ||||
if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { | if (RB_EMPTY(&e->e_u.e_elf.e_scn)) { | ||||
assert(e->e_u.e_elf.e_nscn == 0); | assert(e->e_u.e_elf.e_nscn == 0); | ||||
if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == | if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == | ||||
NULL) | NULL) | ||||
return (NULL); | return (NULL); | ||||
e->e_u.e_elf.e_nscn++; | e->e_u.e_elf.e_nscn++; | ||||
} | } | ||||
assert(e->e_u.e_elf.e_nscn > 0); | assert(e->e_u.e_elf.e_nscn > 0); | ||||
Show All 13 Lines | |||||
{ | { | ||||
if (e == NULL || (e->e_kind != ELF_K_ELF) || | if (e == NULL || (e->e_kind != ELF_K_ELF) || | ||||
(s && s->s_elf != e)) { | (s && s->s_elf != e)) { | ||||
LIBELF_SET_ERROR(ARGUMENT, 0); | LIBELF_SET_ERROR(ARGUMENT, 0); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
return (s == NULL ? elf_getscn(e, (size_t) 1) : | return (s == NULL ? elf_getscn(e, (size_t) 1) : | ||||
STAILQ_NEXT(s, s_next)); | RB_NEXT(scntree, &e->e_u.e_elf.e_scn, s)); | ||||
} | } |