libelf_extended.c revision 4484:7c56a6c9c265
15245Sgblack@eecs.umich.edu/*-
28948Sandreas.hansson@arm.com * Copyright (c) 2006 Joseph Koshy
38948Sandreas.hansson@arm.com * All rights reserved.
48948Sandreas.hansson@arm.com *
58948Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68948Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions
78948Sandreas.hansson@arm.com * are met:
88948Sandreas.hansson@arm.com * 1. Redistributions of source code must retain the above copyright
98948Sandreas.hansson@arm.com *    notice, this list of conditions and the following disclaimer.
108948Sandreas.hansson@arm.com * 2. Redistributions in binary form must reproduce the above copyright
118948Sandreas.hansson@arm.com *    notice, this list of conditions and the following disclaimer in the
128948Sandreas.hansson@arm.com *    documentation and/or other materials provided with the distribution.
138948Sandreas.hansson@arm.com *
145245Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
155245Sgblack@eecs.umich.edu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165245Sgblack@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
177087Snate@binkert.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
187087Snate@binkert.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
197087Snate@binkert.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
207087Snate@binkert.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
217087Snate@binkert.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
227087Snate@binkert.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
237087Snate@binkert.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
247087Snate@binkert.org * SUCH DAMAGE.
255245Sgblack@eecs.umich.edu */
267087Snate@binkert.org
277087Snate@binkert.org#include <assert.h>
287087Snate@binkert.org#include "libelf.h"
297087Snate@binkert.org
307087Snate@binkert.org#include "_libelf.h"
317087Snate@binkert.org
327087Snate@binkert.org/*
337087Snate@binkert.org * Retrieve section #0, allocating a new section if needed.
345245Sgblack@eecs.umich.edu */
357087Snate@binkert.orgstatic Elf_Scn *
365245Sgblack@eecs.umich.edu_libelf_getscn0(Elf *e)
375245Sgblack@eecs.umich.edu{
385245Sgblack@eecs.umich.edu        Elf_Scn *s;
395245Sgblack@eecs.umich.edu
405245Sgblack@eecs.umich.edu        if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL)
415245Sgblack@eecs.umich.edu                return (s);
425245Sgblack@eecs.umich.edu
435245Sgblack@eecs.umich.edu        return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF));
445245Sgblack@eecs.umich.edu}
455245Sgblack@eecs.umich.edu
465245Sgblack@eecs.umich.eduint
475245Sgblack@eecs.umich.edu_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum)
485245Sgblack@eecs.umich.edu{
495245Sgblack@eecs.umich.edu        Elf_Scn *scn;
505245Sgblack@eecs.umich.edu
515245Sgblack@eecs.umich.edu        if (shnum >= SHN_LORESERVE) {
525245Sgblack@eecs.umich.edu                if ((scn = _libelf_getscn0(e)) == NULL)
535245Sgblack@eecs.umich.edu                        return (0);
545245Sgblack@eecs.umich.edu
557912Shestness@cs.utexas.edu                assert(scn->s_ndx == SHN_UNDEF);
565245Sgblack@eecs.umich.edu
578953Sgblack@eecs.umich.edu                if (ec == ELFCLASS32)
588229Snate@binkert.org                        scn->s_shdr.s_shdr32.sh_size = shnum;
595245Sgblack@eecs.umich.edu                else
608232Snate@binkert.org                        scn->s_shdr.s_shdr64.sh_size = shnum;
615245Sgblack@eecs.umich.edu
625245Sgblack@eecs.umich.edu                (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
635245Sgblack@eecs.umich.edu
645245Sgblack@eecs.umich.edu                shnum = 0;
655245Sgblack@eecs.umich.edu        }
665245Sgblack@eecs.umich.edu
675245Sgblack@eecs.umich.edu        if (ec == ELFCLASS32)
685245Sgblack@eecs.umich.edu                ((Elf32_Ehdr *) eh)->e_shnum = shnum;
695245Sgblack@eecs.umich.edu        else
705245Sgblack@eecs.umich.edu                ((Elf64_Ehdr *) eh)->e_shnum = shnum;
715245Sgblack@eecs.umich.edu
725245Sgblack@eecs.umich.edu
735245Sgblack@eecs.umich.edu        return (1);
745245Sgblack@eecs.umich.edu}
755245Sgblack@eecs.umich.edu
765245Sgblack@eecs.umich.eduint
775245Sgblack@eecs.umich.edu_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx)
785245Sgblack@eecs.umich.edu{
795245Sgblack@eecs.umich.edu        Elf_Scn *scn;
805245Sgblack@eecs.umich.edu
815245Sgblack@eecs.umich.edu        if (shstrndx >= SHN_LORESERVE) {
825245Sgblack@eecs.umich.edu                if ((scn = _libelf_getscn0(e)) == NULL)
835895Sgblack@eecs.umich.edu                        return (0);
847912Shestness@cs.utexas.edu
857912Shestness@cs.utexas.edu                assert(scn->s_ndx == SHN_UNDEF);
865245Sgblack@eecs.umich.edu
877912Shestness@cs.utexas.edu                if (ec == ELFCLASS32)
887912Shestness@cs.utexas.edu                        scn->s_shdr.s_shdr32.sh_link = shstrndx;
897912Shestness@cs.utexas.edu                else
907912Shestness@cs.utexas.edu                        scn->s_shdr.s_shdr64.sh_link = shstrndx;
917912Shestness@cs.utexas.edu
927912Shestness@cs.utexas.edu                (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
937912Shestness@cs.utexas.edu
947912Shestness@cs.utexas.edu                shstrndx = SHN_XINDEX;
957912Shestness@cs.utexas.edu        }
967912Shestness@cs.utexas.edu
977912Shestness@cs.utexas.edu        if (ec == ELFCLASS32)
987912Shestness@cs.utexas.edu                ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx;
997912Shestness@cs.utexas.edu        else
1007912Shestness@cs.utexas.edu                ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx;
1017912Shestness@cs.utexas.edu
1027912Shestness@cs.utexas.edu        return (1);
1035895Sgblack@eecs.umich.edu}
1047912Shestness@cs.utexas.edu
1055245Sgblack@eecs.umich.eduint
1065245Sgblack@eecs.umich.edu_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum)
1075245Sgblack@eecs.umich.edu{
1085895Sgblack@eecs.umich.edu        Elf_Scn *scn;
1098953Sgblack@eecs.umich.edu
1107912Shestness@cs.utexas.edu        if (phnum >= PN_XNUM) {
1115245Sgblack@eecs.umich.edu                if ((scn = _libelf_getscn0(e)) == NULL)
1127912Shestness@cs.utexas.edu                        return (0);
1138953Sgblack@eecs.umich.edu
1145245Sgblack@eecs.umich.edu                assert(scn->s_ndx == SHN_UNDEF);
1155245Sgblack@eecs.umich.edu
1165245Sgblack@eecs.umich.edu                if (ec == ELFCLASS32)
1178975Sandreas.hansson@arm.com                        scn->s_shdr.s_shdr32.sh_info = phnum;
1185245Sgblack@eecs.umich.edu                else
1198975Sandreas.hansson@arm.com                        scn->s_shdr.s_shdr64.sh_info = phnum;
1205245Sgblack@eecs.umich.edu
1215245Sgblack@eecs.umich.edu                (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
1225245Sgblack@eecs.umich.edu
1238975Sandreas.hansson@arm.com                phnum = PN_XNUM;
1245245Sgblack@eecs.umich.edu        }
1258948Sandreas.hansson@arm.com
1268948Sandreas.hansson@arm.com        if (ec == ELFCLASS32)
1278948Sandreas.hansson@arm.com                ((Elf32_Ehdr *) eh)->e_phnum = phnum;
1288948Sandreas.hansson@arm.com        else
1298948Sandreas.hansson@arm.com                ((Elf64_Ehdr *) eh)->e_phnum = phnum;
1308948Sandreas.hansson@arm.com
1318948Sandreas.hansson@arm.com        return (1);
1328948Sandreas.hansson@arm.com}
1338948Sandreas.hansson@arm.com
1348948Sandreas.hansson@arm.com