DT_USED entry in .dynamic section of ELF file - c

I am curious about DT_USED entry in .dynamic section. However, I could only find two code examples that describe this entry.
1.
#define DT_USED 0x7ffffffe /* ignored - same as needed */
in https://github.com/switchbrew/switch-tools/blob/master/src/elf_common.h
2.
case DT_USED:
case DT_INIT_ARRAY:
case DT_FINI_ARRAY:
if (do_dynamic)
{
if (entry->d_tag == DT_USED
&& VALID_DYNAMIC_NAME (entry->d_un.d_val))
{
char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
if (*name)
{
printf (_("Not needed object: [%s]\n"), name);
break;
}
}
print_vma (entry->d_un.d_val, PREFIX_HEX);
putchar ('\n');
}
break;
in http://web.mit.edu/freebsd/head/contrib/binutils/binutils/readelf.c
I want to know, what's the meaning of "Not needed object"? Does it mean that file names listed here are not needed?

In general, when looking at Solaris dynamic linker features, it is possible to find more information in the public Illumos sources (which were once derived from OpenSolaris). In this case, it seems that DT_USED is always treated like DT_NEEDED, so they are the essentially same thing. One of the header files, usr/src/uts/common/sys/link.h also contains this:
/*
* DT_* entries between DT_HIPROC and DT_LOPROC are reserved for processor
* specific semantics.
*
* DT_* encoding rules apply to all tag values larger than DT_LOPROC.
*/
#define DT_LOPROC 0x70000000 /* processor specific range */
#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
#define DT_USED 0x7ffffffe /* ignored - same as needed */
#define DT_FILTER 0x7fffffff /* shared library filter name */
#define DT_HIPROC 0x7fffffff
There may have been planned something here, but it doesn't seem to be implemented (or it used to be and no longer is).

Related

How to log to /var/log/mail.log using rsyslogd?

I am currently playing around with logging under Linux. I have made the following very simple test application (in plain C):
#include <syslog.h>
int main(int argc, char **argv)
{
openlog("mytest", (LOG_PID | LOG_NDELAY), LOG_MAIL);
syslog(LOG_MAKEPRI(LOG_MAIL, LOG_ERR), "Test");
return(0);
}
This "application" compiles, and when I execute it, it generates an entry in /var/log/syslog, but no entry in /var/log/mail.log and no entry in /var/log/mail.err.
Could somebody please explain why?
I am using rsyslogd on the test machine; this is the configuration from /etc/rsyslog.conf (please note that /etc/rsyslog.d is just empty, and that I have stripped out all comments and lines which clearly don't have anything to do with the problem):
:msg,startswith, " fetching user_deny" ~
:msg,startswith, " seen_db: user " ~
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
*.=debug;\
auth,authpriv.none;\
news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
*.emerg :omusrmsg:*
daemon.*;mail.*;\
news.err;\
*.=debug;*.=info;\
*.=notice;*.=warn |/dev/xconsole
As far as I have understood from reading man rsyslog.conf, that configuration should make rsyslogd write messages for LOG_MAIL with priority LOG_ERR to /var/log/mail.err. I am somewhat mistrustful regarding the lines where the file path has a - prepended, though. I don't know what this means because I could not find any hint in the manual.
So what is going wrong?
I hate answering my own question, but I think I have found a bug either in the documentation or in the source of glibc, and I'd like to have it documented for future visitors of this question.
From https://www.gnu.org/software/libc/manual/html_node/syslog_003b-vsyslog.html#syslog_003b-vsyslog (as per the time of this writing):
syslog submits the message with the facility and priority indicated by
facility_priority. The macro LOG_MAKEPRI generates a facility/priority
from a facility and a priority, as in the following example:
LOG_MAKEPRI(LOG_USER, LOG_WARNING)
Now look at some code from syslog.h as it resides on my test machine (Debian wheezy, up-to-date, no custom patches, non-relevant parts stripped out):
/*
* priorities/facilities are encoded into a single 32-bit quantity, where the
* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
* (0-big number). Both the priorities and the facilities map roughly
* one-to-one to strings in the syslogd(8) source code. This mapping is
* included in this file.
*
* priorities (these are ordered)
*/
#define LOG_EMERG 0 /* system is unusable */
#define LOG_ALERT 1 /* action must be taken immediately */
#define LOG_CRIT 2 /* critical conditions */
#define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE 5 /* normal but significant condition */
#define LOG_INFO 6 /* informational */
#define LOG_DEBUG 7 /* debug-level messages */
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
/* facility codes */
#define LOG_KERN (0<<3) /* kernel messages */
#define LOG_USER (1<<3) /* random user-level messages */
#define LOG_MAIL (2<<3) /* mail system */
#define LOG_DAEMON (3<<3) /* system daemons */
#define LOG_AUTH (4<<3) /* security/authorization messages */
#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
#define LOG_LPR (6<<3) /* line printer subsystem */
#define LOG_NEWS (7<<3) /* network news subsystem */
#define LOG_UUCP (8<<3) /* UUCP subsystem */
#define LOG_CRON (9<<3) /* clock daemon */
#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
#define LOG_FTP (11<<3) /* ftp daemon */
/* other codes through 15 reserved for system use */
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
#define LOG_LOCAL3 (19<<3) /* reserved for local use */
#define LOG_LOCAL4 (20<<3) /* reserved for local use */
#define LOG_LOCAL5 (21<<3) /* reserved for local use */
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
We are obviously having multiple problems here.
The comment at the top: If I have 3 bottom bits, then I have 29 top bits (and not 28). But this is a minor problem.
The facility codes are already defined as shifted-to-left by three bits. Using the macro LOG_MAKEPRI (as recommended by the manual page linked above) obviously shifts them to the left by three bits a second time, which clearly is wrong.
SOLUTION
The solution is simple: Don't use that macro; instead, just OR the facility code and the priority code. I have tried that, and it worked. Error messages from my test programs are now logged as expected, according to the configuration of rsyslogd in /etc/rsyslog.conf.
I am quite surprised about that very obvious bug in syslog.h ...

How to determine the size of a PIM within an AUTOSAR Runnable?

How can I determine the size of a PIM (Per Instance Memory) in c from inside a Runnable (without looking it up in the generated RTE and adding a fix value)?
Situation:
Runnable Foo has access to two PIMs Pim1 and Pim2. In the example the data from Pim1 shall be copied to Pim2.
Not only because of security and safety I need to check the size of both PIMs in order NOT to overwrite illegal data areas.
I know that the size of the PIM is configured in the SW-C description (SWCD). But as the SWCD may be changed after code implementation and in order to keep the code of the Runnable more generic, the size checking should not be based on fix values.
I also considered the problem of the sizeof for an array:
How to find the 'sizeof'(a pointer pointing to an array)?
For the PIMs the following code is generated by the RTE-Generator:
In Rte_Type.h
typedef uint8 Rte_DT_DtImplRec1_0;
typedef uint16 Rte_DT_DtImplRec1_1;
typedef struct
{
Rte_DT_DtImplRec1_0 var1;
Rte_DT_DtImplRec1_1 var2;
Rte_DT_DtImplRec1_2 var3;
} DtImplRec1;
typedef uint8 Rte_DT_DtImplAry1_0;
typedef Rte_DT_DtImplAry1_0 DtImplAry1[5];
In Rte.c
VAR(DtImplRec1, RTE_VAR_DEFAULT_RTE_PIM_GROUP) Rte_FOO_Pim1;
VAR(DtImplAry1, RTE_VAR_DEFAULT_RTE_PIM_GROUP) Rte_FOO_Pim2;
In Rte_FOO.h
#define Rte_Pim_Pim1() (&Rte_FOO_Pim1)
#ifdef RTE_PTR2ARRAYBASETYPE_PASSING
# define Rte_Pim_Pim2() (&((*RtePim_Pim2())[0]))
#else
# define Rte_Pim_Pim2() RtePim_Pim2()
#endif
#define RtePim_Pim2() (&Rte_FOO_Pim2)
Note that the define for array PIMs might also be changing, depending on the RTE_PTR2ARRAYBASETYPE_PASSING “switch”.
The following “access” is generated for the FOO template:
DtImplRec1 *Rte_Pim_Pim1(void);
Rte_DT_DtImplAry1_0 *Rte_Pim_Pim2(void)
The code for the Foo-Runnable may look like this:
FUNC(void, FOO_CODE) Foo(void)
{
DtImplRec1 *pim1 = Rte_Pim_Pim1();
Rte_DT_DtImplAry1_0 *pim2 = Rte_Pim_Pim2();
uint8 sizeOfPim1a = sizeof(Rte_Pim_Pim1()); /* always returns 4 as the size of the pointer */
uint8 sizeOfPim1b = sizeof(*Rte_Pim_Pim1()); /* evaluates to 6 */
uint8 sizeOfPim1c = sizeof(DtImplRec1); /* evaluates to 6 */
uint8 sizeOfPim1d = sizeof(Rte_FOO_Pim1); /* evaluates to 6 */
uint8 sizeOfPim2a = sizeof(Rte_Pim_Pim2()); /* always returns 4 as the size of the pointer */
uint8 sizeOfPim2b = sizeof(*Rte_Pim_Pim2()); /* evaluates to 1 */
uint8 sizeOfPim2c = sizeof(Rte_DT_DtImplAry1_0); /* evaluates to 1: sizeof(uint8) */
uint8 finalSize = MIN(sizeOfPim1b, sizeOfPim2b);
memcpy( pim2, pim1, finalSize ); /* (use of) memcpy is not the topic here */
}
To make my problem more "visible", here is a Callback-Runnable example for writing a DID via diagnostics:
FUNC(Std_ReturnType, FOO_CODE)
DataServices_Data_FFFF_WriteData(P2CONST(uint8, AUTOMATIC, RTE_APPL_DATA) Data, Dcm_OpStatusType OpStatus, P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, RTE_APPL_DATA) ErrorCode)
{
Std_ReturnType ret = E_NOT_OK;
#define sizeOfPim1 (5) /* how to determine the PIM size here if we do not know anything about it here? (PIM structure can change without modifying the code here) */
#define sizeOfDidFFFF (5) /* This is even another problem: How to determine the size of a DID. I will create another discussion thread for this question. */
/* Instead of this if-condition, an assert during compile-time would also be appropriate */
if( sizeOfPim1 == sizeOfDidFFFF )
{
/* We have to make sure that we do not copy more bytes as of the size of Pim1 */
memcpy( Rte_Pim_Pim1(), Data, sizeOfPim1 ); /* (use of) memcpy is not the topic here */
ret = E_OK;
}
return ret;
}
I don't have here any AUTOSAR environment to test this, so, please, if you try any of this, just let me know if it works. Besides, I am not an expert and it is quite a long time I don't write AUTOSAR code, so I will probably be missing something. I also don't want to publicize any RTE generator from any vendor, so I will cite only the standard.
Use sizeof(DtImplAry1)
You define that type and give it as input to the RTE generator, so you know the name. If your SWC doesn't make explicit use of that type the RTE generator could not include it in your .h, but you could add it manually to you SWC arxml. I think all tools out there allow to do this without having to edit the arxml by hand, just look for the option to include additional SWC types in your tool.
Use Instance API to access SWC data
The standard specifies a variable of type Rte_CDS_FOO to hold all pointers to PIMs of the SWC (among other things) if you enable the API (look for it in your tool).
Besides, a variable Rte_Inst_FOO should be available to you, declared as extern in your header. You could do sizeof(*Rte_Inst_FOO->Pim_Pim2).
EDIT: reply to some of your comments
I guess the reason you don't find the CDS is because of this (from Specification of RTE, 4.2.2, 5.4 RTE Data Structures):
The [CDS and Instance handler] definitions only apply to RTE generators operating in compatibility mode – in this mode the instance handle and the component data structure have to be defined even for those (object-code) software components for which multiple instantiation is forbidden to ensure compatibility.
Also,
[SWS_Rte_03793] If a software component does not support multiple instantiation,the name of the component data instance shall be Rte_Inst_cts, where cts is the component type symbol of the AtomicSwComponentType. (SRS_Rte_00011)
So, when the RTE-generator adheres to this compatibility mode, those variables must be there. If you are using a vendor specific solution, well, try to tag the question with that vendor name also, hopefully somebody can answer.
Assert at compile time
I am not going to ask why you are doing this, but IMHO I think it does not sound right, does it makes sense for the receiving buffer to be smaller that the data to copy?. Maybe it is better to assert at compile time if the buffer is smaller than your struct. Or you could define your array instead to be a struct and cast it if needed (if your are following MISRA rules, maybe you will have problems with it, just check). Just for reference, compile time assertions can use sizeof.
You have several problems here:
a) your sizeof(*pim1) returns 6 because of padding, because you start with an uint8, the second is uint16, and I guess the 3rd ist also uint16.
That's, why you should rather sort them by type size/alignment .. biggest to smallest
uint32
uint16
uint8
Even though, the elements might not be ordered anymore, but it also decreases finally the gaps in memory created by the linker.
b) the pim2 is an array, you can not get the array len/size from the pointer.
But, you should have the Rte definition of DtImplAry1.
typedef uint8 Rte_DT_DtImplAry1_0;
typedef Rte_DT_DtImplAry1_0 DtImplAry1[5]; // <-- taken in through Rte_Foo_Type.h (includes Rte_Type.h
uint32 ary_len = sizeof(DtImplAry1) / sizeof(DtImplAry1[0]);

How to use/convert string defined in macro to integer?

I would like to compute something according to the version of a library (which I can't change the values) by using C language.
However, the version of the library, that I am using, is defined as string by using #defines like:
/* major version */
#define MAJOR_VERSION "2"
/* minor version */
#define MINOR_VERSION "2"
Then, my question is: how to do define the macro STR_TO_INT in order to convert the strings MINOR_VERSION and MAJOR_VERSION to integer?
#if ((STR_TO_INT(MAJOR_VERSION) == 2 && STR_TO_INT(MINOR_VERSION) >= 2) || (STR_TO_INT(MAJOR_VERSION > 2))
//I perform an action...
#else
//I perform a different action
#endif
I prefer to define it as macro since I am using a lot of function from this library. Please feel free to give me any idea.
Preprocess the official library header, libheader.h, to generate your more useful information without the quotes in a new header, libversion.h:
sed -n -e '/^#define \(M[AI][JN]OR\)_VERSION "\([0-9][0-9]*\)".*/ {
s//#define NUM_\1_VERSION \2/p
}' libheader.h >libversion.h
You might need to be more flexible about allowing spaces and tabs around the separate parts of #, define and the macro name. I also assume there are no comments in the definition (trailing comments are handled):
/* This starts in column 1 - unlike the next line */
# define /* No comment here */ MAJOR_VERSION /* Nor here */ "2"
Now you can include both libheader.h and libversion.h and compare the numeric versions with impunity (as long as you get the expressions correct):
#include "libheader.h"
#include "libversion.h"
#if ((NUM_MAJOR_VERSION == 2 && NUM_MINOR_VERSION >= 2) || NUM_MAJOR_VERSION > 2)
…perform the new action…
#else
…perform the old action…
#endif
Strictly, the sed script will also convert MIJOR_VERSION and MANOR_VERSION; however, they're unlikely to appear in the library header, and you can ignore the generated numeric versions with ease. There are ways to deal with that if you really think it is an actual rather than hypothetical problem.
More seriously, if the library has complicated controls on the version information, it could be that a single header can masquerade as different versions of the library — there could be multiple lines defining the major and minor versions. If that's the case, you have to work a lot harder.
#define MAJOR_VERSION 2 will work anywhere, as an int, as you have, 2, there is no need for string/ conversions. You can directly do:
if (MAJOR_VERSION == 2) { /* version 2 */ }
else { /* not version 2 */ }

Understanding a function definition in a header file

I am porting a software written to a specific microcontroller to another microcontroller but I have a problem in C language.
I would like to draw attention to the below mentioned functions defined inside hal_spi_rf_trxeb.c file. Although I searched within the file I was not able to find the full function description for the following functions.
TRXEM_SPI_WAIT_DONE()
TRXEM_SPI_RX()
TRXEM_SPI_WAIT_DONE()
TRXEM_SPI_WAIT_TX_DONE()
TRXEM_SPI_RX()
TRXEM_SPI_WAIT_MISO_LOW(x)
After a bit more searching I figured that these functions exist in the header file itself. More specifically inhal_spi_rf_trxeb.h file.
/******************************************************************************
* #fn trx16BitRegAccess
*
* #brief This function performs a read or write in the extended adress
* space of CC112X.
*
* input parameters
*
* #param accessType - Specifies if this is a read or write and if it's
* a single or burst access. Bitmask made up of
* RADIO_BURST_ACCESS/RADIO_SINGLE_ACCESS/
* RADIO_WRITE_ACCESS/RADIO_READ_ACCESS.
* #param extAddr - Extended register space address = 0x2F.
* #param regAddr - Register address in the extended address space.
* #param *pData - Pointer to data array for communication
* #param len - Length of bytes to be read/written from/to radio
*
* output parameters
*
* #return rfStatus_t
*/
rfStatus_t trx16BitRegAccess(uint8 accessType, uint8 extAddr, uint8 regAddr, uint8 *pData, uint8 len)
{
uint8 readValue;
<span style="background-color:#ff0000;">TRXEM_SPI_BEGIN();</span>
while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN);
/* send extended address byte with access type bits set */
<span style="background-color:#ff0000;"> TRXEM_SPI_TX</span>(accessType|extAddr);
TRXEM_SPI_WAIT_DONE();
/* Storing chip status */
readValue = TRXEM_SPI_RX();
TRXEM_SPI_TX(regAddr);
TRXEM_SPI_WAIT_DONE();
/* Communicate len number of bytes */
trxReadWriteBurstSingle(accessType|extAddr,pData,len);
hal_spi_rf_trxeb.h claims to have the function I was searching in the form of a macro. Those macros are shown below.
/******************************************************************************
* MACROS
*/
/* Macros for Tranceivers(TRX) */
#define TRXEM_SPI_BEGIN() st( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP(); )
#define TRXEM_SPI_TX(x) st( UCB0IFG &= ~UCRXIFG; UCB0TXBUF= (x); )
#define TRXEM_SPI_WAIT_DONE() st( while(!(UCB0IFG & UCRXIFG)); )
#define TRXEM_SPI_WAIT_TX_DONE() st( while(!(UCB0IFG & UCTXIFG)); )
#define TRXEM_SPI_RX() UCB0RXBUF
#define TRXEM_SPI_WAIT_MISO_LOW(x) st( uint8 count = 200; \
while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN) \
{ \
__delay_cycles(5000); \
count--; \
if (count == 0) break; \
} \
if(count>0) (x) = 1; \
else (x) = 0; )
Questions
I do not understand how these macros work.
Could someone please tell me how a function has been defined in the header file?
How can a function be defined in the header file itself?
What does the function st() do?
Should you require, the whole project can be downloaded by this link.
For more information you may view the linked header and source (.h and .c) files.
As you have already said, those are not functions but rather macros. You can read about macros in the gcc manual.
A macro is a fragment of code which has been given a name. Whenever
the name is used, it is replaced by the contents of the macro.
That's the summary. There's a lot more detail to it than that. But for starters you can think of macros as code replacement rules. Macros are expanded by the preprocessor before the compiler does it's job.
A simple example:
#define MY_PRINT_MACRO(string1, string2) printf("%s %s\n", string1, string2)
MY_PRINT_MACRO("hello", "world");
The preprocessor will change the second line to be:
printf("%s %s\n", "hello", "world");
And that is exactly what the compiler will see (it does not see MY_PRINT_MACRO at all).
These are not functions but macros. Macros are basically being replaced by the code they represent before compilation (preprocessing).
Macros can be defined and redefined over header files.
st() function is not written in the context so not sure what it does.

Disable functions using MACROS

After searching quite a bit in the Internet for a solution I decided to ask here if my solution is fine.
I'm trying to write a simple and modular C logging library intended to be simple to disable and specially helping PhD students and researchers to debug an algorithm reducing as much as possibile the impact of the logging system.
My problem is that I want make possible for the user of the library to disable the logging system at compile time producing an executable in which the cost of the logger is 0.
The C code would look like this:
...
logger_t * logger;
result = logger_init(logger);
if(result == -1) {...}
...
this will simply initialize the logger. Looking for an example code I have checked the assert.h header but that soulution results in a list of warnings in my case. In fact, if logger_init() is substituted by 0 using the macro this will result in the variable logger never used.
For this reason I've decided to use this approach:
int logger_init(logger_t *logger);
#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger) (int)((logger = NULL) == NULL)
#endif /* NLOG */
this does not result in warnings and I also avoid the overhead of calling the function. In fact my first try was to do like this:
int logger_init(logger_t *logger) {
#ifndef NLOG /* NLOG not defined -> enable logging */
...
#endif
return 0;
}
keep calling the function even if I do not need it.
Do you think my solution could be considered a good solution? Is there a better solution?
Thanks a lot, guys!
Cheers,
Armando
The standard idiom for that, at least in the 90s, was:
#ifndef NLOG
void logger_init(logger_t *logger);
void logger_log(logger_t *logger, ...);
#else
#define logger_init (void)sizeof
#define logger_log (void)sizeof
#endif
Remember that sizeof operands are not evaluated, although they are syntax checked.
This trick works also with variadic functions, because the sizeof operator will see an expresion with several comma operators:
logger_log(log, 1, 2, 3);
Converts to:
(void)sizeof(log, 1, 2, 3);
Those commas are not separating parameters (sizeof is not a function but an operator), but they are comma operators.
Note that I changed the return value from int to void. No real need for that, but the sizeof return would be mostly meaningless.
Can't your disabled version simply be a constant:
#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger) 0
#endif /* NLOG */
This way, you just have (after pre-compilation): result = 0; which shouldn't produce any warnings.

Resources