MOT6502 assembler, disassembler and linker
Revisión | 7f339f6d925833cc2e08ebf51c430b73a42d0fe3 (tree) |
---|---|
Tiempo | 2013-02-08 14:27:32 |
Autor | astoria-d <astoria-d@my-s...> |
Commiter | astoria-d |
link ok
@@ -17,6 +17,8 @@ struct seginfo { | ||
17 | 17 | struct symmap *sym_table; |
18 | 18 | struct symmap *unresolved_symbol; |
19 | 19 | unsigned short current_pc; |
20 | + unsigned short segaddr; | |
21 | + unsigned short segpos; | |
20 | 22 | unsigned short segsize; |
21 | 23 | |
22 | 24 | char* out_fname; |
@@ -6,6 +6,7 @@ | ||
6 | 6 | #include "segment.h" |
7 | 7 | |
8 | 8 | #define DEFAULT_SEGMENT "<default>" |
9 | +#define BUF_SIZE 100 | |
9 | 10 | |
10 | 11 | static struct seginfo* seg_list; |
11 | 12 |
@@ -35,7 +36,7 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
35 | 36 | if (pp->unresolved_symbol) |
36 | 37 | clear_symtbl_list(pp->unresolved_symbol); |
37 | 38 | |
38 | - dprint("free segmeng %s: %s\n", pp->out_fname, pp->name); | |
39 | + //dprint("free segmeng %s: %s\n", pp->out_fname, pp->name); | |
39 | 40 | if (pp->name) |
40 | 41 | free(pp->name); |
41 | 42 |
@@ -94,14 +95,13 @@ static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char | ||
94 | 95 | else |
95 | 96 | pseg->name = strdup(sgh->seg_name); |
96 | 97 | |
97 | - dprint("segment: %s\n", pseg->name); | |
98 | + //dprint("segment: %s\n", pseg->name); | |
98 | 99 | //mv symtable |
99 | 100 | pseg->sym_table = sgh->symbols; |
100 | 101 | sgh->symbols = NULL; |
101 | 102 | pseg->unresolved_symbol = sgh->unresolved_symbols; |
102 | 103 | sgh->unresolved_symbols = NULL; |
103 | 104 | |
104 | - ///current pc is set to segment start address. | |
105 | 105 | ret = lookup_lmap(pseg->name, &start, &size); |
106 | 106 | if (!ret) { |
107 | 107 | fprintf(stderr, "invalid segment [%s]\n", pseg->name); |
@@ -109,7 +109,9 @@ static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char | ||
109 | 109 | free (pseg); |
110 | 110 | return NULL; |
111 | 111 | } |
112 | - pseg->current_pc = start; | |
112 | + pseg->current_pc = 0; | |
113 | + pseg->segaddr = start; | |
114 | + pseg->segpos = sgh->seg_start_pos; | |
113 | 115 | pseg->segsize = sgh->seg_data_size; |
114 | 116 | |
115 | 117 | pseg->out_fname = strdup(fname); |
@@ -119,6 +121,7 @@ static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char | ||
119 | 121 | } |
120 | 122 | |
121 | 123 | static int add_segment_list(struct seginfo *pseg) { |
124 | + //dprint("add_seg: %s\n", pseg->name); | |
122 | 125 | if (seg_list == NULL) |
123 | 126 | seg_list = pseg; |
124 | 127 | else |
@@ -135,16 +138,19 @@ static int add_segment_list(struct seginfo *pseg) { | ||
135 | 138 | |
136 | 139 | node = seg_list; |
137 | 140 | while(node != NULL) { |
138 | - //now current_pc is pointing at the segment start address. | |
139 | - if (node->current_pc > start) { | |
141 | + //dprint("%s: segaddr:%04x, start:%04x\n", node->name, node->segaddr, start); | |
142 | + if (node->segaddr > start) { | |
140 | 143 | break; |
141 | 144 | } |
142 | 145 | node = (struct seginfo*) node->list.next; |
143 | 146 | } |
144 | 147 | |
145 | 148 | //sort segment by the start address |
146 | - if (node) | |
149 | + if (node) { | |
147 | 150 | dlist_add_prev(&node->list, &pseg->list); |
151 | + if (node == seg_list) | |
152 | + seg_list = pseg; | |
153 | + } | |
148 | 154 | else |
149 | 155 | dlist_add_tail(&seg_list->list, &pseg->list); |
150 | 156 | } |
@@ -209,7 +215,49 @@ int load_object (const char* obj_fname) { | ||
209 | 215 | return TRUE; |
210 | 216 | } |
211 | 217 | |
212 | -int link_segment(const char* out_name) { | |
218 | +static int resolve_symbol(const char* symname) { | |
219 | + ////not worked yet... | |
220 | + return FALSE; | |
221 | +} | |
222 | + | |
223 | +int link_segment(FILE* outf) { | |
224 | + struct seginfo* pseg; | |
225 | + pseg = seg_list; | |
226 | + while (pseg != NULL) { | |
227 | + FILE *objfp = pseg->fp; | |
228 | + int ret; | |
229 | + char * buf; | |
230 | + int read_size = 0; | |
231 | + int len, total_len; | |
232 | + | |
233 | + dprint("link seg: %s %d byte @ %04x from %04x\n", pseg->name, | |
234 | + pseg->segsize, pseg->segaddr, pseg->segpos); | |
235 | + | |
236 | + ret = fseek(objfp, pseg->segpos, SEEK_SET); | |
237 | + if (ret) | |
238 | + return FALSE; | |
239 | + | |
240 | + buf = malloc(BUF_SIZE); | |
241 | + if (!buf) | |
242 | + return FALSE; | |
243 | + len = total_len = 0; | |
244 | + read_size = pseg->segsize < BUF_SIZE ? pseg->segsize : BUF_SIZE ; | |
245 | + while ( (len = fread(buf, 1, read_size, objfp)) > 0) { | |
246 | + fwrite(buf, 1, read_size, outf); | |
247 | + total_len += len; | |
248 | + read_size = pseg->segsize - total_len < BUF_SIZE ? | |
249 | + pseg->segsize - total_len : BUF_SIZE ; | |
250 | + | |
251 | + if ( total_len == pseg->segsize) | |
252 | + break; | |
253 | + } | |
254 | + free(buf); | |
255 | + if ( total_len != pseg->segsize ) { | |
256 | + return FALSE; | |
257 | + } | |
258 | + | |
259 | + pseg = (struct seginfo*) pseg->list.next; | |
260 | + } | |
213 | 261 | return TRUE; |
214 | 262 | } |
215 | 263 |
@@ -9,7 +9,7 @@ int init_linker(void); | ||
9 | 9 | void destroy_linker(void); |
10 | 10 | |
11 | 11 | int sort_segment(void); |
12 | -int link_segment(const char* out_name); | |
12 | +int link_segment(FILE* outf); | |
13 | 13 | int init_lmap(void); |
14 | 14 | void destory_lmap(void); |
15 | 15 |
@@ -49,6 +49,7 @@ int main (int argc, char** argv) { | ||
49 | 49 | int i; |
50 | 50 | char* out_fname = NULL; |
51 | 51 | char* lmap_fname = NULL; |
52 | + FILE *outfp; | |
52 | 53 | |
53 | 54 | dprint("main...\n"); |
54 | 55 |
@@ -128,14 +129,21 @@ int main (int argc, char** argv) { | ||
128 | 129 | } |
129 | 130 | |
130 | 131 | //linker main work here. |
131 | - ret = link_segment(out_fname); | |
132 | + outfp = fopen (out_fname, "w"); | |
133 | + if (outfp == NULL) { | |
134 | + fprintf(stderr, "out file error...\n", out_fname); | |
135 | + goto done; | |
136 | + } | |
137 | + ret = link_segment(outfp); | |
132 | 138 | if (!ret) { |
139 | + fclose(outfp); | |
133 | 140 | fprintf(stderr, "link error...\n"); |
134 | 141 | goto done; |
135 | 142 | } |
136 | 143 | |
137 | 144 | dprint("link succeeded\n"); |
138 | 145 | ret = RT_OK; |
146 | + fclose(outfp); | |
139 | 147 | |
140 | 148 | done: |
141 | 149 |