Can symAdd be used to overwrite a existing symbol in sysSymTbl? - c

A function foo is already present in the system symbol table in vxworks. Now I want to know if I can replace symbol foo with similar function foo1 which takes same arguments and returns the same type as foo, using symAdd routine?

You shouldn't be able to do this using system instruments. If some function g() invokes foo(), then this function is statically linked to foo(). This means, that g() body contains machine instruction like call <hardcoded_address_of_foo()>. This means, you can't replace foo() with foo1() without actually altering machine instructions either of all foo() callers or foo() itself.
However, altering machine instructions of some function on the fly is quite possible. So if you know your platform well, you can actually do function replacement trick on lower level. I successfully did this for VxWorks 5.5 compiled for MIPS architecture.
What worked for me (everything is done in shell):
Get address of foo() and foo1() using lkup
Calculate, how machine instruction jump <address_of_foo1> should be represented in hex
Use m() to modify RAM occupied by foo() body in order to replace first instruction of foo() with calculated one, second instruction of foo() with nop. The latter is needed since all jumps are performed after executing one more instruction on my platform (delay slot instruction)
As a result foo() is corrupted, but now it performs instant jump to foo1() while keeping all information intact (stack, registers etc), so it looks like foo1() is always called instead.
This is applicable to debugging purposes only, so you can continue debugging by patching code on the fly without writing new image to device. However, this approach shouldn't be ever used in production.

Related

Does a C function without any argument and return value require a stack to execute?

Does below function need any stack for execution?
int a;
void func(void)
{
a = 10;
}
As long as a C compiler can see the definition of func, it can1 implement func without using any stack space. For example, where it sees a call to func, it can implement that by emitting an instruction or two to move 10 into a. That would achieve the same result as calling func as a subroutine, so the C rules permit a C implementation to implement a call to func in that way, and it does not use any stack space.
Generally, if the compiler could not see the definition of func, as when compiling another source file that calls func but does not define it, the compiler would have to issue a call instruction or something similar, and that would, at the least, push the return address onto the stack.
Additionally, if the routine being called were more complicated, the compiler might choose not to implement it inline or might not be able to do so. (For example, if func contained calls to itself, it is generally not possible for the compiler to implement it with inline code in all situations; the compiler will need to implement it with actual subroutine call instructions, which do use stack space.)
Footnote
1 Whether any particular compiler will implement func without using stack space is another matter, dependent on the compiler, the switches used to compile, and other factors.

Jumping between object code with different (and unknown) calling convention in C

I have (mapped in memory) two object files, "A.o" and "B.o", with the same CPU Instruction Set (not necessarily Intel --it can be x86, x86_64, MIPS(32/64), ARM(32/64), PowerPC(32/64),..., but always the same in both object files).
Also, both object files are compiled with the same endianness (both little endian, or both big endian).
However (you knew there was a however, otherwise there wouldn't be any question), "A.o" and "B.o" can have a different function calling convention and, to make things worse, unknown to each other ("A.o" has not even the slightest idea about the calling convention for functions in "B.o", and vice versa).
"A.o" and "B.o" are obviously designed to call functions within their same object file, but there must be a (very) limited interface for communicating between them (otherwise, if execution starts at some function in "A.o", no function from "B.o" would ever be executed if there was no such interface).
The file where execution started (let's suppose it's "A.o") knows the addresses of all static symbols from "B.o" (the addresses of all functions and all global variables). But the opposite is not true (well, the limited interface I'm trying to write would overcome that, but "B.o" doesn't know any address from "A.o" before such interface is established).
Finally the question: How can execution jump from a function in "A.o" to a function in "B.o", and back, while also communicating some data?
I need it to:
Be done in standard C (no assembly).
Be portable C (not compiler-dependent, nor CPU-dependent).
Be thread safe.
Don't make any assumption about the calling conventions involved.
Be able to communicate data between the two object files.
My best idea, for the moment, seems that can meet all these requirements, except thread safety. For example, if I define an struct like this:
struct data_interface {
int value_in;
int value_out; };
I could write a pointer to an struct like this from "A.o" into a global variable of "B.o" (knowing in advance that such global variable in "B.o" has space enough for storing a pointer).
Then, the interface function would be a void interface(void) (I'm assuming that calling void(void) functions is safe across different calling conventions... if this is not true, then my idea wouldn't work). Calling such a function from "A.o" to "B.o" would communicate the data to the code in "B.o". And, fingers crossed, when the called function in "B.o" returns, it would travel back nicely (supposing the different calling convention doesn't change the behaviour when returning from void(void) functions).
However, this is not thread safe, of course.
For it to be thread safe, I guess my only option is to access the stack.
But... can the stack be accessed in a portable way in standard C?
Here are two suggestions.
Data interface
This elaborates on the struct you defined yourself. From what I've seen in the past, compilers typically use a single register (e.g. eax) for their return value (provided the return type fits in a register). My guess is, the following function prototype is likely to be unaffected by differing calling conventions.
struct data_interface *get_empty_data_interface(void);
If so, then you could use that in a way that is similar to the idea you already had about using arrays. Define the following struct and functions in B:
struct data_interface {
int ready;
int the_real_data;
};
struct data_interface *get_empty_data_interface(void)
{
struct data_interface *ptr = malloc(sizeof(struct data_interface));
add_to_list_of_data_block_pointers(ptr);
ptr->ready = 0;
return ptr;
}
void the_function(void)
{
execute_functionality_for_every_data_block_in_my_list_that_is_flagged_ready_and_remove_from_list();
}
To call the function, do this in A:
struct data_interface *ptr = get_empty_data_interface();
ptr->the_real_data = 12345;
ptr->ready = 1;
the_function();
For thread-safety, make sure the list of data blocks maintained by B is thread-safe.
Simultaneous calls to get_empty_data_interface should not overwrite each other's slot in the list.
Simultaneous calls to the_function should not both pick up the same list element.
Wrapper functions
You could try to expose wrapper functions with a well-known calling convention (e.g. cdecl); if necessary defined in a separate object file that is aware of the calling convention of the functions it wraps.
Unfortunately you will probably need non-portable function attributes for this.
You may be able to cheat your way out of it by declaring variadic wrapper functions (with an ellipsis parameter, like printf has); compilers are likely to fall back on cdecl for those. This eliminates non-portable function attributes, but it may be unreliable; you would have to verify my assumption for every compiler you'd like to support. When testing this, keep in mind that compiler options (in particular optimizations) may well play a role. All in all, quite a dirty approach.
the question implies that both object files are compiled differently except for the endianness and that they are linked together into one executable.
it says that A.o knows all static symbols from B.o, but the opposite is not true.
Don't make any assumption about the calling conventions involved.
so we'll be using only void f(void) type of functions.
you'll declare int X, Y; in B.o and extern int X, Y; in A.o so before you call the functions in B.o you check the Y flag, if raised wait until it falls. when a B's function is called it raises the Y flag, read the input from X, do some calculations, write the result back in X and return.
then the calling function in A.o copies the value from X into it's own compilation unit and clears the Y flag.
...if calling a void f(void) function just makes a wild jump from one point in the code to another.
another way to do it would be to declare static int Y = 0; in B.o and omit it entirely in A.o
then when a B.o function gets called it checks if Y == 0 and if so increase Y, read X, do calculations, write X, decrease Y and return. if not so then wait to become 0 and block the calling function.
or maybe even have a static flag in every B.o function, but i don't see the point in this waste since the communication data is global in B.o
Remember that there are both caller saves and callee saves conventions out there, together with variations on use of registers to pass values, use or not of a frame pointer, and even (in some architectures, in some optimisation levels) the use of the delay slot in a branch to hold the first instruction of the subroutine. You are not going to be able to do this without some knowledge of the calling conventions in play, but fortunately the linker will need that anyway. Presumably there is some higher level entity that is responsible for loading those DLLs and that knows the calling conventions for both of them?
Anything you do here is going to be at best deep into implementation defined territory, if not technically undefined behaviour, and you will want to make a deep study of the linker and loader (In particular the linker must know how to resolve dynamic linkage in your unknown calling convention or you will not be able to load that shared object in a meaningful way, so you may be able to leaverage it using libbfd or such but that is outside the scope of C).
The place this sort of thing can go very wrong is if shared resources are allocated in A and freed in B (Memory springs to mind) as memory management is a usually a library based wrapper over the operating systems SBRK or similar, and these implementations of memory management are not inherently compatible in memory layout, other places you may be bitten by this include IO (see shennanigans you sometimes get when mixing printf and cout in c++ for a benign example), and locking.

How to set up a callback function when an Exception occurs?

I've been stuck for a while on how to set up a callback when an exception occurs.
I have this test code:
void main()
{
long * bad = (long*)0x0A000000; //Invalid address
//When the following line gets executed
//it causes an error and the debugger sends me to an assembly file.
*bad = 123456789;
}
The assembly file that I am sent to looks like this(fragment of the real file):
.macro DEFAULT_ISR_HANDLER name=
.thumb_func
.weak \name
\name:
1: b 1b /* endless loop */
.endm
DEFAULT_ISR_HANDLER SRC_IRQHandler /*Debugger stops on this line*/
As I understand DEFAULT_ISR_HANDLER is a macro that defines an endless loop.
What I want to do is define my own function in a C file, that I could call when an exception occurs, instead of calling whats defined in the DEFAULT_ISR_HANDLER macro.
My question is, How would I define a macro, in that assembly, that calls an specific C function?
Hopefully I explained myself. Any information or direction around this topic is appreciated.
In case it's relevant I am using GCC ARM compiler v5.4_2016q3
Thanks,
Isaac
EDIT
I am using a Cortex-M3.
Until now I realized I was talking about processor exceptions. According to the datasheet there is a list with 16 exception types.
Apparently, the way it works is that all the exception types are being redirected to the macro, which in turn calls some thumb function and afterwards an endless loop(according to DEFAULT_ISR_HANDLER above in code).
What I would like to do is define my own function in a C file, for convenience, so every time any type of processor exception appear, I could control how to proceed.
You have two options:
Just define a C function with the void SRC_IRQHandler(void) signature and since the macro is defining the default handler as weak, your function will override the default handler in the linking stage.
There should be a place in your project where SRC_IRQHandler is placed in what is called a Vector Table in the Cortex-M3 architecture. You can replace the name of this function with your own C function and your function will be called when this interrupt (exception) happens.
The cortex-m family in general has well more than 16 exceptions there are those plus as many interrupts are implemented by that core, 32, 64, 128, 256. But it is all fundamentally the same. The way the cortex-m family works is they perform the EABI call for you if you will, they preserve some of the registers and then start execution at the address called out in the vector table done in such a way that you can have the address of a normally compiled C function directly in the table. Historically you needed to wrap that function with some code to preserve and restore the state and often instruction sets have a special return from interrupt, but the cortex-m they did a bit different.
so knowing that then the next question is how do you get that address in the table, and that depends on your code, build system, etc. Those handlers might be setup to point to an address in ram and maybe you are running on an RTOS and there is a function you call runtime to register a function for an exception then the RTOS changes the code or some data value in ram that is tied into their handler which essentially wraps around yours. or you are making the vector table in assembly or some other tool specific thing (although assembly is there, works and easy) and you simply count down the right number of entries (or add a hundred more entries so you can count down to the right entry) and place the name of your C function.
good idea to disassemble or do some other check on the result before running to double check that you have placed the handler address at the right physical address for that interrupt/exception.

Compiler optimization call-ret vs jmp

I am building one of the projects and I am looking at the generated list file.(target: x86-64) My code looks like:
int func_1(var1,var2){
asm_inline_(
)
func_2(var1,var2);
return_1;
}
void func_2(var_1,var_2){
asm __inline__(
)
func_3();
}
/**** Jump to kernel ---> System call stub in assembly. This func in .S file***/
void func_3(){
}
When I see the assembly code, I find "jmp" instruction is used instead of "call-return" pair when calling func_2 and func_3. I am sure it is one of the compiler optimization and I have not explored how to disable it. (GCC)
The moment I add some volatile variables to func_2 and func_3 and increment them then "jmp" gets replaced by "call-ret" pair.
I am bemused to see the behavior because those variables are useless and they don't serve any purpose.
Can someone please explain the behavior?
Thanks
If code jumps to the start of another function rather than calling it, when the jumped-to function returns, it will return back to the point where the outer function was called from, ignoring any more of the first function after that point. Assuming the behaviour is correct (the first function contributed nothing else to the execution after that point anyway), this is an optimisation because it reduces the number of instructions and stack manipulations by one level.
In the given example, the behaviour is correct; there's no local stack to pop and no value to return, so there is no code that needs to run after the call. (return_1, assuming it's not a macro for something, is a pure expression and therefore does nothing no matter its value.) So there's no reason to keep the stack frame around for the future when it has nothing more to contribute to events.
If you add volatile variables to the function bodies, you aren't just adding variables whose flow the compiler can analyse - you're adding slots that you've explicitly told the compiler could be accessed outside the normal control flow it can predict. The volatile qualifier warns the compiler that even though there's no obvious way for the variables to escape, something outside has a way to get their address and write to it at any time. So it can't reduce their lifetime, because it's been told that code outside the function might still try to write to that stack space; and obviously that means the stack frame needs to continue to exist for its entire declared lifespan.

C function call with too few arguments

I am working on some legacy C code. The original code was written in the mid-90s, targeting Solaris and Sun's C compiler of that era. The current version compiles under GCC 4 (albeit with many warnings), and it seems to work, but I'm trying to tidy it up -- I want to squeeze out as many latent bugs as possible as I determine what may be necessary to adapt it to 64-bit platforms, and to compilers other than the one it was built for.
One of my main activities in this regard has been to ensure that all functions have full prototypes (which many did not have), and in that context I discovered some code that calls a function (previously un-prototyped) with fewer arguments than the function definition declares. The function implementation does use the value of the missing argument.
Example:
impl.c:
int foo(int one, int two) {
if (two) {
return one;
} else {
return one + 1;
}
}
client1.c:
extern foo();
int bar() {
/* only one argument(!): */
return foo(42);
}
client2.c:
extern int foo();
int (*foop)() = foo;
int baz() {
/* calls the same function as does bar(), but with two arguments: */
return (*foop)(17, 23);
}
Questions: is the result of a function call with missing arguments defined? If so, what value will the function receive for the unspecified argument? Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a predictable implementation-specific behavior that I can emulate by adding a particular argument value to the affected calls?
EDIT: I found a stack thread C function with no parameters behavior which gives a very succinct and specific, accurate answer. PMG's comment at the end of the answer taks about UB. Below were my original thoughts, which I think are along the same lines and explain why the behaviour is UB..
Questions: is the result of a function call with missing arguments defined?
I would say no... The reason being is that I think the function will operate as-if it had the second parameter, but as explained below, that second parameter could just be junk.
If so, what value will the function receive for the unspecified argument?
I think the values received are undefined. This is why you could have UB.
There are two general ways of parameter passing that I'm aware of... (Wikipedia has a good page on calling conventions)
Pass by register. I.e., the ABI (Application Binary Interface) for the plat form will say that registers x & y for example are for passing in parameters, and any more above that get passed via stack...
Everything gets passed via stack...
Thus when you give one module a definition of the function with "...unspecified (but not variable) number of parameters..." (the extern def), it will not place as many parameters as you give it (in this case 1) in either the registers or stack location that the real function will look in to get the parameter values. Therefore the second area for the second parameter, which is missed out, essentially contains random junk.
EDIT: Based on the other stack thread I found, I would ammended the above to say that the extern declared a function with no parameters to a declared a function with "unspecified (but not variable) number of parameters".
When the program jumps to the function, that function assumes the parameter passing mechanism has been correctly obeyed, so either looks in registers or the stack and uses whatever values it finds... asumming them to be correct.
Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a >> predictable implementation-specific behavior
You'd have to check your compiler documentation. I doubt it... the extern definition would be trusted completely so I doubt the registers or stack, depending on parameter passing mechanism, would get correctly initialised...
If the number or the types of arguments (after default argument promotions) do not match the ones used in the actual function definition, the behavior is undefined.
What will happen in practice depends on the implementation. The values of missing parameters will not be meaningfully defined (assuming the attempt to access missing arguments will not segfault), i.e. they will hold unpredictable and possibly unstable values.
Whether the program will survive such incorrect calls will also depend on the calling convention. A "classic" C calling convention, in which the caller is responsible for placing the parameters into the stack and removing them from there, will be less crash-prone in presence of such errors. The same can be said about calls that use CPU registers to pass arguments. Meanwhile, a calling convention in which the function itself is responsible for cleaning the stack will crash almost immediately.
It is very unlikely the bar function ever in the past would give consistent results. The only thing I can imagine is that it is always called on fresh stack space and the stack space was cleared upon startup of the process, in which case the second parameter would be 0. Or the difference between between returning one and one+1 didn't make a big difference in the bigger scope of the application.
If it really is like you depict in your example, then you are looking at a big fat bug. In the distant past there was a coding style where vararg functions were implemented by specifying more parameters than passed, but just as with modern varargs you should not access any parameters not actually passed.
I assume that this code was compiled and run on the Sun SPARC architecture. According to this ancient SPARC web page: "registers %o0-%o5 are used for the first six parameters passed to a procedure."
In your example with a function expecting two parameters, with the second parameter not specified at the call site, it is likely that register %01 always happened to have a sensible value when the call was made.
If you have access to the original executable and can disassemble the code around the incorrect call site, you might be able to deduce what value %o1 had when the call was made. Or you might try running the original executable on a SPARC emulator, like QEMU. In any case this won't be a trivial task!

Resources