Check if a symbol is available, to prevent dlopen lazy binding failure - symbols

I load a .so library using dlopen(). The library calls myfunc(). The function is available in version 1.0 of the loader. So calling myfunc() works. In version 0.9 however, there is no myfunc(), and libdl shows error about lazy binding failure.
Can I, within the so. library, check if myfunc() exists, and only then call the function? The function is not mandatory, not important, I can safely skip calling it if loader is in version 0.9 or lower.

On and ELF platform, you can use weak unresolved reference to achieve your goal:
// libfoo.c
extern int myfunc() __attribute__((weak));
int foo()
{
if (&myfunc == NULL) {
printf("myfunc is not defined\n");
} else {
// myfunc is available, call it
printf ("myfunc returns %d\n", myfunc());
}
}

Related

Where is num's operator == defined in Dart?

When I run this code in my Android emulator, it prints the following.
void main() {
print(1 == 1.0); // true
print(identical(1, 1.0)); // false
}
I also read that the default implementation of == is identical. That means the operator == is overridden, however, when I went to num class to see its implementation, it shows the method is abstract.
bool operator ==(Object other);
So, I went to see its implementation in double and int classes but couldn't find anything there. So, where is that magic happening?
These are implemented at the native level and the Dart declarations are just an interface for these implementations. These implementations can be found at sdk/sdk/lib/_internal/ in the Dart sdk repository.
If you want to see the implementation in the VM you can go down to the vm/lib folder and find the double and integer implementations, which include the operators.
I'll use the VM implementation of integers as an example which defines the == operator and a method it uses:
#pragma("vm:recognized", "asm-intrinsic")
#pragma("vm:exact-result-type", bool)
#pragma("vm:never-inline")
bool operator ==(Object other) {
if (other is num) {
return other._equalToInteger(this);
}
return false;
}
#pragma("vm:recognized", "asm-intrinsic")
#pragma("vm:exact-result-type", bool)
bool _equalToInteger(int other) native "Integer_equalToInteger";
You can find the same for doubles and possibly something similar for the dart2js compiler. It's possible, however, that the JS compiler doesn't need a special definition because the defined behavior of the == operator of num seems to be identical to that of JS.

How to import zig modules dynamically?

I'm using zig 0.7.0. and I'm trying to import a list of zig source files from an array. Each source file has a main function (whose return type is !void) that I would like to call. The array module_names is known at compile time.
Here is what I tried to do:
const std = #import("std");
const log = std.log;
const module_names = [_][]const u8{
"01.zig", "02.zig", "03.zig", "04.zig", "05.zig",
};
pub fn main() void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
for (module_names) |module_name, i| {
const module = #import(module_name); // this fails
log.info("i {}", .{i});
try module.main();
}
}
Even if the array is known at compile time, #import(module_name) gives me this error:
./src/main.zig:13:32: error: unable to evaluate constant expression
const module = #import(module_name);
^
./src/main.zig:13:24: note: referenced here
const module = #import(module_name);
I could understand the error if the array would be dynamically generated and only known at runtime, but here the module_names array is known at compile time. So I am a bit confused...
Alternatively, I also tried to wrap the entire main body in a comptime block:
pub fn main() void {
comptime {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
for (module_names) |module_name, i| {
const module = #import(module_name); // no errors here
log.info("i {}", .{i});
try module.main();
}
}
}
Here #import(module_name) gives me no errors, but the log.info fails with this other error:
/home/jack/.zig/lib/zig/std/mutex.zig:59:87: error: unable to evaluate constant expression
if (#cmpxchgWeak(usize, &self.state, 0, MUTEX_LOCK, .Acquire, .Monotonic) != null)
^
/home/jack/.zig/lib/zig/std/mutex.zig:65:35: note: called from here
return self.tryAcquire() orelse {
^
/home/jack/.zig/lib/zig/std/log.zig:145:60: note: called from here
const held = std.debug.getStderrMutex().acquire();
^
/home/jack/.zig/lib/zig/std/log.zig:222:16: note: called from here
log(.info, scope, format, args);
^
./src/main.zig:26:21: note: called from here
log.info("i {}", .{i});
Is this kind of dynamic import possible in zig?
As of Zig 0.8.0, the operand to #import is required to be a string literal.
A Zig compiler wants to know all the possibly imported files so that it can eagerly go find them and compile them when you kick off a compilation process. The design of the language is constrained by making it possible for a fast compiler to exist.
So what can we do? I think this accomplishes the task in an equivalent manner:
const std = #import("std");
const log = std.log;
const modules = struct {
pub const module_01 = #import("01.zig");
pub const module_02 = #import("02.zig");
pub const module_03 = #import("03.zig");
pub const module_04 = #import("04.zig");
pub const module_05 = #import("05.zig");
};
pub fn main() void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
inline for (#typeInfo(modules).Struct.decls) |decl, i| {
const module = #field(modules, decl.name);
log.info("i {d}", .{i});
try module.main();
}
}
And the neat thing here is that, indeed, the compiler is able to eagerly fetch all 5 of those files and kick-start the compilation process, even before running the compile-time code to determine which one actually gets imported. Win-win.
I think the kind of import you're after is possible, my understanding is that #import is taking a zig source file and turning it into a struct type. It actually seems like something that could even be done at runtime (although not using #import, which wants a comptime parameter (this is the important part for your problem).
The reason why your first example fails is that the argument you're passing, module_name isn't known at comptime, your for loop won't execute until your program runs.
Your instinct to solve the problem is correct, get the loop to evaluate at compile time (specifically the capture value and iterator); I think there are two things you could do fix it.
Wrapping the loop in a comptime block as you have done will work, but you'll need to think about what exactly it means to evaluate expressions at compile time, and if it makes sense. I think the implementation of log will prevent you from logging at compile time, so you'd need to collect the values you're interested in inside the loop, and log them once outside the comptime block.
The other way you could fix it is to force the capture values of the loop to be evaluated at compile time by unrolling the loop using an inline for:
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
inline for (module_names) |module_name, i| {
const module = #import(module_name);
log.info("i {}", .{i});
try module.main();
}
}
Disclaimer: There might be a better way of doing this, I'm comparatively new to the language =D

pragma solidity - compilation error in jpmorganchase cakeshop

I am running a simple code from SimpleStorage example and just added few lines on top of it which I was using for my other contracts. The contract compiles fine from truffle. But on the Cakeshop Integrated IDE it shows compilation error.
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
contract SimpleStorage {
uint public storedData;
event Change(string message, uint newVal);
function SimpleStorage(uint initVal) {
Change("initialized", initVal);
storedData = initVal;
}
function set(uint x) {
Change("set", x);
storedData = x;
}
function get() constant returns (uint retVal) {
return storedData;
}
}
It should compile on the cakeshop web UI as it compiles on local machine
Utilizing Remix, it seems the following could be potential issues with your contract:
You are using the Contract name for the constructor. You should use the constructor keyword instead.
All of your functions are missing visibility modifiers. Consider adding the public modifier to each function including the constructor.
Events should be invoked using the emit keyword. Example: emit Change("set", x);

using llvm RecursiveASTVisitor for Objective C and iOS

I would like to use clang to preprocess objective C files from an iOS app. I looked over the source code and am trying to implement a pre-processor based on the RecursiveASTVisitor class. However, I seem to be running into many issues that I cannot resolve. I developed a preprocessor to add a "Enter" call at the beginning of each method and an "Exit" call at the end. I also added an "Exit" call before each return statement. I am using the following code to do the instrumentation:
class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
ASTContext *astContext; // used for getting additional AST info
std::string funcName;
public:
explicit ExampleVisitor(CompilerInstance *CI)
: astContext(&(CI->getASTContext())) // initialize private members
{
rewriter.setSourceMgr(astContext->getSourceManager(), astContext->getLangOpts());
}
virtual bool VisitObjCMethodDecl(ObjCMethodDecl *ND) {
funcName = ND->getDeclName().getAsString();
errs() << "Testing function: " << funcName << "\n";
if (ND->hasBody()) {
rewriter.InsertText(ND->getBody()->getSourceRange().getBegin().getLocWithOffset(1), "\nEnter(\""+funcName+"\");\n");
rewriter.InsertText(ND->getBody()->getSourceRange().getEnd(),"Exit(\""+funcName+"\");\n");
}
return true;
}
virtual bool VisitReturnStmt(ReturnStmt *ret) {
rewriter.InsertText(ret->getSourceRange().getBegin(), "\nExit(\""+funcName+"\");\n");
errs() << "** Rewrote ReturnStmt\n";
return true;
}
virtual ~ExampleVisitor() {}
};
class ExampleASTConsumer : public ASTConsumer {
private:
ExampleVisitor *visitor; // doesn't have to be private
public:
// override the constructor in order to pass CI
explicit ExampleASTConsumer(CompilerInstance *CI)
: visitor(new ExampleVisitor(CI)) // initialize the visitor
{ }
// override this to call our ExampleVisitor on the entire source file
virtual void HandleTranslationUnit(ASTContext &Context) {
/* we can use ASTContext to get the TranslationUnitDecl, which is
a single Decl that collectively represents the entire source file */
visitor->TraverseDecl(Context.getTranslationUnitDecl());
}
};
The code compiles. I created a command line executable "instrument". I then used the following command to run this on a simple Objective C program generated by Xcode:
instrument AppDelegate.m --
I run into two problems. First, I get the error: 'UIKit/UIKit.h' file not found. This is one of the includes generated by Xcode. Second, I'm seeing only some of the return statements being processed in the file. Can someone give me some insights into what is happening?
I'm using the 3.7.0 version of llvm.

How to prevent function return result declaratively?

Assume such conditions:
Some operation does not provide possibility of returning the result.
This operation declared as callback
Using typedef not recommended
Some operation provide of returning the result.
This operation declared as callback
Using typedef not recommended
Assume such scenario:
void main() {
executeVoidOperation(methodNonVoid); // Must throw if method void?
executeNonVoidOperation(methodVoid); // Must throw if method non-void?
}
int methodNonVoid() {
return 0;
}
void methodVoid() {
}
void executeVoidOperation(void operation()) {
operation(); // Must throw if method non-void?
}
void executeNonVoidOperation(dynamic operation()) {
var result = operation(); // Must throw if method void?
print(result); // Result of void operation? (if such passed as argument)
}
Displayed results:
null
Questions (where I wrong?):
Null is object. From where this null appeared (as result) if void function cannot return result (even null)?
Functions with different return types in Dart assumed as the same (not conflicting) types?
How in Dart called this function transformations?
executeNonVoidOperation(methodVoid); works because the callback is defined as dynamic operation(). dynamic can be anything, including void. It's the same as if you just don't specify a type.
The null value stems from a simple rule in Dart. Quoted from the Dart Language Tour:
All functions return a value. If no return value is specified, the statement return null; is implicitly appended to the function body.
That means that every void method always returns null. If you try to return something else, you'll get a runtime error (in checked mode).
executeVoidOperation(methodNonVoid); is a bit more tricky - I'd expect it to throw a runtime error, but it seems the callback is treated as dynamic operation() instead of void operation(). Dart Editor's analyzer seems to think that, too. This may be either a bug or a design choice by the Dart team.

Resources