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

add section in ELF file : unexpected section size #661

Open
arnopo opened this issue Jan 31, 2022 · 4 comments
Open

add section in ELF file : unexpected section size #661

arnopo opened this issue Jan 31, 2022 · 4 comments

Comments

@arnopo
Copy link

arnopo commented Jan 31, 2022

Describe the bug
I'm trying to add a binary as a section in an existing elf file.
my code is

def main():
    logging.basicConfig()
    logger = logging.getLogger(os.path.basename(__file__))

    elffile = lief.parse("input.elf")

    if elffile.format != lief.EXE_FORMATS.ELF:
        raise Exception('"%s" invalid executable format %s, expected %s'
                        % (args.inf, elffile.format, lief.EXE_FORMATS.ELF))
        return

    with open("binary.bin", 'rb') as f:
        bin_img = f.read()

    new_sec = lief.ELF.Section()
    new_sec.name = ".ext_bin"
    new_sec.content = bytearray(bin_img)
    new_sec.size = len(bin_img)
    new_sec.alignment = 4
    new_sec.virtual_address = 100000

    elffile.add(new_sec, True)
    print ('size written : %s' % new_sec.size, 'size expected: %s' % len(bin_img))

    elffile.write("out.elf")

    read_sec = elffile.get_section(".ext_bin")
    print ('size read : %s' % read_sec.size, 'size expected: %s' % new_sec.size)
    read_sec.size = len(bin_img)

    elffile.write("out.elf")

on console the result is

$ ./test.py
size written : 1900 size expected: 1900
size read : 4096 size expected: 1900

Seems that the new_sec.size is not reported in the out.elf ( readelf -S confirm it).
does the issue come from the elffile.add? or does is a normal behavior ( 4k page alignment forced)?

To Reproduce
Steps to reproduce the behavior: explained above

Expected behavior
size written : 1900 size expected: 1900
size read : 4096 size expected: 1900

Environment (please complete the following information):

  • Ubuntu 20.04
  • Target format: ELF
  • LIEF commit version:0.11.5-37bc2c9

Additional context
The elf file used for my test is generated for arm Cortex-M4 target

Thanks in advance for the help

@romainthomas
Copy link
Member

Hi @arnopo

Yes the +4k when adding a new section is the normal behavior as the loader enforces a relationship between segment VA and offset (c.f the recent blog post: Challenges in Modifying ELF Binaries)

In addition and for the specific case of AArch64, the ADRP instruction also makes this +4k mandatory.

@arnopo
Copy link
Author

arnopo commented Feb 1, 2022

Hi @romainthomas
Thanks for your answer! Agree that the elf format is quite tricky...

Does the rule your point out is applicable for all elf files? I'm working on micro-controllers such as Arm Cortex-M architecture...
Regarding Zephyr project elf files generated by gcc-arm-none-eabi, seems that this page alignment rule is not respected.

objdump -hw build/zephyr/zephyr_openamp_rsc_table.elf 

build/zephyr/zephyr_openamp_rsc_table.elf:     file format elf32-little

Sections:
Idx Name            Size      VMA       LMA       File off  Algn  Flags
  0 rom_start       00000298  00000000  00000000  000000d4  2**2  CONTENTS, ALLOC, LOAD, CODE
  1 text            0000659e  00000298  00000298  0000036c  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .ARM.exidx      00000008  00006838  00006838  0000690c  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 initlevel       000000a8  00006840  00006840  00006914  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 devices         00000198  000068e8  000068e8  000069bc  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 sw_isr_table    000004b0  00006a80  00006a80  00006b54  2**2  CONTENTS, ALLOC, LOAD, DATA
  6 device_handles  0000008e  00006f30  00006f30  00007004  2**1  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 rodata          000005b4  00006fc0  00006fc0  00007094  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .ramfunc        00000000  10000000  10000000  00007860  2**0  CONTENTS
  9 datas           00000104  10000000  00007574  00007648  2**2  CONTENTS, ALLOC, LOAD, DATA
 10 device_states   00000044  10000104  00007678  0000774c  2**2  CONTENTS, ALLOC, LOAD, DATA
 11 k_heap_area     00000014  10000148  000076bc  00007790  2**2  CONTENTS, ALLOC, LOAD, DATA
 12 k_sem_area      00000030  1000015c  000076d0  000077a4  2**2  CONTENTS, ALLOC, LOAD, DATA
 13 bss             000009eb  10000190  10000190  00007870  2**3  ALLOC
 14 noinit          000017c0  10000b80  10000b80  00007870  2**5  ALLOC
 15 .comment        0000002e  00000000  00000000  00007860  2**0  CONTENTS, READONLY
 16 .debug_aranges  000014e8  00000000  00000000  00007890  2**3  CONTENTS, READONLY, DEBUGGING, OCTETS
 17 .debug_info     0004b876  00000000  00000000  00008d78  2**0  CONTENTS, READONLY, DEBUGGING, OCTETS
 18 .debug_abbrev   0000ab14  00000000  00000000  000545ee  2**0  CONTENTS, READONLY, DEBUGGING, OCTETS
 19 .debug_line     0001b477  00000000  00000000  0005f102  2**0  CONTENTS, READONLY, DEBUGGING, OCTETS
 20 .debug_frame    00003198  00000000  00000000  0007a57c  2**2  CONTENTS, READONLY, DEBUGGING, OCTETS
 21 .debug_str      0000b18e  00000000  00000000  0007d714  2**0  CONTENTS, READONLY, DEBUGGING, OCTETS
 22 .debug_loc      000197ea  00000000  00000000  000888a2  2**0  CONTENTS, READONLY, DEBUGGING, OCTETS
 23 .debug_ranges   000057b8  00000000  00000000  000a2090  2**3  CONTENTS, READONLY, DEBUGGING, OCTETS
 24 .ARM.attributes 00000033  00000000  00000000  000a7848  2**0  CONTENTS, READONLY
 25 .resource_table 0000008c  00007700  00007700  000077d4  2**2  CONTENTS, ALLOC, LOAD, DATA

Sections are not aligned on page but on cache line or memory word size (32 bits in this case). And for this it seems to rely on the alignment property instead of the page alignment.

@romainthomas
Copy link
Member

Yes at least for Linux & Android it is applicable for all the ELF LOAD segments but not necessarily the sections.

Could you add a reference to the Zephyr Project, I'll check if the loader enforces this rule?

@arnopo
Copy link
Author

arnopo commented Feb 2, 2022

Yes at least for Linux & Android it is applicable for all the ELF LOAD segments but not necessarily the sections.

Regarding same elf file:

$ readelf -l build/zephyr/zephyr_openamp_rsc_table.elf 

Elf file type is EXEC (Executable file)
Entry point 0x1c0d
There are 5 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x00690c 0x00006838 0x00006838 0x00008 0x00008 R   0x4
  LOAD           0x0000d4 0x00000000 0x00000000 0x07574 0x07574 RWE 0x4
  LOAD           0x007648 0x10000000 0x00007574 0x0018c 0x0018c RW  0x4
  LOAD           0x0077d4 0x00007700 0x00007700 0x0008c 0x0008c RW  0x4
  LOAD           0x000000 0x10000190 0x10000190 0x00000 0x021b0 RW  0x20

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx 
   01     rom_start text .ARM.exidx initlevel devices sw_isr_table device_handles rodata 
   02     datas device_states k_heap_area k_sem_area 
   03     .resource_table 
   04     bss noinit 

Could you add a reference to the Zephyr Project, I'll check if the loader enforces this rule?

The zephyr Project supports more than 300 platforms, the flasher used to load the firmware in embedded flashes depends on the platform, so not an unique loader.

If you need a reference perhaps the linux remoteproc elf loader is a good candidate. It is used to load the coprocessor firmware based on a ELF file.

if you want more details on arm elf format: https://developer.arm.com/documentation/dui0101/a/

Thanks
Arnaud

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

No branches or pull requests

2 participants