[PATCH v2] libgloss: Resolve compilation errors for mips.

"Roger Sayle" <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
Here's an updated version of my patch from last year to restore libgloss builds
on MIPS targets, incorporating the feedback from Mike Frysinger's review.
Tested by building a combined gcc/binutils/newlib tree with --target=mips64-elf.
Ok?

2025-02-10  Roger Sayle  <[email protected]>
            Mike Frysinger  <[email protected]>

libgloss/ChangeLog
        * glue.h (print): Provide prototype.
        * kill.c: Prototype _exit with noreturn attribute.
        * mips/cfe_mem.c (memtop): Change to a pointer type.
        (__libcfe_meminit): Add casts to avoid compilation
        warnings/errors.
        * mips/cma101.c: Prototype __cpu_timer_poll and __cpu_flush.
        (convertbcd): Update K&R-style function declaration.
        (time): Likewise.
        * mips/nullmon.c (get_mem_info): Likewise.
        * mips/syscalls.c: Declare struct s_mem and prototype get_mem_info.
        (sbrk): Update K&R-style function declaration.  Add casts to avoid
        compilation warnings/errors.
        * mips/test.c: Prototype outbyte and print. Fix return type of main.
        * print.c (print): Make ptr argument const char*.
        * putnum.c: Remove print prototype, which is now in glue.h.
        * write.c: Remove outbyte prototype, which is now in glue.h.


Thanks in advance,
Roger
--

> -----Original Message-----
> From: Mike Frysinger <[email protected]>
> Sent: 04 January 2024 23:55
> To: Roger Sayle <[email protected]>
> Cc: [email protected]; 'Jeff Law' <[email protected]>
> Subject: Re: [PATCH] libgloss: Resolve compilation errors for mips.
> 
> On 04 Jan 2024 13:59, Roger Sayle wrote:
> > --- a/libgloss/kill.c
> > +++ b/libgloss/kill.c
> >
> > +extern void _exit (int);
> 
> missing noreturn markings.  can this file include stdlib.h instead ?
> 
> > --- a/libgloss/mips/cfe_mem.c
> > +++ b/libgloss/mips/cfe_mem.c
> >
> > -    memtop = __libcfe_mem_limit ();
> > +    memtop = (unsigned long)__libcfe_mem_limit ();
> 
> if memtop is supposed to be a pointer, then it should be a pointer, not an integer.
> 
> ignoring that, never use long or int to cast pointers.  this is what uintptr_t is
> designed for.
> 
> > --- a/libgloss/mips/syscalls.c
> > +++ b/libgloss/mips/syscalls.c
> >
> >  extern char _end[];
> > +extern void *get_mem_info (void*);
> 
> seems like mips should have a header for its prototypes rather than duplicating it
> across multiple files, and so it makes sure it's defined correctly both in the callers
> & definitions.  seems like get_mem_info takes a struct pointer, not a void.
> 
> > -  if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start +
> mem.size))) {
> > -    avail = (heap_start + mem.size) - (size_t)heap_ptr;
> > +  if ((heap_ptr >= heap_start) && (heap_ptr < (heap_start + mem.size))) {
> > +    avail = (unsigned int)((heap_start + mem.size) - heap_ptr);
> 
> use ptrdiff_t to hold the difference between pointers, don't cast like this.
> 
> > --- a/libgloss/print.c
> > +++ b/libgloss/print.c
> >
> >  #include "glue.h"
> >
> > +extern int outbyte (char x);
> 
> outbyte is already defined in glue.h which is included here
> 
> > --- a/libgloss/putnum.c
> > +++ b/libgloss/putnum.c
> > @@ -14,7 +14,7 @@
> >   */
> >  #include "glue.h"
> >
> > -extern void print (char *ptr);
> > +extern void print (const char *ptr);
> 
> this prob should be moved to glue.h instead -mike
libgloss_v2.patch (application/octet-stream, 6.4 KB)
diff --git a/libgloss/glue.h b/libgloss/glue.h
index 98c0a6ad2..1ff388c21 100644
--- a/libgloss/glue.h
+++ b/libgloss/glue.h
@@ -29,5 +29,6 @@ extern char _end[];                /* _end is set in the linker command file */
 /* only one prcess support, as this is OS dependant */
 #define __MYPID 1
 
-int outbyte (char);
+extern int outbyte (char);
+extern void print (const char *);
 
diff --git a/libgloss/kill.c b/libgloss/kill.c
index a0eaee75b..4b9b73636 100644
--- a/libgloss/kill.c
+++ b/libgloss/kill.c
@@ -14,6 +14,8 @@
  */
 #include "glue.h"
 
+extern void _exit (int) __attribute__((__noreturn__));
+
 /*
  * kill -- go out via exit...
  */
diff --git a/libgloss/mips/cfe_mem.c b/libgloss/mips/cfe_mem.c
index 87caabf8c..2b782e923 100644
--- a/libgloss/mips/cfe_mem.c
+++ b/libgloss/mips/cfe_mem.c
@@ -47,7 +47,7 @@ void *get_mem_info (struct s_mem *);
 extern char _end[];
 
 /* Address immediately after available memory.  */
-static unsigned long memtop;
+static void *memtop;
 
 /* Program stack size.  */
 static unsigned long stack_size;
@@ -63,15 +63,15 @@ __libcfe_meminit (void)
     {
       uint64_t start, length, type;
       int i, rv;
-      long end_segbits, end_pa;
+      uintptr_t end_segbits, end_pa;
 
       /* Note that this only works if _end and the program live in kseg0
          or kseg1.  Not a problem with the default linker script, but
          if you're writing your own, keep it in mind.  For more complex
          memory allocation needs, you're encouraged to copy this file
          and syscalls.c (for sbrk()), and reimplement as appropriate.  */
-      end_segbits = (long)_end & ~ 0x1fffffffL;
-      end_pa = (long)_end & 0x1fffffffL;
+      end_segbits = (uintptr_t)_end & ~ 0x1fffffffL;
+      end_pa = (uintptr_t)_end & 0x1fffffffL;
 
       for (i = 0; ; i++)
         {
@@ -92,7 +92,7 @@ __libcfe_meminit (void)
 	     a winner.  */
           if (end_pa >= start && end_pa < (start + length))
             {
-              memtop = (start + length) | end_segbits;
+              memtop = (void*)(uintptr_t)((start + length) | end_segbits);
               break;
             }
         }
@@ -107,7 +107,7 @@ __libcfe_meminit (void)
 
   /* Chop the top of memory to a 32-byte aligned location, and
      round the stack size up to a 32-byte multiple.  */
-  memtop = memtop & ~(unsigned long)31;
+  memtop = (void*)((unsigned long)memtop & ~(unsigned long)31);
   stack_size = (stack_size + 31) & ~(unsigned long)31;
 }
 
diff --git a/libgloss/mips/cma101.c b/libgloss/mips/cma101.c
index e8f381864..f39925cf1 100644
--- a/libgloss/mips/cma101.c
+++ b/libgloss/mips/cma101.c
@@ -133,6 +133,7 @@ set_pclock (void)
   return;
 }
 
+extern void __cpu_timer_poll (int);
 #define PCLOCK_WAIT(x)  __cpu_timer_poll((x) * pclock)
 
 /* NOTE: On the Cogent CMA101 board the LCD controller will sometimes
@@ -178,6 +179,7 @@ lcd_display (int line, const char *msg)
 extern unsigned int __buserr_count(void);
 extern void __default_buserr_handler(void);
 extern void __restore_buserr_handler(void);
+extern void __cpu_flush(void);
 
 /* Allow the user to provide his/her own defaults.  */
 unsigned int __sizemem_default;
@@ -261,15 +263,13 @@ __sizemem ()
 /* Provided as a function, so as to avoid reading the I/O location
    multiple times: */
 static int
-convertbcd(byte)
-     unsigned char byte;
+convertbcd(unsigned char byte)
 {
   return ((((byte >> 4) & 0xF) * 10) + (byte & 0xF));
 }
 
 time_t
-time (_timer)
-     time_t *_timer;
+time (time_t *_timer)
 {
   time_t result = 0;
   struct tm tm;
diff --git a/libgloss/mips/nullmon.c b/libgloss/mips/nullmon.c
index 0b519bf7b..cabbec7eb 100644
--- a/libgloss/mips/nullmon.c
+++ b/libgloss/mips/nullmon.c
@@ -45,8 +45,7 @@ struct s_mem
 };
 
 void
-get_mem_info (mem)
-     struct s_mem *mem;
+get_mem_info (struct s_mem *mem)
 {
   mem->size = BOARD_MEM_SIZE - (_end - _ftext);
 }
diff --git a/libgloss/mips/syscalls.c b/libgloss/mips/syscalls.c
index 3ab543674..4e2f73753 100644
--- a/libgloss/mips/syscalls.c
+++ b/libgloss/mips/syscalls.c
@@ -4,22 +4,25 @@
 
 #include "regs.S"
 
+struct s_mem {
+  unsigned int size;
+  unsigned int icsize;
+  unsigned int dcsize;
+};
+
+void *get_mem_info (struct s_mem *);
+
 extern char _end[];
 
 /* FIXME: This is not ideal, since we do a get_mem_info() call for
    every sbrk() call. */
 char *
-sbrk (nbytes)
-     int nbytes;
+sbrk (int nbytes)
 {
   static char *heap_ptr = _end;
   static char *heap_start = _end;
   char        *base;
-  struct s_mem {
-    unsigned int size;
-    unsigned int icsize;
-    unsigned int dcsize;
-  } mem;
+  struct s_mem mem;
   unsigned int avail = 0;
 
   /* The sizeof (s_mem.size) must be 4 bytes.  The compiler should be
@@ -31,8 +34,8 @@ sbrk (nbytes)
   /* NOTE: The value returned from the get_mem_info call is the amount
      of memory, and not the address of the (last byte + 1) */
 
-  if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start + mem.size))) {
-    avail = (heap_start + mem.size) - (size_t)heap_ptr;
+  if ((heap_ptr >= heap_start) && (heap_ptr < (heap_start + mem.size))) {
+    avail = (heap_start + mem.size) - heap_ptr;
     base = heap_ptr;
   } /* else will fail since "nbytes" will be greater than zeroed "avail" value */
 
diff --git a/libgloss/mips/test.c b/libgloss/mips/test.c
index a99347914..b580ea933 100644
--- a/libgloss/mips/test.c
+++ b/libgloss/mips/test.c
@@ -1,4 +1,7 @@
-main()
+extern int outbyte(unsigned char byte);
+extern void print (const char *);
+
+int main()
 {
   outbyte ('&');
   outbyte ('@');
@@ -9,5 +12,5 @@ main()
   
   print ("\r\nDone...");
 
-  return;
+  return 0;
 }
diff --git a/libgloss/print.c b/libgloss/print.c
index 76d543b67..b2dd809c3 100644
--- a/libgloss/print.c
+++ b/libgloss/print.c
@@ -18,7 +18,7 @@
  * print -- do a raw print of a string
  */ 
 void
-print (char *ptr)
+print (const char *ptr)
 {
   while (*ptr) {
     outbyte (*ptr++);
diff --git a/libgloss/putnum.c b/libgloss/putnum.c
index 6e1051e24..c368c4136 100644
--- a/libgloss/putnum.c
+++ b/libgloss/putnum.c
@@ -14,8 +14,6 @@
  */
 #include "glue.h"
 
-extern void print (char *ptr);
-
 /*
  * putnum -- print a 32 bit number in hex
  */
diff --git a/libgloss/write.c b/libgloss/write.c
index 757141291..bc6aa6966 100644
--- a/libgloss/write.c
+++ b/libgloss/write.c
@@ -14,8 +14,6 @@
  */
 #include "glue.h"
 
-extern int  outbyte (char x);
-
 /*
  * write -- write bytes to the serial port. Ignore fd, since
  *          stdout and stderr are the same. Since we have no filesystem,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.