/* * === FUNCTION ====================================================================== * Name: alloc_free * Description: make the node->free be in freelist again * * that's the point of element "free" in node: * avoid freeing a free space * ===================================================================================== */ void alloc_free(void *addr, const char *file, int line) { assert(addr); alloc_n *node = search(addr); /*----------------------------------------------------------------------------- * addr should be the multiple of sizeof(union align) *-----------------------------------------------------------------------------*/ if (node && node->free && (!addr_align(addr))) { /* node->free */ node->free = freelist.free; freelist.free = node; } else { FAILURE(); } }
/* * === FUNCTION ====================================================================== * Name: alloc_realloc * Description: 1st. alloc_malloc * 2nd. alloc_free * ===================================================================================== */ void *alloc_realloc(void *addr, long nbytes, const char *file, int line) { assert(addr_align(addr) == 0); assert(nbytes > 0); void *new_addr = alloc_malloc(nbytes, file, line); long size = search(addr)->size; if (new_addr) { memmove(new_addr, addr, size < nbytes ? size : nbytes); alloc_free(addr, file, line); } else { FAILURE(); } return new_addr; }
/* * === FUNCTION ====================================================================== * Name: get_new_node * Description: apply&init a new alloc_n, return it * just use in this file, static one * ===================================================================================== */ static alloc_n *get_new_node(void *addr, long nbytes, const char *file, int line) { assert(addr_align(addr) == 0); assert(nbytes > 0); int key; alloc_n *node = nalloc(addr, nbytes, file, line); if (node) { node->free = freelist.free; /* alloc_n.free */ freelist.free = node; key = hash(node->addr, htab); node->link = htab[key]->link; /* NULL also works */ htab[key]->link = node; /* add to the start */ } else { FAILURE(); } return node; }
static int read_elfnotes(char *corefilename, struct UCD_info *ui) { FILE *fp = NULL; struct stat stbuf; elf64_header header; elf64_phdr *program_headers = NULL; unsigned char *notes = NULL; int i; size_t ret; elfnote *note; unsigned char *end=NULL, *curr=NULL; unsigned char *filenames = NULL, *descend = NULL , *previous_filenames = NULL; uint64_t count; int retval = -1; if (stat(corefilename, &stbuf) < 0 ) { goto func_exit; } if (!S_ISREG(stbuf.st_mode)) { goto func_exit; } fp = fopen(corefilename, "r"); if (fp == NULL) { goto func_exit; } memset(&header, 0, sizeof(header)); if (fread(&header, sizeof(header), 1, fp)!= 1) { goto func_exit; } if (header.ident[0] !=0x7f ||header.ident[1]!='E' ||header.ident[2]!='L' ||header.ident[3] !='F') { goto func_exit; } if ((header.ident[5] == 2) || (header.ident[4] != 2) || (header.phnum == 0 ) || (header.phentsize != sizeof(elf64_phdr))) { goto func_exit; } program_headers = malloc(sizeof(elf64_phdr)*header.phnum); if (program_headers == NULL) { goto func_exit; } if (fseek(fp,(long)header.phoff,SEEK_SET) == -1) { goto func_exit; } if (fread(program_headers, sizeof(elf64_phdr), header.phnum, fp) != header.phnum) { goto func_exit; } for (i=0; i< header.phnum; i++) { if (program_headers[i].type != 4) continue; retval = fseek(fp,(long) program_headers[i].offset, SEEK_SET); if (retval == -1) { goto func_exit; } notes = malloc(program_headers[i].filesz); if (notes == NULL) { goto func_exit; } ret = fread(notes, 1, program_headers[i].filesz, fp); if (ret != program_headers[i].filesz ) { goto func_exit; } end = notes + program_headers[i].filesz; curr = notes; while (curr < end) { unsigned char *descdata; note = (elfnote*) curr; descdata = (unsigned char *) note->name + addr_align (note->namesz); if (note->type != NT_FILE) { curr = (unsigned char *) (descdata + addr_align (note->descsz)); continue; } if (note->descsz < 16) goto func_exit; descend = descdata + note->descsz; if (descdata[note->descsz - 1] != '\0') goto func_exit; count = *((uint64_t *)descdata); descdata += 8; descdata += 8; if (note->descsz < 16 + count * 24 ) goto func_exit; filenames = descdata + count * 3 * 8; while (count-- > 0) { uint64_t start; if (filenames == descend) goto func_exit; start = *((uint64_t*)descdata); descdata += 8; descdata += 8; descdata += 8; if (filenames && previous_filenames && !strcmp((char*)filenames,(char*)previous_filenames)) { previous_filenames = filenames; filenames += 1 + strlen ((char *) filenames); continue; } if (_UCD_add_backing_file_at_vaddr(ui, (long)start, (char *)filenames) < 0) { // fprintf(stderr, "_UCD_add_backing_file_at_vaddr FAILED %" PRId64 " %s\n", start, filenames); } previous_filenames = filenames; filenames += 1 + strlen ((char *) filenames); } curr = (unsigned char *) (descdata + addr_align (note->descsz)); } if (notes) free(notes); notes = NULL; } retval = 0; func_exit: if (fp) fclose(fp); if (program_headers) free(program_headers); if (notes) free(notes); return(retval); }