3 * Copyright 2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <gc_proc_def_utils.h>
27 #include <gcell/gc_declare_proc.h>
32 static const unsigned char expected[EI_PAD] = {
46 * Basically we're going to find the GC_PROC_DEF_SECTION section
47 * in the ELF file and return a pointer to it. The only things in that
48 * section are gc_proc_def's
51 gcpd_find_table(spe_program_handle_t *handle,
52 struct gc_proc_def **table, int *nentries, uint32_t *ls_addr)
54 if (!handle || !table || !nentries)
60 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image;
62 fprintf(stderr, "gcpd: No ELF image has been loaded\n");
66 // quick check that we're looking at a SPE EXEC object
68 if (memcmp(ehdr->e_ident, expected, EI_PAD) != 0){
69 fprintf(stderr, "gcpd: invalid ELF header\n");
73 if (ehdr->e_machine != 0x17){ // confirm machine type (EM_SPU)
74 fprintf(stderr, "gcpd: not an SPE ELF object\n");
78 if (ehdr->e_type != ET_EXEC){
79 fprintf(stderr, "gcpd: invalid SPE ELF type.\n");
80 fprintf(stderr, "gcpd: SPE type %d != %d\n", ehdr->e_type, ET_EXEC);
84 // find the section header table
89 if (ehdr->e_shentsize != sizeof (*shdr)){
90 fprintf(stderr, "gcpd: invalid section header format.\n");
94 if (ehdr->e_shnum == 0){
95 fprintf(stderr, "gcpd: no section headers in file.\n");
99 shdr = (Elf32_Shdr *) ((char *)ehdr + ehdr->e_shoff);
100 char *str_table = (char *)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
102 // traverse the sections looking for GC_PROC_DEF_SECTION
104 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; sh++){
106 fprintf(stderr, "section name: %s (start: 0x%04x, size: 0x%04x)\n",
107 str_table + sh->sh_name, sh->sh_offset, sh->sh_size);
110 if (strcmp(GC_PROC_DEF_SECTION, str_table+sh->sh_name) == 0){
111 *table = (struct gc_proc_def *)((char *)ehdr + sh->sh_offset);
112 if (sh->sh_size % (sizeof(struct gc_proc_def)) != 0){
113 fprintf(stderr, "gcpd: %s section has invalid format\n", GC_PROC_DEF_SECTION);
116 *nentries = sh->sh_size / sizeof(struct gc_proc_def);
117 *ls_addr = sh->sh_addr;