gelf_sym.c revision 4484
13569Sgblack@eecs.umich.edu/*- 23569Sgblack@eecs.umich.edu * Copyright (c) 2006 Joseph Koshy 33569Sgblack@eecs.umich.edu * All rights reserved. 43569Sgblack@eecs.umich.edu * 53569Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 63569Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions 73569Sgblack@eecs.umich.edu * are met: 83569Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright 93569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer. 103569Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright 113569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 123569Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution. 133569Sgblack@eecs.umich.edu * 143569Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 153569Sgblack@eecs.umich.edu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163569Sgblack@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 173569Sgblack@eecs.umich.edu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 183569Sgblack@eecs.umich.edu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 193569Sgblack@eecs.umich.edu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 203569Sgblack@eecs.umich.edu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 213569Sgblack@eecs.umich.edu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 223569Sgblack@eecs.umich.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 233569Sgblack@eecs.umich.edu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 243569Sgblack@eecs.umich.edu * SUCH DAMAGE. 253569Sgblack@eecs.umich.edu */ 263569Sgblack@eecs.umich.edu 273569Sgblack@eecs.umich.edu#include <limits.h> 283804Ssaidi@eecs.umich.edu 293569Sgblack@eecs.umich.edu#include <assert.h> 303569Sgblack@eecs.umich.edu#include "gelf.h" 313804Ssaidi@eecs.umich.edu 323811Ssaidi@eecs.umich.edu#include "_libelf.h" 333569Sgblack@eecs.umich.edu 343824Ssaidi@eecs.umich.eduGElf_Sym * 353811Ssaidi@eecs.umich.edugelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst) 363811Ssaidi@eecs.umich.edu{ 373823Ssaidi@eecs.umich.edu int ec; 383823Ssaidi@eecs.umich.edu Elf *e; 393823Ssaidi@eecs.umich.edu Elf_Scn *scn; 403569Sgblack@eecs.umich.edu Elf32_Sym *sym32; 413569Sgblack@eecs.umich.edu Elf64_Sym *sym64; 423804Ssaidi@eecs.umich.edu size_t msz; 433804Ssaidi@eecs.umich.edu uint32_t sh_type; 443569Sgblack@eecs.umich.edu 453569Sgblack@eecs.umich.edu if (d == NULL || ndx < 0 || dst == NULL || 463569Sgblack@eecs.umich.edu (scn = d->d_scn) == NULL || 473804Ssaidi@eecs.umich.edu (e = scn->s_elf) == NULL) { 483881Ssaidi@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 493881Ssaidi@eecs.umich.edu return (NULL); 503804Ssaidi@eecs.umich.edu } 513804Ssaidi@eecs.umich.edu 523804Ssaidi@eecs.umich.edu ec = e->e_class; 533804Ssaidi@eecs.umich.edu assert(ec == ELFCLASS32 || ec == ELFCLASS64); 543569Sgblack@eecs.umich.edu 553804Ssaidi@eecs.umich.edu if (ec == ELFCLASS32) 563804Ssaidi@eecs.umich.edu sh_type = scn->s_shdr.s_shdr32.sh_type; 573881Ssaidi@eecs.umich.edu else 583881Ssaidi@eecs.umich.edu sh_type = scn->s_shdr.s_shdr64.sh_type; 593881Ssaidi@eecs.umich.edu 603804Ssaidi@eecs.umich.edu if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { 613569Sgblack@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 623804Ssaidi@eecs.umich.edu return (NULL); 633804Ssaidi@eecs.umich.edu } 643804Ssaidi@eecs.umich.edu 653804Ssaidi@eecs.umich.edu msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); 663881Ssaidi@eecs.umich.edu 673804Ssaidi@eecs.umich.edu assert(msz > 0); 683804Ssaidi@eecs.umich.edu 693804Ssaidi@eecs.umich.edu if (msz * ndx >= d->d_size) { 703804Ssaidi@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 713804Ssaidi@eecs.umich.edu return (NULL); 723804Ssaidi@eecs.umich.edu } 733804Ssaidi@eecs.umich.edu 743569Sgblack@eecs.umich.edu if (ec == ELFCLASS32) { 753569Sgblack@eecs.umich.edu 763804Ssaidi@eecs.umich.edu sym32 = (Elf32_Sym *) d->d_buf + ndx; 773804Ssaidi@eecs.umich.edu 783826Ssaidi@eecs.umich.edu dst->st_name = sym32->st_name; 793804Ssaidi@eecs.umich.edu dst->st_value = (Elf64_Addr) sym32->st_value; 803569Sgblack@eecs.umich.edu dst->st_size = (Elf64_Xword) sym32->st_size; 813569Sgblack@eecs.umich.edu dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), 823804Ssaidi@eecs.umich.edu ELF32_ST_TYPE(sym32->st_info)); 833826Ssaidi@eecs.umich.edu dst->st_other = sym32->st_other; 843907Ssaidi@eecs.umich.edu dst->st_shndx = sym32->st_shndx; 853826Ssaidi@eecs.umich.edu } else { 863811Ssaidi@eecs.umich.edu 873836Ssaidi@eecs.umich.edu sym64 = (Elf64_Sym *) d->d_buf + ndx; 883915Ssaidi@eecs.umich.edu 893907Ssaidi@eecs.umich.edu *dst = *sym64; 903881Ssaidi@eecs.umich.edu } 913881Ssaidi@eecs.umich.edu 923881Ssaidi@eecs.umich.edu return (dst); 933881Ssaidi@eecs.umich.edu} 943907Ssaidi@eecs.umich.edu 953881Ssaidi@eecs.umich.eduint 963881Ssaidi@eecs.umich.edugelf_update_sym(Elf_Data *d, int ndx, GElf_Sym *gs) 973881Ssaidi@eecs.umich.edu{ 983881Ssaidi@eecs.umich.edu int ec; 993881Ssaidi@eecs.umich.edu Elf *e; 1003907Ssaidi@eecs.umich.edu Elf_Scn *scn; 1013907Ssaidi@eecs.umich.edu Elf32_Sym *sym32; 1023907Ssaidi@eecs.umich.edu Elf64_Sym *sym64; 1033907Ssaidi@eecs.umich.edu size_t msz; 1043907Ssaidi@eecs.umich.edu uint32_t sh_type; 1053907Ssaidi@eecs.umich.edu 1063907Ssaidi@eecs.umich.edu if (d == NULL || ndx < 0 || gs == NULL || 1073907Ssaidi@eecs.umich.edu (scn = d->d_scn) == NULL || 1083907Ssaidi@eecs.umich.edu (e = scn->s_elf) == NULL) { 1093907Ssaidi@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 1103907Ssaidi@eecs.umich.edu return (0); 1113907Ssaidi@eecs.umich.edu } 1123907Ssaidi@eecs.umich.edu 1133907Ssaidi@eecs.umich.edu ec = e->e_class; 1143907Ssaidi@eecs.umich.edu assert(ec == ELFCLASS32 || ec == ELFCLASS64); 1153907Ssaidi@eecs.umich.edu 1163907Ssaidi@eecs.umich.edu if (ec == ELFCLASS32) 1173907Ssaidi@eecs.umich.edu sh_type = scn->s_shdr.s_shdr32.sh_type; 1183907Ssaidi@eecs.umich.edu else 1193907Ssaidi@eecs.umich.edu sh_type = scn->s_shdr.s_shdr64.sh_type; 1203907Ssaidi@eecs.umich.edu 1213907Ssaidi@eecs.umich.edu if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { 1223907Ssaidi@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 1233881Ssaidi@eecs.umich.edu return (0); 1243881Ssaidi@eecs.umich.edu } 1253881Ssaidi@eecs.umich.edu 1263881Ssaidi@eecs.umich.edu msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); 1273881Ssaidi@eecs.umich.edu assert(msz > 0); 1283881Ssaidi@eecs.umich.edu 1293881Ssaidi@eecs.umich.edu if (msz * ndx >= d->d_size) { 1303881Ssaidi@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 1313881Ssaidi@eecs.umich.edu return (0); 1323881Ssaidi@eecs.umich.edu } 1333881Ssaidi@eecs.umich.edu 1343881Ssaidi@eecs.umich.edu if (ec == ELFCLASS32) { 1353907Ssaidi@eecs.umich.edu sym32 = (Elf32_Sym *) d->d_buf + ndx; 1363811Ssaidi@eecs.umich.edu 1373826Ssaidi@eecs.umich.edu sym32->st_name = gs->st_name; 1383826Ssaidi@eecs.umich.edu sym32->st_info = gs->st_info; 1393826Ssaidi@eecs.umich.edu sym32->st_other = gs->st_other; 1403826Ssaidi@eecs.umich.edu sym32->st_shndx = gs->st_shndx; 1413881Ssaidi@eecs.umich.edu 1423881Ssaidi@eecs.umich.edu LIBELF_COPY_U32(sym32, gs, st_value); 1433881Ssaidi@eecs.umich.edu LIBELF_COPY_U32(sym32, gs, st_size); 1443881Ssaidi@eecs.umich.edu } else { 1453881Ssaidi@eecs.umich.edu sym64 = (Elf64_Sym *) d->d_buf + ndx; 1463881Ssaidi@eecs.umich.edu 1473881Ssaidi@eecs.umich.edu *sym64 = *gs; 1483881Ssaidi@eecs.umich.edu } 1493881Ssaidi@eecs.umich.edu 1503881Ssaidi@eecs.umich.edu return (1); 1513881Ssaidi@eecs.umich.edu} 1523881Ssaidi@eecs.umich.edu