1 /* Copyright (C) 2003, 2004 Red Hat, Inc.
2 * Contributed by Alexandre Oliva <aoliva@redhat.com>
3 * Copyright (C) 2006-2011 Analog Devices, Inc.
5 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
10 #define __dl_loadaddr_unmap __dl_loadaddr_unmap
12 #include "../fdpic/dl-inlines.h"
15 __dl_loadaddr_unmap (struct elf32_fdpic_loadaddr loadaddr,
16 struct funcdesc_ht *funcdesc_ht)
20 for (i = 0; i < loadaddr.map->nsegs; i++)
22 struct elf32_fdpic_loadseg *segdata;
24 segdata = loadaddr.map->segs + i;
27 A more cleaner way is to add type for struct elf32_fdpic_loadseg,
28 and release the memory according to the type.
29 Currently, we hardcode the memory address of L1 SRAM. */
30 if ((segdata->addr & 0xff800000) == 0xff800000)
32 _dl_sram_free ((void *)segdata->addr);
36 offs = (segdata->p_vaddr & ADDR_ALIGN);
37 _dl_munmap ((void*)segdata->addr - offs,
38 segdata->p_memsz + offs);
40 /* _dl_unmap is only called for dlopen()ed libraries, for which
41 calling free() is safe, or before we've completed the initial
42 relocation, in which case calling free() is probably pointless,
44 _dl_free (loadaddr.map);
46 htab_delete (funcdesc_ht);
49 static __always_inline int
50 __dl_is_special_segment (Elf32_Ehdr *epnt,
53 if (ppnt->p_type != PT_LOAD)
56 if ((epnt->e_flags & EF_BFIN_CODE_IN_L1)
57 && !(ppnt->p_flags & PF_W)
58 && (ppnt->p_flags & PF_X))
61 if ((epnt->e_flags & EF_BFIN_DATA_IN_L1)
62 && (ppnt->p_flags & PF_W)
63 && !(ppnt->p_flags & PF_X))
66 /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000,
67 and 0xffa00000 are also used in GNU ld and linux kernel.
68 They need to be kept synchronized. */
69 if (ppnt->p_vaddr == 0xff700000
70 || ppnt->p_vaddr == 0xff800000
71 || ppnt->p_vaddr == 0xff900000
72 || ppnt->p_vaddr == 0xffa00000
73 || ppnt->p_vaddr == 0xfeb00000
74 || ppnt->p_vaddr == 0xfec00000)
80 static __always_inline char *
81 __dl_map_segment (Elf32_Ehdr *epnt,
86 char *status, *tryaddr, *addr;
89 if (((epnt->e_flags & EF_BFIN_CODE_IN_L1) || ppnt->p_vaddr == 0xffa00000)
90 && !(ppnt->p_flags & PF_W)
91 && (ppnt->p_flags & PF_X)) {
92 status = (char *) _dl_mmap
94 size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz,
95 LXFLAGS(ppnt->p_flags),
96 flags | MAP_EXECUTABLE | MAP_DENYWRITE,
97 infile, ppnt->p_offset & OFFS_ALIGN);
98 if (_dl_mmap_check_error(status)
99 || (tryaddr && tryaddr != status))
101 addr = (char *) _dl_sram_alloc (ppnt->p_filesz, L1_INST_SRAM);
103 _dl_dma_memcpy (addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz);
104 _dl_munmap (status, size);
106 _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__);
110 if (((epnt->e_flags & EF_BFIN_DATA_IN_L1)
111 || ppnt->p_vaddr == 0xff700000
112 || ppnt->p_vaddr == 0xff800000
113 || ppnt->p_vaddr == 0xff900000)
114 && (ppnt->p_flags & PF_W)
115 && !(ppnt->p_flags & PF_X)) {
116 if (ppnt->p_vaddr == 0xff800000)
117 addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_A_SRAM);
118 else if (ppnt->p_vaddr == 0xff900000)
119 addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_B_SRAM);
121 addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM);
123 _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__);
125 if (_DL_PREAD (infile, addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) {
126 _dl_sram_free (addr);
129 if (ppnt->p_filesz < ppnt->p_memsz)
130 _dl_memset (addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
135 if (ppnt->p_vaddr == 0xfeb00000
136 || ppnt->p_vaddr == 0xfec00000) {
137 addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L2_SRAM);
139 _dl_dprintf(2, "%s:%i: L2 allocation failed\n", _dl_progname, __LINE__);
141 if (_DL_PREAD (infile, addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) {
142 _dl_sram_free (addr);
145 if (ppnt->p_filesz < ppnt->p_memsz)
146 _dl_memset (addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);