mold
mold copied to clipboard
Help with --section-order and putting sections at different addresses
Trying to get mold to work with a new processor type, ARC, and also get it working in the embedded world.
What i am trying to do is use the --section-order to create the sections needed and then use arc-elf32-objcopy tool to move certain sections, .bss/.data/.fastcode, into an new initdata section so on boot we can copy this data into the correct areas.
So my cli looks a bit like this
"--section-order=EHDR PHDR =0x20000 .fastcode =0x100000 ! .vectors TEXT RODATA .ctors .dtors =0x800000 !SDA_BASE DATA !BSS_BASE BSS !_fheap .heap !_eheap .stack !_estack"
Now the problem I am finding is that the fastcode is not put into the area 0x20000, but is added at the end of the normal .text area.
Any work around for this?
It's hard to debug without reproducing the issue locally. If your program is open-source, can you give me a pointer to the source code?
Im trying to find a way but what i am seeing is the toolchain is producing 2 sections with the same name but with different flags
I think, or hope, this is the cause
Section #602: lpc_common_retention, type=PROGBITS, addr=0x820800, off=0x7d800 size=16(0x10), link=0, info=0,align=4, entsize=0 flags=<WRITE,ALLOC>
Section #603: lpc_common_retention, type=NOBITS, addr=0x0, off=0x0 size=188(0xbc), link=0, info=0, align=4, entsize=0 flags=<WRITE,ALLOC>
Section #604: lpc_host_retention, type=PROGBITS, addr=0x0, off=0x7e000 size=764(0x2fc), link=0, info=0, align=8, entsize=0 flags=<WRITE,ALLOC>
Section #605: lpc_host_retention, type=NOBITS, addr=0x0, off=0x0 size=1828(0x724), link=0, info=0, align=4, entsize=0 flags=<WRITE,ALLOC>
Section #606: lpc_profiles_retention, type=PROGBITS, addr=0x0, off=0x7f000 size=392(0x188), link=0, info=0, align=4, entsize=0 flags=<WRITE,ALLOC>
Section #607: lpc_profiles_retention, type=NOBITS, addr=0x0, off=0x0 size=384(0x180), link=0, info=0, align=4, entsize=0 flags=<WRITE,ALLOC>
Section #608: lpc_controller_retention, type=NOBITS, addr=0x0, off=0x0 size=20(0x14), link=0, info=0, align=4, entsize=0 flags=<WRITE,ALLOC>
Section #609: lpc_retention_main, type=PROGBITS, addr=0x0, off=0x80000 size=168(0xa8), link=0, info=0, align=8, entsize=0 flags=<WRITE,ALLOC>
Section #610: lpc_retention_main, type=NOBITS, addr=0x0, off=0x0 size=1100(0x44c), link=0, info=0, align=16, entsize=0 flags=<WRITE,ALLOC>
Objdump of the sections
604 lpc_ll_retention 00001428 00000000 00000000 0007e000 2**3 CONTENTS, ALLOC, LOAD, DATA
605 lpc_ll_retention 000022b8 00000000 00000000 00000000 2**2 ALLOC
And the disassembly where the code goes wrong
820900: FF '.'
Content of section lpc_ll_retention (#605) size=0x1428 start=0x7e000
0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................'
10: FF FF FF FF 1F 00 00 00 00 00 00 00 00 00 00 00 '................'
"--section-order=EHDR PHDR =0x20100 time_critical time_critical_d
=0x100000 .vectors TEXT RODATA
=0x800000 !_SDA_BASE_ DATA BSS
=0x820000 lpc_controller_retention lpc_ll_retention lpc_common_retention lpc_host_retention lpc_profiles_retention lpc_retention_main"
Also I have 2 sections called time_critial and time_critical_d, time_critical_d is the only one that is put at address 0x20100, time_critical is just added to the .text, but as you can see the compler has produced a new section for each function.
Objdump gives
0 time_critical_d 00000044 00020100 00020100 00001100 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
--
15 time_critical.BbBleBisRxData 00000092 0016837c 0016837c 0006a37c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
...
105 time_critical.lctrMstBisRxCompletion 00000284 0016b604 0016b604 0006d604 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
I have the linker linking my project, but still missing initdata and a few other problems with sections. Im plodding on
Let me know if there's anything I can help.
I would love some help in creating the .initdat section.
I have the SVR3 parser working and a new sort_output_sections_by_linker_script and set_virtual_addresses_by_linker_script which do the mapping from the linker script, but i cannot work out where to add the initdat section creation and where to populate this.
So what is needed if the INITDATA is in the linker script, which can be checked by looking at a new variable in ctx.arg, std::vectorstd::string initdata_list; which in my test case will contain ".code_in_iccm", "data" and "bss" as the 3 strings
- inidat section created after sorting of the chunks
- Match the section name against the list in initdata_list, and if marked as as BSS append 2 longs into the initdat section, chunk.shdr.sh_addr and -chunk.shdr.sh_size, otherwise append 2 longs, chunk.shdr.sh_addr and chunk.shdr.sh_size, and the data in the chunk
- Remove these chunks from the output section.
- Append 2 longs to the initdat section, 0 and 0
- Create 2 symbols "_initdat" with start address of section and "_einitdat" with the end address.
On 2024-02-17 06:59, Rui Ueyama wrote:
Let me know if there's anything I can help.
-- Reply to this email directly, view it on GitHub [1], or unsubscribe [2]. You are receiving this because you authored the thread.Message ID: @.***>
Links:
[1] https://github.com/rui314/mold/issues/1173#issuecomment-1949718328 [2] https://github.com/notifications/unsubscribe-auth/AAIUQ6FPEE2CP26VQQP6PA3YUBBMPAVCNFSM6AAAAABBUQHT2OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBZG4YTQMZSHA
So, you are extending mold to support linker script SECTION command? It seems what is needed to do to sort it is complicated, and that's why I didn't support it in the first place. So I don't have an answer to your question. Sorry.
Thats a shame as it is only missing the INITDATA processing which would allow mold to be used on embedded projects.
I will carry on and try to integrate this in the code, but its hard work....
Did you make all the other linker script command work for mold?
Not 100 but most of the SVR3 works, I get a full link with all sections begin at the right addresses and the right sizes. And as I keep saying the only thing I am missing is being able to process the INITDATA option.
Once this is done I need to start looking into a few parts that are not implemented, FILL/BYTE/WORD/LONG/ etc
I also have a list of bits that are not working
- Symbols defined but not having a value i set
- Sections always having their section owner as the 1st section in the list, instead of their real section name.
- Variables not being the correct type in the linker map
- SIZE command not setting the section size, so the FILL command cannot work
As you see there are a lot of things that I dont need that do need to be implemented once I can finally build the image with a .initdat section.
OK. Got my initdata section up and running BUT i need to copy the contents of the data/code segemnts into the new segment and then remove the old data from the output list.
Here is the copy_buf code which gets a vector list of Chunk<E> * which need to be moved into this section, and also removed from the output file.
template <typename E>
void InitdataSection<E>::copy_buf(Context<E> &ctx) {
u8 *buf = (u8 *)(ctx.buf + this->shdr.sh_offset);
auto is_bss = [](Chunk<E> *chunk) {
return chunk->shdr.sh_type == SHT_NOBITS;
};
auto is_data = [](Chunk<E> *chunk) ->bool {
return chunk->shdr.sh_flags & SHF_WRITE;
};
auto size = 0;
// Start off initdat with INI and 0x02 (uncompressed)
memcpy( buf + size, "INI\002", 4);
size += 4;
size += 3;
size &= ~3;
// Copy DATA/(Section) or BSS
for( auto &chunk : chunks) {
u32 *ptr = reinterpret_cast<u32 *>(buf + size);
if( is_bss(chunk)) {
if( !chunk->noload) {
*ptr++ = chunk->shdr.sh_addr;
*ptr++ = -chunk->shdr.sh_size;
size += 8;
}
}
else {
*ptr++ = chunk->shdr.sh_addr;
*ptr++ = chunk->shdr.sh_size;
size += 8;
// Here I need to copy the contents of the chunk into the output HELP
auto min_size = std::min( Word<E>(20), chunk->shdr.sh_size);
if(is_data(chunk)) {
memcpy( ptr, "DATA SHOULD BE HERE", min_size);
}
else {
memcpy( ptr, "SECT SHOULD BE HERE", min_size);
}
size += chunk->shdr.sh_size;
}
size += 3;
size &= ~3;
// chunk->shdr.sh_size = 0;
}
// Finish off initdat with 0x00000000, 0x00000000
u32 *ptr = reinterpret_cast<u32 *>(buf + size);
*ptr++ = 0x00000000;
*ptr = 0x00000000;
}
So how do I get access to the data in the sections that need copied?
Thanks in advance
Joolz