summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/bfin/dl-inlines.h55
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;
}