This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
Building libgcj on Linux/Alpha
- To: java-discuss@sourceware.cygnus.com
- Subject: Building libgcj on Linux/Alpha
- From: Jeff Sturm <jsturm@sigma6.com>
- Date: Mon, 21 Jun 1999 10:13:26 -0400
- Organization: AppNet
Below are patches necessary to build/use libgcj on Linux/Alpha. Most
are GC issues. The worst is that __data_start is no longer defined on
my RH 6.0 machine (is this a glibc2.1 problem, or binutils?) so I
included a workaround (based on /proc) to obtain the starting address
of the data segment. I'll bring this up on gclist as well. I'm not
sure the B-W-D collector is handling dynamic loading correctly for Alpha
yet, so I plan to run more tests.
Also I defined GC_test_and_set for Alpha, and __IEEE_LITTLE_ENDIAN in
ieeefp.h.
There is another small problem in boehm-gc... the alpha_mach_dep.s file
has preprocessor symbols, and the current Makefile runs
"as alpha_mach_dep.s" which fails on Linux. I got past by renaming
it to alpha_mach_dep.S and compiling with "gcc -c alpha_mach_dep.S".
Since patch isn't very friendly to renaming files, is there a cleaner
workaround?
I noticed the current libgcj is based on 4.13alpha2... is there a plan
to migrate to 4.14?
diff -r -c libgcj.orig/boehm-gc/config.h libgcj/boehm-gc/config.h
*** libgcj.orig/boehm-gc/config.h Fri Apr 16 05:56:29 1999
--- libgcj/boehm-gc/config.h Sun Jun 20 09:03:55 1999
***************
*** 844,851 ****
# define CPP_WORDSZ 64
# define STACKBOTTOM ((ptr_t) 0x120000000)
# ifdef __ELF__
! extern int __data_start;
! # define DATASTART &__data_start
# define DYNAMIC_LOADING
# else
# define DATASTART ((ptr_t) 0x140000000)
--- 844,851 ----
# define CPP_WORDSZ 64
# define STACKBOTTOM ((ptr_t) 0x120000000)
# ifdef __ELF__
! # define DATASTART GC_data_start
! # define USE_PROC
# define DYNAMIC_LOADING
# else
# define DATASTART ((ptr_t) 0x140000000)
diff -r -c libgcj.orig/boehm-gc/gc_priv.h libgcj/boehm-gc/gc_priv.h
*** libgcj.orig/boehm-gc/gc_priv.h Wed Apr 7 04:01:38 1999
--- libgcj/boehm-gc/gc_priv.h Thu Jun 10 00:09:41 1999
***************
*** 442,451 ****
: "0"(1), "m"(*(addr)));
return oldval;
}
# else
-- > Need implementation of GC_test_and_set()
# endif
- # define GC_clear(addr) (*(addr) = 0)
extern volatile unsigned int GC_allocate_lock;
/* This is not a mutex because mutexes that obey the (optional)
*/
--- 442,473 ----
: "0"(1), "m"(*(addr)));
return oldval;
}
+ inline static void GC_clear(volatile unsigned int *addr) {
+ *(addr) = 0;
+ }
+ # elif defined(__alpha__)
+ inline static int GC_test_and_set(volatile unsigned int *addr)
{
+ long oldval, temp;
+
+ __asm__ __volatile__(
+ "1:\tldl_l %0,%3\n"
+ "\tbne %0,2f\n"
+ "\tor $31,1,%1\n"
+ "\tstl_c %1,%2\n"
+ "\tbeq %1,1b\n"
+ "2:\tmb\n"
+ : "=&r"(oldval), "=&r"(temp), "=m"(*(addr))
+ : "m"(*(addr))
+ : "memory");
+ return (int)oldval;
+ }
+ inline static void GC_clear(volatile unsigned int *addr) {
+ __asm__ __volatile__("mb": : :"memory");
+ *(addr) = 0;
+ }
# else
-- > Need implementation of GC_test_and_set()
# endif
extern volatile unsigned int GC_allocate_lock;
/* This is not a mutex because mutexes that obey the (optional)
*/
diff -r -c libgcj.orig/boehm-gc/misc.c libgcj/boehm-gc/misc.c
*** libgcj.orig/boehm-gc/misc.c Mon Apr 26 10:15:05 1999
--- libgcj/boehm-gc/misc.c Sun Jun 20 09:02:04 1999
***************
*** 436,441 ****
--- 436,444 ----
# if defined(LINUX) && defined(POWERPC)
GC_init_linuxppc();
# endif
+ # if defined(LINUX) && defined(ALPHA)
+ GC_init_linuxalpha();
+ # endif
# ifdef SOLARIS_THREADS
GC_thr_init();
/* We need dirty bits in order to find live stack sections.
*/
diff -r -c libgcj.orig/boehm-gc/os_dep.c libgcj/boehm-gc/os_dep.c
*** libgcj.orig/boehm-gc/os_dep.c Wed Apr 21 05:42:28 1999
--- libgcj/boehm-gc/os_dep.c Sun Jun 20 09:21:58 1999
***************
*** 68,74 ****
# define NEED_FIND_LIMIT
# endif
! # if defined(LINUX) && defined(POWERPC)
# define NEED_FIND_LIMIT
# endif
--- 68,74 ----
# define NEED_FIND_LIMIT
# endif
! # if defined(LINUX) && (defined(POWERPC) || defined(ALPHA))
# define NEED_FIND_LIMIT
# endif
***************
*** 145,150 ****
--- 145,226 ----
/* This may need to be environ, without the underscore, for
*/
/* some versions.
*/
GC_data_start = GC_find_limit((ptr_t)&_environ, FALSE);
+ }
+ #endif
+
+ #if defined(LINUX) && defined(ALPHA)
+ ptr_t GC_data_start;
+
+ void GC_init_linuxalpha()
+ {
+ # ifdef USE_PROC
+ FILE *fp = fopen("/proc/self/maps", "r");
+
+ if (fp) {
+ extern void *_etext;
+ ptr_t stacktop = 0, stackbottom = 0;
+ ptr_t textstart = 0, textend = 0;
+ ptr_t datastart = 0, dataend = 0;
+ ptr_t bssstart = 0, bssend = 0;
+
+ while (!feof(fp)) {
+ ptr_t start, end, offset;
+ unsigned short major, minor;
+ char r, w, x, p;
+ unsigned int inode;
+
+ int n = fscanf(fp, "%lx-%lx %c%c%c%c %lx %hx:%hx %d",
+ &start, &end, &r, &w, &x, &p, &offset, &major, &minor,
&inode);
+ if (n < 10) break;
+
+ /*
+ * If local variable lies within segment, it is stack.
+ * Else if segment lies below _end and is executable,
+ * it is text. Otherwise, if segment start lies between
+ * _etext and _end and segment is writable and is mapped
+ * to the executable image it is data, otherwise bss.
+ */
+ if (start < (ptr_t)&fp && end > (ptr_t)&fp && w == 'w') {
+ stacktop = start;
+ stackbottom = end;
+ } else if (start < (ptr_t)&_end && w == '-' && x == 'x') {
+ textstart = start;
+ textend = end;
+ } else if (start >= (ptr_t)&_etext &&
+ start < (ptr_t)&_end && w == 'w') {
+ if (inode > 0) {
+ datastart = start;
+ dataend = end;
+ } else {
+ bssstart = start;
+ bssend = end;
+ }
+ }
+
+ //printf("%016lx-%016lx %c%c%c%c %016lx %02hx:%02hx %d\n",
+ // start, end, r, w, x, p, offset, major, minor, inode);
+
+ while (fgetc(fp) != '\n') ;
+ }
+ fclose(fp);
+
+ //fprintf(stderr, "text: %lx-%lx\n", textstart, textend);
+ //fprintf(stderr, "data: %lx-%lx\n", datastart, dataend);
+ //fprintf(stderr, "bss: %lx-%lx\n", bssstart, bssend);
+ //fprintf(stderr, "stack: %lx-%lx\n", stacktop, stackbottom);
+
+ GC_data_start = datastart;
+ } else {
+ # endif
+ extern ptr_t GC_find_limit();
+ extern int _edata;
+ /* This may need to be environ, without the underscore, for */
+ /* some versions. */
+ GC_data_start = GC_find_limit((ptr_t)&_edata, FALSE);
+ # ifdef USE_PROC
+ }
+ # endif
+ //fprintf(stderr, "GC_data_start = %p\n", GC_data_start);
}
#endif
diff -r -c libgcj.orig/libjava/java/lang/ieeefp.h
libgcj/libjava/java/lang/ieeefp.h
*** libgcj.orig/libjava/java/lang/ieeefp.h Wed Apr 7 10:52:38 1999
--- libgcj/libjava/java/lang/ieeefp.h Wed Jun 9 21:52:51 1999
***************
*** 1,6 ****
--- 1,10 ----
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
+ #ifdef __alpha__
+ #define __IEEE_LITTLE_ENDIAN
+ #endif
+
#ifdef __arm__
/* ARM always has big-endian words. Within those words the byte
ordering
appears to be big or little endian. Newlib doesn't seem to care
about
--
Jeff Sturm
jsturm@sigma6.com