We have a problem with DT_TEXTREL shared libraries on nommu machines.
The dynamic linker's strategy is to map the text segment read-only
first, then look for DT_TEXTREL, and use mprotect to change protections
if necessary. This fails on nommu, since a nommu kernel can decide to
share the memory for private read-only file mappings, and mprotect
doesn't (can't) do anything about this sharing. Existing nommu targets
apparently have no need for this, but on C6X, we may need to assign
library indices at run-time if no --dsbt-index option was passed to the
linker at build time.
Hence, the following patch, which instead of using mprotect, redoes the
mapping with PF_W set.
As a test, I've changed librt.so not to have a DSBT index (so that we
get DSBT_INDEX relocs and DT_TEXTREL), and run two copies of a program
that uses this library in parallel:
(A)
/home/bernds # LD_DEBUG=1 ./clocktst
_dl_get_ready_to_run:779: file='librt.so.0'; needed by './clocktst'
_dl_load_shared_library:212: find library='librt.so.0'; searching
_dl_load_shared_library:289: searching ldso dir='/lib'
0: mapped 0x0 at 0xe7770000, size 0x116c
1: mapped 0x216c at 0xe788f16c, size 0x204
1: changed mapping 0x0 at 0xe77b4000 (old 0xe7770000), size 0x116c
_dl_get_ready_to_run:779: file='libc.so.0'; needed by './clocktst'
_dl_load_shared_library:212: find library='libc.so.0'; searching
_dl_load_shared_library:289: searching ldso dir='/lib'
0: mapped 0x0 at 0xe7800000, size 0x71d88
1: mapped 0x72d88 at 0xe77f8d88, size 0x3d98
(B)
/home/bernds # LD_DEBUG=1 ./clocktst
_dl_get_ready_to_run:779: file='librt.so.0'; needed by './clocktst'
_dl_load_shared_library:212: find library='librt.so.0'; searching
_dl_load_shared_library:289: searching ldso dir='/lib'
0: mapped 0x0 at 0xe7770000, size 0x116c
1: mapped 0x216c at 0xe76f916c, size 0x204
1: changed mapping 0x0 at 0xe788c000 (old 0xe7770000), size 0x116c
_dl_get_ready_to_run:779: file='libc.so.0'; needed by './clocktst'
_dl_load_shared_library:212: find library='libc.so.0'; searching
_dl_load_shared_library:289: searching ldso dir='/lib'
0: mapped 0x0 at 0xe7800000, size 0x71d88
1: mapped 0x72d88 at 0xe7758d88, size 0x3d98
That seems to demonstrate both the problem (identical initial mappings
for segment 0 of librt.so) and the fix.
Ok to install?
Bernd
Index: ldso/ldso/dl-elf.c
===================================================================
--- ldso/ldso/dl-elf.c (revision 319237)
+++ ldso/ldso/dl-elf.c (working copy)
@@ -314,6 +314,124 @@ goof:
return NULL;
}
+/*
+ * Make a writeable mapping of a segment, regardless of whether PF_W is
+ * set or not.
+ */
+static void *
+map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib, int flags,
+ unsigned long libaddr)
+{
+ int prot_flags = ppnt->p_flags | PF_W;
+ char *status, *retval;
+ char *tryaddr;
+ ssize_t size;
+ unsigned long map_size;
+ char *cpnt;
+ char *piclib2map = 0;
+
+ if (piclib == 2 &&
+ /* We might be able to avoid this call if memsz doesn't
+ require an additional page, but this would require mmap
+ to always return page-aligned addresses and a whole
+ number of pages allocated. Unfortunately on uClinux
+ may return misaligned addresses and may allocate
+ partial pages, so we may end up doing unnecessary mmap
+ calls.
+
+ This is what we could do if we knew mmap would always
+ return aligned pages:
+
+ ((ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) &
+ PAGE_ALIGN) < ppnt->p_vaddr + ppnt->p_memsz)
+
+ Instead, we have to do this: */
+ ppnt->p_filesz < ppnt->p_memsz)
+ {
+ piclib2map = (char *)
+ _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN) +
ppnt->p_memsz,
+ LXFLAGS(prot_flags), flags | MAP_ANONYMOUS,
-1, 0);
+ if (_dl_mmap_check_error(piclib2map))
+ return 0;
+ }
+
+ tryaddr = piclib == 2 ? piclib2map
+ : ((char*) (piclib ? libaddr : 0) +
+ (ppnt->p_vaddr & PAGE_ALIGN));
+
+ size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz;
+
+ /* For !MMU, mmap to fixed address will fail.
+ So instead of desperately call mmap and fail,
+ we set status to MAP_FAILED to save a call
+ to mmap (). */
+#ifndef __ARCH_USE_MMU__
+ if (piclib2map == 0)
+#endif
+ status = (char *) _dl_mmap
+ (tryaddr, size, LXFLAGS(prot_flags),
+ flags | (piclib2map ? MAP_FIXED : 0),
+ infile, ppnt->p_offset & OFFS_ALIGN);
+#ifndef __ARCH_USE_MMU__
+ else
+ status = MAP_FAILED;
+#endif
+#ifdef _DL_PREAD
+ if (_dl_mmap_check_error(status) && piclib2map
+ && (_DL_PREAD (infile, tryaddr, size,
+ ppnt->p_offset & OFFS_ALIGN) == size))
+ status = tryaddr;
+#endif
+ if (_dl_mmap_check_error(status) || (tryaddr && tryaddr != status))
+ return 0;
+
+ if (piclib2map)
+ retval = piclib2map;
+ else
+ retval = status;
+
+ /* Now we want to allocate and zero-out any data from the end
+ of the region we mapped in from the file (filesz) to the
+ end of the loadable segment (memsz). We may need
+ additional pages for memsz, that we map in below, and we
+ can count on the kernel to zero them out, but we have to
+ zero out stuff in the last page that we mapped in from the
+ file. However, we can't assume to have actually obtained
+ full pages from the kernel, since we didn't ask for them,
+ and uClibc may not give us full pages for small
+ allocations. So only zero out up to memsz or the end of
+ the page, whichever comes first. */
+
+ /* CPNT is the beginning of the memsz portion not backed by
+ filesz. */
+ cpnt = (char *) (status + size);
+
+ /* MAP_SIZE is the address of the
+ beginning of the next page. */
+ map_size = (ppnt->p_vaddr + ppnt->p_filesz
+ + ADDR_ALIGN) & PAGE_ALIGN;
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+ _dl_memset (cpnt, 0,
+ MIN (map_size
+ - (ppnt->p_vaddr
+ + ppnt->p_filesz),
+ ppnt->p_memsz
+ - ppnt->p_filesz));
+
+ if (map_size < ppnt->p_vaddr + ppnt->p_memsz && !piclib2map) {
+ tryaddr = map_size + (char*)(piclib ? libaddr : 0);
+ status = (char *) _dl_mmap(tryaddr,
+ ppnt->p_vaddr + ppnt->p_memsz -
map_size,
+ LXFLAGS(prot_flags),
+ flags | MAP_ANONYMOUS | MAP_FIXED,
-1, 0);
+ if (_dl_mmap_check_error(status) || tryaddr != status)
+ return NULL;
+ }
+ return retval;
+}
/*
* Read one ELF library into memory, mmap it into the correct locations and
@@ -475,6 +593,7 @@ struct elf_resolve *_dl_load_elf_shared_
status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
maxvma - minvma, PROT_NONE, flags |
MAP_ANONYMOUS, -1, 0);
if (_dl_mmap_check_error(status)) {
+ cant_map:
_dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname,
__LINE__, libname);
_dl_internal_error_number = LD_ERROR_MMAP_FAILED;
_dl_close(infile);
@@ -495,8 +614,11 @@ struct elf_resolve *_dl_load_elf_shared_
char *addr;
addr = DL_MAP_SEGMENT (epnt, ppnt, infile, flags);
- if (addr == NULL)
+ if (addr == NULL) {
+ cant_map1:
+ DL_LOADADDR_UNMAP (lib_loadaddr, maxvma -
minvma);
goto cant_map;
+ }
DL_INIT_LOADADDR_HDR (lib_loadaddr, addr, ppnt);
ppnt++;
@@ -517,141 +639,9 @@ struct elf_resolve *_dl_load_elf_shared_
}
if (ppnt->p_flags & PF_W) {
- unsigned long map_size;
- char *cpnt;
- char *piclib2map = 0;
-
- if (piclib == 2 &&
- /* We might be able to avoid this
- call if memsz doesn't require
- an additional page, but this
- would require mmap to always
- return page-aligned addresses
- and a whole number of pages
- allocated. Unfortunately on
- uClinux may return misaligned
- addresses and may allocate
- partial pages, so we may end up
- doing unnecessary mmap calls.
-
- This is what we could do if we
- knew mmap would always return
- aligned pages:
-
- ((ppnt->p_vaddr + ppnt->p_filesz
- + ADDR_ALIGN)
- & PAGE_ALIGN)
- < ppnt->p_vaddr + ppnt->p_memsz)
-
- Instead, we have to do this: */
- ppnt->p_filesz < ppnt->p_memsz)
- {
- piclib2map = (char *)
- _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN)
- + ppnt->p_memsz,
- LXFLAGS(ppnt->p_flags),
- flags | MAP_ANONYMOUS, -1, 0);
- if (_dl_mmap_check_error(piclib2map))
- goto cant_map;
- DL_INIT_LOADADDR_HDR
- (lib_loadaddr, piclib2map
- + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
- }
-
- tryaddr = piclib == 2 ? piclib2map
- : ((char*) (piclib ? libaddr : 0) +
- (ppnt->p_vaddr & PAGE_ALIGN));
-
- size = (ppnt->p_vaddr & ADDR_ALIGN)
- + ppnt->p_filesz;
-
- /* For !MMU, mmap to fixed address will fail.
- So instead of desperately call mmap and fail,
- we set status to MAP_FAILED to save a call
- to mmap (). */
-#ifndef __ARCH_USE_MMU__
- if (piclib2map == 0)
-#endif
- status = (char *) _dl_mmap
- (tryaddr, size, LXFLAGS(ppnt->p_flags),
- flags | (piclib2map ? MAP_FIXED : 0),
- infile, ppnt->p_offset & OFFS_ALIGN);
-#ifndef __ARCH_USE_MMU__
- else
- status = MAP_FAILED;
-#endif
-#ifdef _DL_PREAD
- if (_dl_mmap_check_error(status) && piclib2map
- && (_DL_PREAD (infile, tryaddr, size,
- ppnt->p_offset & OFFS_ALIGN)
- == size))
- status = tryaddr;
-#endif
- if (_dl_mmap_check_error(status)
- || (tryaddr && tryaddr != status)) {
- cant_map:
- _dl_dprintf(2, "%s:%i: can't map
'%s'\n",
- _dl_progname, __LINE__,
libname);
- _dl_internal_error_number =
LD_ERROR_MMAP_FAILED;
- DL_LOADADDR_UNMAP (lib_loadaddr, maxvma
- minvma);
- _dl_close(infile);
- _dl_munmap(header, _dl_pagesize);
- return NULL;
- }
-
- if (! piclib2map) {
- DL_INIT_LOADADDR_HDR
- (lib_loadaddr, status
- + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
- }
- /* Now we want to allocate and
- zero-out any data from the end of
- the region we mapped in from the
- file (filesz) to the end of the
- loadable segment (memsz). We may
- need additional pages for memsz,
- that we map in below, and we can
- count on the kernel to zero them
- out, but we have to zero out stuff
- in the last page that we mapped in
- from the file. However, we can't
- assume to have actually obtained
- full pages from the kernel, since
- we didn't ask for them, and uClibc
- may not give us full pages for
- small allocations. So only zero
- out up to memsz or the end of the
- page, whichever comes first. */
-
- /* CPNT is the beginning of the memsz
- portion not backed by filesz. */
- cpnt = (char *) (status + size);
-
- /* MAP_SIZE is the address of the
- beginning of the next page. */
- map_size = (ppnt->p_vaddr + ppnt->p_filesz
- + ADDR_ALIGN) & PAGE_ALIGN;
-
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
- _dl_memset (cpnt, 0,
- MIN (map_size
- - (ppnt->p_vaddr
- + ppnt->p_filesz),
- ppnt->p_memsz
- - ppnt->p_filesz));
-
- if (map_size < ppnt->p_vaddr + ppnt->p_memsz
- && !piclib2map) {
- tryaddr = map_size + (char*)(piclib ?
libaddr : 0);
- status = (char *) _dl_mmap(tryaddr,
- ppnt->p_vaddr + ppnt->p_memsz -
map_size,
- LXFLAGS(ppnt->p_flags), flags |
MAP_ANONYMOUS | MAP_FIXED, -1, 0);
- if (_dl_mmap_check_error(status)
- || tryaddr != status)
- goto cant_map;
- }
+ status = map_writeable (infile, ppnt, piclib,
flags, libaddr);
+ if (status == NULL)
+ goto cant_map1;
} else {
tryaddr = (piclib == 2 ? 0
: (char *) (ppnt->p_vaddr &
PAGE_ALIGN)
@@ -664,11 +654,11 @@ struct elf_resolve *_dl_load_elf_shared_
infile, ppnt->p_offset &
OFFS_ALIGN);
if (_dl_mmap_check_error(status)
|| (tryaddr && tryaddr != status))
- goto cant_map;
- DL_INIT_LOADADDR_HDR
- (lib_loadaddr, status
- + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
+ goto cant_map1;
}
+ DL_INIT_LOADADDR_HDR(lib_loadaddr,
+ status + (ppnt->p_vaddr &
ADDR_ALIGN),
+ ppnt);
/* if (libaddr == 0 && piclib) {
libaddr = (unsigned long) status;
@@ -677,7 +667,6 @@ struct elf_resolve *_dl_load_elf_shared_
}
ppnt++;
}
- _dl_close(infile);
/* For a non-PIC library, the addresses are all absolute */
if (piclib) {
@@ -696,6 +685,7 @@ struct elf_resolve *_dl_load_elf_shared_
_dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",
_dl_progname, libname);
_dl_munmap(header, _dl_pagesize);
+ _dl_close(infile);
return NULL;
}
@@ -711,10 +701,23 @@ struct elf_resolve *_dl_load_elf_shared_
ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
{
+#ifdef __ARCH_USE_MMU__
_dl_mprotect((void *) ((piclib ? libaddr : 0) +
(ppnt->p_vaddr &
PAGE_ALIGN)),
(ppnt->p_vaddr & ADDR_ALIGN) +
(unsigned long) ppnt->p_filesz,
PROT_READ | PROT_WRITE |
PROT_EXEC);
+#else
+ void *new_addr;
+ new_addr = map_writeable (infile, ppnt, piclib,
flags, libaddr);
+ if (!new_addr) {
+ _dl_dprintf(_dl_debug_file, "Can't
modify %s's text section.",
+ libname);
+ _dl_exit(1);
+ }
+ DL_UPDATE_LOADADDR_HDR(lib_loadaddr,
+ new_addr +
(ppnt->p_vaddr & ADDR_ALIGN),
+ ppnt);
+#endif
}
}
#else
@@ -725,6 +728,8 @@ struct elf_resolve *_dl_load_elf_shared_
#endif
}
+ _dl_close(infile);
+
tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info,
dynamic_addr, 0);
tpnt->relro_addr = relro_addr;
Index: ldso/ldso/frv/dl-inlines.h
===================================================================
--- ldso/ldso/frv/dl-inlines.h (revision 319234)
+++ ldso/ldso/frv/dl-inlines.h (working copy)
@@ -83,6 +83,39 @@ __dl_init_loadaddr_hdr (struct elf32_fdp
#endif
}
+/* Replace an existing entry in the load map. */
+static __always_inline void
+__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
+ Elf32_Phdr *phdr)
+{
+ struct elf32_fdpic_loadseg *segdata;
+ void *oldaddr;
+ int i;
+
+ for (i = 0; i < loadaddr.map->nsegs; i++)
+ if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
+ && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
+ break;
+ if (i == loadaddr.map->nsegs)
+ _dl_exit (-1);
+
+ segdata = loadaddr.map->segs + i;
+ oldaddr = (void *)segdata->addr;
+ _dl_munmap (oldaddr, segdata->p_memsz);
+ segdata->addr = (Elf32_Addr) addr;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+ {
+ extern char *_dl_debug;
+ extern int _dl_debug_file;
+ if (_dl_debug)
+ _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size
%x\n",
+ loadaddr.map->nsegs-1,
+ segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
+ }
+#endif
+}
+
static __always_inline void __dl_loadaddr_unmap
(struct elf32_fdpic_loadaddr loadaddr, struct funcdesc_ht *funcdesc_ht);
Index: ldso/ldso/frv/dl-sysdep.h
===================================================================
--- ldso/ldso/frv/dl-sysdep.h (revision 319234)
+++ ldso/ldso/frv/dl-sysdep.h (working copy)
@@ -95,6 +95,8 @@ struct funcdesc_ht;
#define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
(__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
dl_init_loadaddr_load_count))
+#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
+ (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
#define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
(__dl_loadaddr_unmap ((LOADADDR), (NULL)))
#define DL_LIB_UNMAP(LIB, LEN) \
Index: ldso/ldso/c6x/dl-inlines.h
===================================================================
--- ldso/ldso/c6x/dl-inlines.h (revision 319234)
+++ ldso/ldso/c6x/dl-inlines.h (working copy)
@@ -74,6 +74,35 @@ __dl_init_loadaddr_hdr (struct elf32_dsb
#endif
}
+/* Replace an existing entry in the load map. */
+static __always_inline void
+__dl_update_loadaddr_hdr (struct elf32_dsbt_loadaddr loadaddr, void *addr,
+ Elf32_Phdr *phdr)
+{
+ struct elf32_dsbt_loadseg *segdata;
+ void *oldaddr;
+ int i;
+
+ for (i = 0; i < loadaddr.map->nsegs; i++)
+ if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
+ && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
+ break;
+ if (i == loadaddr.map->nsegs)
+ _dl_exit (-1);
+
+ segdata = loadaddr.map->segs + i;
+ oldaddr = (void *)segdata->addr;
+ _dl_munmap (oldaddr, segdata->p_memsz);
+ segdata->addr = (Elf32_Addr) addr;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+ if (_dl_debug)
+ _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old
%x), size %x\n",
+ loadaddr.map->nsegs-1,
+ segdata->p_vaddr, segdata->addr, oldaddr,
segdata->p_memsz);
+#endif
+}
+
static __always_inline void
__dl_loadaddr_unmap (struct elf32_dsbt_loadaddr loadaddr)
{
Index: ldso/ldso/c6x/dl-sysdep.h
===================================================================
--- ldso/ldso/c6x/dl-sysdep.h (revision 319234)
+++ ldso/ldso/c6x/dl-sysdep.h (working copy)
@@ -104,6 +104,9 @@ struct elf32_dsbt_loadaddr;
(__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
dl_init_loadaddr_load_count))
+#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
+ (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
+
#define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
(__dl_loadaddr_unmap ((LOADADDR)))
Index: ldso/ldso/bfin/dl-inlines.h
===================================================================
--- ldso/ldso/bfin/dl-inlines.h (revision 319234)
+++ ldso/ldso/bfin/dl-inlines.h (working copy)
@@ -99,6 +99,39 @@ __dl_init_loadaddr_hdr (struct elf32_fdp
#endif
}
+/* Replace an existing entry in the load map. */
+static __always_inline void
+__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
+ Elf32_Phdr *phdr)
+{
+ struct elf32_fdpic_loadseg *segdata;
+ void *oldaddr;
+ int i;
+
+ for (i = 0; i < loadaddr.map->nsegs; i++)
+ if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
+ && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
+ break;
+ if (i == loadaddr.map->nsegs)
+ _dl_exit (-1);
+
+ segdata = loadaddr.map->segs + i;
+ oldaddr = (void *)segdata->addr;
+ _dl_munmap (oldaddr, segdata->p_memsz);
+ segdata->addr = (Elf32_Addr) addr;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+ {
+ extern char *_dl_debug;
+ extern int _dl_debug_file;
+ if (_dl_debug)
+ _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size
%x\n",
+ loadaddr.map->nsegs-1,
+ segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
+ }
+#endif
+}
+
static __always_inline void __dl_loadaddr_unmap
(struct elf32_fdpic_loadaddr loadaddr, struct funcdesc_ht *funcdesc_ht);
Index: ldso/ldso/bfin/dl-sysdep.h
===================================================================
--- ldso/ldso/bfin/dl-sysdep.h (revision 319234)
+++ ldso/ldso/bfin/dl-sysdep.h (working copy)
@@ -120,6 +120,8 @@ struct funcdesc_ht;
#define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
(__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
dl_init_loadaddr_load_count))
+#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
+ (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
#define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
(__dl_loadaddr_unmap ((LOADADDR), (NULL)))
#define DL_LIB_UNMAP(LIB, LEN) \
Index: ldso/include/dl-elf.h
===================================================================
--- ldso/include/dl-elf.h (revision 319234)
+++ ldso/include/dl-elf.h (working copy)
@@ -184,7 +184,7 @@ unsigned int __dl_parse_dynamic_info(Elf
ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
/* Initialize loadmap dsbt info. */
- load_off.map->dsbt_table = dynamic_info[DT_DSBT_BASE_IDX];
+ load_off.map->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX];
load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
#endif
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc