/* * Get the ELF header and, if it exists, call get_symtab() * to begin processing of the file; otherwise, return from * processing the file with a warning. */ static void process(Elf *elf_file, char *filename) { GElf_Ehdr ehdr; if (gelf_getehdr(elf_file, &ehdr) == NULL) { (void) fprintf(stderr, "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); return; } set_A_header(filename); get_symtab(elf_file, filename); }
int mips_elf_load(struct mips_cpu *pcpu, const char *elf, size_t elfsz) { Elf32_Ehdr *eh = (Elf32_Ehdr*)elf; Elf32_Sym *symgp; /* global pointer value */ Elf32_Sym *symend; /* end of data; break start */ pcpu->elf = elf; pcpu->elfsz = elfsz; /* Check ELF format and load segments to their proper places. Don't allow * segment data to overflow into area reserved for stack. */ if(check_eh_limits(eh, elfsz)) return -1; if(load_segments(pcpu)) return -1; if(get_symtab(elf, elfsz, &pcpu->shsymtab, &pcpu->shsymstr)) return -1; if(eh->e_entry >= pcpu->memsz - pcpu->stksz) return -1; /* Segments successfully loaded; set up registers for program start. */ symgp = mips_elf_find_symbol(pcpu, "_gp"); if(!symgp || (symgp->st_shndx != SHN_ABS) || (symgp->st_value >= pcpu->memsz - pcpu->stksz) || (symgp->st_value < MIPS_LOWBASE)) return -1; symend = mips_elf_find_symbol(pcpu, "_end"); if(!symend || (symend->st_shndx != SHN_ABS) || (symend->st_value >= pcpu->memsz - pcpu->stksz) || (symend->st_value < MIPS_LOWBASE)) return -1; if((eh->e_entry >= pcpu->memsz - pcpu->stksz) || (eh->e_entry < MIPS_LOWBASE)) return -1; pcpu->brk = symend->st_value; pcpu->pc = eh->e_entry; pcpu->r.ur[28] = symgp->st_value; /* global data pointer */ pcpu->r.ur[29] = pcpu->memsz - 4; /* stack pointer */ pcpu->r.ur[31] = 0; /* link register */ return 0; }
void __cyg_profile_func_enter(void* func, void* callsite) { void* funcptr; uint64_t time; HashNode* hn; funcptr = DEREF_IA64_FUNC_PTR(func); /* -- if not yet initialized, initialize VampirTrace -- */ if ( gnu_init ) { VT_MEMHOOKS_OFF(); gnu_init = 0; vt_open(); vt_comp_finalize = gnu_finalize; get_symtab(); VT_MEMHOOKS_ON(); } /* -- if VampirTrace already finalized, return -- */ if ( !vt_is_alive ) return; VT_MEMHOOKS_OFF(); time = vt_pform_wtime(); /* -- get region identifier -- */ if ( (hn = hash_get((long)funcptr))) { if ( hn->vtid == VT_NO_ID ) { /* -- region entered the first time, register region -- */ #if (defined(VT_MT) || defined(VT_HYB)) VTTHRD_LOCK_IDS(); if( hn->vtid == VT_NO_ID ) register_region(hn); VTTHRD_UNLOCK_IDS(); #else /* VT_MT || VT_HYB */ register_region(hn); #endif /* VT_MT || VT_HYB */ } /* -- write enter record -- */ vt_enter(VT_CURRENT_THREAD, &time, hn->vtid); } VT_MEMHOOKS_ON(); }
/* return size needed by the module */ int elf_mod_sizes(int fd, size_t *modsize, int *strtablen, struct lmc_resrv *resrvp, struct stat *sp) { Elf_Ehdr ehdr; ssize_t off = 0; size_t data_hole = 0; char *shstrtab, *strtab; struct elf_section *head, *s, *stab; if (read_elf_header(fd, &ehdr) < 0) return -1; shstrtab = read_shstring_table(fd, &ehdr); read_sections(fd, &ehdr, shstrtab, &head); for (s = head; s; s = s->next) { /* XXX impossible! */ if (s->type == SHT_STRTAB && s->type == SHT_SYMTAB && s->type == SHT_DYNSYM) continue; if (debug) fprintf(stderr, "%s: addr = %p size = %#lx align = %#lx\n", s->name, s->addr, (u_long)s->size, (u_long)s->align); /* * XXX try to get rid of the hole before the data * section that GNU-ld likes to put there */ if (strcmp(s->name, ".data") == 0 && s->addr > (void *)off) { data_offset = roundup(off, s->align); if (debug) fprintf(stderr, ".data section forced to " "offset %p (was %p)\n", (void *)data_offset, s->addr); /* later remove size of compressed hole from off */ data_hole = (ssize_t)s->addr - data_offset; } off = (ssize_t)s->addr + s->size; } off -= data_hole; /* XXX round to pagesize? */ *modsize = roundup(off, sysconf(_SC_PAGESIZE)); /* get string table length */ strtab = read_string_table(fd, head, strtablen); free(shstrtab); free(strtab); /* get symbol table sections */ get_symtab(&head); stab = head; resrvp->sym_symsize = 0; while (stab) { resrvp->sym_symsize += stab->size; stab = stab->next; } resrvp->sym_size = resrvp->sym_symsize + *strtablen; free_sections(head); return (0); }