Path: blob/main/contrib/elftoolchain/libpe/pe_section.c
39483 views
/*-1* Copyright (c) 2016 Kai Wang2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <errno.h>27#include <string.h>2829#include "_libpe.h"3031ELFTC_VCSID("$Id: pe_section.c 3312 2016-01-10 09:23:51Z kaiwang27 $");3233PE_Scn *34pe_getscn(PE *pe, size_t ndx)35{36PE_Scn *ps;3738if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {39errno = EINVAL;40return (NULL);41}4243STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) {44if (ps->ps_ndx == ndx)45return (ps);46}4748errno = ENOENT;4950return (NULL);51}5253size_t54pe_ndxscn(PE_Scn *ps)55{5657if (ps == NULL) {58errno = EINVAL;59return (0);60}6162return (ps->ps_ndx);63}6465PE_Scn *66pe_nextscn(PE *pe, PE_Scn *ps)67{6869if (pe == NULL) {70errno = EINVAL;71return (NULL);72}7374if (ps == NULL)75ps = STAILQ_FIRST(&pe->pe_scn);76else77ps = STAILQ_NEXT(ps, ps_next);7879while (ps != NULL) {80if (ps->ps_ndx >= 1 && ps->ps_ndx <= 0xFFFFU)81return (ps);82ps = STAILQ_NEXT(ps, ps_next);83}8485return (NULL);86}8788PE_Scn *89pe_newscn(PE *pe)90{91PE_Scn *ps, *tps, *_tps;9293if (pe == NULL) {94errno = EINVAL;95return (NULL);96}9798if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {99errno = EACCES;100return (NULL);101}102103if ((ps = libpe_alloc_scn(pe)) == NULL)104return (NULL);105106if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {107STAILQ_FOREACH_SAFE(tps, &pe->pe_scn, ps_next, _tps)108libpe_release_scn(tps);109pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;110}111112STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);113114ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;115pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;116117return (ps);118}119120PE_Scn *121pe_insertscn(PE *pe, size_t ndx)122{123PE_Scn *ps, *a, *b;124125if (pe == NULL || ndx < 1 || ndx > 0xFFFFU) {126errno = EINVAL;127return (NULL);128}129130if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {131errno = EACCES;132return (NULL);133}134135if ((ps = libpe_alloc_scn(pe)) == NULL)136return (NULL);137138if (pe->pe_flags & LIBPE_F_BAD_SEC_HEADER) {139STAILQ_FOREACH_SAFE(a, &pe->pe_scn, ps_next, b)140libpe_release_scn(a);141pe->pe_flags &= ~LIBPE_F_BAD_SEC_HEADER;142}143144b = NULL;145STAILQ_FOREACH(a, &pe->pe_scn, ps_next) {146if (a->ps_ndx & 0xFFFF0000U)147continue;148if (a->ps_ndx == ndx)149break;150b = a;151}152153if (a == NULL) {154STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);155if (b == NULL)156ps->ps_ndx = 1;157else158ps->ps_ndx = b->ps_ndx + 1;159} else if (b == NULL) {160STAILQ_INSERT_HEAD(&pe->pe_scn, ps, ps_next);161ps->ps_ndx = 1;162} else {163STAILQ_INSERT_AFTER(&pe->pe_scn, b, ps, ps_next);164ps->ps_ndx = ndx;165}166167a = ps;168while ((a = STAILQ_NEXT(a, ps_next)) != NULL) {169if ((a->ps_ndx & 0xFFFF0000U) == 0)170a->ps_ndx++;171}172173ps->ps_flags |= PE_F_DIRTY | LIBPE_F_LOAD_SECTION;174pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;175176return (ps);177}178179PE_SecHdr *180pe_section_header(PE_Scn *ps)181{182183if (ps == NULL) {184errno = EINVAL;185return (NULL);186}187188return (&ps->ps_sh);189}190191int192pe_update_section_header(PE_Scn *ps, PE_SecHdr *sh)193{194PE *pe;195196if (ps == NULL || sh == NULL) {197errno = EINVAL;198return (-1);199}200201pe = ps->ps_pe;202203if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {204errno = EACCES;205return (-1);206}207208ps->ps_sh = *sh;209pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER;210211return (0);212}213214215