Rev 3401 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3401 | Rev 3554 | ||
---|---|---|---|
Line 45... | Line 45... | ||
45 | //void __io_init(void); |
45 | //void __io_init(void); |
46 | void __exit(void); |
46 | void __exit(void); |
47 | 47 | ||
48 | static void kputint(unsigned i) |
48 | static void kputint(unsigned i) |
49 | { |
49 | { |
50 | asm volatile ( |
50 | /* asm volatile ( |
51 | "mr %%r3, %0\n" |
51 | "mr %%r3, %0\n" |
52 | "li %%r9, 31\n" |
52 | "li %%r9, 31\n" |
53 | "sc\n" |
53 | "sc\n" |
54 | : |
54 | : |
55 | : "r" (i) |
55 | : "r" (i) |
56 | : "%r3","%r9" |
56 | : "%r3","%r9" |
57 | ) ; |
57 | ) ;*/ |
58 | } |
58 | } |
59 | 59 | ||
60 | #define __L(ptr) ((uint32_t)(ptr) & 0x0000ffff) |
60 | #define __L(ptr) ((uint32_t)(ptr) & 0x0000ffff) |
61 | #define __HA(ptr) ((uint32_t)(ptr) >> 16) |
61 | #define __HA(ptr) ((uint32_t)(ptr) >> 16) |
62 | 62 | ||
Line 140... | Line 140... | ||
140 | sym_table = 0; |
140 | sym_table = 0; |
141 | rel_table = 0; |
141 | rel_table = 0; |
142 | rel_entries = 0; |
142 | rel_entries = 0; |
143 | jmp_rel_table = 0; |
143 | jmp_rel_table = 0; |
144 | jmp_rel_entries = 0; |
144 | jmp_rel_entries = 0; |
145 | 145 | /* |
|
146 | i = 0; |
146 | i = 0; |
147 | while (dynamic[i].d_tag != 0) { |
147 | while (dynamic[i].d_tag != 0) { |
148 | // kputint((uintptr_t)&dynamic[i]); |
148 | // kputint((uintptr_t)&dynamic[i]); |
149 | // kputint((uintptr_t)&(dynamic[i].d_tag)); |
149 | // kputint((uintptr_t)&(dynamic[i].d_tag)); |
150 | // kputint(dynamic[i].d_tag); |
150 | // kputint(dynamic[i].d_tag); |
Line 152... | Line 152... | ||
152 | dptr = (void *)(dynamic[i].d_un.d_val + bias); |
152 | dptr = (void *)(dynamic[i].d_un.d_val + bias); |
153 | dval = dynamic[i].d_un.d_val; |
153 | dval = dynamic[i].d_un.d_val; |
154 | 154 | ||
155 | // kputint(0x10); |
155 | // kputint(0x10); |
156 | register unsigned tag = dynamic[i].d_tag; |
156 | register unsigned tag = dynamic[i].d_tag; |
157 | 157 | */ |
|
158 | /* |
158 | /* |
159 | * Note that switches only work because we are using |
159 | * Note that switches only work because we are using |
160 | * -fno-jump-tables. |
160 | * -fno-jump-tables. |
161 | */ |
161 | */ |
162 | switch (tag) { |
162 | /* switch (tag) { |
163 | case DT_PLTRELSZ: jmp_rel_entries = dval/sizeof(elf_rela_t); break; |
163 | case DT_PLTRELSZ: jmp_rel_entries = dval/sizeof(elf_rela_t); break; |
164 | case DT_JMPREL: jmp_rel_table = dptr; break; |
164 | case DT_JMPREL: jmp_rel_table = dptr; break; |
165 | case DT_PLTGOT: |
165 | case DT_PLTGOT:*/ |
166 | /* PLT address */ |
166 | /* PLT address */ |
167 | plt = dptr; break; |
167 | /* plt = dptr; break; |
168 | case DT_SYMTAB: sym_table = dptr; break; |
168 | case DT_SYMTAB: sym_table = dptr; break; |
169 | case DT_RELA: rel_table = dptr; break; |
169 | case DT_RELA: rel_table = dptr; break; |
170 | case DT_RELASZ: rel_entries = dval / sizeof(elf_rela_t); break; |
170 | case DT_RELASZ: rel_entries = dval / sizeof(elf_rela_t); break; |
171 | default: break; |
171 | default: break; |
172 | } |
172 | } |
173 | 173 | */ |
|
174 | // kputint(0x20); |
174 | // kputint(0x20); |
175 | 175 | /* |
|
176 | ++i; |
176 | ++i; |
177 | } |
177 | } |
178 | 178 | |
|
179 | kputint(1); |
179 | kputint(1); |
180 | kputint((unsigned)sym_table); |
180 | kputint((unsigned)sym_table); |
181 | kputint((unsigned)rel_table); |
181 | kputint((unsigned)rel_table); |
182 | kputint((unsigned)rel_entries); |
182 | kputint((unsigned)rel_entries); |
183 | 183 | ||
184 | /* Now relocate all our dynsyms */ |
184 | */ /* Now relocate all our dynsyms */ |
185 | kputint(-1); |
185 | kputint(-1); |
186 | 186 | ||
187 | // PLT entries start here. However, each occupies 2 words |
187 | // PLT entries start here. However, each occupies 2 words |
188 | _plt_ent = plt + 18; |
188 | // _plt_ent = plt + 18; |
189 | 189 | ||
190 | // By definition of the ppc ABI, there's 1:1 correspondence |
190 | // By definition of the ppc ABI, there's 1:1 correspondence |
191 | // between JMPREL entries and PLT entries |
191 | // between JMPREL entries and PLT entries |
192 | unsigned plt_n = jmp_rel_entries; |
192 | // unsigned plt_n = jmp_rel_entries; |
193 | 193 | /* |
|
194 | uint32_t *_plt_table; |
194 | uint32_t *_plt_table; |
195 | uint32_t *_plt_call; |
195 | uint32_t *_plt_call; |
196 | uint32_t *_plt_resolve; |
196 | uint32_t *_plt_resolve; |
197 | 197 | ||
198 | _plt_resolve = plt; |
198 | _plt_resolve = plt; |
Line 262... | Line 262... | ||
262 | sym_idx = ELF32_R_SYM(r_info); |
262 | sym_idx = ELF32_R_SYM(r_info); |
263 | sym_addr = sym_table[sym_idx].st_value + bias; |
263 | sym_addr = sym_table[sym_idx].st_value + bias; |
264 | kputint(sym_addr); |
264 | kputint(sym_addr); |
265 | res = (sym_addr - (uint32_t)r_ptr + a) >> 2; |
265 | res = (sym_addr - (uint32_t)r_ptr + a) >> 2; |
266 | kputint(res); |
266 | kputint(res); |
267 | if (res & 0xff000000) { |
267 | if (res & 0xff000000) {*/ |
268 | /* out of range?? */ |
268 | /* out of range?? */ |
269 | kputint(0xeeeeeeee); |
269 | /* kputint(0xeeeeeeee); |
270 | //while(1); |
270 | //while(1); |
271 | } |
271 | } |
272 | *r_ptr = (*r_ptr & ~0x00ffffff) | (res & 0x00ffffff); |
272 | *r_ptr = (*r_ptr & ~0x00ffffff) | (res & 0x00ffffff); |
273 | kputint(0x1d); |
273 | kputint(0x1d); |
274 | break; |
274 | break; |
275 | } |
275 | } |
276 | } |
276 | } |
277 | 277 | */ |
|
278 | kputint(-3); |
278 | kputint(-3); |
279 | if (plt != 0) { |
279 | // if (plt != 0) { |
280 | 280 | ||
281 | /* .PLTcall: */ |
281 | /* .PLTcall: */ |
282 | plt[6] = _ldis(11, __HA(_plt_table)); // ldis r11, .PLTtable@ha |
282 | // plt[6] = _ldis(11, __HA(_plt_table)); // ldis r11, .PLTtable@ha |
283 | plt[7] = _lwz(11, __L(_plt_table), 11); // lwz r11, .PLTtable@l(r11) |
283 | // plt[7] = _lwz(11, __L(_plt_table), 11); // lwz r11, .PLTtable@l(r11) |
284 | plt[8] = _mtctr(11); // mtctr r11 |
284 | // plt[8] = _mtctr(11); // mtctr r11 |
285 | plt[9] = _bctr(); |
285 | // plt[9] = _bctr(); |
286 | 286 | ||
287 | /* .PLTi, i = 0..N-1 */ |
287 | /* .PLTi, i = 0..N-1 */ |
288 | /* kputint(-4); |
288 | /* kputint(-4); |
289 | for (i = 0; i < plt_n; ++i) { |
289 | for (i = 0; i < plt_n; ++i) { |
290 | //_plt_table[i] == function address; |
290 | //_plt_table[i] == function address; |
291 | plt[18+i] = _b(_plt_call, &plt[18+i]); // b .PLTcall |
291 | plt[18+i] = _b(_plt_call, &plt[18+i]); // b .PLTcall |
292 | } |
292 | } |
293 | */ |
293 | */ |
294 | kputint(-5); |
294 | // kputint(-5); |
295 | kputint(_plt_table[0]); |
295 | // kputint(_plt_table[0]); |
296 | } |
296 | // } |
297 | 297 | ||
298 | kputint(-6); |
298 | // kputint(-6); |
299 | /* This will come in handy */ |
299 | /* This will come in handy */ |
300 | runtime_env.rtld_dynamic = dynamic; |
300 | // runtime_env.rtld_dynamic = dynamic; |
301 | runtime_env.rtld.bias = bias; |
301 | // runtime_env.rtld.bias = bias; |
302 | 302 | ||
303 | // volatile int ff=1; |
303 | // volatile int ff=1; |
304 | // while(ff); |
304 | // while(ff); |
305 | kputint(-7); |
305 | kputint(-7); |
306 | test_func(); |
306 | test_func(); |