On Thu, Jul 3, 2014 at 5:04 PM, Christian Svensson <[email protected]> wrote:

> Compiling results in the following:
> or1k-elf-gcc vprintf.c
> /srv/compilers/openrisc-devel/lib/gcc/or1k-elf/4.9.0/../../../../or1k-elf/lib/libc.a(lib_a-or1k-impure.o):
> In function `__getreent':
> /home/bluecmd/or1k-devel/newlib/../newlib/or1k-src/newlib/libc/machine/or1k/or1k-impure.c:80:
> multiple definition of `__getreent'
> /srv/compilers/openrisc-devel/lib/gcc/or1k-elf/4.9.0/../../../../or1k-elf/lib/libc.a(lib_a-getreent.o):/home/bluecmd/or1k-devel/newlib/../newlib/or1k-src/newlib/libc/reent/getreent.c:13:
> first defined here
> collect2: error: ld returned 1 exit status
>
> Masking newlib/libc/reent/getreent.c with #if 0 (so the only definition is
> or1k-impure.c) makes it work just fine.
> diff --git a/newlib/libc/reent/getreent.c b/newlib/libc/reent/getreent.c
> index 60ae6fb..d85d654 100644
> --- a/newlib/libc/reent/getreent.c
> +++ b/newlib/libc/reent/getreent.c
> @@ -1,5 +1,6 @@
>  /* default reentrant pointer when multithread enabled */
>
> +#if 0
>  #include <_ansi.h>
>  #include <reent.h>
>
> @@ -12,3 +13,4 @@ _DEFUN_VOID(__getreent)
>  {
>    return _impure_ptr;
>  }
> +#endif
>
> Obviously that is not a correct solution though :-).
>
> Ideas?
>

It seems to me the simplest solution would be to remove the definition of
getreent from or1k-impure.c, and swap the roles of __current_impure_ptr and
__impure_ptr.  Something like this:

====== BEGIN DIFF ========
diff --git a/newlib/libc/machine/or1k/or1k-impure.c
b/newlib/libc/machine/or1k/or1k-impure.c
index 4b47cf9..6dbfcb1 100644
--- a/newlib/libc/machine/or1k/or1k-impure.c
 __impure_init (void)
 {
     // Initialize both impure data structures
-    _REENT_INIT_PTR (_impure_ptr);
+    _REENT_INIT_PTR (_current_impure_ptr);
     _REENT_INIT_PTR (_exception_impure_ptr);

-    // Set current to standard impure pointer
-    _current_impure_ptr = _impure_ptr;
+    // Set standard impure pointer to current
+    _impure_ptr = _current_impure_ptr;
 } /* __impure_init () */
-
-struct _reent * __getreent(void) {
-    // Return the current one. This is set initially above, and during
runtime
-    // at or1k_exception_handler
-    return _current_impure_ptr;
-}
diff --git a/newlib/libc/machine/or1k/or1k-support-asm.S
b/newlib/libc/machine/or1k/or1k-support-asm.S
index 78e29cc..532a5a5 100644
--- a/newlib/libc/machine/or1k/or1k-support-asm.S
+++ b/newlib/libc/machine/or1k/or1k-support-asm.S
@@ -627,12 +627,20 @@ or1k_exception_handler:
  l.sw    0x70(r1), r30
  l.sw    0x74(r1), r31

+ /* Save impure pointer for exception */
+ l.movhi r20, hi(_impure_ptr)
+ l.ori   r20, r20, lo(_impure_ptr)
+ l.lwz   r20, 0(r20)
+ l.movhi r21, hi(_current_impure_ptr)
+ l.ori   r21, r21, lo(_current_impure_ptr)
+ l.sw    0(r21), r20
+
  /* Replace impure pointer for exception */
  l.movhi r20, hi(_exception_impure_ptr)
  l.ori   r20, r20, lo(_exception_impure_ptr)
  l.lwz   r20, 0(r20)
- l.movhi r21, hi(_current_impure_ptr)
- l.ori   r21, r21, lo(_current_impure_ptr)
+ l.movhi r21, hi(_impure_ptr)
+ l.ori   r21, r21, lo(_impure_ptr)
  l.sw    0(r21), r20

  /* Determine offset in table of exception handler using r3*/
@@ -663,11 +671,11 @@ or1k_exception_handler:
         )

     /* Restore impure pointer */
- l.movhi r20, hi(_impure_ptr)
- l.ori   r20, r20, lo(_impure_ptr)
+ l.movhi r20, hi(_current_impure_ptr)
+ l.ori   r20, r20, lo(_current_impure_ptr)
  l.lwz   r20, 0(r20)
- l.movhi r21, hi(_current_impure_ptr)
- l.ori   r21, r21, lo(_current_impure_ptr)
+ l.movhi r21, hi(_impure_ptr)
+ l.ori   r21, r21, lo(_impure_ptr)
  l.sw    0(r21), r20

  /* Restore state */
====== END DIFF ========

I also added a bit of code to save __impure_ptr to __current_impure_ptr at
the start, because it wasn't being saved, which didn't make sense to me.

I haven't tested this change, YMMV :)

-Pete
_______________________________________________
OpenRISC mailing list
[email protected]
http://lists.openrisc.net/listinfo/openrisc

Reply via email to