/** * gum_list_insert: * @list: a pointer to a #GumList * @data: the data for the new element * @position: the position to insert the element. If this is * negative, or is larger than the number of elements in the * list, the new element is added on to the end of the list. * * Inserts a new element into the list at the given position. * * Returns: the new start of the #GumList */ GumList* gum_list_insert (GumList *list, gpointer data, gint position) { GumList *new_list; GumList *tmp_list; if (position < 0) return gum_list_append (list, data); else if (position == 0) return gum_list_prepend (list, data); tmp_list = gum_list_nth (list, position); if (!tmp_list) return gum_list_append (list, data); new_list = _gum_list_alloc (); new_list->data = data; new_list->prev = tmp_list->prev; if (tmp_list->prev) tmp_list->prev->next = new_list; new_list->next = tmp_list; tmp_list->prev = new_list; if (tmp_list == list) return new_list; else return list; }
GumCodeSlice * gum_code_allocator_new_slice_near (GumCodeAllocator * self, gpointer address) { GumList * walk; GumCodePage * cp; GumCodeSlice * slice; for (walk = self->pages; walk != NULL; walk = walk->next) { GumCodePage * page = (GumCodePage *) walk->data; if (gum_code_page_is_near (page, address)) { guint slice_idx; for (slice_idx = 0; slice_idx != self->slices_per_page; slice_idx++) { slice = &page->slice[slice_idx]; if (gum_code_slice_is_free (slice)) { if (!gum_query_is_rwx_supported ()) gum_mprotect (page, self->page_size, GUM_PAGE_RW); gum_code_slice_mark_taken (slice); return slice; } } } } cp = gum_code_allocator_new_page_near (self, address); self->pages = gum_list_prepend (self->pages, cp); slice = &cp->slice[0]; gum_code_slice_mark_taken (slice); return slice; }