I have a bunch of .O files that I generated from a makefile.u which compiles some .C files. I put all of the .O files into my Xcode project and I receive the below error when it builds:
duplicate symbol '_main' in:
/Users/.../Objects-normal/arm64/AppDelegate.o
/Users/.../LIBF2C/main.o
ld: 1 duplicate symbol for architecture arm64
I think I am bit confused because the main.o file is needed for my library, but the error seems to be telling me that I cannot have _main declared twice. So is there a solution for this, am I supposed to rename something to get it to build or any other ideas for how this can get resolved?
For some added context, this is specifically for the f2c libraries. So main.c(->main.o) from libf2c is:
/* STARTUP PROCEDURE FOR UNIX FORTRAN PROGRAMS */
#include "stdio.h"
#include "signal1.h"
#ifndef SIGIOT
#ifdef SIGABRT
#define SIGIOT SIGABRT
#endif
#endif
#ifndef KR_headers
#undef VOID
#include "stdlib.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif
#ifndef VOID
#define VOID void
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef NO__STDC
#define ONEXIT onexit
extern VOID f_exit();
#else
#ifndef KR_headers
extern void f_exit(void);
#ifndef NO_ONEXIT
#define ONEXIT atexit
extern int atexit(void (*)(void));
#endif
#else
#ifndef NO_ONEXIT
#define ONEXIT onexit
extern VOID f_exit();
#endif
#endif
#endif
#ifdef KR_headers
extern VOID f_init(), sig_die();
extern int MAIN__();
#define Int /* int */
#else
extern void f_init(void), sig_die(const char*, int);
extern int MAIN__(void);
#define Int int
#endif
static VOID sigfdie(Sigarg)
{
Use_Sigarg;
sig_die("Floating Exception", 1);
}
static VOID sigidie(Sigarg)
{
Use_Sigarg;
sig_die("IOT Trap", 1);
}
#ifdef SIGQUIT
static VOID sigqdie(Sigarg)
{
Use_Sigarg;
sig_die("Quit signal", 1);
}
#endif
static VOID sigindie(Sigarg)
{
Use_Sigarg;
sig_die("Interrupt", 0);
}
static VOID sigtdie(Sigarg)
{
Use_Sigarg;
sig_die("Killed", 0);
}
#ifdef SIGTRAP
static VOID sigtrdie(Sigarg)
{
Use_Sigarg;
sig_die("Trace trap", 1);
}
#endif
int xargc;
char **xargv;
#ifdef __cplusplus
}
#endif
int
#ifdef KR_headers
main(argc, argv) int argc; char **argv;
#else
main(int argc, char **argv)
#endif
{
xargc = argc;
xargv = argv;
signal1(SIGFPE, sigfdie); /* ignore underflow, enable overflow */
#ifdef SIGIOT
signal1(SIGIOT, sigidie);
#endif
#ifdef SIGTRAP
signal1(SIGTRAP, sigtrdie);
#endif
#ifdef SIGQUIT
if(signal1(SIGQUIT,sigqdie) == SIG_IGN)
signal1(SIGQUIT, SIG_IGN);
#endif
if(signal1(SIGINT, sigindie) == SIG_IGN)
signal1(SIGINT, SIG_IGN);
signal1(SIGTERM,sigtdie);
#ifdef pdp11
ldfps(01200); /* detect overflow as an exception */
#endif
f_init();
#ifndef NO_ONEXIT
ONEXIT(f_exit);
#endif
MAIN__();
#ifdef NO_ONEXIT
f_exit();
#endif
exit(0); /* exit(0) rather than return(0) to bypass Cray bug */
return 0; /* For compilers that complain of missing return values; */
/* others will complain that this is unreachable code. */
}
#ifdef __cplusplus
}
#endif
Related
I have a simple code that creates a simple layer 3 interface using the Wintun library. I want to read and write packets to this interface from a different process. While I'm able to read packets from this interface using Winsock, I'm unable to write packets to the interface using either Winsock/npcap. The only solution that worked is using the WintunSendPacket method from their library. But this method takes the Session variable as a parameter. Things that I've tried till now:-
Tried to inject packet to the interface using npcap
Attempted to create a new session variable using the Adapter obtained by using the WintunOpenAdapter function. (Results in error)
Tried to write the Session variable into a mmap using CreateFileMappingA and MapViewOfFile functions.
None of the solutions seems to be yielding any results. Any help would be much appreciated.
interface.c (gcc -I include/ interface.c -lwsock32 -lWs2_32 -liphlpapi -o interface)
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
*/
// gcc -I include/ example.c -lwsock32 -lWs2_32 -liphlpapi
#include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <in6addr.h>
#include <winternl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sal.h>
#include <winerror.h>
#include <netioapi.h>
#include <stdint.h>
#if !defined(_Must_inspect_result_)
#define _Must_inspect_result_
#endif
#if !defined(_Return_type_success_)
#define _Return_type_success_(x)
#endif
#if !defined(_Post_writable_byte_size_)
#define _Post_writable_byte_size_(x)
#endif
#if !defined(_In_reads_bytes_)
#define _In_reads_bytes_(x)
#endif
#if !defined(_Out_writes_bytes_all_)
#define _Out_writes_bytes_all_(x)
#endif
#if !defined(LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
#endif
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#include "wintun.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
static WINTUN_CREATE_ADAPTER_FUNC *WintunCreateAdapter;
static WINTUN_CLOSE_ADAPTER_FUNC *WintunCloseAdapter;
static WINTUN_OPEN_ADAPTER_FUNC *WintunOpenAdapter;
static WINTUN_GET_ADAPTER_LUID_FUNC *WintunGetAdapterLUID;
static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC *WintunGetRunningDriverVersion;
static WINTUN_DELETE_DRIVER_FUNC *WintunDeleteDriver;
static WINTUN_SET_LOGGER_FUNC *WintunSetLogger;
static WINTUN_START_SESSION_FUNC *WintunStartSession;
static WINTUN_END_SESSION_FUNC *WintunEndSession;
static WINTUN_GET_READ_WAIT_EVENT_FUNC *WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC *WintunReceivePacket;
static WINTUN_RELEASE_RECEIVE_PACKET_FUNC *WintunReleaseReceivePacket;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC *WintunAllocateSendPacket;
static WINTUN_SEND_PACKET_FUNC *WintunSendPacket;
WINTUN_ADAPTER_HANDLE Adapter;
WINTUN_SESSION_HANDLE Session;
HMODULE Wintun;
static HMODULE InitializeWintun(void)
{
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun)
return NULL;
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
X(WintunAllocateSendPacket) || X(WintunSendPacket))
#undef X
{
DWORD LastError = GetLastError();
FreeLibrary(Wintun);
SetLastError(LastError);
return NULL;
}
return Wintun;
}
static void showError()
{
wchar_t err[256];
memset(err, 0, 256);
printf("%ld\n", GetLastError());
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
int msgboxID = MessageBoxW(NULL,
err,
(LPCWSTR)L"☠",
MB_OK);
}
void handleCleanup()
{
WintunEndSession(Session);
WintunCloseAdapter(Adapter);
FreeLibrary(Wintun);
exit(0);
}
BOOL WINAPI consoleHandler(DWORD signal)
{
if (signal == CTRL_C_EVENT)
{
handleCleanup();
}
return TRUE;
}
int main()
{
DWORD LastError;
GUID ExampleGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
DWORD Version;
MIB_UNICASTIPADDRESS_ROW AddressRow;
Wintun = InitializeWintun();
if (!Wintun)
{
printf("Failed to initialize wintun\n");
showError();
}
Adapter = WintunCreateAdapter(L"Sclera", L"Wintun", &ExampleGuid);
if (!Adapter)
{
showError();
handleCleanup();
}
InitializeUnicastIpAddressEntry(&AddressRow);
WintunGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
AddressRow.Address.Ipv4.sin_family = AF_INET;
AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((10 << 24) | (10 << 16) | (10 << 8) | (9 << 0));
AddressRow.OnLinkPrefixLength = 24;
AddressRow.DadState = IpDadStatePreferred;
LastError = CreateUnicastIpAddressEntry(&AddressRow);
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS)
{
showError();
handleCleanup();
}
Session = WintunStartSession(Adapter, WINTUN_MAX_RING_CAPACITY);
if (!Session)
{
showError();
handleCleanup();
}
HANDLE hMap = CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(WINTUN_SESSION_HANDLE),
"ScleraSessionStruct");
WINTUN_SESSION_HANDLE *sharedSession = (WINTUN_SESSION_HANDLE *)MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (sharedSession == NULL)
{
showError();
}
{
Sleep(INT32_MAX);
}
}
main.c (gcc -I include/ main.c -lwsock32 -lWs2_32 -liphlpapi -o main)
#include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <in6addr.h>
#include <winternl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sal.h>
#include <winerror.h>
#include <netioapi.h>
#include <stdint.h>
#if !defined(_Must_inspect_result_)
#define _Must_inspect_result_
#endif
#if !defined(_Return_type_success_)
#define _Return_type_success_(x)
#endif
#if !defined(_Post_writable_byte_size_)
#define _Post_writable_byte_size_(x)
#endif
#if !defined(_In_reads_bytes_)
#define _In_reads_bytes_(x)
#endif
#if !defined(_Out_writes_bytes_all_)
#define _Out_writes_bytes_all_(x)
#endif
#if !defined(LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
#endif
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#include "wintun.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
static WINTUN_CREATE_ADAPTER_FUNC *WintunCreateAdapter;
static WINTUN_CLOSE_ADAPTER_FUNC *WintunCloseAdapter;
static WINTUN_OPEN_ADAPTER_FUNC *WintunOpenAdapter;
static WINTUN_GET_ADAPTER_LUID_FUNC *WintunGetAdapterLUID;
static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC *WintunGetRunningDriverVersion;
static WINTUN_DELETE_DRIVER_FUNC *WintunDeleteDriver;
static WINTUN_SET_LOGGER_FUNC *WintunSetLogger;
static WINTUN_START_SESSION_FUNC *WintunStartSession;
static WINTUN_END_SESSION_FUNC *WintunEndSession;
static WINTUN_GET_READ_WAIT_EVENT_FUNC *WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC *WintunReceivePacket;
static WINTUN_RELEASE_RECEIVE_PACKET_FUNC *WintunReleaseReceivePacket;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC *WintunAllocateSendPacket;
static WINTUN_SEND_PACKET_FUNC *WintunSendPacket;
static HMODULE InitializeWintun(void)
{
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun)
return NULL;
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
X(WintunAllocateSendPacket) || X(WintunSendPacket))
#undef X
{
DWORD LastError = GetLastError();
FreeLibrary(Wintun);
SetLastError(LastError);
return NULL;
}
return Wintun;
}
static void showError()
{
wchar_t err[256];
memset(err, 0, 256);
printf("%ld\n", GetLastError());
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
int msgboxID = MessageBoxW(NULL,
err,
(LPCWSTR)L"☠",
MB_OK);
}
int main()
{
WINTUN_ADAPTER_HANDLE Adapter;
WINTUN_SESSION_HANDLE Session;
HMODULE Wintun = InitializeWintun();
if (!Wintun)
{
printf("Failed to initialize wintun\n");
showError();
}
printf("Wintun initialized successfully....\n");
Adapter = WintunOpenAdapter(L"Sclera");
if (!Adapter)
{
showError();
}
printf("Adapter opened successfully....\n");
HANDLE hMap = CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READONLY,
0,
sizeof(WINTUN_SESSION_HANDLE),
"ScleraSessionStruct");
WINTUN_SESSION_HANDLE *sharedSession = (WINTUN_SESSION_HANDLE *)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (sharedSession == NULL)
{
showError();
}
else
{
printf("Wintun session variable obtained my nigga!\n");
}
printf("Session started successfully\n");
{
Sleep(INT32_MAX);
}
return 1;
}
The idea is that there will be multiple instances of the main.c code running and they will be reading/writing packets from the Wintun interface.
Note: Both programs have to be run in administrator mode
I want to update value of a variable at run time, present in project configuration as per some condition. But currently I am getting this error:
error: lvalue required as left operand of assignment
Actual code:
#include "contiki.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
static void update_project_conf_value(void)
{
printf("Original Value: %d\n",TEST_VALUE);
TEST_VALUE = 0;
printf("After update: %d\n",TEST_VALUE);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_BEGIN();
update_project_conf_value();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
Project configuration:
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#define TEST_VALUE 1
/*---------------------------------------------------------------------------*/
#endif /* PROJECT_CONF_H_ */
/*---------------------------------------------------------------------------*/
Note: I want to update it in one of file as per some condition and then use the updated value in a different file.
First off, TEST_VALUE is a macro. You can read it but you can not write to it. It will also disappear at runtime.
What you really want is a global variable.
In the header put something like this:
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
int g_TEST_VALUE; // Declaration
/*---------------------------------------------------------------------------*/
#endif /* PROJECT_CONF_H_ */
/*---------------------------------------------------------------------------*/
in your source put something like this:
#include "contiki.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
extern int g_TEST_VALUE = 1; // Definition
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
static void update_project_conf_value(void)
{
printf("Original Value: %d\n",TEST_VALUE);
g_TEST_VALUE = 0;
printf("After update: %d\n",TEST_VALUE);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_BEGIN();
update_project_conf_value();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
I am trying to create a ContikiOS firmware that acts as a gateway using Rime and REST. The gateway must communicate to other motes with the Rime mesh, and can communicate to the outside via a REST API.
The following code is a combination from two default Contiki examples (rest-example/rest-server-example.c and rime/example-mesh.c). Therefore I include "rest.h", "net/rime.h", "net/rime/mesh.h".
The problem is when I try to compile this firmware using following makefile, the rime files don't get included into obj_sky and any Rime functions I use in the firmware get an 'undefined reference' error. However when I remove the lines in the makefile and any code referring to REST in the firmware code, it does compile (and adds the rime files to obj_sky).
Would anyone have an idea why rime does not get added after adding the rest-http app and what I can do to have it compile?
Thank you
Code
Compiler info
> make gateway.sky TARGET=sky
CC gateway.c
CC ../../platform/sky/./contiki-sky-main.c
LD gateway.sky
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: gateway.sky section `.data' will not fit in region `rom'
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: section .vectors loaded at [000000000000ffe0,000000000000ffff] overlaps section .data loaded at [000000000000ff0c,0000000000010037]
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: region `rom' overflowed by 88 bytes
gateway.co: In function `process_thread_init_mesh':
gateway.c:(.text.process_thread_init_mesh+0x10): undefined reference to `mesh_close'
gateway.c:(.text.process_thread_init_mesh+0x26): undefined reference to `mesh_open'
gateway.co: In function `recv':
gateway.c:(.text.recv+0x48): undefined reference to `mesh_send'
gateway.co: In function `enable_handler':
gateway.c:(.text.enable_handler+0x80): undefined reference to `mesh_send'
collect2: ld returned 1 exit status
../../Makefile.include:254: recipe for target 'gateway.sky' failed
Process returned error code 2
make: *** [gateway.sky] Error 1
rm obj_sky/contiki-sky-main.o gateway.co
Makefile
all: gateway mote
ifndef TARGET
TARGET=sky
endif
CONTIKI=../..
WITH_UIP6=1
UIP_CONF_IPV6=1
WITH_COAP = 0
APPS += rest-http
include $(CONTIKI)/Makefile.include
Lines to compile for REST
WITH_UIP6=1
UIP_CONF_IPV6=1
WITH_COAP = 0
APPS += rest-http
gateway.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "contiki-net.h"
#include "rest.h"
#include "net/rime.h"
#include "net/rime/mesh.h"
#if defined (PLATFORM_HAS_LIGHT)
#include "dev/light-sensor.h"
#endif
#if defined (PLATFORM_HAS_BATT)
#include "dev/battery-sensor.h"
#endif
#if defined (PLATFORM_HAS_SHT11)
#include "dev/sht11-sensor.h"
#endif
#if defined (PLATFORM_HAS_LEDS)
#include "dev/leds.h"
#endif
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(addr)
#endif
#define MESSAGE "Hello"
/*---------------------------------------------------------------------------*/
/*---------------------------------RIME--------------------------------------*/
/*---------------------------------------------------------------------------*/
static struct mesh_conn mesh;
PROCESS(init_mesh, "RIME Mesh");
/*---------------------------------------------------------------------------*/
static void
sent(struct mesh_conn *c)
{
printf("packet sent\n");
}
static void
timedout(struct mesh_conn *c)
{
printf("packet timedout\n");
}
static void
recv(struct mesh_conn *c, const rimeaddr_t *from, uint8_t hops)
{
printf("Data received from %d.%d: %.*s (%d)\n",
from->u8[0], from->u8[1],
packetbuf_datalen(), (char *)packetbuf_dataptr(), packetbuf_datalen());
packetbuf_copyfrom(MESSAGE, strlen(MESSAGE));
mesh_send(&mesh, from);
}
static void
send(int to, char * msg)
{
printf("Sending data to %d", to);
rimeaddr_t addr;
packetbuf_copyfrom(msg, strlen(msg));
addr.u8[0] = to;
addr.u8[1] = 0;
mesh_send(&mesh, &addr);
}
const static struct mesh_callbacks callbacks = {recv, sent, timedout};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(init_mesh, ev, data)
{
PROCESS_EXITHANDLER(mesh_close(&mesh);)
PROCESS_BEGIN();
mesh_open(&mesh, 132, &callbacks);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/*----------------------------------REST-------------------------------------*/
/*---------------------------------------------------------------------------*/
RESOURCE(enable, METHOD_GET, "enable");
void
enable_handler(REQUEST* request, RESPONSE* response)
{
int moteId = 0;
char moteIdstr[12];
sprintf(moteIdstr, "%d", moteId);
char command[20];
char responseText[255];
if (rest_get_query_variable(request, "moteId", moteIdstr, 10)) {
PRINTF("moteId %s\n", moteIdstr);
send(moteId, command);
sprintf(responseText,"Command execute for mote %s!\n", moteIdstr);
} else {
sprintf(responseText,"Mote not available!\n");
}
rest_set_header_content_type(response, TEXT_PLAIN);
rest_set_response_payload(response, (uint8_t*)responseText, strlen(responseText));
}
PROCESS(gateway_rest, "Gateway Rest");
PROCESS_THREAD(gateway_rest, ev, data)
{
PROCESS_BEGIN();
#ifdef WITH_COAP
PRINTF("COAP Server\n");
#else
PRINTF("HTTP Server\n");
#endif
rest_init();
rest_activate_resource(&resource_enable);
//rest_activate_resource(&resource_disable);
PROCESS_END();
}
/*---------------*/
AUTOSTART_PROCESSES(&init_mesh, &gateway_rest);
Info
I am using Sky motes to compile the code in Cooja.
I have 4 files in the following example ; a header, a default implementation file, and 2 platform-specific implementation files.I define two functions; get_value_1 and get_value_2. The 'default' behavior is to return -1, but some of these functions have special implementations. I would like each function to return -1 only if another file didn't implement it.
/* interface.h *
***************/
int get_value_1();
int get_value_2();
/* default.c *
*************/
#include "interface.h"
#ifndef GET_VALUE_1
int get_value_1() { return -1; }
#endif
#ifndef GET_VALUE_2
int get_value_2() { return -1; }
#endif
/* platform1.c *
***************/
#include "interface.h"
#ifndef GET_VALUE_1
#define GET_VALUE_1
int get_value_1() { return 1; }
#endif
/* platform2.c *
***************/
#include "interface.h"
#ifndef GET_VALUE_2
#define GET_VALUE_2
int get_value_2() { return 2; }
#endif
But when I run the command gcc default.c platform1.c -shared -fpic -o platform1.so, it tells me that I've multiply defined the get_value_1 function, and that it was originally defined in platform1.c.
So how can I have a set of functions where a subset of those functions can have their behavior chosen at compile time?
make them weak in the default.c and "normal" in your platform files. So if the platform.c file implements this function as not weak, the weak one dfrom default.c will be replaced link time.
It is not the part of the standard but most compilers support it (it can be pragma, attribute or something else - you need to check in the compiler documentation)
gcc version:
#define __weak __attribute__((weak))
/* interface.h *
***************/
int get_value_1();
int get_value_2();
/* default.c *
*************/
#include "interface.h"
#ifndef GET_VALUE_1
__weak int get_value_1() { return -1; }
#endif
#ifndef GET_VALUE_2
__weak int get_value_2() { return -1; }
#endif
/* platform1.c *
***************/
#include "interface.h"
#ifndef GET_VALUE_1
#define GET_VALUE_1
int get_value_1() { return 1; }
#endif
/* platform2.c *
***************/
#include "interface.h"
#ifndef GET_VALUE_2
#define GET_VALUE_2
int get_value_2() { return 2; }
#endif
My question is somewhat different from others that have asked about fault addresses. I'm trying to implement a horrible hack to determine, from a signal handler, whether the signal interrupted a syscall or ordinary user code by inspecting the code at the saved instruction pointer and comparing it against the possible syscall entry instructions for the host architecture it's running on. This is part of implementing correct POSIX thread cancellation that does not suffer from the race condition and resource leak described in my old question:
How are POSIX cancellation points supposed to behave?
If this approach is unreliable or otherwise wrong, I'd also like to hear reasons.
/* sigsegv.c */
/**
* This source file is used to print out a stack-trace when your program
* segfaults. It is relatively reliable and spot-on accurate.
*
* This code is in the public domain. Use it as you see fit, some credit
* would be appreciated, but is not a prerequisite for usage. Feedback
* on it's use would encourage further development and maintenance.
*
* Due to a bug in gcc-4.x.x you currently have to compile as C++ if you want
* demangling to work.
*
* Please note that it's been ported into my ULS library, thus the check for
* HAS_ULSLIB and the use of the sigsegv_outp macro based on that define.
*
* Author: Jaco Kroon <jaco#kroon.co.za>
*
* Copyright (C) 2005 - 2010 Jaco Kroon
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
/* Bug in gcc prevents from using CPP_DEMANGLE in pure "C" */
#if !defined(__cplusplus) && !defined(NO_CPP_DEMANGLE)
#define NO_CPP_DEMANGLE
#endif
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <ucontext.h>
#include <dlfcn.h>
#ifndef NO_CPP_DEMANGLE
#include <cxxabi.h>
#ifdef __cplusplus
using __cxxabiv1::__cxa_demangle;
#endif
#endif
#ifdef HAS_ULSLIB
#include "uls/logger.h"
#define sigsegv_outp(x) sigsegv_outp(,gx)
#else
#define sigsegv_outp(x, ...) fprintf(stderr, x "\n", ##__VA_ARGS__)
#endif
#if defined(REG_RIP)
# define SIGSEGV_STACK_IA64
# define REGFORMAT "%016lx"
#elif defined(REG_EIP)
# define SIGSEGV_STACK_X86
# define REGFORMAT "%08x"
#else
# define SIGSEGV_STACK_GENERIC
# define REGFORMAT "%x"
#endif
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};
int i, f = 0;
ucontext_t *ucontext = (ucontext_t*)ptr;
Dl_info dlinfo;
void **bp = 0;
void *ip = 0;
sigsegv_outp("Segmentation Fault!");
sigsegv_outp("info.si_signo = %d", signum);
sigsegv_outp("info.si_errno = %d", info->si_errno);
sigsegv_outp("info.si_code = %d (%s)", info->si_code, si_codes[info->si_code]);
sigsegv_outp("info.si_addr = %p", info->si_addr);
for(i = 0; i < NGREG; i++)
sigsegv_outp("reg[%02d] = 0x" REGFORMAT, i, ucontext->uc_mcontext.gregs[i]);
#ifndef SIGSEGV_NOSTACK
#if defined(SIGSEGV_STACK_IA64) || defined(SIGSEGV_STACK_X86)
#if defined(SIGSEGV_STACK_IA64)
ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
#elif defined(SIGSEGV_STACK_X86)
ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
#endif
sigsegv_outp("Stack trace:");
while(bp && ip) {
if(!dladdr(ip, &dlinfo))
break;
const char *symname = dlinfo.dli_sname;
#ifndef NO_CPP_DEMANGLE
int status;
char * tmp = __cxa_demangle(symname, NULL, 0, &status);
if (status == 0 && tmp)
symname = tmp;
#endif
sigsegv_outp("% 2d: %p <%s+%lu> (%s)",
++f,
ip,
symname,
(unsigned long)ip - (unsigned long)dlinfo.dli_saddr,
dlinfo.dli_fname);
#ifndef NO_CPP_DEMANGLE
if (tmp)
free(tmp);
#endif
if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
break;
ip = bp[1];
bp = (void**)bp[0];
}
#else
sigsegv_outp("Stack trace (non-dedicated):");
sz = backtrace(bt, 20);
strings = backtrace_symbols(bt, sz);
for(i = 0; i < sz; ++i)
sigsegv_outp("%s", strings[i]);
#endif
sigsegv_outp("End of stack trace.");
#else
sigsegv_outp("Not printing stack strace.");
#endif
_exit (-1);
}
static void __attribute__((constructor)) setup_sigsegv() {
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_sigaction = signal_segv;
action.sa_flags = SA_SIGINFO;
if(sigaction(SIGSEGV, &action, NULL) < 0)
perror("sigaction");
}
$ g++ -fPIC -shared -o libsigsegv.so -ldl sigsegv
$ export LD_PRELOAD=/path/to/libsigsegv.so
I found this code on a LUG. Couldn't get to the page to point the URL here, so pasted the whole code. This code prints a small stack trace when SIGSEGV occurs. Not sure if there is some other way that does not use ucontext_t.