• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

MOT6502 assembler, disassembler and linker


Commit MetaInfo

Revisionae0889a7d762f5235290c665d15a558cf5352c3b (tree)
Time2013-02-08 12:06:08
Authorastoria-d <astoria-d@my-s...>
Commiterastoria-d

Log Message

segment sort supported

Change Summary

Incremental Difference

--- a/include/tools.h
+++ b/include/tools.h
@@ -18,6 +18,7 @@ int slist_count (struct slist* head);
1818
1919 void dlist_init (struct dlist* node) ;
2020 void dlist_add_next (struct dlist* dest, struct dlist* node) ;
21+void dlist_add_prev (struct dlist* dest, struct dlist* node) ;
2122 int dlist_remove (struct dlist* node) ;
2223 int dlist_count (struct dlist* head);
2324
--- a/libs/tools.c
+++ b/libs/tools.c
@@ -45,6 +45,17 @@ void dlist_add_next (struct dlist* dest, struct dlist* node) {
4545 node->next = next_node;
4646 }
4747
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+
4859 void dlist_add_tail (struct dlist* dest, struct dlist* node) {
4960 struct dlist* next_node = dest->next;
5061 struct dlist* tail_node = dest;
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -5,8 +5,12 @@
55 #include "obj-format.h"
66 #include "segment.h"
77
8+#define DEFAULT_SEGMENT "<default>"
9+
810 static struct seginfo* seg_list;
911
12+int lookup_lmap(const char* segname, unsigned short *start, unsigned short *size);
13+
1014 static void clear_seglist(struct seginfo* sg_head) {
1115 struct seginfo* pseg;
1216
@@ -16,7 +20,7 @@ static void clear_seglist(struct seginfo* sg_head) {
1620 } * closed_list = NULL;
1721 struct closed_file *wk_list;
1822
19- dprint("clear_seglist.\n");
23+ //dprint("clear_seglist.\n");
2024 pseg = sg_head;
2125 while (pseg != NULL) {
2226 struct seginfo* pp = pseg;
@@ -41,7 +45,7 @@ static void clear_seglist(struct seginfo* sg_head) {
4145 closed_list = malloc (sizeof(struct closed_file));
4246 closed_list->l.next = NULL;
4347 closed_list->fp = pp->fp;
44- dprint("file close %s\n", pp->out_fname);
48+ //dprint("file close %s\n", pp->out_fname);
4549 fclose(pp->fp);
4650 }
4751 else {
@@ -59,7 +63,7 @@ static void clear_seglist(struct seginfo* sg_head) {
5963 cl->l.next = NULL;
6064 cl->fp = pp->fp;
6165 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);
6367 fclose(pp->fp);
6468 }
6569 }
@@ -79,19 +83,33 @@ static void clear_seglist(struct seginfo* sg_head) {
7983
8084
8185 static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char* fname) {
82-
8386 struct seginfo * pseg = malloc (sizeof(struct seginfo));
87+ unsigned short start, size;
88+ int ret;
8489
85- dprint("segment: %s\n", sgh->seg_name);
8690 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);
8898 //mv symtable
8999 pseg->sym_table = sgh->symbols;
90100 sgh->symbols = NULL;
91101 pseg->unresolved_symbol = sgh->unresolved_symbols;
92102 sgh->unresolved_symbols = NULL;
93103
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;
95113 pseg->segsize = sgh->seg_data_size;
96114
97115 pseg->out_fname = strdup(fname);
@@ -100,11 +118,45 @@ static struct seginfo * segh2segi (struct seghdr *sgh, FILE* objfile, const char
100118 return pseg;
101119 }
102120
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+
103154 int load_object (const char* obj_fname) {
104155 FILE* fp;
105156 struct molfhdr* molh;
106157 int segh_start;
107158 int i, seg_cnt;
159+ int ret;
108160
109161 fp=fopen(obj_fname, "r");
110162 if (fp == NULL) {
@@ -139,10 +191,15 @@ int load_object (const char* obj_fname) {
139191 }
140192
141193 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+ }
146203
147204 //segh_start += sgh->seg_data_size;
148205
@@ -152,10 +209,6 @@ int load_object (const char* obj_fname) {
152209 return TRUE;
153210 }
154211
155-int sort_segment(void) {
156- return TRUE;
157-}
158-
159212 int link_segment(const char* out_name) {
160213 return TRUE;
161214 }
--- a/linker/linkmap
+++ b/linker/linkmap
@@ -3,4 +3,4 @@ HEADER 0x0000 0x0010
33 STARTUP 0x8000 0x1000
44 VECINFO 0xfffa 0x0006
55 CHARS 0x0000 0x2000
6-
6+<default> 0x8000 0x1000
--- a/linker/lmap.c
+++ b/linker/lmap.c
@@ -14,6 +14,24 @@ struct lmap_entry {
1414
1515 static struct lmap_entry * lmap_list;
1616
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+
1735 int load_lmap(const char* fname) {
1836 FILE* fp;
1937 char ch;
@@ -72,12 +90,12 @@ int load_lmap(const char* fname) {
7290 free (buf);
7391 return FALSE;
7492 }
75- dprint("seg: %s %04x, %04x\n", seg_name, start, size);
93+ //dprint("seg: %s %04x, %04x\n", seg_name, start, size);
7694
7795 //free (buf);
7896 lm = malloc(sizeof(struct lmap_entry));
7997 dlist_init(&lm->list);
80- lm->seg_name = buf;
98+ lm->seg_name = strdup(seg_name);
8199 lm->start = start;
82100 lm->size = size;
83101
--- a/linker/nesln-main.c
+++ b/linker/nesln-main.c
@@ -128,13 +128,13 @@ int main (int argc, char** argv) {
128128 }
129129
130130 //linker main work here.
131- sort_segment();
132131 ret = link_segment(out_fname);
133132 if (!ret) {
134133 fprintf(stderr, "link error...\n");
135134 goto done;
136135 }
137136
137+ dprint("link succeeded\n");
138138 ret = RT_OK;
139139
140140 done: