Function with weak atributte can not be overwritten - c++

I would like to overwrite function (interupt handlers) with the weak attribute, but linker does not link my definition. Codes are shorted for better reading.
vectors.c
void NMI_Handler (void) __attribute__((weak));
void HardFault_Handler (void) __attribute__((weak));
__attribute__ ((section(".vectors"), used))
void (* const gVectors[])(void) =
{
NMI_Handler,
HardFault_Handler
};
void NMI_Handler (void) { while(1); }
void HardFault_Handler (void) { while(1); }
I redefine default definition in the file cpuexcept.cpp
extern "C" __attribute__((naked))
void NMI_Handler()
{
EXCEPT_ENTRY(CPUExcept);
}
extern "C" __attribute__((naked))
void HardFault_Handler()
{
EXCEPT_ENTRY(CPUExcept);
}
If I compile and dump it, output (library lib.a) is:
cpuexcept.oo: file format elf32-littlearm
rw-rw-rw- 0/0 4728 Jun 26 16:20 2012 cpuexcept.oo
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 .text 0000051c 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000550 2**0 CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000550 2**0 ALLOC
3 .rodata 000001dc 00000000 00000000 00000550 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment 00000012 00000000 00000000 0000072c 2**0 CONTENTS, READONLY
5 .ARM.attributes 00000031 00000000 00000000 0000073e 2**0 CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 cpuexcept.cpp
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
000004e0 g F .text 0000000a NMI_Handler
000004ec g F .text 0000000a HardFault_Handler
000004e0 <NMI_Handler>:
4e0: e92d 0ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp}
4e4: 4668 mov r0, sp
4e6: f7ff fffe bl c0 <CPUExcept> 4e6: R_ARM_THM_CALL CPUExcept
4ea: bf00 nop
000004ec <HardFault_Handler>:
4ec: e92d 0ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp}
4f0: 4668 mov r0, sp
4f2: f7ff fffe bl c0 <CPUExcept> 4f2: R_ARM_THM_CALL CPUExcept
4f6: bf00 nop
vectors.o: file format elf32-littlearm
rw-rw-rw- 0/0 4464 Jun 27 13:52 2012 vectors.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 .text 00000114 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000148 2**0 CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000148 2**0 ALLOC
3 .vectors 00000130 00000000 00000000 00000148 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
4 .comment 00000012 00000000 00000000 00000278 2**0 CONTENTS, READONLY
5 .ARM.attributes 00000031 00000000 00000000 0000028a 2**0 CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 vectors.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .vectors 00000000 .vectors
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 w F .text 00000002 NMI_Handler
00000004 w F .text 00000002 HardFault_Handler
00000000 <NMI_Handler>:
0: e7fe b.n 0 <NMI_Handler>
2: bf00 nop
00000004 <HardFault_Handler>:
4: e7fe b.n 4 <HardFault_Handler>
6: bf00 nop
Default function with the weak attribute is linked in to target application. My definition is linked correct, if I define function f() in cpuexcept.cpp and I use it in main function or if my definiton of handler is in other .c module.
I use arm-none-eabi-gcc 4.6.2 (YAGARTO) compiler in cygwin.

You could try to define your function like
void NMI_Handler(void)
and not as
void NMI_Handler()
As the weak definition is also void NMI_Handler (void) __attribute__((weak));
So the linker will not see any difference.

Related

How to redefine symbol of object file from the arm-none-eabi compile with -flot flag?

I want redefine malloc symbol to own_malloc, so that I can know memory alloc details and print alloc-size.But I found it don't work when I excuting order:
arm-none-eabi-objcopy --redefine-sym malloc=own_malloc test.o
the test source:
#include <stdlib.h>
extern "C" void test();
void test(){
void* ptr = ::malloc(16);
free(ptr);
}
I exec objdump to look the symbol table
arm-none-eabi-objdump -t test.o
I fount there was not malloc/free symbol in symbols table.
SYMBOL TABLE:
00000000 l df *ABS* 00000000 test.cxx
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .gnu.debuglto_.debug_info 00000000 .gnu.debuglto_.debug_info
00000000 l d .gnu.debuglto_.debug_abbrev 00000000 .gnu.debuglto_.debug_abbrev
00000000 l d .gnu.debuglto_.debug_line 00000000 .gnu.debuglto_.debug_line
00000000 l d .gnu.debuglto_.debug_str 00000000 .gnu.debuglto_.debug_str
00000000 l d .gnu.lto_.profile.7c13183f5b427e41 00000000 .gnu.lto_.profile.7c13183f5b427e41
00000000 l d .gnu.lto_.icf.7c13183f5b427e41 00000000 .gnu.lto_.icf.7c13183f5b427e41
00000000 l d .gnu.lto_.ipa_sra.7c13183f5b427e41 00000000 .gnu.lto_.ipa_sra.7c13183f5b427e41
00000000 l d .gnu.lto_.inline.7c13183f5b427e41 00000000 .gnu.lto_.inline.7c13183f5b427e41
00000000 l d .gnu.lto_.jmpfuncs.7c13183f5b427e41 00000000 .gnu.lto_.jmpfuncs.7c13183f5b427e41
00000000 l d .gnu.lto_.pureconst.7c13183f5b427e41 00000000 .gnu.lto_.pureconst.7c13183f5b427e41
00000000 l d .gnu.lto_.lto.7c13183f5b427e41 00000000 .gnu.lto_.lto.7c13183f5b427e41
00000000 l d .gnu.lto_test.0.7c13183f5b427e41 00000000 .gnu.lto_test.0.7c13183f5b427e41
00000000 l d .gnu.lto_.symbol_nodes.7c13183f5b427e41 00000000 .gnu.lto_.symbol_nodes.7c13183f5b427e41
00000000 l d .gnu.lto_.refs.7c13183f5b427e41 00000000 .gnu.lto_.refs.7c13183f5b427e41
00000000 l d .gnu.lto_.decls.7c13183f5b427e41 00000000 .gnu.lto_.decls.7c13183f5b427e41
00000000 l d .gnu.lto_.symtab.7c13183f5b427e41 00000000 .gnu.lto_.symtab.7c13183f5b427e41
00000000 l d .gnu.lto_.ext_symtab.7c13183f5b427e41 00000000 .gnu.lto_.ext_symtab.7c13183f5b427e41
00000000 l d .gnu.lto_.opts 00000000 .gnu.lto_.opts
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 w .gnu.debuglto_.debug_info 00000000 .hidden test.cxx.cee7ff5d
00000001 O *COM* 00000001 __gnu_lto_slim
I used the following compilation parameters:
arm-none-eabi-g++ -c -fno-common -nostdinc++ -Wall -Wshadow -Wundef -fno-exceptions -fcheck-new -fno-rtti -std=c++17 -pipe -Os -fno-strict-aliasing -fomit-frame-pointer -flto -fuse-linker-plugin -fno-builtin -ffunction-sections -fdata-sections -g -march=armv8-m.main+dsp -mtune=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard _ -Wno-cpp --std=c++17 -Werror test.cxx -o test.o
So how can I redefine malloc and free to own_malloc and own_free with lto flag ?

Why there is no .bss segment in COFF object file?

A simple hello world program:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
After dumpbin it with /HEADERS flag, i get those segments:
8 .bss
A0 .debug$S
62 .drectve
F .rdata
8B .text$mn
If compile the program with /TC, so that it's a C program, i get those segments after the same use of a dumpbin:
2000 .data
1000 .gfids
7000 .rdata
1000 .reloc
10000 .text
point is:
How do i get this similar kind of output:
# objdump -hrt hello.o
hello.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000011 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000048 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000048 2**2
ALLOC
3 .rodata.str1.1 0000000d 00000000 00000000 00000048 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment 00000033 00000000 00000000 00000055 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 hello.c
00000000 l d .text 00000000
00000000 l d .data 00000000
00000000 l d .bss 00000000
00000000 l d .rodata.str1.1 00000000
00000000 l d .comment 00000000
00000000 g F .text 00000011 main
00000000 *UND* 00000000 puts

How can the stack be broken at the very start of application

The stack frame pointer (EBP) should always point to where the previous stack frame was right but why is that not the case in my application! That would indicate something is really wrong..hard to believe!
I created multiple simple demo applications where the stack pointer always points to the previous stack frame but I can't make sense of why this is not the case in this application and it is happening when my application is just starting up!
The following is my call stack
0:000> k
# ChildEBP RetAddr
00 0018fee4 6381d1cd acn!CAcnApp::InitInstance+0x41 [c:\acn-project\acn\acn.cpp # 527]
01 0018fef4 00428575 MFC80U!AfxWinMain+0x48 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winmain.cpp # 37]
02 0018ff88 765d336a acn!__tmainCRTStartup+0x150 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 589]
03 0018ff94 76f59902 kernel32!BaseThreadInitThunk+0xe
04 0018ffd4 76f598d5 ntdll!__RtlUserThreadStart+0x70
05 0018ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> dc 0018fee4
0018fee4 ffffffff 6381d1cd 00489498 00000001 .......c..H.....
0018fef4 00000000 00428575 00400000 00000000 ....u.B...#.....
0018ff04 01e53fd2 0000000a 87b8aee0 00000000 .?..............
0018ff14 00000000 7efde000 00000044 01e54012 .......~D....#..
0018ff24 01e53ff2 01e53fd4 00000000 00000000 .?...?..........
0018ff34 00000000 00000000 00000000 00000000 ................
0018ff44 00000000 00000000 00000000 00000000 ................
0018ff54 00000000 00000000 0018ff84 00428e5d ............].B.
0:000> dc 0018fef4
0018fef4 00000000 00428575 00400000 00000000 ....u.B...#.....
0018ff04 01e53fd2 0000000a 87b8aee0 00000000 .?..............
0018ff14 00000000 7efde000 00000044 01e54012 .......~D....#..
0018ff24 01e53ff2 01e53fd4 00000000 00000000 .?...?..........
0018ff34 00000000 00000000 00000000 00000000 ................
0018ff44 00000000 00000000 00000000 00000000 ................
0018ff54 00000000 00000000 0018ff84 00428e5d ............].B.
0018ff64 01e53fd2 00000000 00000000 0018ff0c .?..............
0:000> dc 0018ff88
0018ff88 0018ff94 765d336a 7efde000 0018ffd4 ....j3]v...~....
0018ff98 76f59902 7efde000 7d7a657d 00000000 ...v...~}ez}....
0018ffa8 00000000 7efde000 00000000 00000000 .......~........
0018ffb8 00000000 0018ffa0 00000000 ffffffff ................
0018ffc8 76f958c5 0b965c89 00000000 0018ffec .X.v.\..........
0018ffd8 76f598d5 0042873d 7efde000 00000000 ...v=.B....~....
0018ffe8 00000000 00000000 00000000 0042873d ............=.B.
0018fff8 7efde000 00000000 78746341 00000020 ...~....Actx ...
The control is in the first line of InitInstance() so it's like my application is drawing its first breath and the stack seems to be already corrupted? Well the app class constructor comes before this but I checked the call stack is in similar state there as well.
Notice the stack frame pointer (EFP) check for both 1st and 2nd frame fails but the stack is good beyond that.
My first question is that is there any explanation the call stack can be like this and this being Ok? In other words, can we say the call stack is definitely broken? The application does load and calls various dlls if that may play any part (don't know why it would though).
What could be the suspect in this case since the application has only barely started!?
Update (code)
Here is constructor which is very simple. And as for InitInstance(), that function is very long but my breakpoint is on first line so its code is never executed when call stack is like that.
CAcnApp::CAcnApp()
{
m_bServMode = FALSE;
m_bFactory = FALSE;
m_bDownload = FALSE;
m_pEngine = NULL;
m_hWiztomMod = NULL;
m_pServer = new CAcnServer;
}
Second update
I posted a follow up question to share extra information after further investigation and that does qualify as separate question due to differences.
BTW, global or file global objects are created before the main function is called.
If an object's constructor has problems, you could see any number of defects occurring before main is called.
Review your object's constructors. You should be able to set a breakpoint in the object's constructor.
Edit 1: Memory allocation in constructor
Having a global object that has dynamic memory allocation may cause problems. The object requires that the dynamic memory allocation is initialized before the object is constructed. Try commenting out the dynamic memory allocation and see if the issue goes away.
A workaround is to create an "initialize" method that can be called after the main entry point is reached. The initialize method would perform dynamic memory allocation.

No source available error in accessing shared library

I have two project in my Eclipse IDE. My OS is Ubuntu. One is application project and another one is shared lib project. I have linked all paths and libs requirement as discussed in the link. But when I debug, I got error as No source available for "0x0". The error happened at iOCR* pOCR = (iOCR*)create(); when I access the shared library object. What is wrong with my linking?
My shared library codes and application codes are attached.
Shared library header file
#ifndef OCR_DLL_H_
#define OCR_DLL_H_
#include <opencv/cv.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <tesseract/baseapi.h>
#include <iostream>
#include "Define.h"
using namespace cv;
namespace VIDEOANALYTICS_PLATFORM {
class iOCR{
public:
virtual ~iOCR(){}
virtual int preProcessing(Mat &img) = 0;
virtual int textExtraction(Mat &img) = 0;
};
class OCR : public iOCR{
public:
OCR(){}
~OCR(){ ; }
int preProcessing(Mat &img);
int textExtraction(Mat &img);
private:
};
}
#endif /* OCR_DLL_H_ */
Shared library cpp
#include "OCR_dll.h"
namespace VIDEOANALYTICS_PLATFORM {
extern "C" iOCR* create_object(){
iOCR *p = new OCR();
return p;
}
extern "C" void destroy_object( iOCR* object )
{
delete object;
}
int OCR::preProcessing(Mat &img){
return SUCCESS;
}
int OCR::textExtraction(Mat &img){
return SUCCESS;
}
}
Application main.cpp
#include <stdio.h>
#include "OCR_dll.h"
#define SUCCESS 0
#define FILE_ERROR 1
#define HTTP_ERROR 2
#define THREAD_ERROR 3
using namespace VIDEOANALYTICS_PLATFORM;
using namespace cv;
void *readImage(void *ptr);
void *postHTTP(void *ptr);
int main(int argc, char *argv[])
{
// on Linux, use "./myclass.so"
void* handle = dlopen("OCR.so", RTLD_LAZY);
iOCR* (*create)();
void (*destroy)(iOCR*);
create = (iOCR* (*)())dlsym(handle, "create_object");
destroy = (void (*)(iOCR*))dlsym(handle, "destroy_object");
iOCR* pOCR = (iOCR*)create();
if(pOCR){
destroy( pOCR );
}//if(pOCR)
dlclose(handle);
return 0;
}
I checked with objdumb and the output is as follow
cdc#cdc-desktop:~/workspace/OCR/Debug$ objdump -TC libOCR.so
libOCR.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00000000 DF *UND* 00000000 GLIBC_2.1.3 __cxa_atexit
00000000 w D *UND* 00000000 __gmon_start__
00000000 w D *UND* 00000000 _Jv_RegisterClasses
00000000 DF *UND* 00000000 GLIBCXX_3.4 operator delete(void*)
00000000 DF *UND* 00000000 GLIBCXX_3.4 std::ios_base::Init::Init()
00000000 DF *UND* 00000000 GLIBCXX_3.4 std::ios_base::Init::~Init()
00000000 w D *UND* 00000000 _ITM_deregisterTMCloneTable
00000000 w D *UND* 00000000 _ITM_registerTMCloneTable
00000000 DO *UND* 00000000 CXXABI_1.3 vtable for __cxxabiv1::__class_type_info
00000000 DF *UND* 00000000 CXXABI_1.3 __cxa_pure_virtual
00000000 DF *UND* 00000000 GLIBCXX_3.4 operator new(unsigned int)
00000000 DO *UND* 00000000 CXXABI_1.3 vtable for __cxxabiv1::__si_class_type_info
00000000 w DF *UND* 00000000 GLIBC_2.1.3 __cxa_finalize
00000c95 g DF .text 00000020 Base destroy_object
00000dc4 w DF .text 0000001e Base VIDEOANALYTICS_PLATFORM::OCR::~OCR()
00000de4 g DF .fini 00000000 Base _fini
00000d94 w DF .text 00000030 Base VIDEOANALYTICS_PLATFORM::OCR::~OCR()
00000d94 w DF .text 00000030 Base VIDEOANALYTICS_PLATFORM::OCR::~OCR()
00000d4c w DF .text 0000001e Base VIDEOANALYTICS_PLATFORM::iOCR::~iOCR()
00000cc0 g DF .text 0000000a Base VIDEOANALYTICS_PLATFORM::OCR::textExtraction(cv::Mat&)
00000d78 w DF .text 0000001c Base VIDEOANALYTICS_PLATFORM::OCR::OCR()
00000aec g DF .init 00000000 Base _init
00000e40 w DO .rodata 00000020 Base typeinfo name for VIDEOANALYTICS_PLATFORM::OCR
00000d78 w DF .text 0000001c Base VIDEOANALYTICS_PLATFORM::OCR::OCR()
00003018 g D .bss 00000000 Base __bss_start
00000d26 w DF .text 00000025 Base VIDEOANALYTICS_PLATFORM::iOCR::~iOCR()
00000d6a w DF .text 0000000e Base VIDEOANALYTICS_PLATFORM::iOCR::iOCR()
00000d26 w DF .text 00000025 Base VIDEOANALYTICS_PLATFORM::iOCR::~iOCR()
0000301c g D .bss 00000000 Base _end
00000e18 w DO .rodata 00000018 Base vtable for VIDEOANALYTICS_PLATFORM::iOCR
00000e30 w DO .rodata 0000000c Base typeinfo for VIDEOANALYTICS_PLATFORM::OCR
00000d6a w DF .text 0000000e Base VIDEOANALYTICS_PLATFORM::iOCR::iOCR()
00000cb6 g DF .text 0000000a Base VIDEOANALYTICS_PLATFORM::OCR::preProcessing(cv::Mat&)
00000e00 w DO .rodata 00000018 Base vtable for VIDEOANALYTICS_PLATFORM::OCR
00003018 g D .data 00000000 Base _edata
00000e84 w DO .rodata 00000008 Base typeinfo for VIDEOANALYTICS_PLATFORM::iOCR
00000c6c g DF .text 00000029 Base create_object
00000e60 w DO .rodata 00000021 Base typeinfo name for VIDEOANALYTICS_PLATFORM::iOCR
There are two possible problems that I see.
The first is, and for this I'm only guessing, that you put the shared object in the same path as the executable loading the shared object, and thought that dlopen would look in the process current directory. The manual page says that
If filename contains a slash ("/"), then it is interpreted as a (relative or absolute) pathname. Otherwise, the dynamic linker searches for the library as follows...
And then it lists where the function will look for the shared object, which includes e.g. /usr/lib.
If the library is not in the path that dlopen looks in, then the shared object will not be found.
The simple solution to this first problem is to use an absolute or relative path instead, e.g.
dlopen("./OCR.so", RTLD_LAZY);
This will look in the process current directory (which might not be the same directory as where the executable program is).
The second problem is that you named the shared object libOCR.so, and you ask dlopen to look for OCR.so. The dlopen does not automatically add the lib prefix when looking for files, you need to provide the actual file-name of the shared object.

windbg coredump analysis address with "bad"

I have a corruption memory heap problem with an application.
by using windbg and a dump file of the crash as an input I have the following output with dd esp command
0:002> dd esp
00000000`03e3e490 14badf55 00000000 03e3e8c0 00000000
00000000`03e3e4a0 00000000 00000000 03e3e8c0 00000000
00000000`03e3e4b0 03e3e8c0 00000000 6b0064f2 00000000
00000000`03e3e4c0 03e3f030 00000000 6b002510 00000000
00000000`03e3e4d0 00000000 00000000 03dfede8 00000000
00000000`03e3e4e0 c0000005 00000000 00000000 7d6210e8
00000000`03e3e4f0 00000002 00000000 00000000 00000000
00000000`03e3e500 00000000 00001000 78b83980 036b0000
There is this adress : 14badf55
I really don't know how to interpret this "bad"..
Is anyone have an idea of the meaning of this bad ?
EDIT:
when I try to use this command :
u 14badf55
the following output comes :
00000000`14badf55 ?? ???
^ Memory access error in 'u 14badf55'
The .ecxr command give me :
rax=0000000003e3e488 rbx=0000000003e3e8c0 rcx=0000000003e3dfb0
rdx=0000000000000000 rsi=000000006b005a17 rdi=0000000000000000
rip=000000006b006369 rsp=0000000003e3e490 rbp=0000000003dfede8
r8=000000006b00254a r9=0000000003e3e4d8 r10=0000000000000007
r11=0000000000000000 r12=000000006b01fe90 r13=0000000000000000
r14=0000000003e3f110 r15=0000000078b83980
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=0000 es=0000 fs=0000 gs=0000 efl=00000204
wow64!Wow64NotifyDebugger+0x9:
00000000`6b006369 b001 mov al,1
You can see the c0000005 output in the file. This is the sign of a access violation.
Run the following:
- .cxr 00000000`03e3e4e0 (To set the exception context)
- kL (to get a stack trace)