Blob


1 /*-
2 * Copyright (c) 2006 Matthias Schmidt <xhr @ giessen.ccc.de>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
27 /* $Id: list.c,v 1.2 2006/08/15 12:52:48 matthias Exp $ */
29 #include <errno.h>
31 #include "dermob.h"
32 #include "list.h"
33 #include "mach.h"
35 void print_section(struct section *);
36 void print_load_command(struct load_command *);
37 void print_mo_header(struct mach_header *);
38 void print_fat_header(struct fat_header *);
39 void print_fat_arch(struct fat_arch *);
40 void print_lc_towlevel_hints(struct twolevel_hints_command *two);
41 void display_cmd_name(int);
42 void display_cpu_arch(int);
43 void print_lc_towlevel_hints(struct twolevel_hints_command *two);
44 void print_lc_dysymtab(struct dysymtab_command *dsym);
45 void print_lc_load_dylib(struct dylib_command *dly);
46 void print_lc_segment(struct segment_command *sc);
47 void print_lc_symtab(struct symtab_command *symc);
48 void mprintf(const char *fmt, ...);
50 struct list *
51 list_create_list()
52 {
53 struct list *list;
55 list = malloc(sizeof(struct list));
57 if (list != NULL) {
58 list->head = list->tail = NULL;
59 list->len = 0;
60 return (list);
61 }
63 return (NULL);
64 }
66 void
67 list_insert_node(struct list *list, void *content, unsigned int code)
68 {
69 struct node *new;
71 new = malloc(sizeof(struct node));
73 if (!new) {
74 printf("malloc: %s\n", strerror(errno));
75 return;
76 }
78 new->content = content;
79 new->code = code;
81 if (list->head == NULL) {
82 list->head = new;
83 list->tail = new;
84 /* We'll get two uninitialised pointer at the first node, if we
85 * don't set prev and next to NULL */
86 new->next = new->prev = NULL;
87 list->len = 1;
88 } else {
89 list->head->prev = new;
90 new->next = list->head;
91 new->prev = NULL;
92 list->head = new;
93 list->len++;
94 }
95 }
97 void
98 list_traverse_list(struct list *list)
99 {
100 struct node *cursor;
101 int na, nl, ns;
103 na = nl = ns = 0;
105 // Traverse the list backwards
106 for (cursor = list->tail; cursor != NULL; cursor = cursor->prev) {
107 if (cursor->code == 0x1)
108 print_fat_header((struct fat_header *)cursor->content);
109 else if (cursor->code == 0x2) {
110 mprintf(" Architecture %d\n", ++na);
111 print_fat_arch((struct fat_arch *) cursor->content);
112 } else if (cursor->code == 0x3)
113 print_mo_header((struct mach_header *) cursor->content);
114 else if (cursor->code == 0x4) {
115 mprintf(" - Load command: %d\n", ++nl);
116 print_load_command((struct load_command *) cursor->content);
117 } else if (cursor->code == 0x5) {
118 mprintf(" + Section %d\n", ++ns);
119 print_section((struct section *) cursor->content);
120 } else if (cursor->code == 0x6)
121 print_lc_segment((struct segment_command *) cursor->content);
122 else if (cursor->code == 0x7)
123 print_lc_symtab((struct symtab_command *) cursor->content);
124 else if (cursor->code == 0x8)
125 print_lc_load_dylib((struct dylib_command *) cursor->content);
126 else if (cursor->code == 0x9)
127 print_lc_dysymtab((struct dysymtab_command *) cursor->content);
134 void
135 list_free_list(struct list *list)
137 struct node *cursor;
139 while ((cursor = list->head)) {
140 list->head = cursor->next;
141 free(cursor->content);
142 free(cursor);
145 free(list);
148 void
149 list_remove_node(struct list *list, struct node *temp)
151 /* cursor is the head of the list */
152 if ((temp == list->head) && (temp != list->tail)) {
153 list->head = temp->next;
154 list->head->prev = NULL;
155 /* cursor is the tail of the list */
156 } else if ((temp != list->head) && (temp == list->tail)) {
157 list->tail = temp->prev;
158 list->tail->next = NULL;
159 /* cursor is the only node */
160 } else if ((temp == list->head) && (temp == list->tail)) {
161 list->tail = list->head = NULL;
162 /* cursor is between head and tail */
163 } else {
164 temp->prev->next = temp->next;
165 temp->next->prev = temp->prev;
168 free(temp->content);
169 free(temp);
172 void
173 list_remove(struct list *list, int (*cond)(struct node*))
175 struct node *cursor,
176 *temp;
178 cursor = list->head;
179 while (cursor != NULL) {
180 temp = cursor;
182 cursor = (cursor != list->tail) ? cursor->next : NULL;
184 if ((*cond)(temp))
185 list_remove_node(list, temp);