static __ptr_t mallochook (size_t size, const __ptr_t caller) { struct hdr *hdr; if (pedantic) mcheck_check_all (); if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1)) { __set_errno (ENOMEM); return NULL; } __malloc_hook = old_malloc_hook; if (old_malloc_hook != NULL) hdr = (struct hdr *) (*old_malloc_hook)(sizeof (struct hdr) + size + 1, caller); else hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); __malloc_hook = mallochook; if (hdr == NULL) return NULL; hdr->size = size; link_blk (hdr); hdr->block = hdr; hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD; ((char *) &hdr[1])[size] = MAGICBYTE; flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size); return (__ptr_t) (hdr + 1); }
void vogl_tracked_check_heap(const char *pFile_line) { check(pFile_line); #if defined(COMPILER_MSVC) // Also see_CrtSetDbgFlag () int status = _CrtCheckMemory(); VOGL_VERIFY(status == TRUE); #elif defined(COMPILER_GCCLIKE) // App MUST have been linked with -mlcheck! Unfortunately -mlcheck() causes the CRT's heap API's to be unusable on some dev boxes, no idea why. mcheck_check_all(); #else fprintf(stderr, "%s: Need implementation\n", __FUNCTION__); #endif }
static __ptr_t memalignhook (size_t alignment, size_t size, const __ptr_t caller) { struct hdr *hdr; size_t slop; char *block; if (pedantic) mcheck_check_all (); slop = (sizeof *hdr + alignment - 1) & - alignment; if (size > ~((size_t) 0) - (slop + 1)) { __set_errno (ENOMEM); return NULL; } __memalign_hook = old_memalign_hook; if (old_memalign_hook != NULL) block = (*old_memalign_hook)(alignment, slop + size + 1, caller); else block = memalign (alignment, slop + size + 1); __memalign_hook = memalignhook; if (block == NULL) return NULL; hdr = ((struct hdr *) (block + slop)) - 1; hdr->size = size; link_blk (hdr); hdr->block = (__ptr_t) block; hdr->magic2 = (uintptr_t) block ^ MAGICWORD; ((char *) &hdr[1])[size] = MAGICBYTE; flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size); return (__ptr_t) (hdr + 1); }
static void freehook (__ptr_t ptr, const __ptr_t caller) { if (pedantic) mcheck_check_all (); if (ptr) { struct hdr *hdr = ((struct hdr *) ptr) - 1; checkhdr (hdr); hdr->magic = MAGICFREE; hdr->magic2 = MAGICFREE; unlink_blk (hdr); hdr->prev = hdr->next = NULL; flood (ptr, FREEFLOOD, hdr->size); ptr = hdr->block; } __free_hook = old_free_hook; if (old_free_hook != NULL) (*old_free_hook)(ptr, caller); else free (ptr); __free_hook = freehook; }
static __ptr_t reallochook (__ptr_t ptr, size_t size, const __ptr_t caller) { if (size == 0) { freehook (ptr, caller); return NULL; } struct hdr *hdr; size_t osize; if (pedantic) mcheck_check_all (); if (size > ~((size_t) 0) - (sizeof (struct hdr) + 1)) { __set_errno (ENOMEM); return NULL; } if (ptr) { hdr = ((struct hdr *) ptr) - 1; osize = hdr->size; checkhdr (hdr); unlink_blk (hdr); if (size < osize) flood ((char *) ptr + size, FREEFLOOD, osize - size); } else { osize = 0; hdr = NULL; } __free_hook = old_free_hook; __malloc_hook = old_malloc_hook; __memalign_hook = old_memalign_hook; __realloc_hook = old_realloc_hook; if (old_realloc_hook != NULL) hdr = (struct hdr *) (*old_realloc_hook)((__ptr_t) hdr, sizeof (struct hdr) + size + 1, caller); else hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1); __free_hook = freehook; __malloc_hook = mallochook; __memalign_hook = memalignhook; __realloc_hook = reallochook; if (hdr == NULL) return NULL; hdr->size = size; link_blk (hdr); hdr->block = hdr; hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD; ((char *) &hdr[1])[size] = MAGICBYTE; if (size > osize) flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize); return (__ptr_t) (hdr + 1); }
/* the finishing piece for each section */ static void copy_section_data (bfd *ibfd, sec_ptr isection, void *obfdarg) { bfd *obfd = obfdarg; sec_ptr osection; bfd_size_type size; struct add_reloc_struct *new_reloc; size = bfd_get_section_size (isection); osection = isection->output_section; if (size == 0 || osection == 0) return; if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS) { void *memhunk; mcheck_check_all(); memhunk = malloc (size); if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size)) return; if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) { /* make the data modifications, if requested */ modify_byte_struct *mbyte_ptr = modify_bytes; while (mbyte_ptr != NULL) { ((unsigned char *)memhunk)[mbyte_ptr->location] = (char)(mbyte_ptr->value & 0xff); mbyte_ptr = mbyte_ptr->next; } /* make sure additional relocs have proper data present */ /* kernel implements relocs relative to what's already there in the data! */ /* so if we're overriding a call, we need to set the old PC-relative data back to 0xfffffffc */ for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { ((unsigned char *)memhunk)[new_reloc->loc] = (unsigned char)0xfc; ((unsigned char *)memhunk)[new_reloc->loc+1] = (unsigned char)0xff; ((unsigned char *)memhunk)[new_reloc->loc+2] = (unsigned char)0xff; ((unsigned char *)memhunk)[new_reloc->loc+3] = (unsigned char)0xff; } } if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size)) return; /* note that bfd_set_section_contents will render the symbol table noncanonical */ /* (the array will not be NULL terminated) */ free (memhunk); } else if (!(bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)) { fprintf(stderr, "not copying input section %s because flags %x do not indicate contents (%x)\n", isection->name, bfd_get_section_flags (ibfd, isection), SEC_HAS_CONTENTS); } else { fprintf(stderr, "not copying output section %s because flags %x do not indicate contents (%x)\n", osection->name, bfd_get_section_flags (obfd, osection), SEC_HAS_CONTENTS); } }
/* just reloc parts - data comes later */ static void copy_section_relocs_edit (bfd *ibfd, sec_ptr isection, void *obfdarg) { bfd *obfd = obfdarg; arelent **relpp; long relcount; sec_ptr osection; bfd_size_type size; long relsize; flagword flags; flags = bfd_get_section_flags (ibfd, isection); if ((flags & SEC_GROUP) != 0) return; osection = isection->output_section; size = bfd_get_section_size (isection); if (size == 0 || osection == 0) return; relsize = bfd_get_reloc_upper_bound (ibfd, isection); if (relsize <= 0) { /* not good */ bfd_perror("attempting to do relocs"); return; } relpp = malloc (relsize); relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); /* copy each reloc, possibly removing or changing it on the fly */ arelent **temp_relpp; long temp_relcount = 0; long i; int msg_cnt = 0; struct change_reloc_struct *change_ptr; struct add_reloc_struct *new_reloc; asymbol **osympp; /* count new relocs to allocate space in reloc list */ int reloc_add_cnt; reloc_add_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { reloc_add_cnt++; } osympp = bfd_get_outsymbols(obfd); /* note: cannot run mprobe on osympp b/c the copy contents will sometimes realloc it from internal BFD storage */ temp_relpp = malloc (relsize + reloc_add_cnt * sizeof(arelent *)); for (i = 0; i < relcount; i++) { if (is_delete_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), delete_relocs)) { continue; } else if ((change_ptr = find_change_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), change_relocs)) != NULL) { int sym_idx; sym_idx = find_symbol(osympp, change_ptr->new_symbol_name); if (sym_idx < 0) { fprintf(stderr, "internal error: could not find new symbol %s in output symbol table\n", change_ptr->new_symbol_name); exit(1); } relpp[i]->sym_ptr_ptr = &(osympp[sym_idx]); } temp_relpp [temp_relcount++] = relpp [i]; } /* now the additional relocs from the command line */ if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) { add_reloc_struct *add_reloc; for (add_reloc = additional_relocs; add_reloc != NULL; add_reloc = add_reloc->next) { arelent *new_reloc; int symbol_idx; new_reloc = malloc(sizeof(*new_reloc)); if ((symbol_idx = find_symbol(osympp, add_reloc->symbol_name)) < 0) { fprintf(stderr, "could not find symbol %s to perform a relocation! possible internal error\n", add_reloc->symbol_name); continue; } new_reloc->sym_ptr_ptr = &osympp[symbol_idx]; new_reloc->address = add_reloc->loc; new_reloc->addend = 0; /* never seemed to be used in my cursory investigation */ new_reloc->howto = bfd_reloc_type_lookup(ibfd, BFD_RELOC_32_PCREL); if (new_reloc->howto == NULL) { fprintf(stderr, "could not get howto back from bfd subsystem\n"); exit(1); } temp_relpp[temp_relcount++] = new_reloc; } } temp_relpp[temp_relcount] = NULL; relcount = temp_relcount; free (relpp); relpp = temp_relpp; bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount); if (relcount == 0) free (relpp); mcheck_check_all(); }