Mono 5 on Solaris Build issues - mono

I am trying to build Mono on Solaris 10 and have ran into an issue with error "Posix system lacks support for recursive mutexes". I am trying to build this with gcc 3.4.3 and I have installed gmake, gar, granlib, and gstrip to replace their Solaris alternatives. I have found a possible solution, but I can not locate the blog that references this line "1) patch /usr/lib/pkgconfig/gthread-2.0.pc to replace the -mt option (see Jonel's blog)" located at https://lists.dot.net/pipermail/mono-list/2007-January/034101.html. The blog is no longer active. Does anyone have any ideas what the patch they are referring to may be? Thanks in advance.

Solaris 10 does support recursive mutexes.
Per the Solaris 10 pthread_mutexattr_settype man page:
PTHREAD_MUTEX_RECURSIVE
A thread attempting to relock this mutex without first unlocking it
will succeed in locking the mutex. The relocking deadlock that can
occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with
this type of mutex. Multiple locks of this mutex require the same
number of unlocks to release the mutex before another thread can
acquire the mutex. A thread attempting to unlock a mutex that another
thread has locked will return with an error. A thread attempting to
unlock an unlocked mutex will return with an error. This type of mutex
is only supported for mutexes whose process shared attribute is
PTHREAD_PROCESS_PRIVATE.
Also per the man page, the required compile/link options, and the proper #include statement:
cc –mt [ flag... ] file... –lpthread [ library... ]
#include <pthread.h>
Note the addition of -lpthread. I suspect the blog you're referring to said to replace -mt with -mt -lpthread.

(A bit more research into this problem, prodded by the Unix question How to install .net Mono on Solaris 11 (source code compile)? produced this answer, which I'm repeating here.)
The exact value that you set _XOPEN_SOURCE to doesn't matter. Mono is incorrectly defining the _XOPEN_SOURCE_EXTENDED macro:
case "${host}" in
*solaris* )
AC_MSG_CHECKING(for Solaris XPG4 support)
if test -f /usr/lib/libxnet.so; then
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600"
CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__"
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED=1" <-- WRONG
LIBS="$LIBS -lxnet"
The _XOPEN_SOURCE_EXTENDED macro does not exist in either the POSIX 6 or the POSIX 7 standard.
Even Linux agrees that _XOPEN_SOURCE_EXTENDED should not be defined here. Per the Linux feature_test_macros man page:
_XOPEN_SOURCE_EXTENDED
If this macro is defined, and _XOPEN_SOURCE is defined, then expose definitions corresponding to the XPG4v2 (SUSv1) UNIX extensions (UNIX 95). Defining _XOPEN_SOURCE with a value of 500 or more also produces the same effect as defining _XOPEN_SOURCE_EXTENDED. Use of _XOPEN_SOURCE_EXTENDED in new source code should be avoided.
Since defining _XOPEN_SOURCE with a value of 500 or more has the same effect as defining _XOPEN_SOURCE_EXTENDED, the latter (obsolete) feature test macro is generally not described in the SYNOPSIS in man pages.
Note the precise wording:
If this macro (_XOPEN_SOURCE_EXTENDED) is defined, and _XOPEN_SOURCE is defined, then expose definitions corresponding to the XPG4v2 (SUSv1) UNIX extensions (UNIX 95). ...
Defining _XOPEN_SOURCE to any value while also defining _XOPEN_SOURCE_EXTENDED results in XPG4v2, and that's NOT the XPG6 necessary to get recursive mutexes.
You're likely running into this check in the Solaris 11 /usr/include/sys/feature_tests.h:
/*
* It is invalid to compile an XPG3, XPG4, XPG4v2, or XPG5 application
* using c99. The same is true for POSIX.1-1990, POSIX.2-1992, POSIX.1b,
* and POSIX.1c applications. Likewise, it is invalid to compile an XPG6
* or a POSIX.1-2001 application with anything other than a c99 or later
* compiler. Therefore, we force an error in both cases.
*/
#if defined(_STDC_C99) && (defined(__XOPEN_OR_POSIX) && !defined(_XPG6))
#error "Compiler or options invalid for pre-UNIX 03 X/Open applications \
and pre-2001 POSIX applications"
#elif !defined(_STDC_C99) && \
(defined(__XOPEN_OR_POSIX) && defined(_XPG6))
#error "Compiler or options invalid; UNIX 03 and POSIX.1-2001 applications \
require the use of c99"
#endif
_XPG6 gets defined earlier in the file, in this block:
/*
* Use of _XOPEN_SOURCE
*
* The following X/Open specifications are supported:
*
* X/Open Portability Guide, Issue 3 (XPG3)
* X/Open CAE Specification, Issue 4 (XPG4)
* X/Open CAE Specification, Issue 4, Version 2 (XPG4v2)
* X/Open CAE Specification, Issue 5 (XPG5)
* Open Group Technical Standard, Issue 6 (XPG6), also referred to as
* IEEE Std. 1003.1-2001 and ISO/IEC 9945:2002.
*
* XPG4v2 is also referred to as UNIX 95 (SUS or SUSv1).
* XPG5 is also referred to as UNIX 98 or the Single Unix Specification,
* Version 2 (SUSv2)
* XPG6 is the result of a merge of the X/Open and POSIX specifications
* and as such is also referred to as IEEE Std. 1003.1-2001 in
* addition to UNIX 03 and SUSv3.
*
* When writing a conforming X/Open application, as per the specification
* requirements, the appropriate feature test macros must be defined at
* compile time. These are as follows. For more info, see standards(5).
*
* Feature Test Macro Specification
* ------------------------------------------------ -------------
* _XOPEN_SOURCE XPG3
* _XOPEN_SOURCE && _XOPEN_VERSION = 4 XPG4
* _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED = 1 XPG4v2
* _XOPEN_SOURCE = 500 XPG5
* _XOPEN_SOURCE = 600 (or POSIX_C_SOURCE=200112L) XPG6
*
* In order to simplify the guards within the headers, the following
* implementation private test macros have been created. Applications
* must NOT use these private test macros as unexpected results will
* occur.
*
* Note that in general, the use of these private macros is cumulative.
* For example, the use of _XPG3 with no other restrictions on the X/Open
* namespace will make the symbols visible for XPG3 through XPG6
* compilation environments. The use of _XPG4_2 with no other X/Open
* namespace restrictions indicates that the symbols were introduced in
* XPG4v2 and are therefore visible for XPG4v2 through XPG6 compilation
* environments, but not for XPG3 or XPG4 compilation environments.
*
* _XPG3 X/Open Portability Guide, Issue 3 (XPG3)
* _XPG4 X/Open CAE Specification, Issue 4 (XPG4)
* _XPG4_2 X/Open CAE Specification, Issue 4, Version 2 (XPG4v2/UNIX 95/SUS)
* _XPG5 X/Open CAE Specification, Issue 5 (XPG5/UNIX 98/SUSv2)
* _XPG6 Open Group Technical Standard, Issue 6 (XPG6/UNIX 03/SUSv3)
*/
/* X/Open Portability Guide, Issue 3 */
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE - 0 < 500) && \
(_XOPEN_VERSION - 0 < 4) && !defined(_XOPEN_SOURCE_EXTENDED)
#define _XPG3
/* X/Open CAE Specification, Issue 4 */
#elif (defined(_XOPEN_SOURCE) && _XOPEN_VERSION - 0 == 4)
#define _XPG4
#define _XPG3
/* X/Open CAE Specification, Issue 4, Version 2 */
#elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE_EXTENDED - 0 == 1)
#define _XPG4_2
#define _XPG4
#define _XPG3
/* X/Open CAE Specification, Issue 5 */
#elif (_XOPEN_SOURCE - 0 == 500)
#define _XPG5
#define _XPG4_2
#define _XPG4
#define _XPG3
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199506L
/* Open Group Technical Standard , Issue 6 */
#elif (_XOPEN_SOURCE - 0 == 600) || (_POSIX_C_SOURCE - 0 == 200112L)
#define _XPG6
#define _XPG5
#define _XPG4_2
#define _XPG4
#define _XPG3
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif

Related

Export COMMON block from DLL with gfortran

I am having trouble correctly accessing a variable in a Fortran DLL from a Fortran EXE when the variable is part of a COMMON block.
I have a trivial code simple.f90 which I compile into a DLL using MSYS64/MinGW-w64 gfortran 9.2 as
x86_64-w64-mingw32-gfortran simple.f90 -o simple.dll -shared
! simple.f90
module m
implicit none
integer :: a, b
!common /numbers/ a, b
end module
subroutine init_vals
use m
implicit none
a = 1
b = 2
end subroutine
This library is used from a even simpler program prog.f90, compiled as
x86_64-w64-mingw32-gfortran prog.f90 -o prog -L. -lsimple
! prog.90
program p
use m
implicit none
print *, 'Before', a, b
call init_vals
print *, 'After', a, b
end program
When the COMMON block /numbers/ is commented out, the code works and prints the expected result:
Before 0 0
After 1 2
However, when I uncomment the COMMON block, the output becomes
Before 0 0
After 0 0
as if the variables used by the program were suddenly distinct from those used in the library.
Both variants work equally well in a Linux-based OS with gfortran 9.1.
I am aware that "On some systems, procedures and global variables (module variables and COMMON blocks) need special handling to be accessible when they are in a shared library," as mentioned here: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/GNU-Fortran-Compiler-Directives.html . However, I was not able to insert a statement of the type
!GCC$ ATTRIBUTES DLLIMPORT :: numbers
or
!GCC$ ATTRIBUTES DLLEXPORT :: numbers
anywhere in the code without being snapped at by the compiler.
As pointed out by M. Chinoune in the comment, current gfortran lacks the ability to import common blocks from DLLs. Even though there has been a patch for some time, it is not yet merged. In the end, I needed two things to make the above code work:
First, apply the following patch to GCC 9.2 and compile the compiler manually in MSYS2:
--- gcc/fortran/trans-common.c.org 2019-03-11 14:58:44.000000000 +0100
+++ gcc/fortran/trans-common.c 2019-09-26 08:31:16.243405900 +0200
## -102,6 +102,7 ##
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
+#include "attribs.h"
#include "stor-layout.h"
#include "varasm.h"
#include "trans-types.h"
## -423,6 +424,9 ##
/* If there is no backend_decl for the common block, build it. */
if (decl == NULL_TREE)
{
+ unsigned id;
+ tree attribute, attributes;
+
if (com->is_bind_c == 1 && com->binding_label)
decl = build_decl (input_location, VAR_DECL, identifier, union_type);
else
## -454,6 +458,23 ##
gfc_set_decl_location (decl, &com->where);
+ /* Add extension attributes to COMMON block declaration. */
+ if (com->head)
+ {
+ attributes = NULL_TREE;
+ for (id = 0; id < EXT_ATTR_NUM; id++)
+ {
+ if (com->head->attr.ext_attr & (1 << id))
+ {
+ attribute = build_tree_list (
+ get_identifier (ext_attr_list[id].middle_end_name),
+ NULL_TREE);
+ attributes = chainon (attributes, attribute);
+ }
+ }
+ decl_attributes (&decl, attributes, 0);
+ }
+
if (com->threadprivate)
set_decl_tls_model (decl, decl_default_tls_model (decl));
Second, only the line
!GCC$ ATTRIBUTES DLLIMPORT :: a, b
was needed in the main program (right after implicit none), but not any exports anywhere. This is apparently a different syntactical approach then in Intel Fortran, where one imports the COMMON block rather than its constituents. I also found out that I needed to import both a and b even if I only needed b. (When only a was needed, importing a only was enough.)

assertion from valgrind mc_main.c

My valgrind runs reports errors like this
Memcheck: mc_main.c:8292 (mc_pre_clo_init): Assertion 'MAX_PRIMARY_ADDRESS == 0x1FFFFFFFFFULL' failed.
What does this mean? Is it a valgrind internal error or an error from my program?
This is a valgrind internal error. This is very weird, as this failed
assertion is a self check done very early on.
You should file a bug on valgrind bugzilla, reporting all the needed
details (version, platform, ...)
From the Valgrind source code (from git HEAD)
/* Only change this. N_PRIMARY_MAP *must* be a power of 2. */
#if VG_WORDSIZE == 4
/* cover the entire address space */
# define N_PRIMARY_BITS 16
#else
/* Just handle the first 128G fast and the rest via auxiliary
primaries. If you change this, Memcheck will assert at startup.
See the definition of UNALIGNED_OR_HIGH for extensive comments. */
# define N_PRIMARY_BITS 21
#endif
/* Do not change this. */
#define N_PRIMARY_MAP ( ((UWord)1) << N_PRIMARY_BITS)
/* Do not change this. */
#define MAX_PRIMARY_ADDRESS (Addr)((((Addr)65536) * N_PRIMARY_MAP)-1)
...
tl_assert(MAX_PRIMARY_ADDRESS == 0x1FFFFFFFFFULL);
So it looks like something has been changed that shouldn't have been.

Preprocessor macro C/Objective-C

Hello I am trying to Make A Macro that gets a parameter and tries to add postFix to it.
#define myPostFix HelloWorld
#define macro(x) x ##myPostFix
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)
Expected behavior is to get
CAlgThreadHandleObjectHelloWorld
What I actually get is:
CAlgThreadHandleObjectmyPostFix
Can Some1 help me to get the expected behavior please?
Please note that myPostFix is something I have to define in project GCC definitions and it should vary from project to project.
Try:
#define myPostFix HelloWorld
#define macro_2(x, y) x##y
#define macro_1(x, y) macro_2(x, y)
#define macro(x) macro_1(x, myPostFix)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)
You need the intermediate macro_1 to let the preprocessor substitute myPostFix assignement, then macro_2 to concatenate strings.
This solution let you assign myPostFix to the value you want.
To clarify how preprocessor and symbol replacement works consider that the preprocessing translation phase is not recursive on parameters, so the translation need to pass through a forced parameter expansion more than one time up to expand all parameters.
In our case:
CAlgThreadHandleObject expands to : macro(CAlgThreadHandleObject)
macro(CAlgThreadHandleObject) expands to : macro_1(CAlgThreadHandleObject, myPostFix)
macro_1 expands to: macro_2(CAlgThreadHandleObject, HelloWorld)
And last macro_2 expands to: CAlgThreadHandleObjectHelloWorld
You actually need to go three layers deep with this one in order to get the macro to expand properly. I can't pretend to understand the exact reasoning why this is necessary (not that I want to understand...)
#define MY_ADDPOSTFIX3(x, y) x ## y
#define MY_ADDPOSTFIX2(x, y) MY_ADDPOSTFIX3(x, y)
#define MY_ADDPOSTFIX(x) MY_ADDPOSTFIX2(x, MY_POSTFIX)
MY_ADDPOSTFIX(Func)
You can test this:
$ gcc -E test.c -DMY_POSTFIX=HelloWorld
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
FuncHelloWorld
And...
$ gcc -E test.c -DMY_POSTFIX=Goodbye | tail -n 1
FuncGoodbye
Simply pass it through another call of the macro macro so the define is expanded. I slightly changed the macros, but the functionality is the same:
#define myPostFix HelloWorld
#define macro2(x,y) x##y
#define macro(x,y) macro2(x,y)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject,myPostFix)

saveenv fails after U-Boot update - Writing to NAND... FAILED

to be able to run my eSata Sheevaplug with Debian Wheezy I had to upgrade U-Boot to the DENX version.
As step-by-step guide I used this read from Martin Michlmayr. I did the upgrade using screen and a USB stick at the plug.
The upgrade went good and after resetting I got the plug started with the new version.
Marvell>> version
U-Boot 2013.10 (Oct 21 2013 - 21:06:56)
Marvell-Sheevaplug - eSATA - SD/MMC
gcc (Debian 4.8.1-9) 4.8.1
GNU ld (GNU Binutils for Debian) 2.23.52.20130727
Marvell>>
In the guide is written to set machid environment variable and MAC address.
But unfortunatly saveenv fails due to bad blocks in the NAND. I tried different versions of U-Boot also the one provided by NewIT. All behave the same way.
Marvell>> setenv machid a76
Marvell>> saveenv
Saving Environment to NAND...
Erasing NAND...
Skipping bad block at 0x00060000
Writing to NAND... FAILED!
There are some blocks marked as bad, which might be normal - by NewIT.
Marvell>> nand info
Device 0: nand0, sector size 128 KiB
Page size 2048 b
OOB size 64 b
Erase size 131072 b
Marvell>> nand bad
Device 0 bad blocks:
00060000
00120000
00360000
039c0000
0c300000
10dc0000
1ac40000
1f1c0000
Has someone a clue what the problem is and what I need to change to be able saving environment variables in u-boot?
Thanks,
schibbl
Due to configuration of environment variable storage at NAND, the sector size of 128k and a bad block mapping the environment variable storage adress it is not possible to write env to NAND.
Marvell>> nand bad
Device 0 bad blocks:
00060000
...
include/configs/sheevaplug.h which points perfectly to the bad block.
/*
* max 4k env size is enough, but in case of nand
* it has to be rounded to sector size
*/
#define CONFIG_ENV_SIZE 0x20000 /* 128k */
#define CONFIG_ENV_ADDR 0x60000
#define CONFIG_ENV_OFFSET 0x60000 /* env starts here */
Because of unused sector 0x80000 to 0x9FFFF I moved env storage there.
/*
* max 4k env size is enough, but in case of nand
* it has to be rounded to sector size
*/
#define CONFIG_ENV_SIZE 0x20000 /* 128k */
#define CONFIG_ENV_ADDR 0x80000
#define CONFIG_ENV_OFFSET 0x80000 /* env starts here due to bad block */
Beware! We have to ensure our compiled u-boot.kwb is less then 384k. Otherwise we will write u-boot to bad block marked memory and will brick the device.
Best way to recompile with custom env address, is to use Michlmayrs sources, which includes patches for mmc and e-sata support.

Increasing number of BPF devices on AIX

Anyone know how to increase the number of BPF devices in AIX 5.2/5.3 above the supposed system default of four? i.e. running more than four tcpdump processes concurrently?
The answer I think is "IMPOSSIBLE".
The reason is to read the header file /usr/include/net/bpf.h:
(mine is AIX 5.2)
Then u come across:
#define NBPFILTER 4
/* Flags to set the appropriate minor device */
#define BPF0 0x1 /* /dev/bpf0 */
#define BPF1 0x2 /* /dev/bpf1 */
#define BPF2 0x4 /* /dev/bpf2 */
#define BPF3 0x8 /* /dev/bpf3 */
So the number "4" is in fact hardcoded into the source code, and each of the above bpfX is all preprogrammed up to 4.