How to fetch start address and size of different sections (like text data,rodata etc) - linker-scripts

How to fetch start address and size of different sections (like text data, rodata etc) without editing linker script (.gsi) file?
For example I have tried with the fallowing code and it is working fine:
_fourk_3 = _rvectors_start; (in linker script file)
To access same in code:
extern char fourk_3;
int test = &fourk_3;
Test will now contain rvector start address.

Related

linker script and changing the flash address

I would like to ask the following a question: im using stm32g0xx microcontroller and i want to change the flash address in linker script automatically and not be forced to changed manually every time i want to generate an apllication image to let it run from diffrent address. what im doing i wrote an application and i wrote it to tow different address"0x08001000 and 0x08004800" to have the apility to switch to other application incase one of them is updated or damaged. it worked fine but i need by every image to change the flash address manually and i would like to ask if it is possible to changed somewhere else out of the linker script like startup.s?
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
FLASH (rx) : ORIGIN = 0x8001000, LENGTH = 32K
}
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
FLASH (rx) : ORIGIN = 0x8004800, LENGTH = 32K
}
You can create two linker files and compile two times, each time with a different linker script and a different output binary. You will obtain the two necessary binaries. To integrate it on your project, it depends on your way of working (STM IDE, standalone Makefile...) which you did not mention.
As a side note, you should modify the LENGTH on your linker scripts, it will prevent the linker to place data where you have another application.
Your first application starts at 4KB (0x1000), and the second start at 18KB (0x4800), the lenght of the first application should be 18-4 = 16KB and the second LENGTH should be 32-18 = 14KB (if the FLASH total size is 32KB).
You can write two different linker script and apply one or the other in your building enviroment (with the -T linker flag) or you can use a variable for your ORIGIN and pass it with -Wl,--defsym=<VAR_NAME>=<VAR_VALUE>

Create a .efi to disable egpu and then chainload bootmgfw.efi

I'm using an .nsh to modify my pci from efi, and then I launch Windows from bootmgfw.efi.
But doing so the shell is visible for some seconds while commands are exacuting, and I don't think there is a way to execute this nsh silently.
But I don't know how to achieve this in an efi application:
"mm 000100003E 1" "fs0:/EFI/Microsoft/Boot/bootmgfw.efi"
So I'm here to ask you if there is a way to create an .efi to change my pci the exact same way, and launching the Windows bootloader after those changes, but silently.
The best would be to read pci addresses and the path of the bootloader from a .conf file. It would be helpful for lot of people in my case.
Short questions:
Commands to modify pci in an efi app?
Command to chainload to another .efi file?
EXTRA: Command to read a .conf file from filesystem to get text lines and use them inside the application as variables?
Thank you for your help
mm 000100003E 1 command is to write 1 at memory address 0x000100003E, in edk2 ShellPkg, it is implemented with a simple CopyMem function call, you can implement your own like this:
UINT8 value = 1;
CopyMem((VOID *)0x000100003E, &value, 1);
Calling another efi application in one efi application is possible, but its very complex, you need to do the following works:
Get device handle of fs0
Create device path for /EFI/Microsoft/Boot/bootmgfw.efi
Load and start the efi application
As the efi application you are going to write is also located in fs0, probably fs0:\EFI\BOOT\BOOTX64.EFI, you can get fs0's device handle from it.
// Get device handle of fs0 from current application
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
gBS->OpenProtocol(ImageHandle, &LoadedImageProtocol, &loaded_image, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
// Create device path
EFI_DEVICE_PATH_PROTOCOL *path = FileDevicePath(loaded_image->DeviceHandle, L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
// Load and start the image
EFI_HANDLE image;
gBS->LoadImage(FALSE, ImageHandle, path, NULL, 0, &image);
gBS->StartImage(image, NULL, NULL);
To read a configuration file, you need to use EFI File Protocol to open your config file and parse it on your own.
EFI_FILE_PROTOCOL *rootdir, *conffile;
UINT8 buf[1024];
UINTN bufsize = sizeof(buf);
// Open config file
rootdir = LibOpenRoot(loaded_image->DeviceHandle);
rootdir->Open(rootdir, &conffile, L"\\path\\to\\config", EFI_FILE_MODE_READ, 0);
// Read config file
conffile->Read(conffile, &bufsize, buf);
// Parse the file content in buf
// ...
// Close conffile and rootdir
conffile->Close(conffile);
rootdir->Close(rootdir);
edk2 or gnu-efi is required for the above code to work.
References:
edk2 ShellPkg mm command source code

Libfuzzer target for on-disk parsing

I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:
afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz ##
...where ## was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}
I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.
Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?
You can do as in this example from google security team.
The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:
(from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )
// Write the data provided in buf to a new temporary file. This function is
// meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
// take file names (and not data) as input.
//
// Return the path of the newly created file or NULL on error. The caller should
// eventually free the returned buffer (see delete_file).
extern "C" char *buf_to_file(const uint8_t *buf, size_t size);
Be sure to free the ressource with the delete_file function.
You could use LD_PRELOAD and override fread.

Simple UDP socket in VC++ MFC

I have been trying to write a working program that takes in data from a UDP socket and displays it in an edit control box as you receive the data (My exposure to c++ is also only about a week :P have only done embedded C code before). I have a working program that can send and output data on a button click but I want something that can do it in real time. The aim is scale this up into a larger GUI program that can send control data to hardware and get responses from them.
I have run into various problems including:
The program just not executing my OnReceivefunction (derived from
CAsyncSocket)
Getting the OnReceive function to run on a separate thread so that it can still run after a button has been clicked sending a control packet to the client then waiting for a response in a while loop
Not being able to output the data in the edit box (tried using both CEdit and CString)
ReplaceSel error saying that the type char is incompatible with LPCTSTR
My code is based on this codeproject.com tutorial, being almost exactly what I want but I get the error in 4.
EDIT: the error in 4. disappears when I change it to a TCHAR but then it outputs random chinese characters. The codeproject.com tutorial outputs the correct characters regardless of char or TCHAR declaration. When debugged my code has type wchar_t instead type char like the other code.
Chinese output
In the working program echoBuffer[0] the character sent and displayed was a 1
UINT ReceiveData(LPVOID pParam)
{
CTesterDlg *dlg = (CTesterDlg*)pParam;
AfxSocketInit(NULL);
CSocket echoServer;
// Create socket for sending/receiving datagrams
if (echoServer.Create(12345, SOCK_DGRAM, NULL) == 0)
{
AfxMessageBox(_T("Create() failed"));
}
for (;;)
{ // Run forever
// Client address
SOCKADDR_IN echoClntAddr;
// Set the size of the in-out parameter
int clntAddrLen = sizeof(echoClntAddr);
// Buffer for echo string
char echoBuffer[ECHOMAX];
// Block until receive message from a client
int recvMsgSize = echoServer.ReceiveFrom(echoBuffer, ECHOMAX, (SOCKADDR*)&echoClntAddr, &clntAddrLen, 0);
if (recvMsgSize < 0)
{
AfxMessageBox(_T("RecvFrom() failed"));
}
echoBuffer[recvMsgSize] = '\0';
dlg->m_edit.ReplaceSel(echoBuffer);
dlg->m_edit.ReplaceSel(_T("\r\n"));
}
}
After reading the link that #IInspectable provided about working with strings and checking the settings differences between the two programs it became clear that the issue lay with an incorrect conversion to UNICODE. My program does not require it so I disabled it.
This has cleared up the issue in 4. and provided solutions for 2 and 3.
I also think I know why another instance of my program would not run OnReceivein 1. because that file was not being defined by one that was already being run by the program, but that is now irrelevant.

Sinatra example code to download a large file

I started using sinatra,
Right now I'm using the following code to handle file downloads,
It works great for small files, but when it comes to large files > 500MB
The connection disconnects in the middle.
dpath = "/some root path to file"
get '/getfile/:path' do |path|
s = path.to_s
s.gsub!("-*-","/")
fn = s.split("/").last
s = dpath +"/"+ s
send_file s,:filename => fn
end
Two things:
What does your validate method do? If it's trying to open the file in memory, you might be running out of ram on your server (especially with large files).
Where are you setting fn ? It's a local variable inside the get scope and there's nothing setting it in your code example.