comparison lwlink/link.c @ 236:ce1fdc8d6568

Added ability to add padding after a section when linking. Added the ability for lwlink to automatically append padding bytes to the end of a section (once the section instances are merged). This behaviour is controlled by the link script. See the updated documentation for more information.
author William Astle <lost@l-w.ca>
date Sat, 11 Aug 2012 23:29:57 -0600
parents e3741cf53e00
children 91f91557dc9e
comparison
equal deleted inserted replaced
235:e3741cf53e00 236:ce1fdc8d6568
40 40
41 int quietsym = 1; 41 int quietsym = 1;
42 42
43 symlist_t *symlist = NULL; 43 symlist_t *symlist = NULL;
44 44
45 sectopt_t *section_opts = NULL;
46
45 void check_section_name(char *name, int *base, fileinfo_t *fn) 47 void check_section_name(char *name, int *base, fileinfo_t *fn)
46 { 48 {
47 int sn; 49 int sn;
48
49 // fprintf(stderr, "Considering sections in %s (%d) for %s\n", fn -> filename, fn -> forced, name); 50 // fprintf(stderr, "Considering sections in %s (%d) for %s\n", fn -> filename, fn -> forced, name);
50 if (fn -> forced == 0) 51 if (fn -> forced == 0)
51 return; 52 return;
52 53
53 for (sn = 0; sn < fn -> nsections; sn++) 54 for (sn = 0; sn < fn -> nsections; sn++)
77 78
78 void add_matching_sections(char *name, int yesflags, int noflags, int *base); 79 void add_matching_sections(char *name, int yesflags, int noflags, int *base);
79 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) 80 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn)
80 { 81 {
81 int sn; 82 int sn;
83 sectopt_t *so;
82 84
83 // fprintf(stderr, "Considering sections in %s (%d) for %x/%x\n", fn -> filename, fn -> forced, yesflags, noflags); 85 // fprintf(stderr, "Considering sections in %s (%d) for %x/%x\n", fn -> filename, fn -> forced, yesflags, noflags);
84 86
85 if (fn -> forced == 0) 87 if (fn -> forced == 0)
86 return; 88 return;
101 continue; 103 continue;
102 104
103 // we have a match - now collect *all* sections of the same name! 105 // we have a match - now collect *all* sections of the same name!
104 // fprintf(stderr, " Found\n"); 106 // fprintf(stderr, " Found\n");
105 add_matching_sections((char *)(fn -> sections[sn].name), 0, 0, base); 107 add_matching_sections((char *)(fn -> sections[sn].name), 0, 0, base);
108
109 /* handle "after padding" */
110 for (so = section_opts; so; so = so -> next)
111 if (!strcmp(so -> name, (char *)(fn -> sections[sn].name)))
112 break;
113 if (so)
114 {
115 if (so -> aftersize)
116 {
117 sectlist[nsects - 1].ptr -> afterbytes = so -> afterbytes;
118 sectlist[nsects - 1].ptr -> aftersize = so -> aftersize;
119 *base += so -> aftersize;
120 }
121 }
106 122
107 // and then continue looking for sections 123 // and then continue looking for sections
108 } 124 }
109 for (sn = 0; sn < fn -> nsubs; sn++) 125 for (sn = 0; sn < fn -> nsubs; sn++)
110 { 126 {
144 // make a list of sections to load in order 160 // make a list of sections to load in order
145 void resolve_sections(void) 161 void resolve_sections(void)
146 { 162 {
147 int laddr = 0; 163 int laddr = 0;
148 int ln, sn, fn; 164 int ln, sn, fn;
165 sectopt_t *so;
149 166
150 for (ln = 0; ln < linkscript.nlines; ln++) 167 for (ln = 0; ln < linkscript.nlines; ln++)
151 { 168 {
152 if (linkscript.lines[ln].loadat >= 0) 169 if (linkscript.lines[ln].loadat >= 0)
153 laddr = linkscript.lines[ln].loadat; 170 laddr = linkscript.lines[ln].loadat;
171 fprintf(stderr, "Adding section %s\n", linkscript.lines[ln].sectname);
154 add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr); 172 add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr);
155 173
156 if (linkscript.lines[ln].sectname) 174 if (linkscript.lines[ln].sectname)
157 { 175 {
176 char *sname = linkscript.lines[ln].sectname;
177 /* handle "after padding" */
178 for (so = section_opts; so; so = so -> next)
179 if (!strcmp(so -> name, sname))
180 break;
181 if (so)
182 {
183 if (so -> aftersize)
184 {
185 sectlist[nsects - 1].ptr -> afterbytes = so -> afterbytes;
186 sectlist[nsects - 1].ptr -> aftersize = so -> aftersize;
187 laddr += so -> aftersize;
188 }
189 }
158 } 190 }
159 else 191 else
160 { 192 {
161 // wildcard section 193 // wildcard section
162 // look for all sections not yet processed that match flags 194 // look for all sections not yet processed that match flags
182 if (linkscript.lines[ln].yesflags && ((inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].yesflags) == 0)) 214 if (linkscript.lines[ln].yesflags && ((inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].yesflags) == 0))
183 continue; 215 continue;
184 if (inputfiles[fn0] -> sections[sn0].processed == 0) 216 if (inputfiles[fn0] -> sections[sn0].processed == 0)
185 { 217 {
186 sname = (char *)(inputfiles[fn0] -> sections[sn0].name); 218 sname = (char *)(inputfiles[fn0] -> sections[sn0].name);
219 fprintf(stderr, "Adding sectoin %s\n", sname);
187 for (fn = 0; fn < ninputfiles; fn++) 220 for (fn = 0; fn < ninputfiles; fn++)
188 { 221 {
189 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) 222 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++)
190 { 223 {
191 if (!strcmp(sname, (char *)(inputfiles[fn] -> sections[sn].name))) 224 if (!strcmp(sname, (char *)(inputfiles[fn] -> sections[sn].name)))
718 linkscript.modlang &= 15; 751 linkscript.modlang &= 15;
719 linkscript.modtype &= 15; 752 linkscript.modtype &= 15;
720 linkscript.modrev &= 15; 753 linkscript.modrev &= 15;
721 linkscript.modattr &= 15; 754 linkscript.modattr &= 15;
722 } 755 }
756
757 void resolve_padding(void)
758 {
759 int sn;
760
761 for (sn = 0; sn < nsects; sn++)
762 {
763 if (sectlist[sn].ptr -> afterbytes)
764 {
765 unsigned char *t;
766
767 t = lw_alloc(sectlist[sn].ptr -> codesize + sectlist[sn].ptr -> aftersize);
768 memmove(t, sectlist[sn].ptr -> code, sectlist[sn].ptr -> codesize);
769 sectlist[sn].ptr -> code = t;
770 memmove(sectlist[sn].ptr -> code + sectlist[sn].ptr -> codesize, sectlist[sn].ptr -> afterbytes, sectlist[sn].ptr -> aftersize);
771 sectlist[sn].ptr -> codesize += sectlist[sn].ptr -> aftersize;
772 }
773 }
774 }