Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with --section-order and putting sections at different addresses #1173

Open
joolzg opened this issue Jan 10, 2024 · 11 comments
Open

Help with --section-order and putting sections at different addresses #1173

joolzg opened this issue Jan 10, 2024 · 11 comments

Comments

@joolzg
Copy link

joolzg commented Jan 10, 2024

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?

@rui314
Copy link
Owner

rui314 commented Jan 10, 2024

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?

@joolzg
Copy link
Author

joolzg commented Jan 10, 2024

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"

@joolzg
Copy link
Author

joolzg commented Jan 10, 2024

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
 

@joolzg
Copy link
Author

joolzg commented Feb 9, 2024

I have the linker linking my project, but still missing initdata and a few other problems with sections. Im plodding on

@rui314
Copy link
Owner

rui314 commented Feb 17, 2024

Let me know if there's anything I can help.

@joolzg
Copy link
Author

joolzg commented Mar 14, 2024 via email

@rui314
Copy link
Owner

rui314 commented Mar 19, 2024

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.

@joolzg
Copy link
Author

joolzg commented Mar 19, 2024

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....

@rui314
Copy link
Owner

rui314 commented Mar 19, 2024

Did you make all the other linker script command work for mold?

@joolzg
Copy link
Author

joolzg commented Mar 19, 2024

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

  1. Symbols defined but not having a value i set
  2. Sections always having their section owner as the 1st section in the list, instead of their real section name.
  3. Variables not being the correct type in the linker map
  4. 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.

@joolzg
Copy link
Author

joolzg commented Mar 27, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants