diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/bfin/dl-inlines.h | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/ldso/ldso/bfin/dl-inlines.h b/ldso/ldso/bfin/dl-inlines.h index 0a97065de..18f366873 100644 --- a/ldso/ldso/bfin/dl-inlines.h +++ b/ldso/ldso/bfin/dl-inlines.h @@ -18,7 +18,7 @@ License along with uClibc; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <bits/bfin_sram.h> +#include <bfin_sram.h> #ifndef _dl_assert # define _dl_assert(expr) @@ -463,6 +463,17 @@ __dl_loadaddr_unmap (struct elf32_fdpic_loadaddr loadaddr, struct elf32_fdpic_loadseg *segdata; ssize_t offs; segdata = loadaddr.map->segs + i; + + /* FIXME: + A more cleaner way is to add type for struct elf32_fdpic_loadseg, + and release the memory according to the type. + Currently, we hardcode the memory address of L1 SRAM. */ + if ((segdata->addr & 0xff800000) == 0xff800000) + { + _dl_sram_free ((void *)segdata->addr); + continue; + } + offs = (segdata->p_vaddr & ADDR_ALIGN); _dl_munmap ((void*)segdata->addr - offs, segdata->p_memsz + offs); @@ -493,7 +504,15 @@ __dl_is_special_segment (Elf32_Ehdr *epnt, && !(ppnt->p_flags & PF_X)) return 1; - return 0; + /* 0xff700000, 0xff800000, 0xff900000 and 0xffa00000 are also used in + GNU ld and linux kernel. They need to be keep synchronized. */ + if (ppnt->p_vaddr == 0xff700000 + || ppnt->p_vaddr == 0xff800000 + || ppnt->p_vaddr == 0xff900000 + || ppnt->p_vaddr == 0xffa00000) + return 1; + + return 0; } inline static char * @@ -505,7 +524,7 @@ __dl_map_segment (Elf32_Ehdr *epnt, char *status, *tryaddr, *l1addr; size_t size; - if ((epnt->e_flags & EF_BFIN_CODE_IN_L1) + if (((epnt->e_flags & EF_BFIN_CODE_IN_L1) || ppnt->p_vaddr == 0xffa00000) && !(ppnt->p_flags & PF_W) && (ppnt->p_flags & PF_X)) { status = (char *) _dl_mmap @@ -522,20 +541,32 @@ __dl_map_segment (Elf32_Ehdr *epnt, _dl_dma_memcpy (l1addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz); _dl_munmap (status, size); if (l1addr == NULL) - return NULL; + _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__); return l1addr; } - if ((epnt->e_flags & EF_BFIN_DATA_IN_L1) + if (((epnt->e_flags & EF_BFIN_DATA_IN_L1) + || ppnt->p_vaddr == 0xff700000 + || ppnt->p_vaddr == 0xff800000 + || ppnt->p_vaddr == 0xff900000) && (ppnt->p_flags & PF_W) && !(ppnt->p_flags & PF_X)) { - l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM); - if (l1addr == NULL - || (_DL_PREAD (infile, l1addr, ppnt->p_filesz, ppnt->p_offset) - != ppnt->p_filesz)) - return NULL; - if (ppnt->p_filesz < ppnt->p_memsz) - _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz); + if (ppnt->p_vaddr == 0xff800000) + l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_A_SRAM); + else if (ppnt->p_vaddr == 0xff900000) + l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_B_SRAM); + else + l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM); + if (l1addr == NULL) { + _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__); + } else { + if (_DL_PREAD (infile, l1addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) { + _dl_sram_free (l1addr); + return NULL; + } + if (ppnt->p_filesz < ppnt->p_memsz) + _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz); + } return l1addr; } |