Kingcom / armips

An assembler for various ARM and MIPS platforms. Builds available at http://buildbot.orphis.net/armips/
MIT License
363 stars 77 forks source link

Prevent armips from relocating sections #239

Closed dfuchsgruber closed 1 year ago

dfuchsgruber commented 1 year ago

Hi, I am trying to include an elf-file that has some sections I want armips to relocate (e.g. .text, .rodata) but other sections it should not relocate such as .data. Currently, armips will just bunch all sections in the (relocatable) elf-file together at the address I call .importobj "myelf.o". Of course, this section is given a specific address in the linker script:

.data (NOLOAD) : AT(0x0200000)
        {
                *(.data*)
        } >ewram

And I would like to somehow get armips to respect that this section is declared with the NOLOAD attribute and therefore should not be pasted into the binary. Also, the symbols defined in this sections should not be relocated.

Is there any way to achieve this as of now? If not, is it planned to realize this?

Kingcom commented 1 year ago

Hm... that is probably caused by not checking for SHT_NOBITS here: https://github.com/Kingcom/armips/blob/4f414f39aa3aaa54dd83e04b0c5f9e246d4837b4/Core/ELF/ElfRelocator.cpp#L311 As a quick fix, can you try to exclude the addition if the type is SHT_NOBITS, like here? https://github.com/Kingcom/armips/blob/4f414f39aa3aaa54dd83e04b0c5f9e246d4837b4/Core/ELF/ElfRelocator.cpp#L324

A minimal buildable example for a test would be great for this, if you've got the time!

dfuchsgruber commented 1 year ago

I think the issue is actually that the code tries to relocate the symbols of NOLOAD sections to the consecutive block where the object file is loaded to. What fixed it for me was setting the relocation offset of NOLOAD sections to their original address.

                if (section->getType() == SHT_NOBITS)
        {
            relocationOffsets[index] = section->getAddress();
        } else {
            while (relocationAddress % section->getAlignment())
                relocationAddress++;

            if (entry.label != nullptr)
                entry.label->setValue(relocationAddress);

            relocationOffsets[index] = relocationAddress;
            relocationAddress += size;
        }

Is this what is the intended outcome? If so, I can issue a PR right away.