Compilation failure in cpu_features_get.cc - cobalt

I'm trying to compile Cobalt and getting errors building cpu_features_get.cc. The specific version I'm building is here: https://github.com/Metrological/cobalt/blob/master/src/starboard/shared/linux/cpu_features_get.cc and it appears to be based on Cobalt 22. I'm building using stbgcc-6.3.18, only Ubuntu 20.04. Sysroot is set to the cross compiler. And I'm building the starboard port at https://github.com/Metrological/cobalt/tree/master/src/third_party/starboard/wpe/brcm/arm, for ARM64.
An example of the error:
cpu_features_get.cc:381:12: error: 'HWCAP_SET_FOR_ARMV8' was not declared in this scope
There follow others, all related to HWCAP #defines.
As far as I can tell, the file defines these values if:
53: #if SB_IS(32_BIT) || defined(ANDROID)
Neither of these is true - I am compiling for ARM64 on Linux.
The code using HWCAP_SET_FOR_ARMV8 and the other missing defines is conditionally compiled as well:
340: #if SB_IS(ARCH_ARM) || SB_IS(ARCH_ARM64)
...
// Construct hwcap bitmask by the feature flags in /proc/cpuinfo
uint32_t ConstructHwcapFromCPUInfo(ProcCpuInfo* cpu_info,
int16_t architecture_generation,
uint32_t hwcap_type) {
if (hwcap_type == AT_HWCAP && architecture_generation >= 8) {
// This is a 32-bit ARM binary running on a 64-bit ARM64 kernel.
// The 'Features' line only lists the optional features that the
// device's CPU supports, compared to its reference architecture
// which are of no use for this process.
SB_LOG(INFO) << "Faking 32-bit ARM HWCaps on ARMv"
<< architecture_generation;
return HWCAP_SET_FOR_ARMV8;
}
...
...
So ARCH_ARM64 is true, and this code is compiled. But the defines are missing because it's not 32-bit. This seems contradictory and to my eyes could never have worked. How is it possible to compile Cobalt for ARM64?

Related

Linux kernel 5.4 GCC 9.1.0 does not show code coverage

we are using Linux kernel 5.4 with gcc 9.1.0 on different architectures (arm, arm64, x86_64). I am in charge of creating code coverage for kernel modules. I am not selecting the Linux kernel version nor the compiler version.
I am able to create code coverage for arm/arm64 and see the results in /sys/kernel/debugfs/gcov/... as usual. Also, loaded modules are visible in the gcov subdirectory.
However, for x86_64, I on only see /sys/kernel/debubfs/gcov/reset and nothing else, even if I set CONFIG_GCOV_COVERAGE_ALL=y.
The __gcov_init in kernel/gcov/base.c normally creates a
pr_info("version magic=...")
which is visible on arm/arm64 at boot time but not for x86_64. __gcov_init should be called for every source file as a gcc constructor and the first call creates the version magic message.
It seems to me that in my combination the code coverage function __gcov_init is never called in x86_64.
In the config, I use
CONFIG_GCOV_PROFILE=y
CONFIG_GCOV_FORMAT_4_7=y
and sometimes only for x86 CONFIG_GCOV_PROFILE_ALL=y. Nothing besides the "reset" file is visible /sys/kernel/debug/gcov/... for x86.
Any suggestions are welcome.
Code coverage constructors are now written in a ".ctors.65435" section (the number is possibly a constructor priority), but kernel 5.4 only knows ".ctors".
For the kernel internal code coverage, the following change (already in later kernels, e.g. 5.12) brings back code coverage
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
## -631,6 +631,7 ##
#ifdef CONFIG_CONSTRUCTORS
#define KERNEL_CTORS() . = ALIGN(8); \
__ctors_start = .; \
+ KEEP(*(SORT(.ctors.*))) \
KEEP(*(.ctors)) \
KEEP(*(SORT(.init_array.*))) \
KEEP(*(.init_array)) \
However, kernel/module.c does not know ".ctors.65435" either, and the modules compiled with gcc9 or gcc10 do not have a ".ctors" ELF sections. So I just changed as a HACK (!)
--- a/kernel/module.c
+++ b/kernel/module.c
## -3294,7 +3294,7 ## static int find_module_sections(struct module *mod, struct load_info *info)
mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
#endif
#ifdef CONFIG_CONSTRUCTORS
- mod->ctors = section_objs(info, ".ctors",
+ mod->ctors = section_objs(info, ".ctors.65435",
sizeof(*mod->ctors), &mod->num_ctors);
if (!mod->ctors)
mod->ctors = section_objs(info, ".init_array",
This brings back module code coverage, but
.ctors.* for modules is not known in the newest 5.x kernel, and so I think this should be fixed in the Linux Kernel module handling
Instead of hacking and use ".ctors.65435" in kernel/module.c instead of ".ctors", the proper solution is to change the module linker script to combine all ".ctors.*" section with the ."ctors" section:
diff --git a/scripts/module-common.lds b/scripts/module-common.lds
index d61b9e8678e8..0cd6aabaa460 100644
--- a/scripts/module-common.lds
+++ b/scripts/module-common.lds
## -20,6 +20,7 ## SECTIONS {
__kcrctab_unused_gpl 0 : { *(SORT(___kcrctab_unused_gpl+*)) }
__kcrctab_gpl_future 0 : { *(SORT(___kcrctab_gpl_future+*)) }
+ .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) }
.init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }
__jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) }
--
2.29.2
This brings back the code coverage for modules.

How to use langinfo.h features in glibc without breaking compilation in FreeBSD based system?

I am trying to make the following code work on both Linux and FreeBSD based system, Is it a valid usage of macros __GLIBC__ and __USE_XOPEN2K8?
#include <stdio.h>
#include <langinfo.h>
#include <locale.h>
#include <xlocale.h>
int main(void) {
//#if defined(__GLIBC__) && defined (__USE_XOPEN2K8)
locale_t loc;
char *locale_messages = "en-US.utf-8";
loc = newlocale(LC_ALL_MASK, locale_messages, (locale_t)0);
if (loc != NULL)
{
char result[256];
sprintf(result, "%s_%s.%s",
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
nl_langinfo_l(CODESET, loc));
}
//#endif
}
If I don't use those directives, I get the following error on mac OS. I want to disable that code to avoid the following errors.
error: use of undeclared identifier '_NL_IDENTIFICATION_LANGUAGE'
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
^
error: use of undeclared identifier '_NL_IDENTIFICATION_TERRITORY'
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
I have found one thread recommending use _GNU_SOURCE and _XOPEN_SOURCE, but as result above code is disabled on my linux system too. It seems I need to define _GNU_SOURCE before using it, but before proceding with this idea, can we work with __GLIBC__ and __USE_XOPEN2K8.
You can use
#indef __FreeBSD__
#endif
preprocessor directives to ignore the code that shouldn't be built on FreeBSD. However man nl_langinfo_l on FreeBSD says that this function is present on FreeBSD, so you shouldn't have any problems with it.
The best way is to use a build system to detect if that option is available and then conditionally enable that part of code depending of the detection result. This is how autotools project came to be - to detect differences between operating systems.
In cmake you could:
include(CheckCSourceCompiles)
check_c_source_compiles("
#define _GNU_SOURCE
#define _SOMETHING_READ_FEATURE_TEST_MACROS
#include <something something that is needed.h>
int main() { return _NL_IDENTIFICATION_TERRITORY; }
" WE_HAVE_NL_IDENTIFICATION_TERRITORY)
if(WE_HAVE_NL_IDENTIFICATION_TERRITORY)
target_add_definitions(your_target PUBLIC LIB_HAS_NL_IDENTIFICATION_TERRITORY)
endif()
and then use your own LIB_HAS_NL_IDENTIFICATION_TERRITORY macro that detect if that option is available or not. Such solution is stable, easy to port and dynamically reacts to environment changes.

Creating Haskell shared libraries on OS X

I'm trying to create a shared library from Haskell source code.
I've tried following the instruction here: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/ but I'm just not having any luck.
When I compile with Haskell 64-bit (ghc 7.0.4 from 2011.4.0.0) I get the following error:
ld: pointer in read-only segment not allowed in slidable image, used in
___gmpn_modexact_1c_odd
As an alternative I also tried the 32-bit version, and depending on the exact flags I use to link get errors such as:
Library not loaded: /usr/local/lib/ghc-7.0.4/base-4.3.1.0/libHSbase-4.3.1.0-ghc7.0.4.dylib
I did manage to get a little further by adding -lHSrts to the linker line. This got me to the point of successfully linking and loading the library, but I'm then unable to find the function name using dlsym (or manually using nm | grep)
Any hints would be greatly appreciated, an example make file, or build line that has successfully built (and used) a shared library on OS X would be appreciated. I'm quite new to Haskell and don't know if I should keep banging my head assuming that the problem is on my end, or for various reasons I shouldn't expect this to work on OS X.
A git repo with all the combinations I've tried is available here: https://github.com/bennoleslie/haskell-shared-example I did manage to get something working for 32-bit ghc, but not 64-bit yet.
It is possible to create working shared libraries on 64-bit OS X, with the latest Haskell Platform release (2012.4 64bit)
The invocation line works for me:
ghc -O2 --make \
-no-hs-main -optl '-shared' -optc '-DMODULE=Test' \
-o libTest.so Test.hs module_init.c
module_init.c should be something like:
#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#define STR(a) XSTR(a)
#define XSTR(a) #a
#include <HsFFI.h>
extern void CAT(__stginit_, MODULE)(void);
static void library_init(void) __attribute__((constructor));
static void library_init(void)
{
/* This seems to be a no-op, but it makes the GHCRTS envvar work. */
static char *argv[] = { STR(MODULE) ".so", 0 }, **argv_ = argv;
static int argc = 1;
hs_init(&argc, &argv_);
hs_add_root(CAT(__stginit_, MODULE));
}
static void library_exit(void) __attribute__((destructor));
static void library_exit(void)
{
hs_exit();
}
This git repo: https://github.com/bennoleslie/haskell-shared-example contains a working example.
All credit goes to this original source: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/
You might want to try the ghc port in Homebrew -- https://github.com/mxcl/homebrew/blob/master/Library/Formula/ghc.rb

How to register Linux Security Module in kernel 2.6?

I want to use the LSM framework with kernel ubuntu 2.6.36.
When I compiled the kernel module, it wrote:
WARNING: "register_security " undefined!
After a lot of googlings, I found the reason is that the register_security() symbol is no longer exported in the 2.6 kernel.
So I added EXPORT_SYMBOL(register_security) in the ../security/security.c file, and recompiled the kernel.
After booting with the new kernel, I added extern int register_security(struct security_operations *ops) in my kernel module file, and compiled the module again.
However, the WARNING information still existed. If I continued to insmode the module, the dmesg told me that
Unknown symbol register_security
What should I do? How can I register a Linux Security Module?
Make sure newly loaded kernel is the one, which is compiled by you.
Check the Licence of your module (Ref: http://lists.jammed.com/linux-security-module/2004/08/0053.html)
In modern kernels register_security symbol does not exported. It means that you can't register LSM module as a module. But if you really wish to do that you can do that :) Look at the exported LSM-symbols like security_sb_copy_data. They are simple wrappers over the security_ops->some_lsm_method. So, you can use their code to determine security_ops pointer value. It needs disassembler though.
Unknown symbol register_security
Happened at the line that you unregister your LSM.
So add unregister_security() in security.c and export it:
/**
* unregister_security - allows security modules to be moved
* #ops : a pointer to the struct security_options that had been registered before.
*/
int unregister_security(struct security_operations *ops)
{
if (ops != security_ops)
{
printk (KERN_INFO "%s: trying to unregister "
"a security_opts structure that is not "
"registered, failing.\n", __FUNCTION__);
return -EINVAL;
}
security_ops = &dummy_security_ops;
return 0;
}
EXPORT_SYMBOL(unregister_security);
And recompiled the kernel.

What should I use on linux > 2.6.28 instead of __arch__swab32

I keep getting compilation error for a kernel module:
XXX: In function 'yyy':
ZZZ:125: error: implicit declaration of function '__arch__swab32'
PowerPC, 2.6.30.x, Kamikaze toolchain. According to this the identifier went away after 2.6.28. What should I use instead?
You should be using the generic __swab32 from linux/swab.h (which also exists on earlier kernel versions).

Resources