gelf.c revision 30da143285931291f495cc20b5a1b8869f0618a6
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * CDDL HEADER START
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov *
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * The contents of this file are subject to the terms of the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Common Development and Distribution License, Version 1.0 only
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * (the "License"). You may not use this file except in compliance
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * with the License.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * or http://www.opensolaris.org/os/licensing.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * See the License for the specific language governing permissions
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * and limitations under the License.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * CDDL HEADER END
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Use is subject to license terms.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#pragma ident "%Z%%M% %I% %E% SMI"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <string.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "gelf.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "decl.h"
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#include "msg.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Find elf or it's class from a pointer to an Elf_Data struct.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Warning: this Assumes that the Elf_Data is part of a libelf
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Dnode structure, which is expected to be true for any Elf_Data
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * passed into libelf *except* for the xlatetof() and xlatetom() functions.
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#define EDATA_CLASS(edata) \
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore (((Dnode *)(edata))->db_scn->s_elf->ed_class)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#define EDATA_ELF(edata) \
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov (((Dnode *)(edata))->db_scn->s_elf)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#define EDATA_SCN(edata) \
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore (((Dnode *)(edata))->db_scn)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#define EDATA_READLOCKS(edata) \
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#define EDATA_READUNLOCKS(edata) \
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoresize_t
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoregelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore int class;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (elf == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore class = gelf_getclass(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf32_fsize(type, count, ver));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore else if (class == ELFCLASS64)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf64_fsize(type, count, ver));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_getclass(Elf *elf)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (elf == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Don't rely on the idents, a new ehdr doesn't have it!
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (elf->ed_class);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'AmoreGElf_Ehdr *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoregelf_getehdr(Elf *elf, GElf_Ehdr *dst)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore int class;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (elf == NULL)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return (NULL);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov class = gelf_getclass(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (class == ELFCLASS32) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore Elf32_Ehdr * e = elf32_getehdr(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (e == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (NULL);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFRLOCK(elf);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov (void) memcpy(dst->e_ident, e->e_ident, EI_NIDENT);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov dst->e_type = e->e_type;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->e_machine = e->e_machine;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->e_version = e->e_version;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->e_entry = (Elf64_Addr)e->e_entry;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->e_phoff = (Elf64_Off)e->e_phoff;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->e_shoff = (Elf64_Off)e->e_shoff;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_flags = e->e_flags;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_ehsize = e->e_ehsize;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_phentsize = e->e_phentsize;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_phnum = e->e_phnum;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_shentsize = e->e_shentsize;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_shnum = e->e_shnum;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->e_shstrndx = e->e_shstrndx;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ELFUNLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (dst);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov } else if (class == ELFCLASS64) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf64_Ehdr * e = elf64_getehdr(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (e == NULL)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (NULL);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFRLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = *e;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ELFUNLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_update_ehdr(Elf *elf, GElf_Ehdr *src)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (elf == NULL)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (0);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * In case elf isn't cooked.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov class = gelf_getclass(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASSNONE)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov class = src->e_ident[EI_CLASS];
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (class == ELFCLASS32) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov Elf32_Ehdr * d = elf32_getehdr(elf);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (d == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFWLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore (void) memcpy(d->e_ident, src->e_ident, EI_NIDENT);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->e_type = src->e_type;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->e_machine = src->e_machine;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_version = src->e_version;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* LINTED */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_entry = (Elf32_Addr)src->e_entry;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* LINTED */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_phoff = (Elf32_Off)src->e_phoff;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* LINTED */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_shoff = (Elf32_Off)src->e_shoff;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* could memcpy the rest of these... */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_flags = src->e_flags;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_ehsize = src->e_ehsize;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov d->e_phentsize = src->e_phentsize;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_phnum = src->e_phnum;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore d->e_shentsize = src->e_shentsize;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->e_shnum = src->e_shnum;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore d->e_shstrndx = src->e_shstrndx;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if (class == ELFCLASS64) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf64_Ehdr * d = elf64_getehdr(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (d == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFWLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore *d = *(Elf64_Ehdr *)src;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFUNLOCK(elf);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (1);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreunsigned long
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovgelf_newehdr(Elf *elf, int class)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (elf == NULL)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return ((unsigned long)elf32_newehdr(elf));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore else if (class == ELFCLASS64)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return ((unsigned long)elf64_newehdr(elf));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri PankovGElf_Phdr *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoregelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov size_t phnum;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (elf == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (elf_getphnum(elf, &phnum) == 0)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (NULL);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (phnum <= ndx) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov _elf_seterr(EREQ_RAND, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = gelf_getclass(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ((class != ELFCLASS32) && (class != ELFCLASS64)) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (class == ELFCLASS32) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf32_Phdr *p = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFRLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_type = p->p_type;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_flags = p->p_flags;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_offset = (Elf64_Off)p->p_offset;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_vaddr = (Elf64_Addr)p->p_vaddr;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_paddr = (Elf64_Addr)p->p_paddr;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_filesz = (Elf64_Xword)p->p_filesz;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_memsz = (Elf64_Xword)p->p_memsz;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_align = (Elf64_Xword)p->p_align;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFUNLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else if (class == ELFCLASS64) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf64_Phdr *phdrs = elf64_getphdr(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFRLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = ((GElf_Phdr *)phdrs)[ndx];
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFUNLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return (dst);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreint
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovgelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore int class;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore size_t phnum;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (elf == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (elf_getphnum(elf, &phnum) == 0)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (NULL);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if (phnum < ndx) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore _elf_seterr(EREQ_RAND, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = gelf_getclass(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov Elf32_Phdr *dst = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFWLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_type = src->p_type;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_flags = src->p_flags;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_offset = (Elf32_Off)src->p_offset;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_vaddr = (Elf32_Addr)src->p_vaddr;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_paddr = (Elf32_Addr)src->p_paddr;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_filesz = (Elf32_Word)src->p_filesz;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->p_memsz = (Elf32_Word)src->p_memsz;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->p_align = (Elf32_Word)src->p_align;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else if (class == ELFCLASS64) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov Elf64_Phdr *dst = elf64_getphdr(elf);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ELFWLOCK(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst[ndx] = *(GElf_Phdr *)src;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(elf);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov } else {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovunsigned long
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_newphdr(Elf *elf, size_t phnum)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (elf == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov class = gelf_getclass(elf);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (class == ELFCLASS32)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return ((unsigned long)elf32_newphdr(elf, phnum));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov else if (class == ELFCLASS64)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return ((unsigned long)elf64_newphdr(elf, phnum));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov _elf_seterr(EREQ_CLASS, 0);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (0);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri PankovGElf_Shdr *
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovgelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if (scn == NULL)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (NULL);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (scn->s_elf->ed_class == ELFCLASS32) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf32_Shdr *s = elf32_getshdr(scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (s == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov READLOCKS(scn->s_elf, scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_name = s->sh_name;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_type = s->sh_type;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_flags = (Elf64_Xword)s->sh_flags;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_addr = (Elf64_Addr)s->sh_addr;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_offset = (Elf64_Off)s->sh_offset;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_size = (Elf64_Xword)s->sh_size;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_link = s->sh_link;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_info = s->sh_info;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_addralign = (Elf64_Xword)s->sh_addralign;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_entsize = (Elf64_Xword)s->sh_entsize;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore READUNLOCKS(scn->s_elf, scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if (scn->s_elf->ed_class == ELFCLASS64) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf64_Shdr *s = elf64_getshdr(scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (s == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore READLOCKS(scn->s_elf, scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = *(Elf64_Shdr *)s;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore READUNLOCKS(scn->s_elf, scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoregelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (scn == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (scn->s_elf->ed_class == ELFCLASS32) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore Elf32_Shdr *dst = elf32_getshdr(scn);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (dst == NULL)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (0);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ELFWLOCK(scn->s_elf);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_name = src->sh_name;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->sh_type = src->sh_type;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* LINTED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_flags = (Elf32_Word)src->sh_flags;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov dst->sh_addr = (Elf32_Addr)src->sh_addr;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_offset = (Elf32_Off) src->sh_offset;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_size = (Elf32_Word)src->sh_size;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_link = src->sh_link;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore dst->sh_info = src->sh_info;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* LINTED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_addralign = (Elf32_Word)src->sh_addralign;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* LINTED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->sh_entsize = (Elf32_Word)src->sh_entsize;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(scn->s_elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if (scn->s_elf->ed_class == ELFCLASS64) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf64_Shdr * dst = elf64_getshdr(scn);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (dst == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFWLOCK(scn->s_elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = *(Elf64_Shdr *)src;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(scn->s_elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * gelf_xlatetof/gelf_xlatetom use 'elf' to find the class
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * because these are the odd case where the Elf_Data structs
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * might not have been allocated by libelf (and therefore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * don't have Dnode's associated with them).
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'AmoreElf_Data *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ((elf == NULL) || (dst == NULL) || (src == NULL))
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov class = gelf_getclass(elf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf32_xlatetof(dst, src, encode));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore else if (class == ELFCLASS64)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf64_xlatetof(dst, src, encode));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'AmoreElf_Data *
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovgelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ((elf == NULL) || (dst == NULL) || (src == NULL))
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = gelf_getclass(elf);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf32_xlatetom(dst, src, encode));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore else if (class == ELFCLASS64)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (elf64_xlatetom(dst, src, encode));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'AmoreGElf_Sym *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore size_t entsize;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (data == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = EDATA_CLASS(data);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov entsize = sizeof (Elf32_Sym);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore else if (class == ELFCLASS64)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore entsize = sizeof (GElf_Sym);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov else {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov EDATA_READLOCKS(data);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ((entsize * ndx) > data->d_size) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov _elf_seterr(EREQ_RAND, 0);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov dst = NULL;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov } else if (class == ELFCLASS32) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov Elf32_Sym *s;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov s = &(((Elf32_Sym *)data->d_buf)[ndx]);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov dst->st_name = s->st_name;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->st_value = (Elf64_Addr)s->st_value;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->st_size = (Elf64_Xword)s->st_size;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(s->st_info),
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov ELF32_ST_TYPE(s->st_info));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->st_other = s->st_other;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov dst->st_shndx = s->st_shndx;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = ((GElf_Sym *)data->d_buf)[ndx];
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov EDATA_READUNLOCKS(data);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov int class, rc = 1;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov size_t entsize;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (dst == NULL)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov class = EDATA_CLASS(dst);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if (class == ELFCLASS32)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov entsize = sizeof (Elf32_Sym);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov else if (class == ELFCLASS64)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov entsize = sizeof (GElf_Sym);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov else {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov _elf_seterr(EREQ_CLASS, 0);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return (0);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ELFWLOCK(EDATA_ELF(dst));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ((entsize * ndx) > dst->d_size) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov _elf_seterr(EREQ_RAND, 0);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov rc = 0;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if (class == ELFCLASS32) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf32_Sym * d;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d = &(((Elf32_Sym *)dst->d_buf)[ndx]);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->st_name = src->st_name;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* LINTED */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov d->st_value = (Elf32_Addr)src->st_value;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* LINTED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->st_size = (Elf32_Word)src->st_size;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov d->st_info = ELF32_ST_INFO(ELF64_ST_BIND(src->st_info),
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELF64_ST_TYPE(src->st_info));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->st_other = src->st_other;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore d->st_shndx = src->st_shndx;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ((Elf64_Sym *)dst->d_buf)[ndx] = *((Elf64_Sym *)src);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ELFUNLOCK(EDATA_ELF(dst));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (rc);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri PankovGElf_Syminfo *
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovgelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore size_t entsize;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (data == NULL)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return (NULL);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = EDATA_CLASS(data);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore entsize = sizeof (Elf32_Syminfo);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov else if (class == ELFCLASS64)
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov entsize = sizeof (GElf_Syminfo);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore else {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_CLASS, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (NULL);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore EDATA_READLOCKS(data);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ((entsize * ndx) > data->d_size) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore _elf_seterr(EREQ_RAND, 0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst = NULL;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if (class == ELFCLASS32) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Elf32_Syminfo * si;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore si = &(((Elf32_Syminfo *)data->d_buf)[ndx]);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->si_boundto = si->si_boundto;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore dst->si_flags = si->si_flags;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *dst = ((GElf_Syminfo *)data->d_buf)[ndx];
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov EDATA_READUNLOCKS(data);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoregelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int class, rc = 1;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore size_t entsize;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (dst == NULL)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return (0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore class = EDATA_CLASS(dst);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (class == ELFCLASS32)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore entsize = sizeof (Elf32_Syminfo);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov else if (class == ELFCLASS64)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore entsize = sizeof (GElf_Syminfo);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dst));
if ((entsize * ndx) > dst->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Syminfo * d = &(((Elf32_Syminfo *)dst->d_buf)[ndx]);
d->si_boundto = src->si_boundto;
d->si_flags = src->si_flags;
} else
((Elf64_Syminfo *)dst->d_buf)[ndx] = *((Elf64_Syminfo *)src);
ELFUNLOCK(EDATA_ELF(dst));
return (rc);
}
GElf_Dyn *
gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst)
{
int class;
size_t entsize;
if (data == NULL)
return (NULL);
class = EDATA_CLASS(data);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Dyn);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Dyn);
else {
_elf_seterr(EREQ_CLASS, 0);
return (NULL);
}
EDATA_READLOCKS(data);
if ((entsize * ndx) > data->d_size) {
_elf_seterr(EREQ_RAND, 0);
dst = NULL;
} else if (class == ELFCLASS32) {
Elf32_Dyn * d = &((Elf32_Dyn *)data->d_buf)[ndx];
dst->d_tag = (Elf32_Sword)d->d_tag;
dst->d_un.d_val = (Elf32_Word) d->d_un.d_val;
} else
*dst = ((Elf64_Dyn *)data->d_buf)[ndx];
EDATA_READUNLOCKS(data);
return (dst);
}
int
gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src)
{
int class, rc = 1;
size_t entsize;
if (dst == NULL)
return (0);
class = EDATA_CLASS(dst);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Dyn);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Dyn);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dst));
if ((entsize * ndx) > dst->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Dyn * d = &((Elf32_Dyn *)dst->d_buf)[ndx];
/* LINTED */
d->d_tag = (Elf32_Word)src->d_tag;
/* LINTED */
d->d_un.d_val = (Elf32_Word)src->d_un.d_val;
} else
((Elf64_Dyn *)dst->d_buf)[ndx] = *(Elf64_Dyn*)src;
ELFUNLOCK(EDATA_ELF(dst));
return (rc);
}
GElf_Sym *
gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata,
int ndx, GElf_Sym *symptr, Elf32_Word *xshndx)
{
if (gelf_getsym(symdata, ndx, symptr) == 0)
return (NULL);
if (shndxdata && xshndx) {
EDATA_READLOCKS(shndxdata);
if ((ndx * sizeof (Elf32_Word)) > shndxdata->d_size) {
_elf_seterr(EREQ_RAND, 0);
EDATA_READUNLOCKS(shndxdata);
return (NULL);
}
*xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]);
EDATA_READUNLOCKS(shndxdata);
} else {
*xshndx = 0;
}
return (symptr);
}
int
gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata,
int ndx, GElf_Sym *symptr, Elf32_Word xshndx)
{
if (gelf_update_sym(symdata, ndx, symptr) == 0)
return (0);
if (shndxdata) {
ELFWLOCK(EDATA_ELF(shndxdata));
if ((ndx * sizeof (Elf32_Word)) > shndxdata->d_size) {
_elf_seterr(EREQ_RAND, 0);
ELFUNLOCK(EDATA_ELF(shndxdata));
return (0);
}
((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx;
ELFUNLOCK(EDATA_ELF(shndxdata));
}
return (1);
}
GElf_Move *
gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst)
{
int class;
size_t entsize;
if (src == NULL)
return (NULL);
class = EDATA_CLASS(src);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Move);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Move);
else {
_elf_seterr(EREQ_CLASS, 0);
return (NULL);
}
EDATA_READLOCKS(src);
if ((entsize * ndx) > src->d_size) {
_elf_seterr(EREQ_RAND, 0);
dst = NULL;
} else if (class == ELFCLASS32) {
Elf32_Move * m = &((Elf32_Move *)src->d_buf)[ndx];
dst->m_poffset = (Elf64_Word)m->m_poffset;
dst->m_repeat = (Elf64_Xword)m->m_repeat;
dst->m_stride = (Elf64_Half)m->m_stride;
dst->m_value = (Elf64_Xword)m->m_value;
dst->m_info = ELF64_M_INFO(
ELF32_M_SYM(m->m_info),
ELF32_M_SIZE(m->m_info));
} else
*dst = ((Elf64_Move *)src->d_buf)[ndx];
EDATA_READUNLOCKS(src);
return (dst);
}
int
gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src)
{
int class, rc = 1;
size_t entsize;
if (dest == NULL)
return (0);
class = EDATA_CLASS(dest);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Move);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Move);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dest));
if ((entsize * ndx) > dest->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Move * m = &((Elf32_Move *)dest->d_buf)[ndx];
m->m_poffset = (Elf32_Word)src->m_poffset;
m->m_repeat = (Elf32_Half)src->m_repeat;
m->m_stride = (Elf32_Half)src->m_stride;
m->m_value = (Elf32_Lword)src->m_value;
m->m_info = (Elf32_Word)ELF32_M_INFO(
ELF64_M_SYM(src->m_info),
ELF64_M_SIZE(src->m_info));
} else
((Elf64_Move *)dest->d_buf)[ndx] = *(Elf64_Move *)src;
ELFUNLOCK(EDATA_ELF(dest));
return (rc);
}
GElf_Rela *
gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst)
{
int class;
size_t entsize;
if (src == NULL)
return (NULL);
class = EDATA_CLASS(src);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Rela);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Rela);
else {
_elf_seterr(EREQ_CLASS, 0);
return (NULL);
}
EDATA_READLOCKS(src);
if ((entsize * ndx) > src->d_size) {
_elf_seterr(EREQ_RAND, 0);
dst = NULL;
} else if (class == ELFCLASS32) {
Elf32_Rela * r = &((Elf32_Rela *)src->d_buf)[ndx];
dst->r_offset = (GElf_Addr)r->r_offset;
dst->r_addend = (GElf_Addr)r->r_addend;
/*
* Elf32 will never have the extra data field that
* Elf64's r_info field can have, so ignore it.
*/
/* LINTED */
dst->r_info = ELF64_R_INFO(
ELF32_R_SYM(r->r_info),
ELF32_R_TYPE(r->r_info));
} else
*dst = ((Elf64_Rela *)src->d_buf)[ndx];
EDATA_READUNLOCKS(src);
return (dst);
}
int
gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src)
{
int class, rc = 1;
size_t entsize;
if (dst == NULL)
return (0);
class = EDATA_CLASS(dst);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Rela);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Rela);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dst));
if ((entsize * ndx) > dst->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Rela * r = &((Elf32_Rela *)dst->d_buf)[ndx];
/* LINTED */
r->r_offset = (Elf32_Addr) src->r_offset;
/* LINTED */
r->r_addend = (Elf32_Sword)src->r_addend;
/*
* Elf32 will never have the extra data field that
* Elf64's r_info field can have, so ignore it.
*/
/* LINTED */
r->r_info = ELF32_R_INFO(
ELF64_R_SYM(src->r_info),
ELF64_R_TYPE(src->r_info));
} else
((Elf64_Rela *)dst->d_buf)[ndx] = *(Elf64_Rela *)src;
ELFUNLOCK(EDATA_ELF(dst));
return (rc);
}
GElf_Rel *
gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst)
{
int class;
size_t entsize;
if (src == NULL)
return (NULL);
class = EDATA_CLASS(src);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Rel);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Rel);
else {
_elf_seterr(EREQ_CLASS, 0);
return (NULL);
}
EDATA_READLOCKS(src);
if ((entsize * ndx) > src->d_size) {
_elf_seterr(EREQ_RAND, 0);
dst = NULL;
} else if (class == ELFCLASS32) {
Elf32_Rel * r = &((Elf32_Rel *)src->d_buf)[ndx];
dst->r_offset = (GElf_Addr)r->r_offset;
/*
* Elf32 will never have the extra data field that
* Elf64's r_info field can have, so ignore it.
*/
/* LINTED */
dst->r_info = ELF64_R_INFO(ELF32_R_SYM(r->r_info),
ELF32_R_TYPE(r->r_info));
} else
*dst = ((Elf64_Rel *)src->d_buf)[ndx];
EDATA_READUNLOCKS(src);
return (dst);
}
int
gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src)
{
int class, rc = 1;
size_t entsize;
if (dst == NULL)
return (0);
class = EDATA_CLASS(dst);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Rel);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Rel);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dst));
if ((entsize * ndx) > dst->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Rel * r = &((Elf32_Rel *)dst->d_buf)[ndx];
/* LINTED */
r->r_offset = (Elf32_Addr) src->r_offset;
/*
* Elf32 will never have the extra data field that
* Elf64's r_info field can have, so ignore it.
*/
/* LINTED */
r->r_info = ELF32_R_INFO(
ELF64_R_SYM(src->r_info),
ELF64_R_TYPE(src->r_info));
} else
((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src;
ELFUNLOCK(EDATA_ELF(dst));
return (rc);
}
long
gelf_checksum(Elf *elf)
{
int class = gelf_getclass(elf);
if (class == ELFCLASS32)
return (elf32_checksum(elf));
else if (class == ELFCLASS64)
return (elf64_checksum(elf));
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
GElf_Cap *
gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst)
{
int class;
size_t entsize;
if (data == NULL)
return (NULL);
class = EDATA_CLASS(data);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Cap);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Cap);
else {
_elf_seterr(EREQ_CLASS, 0);
return (NULL);
}
EDATA_READLOCKS(data);
if ((entsize * ndx) > data->d_size) {
_elf_seterr(EREQ_RAND, 0);
dst = NULL;
} else if (class == ELFCLASS32) {
Elf32_Cap *c = &(((Elf32_Cap *)data->d_buf)[ndx]);
dst->c_tag = (Elf64_Xword)c->c_tag;
dst->c_un.c_val = (Elf64_Xword)c->c_un.c_val;
} else
*dst = ((GElf_Cap *)data->d_buf)[ndx];
EDATA_READUNLOCKS(data);
return (dst);
}
int
gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src)
{
int class, rc = 1;
size_t entsize;
if (dst == NULL)
return (0);
class = EDATA_CLASS(dst);
if (class == ELFCLASS32)
entsize = sizeof (Elf32_Cap);
else if (class == ELFCLASS64)
entsize = sizeof (GElf_Cap);
else {
_elf_seterr(EREQ_CLASS, 0);
return (0);
}
ELFWLOCK(EDATA_ELF(dst));
if ((entsize * ndx) > dst->d_size) {
_elf_seterr(EREQ_RAND, 0);
rc = 0;
} else if (class == ELFCLASS32) {
Elf32_Cap *c = &(((Elf32_Cap *)dst->d_buf)[ndx]);
c->c_tag = (Elf32_Word)src->c_tag;
c->c_un.c_val = (Elf32_Word)src->c_un.c_val;
} else
((Elf64_Cap *)dst->d_buf)[ndx] = *((Elf64_Cap *)src);
ELFUNLOCK(EDATA_ELF(dst));
return (rc);
}