MOT6502 assembler, disassembler and linker
Revisión | ae0889a7d762f5235290c665d15a558cf5352c3b (tree) |
---|---|
Tiempo | 2013-02-08 12:06:08 |
Autor | astoria-d <astoria-d@my-s...> |
Commiter | astoria-d |
segment sort supported
@@ -18,6 +18,7 @@ int slist_count (struct slist* head); | ||
18 | 18 | |
19 | 19 | void dlist_init (struct dlist* node) ; |
20 | 20 | void dlist_add_next (struct dlist* dest, struct dlist* node) ; |
21 | +void dlist_add_prev (struct dlist* dest, struct dlist* node) ; | |
21 | 22 | int dlist_remove (struct dlist* node) ; |
22 | 23 | int dlist_count (struct dlist* head); |
23 | 24 |
@@ -45,6 +45,17 @@ void dlist_add_next (struct dlist* dest, struct dlist* node) { | ||
45 | 45 | node->next = next_node; |
46 | 46 | } |
47 | 47 | |
48 | +void dlist_add_prev (struct dlist* dest, struct dlist* node) { | |
49 | + struct dlist* prev_node = dest->prev; | |
50 | + | |
51 | + if (prev_node) { | |
52 | + prev_node->next = node; | |
53 | + } | |
54 | + dest->prev = node; | |
55 | + node->prev = prev_node; | |
56 | + node->next = dest; | |
57 | +} | |
58 | + | |
48 | 59 | void dlist_add_tail (struct dlist* dest, struct dlist* node) { |
49 | 60 | struct dlist* next_node = dest->next; |
50 | 61 | struct dlist* tail_node = dest; |
@@ -5,8 +5,12 @@ | ||
5 | 5 | #include "obj-format.h" |
6 | 6 | #include "segment.h" |
7 | 7 | |
8 | +#define DEFAULT_SEGMENT "<default>" | |
9 | + | |
8 | 10 | static struct seginfo* seg_list; |
9 | 11 | |
12 | +int lookup_lmap(const char* segname, unsigned short *start, unsigned short *size); | |
13 | + | |
10 | 14 | static void clear_seglist(struct seginfo* sg_head) { |
11 | 15 | struct seginfo* pseg; |
12 | 16 |
@@ -16,7 +20,7 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
16 | 20 | } * closed_list = NULL; |
17 | 21 | struct closed_file *wk_list; |
18 | 22 | |
19 | - dprint("clear_seglist.\n"); | |
23 | + //dprint("clear_seglist.\n"); | |
20 | 24 | pseg = sg_head; |
21 | 25 | while (pseg != NULL) { |
22 | 26 | struct seginfo* pp = pseg; |
@@ -41,7 +45,7 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
41 | 45 | closed_list = malloc (sizeof(struct closed_file)); |
42 | 46 | closed_list->l.next = NULL; |
43 | 47 | closed_list->fp = pp->fp; |
44 | - dprint("file close %s\n", pp->out_fname); | |
48 | + //dprint("file close %s\n", pp->out_fname); | |
45 | 49 | fclose(pp->fp); |
46 | 50 | } |
47 | 51 | else { |
@@ -59,7 +63,7 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
59 | 63 | cl->l.next = NULL; |
60 | 64 | cl->fp = pp->fp; |
61 | 65 | slist_add_tail(&closed_list->l, &cl->l); |
62 | - dprint("file close %s\n", pp->out_fname); | |
66 | + //dprint("file close %s\n", pp->out_fname); | |
63 | 67 | fclose(pp->fp); |
64 | 68 | } |
65 | 69 | } |
@@ -79,19 +83,33 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
79 | 83 | |
80 | 84 | |
81 | 85 | static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char* fname) { |
82 | - | |
83 | 86 | struct seginfo * pseg = malloc (sizeof(struct seginfo)); |
87 | + unsigned short start, size; | |
88 | + int ret; | |
84 | 89 | |
85 | - dprint("segment: %s\n", sgh->seg_name); | |
86 | 90 | dlist_init (&pseg->list); |
87 | - pseg->name = strdup(sgh->seg_name); | |
91 | + | |
92 | + if (sgh->seg_name[0] == '\0') | |
93 | + pseg->name = strdup(DEFAULT_SEGMENT); | |
94 | + else | |
95 | + pseg->name = strdup(sgh->seg_name); | |
96 | + | |
97 | + dprint("segment: %s\n", pseg->name); | |
88 | 98 | //mv symtable |
89 | 99 | pseg->sym_table = sgh->symbols; |
90 | 100 | sgh->symbols = NULL; |
91 | 101 | pseg->unresolved_symbol = sgh->unresolved_symbols; |
92 | 102 | sgh->unresolved_symbols = NULL; |
93 | 103 | |
94 | - pseg->current_pc = 0; | |
104 | + ///current pc is set to segment start address. | |
105 | + ret = lookup_lmap(pseg->name, &start, &size); | |
106 | + if (!ret) { | |
107 | + fprintf(stderr, "invalid segment [%s]\n", pseg->name); | |
108 | + free (pseg->name); | |
109 | + free (pseg); | |
110 | + return NULL; | |
111 | + } | |
112 | + pseg->current_pc = start; | |
95 | 113 | pseg->segsize = sgh->seg_data_size; |
96 | 114 | |
97 | 115 | pseg->out_fname = strdup(fname); |
@@ -100,11 +118,45 @@ static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char | ||
100 | 118 | return pseg; |
101 | 119 | } |
102 | 120 | |
121 | +static int add_segment_list(struct seginfo *pseg) { | |
122 | + if (seg_list == NULL) | |
123 | + seg_list = pseg; | |
124 | + else | |
125 | + { | |
126 | + int ret; | |
127 | + unsigned short start, size; | |
128 | + struct seginfo* node; | |
129 | + | |
130 | + ret = lookup_lmap(pseg->name, &start, &size); | |
131 | + if (!ret) { | |
132 | + fprintf(stderr, "invalid segment [%s]\n", pseg->name); | |
133 | + return FALSE; | |
134 | + } | |
135 | + | |
136 | + node = seg_list; | |
137 | + while(node != NULL) { | |
138 | + //now current_pc is pointing at the segment start address. | |
139 | + if (node->current_pc > start) { | |
140 | + break; | |
141 | + } | |
142 | + node = (struct seginfo*) node->list.next; | |
143 | + } | |
144 | + | |
145 | + //sort segment by the start address | |
146 | + if (node) | |
147 | + dlist_add_prev(&node->list, &pseg->list); | |
148 | + else | |
149 | + dlist_add_tail(&seg_list->list, &pseg->list); | |
150 | + } | |
151 | + return TRUE; | |
152 | +} | |
153 | + | |
103 | 154 | int load_object (const char* obj_fname) { |
104 | 155 | FILE* fp; |
105 | 156 | struct molfhdr* molh; |
106 | 157 | int segh_start; |
107 | 158 | int i, seg_cnt; |
159 | + int ret; | |
108 | 160 | |
109 | 161 | fp=fopen(obj_fname, "r"); |
110 | 162 | if (fp == NULL) { |
@@ -139,10 +191,15 @@ int load_object (const char* obj_fname) { | ||
139 | 191 | } |
140 | 192 | |
141 | 193 | pseg = segh2segi(sgh, fp, obj_fname); |
142 | - if (seg_list == NULL) | |
143 | - seg_list = pseg; | |
144 | - else | |
145 | - dlist_add_tail(&seg_list->list, &pseg->list); | |
194 | + if (!pseg) { | |
195 | + clear_segh(sgh); | |
196 | + return FALSE; | |
197 | + } | |
198 | + ret = add_segment_list(pseg); | |
199 | + if (!ret) { | |
200 | + clear_segh(sgh); | |
201 | + return FALSE; | |
202 | + } | |
146 | 203 | |
147 | 204 | //segh_start += sgh->seg_data_size; |
148 | 205 |
@@ -152,10 +209,6 @@ int load_object (const char* obj_fname) { | ||
152 | 209 | return TRUE; |
153 | 210 | } |
154 | 211 | |
155 | -int sort_segment(void) { | |
156 | - return TRUE; | |
157 | -} | |
158 | - | |
159 | 212 | int link_segment(const char* out_name) { |
160 | 213 | return TRUE; |
161 | 214 | } |
@@ -3,4 +3,4 @@ HEADER 0x0000 0x0010 | ||
3 | 3 | STARTUP 0x8000 0x1000 |
4 | 4 | VECINFO 0xfffa 0x0006 |
5 | 5 | CHARS 0x0000 0x2000 |
6 | - | |
6 | +<default> 0x8000 0x1000 |
@@ -14,6 +14,24 @@ struct lmap_entry { | ||
14 | 14 | |
15 | 15 | static struct lmap_entry * lmap_list; |
16 | 16 | |
17 | + | |
18 | +int lookup_lmap(const char* segname, unsigned short *start, unsigned short *size) { | |
19 | + struct lmap_entry *lm; | |
20 | + //dprint("lookup_lmap %s\n", segname); | |
21 | + | |
22 | + lm = lmap_list; | |
23 | + while (lm != NULL) { | |
24 | + //dprint(">>: %s\n", lm->seg_name); | |
25 | + if (!strcmp(segname, lm->seg_name)) { | |
26 | + *start = lm->start; | |
27 | + *size = lm->size; | |
28 | + return TRUE; | |
29 | + } | |
30 | + lm = (struct lmap_entry*)lm->list.next; | |
31 | + } | |
32 | + return FALSE; | |
33 | +} | |
34 | + | |
17 | 35 | int load_lmap(const char* fname) { |
18 | 36 | FILE* fp; |
19 | 37 | char ch; |
@@ -72,12 +90,12 @@ int load_lmap(const char* fname) { | ||
72 | 90 | free (buf); |
73 | 91 | return FALSE; |
74 | 92 | } |
75 | - dprint("seg: %s %04x, %04x\n", seg_name, start, size); | |
93 | + //dprint("seg: %s %04x, %04x\n", seg_name, start, size); | |
76 | 94 | |
77 | 95 | //free (buf); |
78 | 96 | lm = malloc(sizeof(struct lmap_entry)); |
79 | 97 | dlist_init(&lm->list); |
80 | - lm->seg_name = buf; | |
98 | + lm->seg_name = strdup(seg_name); | |
81 | 99 | lm->start = start; |
82 | 100 | lm->size = size; |
83 | 101 |
@@ -128,13 +128,13 @@ int main (int argc, char** argv) { | ||
128 | 128 | } |
129 | 129 | |
130 | 130 | //linker main work here. |
131 | - sort_segment(); | |
132 | 131 | ret = link_segment(out_fname); |
133 | 132 | if (!ret) { |
134 | 133 | fprintf(stderr, "link error...\n"); |
135 | 134 | goto done; |
136 | 135 | } |
137 | 136 | |
137 | + dprint("link succeeded\n"); | |
138 | 138 | ret = RT_OK; |
139 | 139 | |
140 | 140 | done: |