Rev 2929 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2929 | Rev 2932 | ||
---|---|---|---|
Line 42... | Line 42... | ||
42 | #include <align.h> |
42 | #include <align.h> |
43 | #include <assert.h> |
43 | #include <assert.h> |
44 | #include <as.h> |
44 | #include <as.h> |
45 | #include "elf.h" |
45 | #include "elf.h" |
46 | 46 | ||
- | 47 | #define RTLD_BIAS 0x80000 |
|
47 | 48 | ||
48 | static char *error_codes[] = { |
49 | static char *error_codes[] = { |
49 | "no error", |
50 | "no error", |
50 | "invalid image", |
51 | "invalid image", |
51 | "address space error", |
52 | "address space error", |
Line 104... | Line 105... | ||
104 | /* Check if the object type is supported. */ |
105 | /* Check if the object type is supported. */ |
105 | if (header->e_type != ET_EXEC && header->e_type != ET_DYN) { |
106 | if (header->e_type != ET_EXEC && header->e_type != ET_DYN) { |
106 | printf("Object type %d is not supported\n", header->e_type); |
107 | printf("Object type %d is not supported\n", header->e_type); |
107 | return EE_UNSUPPORTED; |
108 | return EE_UNSUPPORTED; |
108 | } |
109 | } |
109 | if (header->e_type == ET_DYN) header->e_entry += 0x40000; |
110 | if (header->e_type == ET_DYN) header->e_entry += RTLD_BIAS; |
110 | 111 | ||
111 | printf("parse segments\n"); |
112 | printf("parse segments\n"); |
112 | 113 | ||
113 | /* Walk through all segment headers and process them. */ |
114 | /* Walk through all segment headers and process them. */ |
114 | for (i = 0; i < header->e_phnum; i++) { |
115 | for (i = 0; i < header->e_phnum; i++) { |
Line 198... | Line 199... | ||
198 | */ |
199 | */ |
199 | int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf) |
200 | int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf) |
200 | { |
201 | { |
201 | void *a; |
202 | void *a; |
202 | int flags = 0; |
203 | int flags = 0; |
203 | uintptr_t load_displ; |
204 | uintptr_t bias; |
204 | int rc; |
205 | int rc; |
205 | 206 | ||
206 | printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr, |
207 | printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr, |
207 | entry->p_memsz); |
208 | entry->p_memsz); |
208 | 209 | ||
209 | /*if (elf->e_type == ET_DYN) load_displ = 0x40000; |
210 | bias = (elf->e_type == ET_DYN) ? RTLD_BIAS : 0; |
210 | else*/ load_displ = 0; |
- | |
211 | 211 | ||
212 | if (entry->p_align > 1) { |
212 | if (entry->p_align > 1) { |
213 | if ((entry->p_offset % entry->p_align) != |
213 | if ((entry->p_offset % entry->p_align) != |
214 | (entry->p_vaddr % entry->p_align)) { |
214 | (entry->p_vaddr % entry->p_align)) { |
215 | printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n", |
215 | printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n", |
Line 239... | Line 239... | ||
239 | printf("vaddr = 0x%x, should be 0x%x\n", |
239 | printf("vaddr = 0x%x, should be 0x%x\n", |
240 | entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE)); |
240 | entry->p_vaddr, ALIGN_UP(entry->p_vaddr, PAGE_SIZE)); |
241 | return EE_UNSUPPORTED; |
241 | return EE_UNSUPPORTED; |
242 | } |
242 | } |
243 | 243 | ||
244 | printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + load_displ, |
244 | printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias, |
245 | entry->p_vaddr + load_displ + ALIGN_UP(entry->p_memsz, PAGE_SIZE)); |
245 | entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE)); |
246 | 246 | ||
247 | a = as_area_create((uint8_t *)entry->p_vaddr + load_displ, |
247 | a = as_area_create((uint8_t *)entry->p_vaddr + bias, |
248 | entry->p_memsz, flags); |
248 | entry->p_memsz, flags); |
249 | if (a == (void *)(-1)) { |
249 | if (a == (void *)(-1)) { |
250 | printf("memory mapping failed\n"); |
250 | printf("memory mapping failed\n"); |
251 | return EE_MEMORY; |
251 | return EE_MEMORY; |
252 | } |
252 | } |
Line 257... | Line 257... | ||
257 | * Load segment data |
257 | * Load segment data |
258 | */ |
258 | */ |
259 | rc = lseek(fd, entry->p_offset, SEEK_SET); |
259 | rc = lseek(fd, entry->p_offset, SEEK_SET); |
260 | if (rc < 0) { printf("seek error\n"); return EE_INVALID; } |
260 | if (rc < 0) { printf("seek error\n"); return EE_INVALID; } |
261 | 261 | ||
262 | rc = read(fd, (void *)entry->p_vaddr, entry->p_filesz); |
262 | rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz); |
263 | if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
263 | if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
264 | 264 | ||
265 | return EE_OK; |
265 | return EE_OK; |
266 | } |
266 | } |
267 | 267 |