MOT6502 assembler, disassembler and linker
Revisión | 353aaf3498160ede02bcb630d3c47755d83cfbd8 (tree) |
---|---|
Tiempo | 2013-02-07 18:40:09 |
Autor | astoria-d <astoria-d@my-s...> |
Commiter | astoria-d |
simple linker script support
@@ -1,7 +1,7 @@ | ||
1 | 1 | |
2 | 2 | BIN=motonesln |
3 | 3 | |
4 | -OBJS=nesln-main.o linker.o | |
4 | +OBJS=nesln-main.o linker.o lmap.o | |
5 | 5 | |
6 | 6 | |
7 | 7 | LIBS=-L../libs -lmotones |
@@ -52,7 +52,7 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
52 | 52 | closed = TRUE; |
53 | 53 | break; |
54 | 54 | } |
55 | - cl = cl->l.next; | |
55 | + cl = (struct closed_file*)cl->l.next; | |
56 | 56 | } |
57 | 57 | if (!closed) { |
58 | 58 | cl = malloc (sizeof(struct closed_file)); |
@@ -72,13 +72,13 @@ static void clear_seglist(struct seginfo* sg_head) { | ||
72 | 72 | wk_list = closed_list; |
73 | 73 | while (wk_list != NULL) { |
74 | 74 | struct closed_file *pp = wk_list; |
75 | - wk_list = wk_list->l.next; | |
75 | + wk_list = (struct closed_file*)wk_list->l.next; | |
76 | 76 | free(pp); |
77 | 77 | } |
78 | 78 | } |
79 | 79 | |
80 | 80 | |
81 | -struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char* fname) { | |
81 | +static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char* fname) { | |
82 | 82 | |
83 | 83 | struct seginfo * pseg = malloc (sizeof(struct seginfo)); |
84 | 84 |
@@ -152,6 +152,14 @@ int load_object (const char* obj_fname) { | ||
152 | 152 | return TRUE; |
153 | 153 | } |
154 | 154 | |
155 | +int sort_segment(void) { | |
156 | + return TRUE; | |
157 | +} | |
158 | + | |
159 | +int link_segment(const char* out_name) { | |
160 | + return TRUE; | |
161 | +} | |
162 | + | |
155 | 163 | void destroy_linker(void) { |
156 | 164 | if (seg_list) |
157 | 165 | clear_seglist (seg_list); |
@@ -0,0 +1,6 @@ | ||
1 | +#segment name, start address, size | |
2 | +HEADER 0x0000 0x0010 | |
3 | +STARTUP 0x8000 0x1000 | |
4 | +VECINFO 0xfffa 0x0006 | |
5 | +CHARS 0x0000 0x2000 | |
6 | + |
@@ -0,0 +1,118 @@ | ||
1 | + | |
2 | +#include <stdio.h> | |
3 | +#include <stdlib.h> | |
4 | +#include "tools.h" | |
5 | + | |
6 | +#define BUF_SIZE 100 | |
7 | + | |
8 | +struct lmap_entry { | |
9 | + struct dlist list; | |
10 | + char* seg_name; | |
11 | + unsigned short start; | |
12 | + unsigned short size; | |
13 | +}; | |
14 | + | |
15 | +static struct lmap_entry * lmap_list; | |
16 | + | |
17 | +int load_lmap(const char* fname) { | |
18 | + FILE* fp; | |
19 | + char ch; | |
20 | + char seg_name [100]; | |
21 | + int start, size; | |
22 | + int scan_cnt; | |
23 | + char* buf; | |
24 | + | |
25 | + fp = fopen (fname, "r"); | |
26 | + if (fp == NULL) | |
27 | + return FALSE; | |
28 | + | |
29 | + | |
30 | + while ( fread(&ch, 1, 1, fp) > 0 ){ | |
31 | + struct lmap_entry* lm; | |
32 | + //read line by line. | |
33 | + if (ch == '#') { | |
34 | + while ( fread(&ch, 1, 1, fp) > 0 ){ | |
35 | + if (ch == '\n') | |
36 | + break; | |
37 | + } | |
38 | + continue; | |
39 | + } | |
40 | + else { | |
41 | + int buf_cnt = 1; | |
42 | + int i = 0; | |
43 | + int size = BUF_SIZE; | |
44 | + | |
45 | + buf = malloc (size); | |
46 | + buf [i++] = ch; | |
47 | + //dprint("%c\n", ch); | |
48 | + while ( fread(&ch, 1, 1, fp) > 0 ){ | |
49 | + if (i == BUF_SIZE * buf_cnt) { | |
50 | + //dprint("realloc: %d\n", BUF_SIZE * buf_cnt); | |
51 | + buf = realloc(buf, BUF_SIZE * ++buf_cnt); | |
52 | + } | |
53 | + if (ch == '\n') { | |
54 | + buf [i] = '\0'; | |
55 | + break; | |
56 | + } | |
57 | + //dprint("%c\n", ch); | |
58 | + buf [i++] = ch; | |
59 | + } | |
60 | + buf [i] = '\0'; | |
61 | + //dprint("buf: %s\n", buf); | |
62 | + } | |
63 | + | |
64 | + //skip blank line | |
65 | + if (*buf == '\n') { | |
66 | + free(buf); | |
67 | + continue; | |
68 | + } | |
69 | + | |
70 | + scan_cnt = sscanf(buf, "%s %x %x", seg_name, &start, &size); | |
71 | + if (scan_cnt != 3) { | |
72 | + free (buf); | |
73 | + return FALSE; | |
74 | + } | |
75 | + dprint("seg: %s %04x, %04x\n", seg_name, start, size); | |
76 | + | |
77 | + //free (buf); | |
78 | + lm = malloc(sizeof(struct lmap_entry)); | |
79 | + dlist_init(&lm->list); | |
80 | + lm->seg_name = buf; | |
81 | + lm->start = start; | |
82 | + lm->size = size; | |
83 | + | |
84 | + if (!lmap_list) { | |
85 | + lmap_list = lm; | |
86 | + } | |
87 | + else { | |
88 | + dlist_add_tail(lmap_list, lm); | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + return TRUE; | |
93 | +} | |
94 | + | |
95 | +static void clear_lmap(void) { | |
96 | + struct lmap_entry *lm; | |
97 | + lm = lmap_list; | |
98 | + while (lm != NULL) { | |
99 | + struct lmap_entry *pp; | |
100 | + | |
101 | + pp = lm; | |
102 | + lm = (struct lmap_entry*)lm->list.next; | |
103 | + dlist_remove(&pp->list); | |
104 | + free(pp->seg_name); | |
105 | + free(pp); | |
106 | + } | |
107 | + | |
108 | +} | |
109 | + | |
110 | +int init_lmap(void) { | |
111 | + lmap_list = NULL; | |
112 | + return TRUE; | |
113 | +} | |
114 | + | |
115 | +void destory_lmap(void) { | |
116 | + clear_lmap(); | |
117 | +} | |
118 | + |
@@ -8,7 +8,10 @@ | ||
8 | 8 | int init_linker(void); |
9 | 9 | void destroy_linker(void); |
10 | 10 | |
11 | -static char* out_fname = NULL; | |
11 | +int sort_segment(void); | |
12 | +int link_segment(const char* out_name); | |
13 | +int init_lmap(void); | |
14 | +void destory_lmap(void); | |
12 | 15 | |
13 | 16 | int init_datas(void) { |
14 | 17 | int ret; |
@@ -18,15 +21,21 @@ int init_datas(void) { | ||
18 | 21 | fprintf(stderr, "linker initalization failed...\n"); |
19 | 22 | return FALSE; |
20 | 23 | } |
24 | + ret = init_lmap(); | |
25 | + if (!ret) { | |
26 | + fprintf(stderr, "linker config init failed...\n"); | |
27 | + return FALSE; | |
28 | + } | |
21 | 29 | return TRUE; |
22 | 30 | } |
23 | 31 | |
24 | 32 | void destroy_datas(void) { |
25 | 33 | destroy_linker(); |
34 | + destory_lmap(); | |
26 | 35 | } |
27 | 36 | |
28 | 37 | void print_usage(void) { |
29 | - printf("motonesln [option...] [.o files]\n"); | |
38 | + printf("motonesln -l linkmap [option...] [.o files]\n"); | |
30 | 39 | printf("Options:\n"); |
31 | 40 | printf("\t-h: print this page.\n"); |
32 | 41 | printf("\t-o [output]: output object file.\n"); |
@@ -38,11 +47,16 @@ int main (int argc, char** argv) { | ||
38 | 47 | extern int optind; |
39 | 48 | int need_free_out = FALSE; |
40 | 49 | int i; |
50 | + char* out_fname = NULL; | |
51 | + char* lmap_fname = NULL; | |
41 | 52 | |
42 | 53 | dprint("main...\n"); |
43 | 54 | |
44 | - while( (ch = getopt(argc, argv, "ho:")) != -1) { | |
55 | + while( (ch = getopt(argc, argv, "ho:l:")) != -1) { | |
45 | 56 | switch (ch) { |
57 | + case 'l': | |
58 | + lmap_fname = optarg; | |
59 | + break; | |
46 | 60 | case 'o': |
47 | 61 | out_fname = optarg; |
48 | 62 | break; |
@@ -62,11 +76,17 @@ int main (int argc, char** argv) { | ||
62 | 76 | return RT_ERROR; |
63 | 77 | } |
64 | 78 | |
65 | - if (argc == 1) { | |
79 | + if (argc == 1 || lmap_fname == NULL) { | |
66 | 80 | print_usage(); |
67 | 81 | return RT_ERROR; |
68 | 82 | } |
69 | 83 | |
84 | + ret = load_lmap(lmap_fname); | |
85 | + if (!ret) { | |
86 | + fprintf(stderr, "link map load error...\n"); | |
87 | + return RT_ERROR; | |
88 | + } | |
89 | + | |
70 | 90 | if (out_fname == NULL && argc == 2) { |
71 | 91 | const char* in_fname = argv[1]; |
72 | 92 | char *p, *pp; |
@@ -102,10 +122,17 @@ int main (int argc, char** argv) { | ||
102 | 122 | |
103 | 123 | ret = load_object(fname); |
104 | 124 | if (!ret) { |
105 | - fprintf(stderr, "link error...\n"); | |
125 | + fprintf(stderr, "load object error...\n"); | |
106 | 126 | goto done; |
107 | 127 | } |
128 | + } | |
108 | 129 | |
130 | + //linker main work here. | |
131 | + sort_segment(); | |
132 | + ret = link_segment(out_fname); | |
133 | + if (!ret) { | |
134 | + fprintf(stderr, "link error...\n"); | |
135 | + goto done; | |
109 | 136 | } |
110 | 137 | |
111 | 138 | ret = RT_OK; |
@@ -120,7 +147,3 @@ done: | ||
120 | 147 | return RT_ERROR; |
121 | 148 | } |
122 | 149 | |
123 | -const char* get_out_fname(void) { | |
124 | - return out_fname; | |
125 | -} | |
126 | - |