How can I have atos print mangled names? - ios

I'm running atos to symbolicate addresses using -arch arm64 -o MyApp -s <slide> -f <symbol file>. However, it prints lines like type metadata accessor for GradientView (in MyApp) (<compiler-generated>:0). I'd like it to print the mangled name instead, e.g. _$s22FeatureImpl12LanguageCellC19GradientViewSo012GradientI0CvpACTk. I need this for various reasons, including to pass to an order file for the linker. Is there any way to do this with atos?

I've found a workaround without atos. I can use the private CoreSymbolication framework directly:
#import <Foundation/Foundation.h>
#include <stdint.h>
#include <mach/machine.h>
#include <mach-o/arch.h>
#include <architecture/byte_order.h>
struct sCSTypeRef {
void* csCppData; // typically retrieved using CSCppSymbol...::data(csData & 0xFFFFFFF8)
void* csCppObj; // a pointer to the actual CSCppObject
};
typedef struct sCSTypeRef CSTypeRef;
typedef CSTypeRef CSSymbolicatorRef;
typedef CSTypeRef CSSourceInfoRef;
typedef CSTypeRef CSSymbolOwnerRef;
typedef CSTypeRef CSSectionRef;
typedef CSTypeRef CSSegmentRef;
typedef CSTypeRef CSSymbolRef;
typedef CSTypeRef CSRegionRef;
typedef CSTypeRef CSUUIDRef;
CSSymbolicatorRef CSSymbolicatorCreateWithURLAndArchitecture(CFURLRef url, cpu_type_t type);
CSSymbolRef CSSymbolicatorGetSymbolWithAddressAtTime(CSSymbolicatorRef cs, vm_address_t addr, uint64_t time);
const char* CSSymbolGetMangledName(CSSymbolRef sym);
int main(int argc, const char * argv[]) {
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/path/to/dSYM/binary"), kCFURLPOSIXPathStyle, false);
CSSymbolicatorRef cs = CSSymbolicatorCreateWithURLAndArchitecture(url, 16777228 /* arm64 cputype */);
int slide = ...;
ptrdiff_t addr = ...;
CSSymbolRef sym = CSSymbolicatorGetSymbolWithAddressAtTime(cs, addr - slide, 0);
const char *name = CSSymbolGetMangledName(sym);
printf("%s\n", name);
return 0;
}
https://github.com/mountainstorm/CoreSymbolication/blob/master/CoreSymbolication/CoreSymbolication.h provided the prototypes

Related

How to use LLVM's SanitizerCoverage code coverage instrumentation with a shared library?

I have a shared library linked to an executable for which I would like to have code coverage instrumentation using custom _sanitizer_cov_trace_pc* functions.
library.cc
#include <stdio.h>
void so_function() {
printf("SO function.");
}
callbacks.cc
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
static uint64_t N;
if (start == stop || *start) return;
printf("INIT: %p %p\n", start, stop);
for (uint32_t *x = start; x < stop; x++)
*x = ++N;
}
extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
if (!*guard) return;
void *PC = __builtin_return_address(0);
char PcDescr[1024];
__sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));
printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
}
main.cc
#include <stdio.h>
void so_function();
int main(int argc, char **argv) {
so_function();
}
I compiled the library using clang's -fsanitize-coverage=trace-pc-guard into position-independent code (-fPIC) and then I created the shared library using both the resulted object file and callbacks.cc using -fsanitize=address.
I compiled main.cc and linked it with the shared library but it seems like these 2 custom __sanitizer_cov_trace_pc_guard* functions don't get called.
I would like have code coverage instrumentation using these 2 functions only for the shared library, and not for the main executable.

JNA to Go DLL - How do I get String returned from Go Func?

I have a Java program that is using JNA to call a Go Func. Here's the Interface to the Go func in Java:
public interface GPG extends Library {
// GoString class maps to: C type struct { const char *p; GoInt n; }
public class GoString extends Structure {
public static class ByValue extends GoString implements Structure.ByValue {}
public String p;
public long n;
protected List getFieldOrder(){
return Arrays.asList(new String[]{"p","n"});
}
}
// Foreign functions
public GoString.ByValue decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
}
The func signature in Go is:
func decrypt(encString string, secretKeyring string, passphrase string) string
The Go generated C header has:
/* Created by "go tool cgo" - DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
typedef _GoString_ GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern GoString decrypt(GoString p0, GoString p1, GoString p2);
#ifdef __cplusplus
}
#endif
I call the Go Func from Java using this code:
GPG gpg = (GPG) Native.loadLibrary("C:/lib/gpg.dll", GPG.class);
GPG.GoString.ByValue encString = new GPG.GoString.ByValue();
encString.p = value;
encString.n = encString.p.length();
GPG.GoString.ByValue secretKeyring = new GPG.GoString.ByValue();
secretKeyring.p = "c:/gnupg/secring.gpg";
secretKeyring.n = secretKeyring.p.length();
GPG.GoString.ByValue passphrase = new GPG.GoString.ByValue();
passphrase.p = "SecretPassPhrase";
passphrase.n = passphrase.p.length();
GPG.GoString.ByValue decValue = gpg.decrypt(encString, secretKeyring, passphrase);
Clearly the func is being called and processes up to the return of the result string. But it then produces: "panic: runtime error: cgo result has Go pointer"
How do I get a String result back from Go?
Using go version go1.10 windows/amd64, JNA 4.5.1, Java 1.8.0_152
Your GO function should looks like this:
//export decrypt
func decrypt(encString string, secretKeyring string, passphrase string) *C.char {
//... your code here
var str string = "returning string"
return C.CString(str)
}
Java Interface:
public String decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
Your const char * in _GoString_ should use a Pointer instead, then use Pointer.getString() with the provided offset to obtain the actual string.
If Go itself is rejecting a string return value, you'll likely have to instead populate a buffer provided by the caller.

Neighbor discovery in contiki

Actually i dont know how to deal with neighbor_recv function. I am not receiving any packet, as was receiving in broadcast-example. All values used in this code are randomly initialized. Moreover I want to store neighbor of each node. Currently I am having 3 telosb motes.
#include "contiki.h"
#include "net/rime/rime.h"
#include "random.h"
#include "node-id.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
#include <stdio.h>
struct adv_msg {
uint16_t val;
};
/*------------------------------------------------------------------------ ---*/
PROCESS(neighbor_process, "Neighbor example");
AUTOSTART_PROCESSES(&neighbor_process);
/*------------------------------------------------------------------------ ---*/
static void
neighbor_recv(struct neighbor_discovery_conn *c, const linkaddr_t *from)
{
printf("message received from %d.%d: '%s'\n",
from->u8[0], from->u8[1], (char *)packetbuf_dataptr());
}
static const struct neighbor_discovery_callbacks cb ={neighbor_recv};
static struct neighbor_discovery_conn neighbor;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(neighbor_process, ev, data)
{
static struct etimer et;
clock_time_t initial=0;// randomly initialize these values
clock_time_t min=0;
clock_time_t max=10;
uint16_t val=108;
PROCESS_EXITHANDLER(neighbor_discovery_close(&neighbor));
PROCESS_BEGIN();
neighbor_discovery_open(&neighbor, 129,initial,min,max,&cb);
while(1) {
/* Delay 2-4 seconds */
etimer_set(&et, CLOCK_SECOND * 4 + random_rand() % (CLOCK_SECOND * 4));
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
packetbuf_copyfrom("Hello", 5);
neighbor_discovery_set_val(&neighbor,val);
neighbor_discovery_start(&neighbor,val);
printf("message sent\n");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

About the parameter of function pthread_create?

We know that we call pthread like this:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void* arg);
Hi guys, i want to know why the return type of third parameter is void*? why not void?
Because there is no way for a start function to know what kind of data a developer wants to return from the function they use a void* that can point to any type. It is up to the developer of the start function to then cast the void* to appropriate type he actually returned before using whatever the void* points to. So now the start function can return a pointer that may in actually point to anything. If the start function is declared to return void, it means this function returns nothing, then what if the developer wants the start function to return a int, a struct? For example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
struct test {
char str[32];
int x;
};
void *func(void*) {
struct test *eg = (struct test *)malloc(sizeof(struct test));
strcpy(eg->str,"hello world");
eg->x = 42;
pthread_exit(eg);
}
int main (void) {
pthread_t id;
struct test *resp;
pthread_create(&id, NULL, func, NULL);
pthread_join(id,(void**)&resp);
printf("%s %d\n",resp->str,resp->x);
free(resp);
return 0;
}
More details on this post: What does void* mean and how to use it?

Using C header and implementation files in Xcode iOS project

I'm trying to use a separate C header and implementation file in Xcode iOS/Objective-C project.
I want to use the method I implemented in main.m but I get these errors:
Full size here
I've included user.h in main.m
Note that Target Membership is selected in user.c for HelloWorld. When I deselect this the errors are gone. But when I try to run the app, I get these errors at compile time:
Full size here
When I implement the struct and method in main.m it compiles and runs just fine. But I don't get it why I can't use this particular code in a separate file?
Source Code:
user.h
#ifndef HelloWorld_user_h
#define HelloWorld_user_h
typedef struct {
char *name;
int age;
char sex;
} User; //sizeof(User) = 16 bytes
void CreateAndDisplay(User *usr, char *name, int age, char sex);
#endif
user.c
#include <stdio.h>
#include <stdlib.h>
void CreateAndDisplay(User *usr, char *name, int age, char sex) {
usr->name = name;
usr->age = age;
usr->sex = sex;
printf("User address -> value:\n");
printf("Name:\t%u\t->\t%s\n", (uint)usr, *&usr->name);
printf("Age:\t%u\t->\t%i\n", (uint)&usr->age, *&usr->age);
printf("Sex:\t%u\t->\t%c\n\n", (uint)&usr->sex, *&usr->sex);
printf("User has a size of %li bytes in memory", sizeof(*usr));
}
main.m
#import <UIKit/UIKit.h>
#import "HelloWorldAppDelegate.h"
#include <stdio.h>
#include <stdlib.h>
#include "user.h"
int main(int argc, char *argv[])
{
User user1;
CreateAndDisplay(&user1, "John Doe", 24, 'm');
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([HelloWorldAppDelegate class]));
}
}
These errors are because there are two types referenced in user.c that haven't been declared in headers that it imports: User (defined in user.h) and uint (defined in <sys/types.h>). To resolve these errors, inside user.c you should add the following includes:
#include "user.h"
#include <sys/types.h>
Try to include user.h in user.c, like you include stdio.h.

Resources