diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2006-11-11 17:16:35 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2006-11-11 17:16:35 +0000 |
commit | 62913629e64cdad23072cfd4ad8340f4c0b91ec5 (patch) | |
tree | c2ad604787a38d6ad26a0bffea71f283f73e901d /lib/libelf/elf_shstrndx.c | |
parent | c51a2c2df9d95524e4fec5b0ec36ca0a9f503823 (diff) | |
download | FreeBSD-src-62913629e64cdad23072cfd4ad8340f4c0b91ec5.zip FreeBSD-src-62913629e64cdad23072cfd4ad8340f4c0b91ec5.tar.gz |
MFP4: Add an implementation of the ELF(3) and GELF(3) API set.
Bump __FreeBSD_version.
Reviewed by: jb
Diffstat (limited to 'lib/libelf/elf_shstrndx.c')
-rw-r--r-- | lib/libelf/elf_shstrndx.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/libelf/elf_shstrndx.c b/lib/libelf/elf_shstrndx.c new file mode 100644 index 0000000..cae25c3 --- /dev/null +++ b/lib/libelf/elf_shstrndx.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2006 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <ar.h> +#include <libelf.h> + +#include "_libelf.h" + +/* + * Helpers to get/set the e_shstrndx field of the ELF header. + */ + +int +_libelf_getshstrndx(Elf *e, void *eh, int ec, size_t *strndx) +{ + Elf_Scn *scn; + void *sh; + size_t n; + + n = (ec == ELFCLASS32) ? ((Elf32_Ehdr *) eh)->e_shstrndx : + ((Elf64_Ehdr *) eh)->e_shstrndx; + + if (n < SHN_LORESERVE) { + *strndx = n; + return (1); + } + + if ((scn = elf_getscn(e, (size_t) SHN_UNDEF)) == NULL) + return (0); + if ((sh = _libelf_getshdr(scn, ec)) == NULL) + return (0); + + if (ec == ELFCLASS32) + *strndx = ((Elf32_Shdr *) sh)->sh_link; + else + *strndx = ((Elf64_Shdr *) sh)->sh_link; + + return (1); +} + +int +_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t strndx) +{ + Elf_Scn *scn; + void *sh; + + if (strndx < SHN_LORESERVE) { + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shstrndx = strndx; + else + ((Elf64_Ehdr *) eh)->e_shstrndx = strndx; + return (1); + } + + if ((scn = elf_getscn(e, (size_t) SHN_UNDEF)) == NULL) + return (0); + if ((sh = _libelf_getshdr(scn, ec)) == NULL) + return (0); + + if (ec == ELFCLASS32) { + ((Elf32_Ehdr *) eh)->e_shstrndx = SHN_XINDEX; + ((Elf32_Shdr *) sh)->sh_link = strndx; + } else { + ((Elf64_Ehdr *) eh)->e_shstrndx = SHN_XINDEX; + ((Elf64_Shdr *) sh)->sh_link = strndx; + } + + return (1); +} + +int +elf_getshstrndx(Elf *e, size_t *strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + return (_libelf_getshstrndx(e, eh, ec, strndx)); +} + +int +elf_setshstrndx(Elf *e, size_t strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + return (_libelf_setshstrndx(e, eh, ec, strndx)); +} |